Noob question, trying to pass variables in subroutines.

Página 1/2
| 2

Por Daemos

Paragon (2044)

imagem de Daemos

11-01-2011, 20:43

OK after reading about three books concerning Z80 CPU assembly. The terrible MSX handbook and offcourse the V9938 manual I started doing some fun stuff on the MSX offcourse starting with a little "hello world" program and after 2 weeks there are finally results. I think I am starting to get it alltogether but something in my logic is still bothering me because I get unexpected results from what I am tring to do right now.

I am trying to learn step by step and after sucessfully reading the keys of the keyboard and getting some tekst on the screen I now try to create a main program loop that exits the entire program after the space key is pressed. I first tried this:

org &hc000
key: equ &HFBE5
ei             ;somehow doesn't work without this

waitspace:

 ld a,(KEY+8)
 bit 0,a
 ret z
 jr waitspace

end

program behaves as expected. The whole systems hangs in a countless amount of loops until I press the space key and I started running through the house of joy upon seeying that I actually have build my first working routine
LOL!

however the party has ended here:

org &hc000
key: equ &HFBE5
ei

main:
 call waitspace
 bit 0,c                   ;check for return from spacekey routine
 ret nz (tried z too) ;stop program if true
 jr main                   ;otherwise keep burning Z80 silicon

waitspace:  ;read the space key and set value if true

 ld a,(KEY+8)
 bit 0,a
 jr z,spacep
 ret
spacep:

 ld c,1 ;set some value for the main loop to do something
 ret

end

You might propably ask yourself what I am trying to do here. Well I am practising. Let me explain. In this exercise I try to build some main loop that will do calls and in the future will parse data to these calls. Then the calls return with some value causing the main routine to do something in return. Well I am doing something utterly wrong let it be my way of thinking or coding so please explain to me what I am failing to understand here.Question

Entrar ou registrar-se para comentar

Por Leo

Paragon (1236)

imagem de Leo

11-01-2011, 21:44

you mean your second example doesnot work ? hangs or something ?
shoudl you put
ld c,0
just after line
jr z,spacep
??

Por Daemos

Paragon (2044)

imagem de Daemos

11-01-2011, 21:54

Maybe I wasn't clear enough. here is the thing I am doing. In main: I do the call to waitspace:
Then the space key is being read and when this is the case waitspace: jumps to spacep: and sets c to 1 via the ld c,1 command and then issues the return to main. The main loop continues its work and checks if C is truly 1 by simply comparing bit 0 from that register in case bit 0 in C = 1 the zero flag gets set and thus the program should end. In case this bit is not set the main loop starts all over again.

This is just a practice thingy. There could also be 3 different calls from main that for example play a sound or print a char to the screen but I started easy by creating a space key detect call that main can call in order to exit.

Somehow under no condition I get good results, either the program exits before I ever get the chance to press the space key or the program stays in the loop forever.

Am I trying something impossible here? Does the c register get reset after you issue a return command?

Por Daemos

Paragon (2044)

imagem de Daemos

11-01-2011, 22:33

Solved LOL!

Forgot to return from the routine if nothing happens and therefore always the same value was passed to the main routine. Thank you for your help.

Por Manuel

Ascended (19270)

imagem de Manuel

11-01-2011, 23:11

Are you clear on when using 'jr' and when using 'call'? 'ret' is only meant to return after a 'call'. jr is more like GOTO. 'call' is more like GOSUB.

EDIT: never mind.

Por Daemos

Paragon (2044)

imagem de Daemos

12-01-2011, 01:14

I will post the result soon to clear up what I am doing.

Thanks for the reply Manuel, I do understand the difference between jr and call

I have now extended my practice to a somewhat bigger program. Now I have build a esc key routine that exits the program and pressing any character key displays that character onto the screen.
All I need to do is figure how to get 1 character on the screen per key press.

Por Daemos

Paragon (2044)

imagem de Daemos

12-01-2011, 14:42

So here is the little tryout program that I have made. It works Big smile to my joy but offcourse I wonder if there are no easier ways to do this. I guess my code is ugly and very inefficient and all that parsing of variables is to my guess not the way it should be done. I have build this program by using all the knowledge I could understand from the manuals I have read and by reading through all of the forum thread over here.

The question now remains: What parts of the code could I have done better? Are there easier ways to achieve what I am doing? The parsing of variables, are there more convenient methods for that? I have many loops and labels, are there ways to reduce these?
stated in a better way. Go ahaid and bash my code and give me hints and examples. I can take pro tech talk but not too much Wink

