Jump to content

Photo

[Aquarius] Cross compiler tool chain

aquarius sdcc z80

5 replies to this topic

#1 Atirez OFFLINE  

Atirez

    Space Invader

  • 10 posts

Posted Thu Jul 24, 2014 5:12 AM

Hi all, first post so my apologies if this is covered else where but I could't find it. Having recieved my childhood Aquarius from my parents attic I would like to get in to programming some games/stuff for it but have been struggling to get a nice tool chain to compile, link, deploy anything.
 
What I am trying to do.
I would like to be able to do the following:
  • Compile my assembler code with an assembler to an object file
  • Compile my c code to an object file
  • Use a linker to link the files together
  • Finally produce a binary file from the resulting linker files
Also I would like to dump the machine code the compiler has generated from my code for debugging/learning purposes. Something like objdump provided in gcc.
 
What I have tried
I have tried several compilers including sd88k, sdcc but (and this may be due to lack of knowledge) have been unable to get these to do that. The sdcc does have a seperate assembler and c compiler however the assembler is also a linker, it produces .lst files which I assume are the generated assembly instructions from the compiler after any optomisation but it doesn't look right - again could just be me.
 
Finally
I have the PDF from Zilog describing the instruction set but can not find out any information about the sections that the assembler should be producing the sdcc produces some but I can not find out any information about them.
 
This is what I have been messing around with at the moment

bootstrap.s
.module	bootstrap
.optsdcc -mz80

.area	HOME (abs)
.org	#0x8000

.globl	_main
.globl 	_notmain

;--------------------------------------------------------
; Home
;--------------------------------------------------------
	.area _HOME
	.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area _CODE

_main:
	.db 98, 97, 114, 114
	.db 121, 156, 106, 176
	.db 111, 108, 110, 100
	.db 101, 168, 199, 112
	jr	_notmain
hang:
	jr	hang
notmain.c
unsigned int x(unsigned int x);

void notmain(void) {
	unsigned int n = 0;
	n = x(1);
	while(1) {
	}
}

x.c
unsigned int x(unsigned int x) {
	unsigned int y;
	unsigned int n = 5;

	y = x - n;
	return y + 2;
}
Batch file for building
@echo off

rem set the current working directory to the same location as the batch file
pushd "%~dp0"

cd ../
call sdcc_paths.bat

rem set the current working directory to the same location as the batch file
pushd "%~dp0"

rem build stuff
rem .rel are .o files

sdasz80 -l -o out/bootstrap.rel bootstrap.s 
sdcc -mz80 -c -o out/notmain.rel notmain.c
sdcc -mz80 -c -o out/x.rel x.c
sdcc -o out/helloworld.ihx out/bootstrap.rel out/notmain.rel out/x.rel

packihx out/helloworld.ihx > out/helloworld.hex
hex2bin -p 00 -l 4000 out/helloworld.ihx

The reason I have random methods in different files was to test linking. Anyway, when trying to run that it doesn't work, it correctly jumps to main but then the address to jump to the method x is incorrect and it jumps to far in memory (using Z80 Simulator IDE)

#2 Atirez OFFLINE  

Atirez

    Space Invader

  • Topic Starter
  • 10 posts

Posted Thu Jul 24, 2014 8:51 AM

Scratch that, I think I have got there - was mostly being stupid :/ Now I have:

 

bootstrap.asm

	.module bootstrap
	.z80
	.optsdcc -mz80
	
	.globl _notmain

_main:
	.db 98, 97, 114, 114
	.db 121, 156, 106, 176
	.db 111, 108, 110, 100
	.db 101, 168, 199, 112
	call	_notmain
hang:
	jr	hang

notmain.c

unsigned int x(unsigned int x);

extern void notmain(void) {
	unsigned int n = 0;
	n = x(1);
	while(1) {
	}
}

x.c

unsigned int x(unsigned int x) {
	unsigned int y;
	unsigned int n = 5;

	y = x - n;
	return y + 2;
}

build.bat

@echo off

rem set the current working directory to the same location as the batch file
pushd "%~dp0"

cd ../
call sdcc_paths.bat

