Page 1 of 1

Z80 asm/disasm in Z80 asm [solution found]

Posted: Tue Aug 04, 2020 8:38 am
by ketmar
does anybody have standalone Z80 assembler and disassembler modules written in Z80 asm? i don't need advanced things, just a code to disasm one command, and to asm one command. speed is not a concern, but size is -- the smaller the thing, the better. there are alot of sources for various Speccy assemblers and disassemblers, but it is quite hard to extract the relevant code from there. sure, i can write it myself, but maybe somebody already did it, and wiling to share the code?

the idea is to incorporate those into my dsForth system, so ideally asm should take a buffer (and maybe callback to get label value), and produce machine code. and disasm should take a pointer, and produce disassembled string.

p.s.: readable and commented source code would be great. ;-)

Re: Z80 asm/disasm in Z80 asm, request

Posted: Thu Aug 06, 2020 10:46 pm
by dom
For a disassembler try this one: https://github.com/z88dk/z88dk/blob/mas ... disz80.asm - it's just over 1k in size so definitely one of the smaller ones. The code was extracted from Utility3 but the history goes back further than that.

Can't help with an assembler unfortunately.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Thu Aug 06, 2020 11:26 pm
by ketmar
thank you alot! i'll take a look at it.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Fri Aug 07, 2020 2:41 am
by Einar Saukas
dom wrote: Thu Aug 06, 2020 10:46 pm For a disassembler try this one: https://github.com/z88dk/z88dk/blob/mas ... disz80.asm
This listing says:
The SUBSET editor David Barrow was able to trim only one byte from John Kerr's compact code. I've forgotten where so there's a challenge.
Right at the beginning:

Code: Select all

cp 255
jr nz, dizloop
It can be replaced with:

Code: Select all

inc a
jr nz, dizloop

Re: Z80 asm/disasm in Z80 asm, request

Posted: Fri Aug 07, 2020 11:31 am
by ketmar
the magic spell "shorten this code" always makes Einar to appear with the solution. ;-)

Re: Z80 asm/disasm in Z80 asm, request

Posted: Fri Aug 07, 2020 12:04 pm
by dom
[laughs] I have a feeling that bit of wrapper code isn't part of the "challenge". I think that code is actually trying to disassemble the following instruction, but the push ix gets in the way of that.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Fri Aug 07, 2020 3:24 pm
by Einar Saukas
Replace this:

Code: Select all

.XTRACT
	or a
	jr z,COPY
.SKIP
	bit 7,(hl)
	inc hl
	jr z,SKIP
	dec a
	jr nz,SKIP
.COPY
With this:

Code: Select all

.SKIP
	bit 7,(hl)
	inc hl
	jr z,SKIP
	dec a
.XTRACT
	or a
	jr nz,SKIP
.COPY

Re: Z80 asm/disasm in Z80 asm, request

Posted: Thu Aug 13, 2020 5:35 am
by ketmar
wow. recently, R.T. Russell's Z80 BBC Basic became opensourced. and it seems to contan full-featured assembler. i quickly scanned the sources, and they seem to be very well written. so i will look if i'll be able to rip asm module. stay tuned, i will report here if i succeed converting it into something that could be used by providing input buffer implementation.

btw, that Basics seems to be quite cool. it would be fun to port it to Speccy (maybe to +3DOS, with support for disk files). i don't think that i will do that myself, so if you have nothing better to do with your life... ;-)

Re: Z80 asm/disasm in Z80 asm, request

Posted: Thu Aug 13, 2020 7:34 am
by ketmar
yay, it is really great! by adding several i/o routines and very dumb expression parser (because it is using the same expression parser as the rest of the system) it correctly parsed "ld a,42", and even printed the generated machine code!

of course, it is far from being usable yet, but it looks really promising. also, it is less than 2kb of machine code. seems like a perfect hit.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Thu Aug 13, 2020 7:53 am
by +3code
ketmar wrote: Thu Aug 13, 2020 5:35 am btw, that Basics seems to be quite cool. it would be fun to port it to Speccy (maybe to +3DOS, with support for disk files).
Look here:
http://mdfs.net/Software/Spectrum/BBCBasic/

But only tape support.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Fri Aug 14, 2020 1:33 am
by ketmar
intermediate results:

Image

assembler size: 752
assembler tables size: 443

sizes are without expression parser and label manager. i'm expecting the whole thing to fit into 2kb (math expression parsing can be quite big). even 2.5/3 kb is still ok -- it is not a big price to pay to have full-featured assembler in dsForth.

i may include expression parser into assembler module, leaving only label manager as external dependence, so people may avoid writing it again and again. it is still nicely isolated from the other asm code, so it would be possible to replace it with your own.

ah, the license. BBC Basic (Z80) is zlib-licensed, so the asm will use the same license too.


p.s.: contrary to my other projects, i'm avoiding self-modifying code here, so the whole thing could be used in ROMs.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Fri Aug 14, 2020 3:46 am
by ketmar
here is the soruce code repository, so you can watch my progress if you want to. ;-) please, note that it is heavy WIP yet.

Re: Z80 asm/disasm in Z80 asm, request

Posted: Sat Aug 15, 2020 1:54 am
by ketmar
as usual, i was slightly overoptimistic. ;-) with expression parser (and without label manager) assembler size is ~2300 bytes. still acceptable, considering that expression parser is quite powerful (it supports operator precedence, parentheses, 16-bit mul/div/mod/shl/shr/and/or/xor/bitneg), and numeric parser supports wide range of prefixes and suffixes ("&"/"#"/"$"/"%"/"0x"/"0b"/"0o" as prefixes, "O"/"B"/"H" as suffixes). this number parser is more than 300 bytes by itself! ;-)

i am sure that Einar will be able to make it at least 50% smaller, but it is already good for me. ;-) my actual budget is ~3KB, and even with label manager it should still fit in 2500-2700 bytes.

i tried to comment the code, and make it easily reusable (including some comments in the original asm source), so feel free to look at it if you'll need built-in assembler for your z80 project. except for several runtime variables, the code is fully ROMable. it never calls any input/output routines too. IY register is used for input buffer pointer, tho, and IX register is used for output buffer pointer.

i will prolly make some more small changes to the code (like moving expression parser to the main asm module, and adding callback for getting label value into it), but there should be no big changes.

here's a k00l screenshot of the testing app, because people love screenshots!
Spoiler
Image

Re: Z80 asm/disasm in Z80 asm, request

Posted: Sat Aug 15, 2020 11:47 am
by ketmar
i moved everything asm-related into one source file (assembler and expression parser), added missing code to expression parser so it now understands labels (i.e. calls label manager callback for that), and added simple label manager to show how it could be written.

i also dropped disasm module to the repository.

in case you missed it, here's the repo with the sources.

Re: Z80 asm/disasm in Z80 asm [solution found]

Posted: Sat Aug 22, 2020 1:25 am
by ketmar
managed to strip out 30 bytes from assembler, and add "division by zero" check. less is more! ;-)