CGA and Tandy 1000 HX/SX: Properly implement the light pen strobe. Jungle Hunt's palette changed area still moves, that's a PIT bug, I'm going to look into that again in 5.0 when I go back to porting 808x etc. from MartyPC.
This commit is contained in:
@@ -31,6 +31,8 @@ typedef struct cga_t {
|
|||||||
uint8_t cgamode;
|
uint8_t cgamode;
|
||||||
uint8_t cgacol;
|
uint8_t cgacol;
|
||||||
|
|
||||||
|
uint8_t lp_strobe;
|
||||||
|
|
||||||
int fontbase;
|
int fontbase;
|
||||||
int linepos;
|
int linepos;
|
||||||
int displine;
|
int displine;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ typedef struct t1kvid_t {
|
|||||||
uint32_t b8000_mask;
|
uint32_t b8000_mask;
|
||||||
uint32_t b8000_limit;
|
uint32_t b8000_limit;
|
||||||
uint8_t planar_ctrl;
|
uint8_t planar_ctrl;
|
||||||
|
uint8_t lp_strobe;
|
||||||
|
|
||||||
int linepos;
|
int linepos;
|
||||||
int displine;
|
int displine;
|
||||||
@@ -770,6 +771,15 @@ recalc_address_sl(tandy_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vid_update_latch(t1kvid_t *vid)
|
||||||
|
{
|
||||||
|
uint32_t lp_latch = vid->displine * vid->crtc[1];
|
||||||
|
|
||||||
|
vid->crtc[0x10] = (lp_latch >> 8) & 0x3f;
|
||||||
|
vid->crtc[0x11] = lp_latch & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -816,6 +826,18 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
|
|||||||
vid->array_index = val & 0x1f;
|
vid->array_index = val & 0x1f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x3db:
|
||||||
|
if (dev->is_sl2 && (vid->lp_strobe == 1))
|
||||||
|
vid->lp_strobe = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3dc:
|
||||||
|
if (dev->is_sl2 && (vid->lp_strobe == 0)) {
|
||||||
|
vid->lp_strobe = 1;
|
||||||
|
vid_update_latch(vid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x03de:
|
case 0x03de:
|
||||||
if (vid->array_index & 16)
|
if (vid->array_index & 16)
|
||||||
val &= 0xf;
|
val &= 0xf;
|
||||||
@@ -852,7 +874,7 @@ static uint8_t
|
|||||||
vid_in(uint16_t addr, void *priv)
|
vid_in(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
const tandy_t *dev = (tandy_t *) priv;
|
const tandy_t *dev = (tandy_t *) priv;
|
||||||
const t1kvid_t *vid = dev->vid;
|
t1kvid_t *vid = dev->vid;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||||
@@ -864,29 +886,25 @@ vid_in(uint16_t addr, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03d5:
|
case 0x03d5:
|
||||||
switch (vid->crtcreg) {
|
|
||||||
default:
|
|
||||||
ret = vid->crtc[vid->crtcreg];
|
ret = vid->crtc[vid->crtcreg];
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
|
||||||
if (dev->is_sl2)
|
|
||||||
ret = vid->crtc[vid->crtcreg];
|
|
||||||
else
|
|
||||||
ret = 0x0f;
|
|
||||||
break;
|
|
||||||
case 0x11:
|
|
||||||
if (dev->is_sl2)
|
|
||||||
ret = vid->crtc[vid->crtcreg];
|
|
||||||
else
|
|
||||||
ret = 0x78;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x03da:
|
case 0x03da:
|
||||||
ret = vid->stat;
|
ret = vid->stat;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x3db:
|
||||||
|
if (dev->is_sl2 && (vid->lp_strobe == 1))
|
||||||
|
vid->lp_strobe = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3dc:
|
||||||
|
if (dev->is_sl2 && (vid->lp_strobe == 0)) {
|
||||||
|
vid->lp_strobe = 1;
|
||||||
|
vid_update_latch(vid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,15 @@ static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w
|
|||||||
|
|
||||||
void cga_recalctimings(cga_t *cga);
|
void cga_recalctimings(cga_t *cga);
|
||||||
|
|
||||||
|
static void
|
||||||
|
cga_update_latch(cga_t *cga)
|
||||||
|
{
|
||||||
|
uint32_t lp_latch = cga->displine * cga->crtc[1];
|
||||||
|
|
||||||
|
cga->crtc[0x10] = (lp_latch >> 8) & 0x3f;
|
||||||
|
cga->crtc[0x11] = lp_latch & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cga_out(uint16_t addr, uint8_t val, void *priv)
|
cga_out(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -87,7 +96,7 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
|
|||||||
old = cga->crtc[cga->crtcreg];
|
old = cga->crtc[cga->crtcreg];
|
||||||
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||||
if (old != val) {
|
if (old != val) {
|
||||||
if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) {
|
if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x11)) {
|
||||||
cga->fullchange = changeframecount;
|
cga->fullchange = changeframecount;
|
||||||
cga_recalctimings(cga);
|
cga_recalctimings(cga);
|
||||||
}
|
}
|
||||||
@@ -111,6 +120,17 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
|
|||||||
cga_recalctimings(cga);
|
cga_recalctimings(cga);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 0x3DB:
|
||||||
|
if (cga->lp_strobe == 1)
|
||||||
|
cga->lp_strobe = 0;
|
||||||
|
return;
|
||||||
|
case 0x3DC:
|
||||||
|
if (cga->lp_strobe == 0) {
|
||||||
|
cga->lp_strobe = 1;
|
||||||
|
cga_update_latch(cga);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -119,8 +139,7 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
|
|||||||
uint8_t
|
uint8_t
|
||||||
cga_in(uint16_t addr, void *priv)
|
cga_in(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
const cga_t *cga = (cga_t *) priv;
|
cga_t *cga = (cga_t *) priv;
|
||||||
|
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||||
@@ -131,22 +150,23 @@ cga_in(uint16_t addr, void *priv)
|
|||||||
ret = cga->crtcreg;
|
ret = cga->crtcreg;
|
||||||
break;
|
break;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
switch (cga->crtcreg) {
|
|
||||||
default:
|
|
||||||
ret = cga->crtc[cga->crtcreg];
|
ret = cga->crtc[cga->crtcreg];
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
|
||||||
ret = 0x0f;
|
|
||||||
break;
|
|
||||||
case 0x11:
|
|
||||||
ret = 0x78;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x3DA:
|
case 0x3DA:
|
||||||
ret = cga->cgastat;
|
ret = cga->cgastat;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x3DB:
|
||||||
|
if (cga->lp_strobe == 1)
|
||||||
|
cga->lp_strobe = 0;
|
||||||
|
break;
|
||||||
|
case 0x3DC:
|
||||||
|
if (cga->lp_strobe == 0) {
|
||||||
|
cga->lp_strobe = 1;
|
||||||
|
cga_update_latch(cga);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user