video/s3virge.cpp: initial steps for major structural refactoring
- flatten s3dvirge.s3d down to one struct (m_bitblt), get rid of src_stride and dest_stride fns, update QA - RAMDAC runs in unpacked mode if streams processor disabled - add primary streams stride override, fix Ubuntu flavor gfxs - move NOP logic in dequeue fn - merge draw & command timers in one, simplify state logic, workaround GFX corruption issue - refine a bit FIFO status - base conversion to FIFO
This commit is contained in:
parent
de5879d489
commit
3b5e60b420
@ -31,7 +31,8 @@ void virge_pci_device::mmio_map(address_map& map)
|
||||
// image transfer ports
|
||||
map(0x0000,0x7fff).w(m_vga, FUNC(s3virge_vga_device::image_xfer));
|
||||
|
||||
//map(0x8180,0x81ff) primary/secondary stream control
|
||||
//map(0x8000,0x8043) PCI Configuration Space regs
|
||||
map(0x8180,0x81ff).m(m_vga, FUNC(s3virge_vga_device::streams_control_map));
|
||||
|
||||
//map(0x8200,0x821f) memory port controller
|
||||
//map(0x8220,0x8227) DMA control
|
||||
@ -39,23 +40,33 @@ void virge_pci_device::mmio_map(address_map& map)
|
||||
// MMIO address map
|
||||
map(0x83b0,0x83df).m(m_vga, FUNC(s3virge_vga_device::io_map));
|
||||
map(0x8504,0x8507).rw(m_vga, FUNC(s3virge_vga_device::s3d_sub_status_r), FUNC(s3virge_vga_device::s3d_sub_control_w));
|
||||
// TODO: writeable
|
||||
map(0x850c,0x850f).r(m_vga, FUNC(s3virge_vga_device::s3d_func_ctrl_r));
|
||||
|
||||
//map(0x8580,0x858b) video DMA
|
||||
//map(0x8590,0x859f) command DMA
|
||||
|
||||
// S3D engine registers
|
||||
map(0xa000,0xb7ff).rw(m_vga, FUNC(s3virge_vga_device::s3d_register_r), FUNC(s3virge_vga_device::s3d_register_w));
|
||||
map(0xa000,0xb7ff).m(m_vga, FUNC(s3virge_vga_device::s3d_register_map));
|
||||
|
||||
// alternate image transfer ports
|
||||
map(0xd000,0xefff).w(m_vga, FUNC(s3virge_vga_device::image_xfer));
|
||||
|
||||
//map(0xff00, 0xff43) LPB control
|
||||
//map(0xff00, 0xff5f) LPB Local Peripheral Bus control
|
||||
//map(0xff1c, 0xff1f) LPB GIP/GOP General Input/Output Port (for OEM implementations)
|
||||
//map(0xff20, 0xff23) Serial Port Register (DDC/I2C, pins 205-206, aliased at I/O ports $e2 or $e8)
|
||||
//map(0xff24, 0xff27) LPB Video Input Window Size
|
||||
//map(0xff28, 0xff2b) LPB Video Data Offsets
|
||||
//map(0xff2c, 0xff2f) LPB Horizontal Decimation Control Register
|
||||
//map(0xff30, 0xff33) LPB Vertical Decimation Control Register
|
||||
//map(0xff34, 0xff37) LPB Line Stride
|
||||
//map(0xff40, 0xff5f) LPB Output FIFO Register
|
||||
}
|
||||
|
||||
void virge_pci_device::lfb_map(address_map& map)
|
||||
{
|
||||
map(0x0, 0x00ffffff).rw(m_vga, FUNC(s3virge_vga_device::fb_r), FUNC(s3virge_vga_device::fb_w));
|
||||
// NOTE: upper mirror is i/f for BE hosts.
|
||||
map(0x0, 0x00ffffff).mirror(0x02000000).rw(m_vga, FUNC(s3virge_vga_device::fb_r), FUNC(s3virge_vga_device::fb_w));
|
||||
}
|
||||
|
||||
void virge_pci_device::config_map(address_map &map)
|
||||
@ -152,6 +163,12 @@ void virge_pci_device::device_start()
|
||||
add_map(64 * 1024 * 1024, M_MEM | M_DISABLED, FUNC(virge_pci_device::lfb_map));
|
||||
set_map_address(0, 0x70000000);
|
||||
|
||||
command = 0x0000;
|
||||
// DAC SNP / BME / MEM / I/O
|
||||
command_mask = 0x27;
|
||||
// medium DEVSELB
|
||||
status = 0x0200;
|
||||
|
||||
remap_cb();
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(virge_pci_device::postload), this));
|
||||
}
|
||||
@ -174,18 +191,23 @@ void virgedx_pci_device::device_start()
|
||||
void virge_pci_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
|
||||
uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space)
|
||||
{
|
||||
memory_space->install_readwrite_handler(0xa0000, 0xbffff, read8sm_delegate(*this, FUNC(virge_pci_device::vram_r)), write8sm_delegate(*this, FUNC(virge_pci_device::vram_w)));
|
||||
|
||||
io_space->install_device(0x03b0, 0x03df, *this, &virge_pci_device::legacy_io_map);
|
||||
|
||||
// NOTE: this looks unrelated to the linear addressing
|
||||
// xubuntu 6.10 and BeOS 3.x definitely wants it this way.
|
||||
if(downcast<s3virge_vga_device *>(m_vga.target())->is_new_mmio_active())
|
||||
if (BIT(command, 1))
|
||||
{
|
||||
const u32 get_bar_address = get_vga_linear_address() | 0x01000000;
|
||||
memory_space->install_readwrite_handler(0xa0000, 0xbffff, read8sm_delegate(*this, FUNC(virge_pci_device::vram_r)), write8sm_delegate(*this, FUNC(virge_pci_device::vram_w)));
|
||||
// NOTE: this looks unrelated to the linear addressing
|
||||
// xubuntu 6.10 and BeOS 3.x definitely wants it this way.
|
||||
if(downcast<s3virge_vga_device *>(m_vga.target())->is_new_mmio_active())
|
||||
{
|
||||
u32 get_bar_address = get_vga_linear_address() | 0x01000000;
|
||||
memory_space->install_device(get_bar_address, get_bar_address | 0xffff, *this, &virge_pci_device::mmio_map);
|
||||
|
||||
memory_space->install_device(get_bar_address, get_bar_address | 0xffff, *this, &virge_pci_device::mmio_map);
|
||||
get_bar_address |= 0x02000000;
|
||||
memory_space->install_device(get_bar_address, get_bar_address | 0xffff, *this, &virge_pci_device::mmio_map);
|
||||
}
|
||||
}
|
||||
|
||||
if (BIT(command, 0))
|
||||
io_space->install_device(0x03b0, 0x03df, *this, &virge_pci_device::legacy_io_map);
|
||||
}
|
||||
|
||||
void virge_pci_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -1161,7 +1161,7 @@ void vga_device::sequencer_map(address_map &map)
|
||||
vga.sequencer.char_sel.A = (((data & 0xc) >> 2)<<1) | ((data & 0x20) >> 5);
|
||||
vga.sequencer.char_sel.B = (((data & 0x3) >> 0)<<1) | ((data & 0x10) >> 4);
|
||||
if(data)
|
||||
popmessage("Char SEL checker, contact MAMEdev (%02x %02x)\n",vga.sequencer.char_sel.A,vga.sequencer.char_sel.B);
|
||||
popmessage("Char SEL checker (%02x %02x)\n",vga.sequencer.char_sel.A,vga.sequencer.char_sel.B);
|
||||
})
|
||||
);
|
||||
// Sequencer Memory Mode Register
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,42 +34,28 @@ public:
|
||||
uint32_t s3d_func_ctrl_r();
|
||||
// void s3d_func_ctrl_w(offs_t offset, uint32_t data, u32 mem_mask = ~0);
|
||||
|
||||
uint32_t s3d_register_r(offs_t offset);
|
||||
void s3d_register_w(offs_t offset, uint32_t data);
|
||||
void s3d_register_map(address_map &map);
|
||||
|
||||
void image_xfer(uint32_t data)
|
||||
void streams_control_map(address_map &map);
|
||||
|
||||
void image_xfer(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
// if(s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x00000080)
|
||||
{
|
||||
// logerror("IMG Xfer:(%u):%08x X:%u(%u) Y:%u(%u)\n",s3virge.s3d.bitblt_step_count,data,s3virge.s3d.bitblt_x_current,s3virge.s3d.bitblt_width,s3virge.s3d.bitblt_y_current,s3virge.s3d.bitblt_height);
|
||||
s3virge.s3d.image_xfer = data;
|
||||
bitblt_step();
|
||||
}
|
||||
if (mem_mask != 0xffff'ffff)
|
||||
logerror("Warning: image_xfer access with non-32 parallelism %08x & %08x\n", data, mem_mask);
|
||||
|
||||
m_xfer_fifo.enqueue(data);
|
||||
//machine().scheduler().synchronize();
|
||||
}
|
||||
|
||||
uint32_t get_linear_address() { return s3virge.linear_address; }
|
||||
void set_linear_address(uint32_t addr) { s3virge.linear_address = addr; }
|
||||
uint8_t get_linear_address_size() { return s3virge.linear_address_size; }
|
||||
uint32_t get_linear_address_size_full() { return s3virge.linear_address_size_full; }
|
||||
bool is_linear_address_active() { return s3virge.linear_address_enable; }
|
||||
uint32_t get_linear_address() { return m_linear_address; }
|
||||
void set_linear_address(uint32_t addr) { m_linear_address = addr; }
|
||||
uint8_t get_linear_address_size() { return m_linear_address_size; }
|
||||
uint32_t get_linear_address_size_full() { return m_linear_address_size_full; }
|
||||
bool is_linear_address_active() { return m_linear_address_enable; }
|
||||
bool is_new_mmio_active() { return s3.cr53 & 0x08; }
|
||||
uint16_t src_stride()
|
||||
{
|
||||
return (s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_DEST_SRC_STR] >> 0) & 0xfff8;
|
||||
}
|
||||
uint16_t dest_stride()
|
||||
{
|
||||
// if((s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x0000001c) == 0x08)
|
||||
// {
|
||||
// popmessage("Stride=%08x",(((s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_DEST_SRC_STR] >> 16) & 0xfff8) / 3)
|
||||
// + ((s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_DEST_SRC_STR] >> 16) & 0xfff8));
|
||||
// return (((s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_DEST_SRC_STR] >> 16) & 0xfff8) / 3)
|
||||
// + ((s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_DEST_SRC_STR] >> 16) & 0xfff8);
|
||||
// }
|
||||
// else
|
||||
return (s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_DEST_SRC_STR] >> 16) & 0xfff8;
|
||||
}
|
||||
|
||||
// has no 8514/A device
|
||||
// FIXME: should map this dependency in machine_config
|
||||
ibm8514a_device* get_8514() { fatalerror("s3virge requested non-existent 8514/A device\n"); return nullptr; }
|
||||
|
||||
protected:
|
||||
@ -100,9 +86,10 @@ protected:
|
||||
OP_3DTRI
|
||||
};
|
||||
|
||||
enum
|
||||
enum s3d_state_t
|
||||
{
|
||||
S3D_STATE_IDLE = 0,
|
||||
S3D_STATE_COMMAND_RX,
|
||||
S3D_STATE_BITBLT,
|
||||
S3D_STATE_2DLINE,
|
||||
S3D_STATE_2DPOLY,
|
||||
@ -110,81 +97,75 @@ protected:
|
||||
S3D_STATE_3DPOLY
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
S3D_REG_SRC_BASE = 0xd4/4,
|
||||
S3D_REG_DEST_BASE = 0xd8/4,
|
||||
S3D_REG_CLIP_L_R = 0xdc/4,
|
||||
S3D_REG_CLIP_T_B = 0xe0/4,
|
||||
S3D_REG_DEST_SRC_STR = 0xe4/4,
|
||||
S3D_REG_MONO_PAT_0 = 0xe8/4,
|
||||
S3D_REG_MONO_PAT_1 = 0xec/4,
|
||||
S3D_REG_PAT_BG_CLR = 0xf0/4,
|
||||
S3D_REG_PAT_FG_CLR = 0xf4/4,
|
||||
S3D_REG_SRC_BG_CLR = 0xf8/4,
|
||||
S3D_REG_SRC_FG_CLR = 0xfc/4,
|
||||
S3D_REG_COMMAND = 0x100/4,
|
||||
S3D_REG_RWIDTH_HEIGHT = 0x104/4,
|
||||
S3D_REG_RSRC_XY = 0x108/4,
|
||||
S3D_REG_RDEST_XY = 0x10c/4
|
||||
};
|
||||
struct {
|
||||
u8 psidf = 0;
|
||||
u8 pshfc = 0;
|
||||
u16 primary_stride = 0;
|
||||
} m_streams;
|
||||
|
||||
u32 m_interrupt_enable = 0;
|
||||
|
||||
bool m_linear_address_enable = false;
|
||||
u32 m_linear_address = 0;
|
||||
u8 m_linear_address_size = 0;
|
||||
u32 m_linear_address_size_full = 0;
|
||||
|
||||
u8 m_cr66 = 0;
|
||||
|
||||
// util::fifo<u32, 16 * 15> m_bitblt_fifo;
|
||||
// TODO: sketchy, command pipeline size is unclear
|
||||
util::fifo<u32, 0x8000> m_bitblt_fifo;
|
||||
util::fifo<u32, 0x8000> m_xfer_fifo;
|
||||
// TODO: sketchy type, verify implications of using a struct class with util::fifo
|
||||
// (may be required if we want to glue in a "execute command" insert flag)
|
||||
u32 m_bitblt_latch[15]{};
|
||||
s3d_state_t m_s3d_state = S3D_STATE_IDLE;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t linear_address;
|
||||
uint8_t linear_address_size;
|
||||
uint32_t linear_address_size_full;
|
||||
bool linear_address_enable;
|
||||
uint32_t interrupt_enable;
|
||||
bool xfer_mode = false;
|
||||
|
||||
struct
|
||||
{
|
||||
int state;
|
||||
bool busy;
|
||||
struct
|
||||
{
|
||||
uint32_t reg[256];
|
||||
int op_type;
|
||||
} cmd_fifo[16];
|
||||
int cmd_fifo_next_ptr; // command added here in FIFO
|
||||
int cmd_fifo_current_ptr; // command currently being processed in FIFO
|
||||
int cmd_fifo_slots_free;
|
||||
u8 pattern[0xc0]{};
|
||||
|
||||
uint8_t pattern[0xc0];
|
||||
uint32_t reg[5][256];
|
||||
u16 x_src = 0;
|
||||
u16 y_src = 0;
|
||||
u16 x_dst = 0;
|
||||
u16 y_dst = 0;
|
||||
s16 x_current = 0;
|
||||
s16 y_current = 0;
|
||||
s16 x_src_current = 0;
|
||||
s16 y_src_current = 0;
|
||||
s8 pat_x = 0;
|
||||
s8 pat_y = 0;
|
||||
u16 height = 0;
|
||||
u16 width = 0;
|
||||
u32 step_count = 0;
|
||||
u64 mono_pattern = 0;
|
||||
u32 current_pixel = 0;
|
||||
// current position in a pixel (for packed 24bpp colour image transfers)
|
||||
u32 pixel_pos = 0;
|
||||
// source data via image transfer ports
|
||||
u32 image_xfer = 0;
|
||||
u16 clip_l = 0;
|
||||
u16 clip_r = 0;
|
||||
u16 clip_t = 0;
|
||||
u16 clip_b = 0;
|
||||
u32 command = 0;
|
||||
u32 src_base = 0;
|
||||
u32 dest_base = 0;
|
||||
u32 pat_bg_clr = 0;
|
||||
u32 pat_fg_clr = 0;
|
||||
u32 src_bg_clr = 0;
|
||||
u32 src_fg_clr = 0;
|
||||
u16 dest_stride = 0;
|
||||
u16 src_stride = 0;
|
||||
} m_bitblt;
|
||||
|
||||
// BitBLT command state
|
||||
uint16_t bitblt_x_src;
|
||||
uint16_t bitblt_y_src;
|
||||
uint16_t bitblt_x_dst;
|
||||
uint16_t bitblt_y_dst;
|
||||
int16_t bitblt_x_current;
|
||||
int16_t bitblt_y_current;
|
||||
int16_t bitblt_x_src_current;
|
||||
int16_t bitblt_y_src_current;
|
||||
int8_t bitblt_pat_x;
|
||||
int8_t bitblt_pat_y;
|
||||
uint16_t bitblt_height;
|
||||
uint16_t bitblt_width;
|
||||
uint32_t bitblt_step_count;
|
||||
uint64_t bitblt_mono_pattern;
|
||||
uint32_t bitblt_current_pixel;
|
||||
uint32_t bitblt_pixel_pos; // current position in a pixel (for packed 24bpp colour image transfers)
|
||||
uint32_t image_xfer; // source data via image transfer ports
|
||||
uint16_t clip_l;
|
||||
uint16_t clip_r;
|
||||
uint16_t clip_t;
|
||||
uint16_t clip_b;
|
||||
} s3d;
|
||||
} s3virge;
|
||||
TIMER_CALLBACK_MEMBER(op_timer_cb);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(draw_step_tick);
|
||||
|
||||
inline void write_pixel32(uint32_t base, uint16_t x, uint16_t y, uint32_t val);
|
||||
inline void write_pixel24(uint32_t base, uint16_t x, uint16_t y, uint32_t val);
|
||||
inline void write_pixel16(uint32_t base, uint16_t x, uint16_t y, uint16_t val);
|
||||
inline void write_pixel8(uint32_t base, uint16_t x, uint16_t y, uint8_t val);
|
||||
inline uint32_t read_pixel32(uint32_t base, uint16_t x, uint16_t y, u16 stride_select);
|
||||
inline uint32_t read_pixel24(uint32_t base, uint16_t x, uint16_t y, u16 stride_select);
|
||||
inline uint16_t read_pixel16(uint32_t base, uint16_t x, uint16_t y, u16 stride_select);
|
||||
inline uint8_t read_pixel8(uint32_t base, uint16_t x, uint16_t y, u16 stride_select);
|
||||
@ -196,9 +177,8 @@ protected:
|
||||
|
||||
virtual void s3_define_video_mode(void) override;
|
||||
|
||||
// has no 8514/A device
|
||||
private:
|
||||
emu_timer* m_draw_timer;
|
||||
emu_timer *m_op_timer;
|
||||
void bitblt_step();
|
||||
void bitblt_colour_step();
|
||||
void bitblt_monosrc_step();
|
||||
@ -206,9 +186,12 @@ private:
|
||||
void poly2d_step();
|
||||
void line3d_step();
|
||||
void poly3d_step();
|
||||
void add_command(int cmd_type);
|
||||
void command_start();
|
||||
void add_command(u8 cmd_type);
|
||||
void command_enqueue(u8 op_type);
|
||||
void command_dequeue(u8 op_type);
|
||||
void command_finish();
|
||||
|
||||
void s3d_reset();
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user