1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-02-11 01:31:03 +00:00

Gace up and switch to interrupts

This commit is contained in:
dschmenk 2017-10-23 15:03:40 -07:00
parent a28083c8e2
commit 11c1b032cb
2 changed files with 173 additions and 86 deletions

View File

@ -1,5 +1,6 @@
const inbuff = $200 const inbuff = $200
const freemem = $0002 const freemem = $0002
const timerInc = $0006
const iobuffer = $1C00 const iobuffer = $1C00
const NMACROS = 7 const NMACROS = 7
const FALSE = 0 const FALSE = 0
@ -152,8 +153,63 @@ asm psgWrite(pVIA, reg, val)#0
RTS RTS
end end
// //
// MockingBoard IRQ handler
//
asm mbIRQ#0
CLD
BIT $C404 ; CLEAR IRQ
INC $06 ; FLAG FOR PLASMA CODE
CLC
RTS
end
//
// CALL PRODOS
//
asm syscall(cmd, params)
SEI
LDA ESTKL,X
LDY ESTKH,X
STA PARAMS
STY PARAMS+1
INX
LDA ESTKL,X
STA CMD
JSR $BF00
CMD: !BYTE 00
PARAMS: !WORD 0000
LDY #$00
STA ESTKL,X
STY ESTKH,X
CLI
RTS
end
//
// Utility routines // Utility routines
// //
asm getStatus#1
PHP
PLA
DEX
STA ESTKL,X
LDA #$00
STA ESTKH,X
RTS
end
asm setStatus(stat)#0
LDA ESTKL,X
PHA
PLP
DEX
RTS
end
asm disableInts#0
SEI
RTS
end
asm enableInts#0
CLI
RTS
end
asm putc#0 asm putc#0
LDA ESTKL,X LDA ESTKL,X
INX INX
@ -163,7 +219,6 @@ end
def putln#0 def putln#0
putc($0D) putc($0D)
end end
def puts(str)#0 def puts(str)#0
byte i byte i
@ -213,6 +268,24 @@ end
// return val // return val
//end //end
// //
// MB interrupt install
//
def mbInstallIRQ#0
byte params[4]
params.0 = 2
params.1 = 1
params:2 = @mbIRQ
syscall($40, @params)
end
def mbUninstallIRQ#0
byte params[2]
params.0 = 1
params.1 = 1
syscall($41, @params)
end
//
// Search slots for MockingBoard // Search slots for MockingBoard
// //
def mbTicklePSG(pVIA) def mbTicklePSG(pVIA)
@ -262,16 +335,6 @@ def mbSearch
return 0 return 0
end end
def psgSetup(pVIA) def psgSetup(pVIA)
//
// Set up the VIA1 (enulators only support Timer1 on first 6522)
//
if pVIA == mbVIA1
pVIA->IER = $7F // Mask all interrupts
pVIA=>T1L = $F9C2 // 16 Ints/sec
pVIA=>T1C = $F9C2 // 16 Ints/sec
pVIA->ACR = $40 // Continuos T1 interrupts
pVIA->IFR = $40 // Clear interrupt
fin
psgWrite(pVIA, MIXER, $00) // Turn everything off psgWrite(pVIA, MIXER, $00) // Turn everything off
psgWrite(pVIA, AENVAMP, $00) psgWrite(pVIA, AENVAMP, $00)
psgWrite(pVIA, BENVAMP, $00) psgWrite(pVIA, BENVAMP, $00)
@ -286,7 +349,7 @@ def psgSetup(pVIA)
end end
def mbSequence(track)#0 def mbSequence(track)#0
word seqEvent, seqTime, eventTime, updateTime, period, n word seqEvent, seqTime, eventTime, updateTime, period, n
byte numNotes, note, volume, channel, i, overflow byte numNotes, note, volume, channel, i, overflow, cpuFlags
byte indexA[2], indexB[2], indexC[2] byte indexA[2], indexB[2], indexC[2]
byte noteA[2], noteB[2], noteC[2] byte noteA[2], noteB[2], noteC[2]
word notes1[MAX_CHAN_NOTES], notes2[MAX_CHAN_NOTES] word notes1[MAX_CHAN_NOTES], notes2[MAX_CHAN_NOTES]
@ -319,94 +382,110 @@ def mbSequence(track)#0
// //
seqTime = 0 seqTime = 0
seqEvent = track seqEvent = track
eventTime = seqTime + seqEvent->deltatime eventTime = seqEvent->deltatime
updateTime = ARPEGGIO updateTime = ARPEGGIO
numNotes = 0 numNotes = 0
overflow = 0 overflow = 0
//
// Enable timer IRQ
//
cpuFlags = getStatus
mbVIA1->IER = $7F // Mask all interrupts
(@mbIRQ).3 = mbVIA1.1 // Relocate IRQ 6522 address
^timerInc = 0 // Clear timer increment
mbInstallIRQ
mbVIA1->ACR = $40 // Continuos T1 interrupts
mbVIA1=>T1L = $F9C2 // 16 Ints/sec
mbVIA1=>T1C = $F9C2 // 16 Ints/sec
mbVIA1->IFR = $40 // Clear interrupt
mbVIA1->IER = $C0 // Enable Timer1 interrupt
enableInts
repeat repeat
//puts("seqTime = "); puti(seqTime); puts(" eventTime = "); puti(eventTime); putln //puts("seqTime = "); puti(seqTime); puts(" eventTime = "); puti(eventTime); putln
while eventTime == seqTime if eventTime <= seqTime
note = seqEvent->percnote repeat
if note & $80 note = seqEvent->percnote
// if note & $80
// Note event
//
volume = seqEvent->perchanvol
channel = (volume & mbVIA2.LSB) >> 7 // Clever - mbVIA2.0 will be $80 if it exists
if volume & $0F
// //
// Note on // Note event
// //
for i = 0 to MAX_CHAN_NOTES-1 volume = seqEvent->perchanvol
channel = (volume & mbVIA2.LSB) >> 7 // Clever - mbVIA2.0 will be $80 if it exists
if volume & $0F
// //
// Look for available slot in active note table // Note on
// //
if !notes[channel, i].LSB //or notes[channel, i] == note for i = 0 to MAX_CHAN_NOTES-1
break //
// Look for available slot in active note table
//
if !notes[channel, i].LSB //or notes[channel, i] == note
break
fin
next
//
// Full note table, kick one out
//
if i == MAX_CHAN_NOTES
i = overflow
overflow = (overflow + 1) % MAX_CHAN_NOTES
//puts("Full note table on channel: "); puti(channel); putln
else
numNotes++
fin fin
next notes[channel, i] = note | (volume << 8)
// periods[channel, i] = mbOctave0[note & $0F] >> ((note >> 4) & $07)
// Full note table, kick one out //puts("Insert note ");puti((note>>4)&$7);putc(':');puti(note&$0F)
// //puts(" in table[");puti(channel);putc(',');puti(i);puts("]\n")
if i == MAX_CHAN_NOTES
i = overflow
overflow = (overflow + 1) % MAX_CHAN_NOTES
//puts("Full note table on channel: "); puti(channel); putln
else else
numNotes++ //
// Note off
//
for i = 0 to MAX_CHAN_NOTES-1
//
// Remove from active note table
//
if notes[channel, i].LSB == note
notes[channel, i] = 0
numNotes--
break
fin
next
//puts("Remove note ");puti((note>>4)&$7);putc(':');puti(note&$0F)
//puts(" from table[");puti(channel);putc(',');puti(i);puts("]\n")
fin fin
notes[channel, i] = note | (volume << 8) updateTime = seqTime
periods[channel, i] = mbOctave0[note & $0F] >> ((note >> 4) & $07)
//puts("Insert note ");puti((note>>4)&$7);putc(':');puti(note&$0F)
//puts(" in table[");puti(channel);putc(',');puti(i);puts("]\n")
else else
// //
// Note off // Percussion event
// //
for i = 0 to MAX_CHAN_NOTES-1 period = seqEvent->perchanvol
// if period
// Remove from active note table psgWrite(mbVIA1, MIXER, $1C) // NG on C, Tone on B, A
// psgWrite(mbVIA1, CENVAMP, $10)
if notes[channel, i].LSB == note psgWrite(mbVIA1, NGFREQ, note)
notes[channel, i] = 0 psgWrite(mbVIA1, ENVPERIOD+1, period)
numNotes-- psgWrite(mbVIA1, ENVSHAPE, $00) // Single decay
break if mbVIA2
psgWrite(mbVIA2, MIXER, $1C) // NG on C, Tone on B, A
psgWrite(mbVIA2, CENVAMP, $10)
psgWrite(mbVIA2, NGFREQ, note)
psgWrite(mbVIA2, ENVPERIOD+1, period)
psgWrite(mbVIA2, ENVSHAPE, $00) // Single decay
fin fin
next else
//puts("Remove note ");puti((note>>4)&$7);putc(':');puti(note&$0F) eventTime = -1
//puts(" from table[");puti(channel);putc(',');puti(i);puts("]\n") break
fin
updateTime = seqTime
else
//
// Percussion event
//
period = seqEvent->perchanvol
if period
psgWrite(mbVIA1, MIXER, $1C) // NG on C, Tone on B, A
psgWrite(mbVIA1, CENVAMP, $10)
psgWrite(mbVIA1, NGFREQ, note)
psgWrite(mbVIA1, ENVPERIOD+1, period)
psgWrite(mbVIA1, ENVSHAPE, $00) // Single decay
if mbVIA2
psgWrite(mbVIA2, MIXER, $1C) // NG on C, Tone on B, A
psgWrite(mbVIA2, CENVAMP, $10)
psgWrite(mbVIA2, NGFREQ, note)
psgWrite(mbVIA2, ENVPERIOD+1, period)
psgWrite(mbVIA2, ENVSHAPE, $00) // Single decay
fin fin
else
eventTime = -1
break
fin fin
fin //
// // Next event
// Next event //
// seqEvent = seqEvent + t_event
seqEvent = seqEvent + t_event eventTime = eventTime + seqEvent->deltatime
eventTime = seqTime + seqEvent->deltatime until seqEvent->deltatime
loop fin
if updateTime == seqTime if updateTime <= seqTime
// //
// Time slice active note tables (arpeggio) // Time slice active note tables (arpeggio)
// //
@ -469,15 +548,23 @@ def mbSequence(track)#0
// //
// Increment time tick // Increment time tick
// //
seqTime++ //seqTime++
if updateTime < seqTime; updateTime = seqTime; fin //if updateTime < seqTime; updateTime = seqTime; fin
while !(mbVIA1->IFR & $40) // Wait for T1 interrupt while !(^timerInc)
//while !(mbVIA1->IFR & $40) // Wait for T1 interrupt
if ^$C000 > 127; eventTime = -1; ^$C010; break; fin if ^$C000 > 127; eventTime = -1; ^$C010; break; fin
loop loop
mbVIA1->IFR = $40 // Clear interrupt seqTime = seqTime + ^timerInc
^timerInc = 0
//mbVIA1->IFR = $40 // Clear interrupt
until eventTime < 0 until eventTime < 0
psgWrite(mbVIA1, MIXER, $FF) // Turn everything off psgWrite(mbVIA1, MIXER, $FF) // Turn everything off
psgWrite(mbVIA1, AENVAMP, $00)
psgWrite(mbVIA1, BENVAMP, $00)
psgWrite(mbVIA1, CENVAMP, $00) psgWrite(mbVIA1, CENVAMP, $00)
mbVIA1->IER = $7F // Mask all interrupts
setStatus(cpuFlags))
mbUninstallIRQ
if mbVIA2 if mbVIA2
psgWrite(mbVIA2, MIXER, $FF) psgWrite(mbVIA2, MIXER, $FF)
psgWrite(mbVIA2, CENVAMP, $00) psgWrite(mbVIA2, CENVAMP, $00)

Binary file not shown.