Giter Club home page Giter Club logo

z88dk / z88dk Goto Github PK

View Code? Open in Web Editor NEW
854.0 56.0 162.0 240.97 MB

The development kit for over a hundred z80 family machines - c compiler, assembler, linker, libraries.

Home Page: https://www.z88dk.org

License: Other

Makefile 0.48% Shell 0.01% C++ 0.44% C 44.42% Batchfile 0.04% M4 3.72% Assembly 46.36% HTML 1.14% Perl 1.72% Awk 0.11% Roff 1.51% Ragel 0.03% Dockerfile 0.01% Lex 0.01% Yacc 0.01% CMake 0.01% BitBake 0.01%
z80 z180 z88dk sdcc c-compiler assembler linker assembly-language asm embedded

z88dk's Introduction

Z88DK - The Development Kit for Z80 Computers

WinXP+ MacOSX Linux and Other

Z88DK is a collection of software development tools that targets the 8080 and z80 family of machines. It allows development of programs in C, assembly language or any mixture of the two. What makes z88dk unique is its ease of use, built-in support for many z80 machines and its extensive set of assembly language library subroutines implementing the C standard and extensions.

INSTALLATION

There are several ways to install z88dk.

  1. Use the Most Recent Official Release. Follow these installation instructions.
  2. Get the Nightly Build. Every night we build complete binary packages for windows and osx and generate source packages for everyone else. The same installation instructions apply. Using a nightly build means you can keep up with bugfixes and new features rather than having to wait an entire year for a release to occur.
  3. Use the Snap package on Linux
  4. Use the Docker image
  5. Use GitHub and build it yourself. The z88dk repository uses git submodules, these are not automatically downloaded by git by default so you will have to either adjust your clone line, or retrieve them manually. To clone with submodules use git clone --recursive https://github.com/z88dk/z88dk.git. To add the submodules to an already existing clone use git submodule update --init --recursive. To build, the following instructions should be followed.

The Tools

Many tools have a z88dk- prefix to distinguish them from tools from other packages that may be installed with the same name. The documentation generally omits the prefix when referring to them.

  • zcc is the toolchain's front end. zcc can generate an output binary out of any set of input source files.
  • z88dk-sccz80 is z88dk's native c compiler. sccz80 is derived from small c but has seen much development to the point that it is nearly c90 compliant.
  • z88dk-zsdcc is z88dk's customization of the sdcc compiler. Our patch makes sdcc compatible with the z88dk toolchain, gives it access to z88dk's extensive assembly language libraries and ready-made crts, addresses code generation bugs where present and improves on sdcc's generated code.
  • z88dk-z80asm (not to be confused with several external projects called z80asm) is a fully featured assembler / linker / librarian implementing sections.
  • z88dk-z80nm is z80asm's companion archiver. It can provide a listing of functions or data encoded in an object or library file.
  • z88dk-appmake processes the raw binaries generated by the toolkit into a form suitable for specific target machines. For example, it can generate intel hex files, tapes, ROMs, etc.
  • z88dk-ticks is a command line emulator that can be used to time execution speed of code fragments. Ticks includes a debugger and disassembler.
  • z88dk-gdb provides the debugger interface from ticks and connects to a gdbserver to permit line-by-line debugging of software in emulators or on real hardware.
  • z88dk-dis is a command line disassembler for 8080, 8085, GBZ80, Z80, Z180, Z80N, EZ80, R800 and Rabbit 2000/3000. It can additionally read map files generated by z80asm to provide a more symbolic output.
  • z88dk-lib is an installer for third party libraries. It manages installation, removal and listing of available libraries.
  • z88dk-zx0 and z88dk-zx7 are PC side data compression tools with companion decompression functions in the z80 library.
  • z88dk-dzx0 and z88dk-dzx7 are PC-side decompressor counterparties to the z88dk-zx0 and z88dk-zx7.

These tools are not normally directly invoked by the user:

  • m4 acts as z88dk's macro preprocessor and can optionally process files ahead of the c preprocessor or assembler.
  • z88dk-ucpp is the c preprocessor invoked for sccz80 and for zsdcc.
  • z88dk-zpragma is used by the toolchain to process pragmas embedded in c source.
  • z88dk-copt is a regular expression engine that is used as peephole optimizer for sccz80 and as a post-processing tool for both sccz80 and zsdcc.

Benchmarks

The assembly language libraries supplied by z88dk give it performance advantages over other z80 compilers. For details please look at the Benchmarks section in the Wiki.

  • Dhrystone 2.1 Dhrystone was a common synthetic benchmark for measuring the integer performance of compilers in the 1980s until more modern benchmarks replaced it. It attempts to simulate typical programs by executing a set of statements statistically determined from common programs.
  • Pi Mainly measures 32-bit integer performance.
  • Sieve of Eratosthenes Popular benchmark for small machine compilers because just about everything is able to compile it. As a benchmark it doesn't reveal much more than loop overhead.
  • Whetstone 1.2 Whetstone is a common synthetic floating point benchmark.
  • Program Size Program size has great importance for small machines. A collection of test programs were compiled for the common cp/m target and resulting binary sizes were compared.

Using cmake to build z88dk projects

CMake can be used to build Z88DK projects (a toolchain is provided). Please refer to CMake wiki.

Using z88dk

Some things to know:

  • There are two c libraries in z88dk. These are referred to as the classic c library and the new c library.
  • There are two c compilers in z88dk. Projects built using the classic library can mix object files generated by the both compilers. Projects built with newlib must use only one of the compilers.

When you form a compile line you must decide which compiler you will use and which c library you will link against. You will make that decision based on which targets you want to compile for and what features you need.

The classic c library is z88dk's main c library and has crts that allow generation of programs for over 100 different z80 family machines. The level of support for each is historically determined by user interest. Documentation begins here and example programs can be found in z88dk/examples with compile lines most often appearing at the top of .c files. Over time it has replaced non-standard implementations with those that exist with new library.

The new c library was z88dk's rewrite aiming for a large subset of C11 conformance. The bulk of the standard library has now been incorporated into classic, however it still supports some targets not supported by classic: hbios, rc2014, scz180, yaz180 as well as some incorporating 3rd party libraries for some duplicated targets: sega master system, zx spectrum, and zx spectrum next. Additionally, a bare bones target for the z180, z80 can be used to compile programs for any z80 machine. Documentation begins here and example programs can be found in z88dk/libsrc/_DEVELOPMENT/EXAMPLES with compile lines most often appearing at the top of .c files.

Quick links

Z88DK Home Page Includes a link to the nightly builds where you can get an up-to-date package.

Install Instructions

Bug Reporting

Introduction to Compiling Using the Classic C Library Examples in z88dk/examples

