eduet: fix up some of the music

This commit is contained in:
Vince Weaver 2023-05-01 02:09:16 -04:00
parent deb0af4914
commit 6a74f2e9a8
13 changed files with 3127 additions and 25 deletions

View File

@ -11,7 +11,7 @@ $(DOS33):
cd ../../utils/dos33fs-utils && make
eduet.dsk: $(DOS33) HELLO ED HIGHWIND.ED FIGHTING.ED SA.ED \
KERBAL.ED KORO.ED PEASANT.ED
KERBAL.ED KORO.ED PEASANT.ED FORTNIGHT.ED
cp $(EMPTY_DISK) eduet.dsk
$(DOS33) -y eduet.dsk SAVE A HELLO
$(DOS33) -y eduet.dsk BSAVE -a 0x0C00 ED
@ -21,6 +21,7 @@ eduet.dsk: $(DOS33) HELLO ED HIGHWIND.ED FIGHTING.ED SA.ED \
$(DOS33) -y eduet.dsk BSAVE -a 0x2000 KERBAL.ED
$(DOS33) -y eduet.dsk BSAVE -a 0x2000 KORO.ED
$(DOS33) -y eduet.dsk BSAVE -a 0x2000 PEASANT.ED
$(DOS33) -y eduet.dsk BSAVE -a 0x2000 FORTNIGHT.ED
###
@ -42,20 +43,34 @@ duet.o: duet.s
PEASANT.ED: peasant.ed
cp peasant.ed PEASANT.ED
###
peasant.ed: $(TEXT_TO_ED) peasant.txt
$(TEXT_TO_ED) peasant.txt peasant
$(TEXT_TO_ED) -o 1 peasant.txt peasant
###
HIGHWIND.ED: highwind.ed
cp highwind.ed HIGHWIND.ED
highwind.ed: $(TEXT_TO_ED) highwind.txt
$(TEXT_TO_ED) -o 0 highwind.txt highwind
###
highwind.ed: $(TEXT_TO_ED) highwind.txt
$(TEXT_TO_ED) -o -2 highwind.txt highwind
FIGHTING.ED: fighting.ed
cp fighting.ed FIGHTING.ED
fighting.ed: $(TEXT_TO_ED) fighting.txt
$(TEXT_TO_ED) -o 0 fighting.txt fighting
###
FORTNIGHT.ED: fortnight.ed
cp fortnight.ed FORTNIGHT.ED
fortnight.ed: $(TEXT_TO_ED) fortnight.txt
$(TEXT_TO_ED) -o 1 fortnight.txt fortnight
###
@ -73,5 +88,3 @@ notes.o: notes.c notes.h
clean:
rm -f *~ *.o *.lst ED text_to_ed

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,295 @@
'
' TITLE: Breakdancing Rat from SBEMAIL #152
' AUTHOR: (tracked by) Vince Weaver <vince@deater.net>
' COMMENTS: based on MIDI converted from recording of the video
'
' LOOP: 640
'
' BPM: 320
' TEMPO: 6
' FREQ: 1000000
' IRQ: 50
'
' LYRICS: 0
'
' ENDHEADER
-------
' 1
' G 3 8
' 2
0 ----- ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C ----- ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 3 8 C 2 8 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 3 8 C 2 8 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 3
0 ----- ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C B 3 8 E 2 8 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 D 4 8 G 2 8 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 B 3 8 E 2 8 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 4
0 F 4 8 A#3 8 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 F 4 8 A#3 8 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 F 4 8 A#3 8 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C A#3 6 A#2 8 -----
D ----- ----- -----
E F 4 6 ----- -----
F ----- ----- -----
10 ----- ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 ----- ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 5
0 ----- ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 C 3 8 C 2 8 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 3 8 C 2 8 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 ----- ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 ----- ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 6
0 ----- ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 F 4 4 A#3 4 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C ----- ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 B 3 8 E 2 8 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 B 3 8 E 2 8 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 7
0 B 3 8 E 2 8 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 B 3 8 E 2 8 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C ----- ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 ----- ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 ----- ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 8
0 ----- ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- C 2 > -----
4 C 3 6 C 2 6 -----
5 ----- ----- -----
6 C 3 6 C 2 6 -----
7 ----- ----- -----
8 C 3 4 C 2 4 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C ----- ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 ----- ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 ----- ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 9
0 B 3 8 E 2 8 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 D 4 8 G 2 8 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 B 3 8 E 2 8 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C F 4 8 A#2 8 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
' A#3 4
10 ----- A#3 8 -----
11 F 4 ? ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 F 4 8 A#3 8 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 10
0 F 4 4 A#3 4 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C ----- ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 ----- ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 3 8 C 2 8 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 11
0 C 3 4 C 2 4 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C ----- ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 ----- ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 F 4 8 A#3 8 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' 12
0 ----- ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 B 3 8 E 2 8 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 B 3 8 E 2 8 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C B 3 8 E 2 8 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 B 3 4 E 2 4 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 ----- ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
' LOOP TO FRAME ?

