Conway's Game of Life - 3D 68000er Assembler-Code für 8x8x8 Game of Life.
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.

polyzoom.s 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. .TEXT
  2. ;-------------------------------------------------------------------------
  3. pitch set 320/2 ; should be multiple of two
  4. xmaxpz set 319
  5. ymaxpz set 199
  6. benchdiv set 0
  7. ;-------------------------------------------------------------------------*
  8. ; LINES
  9. ;-------------------------------------------------------------------------*
  10. ; d0......x1
  11. ; d1......y1
  12. ; d2......x2
  13. ; d3......y2
  14. ; a0......ecran
  15. ;-------------------------------------------------------------------------*
  16. ;-------------------------------------------------------------------------*
  17. line:
  18. cmp.w d1,d3 ;* On ordonne les coordonnees
  19. bge.s line_yordered ;*verticales ;provisoirement y2 > y1
  20. exg.l d0,d2 ;* pour le clip vertical
  21. exg.l d1,d3 ;*
  22. line_yordered:
  23. tst.w d3 ;* Si l'ordonnee la plus grande
  24. bge.s line_y2positive ;*est ;negative (y2 < 0) on trace la droite
  25. ; moveq.l #0,d3 ;* entre x1 et x2 (passe xor oblige)
  26. ; moveq.l #0,d1 ;* On se branche au niveau du clip
  27. ; bra.s clipx ;*horizontal
  28. ; tcr
  29. rts
  30. ; /tcr
  31. line_y2positive:
  32. tst.w d1 ;* Si l'ordonnee la plus petite
  33. bge.s clipy2 ;*negative et l'autre positive
  34. ;
  35. ; On calcule l'intersection avec le
  36. ; bord superieur
  37. ; clipy
  38. move.w d0,d5 ;*
  39. sub.w d2,d5 ;* d5 = x1-x2
  40. ;
  41. move.w d3,d6 ;*
  42. sub.w d1,d6 ;* d6 = y2-y1
  43. .IFNE benchdiv
  44. not.w $ffff8240 ;.w *
  45. .ENDC
  46. muls.w d1,d5 ;* (x1-x2) * y1
  47. divs.w d6,d5 ;* (x1-x2) * y1 / (y2-y1)
  48. .IFNE benchdiv
  49. not.w $ffff8240 ;.w *
  50. .ENDC
  51. add.w d0,d5 ;* (x1-x2) * y1 / (y2-y1) + x1
  52. ; d5: abscisse d'intersection
  53. movem.w d0-d3/d5/d6,-(sp)
  54. move.l a0,-(sp) ;*
  55. moveq.l #0,d1 ;*
  56. moveq.l #0,d3 ;*
  57. move.w d5,d2
  58. ;
  59. ; tcr
  60. ; bsr.s clipx ;*On trace le bout de droite en haut
  61. ; /tcr
  62. ; de l'ecran horizontalement
  63. movea.l (sp)+,a0 ;*
  64. movem.w (sp)+,d0-d3/d5/d6 ;* (passe xor oblige)
  65. move.w d5,d0 ;* On trace le bout de droite
  66. moveq.l #0,d1 ;* restant sur l'ecran
  67. ; coordonnees non inversees
  68. clipy2:
  69. cmpi.w #ymaxpz,d1 ;* Si l'ordonnee la plus petite
  70. bgt.s return ;*est superieure … ymax
  71. cmpi.w #ymaxpz,d3 ;* Si l'ordonnee la plus grande>ymax
  72. ble.s clipx ;*et l'autre <ymax
  73. ; On calcule l'intersection avec le
  74. ; bord superieur
  75. sub.w d0,d2 ;* d2 = x2-x1
  76. sub.w d1,d3 ;* d3 = y2-y1
  77. ;
  78. move.w #ymaxpz,d5 ;*
  79. sub.w d1,d5 ;* d1 = y1-ymax
  80. .IFNE benchdiv
  81. not.w $ffff8240 ;.w *
  82. .ENDC
  83. muls.w d5,d2 ;* (x2-x1) * (y1-ymax)
  84. divs.w d3,d2
  85. .IFNE benchdiv
  86. not.w $ffff8240 ;.w *
  87. .ENDC
  88. add.w d0,d2 ;* (x2-x1) * (y1-ymax) / (y2-y1)+x1
  89. ; d2: abscisse d'intersection
  90. move.w #ymaxpz,d3 ;*
  91. ;----------------------------
  92. ; clipx
  93. ;----------------------------
  94. ; clipx1 --------------------
  95. clipx:
  96. cmp.w d2,d0 ;*
  97. ble.s clipx_ok1 ;*Si ;x1 > x2: Echange x1 x2 & y1 y2
  98. exg.l d2,d0 ;*
  99. exg.l d3,d1
  100. clipx_ok1:
  101. tst.w d2 ;* if d2 < 0 => do nothing
  102. bge.s clipx_ok2 ;
  103. return:
  104. rts ;*
  105. clipx_ok2:
  106. move.w d0,d7 ;* if x1 < 0 => store to fix length when displaying
  107. blt.s clipx_ok3
  108. moveq.l #0,d7
  109. clipx_ok3:
  110. ; clipx2 --------------------
  111. cmpi.w #xmaxpz,d0 ;* Si l'abscisse la plus petite
  112. bgt.s return ;*est ;superieure à xmax
  113. ; => on trace pas
  114. cmpi.w #xmaxpz,d2 ;* Si l'abscisse la plus grande > xmax
  115. ble.s trace
  116. ; On calcule l'intersection avec le
  117. ; bord superieur
  118. sub.w d0,d2 ;* d2 = x2-x1
  119. sub.w d1,d3 ;* d3 = y2-y1
  120. ;
  121. move.w #xmaxpz,d5 ;*
  122. sub.w d0,d5 ;* d0 = xmax-x1
  123. .IFNE benchdiv
  124. not.w $ffff8240 ;.w *
  125. .ENDC
  126. muls.w d5,d3 ;* (y2-y1) * (xmax-x1)
  127. divs.w d2,d3 ;* (y2-y1) * (xmax-x1) / (x2-x1)
  128. .IFNE benchdiv
  129. not.w $ffff8240 ;.w *
  130. .ENDC
  131. add.w d1,d3 ;* (y2-y1) * (xmax-x1) / (x2-x1)+y1
  132. ; d3: ordonnee d'intersection
  133. move.w #xmaxpz,d2 ;*
  134. ; tcr - try to avoid lines at screen edge
  135. rts
  136. ; /tcr
  137. ;----------------------------
  138. ; display
  139. ;----------------------------
  140. ; here we have d0,d1,d2,d3,d7 => x1, y1, x2, y2, lengthfix from x1 clip
  141. trace:
  142. lea -pitch,a2 ;
  143. ; movea.l #-pitch,a2
  144. sub.w d2,d0 ;* d0: largeur
  145. ; beq.s return ;* if dx = 0 => do nothing
  146. neg.w d0 ;*
  147. ; d0.w: -dx,a2.l: -pitch (-160)
  148. sub.w d3,d1 ;* d1: hauteur
  149. ; d1.w: dy,a2.l: -pitch(-160)
  150. ;beq h_line ; *if dy = 0 => hline
  151. ;blt.s trace_ok ;
  152. ble.s trace_ok
  153. lea pitch,a2 ;* if dy negative => invert address increment ¨Illegal adressing mode
  154. ; movea.l #pitch,a2
  155. neg.w d1 ;* abs (dy)
  156. ; d1.w = abs(dy), a2.l=pitch(160)
  157. trace_ok:
  158. neg.w d1 ;*
  159. ; d1 = abs(dy)
  160. lea pitchmul(pc),a1 ;* compute start address : a0 += y2 * pitch
  161. add.w d3,d3 ;*
  162. ; d3 = 2*y
  163. move.w 0(a1,d3.w),d3 ;*
  164. ; d3 = pitch*y
  165. ; add.w d3,d3 * (pitch / 2) * 2
  166. adda.w d3,a0
  167. ; a0 += pitch*y, start address of line
  168. ; at this point:
  169. ; d0.w: -dx
  170. ; d1.w: abs(dy)
  171. cmp.w d0,d1 ;* Compare dx & dy
  172. ; blt.s horizontal ;* => dx > dy => horizontal routine
  173. ; bgt verticalpz ;* => dy > dx => vertical routine
  174. bgt vertbresen
  175. beq d45 ;* => equal => 45 routine
  176. ;
  177. ; Dx>Dy
  178. ;------------------------------------------------------------------
  179. horizontal:
  180. swap.w d1 ;* dy*65536
  181. sub.w d1,d1 ;*
  182. .IFNE benchdiv
  183. not.w $ffff8240 ;.w *
  184. .ENDC
  185. divu.w d0,d1 ;* d1: increment dy*65536/dx
  186. .IFNE benchdiv
  187. not.w $ffff8240 ;.w *
  188. .ENDC
  189. add.w d7,d0 ;* fix length according to x1 clip
  190. lea line_display_horiz(pc),a3 ;* compute routine adresses range
  191. movea.l a3,a4 ;*
  192. add.w d2,d2 ;* start address : get values at x2 * 4
  193. add.w d2,d2
  194. move.l line_display_htab(pc,d2.w),d7
  195. adda.w d7,a0 ;* compute offset into routine
  196. swap.w d7
  197. adda.w d7,a3 ;* add x2 address offset to a0
  198. add.w d0,d0 ;* end address into routine : x2 * 4 + length * 4
  199. add.w d0,d0
  200. sub.w d0,d2
  201. adda.w line_display_htab(pc,d2.w),a4
  202. movem.w precharge(pc),d0/d2-d7
  203. movea.w (a4),a5 ;* backup opcode
  204. move.w #$4e75,(a4) ;* put an rts into the routine
  205. jsr (a3)
  206. move.w a5,(a4) ;* restore overwritten opcode
  207. rts
  208. precharge:
  209. .DC.w 1 ;* d0
  210. .DC.w 4 ;* d2
  211. .DC.w 8 ;* d3
  212. .DC.w 32 ;* d4
  213. .DC.w -32768 ;* d5
  214. .DC.w 64 ;* d6
  215. .DC.w 128 ;* d7
  216. line_display_htab:
  217. screenpz set 0
  218. opcode set (pitch/8)*2+(pitch*2)*8
  219. .REPT pitch/8
  220. ; 8 times
  221. opcode set opcode-8
  222. .DC.w opcode
  223. .DC.w screenpz
  224. opcode set opcode-8
  225. .DC.w opcode
  226. .DC.w screenpz
  227. opcode set opcode-8
  228. .DC.w opcode
  229. .DC.w screenpz
  230. opcode set opcode-8
  231. .DC.w opcode
  232. .DC.w screenpz
  233. opcode set opcode-8
  234. .DC.w opcode
  235. .DC.w screenpz
  236. opcode set opcode-8
  237. .DC.w opcode
  238. .DC.w screenpz
  239. opcode set opcode-8
  240. .DC.w opcode
  241. .DC.w screenpz
  242. screenpz set screenpz+1
  243. opcode set opcode-8
  244. .DC.w opcode
  245. .DC.w screenpz
  246. ; 8 times
  247. opcode set opcode-8
  248. .DC.w opcode
  249. .DC.w screenpz
  250. opcode set opcode-8
  251. .DC.w opcode
  252. .DC.w screenpz
  253. opcode set opcode-8
  254. .DC.w opcode
  255. .DC.w screenpz
  256. opcode set opcode-8
  257. .DC.w opcode
  258. .DC.w screenpz
  259. opcode set opcode-8
  260. .DC.w opcode
  261. .DC.w screenpz
  262. opcode set opcode-8
  263. .DC.w opcode
  264. .DC.w screenpz
  265. opcode set opcode-8
  266. .DC.w opcode
  267. .DC.w screenpz
  268. opcode set opcode-8
  269. .DC.w opcode
  270. .DC.w screenpz
  271. opcode set opcode-2
  272. screenpz set screenpz+7
  273. .ENDR
  274. ;------------------------------------------------------------------
  275. ; Dx<Dy
  276. ;------------------------------------------------------------------
  277. vertbresen:
  278. ; bresenham, also for dx = 0
  279. ; d0: dx
  280. ; d1: abs(dy)
  281. ; a2: pitch / -pitch (address offset for next line)
  282. move.l a2,d6
  283. ; d6: pitch / -pitch
  284. ; dont know if necessary
  285. ; add.w d7,d0
  286. add.w d2,d2
  287. add.w d2,d2
  288. ; d2: 4*x2
  289. lea table2(pc),a1
  290. move.l 0(a1,d2.w),d4
  291. adda.w d4,a0
  292. ; start in at the correct x-word
  293. swap.w d4
  294. ; correct bit mask for pixel in d4 (starting from the right)
  295. move.w d1,d5
  296. ; d1: dy = number of lines
  297. ; here: need to know the block size
  298. lsl.w #4,d5 ; *16
  299. add.w d1,d5
  300. add.w d1,d5
  301. neg.w d5
  302. ; d2: err, initialized as abs(dy)/2
  303. move.w d1,d2
  304. lsr.w #1,d2
  305. lea bres_blocks(pc),a3
  306. jmp 0(a3,d5.w)
  307. .REPT ymaxpz+1
  308. ; eor.w d4,(a0) ;* Affichage point
  309. or.w d4,(a0)
  310. adda.l d6,a0 ;* adr affichage-160 (trace a l'envers)
  311. sub.w d0,d2
  312. bge.s *+12
  313. add.w d1,d2
  314. add.w d4,d4 ;* on decale de 1 le bit tournant
  315. bcc.s *+6
  316. subq.l #8,a0 ;* adr affichage-8 (trace a l'envers)
  317. moveq.l #1,d4
  318. ; this block has 18 bytes
  319. .ENDR
  320. bres_blocks:
  321. rts
  322. verticalpz:
  323. move.l a2,d6
  324. ; d6.l: pitch or -pitch
  325. ; move.w d1,d6
  326. lsl.l #8,d1
  327. andi.l #$ffff00,d1
  328. ; andi.l #$ffff,d1
  329. ; d1.l: abs(dy)*256
  330. .IFNE benchdiv
  331. not.w $ffff8240 ;.w *
  332. .ENDC
  333. divu.w d0,d1 ;* d1: increment dx*65536/dy
  334. ; d1 lower: abs(dy)*256 / dx, upper: remainder
  335. ; d0: -dx (still)
  336. ;test: d1: dy/dx (minimum 1!)
  337. .IFNE benchdiv
  338. not.w $ffff8240 ;.w *
  339. .ENDC
  340. ; add clip length correction from the left
  341. add.w d7,d0
  342. ; move.w d6,d7
  343. ; move.l a2,d6
  344. ; d2: x2
  345. add.w d2,d2
  346. add.w d2,d2
  347. ; d2: 4*x2
  348. lea table2(pc),a1
  349. move.l 0(a1,d2.w),d4
  350. adda.w d4,a0
  351. ; a0: screen address at the correct word
  352. ; lea 0(a0,d4.w),a0
  353. swap.w d4
  354. ; d4.w: bitmask for the correct pixel (in x)
  355. move.l d6,d2
  356. move.l d1,d3
  357. lsr.w #8,d3
  358. ; d3: (abs(dy) * 256 / dx) / 256
  359. .IFNE benchdiv
  360. not.w $ffff8240 ;.w *
  361. .ENDC
  362. ; muls.w d3,d6
  363. .IFNE benchdiv
  364. not.w $ffff8240 ;.w *
  365. .ENDC
  366. ; move.w d7,d0 ; dy
  367. move.w d0,d5 ;* compute jmp distance
  368. lsl.w #5,d0 ; *32
  369. add.w d5,d5 ; *2
  370. ; added tcr
  371. ; add.w d5,d5
  372. ; add.w d5,d5 ; d5 *8 in total -> 24 bytes
  373. ; end addition
  374. add.w d5,d0
  375. neg.w d0
  376. ;move.w d7,d3
  377. ;move.w a5,d3
  378. ; move.w d3,d7 ; number of lines on same level
  379. move.w #-32768,d5
  380. ; move.w #$8000,d5
  381. lea vertical_display(pc),a3
  382. jmp 0(a3,d0.w)
  383. .REPT ymaxpz+1
  384. ; eor.w d4,(a0) ;* Affichage point
  385. or.w d4,(a0)
  386. adda.l d6,a0 ;* adr affichage-160 (trace a l'envers)
  387. add.w d4,d4 ;* on decale de 1 le bit tournant
  388. bcc.s *+6 ;* Si abscisse bit > 15
  389. subq.l #8,a0 ;* adr affichage-8 (trace a l'envers)
  390. moveq.l #1,d4
  391. ; dont know what this was for...
  392. ; nop
  393. ; nop
  394. ; nop
  395. ; add.b d1,d5 ;* Incremente le taux d'erreur
  396. ; bcc.s *+4 ;* Si bit carry , taux > 1 unite (65536)
  397. ; adda.l d2,a0 ;*
  398. ;
  399. ; this block has 34 bytes
  400. .ENDR
  401. vertical_display:
  402. rts
  403. ;
  404. ; Dx=Dy
  405. ;------------------------------------------------------------------
  406. diago:
  407. .REPT 8
  408. ;eor.w d4,(a0) ;* Affiche le point
  409. or.w d4,(a0)
  410. adda.l a2,a0 ;* Mvt vert
  411. add.w d4,d4 ;* Mvt hori
  412. bcc.s *+6 ;*Incremente ;adr si abscisse mod 16 = 0
  413. subq.l #8,a0 ;*
  414. moveq.l #1,d4 ;*
  415. .ENDR
  416. saut3:
  417. dbra d1,diago ; * Longueur ¨Illegal extension
  418. rts
  419. d45:
  420. ;moveq.l #$FFF0,d5
  421. ;and.w d2,d5
  422. ;lsr.w #1,d5
  423. ;add.w d5,a0
  424. add.w d2,d2
  425. add.w d2,d2
  426. lea table2(pc),a1
  427. move.l 0(a1,d2.w),d4
  428. ;adda.w d4,a0
  429. lea 0(a0,d4.w),a0
  430. swap.w d4
  431. add.w d7,d0
  432. add.w d7,d1
  433. andi.w #7,d0
  434. neg.w d0
  435. add.w d0,d0 ;* let's do the mul 12 manually
  436. add.w d0,d0
  437. move.w d0,d7
  438. add.w d7,d7
  439. add.w d7,d0
  440. lsr.w #3,d1
  441. jmp saut3(pc,d0.w)
  442. line_display_horiz:
  443. .REPT pitch/8
  444. subq.l #7,a0 ; decrement address by 7
  445. ;eor.b d0,(a0) ; bit 0
  446. or.b d0,(a0)
  447. add.w d1,d5
  448. bcc.s *+4
  449. adda.l a2,a0
  450. ;bchg.b d0,(a0) ; bit 1
  451. bset.b d0,(a0)
  452. add.w d1,d5
  453. bcc.s *+4
  454. adda.l a2,a0
  455. ;eor.b d2,(a0) ; bit 2
  456. or.b d2,(a0)
  457. add.w d1,d5
  458. bcc.s *+4
  459. adda.l a2,a0
  460. ;eor.b d3,(a0) ; bit 3
  461. or.b d3,(a0)
  462. add.w d1,d5
  463. bcc.s *+4
  464. adda.l a2,a0
  465. ;bchg.b d2,(a0) ; bit 4
  466. bset.b d2,(a0)
  467. add.w d1,d5
  468. bcc.s *+4
  469. adda.l a2,a0
  470. ;eor.b d4,(a0) ; bit 5
  471. or.b d4,(a0)
  472. add.w d1,d5
  473. bcc.s *+4
  474. adda.l a2,a0
  475. ;eor.b d6,(a0) ; bit 6
  476. or.b d6,(a0)
  477. add.w d1,d5
  478. bcc.s *+4
  479. adda.l a2,a0
  480. ;eor.b d7,(a0) ; bit 7
  481. or.b d7,(a0)
  482. add.w d1,d5
  483. bcc.s *+4
  484. adda.l a2,a0
  485. ;eor.b d0,-(a0) ; bit 0 + decrement address by one
  486. or.b d0,-(a0)
  487. add.w d1,d5
  488. bcc.s *+4
  489. adda.l a2,a0
  490. ;bchg.b d0,(a0) ; bit 1
  491. bset.b d0,(a0)
  492. add.w d1,d5
  493. bcc.s *+4
  494. adda.l a2,a0
  495. ;eor.b d2,(a0) ; bit 2
  496. or.b d2,(a0)
  497. add.w d1,d5
  498. bcc.s *+4
  499. adda.l a2,a0
  500. ;eor.b d3,(a0) ; bit 3
  501. or.b d3,(a0)
  502. add.w d1,d5
  503. bcc.s *+4
  504. adda.l a2,a0
  505. ;bchg.b d2,(a0) ; bit 4
  506. bset.b d2,(a0)
  507. add.w d1,d5
  508. bcc.s *+4
  509. adda.l a2,a0
  510. ;eor.b d4,(a0) ; bit 5
  511. or.b d4,(a0)
  512. add.w d1,d5
  513. bcc.s *+4
  514. adda.l a2,a0
  515. ;eor.b d6,(a0) ; bit 6
  516. or.b d6,(a0)
  517. add.w d1,d5
  518. bcc.s *+4
  519. adda.l a2,a0
  520. ;eor.b d7,(a0) ; bit 7
  521. or.b d7,(a0)
  522. add.w d1,d5
  523. bcc.s *+4
  524. adda.l a2,a0
  525. .ENDR
  526. rts
  527. .DATA
  528. ;-------------------------------------------------------------------------*
  529. ; Section data
  530. ;-------------------------------------------------------------------------*
  531. pitchmul:
  532. var set 0
  533. .REPT ymaxpz+2
  534. .DC.w var
  535. var set var+pitch
  536. .ENDR
  537. table2:
  538. var set 0
  539. .REPT pitch/8
  540. .DC.w $8000,var,$4000,var,$2000,var,$1000,var
  541. .DC.w $0800,var,$0400,var,$0200,var,$0100,var
  542. .DC.w $0080,var,$0040,var,$0020,var,$0010,var
  543. .DC.w $0008,var,$0004,var,$0002,var,$0001,var
  544. var set var+8
  545. .ENDR