pt3: add initial pt3_player

This commit is contained in:
Vince Weaver 2019-05-06 20:16:45 -04:00
parent adc5b25f2a
commit b81bae2a48
10 changed files with 1739 additions and 0 deletions

BIN
pt3_player/HELLO Normal file

Binary file not shown.

52
pt3_player/Makefile Normal file
View File

@ -0,0 +1,52 @@
include ../Makefile.inc
DOS33 = ../dos33fs-utils/dos33
PNG2GR = ../gr-utils/png2gr
all: pt3_player.dsk
$(DOS33):
cd ../dos33fs-utils && make
pt3_player.dsk: PT3_PLAYER HELLO
cp empty.dsk pt3_player.dsk
$(DOS33) -y chiptune_player.dsk SAVE A HELLO
$(DOS33) -y chiptune_player.dsk BSAVE -a 0x0800 PT3_PLAYER
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/CAMOUFLAGE.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/CHRISTMAS.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/CRMOROS.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/DEATH2.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/DEMO4.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/HARKONEN.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/INTRO2.KRW
## $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/KORO.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/LYRA2.KRW
## $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/MMCM.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/RANDOM.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/ROBOT.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/SDEMO.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/SPUTNIK.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/TECHNO.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/UNIVERSE.KRW
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/WAVE.KRW
# $(DOS33) -y chiptune_player.dsk SAVE B OUT.LZ4
# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x6000 OUT.0
HELLO: hello.bas
../asoft_basic-utils/tokenize_asoft < hello.bas > HELLO
PT3_PLAYER: pt3_player.o
ld65 -o PT3_PLAYER pt3_player.o -C ../linker_scripts/apple2_800.inc
pt3_player.o: pt3_player.s
# mockingboard.s \
# keypress_minimal.s \
# qkumba_rts.s \
# rasterbars.s volume_bars.s interrupt_handler.s \
# song_list.inc chip_title.inc zp.inc chip_title_uncompressed.inc
ca65 -o pt3_player.o pt3_player.s -l pt3_player.lst
clean:
rm -f *~ TITLE.GR *.o *.lst \
PT3_PLAYER

2
pt3_player/README.pt3 Normal file
View File

@ -0,0 +1,2 @@
PT3_player

BIN
pt3_player/empty.dsk Normal file

Binary file not shown.

4
pt3_player/hello.bas Normal file
View File

@ -0,0 +1,4 @@
5 GR
10 PRINT "LOADING PT3 PLAYER V0.0"
50 PRINT: X=PEEK(49237):REM DISPLAY PAGE2
100 PRINT CHR$ (4)"BRUN PT3_PLAYER"

BIN
pt3_player/pt3_player.dsk Normal file

Binary file not shown.

640
pt3_player/pt3_player.s Normal file
View File

