tfv: add in credits

try to bring them up to speed a bit too
This commit is contained in:
Vince Weaver 2021-01-14 01:28:18 -05:00
parent 5320812dff
commit ef557b62bc
14 changed files with 1452 additions and 7 deletions

View File

@ -14,9 +14,10 @@ all: tfv.dsk
$(DOS33):
cd ../../utils/dos33fs-utils && make
tfv.dsk: $(DOS33) HELLO LOADER TFV_TITLE TFV_FLYING TFV_WORLD
tfv.dsk: $(DOS33) HELLO LOADER TFV_CREDITS TFV_TITLE TFV_FLYING TFV_WORLD
$(DOS33) -y tfv.dsk SAVE A HELLO
$(DOS33) -y tfv.dsk BSAVE -a 0x1000 LOADER
$(DOS33) -y tfv.dsk BSAVE -a 0x4000 TFV_CREDITS
$(DOS33) -y tfv.dsk BSAVE -a 0x2000 TFV_TITLE
$(DOS33) -y tfv.dsk BSAVE -a 0x2000 TFV_FLYING
$(DOS33) -y tfv.dsk BSAVE -a 0x2000 TFV_WORLD
@ -36,6 +37,16 @@ loader.o: loader.s init_vars.s common_defines.inc zp.inc
###
credits.o: credits.s credits_sprites.inc mockingboard.s \
vapor_lock.s gr_putsprite.s move_letters.s \
./graphics_credits/KATC.lzsa
ca65 -o credits.o credits.s -l credits.lst
TFV_CREDITS: credits.o
ld65 -o TFV_CREDITS credits.o -C ../../linker_scripts/apple2_4000.inc
###
TFV_TITLE: tfv_title.o
ld65 -o TFV_TITLE tfv_title.o -C ../../linker_scripts/apple2_2000.inc
@ -78,5 +89,5 @@ graphics_map/tfv_backgrounds.inc:
###
clean:
rm -f *~ TITLE.GR *.o *.lst TFV TFV_TITLE TFV_FLYING TFV_WORLD HELLO LOADER
rm -f *~ TITLE.GR *.o *.lst TFV_CREDITS TFV_TITLE TFV_FLYING TFV_WORLD HELLO LOADER

View File

@ -1,5 +1,21 @@
short-term:
+ Finish mockingboard music (victory and battle)
+ Get credits hooked up
+ Get battle finished
- all menu options
- properly sync hp/mp with title
- hook up name
- sound effects (bleep on menu, clicks/tones during battles)
- rotate intro
- animated fly in
- enemy glow pink before dying
+ load game support
get metrocat by running across him on world map
enemy glow pink before dying
proper slowdown/delay in attack
simple sound effects when selecting menu

668
games/tfv/credits.s Normal file
View File

