CPCWiki forum

General Category => Programming => Topic started by: ced64k on 12:18, 08 February 14

Title: [HELP] Still trying to learn assembly
Post by: ced64k on 12:18, 08 February 14
Two years after, I have to admit that my assembly skills are still close to zero  :D

I setup this The ultimate cross-development IDE (http://pushnpop.net/articles-76.html). It's a combination of PSPad, SjASMPlus, WinApe and custom scripts. It seems really nice, you wrote your assembly code, press F9 and it automatically opens your binary in WinApe.

 I configured all the stuff listed there with the COMPILE_and_CREATE_SNA_and_INSERT_SNA option.
 
 I'm able to compile this example:
 
 
Code: [Select]
OUTPUT "Generated/Main.bin"
 
 LD HL,#C000
 LD DE,#C001
 LD BC,#3FFF
 LD (HL),56
 LDIR 

 And Winape displays correctly the yellow vertical lines.

(http://i.imgur.com/Dvml4Rl.jpg)
 
 After I tried a little asm code that should display T on the screen.
 
 
Code: [Select]
OUTPUT "Generated/Main.bin"
 
 LD A,83
 ADD A,1
 CALL #BB5A
 RET

 The code is compiled without problem but Winape display a blank screen.

(http://i.imgur.com/k2dOoKT.jpg)

However the binary code seems to be correct:
 
 
Code: [Select]
3E53 C601 CD5A BBC9
Is it because SjASMPlus doesn't work with the Amstrad's #BB5A ?

Thanks :)

Title: Re: Still trying to learn assembly
Post by: gerald on 13:03, 08 February 14
It looks like the FW has not been initialized, so BB5A and any other FW routine jumpblock is not in initialised.
This is a side effect of using a snapshot : the CPC is configured from that snapshot, and it is unlikey that the development environment generate a FW initialised snapshot.
You better use the DSK method, which will run after the FW and BASIC are initialised.



Title: Re: Still trying to learn assembly
Post by: ced64k on 15:29, 08 February 14
I have problem to generate the .dsk with cpcfs, it can't find the .bin, I have to check why.

But I had a reply from Targhan himself, and now it works with the sna.

Quote
It seems normal to me. Because the system is gone! If you look at the scripts/snapshot.cfg file, you see that the only thing that the CPC has in memory is... nothing at all except your own code. Only the CRTC is initialized, the stack, as well as some colors for the Gate Array.
 
 If you want to use the system, you could create a snapshot with Winape after the CPC has booted, and use it as a starting point, instead of creating a "blank" one with createsnapshot like in my scripts. It won't work like that directly, because the system has its own "life" and I won't expect your final "RET" to work as you will expect (where would the system "go" anyway?).
 
 So my suggestion is this. If you program starts at &4000, we will poke something two bytes before (#3ffe).
 - Run Winape. In Basic:
 - poke &3ffe,&18
 - poke &3fff,&fe
 - call &3ffe
 
 We have poked a "JR $" in memory, so an infinite loop is performed. Note that the system is still OK because the interruptions are still on.
 
 Open the Winape debugger and put a breakpoint at #3ffe. Click on "Play" to be sure the Z80 is really at the location (this is to be sure the Program Counter is really inside your program, and not somewhere in the ROM because the system wants to do its job (changing the colors, checking the keyboard, and so on.)). Save this as a snapshot (baseSnapshot.sna).
 
 In your scripts/snapshot.cfg file, remove all the lines, and type this:
 -i <path to my baseSnapshot.sna>
 -l Generated\Main.bin 0x3ffe    --> load here you main.bin, exactly where we have poked the two bytes before.
 
 In your main code, make it start at #3ffe instead of #4000, beginning with two NOPS, so that it will clear the infinite loop, allowing your real program to start. Example:
 org #4000 - 2
 nop   ;Clear the infinite loop
 nop
 ;The real code starts here.
 LD A,83
 ADD A,1
 CALL #BB5A
 RET
 
 I haven't tested this but it should work :) .
 
 Remember that since you want to use the system and return from your program gracefully, that you must NOT modify some auxiliary registers (AF' and BC' only, actually) or modify the stack. If you want to do so, you must stop the interruption (EI), save AF', BC', SP, do your stuff, restore AF', BC' and SP, and the interruptions (EI). Nothing to be afraid of!
 
 Keep me posted of your progress!
Title: Re: Still trying to learn assembly
Post by: ced64k on 21:57, 13 February 14
I'm reading the Z80 initiation the french website Quasar (http://quasar.cpcscene.com).

One of the first example, a simple loop:

Code: [Select]
         ORG &5000
         LD HL,TEXT
LOOP LD A,(HL)
         CP 0
         RET Z
         CALL &BB5A
         INC HL
         JP LOOP
;
TEXT   DB "Hello!",0

If I assemble that in Maxam under Arnold emulator, then CALL &5000 in Basic, it works, I see the text "Hello!".
If I assemble with Pasmo, load the bin with Arnold, the emulator reset. Really reset, if I type CALL &5000, I see only "Ready".

However the hex code generated by Maxam and my .bin are the same:

Code: [Select]
210E50
7E
FE00
C8
CD5ABB
23
C30350
426F6E6A
6F757220
2100

What's missing?
Title: Re: [HELP] Still trying to learn assembly
Post by: fano on 22:33, 13 February 14
What is the execution and load address in your file header created with pasmo ?
Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 22:48, 13 February 14
Ahh yes thanks, my iDSK command line wasn't correct.

Code: [Select]
iDSK $project_path/generated/$file_base_name.dsk -i $project_path/generated/$file_base_name.bin -e 8000 -c 8000 -t 1 -f;

Works better with 5000  :laugh: I didn't understand well the link between the ORG and the dsk.

Now I can see the text a second before the reset. I tried a &bb06 but it doesn't stop. You said newbie ?  :P
Title: Re: [HELP] Still trying to learn assembly
Post by: fano on 05:39, 14 February 14
Do you just " run " or load it in basic and call #5000 after ?
Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 08:23, 14 February 14
run
Title: Re: [HELP] Still trying to learn assembly
Post by: fano on 09:11, 14 February 14
Perfectly normal, your program finish with a ret.when you return after a run from asm prog, system reset.
Title: Re: Still trying to learn assembly
Post by: arnoldemu on 13:51, 14 February 14
If I assemble that in Maxam under Arnold emulator, then CALL &5000 in Basic, it works, I see the text "Hello!".
If I assemble with Pasmo, load the bin with Arnold, the emulator reset. Really reset, if I type CALL &5000, I see only "Ready".
correct, and it happens on a real cpc.

When you run a program, it is executed with MC START PROGRAM, if it returns there is a reset.
If you load and call it, return goes back to basic.

Also, if you run it, AMSDOS rom will be disabled, you need to call MC WALK ROMS (not sure it's correct name. It's &BCCB). MC START PROGRAM disables all roms so you have to get firmware to re-enable them again.

With load and call, all roms remain active and AMSDOS is active.

Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 14:04, 14 February 14
So to stay in the program I have to add a CALL &BB06 before the RET Z ?
Title: Re: [HELP] Still trying to learn assembly
Post by: arnoldemu on 15:48, 14 February 14
So to stay in the program I have to add a CALL &BB06 before the RET Z ?
If you did that, you would need to press a key for each letter you draw.

Best to do a CALL LOOP, then a CALL &BB06 then a RET.
So you call the print function, return to wait for a keypress then return.
Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 16:16, 14 February 14
I don't understand where to put that. I presume that the loop starts with the LOOP label and ends with JP LOOP.
I removed the RET Z and tried with :

Code: [Select]
    ORG &5000
    LD HL,TEXT
LOOP    LD A,(HL)
    OR A
    CALL &BB5A
    INC HL
    JP LOOP
    CALL LOOP
    CALL &BB06
    RET
;
TEXT    DB "Hello!",0

I see Hello! for 5 seconds and after the screen goes crazy with all colors and characters (maybe my first demo ? :D)
Title: Re: [HELP] Still trying to learn assembly
Post by: redbox on 16:25, 14 February 14
I don't understand where to put that. I presume that the loop starts with the LOOP label and ends with JP LOOP.
I removed the RET Z and tried with :

Instead of RET Z, you can use a JP Z (or JR Z) to your "exit" routine.

Code: [Select]
           ORG &5000

           LD HL,text

.loop      LD A,(HL)
           CP 0
           JR Z,finished
           CALL &BB5A
           INC HL
           JP loop

.finished  CALL &BB06
           RET

.text      DB "Hello!",0
Title: Re: [HELP] Still trying to learn assembly
Post by: arnoldemu on 16:56, 14 February 14
I would do it like this:

Code: [Select]
    ORG &5000
    LD HL,TEXT
    CALL LOOP
    CALL &BB06
    RET
LOOP    LD A,(HL)
    CP 0
    RET Z
    CALL &BB5A
    INC HL
    JP LOOP
;
TEXT    DB "Hello!",0
Title: Re: [HELP] Still trying to learn assembly
Post by: redbox on 17:00, 14 February 14
I would do it like this:

So would I probably, but it's a bit harder to see what's going on  ;)
Title: Re: [HELP] Still trying to learn assembly
Post by: arnoldemu on 17:01, 14 February 14
Your code is working like this:

Code: [Select]
    ORG &5000
    LD HL,TEXT ;; location of string to display
    CALL LOOP ;; display a string (what happens here is it is like a GOSUB in BASIC. We execute code and when a RET or RET with condition is seen, return back to the instruction after this call)
    CALL &BB06 ;; wait for key press so we can see the message
    RET ;; and quit.
LOOP    LD A,(HL) ;; read character
    CP 0 ;; is it zero (the special character which comes after the last character of the string and marks it's end)
    RET Z ;; return if we found 0, else continue.
    CALL &BB5A ;; print character
    INC HL ;; update HL so it points at the next character
    JP LOOP ;; and perform the loop
;
TEXT    DB "Hello!",0 ;; Text to display, 0 indicates end.

Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 17:03, 14 February 14
Thanks, both examples work. I'm starting to understand.
Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 21:20, 14 February 14
For those who are interested, I put my Mac OS "IDE" on GitHub (https://github.com/ced64k/cpc-mac-asm). Sublime Text + Pasmo + iDSK + AppleScript + Arnold.
Title: Re: [HELP] Still trying to learn assembly
Post by: ced64k on 11:20, 16 February 14
On the Where_to_learn wiki page, there's a link to  Independent Z80 Assembly Guide (http://www.ticalc.org/pub/text/z80/z80asmg.zip): "You can use all of this code with a CPC or CPC emulator and it will work"

It seems well written but all the codes use this strange syntax with "variable" inside brackets (TI-83 asm I think). That returns an error if I compile this kind code, "Symbol Height is undefined". It seems logical because there's no label Height.

Code: [Select]
ld a,(Height)                  ; loading Height into A
Title: Re: [HELP] Still trying to learn assembly
Post by: arnoldemu on 11:42, 16 February 14
That is normal syntax when using labels.

Was this label missing? I say this because assemblers do have differences in how they define labels.

Pasmo defines a label with a colon : at the end.
Maxam defines a label with a dot at the start.
Some require and in columns with label in first column, instruction in second and comment in third.

I found I had to change labels in some code to build with pasmo.

It is this fact I try to say which assembler to use for my examples.