Introduction to Compiling Using the New C Library Examples in z88dk/libsrc/_DEVELOPMENT/EXAMPLES

Using z88dk with the rc2014 target, covers cpm, hbios, and rc2014 subtypes.

Using z88dk with zx, covers the zx target, and by extension the zxn target.

z88dk's People

Contributors

ahjelm avatar aralbrec avatar ashitani avatar b4yuan avatar baltasarq avatar bradstallion avatar brijohn avatar derekfountain avatar desertkun avatar dikdom avatar dp304 avatar empathicqubit avatar feilipu avatar florentflament avatar frodevan avatar heronerin avatar hojoe42 avatar iratahack avatar jorgegv avatar jurajlutter avatar kp1533tm2 avatar litwr avatar nippur72 avatar paintedblck avatar pauloscustodio avatar ped7g avatar pjshumphreys avatar qwazywabbitwos avatar suborb avatar zx70 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

z88dk's Issues

new c lib (+zx): bifrost and nirvana sprite engines should be completely incorporated into z88dk

Currently the library contains an interface only to the bifrost and nirvana engines which are nominally distributed in binary form. To build a program, the user is expected to load the engine binary separately into memory and is expected to source that binary from the author's website.

We can include the entire engine source into z88dk. This has a number of advantages :- z80asm is a linking assembler so it can exclude unused functions from the output binary and can eliminate holes left by conditional assembly which the author is currently using to reduce memory requirements.

z80asm can output a separate bifrost or nirvana binary automatically if the program accesses functions from that engine and the org can be set at library build time. There would be no need to source the engine binary separately from the author's website except to update z88dk's copy if the author makes changes.

zsdcc: delayed error reporting for function prototypes missing terminating semicolon (K&R issue)

This is from a bug report in the forums before the switch to git.

The complaint was in code like this:

#ifndef __MYFILE_H__
#define __MYFILE_H__

void just_some_function(int some_param)   // <=== forgot ;

#endif    //__MYFILE_H__

and

#include "MyFile.h"

void some_other_function(int some_param)
{                                                               // <=== syntax error report on '{'
   // blabla
}

The missing semicolon is not detected in "MyFile.h" but shows up as an error inside "some_other_function()" in another file. This caused a great deal of extra debugging time for what is a trivial mistake.

The compiler saw this after preprocessing:

void just_some_function(int some_param)   // <=== forgot ;

void some_other_function(int some_param)
{                                                               // <=== syntax error report on '{'
   // blabla
}

The reason why sdcc does not complain about the missing semicolon in the right place is that I believe it is a reflection of the halfway support sdcc has for K&R function syntax. sdcc does not support K&R currently but that is something on its to-do list. I think the scanner portion of sdcc may recognize it but the parser / code generator portion does not so the recognition of an error is delayed.

K&R syntax allows types of function parameters to be declared after the function header itself like so:

void func(a,b,c)
int a;
char b;
long c;
{
   ...
}

and if you compare this to the original problem file you will see the compiler seems unable to determine there was an error until the declaration following the prototype with missing semicolon is completely parsed.

The situation is a little worse than that. In this case:

void just_some_function(int some_param)   // <=== forgot ;

int a;

void some_other_function(int some_param)
{                                                               // <=== syntax error report on '{'
   // blabla
}

sdcc is unable to determine there is an error until it's inside some_other_function(). It should be able to report an error at "int a;". This is an error under K&R because "a" does not match the name of any parameter given to just_some_function().

I believe the reason it gets this far is a partial recognition of K&R syntax inside sdcc.

This is not an error but may cause grief in debugging and is something that must be dealt with by the sdcc team.

new c lib: scanf of floats %aefg unsupported

In the new c lib you can printf floats but you can't scanf them. The recommended workaround is to first scan as a string using %s or %[ and then use strtod() or atof() to do the float conversion.

What is missing is a state machine in the stdio library that examines an incoming char stream and decides where a float ends. This is complicated by the fact that floats can take on a number of forms:

  • 123
  • 123.
  • .
  • .123
  • 123.123
  • variations with exponent e
  • hex floats 0xabc.123P-28
  • special strings "nan", "infinity" etc

new c lib (+sms): incorporate devkitSMS into z88dk

DevkitSMS is currently the main game engine used for c programs amongst Sega Master System users.

They currently use sdcc and several tools in a complicated manner to generate binaries. Incorporation into z88dk will turn those things into a one-line compile, speed up and decrease size of programs, and give access to a complete c library.

z88dk: system install on unix-like systems unsupported

We are currently officially not supporting system installs on Unix-like systems.

The reason is mainly due to the new c library which encourages the user to customize the libraries for machines he is compiling for. The customization involves editing a configuration file and rebuilding the target's c library. Of course with a system install this means having to modify files stored in system directories which is not possible for users with user-level permissions. I'd also like to make it easy for users to define new crts for custom hardware or compiles (the main goal being custom instantiation of drivers on file streams). Again, this would involve writing into a system directory.

Instead I had the idea of storing the main z88dk install in system directories but also storing any customizations made by the user in his home directory. For this to work, ZCC would have to search first for customized bits in the user's home directory and then, on fail, search the system directories for any files not found.

z88dk: zsdcc and zsdcpp do not run on windows xp?

I have a report that win xp claims that the zsdcc and zsdcpp binaries are not 32-bit.

However, if I run gnu file on them I get this:
zsdcc.exe; PE32 executable for MS Windows (console) Intel 80386 32-bit

I'll doublecheck that the VS2015 settings used to compile these don't have some os version after WinXP ticked someplace.

new c lib: rewrite shellsort to be re-entrant

The new c library contains three sorting algorithms: insertion sort, shellsort and quicksort. Which one is used by the qsort() function depends on the library configuration but the default is to use shellsort because it is small and reasonably fast for the size of data sets likely to be sorted in casual use.

The only caveat for the shellsort implementation is that it is not re-entrant; the other sorting implementations are. The entire new c library is intended to be re-entrant except where prohibited by the standard (see eg strtok) so this is a bit of a sore.

The intention for shellsort is that it be small and reasonably fast; it is competing with insertion sort in these areas. The quicksort implementation is meant to be faster at the expense of code size.

The classic library uses the same shellsort function for its qsort so any improvement in the new c lib's version should be copied to the classic lib.

github: create a place to download windows and osx binaries from?

For people who are using github rather than downloading the nightly packages should we be offering a place to download the windows and osx binaries from?

We have the nightly builds to pick up quick up-to-date packages but for people using git we will need some simple instructions and a way to get z88dk running. I also made sure all the library binaries were committed for that purpose - maybe we can get the nightly build to update those as well?

sccz80: Forced cast issue