@ -0,0 +1,668 @@
;
; Cycle-counting text/hgr/lowres demo
; by Vince Weaver
;
.include "zp.inc"
.include "hardware.inc"
FRAME = $60
TREE1X = $61
TREE2X = $62
LETTERL = $63
LETTERH = $64
LETTERX = $65
LETTERY = $66
LETTERD = $67
LETTER = $68
BLARGH = $69
MBASE = $97
MBOFFSET = $98
WAITING = $99
MB_VALUE = $91
DONE_PLAYING = $92
MB_ADDRL = $93
MB_ADDRH = $94
MB_CHUNK_OFFSET = $95
MB_DETECTED = $96
WHICH_CHUNK = $97
STATE = $98
;===================
; init screen
jsr TEXT
jsr HOME
;==================
; Init vars
lda #28
sta TREE1X
lda #37
sta TREE2X
lda #0
sta MBOFFSET
lda #>music
sta MBASE
lda #<letters
sta LETTERL
lda #>letters
sta LETTERH
lda #39
sta LETTERX
lda #1
sta LETTERY
lda #15
sta LETTERD
lda #0
sta DISP_PAGE
lda #0
sta DRAW_PAGE
;==========================
; setup mockingboard
jsr mockingboard_detect_slot4
stx MB_DETECTED
ldx MB_DETECTED
beq no_init_mb
jsr mockingboard_init
no_init_mb:
;==========================
; Load the background image
lda #<katahdin
sta getsrc_smc+1
lda #>katahdin
sta getsrc_smc+2
lda #$20 ; Destination is HGR page0
jsr decompress_lzsa2_fast
; Wait
; jsr wait_until_keypressed
; GR part
bit LORES
bit SET_GR
bit FULLGR
; jsr draw_bottom_green ; 6
; Wait
; jsr wait_until_keypressed
; bit HIRES
; Wait
; jsr wait_until_keypressed
;=====================================================
; attempt vapor lock
;=====================================================
jsr vapor_lock
;==========================
; setup text screen
; clear top 6 lines to space
; takes (Y/2)*(6+435+7)+5 = ?
lda #$A0 ; space ; 2
ldy #10 ; 6 lines ; 2
jsr clear_page_loop ; 2693
; 1 2
; 0123456789abcdef0123456789abcdef0123456
;line1:.asciiz " * . " $400
;line2:.asciiz " * . . " $480
;line3:.asciiz " * " $500
;line4:.asciiz " * " $580
;line5:.asciiz " . . . " $600
;line6:.asciiz " . " $680
lda #'.'|$80 ; print star ; 2
sta $420 ; 4
sta $487 ; 4
sta $4A4 ; 4
sta $601 ; 4
sta $61c ; 4
sta $621 ; 4
sta $68d ; 4
;============
; 30
; draw the moon
lda #' ' ; print inv space ; 2
sta $403 ; 4
sta $482 ; 4
sta $502 ; 4
sta $583 ; 4
;============
; 18
; vapor lock returns with us at beginning of hsync in line
; 114 (7410 cycles), so with 5070 cycles to go
; 5070+4550 = 9620
; -2745 (draw text)
; ===========
; 6875
; Try X=97 Y=14 cycles=6875
ldy #14 ; 2
loopA: ldx #97 ; 2
loopB: dex ; 2
bne loopB ; 2nt/3
dey ; 2
bne loopA ; 2nt/3
jmp display_loop
.align $100
;=====================================================
;=====================================================
; Loop forever display loop
;=====================================================
;=====================================================
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
; 16666 = 17030 x=1021.8
; 1000 x
; TODO: find beginning of scan
; Text mode for 6*8=48 scanlines (3120 cycles)
; hgr for 64 scalines (4160 cycles)
; gr for 80 scalines (5200 cycles)
; vblank = 4550 cycles
; text
bit SET_TEXT ; 4
;================
; clear bottom green
jsr draw_bottom_green ; 2209+6
;================
; Draw Small Tree
lda #>small_tree ; 2
sta INH ; 3
lda #<small_tree ; 2
sta INL ; 3
lda TREE1X ; 3
sta XPOS ; 3
lda #28 ; 2
sta YPOS ; 3
jsr put_sprite ; 6
;=========
; 27
; + 576
;========
; 603
; want 3120
; green -2215
; tree1 -603
; set_test -4
;=============== 298 cycles
; Try X=1 Y=27 cycles=298
ldy #27 ; 2
loop2:
ldx #1 ; 2
loop1:
dex ; 2
bne loop1 ; 2nt/3
dey ; 2
bne loop2 ; 2nt/3
;=============================================
; hgr
bit HIRES ; 4
bit SET_GR ; 4
;================
; Draw Big Tree
lda #>big_tree ; 2
sta INH ; 3
lda #<big_tree ; 2
sta INL ; 3
lda TREE2X ; 3
sta XPOS ; 3
lda #30 ; 2
sta YPOS ; 3
jsr put_sprite ; 6
;=========
; 27
; + 1410
;========
; 1437
lda FRAME ; 3
and #$1f ; 2
and #$10 ; 2
beq bird_walking
; 2
lda #>bird_rider_stand_right ; 2
sta INH ; 3
lda #<bird_rider_stand_right ; 2
sta INL ; 3
jmp draw_bird ; 3
bird_walking:
; 3
lda #>bird_rider_walk_right ; 2
sta INH ; 3
lda #<bird_rider_walk_right ; 2
sta INL ; 3
; must be 15
lda #0 ; 2
; Must add another 15 as sprite is different
inc XPOS ; 5
inc XPOS ; 5
inc XPOS ; 5
draw_bird:
; 15 + 7
lda #17 ; 2
sta XPOS ; 3
lda #30 ; 2
sta YPOS ; 3
jsr put_sprite ; 6
;=========
; 38
; + 2190
;========
; 2228
;==========================
; Update frame = 13 cycles
inc FRAME ; frame++ ; 5
lda FRAME ; 3
and #$3f ; roll over after 63 ; 2
sta FRAME ; 3
;===========
; 13
;===========================
; Update tree1 = 21 cycles
and #$3f ; if (frame%64==0) ; 2
beq dec_tree1
; 2
; need to do 19-5 cycles of nonsense
inc TREE1X ; 5
dec TREE1X ; 5
lda #0 ; 2
lda #0 ; 2
jmp done_tree1 ; 3
dec_tree1:
; 3
dec TREE1X ; tree1_x-- ; 5
lda TREE1X ; 3
bmi tree1_neg
; 2
ldx TREE1X ; 3
jmp done_tree1 ; 3
tree1_neg:
; incoming br 3
ldx #37 ; 2
stx TREE1X ; 3
done_tree1:
;===========================
; Update tree2 = 24 cycles
lda FRAME ; 3
and #$f ; if (frame%16==0) ; 2
beq dec_tree2
; 2
; need to do 19-5 cycles of nonsense
inc TREE2X ; 5
dec TREE2X ; 5
lda #0 ; 2
lda #0 ; 2
jmp done_tree2 ; 3
dec_tree2:
; 3
dec TREE2X ; tree2_x-- ; 5
lda TREE2X ; 3
bmi tree2_neg
; 2
ldx TREE2X ; 3
jmp done_tree2 ; 3
tree2_neg:
; incoming br 3
ldx #37 ; 2
stx TREE2X ; 3
done_tree2:
; want 4160
; Tree2 Sprite -1437
; Sprite -2228
; Frame Update -13
; Tree1 Update -21
; Tree2 Update -24
; hgr bits -8
; ====================== 429 cycles
; Try X=13 Y=6 cycles=427 R2
lda #0 ; 2
ldy #6 ; 2
loop3:
ldx #13 ; 2
loop4:
dex ; 2
bne loop4 ; 2nt/3
dey ; 2
bne loop3 ; 2nt/3
;===========================================================================
; gr
bit LORES ; 4
;=========================
; play mockingboard
; 11+ 84*5 + 10*4 + 21 = 492
lda MBASE ; 3
sta MB_ADDRH ; 3
lda #0 ; 2
sta MB_ADDRL ; 3
;=============
; 11
ldx #0 ; 2
ldy MBOFFSET ; 3
lda (MB_ADDRL),Y ; 5
sta MB_VALUE ; 3
jsr write_ay_both ; 6+65
;===============
; 84
clc ; 2
lda #6 ; 2
adc MB_ADDRH ; 3
sta MB_ADDRH ; 3
;==============
; 10
ldx #2
ldy MBOFFSET
lda (MB_ADDRL),Y
sta MB_VALUE
jsr write_ay_both
clc
lda #6
adc MB_ADDRH
sta MB_ADDRH
ldx #3
ldy MBOFFSET
lda (MB_ADDRL),y
sta MB_VALUE
jsr write_ay_both
clc
lda #6
adc MB_ADDRH
sta MB_ADDRH
ldx #8
ldy MBOFFSET
lda (MB_ADDRL),y
sta MB_VALUE
jsr write_ay_both
clc
lda #6
adc MB_ADDRH
sta MB_ADDRH
ldx #9
ldy MBOFFSET
lda (MB_ADDRL),y
sta MB_VALUE
jsr write_ay_both
;
lda FRAME ; 3
and #1 ; 2
clc ; 2
adc MBOFFSET ; 3
sta MBOFFSET ; 3
lda MBASE ; 3
adc #0 ; 2
sta MBASE ; 3
;=============
; 21
; 2=2 not loop
; 2+7+3= 12 = last page
; 2+7+15=24 = loop
cmp #>music+5 ; 2
bne waste_7 ;
; 2
lda MBOFFSET ; 3
cmp #16 ; 2
bne waste_12 ;
; 2
lda #>music ; 2
sta MBASE ; 3
lda #0 ; 2
sta MBOFFSET ; 3
jmp not_ready_to_loop ; 3
waste_7:
lda #0 ; 2
inc BLARGH ; 5
waste_12:
; 3
lda #0 ; 2
inc BLARGH ; 5
inc BLARGH ; 5
not_ready_to_loop:
; lores want 5200
; mockingboard -492
; wrap -24
; softswitch -4
;===================
; 4680 cycles
; Try X=7 Y=114 cycles=4675 R5
inc BLARGH ; 5
; lda #0 ; 2
; lda #0 ; 2
; lda #0 ; 2
; lda #0 ; 2
ldy #114 ; 2
loop5:
ldx #7 ; 2
loop6:
dex ; 2
bne loop6 ; 2nt/3
dey ; 2
bne loop5 ; 2nt/3
;========================================================================
; vertical blank
; want 4550 cycles
; Try X=13 Y=64 cycles=4545 R2
;=========================================================================
jsr move_letters ; 6+126
; Blanking time: 4550
; move_letters -132
; JMP at end -3
;========================4415 cycles
; Try X=24 Y=35 cycles=4411 R4
nop
nop
ldy #35 ; 2
loop7: ldx #24 ; 2
loop8: dex ; 2
bne loop8 ; 2nt/3
dey ; 2
bne loop7 ; 2nt/3
jmp display_loop ; 3
;===========================================================
;===========================================================
;===========================================================
;wait_until_keypressed:
; lda KEYPRESS ; check if keypressed
; bpl wait_until_keypressed ; if not, loop
; bit KEYRESET
; rts
;====================================
; Draw bottom green
;====================================
; using hlin 7127, optimized a bit but still awful
; this one is much better
; 2209 cycles
draw_bottom_green:
lda #$44 ; 2
ldx #39 ; 2
green_loop:
sta $728,X ; 28 ; 5
sta $7a8,X ; 30 ; 5
sta $450,X ; 32 ; 5
sta $4d0,X ; 34 ; 5
sta $550,X ; 36 ; 5
sta $5d0,X ; 38 ; 5
sta $650,X ; 40 ; 5
sta $6d0,X ; 42 ; 5
sta $750,X ; 44 ; 5
sta $7d0,X ; 46 ; 5
dex ; 2
bpl green_loop ; 2nt/3
rts ; 6
; 4 + (40*55) + 6 - 1
.align $100
letters:
;.byte 1,15
.byte "T A L B O T",128
.byte 2,14,"F A N T A S Y",128
.byte 3,16,"S E V E N",128
.byte 1,15," ",128
.byte 2,14," ",128
.byte 3,16," ",128
.byte 1,19,"BY",128
.byte 3,14,"VINCE WEAVER",128
.byte 1,19," ",128
.byte 3,14," ",128
.byte 1,16,"MUSIC BY",128
.byte 3,12,"HIROKAZU TANAKA",128
.byte 1,16," ",128
.byte 3,12," ",128
.byte 2,13,"CYCLE COUNTING",128
.byte 3,16,"IS HARD!"
.byte 255
.include "vapor_lock.s"
.include "delay_a.s"
.include "gr_hline.s"
.include "move_letters.s"
.include "gr_putsprite.s"
.include "mockingboard.s"
;.include "../asm_routines/keypress.s"
.align $100
.include "credits_sprites.inc"
.include "decompress_fast_v2.s"
;.align $1000
katahdin:
.incbin "graphics_credits/KATC.lzsa"
katahdin_end:
.align $100
music:
.incbin "music/music.tfv"

