lr35902ish racket
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
8.7KB

  1. #lang racket
  2. (struct mem
  3. (regs pc sp flags bank))
  4. (define (make-mem [start #x00] [bs '()])
  5. (set-bytes start bs
  6. (mem (make-regs)
  7. start
  8. 0
  9. 0
  10. (make-bank))))
  11. (define (make-regs)
  12. (make-vector 8 0))
  13. (define (get-zero mem)
  14. (bitwise-bit-set? (mem-flags mem) 7))
  15. (define (get-carry mem)
  16. (bitwise-bit-set? (mem-flags mem) 4))
  17. (define (get-reg x mem)
  18. (if (and (< x 8) (>= x 0))
  19. (let ([regs (mem-regs mem)])
  20. (if (not (= x 6))
  21. (vector-ref regs x)
  22. (let([bank (mem-bank mem)]
  23. [h (vector-ref regs 4)]
  24. [l (vector-ref regs 5)])
  25. (vector-ref bank (make-16b-addr h l)))))
  26. (error "unknown register index")))
  27. (define (set-reg x val m)
  28. (if (and (< x 8) (>= x 0))
  29. (let ([regs (mem-regs m)])
  30. (if (not (= x 6))
  31. (let ([newregs (vector-copy regs)])
  32. (vector-set! newregs x (mod-8bit val))
  33. (struct-copy mem m [regs newregs]))
  34. (let ([newbank (vector-copy (mem-bank m))]
  35. [h (vector-ref regs 4)]
  36. [l (vector-ref regs 5)])
  37. (vector-set! newbank (make-16b-addr h l) (mod-8bit val))
  38. (struct-copy mem m [bank newbank]))))
  39. (error "unknown register index")))
  40. (define (make-bank [def #x00])
  41. (make-vector 65536 def))
  42. (define (mod-8bit val)
  43. (modulo val 256))
  44. (define (mod-16bit val)
  45. (modulo val 65536))
  46. (define (set-pc addr m)
  47. (begin
  48. (struct-copy mem m [pc (mod-16bit addr)])))
  49. (define (set-flags f m)
  50. (begin
  51. (struct-copy mem m [flags (mod-8bit f)])))
  52. (define (get-byte addr m)
  53. (let ([b (mem-bank m)])
  54. (if (and (>= addr 0)
  55. (< addr (vector-length b)))
  56. (vector-ref b addr)
  57. (error (format "address ~a out of bounds" addr)))))
  58. (define (set-byte addr val m)
  59. (let ([b (mem-bank m)])
  60. (if (and (>= addr 0)
  61. (< addr (vector-length b)))
  62. (let ([newbank (vector-copy b)])
  63. (vector-set! newbank addr (mod-8bit val))
  64. (struct-copy mem m [bank newbank]))
  65. (error (format "address ~a out of bounds" addr)))))
  66. (define (set-bytes addr bs m)
  67. (if (null? bs)
  68. m
  69. (set-bytes (mod-16bit (add1 addr))
  70. (cdr bs)
  71. (set-byte addr (car bs) m))))
  72. (define (get-x byte)
  73. (arithmetic-shift (bitwise-and #b11000000 byte) -6))
  74. (define (get-y byte)
  75. (arithmetic-shift (bitwise-and #b00111000 byte) -3))
  76. (define (get-z byte)
  77. (bitwise-and #b00000111 byte))
  78. (define (inc-sp m)
  79. (struct-copy mem m [sp (add1 (mem-sp m))]))
  80. (define (inc-pc m)
  81. (struct-copy mem m [pc (add1 (mem-pc m))]))
  82. (define (make-16b-addr x y)
  83. (bitwise-ior y (arithmetic-shift x 8)))
  84. (define (make-8b-ld-reg-imm y m)
  85. (letrec ([pc (mem-pc m)]
  86. [x (get-byte pc m)])
  87. (cons (8b-ld-reg-imm y x)
  88. (set-pc (add1pc pc) m))))
  89. (define (make-jp cc m)
  90. (letrec ([pc (mem-pc m)]
  91. [y (get-byte pc m)]
  92. [npc (add1pc pc)]
  93. [x (get-byte npc m)]
  94. [addr (make-16b-addr x y)]
  95. [cs (cc-tab cc)])
  96. (cons (jp cs addr) (set-pc npc m))))
  97. (define (cc-tab cc)
  98. (case cc
  99. [(0) 'NZ]
  100. [(1) 'Z]
  101. [(2) 'NC]
  102. [(3) 'C]
  103. [else 'uncond]))
  104. (define (make-8b-ld-reg-reg y z m)
  105. (cons (8b-ld-reg-reg y z)
  106. m))
  107. (define (make-alu-imm z m)
  108. (letrec ([pc (mem-pc m)]
  109. [x (get-byte pc m)])
  110. (cons (case z
  111. [(4) (8b-and-imm x)]
  112. [(5) (8b-xor-imm x)]
  113. [(6) (8b-or-imm x)]
  114. [else (nop)])
  115. (inc-pc m))))
  116. (define (make-nop m)
  117. (cons (nop) m))
  118. (define (make-stop m)
  119. (cons 'STOP m))
  120. (define (jp cc addr)
  121. (case cc
  122. [(uncond) (jp-uncond addr)]
  123. [else (jp-cond cc addr)]))
  124. (define (8b-ld-reg-imm reg imm)
  125. (lambda (m)
  126. (set-reg reg imm m)))
  127. (define (8b-ld-reg-reg dst src)
  128. (lambda (m)
  129. (set-reg dst
  130. (get-reg src m)
  131. m)))
  132. (define (jp-cond cc addr)
  133. (lambda (m)
  134. (let ([c (get-carry m)]
  135. [z (get-zero m)])
  136. (if (case cc
  137. [(NZ) (not z)]
  138. [(Z) z]
  139. [(NC) (not c)]
  140. [(C) c])
  141. (set-pc addr m)
  142. m))))
  143. (define (jp-uncond addr)
  144. (lambda (m)
  145. (set-pc addr m)))
  146. (define (8b-xor-imm imm)
  147. (lambda (m)
  148. (let ([a (bitwise-xor (get-reg 7 m)
  149. (mod-8bit imm))])
  150. (displayln (format "~a xor ~a = ~a" (display-byte-hex (get-reg 7 m))
  151. (display-byte-hex (mod-8bit imm))
  152. a))
  153. (set-flags (if (= a 0) #b10000000 #x00)
  154. (set-reg 7 a m)))))
  155. (define (8b-or-imm imm)
  156. (lambda (m)
  157. (let ([a (bitwise-ior (get-reg 7 m)
  158. (mod-8bit imm))])
  159. (set-flags (if (= a 0) #b10000000 #x00)
  160. (set-reg 7 a m)))))
  161. (define (8b-and-imm imm)
  162. (lambda (m)
  163. (let ([a (bitwise-and (get-reg 7 m)
  164. (mod-8bit imm))])
  165. (set-flags (if (= a 0) #b10000000 #x00)
  166. (set-reg 7 a m)))))
  167. (define (nop)
  168. (lambda (m) m))
  169. (define (display-byte-hex v)
  170. (~a #:align 'right #:left-pad-string "0" #:width 2
  171. (format "~x" v)))
  172. (define (display-word-hex v)
  173. (~a #:align 'right #:left-pad-string "0" #:width 4
  174. (format "~x" v)))
  175. (define (display-bin v)
  176. (~a #:left-pad-string "0" #:width 8 #:align 'right
  177. (format "~b" v)))
  178. (define (print-regs m)
  179. (letrec ([regs (mem-regs m)]
  180. [F (display-byte-hex (mem-flags m))]
  181. [B (display-byte-hex (vector-ref regs 0))]
  182. [C (display-byte-hex (vector-ref regs 1))]
  183. [D (display-byte-hex (vector-ref regs 2))]
  184. [E (display-byte-hex (vector-ref regs 3))]
  185. [h (vector-ref regs 4)]
  186. [l (vector-ref regs 5)]
  187. [H (display-byte-hex (vector-ref regs 4))]
  188. [L (display-byte-hex (vector-ref regs 5))]
  189. [HL-ind (display-byte-hex (get-byte (make-16b-addr h l) m))]
  190. [A (display-byte-hex (vector-ref regs 7))])
  191. (displayln (format "BC: $~a~a, DE: $~a~a" B C D E))
  192. (displayln (format "HL: $~a~a, AF: $~a~a" H L A F))
  193. (displayln (format "(HL): $~a" HL-ind))
  194. (void)))
  195. (define (print-state m)
  196. (displayln (format "PC: $~a, SP: $~a, Flags: %~a"
  197. (display-word-hex (mem-pc m))
  198. (display-word-hex (mem-sp m))
  199. (display-bin (mem-flags m)))))
  200. (define (print-part-bank start count m)
  201. (define (print-mem v)
  202. (display (format " $~a" (display-byte-hex v))))
  203. (let ([s (display-word-hex start)]
  204. [e (display-word-hex (mod-16bit (+ start (sub1 count))))])
  205. (display (format "$~a >" s))
  206. (let ([splice (vector-take
  207. (vector-drop (mem-bank m) start)
  208. count)])
  209. (vector-map print-mem splice))
  210. (display (format " < $~a\n" e) ))
  211. (void))
  212. (define (add1pc pc)
  213. (mod-16bit (add1 pc)))
  214. (define (within x y z)
  215. (and (>= x y) (<= x z)))
  216. (define (decode-op m)
  217. (letrec ([pc (mem-pc m)]
  218. [op (get-byte pc m)]
  219. [npc (add1pc pc)]
  220. [x (get-x op)]
  221. [y (get-y op)]
  222. [z (get-z op)])
  223. (cond
  224. [(= #x00 op) (make-nop (set-pc npc m))]
  225. [(= #x10 op) (make-stop (set-pc npc m))]
  226. [(= #xC3 op) (make-jp 'uncond (set-pc npc m))]
  227. [(= 1 x)
  228. (make-8b-ld-reg-reg y z (set-pc npc m))]
  229. [(and (= 3 x) (= z 2) (within y 0 3))
  230. (make-jp y (set-pc npc m))]
  231. [(and (= 3 x) (within z 4 6))
  232. (make-alu-imm y (set-pc npc m))]
  233. [(and (= 0 x) (= 6 z))
  234. (make-8b-ld-reg-imm y (set-pc npc m))]
  235. [else (make-nop (set-pc npc m))])))
  236. (define (run-vm start bank-start bank-count bs)
  237. (let ([m (make-mem start bs)])
  238. (define (fin m)
  239. (begin (print-state m)
  240. (print-regs m)
  241. (print-part-bank bank-start bank-count m)))
  242. (define (run-op m)
  243. (letrec ([op-pc (decode-op m)]
  244. [op (car op-pc)]
  245. [newmem (cdr op-pc)])
  246. (if (and (not (procedure? op))
  247. (eq? op 'STOP))
  248. (fin newmem)
  249. (run-op (op newmem)))))
  250. (run-op m)))
  251. (define (run-lines ls)
  252. (define (run-line-help ls m)
  253. (if (null? ls)
  254. m
  255. (run-line-help (cdr ls)
  256. ((car ls) (inc-pc m)))))
  257. (let ([fin (run-line-help ls (make-mem))])
  258. (begin
  259. (print-state fin)
  260. (print-regs fin)
  261. (print-part-bank #x150 16 fin))))
  262. (provide (all-defined-out))