From 1eba55156d0c74752ccd3a8fd131a25ffa5a13b8 Mon Sep 17 00:00:00 2001 From: Nao Pross 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 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" 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" 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 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 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 + #include + + #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< 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 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 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