byte/word asm comparisons

This commit is contained in:
Irmen de Jong 2018-12-08 00:27:12 +01:00
parent 432960da8b
commit ef2ae60868
13 changed files with 371 additions and 105 deletions

View File

@ -5,16 +5,17 @@
~ main {
sub start() {
str name = "????????????????????????????????????????"
str guess = "??????????"
str guessstr = "??????????"
ubyte guess
ubyte secretnumber = 0
ubyte attempts_left = 10
memory uword freadstr_arg = $22 ; argument for FREADSTR
uword testword
; greeting
c64.VMCSB = %10111 ; switch lowercase chars
c64.VMCSB |= 2 ; switch lowercase chars
c64.STROUT("Please introduce yourself: ")
Y = c64scr.input_chars(name)
c64scr.input_chars(name)
c64.CHROUT('\n')
c64.CHROUT('\n')
c64.STROUT("Hello, ")
@ -28,7 +29,7 @@
c64.FADDH() ; add 0.5..
c64.FADDH() ; and again, so +1 total
A, Y = c64flt.GETADRAY()
secretnumber = A
secretnumber = A ; secret number = rnd()*100+1
ask_guess:
c64.STROUT("\nYou have ")
@ -37,17 +38,22 @@ ask_guess:
if(attempts_left>0) c64.STROUT("es")
c64.STROUT(" left.\nWhat is your next guess? ")
Y = c64scr.input_chars(guess)
c64scr.input_chars(guessstr)
c64.CHROUT('\n')
freadstr_arg = guess
c64.FREADSTR(A)
freadstr_arg = guessstr
rsave()
c64.FREADSTR(Y)
A, Y = c64flt.GETADRAY()
if(A==secretnumber) {
guess=A
rrestore()
c64.EXTCOL=guess ; @debug
c64.BGCOL0=secretnumber ;@debug
if(guess==secretnumber) { ; @todo equal_b doesn't work
c64.STROUT("\nThat's my number, impressive!\n")
goto goodbye
}
c64.STROUT("\nThat is too ")
if(A > secretnumber)
if(guess > secretnumber) ; @todo greater_ub doesn't work?
c64.STROUT("low!\n")
else
c64.STROUT("high!\n")

View File

@ -4,13 +4,13 @@
~ main {
sub start() {
str name = " "
str guess = "000000"
str name = "????????????????????????????????????????"
str guess = "??????????"
ubyte secretnumber = rnd() % 100
c64.VMCSB = %10111 ; switch lowercase chars
c64.VMCSB |= 2 ; switch lowercase chars
c64scr.print_string("Please introduce yourself: ")
Y=c64scr.input_chars(name)
c64scr.input_chars(name)
c64scr.print_string("\n\nHello, ")
c64scr.print_string(name)
c64scr.print_string(".\nLet's play a number guessing game.\nI am thinking of a number from 1 to 100!You'll have to guess it!\n")
@ -21,7 +21,7 @@
c64scr.print_string(" guess")
if attempts_left>1 c64scr.print_string("es")
c64scr.print_string(" left.\nWhat is your next guess? ")
Y=c64scr.input_chars(guess)
c64scr.input_chars(guess)
ubyte guessednumber = str2ubyte(guess)
if guessednumber==secretnumber {
c64scr.print_string("\n\nYou guessed it, impressive!\n")

View File

@ -6,38 +6,227 @@
sub start() {
math.randseed($2ae4)
ubyte ub1
ubyte ub2
byte b1
byte b2
uword uw1
uword uw2
word w1
word w2
float f1
float f2
ubyte loop
c64scr.print_string("random bytes:\n")
for loop in 1 to 5 {
rsave() ; @todo automatic based on clobbers declaration
c64scr.print_byte_decimal(loop)
c64.CHROUT(':')
c64.CHROUT(' ')
ubyte ubr = rnd()
c64scr.print_byte_decimal(ubr)
rsave()
ub1=100
ub2=199
c64.STROUT("ub1=100,ub2=199\n")
rrestore()
if ub1==ub2 {
rsave()
c64.STROUT(" true: ub1==ub2\n")
rrestore()
c64.CHROUT('\n')
}
c64scr.print_string("\nrandom words:\n")
for loop in 1 to 5 {
rsave() ; @todo automatic based on clobbers declaration
c64scr.print_byte_decimal(loop)
c64.CHROUT(':')
c64.CHROUT(' ')
uword uwr = rndw()
c64scr.print_word_decimal(uwr)
} else {
rsave()
c64.STROUT(" false: ub1==ub2\n")
rrestore()
c64.CHROUT('\n')
}
c64scr.print_string("\nrandom floats:\n")
for loop in 1 to 5 {
c64scr.print_byte_decimal(loop)
c64.CHROUT(':')
c64.CHROUT(' ')
float f = rndf()
c64flt.print_float_ln(f)
if ub1!=ub2 {
rsave()
c64.STROUT(" true: ub1!=ub2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: ub1!=ub2\n")
rrestore()
}
rsave()
ub1=199
ub2=199
c64.STROUT("ub1=ub2=199\n")
rrestore()
if ub1==ub2 {
rsave()
c64.STROUT(" true: ub1==ub2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: ub1==ub2\n")
rrestore()
}
if ub1!=ub2 {
rsave()
c64.STROUT(" true: ub1!=ub2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: ub1!=ub2\n")
rrestore()
}
rsave()
b1=50
b2=111
c64.STROUT("b1=50,b2=111\n")
rrestore()
if b1==b2 {
rsave()
c64.STROUT(" true: b1==b2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: b1==b2\n")
rrestore()
}
if b1!=b2 {
rsave()
c64.STROUT(" true: b1!=b2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: b1!=b2\n")
rrestore()
}
rsave()
b1=111
b2=111
c64.STROUT("b1=b2=111\n")
rrestore()
if b1==b2 {
rsave()
c64.STROUT(" true: b1==b2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: b1==b2\n")
rrestore()
}
if b1!=b2 {
rsave()
c64.STROUT(" true: b1!=b2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: b1!=b2\n")
rrestore()
}
rsave()
uw1=1234
uw2=59999
c64.STROUT("uw1=1234,uw2=59999\n")
rrestore()
if uw1==uw2 {
rsave()
c64.STROUT(" true: uw1==uw2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: uw1==uw2\n")
rrestore()
}
if uw1!=uw2 {
rsave()
c64.STROUT(" true: uw1!=uw2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: uw1!=uw2\n")
rrestore()
}
rsave()
uw1=52999
uw2=52999
c64.STROUT("uw1=uw2=52999\n")
rrestore()
if uw1==uw2 {
rsave()
c64.STROUT(" true: uw1==uw2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: uw1==uw2\n")
rrestore()
}
if uw1!=uw2 {
rsave()
c64.STROUT(" true: uw1!=uw2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: uw1!=uw2\n")
rrestore()
}
rsave()
w1=1234
w2=-9999
c64.STROUT("w1=1234, w2=-9999\n")
rrestore()
if w1==w2 {
rsave()
c64.STROUT(" true: w1==w2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: w1==w2\n")
rrestore()
}
if w1!=w2 {
rsave()
c64.STROUT(" true: w1!=w2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: w1!=w2\n")
rrestore()
}
rsave()
w1=44
w2=44
c64.STROUT("w1=w2=44\n")
rrestore()
if w1==w2 {
rsave()
c64.STROUT(" true: w1==w2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: w1==w2\n")
rrestore()
}
if w1!=w2 {
rsave()
c64.STROUT(" true: w1!=w2\n")
rrestore()
} else {
rsave()
c64.STROUT(" false: w1!=w2\n")
rrestore()
}
}
}

View File

@ -156,10 +156,10 @@ fun main(args: Array<String>) {
if(startEmu) {
println("\nStarting C64 emulator...")
val monitorfile = "$programname.mon_list"
val cmdline = listOf("x64", "-moncommands", monitorfile,
val cmdline = listOf("x64", "-moncommands", "$programname.vice-mon-list",
"-autostartprgmode", "1", "-autostart-warp", "-autostart", programname+".prg")
ProcessBuilder(cmdline).inheritIO().start()
val process = ProcessBuilder(cmdline).inheritIO().start()
process.waitFor()
}
}

View File

@ -2141,6 +2141,7 @@ internal fun unescape(str: String, position: Position): String {
'\\' -> '\\'
'n' -> '\n'
'r' -> '\r'
'"' -> '"'
'u' -> {
"${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}".toInt(16).toChar()
}

View File

@ -297,6 +297,11 @@ class AstChecker(private val namespace: INameScope,
if(subroutine.asmClobbers.intersect(regCounts.keys).isNotEmpty())
err("a return register is also in the clobber list")
} else {
// TODO: currently, non-asm subroutines can only take numeric arguments
if(!subroutine.parameters.all{it.type in NumericDatatypes}) {
err("non-asm subroutine can only take numerical parameters (no str/array types) for now")
}
}
return subroutine
}

View File

@ -785,6 +785,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.EQUAL_BYTE -> " jsr prog8_lib.equal_b"
Opcode.EQUAL_WORD -> " jsr prog8_lib.equal_w"
Opcode.EQUAL_F -> " jsr prog8_lib.equal_f"
Opcode.NOTEQUAL_BYTE -> " jsr prog8_lib.notequal_b"
Opcode.NOTEQUAL_WORD -> " jsr prog8_lib.notequal_w"
Opcode.NOTEQUAL_F -> " jsr prog8_lib.notequal_f"
Opcode.LESS_UB -> " jsr prog8_lib.less_ub"
Opcode.LESS_B -> " jsr prog8_lib.less_b"
@ -1452,7 +1455,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// var = (u)wordarray[index_byte]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment ->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
" lda ${segment[1].callLabel}+$index | sta ${segment[2].callLabel} | lda ${segment[1].callLabel}+${index+1} | sta ${segment[2].callLabel}+1"
},
// var = (u)wordarray[index var]
@ -1580,7 +1583,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// mem uword = (u)wordarray[indexvalue]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_MEM_WORD)) { segment ->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
"""
lda ${segment[1].callLabel}+$index
ldy ${segment[1].callLabel}+1+$index
@ -1675,7 +1678,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// ----------- assignment to UWORD ARRAY ----------------
// uwordarray[index] = (u)word value
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[1].arg!!.integerValue()*2
val index = intVal(segment[1])*2
val value = hexVal(segment[0])
"""
lda #<$value
@ -1743,7 +1746,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// uwordarray[index] = ubytevar
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[2].arg!!.integerValue()*2
val index = intVal(segment[2])*2
when(segment[0].callLabel) {
"A" -> " sta ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index+1}"
"X" -> " stx ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index+1}"
@ -1753,7 +1756,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// wordarray[index] = bytevar (extend sign)
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[2].arg!!.integerValue()*2
val index = intVal(segment[2])*2
when(segment[0].callLabel) {
"A" ->
"""
@ -1842,7 +1845,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// wordarray[index] = mem byte (extend sign)
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[2].arg!!.integerValue()*2
val index = intVal(segment[2])*2
"""
lda ${hexVal(segment[0])}
sta ${segment[3].callLabel}+$index
@ -1913,7 +1916,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// wordarray[index] = mem word
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[1].arg!!.integerValue()*2
val index = intVal(segment[1])*2
"""
lda ${hexVal(segment[0])}
sta ${segment[2].callLabel}+$index
@ -2019,7 +2022,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// uwordarray[index] = mem ubyte
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[2].arg!!.integerValue()*2
val index = intVal(segment[2])*2
"""
lda ${hexVal(segment[0])}
sta ${segment[3].callLabel}+$index
@ -2029,17 +2032,17 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// uwordarray[index] = (u)wordvar
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[1].arg!!.integerValue()*2
val index = intVal(segment[1])*2
" lda ${segment[0].callLabel} | sta ${segment[2].callLabel}+$index | lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}+${index+1}"
},
// uwordarray[index] = address-of var
AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[1].arg!!.integerValue()*2
val index = intVal(segment[1])*2
" lda #<${segment[0].callLabel} | sta ${segment[2].callLabel}+$index | lda #>${segment[0].callLabel} | sta ${segment[2].callLabel}+${index+1}"
},
// uwordarray[index] = mem uword
AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
val index = segment[1].arg!!.integerValue()*2
val index = intVal(segment[1])*2
"""
lda ${hexVal(segment[0])}
ldy ${hexValPlusOne(segment[0])}
@ -2061,7 +2064,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// uwordarray2[index2] = (u)wordarray1[index1]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
val index1 = intVal(segment[0])
val index2 = segment[2].arg!!.integerValue()*2
val index2 = intVal(segment[2])*2
"""
lda ${segment[1].callLabel}+$index1
ldy ${segment[1].callLabel}+${index1+1}
@ -2151,7 +2154,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// uwordarray2[indexvar] = uwordarray[index]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
val loadIndex2Y = when(segment[2].callLabel) {
"A" -> " asl a | tay"
"X" -> " txa | asl a | tay"
@ -2355,7 +2358,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// floatvar = wordarray[index]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
"""
lda ${segment[1].callLabel}+$index
ldy ${segment[1].callLabel}+${index+1}
@ -2368,7 +2371,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// floatvar = uwordarray[index]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
"""
lda ${segment[1].callLabel}+$index
ldy ${segment[1].callLabel}+${index+1}
@ -2554,7 +2557,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// memfloat = wordarray[index]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
"""
lda ${segment[1].callLabel}+$index
ldy ${segment[1].callLabel}+${index+1}
@ -2567,7 +2570,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
// memfloat = uwordarray[index]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
val index = segment[0].arg!!.integerValue()*2
val index = intVal(segment[0])*2
"""
lda ${segment[1].callLabel}+$index
ldy ${segment[1].callLabel}+${index+1}
@ -2773,7 +2776,24 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
},
AsmPattern(listOf(Opcode.PUSH_ADDR_STR, Opcode.POP_REGXY_WORD)) { segment ->
TODO("$segment")
},
// push memory byte | bytevalue
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.BITOR_BYTE),
listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITOR_BYTE)) { segment ->
" lda ${hexVal(segment[0])} | ora #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
},
// push memory byte & bytevalue
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.BITAND_BYTE),
listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITAND_BYTE)) { segment ->
" lda ${hexVal(segment[0])} | and #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
},
// push memory byte ^ bytevalue
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE),
listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE)) { segment ->
" lda ${hexVal(segment[0])} | eor #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
}
)
}

