Jump to content

Photo

[AQUARIUS] z88dk Aquarius Development

AQUARIUS z88dk C config cfg z80

29 replies to this topic

#1 Pset OFFLINE  

Pset

    Chopper Commander

  • 124 posts

Posted Sat Jan 4, 2014 11:46 AM

Following are vital Z88 Development Kit files used for compiling C to Aquarius cassette files (.CAQ)

We should discuss and update these to make them more useful for our particular workflow,

 

C:\Program Files (x86)\z88dk\lib\config\aquansi.lnx

Spoiler



Edited by Pset, Sat Jan 4, 2014 11:53 AM.


#2 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sat Jan 4, 2014 11:51 AM

Very subtle differences betwee aquansi.lnx and aquansi.cfg

 

C:\Program Files (x86)\z88dk\lib\config\aquansi.cfg

Spoiler

 



#3 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sat Jan 4, 2014 12:10 PM

C:\Program Files (x86)\z88dk\src\appmake\aquarius.c

 

/*
 *   Mattel Aquarius
 *   This tool creates a BASIC loader file
 *   and a binary file stored in "variable array" format
 *
 *   The machine code starts at 14712.
 *   The original Mattel loader (now commented out) permitted
 *   little changes in the BASIC loader, but we don't need it.
 *
 *   Stefano Bodrato - December 2001: first release
 *
 *   $Id: aquarius.c,v 1.2 2009/06/13 19:16:42 dom Exp $
 */
 
#include "appmake.h"
 
