| 016 28.08.2021, 14:47 Uhr
 Bert
 
 
 
 
 | @Volker, das ist alles gerade erst im Entstehen. Aber hier mal das, was ich bisher habe:
 
 Das Makefile
 
 
 | Quellcode: |  | # Makefile
 PREFIX=WINEARCH=win32 WINEPREFIX=~/.wine32 wine ~/.wine32/drive_c/Z8/bin/
 
 CC=$(PREFIX)z8cc.exe
 LINK=$(PREFIX)z8link.exe
 ASM=$(PREFIX)z8asm.exe
 
 all: main.ihx
 
 main.obj: main.c
 $(CC) -model=S "main.c"
 
 main.ihx: main.obj startup.obj
 $(LINK) -color @main.lnk
 
 startup.obj: startup.asm
 $(ASM) startup.asm
 
 | 
 
 
 Der Startup-Code ist wahrscheinlich noch unvollständig, da ich nicht die initialisierten Variablen umkopiere. Außer dem Vorspann passiert da nix:
 
 
 | Quellcode: |  | ; startup.asm
 XDEF  _c_startup
 XREF  _main:ROM
 
 segment CODE
 _c_startup:
 
 ; Tiny-Basic-Token
 ; to help start the program with '+' (RUN)
 DB $80, 1, 'C%E010', $0d
 DB $80, 2, 'E', $0d
 BLKB 3, 0
 
 CALL  _main
 RET
 
 END _c_startup
 
 | 
 
 
 Das Linkerskript ist auf die Adressen vom tiny2k eingestellt:
 
 
 | Quellcode: |  | -format = INTEL
 
 "main" = "startup","C:\Z8\rtl\crtls.lib","C:\Z8\rtl\fpdumys.obj","main.obj"
 ORDER FAR_DATA,TEXT
 CHANGE TEXT = FAR_DATA
 RANGE ROM $e000 : $e3ff
 RANGE XDATA $fd80 : $fdff
 RANGE RDATA $20 : $4f
 COPY NEAR_DATA ROM
 COPY FAR_DATA ROM
 define _low_near_romdata = copy base of NEAR_DATA
 define _low_neardata = base of NEAR_DATA
 define _len_neardata = length of NEAR_DATA
 define _low_far_romdata = copy base of FAR_DATA
 define _low_fardata = base of FAR_DATA
 define _len_fardata = length of FAR_DATA
 define _low_nearbss = base of NEAR_BSS
 define _len_nearbss = length of NEAR_BSS
 define _low_farbss = base of FAR_BSS
 define _len_farbss = length of FAR_BSS
 define _far_heaptop = top of XDATA
 define _far_stack = highaddr of XDATA
 define _near_stack = highaddr of RDATA
 define _far_heapbot = base of XDATA + length of FAR_BSS + length of FAR_DATA
 
 | 
 
 
 Und dann noch ein kleines Hello-World:
 
 
 | Quellcode: |  | #include <z8.h>
 #include <stdio.h>
 
 /*
 * near -> rdata = register file
 * far  -> edata = external memory
 */
 
 // no inttype.h, no stdint.h
 typedef   signed char  int8_t;
 typedef unsigned char  uint8_t;
 typedef   signed short int16_t;
 typedef unsigned short uint16_t;
 
 #define TINY_CHR (*(unsigned char near volatile *)0x5a)
 #define TINY_POS (*(unsigned char near volatile *)0x5b)
 
 void clear_screen( void)
 {
 asm( "call %08dd"); // cls, geht
 }
 
 void cursor_home( void)
 {
 TINY_POS = 0;
 }
 
 void putc( char c)
 {
 TINY_CHR = c;
 asm( "call %0827"); // cbs
 }
 
 int puts( char near *s)
 {
 while( *s)
 {
 putc( *s);
 s++;
 }
 }
 
 char key( void)
 {
 asm( "call %0c1b"); // tsk
 return TINY_CHR;
 }
 
 char digit2hex( uint8_t digit)
 {
 char result;
 
 result = digit < 10 ? '0' : 'A' - 10;
 result += digit;
 return result;
 }
 
 void main( void)
 {
 far uint8_t * bws = (far uint8_t *) 0xFE00;
 uint8_t dat;
 
 char str[] = "HALLO JU+TE";
 
 clear_screen();
 puts( str);
 
 dat = key();
 putc( digit2hex(dat >> 4));
 putc( digit2hex(dat & 0xF));
 dat = key();
 }
 
 | 
 
 
 Die fertige ihx-Datei läßt sich direkt im neuesten JTCEMU laden und mit '+' starten.
 Bis zum printf bin ich noch nicht gekommen, ich weiß auch noch nicht, ob ich es verwenden will. Je nach Implementierung braucht printf zwischen 2 bis 8 kByte. Das ist auf einem aktuellen STM32 mit 128k Flash natürlich kein Problem. Hier ggf. schon.
 
 @Steffen: Vielen Dank für den Z8CC und die Beispielcodes für das UB88xx-Testboard.
 Da habe ich mir auch Inspirationen geholt.
 
 Viele Grüße,
 Bert
 
 @P.S.: Das wäre eigentlich auch gleich eine gute Übung für github...
 --
 Viele Grüße,
 Bert
 |