// ************************************************************************** // ************************************************************************** // dvm <sa> <ea> - dump lc3 virtual memory void dumpVMemory(char *s, int sa, int ea) { int i, ma; printf("\n%s", s); for (ma = sa; ma < ea;) { printf("\n0x%04x:", ma); for (i=0; i<8; i++) { printf(" %04x", getMemoryData(ma+i)); } ma+=8; } return; } // end dumpVMemory
// *********************************************************************** // *********************************************************************** // lc3 simulator task // // argc = 2 // argv[0] = 0 - load from system // 1 - load from FAT // int lc3Task(int argc, char* argv[]) { int DR, oldpc, ir; // local variables int i; int LC3_REGS[8]; // General purpose registers int LC3_CC = 0x02; // NZP condition codes int LC3_PC = 0x3000; // program counter int ips = 0; // instructions per swap // Initialize LC3 Simulator // clear registers for (i=0; i<8; i++) LC3_REGS[i] = 0; // set condition codes to nZp LC3_CC = 0x02; // load program if ((LC3_PC = loadLC3Program(argv)) < 0) return -1; // Execute LC3 program while(1) { oldpc = LC3_PC; // save old pc for debug message ir = getMemoryData(LC3_PC); // load ir and increment pc LC3_PC = LC3_PC + 1; // increment program counter DR = GET_DR; // preload destination register # switch(GET_OPCODE) { case LC3_ADD: // ADD instruction if (!GET_IMMEDIATE_BIT) { if (LC3_DEBUG&0x01) printf(ADD_MSG, oldpc, DR, GET_SR1, GET_SR2); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] + LC3_REGS[GET_SR2]); } else { if (LC3_DEBUG&0x01) printf(ADDI_MSG, oldpc, DR, GET_SR1, MASKTO16BITS(SEXT5(ir))); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] + SEXT5(ir)); } SET_CC(LC3_REGS[DR]); break; case LC3_AND: // AND instruction if (!GET_IMMEDIATE_BIT) { if (LC3_DEBUG&0x01) printf(AND_MSG, oldpc, DR, GET_SR1, GET_SR2); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] & LC3_REGS[GET_SR2]); } else { if (LC3_DEBUG&0x01) printf(ANDI_MSG, oldpc, DR, GET_SR1, MASKTO16BITS(SEXT5(ir))); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] & SEXT5(ir)); } SET_CC(LC3_REGS[DR]); break; case LC3_BR: // BR instruction if (ir == 0) { printf("\n**(%d) Illegal instruction 0x%04x at 0x%04x (frame %d)", LC3_TID, ir, LC3_PC, LC3_PC>>6); return -1; // abort! } if ((LC3_CC&0x04 && GET_N) || (LC3_CC&0x02 && GET_Z) || (LC3_CC&0x01 && GET_P)) LC3_PC = LC3_PC + SEXT9(ir); if (LC3_DEBUG&0x01) { char cchr[4]; cchr[0] = 0; if (GET_N) strcat(cchr, "N"); if (GET_Z) strcat(cchr, "Z"); if (GET_P) strcat(cchr, "P"); printf(BR_MSG, oldpc, cchr, LC3_PC); } break; case LC3_JMP: // JMP instruction if (LC3_DEBUG&0x01) { if (GET_BASER == 7) printf(RET_MSG, oldpc); else printf(JMP_MSG, oldpc, GET_BASER); } LC3_PC = LC3_REGS[GET_BASER]; break; case LC3_JSR: // JSR instruction LC3_REGS[7] = MASKTO16BITS(LC3_PC); if (GET_ADDR_BIT == 0) { if (LC3_DEBUG&0x01) printf(JSRR_MSG, oldpc, GET_BASER); LC3_PC = LC3_REGS[GET_BASER]; } else { if (LC3_DEBUG&0x01) printf(JSR_MSG, oldpc, LC3_PC + SEXT11(ir)); LC3_PC = LC3_PC + SEXT11(ir); } break; case LC3_LD: // LD instruction if (LC3_DEBUG&0x01) printf(LD_MSG, oldpc, DR, SEXT9(ir)); LC3_REGS[DR] = MASKTO16BITS(getMemoryData(LC3_PC + SEXT9(ir))); SET_CC(LC3_REGS[DR]); break; case LC3_LDI: // LDI instruction if (LC3_DEBUG&0x01) printf(LDI_MSG, oldpc, DR, SEXT9(ir)); LC3_REGS[DR] = MASKTO16BITS(getMemoryData(getMemoryData(LC3_PC + SEXT9(ir)))); SET_CC(LC3_REGS[DR]); break; case LC3_LDR: // LDR instruction if (LC3_DEBUG&0x01) printf(LDR_MSG, oldpc, DR, GET_BASER, SEXT6(ir)); LC3_REGS[DR] = MASKTO16BITS(getMemoryData(LC3_REGS[GET_BASER] + SEXT6(ir))); SET_CC(LC3_REGS[DR]); break; case LC3_LEA: // LEA instruction if (LC3_DEBUG&0x01) printf(LEA_MSG, oldpc, DR, LC3_PC + SEXT9(ir)); LC3_REGS[DR] = MASKTO16BITS(LC3_PC + SEXT9(ir)); SET_CC(LC3_REGS[DR]); break; case LC3_NOT: // NOT instruction if (LC3_DEBUG&0x01) printf(NOT_MSG, oldpc, DR, GET_SR1); LC3_REGS[DR] = MASKTO16BITS(~LC3_REGS[GET_SR1]); SET_CC(LC3_REGS[DR]); break; case LC3_ST: // ST instruction if (LC3_DEBUG&0x01) printf(ST_MSG, oldpc, GET_SR, LC3_PC + SEXT9(ir)); setMemoryData(LC3_PC + SEXT9(ir), LC3_REGS[GET_SR]); break; case LC3_STI: // STI instruction if (LC3_DEBUG&0x01) printf(STI_MSG, oldpc, GET_SR, SEXT9(ir)); setMemoryData(getMemoryData(LC3_PC + SEXT9(ir)), LC3_REGS[GET_SR]); break; case LC3_STR: // STR instruction if (LC3_DEBUG&0x01) printf(STR_MSG, oldpc, GET_SR, GET_BASER, SEXT6(ir)); setMemoryData(LC3_REGS[GET_BASER] + SEXT6(ir), LC3_REGS[GET_SR]); break; case LC3_TRAP: // TRAP instruction { int trapv = getMemoryData(GET_TRAPVECT8); // access trap vector getMemoryData(trapv); // access system routine switch(GET_TRAPVECT8) { int tmp, string_address; case LC3_GETID: { // Note: This function not supported by simulator. if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "GETTID"); //printf("\nLC3_TID = %d (%d)", LC3_TID, curTask); LC3_REGS[0] = LC3_TID; LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_GETC: { // Note: This does not function quite like GETC. if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "GETC"); LC3_REGS[0] = MASKTO8BITS(getCharacter()); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_OUT: { if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "OUT"); putchar(LC3_REGS[0]); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_PUTSP: { if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "PUTSP"); putchar(' '); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_PUTS: { if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "PUTS"); string_address = LC3_REGS[0]; while((tmp=getMemoryData(string_address++)) != 0) putchar(tmp); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_IN: { // Note: This does not function quite like IN. if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "IN"); putchar(':'); LC3_REGS[0] = MASKTO8BITS(getCharacter()); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_HALT: { LC3_REGS[7] = MASKTO16BITS(LC3_PC); if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "HALT"); printf("\nProcess #%d Halted at 0x%04x\n", LC3_TID, LC3_PC); charFlag = 0; // release input return 0; } case LC3_getNextDirEntry: { // Note: This function not supported by simulator. // IN: R0 = int *dirNum // R1 = char* mask // R2 = DirEntry* dirEntry // R3 = int cDir // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsGetNextDirEntry"); LC3_REGS[0] = fmsGetNextDirEntry((int*)getMemAdr(LC3_REGS[0], 1), // int *dirNum (char*)getMemAdr(LC3_REGS[1], 0), // char* mask (DirEntry*)getMemAdr(LC3_REGS[2], 1), // DirEntry* dirEntry (short int)LC3_REGS[3]); // int cDir SWAP break; } case LC3_closeFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsCloseFile"); LC3_REGS[0] = fmsCloseFile((short int)LC3_REGS[0]); // int fileDescriptor SWAP break; } case LC3_defineFile: { // Note: This function not supported by simulator. // IN: R0 = char* fileName // OUT: R0 = 0-success, otherwise error char fileName[32]; char* s = (char*)getMemAdr(LC3_REGS[0], 0); int j = i = 0; if(!s[j]) j++; while((fileName[i++] = s[j])) j+=2; if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsCreateFile"); LC3_REGS[0] = fmsDefineFile(fileName, 0); // char* fileName SWAP break; } case LC3_deleteFile: { // Note: This function not supported by simulator. // IN: R0 = char* fileName // OUT: R0 = 0-success, otherwise error char fileName[32]; char* s = (char*)getMemAdr(LC3_REGS[0], 0); int j = i = 0; if(!s[j]) j++; while((fileName[i++] = s[j])) j+=2; if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsDeleteFile"); LC3_REGS[0] = fmsDeleteFile(fileName); // char* fileName SWAP break; } case LC3_openFile: { // Note: This function not supported by simulator. // IN: R0 = char* fileName // R1 = int rwMode // OUT: R0 = 0-success, otherwise error char fileName[32]; char* s = (char*)getMemAdr(LC3_REGS[0], 0); int j = i = 0; if(!s[j]) j++; while((fileName[i++] = s[j])) j+=2; if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsOpenFile"); LC3_REGS[0] = fmsOpenFile(fileName, // char* fileName (short int)LC3_REGS[1]); // int rwMode SWAP break; } case LC3_readFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // R1 = char* buffer // R2 = int nBytes // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsReadFile"); LC3_REGS[0] = fmsReadFile((short int)LC3_REGS[0], // int fileDescriptor (char*)getMemAdr(LC3_REGS[1], 0), // char* buffer (short int)LC3_REGS[2]); // int nBytes SWAP break; } case LC3_seekFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // R1 = int index // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsSeekFile"); LC3_REGS[0] = fmsSeekFile((short int)LC3_REGS[0], // int fileDescriptor (short int)LC3_REGS[1]); // int index SWAP break; } case LC3_writeFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // R1 = char* buffer // R2 = int nBytes // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsWriteFile"); LC3_REGS[0] = fmsWriteFile((short int)LC3_REGS[0], // int fileDescriptor (char*)getMemAdr(LC3_REGS[1], 0), // char* buffer (short int)LC3_REGS[2]); // int nBytes SWAP break; } default: printf(TRAP_ERROR_MSG, GET_TRAPVECT8); break; } break; } default: printf(UNDEFINED_OPCODE_MSG, GET_OPCODE); return -1; // abort! } if (LC3_DEBUG&0x02) // debug mode { char cchr[4]; // \n--PC:3000 IR:193b Nzp - 0000 0001 0002 0003 0004 0005 0006 0007 printf("\n--PC:%04x IR:%04x ",LC3_PC, ir); cchr[0] = (LC3_CC&0x04)?'N':'n'; cchr[1] = (LC3_CC&0x02)?'Z':'z'; cchr[2] = (LC3_CC&0x01)?'P':'p'; cchr[3] = 0; printf("%s -", &cchr[0]); for (i=0; i<8; i++) printf(" %04x", LC3_REGS[i]); //getchar(); // enable to single step } // swap tasks every INSTRUCTIONS_PER_SWAP instructions if (ips++ > INSTRUCTIONS_PER_SWAP) { ips = 0; SWAP }