static char             *binname      = NULL;
static char             *outfile      = NULL;
static char              help         = 0;
 
 
/* Options that are available for this module */
option_t aquarius_options[] = {
    { 'h', "help",     "Display this help",          OPT_BOOL,  &help},
    { 'b', "binfile",  "Linked binary file",         OPT_STR,   &binname },
    { 'o', "output",   "Name of output file",        OPT_STR,   &outfile },
    {  0,  NULL,       NULL,                         OPT_NONE,  NULL }
};
 
 
 
 
int aquarius_exec(char *target)
{
    char    filename[FILENAME_MAX+1];
    char    ldr_name[FILENAME_MAX+1];
char mybuf[20];
FILE *fpin, *fpout;
int c;
int i;
int len;
int dlen;
 
    strcpy(ldr_name,"_");
 
 
    if ( help || binname == NULL )
        return -1;
 
    if ( outfile == NULL ) {
        strcpy(filename,binname);
        suffix_change(filename,".caq");
    } else {
        strcpy(filename,outfile);
    }
 
 
if ( (fpin=fopen(binname,"rb") ) == NULL ) {
printf("Can't open input file\n");
exit(1);
}
 
 
/*
 * Now we try to determine the size of the file
 * to be converted
 */
 
if (fseek(fpin,0,SEEK_END)) {
printf("Couldn't determine size of file\n");
fclose(fpin);
exit(1);
}
 
len=ftell(fpin);
dlen=(len)/4;
 
fseek(fpin,0L,SEEK_SET);
 
/****************/
/* BASIC loader */
/****************/
 
strcat(ldr_name,filename);
 
if ( (fpout=fopen(ldr_name,"wb") ) == NULL ) {
printf("Can't create the loader file\n");
exit(1);
}
 
/* Write out the header  */
for (i=1;i<=12;i++)
writebyte(255,fpout);
writebyte(0,fpout);
writestring("LOADR",fpout);
writebyte(0,fpout);
for (i=1;i<=12;i++)
writebyte(255,fpout);
 
writebyte(0,fpout);
writeword(14601,fpout); /* points to line 10 */
 
writeword(5,fpout); /*  5 U=0 */
writebyte('U',fpout);
writebyte(0xB0,fpout);
writebyte('0',fpout);
 
writebyte(0,fpout);
writeword(14609,fpout); /* points to line 20 */
 
writeword(10,fpout); /*  10 X=0 */
writebyte('X',fpout);
writebyte(0xB0,fpout);
writebyte('0',fpout);
 
writebyte(0,fpout);
writeword(14621+2,fpout); /* points to line 30 */
 
writeword(20,fpout); /*  20 DIMA(xxxxx) */
writebyte(0x85,fpout);
writebyte('A',fpout);
writebyte('(',fpout);
sprintf(mybuf,"%i",dlen);
for (i=1;i<=(5-strlen(mybuf));i++)
writebyte('0',fpout);
writestring(mybuf,fpout);
writebyte(')',fpout);
 
writebyte(0,fpout);
writeword(14629+2,fpout); /* points to line 40 */
 
writeword(30,fpout); /*  30 CLOAD*A */
writebyte(0x9A,fpout);
writebyte(0xAA,fpout);
writebyte('A',fpout);
 
writebyte(0,fpout);
writeword(14651+2,fpout); /* points to line 50 */
 
writeword(40,fpout); /*  40 POKE14340,PEEK(14552)+7 */
writebyte(0x94,fpout);
writestring("14340,",fpout);
writebyte(0xC1,fpout);
writestring("(14552)",fpout);
writebyte(0xA8,fpout);
writebyte('7',fpout);
 
writebyte(0,fpout);
writeword(14671+2,fpout); /* points to line 60 */
 
writeword(50,fpout); /*  50 POKE14341,PEEK(14553) */
writebyte(0x94,fpout);
writestring("14341,",fpout);
writebyte(0xC1,fpout);
writestring("(14553)",fpout);
 
writebyte(0,fpout);
writeword(14682+2,fpout); /* points to end of program */
 
writeword(60,fpout); /*  60 X=USR(0) */
writebyte('X',fpout);
writebyte(0xB0,fpout);
writebyte(0xB5,fpout);
writestring("(0)",fpout);
 
for (i=1;i<=25;i++)
writebyte(0,fpout);
 
fclose(fpout);
 
 
/*********************/
/* Binary array file */
/*********************/
 
/* Write out the header  */
 
if ( (fpout=fopen(filename,"wb") ) == NULL ) {
printf("Can't create the data file\n");
exit(1);
}
 
 
/* Write out the header  */
for (i=1;i<=12;i++)
writebyte(255,fpout);
 
writebyte(0,fpout);
 
 
/* Write out the "file name" */
for (i=1;i<=6;i++)
writebyte('#',fpout);
 
/* for (i=1;i<=6;i++)
writebyte(0,fpout);*/
 
 
/* Mattel games loader relocator */
/*
writebyte(0x2A,fpout); // ld hl,(14552)
writeword(14552,fpout);
writebyte(0x23,fpout); // inc hl 
writebyte(0x23,fpout); // inc hl 
writebyte(0x4e,fpout); // ld c,(hl) 
writebyte(0x23,fpout); // inc hl 
writebyte(0x46,fpout); // ld b,(hl) 
writebyte(0x11,fpout); // le de,67 
writeword(67,fpout);
writebyte(0x19,fpout); // add hl,de 
writebyte(0xe5,fpout); // push hl 
writebyte(0xc5,fpout); // push bc 
writebyte(0xe1,fpout); // pop hl 
writebyte(0xb7,fpout); // or a 
writebyte(0xed,fpout); // sbc hl,de 
writebyte(0x52,fpout);
writebyte(0xe5,fpout); // push hl 
writebyte(0xc1,fpout); // pop bc 
writebyte(0xe1,fpout); // pop hl 
writebyte(0x23,fpout); // inc hl 
writebyte(0x7e,fpout); // ld a,(hl) 
writebyte(0xb7,fpout); // or a 
writebyte(0x28,fpout); // jr z,-4 
writebyte(0xfb,fpout);
writebyte(0x11,fpout); // ld de,14768 
writeword(14768,fpout);
writebyte(0xed,fpout); // ldir 
writebyte(0xb0,fpout);
 
for (i=1;i<=41;i++)
writebyte(0,fpout);
*/
 
 
/* We append the binary file */
 
for (i=0; i<len;i++) {
c=getc(fpin);
writebyte(c,fpout);
}
 
/* Now let's append zeroes and close */
 
for (i=1;i<=(len%4);i++)
writebyte(0,fpout);
 
for (i=1;i<=38;i++)
writebyte(0,fpout);
 
fclose(fpin);
fclose(fpout);
 
    return 0;
}
 
 

Edited by Pset, Sat Jan 4, 2014 12:16 PM.


#4 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sat Jan 4, 2014 12:31 PM

I've created a batch  for compiling with z88dk it looks like this

CALL z88dkenv.bat
zcc +aquansi -lm -create-app -o OutputName C_InputFile.c

 
I've not tried the other command line options in the zcc documenation:

The Frontend
The frontend of z88dk is called zcc, it is this that you should call if you want to do any compilations. To invoke the frontend use the command:

        zcc [flags]  [files to be compiled/linked]
