Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

mockingboard

243 views
Skip to first unread message

aiia...@gmail.com

unread,
Sep 9, 2012, 3:44:29 PM9/9/12
to
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.

Rich

Michael J. Mahon

unread,
Sep 10, 2012, 3:01:47 AM9/10/12
to
<aiia...@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.

-michael - NadaNet 3.1 and AppleCrate II: http://home.comcast.net/~mjmahon

aiia...@gmail.com

unread,
Sep 10, 2012, 11:42:26 AM9/10/12
to
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.

Ok, I will see about getting it to work today.

Rich

aiia...@gmail.com

unread,
Sep 10, 2012, 7:21:14 PM9/10/12
to
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,128,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

aiia...@gmail.com

unread,
Sep 11, 2012, 11:10:20 AM9/11/12
to
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)



;i Just used DFB for bytes that weren't code

ORG $8500

JMP IntRoutine ;interrupt routine
JMP Setup ;install, setup interrupt routine
JMP SUB10
JMP SUB2
JMP $87E0
JMP $87F3

l8512 DFB #$04
l8513 DFB #$03 ;these two are poked in,

L8514
DFB #$FE
DFB #$3F
DFB #$7E
DFB #$44
DFB #$0A
DFB #$00 ; sub3
DFB #$06 ;sub3
DFB #$08
DFB #$00 ;counter of some sort
DFB #$00 ;these get incremented in interrupt routine
DFB #$00
DFB #$00
DFB #$00
DFB #$00 ;sub3
DFB #$00
DFB #$00
DFB #$01
DFB #$01


TABLE1

DFB #$FF
DFB #$FF
DFB #$FF
DFB #$FF
DFB #$FF
DFB #$FF
DFB #$00 ;sub3 access
DFB #$00
DFB #$00 ;sub4access
DFB #$00
DFB #$00
DFB #$1E
DFB #$1F
DFB #$20
DFB #$22
DFB #$24
DFB #$26
DFB #$29
DFB #$2C
DFB #$2E
DFB #$30
DFB #$33
DFB #$36
DFB #$3A
DFB #$3D
DFB #$41
DFB #$45
DFB #$49
DFB #$4D
DFB #$52
DFB #$56
DFB #$5C
DFB #$61
DFB #$67
DFB #$6D
DFB #$73
DFB #$7A
DFB #$81
DFB #$89
DFB #$91
DFB #$9A
DFB #$A3
DFB #$AD
DFB #$B7
DFB #$C2
DFB #$CE
DFB #$DA
DFB #$E7
DFB #$F4
DFB #$03
DFB #$12
DFB #$23
DFB #$34
DFB #$46
DFB #$5A
DFB #$6E
DFB #$84
DFB #$9B
DFB #$B3
DFB #$CD
DFB #$E9
DFB #$06
DFB #$25
DFB #$45
DFB #$68
DFB #$8C
DFB #$B3
DFB #$DC
DFB #$08
DFB #$36
DFB #$67
DFB #$9B
DFB #$D2
DFB #$01
DFB #$01
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$03
DFB #$03
DFB #$03
DFB #$03
DFB #$03
DFB #$00
DFB #$00


**************************
*
* interrupt routine
*
*************************


IntRoutine

;interrupt vector points to this routine

TXA ;save x and y regs on stack
PHA
TYA
PHA

LDA #$C0
STA $C40D

INC $851D ;these keep track of place in song?
INC $851C

LDA $851D
CMP L8513 ;compare to value poked in,
BNE S6L1
JSR SUB7

LDA #$00 ;reset counter
STA $851D

S6L1
LDA $851C ;compare to counter inc'd above
CMP L8512 ;compare to value poked in
BEQ S6L2
JMP RTNFRMINT ;done processing , return from interrupt

S6L2 LDA #$00
STA $851C ;reset counter


LDX #$00
L85E2 STX $8521
TXA
ASL ;multiply by 2
STA $8522

DEC $8524,X
LDA $8524,X
BNE $8661
JSR SUB3

