mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +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 {
|
||||
Pc,
|
||||
Pz,
|
||||
Pz, // don't use
|
||||
Pv,
|
||||
Pn;
|
||||
Pn; // don't use
|
||||
|
||||
companion object {
|
||||
val names by lazy { values().map { it.toString()} }
|
||||
|
@ -150,7 +150,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
is FunctionCall -> {
|
||||
when (val sub = value.target.targetStatement(program.namespace)) {
|
||||
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")
|
||||
|
||||
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)) {
|
||||
is Subroutine -> {
|
||||
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) {
|
||||
DataType.STR -> {
|
||||
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.AY -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||
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) {
|
||||
val valueIDt = value.inferType(program)
|
||||
if(!valueIDt.isKnown)
|
||||
|
@ -2,7 +2,7 @@
|
||||
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)
|
||||
- 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)
|
||||
|
@ -8,98 +8,12 @@
|
||||
|
||||
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 () {
|
||||
txt.print_ub(target())
|
||||
txt.chrout('\n')
|
||||
|
||||
; cx16.r0 = 65535
|
||||
; set_8_pixels_opaque_OLD(111,222,33)
|
||||
; 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')
|
||||
|
||||
ubyte qq
|
||||
void c64.CHKIN(3)
|
||||
qq++
|
||||
qq=c64.CHKIN(3)
|
||||
qq=c64.OPEN() ; TODO DO NOT REMOVE SECOND ASSIGNMENT IF ITS NOT A SIMPLE VALUE
|
||||
test_stack.test()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user