The files can be either C files (.c) , preprocessed C files(.i), compiled C files (.asm), optimised compiled file (.opt) or assembled files (.obj), any combination of them can be mixed together and the relevant processed done on them.
Processing of a file list is done on each file in turn (i.e. preprocess, compile, optimise, assemble) at the end all files may be linked into a single executable if desired.
Options to control the action of the frontend:

     +[file]       Name of alternate config file 
     		   (must be the first argument)
     -a            Produce .asm (or .opt) file only
     -c            Do not link object files
     -E            Preprocess files only, leave output in .i file
     -o [file]     Specify output file for binary (default is a.bas for BASIC
                   programs and a.bin for application binaries)
     -On           Optimize compiler output (to .opt file)
                   n can be either 0 (none) 1,2,3, level 2 is recommended.
		   Level 3 is suitable for large programs (includes certain
		   lib functions to reduce size of code(!))
     -v            Verbose - echo commands as they are executed
     -vn           Don't be verbose
Options to control library usage:
     -l[name]      Link in a library - supply just the name (after placing them
                   in the correct directory)
     -lm           Link in the generic Z80 maths library
     -lmz          Link in and generate code for OZ's maths routines
     -lmalloc      Link in the near malloc routines
     -lgfx         Link in the graphics routines (for BASIC progams)
     -lgfxapp      Link in the graphics routines (for applications)
     -lz88         Link in some Z88 application routines (eg mailboxing)
     -lnet	   Link the the socket routines for ZSock
     -m            Generate .map files when assembling/linking
Options to control the type code produced:
     -unsigned     Implicitly define everything as unsigned unless explicitly
                   told otherwise.
     -create-app   Create an application image (i.e. bank 63,62 etc)
     -make-app     (App) Notify the compiler that you're trying to make an
                   application
     -reqpag=      (App) Number of 256 byte pages required for bad
                   application
     -zorg=        (App) Origin for a Z88 application
     -safedata=    (App) Amount of safedata required by your code
     -defvars=     (App) Where static variables should be dropped (only
                   valid for single file compilations, but see later)
     -expandz88    (App) Expanded z88 required
     -no-expandz88 (App) Expanded z88 not required (these two flags toggle
                   some startup code to check for an expanded machine)

     -startup=3    Produce standalone code that can be run from a set
                   address from BASIC. Use -zorg= to change the address
     -R            (Use with above) produces relocatable code that can be
                   loaded into a DIM'd BASIC array.

     -smartpf      Intelligent printf routine handling
     -no-smartpf   Turn off the intelligent printf handling
     -make-lib     Shortcut to generate .o files from library .c files
     -stackoffset  Sets the stack offset for shared libs (see package.txt
		   for details)
                   
Miscellaneous options:
     -z80-verb     Allow z80asm to be verbose, this tends to generate a lot
                   of output to the screen so may not be desired.
     -cc           Intersperse C code as comments in the assembler output, warning:
                   this *will* clobber some optimizations.
     -Wall         Turn on all the compiler warnings
     -Wnone        Turn off all compiler warnings
     -Wn[num]      Turn off the compiler warning [num]
     -W[num]       Turn on the compiler warning [num]
     -asxx	   Cause the compiler to emit asxx compatible code
     -Cp[option]   Pass an option through to the pre-processor
     -Ca[option]   Pass an option through to the assembler
In addition, the flags, -D, -I, -U are passed through to the preprocessor.
Any unrecognised options are passed through to the compiler (to allow for improvements in the future.)
Configuration files
In order for z88dk to work on as many platforms as possible and so that it can be easily tweaked, retargetted and generally mutilated, the frontend (zcc) consults a plain text configuration file which is in the directory pointed to be the ZCCCFG variable.
The default is to use the file ZCCCFG/zcc.cfg which by default is a softlink to the configuration file for the z88. Should you mainly be targetting a different machine then simply change the softlink to the appropriate file.
Should you want to occasionally compile for other machines then as the construct your zcc line thusly:

zcc +[name] [....]
Where name is either z88, zx (Spectrum), or vz (for the VZ200/300 port). If you wish to use a config file located in the current directory or anywhere else on the system then specify the full path and filename - make sure the filename as the suffix .cfg.
Finally, for the sake of backwards compatibility zcc will take the value of the environmental variable ZCCFILE and use that config file.

The order of checking is as follows:


"Local" file (if exists) eg +temp.cfg
ZCCCFG/[name].cfg eg +z88
ZCCFILE
ZCCCFG/zcc.cfg
 

Edited by Pset, Sat Jan 4, 2014 12:32 PM.


#5 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sat Jan 4, 2014 1:42 PM

Looks like there's a lot more to this than I thought.

"C:\Program Files (x86)\z88dk\lib\clibs\aquansi_clib.lib"

Is full of binary gabrage and I don't think we can edit it.
I assumed its built from something like this .lst file?

 

C:\Program Files (x86)\z88dk\libsrc\aquansi.lst


stdio/aquarius/fgetc_cons

