Machine Code Keyboard Input
Machine Code Keyboard Input
I’m trying to get to grips with inputing from the keyboard in machine code. I’ve read threads on this forum, and a lot of books, but something isn’t clicking.
Can someone give me a simple routine that would essentially do nothing until a key is pressed, then return to BASIC when the key is pressed? No Rom routines, just pure machine code.
Can someone give me a simple routine that would essentially do nothing until a key is pressed, then return to BASIC when the key is pressed? No Rom routines, just pure machine code.
Re: Machine Code Keyboard Input
Pure M/Ca simple routine that would essentially do nothing until a key is pressed, then return to BASIC when the key is pressed
Code: Select all
W4KEY: LD A,(4025H);LAST_K ;CHECK KEYBOARD STATE
INC A
JR Z,W4KEY ;LOOP UNTIL KEY DOWN
RET
Code: Select all
1 REM .......
10 PAUSE 120
11 RAND USR 16514
20 PRINT "KEY PRESSED"
Code: Select all
POKE 16514,58
POKE 16515,37
POKE 16516,64
POKE 16517,60
POKE 16518,40
POKE 16519,250
POKE 16520,201
Re: Machine Code Keyboard Input
Thanks. I haven’t used an assembler yet, so some assembly language confuses me. I’ve just been learning pure machine code.
What does the LAST_K director mean in assembly? That’s one of the things that’s been confusing me when I try to follow old threads on this forum.
What does the LAST_K director mean in assembly? That’s one of the things that’s been confusing me when I try to follow old threads on this forum.
Re: Machine Code Keyboard Input
LAST_K is a specific location in memory. See ZX81 manual Chapter 28 - The System Variables
ASSEMBLY:
MACHINE CODE of same:
LD A(nn) is opcode 3Ah, and the address is 4025h. I look up the machine codes in Appendix A of the ZX81 manual
POKE takes the decimal format
The keyboard lines are directly wired to memory location 16421 (4025 hexadecimal), so reading that memory location gives the key states. If no keys are pressed it reads -1. If any key is pressed, it will be something different. Fortunately, -1 is easy to test for in M/C -- just INC it. -1 increments to 0, hence the JR Z (Jump if Zero).16421 LAST_K Shows which keys pressed
ASSEMBLY:
Code: Select all
LD A,(4025H);LAST_K
Code: Select all
3A,25,40 hexadecimal
Code: Select all
58,37,46 decimal
POKE takes the decimal format
Re: Machine Code Keyboard Input
Help from VB81:
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
- 1024MAK
- Posts: 5118
- Joined: Mon Sep 26, 2011 10:56 am
- Location: Looking forward to summer in Somerset, UK...
Re: Machine Code Keyboard Input
It should be mentioned that the update display (as in produce the video display video signal) routine in the ROM also scans the keyboard matrix, and puts the result of this in the system variable memory location called LAST_K.
This works if you are using BASIC or a assembly language / machine code routine from BASIC, and hence using the ROM video display system.
Mark
This works if you are using BASIC or a assembly language / machine code routine from BASIC, and hence using the ROM video display system.
Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp
Standby alert
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp
Standby alert
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
Re: Machine Code Keyboard Input
as soon as I posted that, i began to think about how I don't fully understand the keyboard interface. I've always just used that bit of machine code with much success
Reading the LAST_K memory location is the simple solution, and it requires no ROM calls from your machine code
Thanks Mark for pointing out that LAST_K is updated by the display code. I just tried it and see that it indeed only works in SLOW mode. In FAST mode, no keypress is detected by that simple code
Reading the LAST_K memory location is the simple solution, and it requires no ROM calls from your machine code
Thanks Mark for pointing out that LAST_K is updated by the display code. I just tried it and see that it indeed only works in SLOW mode. In FAST mode, no keypress is detected by that simple code
Re: Machine Code Keyboard Input
Ah, I’m really looking for a full understanding of machine code that I can expand to use in coding as I progress. Reading a wired memory location is one thing, but I’m really looking to fully understand the IN A, (c) way of doing things.
Something along the lines described at the link below:
Something along the lines described at the link below:
But something about it isn’t totally clicking for me. So I thought if I could see a bit of code that would achieve the aim outlined in my original post, via the IN A method, it might click.
- 1024MAK
- Posts: 5118
- Joined: Mon Sep 26, 2011 10:56 am
- Location: Looking forward to summer in Somerset, UK...
Re: Machine Code Keyboard Input
Well first you need to understand the hardware.
The keyboard is a matrix. Eight lines are actually derived from the Z80 upper address bus, A8 to A15. So to select which ‘half’ row to scan, the I/O address has to set the upper byte accordingly.
The lower byte on the address bus must be that of the ULA, namely 0xFE. When addressed, the ULA will read the state of the five keyboard column lines and pass this information to the Z80.
Hence when an appropriate machine code IN instruction is executed, both the above are done simultaneously.
Now you need to convert this to a format that is useful to your program, including key switch contact debouching (mechanical contacts have a nasty habit of making and breaking multiple times before settling down to being made due to mechanical vibrations, the replacement keyboards are worse for this than the membrane).
The keyboard layout and matrix is shown on this schematic.
See here for the ZX81 I/O details.
Mark
The keyboard is a matrix. Eight lines are actually derived from the Z80 upper address bus, A8 to A15. So to select which ‘half’ row to scan, the I/O address has to set the upper byte accordingly.
The lower byte on the address bus must be that of the ULA, namely 0xFE. When addressed, the ULA will read the state of the five keyboard column lines and pass this information to the Z80.
Hence when an appropriate machine code IN instruction is executed, both the above are done simultaneously.
Now you need to convert this to a format that is useful to your program, including key switch contact debouching (mechanical contacts have a nasty habit of making and breaking multiple times before settling down to being made due to mechanical vibrations, the replacement keyboards are worse for this than the membrane).
The keyboard layout and matrix is shown on this schematic.
See here for the ZX81 I/O details.
Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp
Standby alert
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp
Standby alert
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
Re: Machine Code Keyboard Input
Ah, I understood the keyboard stuff before, but I couldn’t understand where FE was coming from in the stuff I was reading. I didn’t realise it was the ULA.
I sometimes see programmes doing a compare for 191, from different half row scans, checking for ANY key from that half row. But I don’t understand why 191. What is the reason? I understand that a key press, any key press, will turn one of the 1s to a 0. But surely only one of the keys will give 1011111 (191)?
I sometimes see programmes doing a compare for 191, from different half row scans, checking for ANY key from that half row. But I don’t understand why 191. What is the reason? I understand that a key press, any key press, will turn one of the 1s to a 0. But surely only one of the keys will give 1011111 (191)?