News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_ced64k

[HELP] Still trying to learn assembly

Started by ced64k, 11:18, 08 February 14

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ced64k

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

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.



After I tried a little asm code that should display T on the screen.

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.



However the binary code seems to be correct:

3E53 C601 CD5A BBC9

Is it because SjASMPlus doesn't work with the Amstrad's #BB5A ?

Thanks :)


gerald

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.




ced64k

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.

QuoteIt 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!

ced64k

I'm reading the Z80 initiation the french website Quasar.

One of the first example, a simple loop:


         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:


210E50
7E
FE00
C8
CD5ABB
23
C30350
426F6E6A
6F757220
2100


What's missing?

fano

What is the execution and load address in your file header created with pasmo ?
"NOP" is the perfect program : short , fast and (known) bug free

Follow Easter Egg products on Facebook !

ced64k

Ahh yes thanks, my iDSK command line wasn't correct.


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

fano

Do you just " run " or load it in basic and call #5000 after ?
"NOP" is the perfect program : short , fast and (known) bug free

Follow Easter Egg products on Facebook !

ced64k


fano

Perfectly normal, your program finish with a ret.when you return after a run from asm prog, system reset.
"NOP" is the perfect program : short , fast and (known) bug free

Follow Easter Egg products on Facebook !

arnoldemu

Quote from: ced64k on 20:57, 13 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.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ced64k

So to stay in the program I have to add a CALL &BB06 before the RET Z ?

arnoldemu

Quote from: ced64k on 13:04, 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.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ced64k

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 :


    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)

redbox

Quote from: ced64k on 15: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 :

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


           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


arnoldemu

I would do it like this:


    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
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

redbox

Quote from: arnoldemu on 15:56, 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  ;)

arnoldemu

Your code is working like this:


    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.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ced64k

Thanks, both examples work. I'm starting to understand.

ced64k

For those who are interested, I put my Mac OS "IDE" on GitHub. Sublime Text + Pasmo + iDSK + AppleScript + Arnold.

ced64k

#19
On the Where_to_learn wiki page, there's a link to  Independent Z80 Assembly Guide: "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.

ld a,(Height)                  ; loading Height into A

arnoldemu

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.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Powered by SMFPacks Menu Editor Mod