megademo: merge in fireworks for ending

need to change a bunch to make this work
Now load at $4000 as was too big to fit between $1000 and $2000

also turns out our lz4 code was writing past the end, which you notice
when you have important code right after the end of HGR1
This commit is contained in:
Vince Weaver 2018-09-26 14:01:14 -04:00
parent 6dea94b671
commit a8ab24004d
12 changed files with 2057 additions and 9 deletions

View File

@ -8,7 +8,7 @@ PNG_TO_40x96 = ../gr-utils/png_to_40x96
all: megademo.dsk
megademo.dsk: MEGADEMO
$(DOS33) -y megademo.dsk BSAVE -a 0x1000 MEGADEMO
$(DOS33) -y megademo.dsk BSAVE -a 0x4000 MEGADEMO
# $(DOS33) -y megademo.dsk BSAVE -a 0x2000 C64C.BIN
# $(DOS33) -y megademo.dsk BSAVE -a 0x2000 C64.BIN
# $(DOS33) -y megademo.dsk BSAVE -a 0x2000 C64_BW.BIN
@ -17,13 +17,15 @@ megademo.dsk: MEGADEMO
####
MEGADEMO: megademo.o
ld65 -o MEGADEMO megademo.o -C ../linker_scripts/apple2_1000.inc
ld65 -o MEGADEMO megademo.o -C ../linker_scripts/apple2_4000.inc
megademo.o: megademo.s \
zp.inc hardware.inc \
gr_hline.s gr_offsets.s vapor_lock.s delay_a.s wait_keypress.s \
c64_opener.s c64.img.lz4 \
falling_apple.s apple_40_96.inc
falling_apple.s apple_40_96.inc \
fireworks.s fw_background.inc fw_state_machine.s fw.s \
hgr.s random16.s move_letters.s
ca65 -o megademo.o megademo.s -l megademo.lst

14
megademo/README Normal file
View File

@ -0,0 +1,14 @@
Memory Map:
$0000-$0100 = ZERO PAGE
$0100-$0200 = STACK
$0400-$0800 = TEXT/GR PAGE0
$0800-$0C00 = TEXT/GR PAGE1
$0C00-$0fff = we use this as TEXT/GR offscreen buffer
$1000-$1fff = 4k free
$2000-$3fFF = HGR1 page ; note we never use HGR2 ($4000-$6000)
$4000-$9600 = roughly 20k(?)
$9600-$BFFF = DOS3.3
$C000-$FFFF = peripherals/ROM

View File

@ -29,12 +29,13 @@ c64_opener:
lda #>c64
sta LZ4_SRC+1
lda #<c64_end
lda #<(c64_end-8) ; skip checksum at end
sta LZ4_END
lda #>c64_end
lda #>(c64_end-8) ; skip checksum at end
sta LZ4_END+1
lda #<$2000
sta LZ4_DST
lda #>$2000
@ -45,7 +46,6 @@ c64_opener:
jsr wait_until_keypress
;==============================
; setup graphics for vapor lock
;==============================
@ -377,7 +377,6 @@ c64:
c64_end:
;=========================================================
; DdBbbNnNnNnNnNnNnNnNnNnNn NnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNn Nothing
; DdBbbNnNnNnNnNnNnNnNnNnNn NnNnNnNnNnNnNnNnTtttGgggNnNnNnNnNnNnNnNn 16= 4W

399
megademo/fireworks.s Normal file
View File

