mirror of
https://github.com/irmen/prog8.git
synced 2025-02-22 16:29:05 +00:00
fixes
This commit is contained in:
parent
ca1d6bff56
commit
3a7b341f47
@ -10,7 +10,7 @@
|
||||
byte v1
|
||||
byte v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
v1 = 100
|
||||
@ -110,7 +110,7 @@
|
||||
else
|
||||
c64.STROUT("error in 22>=22!\n")
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
float v1
|
||||
float v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
v1 = 1.11
|
||||
@ -110,7 +110,7 @@
|
||||
else
|
||||
c64.STROUT("error in -22.2>=-22.2!\n")
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
ubyte v1
|
||||
ubyte v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
v1 = 100
|
||||
@ -110,7 +110,7 @@
|
||||
else
|
||||
c64.STROUT("error in 22>=22!\n")
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
uword v1
|
||||
uword v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
v1 = 100
|
||||
@ -110,7 +110,7 @@
|
||||
else
|
||||
c64.STROUT("error in 322>=322!\n")
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
word v1
|
||||
word v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
v1 = 100
|
||||
@ -110,7 +110,7 @@
|
||||
else
|
||||
c64.STROUT("error in -222>=-222!\n")
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
|
||||
; check stack usage:
|
||||
c64.STROUT("signed byte ")
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT(' ')
|
||||
|
||||
cr=v1==v2
|
||||
@ -39,7 +39,7 @@
|
||||
cr=v1>=v2
|
||||
cr=v1>=v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; comparisons:
|
||||
@ -58,7 +58,7 @@
|
||||
c64.STROUT("v1=20, v2=-111\n")
|
||||
compare()
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
return
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
; check stack usage:
|
||||
c64.STROUT("floating point ")
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT(' ')
|
||||
|
||||
cr=v1==v2
|
||||
@ -41,7 +41,7 @@
|
||||
cr=v1>=v2
|
||||
cr=v1>=v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; comparisons:
|
||||
@ -75,7 +75,7 @@
|
||||
c64.STROUT("v1 = v2 = 0\n")
|
||||
compare()
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
return
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
; check stack usage:
|
||||
c64.STROUT("unsigned byte ")
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT(' ')
|
||||
|
||||
cr=v1==v2
|
||||
@ -39,7 +39,7 @@
|
||||
cr=v1>=v2
|
||||
cr=v1>=v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; comparisons:
|
||||
@ -58,7 +58,7 @@
|
||||
c64.STROUT("v1=220, v2=10\n")
|
||||
compare()
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
return
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
; check stack usage:
|
||||
c64.STROUT("unsigned word ")
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT(' ')
|
||||
|
||||
cr=v1==v2
|
||||
@ -39,7 +39,7 @@
|
||||
cr=v1>=v2
|
||||
cr=v1>=v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; comparisons:
|
||||
@ -88,7 +88,7 @@
|
||||
c64.STROUT("v1 = v2 = aa\n")
|
||||
compare()
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
return
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
; check stack usage:
|
||||
c64.STROUT("signed word ")
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT(' ')
|
||||
|
||||
cr=v1==v2
|
||||
@ -40,7 +40,7 @@
|
||||
cr=v1>=v2
|
||||
cr=v1>=v2
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; comparisons:
|
||||
@ -125,7 +125,7 @@
|
||||
c64.STROUT("v1 = v2 = aa\n")
|
||||
compare()
|
||||
|
||||
c64scr.print_byte(X)
|
||||
c64scr.print_ubyte(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
return
|
||||
|
@ -81,11 +81,11 @@
|
||||
sub draw_edges() {
|
||||
|
||||
sub toscreenx(x: float, z: float) -> word {
|
||||
return floor(x/(4.2+z) * flt(height)) + width // 2
|
||||
return fintw(x/(4.2+z) * flt(height)) + width // 2
|
||||
}
|
||||
|
||||
sub toscreeny(y: float, z: float) -> word {
|
||||
return floor(y/(4.2+z) * flt(height)) + height // 2
|
||||
return fintw(y/(4.2+z) * flt(height)) + height // 2
|
||||
}
|
||||
|
||||
; draw all edges of the object
|
||||
@ -93,8 +93,6 @@
|
||||
ubyte e_from = msb(edge)
|
||||
ubyte e_to = lsb(edge)
|
||||
|
||||
float xxxx=rotatedx[msb(edge)] ; @todo weg
|
||||
|
||||
word x1 = toscreenx(rotatedx[e_from], rotatedz[e_from])
|
||||
word y1 = toscreeny(rotatedy[e_from], rotatedz[e_from])
|
||||
word x2 = toscreenx(rotatedx[e_to], rotatedz[e_to])
|
||||
|
@ -80,11 +80,11 @@
|
||||
sub draw_edges() {
|
||||
|
||||
sub toscreenx(x: float, z: float) -> word {
|
||||
return floor(x/(4.2+z) * flt(height)) + width // 2
|
||||
return fintw(x/(4.2+z) * flt(height)) + width // 2
|
||||
}
|
||||
|
||||
sub toscreeny(y: float, z: float) -> word {
|
||||
return floor(y/(4.2+z) * flt(height)) + height // 2
|
||||
return fintw(y/(4.2+z) * flt(height)) + height // 2
|
||||
}
|
||||
|
||||
; draw all edges of the object
|
||||
|
@ -3,22 +3,30 @@
|
||||
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
sub start() {
|
||||
|
||||
; set screen colors and activate lowercase charset
|
||||
c64.EXTCOL = 5
|
||||
c64.BGCOL0 = 0
|
||||
c64.COLOR = 1
|
||||
c64.VMCSB |= 2
|
||||
; set screen colors and activate lowercase charset
|
||||
c64.EXTCOL = 5
|
||||
c64.BGCOL0 = 0
|
||||
c64.COLOR = 1
|
||||
c64.VMCSB |= 2
|
||||
|
||||
; use kernel routine to write text
|
||||
c64.STROUT("Hello!\n")
|
||||
; use kernel routine to write text
|
||||
c64.STROUT("Hello!\n")
|
||||
|
||||
str question = "How are you?\n"
|
||||
|
||||
; use iteration to write text
|
||||
for ubyte char in question {
|
||||
c64.CHROUT(char)
|
||||
}
|
||||
|
||||
; use loop to write characters
|
||||
str bye = "Goodbye!\n"
|
||||
for ubyte c in 0 to len(bye) { ; @TODO fix compiler crash
|
||||
c64.CHROUT(bye[c])
|
||||
}
|
||||
|
||||
str question = "How are you?\n"
|
||||
for ubyte c in 0 to len(question) {
|
||||
c64.CHROUT(question[c])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
37
compiler/examples/mandelbrot-c64.p8
Normal file
37
compiler/examples/mandelbrot-c64.p8
Normal file
@ -0,0 +1,37 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
const uword width = 30
|
||||
const uword height = 20
|
||||
|
||||
sub start() {
|
||||
c64scr.print_string("calculating mandelbrot fractal...\n")
|
||||
|
||||
for ubyte pixely in 0 to height-1 {
|
||||
float yy = pixely/flt(height)/0.4-1.0
|
||||
|
||||
for ubyte pixelx in 0 to width-1 {
|
||||
float xx = pixelx/flt(width)/0.3-2.0
|
||||
|
||||
float xsquared = 0.0
|
||||
float ysquared = 0.0
|
||||
float x = 0.0
|
||||
float y = 0.0
|
||||
ubyte iter = 0
|
||||
|
||||
while (iter<16 and xsquared+ysquared<4.0) {
|
||||
y = x*y*2.0 + yy
|
||||
x = xsquared - ysquared + xx
|
||||
xsquared = x*x
|
||||
ysquared = y*y
|
||||
iter++
|
||||
}
|
||||
|
||||
c64.CHROUT(48-iter)
|
||||
}
|
||||
c64.CHROUT('\n')
|
||||
}
|
||||
c64scr.print_string("finished!\n")
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
const uword width = 320 // 2
|
||||
const uword height = 256 // 2
|
||||
const uword xoffset = 40
|
||||
const uword yoffset = 30
|
||||
|
||||
sub start() {
|
||||
;vm_gfx_clearscr(11)
|
||||
;vm_gfx_text(2, 1, 1, "Calculating Mandelbrot Fractal...")
|
||||
|
||||
for ubyte pixely in yoffset to yoffset+height-1 {
|
||||
float yy = flt((pixely-yoffset))/height/3.6+0.4
|
||||
|
||||
for uword pixelx in xoffset to xoffset+width-1 {
|
||||
float xx = flt((pixelx-xoffset))/width/3.0+0.2
|
||||
|
||||
float xsquared = 0.0
|
||||
float ysquared = 0.0
|
||||
float x = 0.0
|
||||
float y = 0.0
|
||||
ubyte iter = 0
|
||||
|
||||
while (iter<32 and xsquared+ysquared<4.0) {
|
||||
y = x*y*2.0 + yy
|
||||
x = xsquared - ysquared + xx
|
||||
xsquared = x*x
|
||||
ysquared = y*y
|
||||
iter++
|
||||
}
|
||||
|
||||
;vm_gfx_pixel(pixelx, pixely, iter)
|
||||
}
|
||||
}
|
||||
;vm_gfx_text(11, 21, 1, "Finished!")
|
||||
}
|
||||
}
|
29
compiler/examples/swirl-c64.p8
Normal file
29
compiler/examples/swirl-c64.p8
Normal file
@ -0,0 +1,29 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
const uword width = 40
|
||||
const uword height = 25
|
||||
|
||||
sub start() {
|
||||
|
||||
float t
|
||||
ubyte color
|
||||
|
||||
while(1) {
|
||||
float x = sin(t) + cos(t*1.1234)
|
||||
float y = cos(t) + sin(t*1.44)
|
||||
c64scr.setchrclr(screenx(x), screeny(y), 81, color)
|
||||
t += 0.1
|
||||
color++
|
||||
}
|
||||
}
|
||||
|
||||
sub screenx(x: float) -> ubyte {
|
||||
return b2ub(fintb(x * flt(width)/4.2) + width//2)
|
||||
}
|
||||
sub screeny(y: float) -> ubyte {
|
||||
return b2ub(fintb(y * flt(height)/4.2) + height//2)
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
const uword width = 320
|
||||
const uword height = 200
|
||||
|
||||
sub start() {
|
||||
|
||||
;vm_gfx_clearscr(0)
|
||||
|
||||
float t
|
||||
ubyte color
|
||||
|
||||
while(1) {
|
||||
float x = sin(t*1.01) + cos(t*1.1234)
|
||||
float y = cos(t) + sin(t*0.03456)
|
||||
;vm_gfx_pixel(screenx(x), screeny(y), color//16)
|
||||
t += 0.01
|
||||
color++
|
||||
}
|
||||
}
|
||||
|
||||
sub screenx(x: float) -> word {
|
||||
return floor(x * flt(width)/4.1) + width // 2
|
||||
}
|
||||
sub screeny(y: float) -> word {
|
||||
return floor(y * flt(height)/4.1) + height // 2
|
||||
}
|
||||
}
|
@ -23,9 +23,9 @@
|
||||
}
|
||||
|
||||
sub screenx(x: float) -> word {
|
||||
return floor(x * flt(width)/4.1) + width // 2
|
||||
return fintw(x * flt(width)/4.1) + width // 2
|
||||
}
|
||||
sub screeny(y: float) -> word {
|
||||
return floor(y * flt(height)/4.1) + height // 2
|
||||
return fintw(y * flt(height)/4.1) + height // 2
|
||||
}
|
||||
}
|
||||
|
@ -5,67 +5,14 @@
|
||||
|
||||
sub start() {
|
||||
|
||||
uword uw1
|
||||
uword uw2
|
||||
word w1
|
||||
word w2
|
||||
ubyte ub1
|
||||
ubyte ub2
|
||||
byte b1
|
||||
byte b2
|
||||
float f1
|
||||
float f2
|
||||
word[3] wa = [-1000.w,2000.w,3000.w] ; @todo array data type fix (float->word)
|
||||
word[3] wa2 = [1000,2000,3000] ; @todo array data type fix (uword->word)
|
||||
|
||||
ub1 = 200
|
||||
c64scr.print_ubyte(abs(ub1)) ; ok
|
||||
c64.CHROUT('\n')
|
||||
b1 = 100
|
||||
c64scr.print_byte(abs(b1)) ; ok
|
||||
c64.CHROUT('\n')
|
||||
b1 = 0
|
||||
c64scr.print_byte(abs(b1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
b1 = -100
|
||||
c64scr.print_byte(abs(b1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
byte[3] ba1 = [-1, 2, 3]
|
||||
byte[3] ba2 = [100,101,102] ; @todo array data type
|
||||
|
||||
uw1 = 1000
|
||||
c64scr.print_uword(abs(uw1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
w1 = 0
|
||||
c64scr.print_word(abs(w1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
w1 = -1000
|
||||
c64scr.print_word(abs(w1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
;return b2ub(fintb(x * flt(width)/4.2) + width//2)
|
||||
|
||||
f1 = 11.22
|
||||
c64flt.print_float(abs(f1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
f1 = 0
|
||||
c64flt.print_float(abs(f1)) ;ok
|
||||
c64.CHROUT('\n')
|
||||
f1 = -22.33
|
||||
c64flt.print_float(abs(f1)) ;@todo FAIL
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; float t = 0.0
|
||||
; ubyte color=0
|
||||
; while(true) {
|
||||
; ubyte x = lsb(round(sin(t)*17.0))+20
|
||||
; ubyte y = lsb(round(cos(t*1.3634567)*10.0))+12
|
||||
;
|
||||
; c64scr.setchrclr(x,y,color,color)
|
||||
; color++
|
||||
;; vm_gfx_text(x, y, 1, "*")
|
||||
; ;vm_gfx_pixel(x,y,1)
|
||||
;; c64scr.print_ubyte(x)
|
||||
;; c64.CHROUT(',')
|
||||
;; c64scr.print_ubyte(y)
|
||||
;; c64.CHROUT('\n')
|
||||
; ;screen[x] = '*'
|
||||
; t+=0.1
|
||||
; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1007,11 +1007,11 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
"//" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.FLOORDIV_UB
|
||||
DataType.BYTE -> Opcode.FLOORDIV_B
|
||||
DataType.UWORD -> Opcode.FLOORDIV_UW
|
||||
DataType.WORD -> Opcode.FLOORDIV_W
|
||||
DataType.FLOAT -> Opcode.FLOORDIV_F
|
||||
DataType.UBYTE -> Opcode.DIV_UB
|
||||
DataType.BYTE -> Opcode.DIV_B
|
||||
DataType.UWORD -> Opcode.DIV_UW
|
||||
DataType.WORD -> Opcode.DIV_W
|
||||
DataType.FLOAT -> Opcode.FLOORDIV
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
}
|
||||
}
|
||||
@ -1454,6 +1454,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
if(valueDt !in validDt)
|
||||
throw CompilerException("invalid datatype(s) for operand(s)")
|
||||
val opcode = when(aug_op) {
|
||||
// @todo ... need more datatypes here?
|
||||
"+=" -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> Opcode.ADD_UB
|
||||
@ -1480,9 +1481,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
"//=" -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> Opcode.FLOORDIV_UB
|
||||
DataType.UWORD -> Opcode.FLOORDIV_UW
|
||||
DataType.FLOAT -> Opcode.FLOORDIV_F
|
||||
DataType.UBYTE -> Opcode.DIV_UB
|
||||
DataType.UWORD -> Opcode.DIV_UW
|
||||
DataType.FLOAT -> Opcode.FLOORDIV
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
|
@ -55,11 +55,7 @@ enum class Opcode {
|
||||
DIV_UW,
|
||||
DIV_W,
|
||||
DIV_F,
|
||||
FLOORDIV_UB,
|
||||
FLOORDIV_B,
|
||||
FLOORDIV_UW,
|
||||
FLOORDIV_W,
|
||||
FLOORDIV_F,
|
||||
FLOORDIV,
|
||||
REMAINDER_UB,
|
||||
REMAINDER_B,
|
||||
REMAINDER_UW,
|
||||
|
@ -427,6 +427,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
val call = Syscall.values().find { it.callNr==ins.arg.numericValue() }
|
||||
when(call) {
|
||||
Syscall.FUNC_WRD, Syscall.FUNC_UWRD -> ""
|
||||
Syscall.FUNC_STR2UBYTE, Syscall.FUNC_STR2UWORD -> " jsr prog8_lib.func_str2uword"
|
||||
else -> " jsr prog8_lib.${call.toString().toLowerCase()}"
|
||||
}
|
||||
}
|
||||
@ -2708,19 +2709,29 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
|
||||
// byte var = lsb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.LSB, Opcode.POP_VAR_BYTE)) { segment ->
|
||||
" lda #<${segment[0].callLabel} | sta ${segment[2].callLabel}"
|
||||
when(segment[2].callLabel) {
|
||||
"A" -> " lda ${segment[0].callLabel}"
|
||||
"X" -> " ldx ${segment[0].callLabel}"
|
||||
"Y" -> " ldy ${segment[0].callLabel}"
|
||||
else -> " lda ${segment[0].callLabel} | sta ${segment[2].callLabel}"
|
||||
}
|
||||
},
|
||||
// byte var = msb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB, Opcode.POP_VAR_BYTE)) { segment ->
|
||||
" lda #>${segment[0].callLabel} | sta ${segment[2].callLabel}"
|
||||
when(segment[2].callLabel) {
|
||||
"A" -> " lda ${segment[0].callLabel}+1"
|
||||
"X" -> " ldx ${segment[0].callLabel}+1"
|
||||
"Y" -> " ldy ${segment[0].callLabel}+1"
|
||||
else -> " lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}"
|
||||
}
|
||||
},
|
||||
// push lsb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.LSB)) { segment ->
|
||||
" lda #<${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
" lda ${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
// push msb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB)) { segment ->
|
||||
" lda #>${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
" lda ${segment[0].callLabel}+1 | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
|
||||
// set a register pair to a certain memory address (of a variable)
|
||||
|
@ -38,9 +38,9 @@ val BuiltinFunctions = mapOf(
|
||||
"rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
|
||||
"deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
|
||||
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.FLOAT, ::builtinAvg),
|
||||
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) },
|
||||
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) },
|
||||
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) },
|
||||
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) },
|
||||
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) },
|
||||
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) },
|
||||
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", IterableDatatypes)), DataType.UBYTE, ::builtinLen),
|
||||
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
|
||||
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
|
||||
@ -49,6 +49,8 @@ val BuiltinFunctions = mapOf(
|
||||
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes)), DataType.FLOAT, ::builtinFlt),
|
||||
"uwrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.WORD))), DataType.UWORD, ::builtinUwrd),
|
||||
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD))), DataType.WORD, ::builtinWrd),
|
||||
"fintb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.BYTE, ::builtinFintb),
|
||||
"fintw" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD, ::builtinFintw),
|
||||
"b2ub" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.BYTE))), DataType.UBYTE, ::builtinB2ub),
|
||||
"ub2b" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE))), DataType.BYTE, ::builtinUb2b),
|
||||
"rnd" to FunctionSignature(true, emptyList(), DataType.UBYTE),
|
||||
@ -245,6 +247,42 @@ private fun builtinFlt(args: List<IExpression>, position: Position, namespace:IN
|
||||
return LiteralValue(DataType.FLOAT, floatvalue = number.toDouble(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinFintb(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 float arg, convert to byte
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("fintb requires one floating point argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.FLOAT)
|
||||
throw SyntaxError("fintb requires one floating point argument", position)
|
||||
val integer: Short
|
||||
val flt = constval.floatvalue!!
|
||||
integer = when {
|
||||
flt <= -128 -> -128
|
||||
flt >= 127 -> 127
|
||||
else -> flt.toShort()
|
||||
}
|
||||
return LiteralValue(DataType.BYTE, bytevalue = integer, position = position)
|
||||
}
|
||||
|
||||
private fun builtinFintw(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 float arg, convert to word
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("fintw requires one floating point argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.FLOAT)
|
||||
throw SyntaxError("fintw requires one floating point argument", position)
|
||||
val integer: Int
|
||||
val flt = constval.floatvalue!!
|
||||
integer = when {
|
||||
flt <= -32768 -> -32768
|
||||
flt >= 32767 -> 32767
|
||||
else -> flt.toInt()
|
||||
}
|
||||
return LiteralValue(DataType.WORD, wordvalue = integer, position = position)
|
||||
}
|
||||
|
||||
private fun builtinWrd(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 byte arg, convert to word
|
||||
if(args.size!=1)
|
||||
|
@ -39,6 +39,8 @@ enum class Syscall(val callNr: Short) {
|
||||
FUNC_ROUND(79),
|
||||
FUNC_FLOOR(80),
|
||||
FUNC_CEIL(81),
|
||||
FUNC_FINTB(82),
|
||||
FUNC_FINTW(83),
|
||||
FUNC_RND(89), // push a random byte on the stack
|
||||
FUNC_RNDW(90), // push a random word on the stack
|
||||
FUNC_RNDF(91), // push a random float on the stack (between 0.0 and 1.0)
|
||||
@ -442,31 +444,7 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(second, DataType.FLOAT)
|
||||
evalstack.push(second.div(top))
|
||||
}
|
||||
Opcode.FLOORDIV_UB -> {
|
||||
val (top, second) = evalstack.pop2()
|
||||
checkDt(top, DataType.UBYTE)
|
||||
checkDt(second, DataType.UBYTE)
|
||||
evalstack.push(second.floordiv(top))
|
||||
}
|
||||
Opcode.FLOORDIV_UW -> {
|
||||
val (top, second) = evalstack.pop2()
|
||||
checkDt(top, DataType.UWORD)
|
||||
checkDt(second, DataType.UWORD)
|
||||
evalstack.push(second.floordiv(top))
|
||||
}
|
||||
Opcode.FLOORDIV_B -> {
|
||||
val (top, second) = evalstack.pop2()
|
||||
checkDt(top, DataType.BYTE)
|
||||
checkDt(second, DataType.BYTE)
|
||||
evalstack.push(second.floordiv(top))
|
||||
}
|
||||
Opcode.FLOORDIV_W -> {
|
||||
val (top, second) = evalstack.pop2()
|
||||
checkDt(top, DataType.WORD)
|
||||
checkDt(second, DataType.WORD)
|
||||
evalstack.push(second.floordiv(top))
|
||||
}
|
||||
Opcode.FLOORDIV_F -> {
|
||||
Opcode.FLOORDIV -> {
|
||||
val (top, second) = evalstack.pop2()
|
||||
checkDt(top, DataType.FLOAT)
|
||||
checkDt(second, DataType.FLOAT)
|
||||
@ -1649,6 +1627,34 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
evalstack.push(Value(DataType.FLOAT, y.toDouble()))
|
||||
}
|
||||
Syscall.FUNC_FINTB -> {
|
||||
val value = evalstack.pop()
|
||||
if(value.type in NumericDatatypes) {
|
||||
val integer: Short
|
||||
val flt = value.numericValue().toDouble()
|
||||
integer = when {
|
||||
flt <= -128 -> -128
|
||||
flt >= 127 -> 127
|
||||
else -> flt.toShort()
|
||||
}
|
||||
evalstack.push(Value(DataType.BYTE, integer))
|
||||
}
|
||||
else throw VmExecutionException("cannot fintb $value")
|
||||
}
|
||||
Syscall.FUNC_FINTW -> {
|
||||
val value = evalstack.pop()
|
||||
if(value.type in NumericDatatypes) {
|
||||
val integer: Int
|
||||
val flt = value.numericValue().toDouble()
|
||||
integer = when {
|
||||
flt <= -32768 -> -32768
|
||||
flt >= 32767 -> 32767
|
||||
else -> flt.toInt()
|
||||
}
|
||||
evalstack.push(Value(DataType.WORD, integer))
|
||||
}
|
||||
else throw VmExecutionException("cannot fintw $value")
|
||||
}
|
||||
Syscall.FUNC_WRD -> {
|
||||
val value = evalstack.pop()
|
||||
checkDt(value, DataType.UBYTE, DataType.BYTE, DataType.UWORD)
|
||||
|
@ -324,9 +324,7 @@ class TestStackVmOpcodes {
|
||||
|
||||
@Test
|
||||
fun testFloorDiv() {
|
||||
testBinaryOperator(Value(DataType.UBYTE, 244), Opcode.FLOORDIV_UB, Value(DataType.UBYTE, 33), Value(DataType.UBYTE, 7))
|
||||
testBinaryOperator(Value(DataType.UWORD, 3999), Opcode.FLOORDIV_UW, Value(DataType.UWORD, 99), Value(DataType.UWORD, 40))
|
||||
testBinaryOperator(Value(DataType.FLOAT, 4000.25), Opcode.FLOORDIV_F, Value(DataType.FLOAT, 40.2), Value(DataType.FLOAT, 99.0))
|
||||
testBinaryOperator(Value(DataType.FLOAT, 4000.25), Opcode.FLOORDIV, Value(DataType.FLOAT, 40.2), Value(DataType.FLOAT, 99.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -551,6 +551,12 @@ flt(x)
|
||||
Explicitly convert the number x to a floating point number.
|
||||
This is required if you want calculations to have floating point precision when the values aren't float already.
|
||||
|
||||
fintb(x)
|
||||
Take floor of the floating point into a byte value. (no overflow check). Use together with b2ub() to convert into a unsigned byte instead.
|
||||
|
||||
fintw(x)
|
||||
Take floor of the floating point into a word value. (no overflow check).
|
||||
|
||||
wrd(x)
|
||||
Explicitly convert the value x to a signed word (sign extended).
|
||||
This is required if you want calculations to have word precision when the values are different types.
|
||||
|
@ -922,25 +922,59 @@ func_round .proc
|
||||
jsr pop_float_fac1
|
||||
stx SCRATCH_ZPREGX
|
||||
jsr c64.FADDH
|
||||
jsr c64.FTOSWORDYA
|
||||
ldx SCRATCH_ZPREGX
|
||||
sta ESTACK_HI,x
|
||||
tya
|
||||
jsr c64.INT
|
||||
jmp push_fac1_as_result
|
||||
.pend
|
||||
|
||||
func_floor .proc
|
||||
jsr pop_float_fac1
|
||||
stx SCRATCH_ZPREGX
|
||||
jsr c64.INT
|
||||
jmp push_fac1_as_result
|
||||
.pend
|
||||
|
||||
func_ceil .proc
|
||||
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
||||
jsr pop_float_fac1
|
||||
stx SCRATCH_ZPREGX
|
||||
lda #<fmath_float1
|
||||
ldy #>fmath_float1
|
||||
jsr c64.MOVMF
|
||||
jsr c64.INT
|
||||
lda #<fmath_float1
|
||||
ldy #>fmath_float1
|
||||
jsr c64.FCOMP
|
||||
cmp #0
|
||||
beq +
|
||||
lda #<c64.FL_FONE
|
||||
ldy #>c64.FL_FONE
|
||||
jsr c64.FADD
|
||||
+ jmp push_fac1_as_result
|
||||
.pend
|
||||
|
||||
func_fintb .proc
|
||||
jsr pop_float_fac1
|
||||
stx SCRATCH_ZPREGX
|
||||
jsr c64.AYINT
|
||||
lda $65
|
||||
sta ESTACK_LO,x
|
||||
dex
|
||||
rts
|
||||
.warn "round check outcome"
|
||||
.pend
|
||||
|
||||
func_floor .proc ; @todo check outcome vs round/ceil
|
||||
func_fintw .proc
|
||||
jsr pop_float_fac1
|
||||
stx SCRATCH_ZPREGX
|
||||
jsr c64.AYINT
|
||||
lda $64
|
||||
sta ESTACK_HI,x
|
||||
lda $65
|
||||
sta ESTACK_LO,x
|
||||
dex
|
||||
rts
|
||||
.warn "floor not implemented"
|
||||
.pend
|
||||
|
||||
func_ceil .proc ; @todo check outcome vs floor/round
|
||||
rts
|
||||
.warn "ceil not implemented"
|
||||
.pend
|
||||
|
||||
|
||||
peek_address .proc
|
||||
; -- peek address on stack into SCRATCH_ZPWORD1
|
||||
@ -1123,11 +1157,6 @@ _rndf_rnum5 .fill 5
|
||||
.pend
|
||||
|
||||
|
||||
func_str2byte .proc
|
||||
rts
|
||||
.warn "str2byte not implemented"
|
||||
.pend
|
||||
|
||||
; @todo python code for a str-to-ubyte function that doesn't use the basic rom:
|
||||
;def str2ubyte(s, slen):
|
||||
; hundreds_map = {
|
||||
@ -1153,12 +1182,8 @@ func_str2byte .proc
|
||||
; result += digitvalue
|
||||
; return result
|
||||
|
||||
func_str2ubyte .proc
|
||||
jmp func_str2uword
|
||||
.pend
|
||||
|
||||
func_str2uword .proc
|
||||
;-- convert string (address on stack) to uword number
|
||||
;-- convert string (address on stack) to uword number (also used by str2ubyte)
|
||||
lda ESTACK_LO+1,x
|
||||
sta $22
|
||||
lda ESTACK_HI+1,x
|
||||
@ -1188,6 +1213,11 @@ func_str2word .proc
|
||||
.warn "str2word not implemented"
|
||||
.pend
|
||||
|
||||
func_str2byte .proc
|
||||
rts
|
||||
.warn "str2byte not implemented"
|
||||
.pend
|
||||
|
||||
func_str2float .proc
|
||||
rts
|
||||
.warn "str2float not implemented"
|
||||
|
Loading…
x
Reference in New Issue
Block a user