summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/isa/s3virge.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/isa/s3virge.h')
-rw-r--r--src/devices/bus/isa/s3virge.h170
1 files changed, 160 insertions, 10 deletions
diff --git a/src/devices/bus/isa/s3virge.h b/src/devices/bus/isa/s3virge.h
index daa7607ef0c..9b9716b88f2 100644
--- a/src/devices/bus/isa/s3virge.h
+++ b/src/devices/bus/isa/s3virge.h
@@ -35,26 +35,56 @@ public:
DECLARE_WRITE8_MEMBER(fb_w);
DECLARE_READ32_MEMBER(s3d_sub_status_r);
DECLARE_WRITE32_MEMBER(s3d_sub_control_w);
+ DECLARE_READ32_MEMBER(s3d_func_ctrl_r);
DECLARE_READ32_MEMBER(s3d_register_r);
DECLARE_WRITE32_MEMBER(s3d_register_w);
+ DECLARE_WRITE32_MEMBER(image_xfer)
+ {
+// 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();
+ }
+ }
+
uint16_t get_crtc_port() { return (vga.miscellaneous_output&1)?0x3d0:0x3b0; }
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; }
bool is_linear_address_active() { return s3virge.linear_address_enable; }
bool is_new_mmio_active() { return s3.cr53 & 0x08; }
+ 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;
+ }
ibm8514a_device* get_8514() { fatalerror("s3virge requested non-existent 8514/A device\n"); return nullptr; }
+ enum
+ {
+ TIMER_DRAW_STEP = 10
+ };
+
+
protected:
s3virge_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
-
+ virtual uint16_t offset() override;
+
enum
{
LAW_64K = 0,
@@ -63,6 +93,7 @@ protected:
LAW_4MB
};
+ // register groups
enum
{
OP_BITBLT = 0,
@@ -72,6 +103,35 @@ protected:
OP_3DTRI
};
+ enum
+ {
+ S3D_STATE_IDLE = 0,
+ S3D_STATE_BITBLT,
+ S3D_STATE_2DLINE,
+ S3D_STATE_2DPOLY,
+ S3D_STATE_3DLINE,
+ 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
{
uint32_t linear_address;
@@ -82,19 +142,109 @@ protected:
struct
{
- uint32_t src_base[5];
- uint32_t dest_base[5];
- uint32_t command[5];
- uint16_t source_x[5];
- uint16_t source_y[5];
- uint16_t dest_x[5];
- uint16_t dest_y[5];
- uint16_t rect_width[5];
- uint16_t rect_height[5];
+ 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;
+
+ uint8_t pattern[0xc0];
+ uint32_t reg[5][256];
+
+ // 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;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ void write_pixel32(uint32_t base, uint16_t x, uint16_t y, uint32_t val)
+ {
+ if(s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x00000002)
+ if(x < s3virge.s3d.clip_l || x > s3virge.s3d.clip_r || y < s3virge.s3d.clip_t || y > s3virge.s3d.clip_b)
+ return;
+ vga.memory[(base + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] = val & 0xff;
+ vga.memory[(base + 1 + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] = (val >> 8) & 0xff;
+ vga.memory[(base + 2 + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] = (val >> 16) & 0xff;
+ vga.memory[(base + 3 + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] = (val >> 24) & 0xff;
+ }
+ void write_pixel24(uint32_t base, uint16_t x, uint16_t y, uint32_t val)
+ {
+ if(s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x00000002)
+ if(x < s3virge.s3d.clip_l || x > s3virge.s3d.clip_r || y < s3virge.s3d.clip_t || y > s3virge.s3d.clip_b)
+ return;
+ vga.memory[(base + (x*3) + (y*dest_stride())) % vga.svga_intf.vram_size] = val & 0xff;
+ vga.memory[(base + 1 + (x*3) + (y*dest_stride())) % vga.svga_intf.vram_size] = (val >> 8) & 0xff;
+ vga.memory[(base + 2 + (x*3) + (y*dest_stride())) % vga.svga_intf.vram_size] = (val >> 16) & 0xff;
+ }
+ void write_pixel16(uint32_t base, uint16_t x, uint16_t y, uint16_t val)
+ {
+ if(s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x00000002)
+ if(x < s3virge.s3d.clip_l || x > s3virge.s3d.clip_r || y < s3virge.s3d.clip_t || y > s3virge.s3d.clip_b)
+ return;
+ vga.memory[(base + (x*2) + (y*dest_stride())) % vga.svga_intf.vram_size] = val & 0xff;
+ vga.memory[(base + 1 + (x*2) + (y*dest_stride())) % vga.svga_intf.vram_size] = (val >> 8) & 0xff;
+ }
+ void write_pixel8(uint32_t base, uint16_t x, uint16_t y, uint8_t val)
+ {
+ if(s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x00000002)
+ if(x < s3virge.s3d.clip_l || x > s3virge.s3d.clip_r || y < s3virge.s3d.clip_t || y > s3virge.s3d.clip_b)
+ return;
+ vga.memory[(base + x + (y*dest_stride())) % vga.svga_intf.vram_size] = val;
+ }
+ uint32_t read_pixel32(uint32_t base, uint16_t x, uint16_t y)
+ {
+ return (vga.memory[(base + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] << 24) | (vga.memory[(base + 1 + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] << 16)
+ | (vga.memory[(base + 2 + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size] << 8) | vga.memory[(base + 3 + (x*4) + (y*dest_stride())) % vga.svga_intf.vram_size];
+ }
+ uint32_t read_pixel24(uint32_t base, uint16_t x, uint16_t y)
+ {
+ return (vga.memory[(base + (x*3) + (y*dest_stride())) % vga.svga_intf.vram_size]) | (vga.memory[(base + 1 + (x*3) + (y*dest_stride())) % vga.svga_intf.vram_size] << 8)
+ | (vga.memory[(base + 2 + (x*3) + (y*dest_stride())) % vga.svga_intf.vram_size] << 16);
+ }
+ uint16_t read_pixel16(uint32_t base, uint16_t x, uint16_t y)
+ {
+ return (vga.memory[(base + (x*2) + (y*dest_stride()) % vga.svga_intf.vram_size)]) | (vga.memory[(base + 1 + (x*2) + (y*dest_stride())) % vga.svga_intf.vram_size] << 8);
+ }
+ uint8_t read_pixel8(uint32_t base, uint16_t x, uint16_t y)
+ {
+ return vga.memory[(base + x + (y*dest_stride())) % vga.svga_intf.vram_size];
+ }
+ uint32_t GetROP(uint8_t rop, uint32_t src, uint32_t dst, uint32_t pat);
+ bool advance_pixel();
private:
+ emu_timer* m_draw_timer;
+ void bitblt_step();
+ void bitblt_colour_step();
+ void bitblt_monosrc_step();
+ void add_command(int cmd_type);
+ void command_start();
+ void command_finish();
+
virtual uint8_t s3_crtc_reg_read(uint8_t index);
virtual void s3_define_video_mode(void);
virtual void s3_crtc_reg_write(uint8_t index, uint8_t data);