LDX $8522
LDA $06,X
CLC
ADC #$02
STA $06,X
BCC S6L3

INC $07,X
S6L3 LDA ($06,X)


LSR
STA $851F
INC $06,X
LDA ($06,X)
DEC $06,X
STA $8520
ORA $851F
BNE S6L4
JSR SUB2
JMP RTN_INT_2

S6L4
LDX $8521
JSR SUB8
LDA $8521
STA TABLE1,X
STX $8523
LDX $851F
LDA $8531,X
STA $852D
LDA $8571,X
STA $852E
LDA $8518
STA $852C
LDX $8523
JSR SUB4
LDX $8521
LDA $8520
AND #$40
STA $852F,X
LDA $8520
AND #$3F
STA $8524,X
LDA $8520
AND #$80
BNE $85F5

S6L466
LDX $8521
INX
CPX #$02
BEQ RTN_INT_2
JMP L85E2


RTN_INT_2
JSR SUB10


***************************
*
* return from interrupt
*
***************************

RTNFRMINT
PLA
TAY
PLA
TAX
LDA $45
RTI


******************************
*
* sub 8
*
*******************************


SUB8 CPX #$00
BNE SUB8L1
LDX $8519
LDA TABLE1,X
BMI SUB8L2
INX
CPX $851A
BNE $867D ;SUB8L3
DEX
RTS

SUB8L1
LDX $851A
DEX
LDA TABLE1,X
BMI SUB8L2
DEX
CPX $8519
BNE $868E ;SUB8L5
SUB8L2 RTS




*********************
*
* 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

PLA ;restore y register
TAY
RTS


*************************
*
* SUB3
*
*************************

SUB3
LDX $8519 ;=0
S3LOOP LDA TABLE1,X
CMP $8521 ;init to 1 in sub2
BNE S3L1
LDA #$FF
STA TABLE1,X
LDA #$00
STA $852C
JSR SUB4
S3L1 INX
CPX $851A
BNE S3LOOP
RTS


**************************
*
* sub2
*
**************************

SUB2
LDA $8514 ;fe ;setup pointer to 3ffe in 06-07
STA $06 ;
LDA $8515 ;3f
STA $07 ;

LDA $8516 ;7e
STA $08 ;
LDA $8517 ;44
STA $09 ;

;set interrupt vector
LDA #$00 ;3fe/ff = $8500, start of this routine
STA $03FE ;
LDA #$85 ;
STA $03FF ;

LDA #$00 ;d6/d7 = 0300
STA $D6
LDA #$03
STA $D7

LDA #$01 ;init stuff for sub3
STA $8524
STA $8525
LDA #$00
STA $8521

JSR SUB3
LDA #$01 ;reinit something to 1
STA $8521
JSR SUB3
RTS


***********************
*
* Setup
*
***********************


Setup
JSR SUB1 ;move 32 bytes to 0300
JSR SUB2 ;setup vectors and

LDA #$F8
STA $0307
STA $0317

LDA #$40 ;mb inits
STA $C40B
LDA #$7F
STA $C40E
LDA #$C0
STA $C40D
STA $C40E
LDA #$FF
STA $C404
LDA #$40
STA $C405
CLI
RTS


***********************
*
* SUB7
*
***********************

SUB7
LDX #$00
SUB7L0 LDA TABLE1,X
CMP #$02
BCS SUB7L1
TAY
LDA $852F,Y
BNE SUB7L1
LDA $0308,X
CMP $851B
BEQ SUB7L1
DEC $0308,X
SUB7L1
LDA $8529,X
CMP #$02
BCS $87DA ;SUB7L2
TAY
LDA $852F,Y
BNE $87DA ;SUB7L2
LDA $0318,X
CMP $851B
BEQ $87DA ;SUB7L2
DEC $0318,X
INX
CPX #$03
BNE SUB7L0
RTS

SEI
LDA #$00
STA $8521
JSR SUB3
INC $8521
JSR SUB3
JSR SUB10
RTS
CLI
RTS


