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 uint8_t *speechData;
extern uint16_t speechLen; extern uint16_t speechLen;
extern uint8_t speechBusy; extern uint8_t speechBusy;
extern uint16_t outptr;
extern uint16_t endptr;
extern void setupSpeech(void); extern void setupSpeech(void);
extern void unsetupSpeech(void);
#endif /* speech_h */ #endif /* speech_h */

View File

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

View File

@ -15,15 +15,6 @@
bool speechIsBusy(void) 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); return (speechBusy != 0);
} }