News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Doh, assembly is not like a bicycle

Started by menegator, 12:07, 19 March 17

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

menegator

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 :(

fgbrain


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)
_____

6128 (UK keyboard, Crtc type 0/2), 6128+ (UK keyboard), 3.5" and 5.25" drives, Reset switch and Digiblaster (selfmade), Inicron Romram box, Bryce Megaflash, SVideo & PS/2 mouse, , Magnum Lightgun, X-MEM, X4 Board, C4CPC, Multiface2 X4, RTC X4 and Gotek USB Floppy emulator.

menegator

#2
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.

fgbrain

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
_____

6128 (UK keyboard, Crtc type 0/2), 6128+ (UK keyboard), 3.5" and 5.25" drives, Reset switch and Digiblaster (selfmade), Inicron Romram box, Bryce Megaflash, SVideo & PS/2 mouse, , Magnum Lightgun, X-MEM, X4 Board, C4CPC, Multiface2 X4, RTC X4 and Gotek USB Floppy emulator.

menegator

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.




menegator

#5
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.

Bryce

Hmmmm, that'll explain why the stabilisers didn't help when I was trying to get back into assembly programming.  ::)

Bryce.

MacDeath

#7
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 ?

Axelay

#8
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

menegator

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.

opqa

#10
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