From: Alan Cox Date: Sat, 5 Jan 2019 21:18:54 +0000 (+0000) Subject: scm_monitor: interface glue X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=03b3a0bea0f047b2822605508a8c58828379f88a;p=FUZIX.git scm_monitor: interface glue --- diff --git a/Kernel/dev/scm_monitor.h b/Kernel/dev/scm_monitor.h new file mode 100644 index 00000000..4e072e41 --- /dev/null +++ b/Kernel/dev/scm_monitor.h @@ -0,0 +1,33 @@ +extern void scm_reset(void); +extern void scm_version(void); +extern void scm_set_irq(void *ptr); +extern void scm_set_nmi(void *ptr); +extern uint8_t scm_input(uint8_t port) __z88dk_fastcall; +extern uint8_t scm_output(uint16_t portchar) __z88dk_fastcall; +extern void scm_poll(void); +extern uint8_t scm_setbaud(uint16_t portbaud) __z88dk_fastcall; +extern uint8_t scm_execute(uint8_t *cmd) __z88dk_fastcall; +extern void scm_setconsole(uint8_t console) __z88dk_fastcall; +extern uint16_t scm_console(void); +extern uint8_t scm_farget(uint8_t *addr) __z88dk_fastcall; +extern uint16_t scm_ramtop(void); +extern void scm_set_ramtop(uint8_t *addr) __z88dk_fastcall; + + +extern uint16_t scm_monitor_ver; +extern uint16_t scm_config_id; +extern uint16_t scm_hw_info; +extern uint8_t scm_monitor_rev; + +#define SCM_SC108 0 /* Not yet defined FIXME */ + +#define SCM_CUSTOM 0 +#define SCM_SIMULATOR 1 +#define SCM_DEVKIT01 2 +#define SCM_RC2014 3 +#define SCM_SC101 4 +#define SCM_LiNC80 5 +#define SCM_TomsSBC 6 +#define SCM_Z280RC 7 +#define SCM_SC114 8 +#define SCM_SBCRCZ80 9 diff --git a/Kernel/dev/scm_monitor.s b/Kernel/dev/scm_monitor.s new file mode 100644 index 00000000..64625f1b --- /dev/null +++ b/Kernel/dev/scm_monitor.s @@ -0,0 +1,195 @@ + + .module scm + .area _COMMONMEM +; +; Small Computer Monitor interface +; +; The caller has to provide the scm_romcall interface as it is system +; dependent unfortunately +; +; Quirks: +; +; 1. The timer functions are not usually real timers but serial idle +; and as we carefully don't block in serial input can't be used. No +; big deal. We do expose the idle call for platform_idle to use for +; other users +; +; 2. The IRQ handler installed has to be different to our system one +; in RAM as we need to bank the ROM out and back in. If we were to +; task switch in one that would be hell - but we don't call the ROM +; from user space and we don't task switch from kernel so we are good +; for the most part. The from ROM with alt RAM banked case however is +; not pretty so we need to avoid that which has costs. For now we +; don't allow interrupts during ROM calls - that fixes #2 here and +; #2/3 in problems. +; +; 3. The RST 30 vector we use for syscalls. Not a big problem because +; a) our RAM and ROM vectors differ and b) we could use the API to get +; the old vector and call it directly. +; +; Problems: +; +; 1. There is no generic safe way to call it. As it sets up the 0x30 +; vector in ROM and we are run with ROM off, and don't know how to +; re-install the ROM we can't generically call it. We can sort of work +; around this with a bootloader that runs with ROM on and saves all +; the stuff, but a defined call point in high memory that paged in the +; ROM (if needed) would be nice. +; +; 2. Because the monitor is not documented as being re-entrant we need +; to carefully avoid re-entry of the tty logic on an IRQ during a monitor +; call. +; +; 4. There is no API to ask what consoles are present in a generic +; fashion. Even the selection API doesn't return an error code to help +; find out, and set_baud_rate doesn't tell us which was invalid so +; also doesn't help. +; +; 5. There is no generic API for banked memory. Right now it could be +; - None +; - 64K/64K split using port 0x30 +; - 64K/64K split using port 0x38 +; - Banked ROM only +; - Switchable RAM only between 8000-BFFF on a different port. +; +; We can do this by hardware type reported and it's not clear that +; anything else would help much because we need to inline the logic +; in some cases. +; +; 6. There seems to no way to use RTS/CTS, check modem state or +; set character size, parity and stop bits. There is also no break +; support. +; +; Documentation Gaps +; +; Stack pointer requirements when calling the monitor +; Re-entrancy +; Calling with interrupts on or off +; Calling the monitor from interrupts +; State of RAM and ROM mapping on entry and exit +; + .globl _scm_romcall + + + .globl _scm_reset + .globl _scm_conout + .globl _scm_version + .globl _scm_set_irq + .globl _scm_set_nmi + .globl _scm_poll + .globl _scm_input + .globl _scm_output + .globl _scm_setbaud + .globl _scm_execute + .globl _scm_console + .globl _scm_farget + .globl scm_farput + .globl _scm_ramtop + .globl _scm_set_ramtop + +_scm_reset: + xor a + ld c,a + jp _scm_romcall + + +_scm_conout: + ld c,#2 + ld a,l + call _scm_romcall + ret +_scm_version: + ld c,#8 + call _scm_romcall + ld (_scm_monitor_ver),de + ld (_scm_config_id),bc + ld (_scm_hw_info),hl + ld (_scm_monitor_rev),a + ret +_scm_set_irq: + ld c,#0x09 + ld a,#0x07 + ex de,hl + jp _scm_romcall +_scm_set_nmi: + ld c,#0x09 + xor a + ex de,hl + jp _scm_romcall +_scm_input: + ld e,l + ld c,#0x10 + call _scm_romcall + ld l,a + ld h,#0 + ret nz + ld hl,#0xFFFF + ret +_scm_output: + ld a,l + ld e,h + ld c,#0x11 + call _scm_romcall + ld l,a + ret +_scm_poll: + ld c,#0x12 + jp _scm_romcall +_scm_setbaud: + ld c,#0x21 + ld a,h + ld e,l + call _scm_romcall + ld l,a + ret +_scm_execute: + ld c,#0x22 + ex de,hl + call _scm_romcall + ld l,a + ret +_scm_setconsole: + ld c,#0x0d + ld a,l + jp _scm_romcall +_scm_console: + ld c,#0x27 + call _scm_romcall + ex de,hl + ret +_scm_farget: + ld c,#0x2A + ex de,hl + call _scm_romcall + ld l,a + ret +; scm_farput can't be C called but we don't need it for that +scm_farput: + ld c,#0x2B + jp _scm_romcall +_scm_ramtop: + ld c,#0x28 + call _scm_romcall + ex de,hl + ret +_scm_set_ramtop: + ld c,#0x29 + ex de,hl + jp _scm_romcall + + + .area _DATA + + .globl _scm_monitor_ver + .globl _scm_config_id + .globl _scm_hw_info + .globl _scm_monitor_rev + +_scm_monitor_ver: + .dw 0 +_scm_config_id: + .dw 0 +_scm_hw_info: + .dw 0 +_scm_monitor_rev: + .db 0