From: https://www.z88dk.org/forum/viewtopic.php?id=9673 (anton_sh):

Discovered bug of (at least) redundant casting of (unsigned char)
to (unsigned char) which and can be demonstrated using following
testcase:

#include <stdio.h>

unsigned char ex_var = 240;

#define _WITH_ASM_LABLES
//----------------------------------------------------------------
int main(int argc, char** argv) {
    unsigned char loc_var = 240;
    printf("Hello from main.");
#ifdef _WITH_ASM_LABLES
#asm
_dummy_before_if_ext:
    ld a, (_ex_var)
#endasm
#endif
    if (((unsigned char)ex_var) >= ((unsigned char)200)) {
        printf(" ex_var is >= 200;");
    } else {
        printf(" ex_var is < 200;");
    }
#ifdef _WITH_ASM_LABLES
#asm
_dummy_before_if_aut:
    ld a, (_ex_var)
#endasm
#endif
    if (((unsigned char)loc_var) >= ((unsigned char)200)) {
        printf(" loc_var is >= 200;");
    } else {
        printf(" loc_var is < 200;");
    }
    printf(" Bye!\n");
    return 0;
}

This will surprisingly give with the second "if" the message "loc_var is < 200".

The reason behind is the code generated to cast (unsigned char) to (unsigned char) again:

._main
    ld    hl,240    ;const
    ld    a,l
    call    l_sxt
    dec    sp
    ld    a,l
    pop    hl
    ld    l,a
    push    hl
    ld    hl,i_1+0
    push    hl
    ld    a,1
    call    printf
    pop    bc
    _dummy_before_if_ext:
    ld a, (_ex_var)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ld    h,0                 ; <- this is added by cast
                          ; here it does not yet create
                          ; big problem, just corrupt h
                          ; register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ld    a,(_ex_var)
    cp    #(200 % 256 % 256)
    jr    z,i_4_uge
    jp    c,i_4
.i_4_uge
    ld    hl,i_1+17
    push    hl
    ld    a,1
    call    printf
    pop    bc
    jp    i_5
.i_4
    ld    hl,i_1+36
    push    hl
    ld    a,1
    call    printf
    pop    bc
.i_5
    _dummy_before_if_aut:
    ld a, (_ex_var)
    ld    hl,0    ;const
    add    hl,sp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ld    h,0                 ; <- this is added by cast
                          ; here it is worse - instead of
                          ; reading the variable value from
                          ; stack to register "A" we read
                          ; some random value from ROM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ld    a,(hl)
    cp    #(200 % 256 % 256)
...

Following is my naive attempt to fix the problem. It helps to make my testcase working properly ("ld h, 0" disappers). I cannot judge, however, whether such cast to single byte ("ld h, 0") can
be dangerous in other situations - can imagine cases when for example value to be casted is not in HL register pair - so the fix need anyway to be reviewed by somebody who is "deeply inside" the sccz80 compiler code.

dev@allu:/data/sonstiges/spectrum/z88dk/z88dk > diff -u src/sccz80/primary.c.orig src/sccz80/primary.c
--- src/sccz80/primary.c.orig   2016-11-23 20:13:12.488705037 +0100
+++ src/sccz80/primary.c        2016-11-23 23:05:30.446320023 +0100
@@ -276,13 +276,36 @@
        if ( t1 == CCHAR && sign2 == NO && !lconst) {
                if ( sign1 == NO )
                        convSint2char();
-               else
+               else {
+
+// cast must be disabled to avoid a problem, keep enabled to
+// reproduce the problem only !
+//#define _WITH_CHAR2CHAR_CAST
+
+#ifndef _WITH_CHAR2CHAR_CAST
+                    if (t1 == CCHAR && t2 == CCHAR) {
+                        warning(W_HARON1) ;
+                    } else {
+#endif // _WITH_CHAR2CHAR_CAST
                        convUint2char();
+#ifndef _WITH_CHAR2CHAR_CAST
+                    }
+#endif // _WITH_CHAR2CHAR_CAST
+                }
        } else if ( t1 == CCHAR && sign2 == YES && !lconst )  {
                if ( sign1 == NO )
                        convSint2char();
-               else
+               else {
+#ifndef _WITH_CHAR2CHAR_CAST
+                    if (t1 == CCHAR && t2 == CCHAR) {
+                        warning(W_HARON2) ;
+                    } else {
+#endif // _WITH_CHAR2CHAR_CAST
                        convUint2char();
+#ifndef _WITH_CHAR2CHAR_CAST
+                    }
+#endif // _WITH_CHAR2CHAR_CAST
+                }
        }

}

z80asm: DEFL - Future incompatible change in z80asm

from: Paulo Custodio [email protected]
to: "[email protected]" [email protected]
date: Tue, Jan 27, 2015 at 10:09 PM

I intend to implement macros in the assembler, to allow, for example, a linked list to be created at assembly time. In Z80-assembly syntax of other assemblers:

link    DEFL 0                 ; define link as a variable, initialize to zero

; macro to create objects
object MACRO #arg1,#arg2
          DEFW  link             ; point to previous object
link     DEFL   ASMPC-2    ; change link to point to this object
          DEFB  #arg1,#arg2  ; define the object data
          ENDM

          object 1,2               ; call macro to create object 1
          object 3,4               ; and object 2

head: DEFW link               ; create pointer to head of list

Apart from the macro syntax, I need to have DEFL to define a symbol that changes its value during assembly ("link" in the example above). DEFL and EQU are the usual keywords for constant and variable symbols in other assemblers.

Today DEFL is used to define a double-word (4 bytes) in just a couple of places in the library.

PROPOSAL:

  • Create a new DEFDW to be used to define double-word values
  • Replace the few DEFL to DEFDW in the library
  • Create DEFL with the semantic shown above.

Any comments?

z88dk: investigate possible introduction of fastcall linkage for multiple parameters

Oleg N Cher:

Can you improve the functionality of the convention call __z88dk_fastcall to pass not only one argument, but two too? The register that be used for passing the second argument will be determined in advance.

To reduce the complexity, I suggest yet to allow the second argument only of size 1 (or 2) bytes, and use C (or BC) to pass it. For the first argument, let everything is as it is now: L, HL, HL : DE

Yeah, it looks like a half-measure, but can you have a better idea? Or, you never want to pass arguments in this manner?

P.S. I have functions like Plot(char x, char y), Draw(char x, char y), etc, and I want to pass the arguments using registers.

Now for a function that uses two arguments, I use this way:

ะšะพะด:


