sms/vdp: highlight cursor with inverted palette

This commit is contained in:
Virgil Dupras 2020-02-26 09:43:50 -05:00
parent 247b200dcc
commit a442c46935
5 changed files with 66 additions and 26 deletions

View File

@ -108,6 +108,9 @@ void create_window()
xcb_map_window(conn, win); xcb_map_window(conn, win);
} }
// To make things simple with X11, we only support monochrome display, which is
// inverted: As soon as the color of the pixel is non-black, we show a black
// pixel. If the pixel is white, we show black.
void draw_pixels() void draw_pixels()
{ {
xcb_get_geometry_reply_t *geom; xcb_get_geometry_reply_t *geom;

View File

@ -51,6 +51,7 @@ void vdp_data_wr(VDP *vdp, uint8_t val)
} }
} }
// Returns a 8-bit RGB value (0b00bbggrr)
uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y) uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
{ {
if (x >= VDP_SCREENW) { if (x >= VDP_SCREENW) {
@ -63,6 +64,8 @@ uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
uint16_t offset = 0x3800 + ((y/8) << 6) + ((x/8) << 1); uint16_t offset = 0x3800 + ((y/8) << 6) + ((x/8) << 1);
uint16_t tableval = vdp->vram[offset] + (vdp->vram[offset+1] << 8); uint16_t tableval = vdp->vram[offset] + (vdp->vram[offset+1] << 8);
uint16_t tilenum = tableval & 0x1ff; uint16_t tilenum = tableval & 0x1ff;
// is palette select bit on? if yes, use sprite palette instead
uint8_t palettemod = tableval & 0x800 ? 0x10 : 0;
// tile offset this time. Each tile is 0x20 bytes long. // tile offset this time. Each tile is 0x20 bytes long.
offset = tilenum * 0x20; offset = tilenum * 0x20;
// Each 4 byte is a row. Find row first. // Each 4 byte is a row. Find row first.
@ -70,8 +73,10 @@ uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
uint8_t bitnum = 7 - (x%8); uint8_t bitnum = 7 - (x%8);
// Now, let's compose the result by pushing the right bit of our 4 bytes // Now, let's compose the result by pushing the right bit of our 4 bytes
// into our result. // into our result.
return ((vdp->vram[offset] >> bitnum) & 1) + \ uint8_t palette_id = ((vdp->vram[offset] >> bitnum) & 1) + \
(((vdp->vram[offset+1] >> bitnum) & 1) << 1) + \ (((vdp->vram[offset+1] >> bitnum) & 1) << 1) + \
(((vdp->vram[offset+2] >> bitnum) & 1) << 2) + \ (((vdp->vram[offset+2] >> bitnum) & 1) << 2) + \
(((vdp->vram[offset+3] >> bitnum) & 1) << 3); (((vdp->vram[offset+3] >> bitnum) & 1) << 3);
uint8_t rgb = vdp->vram[0x4000+palettemod+palette_id];
return rgb;
} }

View File

@ -119,7 +119,7 @@ gridPushScr:
pop de pop de
ret ret
; Set character under cursor to A ; Set character under cursor to A. C is passed to GRID_SETCELL as-is.
gridSetCur: gridSetCur:
push de push de
push hl push hl
@ -137,11 +137,27 @@ gridSetCur:
pop de pop de
ret ret
; Call gridSetCur with C = 1.
gridSetCurH:
push bc
ld c, 1
call gridSetCur
pop bc
ret
; Call gridSetCur with C = 0.
gridSetCurL:
push bc
ld c, 0
call gridSetCur
pop bc
ret
; Clear character under cursor ; Clear character under cursor
gridClrCur: gridClrCur:
push af push af
ld a, ' ' ld a, ' '
call gridSetCur call gridSetCurL
pop af pop af
ret ret
@ -210,7 +226,7 @@ gridPutC:
cp ' ' cp ' '
ret c ; ignore unhandled control characters ret c ; ignore unhandled control characters
call gridSetCur call gridSetCurL
push af ; --> lvl 1 push af ; --> lvl 1
; Move cursor ; Move cursor
ld a, (GRID_CURX) ld a, (GRID_CURX)

View File

@ -181,7 +181,7 @@ padGetC:
; no action button pressed, but because our pad status changed, update ; no action button pressed, but because our pad status changed, update
; VDP before looping. ; VDP before looping.
ld a, (PAD_SELCHR) ld a, (PAD_SELCHR)
call gridSetCur call gridSetCurH
jp padGetC jp padGetC
.return: .return:
ld a, LF ld a, LF
@ -190,7 +190,7 @@ padGetC:
.advance: .advance:
ld a, (PAD_SELCHR) ld a, (PAD_SELCHR)
; Z was already set from previous BIT instruction ; Z was already set from previous BIT instruction
ret jp gridSetCurL
.backspace: .backspace:
ld a, BS ld a, BS
; Z was already set from previous BIT instruction ; Z was already set from previous BIT instruction

View File

@ -23,8 +23,8 @@
; *** Code *** ; *** Code ***
vdpInit: vdpInit:
ld hl, vdpInitData ld hl, .initData
ld b, vdpInitDataEnd-vdpInitData ld b, .initDataEnd-.initData
ld c, VDP_CTLPORT ld c, VDP_CTLPORT
otir otir
@ -47,10 +47,10 @@ vdpInit:
out (VDP_CTLPORT), a out (VDP_CTLPORT), a
ld a, 0xc0 ld a, 0xc0
out (VDP_CTLPORT), a out (VDP_CTLPORT), a
xor a ; palette 0: black ld hl, .paletteData
out (VDP_DATAPORT), a ld b, .paletteDataEnd-.paletteData
ld a, 0x3f ; palette 1: white ld c, VDP_DATAPORT
out (VDP_DATAPORT), a otir
; Define tiles ; Define tiles
xor a xor a
@ -97,6 +97,28 @@ vdpInit:
out (VDP_CTLPORT), a out (VDP_CTLPORT), a
ret ret
; VDP initialisation data
.initData:
; 0x8x == set register X
.db 0b00000100, 0x80 ; Bit 2: Select mode 4
.db 0b00000000, 0x81
.db 0b11111111, 0x82 ; Name table: 0x3800
.db 0b11111111, 0x85 ; Sprite table: 0x3f00
.db 0b11111111, 0x86 ; sprite use tiles from 0x2000
.db 0b11111111, 0x87 ; Border uses palette 0xf
.db 0b00000000, 0x88 ; BG X scroll
.db 0b00000000, 0x89 ; BG Y scroll
.db 0b11111111, 0x8a ; Line counter (why have this?)
.initDataEnd:
.paletteData:
; BG palette
.db 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
; Sprite palette (inverted colors)
.db 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.paletteDataEnd:
; Convert ASCII char in A into a tile index corresponding to that character. ; Convert ASCII char in A into a tile index corresponding to that character.
; When a character is unknown, returns 0x5e (a '~' char). ; When a character is unknown, returns 0x5e (a '~' char).
vdpConv: vdpConv:
@ -108,7 +130,8 @@ vdpConv:
ld a, 0x5e ld a, 0x5e
ret ret
; grid routine. Sets cell at row D and column E to character A ; grid routine. Sets cell at row D and column E to character A. If C is one, we
; use the sprite palette.
vdpSetCell: vdpSetCell:
call vdpConv call vdpConv
; store A away ; store A away
@ -141,18 +164,11 @@ vdpSetCell:
; We're ready to send our data now. Let's go ; We're ready to send our data now. Let's go
ex af, af' ex af, af'
out (VDP_DATAPORT), a out (VDP_DATAPORT), a
; Palette select is on bit 3 of MSB
ld a, 1
and c
rla \ rla \ rla
out (VDP_DATAPORT), a
ret ret
; VDP initialisation data
vdpInitData:
; 0x8x == set register X
.db 0b00000100, 0x80 ; Bit 2: Select mode 4
.db 0b00000000, 0x81
.db 0b11111111, 0x82 ; Name table: 0x3800
.db 0b11111111, 0x85 ; Sprite table: 0x3f00
.db 0b11111111, 0x86 ; sprite use tiles from 0x2000
.db 0b11111111, 0x87 ; Border uses palette 0xf
.db 0b00000000, 0x88 ; BG X scroll
.db 0b00000000, 0x89 ; BG Y scroll
.db 0b11111111, 0x8a ; Line counter (why have this?)
vdpInitDataEnd: