mirror of
https://github.com/holub/mame
synced 2025-05-21 13:18:56 +03:00
Added a basic FIFO mechanism, added Abort mechanism
This commit is contained in:
parent
d719220c6e
commit
dfa4dc5d77
@ -7,12 +7,198 @@
|
||||
#include "emu.h"
|
||||
#include "video/h63484.h"
|
||||
|
||||
#define LOG 1
|
||||
|
||||
typedef struct _h63484_state h63484_state;
|
||||
struct _h63484_state
|
||||
{
|
||||
h63484_display_pixels_func display_func;
|
||||
screen_device *screen; /* screen */
|
||||
|
||||
UINT8 vram[0x40000];
|
||||
UINT8 ar;
|
||||
UINT8 vreg[0x100];
|
||||
UINT8 sr;
|
||||
|
||||
UINT8 fifo[16]; /* FIFO data queue */
|
||||
int fifo_flag[16]; /* FIFO flag queue */
|
||||
int fifo_ptr; /* FIFO pointer */
|
||||
int fifo_dir; /* FIFO direction */
|
||||
|
||||
UINT8 cr;
|
||||
UINT8 pr[17]; /* parameter byte register */
|
||||
int param_ptr; /* parameter pointer */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FIFO_READ = 0,
|
||||
FIFO_WRITE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FIFO_EMPTY = -1,
|
||||
FIFO_PARAMETER,
|
||||
FIFO_COMMAND
|
||||
};
|
||||
|
||||
#define H63484_SR_CER 0x80 // Command Error
|
||||
#define H63484_SR_ARD 0x40 // Area Detect
|
||||
#define H63484_SR_CED 0x20 // Command End
|
||||
#define H63484_SR_LPD 0x10 // Light Pen Strobe Detect
|
||||
#define H63484_SR_RFF 0x08 // Read FIFO Full
|
||||
#define H63484_SR_RFR 0x04 // Read FIFO Ready
|
||||
#define H63484_SR_WFR 0x02 // Write FIFO Ready
|
||||
#define H63484_SR_WFE 0x01 // Write FIFO Empty
|
||||
|
||||
|
||||
#define CCR 0x02
|
||||
// Command Control
|
||||
#define ABT 0x8000
|
||||
|
||||
|
||||
static const char *const acrtc_regnames[0x100/2] =
|
||||
{
|
||||
"FIFO Entry", // 0x00
|
||||
"Command Control (CCR)", // 0x02
|
||||
"Operation Mode (OMR)", // 0x04
|
||||
"Display Control (DCR)", // 0x06
|
||||
"(Undefined)", // 0x08
|
||||
"(Undefined)", // 0x0a
|
||||
"(Undefined)", // 0x0c
|
||||
"(Undefined)", // 0x0e
|
||||
"(Undefined)", // 0x10
|
||||
"(Undefined)", // 0x12
|
||||
"(Undefined)", // 0x14
|
||||
"(Undefined)", // 0x16
|
||||
"(Undefined)", // 0x18
|
||||
"(Undefined)", // 0x1a
|
||||
"(Undefined)", // 0x1c
|
||||
"(Undefined)", // 0x1e
|
||||
"(Undefined)", // 0x20
|
||||
"(Undefined)", // 0x22
|
||||
"(Undefined)", // 0x24
|
||||
"(Undefined)", // 0x26
|
||||
"(Undefined)", // 0x28
|
||||
"(Undefined)", // 0x2a
|
||||
"(Undefined)", // 0x2c
|
||||
"(Undefined)", // 0x2e
|
||||
"(Undefined)", // 0x30
|
||||
"(Undefined)", // 0x32
|
||||
"(Undefined)", // 0x34
|
||||
"(Undefined)", // 0x36
|
||||
"(Undefined)", // 0x38
|
||||
"(Undefined)", // 0x3a
|
||||
"(Undefined)", // 0x3c
|
||||
"(Undefined)", // 0x3e
|
||||
"(Undefined)", // 0x40
|
||||
"(Undefined)", // 0x42
|
||||
"(Undefined)", // 0x44
|
||||
"(Undefined)", // 0x46
|
||||
"(Undefined)", // 0x48
|
||||
"(Undefined)", // 0x4a
|
||||
"(Undefined)", // 0x4c
|
||||
"(Undefined)", // 0x4e
|
||||
"(Undefined)", // 0x50
|
||||
"(Undefined)", // 0x52
|
||||
"(Undefined)", // 0x54
|
||||
"(Undefined)", // 0x56
|
||||
"(Undefined)", // 0x58
|
||||
"(Undefined)", // 0x5a
|
||||
"(Undefined)", // 0x5c
|
||||
"(Undefined)", // 0x5e
|
||||
"(Undefined)", // 0x60
|
||||
"(Undefined)", // 0x62
|
||||
"(Undefined)", // 0x64
|
||||
"(Undefined)", // 0x66
|
||||
"(Undefined)", // 0x68
|
||||
"(Undefined)", // 0x6a
|
||||
"(Undefined)", // 0x6c
|
||||
"(Undefined)", // 0x6e
|
||||
"(Undefined)", // 0x70
|
||||
"(Undefined)", // 0x72
|
||||
"(Undefined)", // 0x74
|
||||
"(Undefined)", // 0x76
|
||||
"(Undefined)", // 0x78
|
||||
"(Undefined)", // 0x7a
|
||||
"(Undefined)", // 0x7c
|
||||
"(Undefined)", // 0x7e
|
||||
"Raster Count (RCR)", // 0x80
|
||||
"Horizontal Sync (HSR)", // 0x82
|
||||
"Horizontal Display (HDR)", // 0x84
|
||||
"Vertical Sync (VSR)", // 0x86
|
||||
"Vertical Display (VDR)", // 0x88
|
||||
"Split Screen Width (SSW) 0x8a", // 0x8a
|
||||
"Split Screen Width (SSW) 0x8c", // 0x8c
|
||||
"Split Screen Width (SSW) 0x8e", // 0x8e
|
||||
"Blink Control (BCR)", // 0x90
|
||||
"Horizontal Window Display (HWR)", // 0x92
|
||||
"Vertical Window Display (VWR) 0x94", // 0x94
|
||||
"Vertical Window Display (VWR) 0x96", // 0x96
|
||||
"Graphic Cursor (GCR0)", // 0x98
|
||||
"Graphic Cursor (GCR1)", // 0x9a
|
||||
"Graphic Cursor (GCR2)", // 0x9c
|
||||
"(Undefined)", // 0x9e
|
||||
"(Undefined)", // 0xa0
|
||||
"(Undefined)", // 0xa2
|
||||
"(Undefined)", // 0xa4
|
||||
"(Undefined)", // 0xa6
|
||||
"(Undefined)", // 0xa8
|
||||
"(Undefined)", // 0xaa
|
||||
"(Undefined)", // 0xac
|
||||
"(Undefined)", // 0xae
|
||||
"(Undefined)", // 0xb0
|
||||
"(Undefined)", // 0xb2
|
||||
"(Undefined)", // 0xb4
|
||||
"(Undefined)", // 0xb6
|
||||
"(Undefined)", // 0xb8
|
||||
"(Undefined)", // 0xba
|
||||
"(Undefined)", // 0xbc
|
||||
"(Undefined)", // 0xbe
|
||||
// upper screen
|
||||
"Raster Address 0 (RAR0)", // 0xc0
|
||||
"Memory Width 0 (MWR0)", // 0xc2
|
||||
"Start Address 0 (SAR0) 0xc4", // 0xc4
|
||||
"Start Address 0 (SAR0) 0xc6", // 0xc6
|
||||
// base screen
|
||||
"Raster Address 1 (RAR1)", // 0xc8
|
||||
"Memory Width 1 (MWR1)", // 0xca
|
||||
"Start Address 1 (SAR1) 0xcc", // 0xcc
|
||||
"Start Address 1 (SAR1) 0xce", // 0xce
|
||||
// lower screen
|
||||
"Raster Address 2 (RAR2)", // 0xd0
|
||||
"Memory Width 2 (MWR2)", // 0xd2
|
||||
"Start Address 2 (SAR2) 0xd4", // 0xd4
|
||||
"Start Address 2 (SAR2) 0xd6", // 0xd6
|
||||
// window screen
|
||||
"Raster Address 3 (RAR3)", // 0xd8
|
||||
"Memory Width 3 (MWR3)", // 0xda
|
||||
"Start Address 3 (SAR3) 0xdc", // 0xdc
|
||||
"Start Address 3 (SAR3) 0xde", // 0xde
|
||||
// block cursor 1
|
||||
"Block Cursor 1 (BCUR1) 0xe0",
|
||||
"Block Cursor 1 (BCUR1) 0xe2",
|
||||
// block cursor 2
|
||||
"Block Cursor 2 (BCUR2) 0xe4",
|
||||
"Block Cursor 2 (BCUR2) 0xe6",
|
||||
"Cursor Definition (CDR)",
|
||||
"Zoom Factor (ZFR)",
|
||||
"Lightpen Address (LPAR) 0xec",
|
||||
"Lightpen Address (LPAR) 0xee",
|
||||
"(Undefined)", // 0xf0
|
||||
"(Undefined)", // 0xf2
|
||||
"(Undefined)", // 0xf4
|
||||
"(Undefined)", // 0xf6
|
||||
"(Undefined)", // 0xf8
|
||||
"(Undefined)", // 0xfa
|
||||
"(Undefined)", // 0xfc
|
||||
"(Undefined)" // 0xfe
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COMMAND_INVALID = -1
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
@ -34,6 +220,94 @@ INLINE const h63484_interface *get_interface( device_t *device )
|
||||
return (const h63484_interface *) device->static_config();
|
||||
}
|
||||
|
||||
|
||||
INLINE void fifo_clear(h63484_state *h63484)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
h63484->fifo[i] = 0;
|
||||
h63484->fifo_flag[i] = FIFO_EMPTY;
|
||||
}
|
||||
|
||||
h63484->fifo_ptr = -1;
|
||||
|
||||
h63484->sr |= H63484_SR_WFR;
|
||||
h63484->sr |= H63484_SR_WFE;
|
||||
}
|
||||
|
||||
INLINE int fifo_param_count(h63484_state *h63484)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (h63484->fifo_flag[i] != FIFO_PARAMETER) break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
INLINE void fifo_set_direction(h63484_state *h63484, int dir)
|
||||
{
|
||||
if (h63484->fifo_dir != dir)
|
||||
{
|
||||
fifo_clear(h63484);
|
||||
}
|
||||
|
||||
h63484->fifo_dir = dir;
|
||||
}
|
||||
|
||||
INLINE void queue(h63484_state *h63484, UINT8 data, int flag)
|
||||
{
|
||||
if (h63484->fifo_ptr < 15)
|
||||
{
|
||||
h63484->fifo_ptr++;
|
||||
|
||||
h63484->fifo[h63484->fifo_ptr] = data;
|
||||
h63484->fifo_flag[h63484->fifo_ptr] = flag;
|
||||
|
||||
if (h63484->fifo_ptr == 16)
|
||||
h63484->sr &= ~H63484_SR_WFR;
|
||||
|
||||
h63484->sr &= ~H63484_SR_WFE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO what happen? somebody set us up the bomb
|
||||
printf("FIFO?\n");
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void dequeue(h63484_state *h63484, UINT8 *data, int *flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
*data = h63484->fifo[0];
|
||||
*flag = h63484->fifo_flag[0];
|
||||
|
||||
if (h63484->fifo_ptr > -1)
|
||||
{
|
||||
for (i = 0; i < 15; i++)
|
||||
{
|
||||
h63484->fifo[i] = h63484->fifo[i + 1];
|
||||
h63484->fifo_flag[i] = h63484->fifo_flag[i + 1];
|
||||
}
|
||||
|
||||
h63484->fifo[15] = 0;
|
||||
h63484->fifo_flag[15] = 0;
|
||||
|
||||
h63484->fifo_ptr--;
|
||||
|
||||
h63484->sr |= H63484_SR_WFR;
|
||||
|
||||
if (h63484->fifo_ptr == -1)
|
||||
h63484->sr |= H63484_SR_WFE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
ROM( h63484 )
|
||||
-------------------------------------------------*/
|
||||
@ -43,15 +317,103 @@ ROM_START( h63484 )
|
||||
ROM_LOAD( "h63484.bin", 0x000, 0x100, NO_DUMP ) /* internal control ROM */
|
||||
ROM_END
|
||||
|
||||
/*-------------------------------------------------
|
||||
ADDRESS_MAP( upd7220 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER( h63484_vram_r )
|
||||
{
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
|
||||
return h63484->vram[offset];
|
||||
}
|
||||
|
||||
WRITE8_DEVICE_HANDLER( h63484_vram_w )
|
||||
{
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
|
||||
h63484->vram[offset] = data;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
IMPLEMENTATION
|
||||
*****************************************************************************/
|
||||
|
||||
static int translate_command(UINT8 data)
|
||||
{
|
||||
int command = COMMAND_INVALID;
|
||||
|
||||
switch (data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void process_fifo(device_t *device)
|
||||
{
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
UINT8 data;
|
||||
int flag;
|
||||
|
||||
dequeue(h63484, &data, &flag);
|
||||
|
||||
if (flag == FIFO_COMMAND)
|
||||
{
|
||||
h63484->cr = (data & 0xff00) >> 8;
|
||||
h63484->param_ptr = 1;
|
||||
h63484->sr &= ~H63484_SR_CED;
|
||||
dequeue(h63484, &data, &flag);
|
||||
h63484->pr[h63484->param_ptr] = data & 0xff;
|
||||
h63484->param_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
h63484->pr[h63484->param_ptr] = (data & 0xff00) >> 8;
|
||||
h63484->param_ptr++;
|
||||
dequeue(h63484, &data, &flag);
|
||||
h63484->pr[h63484->param_ptr] = data & 0xff;
|
||||
h63484->param_ptr++;
|
||||
}
|
||||
|
||||
switch (translate_command(h63484->cr))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
static void exec_abort_sequence(device_t *device)
|
||||
{
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
|
||||
fifo_clear(h63484);
|
||||
h63484->sr = H63484_SR_WFR | H63484_SR_WFE | H63484_SR_CED; // set to 0x23
|
||||
}
|
||||
|
||||
static void check_video_registers(device_t *device, int offset)
|
||||
{
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
UINT16 vreg_data;
|
||||
|
||||
vreg_data = (h63484->vreg[offset]<<8)|(h63484->vreg[offset+1]&0xff);
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 0x00: // FIFO entry, not covered there
|
||||
break;
|
||||
case CCR: // Command Entry
|
||||
if(vreg_data & ABT) // abort sequence
|
||||
exec_abort_sequence(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ16_DEVICE_HANDLER( h63484_status_r )
|
||||
{
|
||||
//h63484_state *h63484 = get_safe_token(device);
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
|
||||
return 0;
|
||||
return h63484->sr;
|
||||
}
|
||||
|
||||
READ16_DEVICE_HANDLER( h63484_data_r )
|
||||
@ -66,12 +428,39 @@ READ16_DEVICE_HANDLER( h63484_data_r )
|
||||
|
||||
WRITE16_DEVICE_HANDLER( h63484_address_w )
|
||||
{
|
||||
//h63484_state *h63484 = get_safe_token(device);
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
|
||||
if(ACCESSING_BITS_0_7)
|
||||
h63484->ar = data & 0xff;
|
||||
}
|
||||
|
||||
WRITE16_DEVICE_HANDLER( h63484_data_w )
|
||||
{
|
||||
//h63484_state *h63484 = get_safe_token(device);
|
||||
h63484_state *h63484 = get_safe_token(device);
|
||||
|
||||
if(LOG) printf("%s -> %02x\n",acrtc_regnames[h63484->ar/2],data);
|
||||
|
||||
if(ACCESSING_BITS_8_15)
|
||||
h63484->vreg[h63484->ar] = (data & 0xff00) >> 8;
|
||||
|
||||
if(ACCESSING_BITS_0_7)
|
||||
h63484->vreg[h63484->ar+1] = (data & 0xff);
|
||||
|
||||
if(h63484->ar == 0)
|
||||
{
|
||||
fifo_set_direction(h63484, FIFO_WRITE);
|
||||
queue(h63484, (data & 0xff00) >> 8, (h63484->sr & H63484_SR_CED) >> 5);
|
||||
queue(h63484, (data & 0x00ff) >> 0, 0);
|
||||
process_fifo(device);
|
||||
}
|
||||
else
|
||||
check_video_registers(device,h63484->ar);
|
||||
|
||||
if(h63484->ar & 0x80)
|
||||
{
|
||||
h63484->ar+=2;
|
||||
h63484->ar &= 0xff; // TODO: what happens if it overflows?
|
||||
}
|
||||
}
|
||||
|
||||
static DEVICE_START( h63484 )
|
||||
|
@ -51,6 +51,9 @@ READ16_DEVICE_HANDLER( h63484_data_r );
|
||||
WRITE16_DEVICE_HANDLER( h63484_address_w );
|
||||
WRITE16_DEVICE_HANDLER( h63484_data_w );
|
||||
|
||||
READ8_DEVICE_HANDLER( h63484_vram_r );
|
||||
WRITE8_DEVICE_HANDLER( h63484_vram_w );
|
||||
|
||||
#endif /* __H63484_H__ */
|
||||
|
||||
|
||||
|
@ -643,12 +643,12 @@ static READ8_HANDLER( h63484_rom_r )
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( adp_h63484_map, AS_0, 8 )
|
||||
AM_RANGE(0x00000, 0x3ffff) AM_RAM
|
||||
AM_RANGE(0x00000, 0x3ffff) AM_DEVREADWRITE("h63484",h63484_vram_r,h63484_vram_w)
|
||||
AM_RANGE(0x40000, 0x7ffff) AM_READ(h63484_rom_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( fashiong_h63484_map, AS_0, 8 )
|
||||
AM_RANGE(0x00000, 0x3ffff) AM_RAM
|
||||
AM_RANGE(0x00000, 0x3ffff) AM_DEVREADWRITE("h63484",h63484_vram_r,h63484_vram_w)
|
||||
// AM_RANGE(0x40000, 0x7ffff) AM_ROM AM_REGION("gfx1", 0)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user