Hi folks!
today I am very happy to be able to announce that the PIA 65C21 now works on the breadboard. Both ports, configured as output, are lighting up some LEDs implementing a simple counter.
Attachment:
PIA 65C21 working.JPG [ 1.52 MiB | Viewed 3954 times ]
As suggested in this thread, I tried to simplify the address decode logic to a minimum of stages. Also I am still using the original (slow) components, as the faster ones are a bit difficult to obtain.
In order to simplify the address logic I realized, that I am not limited to the specific range of $DFxx and I also didn't take the risk to ruin the board soldering a wire in order to access the CS0B pin directly. Thus I could allocate the PIA to virtually any unused address and choose $C000 giving me the following address mapping:
Code:
+---------------+---------------+
| Addr. Range | Usage/Chip |
+---------------+---------------+
| $E000 - $FFFF | Intern. ROM |
+---------------+---------------+
| $C000 - $C003 | External PIA |
+---------------+---------------+
| $8000 - $9FFF | Ext. NVRAM |
+---------------+---------------+
| $0000 - $7FFF | Ext. SRAM |
+---------------+---------------+
The CS0 and CS1 lines are tied the the A15 and A14 lines. The CS2B line is qualified with PHI2 through an inverter. The RS0 and RS1 are tied to the A00 and A01 lines respectively,
Unfortunately, when wiring up the chip, initially I switched the RS0 and RS1 lines which caused the LEDs light up inversely
![Embarassed :oops:](./images/smilies/icon_redface.gif)
. Writing $FE into $C000 lighted the first and writing $01 into $C000 all but the first.
After fixing this silly mistake, everything works fine as intended.
The simple test code below show the PORT initialization and counts the value of the corresponding PORTA and PORTB data registers, which flashes the LEDs accordingly.
Code:
;----------------------------------------------------------------------------
; PIA_TEST
;----------------------------------------------------------------------------
PIA_TEST:
!zone {
jsl SEND_CR
lda #$00
sta $c001 ; select DDRA
sta $c003 ; select DDRB
lda #$ff ; set all pins as output
sta $c000 ; write into DDRA
sta $c002 ; write into DDRB
lda #$04
sta $c001 ; select PORTA
sta $c003 ; select PORTB
lda #$00 ; set all outputs LOW
sta $c000 ; write into PORTA
sta $c002 ; write into PORTB
.LOOP:
jsl GET_CHR ; wait for input
cmp #$20 ; is char a space?
bne .QUIT ; no then we're done
inc $c000 ; increment PORTA
inc $c002 ; increment PORTB
lda $c000 ; obtain the counter value
jsl SEND_HEX_OUT ; and print it on serial console
jsl SEND_CR ; start a new line
bra .LOOP ; and stay in loop
.QUIT:
rtl
}
An additional improvement in my code-build-test process saved me a lot of time. After assembling the code and generating the required S28 file afterwards, I upload the file to the board via the serial terminal. But once uploaded, I had always to type a J 00:0400 to call the initialization routine. Although the srec_cat tool I am using provides an option to set the start address (-execution-start-address=0x400) which I think should be detected by the monitor and called after uploading is complete, this does not happen. Seems that this behavior is not implemented.
A simple solution to achieve the initialization beeing called right after upload is simply adding the corresponding command to the end of the S28 file.
This is what it looks like in my build script:
Code:
#!/bin/sh
acme -r user.lst user.asm
srec_cat user.bin -binary -offset=0x400 \
-o user.s28 -address-length=3 \
-execution-start-address=0x400
echo "j000400" >> user.s28
Works like a charm.
Happy breadboarding!