From a9c4660e11e7ec9a48259e0c64759d387f387f37 Mon Sep 17 00:00:00 2001 From: tA Date: Wed, 10 Jun 2020 22:36:58 +1200 Subject: [PATCH] added conditional jump --- README.md | 5 +++-- vm.rkt | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 54225c7..524f1f2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ in the racket repl (comments for reader comprehension, remove before running): #xF0 ; (non-instruction, will be arg for previous byte) #x2E #x68 ; LD L, $68 #x77 ; LD (HL), A - #xC3 #x64 #x01 ; JP $0164 + #xC2 #x64 #x01 ; JP $0164 #x10 ; STOP #x7D ; LD A, L (address $0164) #x10 ; STOP @@ -33,12 +33,13 @@ HL: $0168, AF: $6800 $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 `JP` 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`. ## notes currently supported instructions are: * `JP #addr` + * `JP [cc], #addr` * `LD [reg], #imm` * `LD [reg], [reg]` * `XOR #imm` diff --git a/vm.rkt b/vm.rkt index 507b1c3..1dd27b9 100644 --- a/vm.rkt +++ b/vm.rkt @@ -14,6 +14,12 @@ (define (make-regs) (make-vector 8 0)) +(define (get-zero mem) + (bitwise-bit-set? (mem-flags mem) 7)) + +(define (get-carry mem) + (bitwise-bit-set? (mem-flags mem) 4)) + (define (get-reg x mem) (if (and (< x 8) (>= x 0)) (let ([regs (mem-regs mem)]) @@ -108,8 +114,17 @@ [y (get-byte pc m)] [npc (add1pc pc)] [x (get-byte npc m)] - [addr (make-16b-addr x y)]) - (cons (jp cc addr) (set-pc npc m)))) + [addr (make-16b-addr x y)] + [cs (cc-tab cc)]) + (cons (jp cs addr) (set-pc npc m)))) + +(define (cc-tab cc) + (case cc + [(0) 'NZ] + [(1) 'Z] + [(2) 'NC] + [(3) 'C] + [else 'uncond])) (define (make-8b-ld-reg-reg y z m) (cons (8b-ld-reg-reg y z) @@ -134,7 +149,7 @@ (define (jp cc addr) (case cc [(uncond) (jp-uncond addr)] - [else (nop)])) + [else (jp-cond cc addr)])) (define (8b-ld-reg-imm reg imm) (lambda (m) @@ -146,6 +161,16 @@ (get-reg src m) m))) +(define (jp-cond cc addr) + (lambda (m) + (let ([c (get-carry m)] + [z (get-zero m)]) + (case cc + [(NZ) (if (not z) (set-pc addr m) m)] + [(Z) (if z (set-pc addr) m)] + [(NC) (if (not c) (set-pc addr) m)] + [(C) (if c (set-pc addr) m)])))) + (define (jp-uncond addr) (lambda (m) (set-pc addr m))) @@ -245,6 +270,8 @@ [(= #xC3 op) (make-jp 'uncond (set-pc npc m))] [(= 1 x) (make-8b-ld-reg-reg y z (set-pc npc m))] + [(and (= 3 x) (= z 2) (within y 0 3)) + (make-jp y (set-pc npc m))] [(and (= 3 x) (within z 4 6)) (make-alu-imm y (set-pc npc m))] [(and (= 0 x) (= 6 z))