View File

@ -0,0 +1,47 @@
bird_rider_stand_right:
.byte $6,$7
.byte $00,$dd,$bd,$00,$00,$00
.byte $00,$dd,$db,$00,$dd,$90
.byte $00,$00,$22,$02,$dd,$00
.byte $0d,$dd,$d2,$22,$dd,$00
.byte $00,$00,$0d,$82,$8d,$00
.byte $00,$00,$00,$99,$00,$00
.byte $00,$00,$00,$99,$90,$00
; 00=22 0X=3 X0=2 XX=15
; = 33 + Y*(52)+ [30A + 64B + 69C + 54D]-Y
; = 33 + 7*52 + 30*22 + 64*3 + 69*2 + 54*15 - 7
; = 2190
bird_rider_walk_right:
.byte $6,$7
.byte $00,$dd,$bd,$00,$00,$00
.byte $00,$dd,$db,$00,$dd,$90
.byte $00,$00,$22,$02,$dd,$00
.byte $0d,$dd,$d2,$22,$dd,$00
.byte $00,$00,$0d,$82,$8d,$00
.byte $00,$00,$00,$99,$00,$00
.byte $00,$00,$99,$00,$99,$00
; 00=22 0X=3 X0=1 XX=16
; = 33 + Y*(52)+ [30A + 64B + 69C + 54D]-Y
; = 33 + 7*52 + 30*22 + 64*3 + 69*1 + 54*16 - 7
; = 2175
small_tree:
.byte $3,$3
.byte $00,$CC,$00
.byte $CC,$CC,$CC
.byte $00,$88,$00
; 00=4 0X=0 X0=0 XX=5
; = 33 + Y*(52)+ [30A + 64B + 69C + 54D]-Y
; = 33 + 3*52 + [30*4 + 54*5]-3 = 576
big_tree:
.byte $5,$5
.byte $00,$00,$CC,$00,$00
.byte $00,$C0,$CC,$C0,$00
.byte $00,$CC,$CC,$CC,$00
.byte $c0,$CC,$CC,$CC,$c0
.byte $00,$00,$88,$00,$00
; 00=12 0X=0 X0=4 XX=9
; = 33 + Y*(52)+ [30A + 64B + 69C + 54D]-Y
; = 33 + 5*52 + 30*12 + 69*4 + 54*9 - 5 = 1410