SUB1 LDX #$00 ;move 32 bytes from 8803 to 0300
LOOP1 LDA Table77,X
STA $0300,X
INX
CPX #$20
BNE LOOP1
RTS

******************
*
* table 77
*
******************

Table77

DFB #$01
DFB #$00
DFB #$01
DFB #$00
DFB #$01
DFB #$00
DFB #$00
DFB #$3F
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$01
DFB #$00
DFB #$01
DFB #$00
DFB #$01
DFB #$00
DFB #$00
DFB #$3F
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00


10 PRINT CHR$ (4);"bload MKGBDINTRUPT":rem abov file
20 PRINT CHR$ (4)"BLOAD SUGAR2,A$4000": POKE 34066,4: POKE 34067,3:
30 CALL 34051:

I'll do some more work on it today. I'm trying to figure out the file format for MCS generated music, so I can use MJM's midi converter to output music that it will play.

Rich

Antoine Vignau

unread,
Sep 11, 2012, 1:55:00 PM9/11/12
to
Sorry, ugly disassembly...
av

aiia...@gmail.com

unread,
Sep 11, 2012, 4:11:29 PM9/11/12
to
On Tuesday, September 11, 2012 10:55:01 AM UTC-7, Antoine Vignau wrote:
> Sorry, ugly disassembly...
>
> av

:-) 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.

aiia...@gmail.com

unread,
Sep 13, 2012, 1:46:13 AM9/13/12
to
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.

Rich

aiia...@gmail.com

unread,
Sep 13, 2012, 12:16:05 PM9/13/12
to
On Wednesday, September 12, 2012 10:46:14 PM UTC-7, (unknown) wrote:
> 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.



ORG $8500

;ADDRESSES FOR First 6522

ORB EQU $C400 ;PORT B
ORA EQU $C401 ;PORT A
DDRB EQU $C402 ;DATA DIRECTION REGISTER (A)
DDRA EQU $C403 ;DATA DIRECTION REGISTER (B)

;ADDRESSES FOR SECOND 6522

ORA2 EQU $C481 ;PORT A
ORB2 EQU $C480 ;PORT B
DDRA2 EQU $C483 ;DATA DIRECTION REGISTER (A)
DDRB2 EQU $C482 ;DATA DIRECTION REGISTER (B)

IFR EQU $C40D ;interrupt flag


*page 3 equates

TBL300N1 equ $300
TBL300N2 equ $308
TBL300N3 equ $310
TBL300N4 equ $318

*PAGE 0 EQUATES

PTR1LO equ $06
PTR1HI equ $07
TBL300PTRLO EQU $D6
TBL300PTRHI EQU $D7

;only the first 2 jmps are used. The rest are probably for testing purposes?

JMP INTROUTINE ;interrupt routine
JMP SETUP ;install, setup interrupt routine
JMP Music2Card
JMP RESETSTUFF
JMP $87E0
JMP $87F3

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 ;


TempX DFB #$00 ;Table1Code addr=8521
TEMPX2 DFB #$00 ;THIS IS TEMPX * 2
TEMPX3 DFB #$00 ; ADDR= 8523


TABLE22

L8524 DFB #$01
DFB #$01


TABLE1 ;table of 6 bytes, indexed by start=L8519,end=l851a

DFB #$FF ;#0
DFB #$FF ;#1
DFB #$FF ;#2
DFB #$FF ;#3
DFB #$FF ;#4
DFB #$FF ;#5


L852C DFB #$00 ;Table1Code access


L852D DFB #$00 ;TEMP STORAGE FOR DATA GOT FROM TABLE64
L852E DFB #$00 ;TEMP STORAGE FOR DATA GOT FROM TABLE64


L852F DFB #$00
DFB #$00


;64 bytes

