Browse Source

first commit

master
Thorn Avery 3 years ago
commit
0f2beac5c9
13 changed files with 838 additions and 0 deletions
  1. +134
    -0
      old-code/decode.rkt
  2. +23
    -0
      old-code/expander.rkt
  3. +7
    -0
      old-code/expr.rkt
  4. +18
    -0
      old-code/lexer.rkt
  5. +21
    -0
      old-code/main.rkt
  6. +93
    -0
      old-code/memory.rkt
  7. +326
    -0
      old-code/old-code.rkt
  8. +17
    -0
      old-code/parse-only.rkt
  9. +7
    -0
      old-code/parser.rkt
  10. +7
    -0
      old-code/test.rkt
  11. +17
    -0
      old-code/tokenize-only.rkt
  12. +10
    -0
      old-code/tokenizer.rkt
  13. +158
    -0
      vm.rkt

+ 134
- 0
old-code/decode.rkt View File

@@ -0,0 +1,134 @@
#lang racket
(require "memory.rkt")

;---------------------
; Decode dot ry ky ty
;---------------------
; Functions to decode
; a byte to an assembly
; instruction.
;---------------------

(define (inc16b x)
(mod-16bit (add1 x)))

(define (alu-op y)
(case y
[(0) 'RLC]
[(1) 'RRC]
[(2) 'RL]
[(3) 'RR]
[(4) 'SLA]
[(5) 'SRA]
[(6) 'SWAP]
[(7) 'SRL]))

(define (reg-op z)
(case z
[(0) 'reg-B]
[(1) 'reg-C]
[(2) 'reg-D]
[(3) 'reg-E]
[(4) 'reg-H]
[(5) 'reg-L]
[(6) 'reg-ind-HL]
[(7) 'reg-A]))

(define (cc-tab z)
(case z
[(0) 'NZ]
[(1) 'Z]
[(2) 'NC]
[(3) 'C]))

(define (rp-tab z)
(case z
[(0) 'reg-BC]
[(1) 'reg-DE]
[(2) 'reg-HL]
[(3) 'reg-SP]))

(define (read-word-mem memory)
(let ([lsb (read-byte-mem memory)]
[msb (read-byte-mem memory)])
(bitwise-ior lsb
(arithmetic-shift msb 8))))

(define (read-byte-mem memory)
(let ([pc (get-state 'state-PC memory)])
(let ([b (get-byte pc 0 memory)])
(begin
(set-state! 'state-PC memory (inc16b pc))
b))))

(define (read-instruction memory)
(let ([b1 (read-byte-mem memory)])
(if (= #xCB b1)
; $CB prefix ops
(letrec ([b2 (read-byte-mem memory)]
[x (arithmetic-shift (bitwise-and #b11000000 b2) -6)]
[y (arithmetic-shift (bitwise-and #b00111000 b2) -3)]
[z (bitwise-and #b00000111 b2)]
[p (arithmetic-shift y -1)]
[q (modulo y 2)])
(case x
[(0) `(,(alu-op y) ,(reg-op z))]
[(1) `(BIT ,y ,(reg-op z))]
[(2) `(RES ,y ,(reg-op z))]
[(3) `(SET ,y ,(reg-op z))]
[else (error "bad instruction")]))
; No prefix ops
(letrec ([x (arithmetic-shift (bitwise-and #b11000000 b1) -6)]
[y (arithmetic-shift (bitwise-and #b00111000 b1) -3)]
[z (bitwise-and #b00000111 b1)]
[p (arithmetic-shift y -1)]
[q (modulo y 2)])
(case x
[(0)
(case z
[(0)
(case y
[(0) '(NOP)]
[(1) `(LD-ind ,(read-word-mem memory) reg-SP)]
[(2) '(STOP)]
[(3) `(JR expl ,(read-byte-mem memory))]
[(4 5 6 7) `(JR ,(cc-tab (- y 4)) ,(read-byte-mem memory))]
[else (error "bad instruction")])]
[(1)
(case q
[(0) `(LD-16b ,(rp-tab p) ,(read-word-memory))]
[(1) `(ADD-16b reg-HL ,(rp-tab p))]
[else (error "bad instruction")])
]
[(2) (void)]
[(3) (void)]
[(4) (void)]
[(5) (void)]
[(6) (void)]
[(7) (void)])]
[(1) (void)]
[(2) (void)]
[(3) (void)]
[(4 5 6 7) (void)]
[else (error "bad instruction")]
)
)
)))

(define (test1)
(begin
(define m (make-memory))
(set-state! 'state-PC m #x150)
(set-byte! #x150 'nil m #x00)
(read-instruction m)))

(define (test2)
(begin
(define m (make-memory))
(set-state! 'state-PC m #x150)
(set-byte! #x150 'nil m #x08)
(set-byte! #x151 'nil m #x69)
(set-byte! #x152 'nil m #xFF)
(read-instruction m)))

(provide (all-defined-out))

+ 23
- 0
old-code/expander.rkt View File

@@ -0,0 +1,23 @@
#lang br/quicklang

(provide (rename-out [z-module-begin #%module-begin])
val
z-ld)

(define-macro (z-module-begin (z-program LINE ...))
#'(#%module-begin
(define-values (A B C D E F H L)
(values 0 0 0 0 0 0 0 0))
(set! A 8)
LINE ...
(displayln
(format "A: ~a ; F: ~a\nB: ~a ; C: ~a\nD: ~a ; E: ~a\nH: ~a ; L: ~a"
A F B C D E H L))))

(define (val h x)
(if (symbol? x)
(hash-ref h x)
x))

(define-macro-cases z-ld
[(_ (z-r8 S) (_ D)) #'(set! S (val D))])

+ 7
- 0
old-code/expr.rkt View File

@@ -0,0 +1,7 @@
#lang br

(provide z-ld)

(define-macro-cases z-ld
[(_ )]
)

+ 18
- 0
old-code/lexer.rkt View File

@@ -0,0 +1,18 @@
#lang br
(require brag/support)

(define-lex-abbrev digits (:+ (char-set "0123456789")))

(define-lex-abbrev reserved-terms (:or "LD" ","))

(define-lex-abbrev register-terms (:or "A" "B" "C" "D" "E" "F" "H" "L"))

(define basic-lexer
(lexer-srcloc
["\n" (token 'NEWLINE lexeme)]
[whitespace (token lexeme #:skip? #t)]
[reserved-terms (token lexeme lexeme)]
[register-terms (token 'REGISTER-ID (string->symbol lexeme))]
[digits (token 'U8-NUMBER (string->number lexeme))]))

(provide basic-lexer)

+ 21
- 0
old-code/main.rkt View File

@@ -0,0 +1,21 @@
#lang racket/base

(require "parser.rkt" "tokenizer.rkt")
(require syntax/strip-context)

(module+ reader
(provide read-syntax get-info))

(define (read-syntax path port)
(define parse-tree (parse path (make-tokenizer port path)))
(strip-context
#`(module zybino-mod zybino/expander
#,parse-tree)))

(define (get-info port src-mod src-line src-col src-pos)
(define (handle-query key default)
(case key
[(colour-lexer)
(dynamic-require 'zybino/colourer 'zybino-colourer)]
[else default]))
handle-query)

+ 93
- 0
old-code/memory.rkt View File

@@ -0,0 +1,93 @@
#lang racket

(require (for-syntax syntax/parse))

;-----------------------
; Memory Data Structure
;-----------------------
; Methods for accessing a 16 bit addressing memory
; including support for banking (planned) and
; access controls for ROM (planned)
;-----------------------

; Needs:
; Banking
; Routes based on memory location
; Banking based on memory
; Registers:
; Fast access
; Hash?
;

(struct memory
(registers state banks)
#:transparent)

(define (make-memory)
(memory (make-regvec) (make-statevec) (make-bank)))

(define (make-regvec)
(make-vector 8))

(define (make-statevec)
(make-vector 2))

(define (make-bank [init 0])
(make-vector (expt 2 16)))

(define (deref-state sym)
(case sym
[(state-PC) 0]
[(state-SP) 1]
[else (error "invalid state:" sym)]))

(define (deref-reg sym)
(case sym
[(reg-A) 0]
[(reg-F) 1]
[(reg-B) 2]
[(reg-C) 3]
[(reg-D) 4]
[(reg-E) 5]
[(reg-H) 6]
[(reg-L) 7]
[else (error "invalid register:" sym)]))

(define (get-reg sym memory)
(vector-ref (memory-registers memory) (deref-reg sym)))

(define (get-state sym memory)
(vector-ref (memory-state memory) (deref-state sym)))

(define (get-byte addr bank memory)
(if (and (>= addr 0)
(< addr 65536))
(vector-ref (memory-banks memory) addr)
(error (format "ERROR: address ~a out of bounds" addr))))

(define (set-reg! sym memory val)
(vector-set! (memory-registers memory) (deref-reg sym) (mod-8bit val)))

(define (set-state! sym memory val)
(vector-set! (memory-state memory) (deref-state sym) (mod-16bit val)))

(define (set-byte! addr bank memory val)
(if (and (>= addr 0)
(< addr 65536))
(vector-set! (memory-banks memory) addr (mod-8bit val))
(error (format "ERROR: address ~a out of bounds" addr))))

;----------------------------
; define-8bit & define-16bit
;----------------------------
; composes operations with a modulo in order
; to keep numbers within 8 bits
;----------------------------

(define (mod-8bit x)
(modulo x 256))

(define (mod-16bit x)
(modulo x 65536))

(provide (all-defined-out))

+ 326
- 0
old-code/old-code.rkt View File

@@ -0,0 +1,326 @@
(define (alu-tab y)
(case y
[(0) 'RLC]
[(1) 'RRC]
[(2) 'RL]
[(3) 'RR]
[(4) 'SLA]
[(5) 'SRA]
[(6) 'SWAP]
[(7) 'SRL]
[else (error "unknown alu operation")]))

(define (reg-tab z)
(case z
[(0) 'B]
[(1) 'C]
[(2) 'D]
[(3) 'E]
[(4) 'H]
[(5) 'L]
[(6) 'ind-HL]
[(7) 'A]
[else (error "unknown register index")]))

(define (cc-tab z)
(case z
[(0) 'NZ]
[(1) 'Z]
[(2) 'NC]
[(3) 'C]
[else (error "unknown control index")]))

(define (rp-tab y)
(case
[(0) 'BC]
[(1) 'DE]
[(2) 'HL]
[(3) 'SP]
[else (error "unknown register pair index")]))

(define (rp2-tab y)
(case
[(0) 'BC]
[(1) 'DE]
[(2) 'HL]
[(3) 'AF]
[else (error "unknown register pair index")]))

(define (non-prefix byte)
(let ([x (arithmetic-shift (bitwise-and #b11000000 byte) -6)])
(case x
[(0) (dispatch-zero-x byte)]
[(1) (dispatch-ld-r-r byte)]
[(2) (dispatch-alu-x byte)]
[(3) (dispatch-misc byte)]
[else (error "malformed byte: " byte)])))

(define (dispatch-misc byte)
(let ([z (bitwise-and #b00000111 byte)])
(case z
[(0) (returns-and-misc byte)]
[(1) (pop-ret-misc byte)]
[(2) (cond-jps-and-misc-lds byte)]
[(3) (uncond-jp-and-ints byte)]
[(4) (cond-calls byte)]
[(5) (push-and-call byte)]
[(6) (imm-alu-ops byte)]
[(7) (rst-vecs byte)])))

(define (imm-alu-ops byte)
(letrec ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)])
(lambda x
`(,(case y
[(0) 'ADD]
[(1) 'ADC]
[(2) 'SUB]
[(3) 'SBC]
[(4) 'AND]
[(5) 'XOR]
[(6) 'OR]
[(7) 'CP])
,x))))

(define (rst-vecs byte)
(letrec ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)])
`(RST ,(* y 8))))

(define (push-and-call byte)
(letrec ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[p (arithmetic-shift y -1)]
[z (bitwise-and #b00000111 byte)])
(case y
[(0 1 2 3) `(PUSH ,(rp2-tab p))]
[(4) (lambda y2 (lambda x `(CALL ,@(make-16b-addr x y2))))]
[(5 6 7) '(REMOVED)])))

(define (cond-calls byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(case y
[(0 1 2 3) (lambda y2 (lambda x `(CALL ,(cc-tab y) ,(make-16b-addr x y2))))]
[(4 5 6 7) '(REMOVED)])))

(define (uncond-jp-and-ints byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(case y
[(0) (lambda y (lambda x `(JP ,(make-16b-addr x y))))]
[(1) '(CB-PREFIX)]
[(2 3 4 5) '(REMOVED)]
[(6) '(DI)]
[(7) '(EI)])))

(define (cond-jps-and-misc-lds byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(case y
[(0 1 2 3) (lambda y2 (lambda x `(JP ,(cc-tab y) ,(make-16b-addr x y2))))]
[(4) '(LD (ADD #xFF00 C) A)]
[(5) (lambda y (lambda x `(LD ,(make-16b-addr x y) A)))]
[(6) '(LD A (ADD #xFF00 C))]
[(7) (lambda y (lambda x `(LD A ,(make-16b-addr x y))))])))

(define (pop-ret-misc byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(case y
[(0 1 2 3) `(POP ,(rp2-tab z))]
[(4) '(RET)]
[(5) '(RETI)]
[(6) '(JP HL)]
[(7) '(LD SP HL)])))

(define (returns-and-misc byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(if (> y 4)
`(RET ,(cc-tab y))
(make-misc-ldh-and-sp (- y 4)))))

(define (make-misc-ldh-and-sp y)
(case y
[(0) (lambda x `(LD ,(bitwise-ior #xFF00 x) A))]
[(1) (lambda d `(ADD SP ,d))]
[(2) (lambda x `(LD A ,(bitwise-ior #xFF00 x)))]
[(3) (lambda d `(LD HL (ADD SP ,d)))]))

(define (dispatch-alu-x byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(case y
[(0) `(ADD ,(reg-tab z))]
[(1) `(ADC ,(reg-tab z))]
[(2) `(SUB ,(reg-tab z))]
[(3) `(SBC ,(reg-tab z))]
[(4) `(AND ,(reg-tab z))]
[(5) `(XOR ,(reg-tab z))]
[(6) `(OR ,(reg-tab z))]
[(7) `(CP ,(reg-tab z))])))

(define (dispatch-zero-x byte)
(let ([z (bitwise-and #b00000111 byte)])
(case z
[(0) (relative-jp-and-misc byte)]
[(1) (16b-ld-and-add byte)]
[(2) (indirect-lds-a byte)]
[(3) (16b-inc-dec byte)]
[(4 5) (8b-inc-dec byte)]
[(6) (8b-ld-imm byte)]
[(7) (rots-and-misc byte)]
[else (error "malformed instruction: " byte)])))

(define (dispatch-ld-r-r byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
`(LD ,(reg-tab y) ,(reg-tab z))))

(define (rots-and-misc byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)])
(case y
[(0) '(RLCA)]
[(1) '(RRCA)]
[(2) '(RLA)]
[(3) '(RRA)]
[(4) '(DAA)]
[(5) '(CPL)]
[(6) '(SCF)]
[(7) '(CCF)])))

(define (8b-ld-imm byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)])
(lambda x
`(LD (REG ,(reg-tab y)) x))))

(define (8b-inc-dec byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
`(,(if (= 4 z) 'INC 'DEC) (REG ,(reg-tab y)))))

(define (16b-inc-dec byte)
(letrec ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[q (modulo y 2)]
[p (arithmetic-shift y -1)])
`(,(if (= 0 q) 'INC 'DEC) (REGP ,(rp-tab p)))))

(define (indirect-lds-a byte)
(letrec ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[q (modulo y 2)]
[p (arithmetic-shift y -1)])
(if (= 0 q)
(make-ld-ind-p-a p)
(make-ld-ind-a-p p))))

(define (make-ld-ind-p-a p)
(case p
[(0) '(LD (IND BC) (REG A))]
[(1) '(LD (IND DE) (REG A))]
[(2) '(LDI (IND HL) (REG A))]
[(3) '(LDD (IND HL) (REG A))]))

(define (make-ld-ind-a-p p)
(case p
[(0) '(LD (REG A) (IND BC))]
[(1) '(LD (REG A) (IND DE))]
[(2) '(LDI (REG A) (IND HL))]
[(3) '(LDD (REG A) (IND HL))]))

(define (16b-ld-and-add byte)
(letrec ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[q (modulo y 2)]
[p (arithmetic-shift y -1)])
(if (= 0 q)
(make-16b-ld p)
`(ADD (REGP HL) (REGP ,(rp-tab p))))))

(define (relative-jp-and-misc byte)
(let ([y (arithmetic-shift (bitwise-and #b00111000 byte) -3)])
(case y
[(0) '(NOP)]
[(1) (create-ld-16b-ind 'SP)]
[(2) '(STOP)]
[(3) (make-jr '())]
[(4 5 6 7) (make-jr y)]
[else (error "malformed byte: " byte)])))

(define (decode-cb-prefix byte)
(letrec ([x (arithmetic-shift (bitwise-and #b11000000 byte) -6)]
[y (arithmetic-shift (bitwise-and #b00111000 byte) -3)]
[z (bitwise-and #b00000111 byte)])
(case x
[(0) `(,(alu-tab y) ,(reg-tab z))]
[(1) `(BIT ,y ,(reg-tab z))]
[(2) `(RES ,y ,(reg-tab z))]
[(3) `(SET ,y ,(reg-tab z))])))

(define (test bs)
(car (read-instruction (set-bytes #x0000 bs (make-mem)))))

(define (create-ld-16b-ind src)
(lambda y
(lambda x
`(LD (IND ,(make-16b-addr x y)) ,src))))

(define (make-16b-ld p)
(lambda y
(lambda x
`(LD (REGP ,(rp-tab p)) (IND ,(make-16b-addr x y))))))


(define (make-jr cc)
`(JR ,(if (null? cc) 'no-check (cc-tab (- cc 4)))))






(define (read-instruction m)
(begin
(define (ri-loop f npc)
(if (not (procedure? f))
(cons f (struct-copy mem m [pc npc]))
(ri-loop (f (get-byte npc m)) (mod-16bit (add1 npc)))))
(ri-loop decode-instr (mem-pc m))))

(define (decode-instr byte)
(if (or (>= byte 256) (< byte 0))
(error "invalid opcode byte: " byte)
(if (= byte #xCB)
decode-cb-prefix
(non-prefix byte))))



(define (read-instruction m)
(begin
(define (ri-loop f npc)
(if (not (procedure? f))
(cons f (struct-copy mem m [pc npc]))
(ri-loop (f (get-byte npc m)) (mod-16bit (add1 npc)))))
(ri-loop decode-instr (mem-pc m))))

(define (decode-instr byte)
(if (or (>= byte 256) (< byte 0))
(error "invalid opcode byte: " byte)
(if (= byte #xCB)
decode-cb-prefix
(non-prefix byte))))



(define (read-instruction m)
(begin
(define (ri-loop f npc)
(if (not (procedure? f))
(cons f (struct-copy mem m [pc npc]))
(ri-loop (f (get-byte npc m)) (mod-16bit (add1 npc)))))
(ri-loop decode-instr (mem-pc m))))

(define (decode-instr byte)
(if (or (>= byte 256) (< byte 0))
(error "invalid opcode byte: " byte)
(if (= byte #xCB)
decode-cb-prefix
(non-prefix byte))))


+ 17
- 0
old-code/parse-only.rkt View File

@@ -0,0 +1,17 @@
#lang br/quicklang
(require "parser.rkt" "tokenizer.rkt")

(define (read-syntax path port)
(define parse-tree (parse path (make-tokenizer port path)))
(strip-bindings
#`(module zybino-parser-mod zybino/parse-only
#,parse-tree)))

(module+ reader
(provide read-syntax))

(define-macro (parse-only-mb PARSE-TREE)
#'(#%module-begin
'PARSE-TREE))

(provide (rename-out [parse-only-mb #%module-begin]))

+ 7
- 0
old-code/parser.rkt View File

@@ -0,0 +1,7 @@
#lang brag

z-program : ([z-op] /NEWLINE)*
@z-op : z-ld
z-ld : /"LD" z-r8 /"," (z-r8 | z-n8)
z-n8 : U8-NUMBER
z-r8 : REGISTER-ID

+ 7
- 0
old-code/test.rkt View File

@@ -0,0 +1,7 @@
#lang zybino

LD A,8
LD B,A
LD C,B
LD H,16
LD B,H

+ 17
- 0
old-code/tokenize-only.rkt View File

@@ -0,0 +1,17 @@
#lang br/quicklang
(require brag/support "tokenizer.rkt")

(define (read-syntax path port)
(define tokens (apply-tokenizer make-tokenizer port))
(strip-bindings
#`(module zybino-tokens-mod zybino/tokenize-only
#,@tokens)))

(module+ reader
(provide read-syntax))

(define-macro (tokenize-only-mb TOKEN ...)
#'(#%module-begin
(list TOKEN ...)))

(provide (rename-out [tokenize-only-mb #%module-begin]))

+ 10
- 0
old-code/tokenizer.rkt View File

@@ -0,0 +1,10 @@
#lang br
(require "lexer.rkt" brag/support)

(define (make-tokenizer ip [path #f])
(port-count-lines! ip)
(lexer-file-path path)
(define (next-token) (basic-lexer ip))
next-token)

(provide make-tokenizer)

+ 158
- 0
vm.rkt View File

@@ -0,0 +1,158 @@
#lang racket

(struct mem
(regs pc sp flags bank))

(define (make-mem)
(mem (make-regs)
0
0
0
(make-bank)))

(define (make-regs)
(make-vector 8 0))

(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")))

(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")))

(define (make-bank)
(make-vector 65536 #x00))

(define (mod-8bit val)
(modulo val 256))

(define (mod-16bit val)
(modulo val 65536))

(define (set-pc addr m)
(begin
(struct-copy mem m [pc (mod-16bit addr)])))

(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)))))

(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)))))

(define (set-bytes addr bs m)
(if (null? bs)
m
(set-bytes (mod-16bit (add1 addr))
(cdr bs)
(set-byte addr (car bs) m))))

(define (inc-sp m)
(struct-copy mem m [sp (add1 (mem-sp m))]))

(define (inc-pc m)
(struct-copy mem m [pc (add1 (mem-pc m))]))


(define (make-16b-addr x y)
(bitwise-ior y (arithmetic-shift x 8)))

(define (8b-ld-reg-imm reg imm)
(lambda (m)
(set-reg reg imm m)))

(define (8b-ld-reg-reg dst src)
(lambda (m)
(set-reg dst
(get-reg src m)
m)))

(define (display-byte-hex v)
(~a #:align 'right #:left-pad-string "0" #:width 2
(format "~x" v)))

(define (display-word-hex v)
(~a #:align 'right #:left-pad-string "0" #:width 4
(format "~x" v)))

(define (display-bin v)
(~a #:left-pad-string "0" #:width 8 #:align 'right
(format "~b" v)))

(define (print-regs m)
(letrec ([regs (mem-regs m)]
[F (display-byte-hex (mem-flags m))]
[B (display-byte-hex (vector-ref regs 0))]
[C (display-byte-hex (vector-ref regs 1))]
[D (display-byte-hex (vector-ref regs 2))]
[E (display-byte-hex (vector-ref regs 3))]
[h (vector-ref regs 4)]
[l (vector-ref regs 5)]
[H (display-byte-hex (vector-ref regs 4))]
[L (display-byte-hex (vector-ref regs 5))]
[HL-ind (display-byte-hex (get-byte (make-16b-addr h l) m))]
[A (display-byte-hex (vector-ref regs 7))])
(displayln (format "BC: $~a~a, DE: $~a~a" B C D E))
(displayln (format "HL: $~a~a, AF: $~a~a" H L A F))
(displayln (format "(HL): $~a" HL-ind))
(void)))

(define (print-state m)
(displayln (format "PC: $~a, SP: $~a, Flags: %~a"
(display-byte-hex (mem-pc m))
(display-byte-hex (mem-sp m))
(display-bin(mem-flags m)))))

(define (print-part-bank start count m)
(define (print-mem v)
(display (format " $~a" (display-byte-hex v))))
(let ([s (display-word-hex start)]
[e (display-word-hex (mod-16bit (+ start count)))])
(display (format "$~a >" s))
(let ([splice (vector-take
(vector-drop (mem-bank m) start)
count)])
(vector-map print-mem splice))
(display (format " < $~a\n" e) ))
(void))

(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))

Loading…
Cancel
Save