*
* sound driver demo
*
lst off
xc
xc
rel
cas in
dsk /devel/projects/snddemo/snddemo.L
use 1/tool.equates/e16.gsos
use 4/util.macs ; pushword, pushlong
use 4/misc.macs
use 4/locator.macs
use 4/mem.macs
use 4/qd.macs
use 4/qdaux.macs
use 4/event.macs
use 4/window.macs
use 4/ctl.macs
use 4/menu.macs
use 4/desk.macs
use 4/gsos.macs
use 4/sound.macs
*-----------------------------------------------------------------------------
* DP variables and local equates
*-----------------------------------------------------------------------------
dum $0000
AppMMID ds 2,0 ; Memory Manager ID
HndlRef ds 2,0 ; For Dereferencing MM Handle
DPBase ds 1,0 ; Deref'd handle
BuffPtr ds 2,0 ; $4000 bytes for sound
dend
*-----------------------------------------------------------------------------
* GS/OS Program Entry Point
*-----------------------------------------------------------------------------
Entry mx %00
phk
plb
brl Main
*
* Check for toolbox errors
* too-simple error handler
*
CheckError
bcs SysDeath
rts
SysDeath pha
pushlong #0000
_SysFailMgr
*
* StartUpTools - start up the various toolsets
*
StartUpTools
_TLStartUp
pha
_MMStartUp
jsr CheckError
pullword AppMMID
_MTStartUp
pha
pha
pushlong #$700 ; 7 pages of DP space
pushword AppMMID
pushword #$C005 ; Fixed, Page-Aligned, Locked, Unpurgeable
pushlong #$000000 ; in Bank $00, $0000
_NewHandle
jsr CheckError
pulllong HndlRef
lda [HndlRef]
sta DPBase
pha ; save dp pointer for later
pha
pushword #$0080 ; Screen Mode ($0000 = 320, $0080 = 640)
pushword #$00A0 ; Pixel Map Size ($0050 = 320, $00A0 = 640)
pushword AppMMID
_QDStartUp
jsr CheckError
pla ; saved dp pointer
clc
adc #$300
pha ; save dp pointer for later
pha
pushword #20 ; Event Queue size
pushword #0 ; Min X clamp
pushword #640 ; Max X clamp
pushword #0 ; Min Y clamp
pushword #200 ; Max Y clamp
pushword AppMMID
_EMStartUp
jsr CheckError
pushword #0
_SetBackColor
pushword #3
_SetForeColor
pushword #50 ; X position
pushword #85 ; Y position
_MoveTo
pushlong #OneMoment
_DrawCString
pushlong #ToolList
_LoadTools
jsr CheckError
pushword AppMMID
_WindStartUp
jsr CheckError
pla ; saved dp pointer
clc
adc #$100
pha ; save it for later
tax ; save dp pointer in x
pushword AppMMID
phx
_CtlStartUp
jsr CheckError
pla
clc
adc #$100
pha
tax
pushword AppMMID
phx
_MenuStartUp
jsr CheckError
_DeskStartUp
jsr CheckError
pla
clc
adc #$100
pha
_SoundStartUp
jsr CheckError
rts
*
* ShutDownTools - shut em back down
*
ShutDownTools
lda ToolList
asl
asl
tax
lda ToolList-2,x
cmp #$2 ; Memory Manager?
bne ShutDownOne ; Nope, do it normally
pushword AppMMID
_DisposeAll
pushword AppMMID
lda #$2 ; set up for toolset #2 (MM)
ShutDownOne
ora #$300 ; Call #3 (Shutdown)
tax
jsl $E10000
dec ToolList
bne ShutDownTools
rts
*
* Main - main sequence of events
*
Main jsr StartUpTools
jsr PrepDeskTop
sep $20
ldal $e0c034
sta ScreenColorByte
lda #00
stal $e0c034
rep $30
* corner rounding
pushword #0000
_SetForeColor
* upper left
pushword #0001
pushword #0000
_MoveTo
pushword #0001
pushword #0002
_LineTo
pushword #0002
pushword #0000
_MoveTo
pushword #0002
pushword #0001
_LineTo
pushword #0003
pushword #0000
_MoveTo
pushword #0003
pushword #0000
_LineTo
* upper right
pushword #0638
pushword #0000
_MoveTo
pushword #0638
pushword #0002
_LineTo
pushword #0637
pushword #0000
_MoveTo
pushword #0637
pushword #0001
_LineTo
* lower left
pushword #0000
pushword #0195
_MoveTo
pushword #0000
pushword #0199
_LineTo
pushword #0001
pushword #0197
_MoveTo
pushword #0001
pushword #0199
_LineTo
pushword #0002
pushword #0199
_MoveTo
pushword #0002
pushword #0199
_LineTo
* lower right
pushword #0639
pushword #0195
_MoveTo
pushword #0639
pushword #0199
_LineTo
pushword #0638
pushword #0197
_MoveTo
pushword #0638
pushword #0199
_LineTo
pushword #0637
pushword #0199
_MoveTo
pushword #0637
pushword #0199
_LineTo
EventLoop
jsr Maint ; Music maintenance if it's playing
pha ; Result Space
pushword #$ffff ; Event Mask
pushlong #EventRec
_TaskMaster
pla
beq EventLoop
cmp #$11 ; wInMenuBar?
bne EventLoop ; no, so ignore
jsr MenuDispatch
bit QuitFlag
bpl EventLoop
sep $20
lda ScreenColorByte
stal $e0c034
rep $30
jsr ShutDownTools
iGSOS _Quit;QParams;1
*
* Prepare Desktop
*
PrepDeskTop
pushlong #0000
_RefreshDesktop
_InitCursor
NextMenu pha
pha
lda MenuTbl
asl
tax
lda MenuTbl,x
phb
phb
pha
_NewMenu
pushword #0000
_InsertMenu
dec MenuTbl
bne NextMenu
pushword #1
_FixAppleMenu
pha
_FixMenuBar
pla
_DrawMenuBar
rts
*
* Apple Menu: About
*
About rts
*
* File Menu: Quit
*
Quit dec QuitFlag
rts
*
* Play the noise
*
Play jsr init
rts
*
* Menu Dispatcher
*
MenuDispatch
lda TaskData
and #$00ff
asl
tax
jsr (MenuDispatchTbl,x)
pushword #0000
pushword TaskData+2
_HiliteMenu
rts
*
* Non-DP Variables
*
QuitFlag
dw 00,00
ScreenColorByte
dw 00
*
* Tool List
*
ToolList
dw 10 ; Tool Count
dw 01,00 ; Tool Locator, any vers
dw 02,00 ; Memory Manager, any vers
dw 03,00 ; Misc Tools, any vers
dw 04,00 ; QuickDraw II, any vers
dw 06,00 ; Event Manager, any vers
dw 14,00 ; Window Manager, any vers
dw 16,00 ; Control Manager, any vers
dw 15,00 ; Menu Manager, any vers
dw 05,00 ; Desk Manager, any vers
dw 08,00 ; Sound Manager, any vers
ToolListEnd
*
* Menu Structures
*
MenuDispatchTbl
dw About
dw Quit
dw Play
MenuTbl dw 4 ; count
dw Menu1
dw Menu2
dw Menu3
dw Menu4
MenuTblEnd
Menu1 asc '>>@\XN1'00
asc '--About This Program...\N256*??'00
asc '---\D'00
asc '>'
Menu2 asc '>> File \N2'00
asc '--Quit\N257*Qq'00
asc '>'
Menu3 asc '>> Edit \N3D'00
asc '--Undo\N250V*Zz'00
asc '--Cut\N251*Xx'00
asc '--Copy\N252*Cc'00
asc '--Paste\N253V*Vv'00
asc '--Clear\N254'00
asc '>'
Menu4 asc '>> Music \N4'00
asc '--Play\N258*Pp'00
asc '>'
*
* Event Record
*
EventRec
Event_What
ds 2
Event_Msg
ds 4
Event_When
ds 4
Event_Where
ds 4
Event_Mods
ds 2
TaskData
ds 4
TaskMask
dw $1fff,$0000
*
* Strings
*
OneMoment
asc 'One Moment Please...'00
*
* GS/OS Quit Params
*
QParams ds 4
ds 4
*
* apple iigs streaming sound driver
* based on OVERSAMPLER
* christopher shepherd <cshepher@ieee.org>
* june 2007
*
init
ldx #$4000
ldy #0000
jsr Alloc
jsr checkError
stx HndlRef
sty HndlRef+2
lda [HndlRef]
sta BuffPtr
ldy #0002
lda [HndlRef],y
sta BuffPtr+2
jsr DOCHalt
pushLong #SoundMIRQV
_SetSoundMIRQV
jsr checkError
player
jsr DOCInit
jsr FileOpen
jsr FirstDiskRead
ldy #0000
]pl1 lda RegTbl2,y
cmp #$FFFF
beq ]pl2
and #$00FF
tax
lda RegTbl2,y
xba
and #$00FF
jsr SetDOCReg
iny
iny
bra ]pl1
]pl2 ldx EchoDelay
beq ]noecho
]vbl sep $20
]vbl1 ldal $E0C019
bpl ]vbl1
]vbl2 ldal $E0C019
bpl ]vbl2
rep $20
dex
bne ]vbl
]noecho ldx #$00A0 ; A0 - Control 0
lda #0000 ; 00 - free run, no int, no halt (playing)
jsr SetDOCReg
stz BadIntCount
stz SndBank
stz EndFlag
lda #$FFFF
sta IntFlag
lda EndFlag
bne ]end2
Maint
lda IntFlag
beq NextChunk
]mret rts
NextChunk
dec IntFlag
jsr DiskRead
bcs ]end2
ldx SndBank
jsr PutSndData
lda SndBank
eor #0001
sta SndBank
lda IntFlag
bne ]mret
* interrupt happened during refilling (too slow!)
inc BadIntCount
lda BadIntCount
cmp #0003
beq ]end2
bra ]mret
]end2
jsr DOCHalt
rts
RegTbl2
db $00,$01 ; freq low0 = E3
db $20,$02 ; freq high0 = 01 (freq0 = 1E3 or d483)
db $10,$01 ; freq low16 = E3
db $30,$02 ; freq high16 = 01 (freq16 = 1E3 or d483)
db $08,$01 ; freq low8 = E3
db $28,$02 ; freq high8 = 01 (freq8 = 1E3 or d483)
db $40,$FF ; volume0 = FF
db $50,$FF ; volume16 = FF
db $48,$00 ; volume8 = 00
db $80,$00 ; addr0 = 00
db $88,$80 ; addr8 = 80
db $90,$00 ; addr16 = 00
db $C0,$3F ; multi0 = 3F (play 32k sound)
db $C8,$3E ; multi8 = 3E (play 32k sound, half resolution)
db $D0,$3F ; multi16 = 3F (play 32k sound)
db $A0,$01 ; control0 = 01 (free run, halt, no int)
db $A8,$08 ; control8 = 08 (free run, no halt, int)
db $B0,$10 ; control16 = 10 (free run, no halt, no int, stereo?)
db $FF,$FF ; end of table
* halt all DOC voices
DOCHalt ldx #$00A0
lda #$0001
]dh jsr SetDOCReg
inx
cpx #$00C0
bne ]dh
rts
* read a DOC register
* a = data
* x = register
GetDOCReg
sep $20
]busy ldal $E1C03C
bmi ]busy
ldal $E100CA
and $0F
stal $E1C03C
txa
stal $E1C03E
ldal $E1C03D
ldal $E1C03D
rep $20
rts
* set a DOC register
* a = data
* x = register
SetDOCReg
sep $20
pha
]busy2 ldal $E1C03C
bmi ]busy2
ldal $E100CA
and $0F
stal $E1C03C
txa
stal $E1C03E
pla
stal $E1C03D
rep $20
rts
* init DOC registers to defaults
DOCInit sep $20
ldal $E100CA
and #$0F
ora #$60
stal $E1C03C ; DOC RAM, auto-increment
lda #00
stal $E1C03E
stal $E1C03F ; address $0000
ldy #00
lda #80
]base stal $E1C03D ; put $80 (baseline) into DOC RAM
iny
bne ]base
rep $20
ldy #0000
]init lda RegTbl1,y
cmp #$FFFF
beq ]ret
and #$00FF
tax
lda RegTbl1,y
xba
and #$00FF
jsr SetDOCReg
iny
iny
bra ]init
]ret rts
RegTbl1
db $00,$00 ; freq low0 = 00
db $20,$08 ; freq hi0 = 08
db $10,$00 ; freq low16 = 00
db $30,$08 ; freq hi16 = 08
db $08,$00 ; freq low8 = 00
db $28,$08 ; freq hi8 = 00
db $40,$00 ; volume 0 = 00
db $50,$00 ; volume 16 = 00
db $48,$00 ; volume 8 = 00
db $80,$00 ; address low0 = 00
db $88,$00 ; address low8 = 00
db $90,$00 ; address low16 = 00
db $C0,$00 ; wavtbl0 = 00
db $C8,$00 ; wavtbl8 = 00
db $D0,$00 ; wavtbl16 = 00
db $A0,$00 ; control0 = 00
db $A8,$00 ; control8 = 00
db $B0,$00 ; control16 = 00
db $FF,$FF ; end of table
* slam data from buffer into DOC ram
* a, y - trashed
* $88 - pointer to the data
* x=0 - stash in DOC $0000
* x=1 - stash in DOC $4000
PutSndData
sep $20
ldal $E100CA
and #$0F
ora #$60 ; DOC RAM, auto increment
stal $E1C03C
lda #00
stal $E1C03E ; address low byte: 00
cpx #00
beq ]hi
lda #$40
]hi stal $E1C03F
ldy #0000
]sloop lda [BuffPtr],y
bne ]nozero
inc
]nozero ldx OverSample
beq ]noover
jsr OverSample2x
]noover stal $E1C03D
iny
cpy RTrans
bcc ]sloop
cpy RReq
beq ]ret2
lda #00
stal $E1C03D ; 00 byte for end of sound
]ret2 rep $20
rts
OverSample2x
cpx #0002
beq OverSample4x
pha
rep $20
clc
adc OSByte2
lsr
sep $20
stal $E1C03D
pla
sta OSByte2
rts
OverSample4x
pha
rep $20
clc
adc OSByte2
lsr
sta OSByte1
clc
adc OSByte2
lsr
sep $20
stal $E1C03D
lda OSByte1
stal $E1C03D
pla
sta OSByte2
rep $20
clc
adc OSByte1
lsr
sep $20
stal $E1C03D
lda OSByte2
rts
* Sound MIRQ handler
SoundMIRQV
php
phb
phd
rep $30
phk
plb
lda OrigDataBank
tcd
ldx #$00E0 ; oscillator interrupt register
jsr GetDOCReg
bit #$0080 ; interrupt?
beq ]smi1
and #$003E ; get osc number
cmp #$0010 ; oscillator8?
bne ]smi1
stz IntFlag ; clear interrupt flag to show this happened
]smi1 ldx #$00A0 ; Control Register 0
jsr GetDOCReg
and #0001 ; halted?
beq ]smi2
dec EndFlag
jsr DOCHalt
]smi2 pld
plb
plp
clc
rtl
IntFlag dw $FFFF
EndFlag dw 0000
EchoDelay dw 0000
SndBank dw 0000
BadIntcount dw 0000
OverSample dw 0000
Length dw 0000
Length2 dw 0000
OSByte1 dw 0000
OSByte2 dw 0000
OrigDataBank dw 0000
* read a chunk from disk
* first time - fill low and high $4000's
FirstDiskRead
lda #0000
sta SDisp
sta SDisp+2 ; init position to 0
iGSOS _SetMark;SeekParams;1
jsr CheckError
ldx BuffPtr
ldy BuffPtr+2
stx RData
sty RData+2 ; set GSOS to read to our allocated buffer
lda #$4000
ldx OverSample
beq ]noOS
]OS lsr ; reduce to $2000 or $1000 if 2x or 4x oversample
dex
bne ]OS
]noOS sta RReq
stz RReq+2
iGSOS _Read;ReadParams;1
jsr CheckError
ldx #0000
jsr PutSndData
iGSOS _Read;ReadParams;1
jsr CheckError
ldx #0001
jsr PutSndData
clc
rts
* just get one chunk from disk
DiskRead
iGSOS _Read;ReadParams;1
clc
rts
* open the file for reading
FileOpen
iGSOS _Open;OpenParams;1
jsr CheckError
lda OHndl
sta RHndl
sta CHndl
sta GHndl
sta SHndl
iGSOS _GetEOF;GetEOFParams;1
jsr CheckError
rts
OpenParams
dw $0002
OHndl dw 0000
OPath adrl FilePath
FilePath strl 'demjeans.WAV'
ReadParams
dw $0004
RHndl dw 0000
RData dw 0000
dw 0000
RReq dw 0000
dw 0000
RTrans dw 0000
dw 0000
CloseParams
dw $0001
CHndl dw 0000
GetEOFParams
dw $0002
GHndl dw 0000
GEOF dw 0000
dw 0000
SeekParams
dw $0003
SHndl dw 0000
SBase dw 0000
SDisp dw 0000
dw 0000
* Get Memory from the Memory Manager
* x = size lo
* y = size hi
Alloc pha
pha
phy
phx
pushword AppMMID
pushword #$C000
pushlong #$000000
_NewHandle
plx
ply
rts