home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff255.lzh / CyclicSpace / CyclicSpace.asm < prev    next >
Assembly Source File  |  1989-10-19  |  26KB  |  1,371 lines

  1.     OPT    A-,M-,O+,OW-,P+,I+,O3-
  2.  
  3.     INCLUDE    "macros/g_generalmacs.i"
  4.     INCLUDE    "macros/g_libmacs.i"
  5.     INCLUDE    "macros/g_execmacs.i"
  6.     INCLUDE    "macros/g_dosmacs.i"
  7.     INCLUDE    "cyc.ver"
  8.  
  9.     INCEQUS
  10.  
  11.     INCLIB    resource
  12.     INCLIB    string
  13.     INCLIB    compute
  14.  
  15.     XREF    ErrorStr
  16.     XREF    ErrorStrSize
  17.  
  18. DefaultWidth    =    320
  19. DefaultDepth    =    14
  20. MinPushDown    =    82
  21. MaxMinLace    =    300
  22. MaxMaxHeight    =    600
  23. D16Offset    =    (640*MaxMaxHeight/8)/2
  24.  
  25.     INITSYS    CLICON,WBCON,<CON:24/0/410/85/Griffeathian Cyclic Space Generator>
  26.     BRA    CodeStart
  27.  
  28. ; Build the cyclic color table
  29.  
  30. Saturation    =    12            ;  S  =  8,10,12,14 or 16
  31. Brightness    =    -2            ; |B| <= (16-S)/2
  32. ColTabWords    =    (Saturation-1)*6
  33.  
  34. DOEDGE    MACRO
  35.     REPT    Saturation-1
  36.     DC.W    red<<8+grn<<4+blu
  37.  
  38. red    SET    red+redcnt
  39. grn    SET    grn+grncnt
  40. blu    SET    blu+blucnt
  41.     ENDR
  42.     ENDM
  43.  
  44. HOOKIT    MACRO
  45. nwrdcnt    SET    -grncnt
  46. grncnt    SET    -blucnt
  47. blucnt    SET    -redcnt
  48. redcnt    SET    nwrdcnt
  49.     ENDM
  50.  
  51. red    SET    $F-(16-Saturation)/2
  52. grn    SET    $0+(16-Saturation)/2
  53. blu    SET    $0+(16-Saturation)/2
  54.  
  55. redcnt    SET    0
  56. grncnt    SET    1
  57. blucnt    SET    0
  58.  
  59. CycColTab:
  60.     DOEDGE
  61.     HOOKIT
  62.     DOEDGE
  63.     HOOKIT
  64.     DOEDGE
  65.     HOOKIT
  66.     DOEDGE
  67.     HOOKIT
  68.     DOEDGE
  69.     HOOKIT
  70.     DOEDGE
  71.     HOOKIT
  72.  
  73. ; Space for a few internal subs
  74.  
  75. ; InDeci:
  76. ; This sub fetches a decimal number from the console
  77. ; I : none
  78. ; O : D0.L = Number
  79.  
  80. InDeci:
  81.     XBSR    StdReadStr
  82.     XBRA    GetDecVal
  83.  
  84. ; UpLine
  85. ; This sub moves the cursor position to the start of the previous
  86. ; line and clears it.
  87. ; I : none
  88. ; O : none
  89. ; No regs modified
  90.  
  91. UpLine:
  92.     CONTEXT    <$B,$D,$9B,'1K'>
  93.     RTS
  94.  
  95. ; DropScreen:
  96. ; This sub moves the screen down in order to show the console
  97. ; window.
  98. ; I : none
  99. ; O : none
  100.  
  101.     GBYTE    Dropped
  102.  
  103. DropScreen:
  104.     TST.B    Dropped(GP)
  105.     BNE.S    NoNeedToDrop
  106.     MOVE.W    Push(GP),D1
  107.     BEQ.S    NoNeedToDrop
  108.     MOVE.L    ScreenBase(GP),A0
  109.     MOVE.L    #0,D0
  110.     EXT.L    D1
  111.     CALL    intuition,MoveScreen
  112.     ST    Dropped(GP)
  113. NoNeedToDrop:
  114.     RTS
  115.  
  116. ; PopScreen:
  117. ; This sub moves the screen back up,
  118. ; I : none
  119. ; O : none
  120.  
  121. PopScreen:
  122.     MOVE.W    Push(GP),D1
  123.     BEQ.S    NoNeedToPop
  124.     MOVE.L    ScreenBase(GP),A0
  125.     MOVE.L    #0,D0
  126.     EXT.L    D1
  127.     NEG.L    D1
  128.     CALL    intuition,MoveScreen
  129.     SF    Dropped(GP)
  130. NoNeedToPop:
  131.     RTS
  132.  
  133. ;-----------------------------------------
  134. ;To start with, set the return code to 10.
  135. ;-----------------------------------------
  136.  
  137.  
  138. CodeStart:
  139.     MOVEQ    #10,D0
  140.     MOVE.L    D0,ReturnCode(GP)
  141.  
  142. ; Open libraries
  143.  
  144.     OPENRLB    intuition,ResourceErrorExit
  145.     OPENRLB    graphics,ResourceErrorExit
  146.  
  147. ; Interpret the NormalDisplayColumns graphics base value
  148.  
  149.     LIBBASE    graphics,A6
  150.  
  151. *    The width of the screen is fixed to either 320 or 640, the height
  152. *    of the screen may vary within a certain degree in order to accommodate
  153. *    PAL/NTSC differences and perhaps 1.4 preferences overscan settings.
  154. *    The reason for the fixed screen widths is that it being fixed allows
  155. *    for a significant speedup in the display routine.
  156.  
  157.     GWORD    MaxHeight
  158.     GWORD    MaxNoLace
  159.  
  160.     MOVE.W    gb_NormalDisplayRows(A6),D0
  161.     CMP.W    #MaxMinLace,D0
  162.     BHS.S    DoNotDoubleHeight
  163.     LSL.W    #1,D0
  164. DoNotDoubleHeight:
  165.     CMP.W    #MaxMaxHeight,D0
  166.     BLS.S    DoNotLimitHeight
  167.     MOVE.W    #MaxMaxHeight,D0
  168. DoNotLimitHeight:
  169.     MOVE.W    D0,MaxHeight(GP)
  170.     LSR.W    #1,D0
  171.     MOVE.W    D0,MaxNoLace(GP)
  172.  
  173. ; Show version number, last assembly date and startup bla
  174.  
  175. Restart:
  176.     CONTEXT
  177.     DC.B    12,'V'
  178.     VERNUM
  179.     DC.B    ', '
  180.     CDATE
  181.     DC.B    ', Programmed by A.J.Brouwer',10
  182.     DC.B    'Height: 16-',0
  183.     EVEN
  184.     PRDEC.W    MaxHeight(GP)
  185.     CONTEXT    
  186.     DC.B    ', Width: 24-640, it will be',10
  187.     DC.B    'set to the nearest multiple of 8.',10
  188.     DC.B    'Depth : 2-31 , Seed : Any number > 0',10,10,10,0
  189.     EVEN
  190.  
  191. ; Check how user wants settings, if at all.
  192.  
  193. QueryUser:
  194.     BSR    UpLine
  195.     CONTEXT    <'Set [C]ustom, [D]efaults or [Q]uit ?'>
  196.     XBSR    StdReadStr
  197.     MOVE.B    (A0),D0
  198.     AND.B    #$DF,D0
  199.     CMP.B    #'Q',D0    
  200.     BEQ    Exit
  201.     CMP.B    #'C',D0
  202.     BEQ.S    SetCustomSettings
  203.     CMP.B    #'D',D0
  204.     BNE.S    QueryUser
  205.     MOVE.W    #DefaultWidth,Width(GP)
  206.     MOVE.W    MaxNoLace(GP),Height(GP)
  207.     MOVE.W    #DefaultDepth,Depth(GP)
  208.     BRA    AskForSeed
  209.  
  210. ; Ask the user for the width
  211.  
  212. SetCustomSettings:
  213.     GWORD    Width
  214.  
  215. RetryWidthInput:
  216.     BSR    UpLine
  217.     CONTEXT    <'Enter width : '>
  218.     BSR    InDeci
  219.     TST.L    D0
  220.     BEQ    Restart
  221.     ADDQ.L    #4,D0
  222.     AND.B    #$F8,D0
  223.     CMP.L    #640,D0
  224.     BHI    RetryWidthInput
  225.     CMP.W    #24,D0
  226.     BLO    RetryWidthInput
  227.     MOVE.W    D0,Width(GP)
  228.  
  229. ; Ask the user for the height
  230.  
  231.     GWORD    Height
  232.  
  233. RetryHeightInput:
  234.     BSR    UpLine
  235.     CONTEXT    <'Enter height : '>
  236.     BSR    InDeci
  237.     MOVE.W    MaxHeight(GP),D1
  238.     EXT.L    D1
  239.     CMP.L    D1,D0
  240.     BHI    RetryHeightInput
  241.     MOVE.W    D0,Height(GP)
  242.     BEQ    Restart
  243.     CMP.W    #16,D0
  244.     BLO    RetryHeightInput
  245.  
  246. ; Ask the user for the depth
  247.  
  248.     GWORD    Depth
  249.  
  250. RetryDepthInput:
  251.     BSR    UpLine
  252.     CONTEXT    <'Enter depth : '>
  253.     BSR    InDeci
  254.     CMP.L    #31,D0
  255.     BHI    RetryDepthInput
  256.     MOVE.W    D0,Depth(GP)
  257.     BEQ    Restart
  258.     CMP.W    #2,D0
  259.     BLO    RetryDepthInput
  260.     CMP.W    #320,Width(GP)
  261.     BLS.S    DepthOK
  262.     CMP.W    #15,D0
  263.     BLS.S    DepthOK
  264.     CONTEXT    <'Width requires Hires, Hires can display',10>
  265.     CONTEXT    <'upto 16 colours. Choose Depth<16 RETURN'>
  266.     BSR    InDeci
  267.     BSR    UpLine
  268.     BSR    UpLine
  269.     BRA    RetryDepthInput
  270. DepthOK:
  271.  
  272. ; Ask the user to seed the randomizer
  273.  
  274. AskForSeed:
  275.     GLONG    Seed
  276.  
  277.     BSR    UpLine
  278.     CONTEXT    <'Please enter seed value : '>
  279.     BSR    InDeci
  280.     MOVE.L    D0,Seed(GP)
  281.     BEQ    Restart
  282.  
  283. ; Show the settings that will be used
  284.  
  285.     BSR    UpLine
  286.     CONTEXT    <'Width:'>
  287.     PRDEC.W    Width(GP)
  288.     CONTEXT    <' Height:'>
  289.     PRDEC.W    Height(GP)
  290.     CONTEXT    <' Depth:'>
  291.     PRDEC.W    Depth(GP)
  292.     CONTEXT    <' Seed:'>
  293.     PRDEC.L    Seed(GP)
  294.     CONTEXT    <10>
  295.  
  296. ; Initialize the newscreen structure
  297.  
  298. NS    EQUR    A2
  299.  
  300.     GSTRUC    NewScreen,ns_SIZEOF
  301.  
  302.     LEA    NewScreen(GP),NS
  303.     MOVE.L    A2,A0
  304.     MOVEQ    #ns_SIZEOF-1,D0
  305. ClrNewScrStr:
  306.     CLR.B    (A0)+
  307.     DBRA    D0,ClrNewScrStr
  308.     MOVE.W    #CUSTOMSCREEN,ns_Type(NS)
  309.  
  310. ;    Set the position of the top edge of the screen
  311.  
  312.     GWORD    Push
  313.  
  314.     CLR.W    Push(GP)
  315.     CLR.W    ns_TopEdge(NS)
  316.     MOVE.W    Height(GP),D0
  317.     CMP.W    MaxNoLace(GP),D0
  318.     BLS.S    NoInterlace
  319.     SUB.W    MaxHeight(GP),D0
  320.     NEG.W    D0
  321.     MOVE.W    #2*MinPushDown,D1
  322.     CMP.W    D1,D0
  323.     BGT.S    SetScreenTop
  324.     BRA.S    SetPush
  325. NoInterlace:
  326.     SUB.W    MaxNoLace(GP),D0
  327.     NEG.W    D0
  328.     MOVEQ    #MinPushDown,D1
  329.     CMP.W    D1,D0
  330.     BGT.S    SetScreenTop
  331. SetPush:
  332.     MOVE.W    D1,Push(GP)
  333.     MOVEQ    #0,D0
  334. SetScreenTop:
  335.     MOVE.W    D0,ns_TopEdge(NS)
  336.  
  337. ;    Set screen width and resolution
  338.  
  339.     MOVE.W    #320,D0
  340.     CMP.W    Width(GP),D0
  341.     BHS.S    SetScrWidth
  342.     ADD.W    D0,D0
  343.     OR.W    #V_HIRES,ns_ViewModes(NS)
  344. SetScrWidth:
  345.     MOVE.W    D0,ActScrWidth(GP)
  346.     MOVE.W    D0,ns_Width(NS)
  347.  
  348. ;    Set screen height and lace
  349.  
  350.     MOVE.W    Height(GP),D0
  351.     CMP.W    MaxNoLace(GP),D0
  352.     BLS.S    NoNeedForLace
  353.     OR.W    #V_LACE,ns_ViewModes(NS)
  354. NoNeedForLace:
  355.     MOVE.W    D0,ns_Height(NS)
  356.  
  357. ;    Set the number of bitplanes
  358.  
  359.     GWORD    ActScrDepth
  360.  
  361.     MOVE.W    Depth(GP),D0
  362.     MOVEQ    #0,D1
  363. ComputePlaneNum:
  364.     BTST    D1,D0
  365.     BEQ.S    NoBitSoNoSet
  366.     MOVE.W    D1,ns_Depth(NS)
  367.     ADDQ.W    #1,ns_Depth(NS)
  368. NoBitSoNoSet:
  369.     ADDQ.L    #1,D1
  370.     CMP.W    #10,D1
  371.     BNE    ComputePlaneNum
  372.     MOVE.W    ns_Depth(NS),ActScrDepth(GP)
  373.  
  374. ;    Set potential mouse pointer colours
  375.  
  376.     CLR.W    ColourMap+16*2(GP)
  377.     MOVE.W    #$F22,ColourMap+17*2(GP)
  378.     CLR.W    ColourMap+18*2(GP)
  379.     MOVE.W    #$FDB,ColourMap+19*2(GP)
  380.  
  381. ; Compute the actual color table
  382.  
  383.     GSTRUC    ColourMap,32*2
  384.  
  385.     BRA.S    JumpOverTable
  386. WeirdCountTab:
  387.     DC.B         2*%00001,2*%00011,2*%00010
  388.     DC.B    2*%00110,2*%00111,2*%00101,2*%00100
  389.  
  390.     DC.B    2*%01100,2*%01101,2*%01111,2*%01110
  391.     DC.B    2*%01010,2*%01011,2*%01001,2*%01000
  392.  
  393.     DC.B    2*%11000,2*%11001,2*%11011,2*%11010
  394.     DC.B    2*%11110,2*%11111,2*%11101,2*%11100
  395.  
  396.     DC.B    2*%10100,2*%10101,2*%10111,2*%10110
  397.     DC.B    2*%10010,2*%10011,2*%10001,2*%10000
  398.     EVEN
  399. JumpOverTable:
  400.  
  401.     LEA    CycColTab(PC),A0
  402.     LEA    ColourMap(GP),A1
  403.     MOVEQ    #0,D0
  404. SetEachColourWord:
  405.     MOVE.W    D0,D1
  406.     MULU    #2*ColTabWords,D1
  407.     DIVU    Depth(GP),D1
  408.     ADDQ.W    #1,D1
  409.     BCLR    #0,D1
  410.     MOVE.W    0(A0,D1.W),-(SP)
  411.     MOVE.B    WeirdCountTab(PC,D0.W),D1
  412.     MOVE.W    (SP)+,0(A1,D1.W)
  413.     ADDQ.W    #1,D0
  414.     CMP.W    Depth(GP),D0
  415.     BNE    SetEachColourWord
  416.  
  417. ; Execute the actual cyclic space evolution routine.
  418.  
  419.     BSR    EvolveTheCyclicSpace
  420.     BRA    Restart
  421.  
  422. ; The cleanup code
  423.  
  424. Exit:
  425.     CLR.L    ReturnCode(GP)
  426. ResourceErrorExit:
  427.     MOVE.L    ErrorStrSize(GP),D0
  428.     BEQ.S    NoErrorStringSet
  429.     LEA    ErrorStr(A5),A0
  430.     XBSR    StdWrite
  431.     CONTEXT    <', [ENTER]'>
  432.     BSR    InDeci
  433. NoErrorStringSet:
  434.     RTS
  435.  
  436.  
  437.  
  438. ;-------------------------------------------------------
  439. ; Building blocks for the cyclic space evolution routine
  440. ;-------------------------------------------------------
  441.  
  442.     GLONG    Plane1
  443.     GLONG    Plane2
  444.     GLONG    Plane3
  445.     GLONG    Plane4
  446.     GLONG    Plane5
  447.     GWORD    InitialSOLOffset
  448.     GWORD    InitialEOLOffset
  449.     GLONG    CntrBufWrap
  450.     GLONG    BitBufWrap
  451.     GWORD    MiddleLines
  452.  
  453.  
  454. INITVARS MACRO
  455.  
  456. ; Initialize the plane pointers used for the full pixel redraw
  457.  
  458.     MOVE.L    ScreenBase(GP),A0
  459.     LEA    sc_BitMap+bm_Planes(A0),A0
  460.     CLR.L    Plane3(GP)
  461.     CLR.L    Plane4(GP)
  462.     CLR.L    Plane5(GP)
  463.     MOVE.L    #D16Offset,D0
  464.  
  465.     MOVE.L    (A0)+,Plane1(GP)
  466.     ADD.L    D0,Plane1(GP)
  467.  
  468.     MOVE.L    (A0)+,Plane2(GP)
  469.     ADD.L    D0,Plane2(GP)
  470.  
  471.     CMP.W    #4,Depth(GP)
  472.     BLO.S    .PlanesSet
  473.     MOVE.L    (A0)+,Plane3(GP)
  474.     ADD.L    D0,Plane3(GP)
  475.  
  476.     CMP.W    #8,Depth(GP)
  477.     BLO.S    .PlanesSet
  478.     MOVE.L    (A0)+,Plane4(GP)
  479.     ADD.L    D0,Plane4(GP)
  480.  
  481.     CMP.W    #16,Depth(GP)
  482.     BLO.S    .PlanesSet
  483.     MOVE.L    (A0),Plane5(GP)
  484.     ADD.L    D0,Plane5(GP)
  485. .PlanesSet:
  486.  
  487. ; Set the initial start- and end-of-line offsets
  488.  
  489.     MOVE.W    ActScrWidth(GP),D0
  490.     SUB.W    Width(GP),D0
  491.     LSR.W    #4,D0
  492.     MOVE.W    Width(GP),D1
  493.     LSR.W    #3,D1
  494.     ADD.W    D0,D1
  495.     SUB.W    #D16Offset,D0
  496.     SUB.W    #D16Offset+1,D1
  497.     MOVE.W    D0,InitialSOLOffset(GP)
  498.     MOVE.W    D1,InitialEOLOffset(GP)
  499.  
  500. ; Set the counter and bit buffer wrap offsets
  501.  
  502.     MOVE.W    Height(GP),D0
  503.     SUBQ.W    #1,D0
  504.     MULU    Width(GP),D0
  505.     MOVE.L    D0,CntrBufWrap(GP)
  506.  
  507.     MOVE.W    Height(GP),D0
  508.     SUBQ.W    #1,D0
  509.     MULU    ActScrWidth(GP),D0
  510.     LSR.L    #3,D0
  511.     MOVE.L    D0,BitBufWrap(GP)
  512.  
  513. ; And some more
  514.  
  515.     MOVE.W    Height(GP),D0
  516.     SUBQ.W    #2,D0
  517.     MOVE.W    D0,MiddleLines(GP)
  518.  
  519.     ENDM
  520.  
  521.  
  522. ; INITPIX: This macro intializes all used screen pixels.
  523.  
  524. P1    EQUR    A1
  525. P2    EQUR    A2
  526. P3    EQUR    A3
  527. P4    EQUR    A4
  528. P5    EQUR    A6
  529.  
  530. CNTRFETCH    EQUR    A0
  531. LINECOUNTER    EQUR    D0
  532. SOLWORDOFF    EQUR    D1
  533. EOLWORDOFF    EQUR    D2
  534. WORDOFF        EQUR    D3
  535. BITDOWNCOUNT    EQUR    D4
  536. SHIFTBYTE    EQUR    D5
  537. PLTEST        EQUR    D6
  538. WIDTHINBYTES    EQUR    D7
  539.  
  540. InitPixRegs    REG    A0-A4/A6/D0-D7
  541.  
  542. INITPIX    MACRO
  543.     BRA.S    .SetAllPlanes
  544. .PlaneBits
  545.     DC.B    00001,%00011,%00010
  546.     DC.B    %00110,%00111,%00101,%00100
  547.  
  548.     DC.B    %01100,%01101,%01111,%01110
  549.     DC.B    %01010,%01011,%01001,%01000
  550.  
  551.     DC.B    %11000,%11001,%11011,%11010
  552.     DC.B    %11110,%11111,%11101,%11100
  553.  
  554.     DC.B    %10100,%10101,%10111,%10110
  555.     DC.B    %10010,%10011,%10001,%10000
  556.     EVEN
  557.  
  558. .SetAllPlanes:
  559.     PUSH    InitPixRegs
  560.     MOVE.L    CntrBufBase(GP),CNTRFETCH
  561.     MOVE.W    Height(GP),LINECOUNTER
  562.     MOVE.W    InitialSOLOffset(GP),SOLWORDOFF
  563.     MOVE.W    InitialEOLOffset(GP),EOLWORDOFF
  564.     MOVEQ    #0,SHIFTBYTE
  565.     MOVE.L    Plane1(GP),P1
  566.     MOVE.L    Plane2(GP),P2
  567.     MOVE.L    Plane3(GP),P3
  568.     MOVE.L    Plane4(GP),P4
  569.     MOVE.L    Plane5(GP),P5
  570. .DoNextLine:
  571.     MOVE.W    SOLWORDOFF,WORDOFF
  572. .DoForEachEight:
  573.     MOVEQ    #7,BITDOWNCOUNT
  574. .DoForEachByte:
  575.     MOVE.B    (CNTRFETCH)+,SHIFTBYTE
  576.     SUBQ.B    #4,SHIFTBYTE
  577.     LSR.B    #2,SHIFTBYTE
  578.     MOVE.B    .PlaneBits(PC,SHIFTBYTE.W),SHIFTBYTE
  579.  
  580.     LSR.B    #1,SHIFTBYTE
  581.     BCS.S    .SetPlane1
  582.     BCLR    BITDOWNCOUNT,0(P1,WORDOFF.W)
  583.     BRA.S    .Plane1Done
  584. .SetPlane1:
  585.     BSET    BITDOWNCOUNT,0(P1,WORDOFF.W)
  586. .Plane1Done:
  587.  
  588.     LSR.B    #1,SHIFTBYTE
  589.     BCS.S    .SetPlane2
  590.     BCLR    BITDOWNCOUNT,0(P2,WORDOFF.W)
  591.     BRA.S    .Plane2Done
  592. .SetPlane2:
  593.     BSET    BITDOWNCOUNT,0(P2,WORDOFF.W)
  594. .Plane2Done:
  595.  
  596.     MOVE.L    P3,PLTEST
  597.     BEQ.S    .PlanesDone
  598.     LSR.B    #1,SHIFTBYTE
  599.     BCS.S    .SetPlane3
  600.     BCLR    BITDOWNCOUNT,0(P3,WORDOFF.W)
  601.     BRA.S    .Plane3Done
  602. .SetPlane3:
  603.     BSET    BITDOWNCOUNT,0(P3,WORDOFF.W)
  604. .Plane3Done:
  605.  
  606.     MOVE.L    P4,PLTEST
  607.     BEQ.S    .PlanesDone
  608.     LSR.B    #1,SHIFTBYTE
  609.     BCS.S    .SetPlane4
  610.     BCLR    BITDOWNCOUNT,0(P4,WORDOFF.W)
  611.     BRA.S    .Plane4Done
  612. .SetPlane4:
  613.     BSET    BITDOWNCOUNT,0(P4,WORDOFF.W)
  614. .Plane4Done:
  615.  
  616.     MOVE.L    P5,PLTEST
  617.     BEQ.S    .PlanesDone
  618.     LSR.B    #1,SHIFTBYTE
  619.     BCS.S    .SetPlane5
  620.     BCLR    BITDOWNCOUNT,0(P5,WORDOFF.W)
  621.     BRA.S    .Plane5Done
  622. .SetPlane5:
  623.     BSET    BITDOWNCOUNT,0(P5,WORDOFF.W)
  624. .Plane5Done:
  625.  
  626. .PlanesDone
  627.     SUBQ.W    #1,BITDOWNCOUNT
  628.     BPL    .DoForEachByte
  629.     ADDQ.W    #1,WORDOFF
  630.     CMP.W    EOLWORDOFF,WORDOFF
  631.     BLE    .DoForEachEight
  632.     MOVE.W    ActScrWidth(GP),WIDTHINBYTES
  633.     LSR.W    #3,WIDTHINBYTES
  634.     ADD.W    WIDTHINBYTES,SOLWORDOFF
  635.     ADD.W    WIDTHINBYTES,EOLWORDOFF
  636.     SUBQ.W    #1,LINECOUNTER
  637.     BNE    .DoNextLine
  638.  
  639.     PULL    InitPixRegs
  640.     ENDM
  641.  
  642.  
  643. ; These are the register assignments used in the computation loop
  644.  
  645. ; Constant address registers
  646.  
  647. BOOLBAS1    EQUR    A0
  648. BOOLBAS2    EQUR    A1
  649. TABLES        EQUR    A2
  650.  
  651. ; Variable address registers
  652.  
  653. PLANEPTR    EQUR    A3
  654. CNTRPTR        EQUR    A4
  655. SOLOFFSET    EQUR    A6
  656.  
  657. ; Constant data registers
  658.  
  659. MINWIDTH    EQUR    D0
  660. PLSWIDTH    EQUR    D1
  661.  
  662. ; Variable data registers
  663.  
  664. BITCNTR        EQUR    D2
  665. OFFSET        EQUR    D3
  666. EOLOFFSET    EQUR    D4
  667. CURRCNTR    EQUR    D5    <= locked (> D1)
  668. PLUS2CNTR    EQUR    D6
  669. LINEDOWNCOUNT    EQUR    D7
  670.  
  671. INITREGS MACRO
  672.     MOVE.L    IncBoolBitBuf1(GP),BOOLBAS1
  673.     LEA    D16Offset(BOOLBAS1),BOOLBAS1
  674.     MOVE.L    IncBoolBitBuf2(GP),BOOLBAS2
  675.     LEA    D16Offset(BOOLBAS2),BOOLBAS2
  676.     LEA    TableStruc+2*4(GP),TABLES
  677.     MOVE.W    Width(GP),MINWIDTH
  678.     MOVE.W    MINWIDTH,PLSWIDTH
  679.     NEG.W    MINWIDTH
  680.     MOVEQ    #0,BITCNTR
  681.     MOVEQ    #0,OFFSET
  682.     MOVEQ    #0,EOLOFFSET
  683.     MOVEQ    #0,CURRCNTR
  684.     MOVEQ    #0,PLUS2CNTR
  685.     MOVEQ    #0,LINEDOWNCOUNT
  686.     ENDM
  687.  
  688.  
  689. ; Combine the three initialization macros
  690.  
  691. INITALL    MACRO
  692.     INITVARS
  693.     INITPIX
  694.     INITREGS
  695.     ENDM
  696.  
  697.  
  698. ; This macro increments a counter and adapts a pixel's colour
  699.  
  700. INCIT    MACRO
  701.     MOVE.B    (CNTRPTR),CURRCNTR
  702.     MOVE.B    d8_CounterValues+2*4(TABLES,CURRCNTR.W),PLUS2CNTR
  703.     BNE.S    NoColourOverflow\@
  704.     MOVE.L    Plane1(GP),PLANEPTR
  705.     BSET    BITCNTR,0(PLANEPTR,OFFSET.W)
  706.     MOVE.L    Plane2(GP),PLANEPTR
  707.     BCLR    BITCNTR,0(PLANEPTR,OFFSET.W)
  708.     MOVE.L    Plane3(GP),PLUS2CNTR
  709.     BEQ.S    PlanesDone\@
  710.     MOVE.L    PLUS2CNTR,PLANEPTR
  711.     BCLR    BITCNTR,0(PLANEPTR,OFFSET.W)
  712.     MOVE.L    Plane4(GP),PLUS2CNTR
  713.     BEQ.S    PlanesDone\@
  714.     MOVE.L    PLUS2CNTR,PLANEPTR
  715.     BCLR    BITCNTR,0(PLANEPTR,OFFSET.W)
  716.     MOVE.L    Plane5(GP),PLUS2CNTR
  717.     BEQ.S    PlanesDone\@
  718.     MOVE.L    PLUS2CNTR,PLANEPTR
  719.     BCLR    BITCNTR,0(PLANEPTR,OFFSET.W)
  720. PlanesDone\@:
  721.     MOVEQ    #8,PLUS2CNTR
  722.     MOVE.B    #4,(CNTRPTR)
  723.     BRA.S    PixelSet\@
  724. NoColourOverflow\@:
  725.     MOVE.L    d8_PlaneBasePtrs(TABLES,CURRCNTR.W),PLANEPTR
  726.     BCHG    BITCNTR,0(PLANEPTR,OFFSET.W)
  727.     ADDQ.B    #4,(CNTRPTR)
  728. PixelSet\@:
  729.     ENDM
  730.  
  731.  
  732. ; These CHK.. macros check with neighbours and set the boolbuffer accordingly.
  733.  
  734. CHKLEFTWRAP    MACRO
  735.     BTST    #0,0(BOOLBAS1,EOLOFFSET.W)
  736.     BNE.S    NeigMarked\@
  737.     CMP.B    -1(CNTRPTR,PLSWIDTH.W),PLUS2CNTR
  738.     BNE.S    NoNewInc\@
  739.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  740. NoNewInc\@:
  741.     CMP.B    -1(CNTRPTR,PLSWIDTH.W),CURRCNTR
  742.     BNE.S    NoNeigInc\@
  743.     BSET    #0,0(BOOLBAS2,EOLOFFSET.W)
  744. NoNeigInc\@:
  745. NeigMarked\@:
  746.     ENDM
  747.  
  748. CHKLEFTOVER    MACRO
  749.     CMP.B    -1(CNTRPTR),PLUS2CNTR
  750.     BNE.S    NoNewInc\@
  751.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  752. NoNewInc\@:
  753.     CMP.B    -1(CNTRPTR),CURRCNTR
  754.     BNE.S    NoNeigInc\@
  755.     BSET    #0,-1(BOOLBAS2,OFFSET.W)
  756. NoNeigInc\@:
  757.     ENDM
  758.  
  759. CHKLEFTNEIG    MACRO
  760.     CMP.B    -1(CNTRPTR),PLUS2CNTR
  761.     BNE.S    NoNewInc\@
  762.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  763. NoNewInc\@:
  764.     CMP.B    -1(CNTRPTR),CURRCNTR
  765.     BNE.S    NoNeigInc\@
  766.     ADDQ.B    #1,BITCNTR
  767.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  768.     SUBQ.B    #1,BITCNTR
  769. NoNeigInc\@:
  770.     ENDM
  771.  
  772. CHKTOPWRAP    MACRO
  773.     ADD.L    BitBufWrap(GP),BOOLBAS1
  774.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  775.     BNE.S    NeigMarked\@
  776.     ADD.L    CntrBufWrap(GP),CNTRPTR
  777.     CMP.B    (CNTRPTR),PLUS2CNTR
  778.     BNE.S    NoNewInc\@
  779.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  780. NoNewInc\@:
  781.     CMP.B    (CNTRPTR),CURRCNTR
  782.     BNE.S    NoNeigInc\@
  783.     ADD.L    BitBufWrap(GP),BOOLBAS2
  784.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  785.     SUB.L    BitBufWrap(GP),BOOLBAS2
  786. NoNeigInc\@:
  787.     SUB.L    CntrBufWrap(GP),CNTRPTR
  788. NeigMarked\@:
  789.     SUB.L    BitBufWrap(GP),BOOLBAS1
  790.     ENDM
  791.  
  792. CHKTOPNEIG    MACRO
  793.     CMP.B    0(CNTRPTR,MINWIDTH.W),PLUS2CNTR
  794.     BNE.S    NoNewInc\@
  795.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  796. NoNewInc\@:
  797.     CMP.B    0(CNTRPTR,MINWIDTH.W),CURRCNTR
  798.     BNE.S    NoNeigInc\@
  799.     BSET    BITCNTR,-\1/8(BOOLBAS2,OFFSET.W)
  800. NoNeigInc\@:
  801.     ENDM
  802.  
  803. CHKRIGHTWRAP    MACRO
  804.     CMP.B    1(CNTRPTR,MINWIDTH.W),PLUS2CNTR
  805.     BNE.S    NoNewInc\@
  806.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  807. NoNewInc\@:
  808.     CMP.B    1(CNTRPTR,MINWIDTH.W),CURRCNTR
  809.     BNE.S    NoNeigInc\@
  810.     BSET    #7,0(BOOLBAS2,SOLOFFSET.W)
  811. NoNeigInc\@:
  812.     ENDM
  813.  
  814. CHKRIGHTOVER    MACRO
  815.     TST.B    1(BOOLBAS1,OFFSET.W)
  816.     BMI.S    NeigMarked\@
  817.     CMP.B    1(CNTRPTR),PLUS2CNTR
  818.     BNE.S    NoNewInc\@
  819.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  820. NoNewInc\@:
  821.     CMP.B    1(CNTRPTR),CURRCNTR
  822.     BNE.S    NoNeigInc\@
  823.     BSET    #7,1(BOOLBAS2,OFFSET.W)
  824. NoNeigInc\@:
  825. NeigMarked\@:
  826.     ENDM
  827.  
  828. CHKRIGHTNEIG    MACRO
  829.     SUBQ.B    #1,BITCNTR
  830.     BTST.B    BITCNTR,0(BOOLBAS1,OFFSET.W)
  831.     BNE.S    NeigMarked\@
  832.     CMP.B    1(CNTRPTR),CURRCNTR
  833.     BNE.S    NoNeigInc\@
  834.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  835. NoNeigInc\@:
  836.     CMP.B    1(CNTRPTR),PLUS2CNTR
  837.     BNE.S    NoNewInc\@
  838.     ADDQ.B    #1,BITCNTR
  839.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  840.     BRA.S    MacDone\@
  841. NoNewInc\@:
  842. NeigMarked\@:
  843.     ADDQ.B    #1,BITCNTR
  844. MacDone\@:
  845.     ENDM
  846.  
  847. CHKBOTTOMWRAP    MACRO
  848.     SUB.L    CntrBufWrap(GP),CNTRPTR
  849.     CMP.B    (CNTRPTR),PLUS2CNTR
  850.     BNE.S    NoNewInc\@
  851.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  852. NoNewInc\@:
  853.     CMP.B    (CNTRPTR),CURRCNTR
  854.     BNE.S    NoNeigInc\@
  855.     SUB.L    BitBufWrap(GP),BOOLBAS2
  856.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  857.     ADD.L    BitBufWrap(GP),BOOLBAS2
  858. NoNeigInc\@:
  859.     ADD.L    CntrBufWrap(GP),CNTRPTR
  860.     ENDM
  861.  
  862. CHKBOTTOMNEIG    MACRO
  863.     BTST    BITCNTR,\1/8(BOOLBAS1,OFFSET.W)
  864.     BNE.S    NeigMarked\@
  865.     CMP.B    0(CNTRPTR,PLSWIDTH.W),PLUS2CNTR
  866.     BNE.S    NoNewInc\@
  867.     BSET    BITCNTR,0(BOOLBAS2,OFFSET.W)
  868. NoNewInc\@:
  869.     CMP.B    0(CNTRPTR,PLSWIDTH.W),CURRCNTR
  870.     BNE.S    NoNeigInc\@
  871.     BSET    BITCNTR,\1/8(BOOLBAS2,OFFSET.W)
  872. NoNeigInc\@:
  873. NeigMarked\@:
  874.     ENDM
  875.  
  876.  
  877. ; These 3 macros are for the leftmost, middle and rightmost pixel-bytes
  878.  
  879.  
  880. DOLEFT    MACRO
  881.  
  882.     MOVE.W    SOLOFFSET,OFFSET
  883.     TST.B    0(BOOLBAS1,OFFSET.W)
  884.     BEQ    NoIncPixels\@
  885.  
  886.     BPL    NotLeftPixel\@
  887.     MOVEQ    #7,BITCNTR
  888.     INCIT
  889.     CHKLEFTWRAP    \1
  890.     CHKTOP\2    \1
  891.     CHKRIGHTNEIG    \1
  892.     CHKBOTTOM\3    \1
  893. NotLeftPixel\@:
  894.  
  895.     MOVEQ    #6,BITCNTR
  896. CheckNextMidPixel\@:
  897.     ADDQ.L    #1,CNTRPTR
  898.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  899.     BEQ    NotThisMidPixel\@
  900.     INCIT
  901.     CHKLEFTNEIG    \1
  902.     CHKTOP\2    \1
  903.     CHKRIGHTNEIG    \1
  904.     CHKBOTTOM\3    \1
  905. NotThisMidPixel\@:
  906.     SUBQ.B    #1,BITCNTR
  907.     BNE    CheckNextMidPixel\@
  908.  
  909.     ADDQ.L    #1,CNTRPTR
  910.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  911.     BEQ    NotThisRightPixel\@
  912.     INCIT
  913.     CHKLEFTNEIG    \1
  914.     CHKTOP\2    \1
  915.     CHKRIGHTOVER    \1
  916.     CHKBOTTOM\3    \1
  917. NotThisRightPixel\@:
  918.     CLR.B    0(BOOLBAS1,OFFSET.W)
  919.     SUBQ.L    #7,CNTRPTR
  920.  
  921. NoIncPixels\@:
  922.     ADDQ.L    #8,CNTRPTR
  923.     ADDQ.W    #1,OFFSET
  924.  
  925.     ENDM
  926.  
  927.  
  928. DOMIDDLE MACRO
  929.  
  930. DoNextEight\@:
  931.     TST.B    0(BOOLBAS1,OFFSET.W)
  932.     BEQ    NoIncPixels\@
  933.  
  934.     BPL    NotLeftPixel\@
  935.     MOVEQ    #7,BITCNTR
  936.     INCIT
  937.     CHKLEFTOVER    \1
  938.     CHKTOP\2    \1
  939.     CHKRIGHTNEIG    \1
  940.     CHKBOTTOM\3    \1
  941. NotLeftPixel\@:
  942.  
  943.     MOVEQ    #6,BITCNTR
  944. CheckNextMidPixel\@:
  945.     ADDQ.L    #1,CNTRPTR
  946.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  947.     BEQ    NotThisMidPixel\@
  948.     INCIT
  949.     CHKLEFTNEIG    \1
  950.     CHKTOP\2    \1
  951.     CHKRIGHTNEIG    \1
  952.     CHKBOTTOM\3    \1
  953. NotThisMidPixel\@:
  954.     SUBQ.B    #1,BITCNTR
  955.     BNE    CheckNextMidPixel\@
  956.  
  957.     ADDQ.L    #1,CNTRPTR
  958.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  959.     BEQ    NotThisRightPixel\@
  960.     INCIT
  961.     CHKLEFTNEIG    \1
  962.     CHKTOP\2    \1
  963.     CHKRIGHTOVER    \1
  964.     CHKBOTTOM\3    \1
  965. NotThisRightPixel\@:
  966.     CLR.B    0(BOOLBAS1,OFFSET.W)
  967.     SUBQ.L    #7,CNTRPTR
  968.  
  969. NoIncPixels\@:
  970.     ADDQ.L    #8,CNTRPTR
  971.     ADDQ.W    #1,OFFSET
  972.     CMP.W    EOLOFFSET,OFFSET
  973.     BNE    DoNextEight\@
  974.  
  975.     ENDM
  976.  
  977.  
  978. DORIGHT    MACRO
  979.  
  980.     TST.B    0(BOOLBAS1,OFFSET.W)
  981.     BEQ    NoIncPixels\@
  982.  
  983.     BPL    NotLeftPixel\@
  984.     MOVEQ    #7,BITCNTR
  985.     INCIT
  986.     CHKLEFTOVER    \1
  987.     CHKTOP\2    \1
  988.     CHKRIGHTNEIG    \1
  989.     CHKBOTTOM\3    \1
  990. NotLeftPixel\@:
  991.  
  992.     MOVEQ    #6,BITCNTR
  993. CheckNextMidPixel\@:
  994.     ADDQ.L    #1,CNTRPTR
  995.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  996.     BEQ    NotThisMidPixel\@
  997.     INCIT
  998.     CHKLEFTNEIG    \1
  999.     CHKTOP\2    \1
  1000.     CHKRIGHTNEIG    \1
  1001.     CHKBOTTOM\3    \1
  1002. NotThisMidPixel\@:
  1003.     SUBQ.B    #1,BITCNTR
  1004.     BNE    CheckNextMidPixel\@
  1005.  
  1006.     ADDQ.L    #1,CNTRPTR
  1007.     BTST    BITCNTR,0(BOOLBAS1,OFFSET.W)
  1008.     BEQ    NotThisRightPixel\@
  1009.     INCIT
  1010.     CHKLEFTNEIG    \1
  1011.     CHKTOP\2    \1
  1012.     CHKRIGHTWRAP    \1
  1013.     CHKBOTTOM\3    \1
  1014. NotThisRightPixel\@:
  1015.     CLR.B    0(BOOLBAS1,OFFSET.W)
  1016.     SUBQ.L    #7,CNTRPTR
  1017.  
  1018. NoIncPixels\@:
  1019.     ADDQ.L    #8,CNTRPTR
  1020.     ADD.W    #\1/8,SOLOFFSET
  1021.     ADD.W    #\1/8,EOLOFFSET
  1022.  
  1023.     ENDM
  1024.  
  1025.  
  1026. ; These three macros are for the top, middle and bottom lines
  1027.  
  1028.  
  1029. DOTOP    MACRO
  1030.     DOLEFT     \1,WRAP,NEIG
  1031.     DOMIDDLE \1,WRAP,NEIG
  1032.     DORIGHT     \1,WRAP,NEIG
  1033.     ENDM
  1034.  
  1035. DOMID    MACRO
  1036.     DOLEFT     \1,NEIG,NEIG
  1037.     DOMIDDLE \1,NEIG,NEIG
  1038.     DORIGHT     \1,NEIG,NEIG
  1039.     ENDM
  1040.  
  1041. DOBOT    MACRO
  1042.     DOLEFT     \1,NEIG,WRAP
  1043.     DOMIDDLE \1,NEIG,WRAP
  1044.     DORIGHT     \1,NEIG,WRAP
  1045.     ENDM
  1046.  
  1047.  
  1048. ; This is the big one (\1 must be the acual screen width)
  1049.  
  1050.  
  1051. COMPUTE    MACRO
  1052.     ADDQ.L    #1,CycleCounter(GP)
  1053.     MOVE.W    InitialSOLOffset(GP),SOLOFFSET
  1054.     MOVE.W    InitialEOLOffset(GP),EOLOFFSET
  1055.     MOVE.L    CntrBufBase(GP),CNTRPTR
  1056.  
  1057.     DOTOP    \1
  1058.  
  1059.     MOVE.W    MiddleLines(GP),LINEDOWNCOUNT
  1060. DoNextMiddleLine\@:
  1061.     DOMID    \1
  1062.     SUBQ.W    #1,LINEDOWNCOUNT
  1063.     BNE    DoNextMiddleLine\@
  1064.  
  1065.     DOBOT    \1
  1066.  
  1067.     EXG.L    BOOLBAS1,BOOLBAS2
  1068.     ENDM
  1069.  
  1070.  
  1071.  
  1072. ;------------------------
  1073. ; The display sub-program
  1074. ;------------------------
  1075.  
  1076.  
  1077. EvolveTheCyclicSpace:
  1078.     XBSR    RunSubProgram
  1079.  
  1080. ; Show the user how to abort sometime before the screen opens
  1081.  
  1082.     CLRBREAK
  1083.     CONTEXT    <'Press CTRL-C to abort.',10>
  1084.     CONTEXT    <'Initializing'>
  1085.  
  1086. ; Allocate the buffer for the counters
  1087.  
  1088.     GLONG    CntrBufBase
  1089.  
  1090.     MOVE.W    Height(GP),D0
  1091.     MULU    Width(GP),D0
  1092.     MOVEQ    #0,D1
  1093.     XBSR    AllocateMemory
  1094.     BEQ    CleanupSubProg
  1095.     MOVE.L    A0,CntrBufBase(GP)
  1096.  
  1097. ; Allocate the first increment boolean bit buffer and set all to TRUE
  1098.  
  1099.     GLONG    IncBoolBitBuf1
  1100.     GLONG    IncBoolBitBufSize
  1101.  
  1102.     CONTEXT    <'.'>
  1103.     MOVE.W    Height(GP),D0
  1104.     MULU    ActScrWidth(GP),D0
  1105.     LSR.L    #3,D0
  1106.     MOVE.L    D0,IncBoolBitBufSize(GP)
  1107.     MOVEQ    #0,D1
  1108.     XBSR    AllocateMemory
  1109.     BEQ    CleanupSubProg
  1110.     MOVE.L    A0,IncBoolBitBuf1(GP)
  1111. SetBoolBitsTrue:
  1112.     ST    (A0)+
  1113.     SUBQ.L    #1,D0
  1114.     BNE    SetBoolBitsTrue
  1115.  
  1116. ; Allocate the second increment boolean bit buffer with all set FALSE
  1117.  
  1118.     GLONG    IncBoolBitBuf2
  1119.  
  1120.     CONTEXT    <'.'>
  1121.     MOVE.L    IncBoolBitBufSize(GP),D0
  1122.     MOVE.L    #MEMF_CLEAR,D1
  1123.     XBSR    AllocateMemory
  1124.     BEQ    CleanupSubProg
  1125.     MOVE.L    A0,IncBoolBitBuf2(GP)
  1126.  
  1127. ; Initialize the cyclic counter buffer with random values.
  1128.  
  1129. AMOUNTCOUNT    EQUR    D2
  1130. CNTRVAL1    EQUR    D3
  1131. CNTRVAL2    EQUR    D4
  1132. CNTRBUFPTR    EQUR    A2
  1133.  
  1134.     CONTEXT    <'.'>
  1135.     MOVE.W    Width(GP),AMOUNTCOUNT
  1136.     MULU    Height(GP),AMOUNTCOUNT
  1137.     MOVE.L    CntrBufBase(GP),CNTRBUFPTR
  1138.     MOVE.L    Seed(GP),D0
  1139.     XBSR    SeedLongRnd
  1140. ComputeNextRandomCounter:
  1141.     XBSR    LongRnd
  1142.     MOVEQ    #0,CNTRVAL1
  1143.     MOVEQ    #0,CNTRVAL2
  1144.     SWAP    D0
  1145.     MOVE.W    D0,CNTRVAL1
  1146.     SWAP    D0
  1147.     MOVE.W    D0,CNTRVAL2
  1148.     DIVU    Depth(GP),CNTRVAL1
  1149.     DIVU    Depth(GP),CNTRVAL2
  1150.     SWAP    CNTRVAL1
  1151.     SWAP    CNTRVAL2
  1152.     LSL.B    #2,CNTRVAL1
  1153.     LSL.B    #2,CNTRVAL2
  1154.     ADDQ.B    #4,CNTRVAL1
  1155.     ADDQ.B    #4,CNTRVAL2
  1156.     MOVE.B    CNTRVAL1,(CNTRBUFPTR)+
  1157.     MOVE.B    CNTRVAL2,(CNTRBUFPTR)+
  1158.     SUBQ.L    #2,AMOUNTCOUNT
  1159.     BNE    ComputeNextRandomCounter
  1160.  
  1161. ; Open the screen
  1162.  
  1163.     GLONG    ScreenBase
  1164.     GWORD    ActScrWidth
  1165.  
  1166.     LEA    NewScreen(GP),A0
  1167.     CALL    intuition,OpenScreen
  1168.     MOVE.L    D0,ScreenBase(GP)
  1169.     BNE.S    ScreenOpenedOK
  1170.     XBSTR    SetErrorConStr,<'Could not open screen.'>
  1171.     BRA    CleanupSubProg
  1172. ScreenOpenedOK:
  1173.     MOVE.L    D0,A0
  1174.     MOVE.W    ActScrDepth(GP),D1    
  1175.     MOVEQ    #0,D0
  1176.     BSET    D1,D0
  1177.     LEA    sc_ViewPort(A0),A0
  1178.     LEA    ColourMap(GP),A1
  1179.     CALL    graphics,LoadRGB4
  1180.  
  1181. ; These tables are all ind.-indexed with as base the "TABLES" address register.
  1182.  
  1183. d8_PlaneBasePtrs    =    -2*4
  1184. d8_CounterValues    =    -2*4+(1+31-1)*4
  1185.  
  1186.     GSTRUC    TableStruc,(1+31-1)*4+(1+31+2)*4
  1187.  
  1188. ; Initialize the counter value table
  1189.  
  1190.     LEA    TableStruc+2*4(GP),A0
  1191.     MOVEQ    #0,D0
  1192. SetNextTabCntByte:
  1193.     ADDQ.W    #1,D0
  1194.     LSL.W    #2,D0
  1195.     MOVE.B    D0,d8_CounterValues(A0,D0.W)
  1196.     LSR.W    #2,D0
  1197.     CMP.W    Depth(GP),D0
  1198.     BNE    SetNextTabCntByte
  1199.     LSL.W    #2,D0
  1200.     MOVE.B    #4,d8_CounterValues+4(A0,D0.W)
  1201.     CLR.B    d8_CounterValues+2*4(A0,D0.W)
  1202.  
  1203. ; Initialize the bitplane pointer table
  1204.  
  1205.     BRA.S    SkipBitChangeTable
  1206. BitChangeTable:
  1207.     DC.B    4*0,4*1,4*0,4*2,4*0,4*1,4*0,4*3
  1208.     DC.B    4*0,4*1,4*0,4*2,4*0,4*1,4*0,4*4
  1209.     DC.B    4*0,4*1,4*0,4*2,4*0,4*1,4*0,4*3
  1210.     DC.B    4*0,4*1,4*0,4*2,4*0,4*1,4*0,4*5
  1211.     EVEN
  1212. SkipBitChangeTable:
  1213.     LEA    TableStruc+2*4+d8_PlaneBasePtrs(GP),A0
  1214.     MOVE.L    ScreenBase(GP),A1
  1215.     LEA    sc_BitMap+bm_Planes(A1),A1
  1216.     MOVEQ    #0,D0
  1217.     MOVEQ    #0,D1
  1218. InitNextPlanePtr:
  1219.     MOVE.B    BitChangeTable(PC,D0.W),D1
  1220.     MOVE.L    0(A1,D1.W),(A0)
  1221.     ADD.L    #D16Offset,(A0)+
  1222.     ADDQ.W    #1,D0
  1223.     CMP.W    Depth(GP),D0
  1224.     BNE    InitNextPlanePtr
  1225.  
  1226. ; Reset cycle counter, clear "init.." line and reset dropped boolean
  1227.  
  1228.     GLONG    CycleCounter
  1229.  
  1230.     CLR.L    CycleCounter(GP)
  1231.     CONTEXT    <$D,$9B,'1K'>
  1232.     SF    Dropped(GP)
  1233.  
  1234. ; Start the cellular automat (scrambles all regs except A5 & A7)
  1235.  
  1236. BreakRegs    REG    D0/A0/D1/A1/A6
  1237.  
  1238.     INITALL
  1239. DoComputation:
  1240.     CMP.W    #640,ActScrWidth(GP)
  1241.     BEQ    DoWideVersion
  1242. DoNarrowVersion:
  1243.     MOVEQ    #0,CURRCNTR
  1244.     COMPUTE    320
  1245.     IFBREAK    UserBreak
  1246.     TST.B    CURRCNTR
  1247.     BEQ    StationaryState
  1248.     BRA    DoNarrowVersion
  1249. DoWideVersion:
  1250.     MOVEQ    #0,CURRCNTR
  1251.     COMPUTE    640
  1252.     IFBREAK    UserBreak
  1253.     TST.B    CURRCNTR
  1254.     BEQ    StationaryState
  1255.     BRA    DoWideVersion
  1256.  
  1257. ; User hit ^-C. Save scratch regs used by display routine.
  1258.  
  1259. UserBreak:
  1260.     PUSH    BreakRegs
  1261.  
  1262. ; Display cycle number and check if quit was due to stationary state
  1263.  
  1264. StationaryState:
  1265.     BSR    DropScreen
  1266.     BSR    UpLine
  1267.     CONTEXT    <'Number of computation cycles: '>
  1268.     PRDEC.L    CycleCounter(GP)
  1269.     CONTEXT    <10>
  1270.     TST.B    CURRCNTR
  1271.     BNE.S    ThisBeRealBreak
  1272.     CONTEXT    <'Automata reached stationary state. [ENTER]'>
  1273.     BSR    InDeci
  1274.     BRA    CleanupSubProg
  1275.  
  1276. ; So, what next sucker?
  1277.  
  1278. ThisBeRealBreak:
  1279.     CONTEXT    <10>
  1280. RetryWhatNextInput:
  1281.     BSR    UpLine
  1282.     CONTEXT    <'[A]bort, [C]ontinue or [S]tep ?'>
  1283.     XBSR    StdReadStr
  1284.     MOVE.B    (A0),D0
  1285.     AND.B    #$DF,D0
  1286.     CMP.B    #'A',D0    
  1287.     BEQ.S    AbortComputation
  1288.     CMP.B    #'C',D0
  1289.     BEQ.S    RestartComputation
  1290.     CMP.B    #'S',D0
  1291.     BEQ.S    DoOneComputationCycle
  1292.     BRA    RetryWhatNextInput
  1293.  
  1294. ; Clear the break flag and continue
  1295.  
  1296. RestartComputation:
  1297.     BSR    UpLine
  1298.     BSR    UpLine
  1299.     CONTEXT    <'Press CTRL-C to abort.',10>
  1300.     CLRBREAK
  1301.     BSR    PopScreen
  1302.     PULL    BreakRegs
  1303.     BRA    DoComputation
  1304.  
  1305. ; Reset cursor and continue
  1306.  
  1307. DoOneComputationCycle:
  1308.     CONTEXT    <$D,$B>
  1309.     PULL    BreakRegs
  1310.     BRA    DoComputation
  1311.  
  1312. ; Got user request to abort
  1313.  
  1314. AbortComputation:
  1315.     PULL    BreakRegs
  1316.  
  1317. ; Subprogram resource cleanup and error processing. (Screens not tracked yet)
  1318.  
  1319. CleanupSubProg:
  1320.     MOVE.L    ScreenBase(GP),D0
  1321.     BEQ.S    ScreenNotOpened
  1322.     MOVE.L    D0,A0
  1323.     CALL    intuition,CloseScreen
  1324.     CLR.L    ScreenBase(GP)
  1325. ScreenNotOpened:
  1326.     MOVE.L    ErrorStrSize(GP),D0
  1327.     BEQ.S    NoErrorString
  1328.     CONTEXT    <$D,$9B,'1K'>
  1329.     BSR    UpLine
  1330.     LEA    ErrorStr(GP),A0
  1331.     XBSR    StdWrite
  1332.     CONTEXT    <10,'Try to reduce space dimensions. RETURN'>
  1333.     BSR    InDeci
  1334.     XBSR    ClrErrorStr
  1335. NoErrorString:
  1336.     RTS
  1337.  
  1338.     END
  1339.  
  1340.  
  1341.  
  1342. ;---------------------------------------------------------
  1343. ; A stylized and simplified version of the display routine
  1344. ;---------------------------------------------------------
  1345.  
  1346.  
  1347. B¹     = Buffer with bools indicating which pixels need to be incremented
  1348.          during this space update
  1349. B²     = Buffer with bools indicating which pixels need to be incremented
  1350.          during the next space update
  1351. X      = Pixel index
  1352. Cntr   = Counter of pixel in cyclic space
  1353. ProcNe = Already processed neighbour of pixel in C.S.
  1354. UnprNe = Not yet processed neighbour od pixel in C.S.
  1355.  
  1356. DO
  1357.    FOR ALL X DO
  1358.        IF B¹(X) <> 0
  1359.           FOR ALL ProcNe(X) DO
  1360.               IF Cntr(X) = Cntr(ProcNe(X)) Set(B²(ProcNe(X)))
  1361.               IF Cntr(X)+2 = Cntr(ProcNe(X)) Set(B²(X))
  1362.           FOR ALL UnprNe(X) DO
  1363.               IF B¹(UnprNe(X)) = 0
  1364.                  IF Cntr(X) = Cntr(UnprNe(X)) Set(B²(UnprNe(X)))
  1365.                  IF Cntr(X)+2 = Cntr(UnprNe(X)) Set(B²(X))
  1366.           Cntr(X) = Cntr(X)+1
  1367.           B¹(X) = 0
  1368.           SETPIXEL(X,Cntr(X))
  1369.    Exchange(B¹,B²)
  1370. UNTIL CTRL-C
  1371.