/*--------------------------------- Cut here ---------------------------------*/
unsigned char Basic_ATTR_callee (unsigned char y, unsigned char x) __z88dk_callee {
__asm
  POP  HL
  POP  BC
  PUSH HL
  CALL 0x2583
  CALL 0x2DD5
  LD   L,A
__endasm;
} //Basic_ATTR_callee

/*--------------------------------- Cut here ---------------------------------*/
unsigned char Basic_ATTR_fastcall (unsigned int yx) __z88dk_fastcall {
__asm
  LD   C,L
  LD   B,H
  CALL 0x2583
  CALL 0x2DD5
  LD   L,A
__endasm;
} //Basic_ATTR_fastcall

ะšะพะด:

//----------------------- ATTR (y, x: TextCoords): UBYTE -----------------------
extern unsigned char Basic_ATTR_callee (unsigned char y, unsigned char x) __z88dk_callee;
extern unsigned char Basic_ATTR_fastcall (unsigned int yx) __z88dk_fastcall;
#ifndef ATTR_fastcall
#  define Basic_ATTR Basic_ATTR_callee
#else
#  define Basic_ATTR(y,x) Basic_ATTR_fastcall(((x)<<8) + (y))
#endif

If the token ATTR_fastcall is defined, two unsigned char arguments x, y are packed to one unsigned int, and calls Basic_ATTR_fastcall. It's efficient for constant arguments, but may has some calculations in run-time for non-consts - the inevitable overhead of this method. So the solutions is rather indirect. And I thought, maybe it is possible to expand the scope of the __z88dk_callee to pass at least two 1-byte arguments in registers.

zsdcc: allow user to supply a sequence of peephole files to process on compile line

sdcc allows one user-supplied peephole rule set to be applied during compiles.

zsdcc currently disables sdcc's native peephole rule set and uses that user slot for its own peephole set, which is one file selected from a set of six depending on SO level and whether opt-code-size is enabled.

These rules tremendously improve on code quality but their use does mean the user has no way to add his own.

zsdcc should be modified to accept a list of peephole rule files to process, not just one extra. This may also simplify z88dk's own rules by allowing the removal of duplicate rules from different sets into a common base set.

A short term fix would be to allow one user rule set to be applied to make zsdcc equivalent to the current sdcc.

zsdcc peepholer: add qualifier ifSame(..)

In reference to #11 the specific peephole rule fixed was being applied to "xor" operations only. In fact, the same peephole rule could be useful if applied to other logical operators like "and" & "or". There is currently no way to encode that without duplicating the rules for each logical operator.

Instead, I think introducing a new peephole qualifier "ifSame(%n 'xor' 'or' 'and')" would ease writing of peephole rules by allowing comparison of the logical operator to a list. This feature would have been useful in writing many other rules now in the rule set which currently work by duplicating for each instance of instruction type.

z88dk: investigate support of automatic bankswitching in compiled programs

Finding a way to get the linker to automatically do this given a variably defined memory map would be a fantastic step forward. This has been done for z180-style banking by a commercial compiler still sold by Softools.

We have a lot of irons in the fire concerning z80asm and sectioning for weird memory maps already but getting all the requirements articulated will help nail down the structure of the next z80asm linker implementation.

I do have ideas about how automatic linking might work but I think the best way to get to what will be practical in the end is to first make sure we can compile across banks manually.

We can generate bankswitched programs manually now and the z88dk tools are very helpful in creating such programs but we did identify some things that needed improving in the compilers in past discussion (such as in-source section changes with pushes and pops). So I think maybe what we can do is try to build a simple bankswitched program manually to help identify what things can improve.

Then we should have a look at the embedded tr to see if what they recommend for bankswitched code and data access makes sense.

So another discussion topic to help make progress in this area.

z80asm: .reloc for runtime binary relocation

from: alvin ([email protected]) [email protected] via lists.sourceforge.net
to: [email protected]
date: Wed, Nov 2, 2016 at 2:24 AM

After some discussion on this, it turns out the reloc file is inadequate as-is for relocating most binaries.

Right now, it is only a list of binary offsets where a 16-bit adjustment would have to be made if the binary is moved from its original ORG. This is obviously inadequate for instances were the upper or lower 8 bits of an address is used in computations which occurs frequently in (eg) sdcc-generated code.

   0109 DD 7E FC      [19]  343         ld      a,-4 (ix)
   010C C6r00         [ 7]  344         add     a, #<(_dos_filenum)
   010E DD 77 FC      [19]  345         ld      -4 (ix),a
   0111 DD 7E FD      [19]  346         ld      a,-3 (ix)
   0114 CEs00         [ 7]  347         adc     a, #>(_dos_filenum)
   0116 DD 77 FD      [19]  348         ld      -3 (ix),a[/code]

Here the address "_dos_filenum" is divided into 8-bit parts.

What I think will work is to have the reloc file consist of three parts. The first part is a 16-bit count (number of offsets) followed by a list of 16-bit offsets where a 16-bit quantity needs adjustment by the code movement (this is what is done now for .reloc). The second part is a 16-bit count followed by a list of 16-bit offsets where an 8-bit quantity needs adjustment by the LSB of the code movement. The last part is a 16-bit count followed by a list of 16-bit offsets where an 8-bit quantity needs adjustment by the MSB of the code movement.

Any thoughts on this? Will this finally put to bed the runtime relocation issue and if so how easy would it be to put into z80asm?

z88dk: source code reorganization

z88dk's source code organization has been growing a bit like a weed over the past decade and needs some attention to restore a cleanly organized code base.

As part of that I'd like to move the new c library out of the basement (z88dk/libsrc/_DEVELOPMENT) and into a parallel footing with the classic c library in z88dk/. We can also take the opportunity to get rid of unused bits or reorganize the source code tree in the classic c library and perhaps come up with a way to share more of the code between the new c library and the classic c library. Although some things are different between the two, there is no need for two stdlib implementations, for example.

I think it would be a good idea to think ahead a little bit to what else might be added and how it should fit into the directory structure. There are three things that may come in in the long run:

  • I'm thinking about standalone operating systems for z80 systems. Things like Fuzix or CPM. Fuzix has its own git repository but it's looking like it would not be possible to cleanly add z88dk as z80/z180 compiler into the code base. The reason is z88dk is a much lower level compiler that contains a lot of assembly language and its c libraries contain a lot of specialized prototypes to communicate assembly language level attributes like call linkage, register preservation and so on. These headers do not look anything like what is shared in Fuzix between the 65xx/68xx/z80/68k/etc c compilers. I'm also seeing that there may need to be substantial changes made within the Fuzix code base to take full advantage of z88dk which would be disturbing to the existing ports.

  • In the faraway long term, there is the possibility of using LLVM to compile languages other than C using z88dk. In that case these other languages might need different runtime libraries that would be conceptually at the same level as the new or classic c libraries.

  • I'd like to look at properly supporting z80-derived chips like z180, ez80, rabbit and so on. How should that fit in?

