diff --git a/common/common.asm b/common/common.asm index 08b986a..742c50e 100644 --- a/common/common.asm +++ b/common/common.asm @@ -269,12 +269,101 @@ _HEX .( ; HEX r 9r Rr <- hex(Rr) - convert Rr from decimal ######.## to hex RTS .) +_GETPQ .( ; sets X as p register and Y as q register, advances PC + LDY #0 + LDA (_PC),Y ; get source registers + LSR + LSR + AND #_MSK_R ; p register + TAX + LDA (_PC),Y + ASL + ASL + AND #_MSK_R ; q register + TAY + LDA _R0+3,X + AND #_MSK_O ; check for existing overflow condition + BEQ _1 ; sign and overflow are both clear + EOR #_MSK_O + BEQ _1 ; sign and overflow are both set + BRK ; an operand is in an overflow condition, abort and call exception handler (TODO) +_1 LDA _R0+3,Y + AND #_MSK_O ; check for existing overflow condition + BEQ _2 ; sign and overflow are both clear + EOR #_MSK_O + BEQ _2 ; sign and overflow are both set + BRK ; an operand is in an overflow condition, abort and call exception handler (TODO) +_2 INC _PCL ; advance PC + BNE _3 + INC _PCH +_3 RTS +.) + +_TRFDR .( ; transfers RD to X as r register, updates overflow flag + LDA _RD ; transfer result to Rr + STA _R0,X + LDA _RD+1 + STA _R0+1,X + LDA _RD+2 + STA _R0+2,X + LDA _RD+3 + STA _R0+3,X + AND #_MSK_O ; check for overflow + BEQ _4 + EOR #_MSK_O + BEQ _4 +_3 LDA _F ; set overflow + ORA #_F_O + STA _F + BNE _5 +_4 LDA _F ; clear overflow + AND #_F_O^$FF + STA _F +_5 RTS +.) + _ADD .( ; ADD r pq ar pq Rr <- Rp + Rq - addition - RTS + TXA + PHA ; save r register for later + JSR _GETPQ + CLC ; set RD to Rp + Rq + LDA _R0,X + ADC _R0,Y + STA _RD + LDA _R0+1,X + ADC _R0+1,Y + STA _RD+1 + LDA _R0+2,X + ADC _R0+2,Y + STA _RD+2 + LDA _R0+3,X + ADC _R0+3,Y + STA _RD+3 + PLA ; get r register + TAX + JMP _TRFDR ; transfer RD to r register, let it handle the return .) _SUB .( ; SUB r pq br pq Rr <- Rp - Rq - subtraction - RTS + TXA + PHA ; save r register for later + JSR _GETPQ + SEC ; set RD to Rp - Rq + LDA _R0,X + SBC _R0,Y + STA _RD + LDA _R0+1,X + SBC _R0+1,Y + STA _RD+1 + LDA _R0+2,X + SBC _R0+2,Y + STA _RD+2 + LDA _R0+3,X + SBC _R0+3,Y + STA _RD+3 + PLA ; get r register + TAX + JMP _TRFDR ; transfer RD to r register, let it handle the return .) _MUL .( ; MUL r pq cr pq Rr <- Rp * Rq - multiplication diff --git a/common/common.h b/common/common.h index c98b000..c959ce7 100644 --- a/common/common.h +++ b/common/common.h @@ -7,9 +7,9 @@ ; calculation. ; Largest value: $3fffffff or 1048575.999(5) -; Smallest value: $c0000001 or -1048575.998(5) <- note 998(5) -; Largest value for DEC/HEX: $3d08ffff or 999999.999(5) -; Smallest value for DEC/HEX: $c2f70000 or -999999.999(5) +; Smallest value: $c0000000 or -1048576.000(0) +; Largest value for DEC/HEX: $3d08ffff or 999999.999 +; Smallest value for DEC/HEX: $c2f70001 or -999999.999 ; Instructions @@ -47,7 +47,7 @@ ; CMR pq 0f pq F <- Rp <=> Rq - compare registers ; 64 bytes in page zero for common registers -_R0 = $C0 +_R0 = $c0 _R1 = _R0 + 4 _R2 = _R1 + 4 _R3 = _R2 + 4 @@ -94,7 +94,7 @@ _RS = $200 ; register stack _RSS = (FN_FX - _RS) ; register stack size ; last 32 bytes of page two -FN_FX = $2E0 ; list of system and user functions +FN_FX = $2e0 ; list of system and user functions ; function constants _ESC_C = $00 @@ -134,11 +134,12 @@ _EXT_C = $f0 ; plus and minus 1 for increment and decrement _PLS_1 = %00000100 ; i.e. the $04 part of $00000400 -_MNS_1 = %11111100 ; i.e. the $FC part of $FFFFFC00 +_MNS_1 = %11111100 ; i.e. the $fc part of $fffffc00 _MSK_O = %11000000 ; mask for overflow +_MSK_R = %00111100 ; mask for registers ; mask for TST -_MSK_T = (_F_Z + _F_P + _F_N)^$FF +_MSK_T = (_F_Z + _F_P + _F_N)^$ff #endif /* __COMMON_H */ diff --git a/common/macros.h b/common/macros.h index e3d8951..ea524a2 100644 --- a/common/macros.h +++ b/common/macros.h @@ -83,7 +83,7 @@ #define TST(r) .BYTE _TST_C + r #define DEC(r) .BYTE _DEC_C + r #define HEX(r) .BYTE _HEX_C + r -#define ADD(r) .BYTE _ADD_C + r +#define ADD(r, p, q) .BYTE _ADD_C + r, p * 16 + q #define SUB(r, p, q) .BYTE _SUB_C + r, p * 16 + q #define MUL(r, p, q) .BYTE _MUL_C + r, p * 16 + q #define DIV(r, p, q) .BYTE _DIV_C + r, p * 16 + q diff --git a/common/page6.src b/common/page6.src index cb6cdbb..1ca4d44 100644 --- a/common/page6.src +++ b/common/page6.src @@ -5,19 +5,10 @@ HDR(DEMO) CMN - SET(R0, +1048575.999) - SET(R1, -1048575.999) - SET(R2, 0.0) - SET(R3, 0.0) - INR(R0) - DCR(R1) - INR(R2) - DCR(R3) - INR(R0) - DCR(R1) - TST(R4) - TST(R2) - TST(R3) + SET(R0, 1/1024) + SET(R1, -1/1024) + ADD(R2, R0, R1) + SUB(R3, R0, R1) ESC BRK diff --git a/xa-pre-process/main.c b/xa-pre-process/main.c index ad4d7e8..2d2f30c 100644 --- a/xa-pre-process/main.c +++ b/xa-pre-process/main.c @@ -24,7 +24,6 @@ int main(int argc, char **argv) for (i = 0; i < count; ++i) { int j, sign; - unsigned long working; const char *s = "", *p, *q; switch (tokens[i].type) { @@ -41,14 +40,14 @@ int main(int argc, char **argv) sign = result < 0? -1: +1; if (sign < 0) result = -result; result += 1 << (INT_FRAC - EXP_FRAC - 1); - if (sign < 0) result = -result; /* Normalize */ - working = (unsigned long)((result >> (INT_FRAC - EXP_FRAC)) % (1 << EXP_FULL)); + result >>= (INT_FRAC - EXP_FRAC); + if (sign < 0) result = -result; /* Output in .BYTE format */ for (j = 0; j < EXP_FULL; j += CHAR_BIT) { - printf("%s$%02lX", s, working & 0xff); - working >>= CHAR_BIT; + printf("%s$%02llX", s, result & 0xff); + result >>= CHAR_BIT; s = ", "; } break;