25
games/tfv/delay_a.s Normal file
View File

@ -0,0 +1,25 @@
; From http://6502org.wikidot.com/software-delay
; 25+A cycles (including JSR), 19 bytes (excluding JSR)
;
; The branches must not cross page boundaries!
;
; Cycles Accumulator Carry flag
; 0 1 2 3 4 5 6 (hex) 0 1 2 3 4 5 6
; jsr delay_a ; 6 6 6 6 6 6 6 00 01 02 03 04 05 06
dly0: sbc #7
delay_a:cmp #7 ; 2 2 2 2 2 2 2 00 01 02 03 04 05 06 0 0 0 0 0 0 0
bcs dly0 ; 2 2 2 2 2 2 2 00 01 02 03 04 05 06 0 0 0 0 0 0 0
lsr ; 2 2 2 2 2 2 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0
bcs dly1 ; 2 3 2 3 2 3 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0
dly1: beq dly2 ; 3 3 2 2 2 2 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0
lsr ; 2 2 2 2 2 00 00 01 01 01 1 1 0 0 1
beq dly3 ; 3 3 2 2 2 00 00 01 01 01 1 1 0 0 1
bcc dly3 ; 3 3 2 01 01 01 0 0 1
dly2: bne dly3 ; 2 2 3 00 00 01 0 1 0
dly3: rts ; 6 6 6 6 6 6 6 00 00 00 00 01 01 01 0 1 1 1 0 0 1
;
; Total cycles: 25 26 27 28 29 30 31

