123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909 |
- /*****************************************************************************/
- /* */
- /* ASM (B322 Assembler) */
- /* */
- /* Assembler for B322 */
- /* Specifically made to assemble the output of BCC on FPGC */
- /* Assembles for userBDOS specifically */
- /* */
- /* Main file */
- /* */
- /*****************************************************************************/
- /* Notes:
- - everything after the last \n is ignored, should not be a problem because wrapper
- - does not support includes or other things that are not used when using BCC
- - does not support asm defines, because of performance reasons
- - also does not keep track of line numbers for errors and does less checks for errors
- since the input is from BCC and therefore has some kind of standard
- */
- #define word char
- #define STDIO_FBUF_ADDR 0x440000
- #include "lib/math.c"
- #include "lib/sys.c"
- #include "lib/stdlib.c"
- #include "lib/fs.c"
- #include "lib/stdio.c"
- #define USERBDOS_OFFSET 0x400000 // applied offset to all labels
- #define OUTFILE_DATA_ADDR 0x500000
- #define OUTFILE_CODE_ADDR 0x540000
- #define OUTFILE_PASS1_ADDR 0x580000
- #define OUTFILE_PASS2_ADDR 0x600000
- #define LABELLISTLINENR_ADDR 0x65F000
- #define LABELLIST_ADDR 0x660000
- #define LINEBUFFER_ADDR 0x4C0000
- char infilename[96];
- char *lineBuffer = (char*) LINEBUFFER_ADDR;
- word memCursor = 0; // cursor for readMemLine
- word globalLineCursor = 0; // to keep track of the line number for labels
- #define LABELLIST_SIZE 2048 // expecting a lot of labels! as of writing, BDOS has ~1000 TODO: 2048 when done
- #define LABEL_NAME_SIZE 32 // max length of a label (therefore of a function name)
- char (*labelListName)[LABEL_NAME_SIZE] = (char (*)[LABEL_NAME_SIZE]) LABELLIST_ADDR; // 2d array containing all lines of the input file
- //char labelListName[LABELLIST_SIZE][LABEL_NAME_SIZE]; // old version, makes binary too large
- word* labelListLineNumber = (word*) LABELLISTLINENR_ADDR;
- //word labelListLineNumber[LABELLIST_SIZE]; // value should be the line number of the corresponding label name
- word labelListIndex = 0; // current index in the label list
- word prevLinesWereLabels = 0; // allows the current line to know how many labels are pointing to it
- // reads a line from the input file, tries to remove all extra characters
- word readFileLine()
- {
- word foundStart = 0;
- word foundComment = 0;
- word outputi = 0;
- char c = fgetc();
- char cprev = c;
- // stop on EOF or newline
- while (c != EOF && c != '\n')
- {
- // if we have found a comment, ignore everything after
- if (c == ';')
- {
- foundComment = 1;
- }
- if (!foundComment)
- {
- // if we have not found the first non-space yet, ignore until a non-space
- if (!foundStart)
- {
- if (c == ' ')
- {
- // do nothing until we find a non-space
- }
- else
- {
- foundStart = 1;
- lineBuffer[outputi] = c;
- outputi++;
- }
- }
- else
- {
- if (cprev == ' ' && c == ' ')
- {
- // ignore double space
- }
- else
- {
- lineBuffer[outputi] = c;
- outputi++;
- }
- }
- }
-
-
- cprev = c;
- c = fgetc();
- }
- lineBuffer[outputi] = 0; // terminate
- if (c == EOF)
- {
- if (lineBuffer[0] != 0)
- {
- // all code after the last \n is ignored!
- BDOS_PrintConsole("Skipped: ");
- BDOS_PrintConsole(lineBuffer);
- BDOS_PrintConsole("\n");
- }
- return EOF;
- }
- // if empty line, read next line
- if (outputi == 0)
- {
- return readFileLine();
- }
- else if (lineBuffer[outputi-1] == ' ')
- {
- // remove trailing space
- lineBuffer[outputi-1] = 0;
- }
- return 0;
- }
- // Reads a line from memory
- // Assumes all extra characters are already processed
- word readMemLine(char* memAddr)
- {
- word outputi = 0;
- char c = memAddr[memCursor];
- memCursor++;
- while (c != 0 && c != '\n')
- {
- lineBuffer[outputi] = c;
- outputi++;
- c = memAddr[memCursor];
- memCursor++;
- }
- lineBuffer[outputi] = 0; // terminate
- // memory ends with a 0
- if (c == 0)
- {
- return EOF;
- }
- // if empty line, read next line
- if (outputi == 0)
- {
- BDOS_PrintConsole("Empty string in readMemLine!!!\n");
- return EOF;
- }
- return 0;
- }
- // Fills bufOut with argi in linebuffer
- void getArgPos(word argi, char* bufOut)
- {
- word linei = 0;
- char c = 0;
- word lineLength = strlen(lineBuffer);
- while(argi > 0 && linei < lineLength)
- {
- c = lineBuffer[linei];
- if (c == ' ')
- {
- argi--;
- }
- linei++;
- }
- if (linei == 0)
- {
- BDOS_PrintConsole("getArgPos error");
- exit(1);
- }
- // copy until space or \n
- word i = 0;
- c = lineBuffer[linei];
- while (c != ' ' && c != 0)
- {
- bufOut[i] = c;
- linei++;
- i++;
- c = lineBuffer[linei];
- }
- bufOut[i] = 0; // terminate
- }
- // parses the number at argument i in linebuffer
- // can be hex or decimal or binary
- word getNumberAtArg(word argi)
- {
- word linei = 0;
- char c = 0;
- word lineLength = strlen(lineBuffer);
- while(argi > 0 && linei < lineLength)
- {
- c = lineBuffer[linei];
- if (c == ' ')
- {
- argi--;
- }
- linei++;
- }
- if (linei == 0)
- {
- BDOS_PrintConsole("NumberAtArg error");
- exit(1);
- }
- // linei is now at the start of the number string
- // copy until space or \n
- char strNumberBuf[36];
- word i = 0;
- c = lineBuffer[linei];
- while (c != ' ' && c != 0)
- {
- strNumberBuf[i] = c;
- linei++;
- i++;
- c = lineBuffer[linei];
- }
- strNumberBuf[i] = 0; // terminate
- word valueToReturn = 0;
- if (strNumberBuf[1] == 'x' || strNumberBuf[1] == 'X')
- {
- // hex number
- valueToReturn = hexToInt(strNumberBuf);
- }
- else if (strNumberBuf[1] == 'b' || strNumberBuf[1] == 'B')
- {
- // binary number
- valueToReturn = binToInt(strNumberBuf);
- }
- else
- {
- // dec number
- valueToReturn = decToInt(strNumberBuf);
- }
- return valueToReturn;
- }
- // returns 1 if the current line is a label
- word isLabel()
- {
- // loop until \0 or space
- word i = 0;
- while(lineBuffer[i] != 0 && lineBuffer[i] != ' ')
- {
- i++;
- }
- // empty line
- if (i == 0)
- {
- return 0;
- }
- // label if ends with :
- if (lineBuffer[i-1] == ':')
- {
- return 1;
- }
- return 0;
- }
- void Pass1StoreLabel()
- {
- // loop until \0 or space
- word labelStrLen = 0;
- while(lineBuffer[labelStrLen] != 0 && lineBuffer[labelStrLen] != ' ')
- {
- labelStrLen++;
- }
- // store label name minus the :
- memcpy(labelListName[labelListIndex], lineBuffer, labelStrLen-1);
- // terminate
- labelListName[labelListIndex][labelStrLen-1] = 0;
- labelListIndex++;
- // labelListLineNumber will be set when the next instruction is found
- // notify next line that it has a label
- prevLinesWereLabels++;
- }
- void Pass1StoreDefine()
- {
- // defines are not supported right now, so they are skipped
- }
- // Create two lines with the same args:
- // loadLabelLow
- // loadLabelHigh
- // returns the number of lines added
- word Pass1Addr2reg(char* outputAddr, char* outputCursor)
- {
- word lineBufArgsLen = strlen(lineBuffer) - 9; // minus addr2len and space
- // copy name of instruction
- memcpy((outputAddr + *outputCursor), "loadLabelLow ", 13);
- (*outputCursor) += 13;
- // copy args
- memcpy((outputAddr + *outputCursor), (lineBuffer+9), lineBufArgsLen);
- (*outputCursor) += lineBufArgsLen;
- // add a newline
- *(outputAddr + *outputCursor) = '\n';
- (*outputCursor)++;
- // copy name of instruction
- memcpy((outputAddr + *outputCursor), "loadLabelHigh ", 14);
- (*outputCursor) += 14;
- // copy args
- memcpy((outputAddr + *outputCursor), (lineBuffer+9), lineBufArgsLen);
- (*outputCursor) += lineBufArgsLen;
- // add a newline
- *(outputAddr + *outputCursor) = '\n';
- (*outputCursor)++;
- return 2;
- }
- // Converts into load and loadhi
- // skips loadhi if the value fits in 32bits
- // returns the number of lines added
- word Pass1Load32(char* outputAddr, char* outputCursor)
- {
- // get the destination register
- char dstRegBuf[16];
- getArgPos(2, dstRegBuf);
- word dstRegBufLen = strlen(dstRegBuf);
- // get and parse the value that is being loaded
- word load32Value = getNumberAtArg(1);
- // split into 16 bit unsigned values
- word mask16Bit = 0xFFFF;
- word lowVal = load32Value & mask16Bit;
- word highVal = (load32Value >> 16) & mask16Bit;
- // add lowval
- char buf[16];
- itoa(lowVal, buf);
- word buflen = strlen(buf);
- // copy name of instruction
- memcpy((outputAddr + *outputCursor), "load ", 5);
- (*outputCursor) += 5;
- // copy value
- memcpy((outputAddr + *outputCursor), buf, buflen);
- (*outputCursor) += buflen;
- // add a space
- *(outputAddr + *outputCursor) = ' ';
- (*outputCursor)++;
- // copy destination register
- memcpy((outputAddr + *outputCursor), dstRegBuf, dstRegBufLen);
- (*outputCursor) += dstRegBufLen;
- // add a newline
- *(outputAddr + *outputCursor) = '\n';
- (*outputCursor)++;
- // add highval
- if (highVal) // skip if 0
- {
- itoa(highVal, buf);
- word buflen = strlen(buf);
- // copy name of instruction
- memcpy((outputAddr + *outputCursor), "loadhi ", 7);
- (*outputCursor) += 7;
- // copy value
- memcpy((outputAddr + *outputCursor), buf, buflen);
- (*outputCursor) += buflen;
- // add a space
- *(outputAddr + *outputCursor) = ' ';
- (*outputCursor)++;
- // copy destination register
- memcpy((outputAddr + *outputCursor), dstRegBuf, dstRegBufLen);
- (*outputCursor) += dstRegBufLen;
- // add a newline
- *(outputAddr + *outputCursor) = '\n';
- (*outputCursor)++;
- return 2;
- }
- return 1;
- }
- // Creates a single .dw line using numBuf as value
- void addSingleDwLine(char* outputAddr, char* outputCursor, char* numBuf)
- {
- word numBufLen = strlen(numBuf);
- // copy name of instruction
- memcpy((outputAddr + *outputCursor), ".dw ", 4);
- (*outputCursor) += 4;
- // copy value
- memcpy((outputAddr + *outputCursor), numBuf, numBufLen);
- (*outputCursor) += numBufLen;
- // add a newline
- *(outputAddr + *outputCursor) = '\n';
- (*outputCursor)++;
- }
- // Puts each value after .dw on its own line with its own .dw prefix
- // returns the number of lines added
- word Pass1Dw(char* outputAddr, char* outputCursor)
- {
- word numberOfLinesAdded = 0;
- char numBuf[36]; // buffer to store each space separated number in
- word i = 0;
- word linei = 4; // index of linebuffer, start after .dw
- char c = lineBuffer[linei];
- while (c != 0)
- {
- if (c == ' ')
- {
- numBuf[i] = 0; // terminate
- addSingleDwLine(outputAddr, outputCursor, numBuf); // process number
- numberOfLinesAdded++;
- i = 0; // reset numBuf index
- }
- else
- {
- numBuf[i] = c;
- i++;
- }
- linei++;
- c = lineBuffer[linei];
- }
- numBuf[i] = 0; // terminate
- addSingleDwLine(outputAddr, outputCursor, numBuf); // process the final number
- numberOfLinesAdded++;
- return numberOfLinesAdded;
- }
- void Pass1Db(char* outputAddr, char* outputCursor)
- {
- BDOS_PrintConsole(".DB is not yet implemented!\n");
- exit(1);
- }
- // Convert each line into the number of lines equal to the number of words in binary
- // Also reads defines and processes labels
- void LinePass1(char* outputAddr, char* outputCursor)
- {
- // non-instructions
- if (memcmp(lineBuffer, "define ", 7))
- {
- Pass1StoreDefine();
- }
- else if (isLabel())
- {
- Pass1StoreLabel();
- }
- else
- {
- // all instructions that can end up in multiple lines
- // set values to the labels (while loop, since multiple labels can point to the same addr)
- while(prevLinesWereLabels > 0)
- {
- labelListLineNumber[labelListIndex - prevLinesWereLabels] = globalLineCursor;
- prevLinesWereLabels--;
- }
- if (memcmp(lineBuffer, "addr2reg ", 9))
- {
- globalLineCursor += Pass1Addr2reg(outputAddr, outputCursor);
- }
- else if (memcmp(lineBuffer, "load32 ", 7))
- {
- globalLineCursor += Pass1Load32(outputAddr, outputCursor);
- }
- else if (memcmp(lineBuffer, ".dw ", 4))
- {
- globalLineCursor += Pass1Dw(outputAddr, outputCursor);
- }
- else if (memcmp(lineBuffer, ".db ", 4))
- {
- Pass1Db(outputAddr, outputCursor);
- }
- else
- {
- // just copy the line
- word lineBufLen = strlen(lineBuffer);
- memcpy((outputAddr + *outputCursor), lineBuffer, lineBufLen);
- (*outputCursor) += lineBufLen;
- // add a newline
- *(outputAddr + *outputCursor) = '\n';
- (*outputCursor)++;
- globalLineCursor++;
- }
- }
- }
- void doPass1()
- {
- BDOS_PrintConsole("Doing pass 1\n");
- memCursor = 0; // reset cursor for readMemLine
- globalLineCursor = 0; // keep track of the line number for the labels
- char* outfileCodeAddr = (char*) OUTFILE_CODE_ADDR; // read from
- char* outfilePass1Addr = (char*) OUTFILE_PASS1_ADDR; // write to
- word filePass1Cursor = 0;
- // add userBDOS header instructions
- memcpy(outfilePass1Addr, "jump Main\njump Int1\njump Int2\njump Int3\njump Int4\n", 50);
- filePass1Cursor += 50;
- globalLineCursor += 5;
- while (readMemLine(outfileCodeAddr) != EOF)
- {
- LinePass1(outfilePass1Addr, &filePass1Cursor);
- }
- outfilePass1Addr[*(&filePass1Cursor)] = 0; // terminate
- }
- #include "pass2.c"
- void LinePass2(char* outputAddr, char* outputCursor)
- {
- // Go through all possible instructions:
- if (memcmp(lineBuffer, "halt", 4))
- pass2Halt(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "read ", 5))
- pass2Read(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "write ", 6))
- pass2Write(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "copy ", 5))
- pass2Copy(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "push ", 5))
- pass2Push(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "pop ", 4))
- pass2Pop(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "jump ", 5))
- pass2Jump(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "jumpo ", 6))
- pass2Jumpo(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "jumpr ", 6))
- pass2Jumpr(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "load ", 5))
- pass2Load(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "loadhi ", 7))
- pass2Loadhi(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "beq ", 4))
- pass2Beq(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "bne ", 4))
- pass2Bne(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "bgt ", 4))
- pass2Bgt(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "bge ", 4))
- pass2Bge(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "bgts ", 5))
- pass2Bgts(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "bges ", 5))
- pass2Bges(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "savpc ", 6))
- pass2Savpc(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "reti", 4))
- pass2Reti(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "or ", 3))
- pass2Or(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "and ", 4))
- pass2And(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "xor ", 4))
- pass2Xor(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "add ", 4))
- pass2Add(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "sub ", 4))
- pass2Sub(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "shiftl ", 7))
- pass2Shiftl(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "shiftr ", 7))
- pass2Shiftr(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "mult ", 5))
- pass2Mult(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "not ", 4))
- pass2Not(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "loadLabelLow ", 13))
- pass2LoadLabelLow(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "loadLabelHigh ", 14))
- pass2LoadLabelHigh(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "nop", 3))
- pass2Nop(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, ".dw ", 4))
- pass2Dw(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, ".dl ", 4))
- pass2Dl(outputAddr, outputCursor);
- else if (memcmp(lineBuffer, "readintid ", 10))
- pass2Readintid(outputAddr, outputCursor);
- else
- {
- BDOS_PrintConsole("Unknown instruction!\n");
- BDOS_PrintConsole(lineBuffer);
- BDOS_PrintConsole("\n");
- exit(1);
- }
- }
- // returns the length of the binary
- word doPass2()
- {
- BDOS_PrintConsole("Doing pass 2\n");
- memCursor = 0; // reset cursor for readMemLine
- char* outfilePass1Addr = (char*) OUTFILE_PASS1_ADDR; // read from
- char* outfilePass2Addr = (char*) OUTFILE_PASS2_ADDR; // write to
- word filePass2Cursor = 0;
- while (readMemLine(outfilePass1Addr) != EOF)
- {
- LinePass2(outfilePass2Addr, &filePass2Cursor);
- }
- return filePass2Cursor;
- }
- void moveDataDown()
- {
- char* outfileDataAddr = (char*) OUTFILE_DATA_ADDR;
- *outfileDataAddr = 0; // initialize to 0
- word fileDataCursor = 0;
- char* outfileCodeAddr = (char*) OUTFILE_CODE_ADDR;
- *outfileCodeAddr = 0; // initialize to 0
- word fileCodeCursor = 0;
- BDOS_PrintConsole("Looking for .data and .code sections\n");
- // .data, also do pass one on the code
- word inDataSection = 0;
- word inCodeSection = 0;
- while (readFileLine() != EOF)
- {
- if (memcmp(lineBuffer, ".data", 5))
- {
- inDataSection = 1;
- inCodeSection = 0;
- continue; // skip this line
- }
- if (memcmp(lineBuffer, ".rdata", 6))
- {
- inDataSection = 0;
- inCodeSection = 0;
- continue; // skip this line
- }
- if (memcmp(lineBuffer, ".code", 5))
- {
- inDataSection = 0;
- inCodeSection = 1;
- continue; // skip this line
- }
- if (memcmp(lineBuffer, ".bss", 4))
- {
- inDataSection = 0;
- inCodeSection = 0;
- continue; // skip this line
- }
- if (inDataSection)
- {
- // copy to data section
- word lineBufLen = strlen(lineBuffer);
- memcpy((outfileDataAddr + fileDataCursor), lineBuffer, lineBufLen);
- fileDataCursor += lineBufLen;
- // add a newline
- *(outfileDataAddr + fileDataCursor) = '\n';
- fileDataCursor++;
- }
- if (inCodeSection)
- {
- // copy to code section
- word lineBufLen = strlen(lineBuffer);
- memcpy((outfileCodeAddr + fileCodeCursor), lineBuffer, lineBufLen);
- fileCodeCursor += lineBufLen;
- // add a newline
- *(outfileCodeAddr + fileCodeCursor) = '\n';
- fileCodeCursor++;
- }
- }
- *(outfileCodeAddr+fileCodeCursor) = 0; // terminate code section
- // do not increment the codeCursor, because we will append the data section
- BDOS_PrintConsole("Looking for .rdata and .bss sections\n");
- // reopen file to reiterate
- fclose();
- fopenRead(infilename);
- //.rdata and .bss at the same time
- inDataSection = 0;
- while (readFileLine() != EOF)
- {
- if (memcmp(lineBuffer, ".data", 5))
- {
- inDataSection = 0;
- continue; // skip this line
- }
- if (memcmp(lineBuffer, ".rdata", 6))
- {
- inDataSection = 1;
- continue; // skip this line
- }
- if (memcmp(lineBuffer, ".code", 5))
- {
- inDataSection = 0;
- continue; // skip this line
- }
- if (memcmp(lineBuffer, ".bss", 4))
- {
- inDataSection = 1;
- continue; // skip this line
- }
- if (inDataSection)
- {
- // copy to data section
- word lineBufLen = strlen(lineBuffer);
- memcpy((outfileDataAddr + fileDataCursor), lineBuffer, lineBufLen);
- fileDataCursor += lineBufLen;
- // add a newline
- *(outfileDataAddr + fileDataCursor) = '\n';
- fileDataCursor++;
- }
- }
- *(outfileDataAddr+fileDataCursor) = 0; // terminate data section
- fileDataCursor++;
- BDOS_PrintConsole("Appending all to .code section\n");
- // append data section to code section, including \0
- memcpy((outfileCodeAddr+fileCodeCursor), outfileDataAddr, fileDataCursor);
- }
- int main()
- {
- BDOS_PrintConsole("B322 Assembler\n");
- // output file
- char outfilename[96];
- BDOS_GetArgN(2, outfilename);
- // Default to a.out
- if (outfilename[0] == 0)
- {
- strcat(outfilename, BDOS_GetPath());
- if (outfilename[strlen(outfilename)-1] != '/')
- {
- strcat(outfilename, "/");
- }
- strcat(outfilename, "A.OUT");
- }
- // Make full path if it is not already
- if (outfilename[0] != '/')
- {
- char bothPath[96];
- bothPath[0] = 0;
- strcat(bothPath, BDOS_GetPath());
- if (bothPath[strlen(bothPath)-1] != '/')
- {
- strcat(bothPath, "/");
- }
- strcat(bothPath, outfilename);
- strcpy(outfilename, bothPath);
- }
- // create output file, test if it can be created/opened
- if (!fopenWrite(outfilename))
- {
- BDOS_PrintConsole("Could not open outfile\n");
- return 0;
- }
- fclose();
- // input file
- BDOS_GetArgN(1, infilename);
- // Default to out.asm
- if (infilename[0] == 0)
- {
- strcat(infilename, BDOS_GetPath());
- if (infilename[strlen(infilename)-1] != '/')
- {
- strcat(infilename, "/");
- }
- strcat(infilename, "OUT.ASM");
- }
- // Make full path if it is not already
- if (infilename[0] != '/')
- {
- char bothPath[96];
- bothPath[0] = 0;
- strcat(bothPath, BDOS_GetPath());
- if (bothPath[strlen(bothPath)-1] != '/')
- {
- strcat(bothPath, "/");
- }
- strcat(bothPath, infilename);
- strcpy(infilename, bothPath);
- }
- // Open the input file
- if (!fopenRead(infilename))
- {
- BDOS_PrintConsole("Cannot open input file\n");
- return 1;
- }
- moveDataDown(); // move all data sections below the code sections
- fclose(); // done reading file, everything else can be done in memory
- doPass1();
- word pass2Length = doPass2();
- BDOS_PrintConsole("Writing to file\n");
- // write binary to output file
- if (!fopenWrite(outfilename))
- {
- BDOS_PrintConsole("Could not open outfile\n");
- return 0;
- }
- char* outfilePass2Addr = (char*) OUTFILE_PASS2_ADDR;
- fputData(outfilePass2Addr, pass2Length-1);
- fclose();
-
- return 0;
- }
- void interrupt()
- {
- // handle all interrupts
- word i = getIntID();
- switch(i)
- {
- case INTID_TIMER1:
- timer1Value = 1; // notify ending of timer1
- break;
- case INTID_TIMER2:
- break;
- case INTID_UART0:
- break;
- case INTID_GPU:
- break;
- case INTID_TIMER3:
- break;
- case INTID_PS2:
- break;
- case INTID_UART1:
- break;
- case INTID_UART2:
- break;
- }
- }
|