View File

@ -8,10 +8,11 @@
45 PRINT "4. KERBAL THEME"
50 PRINT "5. KOROBEINIKI (TETRIS THEME)"
55 PRINT "6. PEASANT'S QUEST"
60 PRINT "7. FORTNIGHT (BREAKDANCE RAT)"
100 PRINT CHR$ (4)"BLOAD ED"
120 PRINT "-----> ";: INPUT A
130 IF A < 0 OR A > 6 THEN GOTO 120
140 ON A GOTO 200,210,220,230,240,250
130 IF A < 0 OR A > 7 THEN GOTO 120
140 ON A GOTO 200,210,220,230,240,250,260
200 PRINT CHR$ (4)"BLOAD SA.ED,A$2000"
205 GOTO 1000
210 PRINT CHR$ (4)"BLOAD FIGHTING.ED,A$2000"
@ -24,6 +25,8 @@
245 GOTO 1000
250 PRINT CHR$ (4)"BLOAD PEASANT.ED,A$2000"
255 GOTO 1000
260 PRINT CHR$ (4)"BLOAD FORTNIGHT.ED,A$2000"
265 GOTO 1000
1000 POKE 30,0: POKE 31,32
1010 CALL 256*12
1020 GOTO 2

View File

@ -85,14 +85,24 @@ double note_to_freq(char note, int flat, int sharp, int octave, double sub) {
*/
//static unsigned char ed_freqs[]={
///* A A# B C C# D D# E F F# G G# */
// 255,240,228,216,204,192,180,172,160,152,144,136,
// 128,120,114,108,102,96, 90, 86, 80, 76, 72, 68,
// 64, 60, 57, 54, 51, 48, 45, 43, 40, 38, 36, 34,
// 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17,
// 16, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8,
// 8, 8, 7};
static unsigned char ed_freqs[]={
/* A A# B C C# D D# E F F# G G# */
255,240,228,216,204,192,180,172,160,152,144,136,
128,120,114,108,102,96, 90, 86, 80, 76, 72, 68,
64, 60, 57, 54, 51, 48, 45, 43, 40, 38, 36, 34,
32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8,
8, 8, 7};
/* C C# D D# E F F# G G# A A# B*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 255,240,228, /* 1 */
216,204,192,180,172,160,152,144,136,128,120,114, /* 2 */
108,102,96, 90, 86, 80, 76, 72, 68, 64, 60, 57, /* 3 */
54, 51, 48, 45, 43, 40, 38, 36, 34, 32, 30, 28, /* 4 */
27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14, /* 5 */
13, 12, 12, 11, 10, 10, 9, 9, 8, 8, 8, 7}; /* 6 */
/* c1 c1
d1 d1
@ -109,13 +119,14 @@ int note_to_ed(char note, int flat, int sharp, int octave) {
int offset;
switch(note) {
case 'A': offset=12; break;
case 'B': offset=14; break;
case 'C': offset=3; break;
case 'D': offset=5; break;
case 'E': offset=7; break;
case 'F': offset=8; break;
case 'G': offset=10; break;
case 'C': offset=0; break;
case 'D': offset=2; break;
case 'E': offset=4; break;
case 'F': offset=5; break;
case 'G': offset=7; break;
case 'A': offset=9; break;
case 'B': offset=11; break;
default:
fprintf(stderr,"Unknown note %c\n",note);
return -1;
@ -126,7 +137,7 @@ int note_to_ed(char note, int flat, int sharp, int octave) {
offset+=((octave-1)*12);
if (offset>63) {
if (offset>72) {
fprintf(stderr,"Out of range offset %d\n",offset);
return 7;
}

View File

@ -71,6 +71,8 @@ static int note_to_length(int length) {
case 11: len=(baselen*9)/8; break; // ; = 9/8 dotted half + dotted quarter
case 12: len=(baselen*3)/2; break; // < = 3/2 dotted whole
case 13: len=(baselen*2); break; // = = 2 double whole
case 14: len=(baselen/32); break; // > = 1/32
case 15: len=(baselen/32)*3; break; // ? = 3/32 dotted sixteenth
default:
fprintf(stderr,"Unknown length %d, line %d\n",
length,line);
@ -362,6 +364,9 @@ int main(int argc, char **argv) {
// baselen=60;
baselen=64; // multiple of 16?
}
else if (bpm==180) {// 3.33Hz, 333ms,
baselen=64; // multiple of 16?
}
else if (bpm==250) {
baselen=48; // eyeballed
}

View File

@ -0,0 +1,32 @@
include ../../Makefile.inc
DOS33 = ../../utils/dos33fs-utils/dos33
TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft
LINKERSCRIPTS = ../../linker_scripts
EMPTYDISK = ../../empty_disk/empty.dsk
all: double.dsk
double.dsk: HELLO DOUBLE
cp $(EMPTYDISK) double.dsk
$(DOS33) -y double.dsk SAVE A HELLO
$(DOS33) -y double.dsk BSAVE -a 0x1000 DOUBLE
###
HELLO: hello.bas
$(TOKENIZE) < hello.bas > HELLO
###
DOUBLE: double.o
ld65 -o DOUBLE double.o -C $(LINKERSCRIPTS)/apple2_1000.inc
double.o: double.s \
zp.inc
ca65 -o double.o double.s -l double.lst
###
clean:
rm -f *~ *.o *.lst HELLO DOUBLE

View File

@ -0,0 +1,279 @@
; Double Hi-res / Double lo-res mode switch fun
; by Vince `deater` Weaver
.include "zp.inc"
.include "hardware.inc"
;================================
; Clear screen and setup graphics
;================================
double:
jsr SETGR ; set lo-res 40x40 mode
; set 80-store mode
sta EIGHTYSTORE ; PAGE2 selects AUX memory
bit PAGE1
;===================
; draw lo-res lines
ldx #39
draw_lores_lines:
txa
tay
jsr SETCOL
lda #47
sta V2
lda #0
jsr VLINE ; VLINE A,$2D at Y
dex
bpl draw_lores_lines
; copy to 800 temporarily
; yes this is a bit of a hack
ldy #0
cp_loop:
lda $400,Y
sta $800,Y
lda $500,Y
sta $900,Y
lda $600,Y
sta $A00,Y
lda $700,Y
sta $B00,Y
iny
bne cp_loop
bit PAGE1
; copy to $400 in AUX
bit PAGE2 ; $400 now maps to AUX:$400
ldy #0
cp2_loop:
lda $800,Y
eor #$FF
sta $400,Y
lda $900,Y
eor #$FF
sta $500,Y
lda $A00,Y
eor #$FF
sta $600,Y
lda $B00,Y
eor #$FF
sta $700,Y
iny
bne cp2_loop
bit PAGE1
;===================
; draw hi-res lines
jsr HGR
bit FULLGR ; make it 40x48
lda #$FF
sta $E4 ; HCOLOR
ldx #0
ldy #0
lda #96
jsr HPLOT0 ; plot at (Y,X), (A)
ldx #0
lda #140
ldy #191
jsr HGLIN ; line to (X,A),(Y)
ldx #1
lda #23
ldy #96
jsr HGLIN ; line to (X,A),(Y)
; draw double-hires lines
lda #$20 ; draw to page0 (MAIN?)
sta HGRPAGE
lda #150 ; start at 150
sta YPOS
color_loop:
lda YPOS
and #$f
sta TCOLOR
asl
asl
asl
asl
ora TCOLOR
sta TCOLOR ; update color
lda YPOS
jsr draw_line_color
inc YPOS
lda YPOS
cmp #192
bne color_loop
; wait for vblank on IIe
; positive? during vblank
wait_vblank_iie:
lda VBLANK
bmi wait_vblank_iie ; wait for positive (in vblank)
wait_vblank_done_iie:
lda VBLANK ; wait for negative (vlank done)
bpl wait_vblank_done_iie
;
double_loop:
;===========================
; text mode first 6*4 (24) lines
; each line 65 cycles (25 hblank+40 bytes)
; 3 LINES 80-COL AN3
sta SET80COL ; 4
bit SET_TEXT ; 4
; wait 6*4=24 lines
; (24*65)-8 = 1560-8 = 1552
jsr delay_1552
; 3 LINES 40-COL AN3
sta CLR80COL ; 4
bit SET_TEXT ; 4
jsr delay_1552
; 3 LINES 40-col LORES AN3
lda LORES ; 4
bit SET_GR ; 4
jsr delay_1552
; 3 LINES 80-col DLORES AN3
sta SET80COL ; 4
sta CLRAN3 ; 4
jsr delay_1552
; 3 lines 40-col LORES
sta CLR80COL ; 4
sta SETAN3 ; 4 ; doublehiresoff
jsr delay_1552
; 3 lines HIRES
sta HIRES ; 4
sta CLRAN3 ; 4
jsr delay_1552
; 3 lines HIRES
sta HIRES ; 4
sta SETAN3 ; 4
jsr delay_1552
; 3 line Double-HIRES
sta SET80COL ; 4
sta CLRAN3 ; 4
jsr delay_1552
;==================================
; vblank = 4550 cycles
; Try X=226 Y=4 cycles=4545
skip_vblank:
nop
ldy #4 ; 2
loop3: ldx #226 ; 2
loop4: dex ; 2
bne loop4 ; 2nt/3
dey ; 2
bne loop3 ; 2nt/3
jmp double_loop ; 3
;=======================================================
; need to align because if we straddle a page boundary
; the time counts end up off
.align $100
; actually want 1552-12 (6 each for jsr/rts)
; 1540
; Try X=15 Y=19 cycles=1540
delay_1552:
ldy #19 ; 2
loop5: ldx #15 ; 2
loop6: dex ; 2
bne loop6 ; 2nt/3
dey ; 2
bne loop5 ; 2nt/3
rts
;==========================
; draw horizontal DHGR line
;==========================
; color is in TCOLOR
; Y position is in A
;=========================
draw_line_color:
ldx #0
ldy #0
jsr HPOSN ; setup GBASL/GBASH with Y position
ldy #0
line_loop_it:
; set page2
sta PAGE2
lda TCOLOR
sta (GBASL),Y
cmp #$80
rol TCOLOR
; set page1
sta PAGE1
lda TCOLOR
sta (GBASL),Y
cmp #$80
rol TCOLOR
iny
cpy #40
bne line_loop_it
rts

View File

@ -0,0 +1,28 @@
; soft-switches
; yes, I know these aren't necessary the "official" names
EIGHTYSTORE = $C001
CLR80COL = $C00C
SET80COL = $C00D
SET_GR = $C050
SET_TEXT= $C051
FULLGR = $C052
TEXTGR = $C053
PAGE1 = $C054
PAGE2 = $C055
LORES = $C056
HIRES = $C057
CLRAN3 = $C05E
SETAN3 = $C05F
VBLANK = $C019 ; *not* RDVBL (VBL signal low)
; ROM routines
SETCOL = $F864 ; COLOR=A*17
SETGR = $FB40
VLINE = $F828 ; VLINE A,$2D at Y
HGR = $F3E2
HPOSN = $F411
HPLOT0 = $F457 ; plot at (Y,X), (A)
HGLIN = $F53A ; line to (X,A),(Y)

View File

@ -0,0 +1,2 @@
5 HOME
10 PRINT CHR$(4);"CATALOG"

View File

@ -0,0 +1,222 @@
;===================================================================
; code to detect mockingboard
;===================================================================
; this isn't always easy
; my inclination is to just assume slot #4 but that isn't always realistic
; code below based on "hw.mockingboard.a" from "Total Replay"
;license:MIT
; By Andrew Roughan
; in the style of 4am for Total Replay
;
; Mockingboard support functions
;
;------------------------------------------------------------------------------
; HasMockingboard
; detect Mockingboard card by searching for 6522 timers across all slots
; access 6522 timers with deterministic cycle counts
;
; based on prior art in Mockingboard Developers Toolkit
; with optimisation from deater/french touch
; also takes into account FastChip //e clock difference
;
; in: none
; accelerators should be off
; out: C set if Mockingboard found in any slot
; if card was found, X = #$Cn where n is the slot number of the card
; C clear if no Mockingboard found
; other flags clobbered
; A/Y clobbered
;------------------------------------------------------------------------------
mockingboard_detect:
; activate Mockingboard IIc
; + the Mockingboard has to take over Slot#4 (IIc has no slots)
; in theory any write to the firmware area in $C400 will
; activate it, but that might not be fast enough when detecting
; so writing $FF to $C403/$C404 is official way to enable
; + Note this disables permanently the mouse firmware in $C400
; so "normal" interrupts are broken :( The hack to fix things
; is to switch in RAM for $F000 and just replace the IRQ
; vectors at $FFFE/$FFFF instead of $3FE/$3FF but that makes
; it difficult if you actually wanted to use any
; Applesoft/Monitor ROM routines
;.ifdef PT3_ENABLE_APPLE_IIC
lda APPLEII_MODEL
cmp #'C'
bne not_iic
lda #$ff
; don't bother patching these, IIc mockingboard always slot 4
sta MOCK_6522_DDRA1 ; $C403
sta MOCK_6522_T1CL ; $C404
;.endif
not_iic:
lda #$00
sta MB_ADDR_L
ldx #$C7 ; start at slot #7
mb_slot_loop:
stx MB_ADDR_H
ldy #$04 ; 6522 #1 $Cx04
jsr mb_timer_check
bne mb_next_slot
ldy #$84 ; 6522 #2 $Cx84
jsr mb_timer_check
bne mb_next_slot
mb_found:
sec ; found
rts
mb_next_slot:
dex
cpx #$C0
bne mb_slot_loop
clc ; not found
rts
mb_timer_check:
lda (MB_ADDR_L),Y ; read 6522 timer low byte
sta MB_VALUE
lda (MB_ADDR_L),Y ; second time
sec
sbc MB_VALUE
cmp #$F8 ; looking for (-)8 cycles between reads
beq mb_timer_check_done
cmp #$F7 ; FastChip //e clock is different
mb_timer_check_done:
rts
.if 0
;=======================================
; Detect a Mockingboard card
;=======================================
; Based on code from the French Touch "Pure Noise" Demo
; Attempts to time an instruction sequence with a 6522
;
; If found, puts in bMB
; MB_ADDRL:MB_ADDRH has address of Mockingboard
; returns X=0 if not found, X=1 if found
mockingboard_detect:
lda #0
sta MB_ADDRL
mb_detect_loop: ; self-modifying
lda #$07 ; we start in slot 7 ($C7) and go down to 0 ($C0)
ora #$C0 ; make it start with C
sta MB_ADDRH
ldy #04 ; $CX04
ldx #02 ; 2 tries?
mb_check_cycle_loop:
lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter)
; count down
sta PT3_TEMP ; 3 cycles
lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles
; between the two accesses to the timer
sec
sbc PT3_TEMP ; subtract to see if we had 8 cycles
cmp #$f8 ; -8
bne mb_not_in_this_slot
dex ; decrement, try one more time
bne mb_check_cycle_loop ; loop detection
inx ; Mockingboard found (X=1)
done_mb_detect:
;stx bMB ; store result to bMB
rts ; return
mb_not_in_this_slot:
dec mb_detect_loop+1 ; decrement the "slot" (self_modify)
bne mb_detect_loop ; loop down to one
ldx #00
beq done_mb_detect
;alternative MB detection from Nox Archaist
; lda #$04
; sta MB_ADDRL
; ldx #$c7
;
;find_mb:
; stx MB_ADDRH
;
; ;detect sound I
;
; sec
; ldy #$00
; lda (MB_ADDRL), y
; sbc (MB_ADDRL), y
; cmp #$05
; beq found_mb
; dex
; cpx #$c0
; bne find_mb
; ldx #$00 ;no mockingboard found
; rts
;
;found_mb:
; ldx #$01 ;mockingboard found
; rts
;
; ;optionally detect sound II
;
; sec
; ldy #$80
; lda (MB_ADDRL), y
; sbc (MB_ADDRL), y
; cmp #$05
; beq found_mb
;=======================================
; Detect a Mockingboard card in Slot4
;=======================================
; Based on code from the French Touch "Pure Noise" Demo
; Attempts to time an instruction sequence with a 6522
;
; MB_ADDRL:MB_ADDRH has address of Mockingboard
; returns X=0 if not found, X=1 if found
mockingboard_detect_slot4:
lda #0
sta MB_ADDRL
mb4_detect_loop: ; self-modifying
lda #$04 ; we're only looking in Slot 4
ora #$C0 ; make it start with C
sta MB_ADDRH
ldy #04 ; $CX04
ldx #02 ; 2 tries?
mb4_check_cycle_loop:
lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter)
; count down
sta PT3_TEMP ; 3 cycles
lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles
; between the two accesses to the timer
sec
sbc PT3_TEMP ; subtract to see if we had 8 cycles
cmp #$f8 ; -8
bne mb4_not_in_this_slot
dex ; decrement, try one more time
bne mb4_check_cycle_loop ; loop detection
inx ; Mockingboard found (X=1)
done_mb4_detect:
rts ; return
mb4_not_in_this_slot:
ldx #00
beq done_mb4_detect
.endif

View File

@ -0,0 +1,261 @@
; Mockingboad programming:
; + Has two 6522 I/O chips connected to two AY-3-8910 chips
; + Optionally has some speech chips controlled via the outport on the AY
; + Often in slot 4
; TODO: how to auto-detect?
; References used:
; http://macgui.com/usenet/?group=2&id=8366
; 6522 Data Sheet
; AY-3-8910 Data Sheet
;========================
; Mockingboard card
; Essentially two 6522s hooked to the Apple II bus
; Connected to AY-3-8910 chips
; PA0-PA7 on 6522 connected to DA0-DA7 on AY
; PB0 on 6522 connected to BC1
; PB1 on 6522 connected to BDIR
; PB2 on 6522 connected to RESET
; left speaker
MOCK_6522_ORB1 = $C400 ; 6522 #1 port b data
MOCK_6522_ORA1 = $C401 ; 6522 #1 port a data
MOCK_6522_DDRB1 = $C402 ; 6522 #1 data direction port B
MOCK_6522_DDRA1 = $C403 ; 6522 #1 data direction port A
MOCK_6522_T1CL = $C404 ; 6522 #1 t1 low order latches
MOCK_6522_T1CH = $C405 ; 6522 #1 t1 high order counter
MOCK_6522_T1LL = $C406 ; 6522 #1 t1 low order latches
MOCK_6522_T1LH = $C407 ; 6522 #1 t1 high order latches
MOCK_6522_T2CL = $C408 ; 6522 #1 t2 low order latches
MOCK_6522_T2CH = $C409 ; 6522 #1 t2 high order counters
MOCK_6522_SR = $C40A ; 6522 #1 shift register
MOCK_6522_ACR = $C40B ; 6522 #1 auxilliary control register
MOCK_6522_PCR = $C40C ; 6522 #1 peripheral control register
MOCK_6522_IFR = $C40D ; 6522 #1 interrupt flag register
MOCK_6522_IER = $C40E ; 6522 #1 interrupt enable register
MOCK_6522_ORANH = $C40F ; 6522 #1 port a data no handshake
; right speaker
MOCK_6522_ORB2 = $C480 ; 6522 #2 port b data
MOCK_6522_ORA2 = $C481 ; 6522 #2 port a data
MOCK_6522_DDRB2 = $C482 ; 6522 #2 data direction port B
MOCK_6522_DDRA2 = $C483 ; 6522 #2 data direction port A
; AY-3-8910 commands on port B
; RESET BDIR BC1
MOCK_AY_RESET = $0 ; 0 0 0
MOCK_AY_INACTIVE = $4 ; 1 0 0
MOCK_AY_READ = $5 ; 1 0 1
MOCK_AY_WRITE = $6 ; 1 1 0
MOCK_AY_LATCH_ADDR = $7 ; 1 1 1
;========================
; Mockingboard Init
;========================
; Initialize the 6522s
; set the data direction for all pins of PortA/PortB to be output
mockingboard_init:
lda #$ff ; all output (1)
mock_init_smc1:
sta MOCK_6522_DDRB1
sta MOCK_6522_DDRA1
mock_init_smc2:
sta MOCK_6522_DDRB2
sta MOCK_6522_DDRA2
rts
;===================================
;===================================
; Reset Both AY-3-8910s
;===================================
;===================================
;======================
; Reset Left AY-3-8910
;======================
reset_ay_both:
lda #MOCK_AY_RESET
reset_ay_smc1:
sta MOCK_6522_ORB1
lda #MOCK_AY_INACTIVE
reset_ay_smc2:
sta MOCK_6522_ORB1
;======================
; Reset Right AY-3-8910
;======================
;reset_ay_right:
;could be merged with both
lda #MOCK_AY_RESET
reset_ay_smc3:
sta MOCK_6522_ORB2
lda #MOCK_AY_INACTIVE
reset_ay_smc4:
sta MOCK_6522_ORB2
rts
; Write sequence
; Inactive -> Latch Address -> Inactive -> Write Data -> Inactive
;=========================================
; Write Right/Left to save value AY-3-8910
;=========================================
; register in X
; value in MB_VALUE
write_ay_both:
; address
write_ay_smc1:
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 on PB1 ; 2
write_ay_smc2:
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4
ldy #MOCK_AY_INACTIVE ; go inactive ; 2
write_ay_smc3:
sty MOCK_6522_ORB1 ; 4
sty MOCK_6522_ORB2 ; 4
;===========
; 28
; value
lda MB_VALUE ; 3
write_ay_smc4:
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
sta MOCK_6522_ORA2 ; put value on PA2 ; 4
lda #MOCK_AY_WRITE ; ; 2
write_ay_smc5:
sta MOCK_6522_ORB1 ; write on PB1 ; 4
sta MOCK_6522_ORB2 ; write on PB2 ; 4
write_ay_smc6:
sty MOCK_6522_ORB1 ; 4
sty MOCK_6522_ORB2 ; 4
;===========
; 29
rts ; 6
;===========
; 63
write_ay_both_end:
;.assert >write_ay_both = >write_ay_both_end, error, "write_ay_both crosses page"
;=======================================
; clear ay -- clear all 14 AY registers
; should silence the card
;=======================================
; 7+(74*14)+5=1048
clear_ay_both:
ldx #13 ; 2
lda #0 ; 2
sta MB_VALUE ; 3
clear_ay_left_loop:
jsr write_ay_both ; 6+63
dex ; 2
bpl clear_ay_left_loop ; 3
; -1
rts ; 6
clear_ay_end:
;.assert >clear_ay_both = >clear_ay_end, error, "clear_ay_both crosses page"
;=============================
; Setup
;=============================
mockingboard_setup_interrupt:
; for this game with things in language card including
; irq handler, always force IIc mode (where RAM swapped in
; and we put the irq handler address directly up at $FFFE)
lda #<interrupt_handler
sta $fffe
lda #>interrupt_handler
sta $ffff
; nop out the "lda $45" since we are bypassing the ROM irq handler
; that puts A in $45
lda #$EA
sta interrupt_smc
sta interrupt_smc+1
;=========================
; 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
;============================
; Note, on Apple II the clock isn't 1MHz but is actually closer to
; roughly 1.023MHz, and every 65th clock is stretched (it's complicated)
; 4fe7 / 1.023e6 = .020s, 50Hz
; 9c40 / 1.023e6 = .040s, 25Hz
; 411a / 1.023e6 = .016s, 60Hz
; French Touch uses
; 4e20 / 1.000e6 = .020s, 50Hz, which assumes 1MHz clock freq
sei ; disable interrupts just in case
lda #$40 ; Continuous interrupts, don't touch PB7
setup_irq_smc1:
sta MOCK_6522_ACR ; ACR register
lda #$7F ; clear all interrupt flags
setup_irq_smc2:
sta MOCK_6522_IER ; IER register (interrupt enable)
lda #$C0
setup_irq_smc3:
sta MOCK_6522_IFR ; IFR: 1100, enable interrupt on timer one oflow
setup_irq_smc4:
sta MOCK_6522_IER ; IER: 1100, enable timer one interrupt
lda #$E7
; lda #$20
setup_irq_smc5:
sta MOCK_6522_T1CL ; write into low-order latch
lda #$4f
; lda #$4E
setup_irq_smc6:
sta MOCK_6522_T1CH ; write into high-order latch,
; load both values into counter
; clear interrupt and start counting
rts
;=============================
; Disable Interrupt
;=============================
mockingboard_disable_interrupt:
sei ; disable interrupts just in case
lda #$40 ; Continuous interrupts, don't touch PB7
disable_irq_smc1:
sta MOCK_6522_ACR ; ACR register
lda #$7F ; clear all interrupt flags
disable_irq_smc2:
sta MOCK_6522_IER ; IER register (interrupt enable)
rts

View File

@ -0,0 +1,10 @@
; zero page
GBASL = $26
GBASH = $27
V2 = $2D
HGRPAGE = $E6
YPOS = $FE
TCOLOR = $FF