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