mirror of
https://github.com/dschmenk/PLASMA.git
synced 2024-08-21 06:29:07 +00:00
Add MockingBoard select options and Apple /// support
This commit is contained in:
parent
be5dfdba4b
commit
14fabc1467
@ -48,6 +48,10 @@ struc t_PSG
|
||||
byte ENVSHAPE // Envelope Shape
|
||||
end
|
||||
//
|
||||
// Apple III hardware constants.
|
||||
//
|
||||
const ENV_REG = $FFDF
|
||||
//
|
||||
// Sequence event
|
||||
//
|
||||
struc t_event
|
||||
@ -60,10 +64,17 @@ end
|
||||
//
|
||||
predef musicPlay(track, rept)#0
|
||||
predef musicStop#0
|
||||
predef spkrSequence(yield, func)#0
|
||||
predef a2spkrTone(pitch, duration)#0
|
||||
predef a2spkrPWM(sample, speed, len)#0
|
||||
//
|
||||
// Static sequencer values
|
||||
//
|
||||
export word musicSequence
|
||||
export word musicSequence = @spkrSequence
|
||||
export word spkrTone = @a2spkrTone
|
||||
export word spkrPWM = @a2spkrPWM
|
||||
|
||||
word instr[] // Overlay with other variables
|
||||
word seqTrack, seqEvent, seqTime, eventTime, updateTime
|
||||
byte numNotes, seqRepeat
|
||||
byte indexA[2], indexB[2], indexC[2]
|
||||
@ -76,8 +87,8 @@ word periods[2] = @periods1, @periods2
|
||||
// MockingBoard data.
|
||||
//
|
||||
word[] mbVIAs // Treat this as an array of VIA ptrs
|
||||
word mbVIA1 = -1 // Init to "discover MockingBoard flag" value
|
||||
word mbVIA2 = 0
|
||||
word mbVIA1, mbVIA2
|
||||
word mbSlot = -1
|
||||
//
|
||||
// Octave basis frequency periods (starting at MIDI note #12)
|
||||
// Notes will be encoded as basis note (LSNibble) and octave (MSNibble))
|
||||
@ -203,7 +214,7 @@ end
|
||||
//
|
||||
// Apple II speaker tone generator routines
|
||||
//
|
||||
export asm spkrTone(pitch, duration)#0
|
||||
asm a2spkrTone(pitch, duration)#0
|
||||
STX ESP
|
||||
LDY ESTKH,X
|
||||
LDA ESTKL,X
|
||||
@ -277,7 +288,7 @@ TONEXIT PLP
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
export asm spkrPWM(sample, speed, len)#0
|
||||
asm a2spkrPWM(sample, speed, len)#0
|
||||
STX ESP
|
||||
LDY ESTKH,X
|
||||
LDA ESTKL,X
|
||||
@ -317,6 +328,22 @@ export asm spkrPWM(sample, speed, len)#0
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
def a3spkrTone(pitch, duration)#0
|
||||
byte env
|
||||
|
||||
env = ^ENV_REG
|
||||
^ENV_REG = env | $C0
|
||||
a2spkrTone(pitch, duration)
|
||||
^ENV_REG = env
|
||||
end
|
||||
def a3spkrPWM(sample, speed, len)#0
|
||||
byte env
|
||||
|
||||
env = ^ENV_REG
|
||||
^ENV_REG = env | $C0
|
||||
a2spkrPWM(sample, speed, len)
|
||||
^ENV_REG = env
|
||||
end
|
||||
//
|
||||
// Search slots for MockingBoard
|
||||
//
|
||||
@ -344,25 +371,27 @@ def mbTicklePSG(pVIA)
|
||||
return 0
|
||||
end
|
||||
def mbSearch(slot)
|
||||
if slot
|
||||
mbVIA1 = mbTicklePSG($C000 + (slot << 8))
|
||||
if mbVIA1
|
||||
mbVIA2 = mbTicklePSG(mbVIA1 + $80)
|
||||
return slot
|
||||
fin
|
||||
else
|
||||
for slot = 1 to 7
|
||||
if slot == 3 or slot == 6
|
||||
continue
|
||||
fin
|
||||
if MACHID <> $F2 and slot >= 0 and slot <= 7// Apple 3
|
||||
if slot
|
||||
mbVIA1 = mbTicklePSG($C000 + (slot << 8))
|
||||
if mbVIA1
|
||||
mbVIA2 = mbTicklePSG(mbVIA1 + $80)
|
||||
return slot
|
||||
fin
|
||||
next
|
||||
else
|
||||
for slot = 1 to 7
|
||||
if slot == 3 or slot == 6
|
||||
continue
|
||||
fin
|
||||
mbVIA1 = mbTicklePSG($C000 + (slot << 8))
|
||||
if mbVIA1
|
||||
mbVIA2 = mbTicklePSG(mbVIA1 + $80)
|
||||
return slot
|
||||
fin
|
||||
next
|
||||
fin
|
||||
fin
|
||||
return 0
|
||||
return -1
|
||||
end
|
||||
def psgSetup(pVIA)#0
|
||||
psgWrite(pVIA, MIXER, $3F) // Turn everything off
|
||||
@ -672,7 +701,7 @@ def spkrSequence(yield, func)#0
|
||||
if numNotes > 1
|
||||
for i = 0 to MAX_SPKR_NOTES-1
|
||||
if notes1[i]
|
||||
spkrTone(periods1[i], arpeggioDuration[numNotes])
|
||||
spkrTone(periods1[i], arpeggioDuration[numNotes])#0
|
||||
fin
|
||||
*rndseed++
|
||||
next
|
||||
@ -688,7 +717,7 @@ def spkrSequence(yield, func)#0
|
||||
next
|
||||
duration = eventTime - seqTime
|
||||
seqTime = duration + seqTime
|
||||
spkrTone(period, DUR16TH * duration)
|
||||
spkrTone(period, DUR16TH * duration)#0
|
||||
fin
|
||||
if ^$C000 > 127; return; fin
|
||||
if yieldTime <= seqTime; func()#0; yieldTime = seqTime + yield; fin
|
||||
@ -709,7 +738,7 @@ def noSequence(yield, func)#0
|
||||
seqTime++
|
||||
if seqTime < 0; seqTime = 1; fin // Capture wrap-around
|
||||
*rndseed++
|
||||
spkrTone(0, DUR16TH) // Waste 16th of a second playing silence
|
||||
a2spkrTone(0, DUR16TH) // Waste 16th of a second playing silence
|
||||
if ^$C000 > 127; return; fin
|
||||
if yield == seqTime; func()#0; seqTime = 0; fin
|
||||
until FALSE
|
||||
@ -721,22 +750,17 @@ export def musicPlay(track, rept)#0
|
||||
byte i
|
||||
|
||||
//
|
||||
// First time search for MockingBoard
|
||||
// Select proper sequencer based on hardware
|
||||
//
|
||||
if mbVIA1 == -1
|
||||
if !mbSearch(0)
|
||||
//
|
||||
// No MockingBoard - scale octave0 for speaker
|
||||
//
|
||||
for i = 0 to 11
|
||||
spkrOctave0[i] = mbOctave0[i]/NOTEDIV
|
||||
next
|
||||
fin
|
||||
if mbSlot > 0
|
||||
musicSequence = @mbSequence
|
||||
else
|
||||
musicSequence = @spkrSequence
|
||||
fin
|
||||
//
|
||||
// Zero out active notes
|
||||
//
|
||||
for i = 0 to MAX_MBCH_NOTES-1; notes1[i] = 0; notes2[i] = 0; next
|
||||
for i = 0 to MAX_MBCH_NOTES-1; notes1[i] = 0; notes2[i] = 0; next
|
||||
for i = 0 to MAX_MBCH_NOTES-1; periods1[i] = 0; periods2[i] = 0; next
|
||||
//
|
||||
// Start sequencing
|
||||
@ -747,14 +771,6 @@ export def musicPlay(track, rept)#0
|
||||
seqTime = 0
|
||||
eventTime = seqEvent->deltatime
|
||||
numNotes = 0
|
||||
//
|
||||
// Select proper sequencer based on hardware
|
||||
//
|
||||
if mbVIA1
|
||||
musicSequence = @mbSequence
|
||||
else
|
||||
musicSequence = @spkrSequence
|
||||
fin
|
||||
end
|
||||
//
|
||||
// Stop sequencing music track
|
||||
@ -772,6 +788,36 @@ export def musicGetKey(yield, backgroundProc)#1
|
||||
^$C010
|
||||
return ^$C000
|
||||
end
|
||||
|
||||
when MACHID & MACHID_MODEL
|
||||
is MACHID_III
|
||||
spkrTone = @a3spkrTone
|
||||
spkrPWM = @a3spkrPWM
|
||||
break
|
||||
is MACHID_I
|
||||
puts("Sound unsupported.\n")
|
||||
return -1
|
||||
break
|
||||
otherwise
|
||||
puts("MockingBoars Slot:\n")
|
||||
puts("ENTER = None\n")
|
||||
puts("0 = Scan\n")
|
||||
puts("1-7 = Slot #\n")
|
||||
instr = gets('>'|$80)
|
||||
if ^instr
|
||||
mbSlot = mbSearch(^(instr + 1) - '0')
|
||||
fin
|
||||
if mbSlot < 0
|
||||
//
|
||||
// No MockingBoard - scale octave0 for speaker
|
||||
//
|
||||
for instr = 0 to 11
|
||||
spkrOctave0[instr] = mbOctave0[instr]/NOTEDIV
|
||||
next
|
||||
fin
|
||||
break
|
||||
wend
|
||||
|
||||
done
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -805,13 +851,13 @@ musicGetKey(yieldtime, yieldproc)
|
||||
The low level internal speaker routines used to generate tones and waveforms
|
||||
can be called for warnings, sound effects, etc:
|
||||
|
||||
spkrTone(period, duration)
|
||||
spkrTone(period, duration)#0
|
||||
Play a tone
|
||||
Params:
|
||||
(1020000 / 64 / period) Hz
|
||||
(duration * 32 * 256 / 1020000) seconds
|
||||
|
||||
spkrPWM(samples, speed, len)
|
||||
spkrPWM(samples, speed, len)#0
|
||||
Play a Pulse Width Modulated waveform
|
||||
Params:
|
||||
Pointer to 8 bit pulse width samples
|
||||
|
Loading…
Reference in New Issue
Block a user