@ -0,0 +1,399 @@
; Display fancy Fireworks
; HGR plus 40x48d page1/page2 every-1-scanline pageflip mode
; Zero Page
FRAMEBUFFER = $00 ; $00 - $0F
;YPOS = $10
FRAME = $60
WAITING = $62
LETTERL = $63
LETTERH = $64
LETTERX = $65
LETTERY = $66
LETTERD = $67
LETTER = $68
BLARGH = $69
HGR_COLOR = $E4
STATE = $ED
;DRAW_PAGE = $EE
LASTKEY = $F1
PADDLE_STATUS = $F2
;==================================
;==================================
fireworks:
setup_background:
;===================
; init screen
jsr TEXT
jsr HOME
jsr hgr
bit KEYRESET
;gom:
; jmp gom
;===================
; init vars
lda #0
sta DRAW_PAGE
sta STATE
sta WAITING
init_letters:
lda #<letters
sta LETTERL
lda #>letters
sta LETTERH
lda #39
sta LETTERX
lda #22
sta LETTERY
lda #25
sta LETTERD
;=============================
; Load graphic page0
lda #$0c
sta BASH
lda #$00
sta BASL ; load image to $c00
lda #<bg_final_low
sta GBASL
lda #>bg_final_low
sta GBASH
jsr load_rle_gr
lda #4
sta DRAW_PAGE
jsr gr_copy_to_current ; copy to page1
; GR part
bit PAGE1
bit LORES ; 4
bit SET_GR ; 4
bit FULLGR ; 4
; jsr wait_until_keypressed
;=============================
; Load graphic page1
lda #$0c
sta BASH
lda #$00
sta BASL ; load image to $c00
lda #<bg_final_high
sta GBASL
lda #>bg_final_high
sta GBASH
jsr load_rle_gr
lda #0
sta DRAW_PAGE
jsr gr_copy_to_current
; GR part
bit PAGE0
; jsr wait_until_keypressed
;==============================
; setup graphics for vapor lock
;==============================
jsr vapor_lock ; 6
; vapor lock returns with us at beginning of hsync in line
; 114 (7410 cycles), so with 5070 lines to go
; so we have 5070 + 4550 = 9620 to kill
jsr gr_copy_to_current ; 6+ 9292
; now we have 322 left
; GR part
bit LORES ; 4
bit SET_GR ; 4
bit FULLGR ; 4
; 322 - 12 = 310
; - 3 for jmp
; 307
; Try X=9 Y=6 cycles=307
ldy #6 ; 2
fwloopA:ldx #9 ; 2
fwloopB:dex ; 2
bne fwloopB ; 2nt/3
dey ; 2
bne fwloopA ; 2nt/3
jmp fw_display_loop ; 3
.align $100
;================================================
; Display Loop
;================================================
; each scan line 65 cycles
; 1 cycle each byte (40cycles) + 25 for horizontal
; Total of 12480 cycles to draw screen
; Vertical blank = 4550 cycles (70 scan lines)
; Total of 17030 cycles to get back to where was
; We want to alternate between page1 and page2 every 65 cycles
; vblank = 4550 cycles to do scrolling
; 2 + 48*( (4+2+25*(2+3)) + (4+2+23*(2+3)+4+5)) + 9)
; 48*[(6+125)-1] + [(6+115+10)-1]
fw_display_loop:
;===================================
; HIRES PAGE0 for the top 152 lines
;===================================
; 152 * 65 = 9880
; -12 for HIRES/PAGE0 at top
; -5 for LORES+ldy+br fallthrough at bottom
; -132 for move_letters
; 9731
bit HIRES ; 4
bit PAGE0 ; 4
bit FULLGR ; 4
;===========
; 12
jsr move_letters ; 6+126
; Try X=242 Y=8 cycles=9729 R2
nop ; 2
ldy #8 ; 2
hgloop1:ldx #242 ; 2
hgloop2:dex ; 2
bne hgloop2 ; 2nt/3
dey ; 2
bne hgloop1 ; 2nt/3
bit LORES ; 4
;====================================================
; LORES PAGE0/PAGE1 alternating for the next 24 lines
;====================================================
ldy #12 ; *2=24 lines ; 2
; we set PAGE0 (4) then want to NOP (61) for a total of 65
bouter_loop:
bit PAGE0 ; 4
ldx #12 ; 65 cycles with PAGE0 ; 2
bpage0_loop: ; delay 61+bit
dex ; 2
bne bpage0_loop ; 2/3
;=============
; 6+(12*5)-1=65
; we set PAGE1 (4) as well as dey (2) and bne (3) then nop (55)
;
bit PAGE1 ; 4
ldx #11 ; 65 cycles with PAGE1 ; 2
bpage1_loop:
dex ; 2
bne bpage1_loop ; 2/3
;=============
; 6+(11*5)-1=60
dey ; 2
bne bouter_loop ; 2/3
;==============
; 5 to make 65
;=========================================================
; LORES PAGE0/PAGE1+TEXT alternating for the next 16 lines
;=========================================================
ldy #8 ; *2=16 lines ; 2
; we set PAGE0 (4) then want to NOP (61) for a total of 65
couter_loop:
bit FULLGR ; 4
bit PAGE0 ; 4
ldx #5 ; 2
cpage0_loop:
dex ; 2
bne cpage0_loop ; 2/3
;=============
; 10+(5*5)-1=34
bit $1000 ; 4
bit $1000 ; 4
bit TEXTGR ; 4
bit $1000 ; 4
bit $1000 ; 4
bit $1000 ; 4
bit $1000 ; 4
lda DRAW_PAGE ; 3
; we set PAGE1 (4) as well as dey (2) and bne (3) then nop (55)
;
bit FULLGR ; 4
bit PAGE1 ; 4
ldx #5 ; 2
cpage1_loop:
dex ; 2
bne cpage1_loop ; 2/3
;=============
; 10+(5*5)-1=34
bit $1000 ; 4
bit $1000 ; 4
bit TEXTGR ; 4
bit $1000 ; 4
lda DRAW_PAGE ; 3
nop ; 2
lda DRAW_PAGE ; 3
nop ; 2
dey ; 2
bne couter_loop ; 2/3
;==============
; 5 to make 65
;======================================================
; We have 4550 cycles in the vblank, use them wisely
;======================================================
; 4550
; +1 fallthrough
; -2 for ldy in previous
; -35 call through jumptable
; -7 keyboard
; -3 jmp
; ========
; 4504
;========================
; each subunit should take 4504 cycles
firework_state_machine:
; if killing time, 16+19 = 35
; if not, 16+19 = 35
ldy STATE ; 3
inc FRAME ; 5
lda FRAME ; 3
and #$3 ; 2
beq kill_time ; 3
;===========
; 16
; Set up jump table that runs same speed on 6502 and 65c02
;-1
lda jump_table+1,y ; 4
pha ; 3
lda jump_table,y ; 4
pha ; 3
rts ; 6
;=============
; 19
kill_time:
; need 16 cycles nop
ldy STATE ; (nop) ; 3
ldy STATE ; (nop) ; 3
ldy STATE ; (nop) ; 3
ldy STATE ; (nop) ; 3
nop ; 2
nop ; 2
jmp action_stars ; 3
;=============
; 19
fw_check_keyboard:
lda KEYPRESS ; 4
bpl fw_no_keypress ; 3
jmp restart
fw_no_keypress:
jmp fw_display_loop ; 3
; Restart and toggle sound
restart:
; self mofifying code, flip from bit C030 to bit 0030
lda sound1+2
eor #$C0
sta sound1+2
; lda sound2+2
; eor #$C0
; sta sound2+2
lda sound3+2
eor #$C0
sta sound3+2
jmp setup_background
jump_table:
.word (action_launch_firework-1)
.word (action_move_rocket-1)
.word (action_start_explosion-1)
.word (action_continue_explosion-1)
.word (action_stall_rocket-1)
.include "fw_state_machine.s"
.include "fw.s"
;.include "gr_hline.s"
;.include "../asm_routines/gr_unrle.s"
;.include "../asm_routines/keypress.s"
;.include "gr_copy.s"
;.include "random16.s"
;.include "hgr.s"
;.include "vapor_lock.s"
;.include "move_letters.s"
;.include "delay_a.s"
background:
.include "fw_background.inc"

843
megademo/fw.s Normal file
View File

@ -0,0 +1,843 @@
;=======================================================================
; Based on BASIC program posted by FozzTexx, originally written in 1987
;=======================================================================
; State:
; 0: Launch Rocket -> goes to 1
; 1: Move Rocket -> repeats 1 until CS done, then 2
; 2: Start Explosion -> goes to 3
; 3: Continue Explosion -> repeats 3 until done.
; then randomly might go to 2
; before going to 0
STATE_LAUNCH_ROCKET = 0
STATE_MOVE_ROCKET = 2
STATE_START_EXPLOSION = 4
STATE_CONTINUE_EXPLOSION = 6
STATE_STALL_ROCKET = 8
; Constants
NUMSTARS = 16
YSIZE = 160
XSIZE = 280
MARGIN = 24
; Zero page addresses
;STATE = $ED
OFFSET = $EF
COLOR_GROUP = $F0
X_VELOCITY = $F1
Y_VELOCITY_H = $F2
Y_VELOCITY_L = $F3
MAX_STEPS = $F4
XPOS_H = $F5
XPOS_L = $F6
YPOS_H = $F7
YPOS_L = $F8
PEAK = $F9
CURRENT_STEP = $FA
Y_OLD = $FB
Y_OLDER = $FC
X_OLD = $FD
X_OLDER = $FE
FWTEMP = $FF
.align $100
;===========================
; LAUNCH_FIREWORK
;===========================
; cycles= 60+60+67+60+56+56+15+8+21+11 = 414
launch_firework:
sound1:
bit SPEAKER ; 4
jsr random16 ; 6+42
lda SEEDL ; 3
and #$4 ; 2
sta COLOR_GROUP ; HGR color group (0 PG or 4 BO) ; 3
;============
; 60
jsr random16 ; 6+42
lda SEEDL ; 3
and #$3 ; 2
clc ; 2
adc #$1 ; 2
sta X_VELOCITY ; x velocity = 1..4 ; 3
;===========
; 60
jsr random16 ; 6+42
lda SEEDL ; 3
and #$3 ; 2
clc ; 2
adc #$2 ; 2
eor #$ff ; 2
sta Y_VELOCITY_H ; y velocity = -3..-6 ; 3
lda #0 ; 2
sta Y_VELOCITY_L ; it's 8:8 fixed point ; 3
;============
; 67
jsr random16 ; 6+42
lda SEEDL ; 3
and #$1f ; 2
clc ; 2
adc #33 ; 2
sta MAX_STEPS ; 33..64 ; 3
;============
; 60
; launch from the two hills
jsr random16 ; 6+42
lda SEEDL ; 3
and #$3f ; 2
sta XPOS_L ; base of 0..63 ; 3
;============
; 56
jsr random16 ; 6+42
lda SEEDL ; 3
and #$1 ; 2
beq right_hill ; 3
;============
; 56
left_hill: ;-1
lda X_VELOCITY ; nop ; 3
lda X_VELOCITY ; nop ; 3
lda X_VELOCITY ; nop ; 3
nop ; 2
lda #24 ; make it 24..87 ; 2
jmp done_hill ; 3
;===========
; 15
right_hill:
lda X_VELOCITY ; 3
eor #$ff ; 2
sta X_VELOCITY ; 3
inc X_VELOCITY ; aim toward middle ; 5
lda #191 ; make it 191..254 ; 2
;===========
; 15
done_hill:
clc ; 2
adc XPOS_L ; 3
sta XPOS_L ; 3
;===========
; 8
lda #YSIZE ; 2
sta YPOS_H ; 3
lda #0 ; fixed point 8:8 ; 2
sta YPOS_L ; start at ground ; 3
lda YPOS_H ; 3
sta PEAK ; peak starts at ground ; 3
lda #1 ; 2
sta CURRENT_STEP ; 3
;===========
; 21
lda #STATE_MOVE_ROCKET ; 2
sta STATE ; move to launch ; 3
rts ; 6
;============
; 11
.align $100
;==========================================================================
; Move rocket
;==========================================================================
; cycles=24+11+20+18+14+53 = 140+1096 = 1236
move_rocket:
; save old values
lda Y_OLD ; 3
sta Y_OLDER ; 3
lda YPOS_H ; 3
sta Y_OLD ; 3
lda X_OLD ; 3
sta X_OLDER ; 3
lda XPOS_L ; 3
sta X_OLD ; 3
;===========
; 24
; Move xpos
lda XPOS_L ; 3
clc ; 2
adc X_VELOCITY ; 3
sta XPOS_L ; 3
;============
; 11
; Move ypos, 16-bit add
clc ; 2
lda YPOS_L ; 3
adc Y_VELOCITY_L ; 3
sta YPOS_L ; 3
lda YPOS_H ; 3
adc Y_VELOCITY_H ; 3
sta YPOS_H ; 3
;===========
; 20
; adjust Y velocity, slow it down
clc ; 2
lda Y_VELOCITY_L ; 3
adc #$20 ; $20 = 0.125 ; 2
sta Y_VELOCITY_L ; 3
lda Y_VELOCITY_H ; 3
adc #0 ; 2
sta Y_VELOCITY_H ; 3
;===========
; 18
; if we went higher, adjust peak
lda YPOS_H ; 3
cmp PEAK ; 3
bcc no_peak_nop ; blt ; 3
;-1
sta PEAK ; 3
jmp no_peak ; 3
no_peak_nop:
nop ; 2
jmp no_peak ; 3
no_peak:
;=============
; 14
;========================================
; Check if out of bounds and stop moving
;========================================
; bcc = 8+7+12+20+6 = 53
; bcs/bcc = 8+7+12+20+6 = 53
; bcs/bcs/bmi = 8+7+5+33 = 53
; bcs/bcs/bpl/bcs = 8+7+5+7+20+6 = 53
; bcs/bcs/bpl/bcc/bcc = 8+7+5+7+20+6 = 53
; bcs/bcs/bpl/bcc/bcs = 8+7+5+7+20+6 = 53
lda XPOS_L ; if (xpos_l<=margin) too far left ; 3
cmp #MARGIN ; 2
bcc done_moving_first ; 3
;===========
; 8
; Due to 256 wraparound, the above will catch this case???
; cmp #XSIZE-MARGIN ; if (xpos_l>=(xsize-margin)) too far right
; bcs done_moving
; -1
lda YPOS_H ; if (ypos_h<=margin) too far up ; 3
cmp #MARGIN ; 2
bcc done_moving_second ; 3
;===========
; 7
;======================
; if falling downward
;======================
; -1
lda Y_VELOCITY_H ; 3
bmi going_up ; if (y_velocity_h>0) ; 3
;============
; 5
; if too close to ground, explode ; -1
lda YPOS_H ; if (ypos_h>=ysize-margin) ; 3
cmp #(YSIZE-MARGIN) ; 2
bcs done_moving_third ; 3
;============
; 7
; if fallen a bit past peak, explode ; -1
sec ; if (ypos_h>ysize-(ysize-peak)/2) ; 2
lda #YSIZE ; 2
sbc PEAK ; 3
lsr ; 2
eor #$FF ; 2
sec ; 2
adc #YSIZE ; 2
cmp YPOS_H ; 3
bcc done_moving ; 3
;===========
; 20
;-1
done_moving_ft:
nop ; 2
nop ; 2
jmp done_bounds_checking ; 3
;===========
; 6
going_up:
; 33 cycles
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
nop ; 2
jmp done_moving_ft ; 3+7
done_moving_first:
; 7 cycles
lda MAX_STEPS ; 3
nop ; 2
nop ; 2
done_moving_second:
; 12 cycles
lda MAX_STEPS ; 3
nop ; 2
lda MAX_STEPS ; 3
nop ; 2
nop ; 2
done_moving_third:
; 20 cycles
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
lda MAX_STEPS ; 3
nop ; 2
done_moving:
lda MAX_STEPS ; 3
sta CURRENT_STEP ; 3
;============
; 6
done_bounds_checking:
;=======================================================================
; draw rocket
;=======================================================================
;
; cs!=mx 9+15+258+258+3+10+258+258+9+7+11 = 1096
; cs==mx 9+ + + + +10+258+258+9+7+11 = 562 (need 534)
draw_rocket:
lda CURRENT_STEP ; 3
cmp MAX_STEPS ; 3
beq skip_drawing_rocket ; 3
;===========
; 9
; set hcolor to proper white (3 or 7)
;-1
clc ; 2
lda COLOR_GROUP ; 3
adc #3 ; 2
tax ; 2
lda colortbl,X ; get color from table ; 4+
sta HGR_COLOR ; 3
;============
; 15
; HPLOT X,Y: X= (y,x), Y=a
ldx X_OLD ; 3
lda Y_OLD ; 3
ldy #0 ; 2
jsr hplot0 ; hplot(x_old,y_old); ;6+244
;=============
; 258
; HPLOT TO X,Y X=(x,a), y=Y
ldx XPOS_L ; 3
ldy #0 ; 2
lda YPOS_H ; 3
jsr hplot0 ;6+244
;=============
; 258
; lda XPOS_L ; 3
; ldx #0 ; 2
; ldy YPOS_H ; 3
; jsr hglin ; hplot_to(xpos_l,ypos_h); ;?????
jmp erase_rocket ; 3
skip_drawing_rocket:
; Try X=7 Y=13 cycles=534
ldy #13 ; 2
sdloop1:ldx #7 ; 2
sdloop2:dex ; 2
bne sdloop2 ; 2nt/3
dey ; 2
bne sdloop1 ; 2nt/3
erase_rocket:
; erase with proper color black (0 or 4)
ldx COLOR_GROUP ; 3
lda colortbl,X ; get color from table ; 4+
sta HGR_COLOR ; 3
;===========
; 10
; HPLOT X,Y: X= (y,x), Y=a
ldx X_OLDER ; 3
lda Y_OLDER ; 3
ldy #0 ; 2
jsr hplot0 ; hplot(x_old,y_old); ; 6+244
;============
; 258
; HPLOT TO X,Y X=(x,a), y=Y
ldx X_OLD ; 3
ldy #0 ; 2
lda Y_OLD ; 3
jsr hplot0 ;6+244
;=============
; 258
; lda X_OLD
; ldx #0
; ldy Y_OLD
; jsr hglin ; hplot_to(x_old,y_old);
done_with_loop:
lda CURRENT_STEP ; 3
cmp MAX_STEPS ; 3
bne not_done_with_launch ; 3
;=============
; 9
;-1
lda #STATE_START_EXPLOSION ; 2
sta STATE ; 3
jmp not_done_with_launch2 ; 3
;==========
; 7
not_done_with_launch:
lda #STATE_STALL_ROCKET ; 2
sta STATE ; 3
nop ; 2
;==========
; 7
not_done_with_launch2:
inc CURRENT_STEP ; 5
rts ; 6
;===========
; 11
.align $100
;======================================================================
; Start explosion near x_old, y_old
;======================================================================
; cycles = 67+16+63+16+258+20 = 440
;
start_explosion:
; Set X position
lda #0 ; 2
sta XPOS_H ; 3
jsr random16 ; 6+42
lda SEEDL ; 3
and #$f ; 0..15 ; 2
sec ; 2
sbc #8 ; -8..7 ; 2
clc ; 2
bmi signextend_neg ; 3
;============
; 67
;-1
adc X_OLD ; 3
sta XPOS_L ; xpos=x_old+(random()%16)-8; x +/- 8 ; 3
lda #0 ; 2
adc XPOS_H ; 3
sta XPOS_H ; 3
jmp exp_sub_done ; 3
;===========
; 16
signextend_neg:
adc X_OLD ; 3
sta XPOS_L ; xpos=x_old+(random()%16)-8; x +/- 8 ; 3
lda #$ff ; 2
adc XPOS_H ; 3
sta XPOS_H ; 3
nop ; 2
;===========
; 16
exp_sub_done:
; set Y position
jsr random16 ; 6+42
lda SEEDL ; 3
and #$f ; 0..15 ; 2
sec ; 2
sbc #8 ; -8..7 ; 2
adc Y_OLD ; 3
sta YPOS_H ; ypos_h=y_old+(random()%16)-8; y +/- 8 ; 3
;============
; 63
; draw white (with fringes)
lda COLOR_GROUP ; 3
clc ; 2
adc #$3 ; 2
tax ; 2
lda colortbl,X ; get color from table ; 4+
sta HGR_COLOR ; 3
;===========
; 16
; hplot(xpos,ypos_h); draw at center of explosion
; HPLOT X,Y: X= (y,x), Y=a
ldx XPOS_L ; 3
lda YPOS_H ; 3
ldy #0 ; never above 255 ; 2
jsr hplot0 ; hplot(x_old,y_old); ; 6+244
;==============
; 258
; Make sound and ready explosion
sound3:
bit SPEAKER ; 4
ldy #1 ; 2
sty FWTEMP ; save Y ; 3
; move to continue explosion
lda #STATE_CONTINUE_EXPLOSION ; 2
sta STATE ; 3
rts ; 6
;=============
; 20
;==========================================================================
; Continue Explosion
;==========================================================================
;
; cycles cpy!=9 : 8+2233+2227+13+5 = 4486
; cpy==9 : 8+ +2227+13+62 = 2310 waste 2176
continue_explosion:
ldy FWTEMP ; 3
;================================
; Draw spreading dots in white
cpy #9 ; 2
beq explosion_erase_waste ; 3
;===========
; 8
; -1
; hcolor_equals(color_group+3);
lda COLOR_GROUP ; 3
clc ; 2
adc #$3 ; 2
tax ; 2
lda colortbl,X ; get color from table ; 4+
sta HGR_COLOR ; 3
ldx FWTEMP ; 3
stx OFFSET ; 3
jsr explosion ; 6+2203
jmp explosion_erase ; 3
;============
; 2233
explosion_erase_waste:
; waste 2176-4 = 2172
sound2:
; bit SPEAKER ; 4
nop
nop
; Try X=47 Y=9 cycles=2170 R2
nop ; 2
ldy #9 ; 2
eeloop1:ldx #47 ; 2
eeloop2:dex ; 2
bne eeloop2 ; 2nt/3
dey ; 2
bne eeloop1 ; 2nt/3
explosion_erase:
;======================
; erase old
; erase with proper color black (0 or 4)
ldx COLOR_GROUP ; 3
lda colortbl,X ; get color from table ; 4+
sta HGR_COLOR ; 3
ldx FWTEMP ; 3
dex ; 2
stx OFFSET ; 3
jsr explosion ; 6+2203
;==============
; 2227
done_with_explosion:
; lda #$c0 ;
; jsr WAIT ;
inc FWTEMP ; 5
lda FWTEMP ; 3
cmp #10 ; 2
beq explosion_done ; 3
;=============
; 13
; -1
rts ; 6
explosion_done:
;==================================
; randomly draw more explosions
;==================================
jsr random16 ; 6+42
lda SEEDL ; 3
and #$4 ; 2
sta STATE ; 3
; if 0, then move to state 0 (start over)
; if 1, then move to state 4 (new random explosion)
rts ; 6
;============
; 62
.align $100
;===============================
; Draw explosion rays
;===============================
;
; Note: the western pixels don't do the full 16-bit math
; as currently it's not possible for those to overflow 256
;
; cycles = 275+275+270+270+272+278+278+279+6=2203
explosion:
; HPLOT X,Y: X= (y,x), Y=a
; Southeast pixel
clc ; 2
lda XPOS_L ; 3
adc OFFSET ; 3
tax ; 2
lda XPOS_H ; 3
adc #0 ; 2
tay ; 2
clc ; 2
lda YPOS_H ; 3
adc OFFSET ; 3
jsr hplot0 ; hplot(xpos+o,ypos_h+o); ; 6+244
;==============
; 275
; Northeast Pixel
clc ; 2
lda XPOS_L ; 3
adc OFFSET ; 3
tax ; 2
lda XPOS_H ; 3
adc #0 ; 2
tay ; 2
sec ; 2
lda YPOS_H ; 3
sbc OFFSET ; 3
jsr hplot0 ; hplot(xpos+o,ypos_h-o); ; 6+244
;==============
; 275
; Northwest Pixel
sec ; 2
lda XPOS_L ; 3
sbc OFFSET ; 3
tax ; 2
ldy #0 ; 2
sec ; 2
lda YPOS_H ; 3
sbc OFFSET ; 3
jsr hplot0 ; hplot(xpos-o,ypos_h-o); NW ; 6+244
;==============
; 270
; Southwest Pixel
sec ; 2
lda XPOS_L ; 3
sbc OFFSET ; 3
tax ; 2
ldy #0 ; 2
clc ; 2
lda YPOS_H ; 3
adc OFFSET ; 3
jsr hplot0 ; hplot(xpos-o,ypos_h+o); SW ; 6+244
;=============
; 270
; HPLOT X,Y: X= (y,x), Y=a
; South Pixel
ldx XPOS_L ; 3
ldy XPOS_H ; 3
clc ; 2
lda OFFSET ; 3
adc OFFSET ; 3
adc OFFSET ; 3
lsr ; 2
adc YPOS_H ; 3
jsr hplot0 ; hplot(xpos,ypos_h+(o*1.5)); S ; 6+244
;=============
; 272
; North Pixel
ldx XPOS_L ; 3
ldy XPOS_H ; 3
clc ; O O*1.5 NEG ; 2
lda OFFSET ; 0 = 0 0 ; 3
adc OFFSET ; 1 = 1 -1 ; 3
adc OFFSET ; 2 = 3 -3 ; 3
lsr ; 3 = 4 -4 ; 2
eor #$FF ; 4 = 6 -6 ; 2
clc ; 2
adc #1 ; 2
adc YPOS_H ; 3
jsr hplot0 ; hplot(xpos,ypos_h-(o*1.5)); N ; 6+244
;==============
; 278
; HPLOT X,Y: X= (y,x), Y=a
; East Pixel
clc ; 2
lda OFFSET ; 3
adc OFFSET ; 3
adc OFFSET ; 3
lsr ; 2
adc XPOS_L ; 3
tax ; 2
lda #0 ; 2
adc XPOS_H ; 3
tay ; 2
lda YPOS_H ; 3
jsr hplot0 ; hplot(xpos+(o*1.5),ypos_h); E ; 6+244
;==============
; 278
; West Pixel
clc ; O O*1.5 NEG ; 2
lda OFFSET ; 0 = 0 0 ; 3
adc OFFSET ; 1 = 1 -1 ; 3
adc OFFSET ; 2 = 3 -3 ; 3
lsr ; 3 = 4 -4 ; 2
eor #$FF ; 4 = 6 -6 ; 2
clc ; 2
adc #1 ; 2
adc XPOS_L ; 3
tax ; 2
ldy #0 ; 2
lda YPOS_H ; 3
jsr hplot0 ; hplot(xpos-(o*1.5),ypos_h); W ; 6+244
;==============
; 279
rts ; 6
;=========================================================================
; Draw the stars
;=========================================================================
; 7+ 280X + 5
; 16 stars = 4492
.align $100
draw_stars:
; HCOLOR = 3, white (though they are drawn purple)
lda #$7f ; 2
sta HGR_COLOR ; 3
ldy #0 ; 2
;===========
; 7
star_loop:
tya ; 2
pha ; 3
; HPLOT X,Y
; X= (y,x), Y=a
ldx stars,Y ; 4+
lda stars+1,Y ; 4+
ldy #0 ; 2
jsr hplot0 ;6+244
pla ; 4
tay ; 2
iny ; 2
iny ; 2
cpy #NUMSTARS*2 ; 2
bne star_loop ; 3
;============
; 279
; -1
rts ; 6
stars: ; even x so they are purple
.byte 28,107, 108, 88, 126, 88, 136, 95
.byte 150,108, 148,120, 172,124, 180,109
.byte 216, 21, 164, 40, 124, 18, 60, 12
.byte 240,124, 94,125, 12, 22, 216,116

