Skip to content

Commit

Permalink
serial: define an interface for user programs
Browse files Browse the repository at this point in the history
The interface is implemented on the Zeal 8-bit computer. It mainly allows
changing the mode attribute, to switch to RAW mode (no LR -> CRLF conversion)
  • Loading branch information
Zeal8bit committed Nov 18, 2023
1 parent 0898753 commit 6503a4b
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 16 deletions.
44 changes: 44 additions & 0 deletions kernel_headers/sdcc/include/zos_serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* SPDX-FileCopyrightText: 2023 Zeal 8-bit Computer <contact@zeal8bit.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

/**
* This file represents the Serial interface.
* THIS INTERFACE IS SUBJECT TO CHANGE.
*/


/**
* IOCTL commands for the serial device.
*/
typedef enum {
SERIAL_CMD_GET_ATTR = 0x80,
SERIAL_CMD_SET_ATTR,

SERIAL_CMD_GET_BAUDRATE,
SERIAL_CMD_SET_BAUDRATE,

SERIAL_GET_TIMEOUT,
SERIAL_SET_TIMEOUT,

SERIAL_GET_BLOCKING,
SERIAL_SET_BLOCKING,

SERIAL_CMD_LAST
} ser_cmd_t;


/**
* Attributes bitmap to use with SERIAL_CMD_GET_ATTR/SERIAL_CMD_SET_ATTR commands
*/
#define SERIAL_ATTR_MODE_RAW (1 << 0)
#define SERIAL_ATTR_RSVD1 (1 << 1)
#define SERIAL_ATTR_RSVD2 (1 << 2)
#define SERIAL_ATTR_RSVD3 (1 << 3)
#define SERIAL_ATTR_RSVD4 (1 << 4)
#define SERIAL_ATTR_RSVD5 (1 << 5)
#define SERIAL_ATTR_RSVD6 (1 << 6)
#define SERIAL_ATTR_RSVD7 (1 << 7)
53 changes: 53 additions & 0 deletions kernel_headers/z88dk-z80asm/zos_serial.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

; SPDX-FileCopyrightText: 2023 Zeal 8-bit Computer <contact@zeal8bit.com>
;
; SPDX-License-Identifier: Apache-2.0

IFNDEF ZOS_SERIAL_H
DEFINE ZOS_SERIAL_H

; This file represents the minimal interface for a serial driver.
; If any command below is not supported, the driver should return
; ERR_NOT_SUPPORTED.

; IOCTL commands the driver should implement
DEFGROUP {
; Get the serial driver attributes.
; Parameter:
; DE - Address to fill with the 16-bit attribute
SERIAL_CMD_GET_ATTR = 0x80, ; See attribute group below

; Set the serial driver attributes.
; Parameter:
; DE - 16-bit attributes to set (NOT AN ADDRESS/POINTER)
SERIAL_CMD_SET_ATTR,


SERIAL_CMD_GET_BAUDRATE,
SERIAL_CMD_SET_BAUDRATE,


SERIAL_GET_TIMEOUT,
SERIAL_SET_TIMEOUT,


SERIAL_GET_BLOCKING,
SERIAL_SET_BLOCKING,

; Number of commands above
SERIAL_CMD_COUNT
}

; Serial driver attribute bitmap to use with SERIAL_CMD_GET_ATTR command
DEFGROUP {
SERIAL_ATTR_MODE_RAW = 1 << 0,
SERIAL_ATTR_RSVD1 = 1 << 1,
SERIAL_ATTR_RSVD2 = 1 << 2,
SERIAL_ATTR_RSVD3 = 1 << 3,
SERIAL_ATTR_RSVD4 = 1 << 4,
SERIAL_ATTR_RSVD5 = 1 << 5,
SERIAL_ATTR_RSVD6 = 1 << 6,
SERIAL_ATTR_RSVD7 = 1 << 7
}

ENDIF ; ZOS_SERIAL_H
28 changes: 22 additions & 6 deletions target/zeal8bit/include/uart_h.asm
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,42 @@
IFNDEF UART_H
DEFINE UART_H

INCLUDE "drivers/video_text_h.asm"

; UART commands
; UART commands, start at 0x80 to allow drivers to also handle the video commands (when UART is STDOUT)
DEFGROUP {
UART_SET_BAUDRATE = CMD_COUNT,
; The attributes bits are defines below
UART_CMD_GET_ATTR = 0x80,
UART_CMD_SET_ATTR,

; The values for the baudrates are defined below
UART_CMD_GET_BAUDRATE,
UART_CMD_SET_BAUDRATE,

UART_GET_TIMEOUT,
UART_SET_TIMEOUT,

UART_GET_BLOCKING,
UART_SET_BLOCKING,

UART_CMD_LAST
}

; UART attributes
DEFC UART_ATTR_MODE_RAW = 1 << 0
DEFC UART_ATTR_RSVD1 = 1 << 1
DEFC UART_ATTR_RSVD2 = 1 << 2
DEFC UART_ATTR_RSVD3 = 1 << 3
DEFC UART_ATTR_RSVD4 = 1 << 4
DEFC UART_ATTR_RSVD5 = 1 << 5
DEFC UART_ATTR_RSVD6 = 1 << 6
DEFC UART_ATTR_RSVD7 = 1 << 7