48
games/tfv/gr_hline.s Normal file
View File

@ -0,0 +1,48 @@
;==================================
; HLINE
;==================================
; Color in A
; Y has which line
; takes 435 cycles
hline:
pha ; 3
ldx gr_offsets,y ; 4+
stx hline_loop+1 ; self-modify code ; 4
lda gr_offsets+1,y ; 4+
clc ; 2
adc DRAW_PAGE ; 3
sta hline_loop+2 ; self-modify code ; 4
pla ; 4
ldx #39 ; 2
;===========
; 30
hline_loop:
sta $5d0,X ; 38 ; 5
dex ; 2
bpl hline_loop ; 2nt/3
;===========
; 40*(10)=400
; -1
rts ; 6
;==========================
; Clear gr screen
;==========================
; Color in A, Clears 0 to and including Y
; clear_gr: takes 2+(48/2)*(6+435+7)+5 = 10759
; cpl: takes (Y/2)*(6+435+7)+5 = ?
clear_gr:
ldy #46 ; 2
clear_page_loop:
jsr hline ; 6+435
dey ; 2
dey ; 2
bpl clear_page_loop ; 2/3
rts ; 6
gr_offsets:
.word $400,$480,$500,$580,$600,$680,$700,$780
.word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8
.word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0

Binary file not shown.

