---
# System prepended metadata

title: sp1131

---

# 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;
}

```