mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
cbm.STOP2() and cbm.GETIN2() convenience routines
This commit is contained in:
parent
88ae3daa42
commit
66a6659a6e
@ -66,7 +66,7 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
|
||||
if(node.type in SplitWordArrayTypes && (lookupName.endsWith("_lsb") || lookupName.endsWith("_msb"))) {
|
||||
lookupName = lookupName.dropLast(4)
|
||||
}
|
||||
val stNode = st.lookup(lookupName)!!
|
||||
val stNode = st.lookup(lookupName) ?: throw AssemblyError("unknown identifier $node")
|
||||
if(stNode.astNode.definingBlock()?.options?.noSymbolPrefixing!=true) {
|
||||
val index = node.parent.children.indexOf(node)
|
||||
nodesToPrefix += node.parent to index
|
||||
|
@ -93,8 +93,8 @@ romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A
|
||||
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
|
||||
romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock
|
||||
romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high)
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A)
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2
|
||||
romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files
|
||||
romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock
|
||||
romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns
|
||||
@ -105,6 +105,23 @@ romsub $FFF3 = IOBASE() -> uword @ XY ; read base addr
|
||||
|
||||
; ---- utilities -----
|
||||
|
||||
inline asmsub STOP2() clobbers(X,A) -> bool @Pz {
|
||||
; -- just like STOP, but omits the special keys result value in A.
|
||||
; just for convenience because most of the times you're only interested in the stop pressed or not status.
|
||||
%asm {{
|
||||
jsr cbm.STOP
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub GETIN2() clobbers(X,Y) -> ubyte @A {
|
||||
; -- just like GETIN, but omits the carry flag result value.
|
||||
; just for convenience because GETIN is so often used to just read keyboard input,
|
||||
; where you don't have to deal with a potential error status
|
||||
%asm {{
|
||||
jsr cbm.GETIN
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub RDTIM16() clobbers(X) -> uword @AY {
|
||||
; -- like RDTIM() but only returning the lower 16 bits in AY for convenience
|
||||
%asm {{
|
||||
|
@ -94,14 +94,32 @@ romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A
|
||||
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
|
||||
romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock
|
||||
romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high)
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A)
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2
|
||||
romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files
|
||||
romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock
|
||||
romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns
|
||||
romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X.
|
||||
romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices
|
||||
|
||||
|
||||
inline asmsub STOP2() clobbers(X,A) -> bool @Pz {
|
||||
; -- just like STOP, but omits the special keys result value in A.
|
||||
; just for convenience because most of the times you're only interested in the stop pressed or not status.
|
||||
%asm {{
|
||||
jsr cbm.STOP
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub GETIN2() clobbers(X,Y) -> ubyte @A {
|
||||
; -- just like GETIN, but omits the carry flag result value.
|
||||
; just for convenience because GETIN is so often used to just read keyboard input,
|
||||
; where you don't have to deal with a potential error status
|
||||
%asm {{
|
||||
jsr cbm.GETIN
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub RDTIM16() clobbers(X) -> uword @AY {
|
||||
; -- like RDTIM() but only returning the lower 16 bits in AY for convenience
|
||||
%asm {{
|
||||
|
@ -43,8 +43,8 @@ romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A
|
||||
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) clobbers (X, Y) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device. See also BSAVE
|
||||
romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock
|
||||
romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (in little endian order: A=lo,X=mid,Y=high) , however use RDTIM_safe() instead
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A)
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2
|
||||
romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files
|
||||
romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock
|
||||
romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns
|
||||
@ -53,6 +53,23 @@ romsub $FFF3 = IOBASE() -> uword @ XY ; read base addr
|
||||
|
||||
; ---- utility
|
||||
|
||||
inline asmsub STOP2() clobbers(X,A) -> bool @Pz {
|
||||
; -- just like STOP, but omits the special keys result value in A.
|
||||
; just for convenience because most of the times you're only interested in the stop pressed or not status.
|
||||
%asm {{
|
||||
jsr cbm.STOP
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub GETIN2() clobbers(X,Y) -> ubyte @A {
|
||||
; -- just like GETIN, but omits the carry flag result value.
|
||||
; just for convenience because GETIN is so often used to just read keyboard input,
|
||||
; where you don't have to deal with a potential error status
|
||||
%asm {{
|
||||
jsr cbm.GETIN
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub RDTIM_safe() -> ubyte @ A, ubyte @ X, ubyte @ Y {
|
||||
; -- read the software clock (in little endian order: A=lo,X=mid,Y=high)
|
||||
; with safeguard for ram bank issue for irqs.
|
||||
|
@ -29,11 +29,29 @@ romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; define an outp
|
||||
romsub $FFCC = CLRCHN() clobbers(A,X) ; restore default devices
|
||||
romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; input a character (for keyboard, read a whole line from the screen) A=byte read.
|
||||
romsub $FFD2 = CHROUT(ubyte character @ A) ; output a character
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; check the STOP key (and some others in A)
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; get a character
|
||||
romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; check the STOP key (and some others in A) also see STOP2
|
||||
romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; get a character also see GETIN2
|
||||
romsub $FFE7 = CLALL() clobbers(A,X) ; close all files
|
||||
romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock
|
||||
|
||||
|
||||
inline asmsub STOP2() clobbers(X,A) -> bool @Pz {
|
||||
; -- just like STOP, but omits the special keys result value in A.
|
||||
; just for convenience because most of the times you're only interested in the stop pressed or not status.
|
||||
%asm {{
|
||||
jsr cbm.STOP
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub GETIN2() clobbers(X,Y) -> ubyte @A {
|
||||
; -- just like GETIN, but omits the carry flag result value.
|
||||
; just for convenience because GETIN is so often used to just read keyboard input,
|
||||
; where you don't have to deal with a potential error status
|
||||
%asm {{
|
||||
jsr cbm.GETIN
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) {
|
||||
; PET stub to set the software clock
|
||||
%asm {{
|
||||
|
@ -12,6 +12,9 @@ import prog8.ast.ParentSentinel
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
import prog8.code.ast.PtAssignTarget
|
||||
import prog8.code.ast.PtAssignment
|
||||
import prog8.code.ast.PtFunctionCall
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Position
|
||||
import prog8.code.target.C64Target
|
||||
@ -972,4 +975,59 @@ main {
|
||||
(right2.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_read")
|
||||
(right3.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_read")
|
||||
}
|
||||
|
||||
test("eliminate same target register assignments") {
|
||||
val src="""
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
romsub ${'$'}2000 = func1() clobbers(X) -> ubyte @A, word @R0, byte @R1
|
||||
romsub ${'$'}3000 = func2() clobbers(X) -> ubyte @A, uword @R0, uword @R1
|
||||
romsub ${'$'}4000 = func3() clobbers(X) -> ubyte @R0
|
||||
|
||||
sub start() {
|
||||
bool flag
|
||||
void cbm.GETIN()
|
||||
flag, cx16.r1L = cbm.GETIN()
|
||||
void, cx16.r0s, cx16.r1sL = func1()
|
||||
void, cx16.r2, cx16.r1 = func2()
|
||||
cx16.r0L = func3()
|
||||
cx16.r0H = func3()
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), true, src, writeAssembly = true)!!
|
||||
val st = result.codegenAst!!.entrypoint()!!.children
|
||||
st.size shouldBe 9
|
||||
(st[2] as PtFunctionCall).name shouldBe "cbm.GETIN"
|
||||
(st[2] as PtFunctionCall).void shouldBe true
|
||||
val a1 = st[3] as PtAssignment
|
||||
(a1.value as PtFunctionCall).name shouldBe "cbm.GETIN"
|
||||
a1.multiTarget shouldBe true
|
||||
a1.children.size shouldBe 3
|
||||
(a1.children[0] as PtAssignTarget).void shouldBe false
|
||||
(a1.children[0] as PtAssignTarget).identifier!!.name shouldBe "p8b_main.p8s_start.p8v_flag"
|
||||
(a1.children[1] as PtAssignTarget).void shouldBe false
|
||||
(a1.children[1] as PtAssignTarget).identifier!!.name shouldBe "cx16.r1L"
|
||||
|
||||
(st[4] as PtFunctionCall).name shouldBe "p8b_main.p8s_func1"
|
||||
(st[4] as PtFunctionCall).void shouldBe true
|
||||
val a2 = st[5] as PtAssignment
|
||||
(a2.value as PtFunctionCall).name shouldBe "p8b_main.p8s_func2"
|
||||
a2.multiTarget shouldBe true
|
||||
a2.children.size shouldBe 4
|
||||
(a2.children[0] as PtAssignTarget).void shouldBe true
|
||||
(a2.children[1] as PtAssignTarget).void shouldBe false
|
||||
(a2.children[1] as PtAssignTarget).identifier!!.name shouldBe "cx16.r2"
|
||||
(a2.children[2] as PtAssignTarget).void shouldBe true
|
||||
|
||||
(st[6] as PtFunctionCall).name shouldBe "p8b_main.p8s_func3"
|
||||
(st[6] as PtFunctionCall).void shouldBe true
|
||||
val a3 = st[7] as PtAssignment
|
||||
(a3.value as PtFunctionCall).name shouldBe "p8b_main.p8s_func3"
|
||||
a3.multiTarget shouldBe false
|
||||
a3.children.size shouldBe 2
|
||||
(a3.children[0] as PtAssignTarget).void shouldBe false
|
||||
(a3.children[0] as PtAssignTarget).identifier!!.name shouldBe "cx16.r0H"
|
||||
}
|
||||
})
|
||||
|
@ -1,7 +1,10 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
add unit test for what's now in test.p8 (multi assign stuff)
|
||||
imageviewer is a lot larger now?
|
||||
|
||||
fix compiler crash for assembler: unknown identifier [PtIdentifier:parser.proces_directive_str.prog8_subexprvar_1 UBYTE [src/assembler.p8: line 875 col 29-29]]
|
||||
fix similar crash for petaxian
|
||||
|
||||
check docs on assign about status register in assignment (can no longer be ignored, use void to not assign it)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user