Remove some debug code. Chain the speech interrupt handler with the usual cc65 one since I can't seem to get the cc65 IRQ mechanism to work. General cleanup of the assembly code.

This commit is contained in:
Jeremy Rand 2016-12-14 23:56:00 -05:00
parent 1f25311a93
commit 80cabff983
3 changed files with 133 additions and 113 deletions

View File

@ -13,10 +13,9 @@
extern uint8_t *speechData;
extern uint16_t speechLen;
extern uint8_t speechBusy;
extern uint16_t outptr;
extern uint16_t endptr;
extern void setupSpeech(void);
extern void unsetupSpeech(void);
#endif /* speech_h */

View File

@ -7,139 +7,169 @@
;
.export _setupSpeech, _speechData, _speechLen, _speechBusy
.export _outptr, _endptr
; .interruptor speechIRQ
.export _setupSpeech, _unsetupSpeech
.export _speechData, _speechLen, _speechBusy
OUTPTR := $FB ;START OF DATA POINTER
IRQL := $03FE ;INTERRUPT VECTOR, LOW BYTE
IRQH := $03FF ;INTERRUPT VECTOR, HIGH BYTE
BASE := $C440 ;FIRST SPEECH CHIP
DURPHON := BASE ;REGISTER 0 OF SPEECH CHIP
INFLECT := BASE+$01 ;REGISTER 1 OF SPEECH CHIP
RATEINF := BASE+$02 ;REGISTER 2 OF SPEECH CHIP
CTTRAMP := BASE+$03 ;REGISTER 3 OF SPEECH CHIP
FILFREQ := BASE+$04 ;REGISTER 4 OF SPEECH CHIP
TMPPTR := $FB ; Temporary pointer used in interrupt handler
IRQL := $03FE ; Interrupt vector, low byte
IRQH := $03FF ; Interrupt vector, high byte
BASE := $C440 ; First speech chip
DURPHON := BASE ; Register 0 of speech chip
INFLECT := BASE+$01 ; Register 1 of speech chip
RATEINF := BASE+$02 ; Register 2 of speech chip
CTTRAMP := BASE+$03 ; Register 3 of speech chip
FILFREQ := BASE+$04 ; Register 4 of speech chip
DDRB := $C402
DDRA := $C403
PCR := $C48C ;PERIPHERAL CONTROL REG-6522
IFR := $C48D ;INTERRUPT FLAG REG-6522
PCR := $C48C ; Peripheral control register, 6522
IFR := $C48D ; Interrupt flag register, 6522
IER := $C48E
.DATA
speechIRQ: .byte $60, <_interr, >_interr ; RTS plus two dummy bytes
_speechData: .byte $00, $00
_speechLen: .byte $00, $00
_outptr: .byte $00, $00
_endptr: .byte $00, $00
_speechBusy: .byte $00
_irqLandingPad: .byte $4C, $00, $00
.CODE
.proc _setupSpeech
SEI ;DISABLE INTERRUPTS
LDA #<_interr ;SET INTERRUPT VECTOR
STA IRQL ;TO POINT TO INTERRUPT
LDA #>_interr ;SERVICE ROUTINE
STA IRQH
; LDA #$4C ; JMP opcode
; STA speechIRQ
LDA #$00
STA DDRA
STA DDRB
sei ; Disable interrupts
LDA _speechData+1 ;GET HIGH ADDRESS OF DATA
STA OUTPTR+1 ;STORE IN WORK POINTER
LDA _speechData ;GET LOW ADDRESS OF DATA
STA OUTPTR ;STORE LOW BYTE
lda IRQL ; Store the old interrupt vector
sta _irqLandingPad+1
lda IRQH
sta _irqLandingPad+2
LDA _speechLen+1 ;GET HIGH LENGTH BYTE
CLC
ADC _speechData+1 ;AND ADD TO BASE ADDRESS
STA _endptr+1 ;STORE END ADDRESS
LDA _speechLen ;GET LOW LENGTH BYTE
CLC
ADC _speechData ;AND ADD TO BASE ADDRESS
BCC @L2 ;CHECK FOR PAGE BOUNDARY
INC _endptr+1
lda #<_interr ; Set interrupt vector
sta IRQL ; to point to interrupt
lda #>_interr ; service routine
sta IRQH
lda #$00
sta DDRA
sta DDRB
lda _speechData+1 ; Get high address of data
sta _outptr+1 ; Store in work pointer
lda _speechData ; Get low address of data
sta _outptr ; Store low byte
lda _speechLen+1 ; Get high length byte
clc
adc _speechData+1 ; And add to base address
sta _endptr+1 ; Store end address
lda _speechLen ; Get low length byte
clc
adc _speechData ; And add to base address
bcc @L2 ; Check for page boundary
inc _endptr+1
@L2:
STA _endptr ;STORE END ADDRESS
sta _endptr ; Store end address
LDA #$FF ;SET BUSY FLAG
STA _speechBusy ;AND SET PERIPHERAL CONTROL
LDA #$0C ;REGISTER TO RECOGNIZE
STA PCR ;SIGNAL FROM SPEECH CHIP
LDA #$80 ;RAISE CTRL BIT IN REGISTER 3
STA CTTRAMP
LDA #$C0 ;SET TRANSITIONED INFLECTION
STA DURPHON ;MODE IN REGISTER 0
LDA #$70 ;LOWER CTRL BIT
STA CTTRAMP
LDA #$82 ;ENABLE 6522 INTERRUPTS
STA IER
CLI ;CLEAR INTERRUPT MASK
RTS ;RETURN TO CALLER
lda #$FF ; Set busy flag
sta _speechBusy ; And set peripheral control
lda #$0C ; Register to recognize
sta PCR ; Signal from speech chip
lda #$80 ; Raise control bit in register 3
sta CTTRAMP
lda #$C0 ; Set transitioned inflection
sta DURPHON ; Mode in register 0
lda #$70 ; Lower control bit
sta CTTRAMP
lda #$82 ; Enable 6522 interrupts
sta IER
cli ; Clear interrupt mask
rts ; Return to caller
.endproc
.proc _unsetupSpeech
sei ; Restore the old interrupt vector
lda _irqLandingPad+1
sta IRQL
lda _irqLandingPad+2
sta IRQH
cli
rts
.endproc
.proc _interr
PHA
TXA ;SAVE REGISTERS
PHA
TYA
PHA
LDA IFR
BPL @L2
LDA #$02 ;CLEAR INTERRUPT FLAG
STA IFR
LDY #$00 ;INIT REGISTERS
LDX #$04
LDA OUTPTR+1
CMP _endptr+1
BCC @L1
BNE @L5
LDA OUTPTR ;CHECK FOR END OF DATA FILE
CMP _endptr
BCC @L1 ;IF NOT THEN CONTINUE
pha ; Save accumulator
lda IFR
bmi @L4 ; If we have 6522 interrupt jump to L4
pla ; Otherwise restore the accumulator
jmp _irqLandingPad ; And jump to the old interrupt handler
@L4:
txa ; Save other registers
pha
tya
pha
lda #$02 ; Clear interrupt flag
sta IFR
ldy #$00 ; Init registers
ldx #$04
lda _outptr+1
cmp _endptr+1
bcc @L1
bne @L5
lda _outptr ; Check for end of data file
cmp _endptr
bcc @L1 ; If not, then continue
@L5:
LDA #$00 ;IF END, TURN EVERYTHING OFF
STA DURPHON ;STORE PAUSE PHONEME
LDA #$70 ;ZERO AMPLITUDE
STA CTTRAMP
LDA #$00 ;CLEAR BUSY FLAG
STA _speechBusy
LDA #$02 ;CLEAR INTERRUPT ENABLE
STA IER ;IN 6522
LDA #$FF
STA DDRA
LDA #$07
STA DDRB
lda #$00 ; If end, turn everything off
sta DURPHON ; Store pause phoneme
lda #$70 ; Zero amplitude
sta CTTRAMP
lda #$00 ; Clear busy flag
sta _speechBusy
lda #$02 ; Clear interrupt enable
sta IER ; In 6522
lda #$FF
sta DDRA
lda #$07
sta DDRB
@L2:
LDA OUTPTR
STA _outptr
LDA OUTPTR+1
STA _outptr+1
PLA ;RESTORE REGISTERS
TAY
PLA
TAX
PLA
RTI ;RETURN FROM INTERRUPT
pla ; Restore registers
tay
pla
tax
pla
rti ; Return from interrupt
@L1:
LDA (OUTPTR),Y ;GET DATA
STA BASE,X ;STORE IN SPEECH CHIP
INC OUTPTR ;NEXT DATA
BNE @L3
INC OUTPTR+1
lda TMPPTR ; Save the value in the tmp pointer
pha
lda TMPPTR+1
pha
lda _outptr ; Move the _outptr into the tmp pointer
sta TMPPTR
lda _outptr+1
sta TMPPTR+1
@L6:
lda (TMPPTR),Y ; Get data
sta BASE,X ; Store in speech chip
inc TMPPTR ; Next data
bne @L3
inc TMPPTR+1
@L3:
DEX ;NEXT REGISTER
CPX #$FF ;LAST REGISTER?
BNE @L1 ;NO, CONTINUE
BEQ @L2 ;YES, RETURN
dex ; Next register
cpx #$FF ; Last register?
bne @L6 ; No, then continue
lda TMPPTR ; We are done, move tmp pointer to _outptr
sta _outptr
lda TMPPTR+1
sta _outptr+1
pla ; Restore the tmp pointer
sta TMPPTR+1
pla
sta TMPPTR
jmp @L2 ; Finish the interrupt handler
.endproc

View File

@ -15,15 +15,6 @@
bool speechIsBusy(void)
{
static uint16_t old_outptr = 0;
if (old_outptr == 0) {
printf("endptr=%x\n", endptr);
}
if (old_outptr != outptr) {
old_outptr = outptr;
printf("%x ", old_outptr);
}
//printf("busy=0x%x, outptr=0x%x, endptr=0x%x\n", speechBusy, outptr, endptr);
return (speechBusy != 0);
}