fachat wrote:
Still bravo, so let's get the remaining bugs fixed
Thanks a lot!
Quote:
I don't know if you've got your schematics here, but the VIA has an "undocumented" feature. It needs the address lines and select stable at rising phi2.
I learned about this, but I don't think it's the problem here. My decoding is
extremely simple:
(A13...A15 are unused)
Code:
VIA CS = A11
VIA /CS = A12
ROM /CS = NOT( A12 )
RAM /CS = NAND( NOT(A11), NOT(A12) )
RAM /WE = OR ( Phi1, R/W )
The VIA chip selects go
directly to the address bus, with no gates in between, thus well before the rising edge of Phi2.
Quote:
Another one: how do you compute the VIA timer values? How do you create the sound?
I'm using a simple square wave generator from PB7 toggling at each timeout of Timer 1. I computed the appropiate timer values for each note, and they're directly copied into the VIA's registers from a table with three-byte entries for each note. The last byte of each entry indicates the
duration, and goes to a delay loop.
There are some "special" values for the
pitch MSB: zero means
rest, disabling the PB7 toggling for the silence. And $FF marks the end of the score.
Quote:
Though, ... are you using CMOS logic? (Like 74HCTxxx) or other fast logic like 74ALSxxx.
The only logic IC is a 74HC132 (also tried an HCT; I have no TTL equivalent). I chose a
Schmitt-trigger gate for the Reset circuit. Two gates are used as inverters for A11 and A12, and the remaining gate implements the NAND function for RAM /CS.
Quote:
I have to add that the VIA actually does SPI mode 3 "naturally". You only need to shift out the byte via the shift register, and shift it into a 74164 Serial-in-parallel-out.
Interesting... but my main intent for using SPI was for SD/MMC card access, which uses mode 0. Fortunately,
jesari designed a nice workaround for it.
BigEd wrote:
Are the notes consistently too high, or too low? Or really very wrong?
They're
very wrong, not just
slightly detuned. There is some variability, especially depending on the particular VIA sample (although all of them work great on the breadboard) but the usual behaviour is one out of these two:
1) A
single frequency is played for all the notes, only the silences (rests) are correctly "played" (sound is muted)
2) Only
two frequencies are used, depending on the particular note. Seems like it's rounded to the nearest octave (or something)
On second thought, it seems the data bits aren't arriving to the VIA, although D7 should be fine because is used in ACR to switch the PB7 toggling on and off, which is done properly.
By the way: continuity of the data lines between the CPU and VIA (less than an inch) is OK. On the 'scope, waveforms seem OK -- they seem worse on the breadboard, and that works just fine!
Quote:
I wonder if stray interrupts could slow things down.
Interrupts are
disabled. Since the code is designed to work RAMless, any interrupt would crash the computer at once.
GARTHWILSON wrote:
For such a small board and 1MHz, I doubt that the AC behavior is a problem.
I really hope so...
Quote:
I have done what you're talking about zuiko21, so if you post your code to set up the VIA and set the notes, I wonder if I could find the problem.
Don't think it could be the culprit, since the very same EPROM with the very same code and the very same VIA work great on the breadboard... but anyway, here it is (not sure if this is the latest version, though)
Code:
play LDA #$0E ; some intialization
STA PCR
STA IER ; disable interrupts, just in case (a SEI was previously executed)
LDA #$80 ; will set PB7 as output
STA DDRB
STA ORB ; don't think is needed, but won't hurt anyway
LDX #0 ; reset note pointer
note LDA score, X ; get pitch LSB for current note
STA T1LL ; put it into latch
LDA score+1, X ; get pitch MSB (could be special value)
BNE no_rest ; must sound
STZ ACR ; otherwise, turn off PB7 toggling
BRA delay ; no subroutines, in case of RAMless
no_rest CMP #$FF ; is it the end of the score?
lock BEQ lock ; "stop" the CPU
LDY #$C0 ; otherwise, turn sound back on again
STY ACR
STA T1LH ; not a special value, put the MSB in
STA T1CH ; start counting
delay LDA score+2, X ; get note length
LDY #0 ; reset delay counter LSB
loop ROL ORA ; lose some time rotating a meaningless value a few times
ROR ORA
ROL ORA
ROR ORA
ROL ORA
ROR ORA
DEY ; LSB counter
BNE loop
DEC ; MSB counter, the delay from table entry
BNE loop
STZ ACR ; turn sound off, just in case
INX ; increase pointer to the next note
INX
INX
BRA note ; loop until the end-of-score is detected
This code could use some optimization, like writing only to the T1 counter registers, and not the latches; but this version worked just fine on the breadboard.