@ -0,0 +1,640 @@
; VMW Chiptune Player
.include "zp.inc"
; program is ~4k, so from 0xc00 to 0x1C00
LZ4_BUFFER EQU $1C00 ; $1C00 - $5C00, 16k for now
DISK_BUFFER EQU $5D00 ; for disk loading
UNPACK_BUFFER EQU $6000 ; $6000 - $9800, 14k, $3800
; by using qkumba's RTS code
; no need for DOS, so we actually
; are free the whole way to $C000
; instead of stopping at $9600
; $6000 - $C000 = 24k
NUM_FILES EQU 15
jmp chiptune_setup
.include "chip_title_uncompressed.inc"
.align $400
;=============================
; Setup
;=============================
chiptune_setup:
; jsr HOME
; jsr TEXT
; Init disk code
jsr rts_init
; init variables
lda #0
sta DRAW_PAGE
sta CH
sta CV
sta DONE_PLAYING
sta MB_CHUNK_OFFSET
sta DECODE_ERROR
; lda #0
; lda #4 ; start at DEMO4
; lda #7 ; start at LYRA
; lda #10 ; start at SDEMO
sta WHICH_FILE
lda #$ff
sta RASTERBARS_ON
; print detection message
; lda #<mocking_message ; load loading message
; sta OUTL
; lda #>mocking_message
; sta OUTH
; jsr move_and_print ; print it
jsr mockingboard_detect_slot4 ; call detection routine
cpx #$1
beq mockingboard_found
lda #<not_message ; if not found, print that
sta OUTL
lda #>not_message
sta OUTH
inc CV
jsr move_and_print
; jmp forever_loop ; and wait forever
mockingboard_found:
; lda #<found_message ; print found message
; sta OUTL
; lda #>found_message
; sta OUTH
; inc CV
; jsr move_and_print
;============================
; Init the Mockingboard
;============================
jsr mockingboard_init
jsr reset_ay_both
jsr clear_ay_both
;=========================
; Setup Interrupt Handler
;=========================
; Vector address goes to 0x3fe/0x3ff
; FIXME: should chain any existing handler
lda #<interrupt_handler
sta $03fe
lda #>interrupt_handler
sta $03ff
;============================
; Enable 50Hz clock on 6522
;============================
sei ; disable interrupts just in case
lda #$40 ; Continuous interrupts, don't touch PB7
sta $C40B ; ACR register
lda #$7F ; clear all interrupt flags
sta $C40E ; IER register (interrupt enable)
lda #$C0
sta $C40D ; IFR: 1100, enable interrupt on timer one oflow
sta $C40E ; IER: 1100, enable timer one interrupt
lda #$E7
sta $C404 ; write into low-order latch
lda #$4f
sta $C405 ; write into high-order latch,
; load both values into counter
; clear interrupt and start counting
; 4fe7 / 1e6 = .020s, 50Hz
;============================
; Draw title screen
;============================
; jsr set_gr_page0 ; set page 0
; lda #$4 ; draw page 1
; sta DRAW_PAGE
; jsr clear_screens ; clear both screens
; lda #<chip_title ; point to title data
; sta GBASL
; lda #>chip_title
; sta GBASH
; bit PAGE1
; Load image ; load the image
; lda #<$800
; sta BASL
; lda #>$800
; sta BASH
; jsr load_rle_gr
;==================
; load first song
;==================
jsr new_song
;============================
; Init Background
;============================
jsr set_gr_page0
lda #0
sta DRAW_PAGE
sta SCREEN_Y
;============================
; Enable 6502 interrupts
;============================
cli ; clear interrupt mask
;============================
; Loop forever
;============================
main_loop:
lda DECODE_ERROR
beq check_copy
sei
brk
check_copy:
lda COPY_TIME
beq check_decompress ; if zero, skip
lda #0
sta COPY_OFFSET
check_copy_loop:
jsr page_copy ;6+3621
inc COPY_OFFSET ; (opt: make subtract?) ; 5
lda #14 ; NOT HEX URGH!
cmp COPY_OFFSET
bne check_copy_loop
lda #0 ; we are done
sta COPY_TIME
check_decompress:
lda DECOMPRESS_TIME
beq check_done ; if zero, skip
jsr setup_next_subsong ; decompress
lda MB_CHUNK_OFFSET
sta TIME_TAKEN
lda #0
sta DECOMPRESS_TIME
;============================
; visualization
;============================
; jsr clear_top
; jsr draw_rasters
; jsr volume_bars
; jsr page_flip
check_done:
lda #$ff
bit DONE_PLAYING
beq main_loop ; if was all zeros, loop
bmi main_loop ; if high bit set, paused
bvs minus_song ; if bit 6 set, then left pressed
; else, either song finished or
; right pressed
plus_song:
sei ; disable interrupts
jsr increment_file
jmp done_play
minus_song:
sei ; disable interrupts
jsr decrement_file
done_play:
lda #0
sta DONE_PLAYING
lda #0
sta CH
jsr clear_bottoms
jsr new_song
cli ; re-enable interrupts
jmp main_loop
forever_loop:
jmp forever_loop
;=================
; load a new song
;=================
new_song:
;=========================
; Init Variables
;=========================
lda #$0
sta FRAME_COUNT
sta A_VOLUME
sta B_VOLUME
sta C_VOLUME
sta COPY_OFFSET
sta DECOMPRESS_TIME
sta COPY_TIME
sta MB_CHUNK_OFFSET
lda #$20
sta DECODER_STATE
lda #3
sta CHUNKSIZE
;===========================
; Print loading message
;===========================
jsr clear_bottoms ; clear bottom of page 0/1
lda #0 ; print LOADING message
sta CH
lda #21
sta CV
lda #<loading_message
sta OUTL
lda #>loading_message
sta OUTH
jsr print_both_pages
;===========================
; Load in KRW file
;===========================
jsr get_filename
lda #8 ; print filename to screen
sta CH
lda #21
sta CV
lda INL
sta OUTL
lda INH
sta OUTH
jsr print_both_pages
; needs to be space-padded $A0 30-byte filename
lda #<readfile_filename
sta namlo
lda #>readfile_filename
sta namhi
ldy #0
ldx #30 ; 30 chars
name_loop:
lda (INL),Y
beq space_loop
ora #$80
sta (namlo),Y
iny
dex
bne name_loop
beq done_name_loop
space_loop:
lda #$a0 ; pad with ' '
sta (namlo),Y
iny
dex
bne space_loop
done_name_loop:
; open and read a file
; loads to whatever it was BSAVED at (default is $1C00)
jsr read_file ; read KRW file from disk
;=========================
; Print Info
;=========================
jsr clear_bottoms ; clear bottom of page 0/1
lda #>LZ4_BUFFER ; point to LZ4 data
sta OUTH
lda #<LZ4_BUFFER
sta OUTL
ldy #3 ; skip KRW magic at front
; print title
lda #20 ; VTAB 20: HTAB from file
jsr print_header_info
; Print Author
lda #21 ; VTAB 21: HTAB from file
jsr print_header_info
; Print clock
lda #23 ; VTAB 23: HTAB from file
jsr print_header_info
; Print Left Arrow (INVERSE)
lda #'<'
sta $750
sta $B50
lda #'-'
sta $751
sta $B51
; Print Rright Arrow (INVERSE)
lda #'-'
sta $776
sta $B76
lda #'>'
sta $777
sta $B77
; Point LZ4 src at proper place
ldy #0
lda #>(LZ4_BUFFER+3)
sta LZ4_SRC+1
lda #<(LZ4_BUFFER+3)
sta LZ4_SRC
lda (LZ4_SRC),Y ; get header skip
clc
adc LZ4_SRC
sta LZ4_SRC
lda LZ4_SRC+1
adc #0
sta LZ4_SRC+1
lda #<UNPACK_BUFFER ; set input pointer
sta INL
lda #>UNPACK_BUFFER
sta INH
; Decompress first chunks
lda #$0
sta COPY_OFFSET
sta DECOMPRESS_TIME
lda #$3
sta CHUNKSIZE
lda #$20
sta DECODER_STATE
sta COPY_TIME
jsr setup_next_subsong
rts
;=================
; next sub-song
;=================
setup_next_subsong:
ldy #0
lda (LZ4_SRC),Y ; get next size value
sta LZ4_END
iny
lda (LZ4_SRC),Y
sta LZ4_END+1
lda #2 ; increment pointer
clc
adc LZ4_SRC
sta LZ4_SRC
lda LZ4_SRC+1
adc #0
sta LZ4_SRC+1
jsr lz4_decode ; decode
; tail-call?
rts
;===================
; print header info
;===================
; shortcut to print header info
; a = VTAB
print_header_info:
sta CV
iny ; adjust pointer
tya
ldy #0
clc
adc OUTL
sta OUTL
lda OUTH
adc #$0
sta OUTH
lda (OUTL),Y ; get HTAB value
sta CH
inc OUTL ; increment 16-bits
bne bloop22
inc OUTH
bloop22:
jmp print_both_pages ; print, tail call
;==============================================
; plan: takes 256 50Hz to play a chunk
; need to copy 14 256-byte blocks
; PLAY A (copying C)
; PLAY B (copying C)
; PLAY D (decompressing A/B/C)
;========================
; page copy
;========================
; want to copy:
; SRC: chunk_buffer+(2*256)+(COPY_OFFSET*3*256)
; DST: chunk_buffer+$2A00+(COPY_OFFSET*256)
page_copy:
clc ; 2
lda #>(UNPACK_BUFFER+512) ; 3
adc COPY_OFFSET ; 3
adc COPY_OFFSET ; 3
adc COPY_OFFSET ; 3
sta page_copy_loop+2 ; self modify ; 5
lda #>(UNPACK_BUFFER+$2A00) ; 2
adc COPY_OFFSET ; 3
sta page_copy_loop+5 ; self modify ; 5
ldx #$00 ; 2
page_copy_loop:
lda $1000,x ; 4
sta $1000,X ; 5
inx ; 2
bne page_copy_loop ; 2nt/3
rts ; 6
;======================
; 2+14*256+6+29= 3621
;==================
; Get filename
;==================
; WHICH_FILE holds number
; MAX_FILES has max
; Scroll through until find
; point INH:INL to it
get_filename:
ldy #0
ldx WHICH_FILE
lda #<krw_file ; point to filename
sta INL
lda #>krw_file
sta INH
get_filename_loop:
cpx #0
beq filename_found
inner_loop:
iny
lda (INL),Y
bne inner_loop
iny
dex
jmp get_filename_loop
filename_found:
tya
clc
adc INL
sta INL
lda INH
adc #0
sta INH
rts
;===============================
; Increment file we want to load
;===============================
increment_file:
inc WHICH_FILE
lda WHICH_FILE
cmp #NUM_FILES
bne done_increment
lda #0
sta WHICH_FILE
done_increment:
rts
;===============================
; Decrement file we want to load
;===============================
decrement_file:
dec WHICH_FILE
bpl done_decrement
lda #(NUM_FILES-1)
sta WHICH_FILE
done_decrement:
rts
;==========
; filenames
;==========
krw_file:
.include "song_list.inc"
;=========
;routines
;=========
.include "../asm_routines/gr_offsets.s"
.include "text_print.s"
.include "../asm_routines/mockingboard_a.s"
.include "../asm_routines/gr_fast_clear.s"
.include "../asm_routines/pageflip.s"
;.include "../asm_routines/gr_unrle.s"
.include "../asm_routines/gr_setpage.s"
.include "qkumba_rts.s"
.include "../asm_routines/gr_hlin.s"
.include "../asm_routines/lz4_decode.s"
.include "../asm_routines/keypress_minimal.s"
.include "rasterbars.s"
.include "volume_bars.s"
.if .def(UNROLLED)
.include "interrupt_handler_unrolled.s"
.else
.include "interrupt_handler.s"
.endif
;=========
; strings
;=========
;mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD IN SLOT #4"
not_message: .byte "NOT "
found_message: .asciiz "FOUND"
;done_message: .asciiz "DONE PLAYING"
loading_message: .asciiz "LOADING"

