mirror of
https://github.com/86Box/86Box.git
synced 2025-01-23 09:42:47 -05:00
Merge branch 'master' of https://github.com/86Box/86Box into qt
This commit is contained in:
commit
0be3204ad3
4 changed files with 274 additions and 203 deletions
|
@ -19,7 +19,7 @@ cmake_policy(SET CMP0091 NEW)
|
|||
cmake_policy(SET CMP0079 NEW)
|
||||
|
||||
project(86Box
|
||||
VERSION 3.1
|
||||
VERSION 3.2
|
||||
DESCRIPTION "Emulator of x86-based systems"
|
||||
HOMEPAGE_URL "https://86box.net"
|
||||
LANGUAGES C CXX)
|
||||
|
|
|
@ -143,6 +143,8 @@ sis_85c496_recalcmapping(sis_85c496_t *dev)
|
|||
} else
|
||||
mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,13 +242,8 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||
break;
|
||||
case 0x45: /* Shadow Configure */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
if (valxor & 0x03) {
|
||||
if (valxor & 0x03)
|
||||
sis_85c496_recalcmapping(dev);
|
||||
if ((old == 0x0a) && (val == 0x09))
|
||||
flushmmucache_nopc();
|
||||
else
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
case 0x46: /* Cacheable Control */
|
||||
dev->pci_conf[addr] = val;
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
#define EMU_NAME "86Box"
|
||||
#define EMU_NAME_W LSTR(EMU_NAME)
|
||||
|
||||
#define EMU_VERSION "3.1"
|
||||
#define EMU_VERSION "3.2"
|
||||
#define EMU_VERSION_W LSTR(EMU_VERSION)
|
||||
#define EMU_VERSION_EX "3.01"
|
||||
#define EMU_VERSION_EX "3.02"
|
||||
#define EMU_VERSION_MAJ 3
|
||||
#define EMU_VERSION_MIN 0
|
||||
#define EMU_VERSION_PATCH 0
|
||||
|
|
|
@ -158,7 +158,7 @@ enum
|
|||
#define FIFO_ENTRY_SIZE (1 << 31)
|
||||
|
||||
#define FIFO_ENTRIES (s3->fifo_write_idx - s3->fifo_read_idx)
|
||||
#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= FIFO_SIZE)
|
||||
#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= (FIFO_SIZE - 4))
|
||||
#define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx)
|
||||
|
||||
#define FIFO_TYPE 0xff000000
|
||||
|
@ -337,6 +337,8 @@ typedef struct s3_t
|
|||
fifo_entry_t fifo[FIFO_SIZE];
|
||||
volatile int fifo_read_idx, fifo_write_idx;
|
||||
|
||||
uint8_t fifo_thread_run;
|
||||
|
||||
thread_t *fifo_thread;
|
||||
event_t *wake_fifo_thread;
|
||||
event_t *fifo_not_full_event;
|
||||
|
@ -426,6 +428,42 @@ dword_remap_l(svga_t *svga, uint32_t in_addr)
|
|||
(in_addr & ~0xffff);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wake_fifo_thread(s3_t *s3)
|
||||
{
|
||||
thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
|
||||
}
|
||||
|
||||
static void
|
||||
s3_wait_fifo_idle(s3_t *s3)
|
||||
{
|
||||
while (!FIFO_EMPTY) {
|
||||
wake_fifo_thread(s3);
|
||||
thread_wait_event(s3->fifo_not_full_event, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type)
|
||||
{
|
||||
fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK];
|
||||
|
||||
if (FIFO_FULL) {
|
||||
thread_reset_event(s3->fifo_not_full_event);
|
||||
if (FIFO_FULL) {
|
||||
thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/
|
||||
}
|
||||
}
|
||||
|
||||
fifo->val = val;
|
||||
fifo->addr_type = (addr & FIFO_ADDR) | type;
|
||||
|
||||
s3->fifo_write_idx++;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8)
|
||||
wake_fifo_thread(s3);
|
||||
}
|
||||
|
||||
static void
|
||||
s3_update_irqs(s3_t *s3)
|
||||
{
|
||||
|
@ -666,7 +704,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
|
||||
switch (port) {
|
||||
case 0x8148: case 0x82e8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val;
|
||||
s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val;
|
||||
s3->accel.poly_cy = s3->accel.cur_y;
|
||||
|
@ -678,7 +715,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
s3->accel.poly_cy = s3->accel.cur_y;
|
||||
break;
|
||||
case 0x814a: case 0x82ea:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val;
|
||||
s3->accel.poly_cy2 = s3->accel.cur_y2;
|
||||
break;
|
||||
|
@ -688,7 +724,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x8548: case 0x86e8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val;
|
||||
s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val;
|
||||
s3->accel.poly_cx = s3->accel.cur_x << 20;
|
||||
|
@ -702,7 +737,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
s3->accel.poly_x = s3->accel.poly_cx >> 20;
|
||||
break;
|
||||
case 0x854a: case 0x86ea:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val;
|
||||
s3->accel.poly_cx2 = s3->accel.cur_x2 << 20;
|
||||
break;
|
||||
|
@ -713,7 +747,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
|
||||
case 0xcae8:
|
||||
case 0x8948: case 0x8ae8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val;
|
||||
s3->accel.point_1_updated = 1;
|
||||
break;
|
||||
|
@ -725,7 +758,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
s3->accel.point_1_updated = 1;
|
||||
break;
|
||||
case 0x894a: case 0x8aea:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val;
|
||||
s3->accel.point_2_updated = 1;
|
||||
break;
|
||||
|
@ -737,7 +769,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x8d48: case 0x8ee8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val;
|
||||
s3->accel.point_1_updated = 1;
|
||||
break;
|
||||
|
@ -748,7 +779,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
s3->accel.point_1_updated = 1;
|
||||
break;
|
||||
case 0x8d4a: case 0x8eea:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.x2 = (s3->accel.x2 & 0xf00) | val;
|
||||
s3->accel.point_2_updated = 1;
|
||||
break;
|
||||
|
@ -758,7 +788,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x9148: case 0x92e8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val;
|
||||
break;
|
||||
case 0x9149: case 0x92e9:
|
||||
|
@ -776,7 +805,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x9548: case 0x96e8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xf00) | val;
|
||||
break;
|
||||
case 0x9459: case 0x96e9:
|
||||
|
@ -794,7 +822,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x9948: case 0x9ae8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.cmd = (s3->accel.cmd & 0xff00) | val;
|
||||
s3->data_available = 0;
|
||||
s3->accel.b2e8_pix = 0;
|
||||
|
@ -835,7 +862,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0xa148: case 0xa2e8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
|
||||
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16);
|
||||
else
|
||||
|
@ -872,7 +898,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0xa548: case 0xa6e8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
|
||||
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16);
|
||||
else
|
||||
|
@ -909,7 +934,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0xa948: case 0xaae8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
|
||||
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16);
|
||||
else
|
||||
|
@ -946,7 +970,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0xad48: case 0xaee8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
|
||||
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16);
|
||||
else
|
||||
|
@ -1019,12 +1042,10 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0xb548: case 0xb6e8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
s3->accel.bkgd_mix = val;
|
||||
break;
|
||||
|
||||
case 0xb948: case 0xbae8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
s3->accel.frgd_mix = val;
|
||||
break;
|
||||
|
||||
|
@ -1034,25 +1055,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
case 0xbd49: case 0xbee9:
|
||||
s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8);
|
||||
s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff;
|
||||
switch (s3->accel.multifunc_cntl >> 12) {
|
||||
case 0:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
break;
|
||||
case 0xa:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xd148: case 0xd2e8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val;
|
||||
break;
|
||||
case 0xd149: case 0xd2e9:
|
||||
s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8);
|
||||
break;
|
||||
case 0xe548: case 0xe6e8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
|
||||
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
|
||||
else
|
||||
|
@ -1088,21 +1099,18 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
}
|
||||
break;
|
||||
case 0xe948: case 0xeae8:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.pat_y = (s3->accel.pat_y & 0xf00) | val;
|
||||
break;
|
||||
case 0xe949: case 0xeae9:
|
||||
s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8);
|
||||
break;
|
||||
case 0xe94a: case 0xeaea:
|
||||
s3->accel.draw_fifo_slot++;
|
||||
s3->accel.pat_x = (s3->accel.pat_x & 0xf00) | val;
|
||||
break;
|
||||
case 0xe94b: case 0xeaeb:
|
||||
s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8);
|
||||
break;
|
||||
case 0xed48: case 0xeee8:
|
||||
s3->accel.setup_fifo_slot++;
|
||||
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
|
||||
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
|
||||
else
|
||||
|
@ -1297,11 +1305,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (s3_enable_fifo(s3) == 0) {
|
||||
s3->accel.setup_fifo_slot = 0;
|
||||
s3->accel.draw_fifo_slot = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3366,7 +3369,10 @@ s3_accel_out(uint16_t port, uint8_t val, void *p)
|
|||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
s3_accel_out_fifo(s3, port, val);
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_queue(s3, port, val, FIFO_OUT_BYTE);
|
||||
else
|
||||
s3_accel_out_fifo(s3, port, val);
|
||||
} else {
|
||||
switch (port)
|
||||
{
|
||||
|
@ -3406,7 +3412,10 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *p)
|
|||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
s3_accel_out_fifo_w(s3, port, val);
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_queue(s3, port, val, FIFO_OUT_WORD);
|
||||
else
|
||||
s3_accel_out_fifo_w(s3, port, val);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3417,7 +3426,10 @@ s3_accel_out_l(uint16_t port, uint32_t val, void *p)
|
|||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
s3_accel_out_fifo_l(s3, port, val);
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_queue(s3, port, val, FIFO_OUT_DWORD);
|
||||
else
|
||||
s3_accel_out_fifo_l(s3, port, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
|
@ -3437,40 +3449,60 @@ s3_accel_in(uint16_t port, void *p)
|
|||
return s3->subsys_cntl;
|
||||
|
||||
case 0x8148: case 0x82e8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.cur_y & 0xff;
|
||||
case 0x8149: case 0x82e9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.cur_y >> 8;
|
||||
|
||||
case 0x8548: case 0x86e8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.cur_x & 0xff;
|
||||
case 0x8549: case 0x86e9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.cur_x >> 8;
|
||||
|
||||
case 0x8948: case 0x8ae8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.desty_axstp & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0x8949: case 0x8ae9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.desty_axstp >> 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8d48: case 0x8ee8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.destx_distp & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0x8d49: case 0x8ee9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.destx_distp >> 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9148: case 0x92e8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.err_term & 0xff;
|
||||
case 0x9149: case 0x92e9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.err_term >> 8;
|
||||
|
||||
case 0x9548: case 0x96e8:
|
||||
|
@ -3480,6 +3512,8 @@ s3_accel_in(uint16_t port, void *p)
|
|||
break;
|
||||
case 0x9549: case 0x96e9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.maj_axis_pcnt >> 8;
|
||||
}
|
||||
break;
|
||||
|
@ -3488,43 +3522,29 @@ s3_accel_in(uint16_t port, void *p)
|
|||
case 0x9948: case 0x9ae8:
|
||||
temp = 0; /* FIFO empty */
|
||||
if (s3_enable_fifo(s3)) {
|
||||
if (s3->accel.setup_fifo_slot) {
|
||||
temp = s3->accel.setup_fifo;
|
||||
s3->accel.setup_fifo = 0;
|
||||
} else if (s3->accel.draw_fifo_slot) {
|
||||
temp = s3->accel.draw_fifo;
|
||||
s3->accel.draw_fifo = 0;
|
||||
}
|
||||
if (!s3->blitter_busy)
|
||||
wake_fifo_thread(s3);
|
||||
if (FIFO_FULL)
|
||||
temp = 0xff;
|
||||
}
|
||||
return temp;
|
||||
case 0x8119:
|
||||
case 0x9949: case 0x9ae9:
|
||||
temp = 0;
|
||||
if (s3_enable_fifo(s3)) {
|
||||
if ((s3->accel.setup_fifo_slot && s3->accel.draw_fifo_slot) || s3->force_busy) {
|
||||
if (!s3->blitter_busy)
|
||||
wake_fifo_thread(s3);
|
||||
|
||||
if (!FIFO_EMPTY || s3->force_busy)
|
||||
temp |= 0x02; /*Hardware busy*/
|
||||
} else {
|
||||
else
|
||||
temp |= 0x04; /*FIFO empty*/
|
||||
s3->subsys_stat |= INT_FIFO_EMP;
|
||||
s3_update_irqs(s3);
|
||||
}
|
||||
|
||||
s3->force_busy = 0;
|
||||
|
||||
if (s3->chip >= S3_VISION964) {
|
||||
if (s3->accel.setup_fifo_slot > 8) {
|
||||
temp |= s3->accel.setup_fifo2;
|
||||
s3->accel.setup_fifo2 = 0;
|
||||
} else if (s3->accel.draw_fifo_slot > 8) {
|
||||
temp |= s3->accel.draw_fifo2;
|
||||
s3->accel.draw_fifo2 = 0;
|
||||
}
|
||||
if (FIFO_FULL)
|
||||
temp |= 0xf8; /*FIFO full*/
|
||||
}
|
||||
|
||||
if (s3->accel.setup_fifo_slot)
|
||||
s3->accel.setup_fifo_slot--;
|
||||
if (s3->accel.draw_fifo_slot)
|
||||
s3->accel.draw_fifo_slot--;
|
||||
|
||||
if (s3->data_available) {
|
||||
temp |= 0x01; /*Read Data available*/
|
||||
|
@ -3544,101 +3564,151 @@ s3_accel_in(uint16_t port, void *p)
|
|||
|
||||
case 0x9d48: case 0x9ee8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.short_stroke & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0x9d49: case 0x9ee9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.short_stroke >> 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa148: case 0xa2e8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.bkgd_color & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0xa149: case 0xa2e9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.bkgd_color >> 8;
|
||||
}
|
||||
break;
|
||||
case 0xa14a: case 0xa2ea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.bkgd_color >> 16;
|
||||
case 0xa14b: case 0xa2eb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.bkgd_color >> 24;
|
||||
|
||||
case 0xa548: case 0xa6e8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.frgd_color & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0xa549: case 0xa6e9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.frgd_color >> 8;
|
||||
}
|
||||
break;
|
||||
case 0xa54a: case 0xa6ea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.frgd_color >> 16;
|
||||
case 0xa54b: case 0xa6eb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.frgd_color >> 24;
|
||||
|
||||
case 0xa948: case 0xaae8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.wrt_mask & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0xa949: case 0xaae9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.wrt_mask >> 8;
|
||||
}
|
||||
break;
|
||||
case 0xa94a: case 0xaaea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.wrt_mask >> 16;
|
||||
case 0xa94b: case 0xaaeb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.wrt_mask >> 24;
|
||||
|
||||
case 0xad48: case 0xaee8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.rd_mask & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0xad49: case 0xaee9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.rd_mask >> 8;
|
||||
case 0xad4a: case 0xaeea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.rd_mask >> 16;
|
||||
case 0xad4b: case 0xaeeb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.rd_mask >> 24;
|
||||
|
||||
case 0xb148: case 0xb2e8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.color_cmp & 0xff;
|
||||
}
|
||||
break;
|
||||
case 0xb149: case 0xb2e9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.color_cmp >> 8;
|
||||
}
|
||||
break;
|
||||
case 0xb14a: case 0xb2ea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.color_cmp >> 16;
|
||||
case 0xb14b: case 0xb2eb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.color_cmp >> 24;
|
||||
|
||||
case 0xb548: case 0xb6e8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.bkgd_mix;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb948: case 0xbae8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.frgd_mix;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xbd48: case 0xbee8:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->accel.multifunc[0xf] & 0xf;
|
||||
switch (temp)
|
||||
{
|
||||
|
@ -3659,6 +3729,8 @@ s3_accel_in(uint16_t port, void *p)
|
|||
break;
|
||||
case 0xbd49: case 0xbee9:
|
||||
if (s3->chip >= S3_86C928) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->accel.multifunc[0xf] & 0xf;
|
||||
s3->accel.multifunc[0xf]++;
|
||||
switch (temp)
|
||||
|
@ -3680,45 +3752,73 @@ s3_accel_in(uint16_t port, void *p)
|
|||
break;
|
||||
|
||||
case 0xd148: case 0xd2e8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.ropmix & 0xff;
|
||||
|
||||
case 0xd149: case 0xd2e9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.ropmix >> 8;
|
||||
|
||||
case 0xe548: case 0xe6e8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_bg_color & 0xff;
|
||||
|
||||
case 0xe549: case 0xe6e9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_bg_color >> 8;
|
||||
|
||||
case 0xe54a: case 0xe6ea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_bg_color >> 16;
|
||||
|
||||
case 0xe54b: case 0xe6eb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_bg_color >> 24;
|
||||
|
||||
case 0xe948: case 0xeae8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_y & 0xff;
|
||||
|
||||
case 0xe949: case 0xeae9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_y >> 8;
|
||||
|
||||
case 0xe94a: case 0xeaea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_x & 0xff;
|
||||
|
||||
case 0xe94b: case 0xeaeb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_x >> 8;
|
||||
|
||||
case 0xed48: case 0xeee8:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_fg_color & 0xff;
|
||||
|
||||
case 0xed49: case 0xeee9:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_fg_color >> 8;
|
||||
|
||||
case 0xed4a: case 0xeeea:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_fg_color >> 16;
|
||||
|
||||
case 0xed4b: case 0xeeeb:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.pat_fg_color >> 24;
|
||||
|
||||
case 0xe148: case 0xe2e8:
|
||||
|
@ -3882,6 +3982,8 @@ s3_accel_in_w(uint16_t port, void *p)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->accel.short_stroke;
|
||||
}
|
||||
|
||||
|
@ -3950,10 +4052,13 @@ s3_accel_write(uint32_t addr, uint8_t val, void *p)
|
|||
|
||||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
if (svga->crtc[0x53] & 0x08)
|
||||
s3_accel_write_fifo(s3, addr & 0x1ffff, val);
|
||||
else
|
||||
|
||||
if (s3_enable_fifo(s3)) {
|
||||
if (svga->crtc[0x53] & 0x08)
|
||||
s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE);
|
||||
else
|
||||
s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE);
|
||||
} else
|
||||
s3_accel_write_fifo(s3, addr & 0xffff, val);
|
||||
}
|
||||
|
||||
|
@ -3966,9 +4071,12 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *p)
|
|||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
if (svga->crtc[0x53] & 0x08)
|
||||
s3_accel_write_fifo_w(s3, addr & 0x1ffff, val);
|
||||
else
|
||||
if (s3_enable_fifo(s3)) {
|
||||
if (svga->crtc[0x53] & 0x08)
|
||||
s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD);
|
||||
else
|
||||
s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD);
|
||||
} else
|
||||
s3_accel_write_fifo_w(s3, addr & 0xffff, val);
|
||||
}
|
||||
|
||||
|
@ -3981,9 +4089,12 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *p)
|
|||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
if (svga->crtc[0x53] & 0x08)
|
||||
s3_accel_write_fifo_l(s3, addr & 0x1ffff, val);
|
||||
else
|
||||
if (s3_enable_fifo(s3)) {
|
||||
if (svga->crtc[0x53] & 0x08)
|
||||
s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD);
|
||||
else
|
||||
s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD);
|
||||
} else
|
||||
s3_accel_write_fifo_l(s3, addr & 0xffff, val);
|
||||
}
|
||||
|
||||
|
@ -4068,6 +4179,8 @@ s3_accel_read_w(uint32_t addr, void *p)
|
|||
if (svga->crtc[0x53] & 0x08) {
|
||||
switch (addr & 0x1fffe) {
|
||||
case 0x811c:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
return s3->accel.short_stroke;
|
||||
|
||||
default:
|
||||
|
@ -4077,9 +4190,11 @@ s3_accel_read_w(uint32_t addr, void *p)
|
|||
return 0xffff;
|
||||
} else {
|
||||
if (addr & 0x8000) {
|
||||
if (addr == 0x811c)
|
||||
if (addr == 0x811c) {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->accel.short_stroke;
|
||||
else {
|
||||
} else {
|
||||
temp = s3_accel_read((addr & 0xfffe), p);
|
||||
temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8;
|
||||
}
|
||||
|
@ -4194,9 +4309,13 @@ s3_accel_read_l(uint32_t addr, void *p)
|
|||
break;
|
||||
|
||||
case 0x18080:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = 0;
|
||||
break;
|
||||
case 0x18088:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->videoengine.cntl;
|
||||
if (s3->bpp == 1) { /*The actual bpp is decided by the guest when idf is the same as odf*/
|
||||
if (s3->videoengine.idf == 0 && s3->videoengine.odf == 0) {
|
||||
|
@ -4211,18 +4330,28 @@ s3_accel_read_l(uint32_t addr, void *p)
|
|||
}
|
||||
break;
|
||||
case 0x1808c:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->videoengine.stretch_filt_const;
|
||||
break;
|
||||
case 0x18090:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->videoengine.src_dst_step;
|
||||
break;
|
||||
case 0x18094:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->videoengine.crop;
|
||||
break;
|
||||
case 0x18098:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->videoengine.src_base;
|
||||
break;
|
||||
case 0x1809c:
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
temp = s3->videoengine.dest_base;
|
||||
if (s3->videoengine.busy) {
|
||||
temp |= (1 << 31);
|
||||
|
@ -5002,104 +5131,6 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s3_fifo_slots(s3_t *s3)
|
||||
{
|
||||
switch (s3->accel.setup_fifo_slot) {
|
||||
case 1:
|
||||
s3->accel.setup_fifo |= 1;
|
||||
break;
|
||||
case 2:
|
||||
s3->accel.setup_fifo |= 3;
|
||||
break;
|
||||
case 3:
|
||||
s3->accel.setup_fifo |= 7;
|
||||
break;
|
||||
case 4:
|
||||
s3->accel.setup_fifo |= 0x0f;
|
||||
break;
|
||||
case 5:
|
||||
s3->accel.setup_fifo |= 0x1f;
|
||||
break;
|
||||
case 6:
|
||||
s3->accel.setup_fifo |= 0x3f;
|
||||
break;
|
||||
case 7:
|
||||
s3->accel.setup_fifo |= 0x7f;
|
||||
break;
|
||||
case 8:
|
||||
s3->accel.setup_fifo |= 0xff; /* FIFO full */
|
||||
break;
|
||||
case 9:
|
||||
s3->accel.setup_fifo |= 0xff;
|
||||
s3->accel.setup_fifo2 |= 0x08;
|
||||
break;
|
||||
case 10:
|
||||
s3->accel.setup_fifo |= 0xff;
|
||||
s3->accel.setup_fifo2 |= 0x18;
|
||||
break;
|
||||
case 11:
|
||||
s3->accel.setup_fifo |= 0xff;
|
||||
s3->accel.setup_fifo2 |= 0x38;
|
||||
break;
|
||||
case 12:
|
||||
s3->accel.setup_fifo |= 0xff;
|
||||
s3->accel.setup_fifo2 |= 0x78;
|
||||
break;
|
||||
case 13:
|
||||
s3->accel.setup_fifo |= 0xff;
|
||||
s3->accel.setup_fifo2 |= 0xf8; /* FIFO full */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (s3->accel.draw_fifo_slot) {
|
||||
case 1:
|
||||
s3->accel.draw_fifo |= 1;
|
||||
break;
|
||||
case 2:
|
||||
s3->accel.draw_fifo |= 3;
|
||||
break;
|
||||
case 3:
|
||||
s3->accel.draw_fifo |= 7;
|
||||
break;
|
||||
case 4:
|
||||
s3->accel.draw_fifo |= 0x0f;
|
||||
break;
|
||||
case 5:
|
||||
s3->accel.draw_fifo |= 0x1f;
|
||||
break;
|
||||
case 6:
|
||||
s3->accel.draw_fifo |= 0x3f;
|
||||
break;
|
||||
case 7:
|
||||
s3->accel.draw_fifo |= 0x7f;
|
||||
break;
|
||||
case 8:
|
||||
s3->accel.draw_fifo |= 0xff; /* FIFO full */
|
||||
break;
|
||||
case 9:
|
||||
s3->accel.draw_fifo |= 0xff;
|
||||
s3->accel.draw_fifo2 |= 0x08;
|
||||
break;
|
||||
case 10:
|
||||
s3->accel.draw_fifo |= 0xff;
|
||||
s3->accel.draw_fifo2 |= 0x18;
|
||||
break;
|
||||
case 11:
|
||||
s3->accel.draw_fifo |= 0xff;
|
||||
s3->accel.draw_fifo2 |= 0x38;
|
||||
break;
|
||||
case 12:
|
||||
s3->accel.draw_fifo |= 0xff;
|
||||
s3->accel.draw_fifo2 |= 0x78;
|
||||
break;
|
||||
case 13:
|
||||
s3->accel.draw_fifo |= 0xff;
|
||||
s3->accel.draw_fifo2 |= 0xf8; /* FIFO full */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv)
|
||||
{
|
||||
|
@ -5107,9 +5138,7 @@ s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_d
|
|||
s3->accel.ssv_len = ssv & 0x0f;
|
||||
s3->accel.ssv_dir = ssv & 0xe0;
|
||||
s3->accel.ssv_draw = ssv & 0x10;
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
|
||||
|
||||
if (s3_cpu_src(s3)) {
|
||||
return; /*Wait for data from CPU*/
|
||||
}
|
||||
|
@ -5280,9 +5309,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff;
|
||||
|
||||
s3->accel.sy = s3->accel.maj_axis_pcnt;
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
|
||||
|
||||
if (s3_cpu_src(s3)) {
|
||||
return; /*Wait for data from CPU*/
|
||||
}
|
||||
|
@ -5464,8 +5491,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
|
||||
s3->accel.dest = dstbase + s3->accel.cy * s3->width;
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
|
||||
if (s3_cpu_src(s3)) {
|
||||
s3->data_available = 0;
|
||||
return; /*Wait for data from CPU*/
|
||||
|
@ -5593,8 +5618,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
|
||||
polygon_setup(s3);
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
|
||||
|
||||
end_y1 = s3->accel.desty_axstp;
|
||||
|
@ -5707,8 +5730,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
|
||||
s3->accel.src = srcbase + s3->accel.cy * s3->width;
|
||||
s3->accel.dest = dstbase + s3->accel.dy * s3->width;
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
}
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && !cpu_input) {
|
||||
|
@ -5886,8 +5907,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
s3->accel.cy = s3->accel.dy & 7;
|
||||
|
||||
s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width);
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
}
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && !cpu_input) {
|
||||
|
@ -6010,8 +6029,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
s3->accel.cy = s3->accel.cur_y;
|
||||
if (s3->accel.cur_y_bit12)
|
||||
s3->accel.cy |= ~0xfff;
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
}
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
|
||||
|
@ -6104,8 +6121,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
|
||||
polygon_setup(s3);
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
|
||||
|
||||
end_y1 = s3->accel.desty_axstp;
|
||||
|
@ -6217,8 +6232,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
|||
s3->accel.dest = dstbase + (s3->accel.dy * s3->width);
|
||||
s3->accel.src = srcbase + (s3->accel.cy * s3->width);
|
||||
s3->accel.pattern = (s3->accel.py * s3->width);
|
||||
|
||||
s3_fifo_slots(s3);
|
||||
}
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
|
||||
|
@ -6481,6 +6494,56 @@ s3_pci_write(int func, int addr, uint8_t val, void *p)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fifo_thread(void *param)
|
||||
{
|
||||
s3_t *s3 = (s3_t *)param;
|
||||
uint64_t start_time, end_time;
|
||||
|
||||
while (s3->fifo_thread_run) {
|
||||
thread_set_event(s3->fifo_not_full_event);
|
||||
thread_wait_event(s3->wake_fifo_thread, -1);
|
||||
thread_reset_event(s3->wake_fifo_thread);
|
||||
s3->blitter_busy = 1;
|
||||
while (!FIFO_EMPTY) {
|
||||
start_time = plat_timer_read();
|
||||
fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK];
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE) {
|
||||
case FIFO_WRITE_BYTE:
|
||||
s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_WRITE_WORD:
|
||||
s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_WRITE_DWORD:
|
||||
s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_OUT_BYTE:
|
||||
s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_OUT_WORD:
|
||||
s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_OUT_DWORD:
|
||||
s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
}
|
||||
|
||||
s3->fifo_read_idx++;
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
thread_set_event(s3->fifo_not_full_event);
|
||||
|
||||
end_time = plat_timer_read();
|
||||
s3->blitter_time += (end_time - start_time);
|
||||
}
|
||||
s3->blitter_busy = 0;
|
||||
s3->subsys_stat |= INT_FIFO_EMP;
|
||||
s3_update_irqs(s3);
|
||||
}
|
||||
}
|
||||
|
||||
static int vram_sizes[] =
|
||||
{
|
||||
|
@ -7264,6 +7327,11 @@ static void *s3_init(const device_t *info)
|
|||
s3->i2c = i2c_gpio_init("ddc_s3");
|
||||
s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c));
|
||||
|
||||
s3->wake_fifo_thread = thread_create_event();
|
||||
s3->fifo_not_full_event = thread_create_event();
|
||||
s3->fifo_thread_run = 1;
|
||||
s3->fifo_thread = thread_create(fifo_thread, s3);
|
||||
|
||||
return s3;
|
||||
}
|
||||
|
||||
|
@ -7426,6 +7494,12 @@ static void s3_close(void *p)
|
|||
{
|
||||
s3_t *s3 = (s3_t *)p;
|
||||
|
||||
s3->fifo_thread_run = 0;
|
||||
thread_set_event(s3->wake_fifo_thread);
|
||||
thread_wait(s3->fifo_thread);
|
||||
thread_destroy_event(s3->fifo_not_full_event);
|
||||
thread_destroy_event(s3->wake_fifo_thread);
|
||||
|
||||
svga_close(&s3->svga);
|
||||
|
||||
ddc_close(s3->ddc);
|
||||
|
|
Loading…
Add table
Reference in a new issue