home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / scrnsave / pyrocfg2 / pyro_src.txt next >
Encoding:
Text File  |  1989-09-10  |  27.0 KB  |  691 lines

  1. ; THE ULTIMATE SCREEN SAVER
  2. ;   by Richard Leinecker
  3. ; Copyright 1989 by ST-LOG
  4.  
  5. Kbdvbase        = $22
  6. Supexec         = $26
  7. Ptermres        = $31
  8.  
  9. GEMDOS          = 1
  10. XBIOS           = 14
  11.  
  12.  
  13. **********************************************************************
  14. *************************** start of program *************************
  15. **********************************************************************
  16.  
  17.         .text
  18.  
  19. start:
  20.         movea.l a7,a5           ; copy a7 for base page calc
  21.         movea.l #ustk,a7        ; init adr for local stack
  22.  
  23.         move.l  #setup,-(sp)    ; put address of set up routine on stack
  24.         move.w  #Supexec,-(sp)  ; SUPER mode command
  25.         trap    #XBIOS          ; execute setup routine in SUPERVISOR mode
  26.         addq.l  #6,sp           ; restore the stack pointer
  27.  
  28.  
  29. **********************************************************************
  30. *                Insert keyboard patch                               *
  31. **********************************************************************
  32.  
  33.         move.w  #Kbdvbase,-(sp)         ; XBIOS to get vectors
  34.         trap    #XBIOS                  ; do the trap
  35.         addq.l  #2,sp                   ; clean up stack
  36.         add.l   #32,d0                  ; +32 to get the keyboard vector address
  37.         movea.l d0,a0                   ; put it in a0
  38.         move.l  (a0),keyvector          ; move the vector to keyvector
  39.  
  40.         movea.l #insert,a0              ; address of the jmp in the patch
  41.         adda.l  #2,a0                   ; adjust it
  42.         move.l  keyvector,(a0)          ; now put the keyboard vector in place
  43.  
  44.         movea.l d0,a0                   ; get address of patch
  45.         move.l  #trapper,(a0)           ; install it
  46.  
  47.         move.l  #newmem,d0              ; new screen memory into d0
  48.         andi.l  #$fffffe00,d0           ; assure 512 byte boundary
  49.         addi.l  #512,d0
  50.         move.l  d0,newscreen            ; put this value in newscreen
  51.  
  52. **********************************************************************
  53. *       calculate amount of memory to keep, then terminate!          *
  54. **********************************************************************
  55.  
  56.         movea.l 4(a5),a5        ; basepage address
  57.         move.l  $c(a5),d0       ; length of text segment
  58.         add.l   $14(a5),d0      ; length of data segment
  59.         add.l   $1c(a5),d0      ; length of bss segment
  60.         add.l   #$100,d0        ; allow for basepage
  61.  
  62.         clr.w   -(sp)           ; specify exit code
  63.         move.l  d0,-(sp)        ; length of block to keep
  64.         move.w  #Ptermres,-(sp) ; Terminate and stay resident
  65.         trap    #GEMDOS         ; This doesn't return!
  66.  
  67. **********************************************************************
  68. *          Install the vertical blank interrupt                      *
  69. **********************************************************************
  70.  
  71. setup:
  72.         move.w  #0,d1           ; set the counter to zero
  73.         movea.l #$456,a0        ; load a0 with address of the pointer to the vector table
  74.         movea.l (a0),a1         ; load a1 with the address of the vector table
  75.  
  76.         move.w  #0,d0           ; zero the color
  77.         move.w  d0,vbiflag      ; set the flag to 0
  78.  
  79.         movea.l #$454,a2        ; nvbls
  80.         move.w  (a2),d3         ; get the number of vector slots
  81.  
  82.         adda.l  #4,a1
  83. check:
  84.         move.l  (a1),d2         ; put the vector address in d2
  85.         cmpi.l  #0,d2           ; see if it is a null
  86.         beq     install         ; if it is null then go to the install phase
  87.         addq.w  #1,d1           ; add one to the counter
  88.         cmp.w   d3,d1           ; see if all 8 slots have been checked
  89.         beq     skip            ; skip it if there are no slots left
  90.         adda.l  #4,a1           ; increment a1 to the next vector slot
  91.         bra     check           ; go back and check the next vector slot
  92.  
  93. install:
  94.         move.l  #vbi,(a1)       ; install the vbi address in the vacant slot
  95.         rts                     ; then leave
  96.  
  97. skip:
  98.         rts                     ; leave
  99.  
  100.  
  101. **********************************************************************
  102. *                      Here is the interrupt code                    *
  103. **********************************************************************
  104.  
  105. vbi:
  106.         move.w  vbiflag,d0              ; see if the fireworks are going off
  107.         cmpi.w  #1,d0                   ; 1 means yes
  108.         bne     continue                ; if not, keep counting
  109.  
  110.         ; firework 1
  111.  
  112.         movea.l #fw1,a0                 ; copy firework data to the
  113.         movea.l #fcolor,a1              ; work area - first assign the
  114.         jsr     assign                  ; pointers then jsr 'assign'
  115.         jsr     realvbi                 ; do the actual  firework stuff
  116.         movea.l #fw1,a1                 ; copy the work area back to
  117.         movea.l #fcolor,a0              ; the firework data
  118.         jsr     assign
  119.  
  120.         ; firework 2
  121.  
  122.         movea.l #fw2,a0                 ; copy firework data to the
  123.         movea.l #fcolor,a1              ; work area - first assign the
  124.         jsr     assign                  ; pointers then jsr 'assign'
  125.         jsr     realvbi                 ; do the actual  firework stuff
  126.         movea.l #fw2,a1                 ; copy the work area back to
  127.         movea.l #fcolor,a0              ; the firework data
  128.         jsr     assign
  129.  
  130.         ; firework 3
  131.  
  132.         movea.l #fw3,a0                 ; copy firework data to the
  133.         movea.l #fcolor,a1              ; work area - first assign the
  134.         jsr     assign                  ; pointers then jsr 'assign'
  135.         jsr     realvbi                 ; do the actual  firework stuff
  136.         movea.l #fw3,a1                 ; copy the work area back to
  137.         movea.l #fcolor,a0              ; the firework data
  138.         jsr     assign
  139.  
  140.         ; firework 4
  141.  
  142.         movea.l #fw4,a0                 ; copy firework data to the
  143.         movea.l #fcolor,a1              ; work area - first assign the
  144.         jsr     assign                  ; pointers then jsr 'assign'
  145.         jsr     realvbi                 ; do the actual  firework stuff
  146.         movea.l #fw4,a1                 ; copy the work area back to
  147.         movea.l #fcolor,a0              ; the firework data
  148.         jsr     assign
  149.  
  150.         rts                             ; leave, all 4 fireworks done
  151.  
  152. realvbi:
  153.         move.w  fnum,d0         ; see if there are fireworks going off
  154.         cmpi.w  #0,d0           ; are there any?
  155.         bne     makefw          ; If so, go there
  156.  
  157.         move.w  fcolor,d0       ; load the color
  158.         move.w  ty,d1           ; load the y coordinate
  159.         move.w  tx,d2           ; load the x coordinate
  160.         jsr     pixel           ; XOR the old pixel
  161.  
  162.         move.w  ty,d1           ; load the y coordinate
  163.         move.w  tx,d2           ; load the x coordinate
  164.         subq.w  #1,d1           ; decrement by delta y
  165.         move.w  trajectory,d4   ; load the trajectory number
  166.         cmpi.w  #0,d4           ; is it zero?
  167.         bne     notleft
  168.         addq.w  #1,d2           ; is it one?
  169.         bra     notside
  170.  
  171. notleft:
  172.         cmpi.w  #3,d4
  173.         bne     notside
  174.         subq.w  #1,d2
  175.  
  176. notside:
  177.         move.w  d2,tx           ; save tx
  178.         move.w  d1,ty           ; save ty
  179.  
  180.         cmp.w   fheight,d1      ; compare with the intended height
  181.         bgt     makepixel       ; if not there, just make a pixel
  182.  
  183.         move.w  #0,numcount     ; zero the explosion counter
  184.         move.w  #1,fnum         ; set fnum to the small pattern
  185.         move.w  #0,fwvblanks    ; zero the counter
  186.         jsr     drawfw          ; jump and XOR the fw explosion
  187.         rts                     ; leave
  188.  
  189. makefw:
  190.         move.w  fwvblanks,d0    ; load the counter
  191.         addq.w  #1,d0           ; increment it
  192.         cmpi.w  #4,d0           ; see if a delay has passed
  193.         beq     delaygone       ; go on if so
  194.         move.w  d0,fwvblanks    ; store the value
  195.         rts                     ; leave
  196.  
  197. delaygone:
  198.         move.w  #0,fwvblanks    ; zero the counter
  199.         jsr     drawfw          ; jump and XOR the fw explosion
  200.         move.w  fnum,d0         ; load from fnum
  201.         addq.w  #1,d0           ; increment the counter
  202.         move.w  d0,fnum         ; store it
  203.         cmpi.w  #9,d0           ; have there been seven patterns
  204.         beq     is_nine         ; go on if not
  205.         jsr     drawfw          ; jump and XOR the fw explosion
  206.         rts                     ; leave
  207.  
  208. is_nine:
  209.         move.w  numcount,d0     ; load numcount
  210.         addq.w  #1,d0           ; increment counter
  211.         move.w  d0,numcount     ; store it
  212.         move.w  numexplode,d1   ; load explosion number
  213.         cmp.w   d0,d1           ; compare them
  214.         beq     is_done         ; firework explosions finished!
  215.  
  216.         move.w  #1,fnum         ; reset fnum to 1
  217.  
  218.         movea.l #$4bc,a0        ; pointer to system clock
  219.  
  220.         move.w  (a0),d0         ; get the value
  221.         move.w  colormask,d1
  222.         and.w   d1,d0           ; mask to use maximum colors only
  223.         cmpi.w  #0,d0
  224.         bne     nzero1
  225.         ori.w   #1,d0           ; insure plane one
  226. nzero1:
  227.         move.w  d0,fcolor       ; store in fcolor
  228.  
  229.         move.w  (a0),d0         ; get a number
  230.         andi.w  #15,d0          ; and it to assure value in range
  231.         move.w  (a0),d3         ; get another number
  232.         andi.w  #7,d3           ; and it to assure value in range
  233.         move.w  tx,d1           ; load x coordinate
  234.         move.w  ty,d2           ; load y coordinate
  235.         subi.w  #7,d1           ; subtract 4
  236.         subi.w  #4,d2           ; subtract 4
  237.         add.w   d0,d1           ; add the random value
  238.         add.w   d3,d2           ; add the other random value
  239.         move.w  d1,tx           ; store it
  240.         move.w  d2,ty           ; store it
  241.  
  242.         jsr     drawfw          ; make the pattern
  243.         rts                     ; leave
  244.  
  245. is_done:
  246.         move.w  #0,fnum         ; zero fnum
  247.  
  248.         movea.l #$4bc,a0        ; pointer to system clock
  249.  
  250.         move.w  (a0),d0         ; get the value
  251.         move.w  colormask,d1
  252.         and.w   d1,d0           ; mask to use maximum colors only
  253.         cmpi.w  #0,d0
  254.         bne     nzero2
  255.         ori.w   #1,d0           ; insure plane one
  256. nzero2:
  257.         move.w  d0,fcolor       ; store in fcolor
  258.  
  259.         move.w  (a0),d4         ; now get another value
  260.         andi.w  #31,d4          ; and it to insure value is in range
  261.         addi.w  #40,d4          ; add 31
  262.         move.w  d4,fheight      ; store in fheight
  263.  
  264.         move.w  (a0),d4         ; get another random number
  265.         andi.w  #3,d4           ; and it to assure value is in range
  266.         addq.w  #1,d4           ; add one
  267.         move.w  d4,numexplode   ; store the value
  268.  
  269.         move.w  (a0),d4         ; get yet another value
  270.         andi.w  #3,d4           ; and it to assure value is in range
  271.         move.w  d4,trajectory   ; store in trajectory
  272.         mulu    onethird,d4     ; adjust the starting point
  273.         add.w   fromleft,d4     ; according to resolution
  274.  
  275.         move.w  #199,ty         ; store the y coordinate starting point
  276.         move.w  #199,d1         ; put 199 in d1
  277.         move.w  d4,tx           ; store the x coordinate starting point
  278.         move.w  d4,d2           ; store x value
  279.  
  280. makepixel:
  281.         move.w  fcolor,d0       ; move the color into d0
  282.         jsr     pixel           ; goto the pixel routine
  283.         rts                     ; leave
  284.  
  285. continue:
  286.         move.w  vblanks,d0      ; get the vblanks counter value
  287.         addq.w  #1,d0           ; increment the counter
  288.         move.w  d0,vblanks      ; store the vblanks counter value
  289.         cmpi.w  #32000,d0       ; see if the appropriate time has passed
  290.         bne     gohome          ; otherwise skip it
  291.  
  292.         move.l  newscreen,d0    ; get the screen address
  293.         movea.l d0,a0           ; move the newscreen address into a0
  294.         move.w  #0,d0           ; set the loop counter to zero
  295.  
  296. clearit:
  297.         move.l  #0,(a0)+        ; clear the screen
  298.         addq.w  #1,d0           ; increment loop counter
  299.         cmpi    #8000,d0        ; have 8000 longs been cleared?
  300.         bne     clearit         ; otherwise do some more
  301.  
  302.         movea.l #$44e,a0        ; set to _v_bas_ad - contains the screen address
  303.         move.l  (a0),oldscreen  ; get the old screen location
  304.  
  305.         movea.l #$ffff8201,a0   ; set to the Physbase location
  306.         movea.l #newscreen,a1   ; move the address of newscreen into a1
  307.         adda.l  #1,a1           ; increment the pointer to get correct byte
  308.         move.b  (a1),(a0)       ; move the byte to the Physbase location
  309.         adda.l  #2,a0           ; increment to the other byte location
  310.         adda.l  #1,a1           ; add 1 to get the correct byte of newscreen
  311.         move.b  (a1),(a0)       ; move the second byte
  312.  
  313.         movea.l #$ff8260,a0     ; set to ff8260 - contains the resolution
  314.         move.b  (a0),d0         ; put resolution in d0
  315.         andi.w  #$0003,d0       ; mask off any rubish
  316.         move.w  d0,rez          ; store it in 'rez'
  317.         move.w  #0,oldrez       ; store '0' in oldrez
  318.  
  319.         cmpi.w  #1,d0           ; see if we are in medium resolution
  320.         bne     dontchange      ; if not, don't attempt to change res
  321.         movea.l #$ff8260,a0     ; set to the hardware resolution location
  322.         move.w  (a0),d1         ; get the old resolution value
  323.         move.w  d1,oldrez       ; save it
  324.         move.w  #0,d0           ; move a zero into d0
  325.         movea.l #$44c,a0        ; set to the system variable location
  326.         move.b  d0,(a0)         ; store the new res
  327.         movea.l #$ff8260,a0     ; set to the hardware location
  328.         move.b  d0,(a0)         ; store the new res
  329.         move.w  d0,rez          ; store the new res in 'rez'
  330.  
  331. dontchange:
  332.         cmpi.w  #0,d0           ; assign resolution dependant values
  333.         bne     notlow
  334.         move.w  #8,wordbytes    ; bytes per 16 screen pixels
  335.         move.w  #$000f,colormask; number of colors to be used
  336.         move.w  #80,onethird    ; horizontal distance (c. one third of screen)
  337.         move.w  #40,fromleft    ; value to start from left of screen
  338.         move.w  #1,xadjust      ; x factor
  339.         bra     gotrez
  340.  
  341. notlow:
  342.         move.w  #2,wordbytes    ; bytes per 16 screen pixels
  343.         move.w  #0,colormask    ; number of colors to be used
  344.         move.w  #160,onethird   ; horizontal distance (c. one third of screen)
  345.         move.w  #40,fromleft    ; value to start from left of screen
  346.         move.w  #2,xadjust      ; x factor
  347.  
  348. gotrez:
  349.         movea.l #oldpalette,a1  ; set destination of palette copy
  350.         movea.l #$ff8240,a0     ; set source of palette copy
  351.         jsr     getsetpalette   ; jump and do the copy
  352.         movea.l #newpalette,a0  ; set source of palette copy
  353.         movea.l #$ff8240,a1     ; set destination of palette copy
  354.         jsr     getsetpalette   ; jump and do the copy
  355.  
  356.         move.w  #1,vbiflag
  357.  
  358.         move.w  #0,countfw              ; zero the counter
  359.         move.w  #0,d7
  360.         move.w  #0,fnum
  361.         move.w  #0,numcount
  362.  
  363. four_fw:
  364.         movea.l #$4bc,a0        ; pointer to system clock
  365.         move.w  (a0),d0         ; get the value
  366.         move.w  colormask,d1
  367.         and.w   d1,d0           ; mask to use maximum colors only
  368.         cmpi.w  #0,d0
  369.         bne     nzero3
  370.         ori.w   #1,d0           ; insure plane one
  371. nzero3:
  372.         move.w  d0,fcolor       ; store in fcolor
  373.  
  374.         move.w  d7,d4
  375.         addq.w  #1,d4
  376.         mulu    #10,d4
  377.         addi.w  #40,d4
  378.         move.w  d4,fheight      ; store in fheight
  379.  
  380.         move.w  (a0),d4         ; get another random number
  381.         andi.w  #3,d4           ; and it to assure value is in range
  382.         addq.w  #1,d4           ; add one
  383.         move.w  d4,numexplode   ; store the value
  384.  
  385.         move.w  d7,d4
  386.         move.w  d4,trajectory   ; store in trajectory
  387.         mulu    onethird,d4     ; adjust the starting point
  388.         add.w   fromleft,d4     ; according to resolution
  389.  
  390.         move.w  #199,ty         ; store the y coordinate starting point
  391.         move.w  #199,d1         ; put 199 in d1
  392.         move.w  d4,tx           ; store the x coordinate starting point
  393.         move.w  d4,d2           ; store x value
  394.  
  395.         move.w  countfw,d7
  396.  
  397.         addq.w  #1,d7
  398.         move.w  d7,countfw
  399.         cmpi.w  #1,d7
  400.         bne     pastfw1
  401.         movea.l #fcolor,a0
  402.         movea.l #fw1,a1
  403.         jsr     assign
  404.         move.w  fcolor,d0
  405.         move.w  ty,d1
  406.         move.w  tx,d2
  407.         jsr     pixel           ; make the pixel
  408.         bra     four_fw
  409.  
  410. * Generate four sets of random firework data
  411.  
  412. pastfw1:
  413.         cmpi.w  #2,d7
  414.         bne     pastfw2
  415.         movea.l #fcolor,a0
  416.         movea.l #fw2,a1
  417.         jsr     assign
  418.         move.w  fcolor,d0
  419.         move.w  ty,d1
  420.         move.w  tx,d2
  421.         jsr     pixel           ; make the pixel
  422.         bra     four_fw
  423. pastfw2:
  424.         cmpi.w  #3,d7
  425.         bne     pastfw3
  426.         movea.l #fcolor,a0
  427.         movea.l #fw3,a1
  428.         jsr     assign
  429.         move.w  fcolor,d0
  430.         move.w  ty,d1
  431.         move.w  tx,d2
  432.         jsr     pixel           ; make the pixel
  433.         bra     four_fw
  434. pastfw3:
  435.         cmpi.w  #4,d7
  436.         bne     gohome
  437.         movea.l #fcolor,a0
  438.         movea.l #fw4,a1
  439.         jsr     assign
  440.         move.w  fcolor,d0
  441.         move.w  ty,d1
  442.         move.w  tx,d2
  443.         jsr     pixel           ; make the pixel
  444.  
  445. gohome: rts                     ; leave
  446.  
  447.  
  448.  
  449. **********************************************************************
  450. *                      Here is the keyboard patch                    *
  451. **********************************************************************
  452.  
  453. trapper:
  454.         move.w  #0,vblanks      ; reset the vbi counter to zero
  455.         movem.l a0-a1/d0/d7,-(sp)  ; save addresses and loop counter
  456.         move.w  vbiflag,d0      ; get the value in the vbi flag
  457.         cmpi.w  #1,d0           ; see if it is one (enabled)
  458.         bne     getlost         ; if not leave...
  459.  
  460.         movea.l #$ffff8201,a0
  461.         movea.l #oldscreen,a1
  462.         adda.l  #1,a1
  463.         move.b  (a1),(a0)
  464.         adda.l  #2,a0
  465.         adda.l  #1,a1
  466.         move.b  (a1),(a0)
  467.  
  468.         move.w  #0,fnum         ; zero fnum in case of fireworks going off
  469.  
  470.         movea.l #$ff8240,a1     ; set destination of palette copy
  471.         movea.l #oldpalette,a0  ; set source of palette copy
  472.         jsr     getsetpalette   ; jump and do the copy
  473.  
  474.         move.w  #0, vbiflag     ; set the vbi flag to zero
  475.  
  476.         move.w  oldrez,d0
  477.         cmpi.w  #0,d0
  478.         beq     getlost
  479.         move.w  #1,d0
  480.         movea.l #$44c,a0
  481.         move.b  d0,(a0)
  482.         movea.l #$ff8260,a0
  483.         move.b  d0,(a0)
  484.  
  485. getlost:
  486.         movem.l (sp)+,a0-a1/d0/d7  ; restore addresses and loop counter
  487. insert:
  488.         jmp     $11111111       ; this address is changed upon program init
  489.  
  490.  
  491. **********************************************************************
  492. *        This routine XORs a pixel on the screen                     *
  493. **********************************************************************
  494.  
  495. pixel:
  496.  
  497. * Pixel color in d0
  498. * y coordinate in d1
  499. * x coordinate in d2
  500. * use a3 for screen address
  501. * use a4 for bit mask
  502.  
  503.         movea.l newscreen,a3    ; put the screen address in a3
  504.         mulu    #160,d1         ; multiply the y coordinate by 16
  505.         andi.l  #$0000ffff,d1
  506.         adda.l  d1,a3           ; add the y value to a3
  507.         andi.l  #$0000ffff,d2
  508.         divu    #16,d2          ; divide the x by 16 to get the number of words
  509.         move.l  d2,d1           ; store the result in order to ascertain the remainder
  510.         andi.l  #$0000ffff,d2
  511.         mulu    wordbytes,d2    ; multiply by wordbytes to find the correct byte offset
  512.         andi.l  #$0000ffff,d2
  513.         adda.l  d2,a3           ; add the byte offset to a3
  514.         lsr.l   #8,d1           ; shift 8
  515.         lsr.l   #7,d1           ; shift 7
  516.         andi.l  #$000000fe,d1   ; offset in d1
  517.  
  518.         movea.l #pixbits,a4     ; put the pixbit address in a4
  519.         adda.w  d1,a4           ; add the correct offset to a4
  520.         move.w  (a4),d3         ; move the data into d3
  521.  
  522. * Now the pixel data is in d3 and the screen address is in a3
  523.  
  524.         btst    #0,d0
  525.         beq     secondplane     ; if not, skip to the second plane
  526.  
  527.         move.w  (a3),d2         ; get the screen byte
  528.         eor.w   d3,d2           ; XOR it with the data
  529.         move.w  d2,(a3)         ; put it back on the screen
  530.  
  531. secondplane:
  532.         adda.w  #2,a3           ; add the correct number of bytes
  533.         btst    #1,d0
  534.         beq     thirdplane      ; if not, skip to third plane
  535.  
  536.         move.w  (a3),d2         ; get the screen byte
  537.         eor.w   d3,d2           ; XOR it with the data
  538.         move.w  d2,(a3)         ; put it back on the screen
  539.  
  540. thirdplane:
  541.         adda.w  #2,a3           ; add the correct number of bytes
  542.         btst    #2,d0
  543.         beq     fourthplane     ; if not, skip to the fourth plane
  544.  
  545.         move.w  (a3),d2         ; get the screen byte
  546.         eor.w   d3,d2           ; XOR it with the data
  547.         move.w  d2,(a3)         ; put it back on the screen
  548.  
  549. fourthplane:
  550.         btst    #3,d0
  551.         beq     lastplane       ; if not then leave
  552.  
  553.         adda.w  #2,a3           ; add the correct number of bytes
  554.         move.w  (a3),d2         ; get the screen byte
  555.         eor.w   d3,d2           ; XOR it with the data
  556.         move.w  d2,(a3)         ; put it back on the screen
  557.  
  558. lastplane:
  559.         rts                     ; leave the routine
  560.  
  561.  
  562. *************************************************************************
  563. *       Get/Set current pallete  (must be in Supervisor)                *
  564. *************************************************************************
  565.  
  566. getsetpalette:
  567.         move.w  #0,d7                   ; zero the counter
  568.  
  569. gsploop:move.w  (a0)+,(a1)+             ; move the data
  570.         addq.w  #1,d7                   ; increment the counter
  571.         cmpi.w  #16,d7                  ; have you copied 16?
  572.         bne     gsploop                 ; if not, do some more
  573.  
  574.         rts                             ; leave subroutine
  575.  
  576. ************************************************************************
  577. *                     Draw a firework explosion part                   *
  578. ************************************************************************
  579.  
  580. drawfw:
  581.         move.w  fcolor,d0       ; get the firework color
  582.         move.w  #0,d7           ; zero the counter
  583.         movea.l #fpattern,a5    ; get the address of fpattern
  584.         move.w  fnum,d6         ; load the firework number
  585.         move.w  d6,d5           ; save the firework number in d5 for future use
  586.         mulu    #3,d6           ; figure out the radius
  587.  
  588. do_dots:
  589.         move.w  tx,d2           ; get the x coordinate
  590.         sub.w   d6,d2           ; adjust to top left of firework pattern
  591.         move.w  xadjust,d4      ; load xadjust
  592.         cmpi.w  #2,d4           ; see if it is 2
  593.         bne     xa_not_2        ; go on otherwise
  594.         sub.w   d6,d2           ; adjust additional amount
  595. xa_not_2:
  596.         move.w  ty,d1           ; get the y coordinate
  597.         sub.w   d6,d1           ; adjust to top left of firework pattern
  598.         move.w  (a5)+,d4        ; get the x pattern element
  599.         mulu    d5,d4           ; multiply according to the size of the fw
  600.         mulu    xadjust,d4      ; resolution factor
  601.         add.w   d4,d2           ; add the x position to the top left of pattern
  602.         move.w  (a5)+,d4        ; get the y pattern element
  603.         mulu    d5,d4           ; multiply according to the size of the fw
  604.         add.w   d4,d1           ; add the y position to the top left of pattern
  605.         addq.w  #1,d7           ; increment the counter
  606.         jsr     pixel           ; now, make the pixel
  607.         cmpi.w  #8,d7           ; see if you have done the 8 dots
  608.         bne     do_dots         ; do some more if not
  609.  
  610.         rts                     ; leave the routine
  611.  
  612. ************************************************************************
  613. *           Move the specified firework data to the work area          *
  614. ************************************************************************
  615.  
  616. assign:
  617.         move.w  #0,d0
  618.  
  619. do_more:
  620.         move.w  (a0)+,(a1)+
  621.         addq.w  #1,d0
  622.         cmpi.w  #10,d0
  623.         bne     do_more
  624.  
  625.         rts
  626.  
  627.  
  628. **********************************************************************
  629. *                       Data Storage Segment                         *
  630. **********************************************************************
  631.  
  632.                 .even
  633.                 .data
  634.  
  635. pixbits:        .dc.w   $8000,$4000,$2000,$1000,$0800,$0400,$0200,$0100
  636.                 .dc.w   $0080,$0040,$0020,$0010,$0008,$0004,$0002,$0001
  637.  
  638. newpalette:     .dc.w   $0000,$0070,$0700,$0700,$0770,$0707,$0077,$0777
  639.                 .dc.w   $0770,$0704,$0074,$0740,$0704,$0740,$0400,$0700
  640.  
  641. fpattern:       .dc.w   $0000,$0003,$0001,$0001,$0003,$0000,$0005,$0001
  642.                 .dc.w   $0006,$0003,$0005,$0005,$0003,$0006,$0001,$0005
  643.  
  644. fw1:            .dc.w   $0000,$0000,$0000,$0000,$0000,$0000
  645.                 .dc.w   $0000,$0000,$0000,$0000
  646. fw2:            .dc.w   $0000,$0000,$0000,$0000,$0000,$0000
  647.                 .dc.w   $0000,$0000,$0000,$0000
  648. fw3:            .dc.w   $0000,$0000,$0000,$0000,$0000,$0000
  649.                 .dc.w   $0000,$0000,$0000,$0000
  650. fw4:            .dc.w   $0000,$0000,$0000,$0000,$0000,$0000
  651.                 .dc.w   $0000,$0000,$0000,$0000
  652.  
  653.  
  654. **************************************************************************
  655. * Block Storage Segment
  656.  
  657.                 .bss
  658.  
  659. rez:            .ds.w   1       ; current resolution
  660. oldrez:         .ds.w   1
  661. oldscreen:      .ds.l   1       ; old screen pointer
  662. keyvector:      .ds.l   1       ; keyboard vector
  663. oldpalette:     .ds.w   16
  664. wordbytes:      .ds.w   1       ; bytes per screen word
  665. colormask:      .ds.w   1
  666. onethird:       .ds.w   1
  667. fromleft:       .ds.w   1
  668. xadjust:        .ds.w   1
  669. newmem:         .ds.l   8200
  670. newscreen:      .ds.l   1
  671. vblanks:        .ds.w   1       ; vblank counter
  672. countfw:        .ds.w   1
  673. vbiflag:        .ds.w   1       ; status of the screen saver
  674.                                 ; 0=not enabled
  675.                                 ; 1=enabled
  676.  
  677. fcolor:         .ds.w   1
  678. numexplode:     .ds.w   1
  679. trajectory:     .ds.w   1
  680. fheight:        .ds.w   1
  681. ty:             .ds.w   1
  682. tx:             .ds.w   1
  683. fnum:           .ds.w   1
  684. numcount:       .ds.w   1
  685. fwvblanks:      .ds.w   1
  686.  
  687.  
  688.                 .ds.l    255    ; the stack can grow down 1K before
  689. ustk:           .ds.l    1      ; it starts to eat the program!!
  690.                 .end
  691. əəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəə