mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-11-18 21:06:31 +00:00
interlace: add rasterbars_sound demo
This commit is contained in:
parent
bc93edf06b
commit
aa1ad5752a
@ -7,11 +7,12 @@ PNG_TO_40x48D = ../gr-utils/png_to_40x48d
|
||||
|
||||
all: interlace.dsk
|
||||
|
||||
interlace.dsk: INTERLACE RASTERBARS SPRITES HELLO
|
||||
interlace.dsk: INTERLACE RASTERBARS SPRITES HELLO RASTERBARS_SOUND
|
||||
$(DOS33) -y interlace.dsk SAVE A HELLO
|
||||
$(DOS33) -y interlace.dsk BSAVE -a 0x1000 INTERLACE
|
||||
$(DOS33) -y interlace.dsk BSAVE -a 0x1000 RASTERBARS
|
||||
$(DOS33) -y interlace.dsk BSAVE -a 0x1000 SPRITES
|
||||
$(DOS33) -y interlace.dsk BSAVE -a 0x1000 RASTERBARS_SOUND
|
||||
|
||||
####
|
||||
|
||||
@ -39,6 +40,17 @@ rasterbars.o: rasterbars.s gr_copy.s \
|
||||
|
||||
####
|
||||
|
||||
RASTERBARS_SOUND: rasterbars_sound.o
|
||||
ld65 -o RASTERBARS_SOUND rasterbars_sound.o -C ../linker_scripts/apple2_1000.inc
|
||||
|
||||
rasterbars_sound.o: rasterbars_sound.s gr_copy.s \
|
||||
rasterbars_screen.s rasterbars_table.s movement_table.s rb_bg.inc \
|
||||
pt3_lib.s interrupt_handler.s
|
||||
ca65 -o rasterbars_sound.o rasterbars_sound.s -l rasterbars_sound.lst
|
||||
|
||||
|
||||
####
|
||||
|
||||
SPRITES: sprites.o
|
||||
ld65 -o SPRITES sprites.o -C ../linker_scripts/apple2_1000.inc
|
||||
|
||||
@ -66,4 +78,4 @@ install:
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o *.lst INTERLACE RASTERBARS SPRITES HELLO
|
||||
rm -f *~ *.o *.lst INTERLACE RASTERBARS SPRITES HELLO RASTERBARS_SOUND
|
||||
|
115
interlace_demo/gr_unrle.s
Normal file
115
interlace_demo/gr_unrle.s
Normal file
@ -0,0 +1,115 @@
|
||||
;=================
|
||||
; load RLE image
|
||||
;=================
|
||||
; Output is BASH/BASL
|
||||
; Input is in GBASH/GBASL
|
||||
load_rle_gr:
|
||||
lda #$0
|
||||
tay ; init Y to 0
|
||||
sta TEMP ; stores the xcoord
|
||||
|
||||
sta CV ; ycoord=0
|
||||
|
||||
jsr load_and_increment ; load xsize
|
||||
sta CH
|
||||
|
||||
rle_loop:
|
||||
jsr load_and_increment
|
||||
|
||||
cmp #$A1 ; if 0xa1
|
||||
beq rle_done ; we are done
|
||||
|
||||
pha
|
||||
|
||||
and #$f0 ; mask
|
||||
cmp #$a0 ; see if special AX
|
||||
beq decompress_special
|
||||
|
||||
pla ; note, PLA sets flags!
|
||||
|
||||
ldx #$1 ; only want to print 1
|
||||
bne decompress_run
|
||||
|
||||
decompress_special:
|
||||
pla
|
||||
|
||||
and #$0f ; check if was A0
|
||||
|
||||
bne decompress_color ; if A0 need to read run, color
|
||||
|
||||
decompress_large:
|
||||
jsr load_and_increment ; get run length
|
||||
|
||||
decompress_color:
|
||||
tax ; put runlen into X
|
||||
jsr load_and_increment ; get color
|
||||
|
||||
decompress_run:
|
||||
rle_run_loop:
|
||||
sta (BASL),y ; write out the value
|
||||
inc BASL ; increment the pointer
|
||||
bne rle_skip3 ; if wrapped
|
||||
inc BASH ; then increment the high value
|
||||
|
||||
rle_skip3:
|
||||
pha ; store colore for later
|
||||
|
||||
inc TEMP ; increment the X value
|
||||
lda TEMP
|
||||
cmp CH ; compare against the image width
|
||||
bcc rle_not_eol ; if less then keep going
|
||||
|
||||
lda BASL ; cheat to avoid a 16-bit add
|
||||
cmp #$a7 ; we are adding 0x58 to get
|
||||
bcc rle_add_skip ; to the next line
|
||||
inc BASH
|
||||
rle_add_skip:
|
||||
clc
|
||||
adc #$58 ; actually do the 0x58 add
|
||||
sta BASL ; and store it back
|
||||
|
||||
inc CV ; add 2 to ypos
|
||||
inc CV ; each "line" is two high
|
||||
|
||||
lda CV ; load value
|
||||
cmp #15 ; if it's greater than 14 it wraps
|
||||
bcc rle_no_wrap ; Thanks Woz
|
||||
|
||||
lda #$0 ; we wrapped, so set to zero
|
||||
sta CV
|
||||
|
||||
; when wrapping have to sub 0x3d8
|
||||
sec ; this is a 16-bit subtract routine
|
||||
lda BASL
|
||||
sbc #$d8 ; LSB
|
||||
sta BASL
|
||||
lda BASH ; MSB
|
||||
sbc #$3 ;
|
||||
sta BASH
|
||||
|
||||
rle_no_wrap:
|
||||
lda #$0 ; set X value back to zero
|
||||
sta TEMP
|
||||
|
||||
rle_not_eol:
|
||||
pla ; restore color
|
||||
dex
|
||||
bne rle_run_loop ; if not zero, keep looping
|
||||
beq rle_loop ; and branch always
|
||||
|
||||
rle_done:
|
||||
lda #$15 ; move the cursor somewhere sane
|
||||
sta CV
|
||||
rts
|
||||
|
||||
|
||||
load_and_increment:
|
||||
lda (GBASL),y ; load value ; 5?
|
||||
inc GBASL ; 5?
|
||||
bne lskip2 ; 2nt/3
|
||||
inc GBASH ; 5?
|
||||
lskip2:
|
||||
rts ; 6
|
||||
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
10 PRINT "INTERLACE V0.2"
|
||||
100 PRINT CHR$ (4)"BRUN RASTERBARS"
|
||||
10 PRINT "INTERLACE V0.3"
|
||||
100 PRINT CHR$ (4)"BRUN RASTERBARS_SOUND"
|
||||
|
170
interlace_demo/interrupt_handler.s
Normal file
170
interlace_demo/interrupt_handler.s
Normal file
@ -0,0 +1,170 @@
|
||||
;================================
|
||||
;================================
|
||||
; mockingboard interrupt handler
|
||||
;================================
|
||||
;================================
|
||||
; On Apple II/6502 the interrupt handler jumps to address in 0xfffe
|
||||
; This is in the ROM, which saves the registers
|
||||
; on older IIe it saved A to $45 (which could mess with DISK II)
|
||||
; newer IIe doesn't do that.
|
||||
; It then calculates if it is a BRK or not (which trashes A)
|
||||
; Then it sets up the stack like an interrupt and calls 0x3fe
|
||||
|
||||
; Note: the IIc is much more complicated
|
||||
; its firmware tries to decode the proper source
|
||||
; based on various things, including screen hole values
|
||||
; we bypass that by switching out ROM and replacing the
|
||||
; $fffe vector with this, but that does mean we have
|
||||
; to be sure status flag and accumulator set properly
|
||||
|
||||
|
||||
interrupt_handler:
|
||||
php
|
||||
pha ; save A ; 3
|
||||
; A is saved in $45 by firmware
|
||||
txa
|
||||
pha ; save X
|
||||
tya
|
||||
pha ; save Y
|
||||
|
||||
|
||||
|
||||
; inc $0404 ; debug (flashes char onscreen)
|
||||
|
||||
bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4
|
||||
|
||||
lda DONE_PLAYING ; 3
|
||||
beq pt3_play_music ; if song done, don't play music ; 3/2nt
|
||||
jmp exit_interrupt ; 3
|
||||
|
||||
pt3_play_music:
|
||||
|
||||
; decode a frame of music
|
||||
|
||||
jsr pt3_make_frame
|
||||
|
||||
; handle song over condition
|
||||
lda DONE_SONG
|
||||
beq mb_write_frame ; if not done, continue
|
||||
|
||||
lda LOOP ; see if looping
|
||||
beq move_to_next
|
||||
|
||||
pt3_loop_smc:
|
||||
lda #$d1 ; looping, move to loop location
|
||||
; non-zero to avoid the temptation
|
||||
; to merge with following lda #$0
|
||||
sta current_pattern_smc+1
|
||||
lda #$0
|
||||
sta current_line_smc+1
|
||||
sta current_subframe_smc+1
|
||||
sta DONE_SONG ; undo the next song
|
||||
|
||||
beq done_interrupt ; branch always
|
||||
|
||||
move_to_next:
|
||||
; same as "press right"
|
||||
ldx #$20
|
||||
jmp quiet_exit
|
||||
|
||||
;======================================
|
||||
; Write frames to Mockingboard
|
||||
;======================================
|
||||
; for speed could merge this into
|
||||
; the decode code
|
||||
|
||||
mb_write_frame:
|
||||
|
||||
|
||||
tax ; set up reg count ; 2
|
||||
;============
|
||||
; 2
|
||||
|
||||
;==================================
|
||||
; loop through the 14 registers
|
||||
; reading the value, then write out
|
||||
;==================================
|
||||
|
||||
mb_write_loop:
|
||||
lda AY_REGISTERS,X ; load register value ; 4
|
||||
|
||||
; special case R13. If it is 0xff, then don't update
|
||||
; otherwise might spuriously reset the envelope settings
|
||||
|
||||
cpx #13 ; 2
|
||||
bne mb_not_13 ; 3/2nt
|
||||
cmp #$ff ; 2
|
||||
beq mb_skip_13 ; 3/2nt
|
||||
;============
|
||||
; typ 5
|
||||
mb_not_13:
|
||||
|
||||
|
||||
; address
|
||||
stx MOCK_6522_ORA1 ; put address on PA1 ; 4
|
||||
stx MOCK_6522_ORA2 ; put address on PA2 ; 4
|
||||
ldy #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
|
||||
sty MOCK_6522_ORB1 ; latch_address on PB1 ; 4
|
||||
sty MOCK_6522_ORB2 ; latch_address on PB2 ; 4
|
||||
ldy #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||
sty MOCK_6522_ORB1 ; 4
|
||||
sty MOCK_6522_ORB2 ; 4
|
||||
|
||||
; value
|
||||
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
|
||||
sta MOCK_6522_ORA2 ; put value on PA2 ; 4
|
||||
lda #MOCK_AY_WRITE ; ; 2
|
||||
sta MOCK_6522_ORB1 ; write on PB1 ; 4
|
||||
sta MOCK_6522_ORB2 ; write on PB2 ; 4
|
||||
sty MOCK_6522_ORB1 ; 4
|
||||
sty MOCK_6522_ORB2 ; 4
|
||||
;===========
|
||||
; 56
|
||||
mb_no_write:
|
||||
inx ; point to next register ; 2
|
||||
cpx #14 ; if 14 we're done ; 2
|
||||
bmi mb_write_loop ; otherwise, loop ; 3/2nt
|
||||
;============
|
||||
; 7
|
||||
mb_skip_13:
|
||||
|
||||
|
||||
|
||||
; stop playing for now
|
||||
; quiet down the Mockingboard
|
||||
; (otherwise will be stuck on last note)
|
||||
|
||||
quiet_exit:
|
||||
stx DONE_PLAYING
|
||||
jsr clear_ay_both
|
||||
|
||||
;ldx #$ff ; also mute the channel
|
||||
stx AY_REGISTERS+7 ; just in case
|
||||
|
||||
;=================================
|
||||
; Finally done with this interrupt
|
||||
;=================================
|
||||
|
||||
done_interrupt:
|
||||
|
||||
exit_interrupt:
|
||||
|
||||
pla
|
||||
tay ; restore Y
|
||||
pla
|
||||
tax ; restore X
|
||||
|
||||
pla ; restore a ; 4
|
||||
|
||||
; this is needed on II+/IIe not not IIc
|
||||
interrupt_smc:
|
||||
lda $45 ; restore A
|
||||
plp
|
||||
|
||||
rti ; return from interrupt ; 6
|
||||
|
||||
;============
|
||||
; typical
|
||||
; ???? cycles
|
||||
|
||||
|
240
interlace_demo/mockingboard_a.s
Normal file
240
interlace_demo/mockingboard_a.s
Normal file
@ -0,0 +1,240 @@
|
||||
; Mockingboad programming:
|
||||
; + Has two 6522 I/O chips connected to two AY-3-8910 chips
|
||||
; + Optionally has some speech chips controlled via the outport on the AY
|
||||
; + Often in slot 4
|
||||
; TODO: how to auto-detect?
|
||||
; References used:
|
||||
; http://macgui.com/usenet/?group=2&id=8366
|
||||
; 6522 Data Sheet
|
||||
; AY-3-8910 Data Sheet
|
||||
|
||||
;========================
|
||||
; Mockingboard card
|
||||
; Essentially two 6522s hooked to the Apple II bus
|
||||
; Connected to AY-3-8910 chips
|
||||
; PA0-PA7 on 6522 connected to DA0-DA7 on AY
|
||||
; PB0 on 6522 connected to BC1
|
||||
; PB1 on 6522 connected to BDIR
|
||||
; PB2 on 6522 connected to RESET
|
||||
|
||||
|
||||
; left speaker
|
||||
MOCK_6522_ORB1 = $C400 ; 6522 #1 port b data
|
||||
MOCK_6522_ORA1 = $C401 ; 6522 #1 port a data
|
||||
MOCK_6522_DDRB1 = $C402 ; 6522 #1 data direction port B
|
||||
MOCK_6522_DDRA1 = $C403 ; 6522 #1 data direction port A
|
||||
|
||||
; right speaker
|
||||
MOCK_6522_ORB2 = $C480 ; 6522 #2 port b data
|
||||
MOCK_6522_ORA2 = $C481 ; 6522 #2 port a data
|
||||
MOCK_6522_DDRB2 = $C482 ; 6522 #2 data direction port B
|
||||
MOCK_6522_DDRA2 = $C483 ; 6522 #2 data direction port A
|
||||
|
||||
; AY-3-8910 commands on port B
|
||||
; RESET BDIR BC1
|
||||
MOCK_AY_RESET = $0 ; 0 0 0
|
||||
MOCK_AY_INACTIVE = $4 ; 1 0 0
|
||||
MOCK_AY_READ = $5 ; 1 0 1
|
||||
MOCK_AY_WRITE = $6 ; 1 1 0
|
||||
MOCK_AY_LATCH_ADDR = $7 ; 1 1 1
|
||||
|
||||
|
||||
;========================
|
||||
; Mockingboard Init
|
||||
;========================
|
||||
; Initialize the 6522s
|
||||
; set the data direction for all pins of PortA/PortB to be output
|
||||
|
||||
mockingboard_init:
|
||||
lda #$ff ; all output (1)
|
||||
sta MOCK_6522_DDRB1
|
||||
sta MOCK_6522_DDRA1
|
||||
sta MOCK_6522_DDRB2
|
||||
sta MOCK_6522_DDRA2
|
||||
rts
|
||||
|
||||
;======================
|
||||
; Reset Left AY-3-8910
|
||||
;======================
|
||||
reset_ay_both:
|
||||
lda #MOCK_AY_RESET
|
||||
sta MOCK_6522_ORB1
|
||||
lda #MOCK_AY_INACTIVE
|
||||
sta MOCK_6522_ORB1
|
||||
|
||||
;======================
|
||||
; Reset Right AY-3-8910
|
||||
;======================
|
||||
;reset_ay_right:
|
||||
;could be merged with both
|
||||
lda #MOCK_AY_RESET
|
||||
sta MOCK_6522_ORB2
|
||||
lda #MOCK_AY_INACTIVE
|
||||
sta MOCK_6522_ORB2
|
||||
rts
|
||||
|
||||
|
||||
;=======================================
|
||||
; clear ay -- clear all 14 AY registers
|
||||
; should silence the card
|
||||
;=======================================
|
||||
clear_ay_both:
|
||||
ldx #14
|
||||
lda #0
|
||||
sta MB_VALUE_smc+1
|
||||
clear_ay_left_loop:
|
||||
; Write sequence
|
||||
; Inactive -> Latch Address -> Inactive -> Write Data -> Inactive
|
||||
|
||||
;=========================================
|
||||
; Write Right/Left to save value AY-3-8910
|
||||
;=========================================
|
||||
; register in X
|
||||
; value in MB_VALUE
|
||||
|
||||
write_ay_both:
|
||||
; address
|
||||
stx MOCK_6522_ORA1 ; put address on PA1 ; 3
|
||||
stx MOCK_6522_ORA2 ; put address on PA2 ; 3
|
||||
lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2
|
||||
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 3
|
||||
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 3
|
||||
ldy #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||
sty MOCK_6522_ORB1 ; 3
|
||||
sty MOCK_6522_ORB2 ; 3
|
||||
|
||||
; value
|
||||
MB_VALUE_smc:
|
||||
lda #$d1 ; 2
|
||||
sta MOCK_6522_ORA1 ; put value on PA1 ; 3
|
||||
sta MOCK_6522_ORA2 ; put value on PA2 ; 3
|
||||
lda #MOCK_AY_WRITE ; ; 2
|
||||
sta MOCK_6522_ORB1 ; write on PB1 ; 3
|
||||
sta MOCK_6522_ORB2 ; write on PB2 ; 3
|
||||
sty MOCK_6522_ORB1 ; 3
|
||||
sty MOCK_6522_ORB2 ; 3
|
||||
|
||||
;===========
|
||||
; 44
|
||||
dex
|
||||
bpl clear_ay_left_loop
|
||||
rts
|
||||
|
||||
;=======================================
|
||||
; Detect a Mockingboard card
|
||||
;=======================================
|
||||
; Based on code from the French Touch "Pure Noise" Demo
|
||||
; Attempts to time an instruction sequence with a 6522
|
||||
;
|
||||
; If found, puts in bMB
|
||||
; MB_ADDRL:MB_ADDRH has address of Mockingboard
|
||||
; returns X=0 if not found, X=1 if found
|
||||
|
||||
mockingboard_detect:
|
||||
lda #0
|
||||
sta MB_ADDRL
|
||||
|
||||
mb_detect_loop: ; self-modifying
|
||||
lda #$07 ; we start in slot 7 ($C7) and go down to 0 ($C0)
|
||||
ora #$C0 ; make it start with C
|
||||
sta MB_ADDRH
|
||||
ldy #04 ; $CX04
|
||||
ldx #02 ; 2 tries?
|
||||
mb_check_cycle_loop:
|
||||
lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter)
|
||||
; count down
|
||||
sta TEMP ; 3 cycles
|
||||
lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles
|
||||
; between the two accesses to the timer
|
||||
sec
|
||||
sbc TEMP ; subtract to see if we had 8 cycles
|
||||
cmp #$f8 ; -8
|
||||
bne mb_not_in_this_slot
|
||||
dex ; decrement, try one more time
|
||||
bne mb_check_cycle_loop ; loop detection
|
||||
inx ; Mockingboard found (X=1)
|
||||
done_mb_detect:
|
||||
;stx bMB ; store result to bMB
|
||||
rts ; return
|
||||
|
||||
mb_not_in_this_slot:
|
||||
dec mb_detect_loop+1 ; decrement the "slot" (self_modify)
|
||||
bne mb_detect_loop ; loop down to one
|
||||
ldx #00
|
||||
beq done_mb_detect
|
||||
|
||||
;alternative MB detection from Nox Archaist
|
||||
; lda #$04
|
||||
; sta MB_ADDRL
|
||||
; ldx #$c7
|
||||
;
|
||||
;find_mb:
|
||||
; stx MB_ADDRH
|
||||
;
|
||||
; ;detect sound I
|
||||
;
|
||||
; sec
|
||||
; ldy #$00
|
||||
; lda (MB_ADDRL), y
|
||||
; sbc (MB_ADDRL), y
|
||||
; cmp #$05
|
||||
; beq found_mb
|
||||
; dex
|
||||
; cpx #$c0
|
||||
; bne find_mb
|
||||
; ldx #$00 ;no mockingboard found
|
||||
; rts
|
||||
;
|
||||
;found_mb:
|
||||
; ldx #$01 ;mockingboard found
|
||||
; rts
|
||||
;
|
||||
; ;optionally detect sound II
|
||||
;
|
||||
; sec
|
||||
; ldy #$80
|
||||
; lda (MB_ADDRL), y
|
||||
; sbc (MB_ADDRL), y
|
||||
; cmp #$05
|
||||
; beq found_mb
|
||||
|
||||
|
||||
;=======================================
|
||||
; Detect a Mockingboard card in Slot4
|
||||
;=======================================
|
||||
; Based on code from the French Touch "Pure Noise" Demo
|
||||
; Attempts to time an instruction sequence with a 6522
|
||||
;
|
||||
; MB_ADDRL:MB_ADDRH has address of Mockingboard
|
||||
; returns X=0 if not found, X=1 if found
|
||||
|
||||
mockingboard_detect_slot4:
|
||||
lda #0
|
||||
sta MB_ADDRL
|
||||
|
||||
mb4_detect_loop: ; self-modifying
|
||||
lda #$04 ; we're only looking in Slot 4
|
||||
ora #$C0 ; make it start with C
|
||||
sta MB_ADDRH
|
||||
ldy #04 ; $CX04
|
||||
ldx #02 ; 2 tries?
|
||||
mb4_check_cycle_loop:
|
||||
lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter)
|
||||
; count down
|
||||
sta TEMP ; 3 cycles
|
||||
lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles
|
||||
; between the two accesses to the timer
|
||||
sec
|
||||
sbc TEMP ; subtract to see if we had 8 cycles
|
||||
cmp #$f8 ; -8
|
||||
bne mb4_not_in_this_slot
|
||||
dex ; decrement, try one more time
|
||||
bne mb4_check_cycle_loop ; loop detection
|
||||
inx ; Mockingboard found (X=1)
|
||||
done_mb4_detect:
|
||||
rts ; return
|
||||
|
||||
mb4_not_in_this_slot:
|
||||
ldx #00
|
||||
beq done_mb4_detect
|
||||
|
2333
interlace_demo/pt3_lib.s
Normal file
2333
interlace_demo/pt3_lib.s
Normal file
File diff suppressed because it is too large
Load Diff
447
interlace_demo/rasterbars_sound.s
Normal file
447
interlace_demo/rasterbars_sound.s
Normal file
@ -0,0 +1,447 @@
|
||||
; Uses the 40x48d page1/page2 every-1-scanline pageflip mode
|
||||
|
||||
; self modifying code to get some extra colors (pseudo 40x192 mode)
|
||||
|
||||
; try adding some sound support
|
||||
|
||||
; by deater (Vince Weaver) <vince@deater.net>
|
||||
|
||||
.include "zp.inc"
|
||||
.include "hardware.inc"
|
||||
|
||||
PT3_LOC = song
|
||||
|
||||
start_rasterbars:
|
||||
|
||||
;===================
|
||||
; init screen
|
||||
jsr TEXT
|
||||
jsr HOME
|
||||
bit KEYRESET
|
||||
|
||||
;===================
|
||||
; init vars
|
||||
|
||||
lda #0
|
||||
sta DRAW_PAGE
|
||||
|
||||
;=============================
|
||||
; Load graphic page0
|
||||
|
||||
lda #$0c
|
||||
sta BASH
|
||||
lda #$00
|
||||
sta BASL ; load image to $c00
|
||||
|
||||
ldy #0
|
||||
|
||||
lda pictures,Y
|
||||
sta GBASL
|
||||
lda pictures+1,Y
|
||||
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
|
||||
|
||||
ldy #0
|
||||
|
||||
lda pictures+2,Y
|
||||
sta GBASL
|
||||
lda pictures+3,Y
|
||||
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
|
||||
|
||||
; vapor lock returns with us at beginning of hsync in line
|
||||
; 114 (7410 cycles), so with 5070 lines to go
|
||||
|
||||
; GR part
|
||||
bit LORES ; 4
|
||||
bit SET_GR ; 4
|
||||
bit FULLGR ; 4
|
||||
|
||||
jsr gr_copy_to_current ; 6+ 9292
|
||||
|
||||
; 5070 + 4550 = 9620
|
||||
; 9292
|
||||
; 12
|
||||
; 6
|
||||
; ====
|
||||
; 310
|
||||
|
||||
; - 3 for jmp
|
||||
; 307
|
||||
|
||||
; Try X=9 Y=6 cycles=307
|
||||
|
||||
ldy #6 ; 2
|
||||
loopA: ldx #9 ; 2
|
||||
loopB: dex ; 2
|
||||
bne loopB ; 2nt/3
|
||||
dey ; 2
|
||||
bne loopA ; 2nt/3
|
||||
|
||||
jmp 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
|
||||
|
||||
|
||||
display_loop:
|
||||
|
||||
.include "rasterbars_screen.s"
|
||||
|
||||
;======================================================
|
||||
; We have 4550 cycles in the vblank, use them wisely
|
||||
;======================================================
|
||||
|
||||
; 4550 -- VBLANK
|
||||
; -582 -- erase 22+4*(8+6+126) = 582
|
||||
; -696 -- move+draw 4*(16+26+6+126) = 696
|
||||
; -10 -- keypress
|
||||
;=======
|
||||
; 3262
|
||||
|
||||
pad_time:
|
||||
|
||||
; we erase, then draw
|
||||
; doing a blanket erase of all 128 lines would cost 3459 cycles!
|
||||
|
||||
;=========================
|
||||
; ERASE
|
||||
;=========================
|
||||
|
||||
lda #$00 ; 2
|
||||
sta smc_raster_color1_1+1 ; 4
|
||||
sta smc_raster_color1_2+1 ; 4
|
||||
sta smc_raster_color2_1+1 ; 4
|
||||
sta smc_raster_color2_2+1 ; 4
|
||||
sta smc_raster_color3_1+1 ; 4
|
||||
;=============
|
||||
; 22
|
||||
|
||||
; erase red
|
||||
|
||||
lda red_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
; erase yellow
|
||||
|
||||
lda yellow_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
; erase green
|
||||
|
||||
lda green_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
; erase red
|
||||
|
||||
lda blue_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
|
||||
;=========================
|
||||
; MOVE and DRAW
|
||||
;=========================
|
||||
|
||||
|
||||
;============
|
||||
; move red
|
||||
|
||||
ldy red_x ; 4
|
||||
lda movement_table,Y ; 4
|
||||
sta red_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
;==========
|
||||
; 16
|
||||
|
||||
; draw red
|
||||
|
||||
lda #$33 ; 2
|
||||
sta smc_raster_color1_1+1 ; 4
|
||||
sta smc_raster_color1_2+1 ; 4
|
||||
lda #$bb ; 2
|
||||
sta smc_raster_color2_1+1 ; 4
|
||||
sta smc_raster_color2_2+1 ; 4
|
||||
lda #$ff ; 2
|
||||
sta smc_raster_color3_1+1 ; 4
|
||||
;=============
|
||||
; 26
|
||||
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
|
||||
;============
|
||||
; move yellow
|
||||
|
||||
ldy yellow_x ; 4
|
||||
lda movement_table,Y ; 4
|
||||
sta yellow_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
;==========
|
||||
; 16
|
||||
|
||||
; draw yellow
|
||||
|
||||
lda #$88 ; 2
|
||||
sta smc_raster_color1_1+1 ; 4
|
||||
sta smc_raster_color1_2+1 ; 4
|
||||
lda #$dd ; 2
|
||||
sta smc_raster_color2_1+1 ; 4
|
||||
sta smc_raster_color2_2+1 ; 4
|
||||
lda #$ff ; 2
|
||||
sta smc_raster_color3_1+1 ; 4
|
||||
;=============
|
||||
; 26
|
||||
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
;============
|
||||
; move green
|
||||
|
||||
ldy green_x ; 4
|
||||
lda movement_table,Y ; 4
|
||||
sta green_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
;==========
|
||||
; 16
|
||||
|
||||
; draw green
|
||||
|
||||
lda #$44 ; 2
|
||||
sta smc_raster_color1_1+1 ; 4
|
||||
sta smc_raster_color1_2+1 ; 4
|
||||
lda #$cc ; 2
|
||||
sta smc_raster_color2_1+1 ; 4
|
||||
sta smc_raster_color2_2+1 ; 4
|
||||
lda #$ff ; 2
|
||||
sta smc_raster_color3_1+1 ; 4
|
||||
;=============
|
||||
; 26
|
||||
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
;============
|
||||
; move blue
|
||||
|
||||
ldy blue_x ; 4
|
||||
lda movement_table,Y ; 4
|
||||
sta blue_x ; 4
|
||||
and #$7f ; 2
|
||||
tax ; 2
|
||||
;==========
|
||||
; 16
|
||||
|
||||
; draw blue
|
||||
|
||||
lda #$22 ; 2
|
||||
sta smc_raster_color1_1+1 ; 4
|
||||
sta smc_raster_color1_2+1 ; 4
|
||||
lda #$66 ; 2
|
||||
sta smc_raster_color2_1+1 ; 4
|
||||
sta smc_raster_color2_2+1 ; 4
|
||||
lda #$ff ; 2
|
||||
sta smc_raster_color3_1+1 ; 4
|
||||
;=============
|
||||
; 26
|
||||
|
||||
|
||||
jsr draw_rasterbar ; 6+126
|
||||
|
||||
|
||||
|
||||
|
||||
;============================
|
||||
; WAIT for VBLANK to finish
|
||||
;============================
|
||||
; Try X=5 Y=105 cycles=3256 R6
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
ldy #105 ; 2
|
||||
loop1: ldx #5 ; 2
|
||||
loop2: dex ; 2
|
||||
bne loop2 ; 2nt/3
|
||||
dey ; 2
|
||||
bne loop1 ; 2nt/3
|
||||
|
||||
|
||||
lda KEYPRESS ; 4
|
||||
bpl no_keypress ; 3
|
||||
jmp display_loop
|
||||
no_keypress:
|
||||
|
||||
jmp display_loop ; 3
|
||||
|
||||
|
||||
;========================
|
||||
; Draw a rasterbar
|
||||
; unroll as memory is free! haha
|
||||
;========================
|
||||
; X is location
|
||||
|
||||
; 2+22+24+24+24+24+6 = 126
|
||||
|
||||
draw_rasterbar:
|
||||
|
||||
ldy #0 ; 2
|
||||
;====
|
||||
|
||||
lda y_lookup_l,X ; 4
|
||||
sta OUTL ; 3
|
||||
lda y_lookup_h,X ; 4
|
||||
sta OUTH ; 3
|
||||
|
||||
smc_raster_color1_1:
|
||||
lda #$33 ; 2
|
||||
sta (OUTL),Y ; 6
|
||||
;============
|
||||
; 22
|
||||
|
||||
inx ; 2
|
||||
lda y_lookup_l,X ; 4
|
||||
sta OUTL ; 3
|
||||
lda y_lookup_h,X ; 4
|
||||
sta OUTH ; 3
|
||||
|
||||
smc_raster_color2_1:
|
||||
lda #$bb ; 2
|
||||
sta (OUTL),Y ; 6
|
||||
|
||||
inx ; 2
|
||||
lda y_lookup_l,X ; 4
|
||||
sta OUTL ; 3
|
||||
lda y_lookup_h,X ; 4
|
||||
sta OUTH ; 3
|
||||
|
||||
smc_raster_color3_1:
|
||||
lda #$ff ; 2
|
||||
sta (OUTL),Y ; 6
|
||||
|
||||
inx
|
||||
lda y_lookup_l,X ; 4
|
||||
sta OUTL ; 3
|
||||
lda y_lookup_h,X ; 4
|
||||
sta OUTH ; 3
|
||||
|
||||
smc_raster_color2_2:
|
||||
lda #$bb ; 2
|
||||
sta (OUTL),Y ; 6
|
||||
|
||||
inx
|
||||
lda y_lookup_l,X ; 4
|
||||
sta OUTL ; 3
|
||||
lda y_lookup_h,X ; 4
|
||||
sta OUTH ; 3
|
||||
|
||||
smc_raster_color1_2:
|
||||
lda #$33 ; 2
|
||||
sta (OUTL),Y ; 6
|
||||
|
||||
rts ; 6
|
||||
|
||||
|
||||
|
||||
|
||||
.include "gr_simple_clear.s"
|
||||
.include "gr_offsets.s"
|
||||
.include "gr_unrle.s"
|
||||
|
||||
.align $100
|
||||
.include "rasterbars_table.s"
|
||||
.include "movement_table.s"
|
||||
.include "gr_copy.s"
|
||||
.include "vapor_lock.s"
|
||||
.include "delay_a.s"
|
||||
|
||||
pictures:
|
||||
.word rb_bg_low,rb_bg_high
|
||||
|
||||
.include "rb_bg.inc"
|
||||
|
||||
red_x: .byte $10
|
||||
yellow_x: .byte $20
|
||||
green_x: .byte $30
|
||||
blue_x: .byte $40
|
||||
|
||||
.include "interrupt_handler.s"
|
||||
.include "pt3_lib.s"
|
||||
.include "mockingboard_a.s"
|
||||
|
||||
;=============
|
||||
; include song
|
||||
;=============
|
||||
.align 256 ; must be on page boundary
|
||||
; this can be fixed but some changes would have
|
||||
; to be made throughout the player code
|
||||
song:
|
||||
.incbin "../pt3_player/music/EA.PT3"
|
||||
|
Loading…
Reference in New Issue
Block a user