aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--explosion.s131
1 files changed, 98 insertions, 33 deletions
diff --git a/explosion.s b/explosion.s
index dbc000d..678e2c0 100644
--- a/explosion.s
+++ b/explosion.s
@@ -2,69 +2,134 @@
; flash the part of the screen where the lorchas are displayed.
; previously this flashed the whole screen, but it gave me a
-; headache.
+; headache. plus, the apple version's "tv static" effect only appears
+; on the lorcha area of the screen, so this is closer to the original
+; than a fullscreen flash would be.
+
+; we're not using a display list interrupt here. basically each flashed
+; frame is:
+; - sync CPU to ANTIC using VSYNC and WSYNC.
+; - change HW color registers for text and background.
+; - wait until enough scanlines have been drawn.
+; - change the colors back to normal.
+
+; pseudo-C for explosion():
+; for(Yreg = flashes; Yreg > 0; --Yreg) {
+; for(framecounter = jiffies; framecounter > 0; --framecounter) {
+; // this loop body takes 1 jiffy to execute
+; while(VCOUNT < startvcount)
+; ;
+; set_flashed_colors();
+; while(VCOUNT < endvcount)
+; ;
+; set_normal_colors();
+; }
+; jsleep(jiffies); // unflashed display for equal amount of time
+; }
.export _explosion
.include "atari.inc"
.importzp tmp1, tmp2
.import _jsleep
-counter = tmp1
-color2save = tmp2
+; how many times the screen will appear to flash.
+flashes = 3
+
+; timing, in jiffies. each flash shows this many 'flashed' frames,
+; followed by the same number of normal frames. the whole explosion takes
+; ((jiffies * flashes * 2) / 60) seconds, or 1 second for jiffies = 10
+; on NTSC (for PAL, it's 1.2 seconds).
+jiffies = 10
+
+; VCOUNT value where we will start the flash effect. Remember, VCOUNT is
+; (scanlines / 2), and a GR.0 text line is 8 scanlines, or 4 VCOUNTs.
+; There are 3 'blank for 8 lines' instructions at the top of the GR.0
+; display list, so the first visible GR.0 line starts at (4+0)*4.
+; The value below is the start of the GR.0 line before the top row
+; of lorchas.
+startvcount = (4+8)*4
+
+; VCOUNT value where we will stop the flash effect and restore normal
+; playfield colors. Value below is 2 GR0 lines after the bottom row
+; of lorchas.
+endvcount = (4+23)*4
+
+; use zero page rather than X register for frame counter, since
+; _jsleep will trash the X register.
+framecounter = tmp1
+
+; bottom 4 bits of COLOR1. Will be ORed with the top 4 bits (the hue)
+; of COLOR2, to get the 'flashed' text background color. The flashed
+; text color is always 0 (black, or actually darkest luma of whatever
+; hue the text BG color is).
+textluma = tmp2
; extern void explosion(void);
_explosion:
; {
- ldy #3 ; loop counter, counts 3 2 1
+ ldy #flashes ; outerloop counter
- lda COLOR1
- and #$0f
- sta tmp2
+ lda COLOR1 ; can't hardcode this, since it can be changed
+ and #$0f ; at the title screen.
+ sta textluma
; {
-@loop:
- lda #$0a
- sta counter
+; each time thru outerloop, show 'jiffies' frames of flash and another
+; 'jiffies' frames of normal display (so the flashing toggles on and off
+; 'flashes' times).
+@outerloop:
+ lda #jiffies
+ sta framecounter ; inner loop, counts 10 to 1
+@frameloop:
; {
-@wait4scanline:
+@wait4startscanline:
; {
- lda VCOUNT
- cmp #(4+8)*4
- bne @wait4scanline
+ lda VCOUNT ; delay until start of flashing area
+ cmp #startvcount
+ bne @wait4startscanline
; }
- sta WSYNC
+ ; set_flashed_colors();
+ sta WSYNC ; finish current scanline (avoid tearing)
-; {
-@scanlines:
- lda COLOR2
- and #$f0
- ora tmp2
- sta WSYNC
- sta COLPF2
- lda #0
- sta COLPF1
+ ; we're in the horizontal blank now. De Re Atari, Chapter 5, says we get
+ ; "from 17 to 26 cycles". We're not using P/M and there's no LMS here,
+ ; but 1 or 2 cycles may be stolen by memory refresh. The "sta COLPF1"
+ ; only has to finish before any non-space characters are displayed on
+ ; the scanline, which would give us a couple extra cycles if needed,
+ ; since there's a border of spaces around the lorchas.
+
+ lda COLOR2 ; +4 = 4
+ and #$f0 ; +2 = 6
+ ora textluma ; +3 = 9
+ sta COLPF2 ; +4 = 13
+ lda #0 ; +2 = 15
+ sta COLPF1 ; +4 = 18
+; {
+@wait4endscanline: ; delay until end of flashing area
lda VCOUNT
- cmp #(4+23)*4
- bne @scanlines ; stop changing color 2 lines after the bottom row of lorchas
+ cmp #endvcount
+ bne @wait4endscanline
; }
- lda COLOR2 ; put colors back like they were for the rest of the frame
+ ; set_normal_colors();
+ sta WSYNC
+ lda COLOR2 ; put colors back like they were for the rest of the frame.
sta COLPF2
lda COLOR1
sta COLPF1
- dec counter
- bne @wait4scanline
+ dec framecounter
+ bne @frameloop ; inner loop done when framecounter == 0
; }
- ldx #0 ;\
- lda #$0a ; | jsleep(10);
- jsr _jsleep ;/
+ ldx #0 ;\
+ lda #jiffies ; | jsleep(jiffies);
+ jsr _jsleep ;/
dey
- bne @loop ; we're done if Y==0
+ bne @outerloop ; we're done if Y == 0
; }
rts