;THESE MAY BE TABLES CORRESPONDING TO FREQUENCIES TO PLAY ???
TABLE641
DFB #$1E ;ADDR=8531
DFB #$1F
DFB #$20
DFB #$22
DFB #$24
DFB #$26
DFB #$29
DFB #$2C
DFB #$2E
DFB #$30
DFB #$33
DFB #$36
DFB #$3A
DFB #$3D
DFB #$41
DFB #$45 ;ADDR = 8540
DFB #$49
DFB #$4D
DFB #$52
DFB #$56
DFB #$5C
DFB #$61
DFB #$67
DFB #$6D
DFB #$73
DFB #$7A
DFB #$81
DFB #$89
DFB #$91
DFB #$9A
DFB #$A3
DFB #$AD ;ADDR =8550
DFB #$B7
DFB #$C2
DFB #$CE
DFB #$DA
DFB #$E7
DFB #$F4
DFB #$03
DFB #$12
DFB #$23
DFB #$34
DFB #$46
DFB #$5A
DFB #$6E
DFB #$84
DFB #$9B
DFB #$B3 ;ADDR=8560
DFB #$CD
DFB #$E9
DFB #$06
DFB #$25
DFB #$45
DFB #$68
DFB #$8C
DFB #$B3
DFB #$DC
DFB #$08
DFB #$36
DFB #$67
DFB #$9B
DFB #$D2
DFB #$01
DFB #$01 ;ADDR=8570

;another 64 bytes

TABLE641
DFB #$00 ;ADDR =8571
DFB #$01 ;40TH
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01
DFB #$01 ;50TH
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$02
DFB #$03
DFB #$03
DFB #$03
DFB #$03
DFB #$03
DFB #$00
DFB #$00


**************************
*
* interrupt routine
*
*************************


INTROUTINE
;DOESN'T DO ANYTHING UNTIL
;COUNTER2 = TEMPO2 (JSR COUNTER2LIMIT)
;OR COUNTER1 = TEMPO1

;interrupt vector points to this routine

TXA ;save x and y regs on stack
PHA ;
TYA ;
PHA ;

LDA #$C0 ;disable mockingboard interrupts
STA IFR

INC Counter2 ;Tempo
INC Counter1

CHECKCOUNTER2
LDA Counter2
CMP Tempo2 ;compare to value poked in,
BNE cHKcOUNTER1

COUNTER2LIMIT
JSR COUNTER2LIMIT ;Counter2 reached limit

LDA #$00 ;reset counter2
STA Counter2

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

LDX TEMPX2
LDA PTR1LO,X
CLC
ADC #$02
STA PTR1LO,X
BCC NOINCREMENT

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

NOTZERO
LDX TempX
JSR SUB8
LDA TempX
STA TABLE1,X
STX TEMPX3
LDX tEMPMUSIC1

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

S6L466
LDX TempX
INX
CPX #$02
BEQ RTN_INT_2
JMP Xloop1


RTN_INT_2
JSR Music2Card


***************************
*
* return from interrupt
*
***************************

RTNFRMINT
PLA ;restore registers
TAY ;
PLA ;
TAX ;
LDA ; $45
RTI


******************************
*
* sub 8
*
*******************************


SUB8 CPX #$00 ;if x=0 and table1,(8519) = 0 to 127 then ??
BNE SUB8L1
LDX L8519
LDA TABLE1,X
BMI DoneSub8
INX
CPX L851A
BNE $867D ;SUB8L3
DEX
RTS

SUB8L1
LDX L851A
DEX
LDA TABLE1,X
BMI DoneSub8
DEX
CPX L8519
BNE $868E ;SUB8L5
DoneSub8 RTS




*********************
*
* MoVdatTo300TBL
*
*********************


;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

**************************
*
* Music2Card
*
**************************

Music2Card ;sends 30 bytes to card,
;15 to 300 to 30E
;15 to 310 to 31e


TYA ;save y register
PHA
LDA #$FF ; init channel A
STA DDRA
STA DDRA2

LDA #$07 ;command = write data, so comfirm init
STA DDRB
STA DDRB2

