Kaynağa Gözat

sms/vdp: highlight cursor with inverted palette

pull/94/head
Virgil Dupras 4 yıl önce
ebeveyn
işleme
a442c46935
5 değiştirilmiş dosya ile 66 ekleme ve 26 silme
  1. +3
    -0
      emul/hw/sms/sms.c
  2. +6
    -1
      emul/hw/sms/vdp.c
  3. +19
    -3
      kernel/grid.asm
  4. +2
    -2
      kernel/sms/pad.asm
  5. +36
    -20
      kernel/sms/vdp.asm

+ 3
- 0
emul/hw/sms/sms.c Dosyayı Görüntüle

@@ -108,6 +108,9 @@ void create_window()
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()
{
xcb_get_geometry_reply_t *geom;


+ 6
- 1
emul/hw/sms/vdp.c Dosyayı Görüntüle

@@ -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)
{
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 tableval = vdp->vram[offset] + (vdp->vram[offset+1] << 8);
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.
offset = tilenum * 0x20;
// 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);
// Now, let's compose the result by pushing the right bit of our 4 bytes
// 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+2] >> bitnum) & 1) << 2) + \
(((vdp->vram[offset+3] >> bitnum) & 1) << 3);
uint8_t rgb = vdp->vram[0x4000+palettemod+palette_id];
return rgb;
}

+ 19
- 3
kernel/grid.asm Dosyayı Görüntüle

@@ -119,7 +119,7 @@ gridPushScr:
pop de
ret

; Set character under cursor to A
; Set character under cursor to A. C is passed to GRID_SETCELL as-is.
gridSetCur:
push de
push hl
@@ -137,11 +137,27 @@ gridSetCur:
pop de
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
gridClrCur:
push af
ld a, ' '
call gridSetCur
call gridSetCurL
pop af
ret

@@ -210,7 +226,7 @@ gridPutC:
cp ' '
ret c ; ignore unhandled control characters

call gridSetCur
call gridSetCurL
push af ; --> lvl 1
; Move cursor
ld a, (GRID_CURX)


+ 2
- 2
kernel/sms/pad.asm Dosyayı Görüntüle

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


+ 36
- 20
kernel/sms/vdp.asm Dosyayı Görüntüle

@@ -23,8 +23,8 @@
; *** Code ***

vdpInit:
ld hl, vdpInitData
ld b, vdpInitDataEnd-vdpInitData
ld hl, .initData
ld b, .initDataEnd-.initData
ld c, VDP_CTLPORT
otir

@@ -47,10 +47,10 @@ vdpInit:
out (VDP_CTLPORT), a
ld a, 0xc0
out (VDP_CTLPORT), a
xor a ; palette 0: black
out (VDP_DATAPORT), a
ld a, 0x3f ; palette 1: white
out (VDP_DATAPORT), a
ld hl, .paletteData
ld b, .paletteDataEnd-.paletteData
ld c, VDP_DATAPORT
otir

; Define tiles
xor a
@@ -97,6 +97,28 @@ vdpInit:
out (VDP_CTLPORT), a
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.
; When a character is unknown, returns 0x5e (a '~' char).
vdpConv:
@@ -108,7 +130,8 @@ vdpConv:
ld a, 0x5e
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:
call vdpConv
; store A away
@@ -141,18 +164,11 @@ vdpSetCell:
; We're ready to send our data now. Let's go
ex af, af'
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

; 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:

Yükleniyor…
İptal
Kaydet