diff options
Diffstat (limited to '')
63 files changed, 2270 insertions, 1020 deletions
diff --git a/sw/z80/coding_rules.txt b/doc/coding_rules.txt index e5c11f0..e5c11f0 100644 --- a/sw/z80/coding_rules.txt +++ b/doc/coding_rules.txt diff --git a/sw/z80/TODO.txt b/sw/z80/TODO.txt new file mode 100644 index 0000000..67be671 --- /dev/null +++ b/sw/z80/TODO.txt @@ -0,0 +1 @@ +- fix kernel makefile (currently broken) diff --git a/sw/z80/arch/include/addresses.h b/sw/z80/arch/include/addresses.h new file mode 100644 index 0000000..32f1997 --- /dev/null +++ b/sw/z80/arch/include/addresses.h @@ -0,0 +1,15 @@ +#ifndef __ADDRESSES_H__ +#define __ADDRESSES_H__ + +#define ADDR_DEV_ROM_L 0x0000 +#define ADDR_DEV_ROM_H 0x2000 + +#define ADDR_DEV_PIO 0x0010 +#define ADDR_DEV_CTC 0x0020 +#define ADDR_DEV_USART 0x0030 + +#define ADDR_DEV_MMU + +#define ADDR_DEV_RAM 0x8000 + +#endif diff --git a/sw/z80/arch/include/sleep.h b/sw/z80/arch/include/sleep.h new file mode 100644 index 0000000..bd4214b --- /dev/null +++ b/sw/z80/arch/include/sleep.h @@ -0,0 +1,14 @@ +#ifndef __SLEEP_H__ +#define __SLEEP_H__ + +#ifndef F_CPU +#error undefined CPU clock speed +#endif + +#define SLEEP_UNIT ((F_CPU/4)/2) + +#include <stdint.h> + +void usleep(uint16_t microseconds); + +#endif // __SLEEP_H__
\ No newline at end of file diff --git a/sw/z80/arch/makefile b/sw/z80/arch/makefile new file mode 100644 index 0000000..2763c10 --- /dev/null +++ b/sw/z80/arch/makefile @@ -0,0 +1,27 @@ +# Drivers library + +LIB := build/arch.a +SOURCES := $(wildcard *.c) +OBJECTS := $(patsubst %.c,build/%.rel,$(SOURCES)) + +F_CPU := 10000 + +CC := sdcc +AR := sdar +CFLAGS := -mz80 \ + -Iinclude \ + -DDEBUG \ + -DF_CPU=$(F_CPU) + +.PHONY: dirs clean +$(LIB): $(OBJECTS) + $(AR) rcs $@ $(OBJECTS) + +$(OBJECTS): build/%.rel: %.c $(SOURCES) dirs + $(CC) $(CFLAGS) -c $< -o $@ + +dirs: + mkdir -p build + +clean: + - rm -rd build diff --git a/sw/z80/arch/sleep.c b/sw/z80/arch/sleep.c new file mode 100644 index 0000000..154e7ec --- /dev/null +++ b/sw/z80/arch/sleep.c @@ -0,0 +1,16 @@ +#include "sleep.h" + +void usleep(uint16_t microseconds) +{ + __asm + pop hl +loop: + ld bc, #SLEEP_UNIT +unit: + nop + dec bc + jr nz, unit + dec hl + jr nz,loop + __endasm; +}
\ No newline at end of file diff --git a/sw/z80/build/helvetiOS.lk b/sw/z80/build/helvetiOS.lk deleted file mode 100644 index c16247f..0000000 --- a/sw/z80/build/helvetiOS.lk +++ /dev/null @@ -1,11 +0,0 @@ --mjwx --i build/helvetiOS.hex --b _CODE = 0x0800 --b _DATA = 0x8000 --k /usr/bin/../share/sdcc/lib/z80 --k /usr/share/sdcc/lib/z80 --l z80 -crt0.rel -build/kernel/kernel.rel - --e diff --git a/sw/z80/build/helvetiOS.map b/sw/z80/build/helvetiOS.map deleted file mode 100644 index 98210c7..0000000 --- a/sw/z80/build/helvetiOS.map +++ /dev/null @@ -1,182 +0,0 @@ -ASxxxx Linker V03.00 + NoICE + sdld, page 1. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -. .ABS. 00000000 00000000 = 0. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ - 00000000 .__.ABS. kernel - 00000000 l__BSEG - 00000000 l__BSS - 00000000 l__CABS - 00000000 l__DABS - 00000000 l__DATA - 00000000 l__HEADER - 00000000 l__HEAP - 00000000 l__HOME - 00000000 l__INITIALIZED - 00000000 l__INITIALIZER - 00000000 s__CABS - 00000000 s__DABS - 00000000 s__HEADER - 00000000 s__HEADER0 - 00000000 s__HEADER1 - 00000000 s__HEADER2 - 00000000 s__HEADER3 - 00000000 s__HEADER4 - 00000000 s__HEADER5 - 00000000 s__HEADER6 - 00000000 s__HEADER7 - 00000000 s__HEADER8 - 00000001 l__GSFINAL - 00000002 l__HEADER1 - 00000002 l__HEADER2 - 00000002 l__HEADER3 - 00000002 l__HEADER4 - 00000002 l__HEADER5 - 00000002 l__HEADER6 - 00000002 l__HEADER7 - 00000003 l__HEADER0 - 00000006 l__GSINIT - 0000000C l__HEADER8 - 00000017 l__CODE - 00000800 s__CODE - 00000817 s__GSINIT - 00000817 s__HOME - 00000817 s__INITIALIZER - 0000081D s__GSFINAL - 00008000 s__BSEG - 00008000 s__BSS - 00008000 s__DATA - 00008000 s__HEAP - 00008000 s__INITIALIZED -ASxxxx Linker V03.00 + NoICE + sdld, page 2. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_CODE 00000800 00000017 = 23. bytes (REL,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ - 00000800 __clock crt0 - 00000804 _exit crt0 - 0000080A _main kernel -ASxxxx Linker V03.00 + NoICE + sdld, page 3. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER0 00000000 00000003 = 3. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 4. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER1 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 5. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER2 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 6. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER3 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 7. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER4 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 8. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER5 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 9. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER6 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 10. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER7 00000000 00000002 = 2. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 11. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_HEADER8 00000000 0000000C = 12. bytes (ABS,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 12. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_GSINIT 00000817 00000006 = 6. bytes (REL,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ - 00000817 gsinit crt0 - -ASxxxx Linker V03.00 + NoICE + sdld, page 13. -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------------------- ---- ---- ------- ----- ------------ -_GSFINAL 0000081D 00000001 = 1. bytes (REL,CON) - - Value Global Global Defined In Module - ----- -------------------------------- ------------------------ -ASxxxx Linker V03.00 + NoICE + sdld, page 14. - -Files Linked [ module(s) ] - -crt0.rel [ crt0 ] -build/kernel/kernel.rel [ kernel ] - -ASxxxx Linker V03.00 + NoICE + sdld, page 15. - -User Base Address Definitions - -_CODE = 0x0800 -_DATA = 0x8000 - -
\ No newline at end of file diff --git a/sw/z80/build/helvetiOS.noi b/sw/z80/build/helvetiOS.noi deleted file mode 100644 index 1b9c284..0000000 --- a/sw/z80/build/helvetiOS.noi +++ /dev/null @@ -1,50 +0,0 @@ -DEF .__.ABS. 0x0 -DEF l__BSEG 0x0 -DEF l__BSS 0x0 -DEF l__CABS 0x0 -DEF l__DABS 0x0 -DEF l__DATA 0x0 -DEF l__HEADER 0x0 -DEF l__HEAP 0x0 -DEF l__HOME 0x0 -DEF l__INITIALIZED 0x0 -DEF l__INITIALIZER 0x0 -DEF s__CABS 0x0 -DEF s__DABS 0x0 -DEF s__HEADER 0x0 -DEF s__HEADER0 0x0 -DEF s__HEADER1 0x0 -DEF s__HEADER2 0x0 -DEF s__HEADER3 0x0 -DEF s__HEADER4 0x0 -DEF s__HEADER5 0x0 -DEF s__HEADER6 0x0 -DEF s__HEADER7 0x0 -DEF s__HEADER8 0x0 -DEF l__GSFINAL 0x1 -DEF l__HEADER1 0x2 -DEF l__HEADER2 0x2 -DEF l__HEADER3 0x2 -DEF l__HEADER4 0x2 -DEF l__HEADER5 0x2 -DEF l__HEADER6 0x2 -DEF l__HEADER7 0x2 -DEF l__HEADER0 0x3 -DEF l__GSINIT 0x6 -DEF l__HEADER8 0xC -DEF l__CODE 0x17 -DEF s__CODE 0x800 -DEF s__GSINIT 0x817 -DEF s__HOME 0x817 -DEF s__INITIALIZER 0x817 -DEF s__GSFINAL 0x81D -DEF s__BSEG 0x8000 -DEF s__BSS 0x8000 -DEF s__DATA 0x8000 -DEF s__HEAP 0x8000 -DEF s__INITIALIZED 0x8000 -DEF __clock 0x800 -DEF _exit 0x804 -DEF _main 0x80A -DEF gsinit 0x817 -LOAD build/helvetiOS.ihx diff --git a/sw/z80/build/kernel/kernel.asm b/sw/z80/build/kernel/kernel.asm deleted file mode 100644 index a29db4d..0000000 --- a/sw/z80/build/kernel/kernel.asm +++ /dev/null @@ -1,65 +0,0 @@ -;-------------------------------------------------------- -; File Created by SDCC : free open source ANSI-C Compiler -; Version 3.5.0 #9253 (Mar 24 2016) (Linux) -; This file was generated Tue May 2 18:13:35 2017 -;-------------------------------------------------------- - .module kernel - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _main -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _INITIALIZED -;-------------------------------------------------------- -; absolute external ram data -;-------------------------------------------------------- - .area _DABS (ABS) -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CODE -;kernel/kernel.c:4: void main(void) -; --------------------------------- -; Function main -; --------------------------------- -_main:: -;kernel/kernel.c:7: for (i = 0; i < 10; i++) { - ld de,#0x000A -00104$: -;kernel/kernel.c:8: j--; - ld c,e - ld b,d - dec bc - ld e, c -;kernel/kernel.c:7: for (i = 0; i < 10; i++) { - ld a,b - ld d,a - or a,c - jr NZ,00104$ - ret - .area _CODE - .area _INITIALIZER - .area _CABS (ABS) diff --git a/sw/z80/build/kernel/kernel.lst b/sw/z80/build/kernel/kernel.lst deleted file mode 100644 index 8ec7438..0000000 --- a/sw/z80/build/kernel/kernel.lst +++ /dev/null @@ -1,65 +0,0 @@ - 1 ;-------------------------------------------------------- - 2 ; File Created by SDCC : free open source ANSI-C Compiler - 3 ; Version 3.5.0 #9253 (Mar 24 2016) (Linux) - 4 ; This file was generated Tue May 2 18:13:35 2017 - 5 ;-------------------------------------------------------- - 6 .module kernel - 7 .optsdcc -mz80 - 8 - 9 ;-------------------------------------------------------- - 10 ; Public variables in this module - 11 ;-------------------------------------------------------- - 12 .globl _main - 13 ;-------------------------------------------------------- - 14 ; special function registers - 15 ;-------------------------------------------------------- - 16 ;-------------------------------------------------------- - 17 ; ram data - 18 ;-------------------------------------------------------- - 19 .area _DATA - 20 ;-------------------------------------------------------- - 21 ; ram data - 22 ;-------------------------------------------------------- - 23 .area _INITIALIZED - 24 ;-------------------------------------------------------- - 25 ; absolute external ram data - 26 ;-------------------------------------------------------- - 27 .area _DABS (ABS) - 28 ;-------------------------------------------------------- - 29 ; global & static initialisations - 30 ;-------------------------------------------------------- - 31 .area _HOME - 32 .area _GSINIT - 33 .area _GSFINAL - 34 .area _GSINIT - 35 ;-------------------------------------------------------- - 36 ; Home - 37 ;-------------------------------------------------------- - 38 .area _HOME - 39 .area _HOME - 40 ;-------------------------------------------------------- - 41 ; code - 42 ;-------------------------------------------------------- - 43 .area _CODE - 44 ;kernel/kernel.c:4: void main(void) - 45 ; --------------------------------- - 46 ; Function main - 47 ; --------------------------------- - 0000 48 _main:: - 49 ;kernel/kernel.c:7: for (i = 0; i < 10; i++) { - 0000 11 0A 00 [10] 50 ld de,#0x000A - 0003 51 00104$: - 52 ;kernel/kernel.c:8: j--; - 0003 4B [ 4] 53 ld c,e - 0004 42 [ 4] 54 ld b,d - 0005 0B [ 6] 55 dec bc - 0006 59 [ 4] 56 ld e, c - 57 ;kernel/kernel.c:7: for (i = 0; i < 10; i++) { - 0007 78 [ 4] 58 ld a,b - 0008 57 [ 4] 59 ld d,a - 0009 B1 [ 4] 60 or a,c - 000A 20 F7 [12] 61 jr NZ,00104$ - 000C C9 [10] 62 ret - 63 .area _CODE - 64 .area _INITIALIZER - 65 .area _CABS (ABS) diff --git a/sw/z80/build/kernel/kernel.rel b/sw/z80/build/kernel/kernel.rel deleted file mode 100644 index 1079edc..0000000 --- a/sw/z80/build/kernel/kernel.rel +++ /dev/null @@ -1,23 +0,0 @@ -XL2 -H 9 areas 2 global symbols -M kernel -O -mz80 -S .__.ABS. Def0000 -A _CODE size D flags 0 addr 0 -S _main Def0000 -A _DATA size 0 flags 0 addr 0 -A _INITIALIZED size 0 flags 0 addr 0 -A _DABS size 0 flags 8 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _INITIALIZER size 0 flags 0 addr 0 -A _CABS size 0 flags 8 addr 0 -T 00 00 -R 00 00 00 00 -T 00 00 11 0A 00 -R 00 00 00 00 -T 03 00 -R 00 00 00 00 -T 03 00 4B 42 0B 59 78 57 B1 20 F7 C9 -R 00 00 00 00 diff --git a/sw/z80/build/kernel/kernel.sym b/sw/z80/build/kernel/kernel.sym deleted file mode 100644 index d01735c..0000000 --- a/sw/z80/build/kernel/kernel.sym +++ /dev/null @@ -1,27 +0,0 @@ -ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 1. -Hexadecimal [16-Bits] - -Symbol Table - - .__.$$$. = 2710 L - .__.ABS. = 0000 G - .__.CPU. = 0000 L - .__.H$L. = 0000 L - 0 _main 0000 GR - - -ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 2. -Hexadecimal [16-Bits] - -Area Table - - 0 _CODE size D flags 0 - 1 _DATA size 0 flags 0 - 2 _INITIALIZED size 0 flags 0 - 3 _DABS size 0 flags 8 - 4 _HOME size 0 flags 0 - 5 _GSINIT size 0 flags 0 - 6 _GSFINAL size 0 flags 0 - 7 _INITIALIZER size 0 flags 0 - 8 _CABS size 0 flags 8 - diff --git a/sw/z80/crt0.rel b/sw/z80/crt0.rel deleted file mode 100644 index 809c0e6..0000000 --- a/sw/z80/crt0.rel +++ /dev/null @@ -1,86 +0,0 @@ -XL2 -H 14 areas 5 global symbols -M crt0 -S _main Ref0000 -S .__.ABS. Def0000 -A _CODE size A flags 0 addr 0 -S __clock Def0000 -S _exit Def0004 -A _HEADER size 0 flags 8 addr 0 -A _HEADER0 size 3 flags 8 addr 0 -A _HEADER1 size 2 flags 8 addr 8 -A _HEADER2 size 2 flags 8 addr 10 -A _HEADER3 size 2 flags 8 addr 18 -A _HEADER4 size 2 flags 8 addr 20 -A _HEADER5 size 2 flags 8 addr 28 -A _HEADER6 size 2 flags 8 addr 30 -A _HEADER7 size 2 flags 8 addr 38 -A _HEADER8 size C flags 8 addr 100 -A _HOME size 0 flags 0 addr 0 -A _INITIALIZER size 0 flags 0 addr 0 -A _GSINIT size 6 flags 0 addr 0 -S gsinit Def0000 -A _GSFINAL size 1 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _INITIALIZED size 0 flags 0 addr 0 -A _BSEG size 0 flags 0 addr 0 -A _BSS size 0 flags 0 addr 0 -A _HEAP size 0 flags 0 addr 0 -T 00 00 -R 00 00 02 00 -T 00 00 C3 00 01 -R 00 00 02 00 00 03 0A 00 -T 08 00 -R 00 00 03 00 -T 08 00 ED 4D -R 00 00 03 00 -T 10 00 -R 00 00 04 00 -T 10 00 ED 4D -R 00 00 04 00 -T 18 00 -R 00 00 05 00 -T 18 00 ED 4D -R 00 00 05 00 -T 20 00 -R 00 00 06 00 -T 20 00 ED 4D -R 00 00 06 00 -T 28 00 -R 00 00 07 00 -T 28 00 ED 4D -R 00 00 07 00 -T 30 00 -R 00 00 08 00 -T 30 00 ED 4D -R 00 00 08 00 -T 38 00 -R 00 00 09 00 -T 38 00 ED 4D -R 00 00 09 00 -T 00 01 -R 00 00 0A 00 -T 00 01 -R 00 00 0A 00 -T 00 01 31 FF FF CD 00 00 CD 00 00 C3 04 00 -R 00 00 0A 00 00 06 0D 00 02 09 00 00 00 0C 00 00 -T 00 00 -R 00 00 00 00 -T 00 00 3E 02 CF C9 -R 00 00 00 00 -T 04 00 -R 00 00 00 00 -T 04 00 3E 00 CF -R 00 00 00 00 -T 07 00 -R 00 00 00 00 -T 07 00 76 18 FD -R 00 00 00 00 -T 00 00 -R 00 00 0D 00 -T 00 00 78 B1 28 02 ED B0 -R 00 00 0D 00 -T 06 00 -R 00 00 0D 00 -T 00 00 C9 -R 00 00 0E 00 diff --git a/sw/z80/drivers/ctc.c b/sw/z80/drivers/ctc.c new file mode 100644 index 0000000..5ac4254 --- /dev/null +++ b/sw/z80/drivers/ctc.c @@ -0,0 +1,6 @@ +#include "ctc.h" + +void ctc_control() +{ + +} diff --git a/sw/z80/drivers/include/ctc.h b/sw/z80/drivers/include/ctc.h new file mode 100644 index 0000000..80e8b4b --- /dev/null +++ b/sw/z80/drivers/include/ctc.h @@ -0,0 +1,6 @@ +#ifndef __CTC_H__ +#define __CTC_H__ + +void ctc_control(); + +#endif /* __CTC_H__ */ diff --git a/sw/z80/drivers/include/pio.h b/sw/z80/drivers/include/pio.h new file mode 100644 index 0000000..ee968d7 --- /dev/null +++ b/sw/z80/drivers/include/pio.h @@ -0,0 +1,52 @@ +#ifndef __PIO_H__ +#define __PIO_H__ + +#include "addresses.h" +#include <stdint.h> + +// DEBUG +#define PIO_ASM_INTERFACE + +// ports +#define PIO_A 0 +#define PIO_B 1 + +// registers +#define PIO_REG_DATA 0 +#define PIO_REG_CTRL 2 + +#define PIO_REG_DATA_A 0 // (PIO_A | PIO_REG_PORT) +#define PIO_REG_DATA_B 1 // (PIO_B | PIO_REG_PORT) +#define PIO_REG_CTRL_A 2 // (PIO_A | PIO_REG_CTRL) +#define PIO_REG_CTRL_B 3 // (PIO_B | PIO_REG_CTRL) + +#define PIO_MODE_BYTE_OUT 0 // mode 0 +#define PIO_MODE_BYTE_IN 1 // mode 1 +#define PIO_MODE_BYTE_BI 2 // mode 2 +#define PIO_MODE_BIT_IO 3 // mode 3 + +#define PIO_INT_DISABLE 0 +#define PIO_INT_ACTIVE_HIGH 2 +#define PIO_INT_AND_MODE 4 +#define PIO_INT_ENABLE 8 + +/* functions used internally to interface with the device */ +inline void _pio_write(uint8_t reg, uint8_t data); +inline uint8_t _pio_read(uint8_t reg); + +/* the last argument is needed only for IO mode */ +void pio_set_mode(int port, int mode, uint8_t io); + +void pio_set_interrupts(int port, int control); +void pio_set_interrupts_mask(int port, int control, uint8_t mask); + +// uint8_t pio_read_data(int port); +uint8_t pio_read(int port); +void pio_write(int port, uint8_t data); + +inline int pio_read_pin(int port, uint8_t pin); +inline void pio_write_pin(int port, uint8_t pin); + +// TODO: implement mode (in/out/both) and interrupt vector + +#endif /* __PIO_H__ */ diff --git a/sw/z80/drivers/include/usart.h b/sw/z80/drivers/include/usart.h new file mode 100644 index 0000000..05aeb4a --- /dev/null +++ b/sw/z80/drivers/include/usart.h @@ -0,0 +1,158 @@ +#ifndef __USART_H__ +#define __USART_H__ + +#include "addresses.h" + +#include <stdint.h> +#include <string.h> + +// baudrate clock divisors +// values from TL16C550C datasheet (table 9 for 1.8432 MHz crystal) +#define USART_BAUDRATE_50 2304 +#define USART_BAUDRATE_75 1536 +#define USART_BAUDRATE_110 1047 +#define USART_BAUDRATE_134_5 857 +#define USART_BAUDRATE_150 768 +#define USART_BAUDRATE_300 384 +#define USART_BAUDRATE_600 192 +#define USART_BAUDRATE_1200 96 +#define USART_BAUDRATE_1800 64 +#define USART_BAUDRATE_2000 58 +#define USART_BAUDRATE_2400 48 +#define USART_BAUDRATE_3600 32 +#define USART_BAUDRATE_4800 24 +#define USART_BAUDRATE_7200 16 +#define USART_BAUDRATE_9600 12 +#define USART_BAUDRATE_19200 6 +#define USART_BAUDRATE_38400 3 +#define USART_BAUDRATE_56000 3 + +// parity +#define USART_PARITY_NONE 0 +#define USART_PARITY_EVEN 1 +#define USART_PARITY_ODD 2 + +// stop bits +#define USART_STOP_BITS_1 10 +#define USART_STOP_BITS_15 15 +#define USART_STOP_BITS_2 20 + +// word lenght +#define USART_WORD_LENGTH_5 0 +#define USART_WORD_LENGTH_6 1 +#define USART_WORD_LENGTH_7 2 +#define USART_WORD_LENGTH_8 3 + +// autoflow +#define USART_AUTOFLOW_ALL 3 +#define USART_AUTOFLOW_CTS 2 +#define USART_AUTOFLOW_OFF 0 + +typedef unsigned int uint; +typedef volatile uint8_t register_t; + +/* stuctures for usart registers */ +struct IER +{ + volatile uint received_data_interrupt :1; + volatile uint transmitter_empty_interrupt :1; + volatile uint receiver_line_status_interrupt :1; + volatile uint modem_status_interrupt :1; + volatile uint reserved :4; +}; + +struct IIR +{ + volatile uint interrupt_pending :1; + volatile uint interrupt_id :3; + volatile uint reserved :2; + volatile uint fifos :2; +}; + +struct FCR +{ + volatile uint fifo_enable :1; + volatile uint receiver_fifo_rst :1; + volatile uint trasmitter_fifo_rst :1; + volatile uint dma_mode_select :1; + volatile uint reserved :1; + volatile uint receiver_trigger :2; +}; + +struct LCR +{ + volatile uint word_length :2; + volatile uint stop_bits :1; + volatile uint parity :1; + volatile uint even_parity :1; + volatile uint stick_parity :1; + volatile uint break_control :1; + volatile uint divisor_latch_access :1; +}; + +struct MCR +{ + volatile uint data_terminal_ready :1; + volatile uint request_to_send :1; + volatile uint out1; + volatile uint out2; + volatile uint loop; + volatile uint autoflow :1; + volatile uint reserved :2; +}; + +struct LSR +{ + volatile uint data_ready :1; + volatile uint overrun_error :1; + volatile uint parity_error :1; + volatile uint framing_error :1; + volatile uint break_interrupt :1; + volatile uint transmitter_holder_empty :1; + volatile uint transmitter_empty :1; + volatile uint fifo_recv_error :1; +}; + +struct MSR +{ + volatile uint delta_cts :1; + volatile uint delta_data_set_ready :1; + volatile uint trailing_edge_ring_indicator :1; + volatile uint delta_data_carrier_detect :1; + volatile uint clear_to_send :1; + volatile uint data_set_ready :1; + volatile uint ring_indicator :1; + volatile uint data_carrier_detect :1; +}; + +/* this structure is only for internal use */ +struct _usart_device +{ + register_t buffer; // also used as LSB for divisor latch + struct IER IER; + struct IIR IIR; + struct FCR FCR; + struct LCR LCR; + struct MCR MCR; + struct LSR LSR; + struct MSR MSR; + register_t scratch; +}; + + +// setup functions (wrappers) +void usart_set_baudrate(uint16_t baudrate); +void usart_set_parity(int mode); +void usart_set_stop_bits(int count); +void usart_set_word_length(int length); +void usart_set_autoflow(int mode); + +inline void usart_init(uint16_t baudrate, int parity, int stop_bits); + +void usart_transmit(uint8_t data); +uint8_t usart_receive(); + +int usart_write(uint8_t *data, size_t size); +int usart_read(uint8_t *buffer, size_t count); + +#endif // __USART__H__ diff --git a/sw/z80/drivers/makefile b/sw/z80/drivers/makefile new file mode 100644 index 0000000..65ded58 --- /dev/null +++ b/sw/z80/drivers/makefile @@ -0,0 +1,24 @@ +# Drivers library + +LIB := build/drivers.a +SOURCES := $(wildcard *.c) +OBJECTS := $(patsubst %.c,build/%.rel,$(SOURCES)) + +CC := sdcc +AR := sdar +CFLAGS := -mz80 -Iinclude -I../arch/include -DDEBUG + +.PHONY: dirs rebuild clean +$(LIB): $(OBJECTS) + $(AR) vrcs $@ $(OBJECTS) + +$(OBJECTS): build/%.rel: %.c $(SOURCES) dirs + $(CC) $(CFLAGS) -c $< -o $@ + +rebuild: clean $(LIB) + +dirs: + mkdir -p build + +clean: + - rm -rd build diff --git a/sw/z80/drivers/pio.c b/sw/z80/drivers/pio.c new file mode 100644 index 0000000..f396e43 --- /dev/null +++ b/sw/z80/drivers/pio.c @@ -0,0 +1,84 @@ +#include "pio.h" + +#ifdef PIO_ASM_INTERFACE +// TODO: set inline +void _pio_write(uint8_t reg, uint8_t data) +{ + __asm + ;; pop function arguments data in h, reg in a (l) + pop hl + ld a, l + ;; add ADDR_DEV_PIO to get the device address + add a, #ADDR_DEV_PIO + ld c, a + ;; load data + out (c), h + __endasm; +} + +inline uint8_t _pio_read(uint8_t reg) +{ + // TODO: check "dec sp" + __asm + ;; pop function argument + dec sp + pop hl + ld a, l + ;; add ADDR_DEV_PIO to get the device address + add a, #ADDR_DEV_PIO + ld c, a + ;; read data + in l, (c) + ret + __endasm; +} + +#else + +inline void _pio_write(uint8_t reg, uint8_t data) +{ + *((uint8_t *) (ADDR_DEV_PIO + reg)) = data; +} + +inline uint8_t _pio_read(uint8_t reg) +{ + return *((uint8_t *) (ADDR_DEV_PIO + reg)); +} + +#endif + +void pio_set_mode(int port, int mode, uint8_t io) +{ + // 0x0F is a control sequence to set mode + _pio_write((PIO_REG_CTRL + port), ((mode << 6) | 0x0F)); + + // this mode requires an additional argument that sets + // a mode for each pin + if (mode == PIO_MODE_BIT_IO) { + _pio_write((PIO_REG_CTRL + port), io); + } +} + +void pio_set_interrupts(int port, int control) +{ + // 0x07 is a control sequence to set interrupts + _pio_write((PIO_REG_CTRL + port), (control<<4 | 0x07)); +} + +void pio_set_interrupts_mask(int port, int control, uint8_t mask) +{ + // 0x17 is a control sequence to set interrupts + // AND interpret the next byte as a bitmask + _pio_write((PIO_REG_CTRL + port),(control | 0x97)); + _pio_write((PIO_REG_CTRL + port), mask); +} + +uint8_t pio_read(int port) +{ + return _pio_read((PIO_REG_DATA + port)); +} + +void pio_write(int port, uint8_t data) +{ + _pio_write((PIO_REG_DATA + port), data); +} diff --git a/sw/z80/kernel/usart.c b/sw/z80/drivers/usart.c index 9ec6dbd..9a5ee38 100644 --- a/sw/z80/kernel/usart.c +++ b/sw/z80/drivers/usart.c @@ -1,6 +1,6 @@ #include "usart.h" -static struct _usart_device *_usart = (struct _usart_device *) ADDR_DEV_USART; +static volatile struct _usart_device *_usart = ((struct _usart_device *) ADDR_DEV_USART); void usart_set_baudrate(uint16_t baudrate) { diff --git a/sw/z80/kernel/boot_loader.c b/sw/z80/kernel/boot_loader.c deleted file mode 100644 index 03a52b5..0000000 --- a/sw/z80/kernel/boot_loader.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "boot.h" -#include "progman.h" -#include "string.h" - -#define DEFAULT_EXEC_STATUS 0x4000 - -struct exec_status *status = EXEC_STATUS; - -void boot_init() { - - *status = DEFAULT_EXEC_STATUS; - - // TODO other stuff -} - -int8_t authenticate(const char *pwd) { - - return !memcmp(PWD_ADDR, pwd, PWD_SIZE); -} - -void set_pwd(const char *pwd) { - - memcpy(PWD_ADDR, pwd, PWD_SIZE); -}
\ No newline at end of file diff --git a/sw/z80/crt0.s b/sw/z80/kernel/crt0.s index 00c7da1..00c7da1 100644 --- a/sw/z80/crt0.s +++ b/sw/z80/kernel/crt0.s diff --git a/sw/z80/kernel/fs/fd.c b/sw/z80/kernel/fs/fd.c new file mode 100644 index 0000000..96603ad --- /dev/null +++ b/sw/z80/kernel/fs/fd.c @@ -0,0 +1,255 @@ +#include "fs/fd.h" +#include "fs/fdop.h" +#include "fs/fs.h" + +/* from fd.h */ +struct file_desc fd_table[FD_TABLE_SIZE]; +struct uint8_t fd_bmap[FD_TABLE_SIZE / 8]; + +/* File descriptors implementation */ + +int8_t open(const char *path, uint8_t flags) +{ + // TODO + return 0; +} + +size_t ls(int8_t fd, struct dirent *buf, uint8_t all) +{ + // TODO + return 0; +} + +size_t find(int8_t fd, struct dirent *buf, const char *name) +{ + // TODO + return 0; +} + +int8_t mkdir(int8_t fd, const char *name) +{ + // TODO + return 0; +} + +int8_t touch(int8_t fd, const char *name) +{ + // TODO + return 0; +} + +int8_t ln(int8_t fd, const char *name) +{ + // TODO + return 0; +} + +int8_t seek(int8_t fd, fsize_t pos) +{ + // TODO + return 0; +} + +size_t readline(int8_t fd, char *buf, char term) +{ + // TODO + return 0; +} + +int8_t print(int8_t fd, const char *str) +{ + // TODO + return 0; +} + +size_t read(int8_t fd, void *buf, size_t n) +{ + // TODO + return 0; +} + +int8_t write(int8_t fd, const void *buf, size_t n) +{ + // TODO + return 0; +} + +void close(int8_t fd) +{ + // TODO + return 0; +} + +/* Set of file descriptors operations */ +/* Determines if to use the serial interface or the address space */ + +/* Address space section */ + +/* File functions */ + +size_t as_readline(inode_t inode, fsize_t seek, char *buf, char term) +{ + // TODO + return 0; +} + +size_t as_print(inode_t inode, fsize_t seek, const char *str) +{ + // TODO + return 0; +} + +size_t as_append(inode_t inode, fsize_t *seek_ptr, const char *str) +{ + // TODO + return 0; +} + +size_t as_read(inode_t inode, fsize_t seek, void *buf, size_t n) +{ + // TODO + return 0; +} + +size_t as_write(inode_t inode, fsize_t seek, const void *buf, size_t n) +{ + // TODO + return 0; +} + +size_t as_bin_append(inode_t inode, fsize_t *seek_ptr, const void *buf, size_t +n) +{ + // TODO + return 0; +} + +/* Directory functions */ + +size_t as_ls(inode_t inode, struct dirent *buf, uint8_t all) +{ + // TODO + return 0; +} + +size_t as_find(inode_t inode, struct dirent *buf, const char *name) +{ + // TODO + return 0; +} + +int8_t as_mkdir(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t as_rmdir(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t as_touch(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t as_rm(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t as_ln(inode_t inode, const char *path, const char *name) +{ + // TODO + return 0; +} + +/* Serial Space section */ +/* Warning, it doesn't switch to the right driver */ + +/* File functions */ + +size_t ss_readline(inode_t inode, fsize_t seek, char *buf, char term) +{ + // TODO + return 0; +} + +size_t ss_print(inode_t inode, fsize_t seek, const char *str) +{ + // TODO + return 0; +} + +size_t ss_append(inode_t inode, fsize_t *seek_ptr, const char *str) +{ + // TODO + return 0; +} + +size_t ss_read(inode_t inode, fsize_t seek, void *buf, size_t n) +{ + // TODO + return 0; +} + +size_t ss_write(inode_t inode, fsize_t seek, const void *buf, size_t n) +{ + // TODO + return 0; +} + +size_t ss_bin_append(inode_t inode, fsize_t *seek_ptr, const void *buf, size_t +n) +{ + // TODO + return 0; +} + +/* Directory functions */ + +size_t ss_ls(inode_t inode, struct dirent *buf, uint8_t all) +{ + // TODO + return 0; +} + +size_t ss_find(inode_t inode, struct dirent *buf, const char *name) +{ + // TODO + return 0; +} + +int8_t ss_mkdir(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t ss_rmdir(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t ss_touch(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t ss_rm(inode_t inode, const char *name) +{ + // TODO + return 0; +} + +int8_t ss_ln(inode_t, const char *path, const char *name) +{ + // TODO + return 0; +} diff --git a/sw/z80/kernel/fs/fs.c b/sw/z80/kernel/fs/fs.c new file mode 100644 index 0000000..584f934 --- /dev/null +++ b/sw/z80/kernel/fs/fs.c @@ -0,0 +1,236 @@ +#include "fs/fs.h" +#include "fs/users.h" +#include "fs/dev.h" + +/* from users.h */ +struct fs_user c_user; + +/* from inode.h */ +inode_t c_inode; + +struct fs_dev devices[FS_MOUNT_LIMIT]; + +/* filesystem basic implementation */ + +devsize_t fs_block(blk_t block) +{ + // TODO + return 0; +} + +devsize_t fs_inode(struct fs_inode *buf) +{ + struct fs_superblock * sb; + devsize_t seek; + + if (FS_USE_ROM(c_inode)) + { + seek = FS_ROM_SPACE; + sb = (struct fs_superblock*) seek; + + } else { + + seek = 0; + + if (c_inode.dev > 0x7) + panic("Invalid device"); // TODO, still to implement + + sb = &devices[c_inode.dev].superblock; + } + + if (c_inode.inode >= sb->imap_size) + { + // TODO, set errno + return 0; // inode doesn't exist + } + + seek += sizeof(struct fs_superblock) + + sizeof(struct fs_inode) * c_inode.inode; + + if (FS_USE_ROM(c_inode)) + *buf = *(struct fs_inode*)seek; + else + { + /* set sio port */ + sio_port = devices[c_inode.dev].port_no; + sio_seek = seek; + + if (sio_read((void *)buf, INODE_META_SIZE) < INODE_META_SIZE) + { + // TODO, set errno + return 0; // cannot read to device + } + } + + return seek + INODE_META_SIZE; +} + +/* from fd.h */ +int8_t __fd_new() +{ + int8_t fd; + for (int8_t = 0; i < FD_TABLE_SIZE / 8; i++) + { + for (uint8_t bit = 0x80, j = 0; bit > 0; bit >>= 1, j++) + { + if (!(bit & fd_bmap[i])) + return i * 8 + j; + } + } + + return -1; +} + +/* from fd.h */ +int8_t __open_c_inode(uint8_t flags) +{ + /* read meta data */ + struct fs_inode inode; + + /* init file_desc buffer */ + struct file_desc desc = {c_inode, 0}; + + desc.begin = fs_inode(&inode); + + /* bind operations */ + + if (flags & OPEN_DIR) + { + /* dir handler */ + + if (inode.type == INODE_TYPE_DIR) + { + /* bind dir functions */ + if (FS_USE_ROM(c_inode)) + /* bind address space functions */ + FD_BIND_AS_DIR(desc.opers) + else + /* bind serial space functions */ + FD_BIND_SS_DIR(desc.opers) + + } else { + + // TODO, set errno + return -1; // not a directory + } + + } else if (flags & OPEN_LINK) { + + /* link handler */ + + if (inode.type == INODE_TYPE_LINK) + { + if (FS_USE_ROM(c_inode)) + FD_BIND_AS_FILE(desc.opers, flags) + else + FD_BIND_SS_FILE(desc.opers, flags) + + if (flags & OPEN_ERASE) + /* empty file content */ + __inode_empty(desc.begin); + + } else { + + // TODO, set errno + return -1; // not a link + } + + } else { + + /* file */ + + if (inode.type == INODE_TYPE_FILE) + ; // do nothing + else if (inode.type == INODE_TYPE_SPECIAL) { + + // TODO, bind special callbacks + + } else { + + // TODO, set errno + return -1; + } + + /* bind operations */ + + if (FS_USE_ROM(c_inode)) + { + if (flags & OPEN_BIN) + FD_BIND_AS_BINFILE(desc.opers, flags) + else + FD_BIND_AS_FILE(desc.opers, flags) + + } else { + + if (flags & OPEN_BIN) + FD_BIND_SS_BINFILE(desc.opers, flags) + else + FD_BIND_SS_FILE(desc.opers, flags) + } + } + + /* find a free fd space */ + + int8_t fd = __fd_new(); + + if (fd < 0) + { + // TODO, set errno, fd not available + + } else + fd_table[fd] = desc; // copy buffer into the table + + return fd; +} + +inode_t fs_rec_path(const char *path); + +inode_t fs_parse_path(const char *path) +{ + inode_t ino, cwd = c_inode; + + switch (path[0]) + { + case '0': + FS_INODE_NULL(ino) + return ino; + + case '/': + FS_INODE_ROOT(ino) + c_inode = ino; // set cwd to root + path++; + break; + + case '~': + + if (path[1] = '/') + { + c_inode.dev = FS_DEV_ROM; + c_inode.inode = c_user.home; // set cwd to home + path += 2; + } + + break; + } + + ino = fs_rec_path(path); + c_inode = cwd; + return ino; +} + +inode_t fs_rec_path(const char *path) +{ + devsize_t inode = fs_inode(c_inode.inode); + inode_t rel; + + if (!inode) // if not exists + { + FS_INODE_NULL(rel) + return rel; + } + + // TODO, check if dir or file + // TODO, if dir, find name + // TODO, set fs_cwd to new inode + // TODO, recall fs_rec_path +} diff --git a/sw/z80/kernel/include/boot.h b/sw/z80/kernel/include/boot.h deleted file mode 100644 index 5310e45..0000000 --- a/sw/z80/kernel/include/boot.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef BOOT_H -#define BOOT_H - -#include "types.h" - -#define LOGIN_PC // TODO find an address in ROM, to perform jumps - -#define EXEC_STATUS // TODO find an address in Kernel space - -#define PWD_ADDR // TODO find an address in ROM, password -#define PWD_SIZE 8 - -struct exec_status { - - volatile int logged_in:1; // authenticated - volatile int k_control:1; // no running programs - volatile int program_id:1; // current running program id, see "progman.h" - volatile int hidden_pc:13; // program counter of the paused program -}; - -void boot_init(); - -/* -* It returns 1 if succeded, otherwise 0 -*/ - -int8_t authenticate(const char *pwd); - -/* -* It sets the password in the ROM space, maximum 8 characters -*/ - -void set_pwd(const char *pwd); - -#endif
\ No newline at end of file diff --git a/sw/z80/kernel/include/devices.h b/sw/z80/kernel/include/devices.h index e8c183f..a846f9b 100644 --- a/sw/z80/kernel/include/devices.h +++ b/sw/z80/kernel/include/devices.h @@ -8,6 +8,8 @@ #define ADDR_DEV_CTC 0x4100 #define ADDR_DEV_PIO 0x4200 +#define ADDR_DEV_MMU + #define ADDR_DEV_RAM 0x8000 #endif diff --git a/sw/z80/kernel/include/errno.h b/sw/z80/kernel/include/errno.h new file mode 100644 index 0000000..7632269 --- /dev/null +++ b/sw/z80/kernel/include/errno.h @@ -0,0 +1,35 @@ +#ifndef ERRNO_H +#define ERRNO_H + +extern int errno; + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* Device not configured */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EDEADLK 11 /* Resource deadlock avoided */ + +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ + +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device busy */ +#define EEXIST 17 /* File exists */ + +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* Operation not supported by device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ + +#endif diff --git a/sw/z80/kernel/include/fs/dev.h b/sw/z80/kernel/include/fs/dev.h new file mode 100644 index 0000000..8e550f3 --- /dev/null +++ b/sw/z80/kernel/include/fs/dev.h @@ -0,0 +1,29 @@ +#ifndef DEV_H +#define DEV_H + +#include "types.h" + +#define FS_MOUNT_LIMIT 16 + +struct fs_superblock +{ + uint8_t magic; // identifier + + size_t blk_size; // size of a single block + size_t imap_size; // quantity of inodes + size_t dmap_size; // quantity of blocks +}; + +struct fs_dev +{ + uint enabled :1; // in use + uint port_no :3; // serial port number + uint :4; + inode_t inode; // dir mounted + struct fs_superblock superblock; // block informations +}; + +/* list of devices */ +extern struct fs_dev devices[FS_MOUNT_LIMIT]; + +#endif diff --git a/sw/z80/kernel/include/fs/dirent.h b/sw/z80/kernel/include/fs/dirent.h new file mode 100644 index 0000000..2fd224a --- /dev/null +++ b/sw/z80/kernel/include/fs/dirent.h @@ -0,0 +1,17 @@ +#ifndef __DIRENT_H__ +#define __DIRENT_H__ + +#include "types.h" + +struct dirent +{ + ino_t inode; // inode referred + uint8_t name_size; // size of the name + char name[]; // name of the referred inode +}; + +/* if inode is FS_INO_NULL, then the dirent is a memory leak */ +/* Warning: dirent leaks are generated by rm or rmdir operations */ +/* Filesystem must be periodically checked and cleaned */ + +#endif // __DIRENT_H__ diff --git a/sw/z80/kernel/include/fs/fd.h b/sw/z80/kernel/include/fs/fd.h new file mode 100644 index 0000000..d2fea2a --- /dev/null +++ b/sw/z80/kernel/include/fs/fd.h @@ -0,0 +1,102 @@ +#ifndef __FD_H__ +#define __FD_H__ + +#include "types.h" + +#define FD_MAX 32 + +#define OPEN_READ 0x1 +#define OPEN_WRITE 0x2 +#define OPEN_BIN 0x4 +#define OPEN_APPEND 0x8 +#define OPEN_ERASE 0x10 +#define OPEN_DIR 0x20 +#define OPEN_LINK 0x40 + +#define LS_ALL 0x1 + +/* declare dirent, not include */ +#ifndef __DIRENT_H__ +struct dirent; +#endif + +/* set of operations callback for fd */ +struct fd_operations +{ + size_t (*readline)(inode_t, fsize_t, char *, char term); + size_t (*print)(inode_t, fsize_t, const char *); + size_t (*append)(inode_t, fsize_t*, const char *); + + size_t (*read)(inode_t, fsize_t, void *, size_t); + size_t (*write)(inode_t, fsize_t, const void *, size_t); + size_t (*bin_append)(inode_t, fsize_t*, const void *, size_t); + + size_t (*ls)(inode_t, struct dirent *, uint8_t); + size_t (*find)(inode_t, struct dirent *, const char *); + int8_t (*mkdir)(inode_t, const char *); + int8_t (*rmdir)(inode_t, const char *); + int8_t (*touch)(inode_t, const char *); + int8_t (*rm)(inode_t, const char *); + int8_t (*ln)(inode_t, const char *, const char *); + + int8_t (*special)(inode_t, void *, size_t); +}; + +/* file descriptor */ +struct file_desc +{ + inode_t inode; // inode pointed + fsize_t seek; // virtual seek + devsize_t begin; // beginning of blocks + struct fd_operations opers; // bound operations +}; + +/* bitmap of used file descriptors */ +extern struct uint8_t fd_bmap[FD_TABLE_SIZE / 8]; + +/* table of file descriptors */ +extern struct file_desc fd_table[FD_TABLE_SIZE]; + +/* returns a free file descriptor */ +int8_t __fd_new(); + +/* opens a file streaming of the cwd */ +int8_t __open_c_inode(uint8_t flags); + +/* opens a file streaming by a path */ +int8_t open(const char *path, uint8_t flags); + +/* list content of directory */ +size_t ls(int8_t fd, struct dirent *buf, uint8_t all); + +/* find name through the directory entries */ +size_t find(int8_t fd, struct dirent *buf, const char *name); + +/* creates a new directory inside fd with the specified name */ +int8_t mkdir(int8_t fd, const char *name); + +/* creates a new file inside fd with the specified name */ +int8_t touch(int8_t fd, const char *name); + +/* creates a new symlink inside fd with the specified name */ +int8_t ln(int8_t fd, const char *name); + +/* change virtual seek position of the fd */ +int8_t seek(int8_t fd, fsize_t pos); + +/* reads a string from the fd until the terminator is reached */ +size_t readline(int8_t fd, char *buf, char term); + +/* writes a string into the fd */ +int8_t print(int8_t fd, const char *str); + +/* reads n bytes from the fd */ +size_t read(int8_t fd, void *buf, size_t n); + +/* writes n bytes into the fd */ +int8_t write(int8_t fd, const void *buf, size_t n); + +/* frees fd space */ +void close(int8_t fd); + +#endif // __FD_H__ diff --git a/sw/z80/kernel/include/fs/fdop.h b/sw/z80/kernel/include/fs/fdop.h new file mode 100644 index 0000000..d4b1b77 --- /dev/null +++ b/sw/z80/kernel/include/fs/fdop.h @@ -0,0 +1,140 @@ +#ifndef __FDOP_H__ +#define __FDOP_H__ + +#include "types.h" + +#ifndef __DIRENT_H__ +struct dirent; +#endif + +/* macro for direct binding */ + +#define FD_BIND_AS_DIR(oper) { \ + oper.ls = &as_ls; \ + oper.find = &as_find; \ + oper.mkdir = &as_mkdir; \ + oper.rmdir = &as_rmdir; \ + oper.touch = &as_touch; \ + oper.rm = &as_rm; \ + oper.ln = &as_ln; \ + } + +#define FD_BIND_SS_DIR(oper) { \ + oper.ls = &ss_ls; \ + oper.find = &ss_find; \ + oper.mkdir = &ss_mkdir; \ + oper.rmdir = &ss_rmdir; \ + oper.touch = &ss_touch; \ + oper.rm = &ss_rm; \ + oper.ln = &ss_ln; \ + } + +#define FD_BIND_AS_FILE(opers, flags) { \ + if (flags & OPEN_READ) \ + opers.readline = as_readline; \ + if (flags & OPEN_APPEND) \ + opers.append = as_append; \ + else if (flags & OPEN_WRITE) \ + opers.print = as_print; \ + } + +#define FD_BIND_SS_FILE(opers, flags) { \ + if (flags & OPEN_READ) \ + opers.readline = ss_readline; \ + if (flags & OPEN_APPEND) \ + opers.append = ss_append; \ + else if (flags & OPEN_WRITE) \ + opers.print = ss_print; \ + } + +#define FD_BIND_AS_BINFILE(opers, flags) { \ + if (flags & OPEN_READ) \ + opers.read = as_read; \ + if (flags & OPEN_APPEND) \ + opers.bin_append = as_bin_append; \ + else if (flags & OPEN_WRITE) \ + opers.write = as_write; \ + } + +#define FD_BIND_SS_BINFILE(opers, flags) { \ + if (flags & OPEN_READ) \ + opers.read = ss_read; \ + if (flags & OPEN_APPEND) \ + opers.bin_append = ss_bin_append; \ + else if (flags & OPEN_WRITE) \ + opers.write = ss_write; \ + } + +/* Set of file descriptors operations */ +/* Determines if to use the serial interface or the address space */ + +/* Address space section */ + +/* File functions */ + +size_t as_readline(inode_t inode, fsize_t seek, char *buf, char term); + +size_t as_print(inode_t inode, fsize_t seek, const char *str); + +size_t as_append(inode_t inode, fsize_t *seek_ptr, const char *str); + + +size_t as_read(inode_t inode, fsize_t seek, void *buf, size_t n); + +size_t as_write(inode_t inode, fsize_t seek, const void *buf, size_t n); + +size_t as_bin_append(inode_t inode, fsize_t *seek_ptr, const void *buf, size_t +n); + +/* Directory functions */ + +size_t as_ls(inode_t inode, struct dirent *buf, uint8_t all); + +size_t as_find(inode_t inode, struct dirent *buf, const char *name); + +int8_t as_mkdir(inode_t inode, const char *name); + +int8_t as_rmdir(inode_t inode, const char *name); + +int8_t as_touch(inode_t inode, const char *name); + +int8_t as_rm(inode_t inode, const char *name); + +int8_t as_ln(inode_t inode, const char *path, const char *name); + +/* Serial Space section */ +/* Warning, it doesn't switch to the right driver */ + +/* File functions */ + +size_t ss_readline(inode_t inode, fsize_t seek, char *buf, char term); + +size_t ss_print(inode_t inode, fsize_t seek, const char *str); + +size_t ss_append(inode_t inode, fsize_t *seek_ptr, const char *str); + + +size_t ss_read(inode_t inode, fsize_t seek, void *buf, size_t n); + +size_t ss_write(inode_t inode, fsize_t seek, const void *buf, size_t n); + +size_t ss_bin_append(inode_t inode, fsize_t *seek_ptr, const void *buf, size_t +n); + +/* Directory functions */ + +size_t ss_ls(inode_t inode, struct dirent *buf, uint8_t all); + +size_t ss_find(inode_t inode, struct dirent *buf, const char *name); + +int8_t ss_mkdir(inode_t inode, const char *name); + +int8_t ss_rmdir(inode_t inode, const char *name); + +int8_t ss_touch(inode_t inode, const char *name); + +int8_t ss_rm(inode_t inode, const char *name); + +int8_t ss_ln(inode_t, const char *path, const char *name); + +#endif // __FDOP_H__ diff --git a/sw/z80/kernel/include/fs/fs.h b/sw/z80/kernel/include/fs/fs.h new file mode 100644 index 0000000..ad20adb --- /dev/null +++ b/sw/z80/kernel/include/fs/fs.h @@ -0,0 +1,63 @@ +#ifndef __FS_H__ +#define __FS_H__ + +#include "types.h" + +#define FS_OFFSET 0x1000 + +#define FS_BLOCKS_SIZE 512 +#define FS_BLOCKS_N 8 +#define FS_BLOCKS_IND 6 + +#define INODE_TYPE_FILE 0x0 +#define INODE_TYPE_DIR 0x1 +#define INODE_TYPE_SLINK 0x2 +#define INODE_TYPE_SPECIAL 0x3 + +#define INODE_META_SIZE 8 + +/* inode basic structure */ +struct fs_inode +{ + /* inode meta data */ + + uint mode :3; // chmod + uint uid :3; // chown + uint type :2; // file, dir, sym-link, special + + time_t ctime; // creation time + + uint24_t size; // inode size + + /* data storage informations */ + /* it doesn't allocate memory, virtual size FS_BLOCKS_N */ + blk_t blocks[]; +}; + +#define FS_DEV_ROM 0x7f /* 01111111 */ +#define FS_DEV_NULL 0x80 /* 10000000 */ + +#define FS_ROM_SPACE 0x2000 // second rom + +#define FS_INO_ROOT 0x0 // first inode + +#define FS_INODE_ROOT(inode) {inode.dev = 0xff; inode.inode = 0x0} +#define FS_INODE_NULL(inode) {inode.dev = 0x80; inode.inode = 0x0} + +#define FS_USE_ROM(inode) {inode.dev == 0x7f} + +/* get block seek in current device */ +devsize_t fs_block(blk_t block); + +/* get common inode seek in current device */ +/* c_inode must be set first */ +/* returns seek at the beginning of blocks field */ +devsize_t fs_inode(struct fs_inode *buf); + +/* common inode for syscalls */ +extern inode_t c_inode; + +/* parse a path, absolute or relative to c_inode */ +inode_t fs_parse_path(const char *path); + +#endif // __FS_H__ diff --git a/sw/z80/kernel/include/fs/iter.h b/sw/z80/kernel/include/fs/iter.h new file mode 100644 index 0000000..41f011d --- /dev/null +++ b/sw/z80/kernel/include/fs/iter.h @@ -0,0 +1,17 @@ +#ifndef __ITER_H__ +#define __ITER_H__ + +struct inode_iter +{ + devsize_t dev_seek; /* seek position in the volume */ + devsize_t blk_end; /* end of the block */ + + int16_t blk_index; /* index of the block */ + + int8_t blk_level; /* recursion level, indirect blocks */ + + fsize_t fseek; /* virtual seek in the file */ + fsize_t size; /* file size */ +}; + +#endif // __ITER_H__ diff --git a/sw/z80/kernel/include/fs/users.h b/sw/z80/kernel/include/fs/users.h new file mode 100644 index 0000000..83980e5 --- /dev/null +++ b/sw/z80/kernel/include/fs/users.h @@ -0,0 +1,21 @@ +#ifndef USERS_H +#define USERS_H + +#include "types.h" + +#define USERS_MAX 8 +#define USER_ROOT 0 + +/* current user in use */ +extern struct fs_user c_user; + +struct fs_user +{ + char name[32]; + ino_t home; + uint8_t perm; // TODO, permissions +}; + +/* all users are in rom device */ + +#endif diff --git a/sw/z80/kernel/include/memory.h b/sw/z80/kernel/include/memory.h new file mode 100644 index 0000000..67c4b88 --- /dev/null +++ b/sw/z80/kernel/include/memory.h @@ -0,0 +1,50 @@ +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +#include "types.h" +#include "devices.h" + +/* maximum number of pages on the system */ +#define PAGES_MAX_COUNT 32 +#define PAGE_SIZE 1000 + +/* in our system there are only 16 pages since only 64KB can be addressed + * to optimize the memory management in ROM and RAM only pages from this set + * shall be used + */ +// ROM +#define ADDR_PAGE_0 0x0000 +#define ADDR_PAGE_1 0x1000 +#define ADDR_PAGE_2 0x2000 +#define ADDR_PAGE_3 0x3000 +// IOSPACE +#define ADDR_PAGE_4 0x4000 +#define ADDR_PAGE_5 0x5000 +#define ADDR_PAGE_6 0x6000 +#define ADDR_PAGE_7 0x7000 +// RAM +#define ADDR_PAGE_8 0x8000 +#define ADDR_PAGE_9 0x9000 +#define ADDR_PAGE_10 0xA000 +#define ADDR_PAGE_11 0xB000 +#define ADDR_PAGE_12 0xC000 +#define ADDR_PAGE_13 0xD000 +#define ADDR_PAGE_14 0xE000 +#define ADDR_PAGE_15 0xF000 + +#define ADDR_PAGE_FIRST ADDR_PAGE_8 +#define ADDR_PAGE_LAST ADDR_PAGE_15 + +struct page +{ + pid_t pid; // process owner of the page (0 if free) + uint16_t addr; // physical address +}; + +int mmu_write_table(void); + +int page_new(void); +int page_map(int page, int pid, uint16_t addr); +int page_unmap(int page); + +#endif // __MEMORY_H__ diff --git a/sw/z80/kernel/include/pio.h b/sw/z80/kernel/include/pio.h deleted file mode 100644 index 5d289ca..0000000 --- a/sw/z80/kernel/include/pio.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __PIO_H__ -#define __PIO_H__ - -#include "devices.h" -#include "types.h" - -#define PIO_A 0 -#define PIO_B 1 - -#define PIO_MODE_0 0 -#define PIO_MODE_1 1 -#define PIO_MODE_2 2 -#define PIO_MODE_3 3 - -#define PIO_INT_ACTIVE_HIGH (1<<5) -#define PIO_INT_AND_MODE (1<<6) -#define PIO_INT_ENABLE (1<<7) - - -void _pio_data(int port, uint8_t data); -void _pio_command(int port, uint8_t cmd); - -void pio_set_mode(int port, int mode); -void pio_set_interrupts(int port, int control); -void pio_set_interrupts_mask(int port, uint8_t mask); -void pio_set_io(int port, uint8_t io); - -// uint8_t pio_read_data(int port); - -inline int pio_read_pin(int port, uint8_t pin); -inline void pio_write_pin(int port, uint8_t pin); - -// TODO: implement mode (in/out/both) and interrupt vector - -#endif // __PIO_H__ diff --git a/sw/z80/kernel/include/process.h b/sw/z80/kernel/include/process.h new file mode 100644 index 0000000..3b0c843 --- /dev/null +++ b/sw/z80/kernel/include/process.h @@ -0,0 +1,43 @@ +#ifndef __PROCESS_H__ +#define __PROCESS_H__ + +#include "types.h" +#include "memory.h" + + /* maximum number of processes (i.e. pages in ram) + * since each program can use only one page in ram + */ +#define PROC_COUNT 2 + +/* the pid is defined with a single byte (pid_t is uint8_t), because of that + * there cannot be more than 255 processes open at the same time. this is a + * limitation but for our purposes is more than enough + */ +#define PID_COUNT_MAX 255 + +struct executable +{ + void *text; + size_t text_size; + void *bss; + size_t bss_size; +}; + +struct process +{ + uint blocked :1; // process is waiting for hardware or locked + uint running :1; // pid is used + uint pages; // number of pages used by the process + struct page page[4]; // pages used by the process +}; + +pid_t newpid(void); + +int fork(void); +int exec(char *path, char *args); +int spawn(char *path, char *args); + +pid_t getpid(void); +int kill(pid_t pid); + +#endif // __PROCESS_H__ diff --git a/sw/z80/kernel/include/progman.h b/sw/z80/kernel/include/progman.h deleted file mode 100644 index 5d01f1c..0000000 --- a/sw/z80/kernel/include/progman.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef PROGRAM_MAN -#define PROGRAM_MAN - -#include "types.h" - -#define PROG_0 0x0 -#define PROG_1 0x1 - -#define PROG_VSTART 0x1000 -#define PROG_0_PREFIX 0xA000 -#define PROG_1_PREFIX 0xC000 - -#define PROG_0_INFO // TODO -#define PROG_1_INFO // TODO find a space in the ram - -struct program_info { - - volatile int enabled:1; - volatile int running:1; - volatile int exiting:1; - volatile int heap_addr:13; - volatile void (*quit_cb)(void); // 16 -}; - -/* -* Initialize the program manager system -*/ - -void progman_init(); - -/* -* Check if it can start a new program -* If it succedes, the program id is returned, -* otherwise it is returned an error number -*/ - -#define PROG_REQ_FULL -1 -#define PROG_REQ_ERR -2 // Maybe we don't need this, but just in case - -int8_t prog_req(struct program_info *info); - -/* -* It allocates a program in the RAM -* To obtain the right id call prog_req() first -* Basic informations must be allocated and referenced by a program_base struct -*/ - -struct program_base { - - void * inst_set; // pointer to the instructions set - size_t inst_size; // size of the instructions set - void * bss_data; // pointer to the bss/data space - size_t data_size; // size of the bss/data space -}; - -void prog_alloc(int8_t id, struct program_info *info, const struct program_base *base); - -/* -* It jumps the program counter to the given one -*/ - -void prog_exec(int8_t id, struct program_info *info); - -/* -* It sets a quit callback -*/ - -void prog_0_qcb(void (*callback)(void)); -void prog_1_qcb(void (*callback)(void)); - -/* -* It quits a program, if a callback is set, it will be called -*/ - -void prog_0_quit(); -void prog_1_quit(); - -/* -* It forces a program to quit -*/ - -void prog_0_fquit(); -void prog_1_fquit(); - -#endif
\ No newline at end of file diff --git a/sw/z80/kernel/include/sio.h b/sw/z80/kernel/include/sio.h new file mode 100644 index 0000000..276b99c --- /dev/null +++ b/sw/z80/kernel/include/sio.h @@ -0,0 +1,43 @@ +#ifndef __SIO_H__ +#define __SIO_H__ + +#include "types.h" + +#define SIO_PORT_0 0x0 +#define SIO_PORT_1 0x1 +#define SIO_PORT_2 0x2 +#define SIO_PORT_3 0x3 +#define SIO_PORT_4 0x4 +#define SIO_PORT_5 0x5 +#define SIO_PORT_6 0x6 +#define SIO_PORT_7 0x7 + +/* current port in use */ +extern uint8_t sio_port; + +/* current seek in the device */ +extern devsize_t sio_seek; + +struct dev_buffer +{ + // TODO, bytes needed to the device buffer interface +}; + +/* points to the buffers mapped in the I/O space */ +/* to be defined precisely in assembly */ +extern volatile struct dev_buffer sio_buffers[8]; + +/* initialize serial interface */ +void sio_init(); + +/* syscall: read one byte from the current device */ +uint8_t sio_recv(); +/* syscall: write one byte into the current device */ +void sio_send(uint8_t value); + +/* read n bytes from the current port */ +size_t sio_read(void *buffer, size_t n); +/* write n bytes into the current port */ +int8_t sio_write(const void *buffer, size_t n); + +#endif // __SIO_H__ diff --git a/sw/z80/kernel/include/stat.h b/sw/z80/kernel/include/stat.h new file mode 100644 index 0000000..44c0f63 --- /dev/null +++ b/sw/z80/kernel/include/stat.h @@ -0,0 +1,24 @@ +#ifndef __STAT_H__ +#define __STAT_H__ + +#include "types.h" + +struct stat +{ + inode_t inode; /* inode reference */ + + uint mode :3; /* mode */ + uint uid :3; /* owner id */ + uint type :2; /* file, dir or link */ + + devsize_t size; /* file size */ + + size_t blk_size; /* single block size */ + size_t blk_used; /* blocks used by the file */ + + time_t ctime; /* creation time */ +} + +struct stat * stat(const char *path, struct stat *buffer); + +#endif // __STAT_H__ diff --git a/sw/z80/kernel/include/types.h b/sw/z80/kernel/include/types.h index 552b7e9..c6e620b 100644 --- a/sw/z80/kernel/include/types.h +++ b/sw/z80/kernel/include/types.h @@ -1,13 +1,62 @@ #ifndef __TYPES_H__ #define __TYPES_H__ -#define register_t volatile unsigned char +/* only types from primitive types are defined in this file */ -#define int8_t char -#define uint8_t unsigned char -#define int16_t int -#define uint16_t unsigned int +typedef volatile unsigned char register_t; -#define size_t uint16_t +typedef unsigned int uint; + +typedef char int8_t; +typedef unsigned char uint8_t; +typedef int int16_t; +typedef unsigned int uint16_t; +typedef long int int32_t; +typedef unsigned long int uint32_t; + +typedef uint16_t size_t; +typedef int16_t ssize_t; + +typedef uint8_t pid_t; +typedef uint16_t ino_t; + +typedef uint8_t dev_t; +typedef uint32_t devsize_t; +typedef uint8_t fd_t; +typedef uint16_t blk_t; +typedef uint8_t user_t; + +typedef struct { + uint8_t member[3]; + +} uint24_t; + +typedef uint32_t fsize_t; + +typedef struct +{ + dev_t dev; // device id, global in the fs + ino_t inode; // inode id relative to the volume + +} inode_t; + +typedef struct time_s +{ + struct + { + uint minutes :6; + uint hour :5; + + } time; + + struct + { + uint day :5; + uint month :4; + uint year :12; + + } date; + +} time_t; #endif diff --git a/sw/z80/kernel/include/usart.h b/sw/z80/kernel/include/usart.h deleted file mode 100644 index 3e5c070..0000000 --- a/sw/z80/kernel/include/usart.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef __USART_H__ -#define __USART_H__ - -#include "types.h" -#include "devices.h" - -#include "string.h" - -// baudrate clock divisors -// values from TL16C550C datasheet (table 9 for 1.8432 MHz crystal) -#define USART_BAUDRATE_50 2304 -#define USART_BAUDRATE_75 1536 -#define USART_BAUDRATE_110 1047 -#define USART_BAUDRATE_134_5 857 -#define USART_BAUDRATE_150 768 -#define USART_BAUDRATE_300 384 -#define USART_BAUDRATE_600 192 -#define USART_BAUDRATE_1200 96 -#define USART_BAUDRATE_1800 64 -#define USART_BAUDRATE_2000 58 -#define USART_BAUDRATE_2400 48 -#define USART_BAUDRATE_3600 32 -#define USART_BAUDRATE_4800 24 -#define USART_BAUDRATE_7200 16 -#define USART_BAUDRATE_9600 12 -#define USART_BAUDRATE_19200 6 -#define USART_BAUDRATE_38400 3 -#define USART_BAUDRATE_56000 3 - -// parity -#define USART_PARITY_NONE 0 -#define USART_PARITY_EVEN 1 -#define USART_PARITY_ODD 2 - -// stop bits -#define USART_STOP_BITS_1 10 -#define USART_STOP_BITS_15 15 -#define USART_STOP_BITS_2 20 - -// word lenght -#define USART_WORD_LENGTH_5 0 -#define USART_WORD_LENGTH_6 1 -#define USART_WORD_LENGTH_7 2 -#define USART_WORD_LENGTH_8 3 - -// autoflow -#define USART_AUTOFLOW_ALL 3 -#define USART_AUTOFLOW_CTS 2 -#define USART_AUTOFLOW_OFF 0 - - -/* this structure is only for internal usage */ -struct _usart_device -{ - register_t buffer; // also used as LSB for divisor latch - - struct IER - { - volatile int received_data_interrupt :1; - volatile int transmitter_empty_interrupt :1; - volatile int receiver_line_status_interrupt :1; - volatile int modem_status_interrupt :1; - volatile int reserved :4; - } IER; - - struct IIR - { - volatile int interrupt_pending :1; - volatile int interrupt_id :3; - volatile int reserved :2; - volatile int fifos :2; - } IIR; - - struct FCR - { - volatile int fifo_enable :1; - volatile int receiver_fifo_rst :1; - volatile int trasmitter_fifo_rst :1; - volatile int dma_mode_select :1; - volatile int reserved :1; - volatile int receiver_trigger :2; - } FCR; - - struct LCR - { - volatile int word_length :2; - volatile int stop_bits :1; - volatile int parity :1; - volatile int even_parity :1; - volatile int stick_parity :1; - volatile int break_control :1; - volatile int divisor_latch_access :1; - } LCR; - - struct MCR - { - volatile int data_terminal_ready :1; - volatile int request_to_send :1; - volatile int out1; - volatile int out2; - volatile int loop; - volatile int autoflow :1; - volatile int reserved :2; - } MCR; - - struct LSR - { - volatile int data_ready :1; - volatile int overrun_error :1; - volatile int parity_error :1; - volatile int framing_error :1; - volatile int break_interrupt :1; - volatile int transmitter_holder_empty :1; - volatile int transmitter_empty :1; - volatile int fifo_recv_error :1; - } LSR; - - struct MSR - { - volatile int delta_cts :1; - volatile int delta_data_set_ready :1; - volatile int trailing_edge_ring_indicator :1; - volatile int delta_data_carrier_detect :1; - volatile int clear_to_send :1; - volatile int data_set_ready :1; - volatile int ring_indicator :1; - volatile int data_carrier_detect :1; - } MSR; - - register_t scratch; -}; - - -// setup functions (wrappers) -void usart_set_baudrate(uint16_t baudrate); -void usart_set_parity(int mode); -void usart_set_stop_bits(int count); -void usart_set_word_length(int length); -void usart_set_autoflow(int mode); - -inline void usart_init(uint16_t baudrate, int parity, int stop_bits); - -void usart_transmit(uint8_t data); -uint8_t usart_receive(); - -int usart_write(uint8_t *data, size_t size); -int usart_read(uint8_t *buffer, size_t count); - -#endif // __USART__H__ diff --git a/sw/z80/makefile b/sw/z80/kernel/makefile index 3d682ca..be8eed4 100644 --- a/sw/z80/makefile +++ b/sw/z80/kernel/makefile @@ -3,7 +3,9 @@ # OSNAME := helvetiOS -CSOURCES := $(wildcard kernel/*.c) $(wildcard libc/*.c) +CSOURCES := $(wildcard *.c) \ + $(wildcard drivers/*.c) + OBJECTS := $(patsubst %.c,build/%.rel,$(CSOURCES)) HEXFILE := build/$(OSNAME).hex BINARY := build/$(OSNAME).bin @@ -14,9 +16,14 @@ BINARY := build/$(OSNAME).bin CC := sdcc CFLAGS := -mz80 \ - -I kernel/include -I libc/include -DDEBUG - -LDFLAGS := -mz80 --no-std-crt0 crt0.rel \ + -I include \ + -I include/drivers \ + -I libc/include \ + --opt-code-size \ + -DDEBUG + +LDFLAGS := -mz80 --no-std-crt0 build/crt0.rel \ + --std-c89 -pedantic \ --code-loc 0x0800 --data-loc 0x8000 .PHONY: dirs dis clean @@ -25,21 +32,22 @@ all: $(BINARY) # build binary $(BINARY): $(OBJECTS) dirs $(CC) $(LDFLAGS) $(OBJECTS) -o $(HEXFILE) - xxd -r -p $(HEXFILE) $(BINARY) + makebin -s 16384 $(HEXFILE) $(BINARY) -$(OBJECTS): build/%.rel : %.c $(CSOURCES) dirs crt0.rel +$(OBJECTS): build/%.rel : %.c $(CSOURCES) dirs build/crt0.rel + @printf "\n" $(CC) $(CFLAGS) -c $< -o $@ -crt0.rel: crt0.s +build/crt0.rel: crt0.s sdasz80 -o $< + @mv crt0.rel build dirs: - mkdir -p build build/kernel build/libc + mkdir -p build build/kernel build/libc build/kernel/drivers dis: $(BINARY) - z80dasm -a -g 0h $< -o $(OSNAME).s + dz80 -b -n $< clean: - rm -rd build/* - - rm $(OSNAME).s - rm crt0.rel diff --git a/sw/z80/kernel/memory.c b/sw/z80/kernel/memory.c new file mode 100644 index 0000000..1b2cc76 --- /dev/null +++ b/sw/z80/kernel/memory.c @@ -0,0 +1,94 @@ +#include "memory.h" + +static struct page pages_table[PAGES_MAX_COUNT]; + +int mmu_write_table(void) +{ + int i; + + for (i = 0; i < PAGES_MAX_COUNT; i++) { + if (pages_table[i].pid != 0) { + // write to mmu table + } + } + + return 0; +} + +int page_new(void) +{ + int i, used; + uint16_t addr; + + for (addr = ADDR_PAGE_FIRST; addr < ADDR_PAGE_LAST; addr += PAGE_SIZE) { + used = 0; + + for (i = 0; i < PAGES_MAX_COUNT; i++) { + if (pages_table[i].addr == addr) { + used = 1; + break; + } + } + + if (!used) + return i; + } + + return -1; +} + +int page_map(int page, int pid, uint16_t addr) +{ + if (page >= PAGES_MAX_COUNT) + return -1; + + if (pages_table[page].pid != 0) + return -2; + + pages_table[page].addr = addr; + pages_table[page].pid = pid; + + return 0; +} + +int page_unmap(int page) +{ + if (page >= PAGES_MAX_COUNT) + return -1; + + if (pages_table[page].pid == 0) + return -2; + + pages_table[page].pid = 0; + pages_table[page].addr = 0; + return 0; +} + +/* k_malloc manager */ +/* +struct k_buf_entry k_buf_table[K_BUF_MAX_COUNT]; + +struct k_buf k_buffers[K_BUF_MAX_COUNT]; + +void * k_malloc() +{ + for (uint8_t i = 0; i < K_BUF_TABLE_COUNT; i++) + { + for (uint8_t bit = 0x80, j = 0; j < 8; bit >>= 1, j++) + { + if (bit & k_buf_table[i]) + { + k_buf_table[i] |= bit; + return &k_buffers[8 * i + j]; + } + } + } +} + +void k_free(void * ptr) +{ + uint8_t index = (ptr - &k_buffers[0]) / K_BUF_SIZE; + + if (index < K_BUF_MAX_COUNT) + k_buf_table[index / 8] ^= 0x80 >> index % 8; +}*/ diff --git a/sw/z80/kernel/pio.c b/sw/z80/kernel/pio.c deleted file mode 100644 index 4b9caee..0000000 --- a/sw/z80/kernel/pio.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "pio.h" - -static uint8_t *pio_port = (uint8_t *) ADDR_DEV_PIO; -static uint8_t *pio_ctrl = (uint8_t *) (ADDR_DEV_PIO + 2); - -void _pio_data(int port, uint8_t data) -{ - *(pio_port + port) = data; -} - -void _pio_command(int port, uint8_t cmd) -{ - *(pio_ctrl + port) = cmd; -} - -void pio_set_mode(int port, int mode) -{ -} diff --git a/sw/z80/kernel/process.c b/sw/z80/kernel/process.c new file mode 100644 index 0000000..7d8db89 --- /dev/null +++ b/sw/z80/kernel/process.c @@ -0,0 +1,58 @@ +#include "process.h" + +static struct process proc_table[PID_COUNT_MAX]; +static struct process *current_proc; + +pid_t newpid(void) +{ + int i; + static pid_t last_pid = 0; + + for (i = 0; i < PID_COUNT_MAX; i++, last_pid++) { + if (last_pid == PID_COUNT_MAX) { + last_pid = 0; + continue; + } + + if (!proc_table[last_pid].running) + break; + } + + if (i >= PID_COUNT_MAX) + return 0; + + return last_pid; +} + +int fork(void) +{ + int i, p; + pid_t child_pid = newpid(); + + if (child_pid == 0) + return -1; + + + for (i = 0; i < current_proc->pages; i++) { + p = page_new(); + + if (p == -1) { + return -2; + } + + // TODO: use memcpy() + // SDCC does not allow assignemnts of structs + + // proc_table[child_pid].page[i] = p; + } +} + +int exec(char *path, char *args) +{ + +} + +int spawn(char *path, char *args) +{ + +} diff --git a/sw/z80/kernel/programs.c b/sw/z80/kernel/programs.c deleted file mode 100644 index 705ea96..0000000 --- a/sw/z80/kernel/programs.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "progman.h" -#include "string.h" - -#define EMPTY_PROG_INFO 0x0 - -struct program_info *prog_0 = PROG_0_INFO, - *prog_1 = PROG_1_INFO; - -void progman_init() { - - *prog_0 = EMPTY_PROG_INFO; - *prog_1 = EMPTY_PROG_INFO; - - // TODO other stuff -} - -int8_t prog_req(struct program_info *info) { - - uint8_t prog; - - if (!prog_0->enabled) { - - prog = PROG_0; - *info = *prog_0; - - } else if (!prog_1->enabled) { - - prog = PROG_1; - *info = *prog_1; - - } else { - - return PROG_REQ_FULL; - } - - return prog; -} - -void prog_alloc(int8_t id, struct program_info *info, const struct program_base *base) { - - void *addr = (id ? PROG_1_PREFIX : PROG_0_PREFIX) + PROG_VSTART; - - if (info->enabled) { - - if (id) - prog_1_fquit(); // force quit operation - else - prog_0_fquit(); - } - - - memcpy(addr, base->inst_set, base->inst_size); - - addr += base->inst_size; - - memcpy(addr, base->bss_data, base->data_size); - - addr += base->data_size; - - // TODO, empty heap and stack -} - -/* -* TODO Called from the assembly, system calls -*/ - -extern void exec_0(void); -extern void exec_1(void); - -void prog_exec(int8_t id, struct program_info *info) { - - // TODO, perform a program counter jump -} - -void prog_0_qcb(void (*callback)(void)) { - - prog_0->quit_cb = callback; -} - -void prog_1_qcb(void (*callback)(void)) { - - prog_1->quit_cb = callback; -} - -void prog_0_quit() { - - if (!prog_0->enabled || prog_0->exiting) - return; - - if (prog_0->quit_cb) - prog_0->quit_cb(); - - // TODO free space in RAM - - *prog_0 = EMPTY_PROG_INFO; - - // TODO jump program counter -} - -void prog_1_quit() { - - if (!prog_1->enabled || prog_1->exiting) - return; - - if (prog_1->quit_cb) - prog_1->quit_cb(); - - // TODO free space in RAM - - *prog_1 = EMPTY_PROG_INFO; - - // TODO jump program counter -} - -void prog_0_fquit() { - - if (!prog_0->enabled) - return; - - // TODO free space in RAM - - *prog_0 = EMPTY_PROG_INFO; - - // TODO jump program counter -} - -void prog_1_fquit() { - - if (!prog_1->enabled) - return; - - // TODO free space in RAM - - *prog_1 = EMPTY_PROG_INFO; - - // TODO jump program counter -}
\ No newline at end of file diff --git a/sw/z80/libc/include/stdint.h b/sw/z80/libc/include/stdint.h new file mode 100644 index 0000000..5e8caf3 --- /dev/null +++ b/sw/z80/libc/include/stdint.h @@ -0,0 +1,13 @@ +#ifndef __STDINT_H__ +#define __STDINT_H__ + +typedef unsigned int uint; + +typedef char int8_t; +typedef unsigned char uint8_t; +typedef int int16_t; +typedef unsigned int uint16_t; +typedef long int int32_t; +typedef unsigned long int uint32_t; + +#endif // __STDINT_H__
\ No newline at end of file diff --git a/sw/z80/libc/include/stdlib.h b/sw/z80/libc/include/stdlib.h new file mode 100644 index 0000000..c69f573 --- /dev/null +++ b/sw/z80/libc/include/stdlib.h @@ -0,0 +1,7 @@ +#ifndef __STDLIB_H__ +#define __STDLIB_H__ + +#include "stdint.h" + + +#endif // __STDLIB_H__
\ No newline at end of file diff --git a/sw/z80/libc/include/types.h b/sw/z80/libc/include/types.h new file mode 100644 index 0000000..a083bfe --- /dev/null +++ b/sw/z80/libc/include/types.h @@ -0,0 +1,60 @@ +#ifndef __TYPES_H__ +#define __TYPES_H__ + +/* only types from primitive types are defined in this file */ + +typedef volatile unsigned char register_t; + +typedef unsigned int uint; + +typedef char int8_t; +typedef unsigned char uint8_t; +typedef int int16_t; +typedef unsigned int uint16_t; +typedef long int int32_t; +typedef unsigned long int uint32_t; + +typedef uint16_t size_t; +typedef int16_t ssize_t; + +typedef uint8_t pid_t; +typedef uint16_t ino_t; + +typedef uint8_t dev_t; +typedef uint32_t devsize_t; +typedef uint8_t fd_t; +typedef uint16_t blk_t; +typedef uint8_t user_t; +typedef struct { + uint8_t member[3]; +} uint24_t; + +typedef uint32_t fsize_t; + +typedef struct +{ + dev_t dev; // device id, global in the fs + ino_t inode; // inode id relative to the volume + +} inode_t; + +typedef struct time_s +{ + struct + { + uint minutes :6; + uint hour :5; + + } time; + + struct + { + uint day :5; + uint month :4; + uint year :12; + + } date; + +} time_t; + +#endif diff --git a/sw/z80/libc/string.c b/sw/z80/libc/string.c index 9dd56cc..57b3a7f 100644 --- a/sw/z80/libc/string.c +++ b/sw/z80/libc/string.c @@ -1,11 +1,11 @@ #include "string.h" -void * memset(void *dest, const int8_t src, size_t n) { +void *memset(void *dest, const int8_t src, size_t n) { - void *dp = dest; + char *dp = (char *) dest; while (n--) - *dp++ = src; + *(dp++) = src; return dest; } @@ -22,16 +22,14 @@ void *memcpy(void *dest, void *src, size_t n) return dest; } -int8_t memcmp(const void *s1, const void *s2, size_t n) { - - uint8_t u1, u2; - - for ( ; n--; s1++, s2++) { +int8_t memcmp(void *s1, void *s2, size_t n) +{ + char *u1 = (char *) s1; + char *u2 = (char *) s2; - u1 = *s1; - u2 = *s2; + for ( ; n--; u1++, u2++) { - if (u1 != u2) + if (*u1 != *u2) return u1 - u2; } diff --git a/sw/z80/tests/asm/main.s b/sw/z80/tests/asm/main.s new file mode 100644 index 0000000..8cf4df0 --- /dev/null +++ b/sw/z80/tests/asm/main.s @@ -0,0 +1,40 @@ + .module crt0 + .area _HEADER (ABS) + +;; Reset vectors + .org 0 + jp init + + .org 0x38 ; the instruction 0xff (not written) resets to this location + jp init + +;; main code + .org 0x100 + .globl _main + +init: + ;; Set stack pointer directly above top of memory. + ld sp,#0xffff + + ;; Start of the program + call _main + jp _exit + +_exit: + halt + ; jp _exit + +;; Ordering of segments for the linker. + .area _HOME + .area _CODE +_main: + ret + .area _INITIALIZER + .area _GSINIT + .area _GSFINAL + + .area _DATA + .area _INITIALIZED + .area _BSEG + .area _BSS + .area _HEAP diff --git a/sw/z80/tests/asm/makefile b/sw/z80/tests/asm/makefile new file mode 100644 index 0000000..413b0fe --- /dev/null +++ b/sw/z80/tests/asm/makefile @@ -0,0 +1,47 @@ +#### +# source code settings +# +OSNAME := ram_test + +CSOURCES := $(wildcard *.s) + +OBJECTS := $(patsubst %.s,build/%.rel,$(SOURCES)) +HEXFILE := build/$(OSNAME).hex +BINARY := build/$(OSNAME).bin + +### +# compiler settings +# +ASM := sdasz80 +LD := sdldz80 + +FLAGS := +LDFLAGS := + +.PHONY: flash dirs dis clean +all: $(BINARY) + +flash: $(BINARY) + minipro -p M28C64 -w $< + +# build binary +$(BINARY): $(OBJECTS) dirs + $(LD) $(LDFLAGS) $(OBJECTS) -o $(HEXFILE) + makebin -s 8192 -yo 1 $(HEXFILE) $(BINARY) + +$(OBJECTS): build/%.rel : %.s $(SOURCES) dirs + @printf "\n" + $(ASM) $(FLAGS) $< -o + +build/crt0.rel: crt0.s + sdasz80 -o $< + @mv crt0.rel build/ + +dirs: + mkdir -p build + +dis: $(BINARY) + r2 -a z80 $< -c 'pd 0x10; s 0x100; pd 10; s 0x200; pd 10' + +clean: + - rm -rd build diff --git a/sw/z80/tests/pio/crt0.s b/sw/z80/tests/pio/crt0.s new file mode 100644 index 0000000..c900065 --- /dev/null +++ b/sw/z80/tests/pio/crt0.s @@ -0,0 +1,38 @@ + .module crt0 + .area _HEADER (ABS) + +;; Reset vectors + .org 0 + jp init + + .org 0x38 ; the instruction 0xff (not written) resets to this location + jp init + +;; main code + .org 0x100 + .globl _main + +init: + ;; Set stack pointer directly above top of memory. + ld sp,#0xffff + + ;; Start of the program + call _main + jp _exit + +_exit: + halt + ; 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 diff --git a/sw/z80/tests/pio/main.c b/sw/z80/tests/pio/main.c new file mode 100644 index 0000000..7ac64bc --- /dev/null +++ b/sw/z80/tests/pio/main.c @@ -0,0 +1,50 @@ +// #include "pio.h" + +#include <stdint.h> + +#define PIO_A_DATA 0x10 +#define PIO_B_DATA 0x11 +#define PIO_A_CMD 0x12 +#define PIO_B_CMD 0x13 + +void main(void) +{ + __asm + ;; output variable + ld h, #0x00 + + ;; set bit mode + ld c, #PIO_B_CMD + + ld a, #0xCF + out (c), a + + ;; set all pins to output + ld a, #0x00 + out (c), a + + ;; disable interrupts + ld a, #0x0C + out (c), a + + ;; load data addr + ld c, #PIO_B_DATA +loop: + out (c), h + ld a, h + + cpl + ld h, a + jr loop + __endasm; + + // uint8_t i = 0; + + // pio_set_mode(PIO_A, PIO_MODE_BIT_IO, 0x00); + // pio_set_interrupts(PIO_A, PIO_INT_DISABLE); + + // while (1) { + // pio_write(PIO_A, i); + // i = ~i; + // } +}
\ No newline at end of file diff --git a/sw/z80/tests/pio/makefile b/sw/z80/tests/pio/makefile new file mode 100644 index 0000000..1213902 --- /dev/null +++ b/sw/z80/tests/pio/makefile @@ -0,0 +1,72 @@ +#### +# source code settings +# +OSNAME := pio_test + +CSOURCES := $(wildcard *.c) +LIBS := ../../arch/build/arch.a \ + ../../drivers/build/drivers.a + +OBJECTS := $(patsubst %.c,build/%.rel,$(CSOURCES)) +HEXFILE := build/$(OSNAME).hex +BINARY := build/$(OSNAME).bin + +### +# compiler settings +# +CC := sdcc + +CFLAGS := -mz80 \ + --no-std-crt0 build/crt0.rel \ + --allow-unsafe-read \ + -I . \ + -I ../../arch/include \ + -I ../../drivers/include \ + -DDEBUG + +LDFLAGS := -mz80 \ + --no-std-crt0 build/crt0.rel \ + -L ../../drivers/build \ + -l drivers.a \ + -pedantic \ + --code-loc 0x0200 + # --data-loc 0x2000 + +.PHONY: flash dirs dis clean +all: $(BINARY) + +flash: $(BINARY) + minipro -p M28C64 -w $< + +# build binary +$(BINARY): $(OBJECTS) dirs + $(CC) $(LDFLAGS) $(OBJECTS) -o $(HEXFILE) + makebin -s 8192 -yo 1 $(HEXFILE) $(BINARY) + +$(OBJECTS): build/%.rel : %.c $(CSOURCES) dirs build/crt0.rel $(LIBS) + @printf "\n" + $(CC) $(CFLAGS) -c $< -o $@ + +$(LIBS): %.a: + @printf "\n" + make -C $(shell printf $@ | sed 's:build.*.::') + +build/crt0.rel: crt0.s + sdasz80 -o $< + @mv crt0.rel build/ + +dirs: + mkdir -p build + +dis: $(BINARY) + dz80 -b -n -t $(BINARY) + r2 -a z80 $< \ + -c 'afn main 0x200; \ + pd 0x10; \ + s 0x100; \ + pd 10; \ + s 0x200; \ + pd 0x95' | tee build/dis.txt + +clean: + - rm -rd build diff --git a/sw/z80/tests/ram/crt0.s b/sw/z80/tests/ram/crt0.s new file mode 100644 index 0000000..b0caa8c --- /dev/null +++ b/sw/z80/tests/ram/crt0.s @@ -0,0 +1,40 @@ + .module crt0 + .area _HEADER (ABS) + +;; Reset vectors + .org 0 + jp init + + .org 0x38 ; the instruction 0xff (not written) resets to this location + jp init + +;; main code + .org 0x100 + .globl _main + +init: + ;; Set stack pointer directly above top of memory. + ld sp,#0xffff + + ;; Start of the program + call _main + jp _exit + +_exit: + halt + 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
\ No newline at end of file diff --git a/sw/z80/tests/ram/main.c b/sw/z80/tests/ram/main.c new file mode 100644 index 0000000..581072b --- /dev/null +++ b/sw/z80/tests/ram/main.c @@ -0,0 +1,13 @@ + +void main(void) +{ + unsigned char j; + unsigned char *mem; + + j = 0; + mem = (unsigned char *) 0x8200; // somwhere in ram + + while (1) { + *mem = j++; + } +} diff --git a/sw/z80/tests/ram/makefile b/sw/z80/tests/ram/makefile new file mode 100644 index 0000000..f8eb9fc --- /dev/null +++ b/sw/z80/tests/ram/makefile @@ -0,0 +1,54 @@ +#### +# source code settings +# +OSNAME := ram_test + +CSOURCES := $(wildcard *.c) + +OBJECTS := $(patsubst %.c,build/%.rel,$(CSOURCES)) +HEXFILE := build/$(OSNAME).hex +BINARY := build/$(OSNAME).bin + +### +# compiler settings +# +CC := sdcc + +CFLAGS := -mz80 \ + -I . \ + -DDEBUG + +LDFLAGS := -mz80 \ + --no-std-crt0 build/crt0.rel \ + -pedantic + + # --code-loc 0x0120 \ + # --data-loc 0x2000 + +.PHONY: flash dirs dis clean +all: $(BINARY) + +flash: $(BINARY) + minipro -p M28C64 -w $< + +# build binary +$(BINARY): $(OBJECTS) dirs + $(CC) $(LDFLAGS) $(OBJECTS) -o $(HEXFILE) + makebin -s 8192 -yo 1 $(HEXFILE) $(BINARY) + +$(OBJECTS): build/%.rel : %.c $(CSOURCES) dirs build/crt0.rel + @printf "\n" + $(CC) $(CFLAGS) -c $< -o $@ + +build/crt0.rel: crt0.s + sdasz80 -o $< + @mv crt0.rel build/ + +dirs: + mkdir -p build + +dis: $(BINARY) + r2 -a z80 $< -c 'pd 0x10; s 0x100; pd 10; s 0x200; pd 10' + +clean: + - rm -rd build diff --git a/sw/z80/tests/usart/crt0.s b/sw/z80/tests/usart/crt0.s new file mode 100644 index 0000000..c900065 --- /dev/null +++ b/sw/z80/tests/usart/crt0.s @@ -0,0 +1,38 @@ + .module crt0 + .area _HEADER (ABS) + +;; Reset vectors + .org 0 + jp init + + .org 0x38 ; the instruction 0xff (not written) resets to this location + jp init + +;; main code + .org 0x100 + .globl _main + +init: + ;; Set stack pointer directly above top of memory. + ld sp,#0xffff + + ;; Start of the program + call _main + jp _exit + +_exit: + halt + ; 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 diff --git a/sw/z80/tests/usart/main.c b/sw/z80/tests/usart/main.c new file mode 100644 index 0000000..a905df2 --- /dev/null +++ b/sw/z80/tests/usart/main.c @@ -0,0 +1,11 @@ +#include "usart.h" +#include <stdint.h> + +void main(void) +{ + usart_init(USART_BAUDRATE_1200, USART_PARITY_NONE, USART_STOP_BITS_1); + + while (1) { + usart_write("Hello World!\n", 13); + } +} diff --git a/sw/z80/tests/usart/makefile b/sw/z80/tests/usart/makefile new file mode 100644 index 0000000..8aaf6b1 --- /dev/null +++ b/sw/z80/tests/usart/makefile @@ -0,0 +1,72 @@ +#### +# source code settings +# +OSNAME := usart_test + +CSOURCES := $(wildcard *.c) +LIBS := ../../arch/build/arch.a \ + ../../drivers/build/drivers.a + +OBJECTS := $(patsubst %.c,build/%.rel,$(CSOURCES)) +HEXFILE := build/$(OSNAME).hex +BINARY := build/$(OSNAME).bin + +### +# compiler settings +# +CC := sdcc + +CFLAGS := -mz80 \ + --no-std-crt0 build/crt0.rel \ + --allow-unsafe-read \ + -I . \ + -I ../../arch/include \ + -I ../../drivers/include \ + -DDEBUG + +LDFLAGS := -mz80 \ + --no-std-crt0 build/crt0.rel \ + -L ../../drivers/build \ + -l drivers.a \ + -pedantic \ + --code-loc 0x0200 + # --data-loc 0x2000 + +.PHONY: flash dirs dis clean +all: $(BINARY) + +flash: $(BINARY) + minipro -p M28C64 -w $< + +# build binary +$(BINARY): $(OBJECTS) dirs + $(CC) $(LDFLAGS) $(OBJECTS) -o $(HEXFILE) + makebin -s 8192 -yo 1 $(HEXFILE) $(BINARY) + +$(OBJECTS): build/%.rel : %.c $(CSOURCES) dirs build/crt0.rel $(LIBS) + @printf "\n" + $(CC) $(CFLAGS) -c $< -o $@ + +$(LIBS): %.a: + @printf "\n" + make -C $(shell printf $@ | sed 's:build.*.::') + +build/crt0.rel: crt0.s + sdasz80 -o $< + @mv crt0.rel build/ + +dirs: + mkdir -p build + +dis: $(BINARY) + dz80 -b -n -t $(BINARY) + r2 -a z80 $< \ + -c 'afn main 0x200; \ + pd 0x10; \ + s 0x100; \ + pd 10; \ + s 0x200; \ + pd 0x95' + +clean: + - rm -rd build |