changed syntax of subroutine parameters (now the same as vardecls)

This commit is contained in:
Irmen de Jong 2018-12-19 02:51:22 +01:00
parent 00ad285d3f
commit c1204b83bd
15 changed files with 996 additions and 888 deletions

View File

@ -223,9 +223,7 @@ statement_block :
;
sub_params : sub_param (',' EOL? sub_param)* ;
sub_param : identifier ':' datatype;
sub_params : vardecl (',' EOL? vardecl)* ;
sub_returns : datatype (',' EOL? datatype)* ;
@ -238,7 +236,7 @@ asmsub_address : '=' address=integerliteral ;
asmsub_params : asmsub_param (',' EOL? asmsub_param)* ;
asmsub_param : identifier ':' datatype '@' (registerorpair | statusregister);
asmsub_param : vardecl '@' (registerorpair | statusregister);
clobber : register (',' register)* ;

View File

@ -31,7 +31,7 @@
float[len(zcoor)] rotatedz
sub start() {
while(1) {
while true {
if irq.time_changed {
irq.time_changed = 0
;vm_gfx_clearscr(0)
@ -49,7 +49,7 @@
}
}
sub rotate_vertices(t: float) {
sub rotate_vertices(float t) {
; rotate around origin (0,0,0)
; set up the 3d rotation matrix values
@ -80,11 +80,11 @@
sub draw_edges() {
sub toscreenx(x: float, z: float) -> word {
sub toscreenx(float x, float z) -> word {
return fintw(x/(4.2+z) * flt(height)) + width // 2
}
sub toscreeny(y: float, z: float) -> word {
sub toscreeny(float y, float z) -> word {
return fintw(y/(4.2+z) * flt(height)) + height // 2
}

View File

@ -31,7 +31,7 @@
float[len(zcoor)] rotatedz
sub start() {
while(1) {
while true {
if irq.time_changed {
irq.time_changed = 0
vm_gfx_clearscr(0)
@ -48,7 +48,7 @@
}
}
sub rotate_vertices(t: float) {
sub rotate_vertices(float t) {
; rotate around origin (0,0,0)
; set up the 3d rotation matrix values
@ -79,11 +79,11 @@
sub draw_edges() {
sub toscreenx(x: float, z: float) -> word {
sub toscreenx(float x, float z) -> word {
return fintw(x/(4.2+z) * flt(height)) + width // 2
}
sub toscreeny(y: float, z: float) -> word {
sub toscreeny(float y, float z) -> word {
return fintw(y/(4.2+z) * flt(height)) + height // 2
}

View File

@ -4,15 +4,20 @@
~ main {
const uword width = 30
const uword height = 20
const ubyte max_iter = 16
sub start() {
c64scr.print_string("calculating mandelbrot fractal...\n")
c64.TIME_HI=0
c64.TIME_MID=0
c64.TIME_LO=0
for ubyte pixely in 0 to height-1 {
float yy = pixely/flt(height)/0.4-1.0
float yy = flt(pixely)/height/0.4-1.0
for ubyte pixelx in 0 to width-1 {
float xx = pixelx/flt(width)/0.3-2.0
float xx = flt(pixelx)/width/0.3-2.0
float xsquared = 0.0
float ysquared = 0.0
@ -20,7 +25,7 @@
float y = 0.0
ubyte iter = 0
while (iter<16 and xsquared+ysquared<4.0) {
while (iter<max_iter and xsquared+ysquared<4.0) {
y = x*y*2.0 + yy
x = xsquared - ysquared + xx
xsquared = x*x
@ -28,10 +33,13 @@
iter++
}
c64.CHROUT(48-iter)
c64.CHROUT(32+max_iter-iter)
}
c64.CHROUT('\n')
}
c64scr.print_string("finished!\n")
float duration = floor((c64.TIME_LO + c64.TIME_MID*256.0 + c64.TIME_HI*65536.0)/60.0)
c64scr.print_string("finished in ")
c64flt.print_float(duration)
c64scr.print_string(" seconds!\n")
}
}

View File

@ -61,7 +61,7 @@
return ending(false)
sub ending(success: ubyte) {
sub ending(ubyte success) {
if success
c64scr.print_string("\n\nYou guessed it, impressive!\n")
else {

View File

@ -11,19 +11,26 @@
float t
ubyte color
while(1) {
float x = sin(t) + cos(t*1.1234)
float y = cos(t) + sin(t*1.44)
c64scr.setchrclr(screenx(x), screeny(y), 81, color)
t += 0.1
while true {
float x = sin(t)
float y = cos(t*1.1356)
ubyte xx=screenx(x)
ubyte yy=screeny(y)
c64.COLOR = color
c64scr.PLOT(xx,yy)
c64.CHROUT('Q') ; shift-q = filled circle
; the 3 lines above can be replaced by: c64scr.setchrclr(xx, yy, 81, color)
t += 0.08
color++
}
}
sub screenx(x: float) -> ubyte {
return b2ub(fintb(x * flt(width)/4.2) + width//2)
sub screenx(float x) -> ubyte {
return b2ub(fintb(x * flt(width)/2.2) + width//2)
}
sub screeny(y: float) -> ubyte {
return b2ub(fintb(y * flt(height)/4.2) + height//2)
sub screeny(float y) -> ubyte {
return b2ub(fintb(y * flt(height)/2.2) + height//2)
}
}

View File

@ -13,7 +13,7 @@
float t
ubyte color
while(1) {
while true {
float x = sin(t*1.01) + cos(t*1.1234)
float y = cos(t) + sin(t*0.03456)
vm_gfx_pixel(screenx(x), screeny(y), color//16)
@ -22,10 +22,10 @@
}
}
sub screenx(x: float) -> word {
sub screenx(float x) -> word {
return fintw(x * flt(width)/4.1) + width // 2
}
sub screeny(y: float) -> word {
sub screeny(float y) -> word {
return fintw(y * flt(height)/4.1) + height // 2
}
}

View File

@ -1,17 +1,53 @@
%import c64utils
%import mathlib
%option enable_floats
~ main {
c64.TIME_HI=1 ; @todo WARNING about 'free' statements in main
c64.TIME_MID=0
c64.TIME_LO=0
;c64scr.PLOT(screenx(x), screeny(y)) ; @todo fix argument calculation???!!!
sub toscreenx(float x, float z) -> word {
return 42
}
asmsub blerp(ubyte x @ A, uword ding @ XY) -> clobbers() -> () {
}
sub start() {
word[3] wa = [-1000.w,2000.w,3000.w] ; @todo array data type fix (float->word)
word[3] wa2 = [1000,2000,3000] ; @todo array data type fix (uword->word)
word x = toscreenx(1.22, 3.22)
blerp(4, 555)
byte[3] ba1 = [-1, 2, 3]
byte[3] ba2 = [100,101,102] ; @todo array data type
;return b2ub(fintb(x * flt(width)/4.2) + width//2)
; const byte width=20
; word w1
; byte b1
; ubyte ub1
; float x = 3.45
; b1 = fintb(x * flt(width)/4.2) + width//2
; c64scr.print_byte(b1)
; c64.CHROUT('\n')
; b1 = fintb(x/4.2 * flt(width)) + width//2
; c64scr.print_byte(b1)
; c64.CHROUT('\n')
; ub1 = b2ub(fintb(x * flt(width)/4.2) + width//2)
; c64scr.print_ubyte(ub1)
; c64.CHROUT('\n')
; ub1 = b2ub(fintb(x/4.2 * flt(width)) + width//2)
; c64scr.print_ubyte(ub1)
; c64.CHROUT('\n')
; w1 = fintw(x * flt(width)/4.2) + width//2
; c64scr.print_word(w1)
; c64.CHROUT('\n')
; w1 = fintw(x/4.2 * flt(width)) + width//2
; c64scr.print_word(w1)
; c64.CHROUT('\n')
;uw1 = w2uw(fintw(x * flt(width)/4.2) + width//2) ; @todo w2uw
}
}

View File

@ -0,0 +1,95 @@
%import c64utils
%option enable_floats
~ main {
sub start() {
ubyte ub1
ubyte ub2
byte b1 = -99
byte b2
uword uw1
uword uw2
word w1 = -9999
word w2
float f1
float f2
float f3
ubyte[3] uba = [1,2,3]
byte[3] ba = [-1,0,3]
uword[3] uwa = [1000,200,0]
ubyte[3] uba0 = 0
byte[3] ba0 = 0
uword[3] uwa0 = 0
word[3] wa0 = -222
word[3] wa1 = [-1000.w,2000.w,3000.w]
word[3] wa2 = [1000,2000,3000]
float[3] fa0 = 0.0
float[3] fa1 = [-1000,44.555, 99.999]
float[3] fa2 = [-1000,44.555, 0]
str string = "hello"
str_p pstring = "hello1"
str_s sstring = "hello12"
str_ps psstring = "hello123"
c64.CHROUT('x')
c64scr.print_ubyte(X)
c64.CHROUT('\n')
; @todo implement max and min, AND FIX STACKPTR (X) ERRORS!
ub1 = max(uba)
c64scr.print_ubyte(ub1)
c64.CHROUT('\n')
b1 = max(ba)
c64scr.print_byte(b1)
c64.CHROUT('\n')
uw1 = max(uwa)
c64scr.print_uword(uw1)
c64.CHROUT('\n')
w1 = max(wa0)
c64scr.print_word(w1)
c64.CHROUT('\n')
w1 = max(wa1)
c64scr.print_word(w1)
c64.CHROUT('\n')
w1 = max(wa2)
c64scr.print_word(w1)
c64.CHROUT('\n')
f1 = max(fa1)
c64flt.print_float(f1)
c64.CHROUT('\n')
c64.CHROUT('x')
c64scr.print_ubyte(X)
c64.CHROUT('\n')
ub1 = min(uba)
c64scr.print_ubyte(ub1)
c64.CHROUT('\n')
b1 = min(ba)
c64scr.print_byte(b1)
c64.CHROUT('\n')
uw1 = min(uwa)
c64scr.print_uword(uw1)
c64.CHROUT('\n')
w1 = min(wa0)
c64scr.print_word(w1)
c64.CHROUT('\n')
w1 = min(wa1)
c64scr.print_word(w1)
c64.CHROUT('\n')
w1 = min(wa2)
c64scr.print_word(w1)
c64.CHROUT('\n')
f1 = min(fa1)
c64flt.print_float(f1)
c64.CHROUT('\n')
c64.CHROUT('x')
c64scr.print_ubyte(X)
c64.CHROUT('\n')
}
}

View File

@ -1829,7 +1829,7 @@ private fun prog8Parser.Asmsub_returnsContext.toAst(): List<AsmSubroutineReturn>
private fun prog8Parser.Asmsub_paramsContext.toAst(): List<AsmSubroutineParameter>
= asmsub_param().map { AsmSubroutineParameter(it.identifier().text, it.datatype().toAst(), it.registerorpair()?.toAst(), it.statusregister()?.toAst(), toPosition()) }
= asmsub_param().map { AsmSubroutineParameter(it.vardecl().identifier().text, it.vardecl().datatype().toAst(), it.registerorpair()?.toAst(), it.statusregister()?.toAst(), toPosition()) }
private fun prog8Parser.StatusregisterContext.toAst() = Statusflag.valueOf(text)
@ -1897,7 +1897,7 @@ private fun prog8Parser.Sub_return_partContext.toAst(): List<DataType> {
private fun prog8Parser.Sub_paramsContext.toAst(): List<SubroutineParameter> =
sub_param().map {
vardecl().map {
SubroutineParameter(it.identifier().text, it.datatype().toAst(), it.toPosition())
}

File diff suppressed because it is too large Load Diff

View File

@ -422,13 +422,13 @@ The syntax is::
}
; example:
sub triple_something (amount: word) -> word {
sub triple_something (word amount) -> word {
return X * 3
}
The open curly brace must immediately follow the subroutine result specification on the same line,
and can have nothing following it. The close curly brace must be on its own line as well.
The parameters is a (possibly empty) comma separated list of "<parametername>: <datatype>" pairs specifying the input parameters.
The parameters is a (possibly empty) comma separated list of "<datatype> <parametername>" pairs specifying the input parameters.
The return type has to be specified if the subroutine returns a value.
.. todo::

View File

@ -9,6 +9,7 @@
~ c64 {
memory ubyte SCRATCH_ZPB1 = $02 ; scratch byte 1 in ZP
memory ubyte SCRATCH_ZPREG = $03 ; scratch register in ZP
memory ubyte SCRATCH_ZPREGX = $fa ; temp storage for X register (stack pointer)
memory uword SCRATCH_ZPWORD1 = $fb ; scratch word in ZP ($fb/$fc)
memory uword SCRATCH_ZPWORD2 = $fd ; scratch word in ZP ($fd/$fe)
@ -110,14 +111,14 @@
; note: for subtraction and division, the left operand is in fac2, the right operand in fac1.
; checked functions below:
asmsub MOVFM (mflpt: uword @ AY) -> clobbers(A,Y) -> () = $bba2 ; load mflpt value from memory in A/Y into fac1
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 (mflpt: uword @ AY) -> clobbers(A,Y) -> () = $ba8c ; load mflpt value from memory in A/Y into fac2
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 (mflpt: uword @ XY) -> clobbers(A,Y) -> () = $bbd4 ; store fac1 to memory X/Y as 5-byte mflpt
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)
@ -136,29 +137,29 @@ 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 (lo: ubyte @ Y, hi: ubyte @ A) -> clobbers(A,X,Y) -> () = $b391
asmsub GIVAYF (ubyte lo @ Y, ubyte hi @ A) -> clobbers(A,X,Y) -> () = $b391
asmsub FREADUY (unsigned: ubyte @ Y) -> clobbers(A,X,Y) -> () = $b3a2 ; 8 bit unsigned Y -> float in fac1
asmsub FREADSA (signed: ubyte @ A) -> clobbers(A,X,Y) -> () = $bc3c ; 8 bit signed A -> float in fac1
asmsub FREADSTR (length: ubyte @ A) -> clobbers(A,X,Y) -> () = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length
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 (mflpt: uword @ 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 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 (mflpt: uword @ AY) -> clobbers(A,X,Y) -> () = $b867 ; fac1 += mflpt value from A/Y
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 (mflpt: uword @ AY) -> clobbers(A,X,Y) -> () = $b850 ; fac1 = mflpt from A/Y - fac1
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 (mflpt: uword @ AY) -> clobbers(A,X,Y) -> () = $ba28 ; fac1 *= mflpt value from A/Y
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 (mflpt: uword @ AY) -> clobbers(A,X,Y) -> () = $bb0f ; fac1 = mflpt in A/Y / fac1 (remainder in fac2)
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 (mflpt: uword @ AY) -> clobbers(A,X,Y) -> () = $bf78 ; fac1 = fac2 ** mflpt from A/Y
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
@ -189,47 +190,47 @@ asmsub HOMECRSR () -> clobbers(A,X,Y) -> () = $E566 ; cursor to top left of sc
; ---- C64 kernal routines ----
asmsub STROUT (strptr: uword @ AY) -> clobbers(A, X, Y) -> () = $AB1E ; print null-terminated string (a bit slow, see if you can use c64scr.print_string instead)
asmsub STROUT (uword strptr @ AY) -> clobbers(A, X, Y) -> () = $AB1E ; print null-terminated string (a bit slow, see if you can use c64scr.print_string 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 (dir: ubyte @ Pc, userptr: uword @ XY) -> clobbers(A,Y) -> () = $FF8D ; read/set I/O vector table
asmsub SETMSG (value: ubyte @ A) -> clobbers() -> () = $FF90 ; set Kernal message control flag
asmsub SECOND (address: ubyte @ A) -> clobbers(A) -> () = $FF93 ; (alias: LSTNSA) send secondary address after LISTEN
asmsub TKSA (address: ubyte @ A) -> clobbers(A) -> () = $FF96 ; (alias: TALKSA) send secondary address after TALK
asmsub MEMTOP (dir: ubyte @ Pc, address: uword @ XY) -> clobbers() -> (uword @ XY) = $FF99 ; read/set top of memory pointer
asmsub MEMBOT (dir: ubyte @ Pc, address: uword @ XY) -> clobbers() -> (uword @ XY) = $FF9C ; read/set bottom of memory pointer
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 (timeout: ubyte @ A) -> clobbers() -> () = $FFA2 ; set time-out flag for IEEE bus
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 (databyte: ubyte @ A) -> clobbers() -> () = $FFA8 ; (alias: IECOUT) output byte to 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 (device: ubyte @ A) -> clobbers(A) -> () = $FFB1 ; command serial bus device to LISTEN
asmsub TALK (device: ubyte @ A) -> clobbers(A) -> () = $FFB4 ; command serial bus device to TALK
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 (logical: ubyte @ A, device: ubyte @ X, address: ubyte @ Y) -> clobbers() -> () = $FFBA ; set logical file parameters
asmsub SETNAM (namelen: ubyte @ A, filename: uword @ XY) -> clobbers() -> () = $FFBD ; set filename parameters
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 (logical: ubyte @ A) -> clobbers(A,X,Y) -> () = $FFC3 ; (via 796 ($31C)) close a logical file
asmsub CHKIN (logical: ubyte @ X) -> clobbers(A,X) -> () = $FFC6 ; (via 798 ($31E)) define an input channel
asmsub CHKOUT (logical: ubyte @ X) -> clobbers(A,X) -> () = $FFC9 ; (via 800 ($320)) define an output channel
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 (char: ubyte @ A) -> clobbers() -> () = $FFD2 ; (via 806 ($326)) output a character
asmsub LOAD (verify: ubyte @ A, address: uword @ XY) -> clobbers() -> (ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y) = $FFD5 ; (via 816 ($330)) load from device
asmsub SAVE (zp_startaddr: ubyte @ A, endaddr: uword @ XY) -> clobbers() -> (ubyte @ Pc, ubyte @ A) = $FFD8 ; (via 818 ($332)) save to a device
asmsub SETTIM (low: ubyte @ A, middle: ubyte @ X, high: ubyte @ Y) -> clobbers() -> () = $FFDB ; set the software clock
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 (dir: ubyte @ Pc, col: ubyte @ Y, row: ubyte @ X) -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFF0 ; read/set position of cursor on screen
asmsub PLOT (ubyte dir @ Pc, ubyte col @ Y, ubyte row @ X) -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFF0 ; read/set position of cursor on screen. See c64scr.PLOT for a 'safe' wrapper that preserves X.
asmsub IOBASE () -> clobbers() -> (uword @ XY) = $FFF3 ; read base address of I/O devices
; ---- end of C64 kernal routines ----

View File

@ -48,7 +48,7 @@ asmsub init_system () -> clobbers(A,X,Y) -> () {
}}
}
asmsub ubyte2decimal (value: ubyte @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X, ubyte @ A) {
asmsub ubyte2decimal (ubyte value @ A) -> clobbers() -> (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
@ -65,7 +65,7 @@ asmsub ubyte2decimal (value: ubyte @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X
}}
}
asmsub byte2decimal (value: ubyte @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X, ubyte @ A) {
asmsub byte2decimal (ubyte value @ A) -> clobbers() -> (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 {{
@ -78,7 +78,7 @@ asmsub byte2decimal (value: ubyte @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X,
}}
}
asmsub ubyte2hex (value: ubyte @ A) -> clobbers(X) -> (ubyte @ A, ubyte @ Y) {
asmsub ubyte2hex (ubyte value @ A) -> clobbers(X) -> (ubyte @ A, ubyte @ Y) {
; ---- A to hex string in AY (first hex char in A, second hex char in Y)
%asm {{
pha
@ -100,7 +100,7 @@ hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as
str word2hex_output = "1234" ; 0-terminated, to make printing easier
asmsub uword2hex (value: uword @ AY) -> clobbers(A,X,Y) -> () {
asmsub uword2hex (uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string into memory 'word2hex_output'
%asm {{
sta c64.SCRATCH_ZPREG
@ -117,7 +117,7 @@ asmsub uword2hex (value: uword @ AY) -> clobbers(A,X,Y) -> () {
}
ubyte[3] word2bcd_bcdbuff = [0, 0, 0]
asmsub uword2bcd (dataword: uword @ AY) -> clobbers(A,X) -> () {
asmsub uword2bcd (uword value @ AY) -> clobbers(A,X) -> () {
; 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
@ -155,7 +155,7 @@ asmsub uword2bcd (dataword: uword @ AY) -> clobbers(A,X) -> () {
ubyte[5] word2decimal_output = 0
asmsub uword2decimal (dataword: uword @ AY) -> clobbers(A,X,Y) -> () {
asmsub uword2decimal (uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- convert 16 bit uword in A/Y into decimal string into memory 'word2decimal_output'
%asm {{
jsr uword2bcd
@ -220,7 +220,7 @@ asmsub FREADUS32 () -> clobbers(A,X,Y) -> () {
}}
}
asmsub FREADS24AXY (lo: ubyte @ A, mid: ubyte @ X, hi: ubyte @ 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 {{
@ -237,7 +237,7 @@ asmsub FREADS24AXY (lo: ubyte @ A, mid: ubyte @ X, hi: ubyte @ Y) -> clobbers(
}}
}
asmsub GIVUAYFAY (value: uword @ 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
@ -248,7 +248,7 @@ asmsub GIVUAYFAY (value: uword @ AY) -> clobbers(A,X,Y) -> () {
}}
}
asmsub GIVAYFAY (value: uword @ 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
@ -280,7 +280,7 @@ asmsub GETADRAY () -> clobbers(X) -> (uword @ AY) {
}}
}
sub print_float (value: float) {
sub print_float (float value) {
; ---- prints the floating point value (without a newline) using basic rom routines.
; clobbers no registers.
; @todo version that takes A/Y pointer to float instead
@ -304,7 +304,7 @@ sub print_float (value: float) {
}}
}
sub print_float_ln (value: float) {
sub print_float_ln (float value) {
; ---- prints the floating point value (with a newline at the end) using basic rom routines
; clobbers no registers.
; @todo version that takes A/Y pointer to float instead
@ -336,7 +336,7 @@ sub print_float_ln (value: float) {
; ---- this block contains (character) Screen and text I/O related functions ----
asmsub clear_screen (char: ubyte @ A, color: ubyte @ Y) -> clobbers(A,X) -> () {
asmsub clear_screen (ubyte char @ A, ubyte color @ Y) -> clobbers(A,X) -> () {
; ---- clear the character screen with the given fill character and character color.
; (assumes screen is at $0400, could be altered in the future with self-modifying code)
; @todo some byte var to set the SCREEN ADDR HI BYTE
@ -366,7 +366,7 @@ _loop lda #0
}
asmsub scroll_left_full (alsocolors: ubyte @ Pc) -> clobbers(A, X, Y) -> () {
asmsub scroll_left_full (ubyte alsocolors @ Pc) -> clobbers(A, X, 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
@ -425,7 +425,7 @@ _scroll_screen ; scroll the screen memory
}
asmsub scroll_right_full (alsocolors: ubyte @ Pc) -> clobbers(A,X) -> () {
asmsub scroll_right_full (ubyte alsocolors @ Pc) -> clobbers(A,X) -> () {
; ---- 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
@ -476,7 +476,7 @@ _scroll_screen ; scroll the screen memory
}
asmsub scroll_up_full (alsocolors: ubyte @ Pc) -> clobbers(A,X) -> () {
asmsub scroll_up_full (ubyte alsocolors @ Pc) -> clobbers(A,X) -> () {
; ---- 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
@ -527,7 +527,7 @@ _scroll_screen ; scroll the screen memory
}
asmsub scroll_down_full (alsocolors: ubyte @ Pc) -> clobbers(A,X) -> () {
asmsub scroll_down_full (ubyte alsocolors @ Pc) -> clobbers(A,X) -> () {
; ---- 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
@ -579,7 +579,7 @@ _scroll_screen ; scroll the screen memory
asmsub print_string (text: str @ AY) -> clobbers(A,Y) -> () {
asmsub print_string (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,
@ -598,7 +598,7 @@ asmsub print_string (text: str @ AY) -> clobbers(A,Y) -> () {
}
asmsub print_pstring (text: str_p @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
asmsub print_pstring (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
; ---- print pstring (length as first byte) from A/Y, returns str len in Y
%asm {{
sta c64.SCRATCH_ZPB1
@ -617,7 +617,7 @@ asmsub print_pstring (text: str_p @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
}
asmsub print_ubyte0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () {
asmsub print_ubyte0 (ubyte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
%asm {{
jsr c64utils.ubyte2decimal
@ -632,7 +632,7 @@ asmsub print_ubyte0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () {
}
asmsub print_ubyte (value: ubyte @ A) -> clobbers(A,X,Y) -> () {
asmsub print_ubyte (ubyte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the ubyte in A in decimal form, without left padding 0s
%asm {{
jsr c64utils.ubyte2decimal
@ -653,7 +653,7 @@ _print_tens txa
}}
}
asmsub print_byte (value: byte @ A) -> clobbers(A,X,Y) -> () {
asmsub print_byte (byte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the byte in A in decimal form, without left padding 0s
%asm {{
pha
@ -668,7 +668,7 @@ asmsub print_byte (value: byte @ A) -> clobbers(A,X,Y) -> () {
}
asmsub print_ubyte_hex (prefix: ubyte @ Pc, value: ubyte @ A) -> clobbers(A,X,Y) -> () {
asmsub print_ubyte_hex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
%asm {{
bcc +
@ -684,7 +684,7 @@ asmsub print_ubyte_hex (prefix: ubyte @ Pc, value: ubyte @ A) -> clobbers(A,X,
}
asmsub print_uword_hex (prefix: ubyte @ Pc, value: uword @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_uword_hex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the uword in A/Y in hexadecimal form (4 digits)
; (if Carry is set, a radix prefix '$' is printed as well)
%asm {{
@ -698,7 +698,7 @@ asmsub print_uword_hex (prefix: ubyte @ Pc, value: uword @ AY) -> clobbers(A,X,
}
asmsub print_uword0 (value: uword @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_uword0 (uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
; @todo shorter in loop form?
%asm {{
@ -717,7 +717,7 @@ asmsub print_uword0 (value: uword @ AY) -> clobbers(A,X,Y) -> () {
}
asmsub print_uword (value: uword @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_uword (uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the uword in A/Y in decimal form, without left padding 0s
%asm {{
jsr c64utils.uword2decimal
@ -749,7 +749,7 @@ _pr_decimal
}}
}
asmsub print_word (value: word @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_word (word value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the (signed) word in A/Y in decimal form, without left padding 0s
%asm {{
cpy #0
@ -770,7 +770,7 @@ asmsub print_word (value: word @ AY) -> clobbers(A,X,Y) -> () {
}}
}
asmsub input_chars (buffer: uword @ AY) -> clobbers(A, X) -> (ubyte @ Y) {
asmsub input_chars (uword buffer @ AY) -> clobbers(A, X) -> (ubyte @ Y) {
; ---- Input a string (max. 80 chars) from the keyboard. Returns length in Y.
; It assumes the keyboard is selected as I/O channel!
@ -791,7 +791,7 @@ asmsub input_chars (buffer: uword @ AY) -> clobbers(A, X) -> (ubyte @ Y) {
}}
}
asmsub setchr (col: ubyte @Y, row: ubyte @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
@ -813,7 +813,7 @@ _screenrows .word $0400 + range(0, 1000, 40)
}}
}
asmsub setclr (col: ubyte @Y, row: ubyte @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
@ -836,7 +836,7 @@ _colorrows .word $d800 + range(0, 1000, 40)
}
sub setchrclr (column: ubyte, row: ubyte, char: ubyte, color: ubyte) {
sub setchrclr (ubyte column, ubyte row, ubyte char, ubyte color) {
; ---- set char+color at the given position on the screen
%asm {{
lda setchrclr_row
@ -866,5 +866,17 @@ _colormod sta $ffff ; modified
}}
}
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
tax
clc
jsr c64.PLOT
ldx c64.SCRATCH_ZPREGX
rts
}}
}
} ; ---- end block c64scr

View File

@ -19,7 +19,7 @@
asmsub multiply_bytes (byte1: ubyte @ A, byte2: ubyte @ Y) -> clobbers(X) -> (ubyte @ A) {
asmsub multiply_bytes (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers(X) -> (ubyte @ A) {
; ---- multiply 2 bytes, result as byte in A (signed or unsigned)
%asm {{
sta SCRATCH_ZPB1
@ -37,7 +37,7 @@ asmsub multiply_bytes (byte1: ubyte @ A, byte2: ubyte @ Y) -> clobbers(X) -> (
}
asmsub multiply_bytes_16 (byte1: ubyte @ A, byte2: ubyte @ Y) -> clobbers(X) -> (uword @ AY) {
asmsub multiply_bytes_16 (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers(X) -> (uword @ AY) {
; ---- multiply 2 bytes, result as word in A/Y (unsigned)
%asm {{
sta SCRATCH_ZPB1
@ -59,7 +59,7 @@ asmsub multiply_bytes_16 (byte1: ubyte @ A, byte2: ubyte @ Y) -> clobbers(X) -
}
word[2] multiply_words_product = 0
asmsub multiply_words (number: uword @ AY) -> clobbers(A,X) -> () {
asmsub multiply_words (uword number @ AY) -> clobbers(A,X) -> () {
; ---- multiply two 16-bit words into a 32-bit result
; input: A/Y = first 16-bit number, SCRATCH_ZPWORD1 in ZP = second 16-bit number
; output: multiply_words_product 32-bits product, LSB order (low-to-high)
@ -93,7 +93,7 @@ mult16 lda #$00
}
asmsub divmod_bytes (number: ubyte @ X, divisor: ubyte @ Y) -> clobbers() -> (ubyte @ X, ubyte @ A) {
asmsub divmod_bytes (ubyte number @ X, ubyte divisor @ Y) -> clobbers() -> (ubyte @ X, ubyte @ A) {
; ---- divide X by Y, result quotient in X, remainder in A (unsigned)
; division by zero will result in quotient = 255 and remainder = original number
%asm {{
@ -116,7 +116,7 @@ asmsub divmod_bytes (number: ubyte @ X, divisor: ubyte @ Y) -> clobbers() -> (
}}
}
asmsub divmod_words (divisor: uword @ AY) -> clobbers(X) -> (uword @ AY) {
asmsub divmod_words (uword divisor @ AY) -> clobbers(X) -> (uword @ AY) {
; ---- divide two words (16 bit each) into 16 bit results
; input: SCRATCH_ZPWORD1 in ZP: 16 bit number, A/Y: 16 bit divisor
; output: SCRATCH_ZPWORD1 in ZP: 16 bit result, A/Y: 16 bit remainder
@ -164,7 +164,7 @@ remainder = SCRATCH_ZPB1
}}
}
asmsub randseed (seed: uword @ AY) -> clobbers(A, Y) -> () {
asmsub randseed (uword seed @ AY) -> clobbers(A, Y) -> () {
; ---- reset the random seeds for the byte and word random generators
; default starting values are: A=$2c Y=$9e
%asm {{