Mercurial > hg > Members > kono > os9 > sbc09
changeset 184:ef64e3f4e229 current
merge
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 30 Jul 2022 18:22:06 +0900 |
parents | 0eb94a8e4d0d |
children | f8a3a2819e2b |
files | README.txt examples/ef09.asm examples_forth/kernel09.4 src/a09.c src/engine.c src/makerom.c src/monitor.asm src/monitor.lst src/monitor.s src/v09.c src/v09s.c |
diffstat | 11 files changed, 354 insertions(+), 345 deletions(-) [+] |
line wrap: on
line diff
--- a/README.txt Sat Jul 30 17:32:55 2022 +0900 +++ b/README.txt Sat Jul 30 18:22:06 2022 +0900 @@ -170,11 +170,66 @@ # differences from real 6809: -ldd #$0fc9 -addb #$40 -adca #$00 + ldd #$0fc9 + addb #$40 ; $C9+$40 -> $09 -> C=1 + adca #$00 ; $0F+C -> $10 -> H=1 + +Should Set the half-carry! + +For this example the half-carry is set on a real 6809, also correctly +emulated on the VCC. v09s does the same. + +According to "Motorola 6809 and Hitachi 6309 Programmer's Reference" +the half-carry is only properly set for ADD and ADC (on 8-bit accumulators). +For ASR, ASL (= LSL), CMP, SBC, SUB this condition flag is undefined. +The v09s simulator calculates the half-carry also for ASR and ASL. + +ASL does the following: + * sets H if bit 4 was set. + * clears H if bit was not set. + +ASR (=LSR) does the following: + * xxx1 xxxx --- (LSR|ASR) ---> xxxx 1xxx => H=1 + * xxx0 xxxx --- (LSR|ASR) ---> xxxx 0xxx => H=0 + + +But note: LSR never touches the half-carry! + + +## TFR/EXG with unaligned register sizes -H is set on VCC but not on real 6809, sim6809 does what? +See http://archive.worldofdragon.org/phpBB3/viewtopic.php?f=8&t=5512 + Points to the 6309 behavior which is not compatible to 6809! + +tfr x,b ; 6809,6309: b low byte of x, a unchanged +tfr x,a ; 6809, a low byte of x, b unchanged + ; on a 6309: a high(!) byte of x, b unchanged + +Might be used to get the low byte out of an index register without harm +the A register: + +instead of + pushs a + tfr x,d + andb #$1f +it could be used + tfr x,b + andb #$1f ; a left untouched! + +REF: http://www.6809.org.uk/dragon/illegal-opcodes.shtml +REF: http://archive.worldofdragon.org/phpBB3/viewtopic.php?f=8&t=4886 + +tfr a,x ; low byte of x has value of a, high byte is $FF +tfr b,x ; low byte of x has value of b, high byte is $FF + +exg a,x ; low byte of x has value of a, high byte is $FF +exg b,x ; low byte of x has value of b, high byte is $FF + +According to Motorola 6809 and Hitachi 6309 Programmer's Reference + +Except for the case where the first operand is 8 bit and register CC or DP: +In this case the 16-bit register has the value of the 8-bit register in +high and low byte! ### special behavior
--- a/examples/ef09.asm Sat Jul 30 17:32:55 2022 +0900 +++ b/examples/ef09.asm Sat Jul 30 18:22:06 2022 +0900 @@ -109,7 +109,7 @@ ; MUST BE IN SAME ORDER AS USER VARIABLES. -UZERO RMB 8 ;reserved space in user area +UZERO FCB 0,0,0,0,0,0,0,0 ;reserved space in user area FDB SPP ;SP0 FDB RPP ;RP0 FDB QRX ;'?KEY @@ -130,7 +130,7 @@ FDB 0 ;HLD FDB 0 ;HANDLER FDB 0 ;CONTEXT pointer - RMB VOCSS*2 ;vocabulary stack + FDB 0,0,0,0,0,0,0,0 ;vocabulary stack (VOCSS*2 bytes) FDB 0 ;CURRENT pointer FDB 0 ;vocabulary link pointer FDB CTOP ;CP
--- a/examples_forth/kernel09.4 Sat Jul 30 17:32:55 2022 +0900 +++ b/examples_forth/kernel09.4 Sat Jul 30 18:22:06 2022 +0900 @@ -42,7 +42,7 @@ LABEL DOCOL STU ,--Y \ Save IP on return stack. - LDU ,S++ \ Pop IP from stack where it is left by JSR DOCOL. + PULS U \ Pop IP from stack where it is left by JSR DOCOL. NEXT LABEL DODEFER @@ -51,8 +51,8 @@ ENDASM CODE LIT ( --- n) - LDD ,U++ \ Get literal from instruction stream. - STD ,--S + PULU D \ Get literal from instruction stream. + PSHS D NEXT END-CODE @@ -84,18 +84,18 @@ END-CODE CODE (DO) ( l s ---) - LDD ,S++ + PULS D LABEL DO1 SUBD 0 ,S EORA # $80 \ Now START-LIMIT-$8000 Initial value for counter. - LDX ,S++ + PULS X STX ,--Y \ Push limit value. STD ,--Y NEXT END-CODE CODE (?DO) ( l s ---) - LDD ,S++ + PULS D CMPD 0 ,S 0<> IF LEAU 2 ,U \ Skip branch address. @@ -143,13 +143,13 @@ LDD 0 ,Y EORA # $80 ADDD 2 ,Y - STD ,--S + PSHS D NEXT END-CODE CODE I' ( ---n) LDD 2 ,Y - STD ,--S + PSHS D NEXT END-CODE @@ -157,7 +157,7 @@ LDD 4 ,Y EORA # $80 ADDD 6 ,Y - STD ,--S + PSHS D NEXT END-CODE @@ -168,19 +168,19 @@ CODE R@ ( --- n) LDD 0 ,Y - STD ,--S + PSHS D NEXT END-CODE CODE >R ( n ---) - LDD ,S++ + PULS D STD ,--Y NEXT END-CODE CODE R> ( --- n) LDD ,Y++ - STD ,--S + PSHS D NEXT END-CODE @@ -196,12 +196,12 @@ CODE SP@ ( --- addr) TFR S, D - STD ,--S + PSHS D NEXT END-CODE CODE SP! ( addr ---) - LDD ,S++ + PULS D TFR D, S NEXT END-CODE @@ -238,38 +238,34 @@ END-CODE CODE UM/MOD ( ud u --- rem quot) - LEAS -1 ,S \ Create room for iteration counter. - LDA # 16 - STA 0 ,S + LDX # 16 \ iteration counter. + LDD 2 ,S BEGIN - ASL 6 ,S - ROL 5 ,S + ASL 5 ,S ROL 4 ,S - ROL 3 ,S - LDD 3 ,S + ROLB + ROLA U< IF \ Account for extra bit shifted out, perform subtraction anyway. - SUBD 1 ,S - STD 3 ,S - INC 6 ,S + SUBD 0 ,S + INC 5 ,S ELSE - SUBD 1 ,S \ Perform trial subtraction. + CMPD 0 ,S \ Perform trial subtraction. U>= IF - STD 3 ,S - INC 6 ,S \ Add 1-bit to quotient. + SUBD 0 ,S + INC 5 ,S \ Add 1-bit to quotient. THEN THEN - DEC 0 ,S + LEAX -1 ,X 0= UNTIL - LEAS 3 ,S - LDD 2 ,S - LDX 0 ,S - STX 2 ,S - STD 0 ,S + LEAS 2 ,S + LDX 2 ,S \ rem and quot on proper positions + STX 0 ,S + STD 2 ,S \ D contains rem NEXT END-CODE CODE + ( n1 n2 ---n3) - LDD ,S++ + PULS D ADDD 0 ,S STD 0 ,S NEXT @@ -291,25 +287,25 @@ END-CODE CODE AND ( n1 n2 ---n3) - LDD 2 ,S - ANDA ,S+ - ANDB ,S+ + PULS D + ANDA ,S + ANDB 1 ,S STD 0 ,S NEXT END-CODE CODE OR ( n1 n2 ---n3) - LDD 2 ,S - ORA ,S+ - ORB ,S+ + PULS D + ORA ,S + ORB 1 ,S STD 0 ,S NEXT END-CODE CODE XOR ( n1 n2 ---n3) - LDD 2 ,S - EORA ,S+ - EORB ,S+ + PULS D + EORA ,S + EORB 1 ,S STD 0 ,S NEXT END-CODE @@ -414,7 +410,7 @@ CODE DUP ( n --- n n ) LDD 0 ,S - STD ,--S + PSHS D NEXT END-CODE @@ -428,7 +424,7 @@ CODE OVER ( n1 n2 --- n1 n2 n1) LDD 2 ,S - STD ,--S + PSHS D NEXT END-CODE @@ -485,9 +481,11 @@ CODE PICK ( n1 --- n2) LDD 0 ,S - ADDD ,S++ - LDD D,S - STD ,--S + ADDD # 1 \ Correct index + ASLB \ Cell* (assert: cellL=2!) + ROLA + LDX D,S \ Pick value + STX 0 ,S \ Replace top NEXT END-CODE @@ -555,7 +553,7 @@ LDD 0 ,X LDX 2 ,X STX 0 ,S - STD ,--S + PSHS D NEXT END-CODE @@ -776,12 +774,12 @@ CODE KEY ( --- c) JSR 0 CLRA - STD ,--S + PSHS D NEXT END-CODE CODE EMIT ( c ---) - LDD ,S++ + PULS D JSR 3 NEXT END-CODE
--- a/src/a09.c Sat Jul 30 17:32:55 2022 +0900 +++ b/src/a09.c Sat Jul 30 18:22:06 2022 +0900 @@ -59,6 +59,16 @@ #define FNLEN 30 #define LINELEN 128 + +/* forward declarations */ + + +void processfile(char *name); + + +/* data structures */ + + static int debug=0; static struct incl { char *name; @@ -237,6 +247,8 @@ void processfile(char *name); +/* functions and procedures */ + struct oprecord * findop(char * nm) /* Find operation (mnemonic) in table using binary search */ { @@ -289,8 +301,7 @@ char *listname,*objname,*srcname,*curname; int lineno,glineno; -void -outsymtable() +void outsymtable() { int i,j=0; fprintf(listfile,"\nSYMBOL TABLE"); @@ -382,8 +393,7 @@ error |= er ; } -void -scanname() +void scanname() { int i=0; char c; @@ -397,8 +407,7 @@ srcptr--; } -void -skipspace() +void skipspace() { char c; do { @@ -678,14 +687,12 @@ } } -void -set3() +void set3() { if(mode<3)mode=3; } -void -scanspecial() +void scanspecial() { set3(); skipspace(); @@ -709,8 +716,7 @@ } } -void -scanindexed() +void scanindexed() { set3(); postbyte=0; @@ -744,8 +750,7 @@ #define RESTORE {srcptr=oldsrcptr;c=*srcptr;goto dodefault;} -void -scanoperands() +void scanoperands() { char c,d,*oldsrcptr; unknown=0; @@ -866,9 +871,7 @@ crc = -1; } - -void -flushhex() +void flushhex() { int i; if(hexcount){ @@ -882,16 +885,14 @@ } } -void -outhex(unsigned char x) +void outhex(unsigned char x) { if(hexcount==16)flushhex(); hexbuffer[hexcount++]=x; chksum+=x; } -void -outbuffer() +void outbuffer() { int i; for(i=0;i<codeptr;i++) { @@ -910,8 +911,7 @@ "Illegal mnemonic" }; -void -report() +void report() { int i; fprintf(stderr,"File %s, line %d:%s\n",curname,lineno,srcline); @@ -926,8 +926,7 @@ errors++; } -void -outlist() +void outlist() { int i; fprintf(listfile,"%04X: ",oldlc); @@ -945,8 +944,7 @@ } } -void -setlabel(struct symrecord * lp) +void setlabel(struct symrecord * lp) { while (prevlp) { struct symrecord *l = prevlp; @@ -966,21 +964,18 @@ } } -void -putbyte(unsigned char b) +void putbyte(unsigned char b) { codebuf[codeptr++]=b; } -void -putword(unsigned short w) +void putword(unsigned short w) { codebuf[codeptr++]=w>>8; codebuf[codeptr++]=w&0x0ff; } -void -doaddress() /* assemble the right addressing bytes for an instruction */ +void doaddress() /* assemble the right addressing bytes for an instruction */ { int offs; switch(mode) { @@ -1009,20 +1004,17 @@ } } -void -onebyte(int co) +void onebyte(int co) { putbyte(co); } -void -twobyte(int co) +void twobyte(int co) { putword(co); } -void -oneimm(int co) +void oneimm(int co) { scanoperands(); if(mode>=3) @@ -1031,8 +1023,7 @@ putbyte(operand); } -void -lea(int co) +void lea(int co) { putbyte(co); scanoperands(); @@ -1046,8 +1037,7 @@ doaddress(); } -void -sbranch(int co) +void sbranch(int co) { int offs; scanoperands(); @@ -1072,8 +1062,7 @@ putbyte(offs); } -void -lbra(int co) +void lbra(int co) { scanoperands(); if(mode!=1&&mode!=2)seterror(2); @@ -1081,8 +1070,7 @@ putword(operand-loccounter-3); } -void -lbranch(int co) +void lbranch(int co) { scanoperands(); if(mode!=1&&mode!=2)seterror(2); @@ -1090,8 +1078,7 @@ putword(operand-loccounter-4); } -void -arith(int co) +void arith(int co) { scanoperands(); switch(mode) { @@ -1103,8 +1090,7 @@ doaddress(); } -void -darith(int co) +void darith(int co) { scanoperands(); switch(mode) { @@ -1116,8 +1102,7 @@ doaddress(); } -void -d2arith(int co) +void d2arith(int co) { scanoperands(); switch(mode) { @@ -1129,8 +1114,7 @@ doaddress(); } -void -oneaddr(int co) +void oneaddr(int co) { scanoperands(); switch(mode) { @@ -1142,8 +1126,7 @@ doaddress(); } -void -tfrexg(int co) +void tfrexg(int co) { struct regrecord * p; putbyte(co); @@ -1160,8 +1143,7 @@ putbyte(postbyte); } -void -pshpul(int co) +void pshpul(int co) { struct regrecord *p; putbyte(co); @@ -1232,9 +1214,7 @@ os9 = 0; } - -void -pseudoop(int co,struct symrecord * lp) +void pseudoop(int co,struct symrecord * lp) { int i; char c; @@ -1430,8 +1410,7 @@ } -void -processline() +void processline() { struct symrecord * lp; struct oprecord * op; @@ -1495,8 +1474,7 @@ loccounter+=codeptr; } -void -suppressline() +void suppressline() { struct oprecord * op; srcptr=srcline; @@ -1520,8 +1498,7 @@ } if(pass==2&&listing)outlist(); } -void -usage(char*nm) +void usage(char*nm) { fprintf(stderr,"Usage: %s [-o objname] [-l listname] [-s srecord-file] srcname\n",nm); exit(2); @@ -1540,9 +1517,7 @@ return out; } - -void -getoptions(int c,char*v[]) +void getoptions(int c,char*v[]) { int i=1; if(c==1)usage(v[0]); @@ -1592,8 +1567,7 @@ listing=(listname!=0); } -void -expandline() +void expandline() { int i=0,j=0,k,j1; for(i=0;i<128&&j<128;i++) @@ -1610,8 +1584,7 @@ } -void -processfile(char *name) +void processfile(char *name) { char *oldname; int oldno; @@ -1666,8 +1639,7 @@ curname=oldname; } -int -main(int argc,char *argv[]) +int main(int argc,char *argv[]) { char c; getoptions(argc,argv);
--- a/src/engine.c Sat Jul 30 17:32:55 2022 +0900 +++ b/src/engine.c Sat Jul 30 18:22:06 2022 +0900 @@ -25,6 +25,16 @@ ACIA emulation at port $E000 Note: BIG_ENDIAN option is no longer needed. + + Implementation notes: + half-carry: + According to Motorola 6809 and Hitachi 6309 Programmer's Reference + half-carry is not defined for ASL, but as an arithmetic operation the + flag behaves like an add operation where the operator is added to itself. + + According to Motorola 6809 and Hitachi 6309 Programmer's Reference + LSR does not influence half-carry. + */ #include <stdio.h> @@ -147,7 +157,10 @@ #define SETNZ8(b) {if(b)CLZ else SEZ if(b&0x80)SEN else CLN} #define SETNZ16(b) {if(b)CLZ else SEZ if(b&0x8000)SEN else CLN} -#define SETSTATUS(a,b,res) if((a^b^res)&0x10) SEH else CLH \ +#define SETSTATUS(a,b,res) if((a^b^res^(res>>1))&0x80)SEV else CLV \ + if(res&0x100)SEC else CLC SETNZ8((Byte)res) + +#define SETSTATUSH(a,b,res) if((a^b^res)&0x10) SEH else CLH \ if((a^b^res^(res>>1))&0x80)SEV else CLV \ if(res&0x100)SEC else CLC SETNZ8((Byte)res) @@ -160,31 +173,44 @@ else{IMMWORD(tw) if(f)ipcreg+=tw;} #define NXORV ((iccreg&0x08)^((iccreg&0x02)<<2)) -/* MAcros for setting/getting registers in TFR/EXG instructions */ +/* Macros for setting/getting registers in TFR/EXG instructions */ +/* see http://www.6809.org.uk/dragon/illegal-opcodes.shtml */ +/* 8 <-> 16, high byte is filled with $ff! */ #define GETREG(val,reg) switch(reg) {\ case 0: val=GETDREG;break;\ case 1: val=ixreg;break;\ case 2: val=iyreg;break;\ - case 3: val=iureg;break;\ - case 4: val=isreg;break;\ - case 5: val=ipcreg;break;\ - case 8: val=iareg;break;\ - case 9: val=ibreg;break;\ - case 10: val=iccreg;break;\ - case 11: val=idpreg;break;} + case 3: val=iureg;break;\ + case 4: val=isreg;break;\ + case 5: val=ipcreg;break;\ + case 6: val=0xffff;break;\ + case 7: val=0xffff;break;\ + case 8: val=iareg|0xff00;break;\ + case 9: val=ibreg|0xff00;break;\ + case 10: val=iccreg|(iccreg<<8);break;\ + case 11: val=idpreg|(idpreg<<8);break;\ + case 12: val=0xffff;break;\ + case 13: val=0xffff;break;\ + case 14: val=0xffff;break;\ + case 15: val=0xffff;break;} #define SETREG(val,reg) switch(reg) {\ - case 0: SETDREG(val) break;\ - case 1: ixreg=val;break;\ - case 2: iyreg=val;break;\ - case 3: iureg=val;break;\ - case 4: isreg=val;break;\ - case 5: ipcreg=val;break;\ - case 8: iareg=val;break;\ - case 9: ibreg=val;break;\ - case 10: iccreg=val;break;\ - case 11: idpreg=val;break;} - + case 0: SETDREG(val) break;\ + case 1: ixreg=val;break;\ + case 2: iyreg=val;break;\ + case 3: iureg=val;break;\ + case 4: isreg=val;break;\ + case 5: ipcreg=val;break;\ + case 6: val=0xffff;break;\ + case 7: val=0xffff;break;\ + case 8: iareg=val&0xff;break;\ + case 9: ibreg=val&0xff;break;\ + case 10: iccreg=val&0xff;break;\ + case 11: idpreg=val&0xff;break;\ + case 12: val=0xffff;break;\ + case 13: val=0xffff;break;\ + case 14: val=0xffff;break;\ + case 15: val=0xffff;break;} #define LOADAC(reg) reg=mem(eaddr); #define STOREAC(reg) SETBYTE(eaddr,reg); @@ -605,9 +631,15 @@ case 0x1B: break; /*ILLEGAL*/ case 0x1C: /* ANDCC*/ IMMBYTE(tb) iccreg&=tb;break; case 0x1D: /* SEX */ tw=SIGNED(ibreg); SETNZ16(tw) SETDREG(tw) break; - case 0x1E: /* EXG */ IMMBYTE(tb) {Word t2;GETREG(tw,tb>>4) GETREG(t2,tb&15) - SETREG(t2,tb>>4) SETREG(tw,tb&15) } break; - case 0x1F: /* TFR */ IMMBYTE(tb) GETREG(tw,tb>>4) SETREG(tw,tb&15) break; + case 0x1E: /* EXG */ IMMBYTE(tb) { Word t2; + GETREG(tw,tb>>4) GETREG(t2,tb&15) + SETREG(t2,tb>>4) SETREG(tw,tb&15) + } + break; + case 0x1F: /* TFR */ IMMBYTE(tb) + GETREG(tw,tb>>4) + SETREG(tw,tb&15) + break; case 0x20: /* (L)BRA*/ BRANCH(1) break; case 0x21: /* (L)BRN*/ BRANCH(0) break; case 0x22: /* (L)BHI*/ BRANCH(!(iccreg&0x05)) break; @@ -731,7 +763,7 @@ case 0x43: /*COMA*/ tb=~iareg;SETNZ8(tb);SEC CLV iareg=tb;break; case 0x44: /*LSRA*/ tb=iareg;if(tb&0x01)SEC else CLC - if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb) + tb>>=1;SETNZ8(tb) iareg=tb;break; case 0x45: break;/* ILLEGAL*/ case 0x46: /*RORA*/ tb=(iccreg&0x01)<<7; @@ -743,7 +775,7 @@ if(tb&0x40)tb|=0x80;iareg=tb;SETNZ8(tb) break; case 0x48: /*ASLA*/ tw=iareg<<1; - SETSTATUS(iareg,iareg,tw) + SETSTATUSH(iareg,iareg,tw) iareg=tw;break; case 0x49: /*ROLA*/ tb=iareg;tw=iccreg&0x01; if(tb&0x80)SEC else CLC @@ -764,7 +796,7 @@ case 0x53: /*COMB*/ tb=~ibreg;SETNZ8(tb);SEC CLV ibreg=tb;break; case 0x54: /*LSRB*/ tb=ibreg;if(tb&0x01)SEC else CLC - if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb) + tb>>=1;SETNZ8(tb) ibreg=tb;break; case 0x55: break;/* ILLEGAL*/ case 0x56: /*RORB*/ tb=(iccreg&0x01)<<7; @@ -772,11 +804,11 @@ ibreg=(ibreg>>1)+tb;SETNZ8(ibreg) break; case 0x57: /*ASRB*/ tb=ibreg;if(tb&0x01)SEC else CLC - if(tb&0x10)SEH else CLH tb>>=1; + tb>>=1; if(tb&0x40)tb|=0x80;ibreg=tb;SETNZ8(tb) break; case 0x58: /*ASLB*/ tw=ibreg<<1; - SETSTATUS(ibreg,ibreg,tw) + SETSTATUSH(ibreg,ibreg,tw) ibreg=tw;break; case 0x59: /*ROLB*/ tb=ibreg;tw=iccreg&0x01; if(tb&0x80)SEC else CLC
--- a/src/makerom.c Sat Jul 30 17:32:55 2022 +0900 +++ b/src/makerom.c Sat Jul 30 18:22:06 2022 +0900 @@ -12,8 +12,7 @@ unsigned char mem[0x8000]; char linebuf[130]; -void -hexerr() +void hexerr() { fprintf(stderr,"Illegal character in hex number\n"); exit(1); @@ -38,8 +37,7 @@ return b; } -int -main() +void main() { FILE *romfile; unsigned int i,length,addr;
--- a/src/monitor.asm Sat Jul 30 17:32:55 2022 +0900 +++ b/src/monitor.asm Sat Jul 30 18:22:06 2022 +0900 @@ -1,4 +1,5 @@ ;Buggy machine language monitor and rudimentary O.S. version 1.0 + ; 2022-01-11 Fix error handing in A command * Memory map of SBC * $0-$40 Zero page variables reserved by monitor and O.S. @@ -302,7 +303,7 @@ jmp endirq jmp xerrhand jmp expr - jmp asmerrvec + jmp asmerr * And this one to the I/O vector table. osvectbl jmp osgetc jmp osputc
--- a/src/monitor.lst Sat Jul 30 17:32:55 2022 +0900 +++ b/src/monitor.lst Sat Jul 30 18:22:06 2022 +0900 @@ -1,4 +1,5 @@ 0000: ;Buggy machine language monitor and rudimentary O.S. version 1.0 +0000: ; 2022-01-11 Fix error handing in A command 0000: 0000: * Memory map of SBC 0000: * $0-$40 Zero page variables reserved by monitor and O.S. @@ -302,7 +303,7 @@ E52F: 7EE517 jmp endirq E532: 7EEE4B jmp xerrhand E535: 7EF6F9 jmp expr -E538: 7E0298 jmp asmerrvec +E538: 7EFBBA jmp asmerr E53B: * And this one to the I/O vector table. E53B: 7EE45A osvectbl jmp osgetc E53E: 7EE471 jmp osputc
--- a/src/monitor.s Sat Jul 30 17:32:55 2022 +0900 +++ b/src/monitor.s Sat Jul 30 18:22:06 2022 +0900 @@ -17,7 +17,7 @@ S113E50004393414E6809D093514390C2C26080C82 S113E5102B26040C2A3B123BD32B10932B26FB39BE S113E5207EE5177EE5177EE50B7EE5167EE56A7EC1 -S113E530E5177EEE4B7EF6F97E02987EE45A7EE481 +S113E530E5177EEE4B7EF6F97EFBBA7EE45A7EE466 S113E540717EE4807EE4E47EE4F57EE4657EED4461 S113E5507EED677EED8C7EEDCF7EEDAC7EE51834EE S113E56010347FBE029BAF6A2007EC6A830001ED82
--- a/src/v09.c Sat Jul 30 17:32:55 2022 +0900 +++ b/src/v09.c Sat Jul 30 18:22:06 2022 +0900 @@ -29,8 +29,10 @@ #include <stdio.h> #include <stdlib.h> + #include <strings.h> #include <sys/stat.h> + #include <string.h> #define engine extern @@ -77,8 +79,7 @@ } -void -read_image() +void read_image() { FILE *image; if((image=fopen(romfile,"rb"))==NULL) @@ -147,8 +148,7 @@ #define CHECKARG if(i==argc)usage();else i++; -int -main(int argc,char *argv[]) +int main(int argc,char *argv[]) { char *imagename=0; int i;
--- a/src/v09s.c Sat Jul 30 17:32:55 2022 +0900 +++ b/src/v09s.c Sat Jul 30 18:22:06 2022 +0900 @@ -51,6 +51,12 @@ http://www.6809.org.uk/dragon/illegal-opcodes.shtml 2016-10-06 JK Fixed: wrong cmpu cycles + 2017-10-20 JK + Fixed: H flag only changed for add and adc. + 2019-09-16 JK + Fixed: TFR/EXG 8 to 16 bit (especially CC/DP handling) + Fixed: CLV for 16-bit ST/LD + */ #include <stdio.h> @@ -66,6 +72,8 @@ void finish(); +void cr(); + static int fdump=0; @@ -257,7 +265,7 @@ { Word w; IMMWORD(w) - char off[6]; + char off[7]; sprintf(off,"$%04x,",w); da_ops(off,dixreg[idx],4); return(*ixregs[idx])+w; @@ -407,8 +415,7 @@ } } -void -ill() /* illegal opcode==noop */ +void ill() /* illegal opcode==noop */ { } @@ -428,12 +435,15 @@ #define SETNZ8(b) {if(b)CLZ else SEZ if(b&0x80)SEN else CLN} #define SETNZ16(b) {if(b)CLZ else SEZ if(b&0x8000)SEN else CLN} -#define SETSTATUS(a,b,res) if((a^b^res)&0x10) SEH else CLH \ + +#define SETSTATUS(a,b,res) if((a^b^res^(res>>1))&0x80)SEV else CLV \ + if(res&0x100)SEC else CLC SETNZ8((Byte)res) + +#define SETSTATUS_H(a,b,res) if((a^b^res)&0x10) SEH else CLH \ if((a^b^res^(res>>1))&0x80)SEV else CLV \ if(res&0x100)SEC else CLC SETNZ8((Byte)res) -void -add() +void add() { Word aop,bop,res; Byte* aaop; @@ -442,12 +452,11 @@ aop=*aaop; bop=mem[eaddr8()]; res=aop+bop; - SETSTATUS(aop,bop,res) + SETSTATUS_H(aop,bop,res) *aaop=res; } -void -sbc() +void sbc() { Word aop,bop,res; Byte* aaop; @@ -460,8 +469,7 @@ *aaop=res; } -void -sub() +void sub() { Word aop,bop,res; Byte* aaop; @@ -474,8 +482,7 @@ *aaop=res; } -void -adc() +void adc() { Word aop,bop,res; Byte* aaop; @@ -484,12 +491,11 @@ aop=*aaop; bop=mem[eaddr8()]; res=aop+bop+(ccreg&0x01); - SETSTATUS(aop,bop,res) + SETSTATUS_H(aop,bop,res) *aaop=res; } -void -cmp() +void cmp() { Word aop,bop,res; Byte* aaop; @@ -501,8 +507,7 @@ SETSTATUS(aop,bop,res) } -void -and() +void and() { Byte aop,bop,res; Byte* aaop; @@ -516,8 +521,7 @@ *aaop=res; } -void -or() +void or() { Byte aop,bop,res; Byte* aaop; @@ -531,8 +535,7 @@ *aaop=res; } -void -eor() +void eor() { Byte aop,bop,res; Byte* aaop; @@ -546,8 +549,7 @@ *aaop=res; } -void -bit() +void bit() { Byte aop,bop,res; Byte* aaop; @@ -560,8 +562,7 @@ CLV } -void -ld() +void ld() { Byte res; Byte* aaop; @@ -573,8 +574,7 @@ *aaop=res; } -void -st() +void st() { Byte res; Byte* aaop; @@ -586,8 +586,7 @@ CLV } -void -jsr() +void jsr() { Word w; @@ -599,8 +598,7 @@ pcreg=w; } -void -bsr() +void bsr() { Byte b; char off[6]; @@ -614,8 +612,7 @@ da_ops(off,NULL,0); } -void -neg() +void neg() { Byte *ea; Word a,r; @@ -629,8 +626,7 @@ *ea=r; } -void -com() +void com() { Byte *ea; Byte r; @@ -649,8 +645,7 @@ *ea=r; } -void -lsr() +void lsr() { Byte *ea; Byte r; @@ -659,14 +654,15 @@ ea=eaddr0(); r=*ea; if(r&0x01)SEC else CLC - if(r&0x10)SEH else CLH + /* according to Motorola 6809 and Hitachi 6309 Programmer's Reference + * half-carry is not changed + */ r>>=1; SETNZ8(r) *ea=r; } -void -ror() +void ror() { Byte *ea; Byte r,c; @@ -681,8 +677,7 @@ *ea=r; } -void -asr() +void asr() { Byte *ea; Byte r; @@ -698,8 +693,7 @@ *ea=r; } -void -asl() +void asl() { Byte *ea; Word a,r; @@ -708,12 +702,16 @@ ea=eaddr0(); a=*ea; r=a<<1; - SETSTATUS(a,a,r) + /* according to Motorola 6809 and Hitachi 6309 Programmer's Reference + * half-carry is not defined, but for an arithmetic operation the + * flag behaves like an add operation where the operator is added to + * itself. + */ + SETSTATUS_H(a,a,r) *ea=r; } -void -rol() +void rol() { Byte *ea; Byte r,c; @@ -729,8 +727,7 @@ *ea=r; } -void -inc() +void inc() { Byte *ea; Byte r; @@ -744,8 +741,7 @@ *ea=r; } -void -dec() +void dec() { Byte *ea; Byte r; @@ -759,8 +755,7 @@ *ea=r; } -void -tst() +void tst() { Byte r; Byte *ea; @@ -772,8 +767,7 @@ CLV } -void -jmp() +void jmp() { Byte *ea; @@ -784,8 +778,7 @@ pcreg=ea-mem; } -void -clr() +void clr() { Byte *ea; @@ -796,8 +789,7 @@ extern void (*instrtable[])(); -void -flag0() +void flag0() { if(iflag) /* in case flag already set by previous flag instr don't recurse */ { @@ -811,8 +803,7 @@ iflag=0; } -void -flag1() +void flag1() { if(iflag) /* in case flag already set by previous flag instr don't recurse */ { @@ -826,26 +817,22 @@ iflag=0; } -void -nop() +void nop() { da_inst("nop",NULL,2); } -void -sync_inst() +void sync_inst() { finish(); } -void -cwai() +void cwai() { sync_inst(); } -void -lbra() +void lbra() { Word w; char off[6]; @@ -858,8 +845,7 @@ da_ops(off,NULL,0); } -void -lbsr() +void lbsr() { Word w; char off[6]; @@ -873,8 +859,7 @@ da_ops(off,NULL,0); } -void -daa() +void daa() { Word a; da_inst("daa",NULL,2); @@ -887,8 +872,7 @@ *areg=a; } -void -orcc() +void orcc() { Byte b; char off[7]; @@ -899,8 +883,7 @@ ccreg|=b; } -void -andcc() +void andcc() { Byte b; char off[6]; @@ -912,8 +895,7 @@ ccreg&=b; } -void -mul() +void mul() { Word w; w=*areg * *breg; @@ -923,8 +905,7 @@ *dreg=w; } -void -sex() +void sex() { Word w; da_inst("sex",NULL,2); @@ -933,23 +914,20 @@ *dreg=w; } -void -abx() +void abx() { da_inst("abx",NULL,3); xreg += *breg; } -void -rts() +void rts() { da_inst("rts",NULL,5); da_len = 1; PULLWORD(pcreg) } -void -rti() +void rti() { Byte x; x=ccreg&0x80; @@ -968,8 +946,7 @@ PULLWORD(pcreg) } -void -swi() +void swi() { int w; da_inst("swi",(iflag==1)?"2":(iflag==2)?"3":"",5); @@ -1007,23 +984,26 @@ Byte *byteregs[]={d_reg+1,d_reg,&ccreg,&dpreg,&fillreg,&fillreg,&fillreg,&fillreg}; #endif -void -tfr() +void tfr() { Byte b; da_inst("tfr",NULL,7); IMMBYTE(b) da_reg(b); Word v; + // see http://www.6809.org.uk/dragon/illegal-opcodes.shtml // source in higher nibble (highest bit set means 8 bit reg.) if(b&0x80) { - v=*byteregs[(b&0x70)>>4] | (b&0x08 ? 0 : 0xff00); + v=*byteregs[(b&0x70)>>4] | 0xff00; + if ((b &0x70) == 0x20 || (b &0x70) == 0x30) { /* source is CC or DP */ + v = (v & 0xff) << 8 | (v & 0xff); /* high byte is the same as the low byte */ + } } else { v=*wordregs[(b&0x70)>>4]; } // dest in lower nibble (highest bit set means 8 bit reg.) if(b&0x8) { - *byteregs[b&0x07]=v&0xff; + *byteregs[b&0x07]=v &0xff; fillreg=0xff; // keep fillvalue } else { *wordregs[b&0x07]=v; @@ -1031,17 +1011,21 @@ } } -void -exg() +void exg() { Byte b; Word f; Word t; da_inst("exg",NULL,8); + // see http://www.6809.org.uk/dragon/illegal-opcodes.shtml + // 8 <-> 16, high byte is filled with $ff! IMMBYTE(b) da_reg(b); if(b&0x80) { f=*byteregs[(b&0x70)>>4] | 0xff00; + if ((b &0x70) == 0x20 || (b &0x70) == 0x30) { /* first operand is CC or DP */ + f = (f & 0xff) << 8 | (f & 0xff); /* high byte is the same as the low byte */ + } } else { f=*wordregs[(b>>4)&0x07]; } @@ -1066,8 +1050,7 @@ } } -void -br(int f) +void br(int f) { Byte b; Word w; @@ -1091,120 +1074,103 @@ #define NXORV ((ccreg&0x08)^(ccreg&0x02)) -void -bra() +void bra() { da_inst(iflag?"l":"","bra",iflag?5:3); br(1); } -void -brn() +void brn() { da_inst(iflag?"l":"","brn",iflag?5:3); br(0); } -void -bhi() +void bhi() { da_inst(iflag?"l":"","bhi",iflag?5:3); br(!(ccreg&0x05)); } -void -bls() +void bls() { da_inst(iflag?"l":"","bls",iflag?5:3); br(ccreg&0x05); } -void -bcc() +void bcc() { da_inst(iflag?"l":"","bcc",iflag?5:3); br(!(ccreg&0x01)); } -void -bcs() +void bcs() { da_inst(iflag?"l":"","bcs",iflag?5:3); br(ccreg&0x01); } -void -bne() +void bne() { da_inst(iflag?"l":"","bne",iflag?5:3); br(!(ccreg&0x04)); } -void -beq() +void beq() { da_inst(iflag?"l":"","beq",iflag?5:3); br(ccreg&0x04); } -void -bvc() +void bvc() { da_inst(iflag?"l":"","bvc",iflag?5:3); br(!(ccreg&0x02)); } -void -bvs() +void bvs() { da_inst(iflag?"l":"","bvs",iflag?5:3); br(ccreg&0x02); } -void -bpl() +void bpl() { da_inst(iflag?"l":"","bpl",iflag?5:3); br(!(ccreg&0x08)); } -void -bmi() +void bmi() { da_inst(iflag?"l":"","bmi",iflag?5:3); br(ccreg&0x08); } -void -bge() +void bge() { da_inst(iflag?"l":"","bge",iflag?5:3); br(!NXORV); } -void -blt() +void blt() { da_inst(iflag?"l":"","blt",iflag?5:3); br(NXORV); } -void -bgt() +void bgt() { da_inst(iflag?"l":"","bgt",iflag?5:3); br(!(NXORV||ccreg&0x04)); } -void -ble() +void ble() { da_inst(iflag?"l":"","ble",iflag?5:3); br(NXORV||ccreg&0x04); } -void -leax() +void leax() { Word w; da_inst("leax",NULL,4); @@ -1213,8 +1179,7 @@ xreg=w; } -void -leay() +void leay() { Word w; da_inst("leay",NULL,4); @@ -1223,15 +1188,13 @@ yreg=w; } -void -leau() +void leau() { da_inst("leau",NULL,4); ureg=postbyte(); } -void -leas() +void leas() { da_inst("leas",NULL,4); sreg=postbyte(); @@ -1256,8 +1219,7 @@ } -void -pshs() +void pshs() { Byte b; IMMBYTE(b) @@ -1273,8 +1235,7 @@ if(b&0x01)PUSHBYTE(ccreg) } -void -puls() +void puls() { Byte b; IMMBYTE(b) @@ -1291,8 +1252,7 @@ if(b&0x80)PULLWORD(pcreg) } -void -pshu() +void pshu() { Byte b; IMMBYTE(b) @@ -1308,8 +1268,7 @@ if(b&0x01)PUSHUBYTE(ccreg) } -void -pulu() +void pulu() { Byte b; IMMBYTE(b) @@ -1330,8 +1289,7 @@ if(((res>>1)^a^b^res)&0x8000) SEV else CLV \ SETNZ16((Word)res)} -void -addd() +void addd() { unsigned long aop,bop,res; Word ea; @@ -1344,8 +1302,7 @@ *dreg=res; } -void -subd() +void subd() { unsigned long aop,bop,res; Word ea; @@ -1369,8 +1326,7 @@ if(iflag==0) *dreg=res; /* subd result */ } -void -cmpx() +void cmpx() { unsigned long aop,bop,res; Word ea; @@ -1393,19 +1349,18 @@ SETSTATUSD(aop,bop,res) } -void -ldd() +void ldd() { Word ea,w; da_inst("ldd",NULL,4); ea=eaddr16(); w=GETWORD(ea); SETNZ16(w) + CLV *dreg=w; } -void -ldx() +void ldx() { Word ea,w; if (iflag) da_inst("ldy",NULL,4); @@ -1413,11 +1368,11 @@ ea=eaddr16(); w=GETWORD(ea); SETNZ16(w) + CLV if (iflag==0) xreg=w; else yreg=w; } -void -ldu() +void ldu() { Word ea,w; if (iflag) da_inst("lds",NULL,4); @@ -1425,22 +1380,22 @@ ea=eaddr16(); w=GETWORD(ea); SETNZ16(w) + CLV if (iflag==0) ureg=w; else sreg=w; } -void -std() +void std() { Word ea,w; da_inst("std",NULL,4); ea=eaddr16(); w=*dreg; SETNZ16(w) + CLV SETWORD(ea,w) } -void -stx() +void stx() { Word ea,w; if (iflag) da_inst("sty",NULL,4); @@ -1448,11 +1403,11 @@ ea=eaddr16(); if (iflag==0) w=xreg; else w=yreg; SETNZ16(w) + CLV SETWORD(ea,w) } -void -stu() +void stu() { Word ea,w; if (iflag) da_inst("sts",NULL,4); @@ -1460,6 +1415,7 @@ ea=eaddr16(); if (iflag==0) w=ureg; else w=sreg; SETNZ16(w) + CLV SETWORD(ea,w) } @@ -1498,8 +1454,7 @@ eor , adc , or , add , ldd , std , ldu , stu , }; -void -read_image(char* name) +void read_image(char* name) { FILE *image; if((image=fopen(name,"rb"))!=NULL) { @@ -1507,9 +1462,7 @@ fclose(image); } } - -void -dump() +void dump() { FILE *image; if((image=fopen("dump.v09","wb"))!=NULL) { @@ -1598,8 +1551,7 @@ static char optstring[]="d"; -int -main(int argc,char *argv[]) +int main(int argc,char *argv[]) { char c; int a; @@ -1661,7 +1613,7 @@ trace(); #endif - pcreg_prev = pcreg; + pcreg_prev = pcreg; } /* for */ return 0;