From: Alan Cox Date: Thu, 19 Apr 2018 22:50:37 +0000 (+0100) Subject: ubee: Next stages to get from prototype to usable X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=85d4aad82dac48340ed5d8d4ef59ab68ceecfd69;p=FUZIX.git ubee: Next stages to get from prototype to usable - Draft code for lpen keyboard - Fix various platform detection bugs - Rework video to bank it out when not used (in progress) - Support attributes and colour - Memory map re-arrange and buffer recovery - Turn on networking and other stuff that is useful Not yet working (still debugging the video changes) --- diff --git a/Kernel/platform-ubee/Makefile b/Kernel/platform-ubee/Makefile index c7a96dbd..8dda780a 100644 --- a/Kernel/platform-ubee/Makefile +++ b/Kernel/platform-ubee/Makefile @@ -1,6 +1,8 @@ CSRCS = devlpr.c devtty.c devfd.c devhd.c -CSRCS += devices.c main.c +CSRCS += devices.c main.c vt.c + +DISCSRCS = discard.c ASRCS = ubee.s crt0.s ASRCS += tricks.s commonmem.s floppy.s @@ -10,7 +12,9 @@ NSRCS = ../dev/net/net_native.c COBJS = $(CSRCS:.c=.rel) AOBJS = $(ASRCS:.s=.rel) NOBJS = $(patsubst ../dev/net/%.c,%.rel, $(NSRCS)) -OBJS = $(COBJS) $(AOBJS) $(NOBJS) +DISCOBJS = $(DISCSRCS:.c=.rel) + +OBJS = $(COBJS) $(AOBJS) $(NOBJS) $(DISCOBJS) JUNK = $(CSRCS:.c=.lst) $(CSRCS:.c=.asm) $(CSRCS:.c=.sym) $(ASRCS:.s=.lst) $(ASRCS:.s=.sym) $(CSRCS:.c=.rst) $(ASRCS:.s=.rst) @@ -19,6 +23,9 @@ all: $(OBJS) $(COBJS): %.rel: %.c $(CROSS_CC) $(CROSS_CCOPTS) -c $< +$(DISCOBJS): %.rel: %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< + $(NOBJS): %.rel: ../dev/net/%.c $(CROSS_CC) $(CROSS_CCOPTS) -c $< @@ -38,4 +45,3 @@ image: dd if=/dev/zero of=fuzix.ss80 bs=512 count=800 dd if=bootstrap.bin of=fuzix.ss80 conv=notrunc dd if=../fuzix.bin of=fuzix.ss80 bs=512 seek=1 conv=notrunc -# dd if=hellotest.bin of=fuzix.ss80 bs=512 seek=1 conv=notrunc diff --git a/Kernel/platform-ubee/README b/Kernel/platform-ubee/README index 741b4f54..e8480f96 100644 --- a/Kernel/platform-ubee/README +++ b/Kernel/platform-ubee/README @@ -25,6 +25,12 @@ The other memory is then overlaid on 0000-7FFF for user space 0100-7CFF Application 7D00-7FFF Udata/stack cache (may be able to move oto 7DFF/7E00) + (User space sees video mapped at 0x8000-8FFF) + + +Testing with uBee512 + +ubee512 Done so far: @@ -118,7 +124,8 @@ There are three kinds of video Standard: A 6545 with 2K of display memory and 128 8x16 ROM characters plus - 128 in programmable character memory. No colour + 128 in programmable character memory. + Colour option (includes flicker workaround) Premium: The 6545 has @@ -137,5 +144,25 @@ Premium: High resolution video is sort of MSX like but cruder. The character memory is filled with unique character codes and the character ram is loaded with the -bit patterns. +bit patterns. Also it's banked and banked so will be horrible to program and +we'll need graphics mode support for other modes + + + +Currently in progress + +- Video support (colour, attributes) DEBUGGING +- Map video at 0x8000 DONE +- Clear attribute ram if present DONE +- Move common up DONE +- Do buffer over discard change UNTESTED +- Check we have video latches/map right everywhere DEBUGGING +- Init vtattr_cap and the video variables correctly PARTLY DONE +- Check if scrolling in hw is doable or not in 80x25 NO +- Support 'map video into my process at 0x8000 hack' PARTLY DONE +- Non premium video +- Non premium video setup +- Copy ROM font to RAM, support RAM font setting +- Figure out how I broke the 6545 cursor +Currently debugging scrolling and multichar writes diff --git a/Kernel/platform-ubee/config.h b/Kernel/platform-ubee/config.h index 62b6e341..a6983fef 100644 --- a/Kernel/platform-ubee/config.h +++ b/Kernel/platform-ubee/config.h @@ -12,8 +12,6 @@ #undef CONFIG_SINGLETASK /* Video terminal, not a serial tty */ #define CONFIG_VT -/* Simple character addressed device (for now) */ -#define CONFIG_VT_SIMPLE /* Banked memory set up */ #define CONFIG_BANK_FIXED #define MAX_MAPS 16 /* 512 KByte... */ @@ -22,11 +20,11 @@ #define CONFIG_NET #define CONFIG_NET_NATIVE +#define CONFIG_DYNAMIC_BUFPOOL + #define CONFIG_BANKS 2 /* 2 x 32K */ -/* Vt definitions. Eventually we need to sort this out and do mapping of - video, correct video attributes, mode setting etc */ -#define VT_BASE ((uint8_t *)0xF000) +/* For now we don't support resizing */ #define VT_WIDTH 80 #define VT_HEIGHT 24 #define VT_RIGHT 79 @@ -59,5 +57,3 @@ #define NBUFS 7 /* Number of block buffers */ #define NMOUNTS 4 /* Number of mounts at a time */ - -#define platform_discard() diff --git a/Kernel/platform-ubee/crt0.s b/Kernel/platform-ubee/crt0.s index 032de368..36773788 100644 --- a/Kernel/platform-ubee/crt0.s +++ b/Kernel/platform-ubee/crt0.s @@ -4,6 +4,7 @@ ; when they are first seen. .area _CODE .area _CODE2 + ; Load video later on so it ends up above 0x8800 .area _VIDEO .area _CONST .area _INITIALIZED @@ -13,8 +14,9 @@ .area _HEAP .area _GSINIT .area _GSFINAL - .area _COMMONMEM + .area _BUFFERS .area _DISCARD + .area _COMMONMEM ; note that areas below here may be overwritten by the heap at runtime, so ; put initialisation stuff in here .area _INITIALIZER @@ -48,7 +50,9 @@ .word 0xC0DE start: di - ld sp, #kstack_top + ; We can't use the kstack yet - we've still got video mapped + ; all over it + ld sp, #0x0200 ; ; Figure out our hardware type. We need to work this out ; before we can shuffle the memory map and set up video @@ -68,33 +72,41 @@ start: ld a,#2 ld (_ubee_model),a ; Do we need to touch ROM etc - not clear we need do - ; anything as we are already in RAM mode. Turn on video - ; mapping at Fxxx just while we boot up so we can poke it - ; for debug. Some day we can map the video just for - ; the video writes. - ld a,#0x04 + ; anything as we are already in RAM mode. Turn off video + ; mapping + ld a,#0x0C out (0x50),a jr relocate -not256tc: ; The uBee might have colour support - ld hl, (0xF7FF) - ld (hl),#0x90 ; zero the last byte - ld a, #0x10 - out (0x1C),a ; attribute latch - ld (hl),#0xFF ; set to 0xFF - ld a,#0x00 ; back to video - out (0x1c),a - ld a,(hl) - ld (_ubee_model),a ; 1 - premium - or a - jr z, unsupported_model ; 128K required and premium - ld a,#0x04 ; ROMs off video at Fxxx +not256tc: ; Are we a premium model + ld a,#0x10 ; Attribute latch + out (0x1c),a ; Set + in a,(0x1c) ; Read + cp #0x10 ; If reads back we are premium + jr nz, premium_model + ld a,#0x40 ; Colour control register + out (0x08),a ; Set + in a,(0x08) ; Read + cp #0x40 + jr nz, unsupported_model; not colour + xor a + jr colour_standard +; +; uBee Premium Board +; +premium_model: + ld a,#1 +colour_standard: + ld (_ubee_model),a ; model - 1 premium 0 colour standard + ld a,#0x0C ; ROMs off video off out (0x50),a ; FIXME: support SBC (128K non premium 5.25 or 3.5 - ; drives, flicker on video writes) + ; drives, without colour flicker on video writes) + ; may also have a 1793 not 2793 fdc relocate: + ld sp,#kstack_top ; ; move the common memory where it belongs ld hl, #s__DATA diff --git a/Kernel/platform-ubee/devtty.h b/Kernel/platform-ubee/devtty.h index a010a725..aaa66bb0 100644 --- a/Kernel/platform-ubee/devtty.h +++ b/Kernel/platform-ubee/devtty.h @@ -7,4 +7,13 @@ extern void lpen_kbd_poll(void); extern uint8_t kbscan(void); extern uint8_t kbtest(uint16_t code); + +extern uint16_t vtattrib; +extern uint16_t vtaddr; +extern uint16_t vtbase; +extern uint16_t vtcount; +extern uint8_t vtchar; + +extern void vwrite(void); + #endif diff --git a/Kernel/platform-ubee/discard.c b/Kernel/platform-ubee/discard.c new file mode 100644 index 00000000..3cfe15fe --- /dev/null +++ b/Kernel/platform-ubee/discard.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + +__sfr __at 0x04 cmos_reg; +__sfr __at 0x07 cmos_read; + +void has_cmos_rtc(void) +{ + /* See if the week looks valid - probably want a stronger check */ + cmos_reg = 0x06; + if (cmos_read == 0 || cmos_read > 7) + panic("RTC required"); +} + +void map_init(void) +{ + +} + +__sfr __at 0x58 portswitch; +__sfr __at 0x45 probe_reg; +__sfr __at 0x41 fdc_cyl; +__sfr __at 0x48 fdc_stat; + +void do_diskprobe(uint8_t *p) +{ + probe_reg = 0x5A; + /* probe_reg is read/write same value for both controllers so if it + doesn't work we have no disk */ + if (probe_reg != 0x5A) + return; + /* If it mirrored check if a second value mirrors */ + if (fdc_cyl == 0x5A) { + probe_reg = 0x22; + if (fdc_cyl == 0x22) { + /* It's a floppy */ + if (fdc_stat & 0x0F) + *p = DISK_TYPE_FDC_D; /* Dream disc */ + else + *p = DISK_TYPE_FDC; + return; + } + } + /* Double check */ + probe_reg = 0x22; + if (probe_reg != 0x22) + return; + *p = DISK_TYPE_HDC; +} + +static const char dcstr[] = "Disk controller %d: %s\n"; +static const char *diskname[4] = { NULL, "2793", "DreamDisc", "WD1010" }; + +void diskprobe(void) +{ + portswitch = 0; + do_diskprobe(disk_type); + portswitch = 1; + do_diskprobe(disk_type + 1); + /* Hard case: two of the same */ + if (disk_type[0] == disk_type[1]) { + /* No disk at all - we don't care if port 58 works */ + if (!disk_type[0]) + return; + /* We might have internal and external the same ? */ + probe_reg = 0x5C; + portswitch = 0; + probe_reg = 0x00; + portswitch = 1; + if (probe_reg != 0x5C) + disk_type[1] = 0; + } + kprintf(dcstr, 0, diskname[disk_type[0]]); + if (disk_type[1]) + kprintf(dcstr, 1, diskname[disk_type[1]]); +} + +/* The bank bits are not laid out nicely for historical reasons + + A classic uBee has the bank selection in bits 0/1 + The 256TC needed an extra bit so reused bit 5 (rom selector) + The 3rd party 512K/1MB add ons used bits 7/6 for the high bank bits + + Bank 0/0 holds the kernel and common Bank 0/1 holds the kernel low 32k */ +static uint8_t map_mod(uint8_t banknum) +{ + uint8_t r = banknum & 0x03; + r |= 0x14; /* ROM off, Video on at 0x8000 */ + if (ubee_model == UBEE_256TC) + r |= (banknum & 4) ? 0x20 : 0; + else + r |= (banknum & 0x0C) << 4; + return r; +} + +/* Kernel in bank 0 low/high,user apps in bank 1 low/high (and if present + other banks too). Memorywise it's a lot like the TRS80 layout */ + +void pagemap_init(void) +{ + uint8_t i; + uint8_t nbank = procmem / 32; + + /* Just a handy spot to run it early */ + has_cmos_rtc(); + + for (i = 1; i < nbank; i++) + pagemap_add(map_mod(i)); + +} + +uint8_t platform_param(char *p) +{ + used(p); + return 0; +} diff --git a/Kernel/platform-ubee/fuzix.lnk b/Kernel/platform-ubee/fuzix.lnk index c83b9d5a..b5082680 100644 --- a/Kernel/platform-ubee/fuzix.lnk +++ b/Kernel/platform-ubee/fuzix.lnk @@ -1,9 +1,8 @@ -mwxuy -i fuzix.ihx -b _CODE=0x0200 --b _DISCARD=0xDC00 --b _COMMONMEM=0xE400 --b _INITIALIZER=0xF000 +-b _COMMONMEM=0xF000 +-b _INITIALIZER=0x0001 -l z80 platform-ubee/crt0.rel platform-ubee/commonmem.rel @@ -15,6 +14,7 @@ usermem.rel usermem_std-z80.rel platform-ubee/tricks.rel platform-ubee/main.rel +platform-ubee/discard.rel timer.rel kdata.rel platform-ubee/devfd.rel @@ -41,4 +41,5 @@ vt.rel devsys.rel platform-ubee/devlpr.rel platform-ubee/devtty.rel +platform-ubee/vt.rel -e diff --git a/Kernel/platform-ubee/kernel.def b/Kernel/platform-ubee/kernel.def index 86bb8dbd..607f6aa9 100644 --- a/Kernel/platform-ubee/kernel.def +++ b/Kernel/platform-ubee/kernel.def @@ -1,6 +1,6 @@ ; UZI mnemonics for memory addresses etc -U_DATA .equ 0xE400 ; (this is struct u_data from kernel.h) +U_DATA .equ 0xF000 ; (this is struct u_data from kernel.h) U_DATA__TOTALSIZE .equ 0x300 ; 256+256+256 bytes. U_DATA_STASH .equ 0x7D00 ; BD00-BFFF @@ -13,3 +13,5 @@ Z80_TYPE .equ 0 Z80_MMU_HOOKS .equ 0 CONFIG_SWAP .equ 1 + +NBUFS .equ 7 diff --git a/Kernel/platform-ubee/main.c b/Kernel/platform-ubee/main.c index b9d04571..25466c46 100644 --- a/Kernel/platform-ubee/main.c +++ b/Kernel/platform-ubee/main.c @@ -37,14 +37,6 @@ uint8_t platform_rtc_secs(void) return cmos_read; } -void has_cmos_rtc(void) -{ - /* See if the week looks valid - probably want a stronger check */ - cmos_reg = 0x06; - if (cmos_read == 0 || cmos_read > 7) - panic("RTC required"); -} - void platform_interrupt(void) { static uint8_t icount; @@ -68,109 +60,31 @@ void platform_interrupt(void) } } -void map_init(void) -{ - -} - -uint8_t disk_type[2]; - -/* More _DISCARD material */ - -__sfr __at 0x58 portswitch; -__sfr __at 0x45 probe_reg; -__sfr __at 0x41 fdc_cyl; -__sfr __at 0x48 fdc_stat; - -void do_diskprobe(uint8_t *p) -{ - probe_reg = 0x5A; - /* probe_reg is read/write same value for both controllers so if it - doesn't work we have no disk */ - if (probe_reg != 0x5A) - return; - /* If it mirrored check if a second value mirrors */ - if (fdc_cyl == 0x5A) { - probe_reg = 0x22; - if (fdc_cyl == 0x22) { - /* It's a floppy */ - if (fdc_stat & 0x0F) - *p = DISK_TYPE_FDC_D; /* Dream disc */ - else - *p = DISK_TYPE_FDC; - return; - } - } - /* Double check */ - probe_reg = 0x22; - if (probe_reg != 0x22) - return; - *p = DISK_TYPE_HDC; -} - -static const char dcstr[] = "Disk controller %d: %s\n"; -static const char *diskname[4] = { NULL, "2793", "DreamDisc", "WD1010" }; +struct blkbuf *bufpool_end = bufpool + NBUFS; -void diskprobe(void) +/* + * We pack discard into the memory image is if it were just normal + * code but place it at the end after the buffers. When we finish up + * booting we turn everything from the buffer pool to common into + * buffers. + */ +void platform_discard(void) { - portswitch = 0; - do_diskprobe(disk_type); - portswitch = 1; - do_diskprobe(disk_type + 1); - /* Hard case: two of the same */ - if (disk_type[0] == disk_type[1]) { - /* No disk at all - we don't care if port 58 works */ - if (!disk_type[0]) - return; - /* We might have internal and external the same ? */ - probe_reg = 0x5C; - portswitch = 0; - probe_reg = 0x00; - portswitch = 1; - if (probe_reg != 0x5C) - disk_type[1] = 0; - } - kprintf(dcstr, 0, diskname[disk_type[0]]); - if (disk_type[1]) - kprintf(dcstr, 1, diskname[disk_type[1]]); -} - + uint16_t discard_size = (uint16_t)udata - (uint16_t)bufpool_end; + bufptr bp = bufpool_end; -/* The bank bits are not laid out nicely for historical reasons + discard_size /= sizeof(struct blkbuf); - A classic uBee has the bank selection in bits 0/1 - The 256TC needed an extra bit so reused bit 5 (rom selector) - The 3rd party 512K/1MB add ons used bits 7/6 for the high bank bits + kprintf("%d buffers added\n", discard_size); - Bank 0/0 holds the kernel and common Bank 0/1 holds the kernel low 32k */ -static uint8_t map_mod(uint8_t banknum) -{ - uint8_t r = banknum & 0x03; - r |= 0xC; /* ROM off, Video off */ - if (ubee_model == UBEE_256TC) - r |= (banknum & 4) ? 0x20 : 0; - else - r |= (banknum & 0x0C) << 4; - return r; -} + bufpool_end += discard_size; -/* Kernel in bank 0 low/high,user apps in bank 1 low/high (and if present - other banks too). Memorywise it's a lot like the TRS80 layout */ - -void pagemap_init(void) -{ - uint8_t i; - uint8_t nbank = procmem / 32; - - /* Just a handy spot to run it early */ - has_cmos_rtc(); - - for (i = 1; i < nbank; i++) - pagemap_add(map_mod(i)); + memset( bp, 0, discard_size * sizeof(struct blkbuf) ); + for( bp = bufpool + NBUFS; bp < bufpool_end; ++bp ){ + bp->bf_dev = NO_DEVICE; + bp->bf_busy = BF_FREE; + } } -uint8_t platform_param(char *p) -{ - return 0; -} +uint8_t disk_type[2]; diff --git a/Kernel/platform-ubee/ubee.s b/Kernel/platform-ubee/ubee.s index b605c394..5022a5d5 100644 --- a/Kernel/platform-ubee/ubee.s +++ b/Kernel/platform-ubee/ubee.s @@ -39,6 +39,7 @@ .globl outcharhex .globl fd_nmi_handler .globl null_handler + .globl _vtinit .globl _ubee_model @@ -48,9 +49,20 @@ .include "kernel.def" .include "../kernel.def" -; ----------------------------------------------------------------------------- +; +; Buffers (we use asm to set this up as we need them in a special segment +; so we can recover the discard memory into the buffer pool +; + + .globl _bufpool + .area _BUFFERS + +_bufpool: + .ds BUFSIZE * NBUFS + +; ; COMMON MEMORY BANK (kept even when we task switch) -; ----------------------------------------------------------------------------- +; .area _COMMONMEM _platform_monitor: @@ -59,7 +71,7 @@ _platform_monitor: jp to_monitor platform_interrupt_all: - in a,(0xef) + in a,(0xef) ; FIXME: remove this line once debugged ret _platform_reboot: @@ -112,8 +124,6 @@ page_codes: ; ----------------------------------------------------------------------------- .area _CODE -; FIXME: most of this belongs in discard - ; These two must be below 32K and not use the stack until they hit ROM ; space. ; @@ -129,6 +139,8 @@ to_reboot: xor a out (0x50), a jp 0xE000 + + .area _DISCARD ; ; This setting list comes from the Microbee 256TC documentation @@ -138,6 +150,7 @@ _ctc6545: ; registers in reverse order .db 0x00, 0x00, 0x00, 0x20, 0x0A, 0x09, 0x0A, 0x48 .db 0x1a, 0x19, 0x05, 0x1B, 0x37, 0x58, 0x50, 0x6B + init_early: ; load the 6545 parameters ld hl, #_ctc6545 @@ -151,18 +164,45 @@ ctcloop: out (c), b ; register ; ensure the CTC clock is right ld a, #0 in a, (9) ; manual says in but double check - in a, (0x1C) - and #0x7F - out (0x1C), a ; ensure we are in simple mode for now + xor a + out (0x0B),a ; vanish the character rom + ld a,#0x40 + out (0x08),a ; colour, black background + ld a,#0x14 ; map the video in at 0x8000 + out (0x50),a ; clear screen - ld hl, #0xF000 + ld hl, #0x8000 ld (hl), #'*' ; debugging aid in top left inc hl - ld de, #0xF002 + ld de, #0x8002 ld bc, #1998 ld (hl), #' ' ldir - ret + ld hl,#0x8800 + ld de,#0x8801 + ld (hl), #4 ; green characters/black + ld bc,#1999 + ldir + ld a,(_ubee_model) + or a + jr z, no_attribs + ; + ; Map in and wipe attribute memory on the premium and tc + ; models. + ; + ld a,#0x10 ; Enable attribute memory and + out (0x1C),a ; wipe it + ld hl,#0x8000 + ld de,#0x8001 + ld bc,#1999 + ld (hl),#0 + ldir + ld a,#0x80 ; extended PCG on + out (0x1C),a +no_attribs: + ld a,#0x0C ; video back off + out (0x50),a + jp _vtinit init_hardware: ld a,(_ubee_model) @@ -296,6 +336,7 @@ _program_vectors: call map_process + out (0xfe), a ; write zeroes across all vectors ld hl, #0 ld de, #1 @@ -330,7 +371,7 @@ _program_vectors: ; map_kernel: push af - ld a, #0x04 ; bank 0, 1 no ROM - FIXME: map video over kernel + ld a, #0x0C ; bank 0, 1 no ROM or video ld (mapreg), a out (0x50), a pop af @@ -418,8 +459,6 @@ _hd_xfer_out: .globl _lpen_kbd_last ; _kbscan: - ; FIXME set right register ??? or do we always put it right - ; irq handling versus video setup ! in a,(0x0C) bit 6,a ; No light pen signal - no key jr z, nokey ; Fast path exit @@ -525,3 +564,157 @@ scanner_done: xor a out (0x0b),a ret + + +; +; Video support code. This has to live below F000 so it can use the +; video memory and not common. Note that this means we need to disable +; interrupts briefly when we do the flipping +; +; TODO: it would make sense to map the ROM and RAM font space and +; copy the ROM font to RAM so we can support font setting ? +; + + .area _VIDEO + + .globl _cursor_off + .globl _cursor_on + .globl _scroll_up + .globl _scroll_down + .globl _vwrite + .globl _patch_std + .globl _patch_std_end + + .globl ___hard_di + + .globl _vtwidth + .globl _vtaddr + .globl _vtcount + .globl _vtattrib + .globl _vtchar +; +; 6545 Hardware Cursor +; +_cursor_off: + ret +_cursor_on: + pop hl + pop de + push de + push hl + ; ld a,i handling is buggy on NMOS Z80 + call ___hard_di + push af + ld c,#0x0d + ld a,#0x0e + out (0x0c),a + out (c),d + inc a + out (0x0c),a + out (c),e +popout: + pop af + ret c + ei + ret +; +; Scroll the display (the memory wraps on a 2K boundary, the +; display wraps on 2000 bytes). Soft scroll - hard scroll only works +; in 64x16 mode +; +; FIXME: on premium/tc we also need to scroll the attribute RAM! +; +_scroll_up: + call ___hard_di + push af + ld a, (mapreg) + push af + and #0xF7 ; enable video memory + or #0x10 ; and put it at 0x8000 + ld (mapreg),a + out (0x50),a + ld hl,#0x8000 + push hl + ld de, (_vtwidth) + add hl,de + pop de + ld bc,#4016 ; FIXME compute for variable width + ldir +unmap_out: + ; now put the RAM back + pop af + ld (mapreg),a + out (0x50),a + ; We usually only do one char + jr popout + +_scroll_down: + call ___hard_di + push af + ld a, (mapreg) + push af + and #0xF7 ; enable video memory + or #0x10 ; and put it at 0x8000 + ld (mapreg),a + out (0x50),a + ld hl,#0x8FCF ; end of display + push hl + ld de, (_vtwidth) + or a + sbc hl,de + pop de + ex de,hl + ld bc,#4016 ; FIXME compute for widths + lddr + jr unmap_out +; +; Write to the display +; +; In theory we can avoid the di/ei but that needs some careful review +; of the banking paths on interrupt +; +_vwrite: + call ___hard_di + push af + ld a, (mapreg) + push af + and #0xF7 ; enable video memory + or #0x10 ; and put it at 0x8000 + ld (mapreg),a + out (0x50),a + ld hl,(_vtaddr) + ld bc,(_vtcount) + ld a,h + and #0x07 + or #0x80 + ld h,a + ld de,(_vtattrib) + ld a,(_vtchar) +vloop: + ld (hl),a ; character + ld a,#0x90 ; attribute RAM / 0x90 if we enable PCG extended +_patch_std: + out (0x1c),a ; latch in attribute RAM + ld (hl),e ; attribute + xor a ; #0x80 if enable PCG extended + out (0x1c),a +_patch_std_end: + set 3,h ; colour is at F8-FF + ld (hl),d ; colour + dec bc + ld a,b + or c + jr nz, nextchar + jr unmap_out +nextchar: + res 3,h + inc hl + jr vloop +; +; Ensure these are in the video mapping +; +_vtaddr: .word 0 +_vtcount: .word 0 +_vtattrib: .word 0 +_vtwidth: .word 80 ; FIXME should be variable +_vtchar: .byte 0 diff --git a/Kernel/platform-ubee/vt.c b/Kernel/platform-ubee/vt.c new file mode 100644 index 00000000..fa3746f8 --- /dev/null +++ b/Kernel/platform-ubee/vt.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include + +/* + * We use a variant of the generic code for now but we need a different + * helper as we bank the video memory. We should also start using hard + * cursors as the 6545 has one + */ + +static void char_addr(unsigned int y1, unsigned char x1) +{ + vtaddr = VT_WIDTH * y1 + x1; +} + +void plot_char(int8_t y, int8_t x, uint16_t c) +{ + char_addr(y,x); + vtcount = 1; + vtchar = c; + vwrite(); +} + +void clear_lines(int8_t y, int8_t ct) +{ + char_addr(y, 0); + vtcount = ct * (uint16_t)VT_WIDTH; + vtchar = ' '; +// vwrite(); +} + +void clear_across(int8_t y, int8_t x, int16_t l) +{ + char_addr(y, x); + vtcount = l; + vtchar = ' '; + vwrite(); +} + +void vtattr_notify(void) +{ + if (ubee_model == UBEE_256TC) { + vtattrib = (((uint16_t)vtink) << 8) | (((uint16_t)vtpaper) << 12); + if (vtattr & VTA_FLASH) + vtattrib |= 0x80; + if (vtattr & VTA_INVERSE) + vtattrib |= 0x40; + /* 5 4 must be zero 3-0 are extended font select -> 0 for now */ + } else if (ubee_model == UBEE_PREMIUM) { + if (vtattr & VTA_INVERSE) + vtattrib = (((uint16_t)vtpaper) << 8) | (((uint16_t)vtink) << 12); + else + vtattrib = (((uint16_t)vtink) << 8) | (((uint16_t)vtpaper) << 12); + /* 7-4 MBZ, 3-0 are extended font select */ + } else + vtattrib = 0; +} +