@@ -3,3 +3,4 @@ | |||||
!old-code | !old-code | ||||
!README.md | !README.md | ||||
!.gitignore | !.gitignore | ||||
!*.txt |
@@ -35,6 +35,36 @@ $0150 > $3e $69 $26 $01 $2e $67 $77 $2e $5b $36 $e6 $e6 $f0 $2e $68 $77 $c3 $64 | |||||
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`. | 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 | ## notes | ||||
currently supported instructions are: | currently supported instructions are: | ||||
@@ -45,6 +75,21 @@ currently supported instructions are: | |||||
* `XOR #imm` | * `XOR #imm` | ||||
* `AND #imm` | * `AND #imm` | ||||
* `OR #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` | * `STOP` | ||||
* `NOP` | * `NOP` | ||||
@@ -0,0 +1,178 @@ | |||||
-- List of Opcodes Sorted by Function -- | |||||
--- Registers --- | |||||
0: B | |||||
1: C | |||||
2: D | |||||
3: E | |||||
4: H | |||||
5: L | |||||
6: (HL) | |||||
7: A | |||||
--- Control Codes --- | |||||
'UNCOND: No condition | |||||
0: NZ | |||||
1: Z | |||||
2: NC | |||||
3: C | |||||
--- Racket Implementation --- | |||||
'(NOP) | |||||
'(STOP) | |||||
'(RLCA) | |||||
'(RRCA) | |||||
'(RLA) | |||||
'(RRA) | |||||
'(DAA) | |||||
'(CPL) | |||||
'(SCF) | |||||
'(CCF) | |||||
'(EI) | |||||
'(DI) | |||||
'(Prefix) | |||||
'(Removed) | |||||
'(RST #x10) | |||||
'(16b-ld-regp-imm 3 #xFFE0) ; uses lookup table for regp | |||||
--- Misc --- | |||||
NOP | |||||
STOP | |||||
RLCA | |||||
RRCA | |||||
RLA | |||||
RRA | |||||
DAA | |||||
CPL | |||||
SCF | |||||
CCF | |||||
EI | |||||
DI | |||||
CB-Prefix | |||||
Removed | |||||
rst-vec: | |||||
RST $0000 | |||||
--- LDs --- | |||||
16b-ld-indimm-regp: | |||||
LD ($XXYY), SP | |||||
16b-ld-regp-imm: | |||||
LD BC, $XXYY | |||||
8b-ld-indregp-a: | |||||
LD (BC), A | |||||
8b-ld-a-indregp: | |||||
LD A, (BC) | |||||
8b-ldi-a-indregp: | |||||
LD A, (HL+) | |||||
8b-ldi-indregp-a: | |||||
8b-ldd-a-indregp: | |||||
8b-ldd-indregp-a: | |||||
8b-ld-reg-imm: | |||||
8b-ld-reg-reg: | |||||
8b-ldh-imm-a: | |||||
8b-ldh-a-imm: | |||||
16b-ld-HL-SP+d: | |||||
16b-ld-SP-HL: | |||||
8b-ldh-c-a: | |||||
8b-ldh-a-c: | |||||
8b-ld-indimm-a: | |||||
8b-ld-a-indimm: | |||||
--- ALU --- | |||||
8b-and-imm: | |||||
8b-adc-imm: | |||||
8b-sub-imm: | |||||
8b-sbc-imm: | |||||
8b-and-imm: | |||||
8b-xor-imm: | |||||
8b-or-imm: | |||||
8b-cp-imm: | |||||
8b-add-a-reg: | |||||
8b-adc-a-reg: | |||||
8b-sub-a-reg: | |||||
8b-sbc-a-reg: | |||||
8b-and-reg: | |||||
8b-xor-reg: | |||||
8b-or-reg: | |||||
8b-cp-reg: | |||||
8b-inc: | |||||
8b-dec: | |||||
16b-inc: | |||||
16b-dec: | |||||
16b-add-regp-regp: | |||||
ADD HL, BC (HL only) | |||||
--- Jumps --- | |||||
jp-relative: | |||||
JR [uncond], $d | |||||
JR NZ, $d | |||||
JR Z, $d | |||||
JR NC, $d | |||||
JR C, $d | |||||
ret: | |||||
RET (uncond) | |||||
RET NZ | |||||
RET Z | |||||
RET NC | |||||
RET C | |||||
reti: | |||||
RETI | |||||
jp-regp: | |||||
JP HL | |||||
jp-imm: | |||||
JP (uncond), $XXYY | |||||
JP NZ, $XXYY | |||||
call-imm: | |||||
CALL (uncond), $XXYY | |||||
CALL NZ, $XXYY | |||||
--- Stack --- | |||||
16b-pop: | |||||
POP BC | |||||
16b-push: | |||||
PUSH BC | |||||
--- CB Prefix --- | |||||
8b-rlc-reg: | |||||
8b-rrc-reg: | |||||
8b-rl-reg: | |||||
8b-rr-reg: | |||||
8b-sla-reg: | |||||
8b-sra-reg: | |||||
8b-swap-reg: | |||||
8b-srl-reg: | |||||
8b-bit-x-reg: | |||||
8b-res-x-reg: | |||||
8b-set-x-reg: |
@@ -0,0 +1,587 @@ | |||||
-- Signed data is stored in 2's complement | |||||
-- 16 bit data stored LSB first | |||||
-- {%XX|YYY|ZZZ} | |||||
-- {%XX|PP|Q|ZZZ} | |||||
== No Prefix Opcodes == | |||||
$00 {%00|000|000} ~ NOP | |||||
$08 $yy $xx {%00|001|000} ~ LD ($xxyy),SP | |||||
$10 {%00|010|000} ~ STOP | |||||
$18 $dd {%00|011|000} ~ JR $dd | |||||
$20 $dd {%00|100|000} ~ JR NZ, $dd | |||||
$28 $dd {%00|101|000} ~ JR Z, $dd | |||||
$30 $dd {%00|110|000} ~ JR NC, $dd | |||||
$38 $dd {%00|111|000} ~ JR C, $dd | |||||
$01 $yy $xx {%00|00|0|001} ~ LD BC, $xxyy | |||||
$11 $yy $xx {%00|01|0|001} ~ LD DE, $xxyy | |||||
$21 $yy $xx {%00|10|0|001} ~ LD HL, $xxyy | |||||
$31 $yy $xx {%00|11|0|001} ~ LD SP, $xxyy | |||||
$09 {%00|00|1|001} ~ ADD HL, BC | |||||
$19 {%00|01|1|001} ~ ADD HL, DE | |||||
$29 {%00|10|1|001} ~ ADD HL, HL | |||||
$39 {%00|11|1|001} ~ ADD HL, SP | |||||
$02 {%00|00|0|010} ~ LD (BC), A | |||||
$12 {%00|01|0|010} ~ LD (DE), A | |||||
$22 {%00|10|0|010} ~ LD (HL+), A | |||||
$32 {%00|11|0|010} ~ LD (HL-), A | |||||
$0A {%00|00|1|010} ~ LD A, (BC) | |||||
$1A {%00|01|1|010} ~ LD A, (DE) | |||||
$2A {%00|10|1|010} ~ LD A, (HL+) | |||||
$3A {%00|11|1|010} ~ LD A, (HL-) | |||||
$03 {%00|00|0|011} ~ INC BC | |||||
$13 {%00|01|0|011} ~ INC DE | |||||
$23 {%00|10|0|011} ~ INC HL | |||||
$33 {%00|11|0|011} ~ INC SP | |||||
$0B {%00|00|1|011} ~ DEC BC | |||||
$1B {%00|01|1|011} ~ DEC DE | |||||
$2B {%00|10|1|011} ~ DEC HL | |||||
$3B {%00|11|1|011} ~ DEC SP | |||||
$04 {%00|000|100} ~ INC B | |||||
$0C {%00|001|100} ~ INC C | |||||
$14 {%00|010|100} ~ INC D | |||||
$1C {%00|011|100} ~ INC E | |||||
$24 {%00|100|100} ~ INC H | |||||
$2C {%00|101|100} ~ INC L | |||||
$34 {%00|110|100} ~ INC (HL) | |||||
$3C {%00|111|100} ~ INC A | |||||
$05 {%00|000|101} ~ DEC B | |||||
$0D {%00|001|101} ~ DEC C | |||||
$15 {%00|010|101} ~ DEC D | |||||
$1D {%00|011|101} ~ DEC E | |||||
$25 {%00|100|101} ~ DEC H | |||||
$2D {%00|101|101} ~ DEC L | |||||
$35 {%00|110|101} ~ DEC (HL) | |||||
$3D {%00|111|101} ~ DEC A | |||||
$06 $xx {%00|000|110} ~ LD B, $xx | |||||
$0E $xx {%00|001|110} ~ LD C, $xx | |||||
$16 $xx {%00|010|110} ~ LD D, $xx | |||||
$1E $xx {%00|011|110} ~ LD E, $xx | |||||
$26 $xx {%00|100|110} ~ LD H, $xx | |||||
$2E $xx {%00|101|110} ~ LD L, $xx | |||||
$36 $xx {%00|110|110} ~ LD (HL), $xx | |||||
$3E $xx {%00|111|110} ~ LD A, $xx | |||||
$07 {%00|000|111} ~ RLCA | |||||
$0F {%00|001|111} ~ RRCA | |||||
$17 {%00|010|111} ~ RLA | |||||
$1F {%00|011|111} ~ RRA | |||||
$27 {%00|100|111} ~ DAA | |||||
$2F {%00|101|111} ~ CPL | |||||
$37 {%00|110|111} ~ SCF | |||||
$3F {%00|111|111} ~ CCF | |||||
$40 {%01|000|000} ~ LD B, B | |||||
$41 {%01|000|001} ~ LD B, C | |||||
$42 {%01|000|010} ~ LD B, D | |||||
$43 {%01|000|011} ~ LD B, E | |||||
$44 {%01|000|100} ~ LD B, H | |||||
$45 {%01|000|101} ~ LD B, L | |||||
$46 {%01|000|110} ~ LD B, (HL) | |||||
$47 {%01|000|111} ~ LD B, A | |||||
$48 {%01|001|000} ~ LD C, B | |||||
$49 {%01|001|001} ~ LD C, C | |||||
$4A {%01|001|010} ~ LD C, D | |||||
$4B {%01|001|011} ~ LD C, E | |||||
$4C {%01|001|100} ~ LD C, H | |||||
$4D {%01|001|101} ~ LD C, L | |||||
$4E {%01|001|110} ~ LD C, (HL) | |||||
$4F {%01|001|111} ~ LD C, A | |||||
$50 {%01|010|000} ~ LD D, B | |||||
$51 {%01|010|001} ~ LD D, C | |||||
$52 {%01|010|010} ~ LD D, D | |||||
$53 {%01|010|011} ~ LD D, E | |||||
$54 {%01|010|100} ~ LD D, H | |||||
$55 {%01|010|101} ~ LD D, L | |||||
$56 {%01|010|110} ~ LD D, (HL) | |||||
$57 {%01|010|111} ~ LD D, A | |||||
$58 {%01|011|000} ~ LD E, B | |||||
$59 {%01|011|001} ~ LD E, C | |||||
$5A {%01|011|010} ~ LD E, D | |||||
$5B {%01|011|011} ~ LD E, E | |||||
$5C {%01|011|100} ~ LD E, H | |||||
$5D {%01|011|101} ~ LD E, L | |||||
$5E {%01|011|110} ~ LD E, (HL) | |||||
$5F {%01|011|111} ~ LD E, A | |||||
$60 {%01|100|000} ~ LD H, B | |||||
$61 {%01|100|001} ~ LD H, C | |||||
$62 {%01|100|010} ~ LD H, D | |||||
$63 {%01|100|011} ~ LD H, E | |||||
$64 {%01|100|100} ~ LD H, H | |||||
$65 {%01|100|101} ~ LD H, L | |||||
$66 {%01|100|110} ~ LD H, (HL) | |||||
$67 {%01|100|111} ~ LD H, A | |||||
$68 {%01|101|000} ~ LD L, B | |||||
$69 {%01|101|001} ~ LD L, C | |||||
$6A {%01|101|010} ~ LD L, D | |||||
$6B {%01|101|011} ~ LD L, E | |||||
$6C {%01|101|100} ~ LD L, H | |||||
$6D {%01|101|101} ~ LD L, L | |||||
$6E {%01|101|110} ~ LD L, (HL) | |||||
$6F {%01|101|111} ~ LD L, A | |||||
$70 {%01|110|000} ~ LD (HL), B | |||||
$71 {%01|110|001} ~ LD (HL), C | |||||
$72 {%01|110|010} ~ LD (HL), D | |||||
$73 {%01|110|011} ~ LD (HL), E | |||||
$74 {%01|110|100} ~ LD (HL), H | |||||
$75 {%01|110|101} ~ LD (HL), L | |||||
$76 {%01|110|110} ~ LD (HL), (HL) ; HALT | |||||
$77 {%01|110|111} ~ LD (HL), A | |||||
$78 {%01|111|000} ~ LD A, B | |||||
$79 {%01|111|001} ~ LD A, C | |||||
$7A {%01|111|010} ~ LD A, D | |||||
$7B {%01|111|011} ~ LD A, E | |||||
$7C {%01|111|100} ~ LD A, H | |||||
$7D {%01|111|101} ~ LD A, L | |||||
$7E {%01|111|110} ~ LD A, (HL) | |||||
$7F {%01|111|111} ~ LD A, A | |||||
$80 {%10|000|000} ~ ADD A, B | |||||
$81 {%10|000|001} ~ ADD A, C | |||||
$82 {%10|000|010} ~ ADD A, D | |||||
$83 {%10|000|011} ~ ADD A, E | |||||
$84 {%10|000|100} ~ ADD A, H | |||||
$85 {%10|000|101} ~ ADD A, L | |||||
$86 {%10|000|110} ~ ADD A, (HL) | |||||
$87 {%10|000|111} ~ ADD A, A | |||||
$88 {%10|001|000} ~ ADC A, B | |||||
$89 {%10|001|001} ~ ADC A, C | |||||
$8A {%10|001|010} ~ ADC A, D | |||||
$8B {%10|001|011} ~ ADC A, E | |||||
$8C {%10|001|100} ~ ADC A, H | |||||
$8D {%10|001|101} ~ ADC A, L | |||||
$8E {%10|001|110} ~ ADC A, (HL) | |||||
$8F {%10|001|111} ~ ADC A, A | |||||
$90 {%10|010|000} ~ SUB B | |||||
$91 {%10|010|001} ~ SUB C | |||||
$92 {%10|010|010} ~ SUB D | |||||
$93 {%10|010|011} ~ SUB E | |||||
$94 {%10|010|100} ~ SUB H | |||||
$95 {%10|010|101} ~ SUB L | |||||
$96 {%10|010|110} ~ SUB (HL) | |||||
$97 {%10|010|111} ~ SUB A | |||||
$98 {%10|011|000} ~ SBC A, B | |||||
$99 {%10|011|001} ~ SBC A, C | |||||
$9A {%10|011|010} ~ SBC A, D | |||||
$9B {%10|011|011} ~ SBC A, E | |||||
$9C {%10|011|100} ~ SBC A, H | |||||
$9D {%10|011|101} ~ SBC A, L | |||||
$9E {%10|011|110} ~ SBC A, (HL) | |||||
$9F {%10|011|111} ~ SBC A, A | |||||
$A0 {%10|100|000} ~ AND B | |||||
$A1 {%10|100|001} ~ AND C | |||||
$A2 {%10|100|010} ~ AND D | |||||
$A3 {%10|100|011} ~ AND E | |||||
$A4 {%10|100|100} ~ AND H | |||||
$A5 {%10|100|101} ~ AND L | |||||
$A6 {%10|100|110} ~ AND (HL) | |||||
$A7 {%10|100|111} ~ AND A | |||||
$A8 {%10|101|000} ~ XOR B | |||||
$A9 {%10|101|001} ~ XOR C | |||||
$AA {%10|101|010} ~ XOR D | |||||
$AB {%10|101|011} ~ XOR E | |||||
$AC {%10|101|100} ~ XOR H | |||||
$AD {%10|101|101} ~ XOR L | |||||
$AE {%10|101|110} ~ XOR (HL) | |||||
$AF {%10|101|111} ~ XOR A | |||||
$B0 {%10|110|000} ~ OR B | |||||
$B1 {%10|110|001} ~ OR C | |||||
$B2 {%10|110|010} ~ OR D | |||||
$B3 {%10|110|011} ~ OR E | |||||
$B4 {%10|110|100} ~ OR H | |||||
$B5 {%10|110|101} ~ OR L | |||||
$B6 {%10|110|110} ~ OR (HL) | |||||
$B7 {%10|110|111} ~ OR A | |||||
$B8 {%10|111|000} ~ CP B | |||||
$B9 {%10|111|001} ~ CP C | |||||
$BA {%10|111|010} ~ CP D | |||||
$BB {%10|111|011} ~ CP E | |||||
$BC {%10|111|100} ~ CP H | |||||
$BD {%10|111|101} ~ CP L | |||||
$BE {%10|111|110} ~ CP (HL) | |||||
$BF {%10|111|111} ~ CP A | |||||
$C0 {%11|000|000} ~ RET NZ | |||||
$C8 {%11|001|000} ~ RET Z | |||||
$D0 {%11|010|000} ~ RET NC | |||||
$D8 {%11|011|000} ~ RET C | |||||
$E0 $xx {%11|100|000} ~ LD ($FF00 + $xx), A | |||||
$E8 $dd {%11|101|000} ~ ADD SP, $dd | |||||
$F0 $xx {%11|110|000} ~ LD A, ($FF00 + $xx) | |||||
$F8 $dd {%11|111|000} ~ LD HL, SP+$dd | |||||
$C1 {%11|00|0|001} ~ POP BC | |||||
$D1 {%11|01|0|001} ~ POP DE | |||||
$E1 {%11|10|0|001} ~ POP HL | |||||
$F1 {%11|11|0|001} ~ POP AF | |||||
$C9 {%11|00|1|001} ~ RET | |||||
$D9 {%11|01|1|001} ~ RETI | |||||
$E9 {%11|10|1|001} ~ JP HL | |||||
$F9 {%11|11|1|001} ~ LD SP, HL | |||||
$C2 $yy $xx {%11|000|010} ~ JP NZ, $xxyy | |||||
$CA $yy $xx {%11|001|010} ~ JP Z, $xxyy | |||||
$D2 $yy $xx {%11|010|010} ~ JP NC, $xxyy | |||||
$DA $yy $xx {%11|011|010} ~ JP C, $xxyy | |||||
$E2 {%11|100|010} ~ LD ($FF00+C), A | |||||
$EA $yy $xx {%11|101|010} ~ LD ($xxyy), A | |||||
$F2 {%11|110|010} ~ LD A, ($FF00+C) | |||||
$FA $yy $xx {%11|111|010} ~ LD A, ($xxyy) | |||||
$C3 $yy $xx {%11|000|011} ~ JP $xxyy | |||||
$CB {%11|001|011} ~ [CB Prefix] | |||||
$D3 {%11|010|011} ~ ! removed ! | |||||
$DB {%11|011|011} ~ ! removed ! | |||||
$E3 {%11|100|011} ~ ! removed ! | |||||
$EB {%11|101|011} ~ ! removed ! | |||||
$F3 {%11|110|011} ~ DI | |||||
$FB {%11|111|011} ~ EI | |||||
$C4 $yy $xx {%11|000|100} ~ CALL NZ, $xxyy | |||||
$CC $yy $xx {%11|001|100} ~ CALL Z, $xxyy | |||||
$D4 $yy $xx {%11|010|100} ~ CALL NC, $xxyy | |||||
$DC $yy $xx {%11|011|100} ~ CALL C, $xxyy | |||||
$E4 {%11|100|100} ~ ! removed ! | |||||
$EC {%11|101|100} ~ ! removed ! | |||||
$F4 {%11|110|100} ~ ! removed ! | |||||
$FC {%11|111|100} ~ ! removed ! | |||||
$C5 {%11|00|0|101} ~ PUSH BC | |||||
$D5 {%11|01|0|101} ~ PUSH DE | |||||
$E5 {%11|10|0|101} ~ PUSH HL | |||||
$F5 {%11|11|0|101} ~ PUSH AF | |||||
$CD $yy $xx {%11|00|1|101} ~ CALL $xxyy | |||||
$DD {%11|01|1|101} ~ ! removed ! | |||||
$ED {%11|10|1|101} ~ ! removed ! | |||||
$FD {%11|11|1|101} ~ ! removed ! | |||||
$C6 $xx {%11|000|110} ~ ADD A, $xx | |||||
$CE $xx {%11|001|110} ~ ADC A, $xx | |||||
$D6 $xx {%11|010|110} ~ SUB $xx | |||||
$DE $xx {%11|011|110} ~ SBC A, $xx | |||||
$E6 $xx {%11|100|110} ~ AND $xx | |||||
$EE $xx {%11|101|110} ~ XOR $xx | |||||
$F6 $xx {%11|110|110} ~ OR $xx | |||||
$FE $xx {%11|111|110} ~ CP $xx | |||||
$C7 {%11|000|111} ~ RST 0x0000 | |||||
$CF {%11|001|111} ~ RST 0x0008 | |||||
$D7 {%11|010|111} ~ RST 0x0010 | |||||
$DF {%11|011|111} ~ RST 0x0018 | |||||
$E7 {%11|100|111} ~ RST 0x0020 | |||||
$EF {%11|101|111} ~ RST 0x0028 | |||||
$F7 {%11|110|111} ~ RST 0x0030 | |||||
$FF {%11|111|111} ~ RST 0x0038 | |||||
== CB Prefixed Opcodes == | |||||
$CB $00 {%00|000|000} ~ RLC B | |||||
$CB $01 {%00|000|001} ~ RLC C | |||||
$CB $02 {%00|000|010} ~ RLC D | |||||
$CB $03 {%00|000|011} ~ RLC E | |||||
$CB $04 {%00|000|100} ~ RLC H | |||||
$CB $05 {%00|000|101} ~ RLC L | |||||
$CB $06 {%00|000|110} ~ RLC (HL) | |||||
$CB $07 {%00|000|111} ~ RLC A | |||||
$CB $08 {%00|001|000} ~ RRC B | |||||
$CB $09 {%00|001|001} ~ RRC C | |||||
$CB $0A {%00|001|010} ~ RRC D | |||||
$CB $0B {%00|001|011} ~ RRC E | |||||
$CB $0C {%00|001|100} ~ RRC H | |||||
$CB $0D {%00|001|101} ~ RRC L | |||||
$CB $0E {%00|001|110} ~ RRC (HL) | |||||
$CB $0F {%00|001|111} ~ RRC A | |||||
$CB $10 {%00|010|000} ~ RL B | |||||
$CB $11 {%00|010|001} ~ RL C | |||||
$CB $12 {%00|010|010} ~ RL D | |||||
$CB $13 {%00|010|011} ~ RL E | |||||
$CB $14 {%00|010|100} ~ RL H | |||||
$CB $15 {%00|010|101} ~ RL L | |||||
$CB $16 {%00|010|110} ~ RL (HL) | |||||
$CB $17 {%00|010|111} ~ RL A | |||||
$CB $18 {%00|011|000} ~ RR B | |||||
$CB $19 {%00|011|001} ~ RR C | |||||
$CB $1A {%00|011|010} ~ RR D | |||||
$CB $1B {%00|011|011} ~ RR E | |||||
$CB $1C {%00|011|100} ~ RR H | |||||
$CB $1D {%00|011|101} ~ RR L | |||||
$CB $1E {%00|011|110} ~ RR (HL) | |||||
$CB $1F {%00|011|111} ~ RR A | |||||
$CB $20 {%00|100|000} ~ SLA B | |||||
$CB $21 {%00|100|001} ~ SLA C | |||||
$CB $22 {%00|100|010} ~ SLA D | |||||
$CB $23 {%00|100|011} ~ SLA E | |||||
$CB $24 {%00|100|100} ~ SLA H | |||||
$CB $25 {%00|100|101} ~ SLA L | |||||
$CB $26 {%00|100|110} ~ SLA (HL) | |||||
$CB $27 {%00|100|111} ~ SLA A | |||||
$CB $28 {%00|101|000} ~ SRA B | |||||
$CB $29 {%00|101|001} ~ SRA C | |||||
$CB $2A {%00|101|010} ~ SRA D | |||||
$CB $2B {%00|101|011} ~ SRA E | |||||
$CB $2C {%00|101|100} ~ SRA H | |||||
$CB $2D {%00|101|101} ~ SRA L | |||||
$CB $2E {%00|101|110} ~ SRA (HL) | |||||
$CB $2F {%00|101|111} ~ SRA A | |||||
$CB $30 {%00|110|000} ~ SWAP B | |||||
$CB $31 {%00|110|001} ~ SWAP C | |||||
$CB $32 {%00|110|010} ~ SWAP D | |||||
$CB $33 {%00|110|011} ~ SWAP E | |||||
$CB $34 {%00|110|100} ~ SWAP H | |||||
$CB $35 {%00|110|101} ~ SWAP L | |||||
$CB $36 {%00|110|110} ~ SWAP (HL) | |||||
$CB $37 {%00|110|111} ~ SWAP A | |||||
$CB $38 {%00|111|000} ~ SRL B | |||||
$CB $39 {%00|111|001} ~ SRL C | |||||
$CB $3A {%00|111|010} ~ SRL D | |||||
$CB $3B {%00|111|011} ~ SRL E | |||||
$CB $3C {%00|111|100} ~ SRL H | |||||
$CB $3D {%00|111|101} ~ SRL L | |||||
$CB $3E {%00|111|110} ~ SRL (HL) | |||||
$CB $3F {%00|111|111} ~ SRL A | |||||
$CB $40 {%01|000|000} ~ BIT 0,B | |||||
$CB $41 {%01|000|001} ~ BIT 0,C | |||||
$CB $42 {%01|000|010} ~ BIT 0,D | |||||
$CB $43 {%01|000|011} ~ BIT 0,E | |||||
$CB $44 {%01|000|100} ~ BIT 0,H | |||||
$CB $45 {%01|000|101} ~ BIT 0,L | |||||
$CB $46 {%01|000|110} ~ BIT 0,(HL) | |||||
$CB $47 {%01|000|111} ~ BIT 0,A | |||||
$CB $48 {%01|001|000} ~ BIT 1,B | |||||
$CB $49 {%01|001|001} ~ BIT 1,C | |||||
$CB $4A {%01|001|010} ~ BIT 1,D | |||||
$CB $4B {%01|001|011} ~ BIT 1,E | |||||
$CB $4C {%01|001|100} ~ BIT 1,H | |||||
$CB $4D {%01|001|101} ~ BIT 1,L | |||||
$CB $4E {%01|001|110} ~ BIT 1,(HL) | |||||
$CB $4F {%01|001|111} ~ BIT 1,A | |||||
$CB $50 {%01|010|000} ~ BIT 2,B | |||||
$CB $51 {%01|010|001} ~ BIT 2,C | |||||
$CB $52 {%01|010|010} ~ BIT 2,D | |||||
$CB $53 {%01|010|011} ~ BIT 2,E | |||||
$CB $54 {%01|010|100} ~ BIT 2,H | |||||
$CB $55 {%01|010|101} ~ BIT 2,L | |||||
$CB $56 {%01|010|110} ~ BIT 2,(HL) | |||||
$CB $57 {%01|010|111} ~ BIT 2,A | |||||
$CB $58 {%01|011|000} ~ BIT 3,B | |||||
$CB $59 {%01|011|001} ~ BIT 3,C | |||||
$CB $5A {%01|011|010} ~ BIT 3,D | |||||
$CB $5B {%01|011|011} ~ BIT 3,E | |||||
$CB $5C {%01|011|100} ~ BIT 3,H | |||||
$CB $5D {%01|011|101} ~ BIT 3,L | |||||
$CB $5E {%01|011|110} ~ BIT 3,(HL) | |||||
$CB $5F {%01|011|111} ~ BIT 3,A | |||||
$CB $60 {%01|100|000} ~ BIT 4,B | |||||
$CB $61 {%01|100|001} ~ BIT 4,C | |||||
$CB $62 {%01|100|010} ~ BIT 4,D | |||||
$CB $63 {%01|100|011} ~ BIT 4,E | |||||
$CB $64 {%01|100|100} ~ BIT 4,H | |||||
$CB $65 {%01|100|101} ~ BIT 4,L | |||||
$CB $66 {%01|100|110} ~ BIT 4,(HL) | |||||
$CB $67 {%01|100|111} ~ BIT 4,A | |||||
$CB $68 {%01|101|000} ~ BIT 5,B | |||||
$CB $69 {%01|101|001} ~ BIT 5,C | |||||
$CB $6A {%01|101|010} ~ BIT 5,D | |||||
$CB $6B {%01|101|011} ~ BIT 5,E | |||||
$CB $6C {%01|101|100} ~ BIT 5,H | |||||
$CB $6D {%01|101|101} ~ BIT 5,L | |||||
$CB $6E {%01|101|110} ~ BIT 5,(HL) | |||||
$CB $6F {%01|101|111} ~ BIT 5,A | |||||
$CB $70 {%01|110|000} ~ BIT 6,B | |||||
$CB $71 {%01|110|001} ~ BIT 6,C | |||||
$CB $72 {%01|110|010} ~ BIT 6,D | |||||
$CB $73 {%01|110|011} ~ BIT 6,E | |||||
$CB $74 {%01|110|100} ~ BIT 6,H | |||||
$CB $75 {%01|110|101} ~ BIT 6,L | |||||
$CB $76 {%01|110|110} ~ BIT 6,(HL) | |||||
$CB $77 {%01|110|111} ~ BIT 6,A | |||||
$CB $78 {%01|111|000} ~ BIT 7,B | |||||
$CB $79 {%01|111|001} ~ BIT 7,C | |||||
$CB $7A {%01|111|010} ~ BIT 7,D | |||||
$CB $7B {%01|111|011} ~ BIT 7,E | |||||
$CB $7C {%01|111|100} ~ BIT 7,H | |||||
$CB $7D {%01|111|101} ~ BIT 7,L | |||||
$CB $7E {%01|111|110} ~ BIT 7,(HL) | |||||
$CB $7F {%01|111|111} ~ BIT 7,A | |||||
$CB $80 {%10|000|000} ~ RES 0,B | |||||
$CB $81 {%10|000|001} ~ RES 0,C | |||||
$CB $82 {%10|000|010} ~ RES 0,D | |||||
$CB $83 {%10|000|011} ~ RES 0,E | |||||
$CB $84 {%10|000|100} ~ RES 0,H | |||||
$CB $85 {%10|000|101} ~ RES 0,L | |||||
$CB $86 {%10|000|110} ~ RES 0,(HL) | |||||
$CB $87 {%10|000|111} ~ RES 0,A | |||||
$CB $88 {%10|001|000} ~ RES 1,B | |||||
$CB $89 {%10|001|001} ~ RES 1,C | |||||
$CB $8A {%10|001|010} ~ RES 1,D | |||||
$CB $8B {%10|001|011} ~ RES 1,E | |||||
$CB $8C {%10|001|100} ~ RES 1,H | |||||
$CB $8D {%10|001|101} ~ RES 1,L | |||||
$CB $8E {%10|001|110} ~ RES 1,(HL) | |||||
$CB $8F {%10|001|111} ~ RES 1,A | |||||
$CB $90 {%10|010|000} ~ RES 2,B | |||||
$CB $91 {%10|010|001} ~ RES 2,C | |||||
$CB $92 {%10|010|010} ~ RES 2,D | |||||
$CB $93 {%10|010|011} ~ RES 2,E | |||||
$CB $94 {%10|010|100} ~ RES 2,H | |||||
$CB $95 {%10|010|101} ~ RES 2,L | |||||
$CB $96 {%10|010|110} ~ RES 2,(HL) | |||||
$CB $97 {%10|010|111} ~ RES 2,A | |||||
$CB $98 {%10|011|000} ~ RES 3,B | |||||
$CB $99 {%10|011|001} ~ RES 3,C | |||||
$CB $9A {%10|011|010} ~ RES 3,D | |||||
$CB $9B {%10|011|011} ~ RES 3,E | |||||
$CB $9C {%10|011|100} ~ RES 3,H | |||||
$CB $9D {%10|011|101} ~ RES 3,L | |||||
$CB $9E {%10|011|110} ~ RES 3,(HL) | |||||
$CB $9F {%10|011|111} ~ RES 3,A | |||||
$CB $A0 {%10|100|000} ~ RES 4,B | |||||
$CB $A1 {%10|100|001} ~ RES 4,C | |||||
$CB $A2 {%10|100|010} ~ RES 4,D | |||||
$CB $A3 {%10|100|011} ~ RES 4,E | |||||
$CB $A4 {%10|100|100} ~ RES 4,H | |||||
$CB $A5 {%10|100|101} ~ RES 4,L | |||||
$CB $A6 {%10|100|110} ~ RES 4,(HL) | |||||
$CB $A7 {%10|100|111} ~ RES 4,A | |||||
$CB $A8 {%10|101|000} ~ RES 5,B | |||||
$CB $A9 {%10|101|001} ~ RES 5,C | |||||
$CB $AA {%10|101|010} ~ RES 5,D | |||||
$CB $AB {%10|101|011} ~ RES 5,E | |||||
$CB $AC {%10|101|100} ~ RES 5,H | |||||
$CB $AD {%10|101|101} ~ RES 5,L | |||||
$CB $AE {%10|101|110} ~ RES 5,(HL) | |||||
$CB $AF {%10|101|111} ~ RES 5,A | |||||
$CB $B0 {%10|110|000} ~ RES 6,B | |||||
$CB $B1 {%10|110|001} ~ RES 6,C | |||||
$CB $B2 {%10|110|010} ~ RES 6,D | |||||
$CB $B3 {%10|110|011} ~ RES 6,E | |||||
$CB $B4 {%10|110|100} ~ RES 6,H | |||||
$CB $B5 {%10|110|101} ~ RES 6,L | |||||
$CB $B6 {%10|110|110} ~ RES 6,(HL) | |||||
$CB $B7 {%10|110|111} ~ RES 6,A | |||||
$CB $B8 {%10|111|000} ~ RES 7,B | |||||
$CB $B9 {%10|111|001} ~ RES 7,C | |||||
$CB $BA {%10|111|010} ~ RES 7,D | |||||
$CB $BB {%10|111|011} ~ RES 7,E | |||||
$CB $BC {%10|111|100} ~ RES 7,H | |||||
$CB $BD {%10|111|101} ~ RES 7,L | |||||
$CB $BE {%10|111|110} ~ RES 7,(HL) | |||||
$CB $BF {%10|111|111} ~ RES 7,A | |||||
$CB $C0 {%11|000|000} ~ SET 0,B | |||||
$CB $C1 {%11|000|001} ~ SET 0,C | |||||
$CB $C2 {%11|000|010} ~ SET 0,D | |||||
$CB $C3 {%11|000|011} ~ SET 0,E | |||||
$CB $C4 {%11|000|100} ~ SET 0,H | |||||
$CB $C5 {%11|000|101} ~ SET 0,L | |||||
$CB $C6 {%11|000|110} ~ SET 0,(HL) | |||||
$CB $C7 {%11|000|111} ~ SET 0,A | |||||
$CB $C8 {%11|001|000} ~ SET 1,B | |||||
$CB $C9 {%11|001|001} ~ SET 1,C | |||||
$CB $CA {%11|001|010} ~ SET 1,D | |||||
$CB $CB {%11|001|011} ~ SET 1,E | |||||
$CB $CC {%11|001|100} ~ SET 1,H | |||||
$CB $CD {%11|001|101} ~ SET 1,L | |||||
$CB $CE {%11|001|110} ~ SET 1,(HL) | |||||
$CB $CF {%11|001|111} ~ SET 1,A | |||||
$CB $D0 {%11|010|000} ~ SET 2,B | |||||
$CB $D1 {%11|010|001} ~ SET 2,C | |||||
$CB $D2 {%11|010|010} ~ SET 2,D | |||||
$CB $D3 {%11|010|011} ~ SET 2,E | |||||
$CB $D4 {%11|010|100} ~ SET 2,H | |||||
$CB $D5 {%11|010|101} ~ SET 2,L | |||||
$CB $D6 {%11|010|110} ~ SET 2,(HL) | |||||
$CB $D7 {%11|010|111} ~ SET 2,A | |||||
$CB $D8 {%11|011|000} ~ SET 3,B | |||||
$CB $D9 {%11|011|001} ~ SET 3,C | |||||
$CB $DA {%11|011|010} ~ SET 3,D | |||||
$CB $DB {%11|011|011} ~ SET 3,E | |||||
$CB $DC {%11|011|100} ~ SET 3,H | |||||
$CB $DD {%11|011|101} ~ SET 3,L | |||||
$CB $DE {%11|011|110} ~ SET 3,(HL) | |||||
$CB $DF {%11|011|111} ~ SET 3,A | |||||
$CB $E0 {%11|100|000} ~ SET 4,B | |||||
$CB $E1 {%11|100|001} ~ SET 4,C | |||||
$CB $E2 {%11|100|010} ~ SET 4,D | |||||
$CB $E3 {%11|100|011} ~ SET 4,E | |||||
$CB $E4 {%11|100|100} ~ SET 4,H | |||||
$CB $E5 {%11|100|101} ~ SET 4,L | |||||
$CB $E6 {%11|100|110} ~ SET 4,(HL) | |||||
$CB $E7 {%11|100|111} ~ SET 4,A | |||||
$CB $E8 {%11|101|000} ~ SET 5,B | |||||
$CB $E9 {%11|101|001} ~ SET 5,C | |||||
$CB $EA {%11|101|010} ~ SET 5,D | |||||
$CB $EB {%11|101|011} ~ SET 5,E | |||||
$CB $EC {%11|101|100} ~ SET 5,H | |||||
$CB $ED {%11|101|101} ~ SET 5,L | |||||
$CB $EE {%11|101|110} ~ SET 5,(HL) | |||||
$CB $EF {%11|101|111} ~ SET 5,A | |||||
$CB $F0 {%11|110|000} ~ SET 6,B | |||||
$CB $F1 {%11|110|001} ~ SET 6,C | |||||
$CB $F2 {%11|110|010} ~ SET 6,D | |||||
$CB $F3 {%11|110|011} ~ SET 6,E | |||||
$CB $F4 {%11|110|100} ~ SET 6,H | |||||
$CB $F5 {%11|110|101} ~ SET 6,L | |||||
$CB $F6 {%11|110|110} ~ SET 6,(HL) | |||||
$CB $F7 {%11|110|111} ~ SET 6,A | |||||
$CB $F8 {%11|111|000} ~ SET 7,B | |||||
$CB $F9 {%11|111|001} ~ SET 7,C | |||||
$CB $FA {%11|111|010} ~ SET 7,D | |||||
$CB $FB {%11|111|011} ~ SET 7,E | |||||
$CB $FC {%11|111|100} ~ SET 7,H | |||||
$CB $FD {%11|111|101} ~ SET 7,L | |||||
$CB $FE {%11|111|110} ~ SET 7,(HL) | |||||
$CB $FF {%11|111|111} ~ SET 7,A |
@@ -0,0 +1,18 @@ | |||||
#lang racket | |||||
(require "vm.rkt") | |||||
(define (test-loop) | |||||
(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 | |||||
))) | |||||
(provide (all-defined-out)) | |||||
@@ -1,144 +1,167 @@ | |||||
#lang racket | #lang racket | ||||
(struct mem | (struct mem | ||||
(regs pc sp flags bank)) | |||||
(regs pc sp flags bank)) | |||||
(define (make-mem [start #x00] [bs '()]) | (define (make-mem [start #x00] [bs '()]) | ||||
(set-bytes start bs | |||||
(mem (make-regs) | |||||
start | |||||
0 | |||||
0 | |||||
(make-bank)))) | |||||
(set-bytes start bs | |||||
(mem (make-regs) | |||||
start | |||||
0 | |||||
0 | |||||
(make-bank)))) | |||||
(define (make-regs) | (define (make-regs) | ||||
(make-vector 8 0)) | |||||
(make-vector 8 0)) | |||||
(define (get-zero mem) | (define (get-zero mem) | ||||
(bitwise-bit-set? (mem-flags mem) 7)) | |||||
(bitwise-bit-set? (mem-flags mem) 7)) | |||||
(define (get-carry mem) | (define (get-carry mem) | ||||
(bitwise-bit-set? (mem-flags mem) 4)) | |||||
(bitwise-bit-set? (mem-flags mem) 4)) | |||||
(define (get-reg x mem) | (define (get-reg x mem) | ||||
(if (and (< x 8) (>= x 0)) | |||||
(let ([regs (mem-regs mem)]) | |||||
(if (not (= x 6)) | |||||
(vector-ref regs x) | |||||
(let([bank (mem-bank mem)] | |||||
[h (vector-ref regs 4)] | |||||
[l (vector-ref regs 5)]) | |||||
(vector-ref bank (make-16b-addr h l))))) | |||||
(error "unknown register index"))) | |||||
(if (and (< x 8) (>= x 0)) | |||||
(let ([regs (mem-regs mem)]) | |||||
(if (not (= x 6)) | |||||
(vector-ref regs x) | |||||
(let([bank (mem-bank mem)] | |||||
[h (vector-ref regs 4)] | |||||
[l (vector-ref regs 5)]) | |||||
(vector-ref bank (make-16b-addr h l))))) | |||||
(error "unknown register index"))) | |||||
(define (set-reg x val m) | (define (set-reg x val m) | ||||
(if (and (< x 8) (>= x 0)) | |||||
(let ([regs (mem-regs m)]) | |||||
(if (not (= x 6)) | |||||
(let ([newregs (vector-copy regs)]) | |||||
(vector-set! newregs x (mod-8bit val)) | |||||
(struct-copy mem m [regs newregs])) | |||||
(let ([newbank (vector-copy (mem-bank m))] | |||||
[h (vector-ref regs 4)] | |||||
[l (vector-ref regs 5)]) | |||||
(vector-set! newbank (make-16b-addr h l) (mod-8bit val)) | |||||
(struct-copy mem m [bank newbank])))) | |||||
(error "unknown register index"))) | |||||
(if (and (< x 8) (>= x 0)) | |||||
(let ([regs (mem-regs m)]) | |||||
(if (not (= x 6)) | |||||
(let ([newregs (vector-copy regs)]) | |||||
(vector-set! newregs x (mod-8bit val)) | |||||
(struct-copy mem m [regs newregs])) | |||||
(let ([newbank (vector-copy (mem-bank m))] | |||||
[h (vector-ref regs 4)] | |||||
[l (vector-ref regs 5)]) | |||||
(vector-set! newbank (make-16b-addr h l) (mod-8bit val)) | |||||
(struct-copy mem m [bank newbank])))) | |||||
(error "unknown register index"))) | |||||
(define (make-bank [def #x00]) | (define (make-bank [def #x00]) | ||||
(make-vector 65536 def)) | |||||
(make-vector 65536 def)) | |||||
(define (mod-8bit val) | (define (mod-8bit val) | ||||
(modulo val 256)) | |||||
(modulo val 256)) | |||||
(define (mod-16bit val) | (define (mod-16bit val) | ||||
(modulo val 65536)) | |||||
(modulo val 65536)) | |||||
(define (set-pc addr m) | (define (set-pc addr m) | ||||
(begin | |||||
(struct-copy mem m [pc (mod-16bit addr)]))) | |||||
(begin | |||||
(struct-copy mem m [pc (mod-16bit addr)]))) | |||||
(define (set-flags f m) | (define (set-flags f m) | ||||
(begin | |||||
(struct-copy mem m [flags (mod-8bit f)]))) | |||||
(begin | |||||
(struct-copy mem m [flags (mod-8bit f)]))) | |||||
(define (get-byte addr m) | (define (get-byte addr m) | ||||
(let ([b (mem-bank m)]) | |||||
(if (and (>= addr 0) | |||||
(< addr (vector-length b))) | |||||
(vector-ref b addr) | |||||
(error (format "address ~a out of bounds" addr))))) | |||||
(let ([b (mem-bank m)]) | |||||
(if (and (>= addr 0) | |||||
(< addr (vector-length b))) | |||||
(vector-ref b addr) | |||||
(error (format "address ~a out of bounds" addr))))) | |||||
(define (set-byte addr val m) | (define (set-byte addr val m) | ||||
(let ([b (mem-bank m)]) | |||||
(if (and (>= addr 0) | |||||
(< addr (vector-length b))) | |||||
(let ([newbank (vector-copy b)]) | |||||
(vector-set! newbank addr (mod-8bit val)) | |||||
(struct-copy mem m [bank newbank])) | |||||
(error (format "address ~a out of bounds" addr))))) | |||||
(let ([b (mem-bank m)]) | |||||
(if (and (>= addr 0) | |||||
(< addr (vector-length b))) | |||||
(let ([newbank (vector-copy b)]) | |||||
(vector-set! newbank addr (mod-8bit val)) | |||||
(struct-copy mem m [bank newbank])) | |||||
(error (format "address ~a out of bounds" addr))))) | |||||
(define (set-bytes addr bs m) | (define (set-bytes addr bs m) | ||||
(if (null? bs) | |||||
m | |||||
(set-bytes (mod-16bit (add1 addr)) | |||||
(cdr bs) | |||||
(set-byte addr (car bs) m)))) | |||||
(if (null? bs) | |||||
m | |||||
(set-bytes (mod-16bit (add1 addr)) | |||||
(cdr bs) | |||||
(set-byte addr (car bs) m)))) | |||||
(define (get-x byte) | (define (get-x byte) | ||||
(arithmetic-shift (bitwise-and #b11000000 byte) -6)) | |||||
(arithmetic-shift (bitwise-and #b11000000 byte) -6)) | |||||
(define (get-y byte) | (define (get-y byte) | ||||
(arithmetic-shift (bitwise-and #b00111000 byte) -3)) | |||||
(arithmetic-shift (bitwise-and #b00111000 byte) -3)) | |||||
(define (get-z byte) | (define (get-z byte) | ||||
(bitwise-and #b00000111 byte)) | |||||
(bitwise-and #b00000111 byte)) | |||||
(define (inc-sp m) | (define (inc-sp m) | ||||
(struct-copy mem m [sp (add1 (mem-sp m))])) | |||||
(struct-copy mem m [sp (add1 (mem-sp m))])) | |||||
(define (inc-pc m) | (define (inc-pc m) | ||||
(struct-copy mem m [pc (add1 (mem-pc m))])) | |||||
(struct-copy mem m [pc (add1 (mem-pc m))])) | |||||
(define (make-16b-addr x y) | (define (make-16b-addr x y) | ||||
(bitwise-ior y (arithmetic-shift x 8))) | |||||
(bitwise-ior y (arithmetic-shift x 8))) | |||||
(define (make-8b-ld-reg-imm y m) | (define (make-8b-ld-reg-imm y m) | ||||
(letrec ([pc (mem-pc m)] | |||||
[x (get-byte pc m)]) | |||||
(cons (8b-ld-reg-imm y x) | |||||
(set-pc (add1pc pc) m)))) | |||||
(letrec ([pc (mem-pc m)] | |||||
[x (get-byte pc m)]) | |||||
(cons (8b-ld-reg-imm y x) | |||||
(set-pc (add1pc pc) m)))) | |||||
(define (make-jp cc m) | (define (make-jp cc m) | ||||
(letrec ([pc (mem-pc m)] | |||||
[y (get-byte pc m)] | |||||
[npc (add1pc pc)] | |||||
[x (get-byte npc m)] | |||||
[addr (make-16b-addr x y)] | |||||
[cs (cc-tab cc)]) | |||||
(cons (jp cs addr) (set-pc npc m)))) | |||||
(letrec ([pc (mem-pc m)] | |||||
[y (get-byte pc m)] | |||||
[npc (add1pc pc)] | |||||
[x (get-byte npc m)] | |||||
[addr (make-16b-addr x y)] | |||||
[cs (cc-tab cc)]) | |||||
(cons (jp cs addr) (set-pc (add1pc npc) m)))) | |||||
(define (cc-tab cc) | (define (cc-tab cc) | ||||
(case cc | |||||
[(0) 'NZ] | |||||
[(1) 'Z] | |||||
[(2) 'NC] | |||||
[(3) 'C] | |||||
[else 'uncond])) | |||||
(case cc | |||||
[(0) 'NZ] | |||||
[(1) 'Z] | |||||
[(2) 'NC] | |||||
[(3) 'C] | |||||
[else 'uncond])) | |||||
(define (make-8b-ld-reg-reg y z m) | (define (make-8b-ld-reg-reg y z m) | ||||
(cons (8b-ld-reg-reg y z) | (cons (8b-ld-reg-reg y z) | ||||
m)) | m)) | ||||
(define (make-alu-imm z m) | (define (make-alu-imm z m) | ||||
(letrec ([pc (mem-pc m)] | |||||
[x (get-byte pc m)]) | |||||
(letrec ([pc (mem-pc m)] | |||||
[x (get-byte pc m)]) | |||||
(cons (case z | (cons (case z | ||||
[(0) (8b-add-imm x)] | |||||
[(1) (8b-adc-imm x)] | |||||
[(2) (8b-sub-imm x)] | |||||
[(3) (8b-sbc-imm x)] | |||||
[(4) (8b-and-imm x)] | [(4) (8b-and-imm x)] | ||||
[(5) (8b-xor-imm x)] | [(5) (8b-xor-imm x)] | ||||
[(6) (8b-or-imm x)] | [(6) (8b-or-imm x)] | ||||
[(7) (8b-cp-imm x)] | |||||
[else (nop)]) | [else (nop)]) | ||||
(inc-pc m)))) | |||||
(inc-pc m)))) | |||||
(define (make-8b-inc-dec-reg y z m) | |||||
(cons ((case z | |||||
[(4) 8b-inc-reg] | |||||
[(5) 8b-dec-reg]) y) | |||||
m)) | |||||
(define (make-alu-reg y z m) | |||||
(cons (case y | |||||
[(0) (8b-add-reg z)] | |||||
[(1) (8b-adc-reg z)] | |||||
[(2) (8b-sub-reg z)] | |||||
[(3) (8b-sbc-reg z)] | |||||
[(4) (8b-and-reg z)] | |||||
[(5) (8b-xor-reg z)] | |||||
[(6) (8b-or-reg z)] | |||||
[(7) (8b-cp-reg z)]) | |||||
m)) | |||||
(define (make-nop m) | (define (make-nop m) | ||||
(cons (nop) m)) | (cons (nop) m)) | ||||
@@ -161,6 +184,23 @@ | |||||
(get-reg src m) | (get-reg src m) | ||||
m))) | m))) | ||||
(define (8b-inc-reg r) | |||||
(lambda (m) | |||||
(let ([a (mod-8bit (add1 (get-reg r m)))]) | |||||
(set-flags | |||||
(bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00)) | |||||
(set-reg r a m))))) | |||||
(define (8b-dec-reg r) | |||||
(lambda (m) | |||||
(let ([a (mod-8bit (sub1 (get-reg r m)))]) | |||||
(set-flags | |||||
(bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
#b01000000) | |||||
(set-reg r a m))))) | |||||
(define (jp-cond cc addr) | (define (jp-cond cc addr) | ||||
(lambda (m) | (lambda (m) | ||||
(let ([c (get-carry m)] | (let ([c (get-carry m)] | ||||
@@ -177,13 +217,129 @@ | |||||
(lambda (m) | (lambda (m) | ||||
(set-pc addr m))) | (set-pc addr m))) | ||||
(define (8b-add-imm v) | |||||
(lambda (m) | |||||
(let ([a (+ (get-reg 7 m) | |||||
(mod-8bit v))]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-sbc-imm v) | |||||
(lambda (m) | |||||
(letrec ([c (bitwise-and #b00010000 (mem-flags m))] | |||||
[a (- (get-reg 7 m) | |||||
(mod-8bit v) | |||||
c)]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-sub-imm v) | |||||
(lambda (m) | |||||
(let ([a (- (get-reg 7 m) | |||||
(mod-8bit v))]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-cp-imm v) | |||||
(lambda (m) | |||||
(let ([a (- (get-reg 7 m) | |||||
(mod-8bit v))]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
m)))) | |||||
(define (8b-adc-imm v) | |||||
(lambda (m) | |||||
(letrec ([c (bitwise-and #b00010000 (mem-flags m))] | |||||
[a (+ (get-reg 7 m) | |||||
(mod-8bit v) | |||||
c)]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-add-reg r) | |||||
(lambda (m) | |||||
(let ([a (+ (get-reg 7 m) | |||||
(get-reg r m))]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-sbc-reg r) | |||||
(lambda (m) | |||||
(letrec ([c (bitwise-and #b00010000 (mem-flags m))] | |||||
[a (- (get-reg 7 m) | |||||
(get-reg r m) | |||||
c)]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-sub-reg r) | |||||
(lambda (m) | |||||
(let ([a (- (get-reg 7 m) | |||||
(get-reg r m))]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-cp-reg r) | |||||
(lambda (m) | |||||
(let ([a (- (get-reg 7 m) | |||||
(get-reg r m))]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
m)))) | |||||
(define (8b-adc-reg r) | |||||
(lambda (m) | |||||
(letrec ([c (bitwise-and #b00010000 (mem-flags m))] | |||||
[a (+ (get-reg 7 m) | |||||
(get-reg r m) | |||||
c)]) | |||||
(set-flags (bitwise-ior (if (= a 0) #b10000000 #x00) | |||||
(if (>= a 16) #b00100000 #x00) | |||||
(if (>= a 256) #b00010000 #x00)) | |||||
(set-reg 7 (mod-8bit a) m))))) | |||||
(define (8b-xor-reg r) | |||||
(lambda (m) | |||||
(let ([a (bitwise-xor (get-reg 7 m) | |||||
(get-reg r m))]) | |||||
(set-flags (if (= a 0) #b10000000 #x00) | |||||
(set-reg 7 a m))))) | |||||
(define (8b-and-reg r) | |||||
(lambda (m) | |||||
(let ([a (bitwise-and (get-reg 7 m) | |||||
(get-reg r m))]) | |||||
(set-flags (if (= a 0) #b10000000 #x00) | |||||
(set-reg 7 a m))))) | |||||
(define (8b-or-reg r) | |||||
(lambda (m) | |||||
(let ([a (bitwise-ior (get-reg 7 m) | |||||
(get-reg r m))]) | |||||
(set-flags (if (= a 0) #b10000000 #x00) | |||||
(set-reg 7 a m))))) | |||||
(define (8b-xor-imm imm) | (define (8b-xor-imm imm) | ||||
(lambda (m) | (lambda (m) | ||||
(let ([a (bitwise-xor (get-reg 7 m) | (let ([a (bitwise-xor (get-reg 7 m) | ||||
(mod-8bit imm))]) | (mod-8bit imm))]) | ||||
(displayln (format "~a xor ~a = ~a" (display-byte-hex (get-reg 7 m)) | |||||
(display-byte-hex (mod-8bit imm)) | |||||
a)) | |||||
(set-flags (if (= a 0) #b10000000 #x00) | (set-flags (if (= a 0) #b10000000 #x00) | ||||
(set-reg 7 a m))))) | (set-reg 7 a m))))) | ||||
@@ -270,16 +426,42 @@ | |||||
[(= #x00 op) (make-nop (set-pc npc m))] | [(= #x00 op) (make-nop (set-pc npc m))] | ||||
[(= #x10 op) (make-stop (set-pc npc m))] | [(= #x10 op) (make-stop (set-pc npc m))] | ||||
[(= #xC3 op) (make-jp 'uncond (set-pc npc m))] | [(= #xC3 op) (make-jp 'uncond (set-pc npc m))] | ||||
[(and (= 0 x) (within z 4 5)) | |||||
(make-8b-inc-dec-reg y z (set-pc npc m))] | |||||
[(= 1 x) | [(= 1 x) | ||||
(make-8b-ld-reg-reg y z (set-pc npc m))] | (make-8b-ld-reg-reg y z (set-pc npc m))] | ||||
[(= 2 x) | |||||
(make-alu-reg y z (set-pc npc m))] | |||||
[(and (= 3 x) (= z 2) (within y 0 3)) | [(and (= 3 x) (= z 2) (within y 0 3)) | ||||
(make-jp y (set-pc npc m))] | (make-jp y (set-pc npc m))] | ||||
[(and (= 3 x) (within z 4 6)) | |||||
[(and (= 3 x) (= z 6)) | |||||
(make-alu-imm y (set-pc npc m))] | (make-alu-imm y (set-pc npc m))] | ||||
[(and (= 0 x) (= 6 z)) | [(and (= 0 x) (= 6 z)) | ||||
(make-8b-ld-reg-imm y (set-pc npc m))] | (make-8b-ld-reg-imm y (set-pc npc m))] | ||||
[else (make-nop (set-pc npc m))]))) | [else (make-nop (set-pc npc m))]))) | ||||
(define (test-vm start bank-start bank-count bs) | |||||
(let ([m (make-mem start bs)]) | |||||
(define (fin m) | |||||
(begin (print-state m) | |||||
(print-regs m) | |||||
(print-part-bank bank-start bank-count m))) | |||||
(define (run-op m) | |||||
(displayln (format "executing: $~a @ $~a" | |||||
(display-byte-hex (get-byte (mem-pc m) m)) | |||||
(display-word-hex (mem-pc m)))) | |||||
(letrec ([op-pc (decode-op m)] | |||||
[op (car op-pc)] | |||||
[newmem (cdr op-pc)]) | |||||
(if (and (not (procedure? op)) | |||||
(eq? op 'STOP)) | |||||
(fin newmem) | |||||
(begin | |||||
;(print-state newmem) | |||||
;(print-regs newmem) | |||||
(run-op (op newmem)))))) | |||||
(run-op m))) | |||||
(define (run-vm start bank-start bank-count bs) | (define (run-vm start bank-start bank-count bs) | ||||
(let ([m (make-mem start bs)]) | (let ([m (make-mem start bs)]) | ||||
(define (fin m) | (define (fin m) | ||||
@@ -296,16 +478,4 @@ | |||||
(run-op (op newmem))))) | (run-op (op newmem))))) | ||||
(run-op m))) | (run-op m))) | ||||
(define (run-lines ls) | |||||
(define (run-line-help ls m) | |||||
(if (null? ls) | |||||
m | |||||
(run-line-help (cdr ls) | |||||
((car ls) (inc-pc m))))) | |||||
(let ([fin (run-line-help ls (make-mem))]) | |||||
(begin | |||||
(print-state fin) | |||||
(print-regs fin) | |||||
(print-part-bank #x150 16 fin)))) | |||||
(provide (all-defined-out)) | (provide (all-defined-out)) |