I've looked around for the interrupt driven music player, but cannot find it (I find cybernoid demo, but it only plays its' own tune)
I entered all of SMB music into Electric Duet. This works fine and sounds great for music when the game isn't being played. I would like to get the interrupt driven mockingboard driver to work so I can play music while playing the game... I can make sounds through the card, and play tunes, but I want interrupts so It can play in the background...
1)where to look for this driver (source code?)
2)how to convert MIDI tunes to the format the driver expects? I think the only person who has midi conversion experience is MJM??
Midi songs that I want to play will be reduced to the # of voices that the MB supports, using an editor on the PC.
<aiiad...@gmail.com> wrote:
> I've looked around for the interrupt driven music player, but cannot find
> it (I find cybernoid demo, but it only plays its' own tune)
> I entered all of SMB music into Electric Duet. This works fine and
> sounds great for music when the game isn't being played. I would like to
> get the interrupt driven mockingboard driver to work so I can play music
> while playing the game... I can make sounds through the card, and play
> tunes, but I want interrupts so It can play in the background...
> 1)where to look for this driver (source code?)
Check the disk that shipped with the Mockingboard for the object code. It's
quite short, so disassembly should be straightforward.
> 2)how to convert MIDI tunes to the format the driver expects? I think
> the only person who has midi conversion experience is MJM??
> Midi songs that I want to play will be reduced to the # of voices that
> the MB supports, using an editor on the PC.
That's a good first step--although the music can have more than three
voices as long as no more than three are sounding simultaneously. (And a
Mockingboard can sound *six* square wave voices and two percussive voices
simultaneously, since it has two AY 8910 chips.
My MIDI converter currently outputs N separate streams, one for each
oscillator. Each note or rest is represented as a byte for the note or rest
followed by a two-byte duration to the next action for the oscillator. For
convenience, the separate oscillator streams are concatenated into a single
binary file.
On Monday, September 10, 2012 12:01:47 AM UTC-7, mjm...@aol.com wrote:
> Check the disk that shipped with the Mockingboard for the object code. It's
> quite short, so disassembly should be straightforward.
OK, I found it. Strange they would make the player interrupt driven, and not make the demo show this. It just waits for a key, stops music, and returns to the menu. If you delete some of the lines is the MUSIC program, it will continue playing music in the background at the ] prompt
> > 2)how to convert MIDI tunes to the format the driver expects? I think
> > the only person who has midi conversion experience is MJM??
> > Midi songs that I want to play will be reduced to the # of voices that
> > the MB supports, using an editor on the PC.
> My MIDI converter currently outputs N separate streams, one for each
> oscillator. Each note or rest is represented as a byte for the note or rest
> followed by a two-byte duration to the next action for the oscillator. For
> convenience, the separate oscillator streams are concatenated into a single
> binary file.
On Monday, September 10, 2012 8:42:26 AM UTC-7, (unknown) wrote:
> On Monday, September 10, 2012 12:01:47 AM UTC-7, mjm...@aol.com wrote:
> > Check the disk that shipped with the Mockingboard for the object code.
Here is the code, I think some of it may be unnecessary (quick cut and paste). It works in Dos3.3 and Prodos. I know that Prodos has its own interrupt handling scheme... This just writes over the interrupt vector. I don't know what software it would break, there aren't many programs that use interrupts.
10 HOME 20 D$ = CHR$ (4)
22 PRINT D$"BLOAD PRIMARY"
23 CALL 36864: CALL 36908: CALL 36897: CALL 36941
205 rem filename table
210 REM TABLE ACCESS ROUTINE
220 REM START
230 DATA 32,33,144,160,0
240 REM LOOP
250 DATA 140,1,196,32,11,144,177,8,141,1,196,32,22,144,192,15,240,4,200,76,5,128,96
260 REM START2
270 DATA 32,77,144,160,0
280 REM LOOP2
290 DATA 140,129,196,32,55,144,177,10,141,129,196,32,66,144,192,15,240,4,200,76,33,1 28,96
300 A = 32768: REM BEGINNING ADDRESS, $8000
310 FOR X = 0 TO 55: READ D
320 POKE A + X,D
330 NEXT 800 rem filename music
810 HOME :D$ = CHR$ (4)
815 VTAB 4: HTAB 11: PRINT "Interrupt driven MUSIC player"
820 VTAB 10: HTAB 6: PRINT "Plays Songs entered"
825 VTAB 12: HTAB 5: PRINT "USING THE MUSIC CONSTRUCTION SET"
828 VTAB 14: HTAB 11: PRINT "Through the Mockingboard"
830 PRINT D$"BLOAD MCS,A$8500"
910 PRINT : PRINT D$"BLOAD SUGAR2,A$4000": 911 POKE 34066,4: 912 POKE 34067,3:
920 CALL 34051: 930 HOME 940 stop
950 POKE 50190,64: 960 CALL 36897: 970 CALL 36941
On Monday, September 10, 2012 4:21:14 PM UTC-7, (unknown) wrote:
> > > Check the disk that shipped with the Mockingboard for the object code.
> Here is the code, I think some of it may be unnecessary (quick cut and paste).
I disassembled the Music Construction Set interrupt driven player for the Mockingboard (only to the point where I could re-assemble it, I didn't reverse engineer it yet)
*********************
*
* SUB 4
*
*********************
SUB4
TXA ;save x and y registers
PHA
TYA
PHA
LDA #$00
CPX #$03
BCC S4L1
DEX
DEX
DEX
LDA #$10
S4L1 STA $D6
TXA
ASL
TAY
LDA $852D
STA ($D6),Y
INY
LDA $852E ;
STA ($D6),Y
TXA
CLC
ADC #$08
TAY
LDA $852C
STA ($D6),Y
PLA ;restore x and y registers
TAY
PLA
TAX
RTS
**************************
*
* sub 10
*
**************************
SUB10
TYA ;save y register
PHA
LDA #$FF
STA $C403
STA $C483
LDA #$07
STA $C402
STA $C482
LDY #$00
STY $C401
LDA #$07
STA $C400
LDA #$04
STA $C400
LDA $0300,Y
STA $C401
LDA #$06
STA $C400
LDA #$04
STA $C400
STY $C481
LDA #$07
STA $C480
LDA #$04
STA $C480
LDA $0310,Y
STA $C481
LDA #$06
STA $C480
LDA #$04
STA $C480
INY
CPY #$0F
BNE $86DC ;L86DC
On Tuesday, September 11, 2012 1:11:29 PM UTC-7, (unknown) wrote:
> :-) I know, just a start to get it to assemble without errors. I have it all figured out now and will post on my website.
most labels are now named according to their function. Tomorrow I start the debugger and figure out how the music file is stored.
Tempo1 DFB #$04 ;tempo
Tempo2 DFB #$03 ;these two are poked in
L8514
MUSLO DFB #$FE ;start of music address - 2
MUSHI DFB #$3F ;
L8516 DFB #$7E ;USED BY SETUP ONLY
L8517 DFB #$44
L8518 DFB #$0A
L8519 DFB #$00 ; startx for Table1Code
L851A DFB #$06 ; endx+1 for Table1Code
;index into table1
DFB #$08
Counter1 DFB #$00 ;counter of some sort
Counter2 DFB #$00 ;these get incremented in interrupt routine
;AND COMPARED TO TEMPO1/2, DETERMINE WETHER OR NOT
;TO PLAY A NOTE?
DFB #$00
tEMPMUSIC1 DFB #$00 ;MUSIC DATA FROM $4000 TEMPORARILY STORED HERE ADDR = 851F
tEMPMUSIC2 DFB #$00 ;
cHKcOUNTER1
LDA Counter1 ;compare to counter inc'd above
CMP Tempo1 ;compare to value poked in
BEQ cOUNTER1LIMIT
JMP RTNFRMINT ;done processing , return from interrupt
* counter1 reached limit
COUNTER1LIMIT
S6L2 LDA #$00
STA Counter1 ;reset counter1
LDX #$00 ;X GOES FROM 0 TO 1 AND THEN IS RESET TO 0
Xloop1 STX TempX
TXA
ASL ;multiply by 2
STA TEMPX2 ;first run through, this = 0
DEC TABLE22,X
LDA TABLE22,X ;=1 first run
BNE $8661
JSR Table1Code
INC PTR1HI,X
NOINCREMENT LDA (PTR1LO,X) ;get a byte from the music file at $4000
LSR ;divide by 2
STA tEMPMUSIC1
INC PTR1LO,X
LDA (PTR1LO,X) ; get a byte from the music file at $4000
DEC PTR1LO,X
STA tEMPMUSIC2
ORA tEMPMUSIC1
BNE NOTZERO
JSR RESETSTUFF
JMP RTN_INT_2 ;done processing sound? JSR's Music2Card before RTI
LDA TABLE641,X
STA L852D ;TEMP STORAGE FOR TABLE64 DATA
LDA TABLE642,X
STA L852E ;TEMP STORAGE FOR TABLE64 DATA
LDA L8518
STA L852C
LDX TEMPX3
JSR MoVdatTo300TBL
LDX TempX
LDA tEMPMUSIC2
AND #$40
STA L852F,X
LDA tEMPMUSIC2
AND #$3F
STA TABLE22,X
LDA tEMPMUSIC2
AND #$80
BNE $85F5
;if x < 3 then x=x-3, deal with second register table (310)
;if X => 3 then deal with first register table ($300)
MoVdatTo300TBL
TXA ;save x and y registers
PHA ;
TYA ;
PHA ;
LDA #$00
CPX #$03 ;x= table1Code value (start = L8519
; end = L851a)
BCC S4L1 ;BRANCH IF >= 3, ;Set TBL300PTR to POINT TO 300
;FIRST AY8910 REGISTER table
DEX
DEX
DEX
LDA #$10 ;SET TBL300PTR TO point to 310, ;SECOND AY8190 REGISTER table
;X >= 3
S4L1 STA TBL300PTRLO ;a=0 or $10, see above
TXA ;x= table1Code value (start = L8519
; end = L851a)
ASL ;multiply by 2
TAY ;transfer to Y
LDA L852D ;THIS IS DATA FROM TABLE64 (music data)
STA (TBL300PTRLO),Y ;put music data in AY8910 register table
INY ;point to next byte in register table
LDA l852E ;THIS IS DATA FROM TABLE64
STA (TBL300PTRLO),Y ;put music data in AU8910 register table
TXA ;x= table1Code value (start = L8519
; end = L851a)
CLC
ADC #$08
TAY ;Y = X+8
LDA L852C
STA (TBL300PTRLO),Y;put music data in AU8910 register table
PLA ;restore x and y registers
TAY ;
PLA ;
TAX ;
RTS
On Friday, September 14, 2012 12:16:32 PM UTC-7, (unknown) wrote:
> On Thursday, September 13, 2012 9:16:06 AM UTC-7, (unknown) wrote:
format for music Construction Set Mockingboard file:
2X1byte pairs:
--------------------------
+00 Byte1=note
+01 Byte2=duration+controlbits
+02 byte1 next note
+03 byte2 next duration
duration+controlbits: ------------------------------
must be EVEN.
Bits 1 to 4 are duration, so duration can be from 0 and 30
(16 possibilities)
bit 7 = set if another note,duration pair to get
Bit 6 = set if no volume reduction (see reduceVOlume routine in source)
Note:
------------------------------
is divided by two to index into a 64 byte table,
must be EVEN
Must be 0 to 128
End of song:
------------------------------
When note and duration both = 0, end of song
Note Table:
------------------------------
See
1)disassembled MCS player Source code 2)APPENDIX E Equal Tempered Chromatic Scale (fCLOCK- 1.023 MHz)
I found these in an old text file (as a start anyway).
======================================
MUSIC CONSTRUCTION SET DOCUMENTATION
=======================================
IF YOU OWN A MOCKINGBOARD SOUND AND
SPEACH GENERATOR YOU CAN PLAY A CHORD
OF UPTO 6 NOTES.
THE 5 GAUGES IN THE CENTER LET YOU
CONTROL PLAYBACK SPEED, VOLUME, AND
SOUND QUALITY. THE SOUND AND VOLUME
GAUGES ONLY WORK IF YOU OWN A MOCKING-
BOARD, THE LEFT ONE IS FOR THE TOP
STAFF THE RIGHT ONE IS FOR THE BOTTOM.
So the music file 2 start addresses seem to correspond to this.
$4000 = top staff in the editor. (chip1, 3 channels)
$447e = bottom staff in the editor. (chip2, 3 channels)
On Monday, September 10, 2012 12:01:47 AM UTC-7, mjm...@aol.com wrote:
> > 2)how to convert MIDI tunes to the format the driver expects? I think > > the only person who has midi conversion experience is MJM??
> My MIDI converter currently outputs N separate streams, one for each
> oscillator. Each note or rest is represented as a byte for the note or rest > followed by a two-byte duration to the next action for the oscillator. For
> convenience, the separate oscillator streams are concatenated into a single
> binary file.
OK, it looks like MCS outputs 2 separate sets of data, one for Chip1 (channels 1 to 3), one for Chip2 (channels 1 to 3). I don't see any references to the NOISE registers on the chips, so I'd hazard a guess that the MCS editor/format will not allow noises through the AY8190 (I see no reference to NOISE in the MCS docs, and no commands relating to NOISE)
I don't think these are actually mapped to Chip1/2 specifically. I think I see "look for open oscillator" code in the source.
Your converter has two byte duration.. MCS has 1 byte duration, with Bits 7 and 6 used for control (bit7 set = more notes to play, bit6 = note is tied). Bit 5 is unused, so perhaps in the future I can figure out how to make this bit indicate NOISE to be played.
I will start by creating a simple MIDI music file, and run it through your converter. Look at the output, and see how I can modify your converter to work with the MCS player.
I'm doing this so I can play SMB sound through the mockingboard using interrupt driven routine (MCS file on the Mockingboard Disk1), but if it all goes as planned, Mockingboard users should be able to play converted MIDI files on their apple II computers..
aiiad...@gmail.com wrote:
> I don't think these are actually mapped to Chip1/2 specifically. I
> think I see "look for open oscillator" code in the source.
The two data sets are mapped to the treble and bass clefs.
The format in general is based on how the music looks in the editor
instead of what the player needs to do (the opposite of Electric Duet).
For example, the format actually stores "play a quarter note with this
pitch" instead of "run oscillator 2 with this delay value for this many
counts".
I did some reverse engineering of the file format recently. I'll try and
get my notes online...
Would have helped a bit as I was reading the OBJ file, disassembling it... I know the OP codes from memory now, almost understand all of the code too :-)
On Sunday, September 16, 2012 10:04:27 AM UTC-7, Daniel Kruszyna wrote:
> ai wrote:
> > I don't think these are actually mapped to Chip1/2 specifically. I
> > think I see "look for open oscillator" code in the source.
> The two data sets are mapped to the treble and bass clefs.
> The format in general is based on how the music looks in the editor > instead of what the player needs to do (the opposite of Electric Duet).
> For example, the format actually stores "play a quarter note with this > pitch" instead of "run oscillator 2 with this delay value for this many
> counts".
Right...
ED stores NOTE, Duration, which is actually:
Frequency, TIME
MCS stores NOTE, Duration which is :
NOTE, Time+controlbits
MCS has to look up the frequency in a table.
Time can be 0 to 30, even, so has 16 values
> I did some reverse engineering of the file format recently. I'll try and
> get my notes online...
On Wednesday, September 19, 2012 3:59:59 PM UTC-7, Daniel Kruszyna wrote:
> I did not have time to type these in, so I took pictures of my notebook:
Hi,
Thank you for those. They show the format for MCS editor files.
I haven't been able to generate any songs from the editor that will play with the MCS file on Mockingboard Disk1 (the interrupt driven player). I guess they would have to be converted/ "compiled" into the format expected? Anyone know how to get Music Construction Set generated music to play with the MCS interrupt player?
I tried this:
bload MUSIC, BRUN MCS. no go.
BLOAD MUSIC.OBJ, BRUN MCS. No go.
I tried to OPEN the files that are on MOCKINGBOARD DISK1 in MCS, they will not open.
On Sunday, September 9, 2012 12:44:30 PM UTC-7, (unknown) wrote:
> I've looked around for the interrupt driven music player, but cannot find it (I find cybernoid demo, but it only plays its' own tune)
To watch the MCS player on the Mockingboard DISK1:
10 PRINT CHR$ (4);"bload MCS"
15 INPUT "FILENAME";F$:rem I've been using sugar2
20 PRINT CHR$ (4)"BLOAD ";F$;",A$4000"
24 TEMPO = 34066:DECAY = TEMPO + 1
25 TP = 1:DC = 3
26 POKE TEMPO,tp: POKE DECAY,dc:
30 CALL 34051:
100 TEXT : HOME 110 VTAB 1: HTAB 1: PRINT "CHIP1"
120 VTAB 1: HTAB 20: PRINT "CHIP2"
130 VTAB 2: HTAB 1: PRINT "----------------------------------------"
200 rem
205 VTAB 3
210 PRINT "ALO= ALO="
212 PRINT "AHI= AHI="
214 PRINT "BLO= BLO="
216 PRINT "BHI= BHI="
218 PRINT "CLO= CLO="
220 PRINT "CHI= CHI="
230 VTAB 18: HTAB 1: PRINT "TEMPO "; PEEK (TEMPO);: VTAB 18: HTAB 10: PRINT "DECAY "; PEEK (DECAY)
235 VTAB 17: HTAB 1: PRINT "PTR1= ";( PEEK (7) * 256) + PEEK (6);" PTR2= ";( PEEK (9) * 256) + PEEK (8)
240 FOR I = 0 TO 5
245 VTAB I + 3: HTAB 5: PRINT PEEK (768 + I);" ";
250 VTAB I + 3: HTAB 25: PRINT PEEK (784 + I);" ";
255 NEXT I
289 HTAB 1
290 VTAB 20: PRINT "----------------------------------------"
300 IF PEEK ( - 16384) > 127 THEN GET A$
310 IF A$ = "=" THEN TP = TP + 1
320 IF A$ = "-" THEN TP = TP - 1
330 IF A$ = "1" THEN DC = DC - 1
340 IF A$ = "2" THEN DC = DC + 1
350 POKE TEMPO,TP: POKE DECAY,DC
360 GOTO 230