From 6dc8517120b6eebc4edaea3d281d79a5a4ee5540 Mon Sep 17 00:00:00 2001 From: Russell-S-Harper Date: Sun, 19 Aug 2018 10:01:59 -0400 Subject: [PATCH] Added MOD instruction. Some refactoring. --- common/common.asm | 199 ++++++++++++++++++++++++++++++++-------------- common/page6.src | 7 +- 2 files changed, 142 insertions(+), 64 deletions(-) diff --git a/common/common.asm b/common/common.asm index 1a5b50c..3af6950 100644 --- a/common/common.asm +++ b/common/common.asm @@ -514,25 +514,7 @@ _8 PLA ; reset the sign of register p _9 JMP _TRFDR ; pull X, transfer RD to r register, let it handle the return .) -_CMPDC .( ; compare D to C, return result in status - LDA _RD+3 - CMP _RC+3 - BCC _1 ; definitely less - BNE _1 ; definitely greater - LDA _RD+2 - CMP _RC+2 - BCC _1 ; definitely less - BNE _1 ; definitely greater - LDA _RD+1 - CMP _RC+1 - BCC _1 ; definitely less - BNE _1 ; definitely greater - LDA _RD - CMP _RC -_1 RTS -.) - -_DIV .( ; DIV r pq dr pq Rr <- Rp / Rq - division +_INTDM .( ; initialize for DIV and MOD, returns sign of result in A TXA PHA ; save r register for later JSR _GETPQ @@ -578,42 +560,32 @@ _2 LDA _R0,X ; copy p to RD STA _R0+1,X STA _R0+2,X STA _R0+3,X - LDA _RD+3 ; save sign of quotient + LDA _RD+3 ; get sign of result EOR _RC+3 AND #_MSK_O - PHA - LDY #_RD-_R0 ; absolute value of register p saved in D - JSR _ABSRY - LDY #_RC-_R0 ; absolute value of register q saved in C - JSR _ABSRY -_3 JSR _CMPDC ; is D < C? - BCC _4 ; yes, continue - BEQ _5 ; D = C - ASL _RC ; RC *= 2 - ROL _RC+1 - ROL _RC+2 - ROL _RC+3 - ASL _RB ; RB *= 2 - ROL _RB+1 - ROL _RB+2 - ROL _RB+3 - BCC _3 - ; carry is set, means a real overflow condition - LDA #$FF ; set to the maximum - STA _R0,X - STA _R0+1,X - STA _R0+2,X - LDA #_MAX_V|_F_O - STA _R0+3,X - JMP _9 -_4 LDA _RB ; is RB > 0? - ORA _RB+1 - ORA _RB+2 - ORA _RB+3 - BEQ _7 ; no, done - JSR _CMPDC ; is D >= C? - BCC _6 ; no, skip subtraction -_5 SEC ; RD -= RC + RTS +.) + +_CMPDC .( ; compare D to C, return result in status + LDA _RD+3 + CMP _RC+3 + BCC _1 ; definitely less + BNE _1 ; definitely greater + LDA _RD+2 + CMP _RC+2 + BCC _1 ; definitely less + BNE _1 ; definitely greater + LDA _RD+1 + CMP _RC+1 + BCC _1 ; definitely less + BNE _1 ; definitely greater + LDA _RD + CMP _RC +_1 RTS +.) + +_UPDDM .( ; update DIV and MOD + SEC ; RD -= RC LDA _RD SBC _RC STA _RD @@ -639,12 +611,23 @@ _5 SEC ; RD -= RC LDA _R0+3,X ADC _RB+3 STA _R0+3,X - LDA _RD ; is RD > 0? - ORA _RD+1 - ORA _RD+2 - ORA _RD+3 - BEQ _7 ; no, done -_6 CLC ; RC /= 2 + RTS +.) + +_SHUDM .( ; shift up for DIV and MOD + ASL _RC ; RC *= 2 + ROL _RC+1 + ROL _RC+2 + ROL _RC+3 + ASL _RB ; RB *= 2 + ROL _RB+1 + ROL _RB+2 + ROL _RB+3 + RTS +.) + +_SHDDM .( ; shift down for DIV and MOD + CLC ; RC /= 2 ROR _RC+3 ROR _RC+2 ROR _RC+1 @@ -654,6 +637,43 @@ _6 CLC ; RC /= 2 ROR _RB+2 ROR _RB+1 ROR _RB + RTS +.) + +_DIV .( ; DIV r pq dr pq Rr <- Rp / Rq - division + JSR _INTDM ; initialize + PHA ; save sign of result + LDY #_RD-_R0 ; absolute value of register p saved in D + JSR _ABSRY + LDY #_RC-_R0 ; absolute value of register q saved in C + JSR _ABSRY +_3 JSR _CMPDC ; is D < C? + BCC _4 ; yes, continue + BEQ _5 ; D = C + JSR _UPDDM ; confirmed D > C, so RD -= RC, RX += RB + JSR _SHUDM ; shift up + BCC _3 ; if carry is set, means a really bad overflow condition + LDA #$FF ; set to the maximum + STA _R0,X + STA _R0+1,X + STA _R0+2,X + LDA #_MAX_V|_F_O + STA _R0+3,X + BNE _9 +_4 LDA _RB ; is RB > 0? + ORA _RB+1 + ORA _RB+2 + ORA _RB+3 + BEQ _7 ; no, done + JSR _CMPDC ; is D >= C? + BCC _6 ; no, skip subtraction +_5 JSR _UPDDM ; RD -= RC, RX += RB + LDA _RD ; is RD > 0? + ORA _RD+1 + ORA _RD+2 + ORA _RD+3 + BEQ _7 ; no, done +_6 JSR _SHDDM ; shift down JMP _4 _7 LDA _R0,X ; check for underflow ORA _R0+1,X @@ -686,7 +706,66 @@ _C RTS .) _MOD .( ; MOD r pq er pq Rr <- Rp % Rq - modulus - RTS + JSR _INTDM ; initialize + PHA ; save sign of result + LDY #_RD-_R0 ; absolute value of register p saved in D + JSR _ABSRY + LDY #_RC-_R0 ; absolute value of register q saved in C + JSR _ABSRY +_3 JSR _CMPDC ; is D < C? + BCC _4 ; yes, continue + BEQ _5 ; D = C + JSR _UPDDM ; confirmed D > C, so RD -= RC, RX += RB + JSR _SHUDM ; shift up + BCC _3 ; if carry is set, means a really bad overflow condition + LDA #1 ; set to "overflowed non-zero" + STA _R0,X + LDA #0 + STA _R0+1,X + STA _R0+2,X + ORA #_F_O + STA _R0+3,X + BNE _9 +_4 LDA _RB+1 ; is RB < 1? + CMP #_PLS_1 + BCC _7 ; yes, done + JSR _CMPDC ; is D >= C? + BCC _6 ; no, skip subtraction +_5 JSR _UPDDM ; RD -= RC, RX += RB + LDA _RD ; is RD > 0? + ORA _RD+1 + ORA _RD+2 + ORA _RD+3 + BEQ _7 ; no, done +_6 JSR _SHDDM ; shift down + JMP _4 +_7 LDA _RD ; transfer RD to RX + STA _R0,X + LDA _RD+1 + STA _R0+1,X + LDA _RD+2 + STA _R0+2,X + LDA _RD+3 + STA _R0+3,X +_8 LDA _F ; clear underflow + AND #_F_U^$FF + STA _F +_9 LDA _R0+3,X ; check for overflow + AND #_MSK_O + BEQ _A ; all zero, no overflow + LDA _F ; set overflow + ORA #_F_O + STA _F + BNE _B +_A LDA _F ; clear overflow + AND #_F_O^$FF + STA _F +_B PLA ; set the sign of modulus + BEQ _C + TXA + TAY + JSR _NEGRY +_C RTS .) _ESC .( ; ESC 00 - escape back into regular assembler diff --git a/common/page6.src b/common/page6.src index 07730f4..5c025d4 100644 --- a/common/page6.src +++ b/common/page6.src @@ -5,10 +5,9 @@ HDR(DEMO) CMN - SET(R0, 1023.9995) - SET(R1, %0.0000000001) - DIV(R2, R0, R1) - MUL(R3, R1, R2) + SET(R0, 1024 * 1024 - 0.001) + SET(R1, 1/4) + MOD(R2, R0, R1) ESC BRK