From 81c60356e5ce17466547d9970aa8f48a14f3e2d4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 25 Nov 2018 22:07:37 +0000 Subject: [PATCH] zxdiv: colour attribute support How to handle the border - interesting question --- Kernel/platform-zxdiv/README | 6 ++-- Kernel/platform-zxdiv/devtty.c | 18 +++++++++- Kernel/platform-zxdiv/zx128.s | 17 +++------- Kernel/platform-zxdiv/zxvideo.s | 60 +++++++++++++++++++++++++++++---- 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/Kernel/platform-zxdiv/README b/Kernel/platform-zxdiv/README index 6a2ac716..97e01640 100644 --- a/Kernel/platform-zxdiv/README +++ b/Kernel/platform-zxdiv/README @@ -77,9 +77,6 @@ To Do: bootloader hack - 6 or 5bit wide fonts (42, 51 column) - Optimize zxvid - especially scrolling -- Colour attributes -- Graphics mapping -- Kempston joystick and mouse - Many of the later Russian clones support putting bank 0 in the low 16K, and more than 8 banks. That would need some changes to the bank logic and some interesting detection code. Also they have rather @@ -181,3 +178,6 @@ DONE - Crash on pre-emption, appears to be a bug in fuse-1.5.4 DONE - Move video to 4000 and data to 6000 so that we have video direct mappable by user space and also make it easier if we have to work via ROMs that want spectrum system variable stuff +DONE - Colour attributes +DONE - Graphics mapping +DONE - Kempston joystick and mouse diff --git a/Kernel/platform-zxdiv/devtty.c b/Kernel/platform-zxdiv/devtty.c index 617303c3..4ba199b2 100644 --- a/Kernel/platform-zxdiv/devtty.c +++ b/Kernel/platform-zxdiv/devtty.c @@ -12,7 +12,8 @@ char tbuf1[TTYSIZ]; -uint8_t vtattr_cap; +uint8_t vtattr_cap = VTA_INVERSE|VTA_FLASH; +uint8_t curattr = 7; struct vt_repeat keyrepeat; static uint8_t kbd_timer; @@ -290,3 +291,18 @@ int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr) } return -1; } + +void vtattr_notify(void) +{ + /* Attribute byte fixups: not hard as the colours map directly + to the spectrum ones */ + if (vtattr & VTA_INVERSE) + curattr = ((vtink & 7) << 3) | (vtpaper & 7); + else + curattr = (vtink & 7) | ((vtpaper & 7) << 3); + if (vtattr & VTA_FLASH) + curattr |= 0x80; + /* How to map the bright bit - we go by either */ + if ((vtink | vtpaper) & 0x10) + curattr |= 0x40; +} diff --git a/Kernel/platform-zxdiv/zx128.s b/Kernel/platform-zxdiv/zx128.s index 605368b2..51bb8cbb 100644 --- a/Kernel/platform-zxdiv/zx128.s +++ b/Kernel/platform-zxdiv/zx128.s @@ -39,6 +39,7 @@ .globl _procmem .globl _vtoutput + .globl _vtinit .globl outcharhex .globl outhl, outde, outbc @@ -122,19 +123,9 @@ init_hardware: ld (_procmem), hl ; screen initialization - ; clear - ld hl, #0x4000 - ld de, #0x4001 - ld bc, #0x1800 ; There should be 0x17FF, but we are going - xor a ; to copy additional byte to avoid need of - ld (hl), a ; DE and HL increment before attribute - ldir ; initialization (2 bytes of RAM economy) - - ; set color attributes - ld a, #7 ; black paper, white ink - ld bc, #0x300 - #1 - ld (hl), a - ldir + push af + call _vtinit + pop af ret diff --git a/Kernel/platform-zxdiv/zxvideo.s b/Kernel/platform-zxdiv/zxvideo.s index 031a19b1..e8f29f8a 100644 --- a/Kernel/platform-zxdiv/zxvideo.s +++ b/Kernel/platform-zxdiv/zxvideo.s @@ -14,8 +14,8 @@ .globl _clear_lines .globl _clear_across .globl _do_beep - .globl _vtattr_notify .globl _fontdata_8x8 + .globl _curattr .area _VIDEO @@ -36,6 +36,23 @@ videopos: ld d,a ret +videoattr: + ; 32 x E + D into HL + ld a,e + rrca + rrca + rrca ; A is now 32xE with the top bits overflowed + ; into the low 2 bits + ld l,a + and #3 ; Extract the low 2 bits for the high + add #0x58 ; Attributes start 0x5800 + ld h,a + ld a,l + and #0xE0 ; mask the bits that are valid + add d ; add the low 5 bits from D + ld l,a ; and done (the add can't overflow) + ret + _plot_char: pop iy pop hl @@ -46,6 +63,7 @@ _plot_char: push hl push iy + push de call videopos ld b, #0 ; calculating offset in font table @@ -72,6 +90,10 @@ plot_char_loop: inc d ; next screen line dec c jr nz, plot_char_loop + pop de + call videoattr + ld a,(_curattr) + ld (hl),a ret @@ -82,6 +104,9 @@ _clear_lines: push de push hl push bc + ; This way we handle 0 correctly + inc d + jr nextline clear_next_line: push de @@ -98,6 +123,7 @@ clear_next_line: pop de inc e +nextline: dec d jr nz, clear_next_line @@ -113,6 +139,11 @@ _clear_across: push de push hl push iy + ld a,c + or a + ret z ; No work to do - bail out + push de + push bc call videopos ; first pixel line of first character in DE push de pop hl ; copy to hl @@ -125,8 +156,7 @@ clear_line: clear_char: ld (de), a inc d - dec b - jr nz, clear_char + djnz clear_char ex de, hl inc de @@ -135,6 +165,15 @@ clear_char: dec c jr nz, clear_line + pop bc + pop de + call videoattr + ld a,(_curattr) + ld b,c +setattr: + ld (hl),a + inc hl + djnz setattr ret copy_line: @@ -161,8 +200,7 @@ copy_pixel_line: ld (de), a inc e inc l - dec b - jr nz, copy_pixel_line + djnz copy_pixel_line pop de pop hl @@ -199,6 +237,12 @@ loop_scroll_down: dec c jr nz, loop_scroll_down + ; Attributes + ld hl,#0x5ADF + ld de,#0x5AFF + ld bc,#0x02E0 + lddr + ret @@ -227,6 +271,10 @@ loop_scroll_up: dec c jr nz, loop_scroll_up + ld hl,#0x5820 + ld de,#0x5800 + ld bc,#0x02E0 + ldir ret _cursor_on: @@ -254,8 +302,6 @@ _cursor_off: ld d, a xor a ld (de), a -_vtattr_notify: - ret _do_beep: ret -- 2.34.1