New modular assembler

Other misc things
Post Reply
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

New modular assembler

Post by dom »

As some people know I've been tinkering with assemblers lately to see how easy/hard it is to upgrade/change z80asm. One of the ones I've been playing with is vasm from the vbcc toolchain. Due to it's slightly odd licence it probably won't be a replacement for z80asm but if you're looking for a 8080/z80/gbz80/64180/rcm2000/rcm3000/rcm4000 assembler with sections and a linker/librarian for a non-commercial projects it might be worth looking at.

It pretty much supports all of the mentioned chips and their opcodes (with the exception of about 5 for the RCM4000) and after going blind looking at output files assembles them to the correct sequence (I believe). I've added in the possiblilty of emulating some of the missing Rabbit instructions (as per z80asm).

The syntax should be similar to z80asm with the exception of labels (they must be of the colon format, not the leading . style) and the standard directives (defc, defb, defm, defw, defl, defp etc) are supported.

I've uploaded a copy of it to: http://vbcc.z88dk.org Any feedback on it is welcome.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I'm thinking at the NEC V20 (and following) CPUs.. those beasts have a Z80 emulation mode, but I don't think an assembler ever supported the tho modes at once, nor the instruction to jump from/to the emulated mode.
Could such tool give a hand ?
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I don't think so - each cpu target is a different binary so you can't mix x86 and z80 opcodes in a single file. You can of course define a macro and include a binary file.

Most of the multi-target assemblers seem to do this which is fair enough since switching cpu families within a single binary is quite an unusual thing to want to do.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Very small contribution, to build the assembler with Visual C:


- Create by hand the obj_win32 folder


- Change a line in z80/cpu.h as follows:

//#include <stdint.h>

#if _MSC_VER >= 1200
/* Predefined by Microsoft Visual C++ 6.0 */
#define snprintf _snprintf
typedef unsigned long uint32_t;
#else
#include <stdint.h>
#endif



- nmake -f Makefile.Win32 CPU=z80 SYNTAX=oldstyle
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

By changing a bit zcc.c, here:

Code: Select all

#ifdef VASM
                BuildAsmLine(asmarg,"-z80asm");
#else
                BuildAsmLine(asmarg,"-easm");
#endif
and here:

Code: Select all

#ifdef VASM
        if (!z80verbose)
                strcat(dest," -w ");
#else
        if (z80verbose)
                strcat(dest," -v ");
        if      (!symbolson)
                strcat(dest," -ns ");
#endif
I got the following:
C:\z88dk\examples>zccnew +vzx -create-app dstar.c
copy c:\progra~1\z88dk\lib\spec_crt0.opt C:\DOCUME~1\stefano\LOCALS~1\Temp\s33s_
1.opt
1 file(s) copied.
copy C:\DOCUME~1\stefano\LOCALS~1\Temp\s33s_1.opt C:\DOCUME~1\stefano\LOCALS~1\T
emp\s33s_1.asm
1 file(s) copied.
zcpp -I. -DZ80 -DSMALL_C -DSPECTRUM -D__SPECTRUM__ -DSCCZ80 -Ic:\progra~1\z88dk\
include dstar.c C:\DOCUME~1\stefano\LOCALS~1\Temp\s33s_.i
sccz80 -// C:\DOCUME~1\stefano\LOCALS~1\Temp\s33s_.i
vasmz80 -z80asm -w C:\DOCUME~1\stefano\LOCALS~1\Temp\s33s_.asm
vasm 1.4 (c) in 2002-2009 Volker Barthelmann
vasm 8080/gbz80/z80/z180/rcmX000 cpu backend 0.2 (c) 2007,2009 Dominic Morris
vasm oldstyle syntax module 0.7c (c) 2002-2009 Frank Wille
vasm test output module 1.0 (c) 2002 Volker Barthelmann

fatal error 13: could not open <#z80_crt0.hdr> for input
aborting...
Now I guess I should instruct vasm some way to find the include files in the correct path...
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Never mind, I discovered the option and adapted a bit oldstyle/syntax.c to 'eat' the leading hash char.

Code: Select all