rem set the current working directory to the same location as the batch file
pushd "%~dp0"

rem build stuff
rem .rel are .o files

sdasz80 -l -o -s out/bootstrap bootstrap
sdcc -mz80 --no-std-crt0 --compile-only -o out/ notmain.c
sdcc -mz80 --no-std-crt0 --compile-only -o out/ x.c

sdld -u -i out/1 out/bootstrap.asm out/notmain.rel out/x.rel

hex2bin -p 00 -l 4000 out/1.ihx

Needed some extra options on the command line stuff and to use the linker.

 

If at all possible though, could someone help me with the different sections that the z80asm expects/requires and help me understand the .org directive. I thought .org was used to tell the assembler to organise the data from that location, but my output in the final binary file seems to jam in to that location. So if I do have this eventually running on an aquarius it will load my file up to 0xE000 (from memory may be wrong) and find nothing there...



#3 mvdsteenoven OFFLINE  

mvdsteenoven

    Chopper Commander

  • 181 posts
  • Location:Netherlands

Posted Fri Jul 25, 2014 10:21 AM

Hi,
I am not familiar with sdcc, I useally compile Z80 code direct to a binary file.
ORG useally sets the startaddress. In Z80 you useally do not have to bother on _CODE, _DATA and _HEAP areas, but that is probally needed for the object file and linker.

I have noticed that you are not using any start addres or memory addresses in your second run.
How does the linker knows that the startaddress needs to be E000 for the Aquarius?
Perhaps the -mz80 sets a default start address?
What is the first object 1? Is this the Z80 object?
My guess is that somewhere in the sdld linker you should give the start address E000 and make the bootstrap object the first object.

Regs,
Martin

#4 Atirez OFFLINE  

Atirez

    Space Invader

  • Topic Starter
  • 10 posts

Posted Sat Jul 26, 2014 12:51 AM

Hi Martin, yeah it is all in the linker file. 

-mjwx
-i out\final\application.ihx
-b _CODE = 0xe000
-b _DATA = 0xf000
-k C:\RETRO\COMPILERS\SDCC\bin\..\lib\z80
-l z80
out\bootstrap.asm
out\data.asm
out\notmain.rel

-e

With this setup I feel a lot more in control of how my assembler/c code is working and it give me better listings in the output, since sdcc providers .rst files I do not seem to need to object dump

them anymore. For example:


extern char aletter;

void notmain(void) {

	char *screen;
	screen = (char*)0x3028;

	aletter = 66;
	*screen = aletter;

	while(1) {
	}
}

Produces this code with the addresses updated after linking.

   E016                      48 _notmain_start::
   E016                      49 _notmain:
                             50 ;source/notmain.c:8: aletter = 66;
   E016 21 15 E0      [10]   51 	ld	hl,#_aletter + 0
   E019 36 42         [10]   52 	ld	(hl), #0x42
                             53 ;source/notmain.c:9: *screen = aletter;
   E01B 21 28 30      [10]   54 	ld	hl,#0x3028
   E01E 36 42         [10]   55 	ld	(hl),#0x42
                             56 ;source/notmain.c:11: while(1) {
   E020                      57 00102$:
   E020 18 FE         [12]   58 	jr	00102$
   E022                      59 _notmain_end::
                             60 	.area _CODE
                             61 	.area _INITIALIZER
                             62 	.area _CABS (ABS)

The only problem I have now is that global variables do not seem to be getting initialised and I do not seem to be able to change their values in code.



#5 mvdsteenoven OFFLINE  

mvdsteenoven

    Chopper Commander

  • 181 posts
  • Location:Netherlands

Posted Sat Jul 26, 2014 1:31 PM

What strikes me in the compiled code; at line 55 the screen pointer is set to a fixed value and it is not using the aletter reference (e015).
Are you using some compiler optimalisations?

Regs,
Martin

#6 Atirez OFFLINE  

Atirez

    Space Invader

  • Topic Starter
  • 10 posts

Posted Sun Jul 27, 2014 7:21 AM

Hmm that is interesting, it must be getting optimised somewhere. I will look in to that.







Also tagged with one or more of these keywords: aquarius, sdcc, z80

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users