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.

482 lines
14KB

  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 (add1pc 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. [(0) (8b-add-imm x)]
  112. [(1) (8b-adc-imm x)]
  113. [(2) (8b-sub-imm x)]
  114. [(3) (8b-sbc-imm x)]
  115. [(4) (8b-and-imm x)]
  116. [(5) (8b-xor-imm x)]
  117. [(6) (8b-or-imm x)]
  118. [(7) (8b-cp-imm x)]
  119. [else (nop)])
  120. (inc-pc m))))
  121. (define (make-8b-inc-dec-reg y z m)
  122. (cons ((case z
  123. [(4) 8b-inc-reg]
  124. [(5) 8b-dec-reg]) y)
  125. m))
  126. (define (make-alu-reg y z m)
  127. (cons (case y
  128. [(0) (8b-add-reg z)]
  129. [(1) (8b-adc-reg z)]
  130. [(2) (8b-sub-reg z)]
  131. [(3) (8b-sbc-reg z)]
  132. [(4) (8b-and-reg z)]
  133. [(5) (8b-xor-reg z)]
  134. [(6) (8b-or-reg z)]
  135. [(7) (8b-cp-reg z)])
  136. m))
  137. (define (make-nop m)
  138. (cons (nop) m))
  139. (define (make-stop m)
  140. (cons 'STOP m))
  141. (define (jp cc addr)
  142. (case cc
  143. [(uncond) (jp-uncond addr)]
  144. [else (jp-cond cc addr)]))
  145. (define (8b-ld-reg-imm reg imm)
  146. (lambda (m)
  147. (set-reg reg imm m)))
  148. (define (8b-ld-reg-reg dst src)
  149. (lambda (m)
  150. (set-reg dst
  151. (get-reg src m)
  152. m)))
  153. (define (8b-inc-reg r)
  154. (lambda (m)
  155. (let ([a (mod-8bit (add1 (get-reg r m)))])
  156. (set-flags
  157. (bitwise-ior (if (= a 0) #b10000000 #x00)
  158. (if (>= a 16) #b00100000 #x00))
  159. (set-reg r a m)))))
  160. (define (8b-dec-reg r)
  161. (lambda (m)
  162. (let ([a (mod-8bit (sub1 (get-reg r m)))])
  163. (set-flags
  164. (bitwise-ior (if (= a 0) #b10000000 #x00)
  165. (if (>= a 16) #b00100000 #x00)
  166. #b01000000)
  167. (set-reg r a m)))))
  168. (define (jp-cond cc addr)
  169. (lambda (m)
  170. (let ([c (get-carry m)]
  171. [z (get-zero m)])
  172. (if (case cc
  173. [(NZ) (not z)]
  174. [(Z) z]
  175. [(NC) (not c)]
  176. [(C) c])
  177. (set-pc addr m)
  178. m))))
  179. (define (jp-uncond addr)
  180. (lambda (m)
  181. (set-pc addr m)))
  182. (define (8b-add-imm v)
  183. (lambda (m)
  184. (let ([a (+ (get-reg 7 m)
  185. (mod-8bit v))])
  186. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  187. (if (>= a 16) #b00100000 #x00)
  188. (if (>= a 256) #b00010000 #x00))
  189. (set-reg 7 (mod-8bit a) m)))))
  190. (define (8b-sbc-imm v)
  191. (lambda (m)
  192. (letrec ([c (bitwise-and #b00010000 (mem-flags m))]
  193. [a (- (get-reg 7 m)
  194. (mod-8bit v)
  195. c)])
  196. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  197. (if (>= a 16) #b00100000 #x00)
  198. (if (>= a 256) #b00010000 #x00))
  199. (set-reg 7 (mod-8bit a) m)))))
  200. (define (8b-sub-imm v)
  201. (lambda (m)
  202. (let ([a (- (get-reg 7 m)
  203. (mod-8bit v))])
  204. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  205. (if (>= a 16) #b00100000 #x00)
  206. (if (>= a 256) #b00010000 #x00))
  207. (set-reg 7 (mod-8bit a) m)))))
  208. (define (8b-cp-imm v)
  209. (lambda (m)
  210. (let ([a (- (get-reg 7 m)
  211. (mod-8bit v))])
  212. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  213. (if (>= a 16) #b00100000 #x00)
  214. (if (>= a 256) #b00010000 #x00))
  215. m))))
  216. (define (8b-adc-imm v)
  217. (lambda (m)
  218. (letrec ([c (bitwise-and #b00010000 (mem-flags m))]
  219. [a (+ (get-reg 7 m)
  220. (mod-8bit v)
  221. c)])
  222. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  223. (if (>= a 16) #b00100000 #x00)
  224. (if (>= a 256) #b00010000 #x00))
  225. (set-reg 7 (mod-8bit a) m)))))
  226. (define (8b-add-reg r)
  227. (lambda (m)
  228. (let ([a (+ (get-reg 7 m)
  229. (get-reg r m))])
  230. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  231. (if (>= a 16) #b00100000 #x00)
  232. (if (>= a 256) #b00010000 #x00))
  233. (set-reg 7 (mod-8bit a) m)))))
  234. (define (8b-sbc-reg r)
  235. (lambda (m)
  236. (letrec ([c (bitwise-and #b00010000 (mem-flags m))]
  237. [a (- (get-reg 7 m)
  238. (get-reg r m)
  239. c)])
  240. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  241. (if (>= a 16) #b00100000 #x00)
  242. (if (>= a 256) #b00010000 #x00))
  243. (set-reg 7 (mod-8bit a) m)))))
  244. (define (8b-sub-reg r)
  245. (lambda (m)
  246. (let ([a (- (get-reg 7 m)
  247. (get-reg r m))])
  248. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  249. (if (>= a 16) #b00100000 #x00)
  250. (if (>= a 256) #b00010000 #x00))
  251. (set-reg 7 (mod-8bit a) m)))))
  252. (define (8b-cp-reg r)
  253. (lambda (m)
  254. (let ([a (- (get-reg 7 m)
  255. (get-reg r m))])
  256. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  257. (if (>= a 16) #b00100000 #x00)
  258. (if (>= a 256) #b00010000 #x00))
  259. m))))
  260. (define (8b-adc-reg r)
  261. (lambda (m)
  262. (letrec ([c (bitwise-and #b00010000 (mem-flags m))]
  263. [a (+ (get-reg 7 m)
  264. (get-reg r m)
  265. c)])
  266. (set-flags (bitwise-ior (if (= a 0) #b10000000 #x00)
  267. (if (>= a 16) #b00100000 #x00)
  268. (if (>= a 256) #b00010000 #x00))
  269. (set-reg 7 (mod-8bit a) m)))))
  270. (define (8b-xor-reg r)
  271. (lambda (m)
  272. (let ([a (bitwise-xor (get-reg 7 m)
  273. (get-reg r m))])
  274. (set-flags (if (= a 0) #b10000000 #x00)
  275. (set-reg 7 a m)))))
  276. (define (8b-and-reg r)
  277. (lambda (m)
  278. (let ([a (bitwise-and (get-reg 7 m)
  279. (get-reg r m))])
  280. (set-flags (if (= a 0) #b10000000 #x00)
  281. (set-reg 7 a m)))))
  282. (define (8b-or-reg r)
  283. (lambda (m)
  284. (let ([a (bitwise-ior (get-reg 7 m)
  285. (get-reg r m))])
  286. (set-flags (if (= a 0) #b10000000 #x00)
  287. (set-reg 7 a m)))))
  288. (define (8b-xor-imm imm)
  289. (lambda (m)
  290. (let ([a (bitwise-xor (get-reg 7 m)
  291. (mod-8bit imm))])
  292. (set-flags (if (= a 0) #b10000000 #x00)
  293. (set-reg 7 a m)))))
  294. (define (8b-or-imm imm)
  295. (lambda (m)
  296. (let ([a (bitwise-ior (get-reg 7 m)
  297. (mod-8bit imm))])
  298. (set-flags (if (= a 0) #b10000000 #x00)
  299. (set-reg 7 a m)))))
  300. (define (8b-and-imm imm)
  301. (lambda (m)
  302. (let ([a (bitwise-and (get-reg 7 m)
  303. (mod-8bit imm))])
  304. (set-flags (if (= a 0) #b10000000 #x00)
  305. (set-reg 7 a m)))))
  306. (define (nop)
  307. (lambda (m) m))
  308. (define (display-byte-hex v)
  309. (~a #:align 'right #:left-pad-string "0" #:width 2
  310. (format "~x" v)))
  311. (define (display-word-hex v)
  312. (~a #:align 'right #:left-pad-string "0" #:width 4
  313. (format "~x" v)))
  314. (define (display-bin v)
  315. (~a #:left-pad-string "0" #:width 8 #:align 'right
  316. (format "~b" v)))
  317. (define (print-regs m)
  318. (letrec ([regs (mem-regs m)]
  319. [F (display-byte-hex (mem-flags m))]
  320. [B (display-byte-hex (vector-ref regs 0))]
  321. [C (display-byte-hex (vector-ref regs 1))]
  322. [D (display-byte-hex (vector-ref regs 2))]
  323. [E (display-byte-hex (vector-ref regs 3))]
  324. [h (vector-ref regs 4)]
  325. [l (vector-ref regs 5)]
  326. [H (display-byte-hex (vector-ref regs 4))]
  327. [L (display-byte-hex (vector-ref regs 5))]
  328. [HL-ind (display-byte-hex (get-byte (make-16b-addr h l) m))]
  329. [A (display-byte-hex (vector-ref regs 7))])
  330. (displayln (format "BC: $~a~a, DE: $~a~a" B C D E))
  331. (displayln (format "HL: $~a~a, AF: $~a~a" H L A F))
  332. (displayln (format "(HL): $~a" HL-ind))
  333. (void)))
  334. (define (print-state m)
  335. (displayln (format "PC: $~a, SP: $~a, Flags: %~a"
  336. (display-word-hex (mem-pc m))
  337. (display-word-hex (mem-sp m))
  338. (display-bin (mem-flags m)))))
  339. (define (print-part-bank start count m)
  340. (define (print-mem v)
  341. (display (format " $~a" (display-byte-hex v))))
  342. (let ([s (display-word-hex start)]
  343. [e (display-word-hex (mod-16bit (+ start (sub1 count))))])
  344. (display (format "$~a >" s))
  345. (let ([splice (vector-take
  346. (vector-drop (mem-bank m) start)
  347. count)])
  348. (vector-map print-mem splice))
  349. (display (format " < $~a\n" e) ))
  350. (void))
  351. (define (add1pc pc)
  352. (mod-16bit (add1 pc)))
  353. (define (within x y z)
  354. (and (>= x y) (<= x z)))
  355. (define (decode-op m)
  356. (letrec ([pc (mem-pc m)]
  357. [op (get-byte pc m)]
  358. [npc (add1pc pc)]
  359. [x (get-x op)]
  360. [y (get-y op)]
  361. [z (get-z op)])
  362. (cond
  363. [(= #x00 op) (make-nop (set-pc npc m))]
  364. [(= #x10 op) (make-stop (set-pc npc m))]
  365. [(= #xC3 op) (make-jp 'uncond (set-pc npc m))]
  366. [(and (= 0 x) (within z 4 5))
  367. (make-8b-inc-dec-reg y z (set-pc npc m))]
  368. [(= 1 x)
  369. (make-8b-ld-reg-reg y z (set-pc npc m))]
  370. [(= 2 x)
  371. (make-alu-reg y z (set-pc npc m))]
  372. [(and (= 3 x) (= z 2) (within y 0 3))
  373. (make-jp y (set-pc npc m))]
  374. [(and (= 3 x) (= z 6))
  375. (make-alu-imm y (set-pc npc m))]
  376. [(and (= 0 x) (= 6 z))
  377. (make-8b-ld-reg-imm y (set-pc npc m))]
  378. [else (make-nop (set-pc npc m))])))
  379. (define (test-vm start bank-start bank-count bs)
  380. (let ([m (make-mem start bs)])
  381. (define (fin m)
  382. (begin (print-state m)
  383. (print-regs m)
  384. (print-part-bank bank-start bank-count m)))
  385. (define (run-op m)
  386. (displayln (format "executing: $~a @ $~a"
  387. (display-byte-hex (get-byte (mem-pc m) m))
  388. (display-word-hex (mem-pc m))))
  389. (letrec ([op-pc (decode-op m)]
  390. [op (car op-pc)]
  391. [newmem (cdr op-pc)])
  392. (if (and (not (procedure? op))
  393. (eq? op 'STOP))
  394. (fin newmem)
  395. (begin
  396. ;(print-state newmem)
  397. ;(print-regs newmem)
  398. (run-op (op newmem))))))
  399. (run-op m)))
  400. (define (run-vm start bank-start bank-count bs)
  401. (let ([m (make-mem start bs)])
  402. (define (fin m)
  403. (begin (print-state m)
  404. (print-regs m)
  405. (print-part-bank bank-start bank-count m)))
  406. (define (run-op m)
  407. (letrec ([op-pc (decode-op m)]
  408. [op (car op-pc)]
  409. [newmem (cdr op-pc)])
  410. (if (and (not (procedure? op))
  411. (eq? op 'STOP))
  412. (fin newmem)
  413. (run-op (op newmem)))))
  414. (run-op m)))
  415. (provide (all-defined-out))