Adding MUL instruction.

This commit is contained in:
Russell-S-Harper 2018-08-14 10:19:39 -04:00
parent 61b9ce0b66
commit ae0e509335
3 changed files with 155 additions and 15 deletions

View File

@ -299,7 +299,17 @@ _2 INC _PCL ; advance PC
_3 RTS _3 RTS
.) .)
_TRFDR .( ; transfers RD to X as r register, updates overflow flag _RETZD .( ; clears register D, falls through to _TRFDR
LDA #0
STA _RD
STA _RD+1
STA _RD+2
STA _RD+3
.)
_TRFDR .( ; pulls X, transfers RD to X as r register, updates overflow flag
PLA
TAX
LDA _RD ; transfer result to Rr LDA _RD ; transfer result to Rr
STA _R0,X STA _R0,X
LDA _RD+1 LDA _RD+1
@ -339,9 +349,7 @@ _ADD .( ; ADD r pq ar pq Rr <- Rp + Rq - addition
LDA _R0+3,X LDA _R0+3,X
ADC _R0+3,Y ADC _R0+3,Y
STA _RD+3 STA _RD+3
PLA ; get r register JMP _TRFDR ; pull X, transfer RD to r register, let it handle the return
TAX
JMP _TRFDR ; transfer RD to r register, let it handle the return
.) .)
_SUB .( ; SUB r pq br pq Rr <- Rp - Rq - subtraction _SUB .( ; SUB r pq br pq Rr <- Rp - Rq - subtraction
@ -361,13 +369,146 @@ _SUB .( ; SUB r pq br pq Rr <- Rp - Rq - subtraction
LDA _R0+3,X LDA _R0+3,X
SBC _R0+3,Y SBC _R0+3,Y
STA _RD+3 STA _RD+3
PLA ; get r register JMP _TRFDR ; pull X, transfer RD to r register, let it handle the return
TAX .)
JMP _TRFDR ; transfer RD to r register, let it handle the return
_TRFQD .( ; transfers Y as q register to RD
LDA _R0,Y
STA _RD
LDA _R0+1,Y
STA _RD+1
LDA _R0+2,Y
STA _RD+2
LDA _R0+3,Y
STA _RD+3
RTS
.)
_NEGRY .( ; negates register at Y
SEC
LDA #0
SBC _R0,Y
STA _R0,Y
LDA #0
SBC _R0+1,Y
STA _R0+1,Y
LDA #0
SBC _R0+2,Y
STA _R0+2,Y
LDA #0
SBC _R0+3,Y
STA _R0+3,Y
RTS
.)
_ABSRY .( ; sets register at Y to absolute value
LDA _R0+3,Y
BMI _NEGRY
RTS
.) .)
_MUL .( ; MUL r pq cr pq Rr <- Rp * Rq - multiplication _MUL .( ; MUL r pq cr pq Rr <- Rp * Rq - multiplication
RTS TXA ; adapted from http://www.6502.org/source/integers/32muldiv.htm
PHA ; save r register for later
JSR _GETPQ
LDA _R0,X ; check for zero argument
ORA _R0+1,X
ORA _R0+2,X
ORA _R0+3,X
BNE _1 ; p is non-zero
JMP _RETZD ; p is zero, return zero
_1 LDA _R0,Y ; check for zero argument
ORA _R0+1,Y
ORA _R0+2,Y
ORA _R0+3,Y
BNE _2 ; q is non-zero
JMP_RETZD ; q is zero, return zero
_2 LDA _R0+3,X ; save sign of register p
AND #%11000000
PHA
EOR _R0+3,Y
AND #%11000000 ; save sign of product
PHA
JSR _TRFQD
TXA
TAY ; absolute value of register p
JSR _ABSRY
LDY #_RD-_R0 ; absolute value of register q saved in D
JSR _ABSRY
LDA #0
STA _RB+4 ; clear upper half of product
STA _RB+5
STA _RB+6
STA _RB+7
LDY #34 ; thirty bit multiply and four bit shift
_3 LSR _RD+3 ; shift operand
ROR _RD+2
ROR _RD+1
ROR _RD
BCC _4 ; skip adding in product if bit is zero
CLC
LDA _RB+4 ; add in p register
ADC _R0,X
STA _RB+4
LDA _RB+5
ADC _R0+1,X
STA _RB+5
LDA _RB+6
ADC _R0+2,X
STA _RB+6
LDA _RB+7
ADC _R0+3,X
_4 ROR ; shift the product
STA _RB+7
ROR _RB+6
ROR _RB+5
ROR _RB+4
ROR _RB+3
ROR _RB+2
ROR _RB+1
ROR _RB
DEY
BNE _3 ; repeat until bits are done
LDA _RB+1 ; copy result to RD
STA _RD
LDA _RB+2
STA _RD+1
LDA _RB+3
STA _RD+2
LDA _RB+4
STA _RD+3
AND #_MSK_O ; consider the overflow bits
ORA _RB+5 ; check all the other bytes
ORA _RB+6
ORA _RB+7
BEQ _5 ; all zeroes means no overflow
LDA _RD+3 ; overflow situation, set accordingly
AND #_MSK_O^$FF ; set overflow
ORA #_F_O
STA _RD+3
BNE _6
_5 LDA _RD ; check for underflow
ORA _RD+1
ORA _RD+2
ORA _RD+3
BNE _6 ; non-zero result means no underflow
LDA _F ; we checked earlier for zero operands, so a zero result means underflow, set underflow
ORA #_F_U
STA _F
BNE _7
_6 LDA _F ; clear underflow
AND #_F_U^$FF
STA _F
_7 PLA ; set the sign of the product
BEQ _8
LDY #_RD-_R0 ; negate register D
JSR _NEGRY
_8 PLA ; reset the sign of register p
BEQ _9
TXA
TAY
JSR _NEGRY
_9 JMP _TRFDR ; pull X, transfer RD to r register, let it handle the return
.) .)
_DIV .( ; DIV r pq dr pq Rr <- Rp / Rq - division _DIV .( ; DIV r pq dr pq Rr <- Rp / Rq - division

View File

@ -58,9 +58,9 @@ _R7 = _R6 + 4
_R8 = _R7 + 4 _R8 = _R7 + 4
_R9 = _R8 + 4 _R9 = _R8 + 4
_RA = _R9 + 4 _RA = _R9 + 4
_RB = _RA + 4 _RB = _RA + 4 ; workspace for MUL, DIV, and MOD
_RC = _RB + 4 ; workspace for arithmetic operations _RC = _RB + 4 ; as above
_RD = _RC + 4 ; as above and for EXC _RD = _RC + 4 ; as above and for ADD, SUB, and EXC
_RE = _RD + 4 ; register E maintains common status _RE = _RD + 4 ; register E maintains common status
_RF = _RE + 4 ; register F saves/restores processor status _RF = _RE + 4 ; register F saves/restores processor status

View File

@ -5,10 +5,9 @@
HDR(DEMO) HDR(DEMO)
CMN CMN
SET(R0, 1/1024) SET(R0, -1023.9995)
SET(R1, -1/1024) SET(R1, -1023.9995)
ADD(R2, R0, R1) MUL(R2, R0, R1)
SUB(R3, R0, R1)
ESC ESC
BRK BRK