View File

@ -0,0 +1,12 @@
bg_final_low: .byte $28 ; ysize=48
.byte $A0,$FF,$22, $A0,$FF,$22, $A0,$FA,$22, $A0,$28,$20, $21, $01,$01, $A8,$00
.byte $01,$01, $AE,$21, $01,$01, $A9,$00, $01,$01, $AE,$00, $01
.byte $A9,$11, $01, $A0,$1F,$00, $01, $A5,$91, $01, $A0,$23,$00
.byte $A3,$0D, $A0,$13,$00
.byte $A1
bg_final_high: .byte $28 ; ysize=48
.byte $A0,$FF,$22, $A0,$FF,$22, $A0,$FA,$22, $A0,$28,$55, $B2, $02,$02, $A8,$00
.byte $02,$02, $AE,$B2, $02,$02, $A9,$00, $02,$02, $AE,$00, $0B
.byte $A9,$1B, $0B, $A0,$1F,$00, $09, $A5,$D9, $09, $A0,$23,$00
.byte $A3,$0D, $A0,$13,$00
.byte $A1

128
megademo/fw_state_machine.s Normal file
View File

@ -0,0 +1,128 @@
;=================================
; action_stars
;=================================
; and take 4504 cycles to do it
; we take 4501, so waste 3
action_stars:
jsr draw_stars ; 6+4492 = 4498
ldy FRAME ;nop ; 3
jmp fw_check_keyboard ; 3
;=================================
; action_launch_firework
;=================================
; and take 4504 cycles to do it
; we take 423 so waste 4081
action_launch_firework:
; Try X=26 Y=30 cycles=4081
ldy #30 ; 2
Xloop1: ldx #26 ; 2
Xloop2: dex ; 2
bne Xloop2 ; 2nt/3
dey ; 2
bne Xloop1 ; 2nt/3
jsr launch_firework ; 6+414 = 420
jmp fw_check_keyboard ; 3
;=================================
; action_move_rocket
;=================================
; and take 4504 cycles to do it
; we take 1245 so waste 3259
action_move_rocket:
; Try X=35 Y=18 cycles=3259
ldy #18 ; 2
Yloop1: ldx #35 ; 2
Yloop2: dex ; 2
bne Yloop2 ; 2nt/3
dey ; 2
bne Yloop1 ; 2nt/3
jsr move_rocket ; 6+1236 = 1242
jmp fw_check_keyboard ; 3
;=================================
; action_start_explosion
;=================================
; and take 4504 cycles to do it
; we take 449 so waste 4055
action_start_explosion:
; Try X=15 Y=50 cycles=4051 R4
nop
nop
ldy #50 ; 2
Zloop1: ldx #15 ; 2
Zloop2: dex ; 2
bne Zloop2 ; 2nt/3
dey ; 2
bne Zloop1 ; 2nt/3
jsr start_explosion ; 6+440 = 446
jmp fw_check_keyboard ; 3
;=================================
; action_continue_explosion
;=================================
; and take 4504 cycles to do it
; we take 4495 so waste 9
action_continue_explosion:
lda STATE ; nop 3
lda STATE ; nop 3
lda STATE ; nop 3
jsr continue_explosion ; 6+4486 = 4492
jmp fw_check_keyboard ; 3
;=================================
; action_stall_rocket
;=================================
; and take 4504 cycles to do it
; 4504 - 8 = 4496
action_stall_rocket:
lda #STATE_MOVE_ROCKET ; 2
sta STATE ; 3
; Try X=12 Y=68 cycles=4489 R7
nop ;
nop ;
lda STATE ;3
ldy #68 ; 2
Bloop1: ldx #12 ; 2
Bloop2: dex ; 2
bne Bloop2 ; 2nt/3
dey ; 2
bne Bloop1 ; 2nt/3
jmp fw_check_keyboard ; 3

