diff --git a/demos/l/flyer_512/Makefile b/demos/l/flyer_512/Makefile index 0d30414b..326b1565 100644 --- a/demos/l/flyer_512/Makefile +++ b/demos/l/flyer_512/Makefile @@ -6,10 +6,12 @@ EMPTYDISK = ../../../empty_disk/empty.dsk all: flyer_512.dsk -flyer_512.dsk: HELLO FLYER - cp $(EMPTYDISK) flyer_512.dsk - $(DOS33) -y flyer_512.dsk SAVE A HELLO - $(DOS33) -y flyer_512.dsk BSAVE -a 0x800 FLYER + +flyer_512.dsk: FLYER + # 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 + dd if=/dev/zero of=flyer_512.dsk bs=256 count=560 + dd conv=notrunc if=FLYER of=flyer_512.dsk bs=256 count=1 + dd conv=notrunc if=FLYER of=flyer_512.dsk bs=256 count=1 seek=7 skip=1 ### @@ -26,21 +28,16 @@ text8.zip: FLYER flyer.s file_id.diz flyer_512.dsk #### - -#### - -HELLO: hello.bas - $(TOKENIZE) < hello.bas > HELLO - -### - FLYER: flyer.o ld65 -o FLYER flyer.o -C ./apple2_800.inc -flyer.o: flyer.s +flyer.o: flyer.s \ + ay3_write_regs.s flyer.s interrupt_handler.s \ + mA2E_3.s mockingboard_constants.s mockingboard_init.s tracker_init.s ca65 -o flyer.o flyer.s -l flyer.lst #### clean: - rm -f *~ *.o *.lst HELLO FLYER *.zip + rm -f *~ *.o *.lst FLYER *.zip + diff --git a/demos/l/flyer_512/ay3_write_regs.s b/demos/l/flyer_512/ay3_write_regs.s new file mode 100644 index 00000000..4015e23c --- /dev/null +++ b/demos/l/flyer_512/ay3_write_regs.s @@ -0,0 +1,37 @@ + + ;===================== + ;===================== + ;===================== + ; ay3 write regs + ;===================== + ;===================== + ;===================== + ; write all 14 registers + ; address in X + ; data in A + +ay3_write_regs: + + ldx #13 +ay3_write_reg_loop: + + lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2 + ldy #MOCK_AY_INACTIVE ; go inactive ; 2 + + stx MOCK_6522_ORA1 ; put address on PA1 ; 4 + sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4 + sty MOCK_6522_ORB1 ; 4 + + ; value + lda AY_REGS,X + sta MOCK_6522_ORA1 ; put value on PA1 ; 4 + lda #MOCK_AY_WRITE ; ; 2 + sta MOCK_6522_ORB1 ; write on PB1 ; 4 + sty MOCK_6522_ORB1 ; 4 + + dex + bpl ay3_write_reg_loop + +; rts + + diff --git a/demos/l/flyer_512/file_id.diz b/demos/l/flyer_512/file_id.diz index f1c9f3f0..94b20290 100644 --- a/demos/l/flyer_512/file_id.diz +++ b/demos/l/flyer_512/file_id.diz @@ -1,5 +1,9 @@ -Tiny Text +Future Flyer - -Textmode Hex Scroller -8-byte Intro for Apple II, Lovebyte 2021 +Shapetable flyer with mockingboard music +512-byte boot-sector for Apple II, Lovebyte 2022 by Deater / dSr +music by mA2E + +Note: assumes Mockingboard in Slot#4. +Music only plays on left speaker. diff --git a/demos/l/flyer_512/flyer.s b/demos/l/flyer_512/flyer.s index 5e529c2f..24a9dfcc 100644 --- a/demos/l/flyer_512/flyer.s +++ b/demos/l/flyer_512/flyer.s @@ -1,15 +1,20 @@ ; Flyer +; 512 byte Apple II "boot sector" with graphics and Music ; by Vince `deater` Weaver, vince@deater.net --- d e s i r e --- - ; 178 bytes -- original conversion from BASIC ; 176 bytes -- know HGR2 returns with A=0 ; 172 bytes -- optimize page flip code ; 170 bytes -- assume XDRAW never got over X=256 +; 504 bytes -- merge in the music code ; zero page locations +AY_REGS = $70 +SONG_OFFSET = $82 +SONG_COUNTDOWN = $83 + HGR_COLOR = $E4 HGR_PAGE = $E6 HGR_SCALE = $E7 @@ -19,6 +24,8 @@ HORIZON_LINE = $FE FRAME = $FF ; soft-switches +KEYPRESS = $C000 +KEYRESET = $C010 PAGE1 = $C054 PAGE2 = $C055 @@ -32,9 +39,37 @@ HGLIN = $F53A ; line to (X,A), (Y) DRAW0 = $F601 XDRAW0 = $F65D + + .byte 2 ; number of sectors to load + + ; turn off drive motor + lda $C088,X ; turn off drive motor + ; hopefully slot*16 is in X + + flyer: + jsr HGR2 ; HGR2 HGR_PAGE=$40 - sta FRAME ; A=0 after HGR2 + sta FRAME ; A=0, Y=0 after HGR2 + + ;=================== + ; music Player Setup + +tracker_song = peasant_song + + ; assume mockingboard in slot#4 + + ; inline mockingboard_init + +.include "mockingboard_init.s" + +.include "tracker_init.s" + + ; start the music playing + + cli + + animate_loop: clc @@ -59,7 +94,10 @@ animate_loop: cmp PAGE1,X ; clear screen - jsr HCLR + lda #$7f + jsr BKGND0 + +; jsr HCLR ;=============== ; draw mountain @@ -165,8 +203,29 @@ reset_frame: lda #0 done_frame: sta FRAME + +bob: + lda KEYPRESS + bmi quiet + jmp animate_loop +quiet: + lda #$3f + sta AY_REGS+7 + +end: + bne end + + + + + + + + + + ;======================= ; xdraw ;======================= @@ -216,3 +275,8 @@ ship_table: ; .byte $0 +; music +.include "mA2E_3.s" +.include "interrupt_handler.s" +; must be last +.include "mockingboard_constants.s" diff --git a/demos/l/flyer_512/hello.bas b/demos/l/flyer_512/hello.bas deleted file mode 100644 index 78952d62..00000000 --- a/demos/l/flyer_512/hello.bas +++ /dev/null @@ -1,8 +0,0 @@ -5 HOME -10 PRINT "TINY TEXT -- AN 8 BYTE APPLE II INTRO" -15 PRINT " BY DEATER / DSR" -20 PRINT CHR$(4)"CATALOG" -25 PRINT:PRINT "PRESS ANY KEY TO 'BRUN TINY_TEXT'" -30 GET A$ -35 PRINT -40 PRINT CHR$(4)"BRUN TINY_TEXT" diff --git a/demos/l/flyer_512/interrupt_handler.s b/demos/l/flyer_512/interrupt_handler.s new file mode 100644 index 00000000..7fb755a4 --- /dev/null +++ b/demos/l/flyer_512/interrupt_handler.s @@ -0,0 +1,189 @@ + ;================================ + ;================================ + ; mockingboard interrupt handler + ;================================ + ;================================ + ; On Apple II/6502 the interrupt handler jumps to address in 0xfffe + ; This is in the ROM, which saves the registers + ; on older IIe it saved A to $45 (which could mess with DISK II) + ; newer IIe doesn't do that. + ; It then calculates if it is a BRK or not (which trashes A) + ; Then it sets up the stack like an interrupt and calls 0x3fe + + ; Note: the IIc is much more complicated + ; its firmware tries to decode the proper source + ; based on various things, including screen hole values + ; we bypass that by switching out ROM and replacing the + ; $fffe vector with this, but that does mean we have + ; to be sure status flag and accumulator set properly + +interrupt_handler: + php ; save status flags + + ; we don't use decimal mode so no need to clear it? + + ; A is saved in $45 by firmware + ; we are assuming a II/II+/IIe here + + txa + pha ; save X + tya + pha ; save Y + +; inc $0404 ; debug (flashes char onscreen) + + +ay3_irq_handler: + + ;========================================== + ; clear 6522 interrupt by reading T1C-L ; 4 + + bit MOCK_6522_T1CL + + ; drop note down after first + lda #$C + sta AY_REGS+8 + sta AY_REGS+10 + +; lda #$0E +; sta AY_REGS+8 ; $08 volume A +; lda #$0C +; sta AY_REGS+9 ; $09 volume B +; sta AY_REGS+10 ; $0A volume C + + + ;============================ + ; see if still counting down + + lda SONG_COUNTDOWN + bpl done_update_song + +set_notes_loop: + + ;================== + ; load next byte + + ldy SONG_OFFSET + lda tracker_song,Y + + ;================== + ; see if hit end + + cmp #$FF + bne all_ok + + ;==================================== + ; if at end, loop back to beginning + + lda #0 ; reset song offset + sta SONG_OFFSET + beq set_notes_loop ; bra + +all_ok: + + ; see if note + +; tay +; and #$C0 +; cmp #$C0 +; beq handle_timing + +note_only: +; tya + ; NNNNNLLC -- c=channel, n=note + + tay + + ldx #0 + lsr + bcc channel_a + ldx #4 ; skip to C +channel_a: + + and #$3 + sta SONG_COUNTDOWN +; inc SONG_COUNTDOWN + + tya + lsr + lsr + lsr + +; and #$FE ; fine register value, want in X +; tax + +; tya ; get note +; and #$1F + tay ; lookup in table + lda frequencies_low,Y + + sta AY_REGS,X ; set proper register value + + lda frequencies_high,Y + sta AY_REGS+1,X + + lda #$F + sta AY_REGS+8 + + ;============================ + ; point to next + + ; assume less than 256 bytes + inc SONG_OFFSET + + + lda SONG_COUNTDOWN + beq set_notes_loop ; bra + + + +.include "ay3_write_regs.s" + +; jsr ay3_write_regs + + + + + +handle_timing: + ; was timing + +; tya + +; and #$3f +; sta SONG_COUNTDOWN + +; inc SONG_OFFSET + +done_update_song: + dec SONG_COUNTDOWN + + + ;================================= + ; Finally done with this interrupt + ;================================= + +done_ay3_irq_handler: + + pla + tay ; restore Y + pla + tax ; restore X + + ; on II+/IIe the firmware saves A in $45 + ; this won't work on a IIc/IIgs + + lda $45 ; restore A + plp ; restore flags + + rti ; return from interrupt ; 6 + + ;============ + ; typical + ; ???? cycles + + + + + + diff --git a/demos/l/flyer_512/mA2E_3.s b/demos/l/flyer_512/mA2E_3.s new file mode 100644 index 00000000..cc4067a2 --- /dev/null +++ b/demos/l/flyer_512/mA2E_3.s @@ -0,0 +1,311 @@ +peasant_song: +; register init + +; A: 7 +; C: 43 +; none: a=-1 c=-1 len=0 +; A: 19 +; C: 38 +; none: a=0 c=1 len=3 + .byte $00 ; A=0 L=0 + .byte $0F ; C=1 L=3 +; A: 5 +; none: a=2 c=3 len=2 + .byte $10 ; A=2 L=0 + .byte $1D ; C=3 L=2 +; A: 7 +; C: 34 +; none: a=4 c=-1 len=1 + .byte $22 ; A=4 L=1 +; A: 7 +; C: 31 +; none: a=0 c=5 len=2 + .byte $00 ; A=0 L=0 + .byte $2D ; C=5 L=2 +; A: 19 +; C: 34 +; none: a=0 c=6 len=3 + .byte $00 ; A=0 L=0 + .byte $37 ; C=6 L=3 +; A: 5 +; none: a=2 c=5 len=2 + .byte $10 ; A=2 L=0 + .byte $2D ; C=5 L=2 +; A: 7 +; C: 38 +; none: a=4 c=-1 len=1 + .byte $22 ; A=4 L=1 +; A: 3 +; C: 43 +; none: a=0 c=3 len=2 + .byte $00 ; A=0 L=0 + .byte $1D ; C=3 L=2 +; A: 15 +; C: 39 +; none: a=7 c=1 len=3 + .byte $38 ; A=7 L=0 + .byte $0F ; C=1 L=3 +; A: 2 +; none: a=8 c=9 len=2 + .byte $40 ; A=8 L=0 + .byte $4D ; C=9 L=2 +; A: 3 +; C: 34 +; none: a=10 c=-1 len=1 + .byte $52 ; A=10 L=1 +; A: 3 +; C: 31 +; none: a=7 c=5 len=2 + .byte $38 ; A=7 L=0 + .byte $2D ; C=5 L=2 +; A: 15 +; C: 34 +; none: a=7 c=6 len=3 + .byte $38 ; A=7 L=0 + .byte $37 ; C=6 L=3 +; A: 2 +; none: a=8 c=5 len=2 + .byte $40 ; A=8 L=0 + .byte $2D ; C=5 L=2 +; A: 3 +; C: 43 +; none: a=10 c=-1 len=1 + .byte $52 ; A=10 L=1 +; A: 5 +; C: 41 +; none: a=7 c=1 len=2 + .byte $38 ; A=7 L=0 + .byte $0D ; C=1 L=2 +; A: 17 +; none: a=4 c=11 len=3 + .byte $20 ; A=4 L=0 + .byte $5F ; C=11 L=3 +; C: 36 +; none: a=12 c=-1 len=1 + .byte $62 ; A=12 L=1 +; A: 3 +; none: a=-1 c=13 len=1 + .byte $6B ; C=13 L=1 +; A: 5 +; C: 33 +; none: a=7 c=-1 len=1 + .byte $3A ; A=7 L=1 +; A: 5 +; C: 29 +; none: a=4 c=14 len=2 + .byte $20 ; A=4 L=0 + .byte $75 ; C=14 L=2 +; A: 17 +; C: 33 +; none: a=4 c=15 len=3 + .byte $20 ; A=4 L=0 + .byte $7F ; C=15 L=3 +; A: 3 +; none: a=12 c=14 len=2 + .byte $60 ; A=12 L=0 + .byte $75 ; C=14 L=2 +; A: 5 +; C: 39 +; none: a=7 c=-1 len=1 + .byte $3A ; A=7 L=1 +; A: 2 +; C: 38 +; none: a=4 c=9 len=2 + .byte $20 ; A=4 L=0 + .byte $4D ; C=9 L=2 +; A: 14 +; C: 39 +; none: a=10 c=3 len=3 + .byte $50 ; A=10 L=0 + .byte $1F ; C=3 L=3 +; A: 0 +; none: a=16 c=9 len=2 + .byte $80 ; A=16 L=0 + .byte $4D ; C=9 L=2 +; A: 2 +; C: 38 +; none: a=17 c=-1 len=1 + .byte $8A ; A=17 L=1 +; A: 2 +; C: 36 +; none: a=10 c=3 len=2 + .byte $50 ; A=10 L=0 + .byte $1D ; C=3 L=2 +; A: 14 +; C: 34 +; none: a=10 c=13 len=3 + .byte $50 ; A=10 L=0 + .byte $6F ; C=13 L=3 +; A: 0 +; none: a=16 c=5 len=2 + .byte $80 ; A=16 L=0 + .byte $2D ; C=5 L=2 +; A: 2 +; C: 33 +; none: a=17 c=-1 len=1 + .byte $8A ; A=17 L=1 +; A: 7 +; C: 43 +; none: a=10 c=14 len=2 + .byte $50 ; A=10 L=0 + .byte $75 ; C=14 L=2 +; A: 19 +; none: a=0 c=1 len=3 + .byte $00 ; A=0 L=0 + .byte $0F ; C=1 L=3 +; A: 5 +; none: a=2 c=-1 len=2 + .byte $14 ; A=2 L=2 +; A: 7 +; C: 41 +; none: a=4 c=-1 len=1 + .byte $22 ; A=4 L=1 +; C: 38 +; none: a=0 c=11 len=1 + .byte $00 ; A=0 L=0 + .byte $5B ; C=11 L=1 +; A: 7 +; C: 31 +; none: a=-1 c=3 len=1 + .byte $1B ; C=3 L=1 +; A: 19 +; none: a=0 c=6 len=3 + .byte $00 ; A=0 L=0 + .byte $37 ; C=6 L=3 +; C: 34 +; none: a=2 c=-1 len=1 + .byte $12 ; A=2 L=1 +; A: 5 +; none: a=-1 c=5 len=1 + .byte $2B ; C=5 L=1 +; A: 7 +; C: 36 +; none: a=4 c=-1 len=1 + .byte $22 ; A=4 L=1 +; A: 3 +; C: 43 +; none: a=0 c=13 len=2 + .byte $00 ; A=0 L=0 + .byte $6D ; C=13 L=2 +; A: 15 +; none: a=7 c=1 len=3 + .byte $38 ; A=7 L=0 + .byte $0F ; C=1 L=3 +; A: 2 +; none: a=8 c=-1 len=2 + .byte $44 ; A=8 L=2 +; A: 3 +; C: 41 +; none: a=10 c=-1 len=1 + .byte $52 ; A=10 L=1 +; C: 43 +; none: a=7 c=11 len=1 + .byte $38 ; A=7 L=0 + .byte $5B ; C=11 L=1 +; A: 3 +; C: 39 +; none: a=-1 c=1 len=1 + .byte $0B ; C=1 L=1 +; A: 15 +; none: a=7 c=9 len=3 + .byte $38 ; A=7 L=0 + .byte $4F ; C=9 L=3 +; C: 38 +; none: a=8 c=-1 len=1 + .byte $42 ; A=8 L=1 +; A: 2 +; none: a=-1 c=3 len=1 + .byte $1B ; C=3 L=1 +; A: 3 +; C: 34 +; none: a=10 c=-1 len=1 + .byte $52 ; A=10 L=1 +; A: 5 +; C: 36 +; none: a=7 c=5 len=2 + .byte $38 ; A=7 L=0 + .byte $2D ; C=5 L=2 +; A: 17 +; none: a=4 c=13 len=3 + .byte $20 ; A=4 L=0 + .byte $6F ; C=13 L=3 +; A: 3 +; none: a=12 c=-1 len=2 + .byte $64 ; A=12 L=2 +; A: 5 +; C: 34 +; none: a=7 c=-1 len=1 + .byte $3A ; A=7 L=1 +; C: 36 +; none: a=4 c=5 len=1 + .byte $20 ; A=4 L=0 + .byte $2B ; C=5 L=1 +; A: 5 +; C: 33 +; none: a=-1 c=13 len=1 + .byte $6B ; C=13 L=1 +; A: 17 +; none: a=4 c=14 len=3 + .byte $20 ; A=4 L=0 + .byte $77 ; C=14 L=3 +; C: 31 +; none: a=12 c=-1 len=1 + .byte $62 ; A=12 L=1 +; A: 3 +; none: a=-1 c=6 len=1 + .byte $33 ; C=6 L=1 +; A: 5 +; C: 33 +; none: a=7 c=-1 len=1 + .byte $3A ; A=7 L=1 +; A: 2 +; C: 29 +; none: a=4 c=14 len=2 + .byte $20 ; A=4 L=0 + .byte $75 ; C=14 L=2 +; A: 14 +; C: 31 +; none: a=10 c=15 len=3 + .byte $50 ; A=10 L=0 + .byte $7F ; C=15 L=3 +; A: 0 +; none: a=16 c=6 len=2 + .byte $80 ; A=16 L=0 + .byte $35 ; C=6 L=2 +; A: 2 +; C: 33 +; none: a=17 c=-1 len=1 + .byte $8A ; A=17 L=1 +; A: 2 +; none: a=10 c=14 len=2 + .byte $50 ; A=10 L=0 + .byte $75 ; C=14 L=2 +; C: 36 +; none: a=10 c=-1 len=1 + .byte $52 ; A=10 L=1 +; A: 14 +; none: a=-1 c=13 len=2 + .byte $6D ; C=13 L=2 +; C: 29 +; none: a=16 c=-1 len=1 + .byte $82 ; A=16 L=1 +; A: 0 +; none: a=-1 c=15 len=1 + .byte $7B ; C=15 L=1 +; A: 2 +; none: a=17 c=-1 len=1 + .byte $8A ; A=17 L=1 +; last: a=10 c=-1 len=2 + .byte $54 ; A=10 L=2 + .byte $FF ; end +; Octave 0 : 4 0 12 12 0 12 0 8 0 0 0 0 +; Octave 1 : 0 0 4 4 0 4 0 4 0 0 0 0 +; Octave 2 : 0 0 0 0 0 3 0 5 0 6 8 0 +; Octave 3 : 6 0 6 4 0 3 0 6 0 0 0 0 +; 18 notes allocated +;.byte 7,43,19,38,5,34,31,3,15,39,2,41,17,36,33,29,14,0, +frequencies_high: +.byte $02,$00,$01,$00,$02,$00,$00,$03,$01,$00,$03,$00,$01,$00,$00,$00,$01,$03 +frequencies_low: +.byte $8C,$51,$46,$6C,$DC,$89,$A3,$36,$9B,$66,$66,$5B,$6E,$7A,$91,$B7,$B3,$D1 +; total len=148 diff --git a/demos/l/flyer_512/mockingboard_constants.s b/demos/l/flyer_512/mockingboard_constants.s new file mode 100644 index 00000000..603437e5 --- /dev/null +++ b/demos/l/flyer_512/mockingboard_constants.s @@ -0,0 +1,16 @@ +init_addresses: + .byte interrupt_handler ; 2 + sta $03ff ; 3 + ;========= + ; 10 + ;========================= + ; Initialize the 6522s + ; Reset Left AY-3-8910 + ;=========================== + + ; entries=10 + ; 14 + 2*entries = 34 bytes + + ldy #0 ; 2 +init_it_loop: + lda init_values,Y ; 3 + ldx init_addresses,Y ; 3 + bmi doneit ; 2 + iny ; 1 + sta $c400,X ; 3 + bne init_it_loop ; 2 +doneit: + + + diff --git a/demos/l/flyer_512/tracker_init.s b/demos/l/flyer_512/tracker_init.s new file mode 100644 index 00000000..b77199a5 --- /dev/null +++ b/demos/l/flyer_512/tracker_init.s @@ -0,0 +1,23 @@ +tracker_init: + + ; setup initial ay-3-8910 values (this depends on song) + +init_registers_to_zero: + ldx #13 + lda #0 + sta SONG_OFFSET ; also init song stuff + sta SONG_COUNTDOWN +init_loop: + sta AY_REGS,X + dex + bpl init_loop + +; jsr ay3_write_regs + + lda #$38 + sta AY_REGS+7 ; $07 mixer (ABC on) +; lda #$0E +; sta AY_REGS+8 ; $08 volume A +; lda #$0C +; sta AY_REGS+9 ; $09 volume B +; sta AY_REGS+10 ; $0A volume C