DATA init w. asm_memcpy fails on 8080

Bug reports (if you don't/won't have a Github account)
Post Reply
ahjelm
New member
Posts: 6
Joined: Tue Nov 09, 2021 7:30 pm

DATA init w. asm_memcpy fails on 8080

Post by ahjelm »

Hi. I'm working with a classic lib port for a 8085 board "Micro8085" (https://hackaday.io/project/176653-micro8085) which I've developed. Target has ROM/EEPROM at $0000 and RAM at $8000-FFFF (i.e. crt_model 1). I've followed the documentation on how to add a new target, and I believe that in a while I will have a candidate target to add.

But to the point: To the best of my knowledge there may be a bug in the combination/interaction of crt_section.asm and asm_memcpy.asm where the latter is located in libsrc\_DEVELOPMENT (indicating it belongs to new_lib?). When initialization of data (i.e. c defined variables with an initial value) shall execute, the crt_section assigns pointers to hl and de, and length in bc. But the call to asm_memcopy appears to do nothing.

Code: Select all

    ld  hl,__ROMABLE_END_tail
    ld  de,__DATA_head
    ld  bc,__DATA_END_tail - __DATA_head
    EXTERN  asm_memcpy
    call    asm_memcpy
The c variables never got their values, and when dissasembling the generated code, the opcode 0x28 appears (which is jr z,d8 for a z80 but will be ld de,hl+d8 for a Intel80). Looking at asm_memcpy source, the instruction jr z, zero_n is present without any IF selecting CPU type. It doesn't crash, but it will not copy the data.

My workaround in crt_section.asm (skips the call to asm_memcpy and does the work itself):

Code: Select all

IF ( __crt_model = 1 )
    ; Just copy the DATA section
    EXTERN      __ROMABLE_END_tail
    EXTERN      __DATA_head
    EXTERN      __DATA_END_tail
; ## BUG Calling asm_memcpy in _DEVELOPMENT (new_lib) renders ##
; ## faulty code for Intel CPU, hence conditional replacement ##
  IF !__CPU_INTEL__
    ld  hl,__ROMABLE_END_tail
    ld  de,__DATA_head
    ld  bc,__DATA_END_tail - __DATA_head
    EXTERN  asm_memcpy
    call    asm_memcpy
  ELSE
    ld      hl,__ROMABLE_END_tail + 1
    ld      de,__DATA_head + 1
    ld      bc,__DATA_END_tail - __DATA_head - 1
datacpy:
    ld      a,b
    or      c
    ret     z
    ld      a,(hl)
    ld      (de),a
    inc     hl
    inc     de
    dec     bc
    jp      datacpy
  ENDIF
ELIF ( __crt_model >= 2 )
...etc...
I added the +1 +1 -1 to copy exactly the data/length and suppress the preceeding zero, but perhaps that's not necessary... It works down to zero length (no copy).

My best regards to all contributors to the z88dk /A.
User avatar
dom
Well known member
Posts: 1506
Joined: Sun Jul 15, 2007 10:01 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by dom »

I'll look into that - we've got 8080/5 code in memcpy so I need to figure out why it's not being invoked.

Regarding this:

Code: Select all

datacpy:
    ld      a,b
    or      c
    ret     z
    ld      a,(hl)
    ld      (de),a
    inc     hl
    inc     de
    dec     bc
    jp      datacpy
This code is in the code_crt_init section which is added to (as needed) by library routines. As a result you shouldn't ret from code put into that section.
So, on on 8085, I think you can just do this?

Code: Select all

datacpy:
    ld      a,(hl)
    ld      (de),a
    inc     hl
    inc     de
    dec     bc
    jp      nk,datacpy
ahjelm
New member
Posts: 6
Joined: Tue Nov 09, 2021 7:30 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by ahjelm »

Yes, my workaround code was written to accept also the 8080. For 8085 the jp k/nk is fine but I believe one must use pre decrement of the loopvar and jump out when flag is true, otherwise there will be one extra copy performed. This code snippet works in my workaround section:

Code: Select all

datacpy:
    dec     bc
    jp      k,donecpy
    ld      a,(hl)
    ld      (de),a
    inc     hl
    inc     de
    jp      datacpy
donecpy:
    ;done (k-flag true when decrement overflows 0 -> ffff)
User avatar
dom
Well known member
Posts: 1506
Joined: Sun Jul 15, 2007 10:01 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by dom »

Doh, I created a nice off-by-one there.

I've just had a little investigate into the 8080 library using the +test target, it looks like the correct implementation of asm_memcpy() is being pulled in:

Code: Select all

asm_memcpy:
                    ld      a,b                             ;[093d] 78
                    or      c                               ;[093e] b1
                    jp      z,zero_n                        ;[093f] ca 50 09
asm0_memcpy:
                    push    de                              ;[0942] d5