stdio/aquarius/getk
stdio/ansi/f_ansi
stdio/ansi/f_ansi_lf
stdio/ansi/f_ansi_putc
stdio/ansi/fputc_cons
stdio/ansi/puts_cons
stdio/ansi/f_ansi_dsr6
stdio/ansi/aquarius/f_ansi_attr
stdio/ansi/aquarius/f_ansi_bel
stdio/ansi/aquarius/f_ansi_char
stdio/ansi/aquarius/f_ansi_cls
stdio/ansi/aquarius/f_ansi_dline
stdio/ansi/aquarius/f_ansi_scrollup
@gfxbasetxt6.lst
graphics/aquarius/textpixl6
games/aquarius/bit_open
games/aquarius/bit_open_di
games/aquarius/bit_close
games/aquarius/bit_close_ei
games/bit_click
games/bit_play
games/bit_fx
games/bit_fx2
games/bit_fx3
games/bit_fx4
games/bit_synth
games/bit_frequency
games/bit_beep
games/beeper
games/joystick
@z80.lst


#6 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sat Jan 4, 2014 1:54 PM

C:\Program Files (x86)\z88dk\lib\aquarius_crt0.asm

 

;       CRT0 for the Mattel Aquarius
;
;       Stefano Bodrato Dec. 2000
;
;       If an error occurs eg break we just drop back to BASIC
;
;       $Id: aquarius_crt0.asm,v 1.8 2009/06/22 21:20:05 dom Exp $
;
 
 
 
                MODULE  aquarius_crt0
;--------
; Include zcc_opt.def to find out some info
;--------
        INCLUDE "zcc_opt.def"
 
;--------
; Some scope definitions
;--------
 
        XREF    _main           ;main() is always external to crt0 code
 
        XDEF    cleanup         ;jp'd to by exit()
        XDEF    l_dcal          ;jp(hl)
 
        XDEF    _std_seed        ;Integer rand() seed
 
        XDEF    _vfprintf       ;jp to the printf() core
 
        XDEF    exitsp          ;atexit() variables
        XDEF    exitcount
 
        XDEF    __sgoioblk      ;stdio info block
 
        XDEF heaplast ;Near malloc heap variables
XDEF heapblocks
 
        XDEF    base_graphics   ;Graphical variables
XDEF coords ;Current xy position
 
XDEF snd_tick ;Sound variable
 
 
        ;;org     14768 ; Mattel relocating loader
org 14712 ; Simpler loader
 
start:
        ld      (start1+1),sp ;Save entry stack
        ld      hl,-64
        add     hl,sp
        ld      sp,hl
        ld      (exitsp),sp
 
IF !DEFINED_nostreams
IF DEFINED_ANSIstdio
; Set up the std* stuff so we can be called again
ld hl,__sgoioblk+2
ld (hl),19 ;stdin
ld hl,__sgoioblk+6
ld (hl),21 ;stdout
ld hl,__sgoioblk+10
ld (hl),21 ;stderr
ENDIF
ENDIF
        call    _main ;Call user program
cleanup:
;
;       Deallocate memory which has been allocated here!
;
 
IF !DEFINED_nostreams
IF DEFINED_ANSIstdio
LIB closeall
call closeall
ENDIF
ENDIF
 
start1: ld sp,0 ;Restore stack to entry value
        ret
 
l_dcal: jp (hl) ;Used for function pointer calls
 
 
;-----------
; Define the stdin/out/err area. For the z88 we have two models - the
; classic (kludgey) one and "ANSI" model
;-----------
__sgoioblk:
IF DEFINED_ANSIstdio
INCLUDE "stdio_fp.asm"
ELSE
        defw    -11,-12,-10
ENDIF
 
 
 
;---------------------------------
; Select which printf core we want
;---------------------------------
_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
 
;-----------
; Now some variables
;-----------
coords:         defw    0       ; Current graphics xy coordinates
base_graphics:  defw    $3028   ; Address of the Graphics map
; (text area-second line)
 
_std_seed:      defw    0       ; Seed for integer rand() routines
 
exitsp:         defw    0       ; Address of where the atexit() stack is
exitcount:      defb    0       ; How many routines on the atexit() stack
 
 
heaplast:       defw    0       ; Address of last block on heap
heapblocks:     defw    0       ; Number of blocks
 
IF DEFINED_NEED1bitsound
snd_tick:       defb    0       ; Sound variable
ENDIF
 
defm "Small C+ Aquarius" ;Unnecessary file signature
defb 0
 
;-----------------------
; Floating point support
;-----------------------
IF NEED_floatpack
        INCLUDE         "float.asm"