700
pt3_player/qkumba_rts.s Normal file
View File

@ -0,0 +1,700 @@
; read any file slot 6 version
; based on FASTLD6 and RTS copyright (c) Peter Ferrie 2011-2013,2018
; modified to assembled with ca64 -- vmw
; added code to patch it to run from current disk slot -- vmw
adrlo = $26 ; constant from boot prom
adrhi = $27 ; constant from boot prom
tmpsec = $3c ; constant from boot prom
reqsec = $3d ; constant from boot prom
sizelo = $44
sizehi = $45
secsize = $46
; TEMPY = $fb
; namlo = $f6
; namhi = $f7
; step = $f8 ; state for stepper motor
; tmptrk = $f9 ; temporary copy of current track
; phase = $fa ; current phase for /seek
dirbuf = $5d00
;$1e00 ; note, don't put this immediately below
; the value being read as destaddr-4
; is temporarily overwritten during read
; process
; filename to open is 30-character Apple text:
readfile_filename:
; .byte "SDEMO.KRW "
.byte 'S'|$80,'D'|$80,'E'|$80,'M'|$80,'O'|$80,'.'|$80,'K'|$80,'R'|$80
.byte 'W'|$80,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0
;unhook DOS and build nibble table
rts_init:
; patch to use current drive
; locate input paramater list
jsr $3E3
; result is in A:Y
sta $FF
sty $FE
ldy #1
lda ($FE),y
; list+1 should have slot<<8
ora #$80 ; add in $80
; c0e0
sta mlsmc06+1
; c0e8
clc
adc #8
sta mlsmc02+1
; c0e9
clc
adc #1
sta mlsmc01+1
; c0ec
clc
adc #3
sta mlsmc03+1
sta mlsmc04+1
sta mlsmc05+1
jsr $fe93 ; clear COUT
jsr $fe89 ; clear KEYIN
;========================
; Create nibble table
; Note: the table starts 16 bytes in, and is sparse
; so it doesn't entirely look like the DOS33 table at
ldy #0
ldx #3
L1: stx $3c ; store tempx (3?)
txa ; a=x (a=3)
asl ; a*=2 (a=6)
bit $3c ; a&tempx, set N/V (a=6)
beq L3 ; if 0, skip to L3
ora $3c ; a|=tempx (a=7)
eor #$ff ; a=~a (a=f8)
and #$7e ; a&=0x7e 0111 1110 (a=78)
L2: bcs L3 ; this set way back at asl??
lsr ; a>>1 a=3c c=0
; a=1e c=0
; a=0f c=0
; a=07 c=1
bne L2 ; if a!=0 goto l2
tya ; if a==0, a=y
sta nibtbl, x ; write out to table
iny ; increment y
L3: inx ; increment x x=4, a=0f
bpl L1 ; loop while high bit not set
rts
;===========================
; opendir / read_file
;===========================
; turn on drive and read volume table of contents
read_file:
opendir:
mlsmc01:lda $c0e9 ; turn slot#6 drive on
ldx #0
stx adrlo ; zero out adrlo
stx secsize ; zero out secsize
lda #$11 ; a=$11 (VTOC)
jsr readdirsec
firstent:
lda dirbuf+1
; lock if entry not found
entry_not_found:
beq entry_not_found
; read directory sector
ldx dirbuf+2
jsr seekread1
ldy #7 ;number of directory entries in a sector
ldx #$2b ;offset of filename in directory entry
nextent:
tya
pha ; was **phy**
txa
pha ; was **phx**
ldy #$1d
; match name backwards (slower but smaller)
L4:
lda (namlo), y
cmp dirbuf, x
beq foundname
pla
; move to next directory in this block, if possible
clc
adc #$23
tax
pla
tay ; was **ply**
dey
bne nextent
beq firstent ; was **bra**
foundname:
dex
dey
bpl L4
pla
tay ; was **ply**
pla
; read track/sector list
lda dirbuf-32, y
ldx dirbuf-31, y
jsr seekread1
; read load offset and length info only, initially
lda #<filbuf
sta adrlo
lda #4
sta secsize
lda dirbuf+12
ldx dirbuf+13
ldy #>filbuf
jsr seekread
; reduce load offset by 4, to account for offset and length
sec
lda filbuf
sbc #4
sta adrlo
lda filbuf+1
sbc #0
sta adrhi
; save on stack bytes that will be overwritten by extra read
ldy #3
L5:
lda (adrlo), y
pha
dey
bpl L5
lda adrhi
pha
lda adrlo
pha
; increase load size by 4, to account for offst and length
lda filbuf+2
adc #3
sta sizelo
sta secsize
lda filbuf+3
adc #0
sta sizehi
beq readfirst
lda #0 ; was **stz secsize**
sta secsize
readfirst:
ldy #$0c
; read a file sector
readnext:
tya
pha
lda dirbuf, y ; A = track
ldx dirbuf+1, y ; x = sector
jsr seekread1
pla
tay
; if low count is non-zero then we are done
; (can happen only for partial last block)
lda secsize
bne readdone
; continue if more than $100 bytes left
dec sizehi
bne L6
; set read size to min(length, $100)
lda sizelo
beq readdone
sta secsize
L6:
inc adrhi
iny
iny
bne readnext
; save current address for after t/s read
lda adrhi
pha
lda adrlo
pha
lda #0
sta adrlo ; was **stz adrlo**
; read next track/sector sector
lda dirbuf+1
ldx dirbuf+2
jsr readdirsec
clc
; restore current address
readdone:
pla
; sta adrhi
; pla
sta adrlo ; code originally had this backwards
pla
sta adrhi
bcc readfirst
mlsmc02:lda $c0e8
; restore from stack bytes that were overwritten by extra read
ldx #3
ldy #0
L7:
pla
sta (adrlo), y
iny
dex
bpl L7
rts
;======================
; readdirsec
;======================
; a = track?
; x = sector?
readdirsec:
ldy #>dirbuf
seekread:
sty adrhi
seekread1:
sta phase
lda sectbl, x
sta reqsec
jsr readadr
; if track does not match, then seek
cpx phase
beq checksec
jsr seek
;=========================================
; re merge in with qkumba's recent changes
; to fix seek problem?
;=========================================
; [re-]read sector
re_read_addr:
jsr readadr
checksec:
cmp reqsec
bne re_read_addr
;=========================
; read sector data
;=========================
readdata:
jsr readd5aa
eor #$ad ; zero A if match
bne re_read_addr
L12:
mlsmc03:ldx $c0ec ; read until valid data (high bit set)
bpl L12
eor nibtbl-$80, x
sta bit2tbl-$aa, y
iny
bne L12
L13:
mlsmc04:ldx $c0ec ; read until valid data (high bit set)
bpl L13
eor nibtbl-$80, x
sta (adrlo), y ; the real address
iny
cpy secsize
bne L13
ldy #0
L14:
ldx #$a9
L15:
inx
beq L14
lda (adrlo), y
lsr bit2tbl-$aa, x
rol
lsr bit2tbl-$aa, x
rol
sta (adrlo), y
iny
cpy secsize
bne L15
rts
; no tricks here, just the regular stuff
;=======================
; readaddr -- read the address field
;=======================
; Find address field, put track in cutrk, sector in tmpsec
readadr:
jsr readd5aa
cmp #$96
bne readadr
ldy #3 ; three?
; first read volume/volume
; then track/track
; then sector/sector?
adr_read_two_bytes:
tax
jsr readnib
rol
sta tmpsec
jsr readnib
and tmpsec
dey
bne adr_read_two_bytes
rts
;========================
; make sure we see the $D5 $AA pattern
readd5aa:
L16:
jsr readnib
L17:
cmp #$d5
bne L16
jsr readnib
cmp #$aa
bne L17
tay ; we need Y=#$AA later
readnib:
mlsmc05:lda $c0ec ; read until valid (high bit set)
bpl readnib
seekret:
rts
;=====================
; SEEK
;=====================
; current track in X?
; desired track in phase
seek:
ldy #0
sty step
asl phase ; multiply by two
txa ; current track?
asl ; mul by two
copy_cur:
tax
sta tmptrk
sec
sbc phase
beq L22
bcs L18
eor #$ff
inx
bcc L19
L18:
sbc #1
dex
L19:
cmp step
bcc L20
lda step
L20:
cmp #8
bcs L21
tay
sec
L21:
txa
pha
ldx step1, y
L22:
php
bne L24
L23:
clc
lda tmptrk
ldx step2, y
L24:
stx tmpsec
and #3
rol
tax
lsr
mlsmc06:lda $c0e0, x
L25:
ldx #$12
L26:
dex
bpl L26
dec tmpsec
bne L25
bcs L23
plp
beq seekret
pla
inc step
bne copy_cur
.if 0
;==============================
; old code
; [re-]read sector
re_read_addr:
jsr readadr
repeat_until_right_sector:
cmp reqsec
bne re_read_addr
;==========================
; read sector data
;==========================
;
readdata:
mlsmc07:
ldy $c0ec ; read data until valid
bpl readdata
find_D5:
cpy #$d5 ; if not D5, repeat
bne readdata
find_AA:
mlsmc08:
ldy $c0ec ; read data until valid, should be AA
bpl find_AA
cpy #$aa ; we need Y=#$AA later
bne find_D5
find_AD:
mlsmc09:lda $c0ec ; read data until high bit set (valid)
bpl find_AD
eor #$ad ; should match $ad
bne * ; lock if didn't find $ad (failure)
L12:
mlsmc0A:ldx $c0ec ; read data until high bit set (valid)
bpl L12
eor nibtbl-$80, x
sta bit2tbl-$aa, y
iny
bne L12
L13:
mlsmc0B:ldx $c0ec ; read data until high bit set (valid)
bpl L13
eor nibtbl-$80, x
sta (adrlo), y ; the real address
iny
cpy secsize
bne L13
ldy #0
L14:
ldx #$a9
L15:
inx
beq L14
lda (adrlo), y
lsr bit2tbl-$aa, x
rol
lsr bit2tbl-$aa, x
rol
sta (adrlo), y
iny
cpy secsize
bne L15
rts
; no tricks here, just the regular stuff
;=================
; readadr -- read address field
;=================
; Find address field, put track in cutrk, sector in tmpsec
readadr:
mlsmc0C:lda $c0ec ; read data until we find a $D5
bpl readadr
adr_d5:
cmp #$d5
bne readadr
adr_aa:
mlsmc0D:lda $c0ec ; read data until we find a $AA
bpl adr_aa
cmp #$aa
bne adr_d5
adr_96:
mlsmc0E:lda $c0ec ; read data until we find a $96
bpl adr_96
cmp #$96
bne adr_d5
ldy #3 ; three?
; first read volume/volume
; then track/track
; then sector/sector?
adr_read_two_bytes:
sta curtrk ; store out current track
tax
L20:
mlsmc0F:lda $c0ec ; read until full value
bpl L20
rol
sta tmpsec
L21:
mlsmc10:lda $c0ec ; read until full value
bpl L21 ; sector value is (v1<<1)&v2????
and tmpsec
dey ; loop 3 times
bne adr_read_two_bytes
seekret:
rts ; return
;================
; SEEK
;================
; current track in curtrk
; desired track in phase
seek:
asl curtrk ; multiply by 2
asl phase ; multiply by 2
lda #0
sta step
copy_cur:
lda curtrk ; load current track
sta tmptrk ; store as temptrk
sec ; calc current-desired
sbc phase
beq seekret ; if they match, we are done!
bcs seek_neg ; if negative, skip ahead
eor #$ff ; ones-complement the distance
inc curtrk ; increment current (make it 2s comp?)
bcc L114 ; skip ahead
seek_neg:
adc #$fe
dec curtrk
L114:
cmp step
bcc L115
lda step
L115:
cmp #8
bcs L116
tay
sec
L116:
lda curtrk
ldx step1, y
bne L118
L117:
clc
lda tmptrk
ldx step2, y
L118:
stx tmpsec
and #3
rol
tax
mlsmc11:sta $c0e0, x
L119:
ldx #$13
L120:
dex
bne L120
dec tmpsec
bne L119
lsr
bcs L117
inc step
bne copy_cur
.endif
step1: .byte $01, $30, $28, $24, $20, $1e, $1d, $1c
step2: .byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c
sectbl: .byte $00,$0d,$0b,$09,$07,$05,$03,$01,$0e,$0c,$0a,$08,$06,$04,$02,$0f
; From $BA96 of DOS33
nibtbl: .res 128 ; = *
; .byte $00,$01,$98,$99,$02,$03,$9C,$04 ; $BA96 ; 00
; .byte $05,$06,$A0,$A1,$A2,$A4,$A4,$A5 ; $BA9E ; 08
; .byte $07,$08,$A8,$A9,$AA,$09,$0A,$0B ; $BAA6 ; 10
; .byte $0C,$0D,$B0,$B1,$0E,$0F,$10,$11 ; $BAAE ; 18
; .byte $12,$13,$B8,$14,$15,$16,$17,$18 ; $BAB6 ; 20
; .byte $19,$1A,$C0,$C1,$C2,$C3,$C4,$C5 ; $BABE ; 28
; .byte $C6,$C7,$C8,$C9,$CA,$1B,$CC,$1C ; $BAC6 ; 30
; .byte $1D,$1E,$D0,$D1,$D2,$1E,$D4,$D5 ; $BACE ; 38
; .byte $20,$21,$D8,$22,$23,$24,$25,$26 ; $BAD6 ; 40
; .byte $27,$28,$E0,$E1,$E2,$E3,$E4,$29 ; $BADE ; 48
; .byte $2A,$2B,$E8,$2C,$2D,$2E,$2F,$30 ; $BAE6 ; 50
; .byte $31,$32,$F0,$F1,$33,$34,$35,$36 ; $BAEE ; 58
; .byte $37,$38,$F8,$39,$3A,$3B,$3C,$3D ; $BAF6 ; 60
; .byte $3E,$3F,$13,$00,$01,$02,$01,$00 ; $BAFE ; 68
; .byte $00,$00,$00,$00,$00,$00,$00,$00
; .byte $00,$00,$00,$00,$00,$00,$00,$00
bit2tbl: .res 86 ; = nibtbl+128
filbuf: .res 4 ; = bit2tbl+86
;dataend = filbuf+4

