From f1b362e1269b6f7c4d644d290212828a0bce5c66 Mon Sep 17 00:00:00 2001 From: Curtis F Kaylor Date: Sun, 7 Aug 2022 15:31:02 -0400 Subject: [PATCH] Added and debugged opcode address modes --- apps/a02.c02 | 267 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 155 insertions(+), 112 deletions(-) diff --git a/apps/a02.c02 b/apps/a02.c02 index 5007283..034dd1d 100644 --- a/apps/a02.c02 +++ b/apps/a02.c02 @@ -10,9 +10,10 @@ * $08 - Individual Mnemonic Assembly * * $10 - Term Evaluation Details * ^ $20 - IF and SWITCH details * - * $40 - Show Binary Output * + * $40 - Show Binary Output * ` + * $80 - Parse Word and Lookup Details * ` */ -#define DEBUG $07 //Print Debug Information +#define DEBUG $00 //Print Debug Information //#include "a02lib.h02" - This will replace all the defs below #include @@ -27,12 +28,16 @@ alias char symtbl = $E000; //Global Symbol Table /* Address Mode Constants, Bit Masks, and Descriptions */ +// 0 1 2 3 4 5 6 7 8 9 10 11 enum {ACMLT, IMMDT, ZPAGE, ZPAGX, ABSLT, ABSLX, ABSLY, IMPLD, INDCT, INDCX, INDCY, RELTV}; +// 0 1 2 3 4 5 6 7 8 9 10 11 const char amodlo = {$01, $02, $04, $08, $20, $40, $80, $00, $00, $00, $00, $00}; const char amodhi = {$00, $00, $00, $00, $00, $00, $00, $01, $02, $04, $08, $10}; const char amdesc = {"Accumulator", "Immediate", "Zero Page", "Zero Page,X", "Absolute", "Absolute,X", "Absolute,Y", "Implied", "(Indirect)", "(Indirect,X)", "(Indirect),Y", "Relative", 0}; +const char amdess = {"ACC","IMM","ZPG","ZPX","ABS","ABX","ABY","IMP", + "IND","INX","INY","REL"}; /* Pseudo-Op Lookup Table */ struct pso {char token, name[5];}; @@ -99,8 +104,8 @@ char eoinp; //End of Input int lineno; //Input File Line Number /* Output Variables */ -char outlin[128]; //Input Buffer -char outidx; //Index into Input Buffer +char outlin[128]; //Output Buffer +char outidx; //Index into Output Buffer /* Assembly Variables */ @@ -509,7 +514,7 @@ char evlopd(opdrqd, reqbyt) { if (#DEBUG&16) printf(setdst(hilo,opdval),"#HILO $%x, OPDVAL SET TO %i%n"); } if (result) { - if (#DEBUG&2) printf(setdst(opdval), "#OPERAND VALUE=%i%n"); + if (#DEBUG&2) printf(setdst(opdval), "#OPDVAL SET TO %i%n"); if (reqbyt & >opdval) error("VALUE TOO LARGE"); } else { if (#DEBUG&2) putln("#NO OPERAND"); @@ -642,11 +647,30 @@ char asmpso() { /* Check for Valid Addressing Mode */ int chkmod(m, f) { - if (amodlo[m] & amdlo and amodhi[m] & amdhi) return #TRUE; + if (#DEBUG&2) { + i = m; i<<; i<<; + puts("#CHECKING ADDR MODE %"); putbin(amodhi[m]); putbin(amodlo[m]); + putspc(); putsub(i,amdess); newlin(); + } + if (amodlo[m] & amdlo or amodhi[m] & amdhi) return #TRUE; if (f) error("ILLEGAL ADDRESS MODE"); return #FALSE; } +/* Assemble Absolute/ZeroPage Indexed */ +void asmidx() { + if (cpychr('X')) { + if (zpflg and chkmod(#ZPAGX)) {opmod = $14; return;} //ZeroPage,X + if (chkmod(#ABSLX)) {opmod = $1C; return;} //Absolute,X + } + if (cpychr('Y')) { + if (zpflg) { + if (token == $82 or token == $A2) {opmod = $14; return;} //ZeroPage,Y + } + zpflg = #FALSE; opmod = $18; return; //Absolute,Y + } + chkmod(0); //Illegal Addressing Mode +} /* Assemble Implied/Accumulator/Absolute/ZeroPage Mode Instruction */ void asmiaz() { @@ -656,32 +680,94 @@ void asmiaz() { return; } if (>opdval) zpflg = #FALSE; else zpflg = #TRUE; - if (zpflg and chkmod(#ZPAGE, #FALSE)) opmod = $04; //ZeroPage - else {if (chkmod(#ABSLT, #TRUE)) opmod = $0C;} //Absolute + if (#DEBUG&2) printf(zpflg,"#ZPFLG SET TO $%x%n"); + if (zpflg and chkmod(#ZPAGE, #FALSE)) {opmod = $04; return;} //ZeroPage + if (chkmod(#ABSLT, #TRUE)) {opmod = $0C; zpflg = #FALSE;} //Absolute + if (cpychr(',')) asmidx(); //Indexed +} + +/* Assemble Immediate Mode Instruction */ +void asmimd() { + if (#DEBUG&2) putln("#IMMEDIATE MODE"); + evlopd(#TRUE, #TRUE); + zpflg = #TRUE; + opmod = $08; //Immediate +} + +/* Assemble Indirect Mode Instruction */ +void asmind() { + if (#DEBUG&2) putln("#INDIRECT MODE"); + zpflg = #TRUE; opdval = evlopd(#TRUE,#FALSE); + if (cpychr(',') and cpychr('X') and chkmod(#INDCX)) {cpychr(')'); return;} + if (!cpychr(')')) chkmod(0); //If no end paren - Illegal Addressing Mode + if (cpychr(',') and cpychr('Y') and chkmod(#INDCY)) {opmod = $10; return;} + if (chkmod(#INDCT)) opmod = $11; //(Indirect) + if (token == $4C) {zpflg = #FALSE;} //JMP (Indirect Absolute) +} + +/* Calculate Branch Offset */ +void asmbro() { + if (#DEBUG&2) putln("#CALCULATING BRANCH OFFSET"); + skpspc(); + if (inplin[inpidx]=='.' or isalph(A)) { + if (#DEBUG&4) putln("#PARSING LABEL"); + if (evlsym()) w = isub(isub(iacc(varble.value),curadr),v); + return; + } + if (cpychr('+')) {w = evlopd(#TRUE,#FALSE); return;} + if (cpychr('-')) {w = ineg(evlopd(#TRUE,#FALSE)); return;} + if (#DEBUG&4) putln("#PARSING ADDRESS"); + w = isub(isub(iacc(evlopd(#TRUE,#FALSE)),curadr),v); +} + +/* Assemble Branch Opcode */ +void asmbrn(zpflg) { + if (#DEBUG&2) putln("#RELATIVE MODE"); + w = 0; //Offset + if (zpflg) v = 2; else v = 3; //Offset Adjustment + asmbro(); + if (#DEBUG&2) printf(setdst(w),"#BRANCH OFFSET IS $%w%n"); + if (>w and A <> $FF) error("BRANCH OUT OF RANGE"); + opdval = int(opdval ) error("OPERAND TOO LARGSE"); - asmiaz(); //Assemble Implied/Accumulator/Absolute/ZeroPage Instruction opcode = fixopc(); //Fixup Opcode + if (#DEBUG&2) printf(opcode, "#WRITING OPCODE $%x%n"); outchr(opcode); - if (opdfnd) {if (zpflg) outbyt(opdval); else outwrd(opdval);} + if (#DEBUG&2 and opdfnd) printf(setdst(opdval), "#WRITING OPDVAL %i%n"); + if (opdfnd) {if (zpflg) outbyt(>"); putln(inplin); } -//Print Operand -void poprnd() { - oprnd[opridx] = 0; - printf(setdst(oprnd)," OPRND=\"%s\"%n"); -} - void slabel() {setln(); plabel();} -//Test function plabel -void tlabel() { - slabel(); - if (label[0]) { - setdst(label); printf(local," LABEL=\"%s\", LOCAL=%d%n"); - setdst(symbol.name); printf(symbol.block, " SYMBOL.BLOCK=%d, NAME=\"%s\", "); - setdst(symbol.value); printf(symbol.bytes,"BYTES=%d, VALUE=%i%n"); - addsym(); printf(" ADDED TO TABLE, SYMPTR=$%w%n"); //dstptr set by setsym() - } - else putln("NO LABEL FOUND"); - curadr++; -} - -//Test function evltrm -void tterm() { - opridx = 0; - setln(); - if (evltrm()) printf(setdst(term)," TERM=%i%n"); - else putln("NO TERM FOUND"); - poprnd(); -} - -//Test evltopd() -void topd() { - opridx = 0; - setln(); - if (evlopd(#FALSE,#FALSE)) printf(setdst(opdval)," OPERAND=%i%n"); - else putln(" NO OPERAND FOUND"); - poprnd(); -} - -//Test find symbol -void tfind(local, tmpptr) { - setdst(word); strcpy(tmpptr); - //found = fndsym(); putdel(found); - if (fndsym()) { - setdst(varble.name); printf(varble.block, " VARBLE.BLOCK=%d, NAME=\"%s\", "); - setdst(varble.value); printf(varble.bytes,"BYTES=%d, VALUE=%i%n"); - } -} - -void tmnmnc() { - setln(); - pmnmnc(); - printf(setdst(mnmnc)," MNEMONIC=\"%s\"%n"); -} - void pout() { puts(" OUTLIN: "); for (i=0; iBIG, \"STRING\" "); - tpso("HEX 0 1 2 F 10 F0 FEEF "); - tpso("WORD 1, 1001, %11111, $F00F, TOP"); - tpso("FILL 300"); - tpso("ALIGN 256"); - tpso("DS 20"); - tpso("SUBR MYLIB"); - tpso("SUBROUTINE"); - tpso("ENDSUB"); - tpso("END"); + tasm(" ORG $0300"); + tasm("ONE: EQU 1"); + tasm("CEE: EQU 'C'"); + tasm("BIG: EQU $ABCD"); + tasm("TOP: EQU $FFFF"); + tasm(".YOKEL BYTE 1,1,1,1"); + tasm(" BYTE 0, ONE ,%10 ,$3,'4',CEE"); + tasm(" .DC BIG, \"STRING\" "); + tasm(" HEX 0 1 2 F 10 F0 FEEF "); + tasm(" WORD 1, 1001, %11111, $F00F, TOP"); + tasm(" FILL 300"); + tasm(" ALIGN 256"); + tasm(" DS 20"); + tasm(" SUBR MYLIB"); + tasm(".YOKEL BYTE 2,2,2,2"); + tasm(" SUBROUTINE"); + tasm(".YOKEL BYTE 3,3,3,3"); + tasm(" ENDSUB"); + tasm(" END"); + tasm(" BRK ;$00"); + tasm(" RTS ;$60"); + tasm(" NOP ;$EA"); + tasm(" JMP $C4 ;$4C $C4 $00"); + tasm(" JMP $C44C ;$4C $C4 $4C"); + tasm(" JMP ($C6) ;$6C $C6 $00"); + tasm(" JMP ($C66C) ;$6C $C6 $6C"); + tasm(" LDA $01 ;$A5 $01"); + tasm(" LDA $0400 ;$AD $00 $04"); + tasm(" LDA #89 ;$A9 $59"); + tasm(" LDA ($1A,X) ;$A1 $1A"); + tasm(" LDA ($1B),Y ;$B1 $1B"); + tasm(" LDA $5B,X ;$B5 $5B"); + tasm(" LDA $B99B,Y ;$B9 $9B $B9"); + tasm(" LDA $BDDB,X ;$BD $DB $BD"); + tasm("BRANCH:"); + tasm(" BCS BRANCH ;$B0 $FE"); + tasm(" BCC BRANCH ;$90 $FB"); + tasm(" BEQ -128 ;$F0 $80"); + tasm(" BNE +127 ;$D9 $7F"); + tasm(" BPL $0500 ;$10 $??"); + tasm(" LSR ;$4A"); + tasm(" LSR $64 ;$46 $64"); + - //tmnmnc("RTS"); tmnmnc("SUBROUTINE"); tmnmnc(" "); tmnmnc("9");tmnmnc(";"); prtsym(); goto exit; +// $A1, 2, "LDA", $61, 2, "ADC", $21, 2, "AND", $C1, 2, "CMP", $81, 2, "STA", +// $E1, 2, "SBC", $01, 2, "ORA", $41, 2, "EOR", $02, 3, "ASL", $22, 3, "ROL", +// $E2, 3, "INC", $42, 3, "LSR", $62, 3, "ROR", $C2, 3, "DEC", $07, 4, "RMB", +// $87, 4, "SMB", $0F, 5, "BBR", $8F, 5, "BBS", $10, 6, "TRB", $00, 6, "TSB", +// $E0, 7, "CPX", $C0, 7, "CPY", $A2, 8, "LDX", $82, 8, "STX", $20, 9, "BIT", +// $60, 10,"STZ", $4C, 11,"JMP", $14, 12,"JSR", $A0, 13,"LDY", $80, 14,"STY", + + + // 'I', "INCL", 'S', 'F', "DS", 'P', "PROC", - -void dolkup() { - found = lookup(#FALSE, psolst); if (#DEBUG:-) {prtbyt(found); newlin();} - if (!found) { - found = lookup(#TRUE, opclst); if (#DEBUG:-) {prtbyt(found); newlin();} - } - if (found) {prtbyt(token); prtbyt(amidx);} else putstr("*NOF* "); - putln(mnmnc); -} - -tstlkp: - setdst(mnmnc); strcpy("BYTE"); dolkup(); - setdst(mnmnc); strcpy("ORG"); dolkup(); - setdst(mnmnc); strcpy("SUBROUTINE"); dolkup(); - setdst(mnmnc); strcpy("BRK"); dolkup(); - setdst(mnmnc); strcpy("BEQ"); dolkup(); - setdst(mnmnc); strcpy("STY"); dolkup(); - setdst(mnmnc); strcpy("XXX"); dolkup(); - setdst(mnmnc); strcpy("INVALID"); dolkup(); - goto exit;