PET Keyboard Read Routine

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

PET Keyboard Read Routine

Post by Oneironaut »

Greets!

If there are any PET gurus out there, I would appreciate some ideas on why I can't seem to read input directly from PORTB on the 6520 that is connected to the PET keyboard. I am familiar enough with the hardware to know that bits (3:0) feed a 74LS145 BCD decoder that drives one of ten ROW lines LOW. I also know that pressing a key will drive one of the Columns LOW that feeds into the 6520 PORTB input.

I need to read input data from PORTB of the 6520 as fast as possible (for reasons I will explain later), so I made this basic assembly test just to make sure I was on the right track. I fully expected this to show characters change on the screen as I pressed various keys....

Code: Select all



; ******************************************************************
; ********** PET BASIC PROGRAM STUB
; ********** SAVE CODE STARTING @ 1025
; ******************************************************************

; START OF BASIC
 .ORG 1025
 .WORD 1025
 
; ADD BASIC SYS2000 COMMAND
 .BYTE 11,4,0,0,158,50,48,48,48,0,0,0
   
; START OF PRORAM + BASIC OFFSET
 .ORG 2000+2
  
; DISABLE PET KERNAL
 ;SEI
  
 
; ******************************************************************
; ********** MAIN LOOP
; ******************************************************************
MAIN:
 
; SET KBD.ROW
 lda #0
 STA $E810
 
; RED KBD.COL  
 LDA $E812
 STA 32768
 
; ALIVE TEST
 INX
 STX 32769
 
 ; LOOP 
 JMP MAIN
 
Simple enough, it sets the 145 to zero, then writes whatever value it finds on the input of PORTB to the upper left corner of the screen. Just to verify my sanity (and that the code works), it also dumps a rolling character to the second location on the screen, and that indeed works.

What is odd is that the keyboard has no effect on the first character, it just stays at 255. Even if I alter the 145 value, nothing changes.

I have run this code on 2 real PETs as well as vice, and it is the same on all.

Any ideas? I am almost certain that my addresses are correct; $E819 to set the 145, and $E812 to read the data.

On a side note, this "Basic Stub" just stuffs "SYS 2000" into basic line zero. Address 2000 is the start of assembly code.
I use this for all my PET progs, and it works well.

Here is a Vice shot, showing the 255 character (top left) and my rolling character working...

Image

Cheers!
Brad
Attachments
vice.jpg
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: PET Keyboard Read Routine

Post by barrym95838 »

I am not a PET guru, but Andre is, and this seems to suggest that you need to double-check your port B address:

http://www.6502.org/users/andre/petinde ... .html#pia1

[Edit: or not ... I just looked back and I can't see what made me think that ... I hope it wasn't a mini-stroke ... maybe you just weren't hitting any Row 0 keys?

http://www.6502.org/users/andre/petinde ... .html#scan

]
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Oneironaut »

Thanks.

I thought that at first as well, so I methodically pressed every key. I then made the 145 address roll from 0 to 15 as well, and still.... no changes.
There must be some other ghost in the machine at work here. Something I don't understand about the PET.

Brad
barrym95838 wrote:
I am not a PET guru, but Andre is, and this seems to suggest that you need to double-check your port B address:

http://www.6502.org/users/andre/petinde ... .html#pia1

[Edit: or not ... I just looked back and I can't see what made me think that ... I hope it wasn't a mini-stroke ... maybe you just weren't hitting any Row 0 keys?

http://www.6502.org/users/andre/petinde ... .html#scan

]
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: PET Keyboard Read Routine

Post by barrym95838 »