80
pt3_player/text_print.s Normal file
View File

@ -0,0 +1,80 @@
;================================
; htab_vtab
;================================
; move to CH/CV
htab_vtab:
lda CV
asl
tay
lda gr_offsets,Y ; lookup low-res memory address
clc
adc CH ; add in xpos
sta BASL ; store out low byte of addy
lda gr_offsets+1,Y ; look up high byte
adc DRAW_PAGE ;
sta BASH ; and store it out
; BASH:BASL now points at right place
rts
;================================
; move_and_print
;================================
; move to CH/CV
move_and_print:
jsr htab_vtab
;================================
; print_string
;================================
print_string:
ldy #0
print_string_loop:
lda (OUTL),Y
beq done_print_string
ora #$80
sta (BASL),Y
iny
bne print_string_loop
done_print_string:
rts
;====================
; point_to_end_string
;====================
point_to_end_string:
iny
tya
clc
adc OUTL
sta OUTL
lda #0
adc OUTH
sta OUTH
rts
;================================
; print_both_pages
;================================
print_both_pages:
lda DRAW_PAGE
pha
lda #0
sta DRAW_PAGE
jsr move_and_print
lda #4
sta DRAW_PAGE
jsr move_and_print
pla
sta DRAW_PAGE
rts ; oops forgot this initially
; explains the weird vertical stripes on the screen

