New modular assembler
New modular assembler
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.
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.
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.
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.
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
- 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
By changing a bit zcc.c, here:
and here:
I got the following:
Code: Select all
#ifdef VASM
BuildAsmLine(asmarg,"-z80asm");
#else
BuildAsmLine(asmarg,"-easm");
#endif
Code: Select all
#ifdef VASM
if (!z80verbose)
strcat(dest," -w ");
#else
if (z80verbose)
strcat(dest," -v ");
if (!symbolson)
strcat(dest," -ns ");
#endif
Now I guess I should instruct vasm some way to find the include files in the correct path...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...
Never mind, I discovered the option and adapted a bit oldstyle/syntax.c to 'eat' the leading hash char.
Now vasm claims: "no current section specified" ... I understand I'm testing it the wrong way.
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++; //
.....
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.
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.
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:
Now the beast produces an "a.out" file and hangs at the linking stage..
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 ?
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)
(...)
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
I suppose the ".LNX" (and ".CFG") files need to have a -I<path> option addedd, right ?
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.
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.
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.
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.
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:
It is obviously something we need to agree about (expecially because of the big work Alvin is doing).
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
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.
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.
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.
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.
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 !
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 !
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.
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.