pouët.net

Conwayův život by Řrřola [web]

; ##                       #
; #  ## ### # # #  #  # # # # # #
; ## ## # #  # #  # #  #  ###  #
;   #                 #   Conwayův život (Conway's Life)
; ##  # # # ## ### a 31-byte intro by rrrola <rrrola@gmail.com>
;  ## #  #  ##  #  greets to everyone who has 2 or 3 neighbors

; RIP John Horton Conway 1937-2020

; How it works:
; - scrolling: the new generation is written into the top left cell
;   - only one buffer is enough (the screen)
; - SS=screen: the stack adds a little randomness during interrupts
;   - [bp], [bp+si], [bp+di] have SS as the default segment
;   - the screen segment works only after the video mode is set
; - 3x3 neighborhood: sum only the right column, reuse left and middle
;   - the center cell is added too
; - B3/S23 rule: use RCR to index into a 9-bit bitfield
;   - LSS initializes the sum so that carry=1 after summing everything
; - overlapping saves 2 bytes: opcode of ADC, smaller offset in [BP+DI]

org 0x100 ; assume ah=bx=0 si=0x100

  mov al,0x13

;Start of overlapping code

;cd 10     int 0x10        ; 320x200 video mode
;d1 d2     rcl dx,1
;d8 0f     fmul dword[bx]
;92        xchg ax,dx      ; dl = 0x13
;46        inc si          ; si = 0x101
;bf 8a 02  mov di,0x28a    ; di = a nice offset

  db 0xcd
M:db 0x10,0xd1 ;=adc cl,dl (can also be "12 ca", but we need "10 d1")

            ; cl = 0x99..9f + 0xcd..d0 = 0x66..6f, carry=1
            ; cl = 0x66 + sum of living cells in the neighborhood
;d2 d8
  rcr al,cl ; dead cell {1|00000000}: carry=1 if cl&0x1f = 9
          ; living cell {1|00000001}: carry=1 if cl&0x1f = 9 or 10
;0f 92 46 bf
  setc [bp+0x101-322] ; top left cell = carry: 0=dead, 1=alive
;8a 02
  mov al,[bp+si]      ; al = center cell: 0=dead, 1=alive
;End of overlapping code

  pop cx    ; pop middle column
  push dx   ; push right column for later
  inc bp    ; move one cell to the right: dx is now the middle column
  add cx,dx ; cl = left column + center column

  lss dx,[bx] ; ss~~0x9fff, dx=0x20cd (bx is always 0)
  add dl,[bp+0x101-320] ; right column = top + middle + bottom
  add dl,[bp+si]
  add dl,[bp+0x101+(di-0x28a)+320] ; dl = right column, carry=0
  loop M    ; cx = cx-1, always jump