LDY #$00 ;command = reset
STY ORA

LDA #$07
STA ORB

LDA #$04
STA ORB

LDA tbl300N1,Y
STA ORA

LDA #$06
STA ORB

LDA #$04
STA ORB
STY ORA2

LDA #$07
STA ORB2

LDA #$04
STA ORB2

LDA TBL300N3,Y
STA ORA2

LDA #$06
STA ORB2

LDA #$04
STA ORB2

INY
CPY #$0F ;send 15 bytes to ora,ora2 from 300

BNE $86DC ;L86DC

PLA ;restore y register
TAY
RTS


*************************
*
* Table1Code
*
*************************

;first run, does nothing

;for x=0 :8519 to l851a-1 (0 to 5)
;if Table1,x=tempx then table1,x = FF, jsr MoVdatTo300TBL

Table1Code
LDX L8519 ;=0
Table1LOOP LDA TABLE1,X
CMP TempX ;init to 1 in sub2
BNE TmpXnotTbl1
LDA #$FF
STA TABLE1,X ;Store FF in table if Table,x = TempX
LDA #$00
STA L852C
JSR MoVdatTo300TBL
TmpXnotTbl1 INX
CPX L851A ;(=$06 in obj file)
BNE Table1Loop
RTS


**************************
*
* RESETSTUFF
*
**************************

RESETSTUFF
;setup vectors, variables and jsr Table1code

LDA MUSLO ;fe ;setup pointer start of music in 06-07
STA PTR1LO ; 3ffe = start of music - 2
LDA MUSHI ;
STA PTR1HI ;

LDA L8516 ;7e
STA $08 ;
LDA L8517 ;44
STA $09 ;

;setUP interrupt vector TO
LDA #$00 ;3fe/ff = $8500, start of this routine
STA $03FE ;
LDA #$85 ;
STA $03FF ;

;setup AY8910 register table
LDA #$00 ;d6/d7 = 0300
STA TBL300PTRLO ;this is POINTER TO table of data moved by sub1
LDA #$03
STA TBL300PTRHI

LDA #$01 ;init stuff
STA TABLE22
STA TABLE22+1


LDA #$00 ;init for Table1Code
STA TempX

JSR Table1Code
LDA #$01 ;Tempx=#$01
STA TempX
JSR Table1Code
RTS


***********************
*
* Setup
*
***********************


SETUP
JSR MOVE300TBL ;move 32 bytes to 0300
JSR RESETSTUFF ;setup vectors, variables and jsr Table1code

LDA #$F8 ;init 307 and 317 to F8
STA $0307
STA $0317

LDA #$40 ;mb inits
STA $C40B ;aux control register

LDA #$7F
STA $C40E ;interrupt enable

LDA #$C0
STA IFR ;interrupt flag
STA $C40E ;interrupt enable

LDA #$FF
STA $C404 ;t1 low order

LDA #$40
STA $C405 ;t1 high order
CLI
RTS


***********************
*
* COUNTER2LIMIT
*
* counter 2 reached limit
*
***********************

COUNTER2LIMIT

LDX #$00
SUB7L0 LDA TABLE1,X
CMP #$02
BCS SUB7L1
TAY
LDA $852F,Y
BNE SUB7L1
LDA TBL300N2,X
CMP $851B
BEQ SUB7L1
DEC TBL300N2,X
SUB7L1
LDA $8529,X
CMP #$02
BCS $87DA ;SUB7L2
TAY
LDA $852F,Y
BNE $87DA ;SUB7L2
LDA TBL300N4,X
CMP $851B
BEQ $87DA ;SUB7L2
DEC TBL300N4,X
INX
CPX #$03
BNE SUB7L0
RTS

SEI

LDA #$00 ;run table1code with X set to 0 then 1
STA TempX
JSR Table1Code
INC TempX
JSR Table1Code
JSR Music2Card ; then send music to card
RTS
CLI
RTS


******************
*
* sub1
*
******************

