ssi263: simple example

This commit is contained in:
Vince Weaver 2021-09-14 10:16:53 -04:00
parent 52341497ac
commit f7e27b176f
3 changed files with 319 additions and 2 deletions

View File

@ -6,10 +6,11 @@ EMPTY_DISK = ../../empty_disk/empty.dsk
all: speech.dsk
speech.dsk: HELLO SSI263_TEST
speech.dsk: HELLO SSI263_TEST TROGDOR
cp $(EMPTY_DISK) speech.dsk
$(DOS33) -y speech.dsk SAVE A HELLO
$(DOS33) -y speech.dsk BSAVE -a 0x1000 SSI263_TEST
$(DOS33) -y speech.dsk BSAVE -a 0x1000 TROGDOR
###
@ -21,6 +22,15 @@ ssi263_test.o: ssi263_test.s ssi263.inc ssi263_detect.s ssi263_speech.s
###
TROGDOR: trogdor.o
ld65 -o TROGDOR trogdor.o -C ../../linker_scripts/apple2_1000.inc
trogdor.o: trogdor.s ssi263.inc ssi263_detect.s ssi263_simple_speech.s
ca65 -o trogdor.o trogdor.s -l trogdor.lst
###
HELLO: hello.bas
$(TOKENIZE) < hello.bas > HELLO
@ -28,6 +38,6 @@ HELLO: hello.bas
####
clean:
rm -f *~ *.o *.lst HELLO SSI263_TEST
rm -f *~ *.o *.lst HELLO SSI263_TEST TROGDOR

View File

@ -0,0 +1,231 @@
; Simple speech routine for ssi-263
; to save space we only change the Phoneme/Delay each time, we don't
; mess with the other registers
;========================
; ssi263_write_chip
;========================
ssi263_write_chip:
wc_smc1:
sta $C000,X
rts
;========================
; read_chip
;========================
ssi263_read_chip:
rc_smc1:
lda $C000,X
rts
;========================
; ssi263_speech_init
;========================
; A = slot number of mockingboard
ssi263_speech_init:
sei ; disable interrupts
and #$7
ora #$c0 ; turn slot number into address
sta wc_smc1+2 ; update the read/write routines
sta rc_smc1+2
lda #<ssi263_speech_irq ; point IRQ handler to our code
sta $3fe
lda #>ssi263_speech_irq
sta $3ff
; set defaults
; filter frequency
lda #$E9
ldx #SSI263_F
jsr ssi263_write_chip
; control / articulation/ amplitude
lda #$5C
ldx #SSI263_CAA
jsr ssi263_write_chip
; rate/inflection
lda #$A8
ldx #SSI263_RI
jsr ssi263_write_chip
; inflection
lda #$50
ldx #SSI263_I
jsr ssi263_write_chip
cli ; enable interrupts
rts
;============================
; ssi263_speech_shutdown
;============================
ssi263_speech_shutdown:
sei
rts
;=========================
; ssi263_speak
;=========================
; pointer to data in SPEECH_PTRL/H
ssi263_speak:
sei ; disable interrupts
; Set the busy flag
lda #$FF
sta speech_busy
; Set peripheral control register to recognize the signal from the
; speech chip.
lda #(VIA6522_PCR2_CA2_LOW|VIA6522_PCR2_CA1_NEG)
ldx #VIA6522_PCR2
jsr ssi263_write_chip
; Set transitioned inflection by setting value while toggling CTL
lda #SSI263_CAA_CTL
ldx #SSI263_CAA
jsr ssi263_write_chip
; Set transitioned inflection mode in register 0
lda #SSI263_DRP_TRANSITIONED_INFLECTION
ldx #SSI263_DRP
jsr ssi263_write_chip
; Lower control bit
lda #$70 ; also T=7
ldx #SSI263_CAA
jsr ssi263_write_chip
; Enable 6522 interrupts
lda #(VIA6522_IER2_SET|VIA6522_IER2_CA1)
ldx #VIA6522_IER2
jsr ssi263_write_chip
cli ; re-enable interrupts
rts
;====================
; speech interrupt
;====================
ssi263_speech_irq:
php ; save flags
cld
pha ; save A
txa
pha ; save X
tya
pha ; save Y
inc $0404 ; irq indicator on screen
; be sure it was a 6522#2 interrupt
ldx #VIA6522_IFR2
jsr ssi263_read_chip
bmi have_interrupt
; wasn't us, return to caller
; this assumes we can handle multiple interrupt sources
jmp end_interrupt
have_interrupt:
; Clear the 6522#2 CA interrupt flag
lda #VIA6522_IFR2_CA1
ldx #VIA6522_IFR2
jsr ssi263_write_chip
; Check if done with speech
ldy #0
lda (SPEECH_PTRL),Y
cmp #$ff
beq speech_end
not_end:
; Set the speech playing flag
lda #$ff
sta speech_playing
ldy #$00
; Get the next data
lda (SPEECH_PTRL),Y
ldx #SSI263_DRP ; duration/phoneme
jsr ssi263_write_chip
; Next data (inc 16 bit)
inc SPEECH_PTRL
bne no_oflo
inc SPEECH_PTRH
no_oflo:
; Finish the interrupt handler
jmp end_interrupt
speech_end:
; If at the end, turn everything off
; Toggle CTL while DR set to disable A/!R
lda #SSI263_CAA_CTL
ldx #SSI263_CAA
jsr ssi263_write_chip
lda #SSI263_DRP_DISABLE_AR
ldx #SSI263_DRP
jsr ssi263_write_chip
; Zero amplitude
lda #$70
ldx #SSI263_CAA
jsr ssi263_write_chip
; Clear busy and playing flags
lda #$00
sta speech_busy
sta speech_playing
; Re-enable interrupt in 6522
lda #VIA6522_IER2_CA1
ldx #VIA6522_IER2
jsr ssi263_write_chip
end_interrupt:
pla
tay ; restore Y
pla
tax ; restore X
pla ; restore A
interrupt_smc:
lda $45 ; restore A (II+/IIe)
plp ; restore flags
rti ; return from interrupt
speech_busy: .byte $00
speech_playing: .byte $00

76
music/ssi-263/trogdor.s Normal file
View File

@ -0,0 +1,76 @@
;
; trogdor.s
;
; Getting text-to-speech on a ssi-263 equipped mockigboard
; for Peasant's Quest
.include "hardware.inc"
.include "ssi263.inc"
speech_test:
jsr HOME
lda #4 ; assume slot #4 for now
jsr detect_ssi263
lda irq_count
clc
adc #'A' ; hack to show if detected or not
sta $400 ; (B is detected, A is not)
lda #4 ; assume slot #4 for now
jsr ssi263_speech_init
speech_loop:
; hello
lda #<hello
sta SPEECH_PTRL
lda #>hello
sta SPEECH_PTRH
jsr ssi263_speak
jsr wait_until_keypress
jmp speech_loop
wait_until_keypress:
lda KEYPRESS
bpl wait_until_keypress
bit KEYRESET
rts
.include "ssi263_detect.s"
.include "ssi263_simple_speech.s"
.byte 34,"I can honestly say it'll",13
.byte "be a pleasure and an honor",13
.byte "to burninate you, Rather",13
.byte "Dashing.",0
; unrefined hello from Programming Guide
hello:
.byte PHONEME_PAUSE ; PA
.byte PHONEME_PAUSE ; PA
.byte PHONEME_HF ; HF
.byte PHONEME_EH ; EH
.byte PHONEME_L ; L
.byte PHONEME_O ; O
.byte PHONEME_PAUSE ; PA
.byte PHONEME_PAUSE ; PA
.byte $FF