280
megademo/hgr.s Normal file
View File

@ -0,0 +1,280 @@
HGR_SHAPE = $1A
HGR_SHAPE_H = $1B
HGR_BITS = $1C
HGR_COUNT = $1D
HMASK = $30
DSCTMP = $9D
HGR_DX = $D0
HGR_DX_H = $D1
HGR_DY = $D2
HGR_QUADRANT = $D3
HGR_E = $D4
HGR_E_H = $D5
HGR_X = $E0
HGR_X_H = $E1
HGR_Y = $E2
;HGR_COLOR = $E4
HGR_HORIZ = $E5
HGR_PAGE = $E6
TXTCLR = $C050
MIXSET = $C053
LOWSCR = $C054
MIXCLR = $C052
HISCR = $C055
.align $100
;==========================
; HGR
;==========================
hgr:
; F3E2
lda #$20 ; HIRES Page 1 at $2000
bit LOWSCR ; BIT SW.LOWSCR Use PAGE1 ($C054)
bit MIXSET ; BIT SW.MIXSET (Mixed text)
sethpg:
; F3EA
sta HGR_PAGE
lda HIRES
lda TXTCLR
hclr:
lda #0 ; black background
sta HGR_BITS
bkgnd:
; F3F6
lda HGR_PAGE
sta HGR_SHAPE+1
ldy #0
sty HGR_SHAPE
bkgnd_loop:
lda HGR_BITS
sta (HGR_SHAPE),y
jsr color_shift
iny
bne bkgnd_loop
inc HGR_SHAPE+1
lda HGR_SHAPE+1
and #$1f ; see if $40 or $60
bne bkgnd_loop
rts
msktbl: .byte $81,$82,$84,$88,$90,$A0,$C0 ; original
;====================================================
; HPOSN
; time = 9 + 61 + 31 + 22 + 42 + 22 + 23 = 210
hposn:
; F411: move values into expected zp locations
sta HGR_Y ; 3
stx HGR_X ; 3
sty HGR_X+1 ; 3
;===========
; 9
; calc y-position addr. no lookup table?
pha ; 3
and #$C0 ; 2
sta GBASL ; 3
lsr ; 2
lsr ; 2
ora GBASL ; 3
sta GBASL ; 3
pla ; 4
sta GBASH ; 3
asl ; 2
asl ; 2
asl ; 2
rol GBASH ; 5
asl ; 2
rol GBASH ; 5
asl ; 2
ror GBASL ; 5
lda GBASH ; 3
and #$1f ; 2
ora HGR_PAGE ; 3
sta GBASH ; 3
;============
; 61
; F438
; divide/mod 16-bit x poisition by 7
; incoming, X=(y,x)
; outgoing y=q, a=r
; Divide by 7 (From December '84 Apple Assembly Line)
txa ; 2
clc ; 2
sta HGR_HORIZ ; 3
lsr ; 2
lsr ; 2
lsr ; 2
adc HGR_HORIZ ; 3
ror ; 2
lsr ; 2
lsr ; 2
adc HGR_HORIZ ; 3
ror ; 2
lsr ; 2
lsr ; 2
; x/7 is in A
;============
; 31
; calculate remainder
clc ; 2
sta HGR_HORIZ ; 3
asl ; 2
adc HGR_HORIZ ; 3
asl ; 2
adc HGR_HORIZ ; 3
; HGR_HORIZ=x/7, A=HGR_HORIZ*7
; calculate remainder by X-(Q*7)
sec ; 2
eor #$ff ; 2
adc HGR_X ; 3
; A = remainder ;===========
; 22
;============================================================================
cpy #0 ; 2
beq done_mod_nop_23 ; 3
;==========
; 5
theres_high:
; -1
clc ; 2
adc #4 ; make remainder match ; 2
pha ; 3
lda HGR_HORIZ ; 3
adc #36 ; 2
sta HGR_HORIZ ; 3
pla ; 4
cmp #7 ; 2
bcc done_mod_nop14 ; blt ; 3
;============
; 23
; -1
sec ; 2
sbc #7 ; 2
inc HGR_HORIZ ; 5
ldy HGR_HORIZ ; nop ; 3
jmp done_mod ; 3
;============
; 14
;===========================
; Y=HIGH,bcc = 5+23+ 14 = 42
; Y=HIGH,bcs = 5+23+ 14 = 42
; Y=LOW = 5 + 14+23 = 42
done_mod_nop_23:
inc HGR_HORIZ,X ; (nop) ; 6
dec HGR_HORIZ,X ; (nop) ; 6
ldy HGR_HORIZ ; (nop) ; 3
ldy HGR_HORIZ ; (nop) ; 3
ldy HGR_HORIZ ; (nop) ; 3
nop ; 2
done_mod_nop14:
inc HGR_HORIZ,X ; (nop) ; 6
dec HGR_HORIZ,X ; (nop) ; 6
nop ; 2
done_mod:
ldy HGR_HORIZ ; 3
tax ; 2
lda msktbl,x ; 4+
sta HMASK ; 3
tya ; 2
lsr ; 2
lda HGR_COLOR ; 3
sta HGR_BITS ; 3
;===========
; 22
bcs color_shift ; 3
; cs = 3+20
;-1
; need 23 = 2+6+X = 15
inc HMASK,X ; nop ; 6
dec HMASK,X ; nop ; 6
lda HMASK ; nop ; 3
rts ; 6
;===========
; 23
;=====================================
; HPLOT0
;=====================================
; point in (YX),A
; 244 cycles
hplot0:
; F457
jsr hposn ; 6+210
lda HGR_BITS ; 3
eor (GBASL),y ; 5+
and HMASK ; 3
eor (GBASL),y ; 5+
sta (GBASL),y ; 6
rts ; 6
;============
; 244
;===================================
; COLOR_SHIFT
;===================================
; positive = 7+(7)+6 = 20
; negative = 7+ 7 +6 = 20
color_shift: ; F47E
asl ; 2
cmp #$c0 ; 2
bpl done_color_shift ; 3
; -1
lda HGR_BITS ; 3
eor #$7f ; 2
sta HGR_BITS ; 3
rts ; 6
done_color_shift:
lda HGR_BITS ; nop ; 3
nop ; 2
nop ; 2
rts ; 6
.align $100
;=============================
; HCOLOR_EQUALS
;=============================
; Color in X
; 13 cycles
hcolor_equals:
; F6E9
; TODO: mask to be less than 8
lda colortbl,x ; 4+
sta HGR_COLOR ; 3
rts ; 6
colortbl:
.byte $00,$2A,$55,$7F,$80,$AA,$D5,$FF

View File

@ -18,7 +18,8 @@
; size=0, checksum=1, reserved
; MAX Blocksize: 40 (64kB)
; HEADER CHECKSUM: a7
; BLOCK HEADER: 4 bytes (le) If highest bit set, uncompressed!
; BLOCK HEADER: 4 bytes (le) length If highest bit set, uncompressed!
; data (see below), followed by checksum?
; BLOCKS:
; Token byte. High 4-bits literal length, low 4-bits copy length
; + If literal length==15, then following byte gets added to length
@ -30,6 +31,11 @@
; 4 added to it. As with the literal length, if it is 15 then
; you read a byte and add (and if that byte is 255, keep adding)
; At end you have 4 byte end-of-block marker (all zeros?) then
; 4 bytes of checksum (if marked in flags)
; our code does that, so be sure to set end -8
;LZ4_SRC EQU $00
;LZ4_DST EQU $02
;LZ4_END EQU $04

View File

@ -11,7 +11,6 @@
;===================
jsr HOME
; C64 Opening Sequence
jsr c64_opener
@ -24,6 +23,25 @@
; E-mail arriving
; Leaving house
; Riding bird
; Waterfall
; Enter ship
; Fly in space
; Arrive
; Fireworks
jsr fireworks
; Game over
game_over_man:
jmp game_over_man
;===================
; Loop Forever
@ -41,3 +59,8 @@ loop_forever:
.include "vapor_lock.s"
.include "delay_a.s"
.include "wait_keypress.s"
.include "random16.s"
.align $100
.include "fireworks.s"
.include "hgr.s"
.include "move_letters.s"

223
megademo/move_letters.s Normal file
View File

@ -0,0 +1,223 @@
;===============================================
; Move Letters
;===============================================
; Normal P0 =6+13+2+22+46+37 = 126
; Normal P1 =6+13+2+22+46+37 = 126
; End of line =6+13+2+22+46+9+(28) = 126
; Next line =6+13+5+14+34+(26+28) = 126
; done entirely =6+13+5+(6+42+26+28) = 126
; Waiting =6+7+(11+6+42+26+28) = 126
; all forced to be 126
move_letters:
ldy WAITING ; 3
beq not_waiting ; 3
;============
; 6
;-1
dec WAITING ; 5
jmp wait_it_out ; 3
;===========
; 7
not_waiting:
; load letter from pointer, save into LETTER
ldy #0 ; 2
lda (LETTERL),Y ; 5
sta LETTER ; 3
; if high bit set, is special case
bmi letter_special ; 3
;==========
; 13
; just regular letter
;-1
lda LETTERY ; get letter Y ; 3
bmi letter_page1
;==========
; 2
letter_page0: ; -1
asl ; map to memory address ; 2
tay ; 2
lda gr_offsets,Y ; lookup low-res memory address ; 4
sta BASL ; store out low byte of addy ; 3
lda gr_offsets+1,Y ; look up high byte ; 4
sta BASH ; 3
lda #0 ; cycle-killer ; 2
jmp letter_erase ; 3
;==========
; 22
letter_page1:
asl ; map to memory address ; 2
tay ; 2
lda gr_offsets,Y ; lookup low-res memory address ; 4
sta BASL ; store out low byte of addy ; 3
lda gr_offsets+1,Y ; look up high byte ; 4
clc ; 2
adc #$4 ; adjust to page1 ; 2
sta BASH ; 3
;==========
; 22
;============================
letter_erase:
ldy LETTERX ; nop ; 3
nop ; nop ; 5
ldy #0 ; erase old char with space ; 2
lda #' '|$80 ; 2
ldy LETTERX ; 3
sta (BASL),Y ; 6
dey ; draw new char ; 2
sty LETTERX ; 3
lda LETTER ; 3
ora #$80 ; 2
ldy LETTERX ; 3
sta (BASL),Y ; 6
lda LETTERX ; see if we are at destination ; 3
cmp LETTERD ; 3
beq letter_next ; 3
;===========
; 46
;-1
lda #0 ; 2
lda #0 ; 2
jmp waste_28 ; 3
;==========
; 9
letter_next:
clc ; 16-bit inc letter pointer ; 2
lda LETTERL ; 3
adc #1 ; 2
sta LETTERL ; 3
lda LETTERH ; 3
adc #0 ; 2
sta LETTERH ; 3
inc LETTERD ; inc destination X ; 5
lda #39 ; start at right of screen ; 2
sta LETTERX ; 3
rts ; 6
;===========
; 37
letter_special:
cmp #$ff ; handle FF, we're done ; 2
beq letter_done ; 3
;==========
; 5
; -1
and #$7f ; clear top ; 2
sta WAITING ; this is waiting value ; 3
ldy #1 ; otherwise, Y,X pair ; 2
lda (LETTERL),Y ; get Y, put in LETTERY ; 5
sta LETTERY ; 3
;===========
; 14
iny ; get dest ; 2
lda (LETTERL),Y ; 5
sta LETTERD ; put in LETTERD ; 3
clc ; skip 3 bytes to begin of letters ; 2
lda LETTERL ; 16-bit add ; 3
adc #3 ; 2
sta LETTERL ; 3
lda LETTERH ; 3
adc #0 ; 2
sta LETTERH ; 3
lda LETTERH ; waste ; 3
jmp waste_26 ; 3
;===========
; 34
wait_it_out:
; wait 11
inc BLARGH ; 5
lda LETTERH ; 3
lda LETTERH ; 3
letter_done:
lda LETTERH ; 3
lda LETTERH ; 3
waste_42:
ldx #0 ; 2
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
waste_26:
ldx #0 ; 2
ldx #0 ; 2
ldx #0 ; 2
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
waste_28:
ldx #0 ; 2
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
inc BLARGH ; 5
rts ; 6
letters:
; .byte 22,28,
.byte " ",128
.byte 22+128,25," ",128
.byte 23,25, " ",128
.byte 23+128,25," ",128
.byte 22,26, "CODE BY",128
.byte 22+128,26,"CODE BY",128
.byte 23,26, "DEATER",128
.byte 23+128,26,"DEATER",198
.byte 22,26, " ",128
.byte 22+128,26," ",128
.byte 23,26, " ",128
.byte 23+128,26," ",128
.byte 22,26, "FIREWORKS",128
.byte 22+128,26,"FIREWORKS",128
.byte 23,26, "FOZZTEXX",128
.byte 23+128,26,"FOZZTEXX",198
.byte 22,26, " ",128
.byte 22+128,26," ",128
.byte 23,26, " ",128
.byte 23+128,26," ",128
.byte 22,26,"A VMW",128
.byte 22+128,26,"A VMW",128
.byte 23,26,"PRODUCTION",128
.byte 23+128,26,"PRODUCTION"
.byte 255

119
megademo/random16.s Normal file
View File

@ -0,0 +1,119 @@
; 16-bit 6502 Random Number Generator (cycle-invariant version)
; Linear feedback shift register PRNG by White Flame
; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng
; The Apple II KEYIN routine increments SEEDL:SEEDH
; while waiting for keypress
SEEDL = $4E
SEEDH = $4F
XOR_MAGIC = $7657 ; "vW"
;=============================
; random16
;=============================
; takes:
; not 0, cs = 6(r16)+12(lnz)+5(nop)+ 19(deo) = 42
; not 0, cc = 6(r16)+14(lnz)+2(nop)+ 20(neo) = 42
; $0000 = 6(r16)+ 6(loz)+11nops+ 19(deo) = 42
; $8000 = 6(r16)+ 6(loz)+ 4(ceo) + 6nops+ 20(neo) = 42
; $XX00 cc = 6(r16)+ 6(loz)+4(ceo)+2(cep) +4nops+ 20(neo) = 42
; $XX00 cs = 6(r16)+ 6(loz)+4(ceo)+4(cep) +3nops+ 19(deo) = 42*
random16:
lda SEEDL ; 3
beq low_zero ; $0000 and $8000 are special values ; 3
;==========
; 6
lownz:
; -1
asl SEEDL ; Do a normal shift ; 5
lda SEEDH ; 3
rol ; 2
bcs five_cycle_do_eor ; 3
;===========
; 12
bcc two_cycle_no_eor ; 3
;==========
; 12+3-1 = 14
;===================================================================
eleven_cycle_do_eor:
nop ; 2
nop ; 2
nop ; 2
five_cycle_do_eor:
nop ; 2
three_cycle_do_eor:
sta SEEDH ; nop ; 3
do_eor:
; high byte is in A
eor #>XOR_MAGIC ; 2
sta SEEDH ; 3
lda SEEDL ; 3
eor #<XOR_MAGIC ; 2
sta SEEDL ; 3
eor_rts:
rts ; 6
;===========
; 19
;=========================================================================
six_cycles_no_eor:
nop ; 2
four_cycle_no_eor:
nop ; 2
two_cycle_no_eor:
nop ; 2
no_eor:
nop ; 2
nop ; 2
nop ; 2
nop ; 2
sta SEEDH ; 3
jmp eor_rts ; 3+6
;===========
; 20
;======================================================================
;======================================================================
low_zero:
lda SEEDH ; 3
beq eleven_cycle_do_eor ; High byte is also zero ; 3
; so apply the EOR
;============
; 6
ceo:
; -1
; wasn't zero, check for $8000
asl ; 2
beq six_cycles_no_eor ; if $00 is left after the shift; 3
; then it was $80
;===========
; 4
; else, do the EOR based on the carry
cep:
; -1
bcc four_cycle_no_eor ; 3
;============
; 2
bcs three_cycle_do_eor ; 2+3-1 = 4