This commit is contained in:
Vince Weaver 2018-11-19 19:33:34 -05:00
commit e6900ced57
22 changed files with 3018 additions and 104 deletions

View File

@ -11,66 +11,67 @@ $(DOS33):
chiptune_player.dsk: CHIPTUNE_PLAYER ./krw/INTRO2.KRW HELLO
cp chiptune_empty.dsk chiptune_player.dsk
$(DOS33) -y chiptune_player.dsk SAVE A HELLO
$(DOS33) -y chiptune_player.dsk BSAVE -a 0x0C00 CHIPTUNE_PLAYER
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/CAMOUFLAGE.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/CHRISTMAS.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/CRMOROS.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/DEATH2.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/DEMO4.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/HARKONEN.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/INTRO2.KRW
# $(DOS33) -y chiptune_player.dsk SAVE B ./krw/KORO.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/LYRA2.KRW
# $(DOS33) -y chiptune_player.dsk SAVE B ./krw/MMCM.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/RANDOM.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/ROBOT.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/SDEMO.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/SPUTNIK.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/TECHNO.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/UNIVERSE.KRW
$(DOS33) -y chiptune_player.dsk SAVE B ./krw/WAVE.KRW
$(DOS33) -y chiptune_player.dsk BSAVE -a 0x0800 CHIPTUNE_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
chiptune_unrolled.dsk: CHIPTUNE_UNROLLED ./krw/INTRO2.KRW
cp chiptune_empty.dsk chiptune_unrolled.dsk
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x0C00 CHIPTUNE_UNROLLED
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/CAMOUFLAGE.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/CHRISTMAS.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/CRMOROS.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/DEATH2.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/DEMO4.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/HARKONEN.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/INTRO2.KRW
# $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/KORO.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/LYRA2.KRW
# $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/MMCM.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/RANDOM.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/ROBOT.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/SDEMO.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/SPUTNIK.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/TECHNO.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/UNIVERSE.KRW
$(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/WAVE.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x0800 CHIPTUNE_UNROLLED
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/CAMOUFLAGE.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/CHRISTMAS.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/CRMOROS.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/DEATH2.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/DEMO4.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/HARKONEN.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/INTRO2.KRW
# $(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/KORO.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/LYRA2.KRW
# $(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/MMCM.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/RANDOM.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/ROBOT.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/SDEMO.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/SPUTNIK.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/TECHNO.KRW
$(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/UNIVERSE.KRW
# $(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x1c00 ./krw/WAVE.KRW
HELLO: hello.bas
../asoft_basic-utils/tokenize_asoft < hello.bas > HELLO
CHIPTUNE_PLAYER: chiptune_player.o
ld65 -o CHIPTUNE_PLAYER chiptune_player.o -C ../linker_scripts/apple2_c00.inc
ld65 -o CHIPTUNE_PLAYER chiptune_player.o -C ../linker_scripts/apple2_800.inc
chiptune_player.o: chiptune_player.s \
../asm_routines/mockingboard.s \
../asm_routines/dos33_routines.s \
../asm_routines/lz4_decode.s \
../asm_routines/keypress_minimal.s \
qkumba_rts.s \
rasterbars.s volume_bars.s interrupt_handler.s \
chip_title.inc zp.inc
song_list.inc chip_title.inc zp.inc chip_title_uncompressed.inc
ca65 -o chiptune_player.o chiptune_player.s -l chiptune_player.lst
CHIPTUNE_UNROLLED: chiptune_unrolled.o
ld65 -o CHIPTUNE_UNROLLED chiptune_unrolled.o -C ../linker_scripts/apple2_c00.inc
ld65 -o CHIPTUNE_UNROLLED chiptune_unrolled.o -C ../linker_scripts/apple2_800.inc
chiptune_unrolled.o: chiptune_player.s \
../asm_routines/mockingboard.s \

View File

@ -0,0 +1,139 @@
; LINE 0-1
; make room for jmp
;.byte $00,$00,$00,
.byte $00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$10,$10,$10,$40,$20,$20
.byte $20,$40,$20,$20,$20,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$0c,$00,$4C
; LINE 16-17
.byte $00,$11,$00,$02,$22,$22,$00,$22,$00,$22
.byte $00,$22,$00,$22,$00,$00,$00,$00,$33,$00
.byte $00,$33,$33,$33,$00,$33,$00,$00,$33,$00
.byte $33,$33,$33,$00,$33,$33,$33,$00,$11,$00
; LINE 32-33
.byte $11,$00,$00,$00,$00,$00,$00,$00,$00,$44
.byte $44,$44,$44,$44,$44,$44,$44,$44,$44,$44
.byte $44,$44,$44,$44,$44,$44,$44,$44,$44,$44
.byte $57,$00,$00,$00,$00,$00,$00,$00,$00,$11
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 2-3
.byte $00,$00,$00,$00,$00,$10,$10,$10,$11,$91
.byte $91,$91,$91,$00,$11,$11,$11,$44,$22,$22
.byte $22,$44,$22,$22,$22,$00,$91,$91,$91,$91
.byte $11,$10,$10,$10,$00,$00,$00,$00,$00,$00
; LINE 18-19
.byte $10,$11,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$11,$10
; LINE 34-35
.byte $11,$00,$00,$00,$00,$00,$00,$00,$00,$05
.byte $04,$04,$04,$04,$04,$04,$04,$04,$04,$04
.byte $04,$C4,$D4,$C4,$D4,$C4,$D4,$C4,$D4,$04
.byte $05,$00,$00,$00,$00,$00,$00,$00,$00,$11
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 4-5
.byte $00,$00,$10,$11,$91,$91,$99,$D9,$D9,$D9
.byte $DD,$CD,$CD,$C0,$00,$11,$44,$44,$44,$22
.byte $44,$44,$44,$22,$00,$C0,$CD,$CD,$DD,$D9
.byte $D9,$D9,$99,$91,$91,$91,$11,$10,$00,$00
; LINE 20-21
.byte $11,$00,$00,$00,$00,$00,$00,$00,$00,$40
.byte $40,$40,$40,$40,$40,$40,$40,$40,$40,$40
.byte $40,$40,$40,$40,$40,$40,$40,$40,$40,$40
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$11
; LINE 36-37
.byte $11,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$0C,$0D,$0C,$0D,$0C,$0D,$0C,$0D,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$11
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 6-7
.byte $00,$10,$91,$D9,$D9,$DD,$CD,$CD,$6C,$6C
.byte $6C,$06,$06,$06,$00,$01,$04,$04,$04,$02
.byte $04,$04,$04,$02,$00,$06,$06,$06,$6C,$6C
.byte $6C,$CD,$CD,$CD,$DD,$D9,$D9,$91,$10,$00
; LINE 22-23
.byte $11,$00,$00,$00,$00,$C0,$00,$00,$00,$44
.byte $55,$55,$55,$44,$55,$55,$55,$55,$55,$44
.byte $55,$45,$55,$44,$94,$44,$4E,$44,$4E,$44
.byte $00,$00,$00,$00,$00,$00,$C0,$00,$00,$11
; LINE 38-39
.byte $11,$10,$10,$10,$10,$10,$10,$10,$10,$10
.byte $10,$10,$10,$10,$10,$10,$10,$10,$10,$10
.byte $10,$10,$10,$10,$10,$10,$10,$10,$10,$10
.byte $10,$10,$10,$10,$10,$10,$10,$10,$10,$11
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 8-9
.byte $00,$11,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$11,$00
; LINE 24-25
.byte $11,$00,$00,$C0,$CC,$C0,$C0,$00,$00,$44
.byte $55,$55,$55,$44,$55,$55,$55,$55,$55,$44
.byte $55,$54,$55,$44,$94,$44,$55,$44,$55,$44
.byte $00,$00,$00,$00,$C0,$CC,$C0,$C0,$00,$11
; LINE 40-41
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 10-11
.byte $00,$11,$00,$20,$22,$22,$00,$22,$00,$22
.byte $00,$22,$00,$22,$22,$20,$00,$33,$33,$33
.byte $00,$33,$00,$33,$00,$33,$00,$00,$33,$00
.byte $33,$33,$33,$00,$33,$33,$33,$00,$11,$00
; LINE 26-27
.byte $11,$00,$9D,$9D,$9D,$9D,$00,$00,$00,$44
.byte $44,$44,$44,$44,$44,$44,$44,$44,$44,$44
.byte $44,$44,$44,$44,$44,$44,$44,$64,$44,$64
.byte $44,$00,$00,$9D,$9D,$9D,$9D,$00,$00,$11
; LINE 42-43
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 12-13
.byte $00,$11,$00,$22,$00,$00,$00,$22,$20,$22
.byte $00,$22,$00,$22,$00,$22,$00,$00,$33,$00
.byte $00,$33,$00,$33,$00,$33,$33,$30,$33,$00
.byte $33,$30,$00,$00,$33,$30,$30,$00,$11,$00
; LINE 28-29
.byte $11,$00,$21,$21,$21,$21,$21,$00,$00,$44
.byte $55,$55,$55,$44,$55,$55,$55,$55,$55,$44
.byte $55,$45,$55,$44,$54,$54,$44,$66,$44,$66
.byte $44,$00,$00,$21,$21,$21,$21,$21,$00,$11
; LINE 44-45
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
; SCREEN HOLE
.byte $00,$00,$00,$00,$00,$00,$00,$00
; LINE 14-15
.byte $00,$11,$00,$22,$00,$00,$00,$22,$02,$22
.byte $00,$22,$00,$22,$22,$02,$00,$00,$33,$00
.byte $00,$33,$00,$33,$00,$33,$00,$33,$33,$00
.byte $33,$03,$00,$00,$03,$03,$33,$00,$11,$00
; LINE 30-31
.byte $11,$00,$00,$06,$06,$06,$00,$00,$00,$44
.byte $55,$55,$55,$44,$55,$55,$55,$55,$55,$44
.byte $55,$54,$55,$44,$45,$45,$44,$46,$44,$46
.byte $44,$00,$00,$00,$06,$06,$06,$00,$00,$11
; LINE 46-47
.byte 'L'|$80,'O'|$80,'A'|$80,'D'|$80,'I'|$80,'N'|$80,'G'|$80,' '|$80,'V'|$80,'M'|$80
.byte 'W'|$80,' '|$80,'C'|$80,'H'|$80,'I'|$80,'P'|$80,'T'|$80,'U'|$80,'N'|$80,'E'|$80
.byte 'P'|$80,'L'|$80,'A'|$80,'Y'|$80,'E'|$80,'R'|$80,' '|$80,'V'|$80,'1'|$80,'.'|$80
.byte '3'|$80,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
; SCREEN HOLE
;.byte $00,$00,$00,$00,$00,$00,$00,$00

View File

@ -3,17 +3,35 @@
.include "zp.inc"
; program is ~4k, so from 0xc00 to 0x1C00
LZ4_BUFFER EQU $1C00 ; $1C00 - $5C00, 16k for now
UNPACK_BUFFER EQU $5E00 ; $5E00 - $9600, 14k, $3800
; trying not to hit DOS at $9600
; Reserve 3 chunks plus spare (14k)
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
;=============================
jsr HOME
jsr TEXT
chiptune_setup:
; jsr HOME
; jsr TEXT
; Init disk code
jsr rts_init
; init variables
@ -22,25 +40,26 @@ NUM_FILES EQU 15
sta CH
sta CV
sta DONE_PLAYING
sta XPOS
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
; lda #4 ; start at DEMO4
; lda #7 ; start at LYRA
lda #10 ; start at SDEMO
sta WHICH_FILE
; print detection message
lda #<mocking_message ; load loading message
sta OUTL
lda #>mocking_message
sta OUTH
jsr move_and_print ; print it
; 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
@ -111,25 +130,27 @@ mockingboard_found:
; Draw title screen
;============================
jsr set_gr_page0 ; set page 0
; jsr set_gr_page0 ; set page 0
lda #$4 ; draw page 1
sta DRAW_PAGE
; lda #$4 ; draw page 1
; sta DRAW_PAGE
jsr clear_screens ; clear both screens
; jsr clear_screens ; clear both screens
lda #<chip_title ; point to title data
sta GBASL
lda #>chip_title
sta GBASH
; lda #<chip_title ; point to title data
; sta GBASL
; lda #>chip_title
; sta GBASH
; bit PAGE1
; Load image ; load the image
lda #<$400
sta BASL
lda #>$400
sta BASH
; lda #<$800
; sta BASL
; lda #>$800
; sta BASH
jsr load_rle_gr
; jsr load_rle_gr
;==================
; load first song
@ -288,7 +309,7 @@ new_song:
jsr get_filename
lda #8
lda #8 ; print filename to screen
sta CH
lda #21
sta CV
@ -299,8 +320,36 @@ new_song:
sta OUTH
jsr print_both_pages
disk_buff EQU LZ4_BUFFER
read_size EQU $4000
; 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
@ -554,25 +603,10 @@ done_decrement:
;==========
; filenames
;==========
krw_file:
.asciiz "CAMOUFLAGE.KRW"
.asciiz "CHRISTMAS.KRW"
.asciiz "CRMOROS.KRW"
.asciiz "DEATH2.KRW"
.asciiz "DEMO4.KRW"
.asciiz "HARKONEN.KRW"
.asciiz "INTRO2.KRW"
.asciiz "LYRA2.KRW"
.asciiz "RANDOM.KRW"
.asciiz "ROBOT.KRW"
.asciiz "SDEMO.KRW"
.asciiz "SPUTNIK.KRW"
.asciiz "TECHNO.KRW"
.asciiz "UNIVERSE.KRW"
.asciiz "WAVE.KRW"
.include "song_list.inc"
;=========
;routines
@ -582,9 +616,9 @@ krw_file:
.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_unrle.s"
.include "../asm_routines/gr_setpage.s"
.include "../asm_routines/dos33_routines.s"
.include "qkumba_rts.s"
.include "../asm_routines/gr_hlin.s"
.include "../asm_routines/lz4_decode.s"
.include "../asm_routines/keypress_minimal.s"
@ -598,13 +632,9 @@ krw_file:
;=========
; strings
;=========
mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD IN SLOT #4"
;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"
;============
; graphics
;============
.include "chip_title.inc"

View File

@ -1,4 +1,4 @@
5 PRINT
10 PRINT "LOADING VMW CHIPTUNE PLAYER V1.2"
50 PRINT
5 GR
10 PRINT "LOADING VMW CHIPTUNE PLAYER V1.3"
50 PRINT: X=PEEK(49237)
100 PRINT CHR$ (4)"BRUN CHIPTUNE_PLAYER"

Binary file not shown.

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

View File

@ -0,0 +1,15 @@
.asciiz "CAMOUFLAGE.KRW"
.asciiz "CHRISTMAS.KRW"
.asciiz "CRMOROS.KRW"
.asciiz "DEATH2.KRW"
.asciiz "DEMO4.KRW"
.asciiz "HARKONEN.KRW"
.asciiz "INTRO2.KRW"
.asciiz "LYRA2.KRW"
.asciiz "RANDOM.KRW"
.asciiz "ROBOT.KRW"
.asciiz "SDEMO.KRW"
.asciiz "SPUTNIK.KRW"
.asciiz "TECHNO.KRW"
.asciiz "UNIVERSE.KRW"
.asciiz "WAVE.KRW"

View File

@ -153,8 +153,18 @@ DRAW_PAGE EQU $EE
;FIRST EQU $F0
LASTKEY EQU $F1
;PADDLE_STATUS EQU $F2
XPOS EQU $F3
YPOS EQU $F4
;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

49
dya/Makefile Normal file
View File

@ -0,0 +1,49 @@
include ../Makefile.inc
DOS33 = ../dos33fs-utils/dos33
PNG2GR = ../gr-utils/png2gr
all: chiptune_dya.dsk
$(DOS33):
cd ../dos33fs-utils && make
chiptune_dya.dsk: CHIPTUNE_PLAYER HELLO
cp chiptune_empty.dsk chiptune_dya.dsk
$(DOS33) -y chiptune_dya.dsk SAVE A HELLO
$(DOS33) -y chiptune_dya.dsk BSAVE -a 0x0C00 CHIPTUNE_PLAYER
$(DOS33) -y chiptune_dya.dsk SAVE B DOTD1.KRW
$(DOS33) -y chiptune_dya.dsk SAVE B DOTD2.KRW
HELLO: hello.bas
../asoft_basic-utils/tokenize_asoft < hello.bas > HELLO
CHIPTUNE_PLAYER: chiptune_player.o
ld65 -o CHIPTUNE_PLAYER chiptune_player.o -C ../linker_scripts/apple2_c00.inc
chiptune_player.o: chiptune_player.s \
../asm_routines/mockingboard.s \
../asm_routines/dos33_routines.s \
../asm_routines/lz4_decode.s \
../asm_routines/keypress_minimal.s \
rasterbars.s volume_bars.s interrupt_handler.s \
chip_title.inc zp.inc
ca65 -o chiptune_player.o chiptune_player.s -l chiptune_player.lst
CHIPTUNE_UNROLLED: chiptune_unrolled.o
ld65 -o CHIPTUNE_UNROLLED chiptune_unrolled.o -C ../linker_scripts/apple2_c00.inc
chiptune_unrolled.o: chiptune_player.s \
../asm_routines/mockingboard.s \
../asm_routines/dos33_routines.s \
../asm_routines/lz4_decode.s \
../asm_routines/keypress_minimal.s \
rasterbars.s volume_bars.s interrupt_handler_unrolled.s \
chip_title.inc zp.inc
ca65 -D UNROLLED=1 -o chiptune_unrolled.o chiptune_player.s -l chiptune_unrolled.lst
clean:
rm -f *~ TITLE.GR *.o *.lst \
CHIPTUNE_PLAYER HELLO

51
dya/chip_title.inc Normal file
View File

@ -0,0 +1,51 @@
chip_title: .byte $28 ; ysize=40
.byte $AE,$00, $A3,$10, $40, $A3,$20, $40, $A3,$20, $A0,$14,$00
.byte $A3,$10, $11, $A4,$91, $00, $A3,$11, $44, $A3,$22
.byte $44, $A3,$22, $00, $A4,$91, $11, $A3,$10, $A8,$00
.byte $10, $11, $91,$91, $99, $A3,$D9, $DD, $CD,$CD
.byte $C0, $00, $11, $A3,$44, $22, $A3,$44, $22
.byte $00, $C0, $CD,$CD, $DD, $A3,$D9, $99, $A3,$91
.byte $11, $10, $A3,$00, $10, $91, $D9,$D9, $DD
.byte $CD,$CD, $A3,$6C, $A3,$06, $00, $01, $A3,$04, $02
.byte $A3,$04, $02, $00, $A3,$06, $A3,$6C, $A3,$CD, $DD
.byte $D9,$D9, $91, $10, $00,$00, $11, $A0,$24,$00, $11
.byte $00,$00, $11, $00, $20, $22,$22, $00, $22
.byte $00, $22, $00, $22, $00, $22,$22, $20
.byte $00, $A3,$33, $00, $33, $00, $33, $00
.byte $33, $00,$00, $33, $00, $A3,$33, $00, $A3,$33
.byte $00, $11, $00,$00, $11, $00, $22, $A3,$00
.byte $22, $20, $22, $00, $22, $00, $22
.byte $00, $22, $00,$00, $33, $00,$00, $33, $00
.byte $33, $00, $33,$33, $30, $33, $00, $33
.byte $30, $00,$00, $33, $30,$30, $00, $11, $00,$00
.byte $11, $00, $22, $A3,$00, $22, $02, $22
.byte $00, $22, $00, $22,$22, $02, $00,$00, $33
.byte $00,$00, $33, $00, $33, $00, $33, $00
.byte $33,$33, $00, $33, $03, $00,$00, $03,$03, $33
.byte $00, $11, $00,$00, $11, $00, $02, $22,$22
.byte $00, $22, $00, $22, $00, $22, $00
.byte $22, $A4,$00, $33, $00,$00, $A3,$33, $00, $33
.byte $00,$00, $33, $00, $A3,$33, $00, $A3,$33, $00
.byte $11, $00, $10, $11, $A0,$24,$00, $11, $10
.byte $11, $A8,$00, $A0,$15,$40, $A9,$00, $11,$11, $A4,$00, $C0
.byte $A3,$00, $44, $A3,$55, $44, $A5,$55, $44, $55
.byte $45, $55, $44, $94, $44, $4E, $44
.byte $4E, $44, $A6,$00, $C0, $00,$00, $11,$11, $00,$00
.byte $C0, $CC, $C0,$C0, $00,$00, $44, $A3,$55, $44
.byte $A5,$55, $44, $55, $54, $55, $44, $94
.byte $44, $55, $44, $55, $44, $A4,$00, $C0
.byte $CC, $C0,$C0, $00, $11,$11, $00, $A4,$9D, $A3,$00
.byte $A0,$12,$44, $64, $44, $64, $44, $00,$00, $A4,$9D
.byte $00,$00, $11,$11, $00, $A5,$21, $00,$00, $44, $A3,$55
.byte $44, $A5,$55, $44, $55, $45, $55, $44
.byte $54,$54, $44, $66, $44, $66, $44, $00,$00
.byte $A5,$21, $00, $11,$11, $00,$00, $A3,$06, $A3,$00, $44
.byte $A3,$55, $44, $A5,$55, $44, $55, $54, $55
.byte $44, $45,$45, $44, $46, $44, $46, $44
.byte $A3,$00, $A3,$06, $00,$00, $11,$11, $A8,$00, $A0,$15,$44, $57
.byte $A8,$00, $11,$11, $A8,$00, $05, $AB,$04, $C4, $D4
.byte $C4, $D4, $C4, $D4, $C4, $D4, $04
.byte $05, $A8,$00, $11,$11, $A0,$14,$00, $0C, $0D, $0C
.byte $0D, $0C, $0D, $0C, $0D, $AA,$00, $11,$11
.byte $A0,$26,$10, $11
.byte $A1

BIN
dya/chiptune_empty.dsk Normal file

Binary file not shown.

595
dya/chiptune_player.s Normal file
View File

@ -0,0 +1,595 @@
; VMW Chiptune Player
.include "zp.inc"
; program is ~4k, so from 0xc00 to 0x1C00
LZ4_BUFFER EQU $1C00 ; $1C00 - $5C00, 16k for now
UNPACK_BUFFER EQU $5E00 ; $5E00 - $9600, 14k, $3800
; trying not to hit DOS at $9600
; Reserve 3 chunks plus spare (14k)
NUM_FILES EQU 15
;=============================
; Setup
;=============================
jsr HOME
jsr TEXT
; init variables
lda #0
sta DRAW_PAGE
sta CH
sta CV
sta DONE_PLAYING
sta XPOS
sta MB_CHUNK_OFFSET
sta DECODE_ERROR
lda #$ff
sta RASTERBARS_ON
; lda #4 ; start at DEMO4
; lda #7 ; start at LYRA
lda #10 ; start at SDEMO
sta WHICH_FILE
; 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
; Load image ; load the image
lda #<$400
sta BASL
lda #>$400
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
sta CH
lda #21
sta CV
lda INL
sta OUTL
lda INH
sta OUTH
jsr print_both_pages
disk_buff EQU LZ4_BUFFER
read_size EQU $4000
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 "../asm_routines/dos33_routines.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"
;============
; graphics
;============
.include "chip_title.inc"

5
dya/hello.bas Normal file
View File

@ -0,0 +1,5 @@
5 PRINT
10 PRINT "LOADING VMW CHIPTUNE PLAYER"
20 PRINT "DYA SPECIAL EDITION V1.0"
50 PRINT
100 PRINT CHR$ (4)"BRUN CHIPTUNE_PLAYER"

376
dya/interrupt_handler.s Normal file
View File

@ -0,0 +1,376 @@
;================================
;================================
; 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
TIME_OFFSET EQU 13
interrupt_handler:
; 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 mb_play_music ; if song done, don't play music ; 3/2nt
jmp check_keyboard ; 3
;============
; 13
mb_play_music:
;======================================
; Write frames to Mockingboard
;======================================
; actually plays frame loaded at end of
; last interrupt, so 20ms behind?
mb_write_frame:
ldx #0 ; set up reg count ; 2
;============
; 2
;==================================
; loop through the 14 registers
; reading the value, then write out
;==================================
; inlined "write_ay_both" to save up to 156 (12*13) cycles
; unrolled
mb_write_loop:
lda REGISTER_DUMP,X ; load register value ; 4
cmp REGISTER_OLD,X ; compare with old values ; 4
beq mb_no_write ; 3/2nt
;=============
; typ 11
; 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
lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_ORB1 ; 4
sta MOCK_6522_ORB2 ; 4
; value
lda REGISTER_DUMP,X ; load register value ; 4
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
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_ORB1 ; 4
sta MOCK_6522_ORB2 ; 4
;===========
; 62
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:
;=====================================
; Copy registers to old
;=====================================
ldx #13 ; 2
mb_reg_copy:
lda REGISTER_DUMP,X ; load register value ; 4
sta REGISTER_OLD,X ; compare with old values ; 4
dex ; 2
bpl mb_reg_copy ; 2nt/3
;=============
; 171
;===================================
; Load all 14 registers in advance
;===================================
; note, assuming not cross page boundary, not any slower
; then loading from zero page?
mb_load_values:
ldx #0 ; set up reg count ; 2
ldy MB_CHUNK_OFFSET ; get chunk offset ; 3
;=============
; 5
mb_load_loop:
lda (INL),y ; load register value ; 5
sta REGISTER_DUMP,X ; 4
;============
; 9
;====================
; point to next page
;====================
clc ; point to next interleaved ; 2
lda INH ; page by adding CHUNKSIZE (3/1); 3
adc CHUNKSIZE ; 3
sta INH ; 3
inx ; point to next register ; 2
cpx #14 ; if 14 we're done ; 2
bmi mb_load_loop ; otherwise, loop ; 3/2nt
;============
; 18
;=========================================
; if A_COARSE_TONE is $ff then we are done
lda A_COARSE_TONE ; 3
bpl mb_not_done ; 3/2nt
lda #1 ; set done playing ; 2
jmp quiet_exit ; 3
;===========
; typ 6
mb_not_done:
;==============================================
; incremement offset. If 0 move to next chunk
;==============================================
increment_offset:
inc MB_CHUNK_OFFSET ; increment offset ; 5
bne back_to_first_reg ; if not zero, done ; 3/2nt
;=====================
; move to next state
;=====================
clc
rol DECODER_STATE ; next state ; 5
; 20 -> 40 -> 80 -> c+00
bcs wraparound_to_a ; 3/2nt
bit DECODER_STATE ;bit7->N bit6->V
bvs back_to_first_reg ; do nothing on B ; 3/2nt
start_c:
lda #1
sta CHUNKSIZE
; setup next three chunks of song
lda #1 ; start decompressing
sta DECOMPRESS_TIME ; outside of handler
jmp back_to_first_reg
wraparound_to_a:
lda #$3
sta CHUNKSIZE
lda #$20
sta DECODER_STATE
sta COPY_TIME ; start copying
lda DECOMPRESS_TIME
beq blah
lda #1
sta DECODE_ERROR
blah:
;==============================
; After 14th reg, reset back to
; read R0 data
;==============================
back_to_first_reg:
lda #0 ; 2
bit DECODER_STATE ; 3
bmi back_to_first_reg_c ; 2nt/3
bvc back_to_first_reg_a ; 2nt/3
back_to_first_reg_b:
lda #$1 ; offset by 1
back_to_first_reg_a:
clc ; 2
adc #>UNPACK_BUFFER ; in proper chunk 1 or 2 ; 2
jmp update_r0_pointer ; 3
back_to_first_reg_c:
lda #>(UNPACK_BUFFER+$2A00) ; in linear C area ; 2
update_r0_pointer:
sta INH ; update r0 pointer ; 3
;=================================
; Finally done with this interrupt
;=================================
done_interrupt:
;=====================
; Update time counter
;=====================
update_time:
inc FRAME_COUNT ; 5
lda FRAME_COUNT ; 3
cmp #50 ; 3
bne done_time ; 3/2nt
lda #$0 ; 2
sta FRAME_COUNT ; 3
update_second_ones:
inc $7d0+TIME_OFFSET+3 ; 6
inc $bd0+TIME_OFFSET+3 ; 6
lda $bd0+TIME_OFFSET+3 ; 4
cmp #$ba ; one past '9' ; 2
bne done_time ; 3/2nt
lda #'0'+$80 ; 2
sta $7d0+TIME_OFFSET+3 ; 4
sta $bd0+TIME_OFFSET+3 ; 4
update_second_tens:
inc $7d0+TIME_OFFSET+2 ; 6
inc $bd0+TIME_OFFSET+2 ; 6
lda $bd0+TIME_OFFSET+2 ; 4
cmp #$b6 ; 6 (for 60 seconds) ; 2
bne done_time ; 3/2nt
lda #'0'+$80 ; 2
sta $7d0+TIME_OFFSET+2 ; 4
sta $bd0+TIME_OFFSET+2 ; 4
update_minutes:
inc $7d0+TIME_OFFSET ; 6
inc $bd0+TIME_OFFSET ; 6
; we don't handle > 9:59 songs yet
done_time:
;=============
; 90 worst
;=================================
; Moved visualization here as a hack
;=================================
;============================
; Visualization
;============================
jsr clear_top
lda RASTERBARS_ON
beq skip_rasters
jsr draw_rasters
skip_rasters:
jsr volume_bars
jsr page_flip
check_keyboard:
jsr get_key
lda LASTKEY
beq exit_interrupt
cmp #(' '+$80)
bne key_R
key_space:
lda #$80
eor DONE_PLAYING
jmp quiet_exit
key_R:
cmp #'R'
bne key_left
lda #$ff
eor RASTERBARS_ON
sta RASTERBARS_ON
jmp done_key
key_left:
cmp #'A'
bne key_right
lda #$40
bne quiet_exit
key_right:
cmp #'D'
bne done_key
lda #$20
bne quiet_exit
done_key:
jmp exit_interrupt
quiet_exit:
sta DONE_PLAYING
jsr clear_ay_both
;=====================================
; clear register area
;=====================================
ldx #13 ; 2
lda #0 ; 2
mb_clear_reg:
sta REGISTER_DUMP,X ; clear register value ; 4
sta REGISTER_OLD,X ; clear old values ; 4
dex ; 2
bpl mb_clear_reg ; 2nt/3
exit_interrupt:
; pla ; restore a ; 4
pla
tay ; restore Y
pla
tax ; restore X
lda $45 ; restore A
rti ; return from interrupt ; 6
;============
; typical
; ???? cycles
REGISTER_OLD:
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0

299
dya/rasterbars.s Normal file
View File

@ -0,0 +1,299 @@
; Not quite a raster-bar, but why not
; OPTIMIZATION (as originally it was 16,200 instructions, a bit much
; for a max 20,000 cycle interrupt handler)
; -120 : Unroll the zero loop, saved 120 cycles
; -5000 : Inline the vlin_double code
;===========
; CONSTANTS
;===========
ELEMENTS EQU 64
NUM_ROWS EQU 20
;=====================
; Rasterbars
;=====================
;===========================
;===========================
; Main Loop
;===========================
;===========================
draw_rasters:
; clear rows
; ldy #(NUM_ROWS-1) ; 2
lda #0 ; 2
init_rows:
sta row_color+0 ; 4
sta row_color+1
sta row_color+2
sta row_color+3
sta row_color+4
sta row_color+5
sta row_color+6
sta row_color+7
sta row_color+8
sta row_color+9
sta row_color+10
sta row_color+11
sta row_color+12
sta row_color+13
sta row_color+14
sta row_color+15
sta row_color+16
sta row_color+17
sta row_color+18
sta row_color+19
; sta row_color,Y ; 5
; dey ; 2
; bpl init_rows ; 2nt/3
;==============
; Originally 4+20*10 = 204 cyles / 10 bytes
; now 2+4*20 = 82 cycles / 62 bytes
;================
; set colors
ldy SCREEN_Y ; 3
lda #COLOR_BOTH_DARKBLUE ; d. blue ; 2
jsr set_row_color ; 6+136
lda #COLOR_BOTH_MEDIUMBLUE ; m.blue ; 2
jsr set_row_color ; 6+136
lda #COLOR_BOTH_AQUA ; aqua ; 2
jsr set_row_color ; 6+136
lda #COLOR_BOTH_PINK ; pink ; 2
jsr set_row_color ; 6+136
lda #COLOR_BOTH_RED ; red ; 2
jsr set_row_color ; 6+136
;==============
; new = 5 * 142 = 710
; original = 1152
;=================
; draw rows
ldy #(NUM_ROWS-1) ; 2
draw_rows_loop:
lda row_color,Y ; 5
beq draw_rows_skip ; skip if black ; 2nt/3
sta COLOR ; 3
sty TEMPY ; 3
tya ; y*2 ; 2
asl ; 2
tay ; 2
; hlin_setup inlined
lda gr_offsets,Y ; lookup low-res memory address ; 4
sta GBASL ; 3
iny ; 2
lda gr_offsets,Y ; 4
clc ; 2
adc DRAW_PAGE ; add in draw page offset ; 3
sta GBASH ; 3
ldy #39 ; 2
lda COLOR ; 3
double_loop:
sta (GBASL),Y ; 6
dey ; 2
bpl double_loop ; 2nt/3
ldy TEMPY ; 3
draw_rows_skip:
dey ; 2
bpl draw_rows_loop ; 3/2nt
;==============================
; Original: 20 * 741 = 14,820
; new = 2+ 20*(53+11*40)=9862
; (note, worst case)
;==================
; update y pointer
;==================
ldy SCREEN_Y ; 3
iny ; 2
cpy #ELEMENTS ; 2
bne not_there ; 3/2nt
ldy #0 ; 2
not_there:
sty SCREEN_Y ; 3
rts ; 6
;===========
; 24
;=====================================
; original total= 16,200
; new total (worst case)= 10,678
; (realistic) = 5,748
;===================
;===================
; set_row_color
;===================
;===================
; color in A
; Y=offset
; Y incremented
; A, X trashed
set_row_color:
sta COLOR ; 3
tya ; wrap y offset ; 2
and #(ELEMENTS-1) ; 2
tax ; 2
lda fine_sine,X ; lookup sine value ; 4
; pre-shifted right by 4, sign-extended
; 18 added to center
sin_no_more:
pha ; save row value ; 3
jsr put_color ; put color at row ; 6+44
pla ; restore row value ; 4
clc ; increment row value ; 2
adc #1 ; 2
jsr put_color ; put color at row ; 6+44
iny ; increment for next time ; 2
rts ; 6
;=============
; 132
;==================
; put_color
;==================
; A = row to set color of
; A trashed
put_color:
clc ; 2
ror ; row/2, with even/odd in carry ; 2
tax ; put row/2 in X ; 2
bcc even_line ; if even, skip to even ; 2nt/3
odd_line:
lda #$f0 ; load mask for odd ; 2
bcs finish_line ; 2nt/3
even_line:
lda #$0f ; load mask for even ; 2
finish_line:
sta MASK ; 3
and COLOR ; mask off color ; 3
sta COLOR2 ; store for later ; 3
lda MASK ; 3
eor #$ff ; invert mask ; 2
and row_color,X ; load existing color ; 4
ora COLOR2 ; combine ; 3
sta row_color,X ; store back ; 5
rts ; 6
;===========
; 44
;======================
; some arrays
;======================
row_color:
.byte $00,$00,$00,$00,$00, $00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00, $00,$00,$00,$00,$00
; arithmatically shifted right by 4, sign extended, added 18 to center
; FIXME: exploit symmetry and get rid of 3/4 of this table
; possibly not worth the extra code
fine_sine:
.byte $00+18 ; 0.000000
.byte $01+18 ; 0.098017
.byte $03+18 ; 0.195090
.byte $04+18 ; 0.290285
.byte $06+18 ; 0.382683
.byte $07+18 ; 0.471397
.byte $08+18 ; 0.555570
.byte $0A+18 ; 0.634393
.byte $0B+18 ; 0.707107
.byte $0C+18 ; 0.773010
.byte $0D+18 ; 0.831470
.byte $0E+18 ; 0.881921
.byte $0E+18 ; 0.923880
.byte $0F+18 ; 0.956940
.byte $0F+18 ; 0.980785
.byte $0F+18 ; 0.995185
.byte $0F+18 ; 1.000000
.byte $0F+18 ; 0.995185
.byte $0F+18 ; 0.980785
.byte $0F+18 ; 0.956940
.byte $0E+18 ; 0.923880
.byte $0E+18 ; 0.881921
.byte $0D+18 ; 0.831470
.byte $0C+18 ; 0.773010
.byte $0B+18 ; 0.707107
.byte $0A+18 ; 0.634393
.byte $08+18 ; 0.555570
.byte $07+18 ; 0.471397
.byte $06+18 ; 0.382683
.byte $04+18 ; 0.290285
.byte $03+18 ; 0.195090
.byte $01+18 ; 0.098017
.byte $00+18 ; 0.000000
.byte ($FE+18)&$ff ; -0.098017
.byte ($FC+18)&$ff ; -0.195090
.byte ($FB+18)&$ff ; -0.290285
.byte ($F9+18)&$ff ; -0.382683
.byte ($F8+18)&$ff ; -0.471397
.byte ($F7+18)&$ff ; -0.555570
.byte ($F5+18)&$ff ; -0.634393
.byte ($F4+18)&$ff ; -0.707107
.byte ($F3+18)&$ff ; -0.773010
.byte ($F2+18)&$ff ; -0.831470
.byte ($F1+18)&$ff ; -0.881921
.byte ($F1+18)&$ff ; -0.923880
.byte ($F0+18)&$ff ; -0.956940
.byte ($F0+18)&$ff ; -0.980785
.byte ($F0+18)&$ff ; -0.995185
.byte ($F0+18)&$ff ; -1.000000
.byte ($F0+18)&$ff ; -0.995185
.byte ($F0+18)&$ff ; -0.980785
.byte ($F0+18)&$ff ; -0.956940
.byte ($F1+18)&$ff ; -0.923880
.byte ($F1+18)&$ff ; -0.881921
.byte ($F2+18)&$ff ; -0.831470
.byte ($F3+18)&$ff ; -0.773010
.byte ($F4+18)&$ff ; -0.707107
.byte ($F5+18)&$ff ; -0.634393
.byte ($F7+18)&$ff ; -0.555570
.byte ($F8+18)&$ff ; -0.471397
.byte ($F9+18)&$ff ; -0.382683
.byte ($FB+18)&$ff ; -0.290285
.byte ($FC+18)&$ff ; -0.195090
.byte ($FE+18)&$ff ; -0.098017

2
dya/song_list.inc Normal file
View File

@ -0,0 +1,2 @@
.asciiz "DOTD1.KRW"

80
dya/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

226
dya/volume_bars.s Normal file
View File

@ -0,0 +1,226 @@
;==============================
;==============================
; Draw volume bars
;==============================
;==============================
volume_bars:
; hline Y,V2 at A
; top line
lda #COLOR_BOTH_GREY ; 2
sta COLOR ; remove for crazy effect ; 3
ldy #12 ; 2
lda #26 ; 2
sta V2 ; 3
lda #6 ; 2
jsr hlin_double ; 6
; 63+14*16=287
;=====================
; 307
; middle
lda #8 ; 2
middle_loop:
pha ; 3
cmp #8 ; 2
beq middle_black ; 2nt/3
cmp #26 ; 2
beq middle_black ; 2nt/3
cmp #10 ; 2
bne not_top ; 2nt/3
ldx #$3B ; pink/purple ; 2
stx A_COLOR ; 3
ldx #$7E ; light-blue/aqua ; 2
stx B_COLOR ; 3
ldx #$CD ; light-green/yellow ; 2
stx C_COLOR ; 3
jmp calc_volume ; 3
not_top:
ldx #COLOR_BOTH_RED ; 2
stx A_COLOR ; 3
ldx #COLOR_BOTH_DARKBLUE ; 2
stx B_COLOR ; 3
ldx #COLOR_BOTH_DARKGREEN ; 2
stx C_COLOR ; 3
calc_volume:
; 10 14/15 24-x = 14 PLUS=none, zero=bottom, neg=all
; 12 12/13 12
; 14 10/11 10
; 16 8/9 8
; 18 6/7 6
; 20 4/5 4
; 22 2/3 2
; 24 0/1 0
; FIXME: there must be a way to make this faster
mod_a:
pha ; 3
sec ; 2
eor #$ff ; negate ; 2
adc #24 ; 24-A ; 2
sec ; 2
sbc A_VOLUME ; 2
bmi mod_b ; 2nt/3
beq mod_a_bottom ; 2nt/3
mod_a_zero:
lda #0 ; 2
beq done_a ; 2nt/3
mod_a_bottom:
lda A_COLOR ; 2
and #$f0 ; 2
done_a:
sta A_COLOR ; 2
mod_b:
pla ; 4
pha ; 3
sec ; 2
eor #$ff ; negate ; 2
adc #24 ; 24-A ; 2
sec ; 2
sbc B_VOLUME ; 2
bmi mod_c ; 2nt/3
beq mod_b_bottom ; 2nt/3
mod_b_zero:
lda #0 ; 2
beq done_b ; 2nt/3
mod_b_bottom:
lda B_COLOR ; 3
and #$f0 ; 2
done_b:
sta B_COLOR ; 3
mod_c:
pla ; 4
pha ; 3
sec ; 2
eor #$ff ; negate ; 2
adc #24 ; 24-A ; 2
sec ; 2
sbc C_VOLUME ; 2
bmi mod_d ; 2nt/3
beq mod_c_bottom ; 2nt/3
mod_c_zero:
lda #0 ; 2
beq done_c ; 2nt/3
mod_c_bottom:
lda C_COLOR ; 3
and #$f0 ; 2
done_c:
sta C_COLOR ; 3
mod_d:
pla ; 4
jmp middle_color_done ; 3
middle_black:
ldx #COLOR_BOTH_BLACK ; 2
stx A_COLOR ; 3
stx B_COLOR ; 3
stx C_COLOR ; 3
middle_color_done:
; left border
ldy #COLOR_BOTH_GREY ; 2
sty COLOR ; 3
ldy #12 ; 2
sty V2 ; 3
ldy #12 ; 2
jsr hlin_double ; 6
; 63+1*16=79
; border space
lda #COLOR_BOTH_BLACK ; 2
sta COLOR ; 3
ldx #1 ; 2
jsr hlin_double_continue ; 10+1*16=27
; A volume
lda A_COLOR ; 3
sta COLOR ; 3
ldx #3 ; 2
jsr hlin_double_continue ; 10+3*16=58
; A space
lda #COLOR_BOTH_BLACK ; 2
sta COLOR ; 3
ldx #1 ; 2
jsr hlin_double_continue ; 6
; 10+1*16=27
; B volume
lda B_COLOR ; 3
sta COLOR ; 3
ldx #3 ; 2
jsr hlin_double_continue ; 6
; 10+3*16=58
; B space
lda #COLOR_BOTH_BLACK ; 2
sta COLOR ; 3
ldx #1 ; 2
jsr hlin_double_continue ; 6
; 10+1*16=27
; C volume
lda C_COLOR ; 3
sta COLOR ; 3
ldx #3 ; 2
jsr hlin_double_continue ; 6
; 10+3*16=58
; C space
lda #COLOR_BOTH_BLACK ; 2
sta COLOR ; 3
ldx #1 ; 2
jsr hlin_double_continue ; 6
; 10+1*16=27
; Right border
lda #COLOR_BOTH_GREY ; 2
sta COLOR ; 3
ldx #1 ; 2
jsr hlin_double_continue ; 6
; 10+1*16=27
pla ; 4
clc ; 2
adc #2 ; 2
cmp #28 ; 2
beq bottom_line ; 2nt/3
jmp middle_loop ; 3
bottom_line:
; bottom line
lda #COLOR_BOTH_GREY ; 2
sta COLOR ; 3
ldy #12 ; 2
lda #26 ; 2
sta V2 ; 3
lda #28 ; 2
jsr hlin_double ; 6
; 63+14*16=287
rts ; 6
; 309+ 684*10 + 313 = roughly worst case 7462

251
dya/zp.inc Normal file
View File

@ -0,0 +1,251 @@
.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
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

View File

@ -2,7 +2,7 @@ include ../Makefile.inc
CFLAGS = -g -Wall -O2
all: png2gr png2rle png_to_40x48d png_to_40x96
all: png2gr png2gr_text png2rle png_to_40x48d png_to_40x96
###
@ -21,6 +21,14 @@ png2gr.o: png2gr.c loadpng.h
###
png2gr_text: png2gr_text.o loadpng.o
$(CC) $(LFLAGS) -lpng -o png2gr_text png2gr_text.o loadpng.o
png2gr_text.o: png2gr_text.c loadpng.h
$(CC) $(CFLAGS) -c png2gr_text.c
###
png2rle: png2rle.o loadpng.o
$(CC) $(LFLAGS) -lpng -o png2rle png2rle.o loadpng.o
@ -48,8 +56,8 @@ png_to_40x96.o: png_to_40x96.c
###
install:
cp png2gr png2rle png_to_40x48d png_to_40x96 $(INSTALL_LOC)
cp png2gr png2gr_text png2rle png_to_40x48d png_to_40x96 $(INSTALL_LOC)
clean:
rm -f *~ *.o png2gr png2rle png_to_40x48d png_to_40x96
rm -f *~ *.o png2gr png2gr_text png2rle png_to_40x48d png_to_40x96

View File

@ -40,7 +40,7 @@ int main(int argc, char **argv) {
exit(-1);
}
printf("Loaded image %d by %d\n",xsize,ysize);
fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize);
short gr_offsets[]={
0x400,0x480,0x500,0x580,0x600,0x680,0x700,0x780,

77
gr-utils/png2gr_text.c Normal file
View File

@ -0,0 +1,77 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "loadpng.h"
/* Converts a PNG to a GR file you can include in your code */
int main(int argc, char **argv) {
int row=0;
int col=0;
int x;
unsigned char out_buffer[1024];
unsigned char *image;
int xsize,ysize;
FILE *outfile;
if (argc<2) {
fprintf(stderr,"Usage:\t%s INFILE\n\n",argv[0]);
exit(-1);
}
outfile=stdout;
if (loadpng(argv[1],&image,&xsize,&ysize)<0) {
fprintf(stderr,"Error loading png!\n");
exit(-1);
}
fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize);
short gr_offsets[]={
0x400,0x480,0x500,0x580,0x600,0x680,0x700,0x780,
0x428,0x4a8,0x528,0x5a8,0x628,0x6a8,0x728,0x7a8,
0x450,0x4d0,0x550,0x5d0,0x650,0x6d0,0x750,0x7d0,
};
memset(out_buffer,0,1024);
for(row=0;row<24;row++) {
for(col=0;col<40;col++) {
out_buffer[(gr_offsets[row]-0x400)+col]=image[row*xsize+col];
}
}
int line=0,which=0;
for(x=0;x<1024;x++) {
line=x%128;
which=(x/128)+(line/40)*8;
if (line%40==0) {
if (line==120) {
fprintf(outfile,"\n; SCREEN HOLE");
}
else {
fprintf(outfile,"\n; LINE %d-%d",
which*2,(which*2)+1);
}
}
if (line%10==0) {
fprintf(outfile,"\n.byte ");
}
fprintf(outfile,"$%02X",out_buffer[x]);
if ((line%10!=9) && (line!=127)) fprintf(outfile,",");
}
fprintf(outfile,"\n");
fclose(outfile);
return 0;
}