View File

@ -28,6 +28,7 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
companion object {
const val SCRATCH_B1 = 0x02
const val SCRATCH_REG = 0x03 // temp storage for a register
const val SCRATCH_REG_X = 0x50 // temp storage for register X (the evaluation stack pointer)
const val SCRATCH_W1 = 0xfb // $fb/$fc
const val SCRATCH_W2 = 0xfd // $fd/$fe
}
@ -36,6 +37,7 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
if(options.zeropage== ZeropageType.FULL) {
free.addAll(0x04 .. 0xfa)
free.add(0xff)
free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_REG_X, SCRATCH_W1, SCRATCH_W1+1, SCRATCH_W2, SCRATCH_W2+1))
free.removeAll(listOf(0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6)) // these are updated by IRQ
} else {
if(options.zeropage== ZeropageType.KERNALSAFE) {
@ -43,18 +45,17 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
free.addAll(listOf(0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x6f, 0x70))
0x47, 0x48, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x51, 0x52, 0x53, 0x6f, 0x70))
}
// add the Zp addresses not even used by BASIC
// add the other free Zp addresses
// 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)
// KNOWN WORKING FREE: 0x04, 0x05, 0x06, 0x2a, 0x52, 0xf7, 0xf8, 0xf9, 0xfa))
free.addAll(listOf(0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0d, 0x0e,
0x12, 0x2a, 0x52, 0x94, 0x95, 0xa7, 0xa8, 0xa9, 0xaa,
0x51, 0x52, 0x94, 0x95, 0xa7, 0xa8, 0xa9, 0xaa,
0xb5, 0xb6, 0xf7, 0xf8, 0xf9, 0xfa))
}
assert(SCRATCH_B1 !in free)
assert(SCRATCH_REG !in free)
assert(SCRATCH_REG_X !in free)
assert(SCRATCH_W1 !in free)
assert(SCRATCH_W2 !in free)

