added conditional jump

This commit is contained in:
Thorn Avery 2020-06-10 22:36:58 +12:00
parent cd8bbe1a88
commit a9c4660e11
2 changed files with 33 additions and 5 deletions

View File

@ -16,7 +16,7 @@ in the racket repl (comments for reader comprehension, remove before running):
#xF0 ; (non-instruction, will be arg for previous byte) #xF0 ; (non-instruction, will be arg for previous byte)
#x2E #x68 ; LD L, $68 #x2E #x68 ; LD L, $68
#x77 ; LD (HL), A #x77 ; LD (HL), A
#xC3 #x64 #x01 ; JP $0164 #xC2 #x64 #x01 ; JP $0164
#x10 ; STOP #x10 ; STOP
#x7D ; LD A, L (address $0164) #x7D ; LD A, L (address $0164)
#x10 ; STOP #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 $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 ## notes
currently supported instructions are: currently supported instructions are:
* `JP #addr` * `JP #addr`
* `JP [cc], #addr`
* `LD [reg], #imm` * `LD [reg], #imm`
* `LD [reg], [reg]` * `LD [reg], [reg]`
* `XOR #imm` * `XOR #imm`

33
vm.rkt
View File

@ -14,6 +14,12 @@
(define (make-regs) (define (make-regs)
(make-vector 8 0)) (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) (define (get-reg x mem)
(if (and (< x 8) (>= x 0)) (if (and (< x 8) (>= x 0))
(let ([regs (mem-regs mem)]) (let ([regs (mem-regs mem)])
@ -108,8 +114,17 @@
[y (get-byte pc m)] [y (get-byte pc m)]
[npc (add1pc pc)] [npc (add1pc pc)]
[x (get-byte npc m)] [x (get-byte npc m)]
[addr (make-16b-addr x y)]) [addr (make-16b-addr x y)]
(cons (jp cc addr) (set-pc npc m)))) [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) (define (make-8b-ld-reg-reg y z m)
(cons (8b-ld-reg-reg y z) (cons (8b-ld-reg-reg y z)
@ -134,7 +149,7 @@
(define (jp cc addr) (define (jp cc addr)
(case cc (case cc
[(uncond) (jp-uncond addr)] [(uncond) (jp-uncond addr)]
[else (nop)])) [else (jp-cond cc addr)]))
(define (8b-ld-reg-imm reg imm) (define (8b-ld-reg-imm reg imm)
(lambda (m) (lambda (m)
@ -146,6 +161,16 @@
(get-reg src m) (get-reg src m)
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) (define (jp-uncond addr)
(lambda (m) (lambda (m)
(set-pc addr m))) (set-pc addr m)))
@ -245,6 +270,8 @@
[(= #xC3 op) (make-jp 'uncond (set-pc npc m))] [(= #xC3 op) (make-jp 'uncond (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))]
[(and (= 3 x) (= z 2) (within y 0 3))
(make-jp y (set-pc npc m))]
[(and (= 3 x) (within z 4 6)) [(and (= 3 x) (within z 4 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))