# Compiling and installing everything and runing test
# ---------------------------------------------------
install: all installdirs
- $(CP) *.h $(sdcc_datadir)/include/
+ $(CP) -r asm *.h $(sdcc_datadir)/include/
# Deleting all the installed files
--- /dev/null
+/** Z80 specific features.
+ */
+#ifndef __SDC51_ASM_Z80_FEATURES_H
+#define __SDC51_ASM_Z80_FEATURES_H 1
+
+#define _REENTRANT reentrant
+#define _CODE code
+
+#endif
--- /dev/null
+/** GBZ80 specific features.
+ */
+#ifndef __SDC51_ASM_GBZ80_FEATURES_H
+#define __SDC51_ASM_GBZ80_FEATURES_H 1
+
+#define _REENTRANT
+#define _CODE
+
+#endif
--- /dev/null
+/** Z80 specific features.
+ */
+#ifndef __SDC51_ASM_Z80_FEATURES_H
+#define __SDC51_ASM_Z80_FEATURES_H 1
+
+#define _REENTRANT
+#define _CODE
+
+#endif
#ifndef __SDC51_CTYPE_H
#define __SDC51_CTYPE_H 1
+#include <sdcc-lib.h>
+
#ifdef SDCC_STACK_AUTO
#warning Make sure you recompile _is*.c files as 'reentrant'
-extern char iscntrl (unsigned char ) reentrant ;
-extern char isdigit (unsigned char ) reentrant ;
-extern char isgraph (unsigned char ) reentrant ;
-extern char islower (unsigned char ) reentrant ;
-extern char isupper (unsigned char ) reentrant ;
-extern char isprint (unsigned char ) reentrant ;
-extern char ispunct (unsigned char ) reentrant ;
-extern char isspace (unsigned char ) reentrant ;
-extern char isxdigit (unsigned char ) reentrant ;
+extern char iscntrl (unsigned char ) _REENTRANT ;
+extern char isdigit (unsigned char ) _REENTRANT ;
+extern char isgraph (unsigned char ) _REENTRANT ;
+extern char islower (unsigned char ) _REENTRANT ;
+extern char isupper (unsigned char ) _REENTRANT ;
+extern char isprint (unsigned char ) _REENTRANT ;
+extern char ispunct (unsigned char ) _REENTRANT ;
+extern char isspace (unsigned char ) _REENTRANT ;
+extern char isxdigit (unsigned char ) _REENTRANT ;
#else
--- /dev/null
+/** Top level header file for the sdcc libraries that enables target
+ specific features.
+*/
+#ifndef __SDC51_SDCC_LIB_H
+#define __SDC51_SDCC_LIB_H 1
+
+#if defined(__z80)
+#include <asm/z80/features.h>
+
+#elif defined(__gbz80)
+#include <asm/gbz80/features.h>
+
+#else
+/* PENDING */
+#include <asm/default/features.h>
+
+#endif
+
+#endif
#ifndef __SDC51_STDARG_H
#define __SDC51_STDARG_H 1
-#if defined(__ds390)
+#if defined(__ds390) || defined(__z80) || defined(__gbz80)
typedef unsigned char * va_list ;
#define va_arg(marker,type) *((type *)(marker -= sizeof(type)))
#include <tinibios.h>
#endif
-extern void printf_small (char *,...) reentrant;
-extern int printf (const char *,...) reentrant;
+#include <sdcc-lib.h>
+
+extern void printf_small (char *,...) _REENTRANT;
+extern int printf (const char *,...) _REENTRANT;
extern int vprintf (const char *, va_list);
-extern int sprintf (const char *, const char *, ...) reentrant;
+extern int sprintf (const char *, const char *, ...) _REENTRANT;
extern int vsprintf (const char *, const char *, va_list);
extern int puts(const char *);
extern char *gets(char *);
srcdir = @srcdir@
CPPFLAGS = -I$(INCDIR)
-CFLAGS =
-
-OBJECTS = _atoi.rel _atol.rel _autobaud.rel _bp.rel _schar2fs.rel \
- _decdptr.rel _divsint.rel _divslong.rel _divuint.rel \
- _divulong.rel _fs2schar.rel _fs2sint.rel _fs2slong.rel \
- _fs2uchar.rel _fs2uint.rel _fs2ulong.rel _fsadd.rel \
- _fsdiv.rel _fseq.rel _fsgt.rel _fslt.rel _fsmul.rel \
- _fsneq.rel _fssub.rel _gptrget.rel _gptrput.rel \
- _sint2fs.rel _iscntrl.rel _isdigit.rel _isgraph.rel \
- _islower.rel _isprint.rel _ispunct.rel _isspace.rel \
- _isupper.rel _isxdigit.rel _slong2fs.rel _memcmp.rel \
- _memcpy.rel _memset.rel _modsint.rel _modslong.rel \
- _moduint.rel _modulong.rel _mulsint.rel _muluint.rel \
- _mululong.rel _mulslong.rel _ser.rel _setjmp.rel \
- _spx.rel _startup.rel _strchr.rel _strcmp.rel _strcpy.rel \
- _strcspn.rel _strlen.rel _strncat.rel _strncmp.rel \
- _strncpy.rel _strpbrk.rel _strrchr.rel _strspn.rel \
- _strstr.rel _strtok.rel _uchar2fs.rel _uint2fs.rel \
- _ulong2fs.rel malloc.rel serial.rel ser_ir.rel printfl.rel \
- printf_large.rel vprintf.rel puts.rel gets.rel \
- assert.rel _strcat.rel time.rel
-SOURCES = $(patsubst %.rel,%.c,$(OBJECTS))
+CFLAGS = $(MODELFLAGS)
+
+BUILDDIR = build
+# Default
+PORT = z80
+PORTDIR = $(BUILDDIR)/$(PORT)
+
+SOURCES = _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \
+ _decdptr.c _divsint.c _divslong.c _divuint.c \
+ _divulong.c _fs2schar.c _fs2sint.c _fs2slong.c \
+ _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c \
+ _fsdiv.c _fseq.c _fsgt.c _fslt.c _fsmul.c \
+ _fsneq.c _fssub.c _gptrget.c _gptrput.c \
+ _sint2fs.c _iscntrl.c _isdigit.c _isgraph.c \
+ _islower.c _isprint.c _ispunct.c _isspace.c \
+ _isupper.c _isxdigit.c _slong2fs.c _memcmp.c \
+ _memcpy.c _memset.c _modsint.c _modslong.c \
+ _moduint.c _modulong.c _mulsint.c _muluint.c \
+ _mululong.c _mulslong.c _ser.c _setjmp.c \
+ _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
+ _strcspn.c _strlen.c _strncat.c _strncmp.c \
+ _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
+ _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \
+ _ulong2fs.c malloc.c serial.c ser_ir.c printfl.c \
+ printf_large.c vprintf.c puts.c gets.c \
+ assert.c _strcat.c time.c
+
+OBJECTS = $(patsubst %.c,$(PORTDIR)/%.rel,$(SOURCES))
+
+Z80SOURCES = _atoi.c \
+ _iscntrl.c _isdigit.c _isgraph.c \
+ _islower.c _isprint.c _ispunct.c _isspace.c \
+ _isupper.c _isxdigit.c _memcmp.c \
+ _memcpy.c _memset.c \
+ _startup.c _strchr.c _strcmp.c _strcpy.c \
+ _strcspn.c _strlen.c _strncat.c _strncmp.c \
+ _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
+ _strstr.c _strtok.c \
+ puts.c gets.c \
+ assert.c _strcat.c
+
+Z80OBJECTS = $(Z80SOURCES:%.c=$(PORTDIR)/%.o)
+
+OEXT = .rel
include incl.mk
# Compiling entire program or any subproject
# ------------------------------------------
-all: checkconf models modelDS390
+all: checkconf models model-ds390 model-z80 model-gbz80
-objects: $(OBJECTS)
+objects: build-dir $(OBJECTS) port-specific-objects
models:
for model in $(MODELS); do \
- test -d $$model || mkdir $$model; \
- $(MAKE) CFLAGS="$(CFLAGS) --model-$$model" objects; \
- mv *.rel $$model; \
- mv *.asm $$model; \
+ $(MAKE) MODELFLAGS="--model-$$model" PORT=$$model objects; \
done
-modelDS390:
+model-ds390:
if [ "`grep ds390 ../../ports.build`" = ds390 ]; then \
- test -d ds390 || mkdir ds390; \
- rm -f ds390/*.lib; \
- $(MAKE) CFLAGS="$(CFLAGS) -mds390" objects; \
- cd ds390; $(MAKE); cd ..; \
- cp *.lib ds390; \
- mv *.rel *.asm ds390; \
+ $(MAKE) MODELFLAGS="-mds390" PORT=ds390 objects; \
+ fi
+
+model-z80:
+ $(MAKE) MODELFLAGS="-mz80" PORT=z80 objects-z80 OEXT=.o
+
+model-gbz80:
+ $(MAKE) MODELFLAGS="-mgbz80" PORT=gbz80 objects-z80 OEXT=.o
+
+objects-z80: build-dir $(Z80OBJECTS) port-specific-objects
+ cd $(PORTDIR); ls *$(OEXT) > $(PORT).lib
+
+build-dir: $(PORTDIR)
+
+$(PORTDIR):
+ mkdir -p $(PORTDIR)
+
+port-specific-objects:
+ if [ -d $(PORT) ]; then \
+ $(MAKE) -C $(PORT); \
+ cp -f $(PORT)/*.lib $(PORT)/*$(OEXT) $(PORTDIR); \
fi
# Compiling and installing everything and runing test
# ---------------------------------------------------
-install: installDS390
- $(CP) *.c $(sdcc_datadir)/lib/
- for model in $(MODELS); do \
- [ -d $$model ] || $(MAKE) all; \
- $(CP) $$model/*.rel *.lib $(sdcc_datadir)/lib/$$model/; \
- $(CP) $$model/*.asm $(sdcc_datadir)/lib/$$model/; \
- done
-
-installDS390: installdirs
- $(CP) ds390/*.lib ds390/*.rel ds390/*.asm $(sdcc_datadir)/lib/ds390
+install: all installdirs
+ cp -r $(BUILDDIR)/* $(sdcc_datadir)/lib
+ cp -r ds390 gbz80 z80 *.c $(sdcc_datadir)/lib/src
+ rm `find $(sdcc_datadir)/lib/src -name '*.rel' -or -name '*.dump*' -or -name '*.sym' -or -name '*.o' -or -name '*.lst' -or -name '*.asm'`
# Deleting all the installed files
# --------------------------------
mkdir -p $(sdcc_datadir)/lib/$$model; \
done
[ -d $(sdcc_datadir)/lib/ds390 ] || mkdir -p $(sdcc_datadir)/lib/ds390
+ mkdir -p $(sdcc_datadir)/lib/src
# Creating dependencies
# ---------------------
# My rules
# --------
-.SUFFIXES: .rel
+.SUFFIXES: .rel .o
-.c.rel:
+$(PORTDIR)/%$(OEXT): %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $<
-
+ mv -f `basename $@` $@
+ mv -f `basename $@ $(OEXT)`.asm $(PORTDIR)
# Remaking configuration
# ----------------------
rm -f *core *[%~] *.[oa] *.rel *.lst *.sym *.asm *.ihx *.dump* *.cdb
rm -f .[a-z]*~
rm -f *.dump*
+ rm -r build
for model in $(MODELS); do \
rm -rf $$model; \
done
- cd ds390; make clean
-
+ make -C ds390 clean
+ make -C z80 clean
+ make -C gbz80 clean
# Deleting all files created by configuring or building the program
# -----------------------------------------------------------------
done
include Makefile.dep
-
-
TOPDIR = ../../..
-SCC = $(TOPDIR)/bin/sdcc -mgbz80 -v
-SAS = as-gb
+SCC = $(TOPDIR)/bin/sdcc -mgbz80
+SAS = as-gbz80
OBJ = putchar.o string.o printf.o div.o mul.o asm_strings.o
-LIB = z80.lib
+LIB = gbz80.lib
CC = $(SCC)
AS = $(SAS)
-CFLAGS = -I../include -I. --dumpall
+CFLAGS = -I../include -I.
all: $(LIB) crt0.o
rm -f $(LIB)
for i in $(OBJ); do echo $$i >> $(LIB); done
+.c.o:
+ $(CC) $(CFLAGS) -c $@
+
_dummy:
clean:
- rm -f $(OBJ) *~ $(CLEANSPEC)
-
-
+ rm -f $(OBJ) *~ $(CLEANSPEC) *.dump*
#include <stdarg.h>
#include <stdio.h>
-int printf (const char *format, ...) reentrant
+int printf (const char *format, ...) _REENTRANT
{
va_list arg;
int done;
return done;
}
-int sprintf (const char *buf, const char *format, ...) reentrant
+int sprintf (const char *buf, const char *format, ...) _REENTRANT
{
va_list arg;
int done;
return t;
}
-static code char monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};
+static _CODE char monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};
-static code char *month[]={"Jan","Feb","Mar","Apr","May","Jun",
+static _CODE char *month[]={"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
-static code char *day[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+static _CODE char *day[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static char ascTimeBuffer[32];
TOPDIR = ../../..
-SCC = $(TOPDIR)/bin/sdcc -mz80 -v
+SCC = $(TOPDIR)/bin/sdcc -mz80
SAS = as-z80
OBJ = div.o mul.o putchar.o string.o printf.o # asm_strings.o
LIB = z80.lib
CC = $(SCC)
AS = $(SAS)
-CFLAGS = -I../include -I. --dumpall
+CFLAGS = -I../include -I.
all: $(LIB) crt0.o
rm -f $(LIB)
for i in $(OBJ); do echo $$i >> $(LIB); done
+.c.o:
+ $(CC) $(CFLAGS) -c $@
+
_dummy:
clean:
- rm -f $(OBJ) *~ $(CLEANSPEC)
+ rm -f $(OBJ) *~ $(CLEANSPEC) *.dump*
;; Generic crt0.s for a Z80
- .globl __main
+ .globl _main
.area _HEADER (ABS)
;; Reset vector
.org 0x38
reti
- .org 0x150
+ .org 0x100
init:
;; Stack at the top of memory.
ld sp,#0xffff
- ;; Use _main instead of main to bypass sdcc's intelligence
- ei
- call __main
+ ;; Initialise global variables
+ call gsinit
+ call _main
jp _exit
;; Ordering of segments for the linker.
.area _CODE
+ .area _GSINIT
+ .area _GSFINAL
+
.area _DATA
+ .area _BSS
+ .area _CODE
__clock::
ld a,#2
out (0xff),a
ld a,#3
out (0xff),a
ret
-
+
_exit::
;; Exit - special code to the emulator
- ld a,#1
- out (0xff),a
+ ld a,#0
+ rst 0x08
1$:
halt
jr 1$
+
+ .area _GSINIT
+gsinit::
+
+ .area _GSFINAL
+ ret
;; Originally from GBDK by Pascal Felber.
.area _CODE
-__divschar::
- push de
- push bc
- push ix
- ld ix,#0
- add ix,sp
-
- ld c,8(ix)
- ld e,9(ix)
- call .div8
+__divschar::
+ push bc
+ ld c,l
+
+ call .div8
ld l,c
-
- pop ix
+ ld h,b
+
pop bc
- pop de
ret
__modschar::
- push de
- push bc
- push ix
- ld ix,#0
- add ix,sp
+ push bc
+ ld c,l
- ld c,8(ix)
- ld e,9(ix)
- call .div8
+ call .div8
ld l,e
-
- pop ix
+ ld h,d
+
pop bc
- pop de
ret
__divsint::
- push de
push bc
- push ix
- ld ix,#0
- add ix,sp
+ ld b,h
+ ld c,l
- ld c,8(ix)
- ld b,9(ix)
- ld e,10(ix)
- ld d,11(ix)
call .div16
ld l,c
ld h,b
- pop ix
pop bc
- pop de
ret
__modsint::
- push de
push bc
- push ix
- ld ix,#0
- add ix,sp
+ ld b,h
+ ld c,l
- ld c,8(ix)
- ld b,9(ix)
- ld e,10(ix)
- ld d,11(ix)
call .div16
ld l,e
ld h,d
- pop ix
pop bc
- pop de
ret
;; Unsigned
call .divu8
ld l,c
-
+ ld h,b
+
pop ix
pop bc
pop de
call .divu8
ld l,e
-
+ ld h,d
+
pop ix
pop bc
pop de
ret
__divuint::
- push de
push bc
- push ix
- ld ix,#0
- add ix,sp
-
- ld c,8(ix)
- ld b,9(ix)
- ld e,10(ix)
- ld d,11(ix)
+ ld b,h
+ ld c,l
call .divu16
ld l,c
ld h,b
- pop ix
pop bc
- pop de
ret
__moduint::
- push de
push bc
- push ix
- ld ix,#0
- add ix,sp
+ ld b,h
+ ld c,l
- ld c,8(ix)
- ld b,9(ix)
- ld e,10(ix)
- ld d,11(ix)
call .divu16
ld l,e
ld h,d
- pop ix
pop bc
- pop de
ret
.div8::
LD (.squot),A ; Save sign of quotient
;; Take absolute value of divisor
BIT 7,D
- JR Z,.chkde ; Jump if divisor is positive
+ jp Z,.chkde ; Jump if divisor is positive
SUB A ; Substract divisor from 0
SUB E
LD E,A
;; Take absolute value of dividend
.chkde:
BIT 7,B
- JR Z,.dodiv ; Jump if dividend is positive
+ jp Z,.dodiv ; Jump if dividend is positive
SUB A ; Substract dividend from 0
SUB C
LD C,A
;; Negate quotient if it is negative
LD A,(.squot)
AND #0x80
- JR Z,.dorem ; Jump if quotient is positive
+ jp Z,.dorem ; Jump if quotient is positive
SUB A ; Substract quotient from 0
SUB C
LD C,A
;; Check for division by zero
LD A,E
OR D
- JR NZ,.divide ; Branch if divisor is non-zero
+ jp NZ,.divide ; Branch if divisor is non-zero
LD BC,#0x00 ; Divide by zero error
LD D,B
LD E,C
SCF ; Set carry, invalid result
RET
.divide:
- LD L,C ; L = low byte of dividend/quotient
- LD H,B ; H = high byte of dividend/quotient
- LD BC,#0x00 ; BC = remainder
+ ld hl,#0
+; LD L,C ; L = low byte of dividend/quotient
+; LD H,B ; H = high byte of dividend/quotient
+; LD BC,#0x00 ; BC = remainder
OR A ; Clear carry to start
+ ex af,af
LD A,#16 ; 16 bits in dividend
.dvloop:
;; Shift next bit of quotient into bit 0 of dividend
;; HL holds remainder
;; Do a 32-bit left shift, shifting carry to L, L to H,
;; H to C, C to B
- LD (.dcnt),A
- RL L ; Carry (next bit of quotient) to bit 0
- RL H ; Shift remaining bytes
- RL C
+ ex af,af'
+ RL C ; Carry (next bit of quotient) to bit 0
RL B ; Clears carry since BC was 0
+ adc hl,hl
+
;; If remainder is >= divisor, next bit of quotient is 1. This
;; bit goes to carry
- PUSH BC ; Save current remainder
- LD A,C ; Substract divisor from remainder
- SBC E
- LD C,A
- LD A,B
- SBC D
- LD B,A
+ PUSH HL ; Save current remainder
+ sbc hl,de
+; LD A,C ; Substract divisor from remainder
+; SBC E
+; LD C,A
+; LD A,B
+; SBC D
+; LD B,A
CCF ; Complement borrow so 1 indicates a
; successful substraction (this is the
; next bit of quotient)
- JR C,.drop ; Jump if remainder is >= dividend
- POP BC ; Otherwise, restore remainder
- JR .nodrop
+ jp C,.drop ; Jump if remainder is >= dividend
+ POP HL ; Otherwise, restore remainder
+ jp .nodrop
.drop:
INC SP
INC SP
.nodrop:
- LD A,(.dcnt)
+ ex af,af'
DEC A ; DEC does not affect carry flag
- JR NZ,.dvloop
+ jp NZ,.dvloop
+ ex af,af'
;; Shift last carry bit into quotient
- LD D,B ; DE = remainder
- LD E,C
- RL L ; Carry to L
- LD C,L ; C = low byte of quotient
- RL H
- LD B,H ; B = high byte of quotient
+ LD D,H ; DE = remainder
+ LD E,L
+ RL C ; Carry to L
+; LD C,L ; C = low byte of quotient
+ RL B
+; LD B,H ; B = high byte of quotient
OR A ; Clear carry, valid result
RET
;; Originally from GBDK by Pascal Felber.
.area _CODE
-__mulschar::
-__muluchar::
- push de
- push bc
- push ix
- ld ix,#0
- add ix,sp
-
- ld c,8(ix)
- ld e,9(ix)
- call .mulu8
- pop ix
- pop bc
- pop de
- ret
+__mulschar::
+ ;; Need to sign extend before going in.
+ push bc
+ ld c,l
+
+ ld a,l
+ rla
+ sbc a,a
+ ld b,a
+
+ ld a,e
+ rla
+ sbc a,a
+ ld d,a
+
+ jp .mul16
+__muluchar::
__mulsint::
__muluint::
- push de
+ ;; Parameters:
+ ;; HL, DE (left, right irrelivent)
+ ;; Must preserve BC
push bc
- push ix
- ld ix,#0
- add ix,sp
-
- ld c,8(ix)
- ld b,9(ix)
- ld e,10(ix)
- ld d,11(ix)
- call .mulu16
-
- pop ix
- pop bc
- pop de
- ret
-
-.mul8:
-.mulu8:
- LD B,#0x00 ; Sign extend is not necessary with mul
- LD D,B
- ; Fall through
+ ld b,h
+ ld c,l
;; 16-bit multiplication
;;
.mlp:
SLA E ; Shift multiplier left 1 bit
RL D
- JR NC,.mlp1 ; Jump if MSB of multiplier = 0
+ jp NC,.mlp1 ; Jump if MSB of multiplier = 0
ADD HL,BC ; Add multiplicand to partial product
.mlp1:
ADD HL,HL ; Shift partial product left
DEC A
- JR NZ,.mlp ; Continue until count = 0
+ jp NZ,.mlp ; Continue until count = 0
;; Add multiplicand one last time if MSB of multiplier is 1
BIT 7,D ; Get MSB of multiplier
JR Z,.mend ; Exit if MSB of multiplier is 0
ADD HL,BC ; Add multiplicand to product
.mend:
- RET ; HL = result
+ ; HL = result
+ pop bc
+ ret
.area _CODE
_putchar::
- push ix
- ld ix,#0
- add ix,sp
+ ld a,#1
+ rst 0x08
- ld l,4(ix)
- ld a,#0
- out (0xff),a
-
- pop ix
- ret
-
+ ret