mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
asm-subroutines that ONLY return a value in the Carry or Overflow status register can now be used in an assignment to store that value.
This commit is contained in:
parent
bba4f84503
commit
5a2f8fdfe1
@ -95,9 +95,9 @@ enum class RegisterOrPair {
|
|||||||
|
|
||||||
enum class Statusflag {
|
enum class Statusflag {
|
||||||
Pc,
|
Pc,
|
||||||
Pz,
|
Pz, // don't use
|
||||||
Pv,
|
Pv,
|
||||||
Pn;
|
Pn; // don't use
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val names by lazy { values().map { it.toString()} }
|
val names by lazy { values().map { it.toString()} }
|
||||||
|
@ -150,7 +150,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
|||||||
is FunctionCall -> {
|
is FunctionCall -> {
|
||||||
when (val sub = value.target.targetStatement(program.namespace)) {
|
when (val sub = value.target.targetStatement(program.namespace)) {
|
||||||
is Subroutine -> {
|
is Subroutine -> {
|
||||||
val returnType = sub.returntypes.zip(sub.asmReturnvaluesRegisters).firstOrNull { rr -> rr.second.registerOrPair != null }?.first
|
val returnType = sub.returntypes.zip(sub.asmReturnvaluesRegisters).firstOrNull { rr -> rr.second.registerOrPair != null || rr.second.statusflag!=null }?.first
|
||||||
?: throw AssemblyError("can't translate zero return values in assignment")
|
?: throw AssemblyError("can't translate zero return values in assignment")
|
||||||
|
|
||||||
AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, returnType, expression = value)
|
AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, returnType, expression = value)
|
||||||
|
@ -143,7 +143,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when (val sub = value.target.targetStatement(program.namespace)) {
|
when (val sub = value.target.targetStatement(program.namespace)) {
|
||||||
is Subroutine -> {
|
is Subroutine -> {
|
||||||
asmgen.translateFunctionCall(value)
|
asmgen.translateFunctionCall(value)
|
||||||
val returnValue = sub.returntypes.zip(sub.asmReturnvaluesRegisters).single { it.second.registerOrPair!=null }
|
val returnValue = sub.returntypes.zip(sub.asmReturnvaluesRegisters).singleOrNull { it.second.registerOrPair!=null } ?:
|
||||||
|
sub.returntypes.zip(sub.asmReturnvaluesRegisters).single { it.second.statusflag!=null }
|
||||||
when (returnValue.first) {
|
when (returnValue.first) {
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
when(assign.target.datatype) {
|
when(assign.target.datatype) {
|
||||||
@ -177,7 +178,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
RegisterOrPair.AX -> assignRegisterpairWord(assign.target, RegisterOrPair.AX)
|
RegisterOrPair.AX -> assignRegisterpairWord(assign.target, RegisterOrPair.AX)
|
||||||
RegisterOrPair.AY -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
RegisterOrPair.AY -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
RegisterOrPair.XY -> assignRegisterpairWord(assign.target, RegisterOrPair.XY)
|
RegisterOrPair.XY -> assignRegisterpairWord(assign.target, RegisterOrPair.XY)
|
||||||
else -> throw AssemblyError("should be just one register byte result value")
|
else -> {
|
||||||
|
val sflag = returnValue.second.statusflag
|
||||||
|
if(sflag!=null)
|
||||||
|
assignStatusFlagByte(assign.target, sflag)
|
||||||
|
else
|
||||||
|
throw AssemblyError("should be just one register byte result value")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,6 +235,24 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun assignStatusFlagByte(target: AsmAssignTarget, statusflag: Statusflag) {
|
||||||
|
when(statusflag) {
|
||||||
|
Statusflag.Pc -> {
|
||||||
|
asmgen.out(" lda #0 | rol a")
|
||||||
|
}
|
||||||
|
Statusflag.Pv -> {
|
||||||
|
asmgen.out("""
|
||||||
|
bvs +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("can't use Z or N flags as return 'values'")
|
||||||
|
}
|
||||||
|
assignRegisterByte(target, CpuRegister.A)
|
||||||
|
}
|
||||||
|
|
||||||
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: Expression, origTypeCastExpression: TypecastExpression) {
|
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: Expression, origTypeCastExpression: TypecastExpression) {
|
||||||
val valueIDt = value.inferType(program)
|
val valueIDt = value.inferType(program)
|
||||||
if(!valueIDt.isKnown)
|
if(!valueIDt.isKnown)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- Cx16 target: support full-screen 640x480 and 320x240 graphics? That requires our own custom graphics routines though to draw lines.
|
- Cx16 target: support full-screen 640x480 and 320x240 graphics? That requires our own custom graphics routines though to draw lines, and plot pixels.
|
||||||
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
||||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
||||||
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
||||||
|
@ -8,98 +8,12 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
;romsub $ff14 = FB_set_8_pixels_opaque(ubyte pattern @R0, ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y)
|
|
||||||
;romsub $ff14 = FB_set_8_pixels_opaque_OLD(ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y)
|
|
||||||
|
|
||||||
asmsub set_8_pixels_opaque(ubyte pattern @R0, ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y) {
|
|
||||||
|
|
||||||
%asm {{
|
|
||||||
sta _a
|
|
||||||
stx _x
|
|
||||||
sty _y
|
|
||||||
|
|
||||||
lda _a
|
|
||||||
jsr txt.print_ub
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
lda _x
|
|
||||||
jsr txt.print_ub
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
lda _y
|
|
||||||
jsr txt.print_ub
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
lda cx16.r0
|
|
||||||
ldy cx16.r0+1
|
|
||||||
jsr txt.print_uw
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
rts
|
|
||||||
|
|
||||||
_a .byte 0
|
|
||||||
_x .byte 0
|
|
||||||
_y .byte 0
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
asmsub set_8_pixels_opaque_OLD(ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y) {
|
|
||||||
%asm {{
|
|
||||||
sta _a
|
|
||||||
stx _x
|
|
||||||
sty _y
|
|
||||||
|
|
||||||
lda _a
|
|
||||||
jsr txt.print_ub
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
lda _x
|
|
||||||
jsr txt.print_ub
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
lda _y
|
|
||||||
jsr txt.print_ub
|
|
||||||
lda #13
|
|
||||||
jsr c64.CHROUT
|
|
||||||
rts
|
|
||||||
|
|
||||||
_a .byte 0
|
|
||||||
_x .byte 0
|
|
||||||
_y .byte 0
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
asmsub withasm(uword foo @R0, ubyte arg1 @A, ubyte arg2 @Y) clobbers(X) -> ubyte @A {
|
|
||||||
%asm {{
|
|
||||||
sty P8ZP_SCRATCH_REG
|
|
||||||
clc
|
|
||||||
adc P8ZP_SCRATCH_REG
|
|
||||||
rts
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub derp(uword aa)-> uword {
|
|
||||||
return 9999+aa
|
|
||||||
}
|
|
||||||
|
|
||||||
sub start () {
|
sub start () {
|
||||||
txt.print_ub(target())
|
ubyte qq
|
||||||
txt.chrout('\n')
|
void c64.CHKIN(3)
|
||||||
|
qq++
|
||||||
; cx16.r0 = 65535
|
qq=c64.CHKIN(3)
|
||||||
; set_8_pixels_opaque_OLD(111,222,33)
|
qq=c64.OPEN() ; TODO DO NOT REMOVE SECOND ASSIGNMENT IF ITS NOT A SIMPLE VALUE
|
||||||
; txt.chrout('\n')
|
|
||||||
; ;ubyte qq=c64.CHKIN(3) ;; TODO fix compiler crash "can't translate zero return values in assignment"
|
|
||||||
;
|
|
||||||
; test_stack.test()
|
|
||||||
; ubyte bb = 44
|
|
||||||
; set_8_pixels_opaque(bb,111,222,33)
|
|
||||||
; txt.chrout('\n')
|
|
||||||
; test_stack.test()
|
|
||||||
;
|
|
||||||
; set_8_pixels_opaque(c64.CHRIN(),111,222,33)
|
|
||||||
; txt.chrout('\n')
|
|
||||||
|
|
||||||
test_stack.test()
|
test_stack.test()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user