MOVE300TBL
SUB1 LDX #$00 ;move 32 bytes from 8803 to 0300
LOOP1 LDA REGTABLE,X
STA $0300,X
INX
CPX #$20
BNE LOOP1
RTS

******************
*
* table 77
*
******************

REGTABLE
TABLE77




l300 DFB #$01 ;table of 8 bytes
DFB #$00 ;but actually table 16 bytes, registers on AY8190
DFB #$01
DFB #$00
DFB #$01
DFB #$00
DFB #$00
DFB #$3F
L308 DFB #$00 ;table of 8 bytes
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00 ;un-used? envelope control
;see music2card, Y counts from 0 to E(15)



L310 DFB #$01 ;table of 8 bytes
DFB #$00 ;but actually table 16 bytes, registers on AY8190
DFB #$01
DFB #$00
DFB #$01
DFB #$00
DFB #$00
DFB #$3F
L318 DFB #$00 ;table of 8 bytes
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00
DFB #$00 ;un-used? envelope control
;see music2card, Y counts from 0 to E(15)



aiia...@gmail.com

unread,
Sep 14, 2012, 3:16:32 PM9/14/12
to
On Thursday, September 13, 2012 9:16:06 AM UTC-7, (unknown) wrote:
> On Wednesday, September 12, 2012 10:46:14 PM UTC-7, (unknown) wrote:
>
> > 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 figured out the music format. Post whole description soon.

aiia...@gmail.com

unread,
Sep 15, 2012, 10:18:32 PM9/15/12
to
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)


note# 16 =E Octave 6
note# 14 =F Octave 6
note# 12 =F# Octave 6
note# 10 =G Octave 6
note# 08 =G# Octave 6
note# 06 =A Octave 6
note# 04 =A# Octave 6
note# 02 =B Octave 6
note# 00 = C Octave 7

----------------------------------------------------------------------------------------------


It looks like the file is separated into two parts,

Load address = chip 1 music?
Load Address + #$47e = chip 2 music?

aiia...@gmail.com

unread,
Sep 16, 2012, 1:16:32 AM9/16/12
to
On Saturday, September 15, 2012 7:18:32 PM UTC-7, (unknown) wrote:
>
> It looks like the file is separated into two parts,
>
>
>
> Load address = chip 1 music?
>
> Load Address + #$47e = chip 2 music?

I just found:

ftp://ftp.apple.asimov.net/pub/apple_II/images/sound/music_construction_set.dsk.gz

has some tips in the text file on disk..

Rich



aiia...@gmail.com

unread,
Sep 16, 2012, 12:25:34 PM9/16/12
to
On Saturday, September 15, 2012 7:18:32 PM UTC-7, (unknown) wrote:
> It looks like the file is separated into two parts,
>
> Load address = chip 1 music?
> Load Address + #$47e = chip 2 music?

from unknown poster on comp.sys.apple2:

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)

aiia...@gmail.com

unread,
Sep 16, 2012, 12:34:53 PM9/16/12
to
On Saturday, September 15, 2012 7:18:32 PM UTC-7, (unknown) wrote:
> 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).


ReduceVolume Routine should be named DIMINISH. Bit6=1 indicates note is TIED. (command key=I to tie note in MCS editor)




aiia...@gmail.com

unread,
Sep 16, 2012, 12:52:40 PM9/16/12
to
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..

Rich


Daniel Kruszyna

unread,
Sep 16, 2012, 1:04:27 PM9/16/12
to
aiia...@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...

-- Daniel

aiia...@gmail.com

unread,
Sep 16, 2012, 1:20:38 PM9/16/12
to
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 :-)

My changes marked in comment field.

Rich


;"WILL HARVEY'S MUSIC"
;"COPYRIGHT (C) 1983"
ORG $8500 ;rem was 4900, rich
OBJ $8500 ;rem was 4900, rich
ORB EQU $C400
ORA EQU $C401
ORB2 EQU $C480
ORA2 EQU $C481
DDRB2 EQU $C482
DDRA2 EQU $C483
DDRB EQU $C402
DDRA EQU $C403
SONGADD EPZ $6
CHANNADD EPZ $D6
JMP INTRUPT
JMP INIT
JMP INITMOCK
JMP SONGADDS

