From 1eba55156d0c74752ccd3a8fd131a25ffa5a13b8 Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Sat, 25 Mar 2017 10:10:24 +0100
Subject: added missing makefile for z80 and fixed gitignore

---
 sw/z80/makefile | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 sw/z80/makefile

(limited to 'sw/z80')

diff --git a/sw/z80/makefile b/sw/z80/makefile
new file mode 100644
index 0000000..94646a9
--- /dev/null
+++ b/sw/z80/makefile
@@ -0,0 +1,27 @@
+####
+# source code settings
+#
+OSNAME := helvetiOS
+
+CSOURCES 	:= $(wildcard *.c)
+BINARY  	:= $(OSNAME).bin
+
+### 
+# compiler settings
+#
+CC 		:= zcc
+CARGS 	:= -Wall -I . -DDEBUG -crt0 loader -asm z80asm -nostdlib
+
+all: $(BINARY)
+
+# build binary
+$(BINARY): $(CSOURCES)
+	cp loader.asm loader.opt
+	$(CC) $(CARGS) $(CSOURCES) -o $@
+
+dis: $(BINARY)
+	z80dasm -a -g 0h $<
+
+clean:
+	- rm $(BINARY)
+	- rm loader.opt
-- 
cgit v1.2.1


From 1ec8f14f03322e3fe1f56f4abcbc85f5c2934dfc Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Tue, 2 May 2017 16:14:41 +0200
Subject: fix for sdcc makefile

fix for the old makefile, because it could't compile more than one source file.
new libc directory with mem.c to start implementing the standard  C library
(or at least the part we need).
---
 sw/z80/crt0.s                 | 125 +++++++++++++++++++++++++++++++++---------
 sw/z80/kernel/include/types.h |   2 +
 sw/z80/libc/mem.c             |   7 +++
 sw/z80/makefile               |  20 +++++--
 4 files changed, 122 insertions(+), 32 deletions(-)
 create mode 100644 sw/z80/libc/mem.c

(limited to 'sw/z80')

diff --git a/sw/z80/crt0.s b/sw/z80/crt0.s
index d0ae3ca..7701ca6 100644
--- a/sw/z80/crt0.s
+++ b/sw/z80/crt0.s
@@ -1,30 +1,103 @@
-    .area _HEADER (ABS)
-    ;; reset vector
-    .org 0
-    jp init
-    
-    .org 0x08
-    reti
-    .org 0x10
-    reti
-    .org 0x18
-    reti
-    .org 0x20
-    reti
-    .org 0x28
-    reti
-    .org 0x30
-    reti
-    .org 0x38
-    reti
-
-    .org 0x100
+;--------------------------------------------------------------------------
+;  crt0.s - Generic crt0.s for a Z80
+;
+;  Copyright (C) 2000, Michael Hope
+;
+;  This library is free software; you can redistribute it and/or modify it
+;  under the terms of the GNU General Public License as published by the
+;  Free Software Foundation; either version 2, or (at your option) any
+;  later version.
+;
+;  This library is distributed in the hope that it will be useful,
+;  but WITHOUT ANY WARRANTY; without even the implied warranty of
+;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;  GNU General Public License for more details.
+;
+;  You should have received a copy of the GNU General Public License 
+;  along with this library; see the file COPYING. If not, write to the
+;  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+;   MA 02110-1301, USA.
+;
+;  As a special exception, if you link this library with other files,
+;  some of which are compiled with SDCC, to produce an executable,
+;  this library does not by itself cause the resulting executable to
+;  be covered by the GNU General Public License. This exception does
+;  not however invalidate any other reasons why the executable file
+;   might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
 
+	.module crt0
+	.globl	_main
+
+	.area	_HEADER (ABS)
+	;; Reset vector
+	.org 	0
+	jp	init
+
+	.org	0x08
+	reti
+	.org	0x10
+	reti
+	.org	0x18
+	reti
+	.org	0x20
+	reti
+	.org	0x28
+	reti
+	.org	0x30
+	reti
+	.org	0x38
+	reti
+
+	.org	0x100
 init:
-    ;; set stack
-    ld sp,#0xFFFF
+	;; Set stack pointer directly above top of memory.
+	ld	sp,#0xFFFF
+
+	;; Initialise global variables
+	call	gsinit
+	call	_main
+	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
+
+__clock::
+	ld	a,#2
+	rst	0x08
+	ret
+
+_exit::
+	;; Exit - special code to the emulator
+	ld	a,#0
+	rst	0x08
+1$:
+	halt
+	jr	1$
+
+	.area   _GSINIT
+gsinit::
+	; ld	bc, #l__INITIALIZER
+	ld	a, b
+	or	a, c
+	jr	Z, gsinit_next
+	; ld	de, #s__INITIALIZED
+	; ld	hl, #s__INITIALIZER
+	ldir
+gsinit_next:
 