z80asm: implement z180 as a target

Has the z180 as assemble target been removed?

If so is it possible to add it back? There are only a handful of instructions different from the z80:

New Instructions Operation

  • SLP Enter SLEEP mode
  • MLT 8-bit multiply with 16-bit result
  • INO g, (m) Input contents of immediate I/O address
  • OUT0 (m), g Output register contents to immediate I/O address
  • OTIM Block output - increment
  • OTIMR Block output - increment and repeat
  • OTDM Block output - decrement
  • OTDMR Block output - decrement and repeat
  • TSTIO m Non-destructive AND, I/O port, and accumulator
  • TST g Non-destructive AND, register, and accumulator
  • TST m Non-destructive AND, immediate data, and accumulator
  • TST (HL) Non-destructive AND, memory data, and accumulator

z180 cpu user manual

There is some interest in targeting this chip.

z88dk: allow object files generated by zsdcc and sccz80 to be mixed in the same binary

The user may want to choose which compiler is used to compile .c source on a per-file basis.

Some reasons:

  • One compiler may do a better job in terms of execution speed.
  • One compiler may do a better job in terms of code size.
  • One compiler has more bits in its float type.
  • One compiler may be more desirable to use during development due to compile speed.

In the documentation it's been mentioned that due to various differences, a project must be completely compiled by one compiler or the other, ie due to these differences the object files are not compatible.

This is not quite correct. The classic c library can mix zsdcc and sccz80 object files in the majority of circumstances whereas the new c library cannot mix them in most circumstances. Also, the c libraries themselves must be aware of the mixing so that library code is shared between the compilers rather than duplicated in output binaries in order for this to be tenable.

This topic is here to act as reminder to the devs and to collect relevant information and commentary.

Some discussion on this has already occurred in #9.

z80asm: memory map composition using sections (problem)

from: alvin ([email protected]) [email protected] via lists.sourceforge.net
to: [email protected]
date: Sat, Nov 28, 2015 at 5:33 AM

I did a test assemble with this brief code:

;;; here's a memory map

section main
org 0
section PART_A
section PART_B
section PART_C

;;; here's some data placed in sections

section PART_B
INB: defs 2

section PART_A
INA: defs 1

section PART_C
INC: defs 3

;; here we introduce a new section and try to place it inside the defined memory map

section PART_B
section PART_OF_B
INB2: defs 4

z80asm -b -o=test test.asm

The output map file shows:

ASMHEAD_PART_A = 0000, G:
INA = 0000, L: test
ASMHEAD_PART_B = 0001, G:
INB = 0001, L: test
ASMHEAD_PART_C = 0003, G:
INC = 0003, L: test
ASMHEAD_PART_OF_B = 0006, G:
INB2 = 0006, L: test

Section "PART_OF_B" is appended to the output binary rather than following section "PART_B" as was intended.

I've been simplifying the memory map for compiles to include general containers like "code_clib" and "code_driver". The memory map only defines the sequencing of these broad containers and then in the library code, finer grained containers are defined such that they get placed into these broad containers by default. So, eg, strcpy() is defined like this:

SECTION code_clib
SECTION code_string

PUBLIC asm_strcpy

asm_strcpy:
....

The first "SECTION code_clib" is referencing a section defined in the memory map which is loaded by the crt. I'm expecting the new "SECTION code_string" to follow section code_clib unless it has been otherwise sequenced prior. The reason it's done this way is so that the general memory map can accommodate any sections the library or user might define and at the same time the user has the option of placing sections of code and data in memory with minimal effort.

Eg, the memory reserved for the heap might be defined like this:

SECTION bss_clib
SECTION bss_alloc_malloc_heap

PUBLIC __malloc_heap
__malloc_heap: defs CLIB_MALLOC_HEAP_SIZE

so by default it is placed in the crt's broadly defined BSS section. But the user could place the heap anywhere simply by referring to that section in the memeory map:

.... default memory map as usual

SECTION bss_alloc_malloc_heap
org 23295

Just by adding those lines to the file defining the memory map, the heap is removed from the default bss_clib and located at a specific address in memory (23295).

I actually thought this is how things worked before but I changed the memory map definition in the new clib tonight and discovered programs stopped working for the above reason. Is it a bug or is there anyway we can adopt this behaviour?

Problem with preprocessor of sccz80?

When building the package from git with ./build.sh, I get:

make -C lib3d
make[1]: Entering directory '/cygdrive/c/Users/paulo/git/z88dk/libsrc/lib3d'
zcc +test -O3 -vn -Wn43  -c *.c
sccz80:"/home/paulo/winhome/git/z88dk/lib/config//../..//include/msx.h" L:341 Warning:#17:Expected ';'
sccz80:"/home/paulo/winhome/git/z88dk/lib/config//../..//include/msx.h" L:342 Error:#45:Missing token, expecting } got \

Line 342 of msx.h has LINE_T_MEMBERS;, which is a macro expansion containing multi-lines with backslash-newline. It seems the preprocessor is keeping the backslashes.

z88dk: create embedded z180 target

I would like to request an enhancement to support an embedded z180 target.

I'm working on a Z180 platform currently, and there is also an option to add a Z180 processor to the RC2014 platform with little effort.

The z180 has a number of additional machine instructions that are mentioned in issue #49.

Additionally, major differences to the z80 include the ability to flexibly assign the location of the z180 I/O base vectors, and its internal interrupt vectors. These are referred to as IO_BASE and VECTOR_BASE in an example initialisation file.

The IO_BASE is loaded into register ICR, and VECTOR_BASE is loaded into register IL, to determine the initial configuration of the z180. These can be redefined as required following initialisation.

Further other initialisation option examples are found in the INIT: section for reference.

z80asm: Remove the z80asm INVOKE directive?

from: pscust ([email protected]) [email protected] via lists.sourceforge.net
to: [email protected]
date: Fri, Jul 29, 2016 at 2:05 PM

z80asm implements the directive "INVOKE xx" as "call xx", or as "rst 28h; defw xx" with the --ti83plus option.
This directive is not used in the library, neither is the option --ti83plus.

I propose to remove the implementation of INVOKE from z80asm, as well as the --ti83plus option. I plan to have a macro facility in z80asm, which will allow this kind of platform-specific directives to be implemented in a platform-specific include file.

Any comments?

zsdcc: compiler generated c fastcall functions bugged for clib=sdcc_iy, reserve-regs-iy

This bug affects zsdcc compiles where the compiler is not allowed to use the iy register. This happens when either --clib=sdcc_iy is used (new c lib) or --reserve-regs-iy is used (classic, new c lib).

