summaryrefslogtreecommitdiffstats
path: root/sw/z80
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/coding_rules.txt (renamed from sw/z80/coding_rules.txt)0
-rw-r--r--sw/z80/TODO.txt1
-rw-r--r--sw/z80/arch/include/addresses.h15
-rw-r--r--sw/z80/arch/include/sleep.h14
-rw-r--r--sw/z80/arch/makefile27
-rw-r--r--sw/z80/arch/sleep.c16
-rw-r--r--sw/z80/build/helvetiOS.lk11
-rw-r--r--sw/z80/build/helvetiOS.map182
-rw-r--r--sw/z80/build/helvetiOS.noi50
-rw-r--r--sw/z80/build/kernel/kernel.asm65
-rw-r--r--sw/z80/build/kernel/kernel.lst65
-rw-r--r--sw/z80/build/kernel/kernel.rel23
-rw-r--r--sw/z80/build/kernel/kernel.sym27
-rw-r--r--sw/z80/crt0.rel86
-rw-r--r--sw/z80/drivers/ctc.c6
-rw-r--r--sw/z80/drivers/include/ctc.h6
-rw-r--r--sw/z80/drivers/include/pio.h52
-rw-r--r--sw/z80/drivers/include/usart.h158
-rw-r--r--sw/z80/drivers/makefile24
-rw-r--r--sw/z80/drivers/pio.c84
-rw-r--r--sw/z80/drivers/usart.c (renamed from sw/z80/kernel/usart.c)2
-rw-r--r--sw/z80/kernel/boot_loader.c24
-rw-r--r--sw/z80/kernel/crt0.s (renamed from sw/z80/crt0.s)0
-rw-r--r--sw/z80/kernel/fs/fd.c255
-rw-r--r--sw/z80/kernel/fs/fs.c236
-rw-r--r--sw/z80/kernel/include/boot.h35
-rw-r--r--sw/z80/kernel/include/devices.h2
-rw-r--r--sw/z80/kernel/include/errno.h35
-rw-r--r--sw/z80/kernel/include/fs/dev.h29
-rw-r--r--sw/z80/kernel/include/fs/dirent.h17
-rw-r--r--sw/z80/kernel/include/fs/fd.h102
-rw-r--r--sw/z80/kernel/include/fs/fdop.h140
-rw-r--r--sw/z80/kernel/include/fs/fs.h63
-rw-r--r--sw/z80/kernel/include/fs/iter.h17
-rw-r--r--sw/z80/kernel/include/fs/users.h21
-rw-r--r--sw/z80/kernel/include/memory.h50
-rw-r--r--sw/z80/kernel/include/pio.h35
-rw-r--r--sw/z80/kernel/include/process.h43
-rw-r--r--sw/z80/kernel/include/progman.h85
-rw-r--r--sw/z80/kernel/include/sio.h43
-rw-r--r--sw/z80/kernel/include/stat.h24
-rw-r--r--sw/z80/kernel/include/types.h61
-rw-r--r--sw/z80/kernel/include/usart.h149
-rw-r--r--sw/z80/kernel/makefile (renamed from sw/z80/makefile)28
-rw-r--r--sw/z80/kernel/memory.c94
-rw-r--r--sw/z80/kernel/pio.c18
-rw-r--r--sw/z80/kernel/process.c58
-rw-r--r--sw/z80/kernel/programs.c137
-rw-r--r--sw/z80/libc/include/stdint.h13
-rw-r--r--sw/z80/libc/include/stdlib.h7
-rw-r--r--sw/z80/libc/include/types.h60
-rw-r--r--sw/z80/libc/string.c20
-rw-r--r--sw/z80/tests/asm/main.s40
-rw-r--r--sw/z80/tests/asm/makefile47
-rw-r--r--sw/z80/tests/pio/crt0.s38
-rw-r--r--sw/z80/tests/pio/main.c50
-rw-r--r--sw/z80/tests/pio/makefile72
-rw-r--r--sw/z80/tests/ram/crt0.s40
-rw-r--r--sw/z80/tests/ram/main.c13
-rw-r--r--sw/z80/tests/ram/makefile54
-rw-r--r--sw/z80/tests/usart/crt0.s38
-rw-r--r--sw/z80/tests/usart/main.c11
-rw-r--r--sw/z80/tests/usart/makefile72
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