-    ;; call C main function
-    call _main
+	.area   _GSFINAL
+	ret
 
-.globl _main
diff --git a/sw/z80/kernel/include/types.h b/sw/z80/kernel/include/types.h
index adde214..c24b311 100644
--- a/sw/z80/kernel/include/types.h
+++ b/sw/z80/kernel/include/types.h
@@ -6,4 +6,6 @@
 #define int16_t     int
 #define uint16_t    unsigned int
 
+#define size_t      uint16_t
+
 #endif
diff --git a/sw/z80/libc/mem.c b/sw/z80/libc/mem.c
new file mode 100644
index 0000000..667a752
--- /dev/null
+++ b/sw/z80/libc/mem.c
@@ -0,0 +1,7 @@
+#include "types.h"
+#include "mem.h"
+
+void *malloc(size_t size)
+{
+    :
+}
diff --git a/sw/z80/makefile b/sw/z80/makefile
index ecdd9a4..3d682ca 100644
--- a/sw/z80/makefile
+++ b/sw/z80/makefile
@@ -4,6 +4,7 @@
 OSNAME := helvetiOS
  
 CSOURCES 	:= $(wildcard kernel/*.c) $(wildcard libc/*.c)
+OBJECTS 	:= $(patsubst %.c,build/%.rel,$(CSOURCES))
 HEXFILE		:= build/$(OSNAME).hex
 BINARY  	:= build/$(OSNAME).bin
 
@@ -12,26 +13,33 @@ BINARY  	:= build/$(OSNAME).bin
 
 CC 		:= sdcc
 
-CFLAGS	:= -mz80 --no-std-crt0 crt0.rel \
+CFLAGS	:= -mz80 \
 			-I kernel/include -I libc/include -DDEBUG
 
-LDFLAGS := --code-loc 0x0800 --data-loc 0x8000
+LDFLAGS := -mz80 --no-std-crt0 crt0.rel \
+			--code-loc 0x0800 --data-loc 0x8000
 
+.PHONY: dirs dis clean
 all: $(BINARY)
 
 # build binary
-$(BINARY): $(CSOURCES) crt0.rel
-	mkdir -p build
-	$(CC) $(CFLAGS) $(LDFLSGS) $(CSOURCES) -o $(HEXFILE)
+$(BINARY): $(OBJECTS) dirs
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $(HEXFILE)
 	xxd -r -p $(HEXFILE) $(BINARY)
 
+$(OBJECTS): build/%.rel : %.c $(CSOURCES) dirs crt0.rel
+	$(CC) $(CFLAGS) -c $< -o $@
+
 crt0.rel: crt0.s
 	sdasz80 -o $<
 
+dirs:
+	mkdir -p build build/kernel build/libc
+
 dis: $(BINARY)
 	z80dasm -a -g 0h $< -o $(OSNAME).s
 
 clean:
-	- rm build/*
+	- rm -rd build/*
 	- rm $(OSNAME).s
 	- rm crt0.rel
-- 
cgit v1.2.1


From 0b5b2c24c52281db0437320a22bced87043d4dfb Mon Sep 17 00:00:00 2001
From: "leleraffa97@hotmail.it" <leleraffa97@hotmail.it>
Date: Tue, 2 May 2017 17:12:23 +0200
Subject: Basic sys io setup

---
 sw/z80/sysio.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 sw/z80/sysio.h

(limited to 'sw/z80')

diff --git a/sw/z80/sysio.h b/sw/z80/sysio.h
new file mode 100644
index 0000000..5d1f5ae
--- /dev/null
+++ b/sw/z80/sysio.h
@@ -0,0 +1,55 @@
+#ifndef __SYSIO_H__
+#define __SYSIO_H__
+
+#include "types.h"
+
+/*
+* 	Memory management
+*/
+
+void * malloc(uint16_t size);
+uint16_t malloc_size(void * address);
+void free(void * address);
+
+/*
+*	File management
+*/
+
+#define F_WRITE "w"
+#define F_READ "r"
+#define F_BIN_WRITE "wb"
+#define F_BIN_READ "rb"
+
+#define F_READ_CODE 0x0
+#define F_WRITE_CODE 0x1
+#define F_BIN_READ_CODE 0x2
+#define F_BIN_WRITE_CODE 0x3
+
+#define F_PERM_READ 0x0
+#define F_PERM_WRITE 0x1
+#define F_PERM_RW 0x2
+
+struct file {
+
+	const char * path;
+	unsigned int mode:4;
+	unsigned int permission:4;
+};
+
+#define FILE struct file
+
+FILE * fopen(const char * path, const char * mode);
+uint8_t fclose(FILE * file);
+
+// TODO: other functions
+
+/*
+*	Processes management
+*/
+
+#define PID uint16_t
+
+void exit();	// exit this program
+void interrupt(PID)
+
+#endif
\ No newline at end of file
-- 
cgit v1.2.1


From 100226618493b6a3c7da96048734d50f5011a01f Mon Sep 17 00:00:00 2001
From: "leleraffa97@hotmail.it" <leleraffa97@hotmail.it>
Date: Tue, 2 May 2017 18:11:33 +0200
Subject: sysio.h libc interface

---
 sw/z80/libc/include/sysio.h | 55 +++++++++++++++++++++++++++++++++++++++++++++
 sw/z80/sysio.h              | 55 ---------------------------------------------
 2 files changed, 55 insertions(+), 55 deletions(-)
 create mode 100644 sw/z80/libc/include/sysio.h
 delete mode 100644 sw/z80/sysio.h

(limited to 'sw/z80')

diff --git a/sw/z80/libc/include/sysio.h b/sw/z80/libc/include/sysio.h
new file mode 100644
index 0000000..5d1f5ae
--- /dev/null
+++ b/sw/z80/libc/include/sysio.h
@@ -0,0 +1,55 @@
+#ifndef __SYSIO_H__
+#define __SYSIO_H__
+
+#include "types.h"
+
+/*
+* 	Memory management
+*/
+
+void * malloc(uint16_t size);
+uint16_t malloc_size(void * address);
+void free(void * address);
+
+/*
+*	File management
+*/
+
+#define F_WRITE "w"
+#define F_READ "r"
+#define F_BIN_WRITE "wb"
+#define F_BIN_READ "rb"
+
+#define F_READ_CODE 0x0
+#define F_WRITE_CODE 0x1
+#define F_BIN_READ_CODE 0x2
+#define F_BIN_WRITE_CODE 0x3
+
+#define F_PERM_READ 0x0
+#define F_PERM_WRITE 0x1
+#define F_PERM_RW 0x2
+
+struct file {
+
+	const char * path;
+	unsigned int mode:4;
+	unsigned int permission:4;
+};
+
+#define FILE struct file
+
+FILE * fopen(const char * path, const char * mode);
+uint8_t fclose(FILE * file);
+
+// TODO: other functions
+
+/*
+*	Processes management
+*/
+
+#define PID uint16_t
+
+void exit();	// exit this program
+void interrupt(PID)
+
+#endif
\ No newline at end of file
diff --git a/sw/z80/sysio.h b/sw/z80/sysio.h
deleted file mode 100644
index 5d1f5ae..0000000
--- a/sw/z80/sysio.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __SYSIO_H__
-#define __SYSIO_H__
-
-#include "types.h"
-
-/*
-* 	Memory management
-*/
-
-void * malloc(uint16_t size);
-uint16_t malloc_size(void * address);
-void free(void * address);
-
-/*
-*	File management
-*/
-
-#define F_WRITE "w"
-#define F_READ "r"
-#define F_BIN_WRITE "wb"
-#define F_BIN_READ "rb"
-
-#define F_READ_CODE 0x0
-#define F_WRITE_CODE 0x1
-#define F_BIN_READ_CODE 0x2
-#define F_BIN_WRITE_CODE 0x3
-
-#define F_PERM_READ 0x0
-#define F_PERM_WRITE 0x1
-#define F_PERM_RW 0x2
-
-struct file {
-
-	const char * path;
-	unsigned int mode:4;
-	unsigned int permission:4;
-};
-
-#define FILE struct file
-
-FILE * fopen(const char * path, const char * mode);
-uint8_t fclose(FILE * file);
-
-// TODO: other functions
-
-/*
-*	Processes management
-*/
-
-#define PID uint16_t
-
-void exit();	// exit this program
-void interrupt(PID)
-
-#endif
\ No newline at end of file
-- 
cgit v1.2.1


From 8a461a14c3ceaf42f1483abe51cda47ac785bfc9 Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Tue, 2 May 2017 22:09:40 +0200
Subject: add serial device struct

other changes:
  - change from main() to kmain() in crt0.s and kernel.c
  - new file devices.h to define all address locations for devices
  - new data type
      - register_t as volatile uint8_t for registers in devices
      - size_t from libc
---
 sw/z80/crt0.s                   |  4 +-
 sw/z80/kernel/include/devices.h | 13 +++++++
 sw/z80/kernel/include/serial.h  | 85 +++++++++++++++++++++++++++++++++++++++++
 sw/z80/kernel/include/types.h   |  2 +
 sw/z80/kernel/kernel.c          |  7 +---
 sw/z80/libc/mem.c               |  7 ----
 6 files changed, 104 insertions(+), 14 deletions(-)
 create mode 100644 sw/z80/kernel/include/devices.h
 create mode 100644 sw/z80/kernel/include/serial.h
 delete mode 100644 sw/z80/libc/mem.c

(limited to 'sw/z80')

diff --git a/sw/z80/crt0.s b/sw/z80/crt0.s
index 7701ca6..00c7da1 100644
--- a/sw/z80/crt0.s
+++ b/sw/z80/crt0.s
@@ -27,7 +27,7 @@
 ;--------------------------------------------------------------------------
 
 	.module crt0
-	.globl	_main
+	.globl	_kmain
 
 	.area	_HEADER (ABS)
 	;; Reset vector
@@ -56,7 +56,7 @@ init:
 
 	;; Initialise global variables
 	call	gsinit
-	call	_main
+	call	_kmain
 	jp	    _exit
 
 	;; Ordering of segments for the linker.
diff --git a/sw/z80/kernel/include/devices.h b/sw/z80/kernel/include/devices.h
new file mode 100644
index 0000000..ea29065
--- /dev/null
+++ b/sw/z80/kernel/include/devices.h
@@ -0,0 +1,13 @@
+#ifndef __DEVICES_H__
+#define __DEVICES_H__
+
+#define ADDR_DEV_ROM_L      0x0000
+#define ADDR_DEV_ROM_H      0x2000
+
+#define ADDR_DEV_USART   0x4000
+#define ADDR_DEV_CTC     
+#define ADDR_DEV_PIO
+
+#define ADDR_DEV_RAM        0x8000
+
+#endif
diff --git a/sw/z80/kernel/include/serial.h b/sw/z80/kernel/include/serial.h
new file mode 100644
index 0000000..03e2448
--- /dev/null
+++ b/sw/z80/kernel/include/serial.h
@@ -0,0 +1,85 @@
+#ifndef __SERIAL_H__
+#define __SERIAL_H__
+
+#include "types.h"
+#include "devices.h"
+
+/* 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;
+    }
+
+    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_register :1;
+        volatile int transmitter_emtpy :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;
+} *_usart = (_usart_device *) ADDR_DEV_USART;
+
+
+#endif // __SERIAL__H__
diff --git a/sw/z80/kernel/include/types.h b/sw/z80/kernel/include/types.h
index c24b311..552b7e9 100644
--- a/sw/z80/kernel/include/types.h
+++ b/sw/z80/kernel/include/types.h
@@ -1,6 +1,8 @@
 #ifndef __TYPES_H__
 #define __TYPES_H__
 
+#define register_t  volatile unsigned char
+
 #define int8_t      char
 #define uint8_t     unsigned char
 #define int16_t     int
diff --git a/sw/z80/kernel/kernel.c b/sw/z80/kernel/kernel.c
index fe87c3d..3db6579 100644
--- a/sw/z80/kernel/kernel.c
+++ b/sw/z80/kernel/kernel.c
@@ -1,10 +1,7 @@
 #include "types.h"
 
 
-void main(void)
+void kmain(void)
 {
-    int i, j = 20;
-    for (i = 0; i < 10; i++) {
-        j--;
-    }
+    
 }
diff --git a/sw/z80/libc/mem.c b/sw/z80/libc/mem.c
deleted file mode 100644
index 667a752..0000000
--- a/sw/z80/libc/mem.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "types.h"
-#include "mem.h"
-
-void *malloc(size_t size)
-{
-    :
-}
-- 
cgit v1.2.1


From 616143a55b8802714a457086beaa2788d1d48058 Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Wed, 3 May 2017 22:36:18 +0200
Subject: new file coding_rules.txt to have a consistent coding style

---
 sw/z80/coding_rules.txt | 120 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)
 create mode 100644 sw/z80/coding_rules.txt

(limited to 'sw/z80')

diff --git a/sw/z80/coding_rules.txt b/sw/z80/coding_rules.txt
new file mode 100644
index 0000000..e5c11f0
--- /dev/null
+++ b/sw/z80/coding_rules.txt
@@ -0,0 +1,120 @@
+CODING STYLE FOR THIS PROJECT
+=============================
+
+In order to have a consistent codebase, there are the following rules on
+writing code in C (and assembly). For the most part they are similar to the
+Linux kernel coding rules by Torvalds.
+
+PROGRAM LOGIC
+-------------
+I expect a certain level of common sense from people so I won't mention the
+super-basic stuff. But I would like to point out a few thing I WON'T accept
+(unless there is a valid reason and an explanation of why).  First, I believe
+that code has to be aesthetically pleasing to watch and with a clear logic
+flow so:
+
+    - Avoid deeply nested code and recursive black magic
+
+    - No special cases: generally the code of a function should behave the
+      same with any argument. Avoid horrible exceptions for magic values
+
+    - No extreme modularization: do not write code that is extremely
+      encapsulated with dozens of helper functions to control every signal
+      that runs through the damn motherboard
+
+EDITOR (SPACES > TABS)
+----------------------
+You can use your favourite editor but spaces are better than tabs, no
+discussion. For this project every source file must have an indent of 4
+spaces. Since 80 characters is the standard terminal width, the code has to be
+hard wrapped at 80, 78 or 72 characters. Also there shouldn't be any markup on
+the source code for your editor, not even in the comments; just the code.
+
+    - use spaces, 1 indent - 4 spaces
+    - hard wrap at 80 / 78 / 72 characters
+    - no markup for folds or any other editor specific feature
+    
+
+C CODE INDENT AND BRACES
+------------------------
+I personally prefer the K&R coding style because it was used in 'The C
+Programming Language' book from Dennis Ritchie which is the 'standard' for
+learning C. But I also like Linus' kernel coding rules, so sometimes I might
+use some of his rules. Anyway, you can look them up if you want to or just
+look at the following example that sums most of the important stuff.
+
+    - K&R braces and function prototypes
+    - snake_case for variables and function names
+    - pointer asterisk in front of the variable ( ex: int *p; )
+
+Here's a short example that uses most of the stuff:
+
+    #include <stdio.h>
+    #include <stdlib.h>
+    
+    #define MY_DEVICE_MEMORY_ADDR   0x5020
+
+    #define MY_DEVICE_FLAG_RDY      1
+    #define MY_DEVICE_FLAG_ERR      2
+
+    // same for unions
+    struct my_device
+    {
+        volatile uint8_t buffer;
+        volatile uint8_t flags;
+    } *_my_dev = (struct my_device *) MY_DEVICE_MEMORY_ADDR;
+
+    
+    int my_device_write(uint8_t *data, size_t size);
+
+    /* This is the main function
+     * and this is a multiline comment to explain something if needed
+     */
+    int main(int argc, char *argv[])
+    {
+        int i;
+        int j = 0;
+        uint8_t data[2] = { 0xFF, 0xAB };
+        const char *string = "My magic string";
+
+        while (j < 100) {
+            j++;
+        }
+
+        printf("%s\n", string);
+
+        if (some_condition) {
+            // inline comment
+        } else {
+            my_device_write(data, 2);
+        }
+
+        switch (i) {
+        case 0:
+            some_function();
+            break;
+
+        case 1:
+            // ...
+            break;
+
+        default:
+            // ...
+        }
+    }
+
+    int my_device_write(uint8_t *data, size_t size) 
+    {
+        int i;
+
+        for (i = 0; i < size; i++) {
+            _my_dev.buffer = data;
+            while (!(_my_dev.flags & (1<<MY_DEVICE_FLAG_RDY)));
+
+            if (_my_dev.flags &  (1<<MY_DEVICE_FLAG_ERR)) {
+                return -1;
+            }
+        }
+
+        return i;
+    }
-- 
cgit v1.2.1


From 4a7f45ee28ac0799ba1ca93fd1683f7858efc54a Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Fri, 2 Jun 2017 16:22:26 +0200
Subject: add serial interface and a few std library functions

changes in usart:
  - new functions to setup the serial comunication settings such as baudrate,
    parity and stop bits
  - init function with most common values
  - transmit and receive functions each with a wrapper to send data blocks

changes in libc:
  - new file stdio.c with basic implementation of putch, printf still a prototype
  - new file string.c with memcpy() function
---
 sw/z80/kernel/include/devices.h |   6 +-
 sw/z80/kernel/include/pio.h     |  18 +++++
 sw/z80/kernel/include/serial.h  |  85 -----------------------
 sw/z80/kernel/include/usart.h   | 149 ++++++++++++++++++++++++++++++++++++++++
 sw/z80/kernel/kernel.c          |   4 +-
 sw/z80/kernel/pio.c             |  29 ++++++++
 sw/z80/kernel/usart.c           |  91 ++++++++++++++++++++++++
 sw/z80/libc/include/stdio.h     |  11 +++
 sw/z80/libc/include/string.h    |   8 +++
 sw/z80/libc/stdio.c             |  12 ++++
 sw/z80/libc/string.c            |  13 ++++
 11 files changed, 336 insertions(+), 90 deletions(-)
 create mode 100644 sw/z80/kernel/include/pio.h
 delete mode 100644 sw/z80/kernel/include/serial.h
 create mode 100644 sw/z80/kernel/include/usart.h
 create mode 100644 sw/z80/kernel/pio.c
 create mode 100644 sw/z80/kernel/usart.c
 create mode 100644 sw/z80/libc/include/stdio.h
 create mode 100644 sw/z80/libc/include/string.h
 create mode 100644 sw/z80/libc/stdio.c
 create mode 100644 sw/z80/libc/string.c

(limited to 'sw/z80')

diff --git a/sw/z80/kernel/include/devices.h b/sw/z80/kernel/include/devices.h
index ea29065..e8c183f 100644
--- a/sw/z80/kernel/include/devices.h
+++ b/sw/z80/kernel/include/devices.h
@@ -4,9 +4,9 @@
 #define ADDR_DEV_ROM_L      0x0000
 #define ADDR_DEV_ROM_H      0x2000
 
-#define ADDR_DEV_USART   0x4000
-#define ADDR_DEV_CTC     
-#define ADDR_DEV_PIO
+#define ADDR_DEV_USART      0x4000
+#define ADDR_DEV_CTC        0x4100
+#define ADDR_DEV_PIO        0x4200
 
 #define ADDR_DEV_RAM        0x8000
 
diff --git a/sw/z80/kernel/include/pio.h b/sw/z80/kernel/include/pio.h
new file mode 100644
index 0000000..8d72ab0
--- /dev/null
+++ b/sw/z80/kernel/include/pio.h
@@ -0,0 +1,18 @@
+#ifndef __PIO_H__
+#define __PIO_H__
+
+#define PIO_A   0
+#define PIO_B   1
+
+
+void pio_data(int port, uint8_t data);
+void pio_command(int port, uint8_t cmd);
+
+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/serial.h b/sw/z80/kernel/include/serial.h
deleted file mode 100644
index 03e2448..0000000
--- a/sw/z80/kernel/include/serial.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __SERIAL_H__
-#define __SERIAL_H__
-
-#include "types.h"
-#include "devices.h"
-
-/* 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;
-    }
-
-    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_register :1;
-        volatile int transmitter_emtpy :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;
-} *_usart = (_usart_device *) ADDR_DEV_USART;
-
-
-#endif // __SERIAL__H__
diff --git a/sw/z80/kernel/include/usart.h b/sw/z80/kernel/include/usart.h
new file mode 100644
index 0000000..f1f428e
--- /dev/null
+++ b/sw/z80/kernel/include/usart.h
@@ -0,0 +1,149 @@
+#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_stob_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/kernel/kernel.c b/sw/z80/kernel/kernel.c
index 3db6579..3d5aeb6 100644
--- a/sw/z80/kernel/kernel.c
+++ b/sw/z80/kernel/kernel.c
@@ -1,7 +1,7 @@
 #include "types.h"
-
+#include "usart.h"
 
 void kmain(void)
 {
-    
+    usart_init(USART_BAUDRATE_9600, USART_PARITY_EVEN, USART_STOP_BITS_1);
 }
diff --git a/sw/z80/kernel/pio.c b/sw/z80/kernel/pio.c
new file mode 100644
index 0000000..e8c7e24
--- /dev/null
+++ b/sw/z80/kernel/pio.c
@@ -0,0 +1,29 @@
+#include "pio.h"
+
+static uint8_t *pio_port_a = (uint8_t *) ADDR_DEV_PIO;
+static uint8_t *pio_port_b = (uint8_t *) ADDR_DEV_PIO + 1;
+static uint8_t *pio_ctrl_a = (uint8_t *) ADDR_DEV_PIO + 2;
+static uint8_t *pio_ctrl_b = (uint8_t *) ADDR_DEV_PIO + 3;
+
+void pio_data(int port, uint8_t data)
+{
+    if (port == PIO_A)
+        *pio_port_a = cmd;
+    else
+        *pio_port_b = cmd;
+}
+
+void pio_command(int port, uint8_t cmd)
+{
+    if (port == PIO_A)
+        *pio_ctrl_a = cmd;
+    else
+        *pio_ctrl_b = cmd;
+}
+
+
+
+inline int pio_read_pin(int port, uint8_t pin)
+{
+
+}
diff --git a/sw/z80/kernel/usart.c b/sw/z80/kernel/usart.c
new file mode 100644
index 0000000..4c2fdaf
--- /dev/null
+++ b/sw/z80/kernel/usart.c
@@ -0,0 +1,91 @@
+#include "usart.h"
+
+static struct _usart_device *_usart = (struct _usart_device *) ADDR_DEV_USART;
+
+void usart_set_baudrate(uint16_t baudrate)
+{
+    // enable latch access
+    _usart->LCR.divisor_latch_access = 1;
+    _usart->buffer = 0x00FF & baudrate; // LSBs
+    memcpy(&_usart->IER, &(baudrate >>8), 1);
+    // _usart->IER    = 0x00FF & (baudrate >> 8); // MSBs
+    _usart->LCR.divisor_latch_access = 0;
+}
+
+void usart_set_parity(int mode)
+{
+    if (mode == USART_PARITY_EVEN) {
+        _usart->LCR.even_parity = 1;
+    }
+    else if (mode == USART_PARITY_ODD) {
+        _usart->LCR.even_parity = 0;
+    }
+
+     _usart->LCR.parity = (mode == USART_PARITY_NONE) ? 0 : 1;
+}
+
+void usart_set_stop_bits(int count)
+{
+    _usart->LCR.stop_bits = (count == USART_STOP_BITS_1) ? 0 : 1;
+}
+
+void usart_word_length(int length)
+{
+    _usart->LCR.word_length = length;
+}
+
+void usart_set_autoflow(int mode)
+{
+    _usart->MCR.autoflow = (mode == USART_AUTOFLOW_OFF) ? 0 : 1;
+    _usart->MCR.data_terminal_ready = (mode == USART_AUTOFLOW_ALL);
+}
+
+inline void usart_init(uint16_t baudrate, int parity, int stop_bits)
+{
+    usart_set_baudrate(baudrate);
+    usart_set_parity(parity);
+    usart_set_stop_bits(stop_bits);
+    usart_set_autoflow(USART_AUTOFLOW_OFF);
+}
+
+void usart_transmit(uint8_t data)
+{
+    _usart->buffer = data;
+    while (_usart->LSR.transmitter_holder_empty == 0); // wait
+}
+
+uint8_t usart_receive()
+{
+    return _usart->buffer;
+}
+
+int usart_write(uint8_t *data, size_t size)
+{
+    uint8_t *dp = data;
+
+    while (size--) {
+        _usart->buffer = *(dp++);
+    }
+    while (_usart->LSR.transmitter_empty);
+
+    // TODO: do something that actually counts for sent bytes 
+    return size;
+}
+
+int usart_read(uint8_t *buffer, size_t count)
+{
+    uint8_t *bp = buffer;
+    size_t read_count = 0;
+
+    while (count--) {
+        *(bp++) = _usart->buffer;
+        // check for errors
+        if (_usart->LSR.framing_error || _usart->LSR.parity_error) {
+            bp--; // delete last byte (?)
+        } else {
+           read_count++;
+        }
+    }
+
+    return read_count;
+}
diff --git a/sw/z80/libc/include/stdio.h b/sw/z80/libc/include/stdio.h
new file mode 100644
index 0000000..b31cdfd
--- /dev/null
+++ b/sw/z80/libc/include/stdio.h
@@ -0,0 +1,11 @@
+#ifndef __STDIO_H__
+#define __STDIO_H__
+
+#include "types.h"
+
+extern uint8_t *stdout, stderr;
+
+void putc(char ch, uint8_t *buffer);
+int printf(const char *fmt, ...);
+
+#endif 
diff --git a/sw/z80/libc/include/string.h b/sw/z80/libc/include/string.h
new file mode 100644
index 0000000..f224c87
--- /dev/null
+++ b/sw/z80/libc/include/string.h
@@ -0,0 +1,8 @@
+#ifndef __STRING_H__
+#define __STRING_H__
+
+#include "types.h"
+
+void *memcpy(void *dest, const void *src, size_t n);
+
+#endif
diff --git a/sw/z80/libc/stdio.c b/sw/z80/libc/stdio.c
new file mode 100644
index 0000000..c2548d6
--- /dev/null
+++ b/sw/z80/libc/stdio.c
@@ -0,0 +1,12 @@
+#include "stdio.h"
+
+void putc(char ch, uint8_t *buffer)
+{
+    *buffer = ch;
+    *(++buffer) = '\0';
+}
+
+
+int printf(const char *fmt, ...)
+{
+}
diff --git a/sw/z80/libc/string.c b/sw/z80/libc/string.c
new file mode 100644
index 0000000..fd6a7ff
--- /dev/null
+++ b/sw/z80/libc/string.c
@@ -0,0 +1,13 @@
+#include "string.h"
+
+void *memcpy(void *dest, void *src, size_t n)
+{
+    char *dp = dest;
+    char *sp = src;
+
+    while (n--) {
+        *dp++ = *sp++;
+    }
+
+    return dest;
+}
-- 
cgit v1.2.1


From b96b0d6c00ea72895582ec14f9c7dccd3fe7062a Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Sat, 10 Jun 2017 17:47:36 +0200
Subject: add port interface header, api still to implement

fix for bug in usart.c, in function usart_write() that checked the
trasmission_empty register at the wrong time causing it to overwrite
the buffer.
---
 sw/z80/kernel/include/pio.h | 27 ++++++++++++++++++++++-----
 sw/z80/kernel/pio.c         | 25 +++++++------------------
 sw/z80/kernel/usart.c       |  4 ++--
 3 files changed, 31 insertions(+), 25 deletions(-)

(limited to 'sw/z80')

diff --git a/sw/z80/kernel/include/pio.h b/sw/z80/kernel/include/pio.h
index 8d72ab0..5d289ca 100644
--- a/sw/z80/kernel/include/pio.h
+++ b/sw/z80/kernel/include/pio.h
@@ -1,14 +1,31 @@
 #ifndef __PIO_H__
 #define __PIO_H__
 
-#define PIO_A   0
-#define PIO_B   1
+#include "devices.h"
+#include "types.h"
 
+#define PIO_A       0
+#define PIO_B       1
 
-void pio_data(int port, uint8_t data);
-void pio_command(int port, uint8_t cmd);
+#define PIO_MODE_0  0
+#define PIO_MODE_1  1
+#define PIO_MODE_2  2
+#define PIO_MODE_3  3
 
-uint8_t pio_read_data(int port);
+#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);
diff --git a/sw/z80/kernel/pio.c b/sw/z80/kernel/pio.c
index e8c7e24..4b9caee 100644
--- a/sw/z80/kernel/pio.c
+++ b/sw/z80/kernel/pio.c
@@ -1,29 +1,18 @@
 #include "pio.h"
 
-static uint8_t *pio_port_a = (uint8_t *) ADDR_DEV_PIO;
-static uint8_t *pio_port_b = (uint8_t *) ADDR_DEV_PIO + 1;
-static uint8_t *pio_ctrl_a = (uint8_t *) ADDR_DEV_PIO + 2;
-static uint8_t *pio_ctrl_b = (uint8_t *) ADDR_DEV_PIO + 3;
+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)
+void _pio_data(int port, uint8_t data)
 {
-    if (port == PIO_A)
-        *pio_port_a = cmd;
-    else
-        *pio_port_b = cmd;
+    *(pio_port + port) = data;
 }
 
-void pio_command(int port, uint8_t cmd)
+void _pio_command(int port, uint8_t cmd)
 {
-    if (port == PIO_A)
-        *pio_ctrl_a = cmd;
-    else
-        *pio_ctrl_b = cmd;
+    *(pio_ctrl + port) = cmd;
 }
 
-
-
-inline int pio_read_pin(int port, uint8_t pin)
+void pio_set_mode(int port, int mode)
 {
-
 }
diff --git a/sw/z80/kernel/usart.c b/sw/z80/kernel/usart.c
index 4c2fdaf..9ec6dbd 100644
--- a/sw/z80/kernel/usart.c
+++ b/sw/z80/kernel/usart.c
@@ -65,8 +65,8 @@ int usart_write(uint8_t *data, size_t size)
 
     while (size--) {
         _usart->buffer = *(dp++);
+        while (_usart->LSR.transmitter_empty);
     }
-    while (_usart->LSR.transmitter_empty);
 
     // TODO: do something that actually counts for sent bytes 
     return size;
@@ -83,7 +83,7 @@ int usart_read(uint8_t *buffer, size_t count)
         if (_usart->LSR.framing_error || _usart->LSR.parity_error) {
             bp--; // delete last byte (?)
         } else {
-           read_count++;
+            read_count++;
         }
     }
 
-- 
cgit v1.2.1


From 436e259b4c3d687bab51cc8ca35fe61103b430a2 Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Fri, 16 Jun 2017 13:51:06 +0200
Subject: fixed typo in usart.h and in doc

---
 sw/z80/kernel/include/usart.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'sw/z80')

diff --git a/sw/z80/kernel/include/usart.h b/sw/z80/kernel/include/usart.h
index f1f428e..3e5c070 100644
--- a/sw/z80/kernel/include/usart.h
+++ b/sw/z80/kernel/include/usart.h
@@ -134,7 +134,7 @@ struct _usart_device
 // setup functions (wrappers)
 void usart_set_baudrate(uint16_t baudrate);
 void usart_set_parity(int mode);
-void usart_set_stob_bits(int count);
+void usart_set_stop_bits(int count);
 void usart_set_word_length(int length);
 void usart_set_autoflow(int mode);
 
-- 
cgit v1.2.1