JMP SONGADDS ;added to fill space of
JMP SONGADDS ;JMP pause and JMP continue
;JMP PAUSE ;commented out cuz Im too lazy
;JMP CONTINUE ;to figure out where they go
TEMPO HEX 04
DECAY HEX 03
STARTADD HEX FE3F7E44
STRONG HEX 0A
START HEX 00
END HEX 06
REST HEX 08
TEMPCNTR HEX 00
DECCNTR HEX 00
TEMP5 HEX 00
TEMP0 HEX 00
TEMP1 HEX 00
TEMP2 HEX 00
TEMP4 HEX 00
TEMP6 HEX 00
CNTR HEX 0101
VOICE HEX FFFFFFFFFFFF
PLUG HEX 00
FREQLO HEX 00
FREQHI HEX 00
TIED HEX 0000
FREQLOS HEX 1E1F20222426292C
HEX 2E3033363A3D4145
HEX 494D52565C61676D
HEX 737A8189919AA3AD
HEX B7C2CEDAE7F40312
HEX 2334465A6E849BB3
HEX CDE9062545688CB3
HEX DC0836679BD20000
FREQHIS HEX 0000000000000000
HEX 0000000000000000
HEX 0000000000000000
HEX 0000000000000000
HEX 0000000000000101
HEX 0101010101010101
HEX 0101020202020202
HEX 0203030303030000
TXA
PHA
TYA
PHA
LDA #%11000000
STA $C40D
CHANCE INC DECCNTR
INC TEMPCNTR
LDA DECCNTR
CMP DECAY
BNE NODECAY
JSR DIMINISH
LDA #0
STA DECCNTR
NODECAY LDA TEMPCNTR
CMP TEMPO
BEQ MUSIC
JMP MUSICRTI
MUSIC LDA #$0
STA TEMPCNTR
LDX #0
MUSIC12 STX TEMP2
TXA
ASL
STA TEMP4
DEC CNTR,X
LDA CNTR,X
BNE MUSIC9
JSR STOPVOIC
MUSIC15 LDX TEMP4
LDA SONGADD,X
CLC
ADC #2
STA SONGADD,X
BCC MUSIC10
INC SONGADD+1,X
MUSIC10 LDA (SONGADD,X)
LSR
STA TEMP0
INC SONGADD,X
LDA (SONGADD,X)
DEC SONGADD,X
STA TEMP1
ORA TEMP0
BNE MUSIC11
JSR SONGADDS
JMP MUSIC3
MUSIC11 LDX TEMP2
JSR SEARCH
LDA TEMP2
STA VOICE,X
STX TEMP6
LDX TEMP0
LDA FREQLOS,X
STA FREQLO
LDA FREQHIS,X
STA FREQHI
LDA STRONG
STA PLUG
LDX TEMP6
JSR PLUGIT
MUSIC7 LDX TEMP2
LDA TEMP1
AND #$40
STA TIED,X
LDA TEMP1
AND #$3F
STA CNTR,X
LDA TEMP1
AND #$80
BNE MUSIC15
MUSIC9 LDX TEMP2
INX
CPX #$2
BEQ MUSIC3
JMP MUSIC12
MUSIC3 JSR INITMOCK
MUSICRTI PLA
TAY
PLA
TAX
LDA $45
RTI
SEARCH CPX #$0
BNE S2
LDX START
S4 LDA VOICE,X
BMI S3
INX
CPX END
BNE S4
DEX
RTS
S2 LDX END
DEX
S5 LDA VOICE,X
BMI S3
DEX
CPX START
BNE S5
S3 RTS
PLUGIT TXA
PHA
TYA
PHA
LDA #0
CPX #3
BCC PI2
DEX
DEX
DEX
LDA #10
PI2 STA CHANNADD
TXA
ASL
TAY
LDA FREQLO
STA (CHANNADD),Y
INY
LDA FREQHI
STA (CHANNADD),Y
TXA
CLC
ADC #$8
TAY
LDA PLUG
STA (CHANNADD),Y
PLA
TAY
PLA
TAX
RTS
INITMOCK TYA
PHA
LDA #$FF
STA DDRA
STA DDRA2
LDA #$7
STA DDRB
STA DDRB2
LDY #$0
IM2 STY ORA
LDA #$7
STA ORB
LDA #$4
STA ORB
LDA $300,Y
STA ORA
LDA #$6
STA ORB
LDA #$4
STA ORB
STY ORA2
LDA #$7
STA ORB2
LDA #$4
STA ORB2
LDA $310,Y
STA ORA2
LDA #$6
STA ORB2
LDA #$4
STA ORB2
INY
CPY #$F
BNE IM2
PLA
TAY
RTS
STOPVOIC LDX START
SV2 LDA VOICE,X
CMP TEMP2
BNE SV3
LDA #$FF
STA VOICE,X
LDA #$0
STA PLUG
JSR PLUGIT
SV3 INX
CPX END
BNE SV2
RTS
SONGADDS LDA STARTADD
STA SONGADD
LDA STARTADD+1
STA SONGADD+1
LDA STARTADD+2
STA SONGADD+2
LDA STARTADD+3
STA SONGADD+3
LDA #$0
STA $3FE
LDA #$49
STA $3FF
LDA #$0
STA CHANNADD
LDA #$3
STA CHANNADD+1
LDA #$1
STA CNTR
STA CNTR+1
LDA #$0
STA TEMP2
JSR STOPVOIC
LDA #$1
STA TEMP2
JSR STOPVOIC
RTS
INIT JSR SONGADDS
LDA #$F8
STA $307
STA $317
LDA #%01000000
STA $C40B
LDA #%11000000
STA $C40D
STA $C40E
LDA #$FF
STA $C404
LDA #$40
STA $C405
CLI
RTS
DIMINISH LDX #$00
D1 LDA VOICE,X
CMP #$2
BCS D2
TAY
LDA TIED,Y
BNE D2
LDA $308,X
CMP REST
BEQ D2
DEC $308,X
D2 LDA VOICE+3,X ;D2 label wasn't in original
CMP #$2
BCS D3
TAY
LDA TIED,Y
BNE D3
LDA $318,X
CMP REST
BEQ D3
DEC $318,X
D3 INX
CPX #$3
BNE D1
RTS


