mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
rename
This commit is contained in:
parent
a5283bfc7b
commit
2f6ef28c80
@ -1514,7 +1514,7 @@ class CodeGenerator:
|
|||||||
# assigning a register to a float requires c64 ROM routines
|
# assigning a register to a float requires c64 ROM routines
|
||||||
if r_register in REGISTER_WORDS:
|
if r_register in REGISTER_WORDS:
|
||||||
def do_rom_calls():
|
def do_rom_calls():
|
||||||
self.p("\t\tjsr c64util.GIVUAYF") # uword AY -> fac1
|
self.p("\t\tjsr c64.GIVUAYF") # uword AY -> fac1
|
||||||
self.p("\t\tldx #<" + lv_string)
|
self.p("\t\tldx #<" + lv_string)
|
||||||
self.p("\t\tldy #>" + lv_string)
|
self.p("\t\tldy #>" + lv_string)
|
||||||
self.p("\t\tjsr c64.FTOMEMXY") # fac1 -> memory XY
|
self.p("\t\tjsr c64.FTOMEMXY") # fac1 -> memory XY
|
||||||
@ -1750,7 +1750,7 @@ class CodeGenerator:
|
|||||||
self.p("\t\tsta c64.SCRATCH_ZPWORD1+1")
|
self.p("\t\tsta c64.SCRATCH_ZPWORD1+1")
|
||||||
self.p("\t\tldx #<" + l_str)
|
self.p("\t\tldx #<" + l_str)
|
||||||
self.p("\t\tldy #>" + l_str)
|
self.p("\t\tldy #>" + l_str)
|
||||||
self.p("\t\tjsr c64_lib.copy_mflt")
|
self.p("\t\tjsr il65_lib.copy_mflt")
|
||||||
elif rvalue.datatype == DataType.BYTE:
|
elif rvalue.datatype == DataType.BYTE:
|
||||||
with self.preserving_registers({'A', 'X', 'Y'}):
|
with self.preserving_registers({'A', 'X', 'Y'}):
|
||||||
self.p("\t\tldy " + r_str)
|
self.p("\t\tldy " + r_str)
|
||||||
@ -1762,7 +1762,7 @@ class CodeGenerator:
|
|||||||
with self.preserving_registers({'A', 'X', 'Y'}, loads_a_within=True):
|
with self.preserving_registers({'A', 'X', 'Y'}, loads_a_within=True):
|
||||||
self.p("\t\tlda " + r_str)
|
self.p("\t\tlda " + r_str)
|
||||||
self.p("\t\tldy {:s}+1".format(r_str))
|
self.p("\t\tldy {:s}+1".format(r_str))
|
||||||
self.p("\t\tjsr c64util.GIVUAYF") # uword AY -> fac1
|
self.p("\t\tjsr c64.GIVUAYF") # uword AY -> fac1
|
||||||
self.p("\t\tldx #<" + l_str)
|
self.p("\t\tldx #<" + l_str)
|
||||||
self.p("\t\tldy #>" + l_str)
|
self.p("\t\tldy #>" + l_str)
|
||||||
self.p("\t\tjsr c64.FTOMEMXY") # fac1 -> memory XY
|
self.p("\t\tjsr c64.FTOMEMXY") # fac1 -> memory XY
|
||||||
|
@ -1308,7 +1308,7 @@ class Parser:
|
|||||||
raise self.PError("all call arguments should have a name or be matched on a named parameter")
|
raise self.PError("all call arguments should have a name or be matched on a named parameter")
|
||||||
if isinstance(target, (type(None), ParseResult.Value)):
|
if isinstance(target, (type(None), ParseResult.Value)):
|
||||||
# special case for the C-64 lib's print function, to be able to use it with a single character argument
|
# special case for the C-64 lib's print function, to be able to use it with a single character argument
|
||||||
if target.name == "c64util.print_string" and len(arguments) == 1 and isinstance(arguments[0], str):
|
if target.name == "c64scr.print_string" and len(arguments) == 1 and isinstance(arguments[0], str):
|
||||||
if arguments[0][1].startswith("'") and arguments[0][1].endswith("'"):
|
if arguments[0][1].startswith("'") and arguments[0][1].endswith("'"):
|
||||||
target = self.parse_expression("c64.CHROUT")
|
target = self.parse_expression("c64.CHROUT")
|
||||||
address = target.address
|
address = target.address
|
||||||
@ -1797,7 +1797,7 @@ class Optimizer:
|
|||||||
def remove_unused_subroutines(self, block: ParseResult.Block) -> None:
|
def remove_unused_subroutines(self, block: ParseResult.Block) -> None:
|
||||||
# some symbols are used by the emitted assembly code from the code generator,
|
# some symbols are used by the emitted assembly code from the code generator,
|
||||||
# and should never be removed or the assembler will fail
|
# and should never be removed or the assembler will fail
|
||||||
never_remove = {"c64util.GIVUAYF", "c64.FREADUY", "c64.FTOMEMXY"}
|
never_remove = {"c64.GIVUAYF", "c64.FREADUY", "c64.FTOMEMXY"}
|
||||||
discarded = []
|
discarded = []
|
||||||
for sub in list(block.symbols.iter_subroutines()):
|
for sub in list(block.symbols.iter_subroutines()):
|
||||||
usages = self.parsed.subroutine_usage[(sub.blockname, sub.name)]
|
usages = self.parsed.subroutine_usage[(sub.blockname, sub.name)]
|
||||||
|
@ -221,6 +221,8 @@ class Zeropage:
|
|||||||
raise SymbolError("cannot configure the ZP multiple times")
|
raise SymbolError("cannot configure the ZP multiple times")
|
||||||
if clobber_zp:
|
if clobber_zp:
|
||||||
self.free = list(range(0x04, 0xfb)) + [0xff]
|
self.free = list(range(0x04, 0xfb)) + [0xff]
|
||||||
|
for updated_by_irq in [0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6]:
|
||||||
|
self.free.remove(updated_by_irq)
|
||||||
else:
|
else:
|
||||||
# these are valid for the C-64 (when no RS232 I/O is performed):
|
# these are valid for the C-64 (when no RS232 I/O is performed):
|
||||||
# ($02, $03, $fb-$fc, $fd-$fe are reserved as scratch addresses for various routines)
|
# ($02, $03, $fb-$fc, $fd-$fe are reserved as scratch addresses for various routines)
|
||||||
|
247
lib/c64lib.ill
247
lib/c64lib.ill
@ -7,14 +7,19 @@
|
|||||||
; indent format: TABS, size=8
|
; indent format: TABS, size=8
|
||||||
|
|
||||||
|
|
||||||
output raw
|
|
||||||
|
|
||||||
~ c64 {
|
~ c64 {
|
||||||
memory .byte SCRATCH_ZP1 = $02 ; scratch register #1 in ZP
|
memory .byte SCRATCH_ZP1 = $02 ; scratch register #1 in ZP
|
||||||
memory .byte SCRATCH_ZP2 = $03 ; scratch register #2 in ZP
|
memory .byte SCRATCH_ZP2 = $03 ; scratch register #2 in ZP
|
||||||
memory .word SCRATCH_ZPWORD1 = $fb ; scratch word in ZP ($fb/$fc)
|
memory .word SCRATCH_ZPWORD1 = $fb ; scratch word in ZP ($fb/$fc)
|
||||||
memory .word SCRATCH_ZPWORD2 = $fd ; scratch word in ZP ($fd/$fe)
|
memory .word SCRATCH_ZPWORD2 = $fd ; scratch word in ZP ($fd/$fe)
|
||||||
|
|
||||||
|
|
||||||
|
memory .byte TIME_HI = $a0 ; software jiffy clock, hi byte
|
||||||
|
memory .byte TIME_MID = $a1 ; .. mid byte
|
||||||
|
memory .byte TIME_LO = $a2 ; .. lo byte. Updated by IRQ every 1/60 sec
|
||||||
|
memory .byte STKEY = $91 ; various keyboard statuses (updated by IRQ)
|
||||||
|
memory .byte SFDX = $cb ; current key pressed (matrix value) (updated by IRQ)
|
||||||
|
|
||||||
memory .byte COLOR = $0286 ; cursor color
|
memory .byte COLOR = $0286 ; cursor color
|
||||||
memory .word CINV = $0314 ; IRQ vector
|
memory .word CINV = $0314 ; IRQ vector
|
||||||
|
|
||||||
@ -107,17 +112,17 @@ sub MOVAF () -> (A?, X?) = $bc0c ; copy fac1 to fac2 (rounded)
|
|||||||
sub MOVEF () -> (A?, X?) = $bc0f ; copy fac1 to fac2
|
sub MOVEF () -> (A?, X?) = $bc0f ; copy fac1 to fac2
|
||||||
sub FTOMEMXY (mflpt: XY) -> (A?, Y?) = $bbd4 ; store fac1 to memory X/Y as 5-byte mflpt
|
sub FTOMEMXY (mflpt: XY) -> (A?, Y?) = $bbd4 ; store fac1 to memory X/Y as 5-byte mflpt
|
||||||
sub FTOSWORDYA () -> (Y, A, X?) = $b1aa ; fac1-> signed word in Y/A (might throw ILLEGAL QUANTITY)
|
sub FTOSWORDYA () -> (Y, A, X?) = $b1aa ; fac1-> signed word in Y/A (might throw ILLEGAL QUANTITY)
|
||||||
; use c64util.FTOSWRDAY to get A/Y output (lo/hi switched to normal order)
|
; use c64.FTOSWRDAY to get A/Y output (lo/hi switched to normal order)
|
||||||
sub GETADR () -> (Y, A, X?) = $b7f7 ; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY)
|
sub GETADR () -> (Y, A, X?) = $b7f7 ; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY)
|
||||||
; (result also in $14/15) use c64util.GETADRAY to get A/Y output (lo/hi switched to normal order)
|
; (result also in $14/15) use c64.GETADRAY to get A/Y output (lo/hi switched to normal order)
|
||||||
sub QINT () -> (?) = $bc9b ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST.
|
sub QINT () -> (?) = $bc9b ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST.
|
||||||
sub AYINT () -> (?) = $b1bf ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY)
|
sub AYINT () -> (?) = $b1bf ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY)
|
||||||
sub GIVAYF (lo: Y, hi: A) -> (?) = $b391 ; signed word in Y/A -> float in fac1
|
sub GIVAYF (lo: Y, hi: A) -> (?) = $b391 ; signed word in Y/A -> float in fac1
|
||||||
; use c64util.GIVAYFAY to use A/Y input (lo/hi switched to normal order)
|
; use c64.GIVAYFAY to use A/Y input (lo/hi switched to normal order)
|
||||||
; there is also c64util.GIVUAYF - unsigned word in A/Y (lo/hi) to fac1
|
; there is also c64.GIVUAYF - unsigned word in A/Y (lo/hi) to fac1
|
||||||
; there is also c64util.FREADS32 that reads from 98-101 ($62-$65) MSB FIRST
|
; there is also c64.FREADS32 that reads from 98-101 ($62-$65) MSB FIRST
|
||||||
; there is also c64util.FREADUS32 that reads from 98-101 ($62-$65) MSB FIRST
|
; there is also c64.FREADUS32 that reads from 98-101 ($62-$65) MSB FIRST
|
||||||
; there is also c64util.FREADS24AXY that reads signed int24 into fac1 from A/X/Y (lo/mid/hi bytes)
|
; there is also c64.FREADS24AXY that reads signed int24 into fac1 from A/X/Y (lo/mid/hi bytes)
|
||||||
sub FREADUY (ubyte: Y) -> (?) = $b3a2 ; 8 bit unsigned Y -> float in fac1
|
sub FREADUY (ubyte: Y) -> (?) = $b3a2 ; 8 bit unsigned Y -> float in fac1
|
||||||
sub FREADSA (sbyte: A) -> (?) = $bc3c ; 8 bit signed A -> float in fac1
|
sub FREADSA (sbyte: A) -> (?) = $bc3c ; 8 bit signed A -> float in fac1
|
||||||
sub FREADSTR (len: A) -> (?) = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length
|
sub FREADSTR (len: A) -> (?) = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length
|
||||||
@ -217,10 +222,9 @@ sub IOBASE () -> (X, Y) = $FFF3 ; read base address of I/O devices
|
|||||||
memory .word RESET_VEC = $FFFC ; reset vector, set by the kernal if banked in
|
memory .word RESET_VEC = $FFFC ; reset vector, set by the kernal if banked in
|
||||||
memory .word IRQ_VEC = $FFFE ; interrupt vector, set by the kernal if banked in
|
memory .word IRQ_VEC = $FFFE ; interrupt vector, set by the kernal if banked in
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
~ c64util {
|
; ----- utility functions ----
|
||||||
|
|
||||||
sub init_system () -> (?) {
|
sub init_system () -> (?) {
|
||||||
; ---- initializes the machine to a sane starting state
|
; ---- initializes the machine to a sane starting state
|
||||||
@ -252,7 +256,6 @@ sub init_system () -> (?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub FREADS32 () -> (?) {
|
sub FREADS32 () -> (?) {
|
||||||
; ---- fac1 = signed int32 from $62-$65 big endian (MSB FIRST)
|
; ---- fac1 = signed int32 from $62-$65 big endian (MSB FIRST)
|
||||||
asm {
|
asm {
|
||||||
@ -335,70 +338,55 @@ sub GETADRAY () -> (AY, X?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub print_string (address: XY) -> (A?, Y?) {
|
|
||||||
; ---- print null terminated string from X/Y
|
|
||||||
; note: the IL65 compiler contains an optimization that will replace
|
|
||||||
; a call to this subroutine with a string argument of just one char,
|
|
||||||
; by just one call to c64.CHROUT of that single char.
|
|
||||||
asm {
|
|
||||||
stx c64.SCRATCH_ZP1
|
|
||||||
sty c64.SCRATCH_ZP2
|
|
||||||
ldy #0
|
|
||||||
- lda (c64.SCRATCH_ZP1),y
|
|
||||||
beq +
|
|
||||||
jsr c64.CHROUT
|
|
||||||
iny
|
|
||||||
bne -
|
|
||||||
+ rts
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub print_pstring (address: XY) -> (A?, X?, Y) {
|
} ; ------ end of block c64
|
||||||
; ---- print pstring (length as first byte) from X/Y, returns str len in Y
|
|
||||||
asm {
|
|
||||||
stx c64.SCRATCH_ZP1
|
|
||||||
sty c64.SCRATCH_ZP2
|
~ c64scr {
|
||||||
ldy #0
|
; ---- this block contains (character) Screen and text I/O related functions ----
|
||||||
lda (c64.SCRATCH_ZP1),y
|
|
||||||
beq +
|
|
||||||
tax
|
sub clear_screen (char:A, color: Y, screenaddr_hi: X) -> () {
|
||||||
- iny
|
; ---- clear the character screen with the given fill character and character color.
|
||||||
lda (c64.SCRATCH_ZP1),y
|
; X must be set to the high byte of the current screen display memory address (usually $04, for $0400).
|
||||||
jsr c64.CHROUT
|
|
||||||
dex
|
|
||||||
bne -
|
|
||||||
+ rts ; output string length is in Y
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub print_pimmediate () -> () {
|
|
||||||
; ---- print pstring in memory immediately following the subroutine fast call instruction
|
|
||||||
; note that the clobbered registers (A,X,Y) are not listed ON PURPOSE
|
|
||||||
asm {
|
asm {
|
||||||
tsx
|
;ldx #$04 ; high byte of screen addres
|
||||||
lda $102,x
|
;lda #1 ; fill char
|
||||||
tay ; put high byte in y
|
;ldy #3 ; fill color
|
||||||
lda $101,x
|
sta _loop +1 ; self-modify
|
||||||
tax ; and low byte in x.
|
sty _mod_col +1 ; self-modify
|
||||||
|
stx _loop + 4 ; self-modify
|
||||||
inx
|
inx
|
||||||
bne +
|
stx _loop + 7 ; self-modify
|
||||||
iny
|
inx
|
||||||
+ jsr print_pstring ; print string in XY, returns string length in y.
|
stx _loop + 10 ; self-modify
|
||||||
tya
|
stx _loop + 13 ; self-modify
|
||||||
tsx
|
|
||||||
clc
|
|
||||||
adc $101,x ; add content of 1st (length) byte to return addr.
|
ldx #0
|
||||||
bcc + ; if that made the low byte roll over to 00,
|
_loop lda #0
|
||||||
inc $102,x ; then increment the high byte too.
|
sta $8400,x ; screen address will be modified
|
||||||
+ clc
|
sta $8500,x
|
||||||
adc #1 ; now add 1 for the length byte itself.
|
sta $8600,x
|
||||||
sta $101,x
|
sta $86e8,x
|
||||||
bne + ; if that made it (the low byte) roll over to 00,
|
_mod_col lda #0
|
||||||
inc $102,x ; increment the high byte of the return addr too.
|
sta $d800,x ; color address is fixed
|
||||||
+ rts
|
sta $d900,x
|
||||||
|
sta $da00,x
|
||||||
|
sta $dae8,x
|
||||||
|
inx
|
||||||
|
bne _loop
|
||||||
|
|
||||||
|
lda _loop+1 ; restore A and X
|
||||||
|
ldx _loop+4
|
||||||
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub byte2decimal (ubyte: A) -> (Y, X, A) {
|
sub byte2decimal (ubyte: A) -> (Y, X, A) {
|
||||||
; ---- A to decimal string in Y/X/A (100s in Y, 10s in X, 1s in A)
|
; ---- A to decimal string in Y/X/A (100s in Y, 10s in X, 1s in A)
|
||||||
asm {
|
asm {
|
||||||
@ -437,10 +425,10 @@ hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
; var .array(4) word2hex_output_array @todo support to use array/matrix type by address
|
|
||||||
var .text word2hex_output = "123" ; 0-terminated, 4 bytes total @todo remove once array works
|
var .text word2hex_output = "1234" ; 0-terminated, to make printing easier
|
||||||
sub word2hex (word: XY) -> (?) {
|
sub word2hex (word: XY) -> (?) {
|
||||||
; ---- convert 16 bit word in X/Y into hexadecimal string into memory 'word2hex_output'
|
; ---- convert 16 bit word in X/Y into 4-character hexadecimal string into memory 'word2hex_output'
|
||||||
asm {
|
asm {
|
||||||
stx c64.SCRATCH_ZP2
|
stx c64.SCRATCH_ZP2
|
||||||
tya
|
tya
|
||||||
@ -526,6 +514,77 @@ sub word2decimal (word: XY) -> (?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; @todo string to 32 bit unsigned integer http://www.6502.org/source/strings/ascii-to-32bit.html
|
||||||
|
|
||||||
|
|
||||||
|
sub print_string (address: XY) -> (A?, Y?) {
|
||||||
|
; ---- print null terminated string from X/Y
|
||||||
|
; note: the IL65 compiler contains an optimization that will replace
|
||||||
|
; a call to this subroutine with a string argument of just one char,
|
||||||
|
; by just one call to c64.CHROUT of that single char.
|
||||||
|
asm {
|
||||||
|
stx c64.SCRATCH_ZP1
|
||||||
|
sty c64.SCRATCH_ZP2
|
||||||
|
ldy #0
|
||||||
|
- lda (c64.SCRATCH_ZP1),y
|
||||||
|
beq +
|
||||||
|
jsr c64.CHROUT
|
||||||
|
iny
|
||||||
|
bne -
|
||||||
|
+ rts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub print_pstring (address: XY) -> (A?, X?, Y) {
|
||||||
|
; ---- print pstring (length as first byte) from X/Y, returns str len in Y
|
||||||
|
asm {
|
||||||
|
stx c64.SCRATCH_ZP1
|
||||||
|
sty c64.SCRATCH_ZP2
|
||||||
|
ldy #0
|
||||||
|
lda (c64.SCRATCH_ZP1),y
|
||||||
|
beq +
|
||||||
|
tax
|
||||||
|
- iny
|
||||||
|
lda (c64.SCRATCH_ZP1),y
|
||||||
|
jsr c64.CHROUT
|
||||||
|
dex
|
||||||
|
bne -
|
||||||
|
+ rts ; output string length is in Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub print_pimmediate () -> () {
|
||||||
|
; ---- print pstring in memory immediately following the subroutine fast call instruction
|
||||||
|
; note that the clobbered registers (A,X,Y) are not listed ON PURPOSE
|
||||||
|
asm {
|
||||||
|
tsx
|
||||||
|
lda $102,x
|
||||||
|
tay ; put high byte in y
|
||||||
|
lda $101,x
|
||||||
|
tax ; and low byte in x.
|
||||||
|
inx
|
||||||
|
bne +
|
||||||
|
iny
|
||||||
|
+ jsr print_pstring ; print string in XY, returns string length in y.
|
||||||
|
tya
|
||||||
|
tsx
|
||||||
|
clc
|
||||||
|
adc $101,x ; add content of 1st (length) byte to return addr.
|
||||||
|
bcc + ; if that made the low byte roll over to 00,
|
||||||
|
inc $102,x ; then increment the high byte too.
|
||||||
|
+ clc
|
||||||
|
adc #1 ; now add 1 for the length byte itself.
|
||||||
|
sta $101,x
|
||||||
|
bne + ; if that made it (the low byte) roll over to 00,
|
||||||
|
inc $102,x ; increment the high byte of the return addr too.
|
||||||
|
+ rts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub print_byte_decimal0 (ubyte: A) -> (?) {
|
sub print_byte_decimal0 (ubyte: A) -> (?) {
|
||||||
; ---- print the byte in A in decimal form, with left padding 0s (3 positions total)
|
; ---- print the byte in A in decimal form, with left padding 0s (3 positions total)
|
||||||
asm {
|
asm {
|
||||||
@ -540,6 +599,7 @@ sub print_byte_decimal0 (ubyte: A) -> (?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub print_byte_decimal (ubyte: A) -> (?) {
|
sub print_byte_decimal (ubyte: A) -> (?) {
|
||||||
; ---- print the byte in A in decimal form, without left padding 0s
|
; ---- print the byte in A in decimal form, without left padding 0s
|
||||||
asm {
|
asm {
|
||||||
@ -560,6 +620,7 @@ _print_tens txa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub print_byte_hex (prefix: SC, ubyte: A) -> (?) {
|
sub print_byte_hex (prefix: SC, ubyte: A) -> (?) {
|
||||||
; ---- print the byte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
|
; ---- print the byte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
|
||||||
asm {
|
asm {
|
||||||
@ -576,6 +637,7 @@ sub print_byte_hex (prefix: SC, ubyte: A) -> (?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub print_word_hex (prefix: SC, word: XY) -> (?) {
|
sub print_word_hex (prefix: SC, word: XY) -> (?) {
|
||||||
; ---- print the (unsigned) word in X/Y in hexadecimal form (4 digits)
|
; ---- print the (unsigned) word in X/Y in hexadecimal form (4 digits)
|
||||||
; (if Carry is set, a radix prefix '$' is printed as well)
|
; (if Carry is set, a radix prefix '$' is printed as well)
|
||||||
@ -641,9 +703,6 @@ _pr_decimal
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; @todo string to 32 bit unsigned integer http://www.6502.org/source/strings/ascii-to-32bit.html
|
|
||||||
|
|
||||||
|
|
||||||
sub input_chars (buffer: AX) -> (A?, Y) {
|
sub input_chars (buffer: AX) -> (A?, Y) {
|
||||||
; ---- Input a string (max. 80 chars) from the keyboard.
|
; ---- Input a string (max. 80 chars) from the keyboard.
|
||||||
; It assumes the keyboard is selected as I/O channel!!
|
; It assumes the keyboard is selected as I/O channel!!
|
||||||
@ -665,6 +724,11 @@ sub input_chars (buffer: AX) -> (A?, Y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} ; ---- end block c64scr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;sub memcopy_basic () -> (?) {
|
;sub memcopy_basic () -> (?) {
|
||||||
; ; ---- copy a memory block by using a BASIC ROM routine @todo fix code
|
; ; ---- copy a memory block by using a BASIC ROM routine @todo fix code
|
||||||
; ; it calls a function from the basic interpreter, so:
|
; ; it calls a function from the basic interpreter, so:
|
||||||
@ -708,36 +772,3 @@ sub input_chars (buffer: AX) -> (A?, Y) {
|
|||||||
; stx $59
|
; stx $59
|
||||||
; jsr $a3bf
|
; jsr $a3bf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
~ c64_lib {
|
|
||||||
|
|
||||||
asm {
|
|
||||||
|
|
||||||
; ---- copy a 5 byte MFLT floating point variable to another place
|
|
||||||
; input: X/Y = source address, SCRATCH_ZPWORD1 = destination address
|
|
||||||
copy_mflt stx c64.SCRATCH_ZP1
|
|
||||||
sty c64.SCRATCH_ZPWORD1+1
|
|
||||||
ldy #0
|
|
||||||
lda (c64.SCRATCH_ZP1),y
|
|
||||||
sta (c64.SCRATCH_ZPWORD1),y
|
|
||||||
iny
|
|
||||||
lda (c64.SCRATCH_ZP1),y
|
|
||||||
sta (c64.SCRATCH_ZPWORD1),y
|
|
||||||
iny
|
|
||||||
lda (c64.SCRATCH_ZP1),y
|
|
||||||
sta (c64.SCRATCH_ZPWORD1),y
|
|
||||||
iny
|
|
||||||
lda (c64.SCRATCH_ZP1),y
|
|
||||||
sta (c64.SCRATCH_ZPWORD1),y
|
|
||||||
iny
|
|
||||||
lda (c64.SCRATCH_ZP1),y
|
|
||||||
sta (c64.SCRATCH_ZPWORD1),y
|
|
||||||
ldy c64.SCRATCH_ZPWORD1+1
|
|
||||||
rts
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
;
|
;
|
||||||
; indent format: TABS, size=8
|
; indent format: TABS, size=8
|
||||||
|
|
||||||
output raw
|
|
||||||
|
|
||||||
~ il65_lib_zp {
|
~ il65_lib_zp {
|
||||||
; note: separate block so the 64tass assembler can remove this when no zp restore is required
|
; note: separate block so the 64tass assembler can remove this when no zp restore is required
|
||||||
@ -17,9 +16,10 @@ save_zeropage
|
|||||||
sei
|
sei
|
||||||
ldx #2
|
ldx #2
|
||||||
- lda $00,x
|
- lda $00,x
|
||||||
sta zp_backup-2,x
|
sta zp_backup,x
|
||||||
inx
|
inx
|
||||||
bne -
|
bne -
|
||||||
|
cli
|
||||||
rts
|
rts
|
||||||
|
|
||||||
restore_zeropage
|
restore_zeropage
|
||||||
@ -28,6 +28,14 @@ restore_zeropage
|
|||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
sei
|
sei
|
||||||
|
|
||||||
|
lda $a0 ; save the current jiffy clock
|
||||||
|
sta zp_backup+$a0
|
||||||
|
lda $a1
|
||||||
|
sta zp_backup+$a1
|
||||||
|
lda $a2
|
||||||
|
sta zp_backup+$a2
|
||||||
|
|
||||||
ldx #2
|
ldx #2
|
||||||
- lda zp_backup-2,x
|
- lda zp_backup-2,x
|
||||||
sta $00,x
|
sta $00,x
|
||||||
@ -40,7 +48,7 @@ restore_zeropage
|
|||||||
plp
|
plp
|
||||||
rts
|
rts
|
||||||
|
|
||||||
zp_backup .fill 254, 0
|
zp_backup .fill 256, 0
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,4 +95,30 @@ jsr_indirect_XY
|
|||||||
jmp (SCRATCH_ZP1)
|
jmp (SCRATCH_ZP1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
asm {
|
||||||
|
|
||||||
|
; ---- copy a 5 byte MFLT floating point variable to another place
|
||||||
|
; input: X/Y = source address, SCRATCH_ZPWORD1 = destination address
|
||||||
|
copy_mflt stx SCRATCH_ZP1
|
||||||
|
sty SCRATCH_ZPWORD1+1
|
||||||
|
ldy #0
|
||||||
|
lda (SCRATCH_ZP1),y
|
||||||
|
sta (SCRATCH_ZPWORD1),y
|
||||||
|
iny
|
||||||
|
lda (SCRATCH_ZP1),y
|
||||||
|
sta (SCRATCH_ZPWORD1),y
|
||||||
|
iny
|
||||||
|
lda (SCRATCH_ZP1),y
|
||||||
|
sta (SCRATCH_ZPWORD1),y
|
||||||
|
iny
|
||||||
|
lda (SCRATCH_ZP1),y
|
||||||
|
sta (SCRATCH_ZPWORD1),y
|
||||||
|
iny
|
||||||
|
lda (SCRATCH_ZP1),y
|
||||||
|
sta (SCRATCH_ZPWORD1),y
|
||||||
|
ldy SCRATCH_ZPWORD1+1
|
||||||
|
rts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
; IL65 integer math library for 6502
|
; IL65 integer math library for 6502
|
||||||
; (floating point math is done via the C-64's BASIC ROM routines)
|
; (floating point math is done via the C-64's BASIC ROM routines)
|
||||||
;
|
;
|
||||||
; some more interesting routines can be found here http://6502org.wikidot.com/software-math
|
; some more interesting routines can be found here:
|
||||||
|
; http://6502org.wikidot.com/software-math
|
||||||
|
; http://codebase64.org/doku.php?id=base:6502_6510_maths
|
||||||
;
|
;
|
||||||
; Written by Irmen de Jong (irmen@razorvine.net)
|
; Written by Irmen de Jong (irmen@razorvine.net)
|
||||||
; License: GNU GPL 3.0, see LICENSE
|
; License: GNU GPL 3.0, see LICENSE
|
||||||
@ -9,8 +11,6 @@
|
|||||||
; indent format: TABS, size=8
|
; indent format: TABS, size=8
|
||||||
|
|
||||||
|
|
||||||
output raw
|
|
||||||
|
|
||||||
~ math {
|
~ math {
|
||||||
; note: the following ZP scratch registers must be the same as in c64lib
|
; note: the following ZP scratch registers must be the same as in c64lib
|
||||||
memory .byte SCRATCH_ZP1 = $02 ; scratch register #1 in ZP
|
memory .byte SCRATCH_ZP1 = $02 ; scratch register #1 in ZP
|
||||||
|
36
reference.md
36
reference.md
@ -102,11 +102,22 @@ The four reserved locations mentioned above are subtracted from this set, leavin
|
|||||||
five 1-byte and two 2-byte usable zero page registers.
|
five 1-byte and two 2-byte usable zero page registers.
|
||||||
IL65 knows about all this: it will use the above zero page locations to place its ZP variables in,
|
IL65 knows about all this: it will use the above zero page locations to place its ZP variables in,
|
||||||
until they're all used up. You can instruct it to treat your program as taking over the entire
|
until they're all used up. You can instruct it to treat your program as taking over the entire
|
||||||
machine, in which case all of the zero page locations are suddenly available for variables.
|
machine, in which case (almost) all of the zero page locations are suddenly available for variables.
|
||||||
IL65 can generate a special routine that saves and restores the zero page to let your program run
|
IL65 can generate a special routine that saves and restores the zero page to let your program run
|
||||||
and return safely back to the system afterwards - you don't have to take care of that yourself.
|
and return safely back to the system afterwards - you don't have to take care of that yourself.
|
||||||
|
|
||||||
@todo some global way (in ZP block) to promote certian other blocks/variables from that block or even
|
**IRQ and the Zero page:**
|
||||||
|
|
||||||
|
The normal IRQ routine in the C-64's kernal will read and write several locations in the zero page:
|
||||||
|
|
||||||
|
``$a0 - $a2``; ``$91``; ``$c0``; ``$c5``; ``$cb``; ``$f5 - $f6``
|
||||||
|
|
||||||
|
These locations will not be used by the compiler for zero page variables, so your variables will
|
||||||
|
not interfere with the IRQ routine and vice versa. This is true for the normal zp mode but also
|
||||||
|
for the mode where the whole zp has been taken over.
|
||||||
|
|
||||||
|
|
||||||
|
@todo: some global way (in ZP block) to promote certian other blocks/variables from that block or even
|
||||||
subroutine to the zeropage. Don't do this in the block itself because it's a global optimization
|
subroutine to the zeropage. Don't do this in the block itself because it's a global optimization
|
||||||
and if blocks require it themselves you can't combine various modules anymore once ZP runs out.
|
and if blocks require it themselves you can't combine various modules anymore once ZP runs out.
|
||||||
|
|
||||||
@ -198,18 +209,15 @@ However you can specify some options globally in your program to change this beh
|
|||||||
be stored in the ZP, which is more efficient.
|
be stored in the ZP, which is more efficient.
|
||||||
- ``zp clobber, restore``
|
- ``zp clobber, restore``
|
||||||
Use the whole zeropage, but make a backup copy of the original values at program start.
|
Use the whole zeropage, but make a backup copy of the original values at program start.
|
||||||
When your program exits, the original ZP is restored and you drop back to the BASIC prompt.
|
When your program exits, the original ZP is restored (except for the software jiffy clock
|
||||||
Not that the interrupts are *disabled* when your program is entered!
|
in ``$a0 - $a2``) and you drop back to the BASIC prompt.
|
||||||
(you want/have to set your own IRQ routine because the default one will write to
|
Not that the default IRQ routine is *still enabled* when your program is entered!
|
||||||
various locations in the zeropage)
|
See the paragraph on the zero page for more info about this.
|
||||||
|
|
||||||
If you use ``zp clobber``, you can no longer use BASIC or KERNAL routines,
|
If you use ``zp clobber``, you can no longer use most BASIC or KERNAL routines,
|
||||||
because these depend on most of the locations in the ZP. This includes most of the floating-point
|
because these depend on most of the locations in the ZP. This includes the floating-point
|
||||||
logic and several utility routines that do I/O, such as ``print_string``.
|
logic and several utility routines that do I/O, such as ``print_string``.
|
||||||
|
|
||||||
@todo default IRQ handling will still change certain values in ZP...
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Program Entry Point
|
### Program Entry Point
|
||||||
|
|
||||||
@ -376,6 +384,12 @@ if-statuses can be used when such a *comparison expression* is used. An example
|
|||||||
``if_not A > 55 goto more_iterations``
|
``if_not A > 55 goto more_iterations``
|
||||||
|
|
||||||
|
|
||||||
|
Conditional jumps are compiled into 6502's branching instructions (such as ``bne`` and ``bcc``) so
|
||||||
|
the rather strict limit on how *far* it can jump applies. The compiler itself can't figure this
|
||||||
|
out unfortunately, so it is entirely possible to create code that cannot be assembled successfully.
|
||||||
|
You'll have to restructure your gotos in the code (place target labels closer to the branch)
|
||||||
|
if you run into this type of assembler error.
|
||||||
|
|
||||||
|
|
||||||
Debugging (with Vice)
|
Debugging (with Vice)
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -38,14 +38,20 @@ def test_zp_noclobber_allocation():
|
|||||||
def test_zp_clobber_allocation():
|
def test_zp_clobber_allocation():
|
||||||
zp = Zeropage()
|
zp = Zeropage()
|
||||||
zp.configure(True)
|
zp.configure(True)
|
||||||
assert zp.available() == 248
|
assert zp.available() == 239
|
||||||
loc = zp.allocate("", DataType.FLOAT)
|
loc = zp.allocate("", DataType.FLOAT)
|
||||||
assert loc > 3 and loc not in zp.free
|
assert loc > 3 and loc not in zp.free
|
||||||
num, rest = divmod(zp.available(), 5)
|
num, rest = divmod(zp.available(), 5)
|
||||||
for _ in range(num):
|
for _ in range(num-3):
|
||||||
zp.allocate("", DataType.FLOAT)
|
zp.allocate("", DataType.FLOAT)
|
||||||
assert zp.available() == rest
|
assert zp.available() == 19
|
||||||
for _ in range(rest // 2):
|
with pytest.raises(LookupError):
|
||||||
|
zp.allocate("", DataType.FLOAT) # can't allocate because no more sequential bytes, only fragmented
|
||||||
|
for _ in range(14):
|
||||||
|
zp.allocate("", DataType.BYTE)
|
||||||
|
zp.allocate("", DataType.WORD)
|
||||||
|
zp.allocate("", DataType.WORD)
|
||||||
|
with pytest.raises(LookupError):
|
||||||
zp.allocate("", DataType.WORD)
|
zp.allocate("", DataType.WORD)
|
||||||
assert zp.available() == 1
|
assert zp.available() == 1
|
||||||
zp.allocate("last", DataType.BYTE)
|
zp.allocate("last", DataType.BYTE)
|
||||||
|
@ -88,11 +88,11 @@ label4
|
|||||||
|
|
||||||
|
|
||||||
start
|
start
|
||||||
c64util.init_system()
|
c64.init_system()
|
||||||
|
|
||||||
A = 0
|
A = 0
|
||||||
printloop
|
printloop
|
||||||
c64util.print_byte_decimal(A)
|
c64scr.print_byte_decimal(A)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
A++
|
A++
|
||||||
if A <20 goto printloop
|
if A <20 goto printloop
|
||||||
|
@ -47,7 +47,7 @@ sub printflt (float: AY) -> (?) {
|
|||||||
c64.MOVFM!(AY)
|
c64.MOVFM!(AY)
|
||||||
goto c64.FPRINTLN
|
goto c64.FPRINTLN
|
||||||
; c64.FOUT!()
|
; c64.FOUT!()
|
||||||
; c64util.print_string!(AY)
|
; c64scr.print_string!(AY)
|
||||||
;goto c64.CHROUT('\n')
|
;goto c64.CHROUT('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import "c64lib"
|
|||||||
var .text name = "?"*80
|
var .text name = "?"*80
|
||||||
|
|
||||||
start
|
start
|
||||||
c64util.init_system()
|
c64.init_system()
|
||||||
|
|
||||||
XY = c64.CINV
|
XY = c64.CINV
|
||||||
SI = 1
|
SI = 1
|
||||||
@ -14,15 +14,15 @@ start
|
|||||||
SI = 0
|
SI = 0
|
||||||
|
|
||||||
|
|
||||||
c64util.print_string("enter your name: ")
|
c64scr.print_string("enter your name: ")
|
||||||
c64util.input_chars(name)
|
c64scr.input_chars(name)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
blop
|
blop
|
||||||
breakpoint ; yeah!
|
breakpoint ; yeah!
|
||||||
|
|
||||||
c64util.print_string("thank you, mr or mrs: ")
|
c64scr.print_string("thank you, mr or mrs: ")
|
||||||
c64util.print_string(name)
|
c64scr.print_string(name)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
SI = 1
|
SI = 1
|
||||||
|
@ -13,19 +13,19 @@ import "c64lib"
|
|||||||
|
|
||||||
|
|
||||||
start
|
start
|
||||||
c64util.init_system()
|
c64.init_system()
|
||||||
|
|
||||||
A = c64.VMCSB
|
A = c64.VMCSB
|
||||||
A |= 2 ; @todo c64.VMCSB |= 2
|
A |= 2 ; @todo c64.VMCSB |= 2
|
||||||
c64.VMCSB = A
|
c64.VMCSB = A
|
||||||
|
|
||||||
; greeting
|
; greeting
|
||||||
c64util.print_string("Enter your name: ")
|
c64scr.print_string("Enter your name: ")
|
||||||
Y = c64util.input_chars(name)
|
Y = c64scr.input_chars(name)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
c64util.print_string("Hello, ")
|
c64scr.print_string("Hello, ")
|
||||||
c64util.print_string(name)
|
c64scr.print_string(name)
|
||||||
c64.CHROUT('.')
|
c64.CHROUT('.')
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
@ -35,43 +35,43 @@ start
|
|||||||
c64.MUL10()
|
c64.MUL10()
|
||||||
c64.FADDH()
|
c64.FADDH()
|
||||||
c64.FADDH()
|
c64.FADDH()
|
||||||
AY = c64util.GETADRAY()
|
AY = c64.GETADRAY()
|
||||||
secretnumber = A
|
secretnumber = A
|
||||||
|
|
||||||
c64util.print_string("I am thinking of a number from 1 to 100!You'll have to guess it!\n")
|
c64scr.print_string("I am thinking of a number from 1 to 100!You'll have to guess it!\n")
|
||||||
|
|
||||||
printloop
|
printloop
|
||||||
c64util.print_string("\nYou have ")
|
c64scr.print_string("\nYou have ")
|
||||||
c64util.print_byte_decimal(attempts_left)
|
c64scr.print_byte_decimal(attempts_left)
|
||||||
c64util.print_string(" guess")
|
c64scr.print_string(" guess")
|
||||||
|
|
||||||
; @todo comparison expression so we can do if attempts_left>0 ...
|
; @todo comparison expression so we can do if attempts_left>0 ...
|
||||||
A = attempts_left
|
A = attempts_left
|
||||||
A--
|
A--
|
||||||
if_zero A goto ask_guess
|
if_zero A goto ask_guess
|
||||||
c64util.print_string("es")
|
c64scr.print_string("es")
|
||||||
ask_guess
|
ask_guess
|
||||||
c64util.print_string(" left.\nWhat is your next guess? ")
|
c64scr.print_string(" left.\nWhat is your next guess? ")
|
||||||
Y = c64util.input_chars(guess)
|
Y = c64scr.input_chars(guess)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
[$22.word] = guess
|
[$22.word] = guess
|
||||||
c64.FREADSTR(A)
|
c64.FREADSTR(A)
|
||||||
AY = c64util.GETADRAY()
|
AY = c64.GETADRAY()
|
||||||
A -= secretnumber ; @todo condition so we can do if guess > secretnumber....
|
A -= secretnumber ; @todo condition so we can do if guess > secretnumber....
|
||||||
if_zero goto correct_guess
|
if_zero goto correct_guess
|
||||||
if_gt goto too_high
|
if_gt goto too_high
|
||||||
c64util.print_string("That is too ")
|
c64scr.print_string("That is too ")
|
||||||
c64util.print_string("low!\n")
|
c64scr.print_string("low!\n")
|
||||||
goto continue
|
goto continue
|
||||||
|
|
||||||
correct_guess
|
correct_guess
|
||||||
c64util.print_string("\nThat's my number, impressive!\n")
|
c64scr.print_string("\nThat's my number, impressive!\n")
|
||||||
goodbye()
|
goodbye()
|
||||||
return
|
return
|
||||||
|
|
||||||
too_high
|
too_high
|
||||||
c64util.print_string("That is too ")
|
c64scr.print_string("That is too ")
|
||||||
c64util.print_string("high!\n")
|
c64scr.print_string("high!\n")
|
||||||
|
|
||||||
continue
|
continue
|
||||||
attempts_left--
|
attempts_left--
|
||||||
@ -79,8 +79,8 @@ continue
|
|||||||
goto printloop
|
goto printloop
|
||||||
|
|
||||||
game_over
|
game_over
|
||||||
c64util.print_string("\nToo bad! It was: ")
|
c64scr.print_string("\nToo bad! It was: ")
|
||||||
c64util.print_byte_decimal(secretnumber)
|
c64scr.print_byte_decimal(secretnumber)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
goodbye()
|
goodbye()
|
||||||
return
|
return
|
||||||
@ -90,7 +90,7 @@ sub goodbye ()->() {
|
|||||||
;memory y = $c000 ; @todo vars in sub
|
;memory y = $c000 ; @todo vars in sub
|
||||||
;const q = 22 ; @todo const in sub
|
;const q = 22 ; @todo const in sub
|
||||||
|
|
||||||
c64util.print_string("\nThanks for playing. Bye!\n")
|
c64scr.print_string("\nThanks for playing. Bye!\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ start
|
|||||||
c64.CHROUT('0')
|
c64.CHROUT('0')
|
||||||
c64.CHROUT('1')
|
c64.CHROUT('1')
|
||||||
c64.CHROUT('2')
|
c64.CHROUT('2')
|
||||||
c64util.print_string(hello)
|
c64scr.print_string(hello)
|
||||||
goto c64.CHROUT('!')
|
goto c64.CHROUT('!')
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,41 +9,41 @@ output prg,basic ; create a c-64 program with basic SYS to() launch it
|
|||||||
const .word BORDER = $d020
|
const .word BORDER = $d020
|
||||||
|
|
||||||
start
|
start
|
||||||
c64util.print_pimmediate ! () ; this prints the pstring immediately following it
|
c64scr.print_pimmediate ! () ; this prints the pstring immediately following it
|
||||||
asm {
|
asm {
|
||||||
.ptext "hello-pimmediate!{cr}"
|
.ptext "hello-pimmediate!{cr}"
|
||||||
}
|
}
|
||||||
|
|
||||||
c64util.print_byte_decimal0 ! (19)
|
c64scr.print_byte_decimal0 ! (19)
|
||||||
c64.CHROUT ! (13)
|
c64.CHROUT ! (13)
|
||||||
c64util.print_byte_decimal ! (19)
|
c64scr.print_byte_decimal ! (19)
|
||||||
c64.CHROUT ! (13)
|
c64.CHROUT ! (13)
|
||||||
|
|
||||||
|
|
||||||
c64util.print_word_decimal0 ! ($0102)
|
c64scr.print_word_decimal0 ! ($0102)
|
||||||
c64.CHROUT ! (13)
|
c64.CHROUT ! (13)
|
||||||
c64util.print_word_decimal ! ($0102)
|
c64scr.print_word_decimal ! ($0102)
|
||||||
c64.CHROUT ! (13)
|
c64.CHROUT ! (13)
|
||||||
return
|
return
|
||||||
|
|
||||||
start2
|
start2
|
||||||
global2.make_screen_black()
|
global2.make_screen_black()
|
||||||
c64.CLEARSCR()
|
c64.CLEARSCR()
|
||||||
c64util.print_string(greeting)
|
c64scr.print_string(greeting)
|
||||||
c64util.print_pstring(p_greeting)
|
c64scr.print_pstring(p_greeting)
|
||||||
c64util.print_byte_decimal(0)
|
c64scr.print_byte_decimal(0)
|
||||||
c64util.print_byte_hex(0, 0)
|
c64scr.print_byte_hex(0, 0)
|
||||||
c64.CHROUT(13)
|
c64.CHROUT(13)
|
||||||
c64util.print_byte_decimal(13)
|
c64scr.print_byte_decimal(13)
|
||||||
c64util.print_byte_hex(0, 13)
|
c64scr.print_byte_hex(0, 13)
|
||||||
c64.CHROUT(13)
|
c64.CHROUT(13)
|
||||||
c64util.print_byte_decimal(255)
|
c64scr.print_byte_decimal(255)
|
||||||
c64util.print_byte_hex(0, 254)
|
c64scr.print_byte_hex(0, 254)
|
||||||
c64util.print_byte_hex(0, 129)
|
c64scr.print_byte_hex(0, 129)
|
||||||
c64.CHROUT(13)
|
c64.CHROUT(13)
|
||||||
|
|
||||||
c64.CHROUT(13)
|
c64.CHROUT(13)
|
||||||
c64util.print_word_decimal($0100)
|
c64scr.print_word_decimal($0100)
|
||||||
c64.CHROUT(13)
|
c64.CHROUT(13)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
49
todo.ill
49
todo.ill
@ -1,48 +1,27 @@
|
|||||||
output prg,basic
|
output prg,basic
|
||||||
zp clobber, restore
|
|
||||||
|
|
||||||
;reg_preserve off ; @todo global option off/on default off?
|
;reg_preserve off ; @todo global option off/on default off?
|
||||||
|
|
||||||
import "c64lib"
|
import "c64lib"
|
||||||
|
|
||||||
~ ZP {
|
|
||||||
var .float fl1 = 3.1415927
|
|
||||||
var .float fl2 = 99.999999
|
|
||||||
var .float fl3 = 100000
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
var .float fl1 = 3.1415927
|
|
||||||
var .float fl2 = 99.999999
|
|
||||||
var .float fl3 = 10
|
|
||||||
|
|
||||||
start
|
start
|
||||||
fl1 = 111111.22222
|
A = $11
|
||||||
fl2 = 0
|
X = $22
|
||||||
fl3 = 1
|
Y = $33
|
||||||
fl3 = -1
|
|
||||||
fl3 = 0.5
|
|
||||||
fl3 = -0.5
|
|
||||||
|
|
||||||
X=6
|
c64scr.clear_screen !(81, 5, $04)
|
||||||
loop1
|
;c64scr.clear_screen !A (81, 5, $04)
|
||||||
A=X
|
;c64scr.clear_screen !AX (81, 5, $04)
|
||||||
c64util.print_byte_hex(0, A)
|
;c64scr.clear_screen !AXY (81, 5, $04)
|
||||||
c64.CHROUT!(" ")
|
|
||||||
X--
|
|
||||||
if_pos goto loop1
|
|
||||||
|
|
||||||
Y=6
|
c64scr.print_byte_hex(1,A)
|
||||||
loop2
|
c64.CHROUT(' ')
|
||||||
A=Y
|
c64scr.print_byte_hex(1,X)
|
||||||
c64util.print_byte_hex(0, A)
|
c64.CHROUT(' ')
|
||||||
c64.CHROUT!(" ")
|
c64scr.print_byte_hex(1,Y)
|
||||||
Y--
|
c64scr.print_word_decimal(1222)
|
||||||
if_neg goto stop
|
c64.CHROUT('\n')
|
||||||
goto loop2
|
|
||||||
|
|
||||||
stop
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user