The issue occasionally occurs for compiler generated c fastcall functions, eg:

extern unsigned char	game_menu_sel;
extern unsigned char	s_lin1;

void game_menu_back(unsigned char f_start) __z88dk_fastcall
{
	game_menu_sel = 0;
	s_lin1 = f_start;
}

With --reserve-regs-iy active, the generated code is:

_game_menu_back::
	ld	hl,#_s_lin1
	ld	(hl),l
	ld	hl,#_game_menu_sel
	ld	(hl),#0x00
	ret

The input parameter is in the L register but that gets wiped out by the first load "ld hl,#_s_lin1".

Without --reserve-regs-iy active, the compiler uses IY to index from "_slin_1" to avoid altering L:

_game_menu_back::
	ld	iy,#_s_lin1
	ld	0 (iy),l
	ld	hl,#_game_menu_sel + 0
	ld	(hl), #0x00
	ret

This code is correct but inefficient. The --reserve-regs-iy option was added by the sdcc team for compatibility with z88dk so sometimes these sorts of code generation errors surface.

Let's see if the sdcc team will try to fix this.
https://sourceforge.net/p/sdcc/bugs/2580/

zcc: module names in generated libraries are temp file names rather than original filenames

zcc's -x option causes it to generate a library out of input source files. This is a very convenient method for making libraries because zcc can receive a list of source files of any type and generate a library in a single line.

However there is one drawback :- the module names stored in the library are the temp filenames zcc creates rather than the original filenames identifiable by the user.

For example, running z80nm on one of the new c lib's libraries z88dk/libsrc/_DEVELOPMENT/lib/sdcc_iy/zx.lib will generate a listing like this:

File zx.lib at $0010: Z80RMF08
  Name: b_array_append
  Names:
    G A $0000 _b_array_append (section code_adt_b_array)
  External names:
    U         asm_b_array_append

File zx.lib at $0110: Z80RMF08
  Name: b_array_append_callee
  Names:
    G A $0000 _b_array_append_callee (section code_adt_b_array)
  External names:
    U         asm_b_array_append
.........
.........

The name, as in "b_array_append", is the module name or, because there are no module names in any of the new c lib's source, it is the name of the original source file "b_array_append.asm" from which that linking unit was generated. This library was created by z80asm directly and z80asm was given the original source files to generate the library.

This library can also be built by zcc by running this from z88dk/libsrc/_DEVELOPMENT:

zcc +zx -vn -x --lstcwd -clib=sdcc_iy -Ca--IXIY -o test @target/zx/library/zx_sdcc_iy.lst

Running z80nm on the resulting test.lib generates this:

File test.lib at $0010: Z80RMF08
  Name: zcc56412
  Names:
    G A $0000 _b_array_append (section code_adt_b_array)
  External names:
    U         asm_b_array_append

File test.lib at $0110: Z80RMF08
  Name: zcc56413
  Names:
    G A $0000 _b_array_append_callee (section code_adt_b_array)
  External names:
    U         asm_b_array_append

The difference is the name of the module is now the temp filename generated by zcc rather than the original filename. z80asm is being given the temp asm files after compiling/processing/whatever. These temp filenames also show up in map files which can cause a little confusion for the user if he wonders where that function is stored.

zcc knows the original filenames of these files so I wonder if there is a way to communicate that to z80asm.

suborb mentioned:

I was talking about sccz80, but for .asm you're right. Given that zcc has the real filename, I wonder if it's worthwhile passing that as an option to z80asm so we don't need to put MODULE in the code.

zcc is going to be passing a mass of files not usually one at a time and quite often as a list of files in a single .lst file to avoid command line limitations. So I don't think there is any way to add a command line parameter sensibly.

What about a new .file directive? zcc could add it automatically at the beginning of a .asm file before it assembles. If it's not present, use the filename.

I'm also thinking a little ahead in terms of multiple modules in the same .asm file #45 where the name of the linking unit inside a file might be filename/modulename

Previous discussion in #40

github: create a place to hold technical docs?

Recently there was a pull request #22 to remove pdf datasheets for the z80 and mc6850 from the rc2014 target within the new c lib because they were commonly available and occupied a lot of space.

There are other pdfs in the repository having to do with the C standard.

I'm wondering if we should have a separate spot to collect such things? They are relevant to drivers and whatnot that are being written as a part of z88dk.

new c lib: need a way to communicate target and library configuration to the c program

This somewhat applies to the classic lib too.

The mechanism for including target-specific information in the new c lib is to #include <arch.h> where that information should be made available via defines. Inside arch.h there should/will be a bunch of #ifdefs guarding info for each specific target with the #ifdef argument coming from the target.cfg file. So, eg, zx.cfg will add -D__SPECTRUM to all compiles so that arch.h can do #ifdef __SPECTRUM .... #endif

However the target and library configuration is currently only available from assembler in z88dk/libsrc/_DEVELOPMENT/target/$ARCH/clib_cfg.asm and clib_target_cfg.asm and there is no way to communicate that information to the c program. Some things don't need to be communicated but some things should be like cpu clock rate, number of display rows managed by a sprite engine, etc.

I can see two ways to do this communication:

  1. Create a c header file in /_DEVELOPMENT/target/$ARCH/.. that is manually kept consistent with the two cfg files by the user. Then arch.h can be made to include this header file.
  2. Make the assembly defines in the cfg files public so that they are accessible to user c and asm subroutines. The c program (through arch.h) can access constant values defined in asm using an array syntax:
Feature defined in cfg file:

PUBLIC _FEATURE
defc _FEATURE = 0x1234

Feature accessed in arch.h:

extern unsigned char FEATURE[];

The address of the "FEATURE" array will equal the FEATURE value defined in asm.

The advantage of the second method is that everything is kept consistent automatically although it is a little bizarre.

Classic: Error when building against CPC target

I get the following error when building against the CPC target.
I'm using z88dk-199B built from source and installed locally on linux.

mariocki from the forum:

Code:

z80asm -b -d  -oSayHello.bin -m -s -L.   -L/home/xxx/z88dk/lib/config/../..//lib/clibs -I/home/xxx/z88dk/lib/config/../..//lib -indos -igen_math -icpcfs -icpcrslib -icpc_clib -iz80_crt0    /tmp/tmpXXYuzT4y.asm @/tmp/tmpXX7PPT8b.lst
Error at file '/tmp/tmpXXYuzT4y.asm' line 135: symbol '__interposer_isr__' not defined
1 errors occurred during assembly
Key to filenames:
/tmp/tmpXX4RGzhj.o = SayHello.c
/tmp/tmpXX5gOdbW.o = other.c
Error at file '/tmp/tmpXXYuzT4y.asm' line 135: symbol '__interposer_isr__' not defined
                   ^ ----    ld hl,__interposer_isr__
