mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.7 KiB
201 lines
5.7 KiB
;*****************************************************************************
|
|
;*****************************************************************************
|
|
;** **
|
|
;** AY-3-8910 Sound Test Program **
|
|
;** Author: Wayne Warthen -- 10/8/2017 **
|
|
;** **
|
|
;*****************************************************************************
|
|
;*****************************************************************************
|
|
;
|
|
;=============================================================================
|
|
; Constants Section
|
|
;=============================================================================
|
|
;
|
|
; Hardware port addresses
|
|
;
|
|
rsel .equ $A4 ; Register seelection port address
|
|
rdat .equ $A5 ; Register data port address
|
|
acr .equ $A2 ; Aux control register port address
|
|
;
|
|
; CPU speed for delay scaling
|
|
;
|
|
cpuspd .equ 4 ; CPU speed in MHz
|
|
;
|
|
; BDOS invocation constants
|
|
;
|
|
bdos .equ $0005 ; BDOS invocation vector
|
|
print .equ 9 ; BDOS print function number
|
|
conwrt .equ 2 ; BDOS console write char
|
|
;
|
|
;=============================================================================
|
|
; Code Section
|
|
;=============================================================================
|
|
;
|
|
.org $100
|
|
;
|
|
ld (stksav),sp ; save incoming stack frame
|
|
ld sp,stack ; setup our private stack
|
|
;
|
|
ld de,banner ; load banner string address
|
|
ld c,print ; BDOS print function number
|
|
call bdos ; do it
|
|
;
|
|
ld a,$FF ; SCG board activation value
|
|
out (acr),a ; write value to ACR
|
|
;
|
|
xor a ; zero accum
|
|
ld (chan),a ; init channel number
|
|
;
|
|
chloop:
|
|
; Test each channel
|
|
call tstchan ; test the current channel
|
|
ld hl,chan ; point to channel number
|
|
ld a,(chan) ; get current channel
|
|
inc a ; bump to next
|
|
ld (chan),a ; save it
|
|
cp 3 ; end of channels?
|
|
jr nz,chloop ; loop if not done
|
|
;
|
|
ld de,crlf ; newline
|
|
ld c,print ; BDOS print function
|
|
call bdos ; do it
|
|
;
|
|
ld sp,(stksav) ; restore stack
|
|
;
|
|
ret ; end of program
|
|
;
|
|
tstchan:
|
|
; Display channel being tested
|
|
ld de,chmsg ; point to channel message
|
|
ld c,print ; BDOS print function number
|
|
call bdos ; do it
|
|
ld a,(chan) ; get current channel number
|
|
add a,'A' ; offset to print as alpha
|
|
ld e,a ; put in E
|
|
ld c,conwrt ; BDOS console out function number
|
|
call bdos ; do it
|
|
ld de,chmsg2 ; point to channel message
|
|
ld c,print ; BDOS print function number
|
|
call bdos ; do it
|
|
;
|
|
ld hl,0 ; initial pitch value
|
|
ld (pitch),hl ; save it
|
|
;
|
|
; Setup mixer register
|
|
ld a,(chan) ; get channel num (0-2)
|
|
inc a ; adjust index (1-3)
|
|
ld b,a ; and use as loop counter
|
|
xor a ; clear accum
|
|
scf ; set carry
|
|
mixloop:
|
|
rla ; rotate bit
|
|
djnz mixloop ; loop based on channel num
|
|
cpl ; invert bits
|
|
and $FF ; so only target bit is cleared
|
|
push af ; save value
|
|
ld a,7 ; mixer register
|
|
out (rsel),a ; select it
|
|
pop af ; recover value
|
|
out (rdat),a ; and set register value
|
|
;
|
|
; Set channel volume to max
|
|
ld a,(chan) ; get channel
|
|
add a,8 ; adjust for start of vol regs
|
|
out (rsel),a ; select register
|
|
ld a,$0F ; max volume
|
|
out (rdat),a ; write it
|
|
;
|
|
pitloop:
|
|
; Pitch loop
|
|
ld a,(chan) ; get channel
|
|
sla a ; A := channel pitch reg, 2 bytes per chan
|
|
out (rsel),a ; select low byte register
|
|
push af ; save register
|
|
ld a,l ; get low byte of pitch value
|
|
out (rdat),a ; and write it to register
|
|
pop af ; recover register index
|
|
inc a ; inc to high byte pitch register
|
|
out (rsel),a ; select high byte register
|
|
ld a,h ; get high byte of pitch value
|
|
out (rdat),a ; and write it to register
|
|
;
|
|
; Delay
|
|
ld b,cpuspd ; cpu speed scalar
|
|
dlyloop:
|
|
call dly64 ; arbitrary delay
|
|
djnz dlyloop ; loop based on cpu speed
|
|
;
|
|
; Next pitch value
|
|
ld hl,(pitch) ; get current pitch
|
|
inc hl ; increment
|
|
ld (pitch),hl ; save new value
|
|
ld a,h ; get high byte
|
|
;cp 16 ; end of max range?
|
|
cp 4 ; end of max range?
|
|
jr nz,pitloop ; loop till done
|
|
;
|
|
; Clean up
|
|
call clrpsg ; shut down psg
|
|
;
|
|
ret ; done
|
|
;
|
|
; Clear PSG registers to default
|
|
;
|
|
clrpsg:
|
|
ld b,16 ; loop for 18 registers
|
|
ld c,0 ; init register index
|
|
clrpsg1:
|
|
ld a,c ; register num to accum
|
|
out (rsel),a ; select it
|
|
xor a ; clear accum
|
|
out (rdat),a ; and write to register
|
|
inc c ; next register
|
|
djnz clrpsg1 ; loop through all registers
|
|
ret ; return
|
|
;
|
|
; Program PSG registers from list at HL
|
|
;
|
|
setpsg:
|
|
ld a,(hl) ; get psg reg number
|
|
inc hl ; bump index
|
|
cp $FF ; check for end
|
|
ret z ; return if end marker $FF
|
|
out (rsel),a ; select psg register
|
|
ld a,(hl) ; get register value
|
|
inc hl ; bump index
|
|
out (rdat),a ; set register value
|
|
jr setpsg ; loop till done
|
|
;
|
|
; Short delay functions. No clock speed compensation, so they
|
|
; will run longer on slower systems. The number indicates the
|
|
; number of call/ret invocations. A single call/ret is
|
|
; 27 t-states on a z80, 25 t-states on a z180
|
|
;
|
|
dly256: call dly128
|
|
dly128: call dly64
|
|
dly64: call dly32
|
|
dly32: call dly16
|
|
dly16: call dly8
|
|
dly8: call dly4
|
|
dly4: call dly2
|
|
dly2: call dly1
|
|
dly1: ret
|
|
;
|
|
;=============================================================================
|
|
; Data Section
|
|
;=============================================================================
|
|
;
|
|
chan .db 0 ; active audio channel
|
|
pitch .dw 0 ; current pitch
|
|
;
|
|
banner .text "\r\nRetroBrew Computers SCG AY-3-8910 Sound Test\r\n"
|
|
.text "Set SCG board base I/O address to 0x98\r\n$"
|
|
chmsg .text "\r\nPlaying descending tones on channel $"
|
|
chmsg2 .text "...$"
|
|
crlf .text "\r\n$"
|
|
;
|
|
stksav .dw 0 ; saved stack frame
|
|
.fill 80,$FF ; 40 level private stack
|
|
stack .equ $ ; start of stack
|
|
;
|
|
.end
|