simplified the asmsub syntax

This commit is contained in:
Irmen de Jong 2019-07-08 23:00:18 +02:00
parent 65fa8c4613
commit d6b6254b72
10 changed files with 994 additions and 937 deletions

View File

@ -41,25 +41,25 @@
; note: for subtraction and division, the left operand is in fac2, the right operand in fac1.
; checked functions below:
asmsub MOVFM (uword mflpt @ AY) -> clobbers(A,Y) -> () = $bba2 ; load mflpt value from memory in A/Y into fac1
asmsub FREADMEM () -> clobbers(A,Y) -> () = $bba6 ; load mflpt value from memory in $22/$23 into fac1
asmsub CONUPK (uword mflpt @ AY) -> clobbers(A,Y) -> () = $ba8c ; load mflpt value from memory in A/Y into fac2
asmsub FAREADMEM () -> clobbers(A,Y) -> () = $ba90 ; load mflpt value from memory in $22/$23 into fac2
asmsub MOVFA () -> clobbers(A,X) -> () = $bbfc ; copy fac2 to fac1
asmsub MOVAF () -> clobbers(A,X) -> () = $bc0c ; copy fac1 to fac2 (rounded)
asmsub MOVEF () -> clobbers(A,X) -> () = $bc0f ; copy fac1 to fac2
asmsub MOVMF (uword mflpt @ XY) -> clobbers(A,Y) -> () = $bbd4 ; store fac1 to memory X/Y as 5-byte mflpt
asmsub MOVFM (uword mflpt @ AY) clobbers(A,Y) = $bba2 ; load mflpt value from memory in A/Y into fac1
asmsub FREADMEM () clobbers(A,Y) = $bba6 ; load mflpt value from memory in $22/$23 into fac1
asmsub CONUPK (uword mflpt @ AY) clobbers(A,Y) = $ba8c ; load mflpt value from memory in A/Y into fac2
asmsub FAREADMEM () clobbers(A,Y) = $ba90 ; load mflpt value from memory in $22/$23 into fac2
asmsub MOVFA () clobbers(A,X) = $bbfc ; copy fac2 to fac1
asmsub MOVAF () clobbers(A,X) = $bc0c ; copy fac1 to fac2 (rounded)
asmsub MOVEF () clobbers(A,X) = $bc0f ; copy fac1 to fac2
asmsub MOVMF (uword mflpt @ XY) clobbers(A,Y) = $bbd4 ; store fac1 to memory X/Y as 5-byte mflpt
; fac1-> signed word in Y/A (might throw ILLEGAL QUANTITY)
; (tip: use c64flt.FTOSWRDAY to get A/Y output; lo/hi switched to normal little endian order)
asmsub FTOSWORDYA () -> clobbers(X) -> (ubyte @ Y, ubyte @ A) = $b1aa
asmsub FTOSWORDYA () clobbers(X) -> (ubyte @ Y, ubyte @ A) = $b1aa
; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15)
; (tip: use c64flt.GETADRAY to get A/Y output; lo/hi switched to normal little endian order)
asmsub GETADR () -> clobbers(X) -> (ubyte @ Y, ubyte @ A) = $b7f7
asmsub GETADR () clobbers(X) -> (ubyte @ Y, ubyte @ A) = $b7f7
asmsub QINT () -> clobbers(A,X,Y) -> () = $bc9b ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST.
asmsub AYINT () -> clobbers(A,X,Y) -> () = $b1bf ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY)
asmsub QINT () clobbers(A,X,Y) = $bc9b ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST.
asmsub AYINT () clobbers(A,X,Y) = $b1bf ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY)
; GIVAYF: signed word in Y/A (note different lsb/msb order) -> float in fac1
; (tip: use c64flt.GIVAYFAY to use A/Y input; lo/hi switched to normal order)
@ -67,50 +67,50 @@ asmsub AYINT () -> clobbers(A,X,Y) -> () = $b1bf ; fac1-> signed word in 100
; there is also c64flt.FREADS32 that reads from 98-101 ($62-$65) MSB FIRST
; there is also c64flt.FREADUS32 that reads from 98-101 ($62-$65) MSB FIRST
; there is also c64flt.FREADS24AXY that reads signed int24 into fac1 from A/X/Y (lo/mid/hi bytes)
asmsub GIVAYF (ubyte lo @ Y, ubyte hi @ A) -> clobbers(A,X,Y) -> () = $b391
asmsub GIVAYF (ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) = $b391
asmsub FREADUY (ubyte value @ Y) -> clobbers(A,X,Y) -> () = $b3a2 ; 8 bit unsigned Y -> float in fac1
asmsub FREADSA (byte value @ A) -> clobbers(A,X,Y) -> () = $bc3c ; 8 bit signed A -> float in fac1
asmsub FREADSTR (ubyte length @ A) -> clobbers(A,X,Y) -> () = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length
asmsub FPRINTLN () -> clobbers(A,X,Y) -> () = $aabc ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well)
asmsub FOUT () -> clobbers(X) -> (uword @ AY) = $bddd ; fac1 -> string, address returned in AY ($0100)
asmsub FREADUY (ubyte value @ Y) clobbers(A,X,Y) = $b3a2 ; 8 bit unsigned Y -> float in fac1
asmsub FREADSA (byte value @ A) clobbers(A,X,Y) = $bc3c ; 8 bit signed A -> float in fac1
asmsub FREADSTR (ubyte length @ A) clobbers(A,X,Y) = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length
asmsub FPRINTLN () clobbers(A,X,Y) = $aabc ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well)
asmsub FOUT () clobbers(X) -> (uword @ AY) = $bddd ; fac1 -> string, address returned in AY ($0100)
asmsub FADDH () -> clobbers(A,X,Y) -> () = $b849 ; fac1 += 0.5, for rounding- call this before INT
asmsub MUL10 () -> clobbers(A,X,Y) -> () = $bae2 ; fac1 *= 10
asmsub DIV10 () -> clobbers(A,X,Y) -> () = $bafe ; fac1 /= 10 , CAUTION: result is always positive!
asmsub FCOMP (uword mflpt @ AY) -> clobbers(X,Y) -> (ubyte @ A) = $bc5b ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than
asmsub FADDH () clobbers(A,X,Y) = $b849 ; fac1 += 0.5, for rounding- call this before INT
asmsub MUL10 () clobbers(A,X,Y) = $bae2 ; fac1 *= 10
asmsub DIV10 () clobbers(A,X,Y) = $bafe ; fac1 /= 10 , CAUTION: result is always positive!
asmsub FCOMP (uword mflpt @ AY) clobbers(X,Y) -> (ubyte @ A) = $bc5b ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than
asmsub FADDT () -> clobbers(A,X,Y) -> () = $b86a ; fac1 += fac2
asmsub FADD (uword mflpt @ AY) -> clobbers(A,X,Y) -> () = $b867 ; fac1 += mflpt value from A/Y
asmsub FSUBT () -> clobbers(A,X,Y) -> () = $b853 ; fac1 = fac2-fac1 mind the order of the operands
asmsub FSUB (uword mflpt @ AY) -> clobbers(A,X,Y) -> () = $b850 ; fac1 = mflpt from A/Y - fac1
asmsub FMULTT () -> clobbers(A,X,Y) -> () = $ba2b ; fac1 *= fac2
asmsub FMULT (uword mflpt @ AY) -> clobbers(A,X,Y) -> () = $ba28 ; fac1 *= mflpt value from A/Y
asmsub FDIVT () -> clobbers(A,X,Y) -> () = $bb12 ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands
asmsub FDIV (uword mflpt @ AY) -> clobbers(A,X,Y) -> () = $bb0f ; fac1 = mflpt in A/Y / fac1 (remainder in fac2)
asmsub FPWRT () -> clobbers(A,X,Y) -> () = $bf7b ; fac1 = fac2 ** fac1
asmsub FPWR (uword mflpt @ AY) -> clobbers(A,X,Y) -> () = $bf78 ; fac1 = fac2 ** mflpt from A/Y
asmsub FADDT () clobbers(A,X,Y) = $b86a ; fac1 += fac2
asmsub FADD (uword mflpt @ AY) clobbers(A,X,Y) = $b867 ; fac1 += mflpt value from A/Y
asmsub FSUBT () clobbers(A,X,Y) = $b853 ; fac1 = fac2-fac1 mind the order of the operands
asmsub FSUB (uword mflpt @ AY) clobbers(A,X,Y) = $b850 ; fac1 = mflpt from A/Y - fac1
asmsub FMULTT () clobbers(A,X,Y) = $ba2b ; fac1 *= fac2
asmsub FMULT (uword mflpt @ AY) clobbers(A,X,Y) = $ba28 ; fac1 *= mflpt value from A/Y
asmsub FDIVT () clobbers(A,X,Y) = $bb12 ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands
asmsub FDIV (uword mflpt @ AY) clobbers(A,X,Y) = $bb0f ; fac1 = mflpt in A/Y / fac1 (remainder in fac2)
asmsub FPWRT () clobbers(A,X,Y) = $bf7b ; fac1 = fac2 ** fac1
asmsub FPWR (uword mflpt @ AY) clobbers(A,X,Y) = $bf78 ; fac1 = fac2 ** mflpt from A/Y
asmsub NOTOP () -> clobbers(A,X,Y) -> () = $aed4 ; fac1 = NOT(fac1)
asmsub INT () -> clobbers(A,X,Y) -> () = $bccc ; INT() truncates, use FADDH first to round instead of trunc
asmsub LOG () -> clobbers(A,X,Y) -> () = $b9ea ; fac1 = LN(fac1) (natural log)
asmsub SGN () -> clobbers(A,X,Y) -> () = $bc39 ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1)
asmsub SIGN () -> clobbers() -> (ubyte @ A) = $bc2b ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive
asmsub ABS () -> clobbers() -> () = $bc58 ; fac1 = ABS(fac1)
asmsub SQR () -> clobbers(A,X,Y) -> () = $bf71 ; fac1 = SQRT(fac1)
asmsub SQRA () -> clobbers(A,X,Y) -> () = $bf74 ; fac1 = SQRT(fac2)
asmsub EXP () -> clobbers(A,X,Y) -> () = $bfed ; fac1 = EXP(fac1) (e ** fac1)
asmsub NEGOP () -> clobbers(A) -> () = $bfb4 ; switch the sign of fac1
asmsub RND () -> clobbers(A,X,Y) -> () = $e097 ; fac1 = RND(fac1) float random number generator
asmsub COS () -> clobbers(A,X,Y) -> () = $e264 ; fac1 = COS(fac1)
asmsub SIN () -> clobbers(A,X,Y) -> () = $e26b ; fac1 = SIN(fac1)
asmsub TAN () -> clobbers(A,X,Y) -> () = $e2b4 ; fac1 = TAN(fac1)
asmsub ATN () -> clobbers(A,X,Y) -> () = $e30e ; fac1 = ATN(fac1)
asmsub NOTOP () clobbers(A,X,Y) = $aed4 ; fac1 = NOT(fac1)
asmsub INT () clobbers(A,X,Y) = $bccc ; INT() truncates, use FADDH first to round instead of trunc
asmsub LOG () clobbers(A,X,Y) = $b9ea ; fac1 = LN(fac1) (natural log)
asmsub SGN () clobbers(A,X,Y) = $bc39 ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1)
asmsub SIGN () -> (ubyte @ A) = $bc2b ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive
asmsub ABS () = $bc58 ; fac1 = ABS(fac1)
asmsub SQR () clobbers(A,X,Y) = $bf71 ; fac1 = SQRT(fac1)
asmsub SQRA () clobbers(A,X,Y) = $bf74 ; fac1 = SQRT(fac2)
asmsub EXP () clobbers(A,X,Y) = $bfed ; fac1 = EXP(fac1) (e ** fac1)
asmsub NEGOP () clobbers(A) = $bfb4 ; switch the sign of fac1
asmsub RND () clobbers(A,X,Y) = $e097 ; fac1 = RND(fac1) float random number generator
asmsub COS () clobbers(A,X,Y) = $e264 ; fac1 = COS(fac1)
asmsub SIN () clobbers(A,X,Y) = $e26b ; fac1 = SIN(fac1)
asmsub TAN () clobbers(A,X,Y) = $e2b4 ; fac1 = TAN(fac1)
asmsub ATN () clobbers(A,X,Y) = $e30e ; fac1 = ATN(fac1)
asmsub FREADS32 () -> clobbers(A,X,Y) -> () {
asmsub FREADS32 () clobbers(A,X,Y) {
; ---- fac1 = signed int32 from $62-$65 big endian (MSB FIRST)
%asm {{
lda $62
@ -122,7 +122,7 @@ asmsub FREADS32 () -> clobbers(A,X,Y) -> () {
}}
}
asmsub FREADUS32 () -> clobbers(A,X,Y) -> () {
asmsub FREADUS32 () clobbers(A,X,Y) {
; ---- fac1 = uint32 from $62-$65 big endian (MSB FIRST)
%asm {{
sec
@ -132,7 +132,7 @@ asmsub FREADUS32 () -> clobbers(A,X,Y) -> () {
}}
}
asmsub FREADS24AXY (ubyte lo @ A, ubyte mid @ X, ubyte hi @ Y) -> clobbers(A,X,Y) -> () {
asmsub FREADS24AXY (ubyte lo @ A, ubyte mid @ X, ubyte hi @ Y) clobbers(A,X,Y) {
; ---- fac1 = signed int24 (A/X/Y contain lo/mid/hi bytes)
; note: there is no FREADU24AXY (unsigned), use FREADUS32 instead.
%asm {{
@ -149,7 +149,7 @@ asmsub FREADS24AXY (ubyte lo @ A, ubyte mid @ X, ubyte hi @ Y) -> clobbers(A,X
}}
}
asmsub GIVUAYFAY (uword value @ AY) -> clobbers(A,X,Y) -> () {
asmsub GIVUAYFAY (uword value @ AY) clobbers(A,X,Y) {
; ---- unsigned 16 bit word in A/Y (lo/hi) to fac1
%asm {{
sty $62
@ -160,7 +160,7 @@ asmsub GIVUAYFAY (uword value @ AY) -> clobbers(A,X,Y) -> () {
}}
}
asmsub GIVAYFAY (uword value @ AY) -> clobbers(A,X,Y) -> () {
asmsub GIVAYFAY (uword value @ AY) clobbers(A,X,Y) {
; ---- signed 16 bit word in A/Y (lo/hi) to float in fac1
%asm {{
sta c64.SCRATCH_ZPREG
@ -170,7 +170,7 @@ asmsub GIVAYFAY (uword value @ AY) -> clobbers(A,X,Y) -> () {
}}
}
asmsub FTOSWRDAY () -> clobbers(X) -> (uword @ AY) {
asmsub FTOSWRDAY () clobbers(X) -> (uword @ AY) {
; ---- fac1 to signed word in A/Y
%asm {{
jsr FTOSWORDYA ; note the inverse Y/A order
@ -181,7 +181,7 @@ asmsub FTOSWRDAY () -> clobbers(X) -> (uword @ AY) {
}}
}
asmsub GETADRAY () -> clobbers(X) -> (uword @ AY) {
asmsub GETADRAY () clobbers(X) -> (uword @ AY) {
; ---- fac1 to unsigned word in A/Y
%asm {{
jsr GETADR ; this uses the inverse order, Y/A

View File

@ -63,8 +63,8 @@
&ubyte SP6Y = $d00d
&ubyte SP7X = $d00e
&ubyte SP7Y = $d00f
&ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array.
&uword[8] SPXYW = $d000 ; the 8 sprite X and Y registers as a combined xy word array.
&ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array.
&uword[8] SPXYW = $d000 ; the 8 sprite X and Y registers as a combined xy word array.
&ubyte MSIGX = $d010
&ubyte SCROLY = $d011
@ -76,7 +76,7 @@
&ubyte YXPAND = $d017
&ubyte VMCSB = $d018
&ubyte VICIRQ = $d019
&ubyte IREQMASK = $d01a
&ubyte IREQMASK = $d01a
&ubyte SPBGPR = $d01b
&ubyte SPMC = $d01c
&ubyte XXPAND = $d01d
@ -98,7 +98,7 @@
&ubyte SP5COL = $d02c
&ubyte SP6COL = $d02d
&ubyte SP7COL = $d02e
&ubyte[8] SPCOL = $d027
&ubyte[8] SPCOL = $d027
; ---- end of VIC-II registers ----
@ -107,8 +107,8 @@
&ubyte CIA1PRA = $DC00 ; CIA 1 DRA, keyboard column drive (and joystick control port #2)
&ubyte CIA1PRB = $DC01 ; CIA 1 DRB, keyboard row port (and joystick control port #1)
&ubyte CIA1DDRA = $DC02 ; CIA 1 DDRA, keyboard column
&ubyte CIA1DDRB = $DC03 ; CIA 1 DDRB, keyboard row
&ubyte CIA1DDRA = $DC02 ; CIA 1 DDRA, keyboard column
&ubyte CIA1DDRB = $DC03 ; CIA 1 DDRB, keyboard row
&ubyte CIA1TAL = $DC04 ; CIA 1 timer A low byte
&ubyte CIA1TAH = $DC05 ; CIA 1 timer A high byte
&ubyte CIA1TBL = $DC06 ; CIA 1 timer B low byte
@ -124,8 +124,8 @@
&ubyte CIA2PRA = $DD00 ; CIA 2 DRA, serial port and video address
&ubyte CIA2PRB = $DD01 ; CIA 2 DRB, RS232 port / USERPORT
&ubyte CIA2DDRA = $DD02 ; CIA 2 DDRA, serial port and video address
&ubyte CIA2DDRB = $DD03 ; CIA 2 DDRB, RS232 port / USERPORT
&ubyte CIA2DDRA = $DD02 ; CIA 2 DDRA, serial port and video address
&ubyte CIA2DDRB = $DD03 ; CIA 2 DDRB, RS232 port / USERPORT
&ubyte CIA2TAL = $DD04 ; CIA 2 timer A low byte
&ubyte CIA2TAH = $DD05 ; CIA 2 timer A high byte
&ubyte CIA2TBL = $DD06 ; CIA 2 timer B low byte
@ -186,8 +186,8 @@
; ---- C64 basic routines ----
asmsub CLEARSCR () -> clobbers(A,X,Y) -> () = $E544 ; clear the screen
asmsub HOMECRSR () -> clobbers(A,X,Y) -> () = $E566 ; cursor to top left of screen
asmsub CLEARSCR () clobbers(A,X,Y) = $E544 ; clear the screen
asmsub HOMECRSR () clobbers(A,X,Y) = $E566 ; cursor to top left of screen
; ---- end of C64 basic routines ----
@ -195,48 +195,48 @@ asmsub HOMECRSR () -> clobbers(A,X,Y) -> () = $E566 ; cursor to top left of sc
; ---- C64 kernal routines ----
asmsub STROUT (uword strptr @ AY) -> clobbers(A, X, Y) -> () = $AB1E ; print null-terminated string (use c64scr.print instead)
asmsub IRQDFRT () -> clobbers(A,X,Y) -> () = $EA31 ; default IRQ routine
asmsub IRQDFEND () -> clobbers(A,X,Y) -> () = $EA81 ; default IRQ end/cleanup
asmsub CINT () -> clobbers(A,X,Y) -> () = $FF81 ; (alias: SCINIT) initialize screen editor and video chip
asmsub IOINIT () -> clobbers(A, X) -> () = $FF84 ; initialize I/O devices (CIA, SID, IRQ)
asmsub RAMTAS () -> clobbers(A,X,Y) -> () = $FF87 ; initialize RAM, tape buffer, screen
asmsub RESTOR () -> clobbers(A,X,Y) -> () = $FF8A ; restore default I/O vectors
asmsub VECTOR (ubyte dir @ Pc, uword userptr @ XY) -> clobbers(A,Y) -> () = $FF8D ; read/set I/O vector table
asmsub SETMSG (ubyte value @ A) -> clobbers() -> () = $FF90 ; set Kernal message control flag
asmsub SECOND (ubyte address @ A) -> clobbers(A) -> () = $FF93 ; (alias: LSTNSA) send secondary address after LISTEN
asmsub TKSA (ubyte address @ A) -> clobbers(A) -> () = $FF96 ; (alias: TALKSA) send secondary address after TALK
asmsub MEMTOP (ubyte dir @ Pc, uword address @ XY) -> clobbers() -> (uword @ XY) = $FF99 ; read/set top of memory pointer
asmsub MEMBOT (ubyte dir @ Pc, uword address @ XY) -> clobbers() -> (uword @ XY) = $FF9C ; read/set bottom of memory pointer
asmsub SCNKEY () -> clobbers(A,X,Y) -> () = $FF9F ; scan the keyboard
asmsub SETTMO (ubyte timeout @ A) -> clobbers() -> () = $FFA2 ; set time-out flag for IEEE bus
asmsub ACPTR () -> clobbers() -> (ubyte @ A) = $FFA5 ; (alias: IECIN) input byte from serial bus
asmsub CIOUT (ubyte databyte @ A) -> clobbers() -> () = $FFA8 ; (alias: IECOUT) output byte to serial bus
asmsub UNTLK () -> clobbers(A) -> () = $FFAB ; command serial bus device to UNTALK
asmsub UNLSN () -> clobbers(A) -> () = $FFAE ; command serial bus device to UNLISTEN
asmsub LISTEN (ubyte device @ A) -> clobbers(A) -> () = $FFB1 ; command serial bus device to LISTEN
asmsub TALK (ubyte device @ A) -> clobbers(A) -> () = $FFB4 ; command serial bus device to TALK
asmsub READST () -> clobbers() -> (ubyte @ A) = $FFB7 ; read I/O status word
asmsub SETLFS (ubyte logical @ A, ubyte device @ X, ubyte address @ Y) -> clobbers() -> () = $FFBA ; set logical file parameters
asmsub SETNAM (ubyte namelen @ A, str filename @ XY) -> clobbers() -> () = $FFBD ; set filename parameters
asmsub OPEN () -> clobbers(A,X,Y) -> () = $FFC0 ; (via 794 ($31A)) open a logical file
asmsub CLOSE (ubyte logical @ A) -> clobbers(A,X,Y) -> () = $FFC3 ; (via 796 ($31C)) close a logical file
asmsub CHKIN (ubyte logical @ X) -> clobbers(A,X) -> () = $FFC6 ; (via 798 ($31E)) define an input channel
asmsub CHKOUT (ubyte logical @ X) -> clobbers(A,X) -> () = $FFC9 ; (via 800 ($320)) define an output channel
asmsub CLRCHN () -> clobbers(A,X) -> () = $FFCC ; (via 802 ($322)) restore default devices
asmsub CHRIN () -> clobbers(Y) -> (ubyte @ A) = $FFCF ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read.
asmsub CHROUT (ubyte char @ A) -> clobbers() -> () = $FFD2 ; (via 806 ($326)) output a character
asmsub LOAD (ubyte verify @ A, uword address @ XY) -> clobbers() -> (ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y) = $FFD5 ; (via 816 ($330)) load from device
asmsub SAVE (ubyte zp_startaddr @ A, uword endaddr @ XY) -> clobbers() -> (ubyte @ Pc, ubyte @ A) = $FFD8 ; (via 818 ($332)) save to a device
asmsub SETTIM (ubyte low @ A, ubyte middle @ X, ubyte high @ Y) -> clobbers() -> () = $FFDB ; set the software clock
asmsub RDTIM () -> clobbers() -> (ubyte @ A, ubyte @ X, ubyte @ Y) = $FFDE ; read the software clock
asmsub STOP () -> clobbers(A,X) -> (ubyte @ Pz, ubyte @ Pc) = $FFE1 ; (via 808 ($328)) check the STOP key
asmsub GETIN () -> clobbers(X,Y) -> (ubyte @ A) = $FFE4 ; (via 810 ($32A)) get a character
asmsub CLALL () -> clobbers(A,X) -> () = $FFE7 ; (via 812 ($32C)) close all files
asmsub UDTIM () -> clobbers(A,X) -> () = $FFEA ; update the software clock
asmsub SCREEN () -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFED ; read number of screen rows and columns
asmsub PLOT (ubyte dir @ Pc, ubyte col @ Y, ubyte row @ X) -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFF0 ; read/set position of cursor on screen. Use c64scr.plot for a 'safe' wrapper that preserves X.
asmsub IOBASE () -> clobbers() -> (uword @ XY) = $FFF3 ; read base address of I/O devices
asmsub STROUT (uword strptr @ AY) clobbers(A, X, Y) = $AB1E ; print null-terminated string (use c64scr.print instead)
asmsub IRQDFRT () clobbers(A,X,Y) = $EA31 ; default IRQ routine
asmsub IRQDFEND () clobbers(A,X,Y) = $EA81 ; default IRQ end/cleanup
asmsub CINT () clobbers(A,X,Y) = $FF81 ; (alias: SCINIT) initialize screen editor and video chip
asmsub IOINIT () clobbers(A, X) = $FF84 ; initialize I/O devices (CIA, SID, IRQ)
asmsub RAMTAS () clobbers(A,X,Y) = $FF87 ; initialize RAM, tape buffer, screen
asmsub RESTOR () clobbers(A,X,Y) = $FF8A ; restore default I/O vectors
asmsub VECTOR (ubyte dir @ Pc, uword userptr @ XY) clobbers(A,Y) = $FF8D ; read/set I/O vector table
asmsub SETMSG (ubyte value @ A) = $FF90 ; set Kernal message control flag
asmsub SECOND (ubyte address @ A) clobbers(A) = $FF93 ; (alias: LSTNSA) send secondary address after LISTEN
asmsub TKSA (ubyte address @ A) clobbers(A) = $FF96 ; (alias: TALKSA) send secondary address after TALK
asmsub MEMTOP (ubyte dir @ Pc, uword address @ XY) -> uword @ XY = $FF99 ; read/set top of memory pointer
asmsub MEMBOT (ubyte dir @ Pc, uword address @ XY) -> uword @ XY = $FF9C ; read/set bottom of memory pointer
asmsub SCNKEY () clobbers(A,X,Y) = $FF9F ; scan the keyboard
asmsub SETTMO (ubyte timeout @ A) = $FFA2 ; set time-out flag for IEEE bus
asmsub ACPTR () -> ubyte @ A = $FFA5 ; (alias: IECIN) input byte from serial bus
asmsub CIOUT (ubyte databyte @ A) = $FFA8 ; (alias: IECOUT) output byte to serial bus
asmsub UNTLK () clobbers(A) = $FFAB ; command serial bus device to UNTALK
asmsub UNLSN () clobbers(A) = $FFAE ; command serial bus device to UNLISTEN
asmsub LISTEN (ubyte device @ A) clobbers(A) = $FFB1 ; command serial bus device to LISTEN
asmsub TALK (ubyte device @ A) clobbers(A) = $FFB4 ; command serial bus device to TALK
asmsub READST () -> ubyte @ A = $FFB7 ; read I/O status word
asmsub SETLFS (ubyte logical @ A, ubyte device @ X, ubyte address @ Y) = $FFBA ; set logical file parameters
asmsub SETNAM (ubyte namelen @ A, str filename @ XY) = $FFBD ; set filename parameters
asmsub OPEN () clobbers(A,X,Y) = $FFC0 ; (via 794 ($31A)) open a logical file
asmsub CLOSE (ubyte logical @ A) clobbers(A,X,Y) = $FFC3 ; (via 796 ($31C)) close a logical file
asmsub CHKIN (ubyte logical @ X) clobbers(A,X) = $FFC6 ; (via 798 ($31E)) define an input channel
asmsub CHKOUT (ubyte logical @ X) clobbers(A,X) = $FFC9 ; (via 800 ($320)) define an output channel
asmsub CLRCHN () clobbers(A,X) = $FFCC ; (via 802 ($322)) restore default devices
asmsub CHRIN () clobbers(Y) -> ubyte @ A = $FFCF ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read.
asmsub CHROUT (ubyte char @ A) = $FFD2 ; (via 806 ($326)) output a character
asmsub LOAD (ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y = $FFD5 ; (via 816 ($330)) load from device
asmsub SAVE (ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A = $FFD8 ; (via 818 ($332)) save to a device
asmsub SETTIM (ubyte low @ A, ubyte middle @ X, ubyte high @ Y) = $FFDB ; set the software clock
asmsub RDTIM () -> ubyte @ A, ubyte @ X, ubyte @ Y = $FFDE ; read the software clock
asmsub STOP () clobbers(A,X) -> ubyte @ Pz, ubyte @ Pc = $FFE1 ; (via 808 ($328)) check the STOP key
asmsub GETIN () clobbers(X,Y) -> ubyte @ A = $FFE4 ; (via 810 ($32A)) get a character
asmsub CLALL () clobbers(A,X) = $FFE7 ; (via 812 ($32C)) close all files
asmsub UDTIM () clobbers(A,X) = $FFEA ; update the software clock
asmsub SCREEN () -> ubyte @ X, ubyte @ Y = $FFED ; read number of screen rows and columns
asmsub PLOT (ubyte dir @ Pc, ubyte col @ Y, ubyte row @ X) -> ubyte @ X, ubyte @ Y = $FFF0 ; read/set position of cursor on screen. Use c64scr.plot for a 'safe' wrapper that preserves X.
asmsub IOBASE () -> uword @ XY = $FFF3 ; read base address of I/O devices
; ---- end of C64 kernal routines ----

View File

@ -17,7 +17,7 @@
; ----- utility functions ----
asmsub ubyte2decimal (ubyte value @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X, ubyte @ A) {
asmsub ubyte2decimal (ubyte value @ A) -> ubyte @ Y, ubyte @ X, ubyte @ A {
; ---- A to decimal string in Y/X/A (100s in Y, 10s in X, 1s in A)
%asm {{
ldy #$2f
@ -34,7 +34,7 @@ asmsub ubyte2decimal (ubyte value @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X,
}}
}
asmsub byte2decimal (ubyte value @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X, ubyte @ A) {
asmsub byte2decimal (ubyte value @ A) -> ubyte @ Y, ubyte @ X, ubyte @ A {
; ---- A (signed byte) to decimal string in Y/X/A (100s in Y, 10s in X, 1s in A)
; note: the '-' is not part of the conversion here if it's a negative number
%asm {{
@ -47,7 +47,7 @@ asmsub byte2decimal (ubyte value @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X,
}}
}
asmsub ubyte2hex (ubyte value @ A) -> clobbers() -> (ubyte @ A, ubyte @ Y) {
asmsub ubyte2hex (ubyte value @ A) -> ubyte @ A, ubyte @ Y {
; ---- A to hex string in AY (first hex char in A, second hex char in Y)
%asm {{
stx c64.SCRATCH_ZPREGX
@ -70,7 +70,7 @@ _hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as
}
asmsub uword2hex (uword value @ AY) -> clobbers(A,Y) -> () {
asmsub uword2hex (uword value @ AY) clobbers(A,Y) {
; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string 'uword2hex.output' (0-terminated)
%asm {{
sta c64.SCRATCH_ZPREG
@ -87,7 +87,7 @@ output .text "0000", $00 ; 0-terminated output buffer (to make printing ea
}}
}
asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
asmsub uword2bcd (uword value @ AY) clobbers(A,Y) {
; Convert an 16 bit binary value to BCD
;
; This function converts a 16 bit binary value in A/Y into a 24 bit BCD. It
@ -134,7 +134,7 @@ bcdbuff .byte 0,0,0
}
asmsub uword2decimal (uword value @ AY) -> clobbers(A) -> (ubyte @ Y) {
asmsub uword2decimal (uword value @ AY) clobbers(A) -> ubyte @ Y {
; ---- convert 16 bit uword in A/Y into 0-terminated decimal string into memory 'uword2decimal.output'
; returns length of resulting string in Y
%asm {{
@ -173,7 +173,7 @@ output .text "00000", $00 ; 0 terminated
}
asmsub str2uword(str string @ AY) -> clobbers() -> (uword @ AY) {
asmsub str2uword(str string @ AY) -> uword @ AY {
; -- returns the unsigned word value of the string number argument in AY
; the number may NOT be preceded by a + sign and may NOT contain spaces
; (any non-digit character will terminate the number string that is parsed)
@ -228,7 +228,7 @@ _result_times_10 ; (W*4 + W)*2
}
asmsub str2word(str string @ AY) -> clobbers() -> (word @ AY) {
asmsub str2word(str string @ AY) -> word @ AY {
; -- returns the signed word value of the string number argument in AY
; the number may be preceded by a + or - sign but may NOT contain spaces
; (any non-digit character will terminate the number string that is parsed)
@ -284,7 +284,7 @@ _negative .byte 0
}
asmsub set_irqvec_excl() -> clobbers(A) -> () {
asmsub set_irqvec_excl() clobbers(A) {
%asm {{
sei
lda #<_irq_handler
@ -303,7 +303,7 @@ _irq_handler jsr set_irqvec._irq_handler_init
}}
}
asmsub set_irqvec() -> clobbers(A) -> () {
asmsub set_irqvec() clobbers(A) {
%asm {{
sei
lda #<_irq_handler
@ -373,7 +373,7 @@ IRQ_SCRATCH_ZPWORD2 .word 0
}
asmsub restore_irqvec() -> clobbers() -> () {
asmsub restore_irqvec() {
%asm {{
sei
lda #<c64.IRQDFRT
@ -390,7 +390,7 @@ asmsub restore_irqvec() -> clobbers() -> () {
}
asmsub set_rasterirq(uword rasterpos @ AY) -> clobbers(A) -> () {
asmsub set_rasterirq(uword rasterpos @ AY) clobbers(A) {
%asm {{
sei
jsr _setup_raster_irq
@ -431,7 +431,7 @@ _setup_raster_irq
}}
}
asmsub set_rasterirq_excl(uword rasterpos @ AY) -> clobbers(A) -> () {
asmsub set_rasterirq_excl(uword rasterpos @ AY) clobbers(A) {
%asm {{
sei
jsr set_rasterirq._setup_raster_irq
@ -465,7 +465,7 @@ _raster_irq_handler
; ---- this block contains (character) Screen and text I/O related functions ----
asmsub clear_screen (ubyte char @ A, ubyte color @ Y) -> clobbers(A) -> () {
asmsub clear_screen (ubyte char @ A, ubyte color @ Y) clobbers(A) {
; ---- clear the character screen with the given fill character and character color.
; (assumes screen and color matrix are at their default addresses)
@ -481,7 +481,7 @@ asmsub clear_screen (ubyte char @ A, ubyte color @ Y) -> clobbers(A) -> () {
}
asmsub clear_screenchars (ubyte char @ A) -> clobbers(Y) -> () {
asmsub clear_screenchars (ubyte char @ A) clobbers(Y) {
; ---- clear the character screen with the given fill character (leaves colors)
; (assumes screen matrix is at the default address)
%asm {{
@ -501,7 +501,7 @@ _loop sta c64.Screen,y
}}
}
asmsub clear_screencolors (ubyte color @ A) -> clobbers(Y) -> () {
asmsub clear_screencolors (ubyte color @ A) clobbers(Y) {
; ---- clear the character screen colors with the given color (leaves characters).
; (assumes color matrix is at the default address)
%asm {{
@ -522,7 +522,7 @@ _loop sta c64.Colors,y
}
asmsub scroll_left_full (ubyte alsocolors @ Pc) -> clobbers(A, Y) -> () {
asmsub scroll_left_full (ubyte alsocolors @ Pc) clobbers(A, Y) {
; ---- scroll the whole screen 1 character to the left
; contents of the rightmost column are unchanged, you should clear/refill this yourself
; Carry flag determines if screen color data must be scrolled too
@ -583,7 +583,7 @@ _scroll_screen ; scroll the screen memory
}
asmsub scroll_right_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
asmsub scroll_right_full (ubyte alsocolors @ Pc) clobbers(A) {
; ---- scroll the whole screen 1 character to the right
; contents of the leftmost column are unchanged, you should clear/refill this yourself
; Carry flag determines if screen color data must be scrolled too
@ -636,7 +636,7 @@ _scroll_screen ; scroll the screen memory
}
asmsub scroll_up_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
asmsub scroll_up_full (ubyte alsocolors @ Pc) clobbers(A) {
; ---- scroll the whole screen 1 character up
; contents of the bottom row are unchanged, you should refill/clear this yourself
; Carry flag determines if screen color data must be scrolled too
@ -689,7 +689,7 @@ _scroll_screen ; scroll the screen memory
}
asmsub scroll_down_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
asmsub scroll_down_full (ubyte alsocolors @ Pc) clobbers(A) {
; ---- scroll the whole screen 1 character down
; contents of the top row are unchanged, you should refill/clear this yourself
; Carry flag determines if screen color data must be scrolled too
@ -743,7 +743,7 @@ _scroll_screen ; scroll the screen memory
asmsub print (str text @ AY) -> clobbers(A,Y) -> () {
asmsub print (str text @ AY) clobbers(A,Y) {
; ---- print null terminated string from A/Y
; note: the compiler contains an optimization that will replace
; a call to this subroutine with a string argument of just one char,
@ -762,7 +762,7 @@ asmsub print (str text @ AY) -> clobbers(A,Y) -> () {
}
asmsub print_ub0 (ubyte value @ A) -> clobbers(A,Y) -> () {
asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) {
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
%asm {{
stx c64.SCRATCH_ZPREGX
@ -780,7 +780,7 @@ asmsub print_ub0 (ubyte value @ A) -> clobbers(A,Y) -> () {
}
asmsub print_ub (ubyte value @ A) -> clobbers(A,Y) -> () {
asmsub print_ub (ubyte value @ A) clobbers(A,Y) {
; ---- print the ubyte in A in decimal form, without left padding 0s
%asm {{
stx c64.SCRATCH_ZPREGX
@ -803,7 +803,7 @@ _end pla
}}
}
asmsub print_b (byte value @ A) -> clobbers(A,Y) -> () {
asmsub print_b (byte value @ A) clobbers(A,Y) {
; ---- print the byte in A in decimal form, without left padding 0s
%asm {{
stx c64.SCRATCH_ZPREGX
@ -821,7 +821,7 @@ asmsub print_b (byte value @ A) -> clobbers(A,Y) -> () {
}
asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,Y) -> () {
asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) clobbers(A,Y) {
; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
%asm {{
stx c64.SCRATCH_ZPREGX
@ -840,7 +840,7 @@ asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,Y) -> ()
}
asmsub print_ubbin (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,Y) ->() {
asmsub print_ubbin (ubyte prefix @ Pc, ubyte value @ A) clobbers(A,Y) {
; ---- print the ubyte in A in binary form (if Carry is set, a radix prefix '%' is printed as well)
%asm {{
stx c64.SCRATCH_ZPREGX
@ -862,7 +862,7 @@ asmsub print_ubbin (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,Y) ->()
}
asmsub print_uwbin (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,Y) ->() {
asmsub print_uwbin (ubyte prefix @ Pc, uword value @ AY) clobbers(A,Y) {
; ---- print the uword in A/Y in binary form (if Carry is set, a radix prefix '%' is printed as well)
%asm {{
pha
@ -875,7 +875,7 @@ asmsub print_uwbin (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,Y) ->()
}
asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,Y) -> () {
asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) clobbers(A,Y) {
; ---- print the uword in A/Y in hexadecimal form (4 digits)
; (if Carry is set, a radix prefix '$' is printed as well)
%asm {{
@ -889,7 +889,7 @@ asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,Y) -> ()
}
asmsub print_uw0 (uword value @ AY) -> clobbers(A,Y) -> () {
asmsub print_uw0 (uword value @ AY) clobbers(A,Y) {
; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
%asm {{
jsr c64utils.uword2decimal
@ -904,7 +904,7 @@ asmsub print_uw0 (uword value @ AY) -> clobbers(A,Y) -> () {
}
asmsub print_uw (uword value @ AY) -> clobbers(A,Y) -> () {
asmsub print_uw (uword value @ AY) clobbers(A,Y) {
; ---- print the uword in A/Y in decimal form, without left padding 0s
%asm {{
jsr c64utils.uword2decimal
@ -936,7 +936,7 @@ _pr_decimal
}}
}
asmsub print_w (word value @ AY) -> clobbers(A,Y) -> () {
asmsub print_w (word value @ AY) clobbers(A,Y) {
; ---- print the (signed) word in A/Y in decimal form, without left padding 0's
%asm {{
cpy #0
@ -957,7 +957,7 @@ asmsub print_w (word value @ AY) -> clobbers(A,Y) -> () {
}}
}
asmsub input_chars (uword buffer @ AY) -> clobbers(A) -> (ubyte @ Y) {
asmsub input_chars (uword buffer @ AY) clobbers(A) -> ubyte @ Y {
; ---- Input a string (max. 80 chars) from the keyboard. Returns length in Y. (string is terminated with a 0 byte as well)
; It assumes the keyboard is selected as I/O channel!
@ -978,7 +978,7 @@ asmsub input_chars (uword buffer @ AY) -> clobbers(A) -> (ubyte @ Y) {
}}
}
asmsub setchr (ubyte col @Y, ubyte row @A) -> clobbers(A) -> () {
asmsub setchr (ubyte col @Y, ubyte row @A) clobbers(A) {
; ---- set the character in SCRATCH_ZPB1 on the screen matrix at the given position
%asm {{
sty c64.SCRATCH_ZPREG
@ -1000,7 +1000,7 @@ _screenrows .word $0400 + range(0, 1000, 40)
}}
}
asmsub getchr (ubyte col @Y, ubyte row @A) -> clobbers(Y) -> (ubyte @ A) {
asmsub getchr (ubyte col @Y, ubyte row @A) clobbers(Y) -> ubyte @ A {
; ---- get the character in the screen matrix at the given location
%asm {{
sty c64.SCRATCH_ZPB1
@ -1019,7 +1019,7 @@ _mod lda $ffff ; modified
}}
}
asmsub setclr (ubyte col @Y, ubyte row @A) -> clobbers(A) -> () {
asmsub setclr (ubyte col @Y, ubyte row @A) clobbers(A) {
; ---- set the color in SCRATCH_ZPB1 on the screen matrix at the given position
%asm {{
sty c64.SCRATCH_ZPREG
@ -1041,7 +1041,7 @@ _colorrows .word $d800 + range(0, 1000, 40)
}}
}
asmsub getclr (ubyte col @Y, ubyte row @A) -> clobbers(Y) -> (ubyte @ A) {
asmsub getclr (ubyte col @Y, ubyte row @A) clobbers(Y) -> ubyte @ A {
; ---- get the color in the screen color matrix at the given location
%asm {{
sty c64.SCRATCH_ZPB1
@ -1086,7 +1086,7 @@ _colormod sta $ffff ; modified
}}
}
asmsub plot (ubyte col @ Y, ubyte row @ A) -> clobbers(A) -> () {
asmsub plot (ubyte col @ Y, ubyte row @ A) clobbers(A) {
; ---- safe wrapper around PLOT kernel routine, to save the X register.
%asm {{
stx c64.SCRATCH_ZPREGX

View File

@ -187,7 +187,7 @@ private fun prog8Parser.AsmsubroutineContext.toAst(): IStatement {
val normalReturnvalues = returns.map { it.type }
val paramRegisters = params.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag, it.stack) }
val returnRegisters = returns.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag, it.stack) }
val clobbers = clobber()?.toAst() ?: emptySet()
val clobbers = asmsub_clobbers()?.clobber()?.toAst() ?: emptySet()
val statements = statement_block()?.toAst() ?: mutableListOf()
return Subroutine(name, normalParameters, normalReturnvalues,
paramRegisters, returnRegisters, clobbers, address, true, statements, toPosition())

View File

@ -86,7 +86,7 @@ fun compileProgram(filepath: Path,
programAst.checkValid(compilerOptions) // check if final tree is valid
programAst.checkRecursion() // check if there are recursive subroutine calls
printAst(programAst)
// printAst(programAst)
// namespace.debugPrint()
// compile the syntax tree into stackvmProg form, and optimize that

View File

@ -71,18 +71,23 @@ internal class StatementOptimizer(private val program: Program, private val opti
val inlined = AnonymousScope(sub.statements.toMutableList(), caller.position)
parent.statements[parent.statements.indexOf(caller)] = inlined
// replace return statements in the inlined sub by a jump to the end of it
var haveNewEndLabel = false
var endLabelUsed = false
var endlabel = inlined.statements.last() as? Label
if(endlabel==null) {
endlabel = makeLabel("_prog8_auto_sub_end", inlined.statements.last().position)
inlined.statements.add(endlabel)
endlabel.parent = inlined
haveNewEndLabel = true
}
val returns = inlined.statements.withIndex().filter { iv -> iv.value is Return }.map { iv -> Pair(iv.index, iv.value as Return)}
for(returnIdx in returns) {
assert(returnIdx.second.values.isEmpty())
val jump = Jump(null, IdentifierReference(listOf(endlabel.name), returnIdx.second.position), null, returnIdx.second.position)
inlined.statements[returnIdx.first] = jump
endLabelUsed = true
}
if(endLabelUsed && haveNewEndLabel)
inlined.statements.add(endlabel)
inlined.linkParents(caller.parent)
sub.calledBy.remove(caller) // if there are no callers left, the sub will be removed automatically later
optimizationsDone++

View File

@ -19,6 +19,8 @@
}
asmsub derp (ubyte arg @ X) -> clobbers(A, X) -> (ubyte @Y) = $a000
asmsub derp2 (ubyte arg @ X) = $a000
asmsub derp1 (ubyte arg @ X) clobbers(A, X) = $a000
asmsub derp (ubyte arg @ X) clobbers(A, X) -> ubyte @Y = $a000
}

View File

@ -244,19 +244,21 @@ sub_params : vardecl (',' EOL? vardecl)* ;
sub_returns : datatype (',' EOL? datatype)* ;
asmsubroutine :
'asmsub' identifier '(' asmsub_params? ')'
'->' 'clobbers' '(' clobber? ')' '->' '(' asmsub_returns? ')' (asmsub_address | statement_block )
'asmsub' identifier '(' asmsub_params? ')' EOL?
asmsub_clobbers? asmsub_returns? (asmsub_address | statement_block )
;
asmsub_address : '=' address=integerliteral ;
asmsub_params : asmsub_param (',' EOL? asmsub_param)* ;
asmsub_param : vardecl '@' (registerorpair | statusregister | stack='stack');
asmsub_param : vardecl '@' (registerorpair | statusregister | stack='stack') ;
asmsub_clobbers : 'clobbers' '(' clobber? ')' ;
clobber : register (',' register)* ;
asmsub_returns : asmsub_return (',' EOL? asmsub_return)* ;
asmsub_returns : '->' asmsub_return (',' EOL? asmsub_return)* ;
asmsub_return : datatype '@' (registerorpair | statusregister | stack='stack') ;

View File

@ -80,7 +80,7 @@ public class prog8Lexer extends Lexer {
"'step'", "'and'", "'or'", "'xor'", "'not'", "'('", "')'", "'as'", "'@'",
"'return'", "'break'", "'continue'", "'.'", "'A'", "'X'", "'Y'", "'AX'",
"'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'.w'", "'true'", "'false'",
"'%asm'", "'sub'", "'->'", "'{'", "'}'", "'asmsub'", "'clobbers'", "'stack'",
"'%asm'", "'sub'", "'->'", "'{'", "'}'", "'asmsub'", "'stack'", "'clobbers'",
"'if'", "'else'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'if_ne'",
"'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_vc'",
"'for'", "'in'", "'while'", "'repeat'", "'until'", null, null, null,
@ -246,7 +246,7 @@ public class prog8Lexer extends Lexer {
"F\3G\3G\3H\3H\3I\3I\3I\3J\3J\3J\3K\3K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3"+
"O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3"+
"T\3T\3T\3U\3U\3U\3V\3V\3W\3W\3X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3"+
"Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3]"+
"Z\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3]"+
"\3]\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3`\3`\3`\3`\3`\3a\3a\3a\3a\3a"+
"\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d\3d\3e\3e\3e"+
"\3e\3e\3e\3f\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3i"+
@ -315,7 +315,7 @@ public class prog8Lexer extends Lexer {
"\u023c\3\2\2\2\u009d\u023f\3\2\2\2\u009f\u0242\3\2\2\2\u00a1\u0245\3\2"+
"\2\2\u00a3\u024a\3\2\2\2\u00a5\u0250\3\2\2\2\u00a7\u0255\3\2\2\2\u00a9"+
"\u0259\3\2\2\2\u00ab\u025c\3\2\2\2\u00ad\u025e\3\2\2\2\u00af\u0260\3\2"+
"\2\2\u00b1\u0267\3\2\2\2\u00b3\u0270\3\2\2\2\u00b5\u0276\3\2\2\2\u00b7"+
"\2\2\u00b1\u0267\3\2\2\2\u00b3\u026d\3\2\2\2\u00b5\u0276\3\2\2\2\u00b7"+
"\u0279\3\2\2\2\u00b9\u027e\3\2\2\2\u00bb\u0284\3\2\2\2\u00bd\u028a\3\2"+
"\2\2\u00bf\u0290\3\2\2\2\u00c1\u0295\3\2\2\2\u00c3\u029b\3\2\2\2\u00c5"+
"\u02a1\3\2\2\2\u00c7\u02a7\3\2\2\2\u00c9\u02ae\3\2\2\2\u00cb\u02b4\3\2"+
@ -420,11 +420,11 @@ public class prog8Lexer extends Lexer {
"\7/\2\2\u025a\u025b\7@\2\2\u025b\u00aa\3\2\2\2\u025c\u025d\7}\2\2\u025d"+
"\u00ac\3\2\2\2\u025e\u025f\7\177\2\2\u025f\u00ae\3\2\2\2\u0260\u0261\7"+
"c\2\2\u0261\u0262\7u\2\2\u0262\u0263\7o\2\2\u0263\u0264\7u\2\2\u0264\u0265"+
"\7w\2\2\u0265\u0266\7d\2\2\u0266\u00b0\3\2\2\2\u0267\u0268\7e\2\2\u0268"+
"\u0269\7n\2\2\u0269\u026a\7q\2\2\u026a\u026b\7d\2\2\u026b\u026c\7d\2\2"+
"\u026c\u026d\7g\2\2\u026d\u026e\7t\2\2\u026e\u026f\7u\2\2\u026f\u00b2"+
"\3\2\2\2\u0270\u0271\7u\2\2\u0271\u0272\7v\2\2\u0272\u0273\7c\2\2\u0273"+
"\u0274\7e\2\2\u0274\u0275\7m\2\2\u0275\u00b4\3\2\2\2\u0276\u0277\7k\2"+
"\7w\2\2\u0265\u0266\7d\2\2\u0266\u00b0\3\2\2\2\u0267\u0268\7u\2\2\u0268"+
"\u0269\7v\2\2\u0269\u026a\7c\2\2\u026a\u026b\7e\2\2\u026b\u026c\7m\2\2"+
"\u026c\u00b2\3\2\2\2\u026d\u026e\7e\2\2\u026e\u026f\7n\2\2\u026f\u0270"+
"\7q\2\2\u0270\u0271\7d\2\2\u0271\u0272\7d\2\2\u0272\u0273\7g\2\2\u0273"+
"\u0274\7t\2\2\u0274\u0275\7u\2\2\u0275\u00b4\3\2\2\2\u0276\u0277\7k\2"+
"\2\u0277\u0278\7h\2\2\u0278\u00b6\3\2\2\2\u0279\u027a\7g\2\2\u027a\u027b"+
"\7n\2\2\u027b\u027c\7u\2\2\u027c\u027d\7g\2\2\u027d\u00b8\3\2\2\2\u027e"+
"\u027f\7k\2\2\u027f\u0280\7h\2\2\u0280\u0281\7a\2\2\u0281\u0282\7e\2\2"+

File diff suppressed because it is too large Load Diff