# 9/23 HW
## 無法存入DEV06
```
test start 1000 test program for sic software
first stl retadr save return address
cloop jsub rdrec read input record
lda length test for eof (length = 0
comp zero eol == 1)
jeq endf exit if eof found
jsub wrrec write output record
j cloop loop
ldl retadr get return address
rsub return to caller
eof byte c'EOF'
three word 3
zero word 0
one word 1
k5 word 5
k11 word 11
retadr resw 1
length resw 1
buffer resb 4096 4096-byte buffer area
.
. subroutine to read record into buffer
.
rdrec ldx zero clear loop counter
lda zero clear a to zero
rloop td input test input device
jeq rloop loop until ready
rd input read character into register a
comp k11 test for eol or eof
jlt exit exit loop if found
sta temp store character in temp
lda temp load character into a
comp ch0 cmp with 0
jeq chg1 if equal change to 1
comp ch1 cmp with 1
jeq chg0 if equal change to 0
comp ch2 cmp with 2
jeq chg3 if equal change to 3
comp ch3 cmp with 3
jeq chg2 if equal change to 2
comp ch4 cmp with 4
jeq chg5 if equal change to 5
comp ch5 cmp with 5
jeq chg4 if equal change to 4
j store else no change
chg1 lda ch1 load 1
j store
chg0 lda ch0 load 0
j store
chg3 lda ch3 load 3
j store
chg2 lda ch2 load 2
j store
chg5 lda ch5 load 5
j store
chg4 lda ch4 load 4
j store
store stch buffer,x store character in buffer
tix maxlen loop unless max length
jlt rloop has been reached
exit stch buffer,x store eol/eof in buffer
stx length save record length
comp k5
jlt endrd
lda length modify record length to include
add one eol
sta length
endrd lda zero set length to zero to indicate EOF
sta length
rsub return to caller
temp resb 1
ch0 word 48
ch1 word 49
ch2 word 50
ch3 word 51
ch4 word 52
ch5 word 53
input byte x'f3' code for input device
maxlen word 4096
.
. subroutine to write record from buffer
.
wrrec ldx zero clear loop counter
wloop td output test output device
jeq wloop loop until ready
ldch buffer,x get character from buffer
wd output write character
tix length loop until all characters
jlt wloop have been written
rsub return to caller
output byte x'06' code for output device
endf end first
```
## exer2(趙哥's version)
```
exer2 start 1000 test program for sic software
first stl retadr save return address
cloop jsub rdrec read input record
lda length test for eof (length = 0
comp zero eol == 1)
jeq last exit if eof found
jsub wrrec write output record
j cloop loop
zero word 0
one word 1
three word 3
k5 word 5
k11 word 11
t0 word 48
t1 word 49
t2 word 50
t3 word 51
t4 word 52
t5 word 53
retadr resw 1
length resw 1
buffer resb 4096 4096-byte buffer area
.
. subroutine to read record into buffer
.
rdrec ldx zero clear loop counter
lda zero clear a to zero
rloop td input test input device
jeq rloop loop until ready
rd input read character into register a
comp k11 test for eol or eof
jlt exit exit loop if found
comp t0
JEQ switch0
comp t1
JEQ switch1
comp t2
JEQ switch2
comp t3
JEQ switch3
comp t4
JEQ switch4
comp t5
JEQ switch5
write stch buffer,x store character in buffer
tix maxlen loop unless max length
jlt rloop has been reached
exit stch buffer,x store eol/eof in buffer
stx length save record length
comp k5
jlt endrd
lda length modify record length to include
add one eol
sta length
endrd rsub return to caller
input byte x'f3' code for input device
maxlen word 4096
.
. subroutine to write record from buffer
.
wrrec ldx zero clear loop counter
wloop td output test output device
jeq wloop loop until ready
ldch buffer,x get character from buffer
wd output write character
tix length loop until all characters
jlt wloop have been written
rsub return to caller
switch0 lda t1
j write
switch1 lda t0
j write
switch2 lda t3
j write
switch3 lda t2
j write
switch4 lda t5
j write
switch5 lda t4
j write
output byte x'06' code for output device
last end first
```
## 3 88bear's final version
```
test start 1000 test program for sic software
first stl retadr save return address
cloop jsub rdrec read input record
lda length test for eof (length = 0
comp zero eol == 1)
jeq endf exit if eof found
jsub wrrec write output record
j cloop loop
eof byte c'EOF'
three word 3
zero word 0
one word 1
k5 word 5
k11 word 11
retadr resw 1
length resw 1
buffer resb 4096 4096-byte buffer area
.
. subroutine to read record into buffer
.
rdrec ldx zero clear loop counter
lda zero clear a to zero
rloop td input test input device
jeq rloop loop until ready
rd input read character into register a
comp k11 test for eol or eof
jlt exit exit loop if found
comp ch0 cmp with 0
jeq chg1 if equal change to 1
comp ch1 cmp with 1
jeq chg0 if equal change to 0
comp ch2 cmp with 2
jeq chg3 if equal change to 3
comp ch3 cmp with 3
jeq chg2 if equal change to 2
comp ch4 cmp with 4
jeq chg5 if equal change to 5
comp ch5 cmp with 5
jeq chg4 if equal change to 4
j store else no change
chg1 lda ch1 load 1
j store
chg0 lda ch0 load 0
j store
chg3 lda ch3 load 3
j store
chg2 lda ch2 load 2
j store
chg5 lda ch5 load 5
j store
chg4 lda ch4 load 4
j store
store stch buffer,x store character in buffer
tix maxlen loop unless max length
jlt rloop has been reached
exit stch buffer,x store eol/eof in buffer
stx length save record length
comp k5
jlt endrd
lda length modify record length to include
add one eol
sta length
endrd rsub return to caller
temp resb 1
ch0 word 48
ch1 word 49
ch2 word 50
ch3 word 51
ch4 word 52
ch5 word 53
input byte x'F3' code for input device
maxlen word 4096
.
. subroutine to write record from buffer
.
wrrec ldx zero clear loop counter
wloop td output test output device
jeq wloop loop until ready
ldch buffer,x get character from buffer
wd output write character
tix length loop until all characters
jlt wloop have been written
rsub return to caller
output byte x'06' code for output device
endf end first
```
---------------------
# 9/30 hw
## 88bear's version
```cpp
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
#include <sstream>
#include <vector>
using namespace std;
signed main(){
string str;
while(getline(cin, str)){
if(str.empty() || str[0] == '.') continue;
if(str.length() > 35) str = str.substr(0, 35);
// 殺掉頭空白 ex:空空空k73 word 73
auto firstnotspace = str.find_first_not_of(" \t");
if(firstnotspace != string::npos)
str = str.substr(firstnotspace);
else
continue;
istringstream iss(str);
string label, opcode, operand;
string token;
vector<string> tokens;
while(iss >> token) tokens.push_back(token);
if(tokens.empty()) continue;
if(tokens.size() == 3){
label = tokens[0];
opcode = tokens[1];
operand = tokens[2];
}else if(tokens.size() == 2){
//endrd 我看成special case去處理 不確定能不能這樣搞
//反正如果有其他指令也只是建表多一個for去遍歷表而已ㄏㄏ
if(tokens[0] == "endrd"){
label = tokens[0];
opcode = tokens[1];
operand = "";
}
else{
label = "";
opcode = tokens[0];
operand = tokens[1];
}
}else if(tokens.size() == 1){
label = "";
opcode = tokens[0];
operand = "";
}
for(auto &ch : label) ch = toupper(ch);
for(auto &ch : opcode) ch = toupper(ch);
bool corx = true; //operand (c'' or x'')
if(operand.size() >= 2 && operand[1] == '\''){
char type = toupper(operand[0]);
if(type == 'C' && operand[1] == '\'')
corx = false;
else if(type == 'X' && operand[1] == '\'')
corx = true;
}
// operand 處理
bool inq = false;
for(size_t i = 0; i < operand.size(); ++i){
if(operand[i] == '\'')
inq = !inq;
else{
if(!inq){
operand[i] = toupper(operand[i]);
}
else{
if(corx)
operand[i] = toupper(operand[i]);
}
}
}
//輸出 left(setw向左靠齊,預設為right)
cout << left << setw(8) << label << ' ';
//endrd 我看成special case去處理 不確定能不能這樣搞
if(tokens.size() == 1 || tokens[0] == "endrd")
cout << opcode;
else
cout << left << setw(6) << opcode << " ";
cout << operand << '\n';
}
return 0;
}
```
# 10/7 HW
## exer4
--------
```cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <vector>
#include <iomanip>
using namespace std;
struct sym{
string label;
int addr;
};
string i2hex(int value, int width = 4){ //int to hex
stringstream ss;
ss << setfill('0') << setw(width) << hex << uppercase << value;
return ss.str();
}
int bytecnt(const string& operand1){ // count the byte C or X
if (operand1[0] == 'C'){
return operand1.length() - 3;
}else if (operand1[0] == 'X') {
return (operand1.length() - 3) / 2;
}
return 1;
}
int main(){
ofstream intfile("INTFILE");
ofstream symtab("SYMTAB");
string line;
int loc = 0x1000;
int staddr = 0x1000;
string codename;
map<string, sym> symtable;
vector<string> intFileLines;
bool findst = false;
int codelong = 0;
while(getline(cin, line)){
// same input
istringstream iss(line);
string label, opcode, operand;
string token;
vector<string> tokens;
while(iss >> token){
tokens.push_back(token);
}
if(tokens.size() == 3){
label = tokens[0];
opcode = tokens[1];
operand = tokens[2];
}else if (tokens.size() == 2){
if(tokens[0] == "ENDRD"){
label = tokens[0];
opcode = tokens[1];
operand = "";
}
else{
label = "";
opcode = tokens[0];
operand = tokens[1];
}
}else if (tokens.size() == 1){
label = "";
opcode = tokens[0];
operand = "";
}
if(opcode == "START"){
loc = stoi(operand, nullptr, 16);
staddr = loc;
codename = label;
findst = true;
string intfileEntry = i2hex(loc, 6) + " " + line;
intFileLines.push_back(intfileEntry);
continue;
}
string intfileEntry = i2hex(loc, 6) + " " + line;
intFileLines.push_back(intfileEntry);
if(!label.empty()){
symtable[label] = {label, loc};
}
if(opcode == "WORD"){ loc += 3;
}else if (opcode == "RESW"){ loc += stoi(operand) * 3;
}else if (opcode == "RESB"){ loc += stoi(operand);
}else if (opcode == "BYTE"){ loc += bytecnt(operand);
}else{ loc += 3;
}
if(opcode == "END"){
codelong = loc - staddr - 3;
}
}
for(const string& entry : intFileLines){
intfile << entry << '\n';
}
symtab << left << setw(6) << codename << " " << i2hex(staddr, 6) << " " << i2hex(codelong, 6) << '\n';
for(const auto& [label, sym] : symtable){
symtab << left << setw(6) << sym.label << " " << i2hex(sym.addr, 6) << '\n';
}
intfile.close();
symtab.close();
return 0;
}
```
---------------
# 1014 HW
## exer5
```cpp=
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <iomanip>
#include <vector>
#include <set>
using namespace std;
map<string, string> symTable;
string codename, staddr, codelen;
map<string, string> opcodeTable = {
{"LDA", "00"}, {"STA", "0C"}, {"ADD", "18"},
{"SUB", "1C"}, {"MUL", "20"}, {"DIV", "24"},
{"COMP", "28"}, {"J", "3C"}, {"JLT", "38"},
{"JEQ", "30"}, {"JGT", "34"}, {"JSUB", "48"},
{"RSUB", "4C"}, {"LDCH", "50"}, {"STCH", "54"},
{"LDX", "04"}, {"STX", "10"}, {"TIX", "2C"},
{"RD", "D8"}, {"WD", "DC"}, {"TD", "E0"},
{"STL", "14"}, {"LDL", "08"}
};
string i2hex(int value, int width){
stringstream ss;
ss << setw(width) << setfill('0') << hex << uppercase << (value & ((1 << (width * 4)) - 1));
return ss.str();
}
void loadSYMTAB(const string& filename){
ifstream symtab_file(filename);
string str;
getline(symtab_file, str);
istringstream iss(str);
iss >> codename >> staddr >> codelen;
string label, address;
while(symtab_file >> label >> address){
symTable[label] = address;
}
symtab_file.close();
}
void pH(){
cout << "H" << setw(6) << left << codename.substr(0, 6)
<< staddr << codelen << '\n';
}
void pE(){
cout << "E" << staddr << '\n';
}
string getOperandAddr(const string& addr){
int addrValue = stoi(addr, nullptr, 16);
addrValue &= 0xFFFF;
return i2hex(addrValue, 4);
}
void pT(const string& intFile){
ifstream inputfile(intFile);
string str, text_st_addr, txt;
int txt_len = 0;
set<string> nonOperand = {"RSUB"};
set<string> directives = {"START", "END", "BYTE", "WORD", "RESW", "RESB"};
while(getline(inputfile, str)){
istringstream iss(str);
string addr, label, opcode, operand;
string token;
vector<string> tokens;
while(iss >> token){
tokens.push_back(token);
}
if(tokens.size() == 4){
addr = tokens[0];
label = tokens[1];
opcode = tokens[2];
operand = tokens[3];
}else if (tokens.size() == 3){
addr = tokens[0];
if(opcodeTable.find(tokens[1]) != opcodeTable.end() || directives.find(tokens[1]) != directives.end()){
label = "";
opcode = tokens[1];
operand = tokens[2];
}else{
label = tokens[1];
opcode = tokens[2];
operand = "";
}
}else if (tokens.size() == 2){
addr = tokens[0];
if(opcodeTable.find(tokens[1]) != opcodeTable.end() || directives.find(tokens[1]) != directives.end()){
label = "";
opcode = tokens[1];
operand = "";
}else{
label = tokens[1];
opcode = "";
operand = "";
}
}else{
continue;
}
if(opcode == "START" || opcode == "END"){
continue;
}
if(opcode == "RESW" || opcode == "RESB"){
if(!txt.empty()){
cout << "T" << text_st_addr << i2hex(txt_len, 2) << txt << '\n';
txt.clear();
text_st_addr.clear();
txt_len = 0;
}
continue;
}
string objCode;
if(opcode == "WORD"){
int value = stoi(operand);
objCode = i2hex(value, 6);
}else if(opcode == "BYTE"){
if(operand[0] == 'C' && operand[1] == '\'' && operand.back() == '\''){
string chars = operand.substr(2, operand.size() - 3);
for(char c : chars){
stringstream ss;
ss << setw(2) << setfill('0') << hex << uppercase << (int)c;
objCode += ss.str();
}
}else if(operand[0] == 'X' && operand[1] == '\'' && operand.back() == '\''){
objCode = operand.substr(2, operand.size() - 3);
}
}else if(opcodeTable.find(opcode) != opcodeTable.end()){
string opcodeHex = opcodeTable[opcode];
string operandAddr = "0000";
if(nonOperand.find(opcode) != nonOperand.end()){
operandAddr = "0000";
}else{
if(!operand.empty()){
bool indexed = false;
if(operand.size() > 2 && operand.substr(operand.size() - 2) == ",X"){
indexed = true;
operand = operand.substr(0, operand.size() - 2);
}
if(symTable.find(operand) != symTable.end()){
operandAddr = getOperandAddr(symTable[operand]);
if(indexed){
int addrValue = stoi(operandAddr, nullptr, 16);
addrValue |= 0x8000;
operandAddr = i2hex(addrValue, 4);
}
}else{
operandAddr = "0000";
}
}
}
objCode = opcodeHex + operandAddr;
}else{
continue;
}
if(text_st_addr.empty()){
text_st_addr = addr;
}
if((txt_len + objCode.length() / 2) > 30){
cout << "T" << text_st_addr << i2hex(txt_len, 2) << txt << '\n';
txt = objCode;
text_st_addr = addr;
txt_len = objCode.length() / 2;
}else{
txt += objCode;
txt_len += objCode.length() / 2;
}
}
if(!txt.empty()){
cout << "T" << text_st_addr << i2hex(txt_len, 2) << txt << '\n';
}
inputfile.close();
}
int main(){
loadSYMTAB("SYMTAB");
pH();
pT("INTFILE");
pE();
return 0;
}
```