Makefile:38: recipe for target 'SayHello.cpc' failed
make: *** [SayHello.cpc] Error 1

sccz80: Support __z88dk_fastcall and __z88dk_callee

In sdcc these are defined after the function prototype, in sccz80 they are defined between type and function name.

In the classic library, there's some macro magic in sys/compiler.h to get this to work if the function is annotated with both versions.

However, it's a bit messy, so allow sccz80 to accept the modifiers after the prototype.

Additionally, swallow __smallc which is the sdcc indicator that the calling convention is l->r

zsdcc SO3 peephole: bug in rule #339c

C Source:

game_sound ^= spec128 ? GAME_SOUND_AY_FX_ON : GAME_SOUND_48_FX_ON;

Generated Asm:

3186  0E47  3A 00 00    	ld	a,(_spec128)
3187  0E4A  B7          	or	a, a
3188  0E4B  28 04       	jr	Z,l_game_menu_config_00124
3189  0E4D  3E 04       	ld	a,0x04
3190  0E4F  18 02       	jr	l_game_menu_config_00125
3191  0E51              l_game_menu_config_00124:
3192  0E51  3E 01       	ld	a,0x01
3193  0E53              l_game_menu_config_00125:
3194  0E53  AE          	xor	a,(hl)
3195  0E54  32 00 00    	ld	(_game_sound),a

In the second to last statement, "xor a,(hl)", hl does not hold _game_sound so the xor is incorrect.

This is caused by an error in rule #339c which is not qualified on "(hl)" appearing in the xor.

zcc: spaces in filenames cause problems

Spaces in filenames and pathnames can cause problems for zcc.

It's not in the initial zcc invocation where the problem lies, it's in the generation of shell commands by zcc.

Although zcc can be given quoted filenames with spaces by the user in its invocation, it is not quoting those filenames when it generates shell commands. It's these generated shell commands that must have quoting applied to all filenames and paths in order to resolve the issue.

z80asm: public constants not being listed in global .def file

Sample program:

org 65000

PUBLIC program

PUBLIC asm_BIFROST2_start
PUBLIC asm_BIFROST2_stop

DEFC asm_BIFROST2_start              = $C9A9 ;   asm_BIFROST2
DEFC asm_BIFROST2_stop               = $C9B2 ;   asm_BIFROST2
DEFC asm_BIFROST2_showNext2Tiles     = $C9C2 ;   asm_BIFROST2
DEFC asm_BIFROST2_showNextTile       = $C9C5 ;   asm_BIFROST2
DEFC asm_BIFROST2_showTilePosH       = $C9E3 ;   asm_BIFROST2
DEFC asm_BIFROST2_drawTileH          = $CA02 ;   asm_BIFROST2
DEFC _BIFROST2_TILE_IMAGES           = $CA17 ;   asm_BIFROST2
DEFC _BIFROST2_ISR_HOOK              = $FD29 ;   asm_BIFROST2
DEFC asm_BIFROST2_fillTileAttrH      = $FD3D ;   asm_BIFROST2

program:
ret

Assemble with:
z80asm -b -s -g -m zzz.asm

When assembled, the unreferenced local symbols ("asm_BIFROST2_showNext2Tiles" through "asm_BIFROST2_fillTileAttrH") are not listed anywhere in symbol files, map files or by z80nm on the object file "zzz.o". That is expected behaviour.

The two publicly exported constants ("asm_BIFROST2_start" and "asm_BIFROST2_stop") show up in the map file, the sym file, and by z80nm on "zzz.o" where they are marked as global as expected. But they are missing from the global zzz.def file.

new c lib: input library in_key_scancode() too heavy for typical uses

A typical use of the in_key_scancode function is to look up keyboard scancodes and attach those to keyboard joysticks.

On the zx target, for example, the in_key_scancode() function searches a table of about 160 bytes to find the scancode associated with a particular ascii char. If you're only using that function to specify keys for a keyboard joystick, the 160 bytes is too high a price to pay. 160 bytes doesn't sound like much but it is making a difference in a current game in development.

So the proposal is to add defines to the header file that can provide the scancodes for typical use as constants:

#define IN_KEY_SCANCODE_m 0x....
#define IN_KEY_SCANCODE_DISABLE  0xffff
etc.

and then the program can use those to define keyboard joysticks to avoid the overhead of in_key_scancode().

k1.up   = IN_KEY_SCANCODE_q;
k1.down = IN_KEY_SCANCODE_a;
...
k1.fire = IN_KEY_SCANCODE_m;

dirs = (joyfunc)(&k1);

zcc: no-crt option results in the first file being compiled in the current working directory

When --no-crt is specified to zcc, the compile proceeds with the first file listed being assembled late. This means it is assembled to an object file last so that it can gather compile-time pragmas from zcc_opt.def as if it were the crt.

Currently the first file's processing is stopped at the .asm stage and then assembled at the compile stage where it can pick up zcc_opt.def. If the first file is a .asm file, this means it skips all processing in zcc's loop, it does not get moved to the temp directory, and later assembly will be done in the user's directory.

The problem with that is twofold:

  • Temp files will be created in the user directory which may overwrite user files.
  • zcc assumes the ancillary files (.map, .def, .o, etc) are located in the temp directory so when it tries to copy those to the output directory it effectively does "cat foo > foo", wiping out the results.

Fix up sourceforge page

From the main menu bar I'd like to get rid of the Tickets category. This will involve deleting the small number of old bug reports and support requests that were posted there.

I'd also like to try to delete or discontinue the commits mailing list. If that involves deleting the mailing list is everyone ok with that? A more thorough history is in github now anyway. I noticed the mailing list quite often missed commits.

z80asm: overflow errors in calculated constants at linking stage

In trying to work around #53, I test assembled this:

org 65000

PUBLIC program

PUBLIC asm_BIFROST2_start
PUBLIC asm_BIFROST2_stop
PUBLIC asm_BIFROST2_showNext2Tiles

DEFC asm_BIFROST2_start              = $C9A9 + ASMPC - ASMPC
DEFC asm_BIFROST2_stop               = $C9B2 + here - there
DEFC asm_BIFROST2_showNext2Tiles     = $C9C2 + 50000 - 50000
DEFC asm_BIFROST2_showNextTile       = $C9C5 ;   asm_BIFROST2
DEFC asm_BIFROST2_showTilePosH       = $C9E3 ;   asm_BIFROST2
DEFC asm_BIFROST2_drawTileH          = $CA02 ;   asm_BIFROST2
DEFC _BIFROST2_TILE_IMAGES           = $CA17 ;   asm_BIFROST2
DEFC _BIFROST2_ISR_HOOK              = $FD29 ;   asm_BIFROST2
DEFC asm_BIFROST2_fillTileAttrH      = $FD3D ;   asm_BIFROST2

