old-code | ||
.gitignore | ||
opcodes.txt | ||
README.md | ||
tests.rkt | ||
vm.rkt |
zybino: LR35902ish racket language
very early days for now.
in the racket repl (comments for reader comprehension, remove before running):
(run-vm #x150 #x150 #x19 ; start-address, end-memory-view-addr, number-bytes-view
'(#x3E #x69 ; LD A, $69
#x26 #x01 ; LD H, $01
#x2E #x67 ; LD L, $67
#x77 ; LD (HL), A
#x2E #x5B ; LD L, $5B
#x36 #xE6 ; LD (HL), $E6 ($E6 is the opcode for XOR $xx)
#x10 ; STOP (this instruction @ address $015B)
#xF0 ; (non-instruction, will be arg for previous byte)
#x2E #x68 ; LD L, $68
#x77 ; LD (HL), A
#xC2 #x64 #x01 ; JP NZ, $0164
#x10 ; STOP
#x7D ; LD A, L (address $0164)
#x10 ; STOP
))
will evaluate to:
PC: $0166, SP: $0000, Flags: %00000000
BC: $0000, DE: $0000
HL: $0168, AF: $6800
(HL): $60
$0150 > $3e $69 $26 $01 $2e $67 $77 $2e $5b $36 $e6 $e6 $f0 $2e $68 $77 $c3 $64 $01 $10 $7d $10 $00 $69 $60 < $0168
here we can see the program loaded starting from address $0150
, including the XOR
instruction loaded to $015B
during execution, and the $69
we loaded to memory, along with the result of XOR $F0
we loaded to memory, at $0167
and $0168
respectively. we can also see that the A
register is $68
, the same as the L
register, as the conditional JP NZ
instruction executed properly and we skipped the STOP
at address $0163
.
example 2 - loops
running:
(run-vm #x0000 #x0160 8
'(#x26 #x01 ; LD H, $01
#x2E #x61 ; LD L, $60
#x3E #x05 ; LD A, $05
#x77 ; LD (HL), A
#x2C ; INC L
#x3D ; DEC A
#xFE #x00 ; CP $00
#xC2 #x06 #x00 ; JP NZ, $0008
#x10 ; STOP
)))
evaluates to:
PC: $000f, SP: $0000, Flags: %10000000
BC: $0000, DE: $0000
HL: $0166, AF: $0080
(HL): $00
$0160 > $00 $05 $04 $03 $02 $01 $00 $00 < $0167
where we can see the zero flag set (bit 7), thus triggering the conditional loop, and the result of our loop saved to addresses $0161
to $0166
notes
currently supported instructions are:
JP #addr
JP [cc], #addr
LD [reg], #imm
LD [reg], [reg]
XOR #imm
AND #imm
OR #imm
ADD #imm
ADC #imm
SUB #imm
SBC #imm
CP #imm
XOR [reg]
AND [reg]
OR [reg]
ADD [reg]
ADC [reg]
SUB [reg]
SBC [reg]
CP [reg]
INC [reg]
DEC [reg]
STOP
NOP
all other instructions treated as NOP
on a gameboy, the instruction LD (HL), (HL)
is treated as a HALT
, however i am not making a gameboy perfect vm as of now, so opcode $76
is currently treated as LD (HL), (HL)