static char *parse_name(char **start)
/* parses a quoted or unquoted name-string and returns a pointer to it */
{
  char *s = *start;
  char c,*name;

  if (*s=='\"' || *s=='\'') {
    c = *s++;
    if (*s=='\#') s++;         //
.....
Now vasm claims: "no current section specified" ... I understand I'm testing it the wrong way.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Yeah, witin z88dk you'll need to put a section directive in codegen.c which will allow you to create the .o and then run vlink on the .o files to pull things together using a ldscript.

I think a good idea would be for z80asm to support -I and -L to allow more paths to libraries and includes to be specified then we can get rid of the # and the requirement for libraries to be within z88dk/lib - I can give that a try this weekend.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Got updates, hope you don't mind I rolled back the parse_option function optimizations in zcc.c, they appeared wrong to me.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Being too curious to stop half way, I changed my own copy of the 'lib' directory by removing the hash prefixes in the include references in assedmbly.
Then I put a new line in z80_crt0.hdr:

Code: Select all

        (...)
        XREF    cleanup                ; cleanup before program exit

        SECTION

        LIB     l_jphl        ; another jp(hl)
        (...)
Now the beast produces an "a.out" file and hangs at the linking stage..

Code: Select all

C:\z88dk\examples\console>zcc +vzx -lndos fib.c
copy c:\progra~1\z88dk\lib\spec_crt0.opt C:\DOCUME~1\stefano\LOCALS~1\Temp\s3d8_
1.opt
        1 file(s) copied.
copy C:\DOCUME~1\stefano\LOCALS~1\Temp\s3d8_1.opt C:\DOCUME~1\stefano\LOCALS~1\T
emp\s3d8_1.asm
        1 file(s) copied.
zcpp -I. -DZ80 -DSMALL_C -DSPECTRUM -D__SPECTRUM__ -DSCCZ80 -Ic:\progra~1\z88dk\
include  fib.c C:\DOCUME~1\stefano\LOCALS~1\Temp\s3d8_.i
sccz80    -//  C:\DOCUME~1\stefano\LOCALS~1\Temp\s3d8_.i
vasmz80 -z80asm  -w -IC:\PROGRA~1\Z88DK\LIB C:\DOCUME~1\stefano\LOCALS~1\Temp\s3
d8_.asm
vasm 1.4 (c) in 2002-2009 Volker Barthelmann
vasm 8080/gbz80/z80/z180/rcmX000 cpu backend 0.2 (c) 2007,2009 Dominic Morris
vasm oldstyle syntax module 0.7c (c) 2002-2009 Frank Wille
vasm test output module 1.0 (c) 2002 Volker Barthelmann
vasmz80 -a -m -Mo -oa.bin -ic:\progra~1\z88dk\lib\clibs\ndos  -ic:\progra~1\z88d
k\lib\clibs\zx_clib  -ic:\progra~1\z88dk\lib\clibs\z80_crt0  C:\DOCUME~1\stefano
\LOCALS~1\Temp\s3d8_1.asm C:\DOCUME~1\stefano\LOCALS~1\Temp\s3d8_.o
vasm 1.4 (c) in 2002-2009 Volker Barthelmann
vasm 8080/gbz80/z80/z180/rcmX000 cpu backend 0.2 (c) 2007,2009 Dominic Morris
vasm oldstyle syntax module 0.7c (c) 2002-2009 Frank Wille
vasm test output module 1.0 (c) 2002 Volker Barthelmann

error 15: unknown option <-a>

error 15: unknown option <-m>

error 15: unknown option <-Mo>

error 15: unknown option <-oa.bin>

error 15: unknown option <-ic:\progra~1\z88dk\lib\clibs\ndos>

***maximum number of errors reached!***

C:\z88dk\examples\console>zcc +vzx -lndos fib.c
Can we take the risk to remove the same hash prefixes in the CVS tree ?
I suppose the ".LNX" (and ".CFG") files need to have a -I<path> option addedd, right ?
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The Z80_OZFILES path is picked up automatically by z80asm so there's no need to add a -Ca-I definition so we can strip out # from all the files.

I've done a bit more poking around and added a -asm=XXX option to both zcc and sccz80 which with a bit of luck will now generate different output for the various assemblers. zcc's asm= also sets the assembler and linker commands to the appropriate type.

Bad arguments will stop vasm from carrying on - so asmopts needs to be ignored. The next issue is that the default output is a.out so it needs to be an outspecified filter (with the -o option), I'll take a look at that tomorrow night hopefully.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I've done a bit more work and now we can define options in the .cfg files to be applied to asz80, aslink, vasm and vlink which are switched in when the -asm=XXX flag is used.

I've also removed the "# syntax from include/ and lib/ - I'm having a bit of fun with libsrc which is giving CVS a few issues :)

I'll do a win32 build of zcc and z80asm tomorrow evening which will support this new stuff.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Very good, I'm getting it right now !
Since we're touching the CRT0s I'm thinking if it is wirth to extract from every startup block the code portions which are common, in example:

Code: Select all

; Now, define some values for stdin, stdout, stderr

.__sgoioblk
IF DEFINED_ANSIstdio
        INCLUDE        "#stdio_fp.asm"
ELSE
        defw    -11,-12,-10
ENDIF


; Now, which of the vfprintf routines do we need?


._vfprintf
IF DEFINED_floatstdio
        LIB        vfprintf_fp
        jp        vfprintf_fp
ELSE
        IF DEFINED_complexstdio
                LIB        vfprintf_comp
                jp        vfprintf_comp
        ELSE
                IF DEFINED_ministdio
                        LIB        vfprintf_mini
                        jp        vfprintf_mini
                ENDIF
        ENDIF
ENDIF
It is obviously something we need to agree about (expecially because of the big work Alvin is doing).
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

The crt0s will look very different with the new stdio implementation and I'm not sure what the best way to go about customizing crt0s will be yet. For the next release it won't matter much as there will be just the one test target from which we can decide on what needs to be improved, changed, etc.

There won't be any selection of vfprintf_mini, *_comp, etc, instead the user can choose to add each scan converter individually and he'll also be able to choose between a 16-bit version vs a 32-bit version. Eg, you can choose to have %d, %s, %f supported but no other, thus eliminating all the extra code for the other converters. If a program uses something like %c, fscanf will return an error and fprintf will output %c on the output stream. 16-bit vs 32-bit choice means using the %d code vs the %ld code, eg. The 32 bit code also does 16 bit conversions so you choose one or the other depending on whether 32 bit integers are needed in the stream i/o (in this example). Code-size wise it probably makes sense to use all 32-bit converters if at least one is needed since one 32 bit converter brings in th emajority of the 32-bit code support. And you don't really want both the 16-bit code and 32-bit code in the project if code size is the main concern. It may be possible to have the compiler identify what converters are necessary froom the program text and have it set some flags, perhaps a 16-bit word, that can be used to enable converters in a standard INCLUDE into the crt0. Allowing the user to OR in a converter word via a define on the compile line would let him add converters the compiler might miss from analyzing the static text in the program.

And then ther's the matter of selecting devices to be attached to stdin, stdout, stderr, the default device and the list of device drivers in the project. There should be a good way to customize this with the default (no custoimization) being sensible.

I've really been waffling on how things should work at the driver level so that's what's been slowing things down. I'm going to pick something and just implmenet that for the test target and then we can argue about whether things should be changed from that when we have some more experience with writing drivers for some real devices.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Detecting format strings isn't a problem - that's what sccz80 currently does to switch in the different printf implementations. Selecting io targets, again isn't a real problem, pragmas are quite handy! I sometimes think JFDI is the best approach to see what niggles come out.

I'd suggest we wait until the new stdio is available before changing all the crt0s.

I've uploaded a new win32 build of the toolchain to the downloads section so if anybody is tracking CVS on win32 and doesn't compile their own binaries can have a working tree once more.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Totally agree about waiting.

New win32 binaries can help a bit but probably windows users will have some hassle with the CFG files, expecially if they had them created automatically by the installer.
BTW I rebuilt the binaries and, after including the [z88dk]/lib tree for the linking pass, etc. I got it working again with z80asm. Nice job !
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Just as an end note, I've spotted that Frank has released vasm 1.4a on his site http://sun.hasenbraten.de/vasm/ which fixes a few silly bugs I introduced with error codes.

However, I spotted last week that only relocations involving a single symbol are supported, so the callee trick (which is a workaround for a z80asm limitation) isn't supported, and even worse doesn't fail noisily.

I'm currently playing around with linking with z80asm libraries so I'm starting to address the multiple symbol issue.
Post Reply