;Little tryout to make typed character visible on the console screen
;the bios call chput is used to print the predefined characters after
;keyread and the esc key is used to exit the program

KEY:    EQU   &HFBE7          ;key adress starting at FBE7 where the first letter is found
CHPUT:  EQU   &HA2
        ORG   &HC000
        EI			;Somehow this MUST be enabled for this program to work

;main loop first checks if escape key is pressed then read one key prints the character
;and waits until the user releases the character until repeat

MAIN:   LD    C,0
        CALL  ESCK
        BIT   0,C
        RET   NZ
        CALL  CHREAD
        BIT   0,C
        JR    NZ,DO
        JR    MAIN

DO:     CALL  PRINT
DOA:    CALL  CHREAD   ;loop until key is released
        BIT   0,C
        JR    NZ,DOA
        JR    MAIN


;print one character



PRINT:  LD    HL,KARA
        LD    A,E
        LD    C,0
        CP    C
        JR    Z,SKELP
        LD    B,E
;row select
ELP:    INC   HL
        INC   HL
        INC   HL
        INC   HL
        INC   HL
        INC   HL
        INC   HL
        INC   HL
        DJNZ  ELP
        LD    B,0


SKELP:  LD    A,D
        LD    B,0
ALP:    RLC   A   ;keep shifting bits until the keypress is found
        INC   B
        JR    NC,PLOOP

        JR    ALP

PLOOP:  INC   HL  ;keep incrementing until correct predefined character is selected
        DJNZ  PLOOP

        LD    A,(HL)

        CALL  CHPUT ;put character on screen
        LD    C,0
        RET






;lees toetsenbord en return
;zodra er een toets is
;ingedrukt die een letter =
;input = geen waarde
;output 8 bits rij in d
;kolom in e
;spatie word apart uitgelezen
;en geeft direct een return met waarde
;indien waar


CHREAD: LD    B,4             ;4 rows to be read from ram
        LD    C,0
        LD    HL,KEY
        CALL  SPACEK
        BIT   0,C
        RET   NZ

CHLOOP: LD    A,(HL)
        LD    D,&B11111111
        CP    D
        INC   HL

        JR    NZ,KPRESS       ;key pressed?
        DJNZ  CHLOOP          ;rows scanned
        RET
KPRESS: LD    D,A             ;8bit row
        LD    A,4
        SUB   B               ;invert row count number for character printer

        LD    E,A             ;column
        LD    C,1             ;tell main that a key was pressed
        RET

SPACEK: LD    C,0		;read spacekey and return its value
        LD    A,(KEY+6)
        BIT   0,A
        JR    Z,SPPRES
        RET
SPPRES:
        LD    D,A
        LD    E,4
        LD    C,1
        RET

ESCK:				;read escape key as requested by main
        LD    C,0
        LD    A,(KEY+5)
        BIT   2,A
        JR    Z,ESPRES
        RET

ESPRES: LD    C,1
        RET




;define asci characters and locate them into the ram


KARA:   DEFB  " ba /.,`'"
        DEFB  "jihgfedcrqponmlkz"
        DEFB  "yxwvuts        ",0





        END

Por ARTRAG

Enlighted (6923)

imagem de ARTRAG

12-01-2011, 18:07

you need EI becouse you relay on the ISR that update the data in the table KEY: you could avod this by reading directly the keyboard matrix

PS
try to use {code} {/code} for posting sources, or the result will be very bad to read (change { } to [ ])

Por commodorejohn

Expert (92)

imagem de commodorejohn

12-01-2011, 18:30

Are you clear on when using 'jr' and when using 'call'? 'ret' is only meant to return after a 'call'. jr is more like GOTO. 'call' is more like GOSUB.
Also, there's no particular reason to use JR unless you're (A) trying to make dynamically-relocatable code, or (B) really strapped for code space. JP takes an extra byte, but it's faster. Not a huge deal, but something to remember.

Por Edwin

Paragon (1182)

imagem de Edwin

12-01-2011, 20:24

JP is only faster if the jump is taken (condition is true). If not, then JR is faster.

Por Daemos

Paragon (2044)

imagem de Daemos

12-01-2011, 20:30

JP is only faster if the jump is taken (condition is true). If not, then JR is faster.

like?:

jump:	ld a,0
	bit 0,a
	jp z,jump  ;faster because condition is true
	jr nz,jump ;jump has not been taken yet using jp nz,jump would be slower

Página 1/2
| 2