CPCWiki forum

General Category => Programming => Topic started by: menegator on 12:07, 19 March 17

Title: Doh, assembly is not like a bicycle
Post by: menegator on 12:07, 19 March 17
Hello,


My last assembly program in z80 was written almost 25 years ago and for the love of God I cannot figure out why the above returns to basic without a key being pressed


org &4000
call &bb03


init
ld B,78


loop
ld a,0
call &bb1e
jr nz,up
ld a,b
call &bb1e
jr nz,key
djnz loop


jp init


.up
ld hl,value
ld (hl),0
ret


.key
ld hl,value
ld a, b
ld (hl),a
ret


.value
defb 99



In theory if a key is not pressed then it should jumb to start, but it doesn't happen and I can't figure out why.


How did I make it work some 25 years ago, I don't remebmer... Z80 assembly is not like a bicycle, if you leave it it leaves you :(
Title: Re: Doh, assembly is not like a bicycle
Post by: fgbrain on 12:56, 19 March 17

Most likely... I guess the  firmware routine corrupts your registers

You need storing them somehow (try PUSH and POP afterwards)

Futhermore, did you notice that even if B is not corrupted,

djnz loop


will count for 78 times (as you set register B)
Title: Re: Doh, assembly is not like a bicycle
Post by: menegator on 13:09, 19 March 17
Quote from: fgbrain on 12:56, 19 March 17
Most likely... I guess the  firmware routine corrupts your registers

You need storing them somehow (try PUSH and POP afterwards)
The firmware call KM TEST KEY according to manual preserves all registers except A, C, HL.


Quote from: fgbrain on 12:56, 19 March 17
Futhermore, did you notice that even if B is not corrupted,

djnz loop


will count for 78 times (as you set register B)
To my understanding the loop is going either to break, thus a key was pressed or will be exhausted without a key press, thus the jp to start.
Title: Re: Doh, assembly is not like a bicycle
Post by: fgbrain on 13:30, 19 March 17
why dont you just omit DJNZ  and B ? seems you want an endless loop here..

loop
ld a,0
call &bb1e
jr nz,up
ld a,78
call &bb1e
jr nz,key
jp loop




and keep in mind :  C register lets you know if ctrl/shift was pressed
Quote
in: A=keyno, out: nz=pressed, C=ctrl/shift flags
Title: Re: Doh, assembly is not like a bicycle
Post by: menegator on 13:36, 19 March 17
I realized that I checked for key_up in each loop. I modified the code


org &4000
call &bb03


init
ld B,78


loop
ld a,b
call &bb1e
jr nz,key
djnz loop


ld a,0
call &bb1e
jr nz,up


jp init


.up
ld hl,value
ld (hl),0
ret


.key
ld hl,value
ld a, b
ld (hl),a
ret


.value
defb 99

but it still doesn't work and exits whether a key was pressed or not.



Title: Re: Doh, assembly is not like a bicycle
Post by: menegator on 13:40, 19 March 17
Quote from: fgbrain on 13:30, 19 March 17
why dont you just omit DJNZ  and B ? seems you want an endless loop here..
Because I want to check if any key (and not only 78 or 0) if is pressed. This is used to a basic procedure to define keys. It could be done with a for loop in basic but it's too slow.


What I basically want is to test ANY key if it's pressed and if yes, then write the keycode to memory and return to basic. I don't want to use CALL &BB06 or CALL &BB18 because using these calls I can't capture for use control, shift and caps lock.
Title: Re: Doh, assembly is not like a bicycle
Post by: Bryce on 09:45, 20 March 17
Hmmmm, that'll explain why the stabilisers didn't help when I was trying to get back into assembly programming.  ::)

Bryce.
Title: Re: Doh, assembly is not like a bicycle
Post by: MacDeath on 11:42, 20 March 17
Dear Bryce.

YOU truelly ARE THE most massive hardware dude, with a magnitue of density in the inventivity that makes no compromise and take no prisoners.

Your sense of design is so unparralleled, even unreachable to us mundane mortal joes.
We, the poor brained average humans, cannot even grasp the beginning of the concepts you would create effortlessly.
Awe is spillt from us as you rip into the very fabric of the universe like the fist of an angry god.

:laugh:

Also we have even more proofs that the CPC was such a stable system.

Now shut up and take my money !!!
[attach=2]

Is there a PLUS or a 6128 version ?
Title: Re: Doh, assembly is not like a bicycle
Post by: Axelay on 11:43, 20 March 17
I'm not familiar with this firmware routine, but I noticed after the call immediately returns, the 'value' memory location holds 18, which is the key for enter, the last key you press to issue the call &4000.  So maybe the problem is the key presses are being queued with that call?  I've chucked together a little variation on your routine that splits the key checking loop out of the overall loop, and then first calls it repeatedly until no key is detected as pressed (or queued, perhaps), and then repeatedly calls the same code again until a key is pressed.  It seems to do something more like you described wanting, though as I mentioned, I'm not familiar with the firmware routine so I'm only guessing at the problem.


I also changed the djnz to a dec b/jp p so the separate check for key 0 was unnecessary, and it then allowed the loop exit to flow through with A being loaded with an invalid key number (255) to indicate no key press to the outer loop.






org &4000
call &bb03


GetKey
; first check no key is currently pressed or queued
call CheckKeys
rla ; a returns holding key pressed value, or 255 if no key pressed, so check bit 7
jr nc,GetKey ; repeat check while a key is being pressed or queued
; now check for a key press
FindKey
call CheckKeys
rla
jr c,FindKey ; if bit 7 set in a then no key was pressed, repeat loop
ret ; foud a key and it has been stored at value


CheckKeys
ld b,78
keycheckloop
ld a,b
call &bb1e
jr nz,keypressed
dec b
jp p,keycheckloop ; if b not reached 255, repeat
; b is 255, use as indicator that no key was pressed and flow through to standard exit
.keypressed
ld a,b
ld (value),a
ret




.value
defb 99
Title: Re: Doh, assembly is not like a bicycle
Post by: menegator on 17:32, 20 March 17
Thank you Axelay, your code did the trick!


I had the call to "&BB03" to clear the keyboard buffer in order to avoid what you mentioned (the key press was queued from basic) but apparently it didn't work.
Title: Re: Doh, assembly is not like a bicycle
Post by: opqa on 21:57, 20 March 17
This is so typical... There is nothing wrong with your original code, it runs well, "too" well in fact.

The problem is not related with key queuing, the firmware indeed maintains a keypress queue, but &bb1e doesn't care about it, it just informs you whether the indicated key is pressed or not. The only "problem" is just that your code is "too" fast. When you hit enter after having written "call &4000" the code starts executing immediately, it doesn't wait for you to release the Enter key. When the loop arrives at the point of checking this key, few milliseconds later, your finger is still there, you just haven't got enough time to lift it.

You can solve this "problem" in many ways, you can just add a long delay at the beginning of execution to give you time to release the key, you can try to detect a "not pressed -> pressed " transition as in Alexay variant instead of just a key pressed condition as in yours, you can test the routine from WinAPE by running it from the Assembler menu instead of calling it from BASIC...

Or you can do nothing, because depending on when and how you call this routine from your program this problem may or may not arise, it's your choice.
Powered by SMFPacks Menu Editor Mod