Senior Moment With SCNKEY

Basic and Machine Language

Moderator: Moderators

Post Reply
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Senior Moment With SCNKEY

Post by FD22 »

As per the title, I'm convinced I'm having a senior moment with SCNKEY at $EB1E; I've obviously just forgotten something elementary here and can't see the wood for the trees. Running this is VICE is doing something odd:

Code: Select all

; wait for selection
.waitkey	jsr _SCNKEY					; [6]	scan keyboard
			  lda _KEYPRESS				 ; [3]	ZP get key scan code
			  cmp #$3B					   ; [2]	keycode for '8'
			  beq .relblk5				  ; [2/3] relocate to 8K block 5
			  cmp #$01					   ; [2]	keycode for '3'
			  beq .relblk0				  ; [2/3] relocate to 3K block 0
			  cmp #$3C					   ; [2]	keycode for '0'
			  bne .waitkey				  ; [3/2] keep scanning if not a valid key
Dead simple, right? Call SCNKEY at $EB1E, get the scancode from $C5, test to see if it was '8', '3' or '0' (fall out of the loop if '0') and keep iterating until one comes up. So why are some other keys sometimes registering as one of the three I'm looking for (e.g. pressing 'H', sometimes once, sometimes a few times) drops #$3B into $C5 and registers as '8'? If I do a PEEK(197) loop in BASIC this never happens.

I'm at the point where I'm studying the SCNKEY code to see if I can find a subtle speed-related bug relating to the code-table lookup; maybe the VIA strobe logic and/or the scancode lookup fails intermittently if the routine is called in a tight loop instead of just on the IRQ...? I've got interrupts disabled at this point, by the way.

This can't be right. I must be missing something obvious. Maybe it's the VICE keyboard table not playing-nice with this laptop...
User avatar
buzbard
Vic 20 Devotee
Posts: 213
Joined: Sun Jul 03, 2005 9:10 am

Re: Senior Moment With SCNKEY

Post by buzbard »

Why not skip the SCNKEY and just read the current key being pressed at $CB?
Ray..
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: Senior Moment With SCNKEY

Post by FD22 »

Because it's SCNKEY that updates $CB and $C5. The keycode for the current keypress is read from the keycode table based on the VIA port-scan result and dropped into $CB - this is then checked against $C5 which holds the keycode from the previous SCNKEY pass, to see if auto-repeat is needed. The last thing SCNKEY does is drop the value it has stashed in $CB into $C5 as well, ready for the next pass.

Normally this happens as part of the regular IRQ processing - SCNKEY is called from the ISR at $EABF; but if you have interrupts disabled, there's no ISR running and therefore SCNKEY isn't updating $CB/$C5. Thus, to read the keyboard, I call SCNKEY and read $C5 (although that's just an arbitrary choice - I could just as easily read $CB instead, since they're essentially the same thing).
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Senior Moment With SCNKEY

Post by tlr »

FD22 wrote:Normally this happens as part of the regular IRQ processing - SCNKEY is called from the ISR at $EABF; but if you have interrupts disabled, there's no ISR running and therefore SCNKEY isn't updating $CB/$C5. Thus, to read the keyboard, I call SCNKEY and read $C5 (although that's just an arbitrary choice - I could just as easily read $CB instead, since they're essentially the same thing).
So you do have IRQs disabled at all times, right? Otherwise you've got a problem. SCNKEY isn't thread safe.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: Senior Moment With SCNKEY

Post by FD22 »

Oh yes, quite definitely; this is the initialisation phase of something that runs in the IRQ, so my very first instruction is SEI because I'm twiddling the IRQ vector. In any case, the entire ROM is pretty-much thread-unsafe, so it's not an assumption I would ever make. ;)

In fact, the keypress check is for a small selection menu giving the choice of where to relocate my IRQ routine (and its associated data structures) to, so interrupts have to be disabled here because the final values for the IRQ vector adjustment are decided and set just after this.

I'm wondering if this is a VICE peculiarity. It looks suspiciously like a keyscan column misfire, because for example I'm looking for '8', but 'U', 'H' and 'B' can also return the same scancode if I hit them two or three times in quick succession.

Anyone else seen this? Or am I doing something daft here?
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Senior Moment With SCNKEY

Post by tlr »

I'm using scnkey directly in fcbpaint and that doesn't have any problems.

Your code looks ok. It's hard to tell what the problems are without seeing more of the environment it lives in.

Are you perhaps running this from cartridge code and in that case are the VIA DDR regs correctly set up?
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: Senior Moment With SCNKEY

Post by FD22 »

Alright, here you go - the code from the beginning to the point where I'd do some relocation of the IRQ routine based on the selection. This is running on a standard 8K-expanded VIC, with a BASIC line stub just before this with a SYS pointing at 'begin'. The program is loaded as a normal .PRG at $1200 and works as far as it goes; the only problem is that keys other than '0', '3' or '8' are returning scancodes which match (i.e. 'U', 'H' and 'B' can be hit in quick succession and produce $3B).

Code: Select all

Removed - completely re-organised following _STROUT interrupt revelation below
Last edited by FD22 on Sun Dec 01, 2013 6:06 pm, edited 1 time in total.
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Senior Moment With SCNKEY

Post by tlr »

FD22 wrote:

Code: Select all

			lda #<_LISTMSG				; [2]	title message start lo-byte
			ldy #>_LISTMSG				; [2]	title message start hi-byte
			jsr _STROUT					; [6]	display string
I'm guessing that _STROUT = $cb1e, right? In any case something that calls CHROUT ($ffd2) will enable interrupts...

Disabling it again before the call to SCNKEY will probably do the trick.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: Senior Moment With SCNKEY

Post by FD22 »

Yep, _STROUT = $CB1E.

Oh holy blap, you're right - interrupts ARE being enabled by _STROUT, as it falls through _SETSPRNT at $E6C5. Why the hell does it do that?? That has got to be a typo in the original ROM source, since it follows a CLC; there's just no reason to do a CLI there.

:shock:
wimoos
Vic 20 Afficionado
Posts: 345
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Re: Senior Moment With SCNKEY

Post by wimoos »

This may very well have to do with the function of the CTRL-key during PRINT.

Regards,

Wim.
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
groepaz
Vic 20 Scientist
Posts: 1180
Joined: Wed Aug 25, 2010 5:30 pm

Re: Senior Moment With SCNKEY

Post by groepaz »

This may very well have to do with the function of the CTRL-key during PRINT.
... and the function of run/stop during disk operations, yes.
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: Senior Moment With SCNKEY

Post by FD22 »

Agreed - but those conditions should either be checked-for in STROUT, or better yet handled outside it. To just arbitrarily enable interrupts in a character-output routine is irresponsible, and is bound to trip people up. Me, for example. ;)
groepaz
Vic 20 Scientist
Posts: 1180
Joined: Wed Aug 25, 2010 5:30 pm

Re: Senior Moment With SCNKEY

Post by groepaz »

hehe, it probably saved a byte or two somewhere.... the irq is disabled during some IEC operations, i guess this cli makes sure they are enabled afterwards :)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: Senior Moment With SCNKEY

Post by FD22 »

Oh, doubtless it's probably saving a few bytes somewhere. Now, let's just count the NOPs in the ROM, shall we...? ;)

Anyway, problem solved. The screen I/O code is now outside the interrupt-disabled area, so it's all good.

EDIT: I did. 113.
Post Reply