261
pt3_player/zp.inc Normal file
View File

@ -0,0 +1,261 @@
.define EQU =
LZ4_SRC EQU $00
LZ4_DST EQU $02
LZ4_END EQU $04
COUNT EQU $06
DELTA EQU $08
;; Zero page monitor routines addresses
WNDLFT EQU $20
WNDWDTH EQU $21
WNDTOP EQU $22
WNDBTM EQU $23
CH EQU $24
CV EQU $25
GBASL EQU $26
GBASH EQU $27
BASL EQU $28
BASH EQU $29
H2 EQU $2C
V2 EQU $2D
MASK EQU $2E
COLOR EQU $30
;INVFLG EQU $32
; dos33 zero page = 26-2f, 35-38, 3e 3f 40-4d
; overlap applesoft 67-6a,6f,70,af,b0,ca-cd,d8
; DOS33: Confirmed kills $68
RWTSL EQU $60
RWTSH EQU $61
DOSBUFL EQU $62
DOSBUFH EQU $63
FILEML EQU $64
FILEMH EQU $65
;TURNING EQU $60
;SCREEN_X EQU $61 ; not used?
;SCREEN_Y EQU $62
;ANGLE EQU $63
;HORIZ_SCALE_I EQU $64
;HORIZ_SCALE_F EQU $65
;FACTOR_I EQU $66
;FACTOR_F EQU $67
;DX_I EQU $68
;DX_F EQU $69
;SPACEX_I EQU $6A
;SPACEX_F EQU $6B
;CX_I EQU $6C
;CX_F EQU $6D
;DY_I EQU $6E
;DY_F EQU $6F
REGISTER_DUMP EQU $70
A_FINE_TONE EQU $70
A_COARSE_TONE EQU $71
B_FINE_TONE EQU $72
B_COARSE_TONE EQU $73
C_FINE_TONE EQU $74
C_COARSE_TONE EQU $75
NOISE EQU $76
ENABLE EQU $77
A_VOLUME EQU $78
B_VOLUME EQU $79
C_VOLUME EQU $7A
ENVELOPE_FINE EQU $7B
ENVELOPE_COARSE EQU $7C
ENVELOPE_SHAPE EQU $7D
COPY_OFFSET EQU $7E
DECODER_STATE EQU $7F
;SPACEY_I EQU $70
;SPACEY_F EQU $71
;CY_I EQU $72
;CY_F EQU $73
;TEMP_I EQU $74
;TEMP_F EQU $75
;DISTANCE_I EQU $76
;DISTANCE_F EQU $77
;SPACEZ_I EQU $78
;SPACEZ_F EQU $79
;DRAW_SPLASH EQU $7A
;SPEED EQU $7B
;SPLASH_COUNT EQU $7C
;OVER_LAND EQU $7D
;NUM1L EQU $7E
;NUM1H EQU $7F
CHUNKSIZE EQU $80
LZ4_DONE EQU $81
DECODE_ERROR EQU $82
A_COLOR EQU $83
B_COLOR EQU $84
C_COLOR EQU $85
COPY_TIME EQU $86
DECOMPRESS_TIME EQU $87
TIME_TAKEN EQU $88
SCREEN_Y EQU $89
WHICH_FILE EQU $8A
;NUM2L EQU $80
;NUM2H EQU $81
;RESULT EQU $82 ; 83,84,85
;NEGATE EQU $86 ; UNUSED?
;LAST_SPACEX_I EQU $87
;LAST_SPACEY_I EQU $88
;LAST_MAP_COLOR EQU $89
;DRAW_SKY EQU $8A
COLOR_MASK EQU $8B
RASTERBARS_ON EQU $8C
;KEY_COUNT EQU $8C
;KEY_OFFSET EQU $8D
;DRAW_BLUE_SKY EQU $8E
RANDOM_POINTER EQU $8F
FRAME_COUNT EQU $90
MB_VALUE EQU $91
;MB_CHUNK EQU $92
MB_ADDRL EQU $91
MB_ADDRH EQU $92
DONE_PLAYING EQU $93
;MB_FRAME_DIFF EQU $94
MB_CHUNK_OFFSET EQU $94
;LZSS_RL EQU $95
;LZSS_RH EQU $96
;LZSS_COUNT EQU $97
;LZSS_MASK EQU $98
;LZSS_ENDL EQU $99
;LZSS_ENDH EQU $9A
;MB_FRAME_DIFF2 EQU $9F
; More zero-page addresses
; we try not to conflict with anything DOS, MONITOR or BASIC related
;COLOR1 EQU $E0
COLOR2 EQU $E1
;MATCH EQU $E2
XX EQU $E3
;YY EQU $E4
;SHIPY EQU $E4
;YADD EQU $E5
;LOOP EQU $E6
;MEMPTRL EQU $E7
;MEMPTRH EQU $E8
;NAMEL EQU $E9
;NAMEH EQU $EA
;NAMEX EQU $EB
;CHAR EQU $EC
DISP_PAGE EQU $ED
DRAW_PAGE EQU $EE
;FIRST EQU $F0
LASTKEY EQU $F1
;PADDLE_STATUS EQU $F2
;XPOS EQU $F3
;YPOS EQU $F4
namlo = $f6
namhi = $f7
step = $f8 ; state for stepper motor
tmptrk = $f9 ; temporary copy of current track
phase = $fa ; current phase for /seek
TEMP EQU $FA
;RUN EQU $FA
;TEMP2 EQU $FB
TEMPY EQU $FB
INL EQU $FC
INH EQU $FD
OUTL EQU $FE
OUTH EQU $FF
KEYPRESS EQU $C000
KEYRESET EQU $C010
;; SOFT SWITCHES
CLR80COL EQU $C000 ; PAGE0/PAGE1 normal
SET80COL EQU $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead
EIGHTYCOL EQU $C00D
SPEAKER EQU $C030
SET_GR EQU $C050
SET_TEXT EQU $C051
FULLGR EQU $C052
TEXTGR EQU $C053
PAGE0 EQU $C054
PAGE1 EQU $C055
LORES EQU $C056 ; Enable LORES graphics
HIRES EQU $C057 ; Enable HIRES graphics
AN3 EQU $C05E ; Annunciator 3
PADDLE_BUTTON0 EQU $C061
PADDL0 EQU $C064
PTRIG EQU $C070
;; BASIC ROUTINES
NORMAL EQU $F273
;; MONITOR ROUTINES
HLINE EQU $F819 ;; HLINE Y,$2C at A
VLINE EQU $F828 ;; VLINE A,$2D at Y
CLRSCR EQU $F832 ;; Clear low-res screen
CLRTOP EQU $F836 ;; clear only top of low-res screen
SETCOL EQU $F864 ;; COLOR=A
TEXT EQU $FB36
TABV EQU $FB5B ;; VTAB to A
BASCALC EQU $FBC1 ;;
VTAB EQU $FC22 ;; VTAB to CV
HOME EQU $FC58 ;; Clear the text screen
WAIT EQU $FCA8 ;; delay 1/2(26+27A+5A^2) us
SETINV EQU $FE80 ;; INVERSE
SETNORM EQU $FE84 ;; NORMAL
COUT EQU $FDED ;; output A to screen
COUT1 EQU $FDF0 ;; output A to screen
COLOR_BLACK EQU 0
COLOR_RED EQU 1
COLOR_DARKBLUE EQU 2
COLOR_PURPLE EQU 3
COLOR_DARKGREEN EQU 4
COLOR_GREY EQU 5
COLOR_MEDIUMBLUE EQU 6
COLOR_LIGHTBLUE EQU 7
COLOR_BROWN EQU 8
COLOR_ORANGE EQU 9
COLOR_GREY2 EQU 10
COLOR_PINK EQU 11
COLOR_LIGHTGREEN EQU 12
COLOR_YELLOW EQU 13
COLOR_AQUA EQU 14
COLOR_WHITE EQU 15
COLOR_BOTH_BLACK EQU $00
COLOR_BOTH_RED EQU $11
COLOR_BOTH_DARKBLUE EQU $22
COLOR_BOTH_DARKGREEN EQU $44
COLOR_BOTH_GREY EQU $55
COLOR_BOTH_MEDIUMBLUE EQU $66
COLOR_BOTH_LIGHTBLUE EQU $77
COLOR_BOTH_BROWN EQU $88
COLOR_BOTH_ORANGE EQU $99
COLOR_BOTH_PINK EQU $BB
COLOR_BOTH_LIGHTGREEN EQU $CC
COLOR_BOTH_YELLOW EQU $DD
COLOR_BOTH_AQUA EQU $EE
COLOR_BOTH_WHITE EQU $FF
AUX_BOTH_MEDIUMBLUE EQU $33 ; 0011 0011
AUX_BOTH_GREY EQU $AA ; 1010 1010