Update CPC port to SDCC 4.2.0
This version of SDCC introduces a new calling convention where some
values can be passed in registers. Adjust the assembler code
accordingly, making it smaller and faster.
Some things are not working quirte right yet:
- The routine to clear a rectangle isn't working correctly
- The keyboard input also does not seem to work completely
diff --git a/README.md b/README.md
index 1c3df44..82fa6db 100644
--- a/README.md
+++ b/README.md
@@ -42,13 +42,25 @@
Bitbox port
-----------
-This port also contains a port for the Bitbox console.
+This repository also contains a port for the Bitbox console.
Not much to say, it uses one of the bitbox textmodes, and was surprisingly
easy to get up and running.
-How to use it
-=============
+VTech V.Smile port
+------------------
+
+This repository also includes a port to the VTech V.Smile. I'm not sure how useful this will be,
+as the console doesn't exactly have a lot of IO. Can we use the second controller port as a
+generic UART and get serial line IP working over it? Well, maybe...
+
+Currently, the UART driver does not even work well enough to get the controller to work on real
+hardware, so that should be fixed first.
+
+This port is currently built with uNSP IDE, but it would be nice to use the VBCC compiler instead.
+
+How to use it (Amstrad CPC)
+===========================
A ready-to-use DSK image is available in the "release" section (look at the tabs
at the top of this page!)
@@ -70,8 +82,8 @@
multiple instances of each application, and navigate between their windows using
the "Desktop" menu.
-How to build it
-===============
+How to build it (Amstrad CPC version)
+=====================================
Requirements
------------
@@ -82,9 +94,8 @@
the CPC would be much less interesting, because it is nearly impossible to write
position independant z80 code.
-A patch for SDCC 3.6.0 (from the current SVN sources) is provided. Get the
-sources using SVN or a nightly snapshot and apply the patch, then configure
-SDCC as usual.
+A patch for SDCC 4.2.0 is provided. Get the sources from the SDCC website and apply
+the patch, then configure SDCC as usual.
You can still use the generated version of SDCC for other projects. The only
difference is the addition of the -h flag to the linker. When this flag is set,
@@ -110,8 +121,8 @@
memory and all programs must be recompiled. This means you should always do
a "make clean", until the dependencies are properly defined in the makefiles.
-Roadmap
-=======
+Roadmap (Amstrad CPC)
+=====================
This port of Contiki is running fairly well, but we can make it more awesome!
diff --git a/contiki-cpc/Makefile.common b/contiki-cpc/Makefile.common
index 57bc7fe..b22e4ea 100644
--- a/contiki-cpc/Makefile.common
+++ b/contiki-cpc/Makefile.common
@@ -18,7 +18,7 @@
-I $(CONTIKI)/ppp \
-I $(CONTIKI)/uip \
-mz80 -D__CPC__ -DCLK_TCK=16384 \
- -DCTK_CONIO --max-allocs-per-node 20000 \
+ -DCTK_CONIO --max-allocs-per-node 50000 \
--no-std-crt0 --opt-code-size --allow-unsafe-read
CLFLAGS=
diff --git a/contiki-cpc/Makefile.programs b/contiki-cpc/Makefile.programs
index 0e2b104..133d8e8 100644
--- a/contiki-cpc/Makefile.programs
+++ b/contiki-cpc/Makefile.programs
@@ -100,7 +100,7 @@
define MAKE_PRG
echo -ihmwn $(@:.prg=.ihx) > $@.lnk
- echo -k /usr/local/share/sdcc/lib/z80 >> $@.lnk
+ echo -k /system/data/sdcc/lib/z80 >> $@.lnk
echo -l z80 >> $@.lnk
echo arch/crt0-prg.o >> $@.lnk
echo loader/loader-arch-module.o >> $@.lnk
diff --git a/contiki-cpc/arch/conio.s b/contiki-cpc/arch/conio.s
index 236a5cb..21c87df 100644
--- a/contiki-cpc/arch/conio.s
+++ b/contiki-cpc/arch/conio.s
@@ -49,7 +49,6 @@
.globl _gotox
_gotox::
- ld a,l
inc a
jp 0xBB6F ; TXT SET COLUMN
@@ -59,20 +58,16 @@
.globl _gotoy
_gotoy::
- ld a,l
inc a
jp 0xBB72 ; TXT SET ROW
-; void gotoyx (unsigned char y, unsigned char x)
+; void gotoxy (unsigned char x, unsigned char y)
; Set the cursor to the specified position
-.globl _gotoyx
+.globl _gotoxy
-_gotoyx::
- pop de
- pop hl
- push de
-
+_gotoxy::
+ ld h,a
inc h
inc l
jp 0xBB75 ; TXT SET CURSOR
@@ -84,8 +79,8 @@
_wherex::
call 0xBB78 ; TXT GET CURSOR
- ld l,h
- dec l
+ ld a,h
+ dec a
ret
; unsigned char wherey (void);
@@ -95,45 +90,37 @@
_wherey::
call 0xBB78 ; TXT GET CURSOR
- dec l
- ret
-
-
-; void cputc (char c);
-; Output one character at the current cursor position
-
-.globl _cputc
-
-_cputc::
ld a,l
- jp 0xbb5d ; TXT OUTPUT
+ dec a
+ ret
; void cputcxy (unsigned char x, unsigned char y, char c)
; Same as "gotoxy (x, y); cputc (c);"
-.globl _cputcyx
+; INPUT: A = x, L = y, char on stack
-_cputcyx::
- pop de ; RV
- pop hl ; XY
+.globl _cputcxy
+_cputcxy::
+ LD H,A ; HL = cursor position
inc h
inc l
call 0xBB75 ; TXT SET CURSOR
+ pop de ; Return value
dec sp
- pop af ; C
- push de
+ pop af ; character to print
+ push de ; Put return value back on stack
jp 0xbb5d
; void cputsn(const char *str, unsigned char len);
+; INPUT: str is in HL, len is on the stack
.globl _cputsn
_cputsn::
pop de ; RV
- pop hl ; str
dec sp
pop bc ; len
push de
@@ -168,34 +155,24 @@
pop hl
jr cputs$
-; void textcolor (unsigned char color);
-; Set the color for text output.
-.globl _textcolor
-
-_textcolor::
- ld a,l
- jp 0xBB90 ; TXT SET PEN
-
-
-; void bgcolor (unsigned char color);
-; Set the color for the background. */
-.globl _bgcolor
-
-_bgcolor::
- ld a,l
- jp 0xBB96 ; TXT SET PAPER
-
-; void bordercolor (unsigned char color);
-; Set the color for the border.
-
.globl _bordercolor
_bordercolor::
- ld b,l
- ld c,l
+ ld b,a
+ ld c,a
jp 0xBC38 ; SCR SET BORDER
+; void cclear (unsigned char length);
+; Clear part of a line (write length spaces).
+
+.globl _cclear
+
+_cclear::
+ ld b,a
+ ld c,#0x020 ; White space
+ jr chlineloop$
+
; void chline (unsigned char length);
; Output a horizontal line with the given length starting at the current
; cursor position.
@@ -203,7 +180,7 @@
.globl _chline
_chline::
- ld b,l
+ ld b,a
dochline$:
ld c,#0x09a
chlineloop$:
@@ -214,20 +191,19 @@
djnz chlineloop$
ret
-; void chlineyx (unsigned char y, unsigned char x, unsigned char length);
-; Same as "gotoxy (y, x); chline (length);"
+; void chlinexy (unsigned char x, unsigned char y, unsigned char length);
+; Same as "gotoxy (x, y); chline (length);"
; TESTED
-.globl _chlineyx
+.globl _chlinexy
-_chlineyx::
-
+_chlinexy::
POP DE ; RV
- POP HL ; XY
- DEC SP
- POP BC ; L
- PUSH DE
+ dec sp
+ POP BC ; Length in B, C is unimportant
+ PUSH DE ; Put return value back on stack
+ LD H, A ; HL = XY
inc h
inc l
call 0xBB75
@@ -240,7 +216,7 @@
.globl _cvline
_cvline::
- ld b,l
+ ld b,a
call 0xBB78 ; TXT GET CURSOR
docvline$:
cvloop$:
@@ -255,56 +231,37 @@
djnz cvloop$
ret
-; void cvlineyx (unsigned char y, unsigned char x, unsigned char length);
-; Same as "gotoyx (y, x); cvline (length);"
+; void cvlinexy (unsigned char x, unsigned char y, unsigned char length);
+; Same as "gotoxy (x, y); cvline (length);"
-.globl _cvlineyx
+; INPUT: A = Y, L = X, length on stack
-_cvlineyx::
+.globl _cvlinexy
+
+_cvlinexy::
POP DE ; RV
- POP HL ; XY
- DEC SP
- POP BC ; L.
- PUSH DE
+ dec sp
+
+ LD H, A ; HL = XY
+
+ POP BC ; Length
+ PUSH DE ; Put return value back on stack
inc h
inc l
jr docvline$
-; void cclear (unsigned char length);
-; Clear part of a line (write length spaces).
-
-.globl _cclear
-
-_cclear::
- ld b,l
- ld c,#0x020 ; White space
-cclearloop$:
- push bc
- ld a,c
- call 0xbb5d
- pop bc
- djnz cclearloop$
- ret
-
; void screensize (unsigned char* x, unsigned char* y);
; Return the current screen size.
+; INPUT: HL = X ptr, DE = Y ptr
.globl _screensize
_screensize::
- pop hl ; RV
- pop de ; ptr1
-
ld a,#40 ; X Size
- ld (de),a
+ ld (hl),a
- pop de ; ptr2
ld a,#25 ; Y Size
ld (de),a
- push de
- push de
-
- jp (hl)
-
+ ret
diff --git a/contiki-cpc/arch/contiki.lnk b/contiki-cpc/arch/contiki.lnk
index ebf8a1e..49240a3 100644
--- a/contiki-cpc/arch/contiki.lnk
+++ b/contiki-cpc/arch/contiki.lnk
@@ -1,5 +1,5 @@
-imwn contiki
--k /usr/local/share/sdcc/lib/z80
+-k /system/data/sdcc/lib/z80
-b _CODE=0x0100
-l z80
./arch/crt0.o
diff --git a/contiki-cpc/arch/key.s b/contiki-cpc/arch/key.s
index 8ca55ad..592f77c 100644
--- a/contiki-cpc/arch/key.s
+++ b/contiki-cpc/arch/key.s
@@ -7,9 +7,9 @@
_kbhit::
call 0xBB09 ; KM READ KEY
ld (key),a
- ld l,#1
+ ld a,#1
ret c
- ld l,#0
+ ld a,#0
ret
; char cgetc (void);
@@ -22,7 +22,6 @@
_cgetc::
ld a,(key)
- ld l,a
ret
;; call 0xBB09
diff --git a/contiki-cpc/ctk/conio.h b/contiki-cpc/ctk/conio.h
index 49163f0..274dac6 100644
--- a/contiki-cpc/ctk/conio.h
+++ b/contiki-cpc/ctk/conio.h
@@ -22,48 +22,41 @@
unsigned char kbhit (void);
-void gotox (unsigned char x) __z88dk_fastcall;
+void gotox (unsigned char x) __preserves_regs(b, c, d, e);
-void gotoy (unsigned char y) __z88dk_fastcall;
+void gotoy (unsigned char y) __preserves_regs(b, c, d, e);
-void gotoyx (unsigned char y, unsigned char x) __z88dk_callee;
-#define gotoxy(x,y) gotoyx(y,x)
+void gotoxy (unsigned char x, unsigned char y) __preserves_regs(b, c, d, e);
unsigned char wherex (void);
unsigned char wherey (void);
-void cputc (char c) __z88dk_fastcall;
+#define cputc ((void (*)(unsigned char))0xBB5D)
-void cputcyx (unsigned char y, unsigned char x, char c) __z88dk_callee;
-#define cputcxy(x,y,c) cputcyx(y,x,c)
+void cputcxy (unsigned char x, unsigned char y, char c) __z88dk_callee;
-void cputs (const char* s) __z88dk_fastcall;
+void cputs (const char* s);
void cputsn(const char *str, unsigned char len) __z88dk_callee;
char cgetc (void);
-void revers (char) __z88dk_fastcall;
+#define textcolor ((void(*)(unsigned char))0xBB90)
+#define bgcolor ((void(*)(unsigned char))0xBB96)
-void textcolor (unsigned char color) __z88dk_fastcall;
+void bordercolor (unsigned char color);
-void bgcolor (unsigned char color) __z88dk_fastcall;
+void chline (unsigned char length);
-void bordercolor (unsigned char color) __z88dk_fastcall;
+void chlinexy (unsigned char x, unsigned char y, unsigned char length) __z88dk_callee;
-void chline (unsigned char length) __z88dk_fastcall;
+void cvline (unsigned char length);
-void chlineyx (unsigned char y, unsigned char x, unsigned char length) __z88dk_callee;
-#define chlinexy(x,y,l) chlineyx(y,x,l)
+void cvlinexy (unsigned char x, unsigned char y, unsigned char length) __z88dk_callee;
-void cvline (unsigned char length) __z88dk_fastcall;
+void cclear (unsigned char length);
-void cvlineyx (unsigned char y, unsigned char x, unsigned char length) __z88dk_callee;
-#define cvlinexy(x,y,l) cvlineyx(y,x,l)
-
-void cclear (unsigned char length) __z88dk_fastcall;
-
-void screensize (unsigned char* x, unsigned char* y);
+void screensize (unsigned char* x, unsigned char* y) __preserves_regs(b,c);
#endif /* __conio_h__ */
diff --git a/contiki-cpc/ctk/ctk-conio-service.c b/contiki-cpc/ctk/ctk-conio-service.c
index f90c5b8..3985711 100644
--- a/contiki-cpc/ctk/ctk-conio-service.c
+++ b/contiki-cpc/ctk/ctk-conio-service.c
@@ -68,12 +68,9 @@
/*-----------------------------------------------------------------------------------*/
-static void customchr(const unsigned char* data) __naked __z88dk_callee
+static void customchr(const unsigned char* data) __naked __preserves_regs(c, d, e)
{
__asm
- pop de
- pop hl
- push de
; Cant use SCR SET MATRIX because some of our icons are in RAM under 0x4000.
; SCR SET MATRIX then gets data from the firmware ROM...
ld a,#0x19
@@ -216,6 +213,7 @@
const unsigned char* ptr = w->widget.icon.bitmap;
for(i = 0; i < 3; ++i) {
gotoxy(xpos, ypos);
+ //gotox(xpos); gotoy(ypos);
if(ypos >= clipy1 && ypos < clipy2) {
customchr(ptr);
cputc(0xff);
@@ -293,19 +291,37 @@
/*-----------------------------------------------------------------------------------*/
static void clearrect(unsigned char y2, unsigned char x2,
- unsigned char y1, unsigned char x1) __naked
+ unsigned char y1, unsigned char x1) __naked __z88dk_callee
{
+ // Y2 is in A
+ // X2 is in L
+ // Stack has:
+ // - Return value
+ // - Y1
+ // - X1
__asm
pop bc ; RV
- pop de ; x2 y2
pop hl ; x1 y1
- push hl
- push de
push bc
+ LD d,l
+ LD e,A
+
call 0xBB99 ; TXT GET PAPER
+
+ ; A contains PAPER number
+
call 0xBC2C ; SCR INK ENCODE
+ ; A contains encoded PEN
+
+ ; Here we need:
+ ; H = X1
+ ; L = Y1
+ ; D = X2
+ ; E = Y2
+ ; A = encoded pen
+
jp 0xBC44 ; SCR FILL BOX
__endasm;
}
diff --git a/contiki-cpc/loader/dir.s b/contiki-cpc/loader/dir.s
index e1f5ee9..e2b97fa 100644
--- a/contiki-cpc/loader/dir.s
+++ b/contiki-cpc/loader/dir.s
@@ -26,6 +26,8 @@
;; find BIOS SET MESSAGE command
;; this is used to disable disc messages.
;; this is compatible with other DOSs that also provide this command
+;; void _readdir(void*)
+;; Input: pointer to buffer in HL
__readdir::
;ld hl,#cmd_bios_set_message
@@ -43,11 +45,7 @@
;;------------------------------------------------------------------
;; do CAT
-ld hl,#2
-add hl,sp
-ld e,(hl)
-inc hl
-ld d,(hl)
+EX DE,HL ;; Put pointer to buffer in DE instead
;;------------------------------------------------------------------
;; display files from data generated by CAS CATALOG function
diff --git a/contiki-cpc/loader/rel.s b/contiki-cpc/loader/rel.s
index 25234a4..ce4bac6 100644
--- a/contiki-cpc/loader/rel.s
+++ b/contiki-cpc/loader/rel.s
@@ -5,15 +5,11 @@
;; get length of file on disc. Assumption file has a AMSDOS header
;;
;; int get_file_length(const char *filename);
-
+;; Input: HL points to filename
+;; Output: DE contains file length
_get_file_length::
- ld hl,#2
- add hl,sp
- ld a,(hl)
- inc hl
- ld h,(hl)
- ld l,a
+ ;; IX is modified by CAS routines
push ix
;; HL = address of null terminated string
@@ -22,7 +18,7 @@
call 0x0bc77 ;; cas in open
push bc ;; BC = length of file
call 0x0bc7d ;; cas in abandon
- pop hl
+ pop de ;; Now DE = length of file
pop ix
ret
@@ -44,27 +40,15 @@
;;---------------------------------------------------------------------------
;; void load_file(const char *filename, void *addr)
-
+;; INPUT: HL = filename, DE = addr
_load_file::
- ld hl,#5
- add hl,sp
- ld d,(hl)
- dec hl
- ld e,(hl)
- dec hl
-
- ld a,(hl)
- dec hl
- ld l,(hl)
- ld h,a
-
push ix
call count_string_length
- push de
+ push de ; Save load address
ld de,#0x0c000
call 0x0bc77 ;; cas in open
- pop hl ;; load address
+ pop hl ;; load address now in HL
call 0x0bc83 ;; cas in direct
call 0x0bc7a ;; cas in close
@@ -73,23 +57,20 @@
ret
;; void relocate(void *addr,void *base)
-
+;; INPUT: HL = addr, DE = base
;; IX = address of relocate data
_relocate::
- ld hl,#5
- add hl,sp
+
push ix
- ld b,(hl) ;; base address
- dec hl
- ld c,(hl)
- dec hl
- ld a,(hl)
- .db #0x0dd
- ld h,a
- dec hl
- ld a,(hl)
- .db #0x0dd
- ld l,a ;; IX is offset of table from start of loaded file
+
+ ; Transfer base address to BC
+ PUSH DE
+ POP BC
+
+ ; Transfer addr to IX
+ PUSH HL
+ POP IX
+
add ix,bc ;; relocate IX to give absolute address of table.
push bc
@@ -101,6 +82,7 @@
push bc
pop hl
call relocate_8bith ;; upper byte
+
pop ix
ret
diff --git a/sdcc-4.0.0.patchset b/sdcc-4.2.0.patchset
similarity index 92%
rename from sdcc-4.0.0.patchset
rename to sdcc-4.2.0.patchset
index 4c3f857..3244d06 100644
--- a/sdcc-4.0.0.patchset
+++ b/sdcc-4.2.0.patchset
@@ -1,8 +1,14 @@
-From 64c8f32ebb624c1b58a0ab5683eed7577d38a29d Mon Sep 17 00:00:00 2001
+From dd799e32d1e14eaebba8c6c6a91615f24695f8aa Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Fri, 22 Jan 2016 21:01:19 +0100
-Subject: Import Kevin Thacker patch for runtime relocation support.
+Subject: Kevin Thacker's patch for runtime relocation support.
+This patch is used to build the Contiki operating system for Z80
+machines.
+
+This version is modified for SDCC 4.2, the addresses are now internally
+stored on 24 bits instead of 16 bits (to help support banked code), and
+the code in the patch was adjusted for that.
diff --git a/sdas/linksrc/Makefile.in b/sdas/linksrc/Makefile.in
index 43e16f5..e37b167 100644
@@ -18,7 +24,7 @@
LKSOURCES = $(SRC) $(ASXXLIBSRC:%.c=$(ASXXLIB)/%.c)
diff --git a/sdas/linksrc/aslink.h b/sdas/linksrc/aslink.h
-index ebad061..7dce058 100644
+index 94c2b7b..f898a19 100644
--- a/sdas/linksrc/aslink.h
+++ b/sdas/linksrc/aslink.h
@@ -1033,6 +1033,8 @@ extern int yflag; /* -y, enable SDCC Debug output
@@ -31,7 +37,7 @@
*/
extern int uflag; /* Listing relocation flag
diff --git a/sdas/linksrc/lkdata.c b/sdas/linksrc/lkdata.c
-index e03cd6a..db7c8ff 100644
+index 169e8c1..8686631 100644
--- a/sdas/linksrc/lkdata.c
+++ b/sdas/linksrc/lkdata.c
@@ -66,6 +66,9 @@ int oflag; /* Output file type flag
@@ -45,10 +51,10 @@
int jflag; /* NoICE output flag
*/
diff --git a/sdas/linksrc/lkmain.c b/sdas/linksrc/lkmain.c
-index fcf7242..5535b95 100644
+index daf5515..d690d46 100644
--- a/sdas/linksrc/lkmain.c
+++ b/sdas/linksrc/lkmain.c
-@@ -233,6 +233,7 @@ main(int argc, char *argv[])
+@@ -212,6 +212,7 @@ main(int argc, char *argv[])
startp->f_idp = "";
pflag = 1;
@@ -56,7 +62,7 @@
for(i=1; i<argc; i++) {
ip = ib;
-@@ -999,6 +1000,11 @@ parse()
+@@ -979,6 +980,11 @@ parse()
}
return(0);
@@ -199,10 +205,10 @@
lkfclose();
diff --git a/sdas/linksrc/lkrrel.c b/sdas/linksrc/lkrrel.c
new file mode 100644
-index 0000000..e9e8383
+index 0000000..0d9f943
--- /dev/null
+++ b/sdas/linksrc/lkrrel.c
-@@ -0,0 +1,251 @@
+@@ -0,0 +1,256 @@
+/* (c) Kevin Thacker, May 2005 */
+#include <stdio.h>
+#include <string.h>
@@ -329,12 +335,15 @@
+{
+ rtval[0] = addr&0x0ff;
+ rtval[1] = (addr>>8)&0x0ff;
-+ rtval[2] = byte&0x0ff;
-+ addr+=1;
++ rtval[2] = (addr>>16)&0x0ff;
++
++ rtval[3] = byte&0x0ff;
++ addr+=1;
+ rtflg[0] = 1;
+ rtflg[1] = 1;
+ rtflg[2] = 1;
-+ rtcnt = 3;
++ rtflg[3] = 1;
++ rtcnt = 4;
+ ixx(1);
+ return addr;
+}
@@ -437,13 +446,15 @@
+ /* re-write offset to relocation records */
+ rtval[0] = 0;
+ rtval[1] = 0;
-+ rtval[2] = areasize&0x0ff;
-+ rtval[3] = (areasize>>8)&0x0ff;
++ rtval[2] = 0;
++ rtval[3] = areasize&0x0ff;
++ rtval[4] = (areasize>>8)&0x0ff;
+ rtflg[0] = 1;
+ rtflg[1] = 1;
+ rtflg[2] = 1;
+ rtflg[3] = 1;
-+ rtcnt = 4;
++ rtflg[4] = 1;
++ rtcnt = 5;
+ ixx(1);
+
+
@@ -478,6 +489,6 @@
+void freerelrec();
+void relrecwrite();
--
-2.28.0
+2.37.3