mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
byte/word asm comparisons
This commit is contained in:
parent
432960da8b
commit
ef2ae60868
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
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)
|
||||
|
||||
if ub1==ub2 {
|
||||
rsave()
|
||||
c64.STROUT(" true: ub1==ub2\n")
|
||||
rrestore()
|
||||
} 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 "
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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!!
|
||||
|
@ -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 -> {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -269,24 +269,36 @@ 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
|
||||
@ -294,6 +306,35 @@ equal_f .proc
|
||||
.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
|
||||
|
Loading…
Reference in New Issue
Block a user