program:
here:
there:
ret

With:
z80asm -b -s -g -m zzz.asm

The idea was by adding a symbol that had to be resolved at link time, the constants "asm_BIFROST2_start" and "asm_BIFROST2_stop" would show up in the global .def file.

And they did but with incorrect values. There is some kind of overflow at 16-bits that is occurring. The incorrect value doesn't change if I subtract then add rather than add then subtract.

The "DEFC asm_BIFROST2_showNext2Tiles = $C9C2 + 50000 - 50000" statement comes up with the correct value despite the overflow. But as noted in #53 this doesn't show up in the .def file and must be seen in the .map file.

Problem building z88 library?

When building the package from git (./build.sh), I get:

make -C fcntl/z88
...
z80asm -d -I/home/paulo/winhome/git/z88dk/lib/config//../ -DFORz88 -x/cygdrive/c/Users/paulo/git/z88dk/libsrc//z88_clib @./z88.lst
Error: cannot read file 'stdio/obj/fopen_z88'
Error: cannot read file 'stdio/obj/freopen_z88'
2 errors occurred during assembly
make: *** [Makefile:244: z88_clib.lib] Error 1

Source files for fopen_z88 and freopen_z88 are missing.

zsdcc: Bytes encoded as hex chars in character strings cause strings to be improperly generated in memory

Example:

const unsigned char hall_valids[42] = "\x01ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.~ {";

zcc +zx -v -a -clib=sdcc_iy test.c

Results in:

_hall_valids:
.db 0xef
.ascii "GHIJKLMNOPQRSTUVWXYZ0123456789.~ {"
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0x00

The 0x01 byte that should be there is replaced by 0xef and the following A-F chars are not present.

If the byte 0x01 is instead encoded in octal, the string is fine.

This is a problem within sdcc that I've tried to push on them :p
https://sourceforge.net/p/sdcc/bugs/2577/

In my imagination this shouldn't be hard to fix so if the sdcc team don't solve it soon maybe we can have a look.

new c lib: investigate instantiation of device drivers for physical hardware

This idea is part of the reason m4 was added as macro processor to the zcc compile chain and probably could be applied to the classic library too.

The idea is to be able to instantiate device drivers for popular peripheral ics mapped to specific i/o addresses (for example) so that the user can specify his hardware in the crt (eg) and have the library automatically supply drivers.

I see something like:

m4_ZILOG_CTC(0xf0, 0x00)
m4_GI_AY38910(0xef, 0xdf)

where some of those numbers are port assignments, some are interrupt vectors and some may be flags or other parameters varying from device to device.

The macro allows m4 to generate source with those parameters filled in, building a unique driver for each instantiation. Then with this method you can create a bespoke z80 system and have drivers automatically supplied by the library.

The rc2014 target is ideal for experimenting with this because it is an open system with a growing number of custom variations put together by users.

new c lib: re-examine zsdcc c interface for opportunities to use char rather than int function parameters

When zsdcc passes char parameters in function calls, it pushes only one byte.

When the c interface was first written, it was considered that this would most often increase code size so int-size parameters were preferred over char. However, in a recent project changing the interface to the nirvana+ engine to use char rather than int parameters saved over 400 bytes in the compiled binary.

So it's worthwhile to re-examine that assumption for the whole c library.

zsdcc: stack frame set up for compiler generated c fastcall functions bugged for --opt-code-size

sdcc is able to compile functions that are written in c that are declared fastcall, eg:

int abs(int n) __z88dk_fastcall
{
   return (n < 0) -n : n;
}

Fastcall functions are delivered their single parameter in a subset of registers DEHL.

When the --opt-code-size switch is applied on the compile line, sdcc will call a function to generate the stack frame instead of inlining the code at the beginning.

The generation of the stack frame in these cases looks like this:

function_begin:
   call ___sdcc_enter_ix
   ..
function_end:
   ret

___sdcc_enter_ix:

   pop hl   ; hl = return address
   push ix   ; save previous stack frame
   ld ix,0
   add ix,sp   ; ix = new stack frame
   jp (hl)   ; return

For fastcall functions, the call to ___sdcc_enter_ix wipes out the HL register which holds the input parameter and there's the bug.

z88dk: prune unreferenced c functions from output binary

This is actually in z80asm's roadmap using the module directive but the issue was originally raised in the context of c programs.

z80asm as linker extracts individual functions from a library as needed when forming the output binary. However the unit of granularity of the extraction is the file (or rather the module, of which there can only be one per file). So all functions and variables intended for a library, c or otherwise, should be partitioned into individual files before being added to a library to take advantage of incremental linking.

However, some tools (and people!) are generating large monolithic c or asm files containing many functions intended to behave as a library. Unfortunately, because the unit of linking is the file, if a user program uses any function from such a large set in a single file, the linker will attach all the functions, the entire file to the output binary no matter how little of it is actually used. Part of the reason this happens is people do not know what linking is since they are acclimatized to basic assemblers but part is due to automatic tools not partitioning their output. Many c programmers are also often surprised to find out a function that has become obsolete or gone unused in a large program is not removed by some sort of dead code eliminator.

The proposed solution is to allow multiple .module directives in the same asm file with each .module directive delimiting the start of a new linking unit. The c compilers would have to insert a .module directive at the start of each function.

I can think of two issues associated with this:

  • How are previously declared public and extern symbols treated in a new module? I think the scoping directives should continue to work as they do now so that an individual module inherits all scoping ahead of its source placement. That may mean turning any public declarations into global if the individual module is effectively processed in isolation from the rest of the source file.
  • What module name does the linker use when making object or library files? I think it probably needs to be a combination of the filename and the module name. If the module name is omitted then some unique (to the file) machine-generated name can be used as module name.

Some previous discussion in #40
Something about module names in #46

z80asm: cannot specify name of generated object file

from: alvin ([email protected]) [email protected] via lists.sourceforge.net
to: [email protected]
date: Sun, Oct 23, 2016 at 9:03 AM

When assembling to a single object file there is no way to control the output filename.

z80asm thing.asm

will always generate thing.o

I'd like to be able to do this:

z80asm thing.asm -o c:\temp\..\zcc0000.o

Line 39 of options_def.h hints that this was considered but never implemented:

OPT_VAR( char *,    consol_obj_file, NULL)      /* set by -o and no -b */

Because z80asm will search for includes from the .asm file's location, zcc needs to assemble .asm source files in their original source directories and we don't want to pollute the source directories with temporary files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.