View File

@ -536,7 +536,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
else if(lv.type==DataType.BYTE && lv.bytevalue!!>=0)
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
else if(lv.type==DataType.WORD && lv.bytevalue!!>=0)
else if(lv.type==DataType.WORD && lv.wordvalue!!>=0)
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
else if(lv.type==DataType.FLOAT) {
val d = lv.floatvalue!!

View File

@ -1126,14 +1126,14 @@ class StackVm(private var traceOutputFile: String?) {
}
Opcode.EQUAL_BYTE -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UBYTE)
checkDt(second, DataType.UBYTE)
checkDt(top, DataType.BYTE, DataType.UBYTE)
checkDt(second, DataType.BYTE, DataType.UBYTE)
evalstack.push(Value(DataType.UBYTE, if (second == top) 1 else 0))
}
Opcode.EQUAL_WORD -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UWORD)
checkDt(second, DataType.UWORD)
checkDt(top, DataType.WORD, DataType.UWORD)
checkDt(second, DataType.WORD, DataType.UWORD)
evalstack.push(Value(DataType.UBYTE, if (second == top) 1 else 0))
}
Opcode.EQUAL_F -> {
@ -1144,14 +1144,14 @@ class StackVm(private var traceOutputFile: String?) {
}
Opcode.NOTEQUAL_BYTE -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UBYTE)
checkDt(second, DataType.UBYTE)
checkDt(top, DataType.BYTE, DataType.UBYTE)
checkDt(second, DataType.BYTE, DataType.UBYTE)
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
}
Opcode.NOTEQUAL_WORD -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UWORD)
checkDt(second, DataType.UWORD)
checkDt(top, DataType.WORD, DataType.UWORD)
checkDt(second, DataType.UWORD, DataType.UWORD)
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
}
Opcode.NOTEQUAL_F -> {

View File

@ -154,17 +154,17 @@ class TestZeropage {
@Test
fun testFreeSpaces() {
val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true))
assertEquals(23, zp1.available())
assertEquals(22, zp1.available())
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), true))
assertEquals(71, zp2.available())
assertEquals(70, zp2.available())
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true))
assertEquals(239, zp3.available())
assertEquals(238, zp3.available())
}
@Test
fun testReservedSpace() {
val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true))
assertEquals(239, zp1.available())
assertEquals(238, zp1.available())
assertTrue(50 in zp1.free)
assertTrue(100 in zp1.free)
assertTrue(49 in zp1.free)
@ -187,7 +187,7 @@ class TestZeropage {
@Test
fun testBasicsafeAllocation() {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true))
assertEquals(23, zp.available())
assertEquals(22, zp.available())
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos))
assertFailsWith<CompilerException> {
@ -211,17 +211,17 @@ class TestZeropage {
@Test
fun testFullAllocation() {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true))
assertEquals(239, zp.available())
assertEquals(238, zp.available())
val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos))
assertTrue(loc > 3)
assertFalse(loc in zp.free)
val num = zp.available() / 5
val rest = zp.available() % 5
for(i in 0..num-4) {
for(i in 0..num-5) {
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos))
}
assertEquals(19,zp.available())
assertEquals(23,zp.available())
assertFailsWith<CompilerException> {
// can't allocate because no more sequential bytes, only fragmented
@ -234,7 +234,9 @@ class TestZeropage {
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
assertEquals(1, zp.available())
assertEquals(5, zp.available())
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
assertFailsWith<CompilerException> {
// no more space
@ -244,23 +246,18 @@ class TestZeropage {
@Test
fun testEfficientAllocation() {
// free = (0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0d, 0x0e,
// 0x12, 0x2a, 0x52, 0x94, 0x95, 0xa7, 0xa8, 0xa9, 0xaa,
// 0xb5, 0xb6, 0xf7, 0xf8, 0xf9, 0xfa))
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true))
assertEquals(23, zp.available())
assertEquals(22, zp.available())
assertEquals(0x04, zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos)))
assertEquals(0x09, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
assertEquals(0x12, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
assertEquals(0x0d, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0x51, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0x94, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0x2a, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
assertEquals(0xa7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0xa9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0xb5, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0xf7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0xf9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
assertEquals(0x52, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
assertEquals(0, zp.available())
}
}

View File

@ -141,7 +141,7 @@ asmsub GIVAYF (lo: ubyte @ Y, hi: ubyte @ A) -> clobbers(A,X,Y) -> () = $b391
asmsub FREADUY (unsigned: ubyte @ Y) -> clobbers(A,X,Y) -> () = $b3a2 ; 8 bit unsigned Y -> float in fac1
asmsub FREADSA (signed: ubyte @ A) -> clobbers(A,X,Y) -> () = $bc3c ; 8 bit signed A -> float in fac1
asmsub FREADSTR (length: ubyte @ A) -> clobbers(A,X,Y) -> () = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length
asmsub FPRINTLN () -> clobbers(A,X,Y) -> () = $aabc ; print string of fac1, on one line (= with newline) (consider FOUT + STROUT as well)
asmsub FPRINTLN () -> clobbers(A,X,Y) -> () = $aabc ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well)
asmsub FOUT () -> clobbers(X) -> (uword @ AY) = $bddd ; fac1 -> string, address returned in AY ($0100)
asmsub FADDH () -> clobbers(A,X,Y) -> () = $b849 ; fac1 += 0.5, for rounding- call this before INT

View File

@ -269,31 +269,72 @@ remainder_f .proc
.warn "not implemented"
.pend
equal_ub .proc
rts
.warn "not implemented"
.pend
equal_b .proc
; -- are the two bytes on the stack identical?
inx
lda ESTACK_LO,x
cmp ESTACK_LO+1,x
bne +
lda #1
sta ESTACK_LO+1,x
rts
+ lda #0
sta ESTACK_LO+1,x
rts
.warn "not implemented"
.pend
equal_w .proc
; -- are the two words on the stack identical?
inx
lda ESTACK_LO,x
cmp ESTACK_LO+1,x
bne +
lda ESTACK_HI,x
cmp ESTACK_HI+1,x
bne +
txa ; words are equal
sta ESTACK_LO+1,x
rts
.warn "not implemented"
.pend
equal_uw .proc
+ lda #0 ; words are not equal
sta ESTACK_LO+1,x
rts
.warn "not implemented"
.pend
equal_f .proc
rts
.warn "not implemented"
.pend
notequal_b .proc
; -- are the two bytes on the stack different?
inx
lda ESTACK_LO,x
eor ESTACK_LO+1,x
sta ESTACK_LO+1,x
rts
.pend
notequal_w .proc
; -- are the two words on the stack different?
inx
lda ESTACK_LO,x
eor ESTACK_LO+1,x
beq +
sta ESTACK_LO+1,x
rts
+ lda ESTACK_HI,x
eor ESTACK_HI+1,x
sta ESTACK_LO+1,x
rts
.pend
notequal_f .proc
rts
.warn "not implemented"
.pend
less_ub .proc
rts
.warn "not implemented"
@ -345,8 +386,14 @@ lesseq_f .proc
.pend
greater_ub .proc
inx
lda ESTACK_LO,x
clc
sbc ESTACK_LO+1,x
lda #0
adc #0
sta ESTACK_LO+1,x
rts
.warn "not implemented"
.pend
greater_b .proc