; Baudrates for receiving bytes from the UART
DEFC UART_BAUDRATE_57600 = 0
DEFC UART_BAUDRATE_38400 = 1
DEFC UART_BAUDRATE_19200 = 4
DEFC UART_BAUDRATE_9600 = 10


; Default baudrate for UART
DEFC UART_BAUDRATE_DEFAULT = UART_BAUDRATE_57600


ENDIF ; UART_H
54 changes: 44 additions & 10 deletions target/zeal8bit/uart.asm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
INCLUDE "uart_h.asm"
INCLUDE "interrupt_h.asm"
INCLUDE "utils_h.asm"
INCLUDE "drivers/video_text_h.asm"

EXTERN zos_sys_remap_de_page_2

Expand Down Expand Up @@ -40,9 +41,9 @@ uart_init:

call pio_init

; Configure the UART to convert LF to CRLF when sending bytes
ld a, 1
ld (_uart_convert_lf), a
; Configure the UART to convert LF to CRLF when sending bytes (not RAW)
xor a
ld (_uart_raw), a

; Initialize the escape sequence
ld hl, ('[' << 8) | 0x1b
Expand Down Expand Up @@ -71,6 +72,9 @@ uart_init:
call zos_log_warning
ENDIF

ELSE
ld a, 1
ld (_uart_raw), a
ENDIF ; CONFIG_TARGET_STDOUT_UART

; Currently, the driver doesn't need to do anything special for open, close or de-init
Expand Down Expand Up @@ -121,7 +125,11 @@ _no_mmu_msg: DEFM "no-MMU Kernel build\n", 0
uart_ioctl:
; Check that the command number is correct
ld a, c
cp UART_SET_BAUDRATE
cp UART_CMD_GET_ATTR
jr z, _uart_ioctl_get_attr
cp UART_CMD_SET_ATTR
jr z, _uart_ioctl_set_attr
cp UART_CMD_SET_BAUDRATE
jr z, _uart_ioctl_set_baud

IF CONFIG_TARGET_STDOUT_UART
Expand All @@ -130,14 +138,40 @@ uart_ioctl:
cp CMD_SET_COLORS
jr z, _uart_ioctl_set_colors
cp CMD_SET_CURSOR_XY
jr z, _uart_ioctl_set_cursor
jp z, _uart_ioctl_set_cursor
cp CMD_CLEAR_SCREEN
jp z, _uart_clear_screen
ENDIF ; CONFIG_TARGET_STDOUT_UART

_uart_ioctl_not_supported:
ld a, ERR_NOT_SUPPORTED
ret

; Return the current attributes (currently only a single one) in the given buffer
_uart_ioctl_get_attr:
IF CONFIG_KERNEL_TARGET_HAS_MMU
; Remap DE to page 2 if it was in page 3
call zos_sys_remap_de_page_2
ENDIF
; Single bit at the moment: RAW/not-RAW. In other words, do we re-interpret LF to CRLF?
ld a, (_uart_raw)
ld (de), a
; Ignore higher bits for now, return success
xor a
ret


; Set the UART attributes, consider DE as the VALUE, not a pointer
_uart_ioctl_set_attr:
; Only consider the first bit of attributes (RAW mode)
ld a, e
and 1
ld (_uart_raw), a
; Return success
xor a
ret


_uart_ioctl_set_baud:
; Command is correct, check that the parameter is correct
ld a, e
Expand All @@ -159,7 +193,6 @@ _uart_ioctl_valid:

_uart_ioctl_get_area:
IF CONFIG_KERNEL_TARGET_HAS_MMU
; Remap DE to page 2 if it was in page 3
call zos_sys_remap_de_page_2
ENDIF
; Let's say that the text area is 80x40
Expand Down Expand Up @@ -397,10 +430,10 @@ uart_send_byte:
cp '\n'
jr nz, _uart_send_byte_raw
; Check if we have to convert LF to CRLF
ld a, (_uart_convert_lf)
ld a, (_uart_raw)
or a
ld a, '\n'
jr z, _uart_send_byte_raw
jr nz, _uart_send_byte_raw
ld a, '\r'
call _uart_send_byte_raw
ld a, '\n'
Expand Down Expand Up @@ -721,8 +754,9 @@ _stdout_save_restore_position:

SECTION DRIVER_BSS
_uart_baudrate: DEFS 1
; When set to 1, LF will be convert to CRLF when sending bytes
_uart_convert_lf: DEFS 1
; When set to 1, bytes will be sent as-is to through UART. When set to 0,
; LF will NOT be convert to CRLF when sending bytes
_uart_raw: DEFS 1
_uart_esc_seq: DEFS 10
_uart_esc_seq_end:

Expand Down

0 comments on commit 6503a4b

Please sign in to comment.