mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
commit
eab35a4470
@ -11,9 +11,6 @@
|
||||
TODO:
|
||||
|
||||
- implement FIFO as ring buffer
|
||||
- commands
|
||||
- DMAR
|
||||
- DMAW
|
||||
- incomplete / unimplemented FIGD / GCHRD draw modes
|
||||
- FIGD character
|
||||
- slanted character
|
||||
@ -21,7 +18,6 @@
|
||||
- read data
|
||||
- modify data
|
||||
- write data
|
||||
- QX-10 diagnostic test has positioning bugs with the bitmap display test;
|
||||
- QX-10 diagnostic test misses the zooming factor (external pin);
|
||||
- compis2 SAD address for bitmap is 0x20000 for whatever reason (presumably missing banking);
|
||||
- A5105 has a FIFO bug with the RDAT, should be a lot larger when it scrolls up.
|
||||
@ -457,9 +453,20 @@ inline void upd7220_device::reset_figs_param()
|
||||
//-------------------------------------------------
|
||||
// read_vram -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void upd7220_device::read_vram(uint8_t type, uint8_t mod)
|
||||
inline uint16_t upd7220_device::read_vram()
|
||||
{
|
||||
uint16_t data;
|
||||
|
||||
data = readword(m_ead*2);
|
||||
m_ead += x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch);
|
||||
m_ead &= 0x3ffff;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
inline void upd7220_device::rdat(uint8_t type, uint8_t mod)
|
||||
{
|
||||
uint16_t data;
|
||||
if (type == 1)
|
||||
{
|
||||
LOG("uPD7220 invalid type 1 RDAT parameter\n");
|
||||
@ -471,35 +478,74 @@ inline void upd7220_device::read_vram(uint8_t type, uint8_t mod)
|
||||
|
||||
while (m_figs.m_dc && m_fifo_ptr < (type ? 15 : 14))
|
||||
{
|
||||
data = read_vram();
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
queue(readbyte(m_ead*2), 0);
|
||||
queue(readbyte(m_ead*2+1), 0);
|
||||
queue(data & 0xff, 0);
|
||||
queue((data >> 8) & 0xff, 0);
|
||||
break;
|
||||
case 2:
|
||||
queue(readbyte(m_ead*2), 0);
|
||||
queue(data & 0xff, 0);
|
||||
break;
|
||||
case 3:
|
||||
queue(readbyte(m_ead*2+1), 0);
|
||||
queue((data >> 8) & 0xff, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
m_figs.m_dc--;
|
||||
m_ead += x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch);
|
||||
m_ead &= 0x3ffff;
|
||||
}
|
||||
|
||||
if (m_figs.m_dc == 0)
|
||||
reset_figs_param();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_vram -
|
||||
//-------------------------------------------------
|
||||
inline void upd7220_device::write_vram(uint8_t type, uint8_t mod, uint16_t data)
|
||||
{
|
||||
switch(mod & 3)
|
||||
{
|
||||
case 0x00: //replace
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, data);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, data & 0xff);
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, data >> 8);
|
||||
break;
|
||||
case 0x01: //complement
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, readword(m_ead*2+0) ^ data);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, readbyte(m_ead*2+0) ^ (data & 0xff));
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, readbyte(m_ead*2+1) ^ (data >> 8));
|
||||
break;
|
||||
case 0x02: //reset to zero
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, readword(m_ead*2+0) & ~data);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, readbyte(m_ead*2+0) & ~(data & 0xff));
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, readbyte(m_ead*2+1) & ~(data >> 8));
|
||||
break;
|
||||
case 0x03: //set to one
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, readword(m_ead*2+0) | data);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, readbyte(m_ead*2+0) | (data & 0xff));
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, readbyte(m_ead*2+1) | (data >> 8));
|
||||
break;
|
||||
}
|
||||
|
||||
inline void upd7220_device::write_vram(uint8_t type, uint8_t mod)
|
||||
m_ead += x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch);
|
||||
m_ead &= 0x3ffff;
|
||||
}
|
||||
|
||||
inline void upd7220_device::wdat(uint8_t type, uint8_t mod)
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
@ -536,44 +582,7 @@ inline void upd7220_device::write_vram(uint8_t type, uint8_t mod)
|
||||
|
||||
for(int i = 0; i < m_figs.m_dc + 1; i++)
|
||||
{
|
||||
switch(mod & 3)
|
||||
{
|
||||
case 0x00: //replace
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, result);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, result & 0xff);
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, result >> 8);
|
||||
break;
|
||||
case 0x01: //complement
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, readword(m_ead*2+0) ^ result);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, readbyte(m_ead*2+0) ^ (result & 0xff));
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, readbyte(m_ead*2+1) ^ (result >> 8));
|
||||
break;
|
||||
case 0x02: //reset to zero
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, readword(m_ead*2+0) & ~result);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, readbyte(m_ead*2+0) & ~(result & 0xff));
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, readbyte(m_ead*2+1) & ~(result >> 8));
|
||||
break;
|
||||
case 0x03: //set to one
|
||||
if(type == 0)
|
||||
writeword(m_ead*2+0, readword(m_ead*2+0) | result);
|
||||
if(type == 2)
|
||||
writebyte(m_ead*2+0, readbyte(m_ead*2+0) | (result & 0xff));
|
||||
if(type == 3)
|
||||
writebyte(m_ead*2+1, readbyte(m_ead*2+1) | (result >> 8));
|
||||
break;
|
||||
}
|
||||
|
||||
m_ead += x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch);
|
||||
m_ead &= 0x3ffff;
|
||||
write_vram(type, mod, result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1335,7 +1344,7 @@ void upd7220_device::process_fifo()
|
||||
LOG("%02x = %02x %02x (%c) %06x %04x\n",m_cr,m_pr[2],m_pr[1],m_pr[1]?m_pr[1]:' ',m_ead,m_figs.m_dc);
|
||||
fifo_set_direction(FIFO_WRITE);
|
||||
|
||||
write_vram((m_cr & 0x18) >> 3,m_cr & 3);
|
||||
wdat((m_cr & 0x18) >> 3,m_cr & 3);
|
||||
reset_figs_param();
|
||||
m_param_ptr = 1;
|
||||
}
|
||||
@ -1414,7 +1423,7 @@ void upd7220_device::process_fifo()
|
||||
case COMMAND_RDAT: /* read data from display memory */
|
||||
fifo_set_direction(FIFO_READ);
|
||||
|
||||
read_vram((m_cr & 0x18) >> 3,m_cr & 3);
|
||||
rdat((m_cr & 0x18) >> 3,m_cr & 3);
|
||||
|
||||
m_sr |= UPD7220_SR_DATA_READY;
|
||||
break;
|
||||
@ -1446,11 +1455,17 @@ void upd7220_device::process_fifo()
|
||||
break;
|
||||
|
||||
case COMMAND_DMAR: /* DMA read request */
|
||||
logerror("uPD7220 Unimplemented command DMAR\n");
|
||||
m_dma_type = (m_cr >> 3) & 3;
|
||||
m_dma_mod = m_cr & 3;
|
||||
m_dma_transfer_length = (m_figs.m_dc + 1) * (m_figs.m_d + 2);
|
||||
start_dma();
|
||||
break;
|
||||
|
||||
case COMMAND_DMAW: /* DMA write request */
|
||||
logerror("uPD7220 Unimplemented command DMAW\n");
|
||||
m_dma_type = (m_cr >> 3) & 3;
|
||||
m_dma_mod = m_cr & 3;
|
||||
m_dma_transfer_length = (m_figs.m_dc + 1) * (m_figs.m_d + 1);
|
||||
start_dma();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1465,7 +1480,7 @@ void upd7220_device::continue_command()
|
||||
// continue RDAT command when data to read are larger than the FIFO (a5105 and dmv text scrolling)
|
||||
if (m_figs.m_dc && translate_command(m_cr) == COMMAND_RDAT)
|
||||
{
|
||||
read_vram((m_cr & 0x18) >> 3, m_cr & 3);
|
||||
rdat((m_cr & 0x18) >> 3, m_cr & 3);
|
||||
m_sr |= UPD7220_SR_DATA_READY;
|
||||
}
|
||||
}
|
||||
@ -1495,7 +1510,6 @@ uint8_t upd7220_device::read(offs_t offset)
|
||||
|
||||
/* TODO: timing of these */
|
||||
m_sr &= ~UPD7220_SR_DRAWING_IN_PROGRESS;
|
||||
m_sr &= ~UPD7220_SR_DMA_EXECUTE;
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -1531,7 +1545,31 @@ void upd7220_device::write(offs_t offset, uint8_t data)
|
||||
|
||||
uint8_t upd7220_device::dack_r()
|
||||
{
|
||||
return 0;
|
||||
uint8_t result = 0;
|
||||
switch(m_dma_type) {
|
||||
case 0:
|
||||
if (m_dma_transfer_length % 2 == 0) {
|
||||
m_dma_data = read_vram();
|
||||
result = m_dma_data & 0xff;
|
||||
} else {
|
||||
result = (m_dma_data >> 8) & 0xff;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
m_dma_data = read_vram();
|
||||
result = m_dma_data & 0xff;
|
||||
break;
|
||||
case 3:
|
||||
m_dma_data = read_vram();
|
||||
result = (m_dma_data >> 8) & 0xff;
|
||||
break;
|
||||
default:
|
||||
logerror("uPD7220 Invalid DMA Transfer Type\n");
|
||||
}
|
||||
if (--m_dma_transfer_length == 0) {
|
||||
stop_dma();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1541,6 +1579,46 @@ uint8_t upd7220_device::dack_r()
|
||||
|
||||
void upd7220_device::dack_w(uint8_t data)
|
||||
{
|
||||
switch(m_dma_type) {
|
||||
case 0:
|
||||
if (m_dma_transfer_length % 2) {
|
||||
m_dma_data = ((m_dma_data & 0xff) | data << 8) & m_mask;
|
||||
write_vram(m_dma_type, m_dma_mod, m_dma_data);
|
||||
} else {
|
||||
m_dma_data = (m_dma_data & 0xff00) | data;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
m_dma_data = data & (m_mask & 0xff);
|
||||
write_vram(m_dma_type, m_dma_mod, m_dma_data);
|
||||
break;
|
||||
case 3:
|
||||
m_dma_data = (data << 8) & (m_mask & 0xff);
|
||||
write_vram(m_dma_type, m_dma_mod, m_dma_data);
|
||||
break;
|
||||
default:
|
||||
logerror("uPD7220 Invalid DMA Transfer Type\n");
|
||||
}
|
||||
if (--m_dma_transfer_length == 0) {
|
||||
stop_dma();
|
||||
}
|
||||
}
|
||||
|
||||
void upd7220_device::start_dma()
|
||||
{
|
||||
if ((m_sr & UPD7220_SR_DMA_EXECUTE) == 0) {
|
||||
m_write_drq(ASSERT_LINE);
|
||||
m_sr |= UPD7220_SR_DMA_EXECUTE;
|
||||
}
|
||||
}
|
||||
|
||||
void upd7220_device::stop_dma()
|
||||
{
|
||||
if ((m_sr & UPD7220_SR_DMA_EXECUTE) == UPD7220_SR_DMA_EXECUTE) {
|
||||
m_write_drq(CLEAR_LINE);
|
||||
m_sr &= ~UPD7220_SR_DMA_EXECUTE;
|
||||
reset_figs_param();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1648,8 +1726,6 @@ void upd7220_device::update_graphics(bitmap_rgb32 &bitmap, const rectangle &clip
|
||||
|
||||
if (im || force_bitmap)
|
||||
{
|
||||
//get_graphics_partition(area, &sad, &len, &im, &wd);
|
||||
|
||||
if(area >= 3) // TODO: most likely to be correct, Quarth (PC-98xx) definitely draws with area 2. We might see an area 3 someday ...
|
||||
break;
|
||||
|
||||
@ -1670,8 +1746,6 @@ void upd7220_device::update_graphics(bitmap_rgb32 &bitmap, const rectangle &clip
|
||||
}
|
||||
else
|
||||
{
|
||||
get_text_partition(area, &sad, &len, &im, &wd);
|
||||
|
||||
if(m_lr)
|
||||
{
|
||||
for (y = 0; y < len; y+=m_lr)
|
||||
|
@ -90,6 +90,8 @@ protected:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
void start_dma();
|
||||
void stop_dma();
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@ -112,8 +114,10 @@ private:
|
||||
inline void update_blank_timer(int state);
|
||||
inline void recompute_parameters();
|
||||
inline void reset_figs_param();
|
||||
inline void read_vram(uint8_t type, uint8_t mod);
|
||||
inline void write_vram(uint8_t type, uint8_t mod);
|
||||
inline void rdat(uint8_t type, uint8_t mod);
|
||||
inline uint16_t read_vram();
|
||||
inline void wdat(uint8_t type, uint8_t mod);
|
||||
inline void write_vram(uint8_t type, uint8_t mod, uint16_t data);
|
||||
inline void get_text_partition(int index, uint32_t *sad, uint16_t *len, int *im, int *wd);
|
||||
inline void get_graphics_partition(int index, uint32_t *sad, uint16_t *len, int *im, int *wd);
|
||||
|
||||
@ -139,6 +143,11 @@ private:
|
||||
devcb_write_line m_write_vsync;
|
||||
devcb_write_line m_write_blank;
|
||||
|
||||
uint8_t m_dma_type; // DMA transfer type
|
||||
uint8_t m_dma_mod; // DMA transfer mode
|
||||
uint16_t m_dma_data; // current word transferred via DMA
|
||||
uint32_t m_dma_transfer_length; // DMA transfer length in bytes
|
||||
|
||||
uint16_t m_mask; // mask register
|
||||
uint8_t m_pitch; // number of word addresses in display memory in the horizontal direction
|
||||
uint32_t m_ead; // execute word address
|
||||
|
@ -112,8 +112,6 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER( qx10_upd765_interrupt );
|
||||
void fdd_motor_w(uint8_t data);
|
||||
uint8_t qx10_30_r();
|
||||
uint8_t gdc_dack_r();
|
||||
void gdc_dack_w(uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER( tc_w );
|
||||
uint8_t mc146818_r(offs_t offset);
|
||||
void mc146818_w(offs_t offset, uint8_t data);
|
||||
@ -445,17 +443,6 @@ WRITE_LINE_MEMBER(qx10_state::dma_hrq_changed)
|
||||
m_dma_1->hack_w(state);
|
||||
}
|
||||
|
||||
uint8_t qx10_state::gdc_dack_r()
|
||||
{
|
||||
logerror("GDC DACK read\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qx10_state::gdc_dack_w(uint8_t data)
|
||||
{
|
||||
logerror("GDC DACK write %02x\n", data);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( qx10_state::tc_w )
|
||||
{
|
||||
/* floppy terminal count */
|
||||
@ -674,6 +661,7 @@ void qx10_state::machine_start()
|
||||
void qx10_state::machine_reset()
|
||||
{
|
||||
m_dma_1->dreq0_w(1);
|
||||
m_dma_1->dreq1_w(1);
|
||||
|
||||
m_spkr_enable = 0;
|
||||
m_pit1_out0 = 1;
|
||||
@ -836,11 +824,9 @@ void qx10_state::qx10(machine_config &config)
|
||||
m_dma_1->in_memr_callback().set(FUNC(qx10_state::memory_read_byte));
|
||||
m_dma_1->out_memw_callback().set(FUNC(qx10_state::memory_write_byte));
|
||||
m_dma_1->in_ior_callback<0>().set(m_fdc, FUNC(upd765a_device::dma_r));
|
||||
m_dma_1->in_ior_callback<1>().set(FUNC(qx10_state::gdc_dack_r));
|
||||
//m_dma_1->in_ior_callback<2>().set(m_hgdc, FUNC(upd7220_device::dack_r));
|
||||
m_dma_1->in_ior_callback<1>().set(m_hgdc, FUNC(upd7220_device::dack_r));
|
||||
m_dma_1->out_iow_callback<0>().set(m_fdc, FUNC(upd765a_device::dma_w));
|
||||
m_dma_1->out_iow_callback<1>().set(FUNC(qx10_state::gdc_dack_w));
|
||||
//m_dma_1->out_iow_callback<2>().set(m_hgdc, FUNC(upd7220_device::dack_w));
|
||||
m_dma_1->out_iow_callback<1>().set(m_hgdc, FUNC(upd7220_device::dack_w));
|
||||
AM9517A(config, m_dma_2, MAIN_CLK/4);
|
||||
|
||||
I8255(config, m_ppi, 0);
|
||||
@ -849,6 +835,7 @@ void qx10_state::qx10(machine_config &config)
|
||||
m_hgdc->set_addrmap(0, &qx10_state::upd7220_map);
|
||||
m_hgdc->set_display_pixels(FUNC(qx10_state::hgdc_display_pixels));
|
||||
m_hgdc->set_draw_text(FUNC(qx10_state::hgdc_draw_text));
|
||||
m_hgdc->drq_wr_callback().set(m_dma_1, FUNC(am9517a_device::dreq1_w)).invert();
|
||||
m_hgdc->set_screen("screen");
|
||||
|
||||
MC146818(config, m_rtc, 32.768_kHz_XTAL);
|
||||
|
Loading…
Reference in New Issue
Block a user