gscifs/Library/Macros.s

572 lines
15 KiB
ArmAsm

*-------------------------
* Macro library
*-------------------------
INCD MAC ;Two byte INC
INC ]1
IF MX>1
BNE NC
INC ]1+1
NC FIN
<<<
DECD MAC ;Two byte DEC
IF MX>1
LDA ]1
BNE NC
DEC ]1+1
NC FIN
DEC ]1
<<<
MOV MAC
LDA ]1
STA ]2
<<<
MOVD MAC
MOV ]1;]2
IF MX>1 ;If A is short
IF (=]1 ;Syntax MOVD (ADR1),Y;????
INY
IF (=]2 ; MOVD (ADR1),Y;(ADR2),Y
MOV ]1;]2
ELSE ; MOVD (ADR1),Y;ADR2
MOV ]1;]2+1
FIN
ELSE
IF (=]2 ;Syntax MOVD ????;(ADR2),Y
INY
IF #=]1 ; MOVD #ADR1;(ADR2),Y
MOV ]1/$100;]2
ELSE ; MOVD ADR1;(ADR2),Y
MOV ]1+1;]2
FIN
ELSE ;Syntax MOVD ????;ADR2
IF #=]1 ; MOVD #ADR1;ADR2
MOV ]1/$100;]2+1
ELSE ; MOVD ADR1;ADR2
MOV ]1+1;]2+1
FIN
FIN
FIN
FIN
<<<
LDHI MAC ;For calls from other macs
IF #=]1
LDA ]1/$100
ELSE
LDA ]1+1
FIN
<<<
ADD MAC
IF #=]2
IF #=]1
ERR 1 ;Error if ADD #lab1;#lab2..
FIN
FIN
CLC
LDA ]1 ;Syntax ADD lab1;lab2;lab3
ADC ]2 ; or ADD #lab1;lab2;lab3 etc
DO ]0/3
STA ]3 ;If 3 parms
ELSE ;2 parm cases:
IF #=]2
STA ]1 ;Syntax ADD lab1;#lab2
ELSE ;Syntax ADD lab1;lab2
STA ]2 ; or ADD #lab1;lab2 -> lab2
FIN
FIN
IF MX>1 ;Following ignored if M long
LDA ]1+1
IF #=]2
ADC ]2/$100
ELSE
ADC ]2+1
FIN
DO ]0/3
STA ]3+1 ;If 3 parms
ELSE ;Two parm cases:
IF #=]2
STA ]1+1 ;Syntax ADD lab1;#lab2
ELSE ; -> lab1
STA ]2+1 ;Syntax ADD lab1;lab2 -> lab2
FIN ; or ADD #lab1;lab2 -> lab2
FIN
FIN
<<<
SUB MAC
IF #=]2
IF #=]1
ERR 1 ;Error if SUB #lab1;#lab2..
FIN
FIN
SEC
LDA ]1 ;Syntax SUB lab1;lab2;lab3
SBC ]2 ; or SUB #lab1;lab2;lab3 etc
DO ]0/3
STA ]3 ;If 3 parms
ELSE ;Two parm cases:
IF #=]2
STA ]1 ;Syntax SUB lab1;#lab2
ELSE ;Syntax SUB lab1;lab2
STA ]2 ; or SUB #lab1;lab2 -> lab2
FIN
FIN ;Of 2 parm cases
IF MX>1 ;Rest ignored if M long
LDHI ]1
IF #=]2
SBC ]2/$100 ;Case #lab2
ELSE
SBC ]2+1 ;Case lab2
FIN
DO ]0/3
STA ]3+1 ;If 3 parms
ELSE ;Two parm cases:
IF #=]2
STA ]1+1 ;Syntax SUB lab1;#lab2
ELSE ; -> lab1
STA ]2+1 ;Syntax SUB lab1;lab2 -> lab2
FIN ; or SUB #lab1;lab2 -> lab2
FIN ;Of 2 parm cases
FIN ;Of M short
<<<
ADDX MAC
TXA
ADDA MAC
CLC
ADC ]1
STA ]2
IF MX>1
LDHI ]1
ADC #0
STA ]2+1
FIN
<<<
ADDY MAC
TYA
ADDA ]1;]2
<<<
ADDNUM MAC
LDA #]1
CLC
ADC ]2
STA ]2
IF MX>1
BCC NC
INC ]2+1
NC FIN
<<<
SWAP MAC
LDA ]1
PHA
LDA ]2
STA ]1
PLA
STA ]2
<<<
COMPARE MAC
LDA ]1
CMP ]2
IF MX>1
LDHI ]1 ;Syntax COMPARE lab1;lab2
IF #=]2 ; or COMPARE lab1;#lab2
SBC ]2/$100
ELSE
SBC ]2+1
FIN
FIN
<<<
POKE MAC
MOV #]2;]1
<<<
STADR MAC
POKE ]2;]1
IF MX>1 ;If M is short, do high byte
POKE ]2+1;]1/$100
FIN
<<<
*=================================================
* Save and restore registers macros. Recommended
* for use at the start and end of subroutines
* which might be called from unknown status and
* which must set up register lengths.
*-------------------------------------------------
SAVSTAT MAC ;Save registers & status
PHA
PHY
PHX
PHP
<<<
RESTORE MAC ;Restore regs & status
PLP ;This must come first
PLX ; so register restores
PLY ; have correct length.
PLA
<<<
*=================================================
* Conditional branches not available on the 65816:
*-------------------------------------------------
BLE MAC ;Branch if less than or =
BEQ ]1
BLT ]1
<<<
BGT MAC ;Branch if greater than
BEQ OV
BGE ]1
OV <<<
*=================================================
* Conditional long branches. For use when out of
* range of a short branch and branching mechanism
* is wanted to be hidden on the listing.
*-------------------------------------------------
BRTL MAC ;BRL if less than (long)
BCCL MAC ;BRL if carry clear (long)
BCS OV
BRL ]1
OV <<<
BGEL MAC ;BRL if greater or equal (long)
BCSL MAC ;BRL if carry set (long)
BCC OV
BRL ]1
OV <<<
BPLL MAC ;BRL if plus (long)
BMI OV
BRL ]1
OV <<<
BMIL MAC ;BRL if minus (long)
BPL OV
BRL ]1
OV <<<
BEQL MAC ;BRL if equal (long)
BNE OV
BRL ]1
OV <<<
BNEL MAC ;BRL if not equal (long)
BEQ OV
BRL ]1
OV <<<
BVCL MAC ;BRL if V clear (long)
BVS OV
BRL ]1
OV <<<
BVSL MAC ;BRL if V set (long)
BVC OV
BRL ]1
OV <<<
BLEL MAC ;BRL if less or equal (long)
BEQ BR
BGE OV
BR BRL ]1
OV <<<
BLTL MAC ;BRL if less than (long)
BGE OV
BRL ]1
OV <<<
BGTL MAC ;BRL if greater than (long)
BEQ OV
BLT OV
BR BRL ]1
OV <<<
*=================================================
* The I/O macros below expect the COUT routine
* to be included or linked in as an external.
* PRINT expects the same of the SENDMSG routine.
*
* (Just declare COUT and SENDMSG as externals
* and include the linker command LIB 5 in the
* linker command file. SENDMSG also requires an
* OUTPUT routine in your source declared as an
* entry. It can be as simple as:
*
* OUTPUT JMP COUT
*
* SENDMSG and COUT are in the LIB directory and
* their source files are in the SOURCE directory.
*-------------------------------------------------
PRINT MAC ;Syntax PRINT "message"
JSR SENDMSG ; or PRINT 8D8D or
ASC ]1 ; PRINT 8D8D"text"8D"more"
BRK ; etc.
<<<
OUT MAC
LDA ]1 ;Syntax OUT #"A"
JSR COUT ; or OUT ADDRESS
<<< ; or OUT (PNT),Y etc.
HOME MAC ;Clear 80 col screen
OUT #"L"&$9F
<<<
NORMAL MAC ;Set normal text
OUT #"N"&$9F
<<<
INVERSE MAC ;Set inverse text
OUT #"O"&$9F
<<<
MOUSEON MAC ;Turn mousetext on
OUT #"["&$9F
INVERSE
<<<
MOUSEOFF MAC ;Turn mousetext off
OUT #"X"&$9F
NORMAL
<<<
BELL MAC ;Ring bell
OUT #"G"&$9F
<<<
CLEOL MAC ;Clear to end of line
OUT #$9D
<<<
CLEOP MAC ;Clear to end of screen
OUT #$8B
<<<
OUTCR MAC ;Do carriage return
OUT #$8D
<<<
GOTOXY MAC ;Pascal output only!
OUT #$1E
LDA ]1 ;X coor (imm or location)
CLC
ADC #' '
JSR COUT
LDA ]2 ;Y coor (")
CLC
ADC #' '
JSR COUT
<<<
CURSXY MAC ;GOTOXY for BASIC output
OUT #"Y"&$9F ;Home cursor
LDX ]2 ;Syntax (both versions):
BEQ H ; CURSXY #55;#10 or
CR OUTCR ; CURSXY XLOC,YLOC etc.
DEX
BNE CR
H IF MX<2 ;If M is long then
SEP %00100000 ; must shorten it
LDA ]1
STAL $24
REP %00100000 ; and lengthen on exit.
ELSE ;If M is short then
LDA ]1 ; leave as is
STAL $24
FIN
<<<
**************************************************
* APW-Equivalent Macros 1/20/89 *
* For use with APW or ORCA/M source listings. *
* *
**************************************************
*================================================
DP MAC
ADRL ]1
<<<
ASL4 MAC
LDA ]1+2
DO ]0/2 ;If 2 parms then set
LDX ]2 ; X to 2nd parm.
FIN
]A ASL ;Otherwise use X to
ASL ]1 ; decide how many
ADC #0 ; ASL's to do.
DEX
BNE ]A
STA ]1+2
<<<
LSR4 MAC
DO ]0/2 ;If 2 parms, then COMPLEMENT
LDA ]2 ; of X must be 2nd parm.
EOR $FFFF
CLC
ADC #1
TAX
FIN
LDA ]1
]A LSR
LSR ]1+2
BCC ]B
ORA #$8000
]B INX
BNE ]A
STA ]1
<<<
DEC4 MAC
IF MX/2-1 ; IF M IS SHORT
ERR 1 ; ERR IF NOT 16-BIT MODE
ELSE
DEC ]1
BPL ]A
DEC ]1+2
]A FIN
<<<
INC4 MAC
IF MX/2-1 ; IF M IS SHORT
ERR 1 ; ERR IF NOT 16-BIT MODE
ELSE
INC ]1
BNE ]A
INC ]1+2
]A FIN
<<<
ADD4 MAC
CLC ;If 3 parms then use
DO ]0/3 ; raw 4 byte addresses.
IF #=]1
LDA #<]1
ELSE ;Make sure we use the
LDA ]1 ; right LDA for data
FIN ; or addresses.
IF #=]2
ADC #<]2
ELSE ;Make sure we use the
ADC ]2 ; right ADC for data
FIN ; or addresses.
STA ]3
IF #=]1
LDA #^]1
ELSE ;Make sure we use the
LDA ]1+2 ; right LDA for data
FIN ; or addresses.
IF #=]2
ADC #^]2
ELSE ;Make sure we use the
ADC ]2+2 ; right ADC for data
FIN ; or addresses.
STA ]3+2
ELSE ;If 2 parms then use
; 2 byte Accumulator.
IF #=]1
ADC #<]1
ELSE ;Make sure we use the
ADC ]1 ; right ADC for data
FIN ; or addresses.
STA ]2
IF #=]1
LDA #^]1
ELSE ;Make sure we use the
LDA ]1+2 ; right LDA for data
FIN ; or addresses.
ADC #0
STA ]2+2
FIN
<<<
SUB4 MAC
SEC ;If 3 parms then use
DO ]0/3 ; raw 4 byte addresses.
IF #=]1
LDA #<]1
ELSE ;Make sure we use the
LDA ]1 ; right LDA for data
FIN ; or addresses.
IF #=]2
SBC #<]2
ELSE ;Make sure we use the
SBC ]2 ; right SBC for data
FIN ; or addresses.
STA ]3
IF #=]1
LDA #^]1
ELSE ;Make sure we use the
LDA ]1+2 ; right LDA for data
FIN ; or addresses.
IF #=]2
SBC #^]2
ELSE ;Make sure we use the
SBC ]2+2 ; right SBC for data
FIN ; or addresses.
STA ]3+2
ELSE
IF #=]1
SBC #<]1
ELSE ;Make sure we use the
SBC ]1 ; right SBC for data
FIN ; or addresses.
STA ]2
IF #=]1
LDA #^]1
ELSE ;Make sure we use the
LDA ]1+2 ; right LDA for data
FIN ; or addresses.
SBC #0
STA ]2+2
FIN
<<<