mirror of
https://github.com/Russell-S-Harper/COMMON.git
synced 2024-09-07 13:54:34 +00:00
799 lines
14 KiB
NASM
799 lines
14 KiB
NASM
#include "rom.h"
|
|
#include "common.h"
|
|
|
|
; ROM code header
|
|
.WORD CMN_CD, _END_CMN_CD - CMN_CD
|
|
|
|
; beginning of ROM code
|
|
* = CMN_CD
|
|
|
|
_CMN .( ; common function interpreter
|
|
JSR _SAV ; save registers
|
|
PLA
|
|
STA _PCL ; set program counter from return address
|
|
PLA
|
|
STA _PCH
|
|
INC _PCL ; advance the program counter
|
|
BNE _1
|
|
INC _PCH
|
|
_1 JSR _2 ; interpret and execute one common instruction
|
|
JMP _1
|
|
_2 LDY #0
|
|
LDA (_PC),Y ; get operand
|
|
INC _PCL ; advance the program counter
|
|
BNE _3
|
|
INC _PCH
|
|
_3 TAX ; save operand for later
|
|
AND #$F0
|
|
BEQ _4 ; go to 0X instructions
|
|
CMP #$F0 ; check for FX functions
|
|
BEQ _5 ; go to FX instructions
|
|
LSR ; get offset to XR instructions
|
|
LSR
|
|
LSR
|
|
TAY
|
|
DEY
|
|
DEY
|
|
LDA FN_XR+1,Y ; push high address
|
|
PHA
|
|
LDA FN_XR,Y ; push low address
|
|
PHA
|
|
TXA ; restore operand
|
|
AND #$F ; mask to get register
|
|
ASL ; shift to get offset to register
|
|
ASL
|
|
TAX ; back to index
|
|
RTS ; "return" to routine
|
|
_4 TXA ; get operand
|
|
ASL ; shift to get offset to 0X instructions
|
|
TAY
|
|
LDA FN_0X+1,Y ; push high address
|
|
PHA
|
|
LDA FN_0X,Y ; push low address
|
|
PHA
|
|
TXA ; restore operand
|
|
RTS ; "return" to routine
|
|
_5 TXA ; get operand
|
|
AND #$F ; mask to get index
|
|
ASL ; shift to get offset to FX instructions
|
|
TAY
|
|
LDA FN_FX+1,Y ; push high address
|
|
PHA
|
|
LDA FN_FX,Y ; push low address
|
|
PHA
|
|
TXA ; restore operand
|
|
RTS ; "return" to routine
|
|
.)
|
|
|
|
_INI .( ; initialize common
|
|
LDA #0 ; initialize RSI
|
|
STA _RSI
|
|
; copy system functions (TODO)
|
|
; load program (TODO)
|
|
JMP (_PC) ; go to last loaded block
|
|
.)
|
|
|
|
_SAV .( ; save the registers prior to entering common
|
|
STA _ACC
|
|
STX _IDX
|
|
STY _IDY
|
|
PHP
|
|
PLA
|
|
STA _PS
|
|
CLD
|
|
RTS
|
|
.)
|
|
|
|
_RES .( ; restore the registers prior to leaving common
|
|
LDA _PS
|
|
PHA
|
|
LDA _ACC
|
|
LDX _IDX
|
|
LDY _IDY
|
|
PLP
|
|
RTS
|
|
.)
|
|
|
|
_SET .( ; SET r aabbcc.dd 1r dd cc bb aa Rr <- aabbcc.dd - set register
|
|
LDY #0
|
|
LDA (_PC),Y ; transfer four bytes over
|
|
STA _R0,X
|
|
INY
|
|
LDA (_PC),Y
|
|
STA _R0+1,X
|
|
INY
|
|
LDA (_PC),Y
|
|
STA _R0+2,X
|
|
INY
|
|
LDA (_PC),Y
|
|
STA _R0+3,X
|
|
LDA #4 ; update program counter
|
|
CLC
|
|
ADC _PCL
|
|
STA _PCL
|
|
BCC _1
|
|
INC _PCH
|
|
_1 RTS ; done
|
|
.)
|
|
|
|
_PSH .( ; PSH r 2r RS <- Rr - push onto stack
|
|
LDY _RSI ; get register stack index
|
|
CPY #_RSS ; compare against limit
|
|
BCC _1 ; still room, all okay
|
|
BRK ; next push will cause a stack overflow, abort and call exception handler (TODO)
|
|
_1 LDA _R0,X ; transfer four bytes over
|
|
STA _RS,Y
|
|
INY
|
|
LDA _R0+1,X
|
|
STA _RS,Y
|
|
INY
|
|
LDA _R0+2,X
|
|
STA _RS,Y
|
|
INY
|
|
LDA _R0+3,X
|
|
STA _RS,Y
|
|
INY
|
|
STY _RSI ; update register stack index
|
|
RTS
|
|
.)
|
|
|
|
_POP .( ; POP r 3r Rr <- RS - pop from stack
|
|
LDY _RSI ; get register stack index
|
|
BNE _1 ; all good, something can be popped off the stack
|
|
BRK ; next pop will cause a stack underflow, abort and call exception handler (TODO)
|
|
_1 DEY ; transfer four bytes over
|
|
LDA _RS,Y
|
|
STA _R0+3,X
|
|
DEY
|
|
LDA _RS,Y
|
|
STA _R0+2,X
|
|
DEY
|
|
LDA _RS,Y
|
|
STA _R0+1,X
|
|
DEY
|
|
LDA _RS,Y
|
|
STA _R0,X
|
|
STY _RSI ; update register stack index
|
|
RTS
|
|
.)
|
|
|
|
_EXC .( ; EXC r 4r Rr <-> RS - exchange Rr with stack
|
|
LDY _RSI ; RS to RD
|
|
LDA _RS-1,Y
|
|
STA _RD+3
|
|
LDA _RS-2,Y
|
|
STA _RD+2
|
|
LDA _RS-3,Y
|
|
STA _RD+1
|
|
LDA _RS-4,Y
|
|
STA _RD
|
|
LDA _R0,X ; copy Rr to RS
|
|
STA _RS-4,Y
|
|
LDA _R0+1,X
|
|
STA _RS-3,Y
|
|
LDA _R0+2,X
|
|
STA _RS-2,Y
|
|
LDA _R0+3,X
|
|
STA _RS-1,Y
|
|
LDA _RD ; copy RD 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
|
|
RTS
|
|
.)
|
|
|
|
_ADDRD .( ; add RD to register indexed by X
|
|
LDA _R0+3,X
|
|
AND #_MSK_O ; check for existing overflow condition
|
|
BEQ _4
|
|
EOR #_MSK_O
|
|
BNE _3 ; existing overflow, skip decrement operation
|
|
_4 CLC ; adding RD
|
|
LDA _RD
|
|
ADC _R0,X
|
|
STA _R0,X
|
|
LDA _RD+1
|
|
ADC _R0+1,X
|
|
STA _R0+1,X
|
|
LDA _RD+2
|
|
ADC _R0+2,X
|
|
STA _R0+2,X
|
|
LDA _RD+3
|
|
ADC _R0+3,X
|
|
STA _R0+3,X
|
|
AND #_MSK_O ; check for overflow
|
|
BEQ _2
|
|
EOR #_MSK_O
|
|
BEQ _2
|
|
_3 LDA _F ; set overflow
|
|
ORA #_F_O
|
|
STA _F
|
|
BNE _5
|
|
_2 LDA _F ; clear overflow
|
|
AND #_F_O^$FF
|
|
STA _F
|
|
_5 RTS
|
|
.)
|
|
|
|
_INR .( ; INR r 5r Rr <- Rr + 1.0 - increment register
|
|
LDA #0 ; set RD to plus one
|
|
STA _RD
|
|
LDA #_PLS_1
|
|
STA _RD+1
|
|
LDA #0
|
|
STA _RD+2
|
|
STA _RD+3
|
|
BEQ _ADDRD
|
|
.)
|
|
|
|
_DCR .( ; DCR r 6r Rr <- Rr - 1.0 - decrement register
|
|
LDA #0 ; set RD to minus one
|
|
STA _RD
|
|
LDA #_MNS_1
|
|
STA _RD+1
|
|
LDA #$FF
|
|
STA _RD+2
|
|
STA _RD+3
|
|
BNE _ADDRD
|
|
.)
|
|
|
|
_TST .( ; TST r 7r F <- Rr <=> 0.0 - test register
|
|
LDA _F
|
|
AND #_MSK_T ; clear TST bits
|
|
STA _F
|
|
LDA _R0+3,X ; check highest byte
|
|
BMI _1 ; is negative
|
|
ORA _R0+2,X ; could be positive or zero, OR with all other bytes
|
|
ORA _R0+1,X
|
|
ORA _R0,X
|
|
BNE _2 ; is positive
|
|
LDA #_F_Z ; set zero flag
|
|
BNE _3
|
|
_1 LDA #_F_N ; set negative flag
|
|
BNE _3
|
|
_2 LDA #_F_P ; set positive flag
|
|
_3 ORA _F
|
|
STA _F
|
|
RTS
|
|
.)
|
|
|
|
_DEC .( ; DEC r 8r Rr <- dec(Rr) - convert Rr from hex aabbcc.dd to decimal ######.##
|
|
RTS
|
|
.)
|
|
|
|
_HEX .( ; HEX r 9r Rr <- hex(Rr) - convert Rr from decimal ######.## to hex aabbcc.dd
|
|
RTS
|
|
.)
|
|
|
|
_GETPQ .( ; sets X as p register and Y as q register, checks for overflow in the operands, 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
|
|
.)
|
|
|
|
_RETZD .( ; clears register D, clears underflow, falls through to _TRFDR
|
|
LDA #0
|
|
STA _RD
|
|
STA _RD+1
|
|
STA _RD+2
|
|
STA _RD+3
|
|
LDA _F ; clear underflow
|
|
AND #_F_U^$FF
|
|
STA _F
|
|
.)
|
|
|
|
_TRFDR .( ; pulls X, transfers RD to X as r register, updates overflow flag
|
|
PLA
|
|
TAX
|
|
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
|
|
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
|
|
JMP _TRFDR ; pull X, transfer RD to r register, let it handle the return
|
|
.)
|
|
|
|
_SUB .( ; SUB r pq br pq Rr <- Rp - Rq - subtraction
|
|
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
|
|
JMP _TRFDR ; pull X, 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
|
|
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 #_MSK_O
|
|
PHA
|
|
EOR _R0+3,Y
|
|
AND #_MSK_O ; 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
|
|
.)
|
|
|
|
_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
|
|
TXA
|
|
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
|
|
BRK ; q is zero, abort and call exception handler (TODO)
|
|
_2 LDA _R0,X ; copy p to RD
|
|
STA _RD
|
|
LDA _R0+1,X
|
|
STA _RD+1
|
|
LDA _R0+2,X
|
|
STA _RD+2
|
|
LDA _R0+3,X
|
|
STA _RD+3
|
|
LDA _R0,Y ; copy q to RC
|
|
STA _RC
|
|
LDA _R0+1,Y
|
|
STA _RC+1
|
|
LDA _R0+2,Y
|
|
STA _RC+2
|
|
LDA _R0+3,Y
|
|
STA _RC+3
|
|
LDA #0 ; set RB to 1
|
|
STA _RB
|
|
LDA #_PLS_1
|
|
STA _RB+1
|
|
LDA #0
|
|
STA _RB+2
|
|
STA _RB+3
|
|
PLA ; restore r register
|
|
TAX
|
|
LDA #0 ; set r to 0
|
|
STA _R0,X
|
|
STA _R0+1,X
|
|
STA _R0+2,X
|
|
STA _R0+3,X
|
|
LDA _RD+3 ; save sign of quotient
|
|
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 _R0+3,X
|
|
ORA #_F_O
|
|
STA _R0+3,X
|
|
BEQ _4
|
|
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
|
|
LDA _RD
|
|
SBC _RC
|
|
STA _RD
|
|
LDA _RD+1
|
|
SBC _RC+1
|
|
STA _RD+1
|
|
LDA _RD+2
|
|
SBC _RC+2
|
|
STA _RD+2
|
|
LDA _RD+3
|
|
SBC _RC+3
|
|
STA _RD+3
|
|
CLC ; RX += RB
|
|
LDA _R0,X
|
|
ADC _RB
|
|
STA _R0,X
|
|
LDA _R0+1,X
|
|
ADC _RB+1
|
|
STA _R0+1,X
|
|
LDA _R0+2,X
|
|
ADC _RB+2
|
|
STA _R0+2,X
|
|
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
|
|
ROR _RC+3
|
|
ROR _RC+2
|
|
ROR _RC+1
|
|
ROR _RC
|
|
CLC ; RB /= 2
|
|
ROR _RB+3
|
|
ROR _RB+2
|
|
ROR _RB+1
|
|
ROR _RB
|
|
JMP _4
|
|
_7 LDA _R0,X ; check for underflow
|
|
ORA _R0+1,X
|
|
ORA _R0+2,X
|
|
ORA _R0+3,X
|
|
BNE _8 ; 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 _A
|
|
_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 quotient
|
|
BEQ _C
|
|
TXA
|
|
TAY
|
|
JSR _NEGRY
|
|
_C RTS
|
|
.)
|
|
|
|
_MOD .( ; MOD r pq er pq Rr <- Rp % Rq - modulus
|
|
RTS
|
|
.)
|
|
|
|
_ESC .( ; ESC 00 - escape back into regular assembler
|
|
PLA ; discard the COMMON _1 return address
|
|
PLA
|
|
JSR _RES ; restore the registers
|
|
JMP (_PC) ; get back in the code
|
|
.)
|
|
|
|
_RTN .( ; RTN 01 - return from subroutine
|
|
RTS
|
|
.)
|
|
|
|
_BRS .( ; BRS xxyy 02 yy xx PC <- PC + xxyy - branch to subroutine
|
|
RTS
|
|
.)
|
|
|
|
_BRA .( ; BRA xxyy 03 yy xx PC <- PC + xxyy - branch always
|
|
RTS
|
|
.)
|
|
|
|
_BRX .( ; generic branch testing
|
|
AND _F ; check the bit
|
|
BNE _BRA ; if set, branch
|
|
CLC ; not set, advance the program counter over the xxyy offset
|
|
LDA #2
|
|
ADC _PCL
|
|
STA _PCL
|
|
LDA #0
|
|
ADC _PCH
|
|
STA _PCH
|
|
RTS
|
|
.)
|
|
|
|
_BRE .( ; BRE xxyy 04 yy xx PC <- PC + xxyy - branch if Rp = Rq (after CMP)
|
|
LDA #_F_E
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRG .( ; BRG xxyy 05 yy xx PC <- PC + xxyy - branch if Rp > Rq (after CMP)
|
|
LDA #_F_G
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRL .( ; BRL xxyy 06 yy xx PC <- PC + xxyy - branch if Rp < Rq (after CMP)
|
|
LDA #_F_L
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRZ .( ; BRZ xxyy 07 yy xx PC <- PC + xxyy - branch if Rr = 0.0 (after TST)
|
|
LDA #_F_Z
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRP .( ; BRP xxyy 08 yy xx PC <- PC + xxyy - branch if Rr > 0.0 (after TST)
|
|
LDA #_F_P
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRN .( ; BRN xxyy 09 yy xx PC <- PC + xxyy - branch if Rr < 0.0 (after TST)
|
|
LDA #_F_N
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRO .( ; BRO xxyy 0a yy xx PC <- PC + xxyy - branch if overflow (after arithmetic operations)
|
|
LDA #_F_O
|
|
BNE _BRX
|
|
.)
|
|
|
|
_BRU .( ; BRU xxyy 0b yy xx PC <- PC + xxyy - branch if underflow (after arithmetic operations)
|
|
LDA #_F_U
|
|
BNE _BRX
|
|
.)
|
|
|
|
_CPR .( ; CPR pq 0c pq Rp <- Rq - copy register
|
|
RTS
|
|
.)
|
|
|
|
_LDI .( ; LDI pq 0d pq Rp <- (Rq:bbcc) - load indirect from memory
|
|
RTS
|
|
.)
|
|
|
|
_SVI .( ; SVI pq 0e pq (Rp:bbcc) <- Rq - save indirect to memory
|
|
RTS
|
|
.)
|
|
|
|
_CMR .( ; CMR pq 0f pq F <- Rp <=> Rq - compare registers
|
|
RTS
|
|
.)
|
|
|
|
_END_CMN_CD
|
|
|
|
; ROM data header
|
|
.WORD CMN_DT, _END_CMN_DT - CMN_DT
|
|
|
|
; beginning of ROM data
|
|
* = CMN_DT
|
|
|
|
FN_0X .WORD _ESC-1, _RTN-1, _BRS-1, _BRA-1, _BRE-1, _BRG-1, _BRL-1, _BRZ-1,
|
|
.WORD _BRP-1, _BRN-1, _BRO-1, _BRU-1, _CPR-1, _LDI-1, _SVI-1, _CMR-1
|
|
FN_XR .WORD _SET-1, _POP-1, _PSH-1, _EXC-1, _INR-1, _DCR-1, _TST-1,
|
|
.WORD _DEC-1, _HEX-1, _ADD-1, _SUB-1, _MUL-1, _DIV-1, _MOD-1
|
|
|
|
_END_CMN_DT
|
|
|
|
; 6502 addresses
|
|
.WORD ADDR, 6
|
|
|
|
; 6502 NMI, Reset and IRQ
|
|
* = $FFFA
|
|
ADDR .WORD 0, _INI, 0
|