From 3624c0bba974f3d718364d10422a1a06b39e6f25 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Mon, 23 Jul 2018 23:57:36 +0200 Subject: [PATCH] dragon-nx32: Add dual-screen support with CRT9128 Adds CRT9128 card on tty2 with shared keyboard. Switch tty with ctrl-1 and ctrl-2 (CLEAR-1 and CLEAR-2 on Dragon keyboard). The 6847 graphics VT interface functions are made private and these or the CRT9128 ones are called depending on the current TTY. Add video.h just in case (not needed since multiplexer is asm). Signed-off-by: Tormod Volden --- Kernel/platform-dragon-nx32/Makefile | 3 + Kernel/platform-dragon-nx32/config.h | 9 ++- Kernel/platform-dragon-nx32/devtty.c | 39 ++++++++++-- Kernel/platform-dragon-nx32/devtty.h | 4 ++ Kernel/platform-dragon-nx32/multihead.s | 82 +++++++++++++++++++++++++ Kernel/platform-dragon-nx32/video.h | 11 ++++ Kernel/platform-dragon-nx32/video.s | 48 +++++++-------- 7 files changed, 164 insertions(+), 32 deletions(-) create mode 100644 Kernel/platform-dragon-nx32/multihead.s create mode 100644 Kernel/platform-dragon-nx32/video.h diff --git a/Kernel/platform-dragon-nx32/Makefile b/Kernel/platform-dragon-nx32/Makefile index af9872b8..8539e160 100644 --- a/Kernel/platform-dragon-nx32/Makefile +++ b/Kernel/platform-dragon-nx32/Makefile @@ -13,6 +13,7 @@ CSRCS += devices.c main.c libc.c CDSRCS = discard.c DSRCS = ../dev/devdw.c ../dev/blkdev.c ../dev/devide.c \ + ../dev/crt9128.c \ ../dev/devsd.c ../dev/devscsi.c DDSRCS = ../dev/devide_discard.c ../dev/devscsi_discard.c ../dev/mbr.c \ @@ -20,6 +21,7 @@ DDSRCS = ../dev/devide_discard.c ../dev/devscsi_discard.c ../dev/mbr.c \ ASRCS = crt0.s dragon.s $(MEMSRC) video.s ide.s spi.s scsi_tc3.s ASRCS += tricks.s commonmem.s usermem_sam.s floppy.s drivewire.s +ASRCS += multihead.s COBJS = $(CSRCS:.c=$(BINEXT)) CDOBJS = $(CDSRCS:.c=$(BINEXT)) @@ -60,6 +62,7 @@ image: dragon.o $(MEMOBJ) ../bankfixed.o \ ../start.o ../version.o ../lowlevel-6809.o \ tricks.o main.o ../timer.o ../kdata.o devfd.o floppy.o devices.o \ + multihead.o crt9128.o \ drivewire.o devdw.o ttydw.o \ ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \ ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \ diff --git a/Kernel/platform-dragon-nx32/config.h b/Kernel/platform-dragon-nx32/config.h index 5903764e..c5e44845 100644 --- a/Kernel/platform-dragon-nx32/config.h +++ b/Kernel/platform-dragon-nx32/config.h @@ -38,14 +38,17 @@ /* Video terminal, not a serial tty */ #define CONFIG_VT +#define CONFIG_VT_MULTI #define CONFIG_FONT8X8 /* Vt definitions */ -#define VT_RIGHT 31 -#define VT_BOTTOM 23 +#define VT_RIGHT (vt_tright[curtty]) +#define VT_BOTTOM (vt_tbottom[curtty]) #define VT_INITIAL_LINE 0 #define VIDEO_BASE 0x0400 +#define CRT9128_BASE 0xFF7C + #define TICKSPERSEC 50 /* Ticks per second */ /* FIXME: This will move once we put the display in the kernel bank and sort the banker out */ @@ -61,7 +64,7 @@ #define CMDLINE NULL /* Location of root dev name */ /* Device parameters */ -#define NUM_DEV_TTY 4 +#define NUM_DEV_TTY 5 #define NDEVS 2 /* Devices 0..NDEVS-1 are capable of being mounted */ /* (add new mountable devices to beginning area.) */ #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ diff --git a/Kernel/platform-dragon-nx32/devtty.c b/Kernel/platform-dragon-nx32/devtty.c index c99b7662..62d3ee34 100644 --- a/Kernel/platform-dragon-nx32/devtty.c +++ b/Kernel/platform-dragon-nx32/devtty.c @@ -10,6 +10,7 @@ #include #include #include +#include #undef DEBUG /* UNdefine to delete debug code sequences */ @@ -18,26 +19,33 @@ uint8_t *uart_status = (uint8_t *)0xFF05; /* ACIA status */ uint8_t *uart_command = (uint8_t *)0xFF06; /* ACIA command */ uint8_t *uart_control = (uint8_t *)0xFF07; /* ACIA control */ -#define ACIA_TTY 2 +#define ACIA_TTY 3 #define is_dw(minor) (minor >= DW_MIN_OFF) unsigned char tbuf1[TTYSIZ]; unsigned char tbuf2[TTYSIZ]; -unsigned char tbuf3[TTYSIZ]; /* drivewire VSER 0 */ -unsigned char tbuf4[TTYSIZ]; /* drivewire VWIN 0 */ +unsigned char tbuf3[TTYSIZ]; +unsigned char tbuf4[TTYSIZ]; /* drivewire VSER 0 */ +unsigned char tbuf5[TTYSIZ]; /* drivewire VWIN 0 */ struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */ {NULL, NULL, NULL, 0, 0, 0}, {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2}, {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2}, - /* Drivewire Virtual Serial Ports */ {tbuf3, tbuf3, tbuf3, TTYSIZ, 0, TTYSIZ / 2}, + /* Drivewire Virtual Serial Ports */ {tbuf4, tbuf4, tbuf4, TTYSIZ, 0, TTYSIZ / 2}, + {tbuf5, tbuf5, tbuf5, TTYSIZ, 0, TTYSIZ / 2}, }; uint8_t vtattr_cap = VTA_INVERSE|VTA_UNDERLINE|VTA_ITALIC|VTA_BOLD| VTA_OVERSTRIKE|VTA_NOCURSOR; +const signed char vt_tright[2] = { 31, 79 }; +const signed char vt_tbottom[2] = { 23, 23 }; +extern uint8_t curtty; +static uint8_t inputtty; +static struct vt_switch ttysave[2]; static uint8_t vmode; static uint8_t kbd_timer; struct vt_repeat keyrepeat = { 40, 4 }; @@ -57,6 +65,8 @@ ttyready_t tty_writeready(uint8_t minor) uint8_t c = 0xff; if (minor == 1) return TTY_READY_NOW; + else if (minor == 2) + c = crt9128_done(); else if (minor == ACIA_TTY) c = *uart_status & 16; /* TX DATA empty */ return c ? TTY_READY_NOW : TTY_READY_SOON; @@ -66,6 +76,8 @@ ttyready_t tty_writeready(uint8_t minor) void tty_putc(uint8_t minor, unsigned char c) { + irqflags_t irq; + if (is_dw(minor)) { dw_putc(minor, c); return; @@ -73,11 +85,20 @@ void tty_putc(uint8_t minor, unsigned char c) *uart_data = c; /* Data */ return; } + irq = di(); + if (curtty != minor - 1) { + vt_save(&ttysave[curtty]); + curtty = minor - 1; + vt_load(&ttysave[curtty]); + } if (minor == 1) { /* We don't do text except in 256x192 resolution modes */ if (vmode < 2) vtoutput(&c, 1); + } else if (minor == 2) { + vtoutput(&c, 1); } + irqrestore(irq); } void tty_sleeping(uint8_t minor) @@ -116,6 +137,10 @@ void tty_setup(uint8_t minor) dw_vopen(minor); return; } + if (minor == 2) { + crt9128_init(); + return; + } if (minor != ACIA_TTY) return; r = ttydata[ACIA_TTY].termios.c_cflag & CBAUD; @@ -255,10 +280,14 @@ static void keydecode(void) else c = keyboard[keybyte][keybit]; if (keymap[1] & 64) { /* control */ + if (c == '1' || c == '2') { + inputtty = c - '1'; + return; + } if (c > 31 && c < 127) c &= 31; } - tty_inproc(1, c); + tty_inproc(inputtty + 1, c); } void platform_interrupt(void) diff --git a/Kernel/platform-dragon-nx32/devtty.h b/Kernel/platform-dragon-nx32/devtty.h index 92b92dfd..89463839 100644 --- a/Kernel/platform-dragon-nx32/devtty.h +++ b/Kernel/platform-dragon-nx32/devtty.h @@ -7,6 +7,10 @@ extern uint8_t keymap[8]; extern uint8_t keyboard[8][7]; extern uint8_t shiftkeyboard[8][7]; +extern const signed char vt_tright[2]; +extern const signed char vt_tbottom[2]; +extern uint8_t curtty; + extern int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr); extern void video_cmd(uint8_t *ptr); diff --git a/Kernel/platform-dragon-nx32/multihead.s b/Kernel/platform-dragon-nx32/multihead.s new file mode 100644 index 00000000..befd8b2a --- /dev/null +++ b/Kernel/platform-dragon-nx32/multihead.s @@ -0,0 +1,82 @@ +; +; dispatches vt calls to different screen routines +; + + .module multihead + + .area .data + + .globl _curtty +_curtty .db 0 + + .area .text + + .globl _clear_across +_clear_across: + tst _curtty + lbeq _m6847_clear_across + jmp _crt9128_clear_across + + .globl _clear_lines +_clear_lines: + tst _curtty + lbeq _m6847_clear_lines + jmp _crt9128_clear_lines + + .globl _scroll_up +_scroll_up: + tst _curtty + lbeq _m6847_scroll_up + jmp _crt9128_scroll_up + + .globl _scroll_down +_scroll_down: + tst _curtty + lbeq _m6847_scroll_down + jmp _crt9128_scroll_down + + .globl _plot_char +_plot_char: + tst _curtty + lbeq _m6847_plot_char + jmp _crt9128_plot_char + + .globl _cursor_off +_cursor_off: + tst _curtty + lbeq _m6847_cursor_off + jmp _crt9128_cursor_off + + .globl _cursor_on +_cursor_on: + tst _curtty + lbeq _m6847_cursor_on + jmp _crt9128_cursor_on + + .globl _cursor_disable +_cursor_disable: + rts + + .globl _vtattr_notify +_vtattr_notify: + tst _curtty + lbeq _m6847_vtattr_notify + jmp _crt9128_vtattr_notify + + .globl _video_cmd +_video_cmd: + tst _curtty + lbeq _m6847_video_cmd + jmp _crt9128_video_cmd + + .globl _video_read +_video_read: + tst _curtty + lbeq _m6847_video_read + jmp _crt9128_video_read + + .globl _video_write +_video_write: + tst _curtty + lbeq _m6847_video_write + jmp _crt9128_video_write diff --git a/Kernel/platform-dragon-nx32/video.h b/Kernel/platform-dragon-nx32/video.h new file mode 100644 index 00000000..18368024 --- /dev/null +++ b/Kernel/platform-dragon-nx32/video.h @@ -0,0 +1,11 @@ +void m6847_clear_across(int8_t y, int8_t x, int16_t num); +void m6847_clear_lines(int8_t y, int8_t num); +void m6847_scroll_up(void); +void m6847_scroll_down(void); +void m6847_plot_char(int8_t y, int8_t x, uint16_t c); +void m6847_cursor_off(void); +void m6847_cursor_on(int8_t newy, int8_t newx); +void m6847_vtattr_notify(void); +void m6847_video_cmd(uint8_t *ptr); +void m6847_video_read(uint8_t *ptr); +void m6847_video_write(uint8_t *ptr); diff --git a/Kernel/platform-dragon-nx32/video.s b/Kernel/platform-dragon-nx32/video.s index 0ab694f2..2a1fc6cc 100644 --- a/Kernel/platform-dragon-nx32/video.s +++ b/Kernel/platform-dragon-nx32/video.s @@ -2,19 +2,19 @@ ; Methods provided .globl _vid256x192 - .globl _plot_char - .globl _scroll_up - .globl _scroll_down - .globl _clear_across - .globl _clear_lines - .globl _cursor_on - .globl _cursor_off - .globl _cursor_disable - .globl _vtattr_notify + .globl _m6847_plot_char + .globl _m6847_scroll_up + .globl _m6847_scroll_down + .globl _m6847_clear_across + .globl _m6847_clear_lines + .globl _m6847_cursor_on + .globl _m6847_cursor_off + .globl _m6847_cursor_disable + .globl _m6847_vtattr_notify - .globl _video_read - .globl _video_write - .globl _video_cmd + .globl _m6847_video_read + .globl _m6847_video_write + .globl _m6847_video_cmd ; ; Imports @@ -55,7 +55,7 @@ vidaddr: ; ; plot_char(int8_t y, int8_t x, uint16_t c) ; -_plot_char: +_m6847_plot_char: pshs y lda 4,s bsr vidaddr ; preserves X (holding the char) @@ -165,7 +165,7 @@ plot_fast: ; ; void scroll_up(void) ; -_scroll_up: +_m6847_scroll_up: pshs y ldy #VIDEO_BASE leax 256,y @@ -210,7 +210,7 @@ vscrolln: ; ; void scroll_down(void) ; -_scroll_down: +_m6847_scroll_down: pshs y ldy #VIDEO_END leax -256,y @@ -260,7 +260,7 @@ video_endptr: ; ; clear_across(int8_t y, int8_t x, uint16_t l) ; -_clear_across: +_m6847_clear_across: pshs y lda 4,s ; x into A, B already has y jsr vidaddr ; Y now holds the address @@ -283,7 +283,7 @@ clearnext: ; ; clear_lines(int8_t y, int8_t ct) ; -_clear_lines: +_m6847_clear_lines: pshs y clra ; b holds Y pos already jsr vidaddr ; y now holds ptr to line start @@ -313,7 +313,7 @@ wipel: bne wipel puls y,pc -_cursor_on: +_m6847_cursor_on: pshs y lda 4,s jsr vidaddr @@ -321,7 +321,7 @@ _cursor_on: puls y stx cursor_save ; Fall through -_cursor_off: +_m6847_cursor_off: ldb _vtattr bitb #0x80 bne nocursor @@ -335,17 +335,17 @@ _cursor_off: com 192,x com 224,x nocursor: -_cursor_disable: -_vtattr_notify: +_m6847_cursor_disable: +_m6847_vtattr_notify: rts ; ; These routines wortk in both 256x192x2 and 128x192x4 modes ; because everything in the X plane is bytewide. ; -_video_write: +_m6847_video_write: clra ; clr C bra tfr_cmd -_video_read: +_m6847_video_read: coma ; set C bra tfr_cmd ; go @@ -393,7 +393,7 @@ vidptr: leau d,u rts -_video_cmd: +_m6847_video_cmd: pshs u bsr vidptr ; u now points to the screen nextline: -- 2.34.1