With interrupts disabled, do you need to manually strobe the DDRA (as an output) somehow? I'm at work, so I can't spend too much time right now studying how the PET ROM does it ... :-(
Last edited by barrym95838 on Sat Nov 13, 2021 7:14 pm, edited 3 times in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
tsky
Posts: 10
Joined: 03 Nov 2011
Location: San Francisco, CA, USA
Contact:

Re: PET Keyboard Read Routine

Post by tsky »

I notice a couple oddities in your code but they probably shouldn't affect its execution. Your BASIC program calls sys(2000) but your .ORG statement starts the code at 2002. That means one or two garbage instructions get executed but it looks like the MAIN loop does get executed. Also, your SEI instruction is commented out. That means once every 1000 loops or so, the program gets interrupted and the row address ($E810) gets modified by the interrupt routine. But, that should be hardly noticeable because the assembly code would quickly change it back. Otherwise, the code looks good and it's a mystery (to me) why it's not working.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Dr Jefyll »

Oneironaut wrote:
Something I don't understand about the PET.
Rather than the PET, could it be the 6520 that's throwing you a curve?

The odd thing (to me) about this chip is how the Data Direction Registers are not directly accessible -- meaning, they're not provided with a register address all their own. Instead, to get at them you need to set bit2 of the Control Register, then use the address that otherwise would give you the Data Register (not the Data Direction Register) . Perhaps you're already aware of this.

Anyway, FWIW I'm just throwing the thought out there. Is it possible that you and the PET firmware and the 6520 itself are having a misunderstanding about whether the '145 bits you're wiggling are supposed to be inputs or outputs?

-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: PET Keyboard Read Routine

Post by barrym95838 »

(HAH! My edit beat Jeff's post by two full minutes!)

Back to work ... another turd just stumbled in, ready for polishing ...
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Dr Jefyll »

Wha ? You edited your post? (I was busy typing!) :)
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Oneironaut »

Thanks for the suggestions!

Ok, the .ORG2000+2 is to remind myself that when you load a program into the PET, it adds 2 bytes to determine the start of the basic program, even though it cannot actually be relocated like on other C= machines. This is all good - no bogus bytes are executed.

One strange thing also is that SEI does nothing it all. Unlike my VIC programs where this stops all kernal routines from running, it does not do the same on the PET. I think the IRQ may be triggered in hardware by the 60Hz vertical sync pulse.

In that case.... perhaps it is impossible to actually stop the editor from running and also not possible to write a fast keyboard routine in assembly for a PET?

This is very odd.
Brad
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: PET Keyboard Read Routine

Post by barrym95838 »

Nothing is impossible in this little corner of the universe, only a bit inconvenient! I thought PETs didn't use NMIs, but even if they did there could be a way to wedge into the vector and force the ISR to lay off your locations.

Are you sure that SEI doesn't work? Or is it ;SEI that's the culprit?
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
tsky
Posts: 10
Joined: 03 Nov 2011
Location: San Francisco, CA, USA
Contact:

Re: PET Keyboard Read Routine

Post by tsky »

Oneironaut wrote:
Ok, the .ORG2000+2 is to remind myself that when you load a program into the PET, it adds 2 bytes to determine the start of the basic program, even though it cannot actually be relocated like on other C= machines. This is all good - no bogus bytes are executed.
Brad
I think you might have a mismatch between the ORG address and where the code lands in memory. The SYS(2000) jumps to 2000. The JMP instruction at the end of the loop is going to jump to 2002. One of those is wrong.
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Oneironaut »

Thanks, that is correct, the +2 was there from another program that needed the offset. Forgot to remove it.

Now when I run the code with SEI, it crashes (ends up in the machine language monitor).
If I remove SEI, then it returns to normal operation, but zero input shown from the keyboard.

Not sure why issuing SEI caused the PET to bomb.


I should probably explain my goals here.

I have a connection between the PET keyboard port and something I am working on. I am, able to read PET keystrokes and even send PET keystrokes, which is required for my project. All good so far.

What I also want to do is have the PET read data being sent as fast as possible from this external device. This is the reason for wiring this PIA input capture program. What it will do is stream bytes read from the PIA into the PET's program memory starting at location 1025. So yeah... it will load programs into the PET just like the IEEE port does, but using the keyboard port instead.

So you may wonder... how does this strange little BootLoader get into memory in the first place? Well, it is poked into the cassette buffer at location 632 by the external device that temporarily hijacks the keyboard through the port. And yup, this part actually works already! The AVR covertly listens to the 74LS154 lines and then stuffs data into the VIA, simulating lightning fast input from the keyboard. It can poke the tiny bootloader into RAM in a few seconds. Once done, the command "SYS 634" is issued and then I want the PET to hurl bytes into RAM from the PIA.

Loading performance will be even faster than anything possible on the IEEE port. I expect to get at least 60 kilobytes per second!
But if I am a slave to the kernal, then I can only read bytes at 60 hertz, so that kills the entire idea dead.
In that case, I will have to go back to a plug in the option ROM socket and run my transfer from there.
I have to tap the keyboard plug anyhow, so I figure this would greatly reduce my wire count.

The only thing I can't solve is how to directly read data on the PIA PORTB, which I thought would be the easiest part of this experiment!
Oh, I am using VICE for the code tests, so I know I am not being beat by some hardware bug.

Here is my hardware rig so far...

Image

The other ICs on the board are converting the video to the 1702 monitor. I will post this project in more detail when it gets off the ground, but here is the core idea...

https://www.youtube.com/watch?v=irBI9fVE9dY

Thanks,
Brad
tsky wrote:
Oneironaut wrote:
Ok, the .ORG2000+2 is to remind myself that when you load a program into the PET, it adds 2 bytes to determine the start of the basic program, even though it cannot actually be relocated like on other C= machines. This is all good - no bogus bytes are executed.
Brad
I think you might have a mismatch between the ORG address and where the code lands in memory. The SYS(2000) jumps to 2000. The JMP instruction at the end of the loop is going to jump to 2002. One of those is wrong.
Attachments
pet1.jpg
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Oneironaut »

Here is the assembled program. This can be run in VICE by just dragging it into the window.
Works on any PET machine, but I am testing on a 4032 model.
I had to trick the forum uploader, so I changed the extension to ZIP.
It is not a zip file, just a binary. Drop it over a VICE window to run on a PET.

Here is the source. Notice how I have to remove SEI?

Code: Select all


; ******************************************************************
; ********** PET BASIC PROGRAM STUB
; ********** SAVE CODE STARTING @ 1025
; ******************************************************************

; START OF BASIC RAM
 .ORG 1025
 
; BASIC LOCATION BYTES 
 .WORD 1025

; ADD BASIC SYS2000 COMMAND
 .BYTE 11,4,0,0,158,50,48,48,48,0,0,0
   
; START OF ASSEMBLY PROGRAM
 .ORG 2000
  
; DISABLE PET KERNAL
 ;SEI
 
; ******************************************************************
; ********** MAIN LOOP
; ******************************************************************
MAIN:

   ; SET KBD.ROW
 lda #0
 STA $E810
 
; READ KBD.COL  
 LDA $E812
 STA 32768
 
; ALIVE TEST
 INX
 STX 32769
  
 ; LOOP 
 JMP MAIN

Thanks,
Brad
Attachments
PIA Test.zip
(4 KiB) Downloaded 65 times
tsky
Posts: 10
Joined: 03 Nov 2011
Location: San Francisco, CA, USA
Contact:

Re: PET Keyboard Read Routine

Post by tsky »

I loaded the program into my emulator and it looks like this in memory:

Code: Select all

0400: 00 0B 04 00 00 9E 32 30         ......20
0408: 30 30 00 00 00 00 00 00         00......
0410: 00 00 00 00 00 00 00 00         ........
0418: 00 00 00 00 00 00 00 00         ........
...
 07CC: 00 00      BRK $00
 07CE: A9 00      LDA #$00
 07D0: 8D 10 E8   STA $E810
 07D3: AD 12 E8   LDA $E812
 07D6: 8D 00 80   STA $8000
 07D9: E8         INX
 07DA: 8E 01 80   STX $8001
 07DD: 4C D0 07   JMP $07D0
 07E0: 00 00      BRK $00
 07E2: 00 00      BRK $00
 07E4: 00 00      BRK $00
MAIN lands at 07CE and notice the JMP jumps to the STA instruction. Try replacing the ".ORG 1025" at the top with ".ORG 1023". The ".WORD 1025" will emit the 2-byte start address and everything should line up at that point. I guess when you insert the SEI, then the JMP instruction points to the zero in the LDA #0 instruction and that would explain jumping the the monitor.

Your project sounds interesting! I'll be interested to see how fast it can load. This would be nice on my old 2001 ROM1 which has a broken IEEE.
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

Re: PET Keyboard Read Routine

Post by Oneironaut »

Thanks for having a look!

Removing the basic "location bytes" makes the PET fail to load the program completely.
If I remember correctly when I wrote this, you have to account for the 2 byte "shift" because after loading, the PET offsets the program, removing those 2 bytes, which is why originally I used .ORG2000+2

Anyhow, I added a whack of NOPS after main, just as a test and the program still fails to read any data.
I wonder if I need to dig into some kind of IRQ vector relocating... like a wedge might do?

Brad
tsky wrote:
I loaded the program into my emulator and it looks like this in memory:

Code: Select all

0400: 00 0B 04 00 00 9E 32 30         ......20
0408: 30 30 00 00 00 00 00 00         00......
0410: 00 00 00 00 00 00 00 00         ........
0418: 00 00 00 00 00 00 00 00         ........
...
 07CC: 00 00      BRK $00
 07CE: A9 00      LDA #$00
 07D0: 8D 10 E8   STA $E810
 07D3: AD 12 E8   LDA $E812
 07D6: 8D 00 80   STA $8000
 07D9: E8         INX
 07DA: 8E 01 80   STX $8001
 07DD: 4C D0 07   JMP $07D0
 07E0: 00 00      BRK $00
 07E2: 00 00      BRK $00
 07E4: 00 00      BRK $00
MAIN lands at 07CE and notice the JMP jumps to the STA instruction. Try replacing the ".ORG 1025" at the top with ".ORG 1023". The ".WORD 1025" will emit the 2-byte start address and everything should line up at that point. I guess when you insert the SEI, then the JMP instruction points to the zero in the LDA #0 instruction and that would explain jumping the the monitor.

Your project sounds interesting! I'll be interested to see how fast it can load. This would be nice on my old 2001 ROM1 which has a broken IEEE.
Post Reply