View File

@ -0,0 +1,14 @@
include ../../../Makefile.inc
PNG2RLE = ../../../utils/gr-utils/png2rle
PNG2GR = ../../../utils/gr-utils/png2gr
LZSA = ~/research/lzsa/lzsa/lzsa
all: KATC.lzsa
%.lzsa: %.BIN
$(LZSA) -r -f2 $< $@
clean:
rm -f *~ KATC.LZSA

View File

@ -80,12 +80,13 @@ which_load_loop:
sta OUTH
lda WHICH_LOAD
cmp #LOAD_CREDITS
bne load_other
load_intro:
lda #<$2000
load_credits:
lda #<$4000
sta entry_smc+1
lda #>$2000
lda #>$4000
sta entry_smc+2
jmp actual_load

188
games/tfv/mockingboard.s Normal file
View File

@ -0,0 +1,188 @@
; ZP addresses
; left channel
MOCK_6522_1_ORB = $C400 ; 6522 #1 port b data
MOCK_6522_1_ORA = $C401 ; 6522 #1 port a data
MOCK_6522_1_DDRB = $C402 ; 6522 #1 data direction port B
MOCK_6522_1_DDRA = $C403 ; 6522 #1 data direction port A
MOCK_6522_1_T1C_L = $C404 ; 6522 #1 Low-order counter
MOCK_6522_1_T1C_H = $C405 ; 6522 #1 High-order counter
MOCK_6522_1_T1L_L = $C406 ; 6522 #1 Low-order latch
MOCK_6522_1_T1L_H = $C407 ; 6522 #1 High-order latch
MOCK_6522_1_T2C_L = $C408 ; 6522 #1 Timer2 Low-order Latch/Counter
MOCK_6522_1_T2C_H = $C409 ; 6522 #1 Timer2 High-order Latch/Counter
MOCK_6522_1_SR = $C40A ; 6522 #1 Shift Register
MOCK_6522_1_ACR = $C40B ; 6522 #1 Auxiliary Control Register
MOCK_6522_1_PCR = $C40C ; 6522 #1 Peripheral Control Register
MOCK_6522_1_IFR = $C40D ; 6522 #1 Interrupt Flag Register
MOCK_6522_1_IER = $C40E ; 6522 #1 Interrupt Enable Register
MOCK_6522_1_ORAN = $C40F ; 6522 #1 port a data, no handshake
; right channel
MOCK_6522_2_ORB = $C480 ; 6522 #2 port b data
MOCK_6522_2_ORA = $C481 ; 6522 #2 port a data
MOCK_6522_2_DDRB = $C482 ; 6522 #2 data direction port B
MOCK_6522_2_DDRA = $C483 ; 6522 #2 data direction port A
MOCK_6522_2_T1C_L = $C484 ; 6522 #2 Low-order counter
MOCK_6522_2_T1C_H = $C485 ; 6522 #2 High-order counter
MOCK_6522_2_T1L_L = $C486 ; 6522 #2 Low-order latch
MOCK_6522_2_T1L_H = $C487 ; 6522 #2 High-order latch
MOCK_6522_2_T2C_L = $C488 ; 6522 #2 Timer2 Low-order Latch/Counter
MOCK_6522_2_T2C_H = $C489 ; 6522 #2 Timer2 High-order Latch/Counter
MOCK_6522_2_SR = $C48A ; 6522 #2 Shift Register
MOCK_6522_2_ACR = $C48B ; 6522 #2 Auxiliary Control Register
MOCK_6522_2_PCR = $C48C ; 6522 #2 Peripheral Control Register
MOCK_6522_2_IFR = $C48D ; 6522 #2 Interrupt Flag Register
MOCK_6522_2_IER = $C48E ; 6522 #2 Interrupt Enable Register
MOCK_6522_2_ORAN = $C48F ; 6522 #2 port a data, no handshake
; 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 8 pins output (1), portA
sta MOCK_6522_1_DDRA
sta MOCK_6522_2_DDRA
; only 3 pins output (1), port B
lda #$7
sta MOCK_6522_1_DDRB
sta MOCK_6522_2_DDRB
reset_ay_both:
;======================
; Reset Left AY-3-8910
;======================
reset_ay_left:
lda #MOCK_AY_RESET
sta MOCK_6522_1_ORB
lda #MOCK_AY_INACTIVE
sta MOCK_6522_1_ORB
; AY-3-8913: Wait 5 us
nop
nop
nop
nop
nop
;======================
; Reset Right AY-3-8910
;======================
reset_ay_right:
lda #MOCK_AY_RESET
sta MOCK_6522_2_ORB
lda #MOCK_AY_INACTIVE
sta MOCK_6522_2_ORB
; AY-3-8913: Wait 5 us
nop
nop
nop
nop
nop
;=========================
; Setup initial conditions
;=========================
; 7: ENABLE
ldx #7
lda #$38 ; noise disabled, ABC enabled
sta MB_VALUE
jsr write_ay_both
rts
;=========================================
; Write Right/Left to save value AY-3-8910
;=========================================
; register in X
; value in MB_VALUE
write_ay_both:
; address
stx MOCK_6522_1_ORA ; put address on PA1 ; 4
stx MOCK_6522_2_ORA ; put address on PA2 ; 4
lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2
sta MOCK_6522_1_ORB ; latch_address on PB1 ; 4
sta MOCK_6522_2_ORB ; latch_address on PB2 ; 4
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_1_ORB ; 4
sta MOCK_6522_2_ORB ; 4
;===========
; 28
; value
lda MB_VALUE ; 3
sta MOCK_6522_1_ORA ; put value on PA1 ; 4
sta MOCK_6522_2_ORA ; put value on PA2 ; 4
lda #MOCK_AY_WRITE ; ; 2
sta MOCK_6522_1_ORB ; write on PB1 ; 4
sta MOCK_6522_2_ORB ; write on PB2 ; 4
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_1_ORB ; 4
sta MOCK_6522_2_ORB ; 4
;===========
; 31
rts ; 6
;===========
; 65
;=======================================
; 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