fp_seed:        defb    $80,$80,0,0,0,0 ;FP seed (unused ATM)
extra:          defs    6 ;FP register
fa:             defs    6 ;FP Accumulator
fasign:         defb    0 ;FP register
 
ENDIF


#7 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sat Jan 4, 2014 2:11 PM

I can't figure out how to change the CAQ loader in Aquarius.c

 

I change the file, adding lines and even just change the
numbering of the lines, recompile and I get the same exact CAQ file.

The number 12 here seems important. Why do these loops exist?

Is that 12 the number of BASIC keywords and operators in the BASIC LOADR file?

for (i=1;i<=12;i++)
writebyte(255,fpout);
writebyte(0,fpout);
writestring("LOADR",fpout);
writebyte(0,fpout);
for (i=1;i<=12;i++)
....

Edited by Pset, Sat Jan 4, 2014 2:12 PM.


#8 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Mon Jan 6, 2014 4:11 PM

Might take some time to figure out how to change z88dk.

For now let's learn some C programming on the Aquarius

 

Here's a C file that takes key input,returns the key value, the character, and demonstrates custom defintion of keys using #Define.

There are several ways of getting key input. I pulled this one from Barnie's sprite demo.

I've been doing all my C for Aquarius dev directly in the z88dk directory. To try it yourself, copy the attached .c and .bat files to the z88dk directory adn double click the .bat file.

You should get two .caq files as a result.

 

Spoiler

Attached Files


Edited by Pset, Mon Jan 6, 2014 4:41 PM.


#9 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 9,310 posts

Posted Mon Jan 6, 2014 4:15 PM

Just so you know: my lack of comment in this topic is not lack of interest!  The next step in my growth as a developer is getting my hands dirty with C.  Topics like this help me get into the right mindset.



#10 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Mon Jan 6, 2014 5:26 PM

Now lets get a series of key down input using C with z88dk.

This one exits to BASIC with Control + C  key combo.