loop:
                    ld      a,(hl)                          ;[0943] 7e
                    inc     hl                              ;[0944] 23
                    ld      (de),a                          ;[0945] 12
                    inc     de                              ;[0946] 13
                    dec     bc                              ;[0947] 0b
                    ld      a,b                             ;[0948] 78
                    or      c                               ;[0949] b1
                    jp      nz,loop                         ;[094a] c2 43 09
                    pop     hl                              ;[094d] e1
                    or      a                               ;[094e] b7
                    ret                                     ;[094f] c9
The fact that you're seeing jr z rather than jp z, suggests to me that the wrong library (i.e. a z80 library) is being linked rather than the base 8080 library. The "correct"/"recommended" linking options for an 8085 would be:

Code: Select all

-m8085  -startuplib=8080_crt0 -l8085_opt -custom-copt-rules=DESTDIR/lib/arch/8085/8085_rules.1
What do you have in your target cfg file?
ahjelm
New member
Posts: 6
Joined: Tue Nov 09, 2021 7:30 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by ahjelm »

Hi, my config file (micro8085.cfg) is:

Code: Select all

# Asm file which contains the startup code (without suffix)
CRT0      DESTDIR\lib\target\micro8085\classic\micro8085_crt0

# Any default options you want - these are options to zcc which are fed through to compiler, assembler etc as necessary
OPTIONS   -m -O2 -SO2 -M --list -subtype=default -clib=default

CLIB      default -Cc-standard-escape-chars -m8085 -lndos -l8085_opt -lmicro8085_clib -LDESTDIR\lib\clibs\8085 -custom-copt-rules=DESTDIR\lib\arch\8085\8085_rules.1

SUBTYPE   default -Cz+hex

INCLUDE   alias.inc
This is mostly reverse engineered from other 8080/8085 cfg files in the package, so I might of course have missed something. (Especially the -lndos option is one that I haven't looked that much into.)

The command line is:

Code: Select all

zcc +micro8085 micro8085.c -o micro8085.bin -create-app
Thanks, A
User avatar
dom
Well known member
Posts: 1506
Joined: Sun Jul 15, 2007 10:01 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by dom »

ahjelm wrote: Thu Nov 11, 2021 2:55 pm Hi, my config file (micro8085.cfg) is:

Code: Select all

# Asm file which contains the startup code (without suffix)
CRT0      DESTDIR\lib\target\micro8085\classic\micro8085_crt0

# Any default options you want - these are options to zcc which are fed through to compiler, assembler etc as necessary
OPTIONS   -m -O2 -SO2 -M --list -subtype=default -clib=default

CLIB      default -Cc-standard-escape-chars -m8085 -lndos -l8085_opt -lmicro8085_clib -LDESTDIR\lib\clibs\8085 -custom-copt-rules=DESTDIR\lib\arch\8085\8085_rules.1

SUBTYPE   default -Cz+hex

INCLUDE   alias.inc
Yes, that's it! The default value of -startuplib is z80_crt0 so it's pulling in the z80 stdlib rather than the 808x one. Add the option -startuplib=8080_crt0 to the CLIB line and hopefully that will sort everything out!
ahjelm
New member
Posts: 6
Joined: Tue Nov 09, 2021 7:30 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by ahjelm »

Yes! With that lib added in cfg file I could reverse my workaround code and still get variables initiated. Thanks!

Off topic: Is there some tutorial or documentation/procedure on how to submit a new target to the z88dk? Or some review one must pass, etc. Perhaps you could point me in the right direction?

Again, thanks /A
User avatar
dom
Well known member
Posts: 1506
Joined: Sun Jul 15, 2007 10:01 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by dom »

ahjelm wrote: Thu Nov 11, 2021 7:16 pm Yes! With that lib added in cfg file I could reverse my workaround code and still get variables initiated. Thanks!
Fantastic - a lot more things should now also work!!
Off topic: Is there some tutorial or documentation/procedure on how to submit a new target to the z88dk? Or some review one must pass, etc. Perhaps you could point me in the right direction?
Nothing really formal, just raise a PR and I'll take a look at it, I suspect @feilipu will take a look as well since he's done fair chunk of 8085 work recently.

There's a couple of things that aren't obvious:

- Updating doc/features/features.csv and regenerating include/features.h using the awk script
- Wiki page linked from: https://github.com/z88dk/z88dk/wiki/Platform (base off +radio86 for example)
ahjelm
New member
Posts: 6
Joined: Tue Nov 09, 2021 7:30 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by ahjelm »

Ok. I probably took a shortcut as I started implementing direct on a downloaded nightly build, but I guess I will need to clone repo from GitHub to get things right? Not familiar with GitHub, but I've created an account, and I guess I'll figure things out.. I'll be back.
User avatar
dom
Well known member
Posts: 1506
Joined: Sun Jul 15, 2007 10:01 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by dom »

No worries - just email me/upload somewhere the changed files if you want and I can add it in.
ahjelm
New member
Posts: 6
Joined: Tue Nov 09, 2021 7:30 pm

Re: DATA init w. asm_memcpy fails on 8080

Post by ahjelm »

dom wrote: Fri Nov 12, 2021 11:01 am No worries - just email me/upload somewhere the changed files if you want and I can add it in.
I sent you an email as discussion is wandering a bit off topic :)
Post Reply