184
games/tfv/move_letters.s Normal file
View File

@ -0,0 +1,184 @@
;===============================================
; 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

BIN
games/tfv/music/music.tfv Normal file

Binary file not shown.

View File

@ -28,8 +28,13 @@ flying:
; Clear screen/pages
;===================
jsr clear_screens
bit PAGE0
bit LORES ; Lo-res graphics
bit TEXTGR ; mixed gr/text mode
bit SET_GR ; set graphics
jsr clear_screens
lda #0
sta DISP_PAGE
lda #4

238
games/tfv/vapor_lock.s Normal file
View File

@ -0,0 +1,238 @@
; This took a while to track down
; On Apple II/II+ the horiz blanking addr are $1000 higher than on IIe
; So on II+ were outside video area, so unlikely to be our set value
; (unless I foolishly use $ff which some uninitialized mem is set to)
; Lots of this color fiddling is to make sure you don't accidentally
; get runs of colors on IIe due to the horiz blank
; 0-5 aqua 6-12 = grey, 13 - 20 = yellow, 21-23 = aqua rainbow 14
;
;
;16 0 YA
;17 1 YA
;18 2 YA
;19 3 YA
;20 4 YA
;21 5 AA
;22 6 AG
;23 7 AG
;0 8 AG
;1 9 AG
;2 10 AG
;3 11 AG
;4 12 AG
;5 13 AY ****
;6 14 GY RAINBOW
;7 15 GY
;8 16 GY
;9 17 GY
;10 18 GY
;11 19 GY
;12 20 GY
;13 21 YA
;14 22 YA
;15 23 YA
;==============================
; setup graphics for vapor lock
;==============================
vapor_lock:
; Clear Page0
lda #$0
sta DRAW_PAGE
lda #$ee ; full screen white $ff
jsr clear_gr
lda #$dd
ldy #40
jsr clear_page_loop ; make bottom half yellow $dd
lda #$aa
ldy #24
jsr clear_page_loop ; make middle grey2 $aa
lda #$ee
ldy #10
jsr clear_page_loop ; make top half aqua $ee
; set up a rainbow to aid in exact lock
ldy #00
rainbow_loop:
tya
sta $728+20,Y
iny
cpy #20
bne rainbow_loop
;btt:
; jmp btt
;=====================================================
; attempt vapor lock
; by reading the "floating bus" we can see most recently
; written value of the display
;=====================================================
; See:
; Have an Apple Split by Bob Bishop
; Softalk, October 1982
; Challenges: each scan line scans 40 bytes.
; The blanking happens at the *beginning*
; So 65 bytes are scanned, starting at adress of the line - 25
; the scan takes 8 cycles, look for 4 repeats of the value
; to avoid false positive found if the horiz blanking is mirroring
; the line (max 3 repeats in that case)
vapor_lock_loop:
; first make sure we have a full line of $aa
lda #$aa ; 2
zxloop:
ldx #$04 ; 2
wiloop:
cmp $C051 ; read the floating bus ; 4
bne zxloop ; if not, start from scratch ; 2/3
dex ; we were, dec ; 2
bne wiloop ; if not 4 of them, restart ; 3/2
; if we get here we read 4 proper pixels, 11 apart (2+4+2+2+3)
; 0 11 22 33, clock at 34
; 1 12 23 34, clock at 35
; 2 13 24 35, clock at 36
; 3 14 25 36, clock at 37
; 4 15 26 37, clock at 38
; 5 16 27 38, clock at 39
; 6 17 28 39, clock at 40
; X X X X
; X X X X
; X X X X
; X X X X
; X X X X
; X X X X
; X X X X
; 0123456789012345678901234 0123456789012345678901234567890123456789
; 1 2 1 2 3
; hsync pixels
; XXXXXXXXXXXXXXXXXXXXXXXXX 4444444444444444444444444444440123456789
; now look for the color change that
; happens at line 13*8 = 104
lda #$dd ; 2
zloop:
ldx #$04 ; 2
qloop:
cmp $C051 ; read floating bus ; 4
bne zloop ; 2/3
dex ; 2
bne qloop ; 3/2
;============
; 11
; Found it!
; if we get here we read 4 proper pixels, 11 apart (2+4+2+2+3)
; 0 11 22 33, clock at 34
; 1 12 23 34, clock at 35
; 2 13 24 35, clock at 36
; 3 14 25 36, clock at 37
; 4 15 26 37, clock at 38
; 5 16 27 38, clock at 39
; 6 17 28 39, clock at 40
;btt:
; jmp btt
; In theory near end of line 104
; now skip ahead 8 lines and read from the rainbow pattern we set
; up to find our exact location
; delay 65 * 8 = 520
; we back off a few to make sure we're not in the horiz blank
; try to delay 510
; *NOTE* sometimes we end up going one (or rarely, two??) lines too far
; so instead try going 7 lines ahead, and if still dd then one more
; so single step until we get a rainbow color
; go to next line, -10
lda #28 ; 2
jsr delay_a ; delay 25+28 = 53
; total delay = 55
vl_try_again:
lda #29 ; 2
jsr delay_a ; delay 25+29 = 54
; total delay = 56
lda $C051 ; 4
cmp #$dd ; 2
beq vl_try_again ; 3
; -1
; now near end of line 112
;lda $0 ; nop to match old code ; 3
; nop ; nop to match old code ; 2
lda $C051 ; 4
;kbb:
; jmp kbb
; we are in theory on line $728 = 14*8 = 112
; so 112*65 = 7280 cycles from start
; we are actualy 25+20+A pixels in
; 7325+A
; Our goal is line 114 at 7410 cycles
; 7410 - 7325 = 85
; so kill 85-A cycles
; -6 to do subtraction
; -6 for rts
; -25 for delay_a overhead
eor #$ff ; 2
sec ; 2
adc #48 ; 2
jsr delay_a ; should total 48 cycles
done_vapor_lock:
rts ; 6
; Some random related work
; Docs:
; Lancaster
; Bishop
; Sather
; Vaguely relevant but no help with the Apple II+ issue
;
; Eamon: Screen display and timing synchronization
; on the Apple IIe and Apple IIgs
;
; Adams: Visually presented verbal stimuli by assembly
; language on the Apple II computer.
; Cavanagh and Anstis: Visual psychophysics on the
; Apple II: Getting started