mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 08:29:25 +00:00
begun with converting builtin functions to new call convention
This commit is contained in:
parent
ebc2c614d7
commit
e0c5ccc16b
@ -343,20 +343,16 @@ neg_f .proc
|
||||
rts
|
||||
.pend
|
||||
|
||||
abs_f .proc
|
||||
; -- strip the sign bit on the stack
|
||||
lda P8ESTACK_HI+3,x
|
||||
and #$7f
|
||||
sta P8ESTACK_HI+3,x
|
||||
rts
|
||||
abs_f_cc .proc
|
||||
; -- push abs(AY) on stack
|
||||
jsr abs_f_into_fac1_cc
|
||||
jmp push_fac1
|
||||
.pend
|
||||
|
||||
abs_f_into_fac1 .proc
|
||||
; -- strip the sign bit on the stack, push stack into FAC1
|
||||
lda P8ESTACK_HI+3,x
|
||||
and #$7f
|
||||
sta P8ESTACK_HI+3,x
|
||||
jmp pop_float_fac1
|
||||
abs_f_into_fac1_cc .proc
|
||||
; -- FAC1 = abs(AY)
|
||||
jsr floats.MOVFM
|
||||
jmp floats.ABS
|
||||
.pend
|
||||
|
||||
equal_f .proc
|
||||
|
@ -245,24 +245,27 @@ xor_w .proc
|
||||
.pend
|
||||
|
||||
|
||||
abs_b .proc
|
||||
; -- push abs(byte) on stack (as byte)
|
||||
lda P8ESTACK_LO+1,x
|
||||
bmi neg_b
|
||||
abs_b_cc .proc
|
||||
; -- push abs(A) on stack (as byte)
|
||||
jsr abs_b_into_A_cc
|
||||
sta P8ESTACK_LO,x
|
||||
dex
|
||||
rts
|
||||
.pend
|
||||
|
||||
abs_w .proc
|
||||
; -- push abs(word) on stack (as word)
|
||||
lda P8ESTACK_HI+1,x
|
||||
bmi neg_w
|
||||
abs_w_cc .proc
|
||||
; -- push abs(AY) on stack (as word)
|
||||
jsr abs_w_into_AY_cc
|
||||
sta P8ESTACK_LO,x
|
||||
tya
|
||||
sta P8ESTACK_HI,x
|
||||
dex
|
||||
rts
|
||||
.pend
|
||||
|
||||
abs_b_into_A .proc
|
||||
; -- A = abs(pop stack byte)
|
||||
inx
|
||||
lda P8ESTACK_LO,x
|
||||
abs_b_into_A_cc .proc
|
||||
; -- A = abs(A)
|
||||
cmp #0
|
||||
bmi +
|
||||
rts
|
||||
+ eor #$ff
|
||||
@ -271,11 +274,9 @@ abs_b_into_A .proc
|
||||
rts
|
||||
.pend
|
||||
|
||||
abs_w_into_AY .proc
|
||||
; -- AY = abs(pop stack word)
|
||||
inx
|
||||
lda P8ESTACK_LO,x
|
||||
ldy P8ESTACK_HI,x
|
||||
abs_w_into_AY_cc .proc
|
||||
; -- AY = abs(AY)
|
||||
cpy #0
|
||||
bmi +
|
||||
rts
|
||||
+ eor #$ff
|
||||
@ -1388,20 +1389,19 @@ func_rndw .proc
|
||||
.pend
|
||||
|
||||
|
||||
func_memcopy255 .proc
|
||||
func_memcopy255_cc .proc
|
||||
; fast memcopy of up to 255 bytes, note: clobbers A,Y
|
||||
inx
|
||||
; note: also uses the _arg variables from regular func_memcopy
|
||||
stx P8ZP_SCRATCH_REG
|
||||
lda P8ESTACK_LO+2,x
|
||||
lda func_memcopy_cc._arg_from
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda P8ESTACK_HI+2,x
|
||||
lda func_memcopy_cc._arg_from+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
lda func_memcopy_cc._arg_to
|
||||
sta P8ZP_SCRATCH_W2
|
||||
lda P8ESTACK_HI+1,x
|
||||
lda func_memcopy_cc._arg_to+1
|
||||
sta P8ZP_SCRATCH_W2+1
|
||||
lda P8ESTACK_LO,x
|
||||
tax
|
||||
ldx func_memcopy_cc._arg_numbytes
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1), y
|
||||
sta (P8ZP_SCRATCH_W2), y
|
||||
@ -1409,31 +1409,23 @@ func_memcopy255 .proc
|
||||
dex
|
||||
bne -
|
||||
ldx P8ZP_SCRATCH_REG
|
||||
inx
|
||||
inx
|
||||
rts
|
||||
.pend
|
||||
|
||||
func_memcopy .proc
|
||||
func_memcopy_cc .proc
|
||||
; memcopy of any number of bytes, note: clobbers A,Y
|
||||
inx
|
||||
stx P8ZP_SCRATCH_REG
|
||||
lda P8ESTACK_LO+2,x
|
||||
lda _arg_from
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda P8ESTACK_HI+2,x
|
||||
lda _arg_from+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
lda _arg_to
|
||||
sta P8ZP_SCRATCH_W2
|
||||
lda P8ESTACK_HI+1,x
|
||||
lda _arg_to+1
|
||||
sta P8ZP_SCRATCH_W2+1
|
||||
lda P8ESTACK_LO,x
|
||||
pha
|
||||
lda P8ESTACK_HI,x
|
||||
pha
|
||||
|
||||
ldy #0
|
||||
pla
|
||||
tax
|
||||
ldx _arg_numbytes+1
|
||||
beq _remain
|
||||
- lda (P8ZP_SCRATCH_W1),y ; move a page at a time
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
@ -1443,8 +1435,7 @@ func_memcopy .proc
|
||||
inc P8ZP_SCRATCH_W2+1
|
||||
dex
|
||||
bne -
|
||||
_remain pla
|
||||
tax
|
||||
_remain ldx _arg_numbytes
|
||||
beq _done
|
||||
- lda (P8ZP_SCRATCH_W1),y ; move the remaining bytes
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
@ -1453,54 +1444,52 @@ _remain pla
|
||||
bne -
|
||||
|
||||
_done ldx P8ZP_SCRATCH_REG
|
||||
inx
|
||||
inx
|
||||
rts
|
||||
|
||||
_arg_from .word 0
|
||||
_arg_to .word 0
|
||||
_arg_numbytes .word 0
|
||||
.pend
|
||||
|
||||
func_memset .proc
|
||||
func_memset_cc .proc
|
||||
; note: clobbers A,Y
|
||||
inx
|
||||
stx P8ZP_SCRATCH_REG
|
||||
lda P8ESTACK_LO+2,x
|
||||
lda _arg_address
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda P8ESTACK_HI+2,x
|
||||
lda _arg_address+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
sta P8ZP_SCRATCH_B1
|
||||
ldy P8ESTACK_HI+1,x
|
||||
lda P8ESTACK_LO,x
|
||||
ldx P8ZP_SCRATCH_B1
|
||||
ldx _arg_numbytes
|
||||
ldy _arg_numbytes+1
|
||||
lda _arg_bytevalue
|
||||
jsr memset
|
||||
ldx P8ZP_SCRATCH_REG
|
||||
inx
|
||||
inx
|
||||
rts
|
||||
_arg_address .word 0
|
||||
_arg_numbytes .word 0
|
||||
_arg_bytevalue .byte 0
|
||||
.pend
|
||||
|
||||
func_memsetw .proc
|
||||
func_memsetw_cc .proc
|
||||
; note: clobbers A,Y
|
||||
; -- fill memory from (SCRATCH_ZPWORD1) number of words in SCRATCH_ZPWORD2, with word value in AY.
|
||||
|
||||
inx
|
||||
lda P8ESTACK_LO+2,x
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda P8ESTACK_HI+2,x
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
sta P8ZP_SCRATCH_W2
|
||||
lda P8ESTACK_HI+1,x
|
||||
sta P8ZP_SCRATCH_W2+1
|
||||
txa
|
||||
pha
|
||||
lda P8ESTACK_LO,x
|
||||
ldy P8ESTACK_HI,x
|
||||
lda _arg_address
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda _arg_address+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda _arg_numwords
|
||||
sta P8ZP_SCRATCH_W2
|
||||
lda _arg_numwords+1
|
||||
sta P8ZP_SCRATCH_W2+1
|
||||
lda _arg_wordvalue
|
||||
ldy _arg_wordvalue+1
|
||||
jsr memsetw
|
||||
pla
|
||||
tax
|
||||
inx
|
||||
inx
|
||||
rts
|
||||
_arg_address .word 0
|
||||
_arg_numwords .word 0
|
||||
_arg_wordvalue .word 0
|
||||
.pend
|
||||
|
||||
strlen .proc
|
||||
@ -1518,7 +1507,7 @@ strlen .proc
|
||||
|
||||
|
||||
memcopy16_up .proc
|
||||
; -- copy memory UP from (SCRATCH_ZPWORD1) to (SCRATCH_ZPWORD2) of length X/Y (16-bit, X=lo, Y=hi)
|
||||
; -- copy memory UP from (P8ZP_SCRATCH_W1) to (P8ZP_SCRATCH_W2) of length X/Y (16-bit, X=lo, Y=hi)
|
||||
; clobbers register A,X,Y
|
||||
source = P8ZP_SCRATCH_W1
|
||||
dest = P8ZP_SCRATCH_W2
|
||||
@ -1546,7 +1535,7 @@ memcopy16_up .proc
|
||||
|
||||
|
||||
memset .proc
|
||||
; -- fill memory from (SCRATCH_ZPWORD1), length XY, with value in A.
|
||||
; -- fill memory from (P8ZP_SCRATCH_W1), length XY, with value in A.
|
||||
; clobbers X, Y
|
||||
stx P8ZP_SCRATCH_B1
|
||||
sty _save_reg
|
||||
@ -1573,7 +1562,7 @@ _save_reg .byte 0
|
||||
|
||||
|
||||
memsetw .proc
|
||||
; -- fill memory from (SCRATCH_ZPWORD1) number of words in SCRATCH_ZPWORD2, with word value in AY.
|
||||
; -- fill memory from (P8ZP_SCRATCH_W1) number of words in P8ZP_SCRATCH_W2, with word value in AY.
|
||||
; clobbers A, X, Y
|
||||
sta _mod1+1 ; self-modify
|
||||
sty _mod1b+1 ; self-modify
|
||||
|
@ -110,7 +110,7 @@ internal object C64MachineDefinition: IMachineDefinition {
|
||||
internal class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
override val SCRATCH_B1 = 0x02 // temp storage for a single byte
|
||||
override val SCRATCH_REG = 0x03 // temp storage for a register
|
||||
override val SCRATCH_REG = 0x03 // temp storage for a register, must be B1+1
|
||||
override val SCRATCH_W1 = 0xfb // temp storage 1 for a word $fb+$fc
|
||||
override val SCRATCH_W2 = 0xfd // temp storage 2 for a word $fb+$fc
|
||||
|
||||
|
@ -117,7 +117,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
if((count!=null && count <= 255) || countDt.istype(DataType.UBYTE) || countDt.istype(DataType.BYTE)) {
|
||||
// fast memcopy of up to 255
|
||||
translateArguments(fcall.args, func)
|
||||
asmgen.out(" jsr prog8_lib.func_memcopy255")
|
||||
asmgen.out(" jsr prog8_lib.func_memcopy255_cc")
|
||||
return
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
}
|
||||
"memsetw" -> {
|
||||
translateArguments(fcall.args, func)
|
||||
asmgen.out(" jsr prog8_lib.func_memsetw")
|
||||
asmgen.out(" jsr prog8_lib.func_memsetw_cc")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -150,12 +150,12 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
val countDt = fcall.args[2].inferType(program)
|
||||
if((count!=null && count <= 255) || countDt.istype(DataType.UBYTE) || countDt.istype(DataType.BYTE)) {
|
||||
translateArguments(fcall.args, func)
|
||||
asmgen.out(" jsr prog8_lib.func_memcopy255")
|
||||
asmgen.out(" jsr prog8_lib.func_memcopy255_cc")
|
||||
return
|
||||
}
|
||||
}
|
||||
translateArguments(fcall.args, func)
|
||||
asmgen.out(" jsr prog8_lib.func_${func.name}")
|
||||
asmgen.out(" jsr prog8_lib.func_${func.name}_cc")
|
||||
}
|
||||
}
|
||||
|
||||
@ -937,16 +937,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT)
|
||||
if(resultToStack) {
|
||||
when (dt) {
|
||||
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b")
|
||||
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w")
|
||||
DataType.FLOAT -> asmgen.out(" jsr floats.abs_f")
|
||||
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_cc")
|
||||
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_cc")
|
||||
DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_cc")
|
||||
else -> throw AssemblyError("weird type")
|
||||
}
|
||||
} else {
|
||||
when (dt) {
|
||||
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A")
|
||||
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY")
|
||||
DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_into_fac1")
|
||||
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A_cc")
|
||||
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY_cc")
|
||||
DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_into_fac1_cc")
|
||||
else -> throw AssemblyError("weird type")
|
||||
}
|
||||
}
|
||||
@ -1052,7 +1052,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
val value = it.first.first
|
||||
when {
|
||||
conv.variable -> {
|
||||
val varname = "prog8_lib.func_${signature.name}_cc.arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again
|
||||
val varname = "prog8_lib.func_${signature.name}_cc._arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again
|
||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
|
@ -75,7 +75,7 @@ internal object CX16MachineDefinition: IMachineDefinition {
|
||||
internal class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
override val SCRATCH_B1 = 0x79 // temp storage for a single byte
|
||||
override val SCRATCH_REG = 0x7a // temp storage for a register
|
||||
override val SCRATCH_REG = 0x7a // temp storage for a register, must be B1+1
|
||||
override val SCRATCH_W1 = 0x7c // temp storage 1 for a word $7c+$7d
|
||||
override val SCRATCH_W2 = 0x7e // temp storage 2 for a word $7e+$7f
|
||||
|
||||
|
@ -5,8 +5,6 @@ import org.hamcrest.Matchers.closeTo
|
||||
import org.hamcrest.Matchers.equalTo
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.*
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
@ -18,8 +16,8 @@ import prog8.compiler.target.c64.C64MachineDefinition.FLOAT_MAX_NEGATIVE
|
||||
import prog8.compiler.target.c64.C64MachineDefinition.FLOAT_MAX_POSITIVE
|
||||
import prog8.compiler.target.c64.C64MachineDefinition.Mflpt5
|
||||
import prog8.compiler.target.c64.Petscii
|
||||
import prog8.compiler.target.cx16.CX16MachineDefinition
|
||||
import java.io.CharConversionException
|
||||
import java.nio.file.Path
|
||||
import kotlin.test.*
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@ -288,6 +286,22 @@ class TestC64Zeropage {
|
||||
assertEquals(0xf9, zp.allocate("", DataType.UBYTE, null, errors))
|
||||
assertEquals(0, zp.available())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReservedLocations() {
|
||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false))
|
||||
assertEquals(zp.SCRATCH_REG, zp.SCRATCH_B1+1, "zp _B1 and _REG must be next to each other to create a word")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class TestCx16Zeropage {
|
||||
@Test
|
||||
fun testReservedLocations() {
|
||||
val zp = CX16MachineDefinition.CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false))
|
||||
assertEquals(zp.SCRATCH_REG, zp.SCRATCH_B1+1, "zp _B1 and _REG must be next to each other to create a word")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- 64tass doesn't output all labels anymore in the vice-mon-list, so %breakpoint labels are no longer present....
|
||||
- calling convention for builtin functions no longer via stack but via registers or statically allocated vars inside the subroutine proc (like normal subroutines)
|
||||
- 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)
|
||||
|
@ -11,20 +11,37 @@ main {
|
||||
sub start() {
|
||||
const uword ADDR = $0400
|
||||
|
||||
byte zerob=0
|
||||
word zerow=0
|
||||
float zerof=0
|
||||
byte bb
|
||||
word ww
|
||||
float fl
|
||||
|
||||
bb = abs(bb)
|
||||
ww = abs(ww)
|
||||
fl = abs(fl)
|
||||
testX()
|
||||
|
||||
bb = -100
|
||||
bb = zerob+abs(bb)
|
||||
txt.print_b(bb)
|
||||
txt.chrout('\n')
|
||||
|
||||
memset(ADDR, 40*25, 100)
|
||||
memsetw(ADDR, 20*10, $3031)
|
||||
memcopy(ADDR, ADDR+40*12, 20*10*2)
|
||||
ww = -12345
|
||||
ww = zerow+abs(ww)
|
||||
txt.print_w(ww)
|
||||
txt.chrout('\n')
|
||||
|
||||
fl = -9.876
|
||||
fl = zerof+abs(fl)
|
||||
floats.print_f(fl)
|
||||
txt.chrout('\n')
|
||||
|
||||
; memset(ADDR, 40*25, 100)
|
||||
; memsetw(ADDR, 20*10, $3031)
|
||||
; memcopy(ADDR, ADDR+40*12, 20*10*2)
|
||||
|
||||
testX()
|
||||
|
||||
bb++
|
||||
}
|
||||
|
||||
asmsub testX() {
|
||||
@ -32,8 +49,23 @@ main {
|
||||
stx _saveX
|
||||
lda #13
|
||||
jsr txt.chrout
|
||||
lda #'x'
|
||||
jsr txt.chrout
|
||||
lda #'='
|
||||
jsr txt.chrout
|
||||
lda _saveX
|
||||
jsr txt.print_ub
|
||||
lda #' '
|
||||
jsr txt.chrout
|
||||
lda #'s'
|
||||
jsr txt.chrout
|
||||
lda #'p'
|
||||
jsr txt.chrout
|
||||
lda #'='
|
||||
jsr txt.chrout
|
||||
tsx
|
||||
txa
|
||||
jsr txt.print_ub
|
||||
lda #13
|
||||
jsr txt.chrout
|
||||
ldx _saveX
|
||||
|
Loading…
Reference in New Issue
Block a user