Advertisement
Kitomas

gol.asm

Aug 4th, 2023
1,913
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;gol.asm
  2. define r16a   $f0
  3. define r16al  $f0
  4. define r16ah  $f1
  5. define r16b   $f2
  6. define r16bl  $f2
  7. define r16bh  $f3
  8. define r16c   $f4
  9. define r16cl  $f4
  10. define r16ch  $f5
  11.  
  12. define tmpA   $f6
  13. define tmpX   $f7
  14. define tmpY   $f8
  15.  
  16. define ccount $f9
  17.  
  18. define tmp0   $fa
  19. define tmp1   $fb
  20. define tmp2   $fc
  21. define tmpf   $fd
  22.  
  23. define random $fe
  24. define key    $ff
  25.  
  26. *=$200
  27. screen:
  28. screen0:
  29. *=$300
  30. screen1:
  31. *=$400
  32. screen2:
  33. *=$500
  34. screen3:
  35.  
  36. *=$fc00
  37. back_buffer:
  38. back_buffer0:
  39. *=$fd00
  40. back_buffer1:
  41. *=$fe00
  42. back_buffer2:
  43. *=$ff00
  44. back_buffer3:
  45.  
  46. *=$600
  47. init:
  48.   lda #0            ;clean up zp and stack
  49.   tax               ;^^
  50.   init_loop_a:      ;^^
  51.     sta $00,x       ;^^
  52.     sta $100,x      ;^^
  53.     inx             ;^^
  54.     bne init_loop_a ;^^
  55.   ldx #$ff ;reset registers, including the stack
  56.   txs      ;^^
  57.   tax      ;^^(A is currently 0)
  58.   tay      ;^^
  59.   init_loop_b:
  60.     ;fill in buffer with either white or black pixels randomly
  61.     lda random
  62.     and #1
  63.     sta back_buffer0,x
  64.     lda random
  65.     and #1
  66.     sta back_buffer1,x
  67.     lda random
  68.     and #1
  69.     sta back_buffer2,x
  70.     lda random
  71.     and #1
  72.     sta back_buffer3,x
  73.     ;also turn the screen black
  74.     lda #0
  75.     sta screen0,x
  76.     sta screen1,x
  77.     sta screen2,x
  78.     sta screen3,x
  79.     inx
  80.     bne init_loop_b ;loop will break once X wraps to 0
  81. main:
  82.   jsr flip_screen
  83.   jsr update_cells
  84.   lda key           ;if a key was pressed, jmp to init
  85.   beq main_loop_end ;^^
  86.   jmp init          ;^^
  87.   main_loop_end:
  88.   jmp main
  89.  
  90. ;r16a += A
  91. add8_16:
  92.   clc
  93.   adc r16al
  94.   sta r16al
  95.   bcc _add8_16_skip_increment
  96.   inc r16ah
  97.   _add8_16_skip_increment:
  98.   rts
  99. ;r16a -= A
  100. sub8_16:
  101.   sta tmp0
  102.   lda r16al
  103.   sec
  104.   sbc tmp0
  105.   sta r16al
  106.   bcs _sub8_16_skip_decrement
  107.   dec r16ah
  108.   _sub8_16_skip_decrement:
  109.   rts
  110.  
  111. ;++r16a
  112. add1_16:
  113.   inc r16al
  114.   bne _add1_16_skip_hi_increment
  115.   inc r16ah
  116.   _add1_16_skip_hi_increment:
  117.   rts
  118. ;++r16c
  119. add1_16c:
  120.   inc r16cl
  121.   bne _add1_16c_skip_hi_increment
  122.   inc r16ch
  123.   _add1_16c_skip_hi_increment:
  124.   rts
  125.  
  126.  
  127. flip_screen:
  128.   ldx #0
  129.   _flip_screen_loop:
  130.     lda back_buffer0,x
  131.     sta screen0,x
  132.     lda back_buffer1,x
  133.     sta screen1,x
  134.     lda back_buffer2,x
  135.     sta screen2,x
  136.     lda back_buffer3,x
  137.     sta screen3,x
  138.     inx
  139.     bne _flip_screen_loop
  140.   rts
  141.  
  142. ;checks neighboring cells around "(r16a)"
  143. ;A should contain flags for which cells to check/skip
  144.  ;bits 7,6,5,4,3,2,1,0 = NW,N,NE,W,E,SW,S,SE respectively
  145. ;cell count is returned into X
  146. count_neighboring_cells: ;r16a,r16b
  147.   sty tmpY    ;save state of Y
  148.   tax         ;save cell flags to X and tmpf
  149.   sta tmpf    ;^^
  150.   lda #0      ;reset cell counter
  151.   sta ccount  ;^^
  152.   tay         ;set indirection index to 0
  153.   lda r16al   ;save state of r16a to r16b
  154.   sta r16bl   ;^^
  155.   lda r16ah   ;^^
  156.   sta r16bh   ;^^
  157.   ;north west
  158.   lda #33        ;-32 (up) -1 (left) for nw cell
  159.   jsr sub8_16    ;^^
  160.   txa            ;skip nw cell if flag 7 ==0
  161.   and #%10000000 ;^^
  162.   beq _cnc_no_nw ;^^
  163.   lda (r16a),y   ;increment if nw cell !=0
  164.   beq _cnc_no_nw ;^^
  165.   inc ccount     ;^^
  166.   _cnc_no_nw:    ;^^
  167.   ;north
  168.   iny            ;+1 (right) for n cell
  169.   txa            ;skip n cell if flag 6 ==0
  170.   and #%01000000 ;^^
  171.   beq _cnc_no_n  ;^^
  172.   lda (r16a),y   ;increment if n cell !=0
  173.   beq _cnc_no_n  ;^^
  174.   inc ccount     ;^^
  175.   _cnc_no_n:     ;^^
  176.   ;north east
  177.   iny            ;+1 (right) for ne cell
  178.   txa            ;skip ne cell if flag 5 ==0
  179.   and #%00100000 ;^^
  180.   beq _cnc_no_ne ;^^
  181.   lda (r16a),y   ;increment if ne cell !=0
  182.   beq _cnc_no_ne ;^^
  183.   inc ccount     ;^^
  184.   _cnc_no_ne:    ;^^
  185.   ;west
  186.   ldy #0         ;reset indirection index (-2 (left))
  187.   lda #32        ;+32 (down) for w cell
  188.   jsr add8_16    ;^^
  189.   txa            ;skip w cell if flag 4 ==0
  190.   and #%00010000 ;^^
  191.   beq _cnc_no_w  ;^^
  192.   lda (r16a),y   ;increment if w cell !=0
  193.   beq _cnc_no_w  ;^^
  194.   inc ccount     ;^^
  195.   _cnc_no_w:     ;^^
  196.   ;east
  197.   ldy #2         ;+2 (right) for e cell
  198.   txa            ;skip e cell if flag 3 ==0
  199.   and #%00001000 ;^^
  200.   beq _cnc_no_e  ;^^
  201.   lda (r16a),y   ;increment if e cell !=0
  202.   beq _cnc_no_e  ;^^
  203.   inc ccount     ;^^
  204.   _cnc_no_e:     ;^^
  205.   ;south west
  206.   ldy #0         ;reset indirection index (-2 (left))
  207.   lda #32        ;+32 (down)  for sw cell
  208.   jsr add8_16    ;^^
  209.   txa            ;skip w cell if flag 2 ==0
  210.   and #%00000100 ;^^
  211.   beq _cnc_no_sw ;^^
  212.   lda (r16a),y   ;increment if sw cell !=0
  213.   beq _cnc_no_sw ;^^
  214.   inc ccount     ;^^
  215.   _cnc_no_sw:    ;^^
  216.   ;south
  217.   iny            ;+1 (right) for s cell
  218.   txa            ;skip s cell if flag 1 ==0
  219.   and #%00000010 ;^^
  220.   beq _cnc_no_s  ;^^
  221.   lda (r16a),y   ;increment if s cell !=0
  222.   beq _cnc_no_s  ;^^
  223.   inc ccount     ;^^
  224.   _cnc_no_s:     ;^^
  225.   ;south east
  226.   iny            ;+1 (right) for se cell
  227.   txa            ;skip se cell if flag 0 ==0
  228.   and #%00000001 ;^^
  229.   beq _cnc_no_se ;^^
  230.   lda (r16a),y   ;increment if se cell !=0
  231.   beq _cnc_no_se ;^^
  232.   inc ccount     ;^^
  233.   _cnc_no_se:    ;^^
  234.   ;wrap things up
  235.   lda r16bl  ;restore r16a's original value
  236.   sta r16al  ;^^
  237.   lda r16bh  ;^^
  238.   sta r16ah  ;^^
  239.   ;ldy tmpY   ;restore original value of Y
  240.   txa        ;restore cell flags
  241.   ldx ccount ;return cell count into X
  242.   rts
  243.  
  244. ;assumes r16a and r16c are tied to the screen and back buffer,
  245.  ;and that A=cell flags
  246. update_cell:
  247.   jsr count_neighboring_cells
  248.   cpx #2                ;if neighbors == 2,
  249.   beq _update_cell_skip ;^^don't do anything to the cell
  250.   cpx #3                ;else if neighbors != 3,
  251.   bne _update_cell_off  ;^^turn cell off
  252.  ;_update_cell_on:      ;else turn cell on
  253.   lda #1                ;^^
  254.   jmp _update_cell_set  ;^^
  255.   _update_cell_off:     ;turn cell off
  256.   lda #0                ;^^
  257.   _update_cell_set:     ;set cell based on the two prev. branches
  258.   ldy #0                ;^^
  259.   sta (r16c),y          ;^^
  260.   _update_cell_skip:
  261.   ldy tmpY ;previously saved by count_neighboring_cells
  262.   lda tmpf
  263.   rts
  264.  
  265. ;assumes back buffer was just copied to the screen (front buffer)
  266. update_cells:
  267.   lda #30           ;set tmp2 to 30 (32 rows - start and end rows = 30)
  268.   sta tmp2          ;^^(tmp2 used as a row counter here)
  269.   lda #<screen      ;set r16a to start of screen
  270.   sta r16al         ;^^
  271.   lda #>screen      ;^^
  272.   sta r16ah         ;^^
  273.   lda #<back_buffer ;set r16c to start of back buffer
  274.   sta r16cl         ;^^
  275.   lda #>back_buffer ;^^
  276.   sta r16ch         ;^^
  277.   ;row 0
  278.   lda #%00001011  ;e,s,se
  279.   jsr update_cell ;update cell @ r16c
  280.   jsr add1_16     ;increment r16a
  281.   jsr add1_16c    ;increment r16c
  282.   lda #%00011111  ;w,e,sw,s,se
  283.   ldy #30         ;32 - the start and end pixels = 30
  284.   _uc_row0_loop:
  285.     jsr update_cell
  286.     jsr add1_16
  287.     jsr add1_16c
  288.     dey               ;will break once y reaches 0
  289.     bne _uc_row0_loop ;^^
  290.   lda #%00010110 ;w,sw,s
  291.   jsr update_cell
  292.   jsr add1_16
  293.   jsr add1_16c
  294.   ;row 1 -> 30
  295.   lda #%01101011 ;n,ne,e,s,sw
  296.   jsr update_cell
  297.   jsr add1_16
  298.   jsr add1_16c
  299.   lda #%11111111 ;nw,n,ne,w,e,sw,s,se
  300.   _uc_rows_loop:
  301.     ldy #30
  302.     _uc_cols_loop:
  303.       jsr update_cell
  304.       jsr add1_16
  305.       jsr add1_16c
  306.       dey
  307.       bne _uc_cols_loop
  308.     dec tmp2
  309.     bne _uc_rows_loop
  310.   lda #%11010110 ;nw,n,w,sw,s
  311.   jsr update_cell
  312.   jsr add1_16
  313.   jsr add1_16c
  314.   ;row 31
  315.   lda #%01101000 ;n,ne,e
  316.   jsr update_cell
  317.   jsr add1_16
  318.   jsr add1_16c
  319.   lda #%11111000 ;nw,n,ne,w,e
  320.   ldy #30
  321.   _uc_row31_loop:
  322.     jsr update_cell
  323.     jsr add1_16
  324.     jsr add1_16c
  325.     dey
  326.     bne _uc_row31_loop
  327.   lda #%11010000 ;nw,n,w
  328.   jsr update_cell
  329.   jsr add1_16
  330.   jsr add1_16c
  331.   ;return
  332.   rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement