mirror of
https://github.com/irmen/prog8.git
synced 2024-07-01 09:29:29 +00:00
byte/word asm comparisons
This commit is contained in:
parent
432960da8b
commit
ef2ae60868
|
@ -5,16 +5,17 @@
|
||||||
~ main {
|
~ main {
|
||||||
sub start() {
|
sub start() {
|
||||||
str name = "????????????????????????????????????????"
|
str name = "????????????????????????????????????????"
|
||||||
str guess = "??????????"
|
str guessstr = "??????????"
|
||||||
|
ubyte guess
|
||||||
ubyte secretnumber = 0
|
ubyte secretnumber = 0
|
||||||
ubyte attempts_left = 10
|
ubyte attempts_left = 10
|
||||||
memory uword freadstr_arg = $22 ; argument for FREADSTR
|
memory uword freadstr_arg = $22 ; argument for FREADSTR
|
||||||
uword testword
|
uword testword
|
||||||
|
|
||||||
; greeting
|
; greeting
|
||||||
c64.VMCSB = %10111 ; switch lowercase chars
|
c64.VMCSB |= 2 ; switch lowercase chars
|
||||||
c64.STROUT("Please introduce yourself: ")
|
c64.STROUT("Please introduce yourself: ")
|
||||||
Y = c64scr.input_chars(name)
|
c64scr.input_chars(name)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
c64.STROUT("Hello, ")
|
c64.STROUT("Hello, ")
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
c64.FADDH() ; add 0.5..
|
c64.FADDH() ; add 0.5..
|
||||||
c64.FADDH() ; and again, so +1 total
|
c64.FADDH() ; and again, so +1 total
|
||||||
A, Y = c64flt.GETADRAY()
|
A, Y = c64flt.GETADRAY()
|
||||||
secretnumber = A
|
secretnumber = A ; secret number = rnd()*100+1
|
||||||
|
|
||||||
ask_guess:
|
ask_guess:
|
||||||
c64.STROUT("\nYou have ")
|
c64.STROUT("\nYou have ")
|
||||||
|
@ -37,17 +38,22 @@ ask_guess:
|
||||||
if(attempts_left>0) c64.STROUT("es")
|
if(attempts_left>0) c64.STROUT("es")
|
||||||
|
|
||||||
c64.STROUT(" left.\nWhat is your next guess? ")
|
c64.STROUT(" left.\nWhat is your next guess? ")
|
||||||
Y = c64scr.input_chars(guess)
|
c64scr.input_chars(guessstr)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
freadstr_arg = guess
|
freadstr_arg = guessstr
|
||||||
c64.FREADSTR(A)
|
rsave()
|
||||||
|
c64.FREADSTR(Y)
|
||||||
A, Y = c64flt.GETADRAY()
|
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")
|
c64.STROUT("\nThat's my number, impressive!\n")
|
||||||
goto goodbye
|
goto goodbye
|
||||||
}
|
}
|
||||||
c64.STROUT("\nThat is too ")
|
c64.STROUT("\nThat is too ")
|
||||||
if(A > secretnumber)
|
if(guess > secretnumber) ; @todo greater_ub doesn't work?
|
||||||
c64.STROUT("low!\n")
|
c64.STROUT("low!\n")
|
||||||
else
|
else
|
||||||
c64.STROUT("high!\n")
|
c64.STROUT("high!\n")
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
sub start() {
|
sub start() {
|
||||||
str name = " "
|
str name = "????????????????????????????????????????"
|
||||||
str guess = "000000"
|
str guess = "??????????"
|
||||||
ubyte secretnumber = rnd() % 100
|
ubyte secretnumber = rnd() % 100
|
||||||
|
|
||||||
c64.VMCSB = %10111 ; switch lowercase chars
|
c64.VMCSB |= 2 ; switch lowercase chars
|
||||||
c64scr.print_string("Please introduce yourself: ")
|
c64scr.print_string("Please introduce yourself: ")
|
||||||
Y=c64scr.input_chars(name)
|
c64scr.input_chars(name)
|
||||||
c64scr.print_string("\n\nHello, ")
|
c64scr.print_string("\n\nHello, ")
|
||||||
c64scr.print_string(name)
|
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")
|
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")
|
c64scr.print_string(" guess")
|
||||||
if attempts_left>1 c64scr.print_string("es")
|
if attempts_left>1 c64scr.print_string("es")
|
||||||
c64scr.print_string(" left.\nWhat is your next guess? ")
|
c64scr.print_string(" left.\nWhat is your next guess? ")
|
||||||
Y=c64scr.input_chars(guess)
|
c64scr.input_chars(guess)
|
||||||
ubyte guessednumber = str2ubyte(guess)
|
ubyte guessednumber = str2ubyte(guess)
|
||||||
if guessednumber==secretnumber {
|
if guessednumber==secretnumber {
|
||||||
c64scr.print_string("\n\nYou guessed it, impressive!\n")
|
c64scr.print_string("\n\nYou guessed it, impressive!\n")
|
||||||
|
|
|
@ -6,38 +6,227 @@
|
||||||
|
|
||||||
sub start() {
|
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")
|
rsave()
|
||||||
for loop in 1 to 5 {
|
ub1=100
|
||||||
rsave() ; @todo automatic based on clobbers declaration
|
ub2=199
|
||||||
c64scr.print_byte_decimal(loop)
|
c64.STROUT("ub1=100,ub2=199\n")
|
||||||
c64.CHROUT(':')
|
|
||||||
c64.CHROUT(' ')
|
|
||||||
ubyte ubr = rnd()
|
|
||||||
c64scr.print_byte_decimal(ubr)
|
|
||||||
rrestore()
|
rrestore()
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
if ub1==ub2 {
|
||||||
c64scr.print_string("\nrandom words:\n")
|
rsave()
|
||||||
for loop in 1 to 5 {
|
c64.STROUT(" true: ub1==ub2\n")
|
||||||
rsave() ; @todo automatic based on clobbers declaration
|
rrestore()
|
||||||
c64scr.print_byte_decimal(loop)
|
} else {
|
||||||
c64.CHROUT(':')
|
rsave()
|
||||||
c64.CHROUT(' ')
|
c64.STROUT(" false: ub1==ub2\n")
|
||||||
uword uwr = rndw()
|
|
||||||
c64scr.print_word_decimal(uwr)
|
|
||||||
rrestore()
|
rrestore()
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
}
|
||||||
c64scr.print_string("\nrandom floats:\n")
|
|
||||||
for loop in 1 to 5 {
|
if ub1!=ub2 {
|
||||||
c64scr.print_byte_decimal(loop)
|
rsave()
|
||||||
c64.CHROUT(':')
|
c64.STROUT(" true: ub1!=ub2\n")
|
||||||
c64.CHROUT(' ')
|
rrestore()
|
||||||
float f = rndf()
|
} else {
|
||||||
c64flt.print_float_ln(f)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,10 +156,10 @@ fun main(args: Array<String>) {
|
||||||
|
|
||||||
if(startEmu) {
|
if(startEmu) {
|
||||||
println("\nStarting C64 emulator...")
|
println("\nStarting C64 emulator...")
|
||||||
val monitorfile = "$programname.mon_list"
|
val cmdline = listOf("x64", "-moncommands", "$programname.vice-mon-list",
|
||||||
val cmdline = listOf("x64", "-moncommands", monitorfile,
|
|
||||||
"-autostartprgmode", "1", "-autostart-warp", "-autostart", programname+".prg")
|
"-autostartprgmode", "1", "-autostart-warp", "-autostart", programname+".prg")
|
||||||
ProcessBuilder(cmdline).inheritIO().start()
|
val process = ProcessBuilder(cmdline).inheritIO().start()
|
||||||
|
process.waitFor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2141,6 +2141,7 @@ internal fun unescape(str: String, position: Position): String {
|
||||||
'\\' -> '\\'
|
'\\' -> '\\'
|
||||||
'n' -> '\n'
|
'n' -> '\n'
|
||||||
'r' -> '\r'
|
'r' -> '\r'
|
||||||
|
'"' -> '"'
|
||||||
'u' -> {
|
'u' -> {
|
||||||
"${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}".toInt(16).toChar()
|
"${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}".toInt(16).toChar()
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,6 +297,11 @@ class AstChecker(private val namespace: INameScope,
|
||||||
|
|
||||||
if(subroutine.asmClobbers.intersect(regCounts.keys).isNotEmpty())
|
if(subroutine.asmClobbers.intersect(regCounts.keys).isNotEmpty())
|
||||||
err("a return register is also in the clobber list")
|
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
|
return subroutine
|
||||||
}
|
}
|
||||||
|
|
|
@ -785,6 +785,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
Opcode.EQUAL_BYTE -> " jsr prog8_lib.equal_b"
|
Opcode.EQUAL_BYTE -> " jsr prog8_lib.equal_b"
|
||||||
Opcode.EQUAL_WORD -> " jsr prog8_lib.equal_w"
|
Opcode.EQUAL_WORD -> " jsr prog8_lib.equal_w"
|
||||||
Opcode.EQUAL_F -> " jsr prog8_lib.equal_f"
|
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_UB -> " jsr prog8_lib.less_ub"
|
||||||
Opcode.LESS_B -> " jsr prog8_lib.less_b"
|
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]
|
// var = (u)wordarray[index_byte]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment ->
|
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"
|
" 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]
|
// var = (u)wordarray[index var]
|
||||||
|
@ -1580,7 +1583,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// mem uword = (u)wordarray[indexvalue]
|
// mem uword = (u)wordarray[indexvalue]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_MEM_WORD)) { segment ->
|
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
|
lda ${segment[1].callLabel}+$index
|
||||||
ldy ${segment[1].callLabel}+1+$index
|
ldy ${segment[1].callLabel}+1+$index
|
||||||
|
@ -1675,7 +1678,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
// ----------- assignment to UWORD ARRAY ----------------
|
// ----------- assignment to UWORD ARRAY ----------------
|
||||||
// uwordarray[index] = (u)word value
|
// uwordarray[index] = (u)word value
|
||||||
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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])
|
val value = hexVal(segment[0])
|
||||||
"""
|
"""
|
||||||
lda #<$value
|
lda #<$value
|
||||||
|
@ -1743,7 +1746,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// uwordarray[index] = ubytevar
|
// uwordarray[index] = ubytevar
|
||||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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) {
|
when(segment[0].callLabel) {
|
||||||
"A" -> " sta ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index+1}"
|
"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}"
|
"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)
|
// wordarray[index] = bytevar (extend sign)
|
||||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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) {
|
when(segment[0].callLabel) {
|
||||||
"A" ->
|
"A" ->
|
||||||
"""
|
"""
|
||||||
|
@ -1842,7 +1845,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// wordarray[index] = mem byte (extend sign)
|
// wordarray[index] = mem byte (extend sign)
|
||||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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])}
|
lda ${hexVal(segment[0])}
|
||||||
sta ${segment[3].callLabel}+$index
|
sta ${segment[3].callLabel}+$index
|
||||||
|
@ -1913,7 +1916,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// wordarray[index] = mem word
|
// wordarray[index] = mem word
|
||||||
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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])}
|
lda ${hexVal(segment[0])}
|
||||||
sta ${segment[2].callLabel}+$index
|
sta ${segment[2].callLabel}+$index
|
||||||
|
@ -2019,7 +2022,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// uwordarray[index] = mem ubyte
|
// uwordarray[index] = mem ubyte
|
||||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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])}
|
lda ${hexVal(segment[0])}
|
||||||
sta ${segment[3].callLabel}+$index
|
sta ${segment[3].callLabel}+$index
|
||||||
|
@ -2029,17 +2032,17 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// uwordarray[index] = (u)wordvar
|
// uwordarray[index] = (u)wordvar
|
||||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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}"
|
" 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
|
// uwordarray[index] = address-of var
|
||||||
AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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}"
|
" lda #<${segment[0].callLabel} | sta ${segment[2].callLabel}+$index | lda #>${segment[0].callLabel} | sta ${segment[2].callLabel}+${index+1}"
|
||||||
},
|
},
|
||||||
// uwordarray[index] = mem uword
|
// uwordarray[index] = mem uword
|
||||||
AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
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])}
|
lda ${hexVal(segment[0])}
|
||||||
ldy ${hexValPlusOne(segment[0])}
|
ldy ${hexValPlusOne(segment[0])}
|
||||||
|
@ -2061,7 +2064,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
// uwordarray2[index2] = (u)wordarray1[index1]
|
// uwordarray2[index2] = (u)wordarray1[index1]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
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 index1 = intVal(segment[0])
|
||||||
val index2 = segment[2].arg!!.integerValue()*2
|
val index2 = intVal(segment[2])*2
|
||||||
"""
|
"""
|
||||||
lda ${segment[1].callLabel}+$index1
|
lda ${segment[1].callLabel}+$index1
|
||||||
ldy ${segment[1].callLabel}+${index1+1}
|
ldy ${segment[1].callLabel}+${index1+1}
|
||||||
|
@ -2151,7 +2154,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// uwordarray2[indexvar] = uwordarray[index]
|
// uwordarray2[indexvar] = uwordarray[index]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
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) {
|
val loadIndex2Y = when(segment[2].callLabel) {
|
||||||
"A" -> " asl a | tay"
|
"A" -> " asl a | tay"
|
||||||
"X" -> " txa | asl a | tay"
|
"X" -> " txa | asl a | tay"
|
||||||
|
@ -2355,7 +2358,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// floatvar = wordarray[index]
|
// floatvar = wordarray[index]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
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
|
lda ${segment[1].callLabel}+$index
|
||||||
ldy ${segment[1].callLabel}+${index+1}
|
ldy ${segment[1].callLabel}+${index+1}
|
||||||
|
@ -2368,7 +2371,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// floatvar = uwordarray[index]
|
// floatvar = uwordarray[index]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
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
|
lda ${segment[1].callLabel}+$index
|
||||||
ldy ${segment[1].callLabel}+${index+1}
|
ldy ${segment[1].callLabel}+${index+1}
|
||||||
|
@ -2554,7 +2557,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// memfloat = wordarray[index]
|
// memfloat = wordarray[index]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
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
|
lda ${segment[1].callLabel}+$index
|
||||||
ldy ${segment[1].callLabel}+${index+1}
|
ldy ${segment[1].callLabel}+${index+1}
|
||||||
|
@ -2567,7 +2570,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||||
},
|
},
|
||||||
// memfloat = uwordarray[index]
|
// memfloat = uwordarray[index]
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
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
|
lda ${segment[1].callLabel}+$index
|
||||||
ldy ${segment[1].callLabel}+${index+1}
|
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 ->
|
AsmPattern(listOf(Opcode.PUSH_ADDR_STR, Opcode.POP_REGXY_WORD)) { segment ->
|
||||||
TODO("$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 "
|
||||||
}
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||||
companion object {
|
companion object {
|
||||||
const val SCRATCH_B1 = 0x02
|
const val SCRATCH_B1 = 0x02
|
||||||
const val SCRATCH_REG = 0x03 // temp storage for a register
|
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_W1 = 0xfb // $fb/$fc
|
||||||
const val SCRATCH_W2 = 0xfd // $fd/$fe
|
const val SCRATCH_W2 = 0xfd // $fd/$fe
|
||||||
}
|
}
|
||||||
|
@ -36,6 +37,7 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||||
if(options.zeropage== ZeropageType.FULL) {
|
if(options.zeropage== ZeropageType.FULL) {
|
||||||
free.addAll(0x04 .. 0xfa)
|
free.addAll(0x04 .. 0xfa)
|
||||||
free.add(0xff)
|
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
|
free.removeAll(listOf(0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6)) // these are updated by IRQ
|
||||||
} else {
|
} else {
|
||||||
if(options.zeropage== ZeropageType.KERNALSAFE) {
|
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,
|
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,
|
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,
|
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):
|
// 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,
|
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))
|
0xb5, 0xb6, 0xf7, 0xf8, 0xf9, 0xfa))
|
||||||
}
|
}
|
||||||
assert(SCRATCH_B1 !in free)
|
assert(SCRATCH_B1 !in free)
|
||||||
assert(SCRATCH_REG !in free)
|
assert(SCRATCH_REG !in free)
|
||||||
|
assert(SCRATCH_REG_X !in free)
|
||||||
assert(SCRATCH_W1 !in free)
|
assert(SCRATCH_W1 !in free)
|
||||||
assert(SCRATCH_W2 !in free)
|
assert(SCRATCH_W2 !in free)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
|
||||||
else if(lv.type==DataType.BYTE && lv.bytevalue!!>=0)
|
else if(lv.type==DataType.BYTE && lv.bytevalue!!>=0)
|
||||||
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
|
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)
|
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
|
||||||
else if(lv.type==DataType.FLOAT) {
|
else if(lv.type==DataType.FLOAT) {
|
||||||
val d = lv.floatvalue!!
|
val d = lv.floatvalue!!
|
||||||
|
|
|
@ -1126,14 +1126,14 @@ class StackVm(private var traceOutputFile: String?) {
|
||||||
}
|
}
|
||||||
Opcode.EQUAL_BYTE -> {
|
Opcode.EQUAL_BYTE -> {
|
||||||
val (top, second) = evalstack.pop2()
|
val (top, second) = evalstack.pop2()
|
||||||
checkDt(top, DataType.UBYTE)
|
checkDt(top, DataType.BYTE, DataType.UBYTE)
|
||||||
checkDt(second, DataType.UBYTE)
|
checkDt(second, DataType.BYTE, DataType.UBYTE)
|
||||||
evalstack.push(Value(DataType.UBYTE, if (second == top) 1 else 0))
|
evalstack.push(Value(DataType.UBYTE, if (second == top) 1 else 0))
|
||||||
}
|
}
|
||||||
Opcode.EQUAL_WORD -> {
|
Opcode.EQUAL_WORD -> {
|
||||||
val (top, second) = evalstack.pop2()
|
val (top, second) = evalstack.pop2()
|
||||||
checkDt(top, DataType.UWORD)
|
checkDt(top, DataType.WORD, DataType.UWORD)
|
||||||
checkDt(second, DataType.UWORD)
|
checkDt(second, DataType.WORD, DataType.UWORD)
|
||||||
evalstack.push(Value(DataType.UBYTE, if (second == top) 1 else 0))
|
evalstack.push(Value(DataType.UBYTE, if (second == top) 1 else 0))
|
||||||
}
|
}
|
||||||
Opcode.EQUAL_F -> {
|
Opcode.EQUAL_F -> {
|
||||||
|
@ -1144,14 +1144,14 @@ class StackVm(private var traceOutputFile: String?) {
|
||||||
}
|
}
|
||||||
Opcode.NOTEQUAL_BYTE -> {
|
Opcode.NOTEQUAL_BYTE -> {
|
||||||
val (top, second) = evalstack.pop2()
|
val (top, second) = evalstack.pop2()
|
||||||
checkDt(top, DataType.UBYTE)
|
checkDt(top, DataType.BYTE, DataType.UBYTE)
|
||||||
checkDt(second, DataType.UBYTE)
|
checkDt(second, DataType.BYTE, DataType.UBYTE)
|
||||||
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
|
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
|
||||||
}
|
}
|
||||||
Opcode.NOTEQUAL_WORD -> {
|
Opcode.NOTEQUAL_WORD -> {
|
||||||
val (top, second) = evalstack.pop2()
|
val (top, second) = evalstack.pop2()
|
||||||
checkDt(top, DataType.UWORD)
|
checkDt(top, DataType.WORD, DataType.UWORD)
|
||||||
checkDt(second, DataType.UWORD)
|
checkDt(second, DataType.UWORD, DataType.UWORD)
|
||||||
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
|
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
|
||||||
}
|
}
|
||||||
Opcode.NOTEQUAL_F -> {
|
Opcode.NOTEQUAL_F -> {
|
||||||
|
|
|
@ -154,17 +154,17 @@ class TestZeropage {
|
||||||
@Test
|
@Test
|
||||||
fun testFreeSpaces() {
|
fun testFreeSpaces() {
|
||||||
val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true))
|
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))
|
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))
|
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true))
|
||||||
assertEquals(239, zp3.available())
|
assertEquals(238, zp3.available())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testReservedSpace() {
|
fun testReservedSpace() {
|
||||||
val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true))
|
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(50 in zp1.free)
|
||||||
assertTrue(100 in zp1.free)
|
assertTrue(100 in zp1.free)
|
||||||
assertTrue(49 in zp1.free)
|
assertTrue(49 in zp1.free)
|
||||||
|
@ -187,7 +187,7 @@ class TestZeropage {
|
||||||
@Test
|
@Test
|
||||||
fun testBasicsafeAllocation() {
|
fun testBasicsafeAllocation() {
|
||||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true))
|
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))
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos))
|
||||||
assertFailsWith<CompilerException> {
|
assertFailsWith<CompilerException> {
|
||||||
|
@ -211,17 +211,17 @@ class TestZeropage {
|
||||||
@Test
|
@Test
|
||||||
fun testFullAllocation() {
|
fun testFullAllocation() {
|
||||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true))
|
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))
|
val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos))
|
||||||
assertTrue(loc > 3)
|
assertTrue(loc > 3)
|
||||||
assertFalse(loc in zp.free)
|
assertFalse(loc in zp.free)
|
||||||
val num = zp.available() / 5
|
val num = zp.available() / 5
|
||||||
val rest = 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))
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos))
|
||||||
}
|
}
|
||||||
assertEquals(19,zp.available())
|
assertEquals(23,zp.available())
|
||||||
|
|
||||||
assertFailsWith<CompilerException> {
|
assertFailsWith<CompilerException> {
|
||||||
// can't allocate because no more sequential bytes, only fragmented
|
// 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))
|
||||||
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))
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||||
assertFailsWith<CompilerException> {
|
assertFailsWith<CompilerException> {
|
||||||
// no more space
|
// no more space
|
||||||
|
@ -244,23 +246,18 @@ class TestZeropage {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testEfficientAllocation() {
|
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))
|
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(0x04, zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos)))
|
||||||
assertEquals(0x09, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, 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(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(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(0xa7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||||
assertEquals(0xa9, 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(0xb5, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||||
assertEquals(0xf7, 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(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())
|
assertEquals(0, zp.available())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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 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 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 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
|
asmsub FADDH () -> clobbers(A,X,Y) -> () = $b849 ; fac1 += 0.5, for rounding- call this before INT
|
||||||
|
|
|
@ -269,24 +269,36 @@ remainder_f .proc
|
||||||
.warn "not implemented"
|
.warn "not implemented"
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
equal_ub .proc
|
|
||||||
rts
|
|
||||||
.warn "not implemented"
|
|
||||||
.pend
|
|
||||||
|
|
||||||
equal_b .proc
|
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
|
rts
|
||||||
.warn "not implemented"
|
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
equal_w .proc
|
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
|
rts
|
||||||
.warn "not implemented"
|
+ lda #0 ; words are not equal
|
||||||
.pend
|
sta ESTACK_LO+1,x
|
||||||
|
|
||||||
equal_uw .proc
|
|
||||||
rts
|
rts
|
||||||
.warn "not implemented"
|
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
equal_f .proc
|
equal_f .proc
|
||||||
|
@ -294,6 +306,35 @@ equal_f .proc
|
||||||
.warn "not implemented"
|
.warn "not implemented"
|
||||||
.pend
|
.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
|
less_ub .proc
|
||||||
rts
|
rts
|
||||||
.warn "not implemented"
|
.warn "not implemented"
|
||||||
|
@ -345,8 +386,14 @@ lesseq_f .proc
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
greater_ub .proc
|
greater_ub .proc
|
||||||
|
inx
|
||||||
|
lda ESTACK_LO,x
|
||||||
|
clc
|
||||||
|
sbc ESTACK_LO+1,x
|
||||||
|
lda #0
|
||||||
|
adc #0
|
||||||
|
sta ESTACK_LO+1,x
|
||||||
rts
|
rts
|
||||||
.warn "not implemented"
|
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
greater_b .proc
|
greater_b .proc
|
||||||
|
|
Loading…
Reference in New Issue
Block a user