Conway's Game of Life - 3D 68000er Assembler-Code für 8x8x8 Game of Life.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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