Had hell of a time trying to use escape (aquarius can't see), and Control + Q never worked. *shrug*

 

Spoiler

Attached Files


Edited by Pset, Mon Jan 6, 2014 5:29 PM.


#11 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Wed Jan 8, 2014 3:29 AM

To make compiling with z88dk easier I've created a program that lets

you peruse your C files and compile them, it then organizes all the various files into one folder.

For instance hello.c produces  hello.bat, _hello.caq, hello.caq, and hello and they all get swept into folder "hello_"

 

I had dozens of small C experiments floating around z88dk folder.

This tool allows you to place C files anywhere.

I added the path to z88dk to my user PATH variable, but I'm not sure its needed.

 

Oh this program also launches the virtual aquarius using the command "aquarius", Which I set up with an alias in my PATH variable somewhere?

I did it long ago, forget how that's done. I'll have to test on another PC to see what kind of trouble that might cause. Hopefully not too much.

 

As usual the livecode source is included with the binaries for win/mac/linux.

EtVg0lr.png

 

 

Attached Files



#12 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Wed Jan 8, 2014 4:00 PM

I've started some discussion with z88dk's developer about getting it to compile cartridge binaries.

He's asking about loading 'snapshots' of memory.

 

Maybe someone besides me should do the talking. 

Maybe drop on over at their forum? 


Edited by Pset, Wed Jan 8, 2014 4:43 PM.


#13 JamesD OFFLINE  

JamesD

    Quadrunner

  • 8,402 posts
  • Location:Flyover State

Posted Thu Jan 9, 2014 3:16 PM

I don't have membership to the Z88dk forum to post so I'll comment here.
This pertains to the last message that mentions carts.

You just have to tell the linker where to put the code and data segments.  These are usually referred to as code, data or bss sections

On the SDCC site there is a comment about _CODE and _DATA being passed to the linker and after looking through the SDCC sources, I found them defined in crt0.s.
You'll need to org them to the proper memory locations to create a cart.
There should be docs for the ".area" directive that will help out with this.



#14 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Thu Jan 9, 2014 5:06 PM

Wooosh you say stuff, its all very mysterious to me. What?

 

"C:\Program Files\SDCC\lib\src\z80\crt0.s"

;--------------------------------------------------------------------------
;  crt0.s - Generic crt0.s for a Z80
;
;  Copyright (C) 2000, Michael Hope
;
;  This library is free software; you can redistribute it and/or modify it
;  under the terms of the GNU General Public License as published by the
;  Free Software Foundation; either version 2, or (at your option) any
;  later version.
;
;  This library is distributed in the hope that it will be useful,
;  but WITHOUT ANY WARRANTY; without even the implied warranty of
;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;  GNU General Public License for more details.
;
;  You should have received a copy of the GNU General Public License 
;  along with this library; see the file COPYING. If not, write to the
;  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
;   MA 02110-1301, USA.
;
;  As a special exception, if you link this library with other files,
;  some of which are compiled with SDCC, to produce an executable,
;  this library does not by itself cause the resulting executable to
;  be covered by the GNU General Public License. This exception does
;  not however invalidate any other reasons why the executable file
;   might be covered by the GNU General Public License.
;--------------------------------------------------------------------------
 
.module crt0
.globl _main
 
.area _HEADER (ABS)
;; Reset vector
.org  0
jp init
 
.org 0x08
reti
.org 0x10
reti
.org 0x18
reti
.org 0x20
reti
.org 0x28
reti
.org 0x30
reti
.org 0x38
reti
 
.org 0x100
init:
;; Stack at the top of memory.
ld sp,#0xffff
 
        ;; Initialise global variables
        call    gsinit
call _main
jp _exit
 
;; Ordering of segments for the linker.
.area _HOME
.area _CODE
.area _INITIALIZER
.area   _GSINIT
.area   _GSFINAL
 
.area _DATA
.area _INITIALIZED
.area _BSEG
.area   _BSS
.area   _HEAP
 
.area   _CODE
__clock::
ld a,#2
rst     0x08
ret
 
_exit::
;; Exit - special code to the emulator
ld a,#0
rst     0x08
1$:
halt
jr 1$
 
.area   _GSINIT
gsinit::
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_next
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_next:
 
.area   _GSFINAL
ret


#15 JamesD OFFLINE  

JamesD

    Quadrunner

  • 8,402 posts
  • Location:Flyover State

Posted Thu Jan 9, 2014 7:14 PM

I'm not completely familiar with SDCC but I'll try to explain it.

*edit*
A compiler does not just mix code and data together like you might in assembly.  It normally generates an intermediate object code that is a mix of code and data with embedded data for the linker and those are organized in segments based on what they are for.
*edit*

These are segments the compiler/linker uses to define where things go in memory:  In the startup code you posted, the code/data segments are just inserted one after the other.  That will need to be changed to specific addresses.
 

C allocates non-static variables on the stack and passes parameters on the stack.  As long as you initialize the stack pointer to some area RAM, most stuff will work.  Normally you initialize this to be the top of RAM or a large area of RAM since the stack builds down as you push things onto it.  This is not a segment but it's built into the code and as long as the stack pointer is set you don't have to worry much about it.  Just remember that things like recursion can build a huge stack and it can run down into memory you use for something else if you aren't careful.  You will need to change the org at the start of the startup code to be the first address executed in a cart.  Note that some game consoles require all sorts of data to reside in the cart before your code and you'll need developer docs for something like that.  I had to look that up for the Colecovision to build the IDE boot image for the Adam.
 
_CODE is your machine code output by the compiler.  All the code is joined together there by the linker.
 

_DATA *should* point to things like strings that aren't modified... this is partially under programmer control so the better way to put it is don't mess with constants once you've created them and you won't have trouble putting the code in ROM... which is where this segment will go, right after your code. 

_BSS goes in RAM.  These are variables, data or data buffers that are at a fixed location, are modified by the program but aren't given a value where they are created in the code.  This will not go in ROM but the linker normally reserves a block of memory for it.  The linker either needs a command to leave it off your you have to chop it off of the binary image generated by the linker.  Make sure you initialize all these variables in your C code somewhere at startup or at least clear that block of RAM to zero in your startup code (crt0.s).
This will explain bss a little better:
https://en.wikipedia.org/wiki/.bss

_HEAP is free memory that you would allocate from and usually contains globals you have defined.  You need to initialize globals before you use them because RAM will have unknown contents when a cart starts.

If you use malloc you will also need to tell the memory handling routines what RAM to use before you call the main C code.  Be sure *not* to include memory you will be using for the stack.

The startup code would need several things moved.  The way it's written,it just stuffs in each segment where the last one ends.

These would need moved to RAM, the rest would be ROM (I think):

.area _BSEG
.area   _BSS
.area   _HEAP

I think the INITIALIZE would be dropped but I'm not sure.  I'd have to study the docs.

Move these to the end and put an org statement before them with the address of where free RAM starts (avoiding any RAM ROM routines you call will use) that should be what you need.  I have done this with other compilers for embedded systems but I make no promises since I haven't done it with this compiler/linker and it's been a few years.  
 

I hope that helps.


 


Edited by JamesD, Thu Jan 9, 2014 7:47 PM.


#16 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Sun Jan 12, 2014 10:34 PM

I wish that made some sense, but it doesn't. Thanks for trying.

 

For now here's a nice sprite demo in which we demonstrate loading files exterior to our main program.

In this case it is the large 10x17 running man sprites produced in Spedito.

 

The C files defining the sprite get a .h (for header) extension and become accessible with the #include statement.

 

I think Licecap GIF screengrabber caught inbetween frames 

 

B6upSpE.gif

 

Spoiler

Edited by Pset, Sun Jan 12, 2014 10:46 PM.


#17 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Tue Jan 14, 2014 3:32 AM

Sorry this forum cuts off anything I do after using code blocks.

 

Here's the source files for that sprite demo.

 

He actually goes left and right with the A and D keys.

Up and down with W and S.

 

Be sure to check out the H files and see how the hex is put into data,

and the 'image' of the sprite is saved in commented code blocks.

Also how these 10x17 sprites were cut into 8x17 blocks for converting to hex.

Well here's an example of an 8 x16 sprite I couldn't use.

The pixels on the edge leave trails when the sprite moves so I had to go larger to add a mask.

char manright2[] = { 8, 16,
  0x00 /* ........ */,
  0x38 /* ..###... */,
  0x3c /* ..####.. */,
  0x00 /* ........ */,
  0x39 /* ..###..# */,
  0x79 /* .####..# */,
  0xdf /* ##.##### */,
  0xdc /* ##.###.. */,
  0x7c /* .#####.. */,
  0x3e /* ..#####. */,
  0x1b /* ...##.## */,
  0x33 /* ..##..## */,
  0xf3 /* ####..## */,
  0xc3 /* ##....## */,
  0x80 /* #....... */,
  0x00 /* ........ */
};
 

 

Attached Files



#18 JamesD OFFLINE  

JamesD

    Quadrunner

  • 8,402 posts
  • Location:Flyover State

Posted Wed Jan 15, 2014 5:03 PM

The documentation for SDCC is a bit lacking and I'll probably need to look at the source code to be sure any changes I make will be correct.
I worked on a 6809 code generator for SDCC but that was many versions ago and a lot has changed.

#19 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Wed Jan 15, 2014 6:03 PM

OK.

Here's a colorful 99 Bottles of Beer program for your Aquarius. Note the for(t=100000) loops to slow it down.

A version in BASIC without coloring is blazing fast to.

Coloring the lines in BASIC  and making them scroll is a chore for another time.

Colors don't scroll in BASIC, although I think there was a poke to get the screen to shift?

 Maybe that was wishful thinking. Something must exist though because we can do it in C

 

// 99 bottles of beer mostly from  http://www.99-bottles-of-beer.net/language-c-844.html
 
#include <stdio.h>
 
int main(void)
{        
        int b;
int c;
        int t;
int color =31;
 
printf ("%c2J",155);
        for (b = 99; b >= 0; b--) {
c = c + 1;
if(c >= 5){
c=0;
//printf("%c2J",155);
}
color =color + 1;
if (color == 39) color=42;
if (color >= 47) color=31; 
sleep(1000);
//slow it down
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
 
                switch (b) {
                case 0:
                        printf("No more bottles of beer on the wall, no more bottles of beer.\n");
 
                        printf("Go to the store and buy some more, 99 bottles of beer on the wall.\n");
                        break;
                case 1:
                        printf("1 bottle of beer on the wall\n 1 bottle of beer.\n");
                        printf("Take one down and pass it around, no more bottles of beer on the wall\n");
                        break;
                default:
                        printf("%d bottles of beer on the wall\n %d bottles of beer.\n", b, b);   
//slow it down
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
for(t=100000; t<=0; t--); 
 
                                // you can break long line  by carriage returns before your semi colon finishes the line good to know.
 
                                  printf("%c[%umTake one down and pass it around\n %d %s of beer on the wall.\n\n",27,color
                                ,b - 1 ,((b - 1) > 1)? "bottles" : "bottle");
                        break;
                }
        }       
        
        return 0;
}
 

Attached Files



#20 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Wed Jan 15, 2014 6:05 PM

Also a note about my compiler app. For whatever reason in stand alone mode it only makes the batch file but doesn't actually compile your C program.

Dragging the batch to the command console will get your C program all compiled up.
I guess double clicking works to but I drag and drop then use the arrow up key  in the command console to recompile my changes every other minute.



#21 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Thu Jan 16, 2014 5:05 AM

Have to kill that sleep(0); line in the code above and likely in the download.

I really wish I could edit posts. 



#22 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Thu Jan 16, 2014 9:25 PM

Here is an ASCII chart in C. It stops after filling the screen and waits for a key press so you can get  a screenshot, or study the chart.

It loops until you press Control C and then drops into BASIC

 

Typing x=usr(0)  and pressing return will run the program again.

Learned this in a CS class last year, knew it would come in handy.

 

Instead of using the CLOAD sequence for the two CAQ files you can use the build bin.

I've renamed one of the build files to asciichart.bin, you can use Virtual Aquarius Util menu "Load Binary File..." and set USR address to $3978 

Then type x=usr(0)  and pressing return will run the program

 

// ascii chart display for the Aauarius  in C
#include <stdio.h>
// prints ascii value list
void main()
{
char cIn;
// ascii value, I force the zero character to print NULL.
int i,x,n, h;
 
// run until command C
do{
i=1;
 
//  column counter
x=0;
 
// variable number of columns
n=5;
   
// half of characters
h = 120
//clear screen to black with white text
printf ("%c2J",155);
printf("0 NULL ");
 
do
{
    //  escape characters 
    if (i>6 && i<14) {
        if (i==7){printf("%d BELL ",i);}
        if (i==8){printf("%d BS ",i);}
        if (i==9){printf("%d TAB ",i);}
        if (i==10){printf("%d LF ",i);}
        if (i==11){printf("%d VT ",i);}
        if (i==12){printf("%d LF ",i);}
 
        // after the carriage return start new column and row 
        if (i==13){
        printf("%d CR \n",i); 
        x = 0;
        }
    } 
 
    // print the ascii value and the character 
    else{
    printf("%d %c ",i,i);
    }
// use longer rows after the escape characters are printed.
    if (i > 14){
    n = 6;
    }
    // make a new row every n chars.
    if (x == n) {
    printf("\n");
    x = 0;
    }
if (i == h){
printf("\n");
while((cIn = getchar()) == ''); 
}
    // increment x and i
    x++;
    i++;
}
while(i<=255);
printf("\n");
// press any key to run again
while((cIn = getchar()) == '');
// press contraol C to exit into BASIC
}while(cIn = getchar() != '\03')
return 0;
 
}
 

Attached Files



#23 JamesD OFFLINE  

JamesD

    Quadrunner

  • 8,402 posts
  • Location:Flyover State

Posted Fri Jan 17, 2014 12:14 AM

I *think* I found what I was looking for. Ignore the stuff I said needed changed.
Just use the startup module you already posted that was written for the Aquarius and set some linger options discussed on the following page:
http://manpages.ubun...an1/sdcc.1.html

I believe the options you want to set to build carts are:
--code-loc
--data-loc
--stack-loc

The startup file may need some changes but I'm not familiar with the Aquarius to know without looking things up and I don't have time at the moment.
The code location should be set to the start address of cart ROM.
The data location should be set to the first usable free RAM address.
The stack location should be set to the top of RAM.

#24 JamesD OFFLINE  

JamesD

    Quadrunner

  • 8,402 posts
  • Location:Flyover State

Posted Fri Jan 17, 2014 9:54 AM

I *think* I found what I was looking for. Ignore the stuff I said needed changed.
Just use the startup module you already posted that was written for the Aquarius and set some linger options discussed on the following page:
http://manpages.ubun...an1/sdcc.1.html

I believe the options you want to set to build carts are:
--code-loc
--data-loc
--stack-loc

The startup file may need some changes but I'm not familiar with the Aquarius to know without looking things up and I don't have time at the moment.
The code location should be set to the start address of cart ROM.
The data location should be set to the first usable free RAM address.
The stack location should be set to the top of RAM.

That was supposed to say linker.

#25 Pset OFFLINE  

Pset

    Chopper Commander

  • Topic Starter
  • 124 posts

Posted Fri Jan 17, 2014 11:52 AM

Ok now which file did you say we insert some changes to? The one in the first post? Well ain't that something.

And then what we need to recompile something somewhere?

 

 

Maybe someone knows for sure what values go in the commands. 

I expect it starts with E010 for the 16 bytes of cartridge header?

But that seems out of range, but maybe out of range is expect because its on the cartridge?

I tried to make heads of Martin's boot loader script but there was even more outrageous numbers in there.

I need to look at it more.

Here's what Boriels zx BASIC does at cartridge compile time


aquariusromheader:
asm
  defb $53,$43,$30,$38,$4B,$9C,$B5,$B0,$A8,$6C,$AC,$64,$CC,$A8,$06,$70
  end asm
'- do not forget to scramble your program with 62
'- rom starts at $E000, and compiled at $E010
 
'- 8K Mode Header:  53 43 30 38 4B 9C B5 B0 A8 6C AC 64 CC A8 06 70
'- 16K Mode Header: 53 43 31 36 4B 9C B5 B0 A8 6C AC 64 CC A8 08 70





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users