mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
remove syscall() builtin functions
vm code can do this via inline assembly
This commit is contained in:
parent
0ee790969d
commit
b32641db87
@ -119,7 +119,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
"cmp" -> funcCmp(fcall)
|
||||
"callfar" -> funcCallFar(fcall)
|
||||
"callrom" -> funcCallRom(fcall)
|
||||
"syscall", "syscall1", "syscall2", "syscall3", "syscall1fp" -> throw AssemblyError("6502 assembly target doesn't use syscall function interface")
|
||||
else -> throw AssemblyError("missing asmgen for builtin func ${func.name}")
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import prog8.code.ast.*
|
||||
import prog8.code.core.ArrayToElementTypes
|
||||
import prog8.code.core.AssemblyError
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.WordDatatypes
|
||||
import prog8.vm.Opcode
|
||||
import prog8.vm.Syscall
|
||||
import prog8.vm.VmDataType
|
||||
@ -32,11 +31,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
||||
"rndw" -> funcRndw(resultRegister)
|
||||
"callfar" -> throw AssemblyError("callfar() is for cx16 target only")
|
||||
"callrom" -> throw AssemblyError("callrom() is for cx16 target only")
|
||||
"syscall" -> funcSyscall(call)
|
||||
"syscall1" -> funcSyscall1(call)
|
||||
"syscall2" -> funcSyscall2(call)
|
||||
"syscall3" -> funcSyscall3(call)
|
||||
"syscall1fp" -> funcSyscall1fp(call)
|
||||
"msb" -> funcMsb(call, resultRegister)
|
||||
"lsb" -> funcLsb(call, resultRegister)
|
||||
"memory" -> funcMemory(call, resultRegister)
|
||||
@ -350,60 +344,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcSyscall(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val vExpr = call.args.single() as PtNumber
|
||||
code += VmCodeInstruction(Opcode.SYSCALL, value=vExpr.number.toInt())
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcSyscall1(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
||||
code += exprGen.translateExpression(call.args[1], 0, -1)
|
||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcSyscall1fp(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
||||
code += exprGen.translateExpression(call.args[1], -1, 0)
|
||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcSyscall2(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1 = 1)
|
||||
while(codeGen.vmRegisters.peekNext()<2) {
|
||||
codeGen.vmRegisters.nextFree()
|
||||
}
|
||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
||||
code += exprGen.translateExpression(call.args[1], 0, -1)
|
||||
code += exprGen.translateExpression(call.args[2], 1, -1)
|
||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
||||
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 1)
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcSyscall3(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1 = 1)
|
||||
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1 = 2)
|
||||
while(codeGen.vmRegisters.peekNext()<3) {
|
||||
codeGen.vmRegisters.nextFree()
|
||||
}
|
||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
||||
code += exprGen.translateExpression(call.args[1], 0, -1)
|
||||
code += exprGen.translateExpression(call.args[2], 1, -1)
|
||||
code += exprGen.translateExpression(call.args[3], 2, -1)
|
||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
||||
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 2)
|
||||
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 1)
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcRolRor2(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||
val vmDt = codeGen.vmType(call.args[0].type)
|
||||
val code = VmCodeChunk()
|
||||
|
@ -19,84 +19,130 @@ sub print_f(float value) {
|
||||
}
|
||||
|
||||
sub pow(float value, float power) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fpow.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.pow.value}
|
||||
loadm.f fr1,{floats.pow.power}
|
||||
fpow.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub fabs(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fabs.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.fabs.value}
|
||||
fabs.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub sin(float angle) -> float {
|
||||
; TODO sin.f instruction
|
||||
; TODO fsin.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.sin.angle}
|
||||
sin.f fr0,fr0
|
||||
fsin.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub cos(float angle) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fcos.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.cos.angle}
|
||||
fcos.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub tan(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO ftan.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.tan.value}
|
||||
ftan.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub atan(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fatan.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.atan.value}
|
||||
fatan.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub ln(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fln.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.ln.value}
|
||||
fln.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub log2(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO flog2.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.log2.value}
|
||||
flog2.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub sqrt(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fsqrt.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.sqrt.value}
|
||||
fsqrt.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub rad(float angle) -> float {
|
||||
; -- convert degrees to radians (d * pi / 180)
|
||||
; TODO
|
||||
return -42.42
|
||||
return angle * PI / 180.0
|
||||
}
|
||||
|
||||
sub deg(float angle) -> float {
|
||||
; -- convert radians to degrees (d * (1/ pi * 180))
|
||||
; TODO
|
||||
return -42.42
|
||||
return angle * 180.0 / PI
|
||||
}
|
||||
|
||||
sub round(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fround.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.round.value}
|
||||
fround.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub floor(float value) -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO ffloor.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.floor.value}
|
||||
ffloor.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub ceil(float value) -> float {
|
||||
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO fceil.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.ceil.value}
|
||||
fceil.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub rndf() -> float {
|
||||
; TODO
|
||||
return -42.42
|
||||
; TODO frnd.f instruction
|
||||
%asm {{
|
||||
frnd.f fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -8,74 +8,26 @@ sys {
|
||||
|
||||
const ubyte target = 255 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 8 = atari800XL, 255 = virtual
|
||||
|
||||
; Syscalls table, taken from Syscall enumeration
|
||||
; 0 = reset ; resets system
|
||||
; 1 = exit ; stops program and returns statuscode from r0.w
|
||||
; 2 = print_c ; print single character
|
||||
; 3 = print_s ; print 0-terminated string from memory
|
||||
; 4 = print_u8 ; print unsigned int byte
|
||||
; 5 = print_u16 ; print unsigned int word
|
||||
; 6 = input ; reads a line of text entered by the user, r0.w = memory buffer, r1.b = maxlength (0-255, 0=unlimited). Zero-terminates the string. Returns length in r0.w
|
||||
; 7 = sleep ; sleep amount of milliseconds
|
||||
; 8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480
|
||||
; 9 = gfx_clear ; clear graphics window with shade in r0.b
|
||||
; 10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness
|
||||
; 11 = set_carry status flag
|
||||
; 12 = clear_carry status flag
|
||||
; 13 = wait ; wait certain amount of jiffies (1/60 sec)
|
||||
; 14 = waitvsync ; wait on vsync
|
||||
; 15 = sort_ubyte array
|
||||
; 16 = sort_byte array
|
||||
; 17 = sort_uword array
|
||||
; 18 = sort_word array
|
||||
; 19 = max_ubyte array
|
||||
; 20 = max_byte array
|
||||
; 21 = max_uword array
|
||||
; 22 = max_word array
|
||||
; 23 = min_ubyte array
|
||||
; 24 = min_byte array
|
||||
; 25 = min_uword array
|
||||
; 26 = min_word array
|
||||
; 27 = sum_byte array
|
||||
; 28 = sum_word array
|
||||
; 29 = any_byte array
|
||||
; 30 = any_word array
|
||||
; 31 = all_byte array
|
||||
; 32 = all_word array
|
||||
; 33 = reverse_bytes array
|
||||
; 34 = reverse_words array
|
||||
; 35 = printf (float arg in fpReg0)
|
||||
const ubyte SC_RESET = 0
|
||||
const ubyte SC_EXIT = 1
|
||||
const ubyte SC_PRINT_C = 2
|
||||
const ubyte SC_PRINT_S = 3
|
||||
const ubyte SC_PRINT_U8 = 4
|
||||
const ubyte SC_PRINT_U16 = 5
|
||||
const ubyte SC_INPUT = 6
|
||||
const ubyte SC_SLEEP = 7
|
||||
const ubyte SC_GFX_ENABLE = 8
|
||||
const ubyte SC_GFX_CLEAR = 9
|
||||
const ubyte SC_GFX_PLOT = 10
|
||||
const ubyte SC_SET_CARRY = 11
|
||||
const ubyte SC_CLEAR_CARRY = 12
|
||||
const ubyte SC_WAIT = 13
|
||||
const ubyte SC_WAITVSYNC = 14
|
||||
const ubyte SC_PRINTF = 35
|
||||
|
||||
|
||||
sub reset_system() {
|
||||
; Soft-reset the system back to initial power-on Basic prompt.
|
||||
void syscall(SC_RESET)
|
||||
%asm {{
|
||||
syscall 0
|
||||
}}
|
||||
}
|
||||
|
||||
sub wait(uword jiffies) {
|
||||
; --- wait approximately the given number of jiffies (1/60th seconds)
|
||||
void syscall1(SC_WAIT, jiffies)
|
||||
%asm {{
|
||||
loadm.w r0, {sys.wait.jiffies}
|
||||
syscall 13
|
||||
}}
|
||||
}
|
||||
|
||||
sub waitvsync() {
|
||||
; --- busy wait till the next vsync has occurred (approximately), without depending on custom irq handling.
|
||||
void syscall(SC_WAITVSYNC)
|
||||
%asm {{
|
||||
syscall 14
|
||||
}}
|
||||
}
|
||||
|
||||
sub internal_stringcopy(uword source, uword target) {
|
||||
@ -112,15 +64,39 @@ sys {
|
||||
|
||||
sub exit(ubyte returnvalue) {
|
||||
; -- immediately exit the program with a return code in the A register
|
||||
void syscall1(SC_EXIT, returnvalue)
|
||||
}
|
||||
|
||||
sub clear_carry() {
|
||||
void syscall(SC_CLEAR_CARRY)
|
||||
%asm {{
|
||||
loadm.b r0,{sys.exit.returnvalue}
|
||||
syscall 1
|
||||
}}
|
||||
}
|
||||
|
||||
sub set_carry() {
|
||||
void syscall(SC_SET_CARRY)
|
||||
%asm {{
|
||||
sec
|
||||
}}
|
||||
}
|
||||
|
||||
sub clear_carry() {
|
||||
%asm {{
|
||||
clc
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
sub gfx_enable(ubyte mode) {
|
||||
%asm {{
|
||||
loadm.b r0, {sys.gfx_enable.mode}
|
||||
syscall 8
|
||||
}}
|
||||
}
|
||||
|
||||
sub gfx_plot(uword xx, uword yy, ubyte color) {
|
||||
%asm {{
|
||||
loadm.w r0, {sys.gfx_plot.xx}
|
||||
loadm.w r1, {sys.gfx_plot.yy}
|
||||
loadm.b r2, {sys.gfx_plot.color}
|
||||
syscall 10
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,11 @@
|
||||
txt {
|
||||
|
||||
sub clear_screen() {
|
||||
void syscall1(3, "\x1b[2J\x1B[H")
|
||||
str @shared sequence = "\x1b[2J\x1B[H"
|
||||
%asm {{
|
||||
load.w r0, {txt.clear_screen.sequence}
|
||||
syscall 3
|
||||
}}
|
||||
}
|
||||
|
||||
sub nl() {
|
||||
@ -27,11 +31,17 @@ sub uppercase() {
|
||||
}
|
||||
|
||||
sub chrout(ubyte char) {
|
||||
void syscall1(2, char)
|
||||
%asm {{
|
||||
loadm.b r0, {txt.chrout.char}
|
||||
syscall 2
|
||||
}}
|
||||
}
|
||||
|
||||
sub print (str text) {
|
||||
void syscall1(3, text)
|
||||
%asm {{
|
||||
loadm.w r0, {txt.print.text}
|
||||
syscall 3
|
||||
}}
|
||||
}
|
||||
|
||||
sub print_ub0 (ubyte value) {
|
||||
@ -105,7 +115,11 @@ sub print_w (word value) {
|
||||
sub input_chars (uword buffer) -> ubyte {
|
||||
; ---- Input a string (max. 80 chars) from the keyboard. Returns length of input. (string is terminated with a 0 byte as well)
|
||||
; It assumes the keyboard is selected as I/O channel!
|
||||
return syscall1(6, buffer)
|
||||
%asm {{
|
||||
loadm.w r0,{txt.input_chars.buffer}
|
||||
syscall 6
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -123,11 +123,6 @@ private val functionSignatures: List<FSignature> = listOf(
|
||||
FSignature("swap" , false, listOf(FParam("first", NumericDatatypes), FParam("second", NumericDatatypes)), null),
|
||||
FSignature("callfar" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
||||
FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
||||
FSignature("syscall" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE))), DataType.UWORD, null),
|
||||
FSignature("syscall1" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD))), DataType.UWORD, null),
|
||||
FSignature("syscall1fp" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.FLOAT))), DataType.FLOAT, null),
|
||||
FSignature("syscall2" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD)), FParam("arg2", arrayOf(DataType.UWORD))), DataType.UWORD, null),
|
||||
FSignature("syscall3" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD)), FParam("arg2", arrayOf(DataType.UWORD)), FParam("arg3", arrayOf(DataType.UWORD))), DataType.UWORD, null),
|
||||
)
|
||||
|
||||
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- vm: get rid of the syscall() functions in prog8 via inline assembly
|
||||
- vm: fix fp reg out of bounds
|
||||
- vm: implement missing floating point functions
|
||||
- vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly?
|
||||
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
|
||||
|
@ -8,14 +8,23 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
txt.print("float tests: ")
|
||||
floats.print_f(-42.42)
|
||||
float f1 = 1.2345
|
||||
float f2 = -9.99
|
||||
float f3
|
||||
f3 = floats.sin(f3)
|
||||
floats.print_f(f3)
|
||||
txt.nl()
|
||||
float fl = 500.0
|
||||
txt.print("rad 180 = ")
|
||||
floats.print_f(floats.rad(180.0))
|
||||
txt.print("rad 360 = ")
|
||||
floats.print_f(floats.rad(360.0))
|
||||
txt.print("deg 2 = ")
|
||||
floats.print_f(floats.deg(2.0))
|
||||
txt.print("deg pi = ")
|
||||
floats.print_f(floats.deg(floats.PI))
|
||||
sys.exit(42)
|
||||
; floats.print_f(-42.42)
|
||||
; float f1 = 1.2345
|
||||
; float f2 = -9.99
|
||||
; float f3
|
||||
; f3 = floats.sin(f3)
|
||||
; floats.print_f(f3)
|
||||
; txt.nl()
|
||||
|
||||
; float f1 = 1.555
|
||||
; floats.print_f(floats.sin(f1))
|
||||
@ -49,23 +58,21 @@ main {
|
||||
; "deg", "round", "floor", "ceil", "rndf"
|
||||
|
||||
; a "pixelshader":
|
||||
; void syscall1(8, 0) ; enable lo res creen
|
||||
; ubyte shifter
|
||||
;
|
||||
; ; pokemon(1,0)
|
||||
;
|
||||
; repeat {
|
||||
; uword xx
|
||||
; uword yy = 0
|
||||
; repeat 240 {
|
||||
; xx = 0
|
||||
; repeat 320 {
|
||||
; syscall3(10, xx, yy, xx*yy + shifter) ; plot pixel
|
||||
; xx++
|
||||
; }
|
||||
; yy++
|
||||
; }
|
||||
; shifter+=4
|
||||
; }
|
||||
sys.gfx_enable(0) ; enable lo res screen
|
||||
ubyte shifter
|
||||
|
||||
repeat {
|
||||
uword xx
|
||||
uword yy = 0
|
||||
repeat 240 {
|
||||
xx = 0
|
||||
repeat 320 {
|
||||
sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte)
|
||||
xx++
|
||||
}
|
||||
yy++
|
||||
}
|
||||
shifter+=4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ SYSCALLS:
|
||||
8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480
|
||||
9 = gfx_clear ; clear graphics window with shade in r0.b
|
||||
10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness
|
||||
11 = set_carry status flag
|
||||
12 = clear_carry status flag
|
||||
11 = <unused 1>
|
||||
12 = <unused 2>
|
||||
13 = wait ; wait certain amount of jiffies (1/60 sec)
|
||||
14 = waitvsync ; wait on vsync
|
||||
15 = sort_ubyte array
|
||||
@ -55,8 +55,8 @@ enum class Syscall {
|
||||
GFX_ENABLE,
|
||||
GFX_CLEAR,
|
||||
GFX_PLOT,
|
||||
SET_CARRY,
|
||||
CLEAR_CARRY,
|
||||
UNUSED_1,
|
||||
UNUSED_2,
|
||||
WAIT,
|
||||
WAITVSYNC,
|
||||
SORT_UBYTE,
|
||||
@ -297,8 +297,6 @@ object SysCalls {
|
||||
else
|
||||
vm.registers.setUB(0, 0u)
|
||||
}
|
||||
Syscall.SET_CARRY -> vm.statusCarry = true
|
||||
Syscall.CLEAR_CARRY -> vm.statusCarry = false
|
||||
Syscall.PRINT_F -> {
|
||||
val value = vm.registers.getFloat(0)
|
||||
print(value)
|
||||
|
@ -61,11 +61,13 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
||||
|
||||
fun reset() {
|
||||
registers.reset()
|
||||
memory.reset()
|
||||
// memory.reset()
|
||||
pc = 0
|
||||
stepCount = 0
|
||||
callStack.clear()
|
||||
statusCarry = false
|
||||
statusNegative = false
|
||||
statusZero = false
|
||||
}
|
||||
|
||||
fun exit() {
|
||||
@ -168,6 +170,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
||||
Opcode.PUSH -> InsPUSH(ins)
|
||||
Opcode.POP -> InsPOP(ins)
|
||||
Opcode.BREAKPOINT -> InsBREAKPOINT()
|
||||
Opcode.CLC -> { statusCarry = false; pc++ }
|
||||
Opcode.SEC -> { statusCarry = true; pc++ }
|
||||
else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user