aiia...@gmail.com

unread,
Sep 16, 2012, 1:47:16 PM9/16/12
to
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...
>

Please!

Rich

aiia...@gmail.com

unread,
Sep 16, 2012, 2:56:48 PM9/16/12
to
On Sunday, September 16, 2012 10:47:16 AM UTC-7, (unknown) wrote:
>

ED stores NOTE1, NOTE2, Duration, which is actually:

Frequency, TIME OR control code

when duration=1, sets channels 1,2 to effect
#'s NOTE1, NOTE2, 1= normal. This is in CoolED
docs on asimov in images/sound/ cooled



Daniel Kruszyna

unread,
Sep 19, 2012, 6:59:59 PM9/19/12
to

aiia...@gmail.com

unread,
Sep 19, 2012, 8:46:27 PM9/19/12
to
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.



Rich



aiia...@gmail.com

unread,
Sep 19, 2012, 11:40:48 PM9/19/12
to
On Wednesday, September 19, 2012 5:46:28 PM UTC-7, (unknown) wrote:
> On Wednesday, September 19, 2012 3:59:59 PM UTC-7, Daniel Kruszyna wrote:
>


http://www.msx.org/forum/development/msx-development/crystal-clean-pcm-8bit-samples-poor-psg

aiia...@gmail.com

unread,
Sep 20, 2012, 12:32:07 PM9/20/12
to
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
0 new messages