summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/amiga/amiga_m.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/amiga/amiga_m.cpp')
-rw-r--r--src/mame/amiga/amiga_m.cpp183
1 files changed, 91 insertions, 92 deletions
diff --git a/src/mame/amiga/amiga_m.cpp b/src/mame/amiga/amiga_m.cpp
index b516ea7c266..15f1739aea0 100644
--- a/src/mame/amiga/amiga_m.cpp
+++ b/src/mame/amiga/amiga_m.cpp
@@ -14,17 +14,21 @@
#include "amiga.h"
#include "cpu/m68000/m68000.h"
-
/*************************************
*
* Debugging
*
*************************************/
-#define LOG_CUSTOM 0
-#define LOG_CIA 0
-#define LOG_BLITS 0
-#define LOG_SERIAL 1
+#define LOG_CUSTOM (1U << 1)
+#define LOG_CIA (1U << 2)
+#define LOG_BLITS (1U << 3)
+#define LOG_SERIAL (1U << 4)
+
+#define VERBOSE (LOG_SERIAL)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+
+#include "logmacro.h"
@@ -152,9 +156,6 @@ void amiga_state::machine_start()
{
m_power_led.resolve();
- // add callback for RESET instruction
- m_maincpu->set_reset_callback(*this, FUNC(amiga_state::m68k_reset));
-
// set up chip RAM access
memory_share *share = memshare("chip_ram");
if (share == nullptr)
@@ -163,8 +164,8 @@ void amiga_state::machine_start()
m_chip_ram_mask = (m_chip_ram.bytes() - 1) & ~1;
// set up the timers
- m_irq_timer = timer_alloc(FUNC(amiga_state::amiga_irq_proc), this);
- m_blitter_timer = timer_alloc(FUNC(amiga_state::amiga_blitter_proc), this);
+ m_irq_timer = timer_alloc(FUNC(amiga_state::irq_process_callback), this);
+ m_blitter_timer = timer_alloc(FUNC(amiga_state::blitter_process_callback), this);
m_serial_timer = timer_alloc(FUNC(amiga_state::serial_shift), this);
m_scanline_timer = timer_alloc(FUNC(amiga_state::scanline_callback), this);
@@ -172,7 +173,7 @@ void amiga_state::machine_start()
m_scanline_timer->adjust(m_screen->time_until_pos(0));
}
-WRITE_LINE_MEMBER( amiga_state::m68k_reset )
+void amiga_state::m68k_reset(int state)
{
logerror("%s: Executed RESET\n", machine().describe_context());
machine_reset();
@@ -194,17 +195,17 @@ void amiga_state::machine_reset()
m_overlay->set_bank(1);
}
-WRITE_LINE_MEMBER(amiga_state::fdc_dskblk_w)
+void amiga_state::fdc_dskblk_w(int state)
{
set_interrupt(INTENA_SETCLR | INTENA_DSKBLK);
}
-WRITE_LINE_MEMBER(amiga_state::fdc_dsksyn_w)
+void amiga_state::fdc_dsksyn_w(int state)
{
set_interrupt((state ? INTENA_SETCLR : 0) | INTENA_DSKSYN);
}
-WRITE_LINE_MEMBER( amiga_state::kbreset_w )
+void amiga_state::kbreset_w(int state)
{
// this is connected to the gary chip, gary then resets the 68k, agnus, paula and the cias
if (!state)
@@ -237,7 +238,8 @@ void amiga_state::vblank()
{
}
-// todo: cia a clock can be connected to either a fixed 50/60hz signal from the power supply, or the vblank
+// TODO: CIA A clock can be connected to either a fixed 50/60hz signal from the power supply, or the vblank
+// TODO: move almost everything to a DMA scheduler, cfr. HRM diagram
TIMER_CALLBACK_MEMBER( amiga_state::scanline_callback )
{
int scanline = param;
@@ -248,9 +250,6 @@ TIMER_CALLBACK_MEMBER( amiga_state::scanline_callback )
// signal vblank irq
set_interrupt(INTENA_SETCLR | INTENA_VERTB);
- // clock tod
- m_cia_0->tod_w(1);
-
// additional bookkeeping by drivers
vblank();
}
@@ -258,6 +257,8 @@ TIMER_CALLBACK_MEMBER( amiga_state::scanline_callback )
// vblank end
if (scanline == m_screen->visible_area().top())
{
+ // clock tod
+ m_cia_0->tod_w(1);
m_cia_0->tod_w(0);
}
@@ -274,13 +275,13 @@ TIMER_CALLBACK_MEMBER( amiga_state::scanline_callback )
}
// render up to this scanline
- if (!m_screen->update_partial(scanline))
+ //if (!m_screen->update_partial(scanline))
{
- bitmap_rgb32 dummy_bitmap;
+ //bitmap_rgb32 dummy_bitmap;
if (IS_AGA())
- aga_render_scanline(dummy_bitmap, scanline);
+ aga_render_scanline(m_scanline_bitmap, scanline);
else
- render_scanline(dummy_bitmap, scanline);
+ render_scanline(m_scanline_bitmap, scanline);
}
// clock tod (if we actually render this scanline)
@@ -329,13 +330,6 @@ void amiga_state::update_int6()
void amiga_state::update_irqs()
{
- // if the external interrupt line is still active, set the interrupt request bit
- if (int2_pending())
- CUSTOM_REG(REG_INTREQ) |= INTENA_PORTS;
-
- if (int6_pending())
- CUSTOM_REG(REG_INTREQ) |= INTENA_EXTER;
-
int ints = CUSTOM_REG(REG_INTENA) & CUSTOM_REG(REG_INTREQ);
// master interrupt switch
@@ -357,9 +351,16 @@ void amiga_state::update_irqs()
m_maincpu->set_input_line(5, CLEAR_LINE);
m_maincpu->set_input_line(6, CLEAR_LINE);
}
+
+ // int 2 and 6 are level triggered
+ if (int2_pending())
+ CUSTOM_REG(REG_INTREQ) |= INTENA_PORTS;
+
+ if (int6_pending())
+ CUSTOM_REG(REG_INTREQ) |= INTENA_EXTER;
}
-TIMER_CALLBACK_MEMBER( amiga_state::amiga_irq_proc )
+TIMER_CALLBACK_MEMBER( amiga_state::irq_process_callback )
{
update_irqs();
m_irq_timer->reset();
@@ -852,24 +853,21 @@ uint32_t amiga_state::blit_line()
*
*************************************/
-TIMER_CALLBACK_MEMBER( amiga_state::amiga_blitter_proc )
+TIMER_CALLBACK_MEMBER( amiga_state::blitter_process_callback )
{
uint32_t blitsum = 0;
/* logging */
- if (LOG_BLITS)
- {
- static const char *const type[] = { "ASCENDING", "LINE", "DESCENDING", "LINE" };
- logerror("BLIT %s: %dx%d %04x %04x\n", type[CUSTOM_REG(REG_BLTCON1) & 0x0003], CUSTOM_REG(REG_BLTSIZH), CUSTOM_REG(REG_BLTSIZV), CUSTOM_REG(REG_BLTCON0), CUSTOM_REG(REG_BLTCON1));
- if (CUSTOM_REG(REG_BLTCON0) & 0x0800)
- logerror(" A: addr=%06X mod=%3d shift=%2d maskl=%04x maskr=%04x\n", CUSTOM_REG_LONG(REG_BLTAPTH), CUSTOM_REG_SIGNED(REG_BLTAMOD), CUSTOM_REG(REG_BLTCON0) >> 12, CUSTOM_REG(REG_BLTAFWM), CUSTOM_REG(REG_BLTALWM));
- if (CUSTOM_REG(REG_BLTCON0) & 0x0400)
- logerror(" B: addr=%06X mod=%3d shift=%2d\n", CUSTOM_REG_LONG(REG_BLTBPTH), CUSTOM_REG_SIGNED(REG_BLTBMOD), CUSTOM_REG(REG_BLTCON1) >> 12);
- if (CUSTOM_REG(REG_BLTCON0) & 0x0200)
- logerror(" C: addr=%06X mod=%3d\n", CUSTOM_REG_LONG(REG_BLTCPTH), CUSTOM_REG_SIGNED(REG_BLTCMOD));
- if (CUSTOM_REG(REG_BLTCON0) & 0x0100)
- logerror(" D: addr=%06X mod=%3d\n", CUSTOM_REG_LONG(REG_BLTDPTH), CUSTOM_REG_SIGNED(REG_BLTDMOD));
- }
+ static const char *const type[] = { "ASCENDING", "LINE", "DESCENDING", "LINE" };
+ LOGMASKED(LOG_BLITS, "BLIT %s: %dx%d %04x %04x\n", type[CUSTOM_REG(REG_BLTCON1) & 0x0003], CUSTOM_REG(REG_BLTSIZH), CUSTOM_REG(REG_BLTSIZV), CUSTOM_REG(REG_BLTCON0), CUSTOM_REG(REG_BLTCON1));
+ if (CUSTOM_REG(REG_BLTCON0) & 0x0800)
+ LOGMASKED(LOG_BLITS, " A: addr=%06X mod=%3d shift=%2d maskl=%04x maskr=%04x\n", CUSTOM_REG_LONG(REG_BLTAPTH), CUSTOM_REG_SIGNED(REG_BLTAMOD), CUSTOM_REG(REG_BLTCON0) >> 12, CUSTOM_REG(REG_BLTAFWM), CUSTOM_REG(REG_BLTALWM));
+ if (CUSTOM_REG(REG_BLTCON0) & 0x0400)
+ LOGMASKED(LOG_BLITS, " B: addr=%06X mod=%3d shift=%2d\n", CUSTOM_REG_LONG(REG_BLTBPTH), CUSTOM_REG_SIGNED(REG_BLTBMOD), CUSTOM_REG(REG_BLTCON1) >> 12);
+ if (CUSTOM_REG(REG_BLTCON0) & 0x0200)
+ LOGMASKED(LOG_BLITS, " C: addr=%06X mod=%3d\n", CUSTOM_REG_LONG(REG_BLTCPTH), CUSTOM_REG_SIGNED(REG_BLTCMOD));
+ if (CUSTOM_REG(REG_BLTCON0) & 0x0100)
+ LOGMASKED(LOG_BLITS, " D: addr=%06X mod=%3d\n", CUSTOM_REG_LONG(REG_BLTDPTH), CUSTOM_REG_SIGNED(REG_BLTDMOD));
/* set the zero flag */
CUSTOM_REG(REG_DMACON) |= 0x2000;
@@ -894,8 +892,7 @@ TIMER_CALLBACK_MEMBER( amiga_state::amiga_blitter_proc )
/* clear the zero flag if we actually wrote data */
if (blitsum)
CUSTOM_REG(REG_DMACON) &= ~0x2000;
- if (LOG_BLITS)
- logerror("%04x ZF=%d\n", blitsum, bool(BIT(CUSTOM_REG(REG_DMACON), 13)));
+ LOGMASKED(LOG_BLITS, "%04x ZF=%d\n", blitsum, bool(BIT(CUSTOM_REG(REG_DMACON), 13)));
/* no longer busy */
CUSTOM_REG(REG_DMACON) &= ~0x4000;
@@ -950,14 +947,14 @@ void amiga_state::blitter_setup()
/* compute the blit time */
// TODO: verify timings
- // According to https://github.com/alpine9000/amiga_examples test 010,
- // blitting is currently taking half the time than necessary.
- // Is it expecting to account for RAM access waitstates or ...?
+ // - https://github.com/alpine9000/amiga_examples test 010,
+ // blitting is currently taking half the time than necessary.
+ // - viz does heavy bbusy checks.
blittime = ticks * height * width;
/* if 'blitter-nasty' is set, then the blitter takes over the bus. Make the blit semi-immediate */
- // TODO: blitter nasty doesn't seem to work as intended.
- // cfr. spinwrld
+ // FIXME: emulate bus priority implications here
+ // cfr. spinwrld no backgrounds
if ( CUSTOM_REG(REG_DMACON) & 0x0400 )
{
/* simulate the 68k not running while the blit is going */
@@ -982,24 +979,24 @@ void amiga_state::blitter_setup()
// CENTRONICS
//**************************************************************************
-WRITE_LINE_MEMBER( amiga_state::centronics_ack_w )
+void amiga_state::centronics_ack_w(int state)
{
m_cia_0->flag_w(state);
}
-WRITE_LINE_MEMBER( amiga_state::centronics_busy_w )
+void amiga_state::centronics_busy_w(int state)
{
m_centronics_busy = state;
m_cia_1->sp_w(state);
}
-WRITE_LINE_MEMBER( amiga_state::centronics_perror_w )
+void amiga_state::centronics_perror_w(int state)
{
m_centronics_perror = state;
m_cia_1->cnt_w(state);
}
-WRITE_LINE_MEMBER( amiga_state::centronics_select_w )
+void amiga_state::centronics_select_w(int state)
{
m_centronics_select = state;
}
@@ -1022,16 +1019,14 @@ uint16_t amiga_state::cia_r(offs_t offset, uint16_t mem_mask)
if ((offset & 0x2000/2) == 0 && ACCESSING_BITS_8_15)
data |= m_cia_1->read(offset >> 7) << 8;
- if (LOG_CIA)
- logerror("%s: cia_r(%06x) = %04x & %04x\n", machine().describe_context(), offset, data, mem_mask);
+ LOGMASKED(LOG_CIA, "%s: cia_r(%06x) = %04x & %04x\n", machine().describe_context(), offset, data, mem_mask);
return data;
}
void amiga_state::cia_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
- if (LOG_CIA)
- logerror("%s: cia_w(%06x) = %04x & %04x\n", machine().describe_context(), offset, data, mem_mask);
+ LOGMASKED(LOG_CIA, "%s: cia_w(%06x) = %04x & %04x\n", machine().describe_context(), offset, data, mem_mask);
if ((offset & 0x1000/2) == 0 && ACCESSING_BITS_0_7)
m_cia_0->write(offset >> 7, data & 0xff);
@@ -1067,10 +1062,9 @@ void amiga_state::cia_0_port_a_write(uint8_t data)
m_power_led = BIT(~data, 1);
}
-WRITE_LINE_MEMBER( amiga_state::cia_0_irq )
+void amiga_state::cia_0_irq(int state)
{
- if (LOG_CIA)
- logerror("%s: cia_0_irq: %d\n", machine().describe_context(), state);
+ LOGMASKED(LOG_CIA, "%s: cia_0_irq: %d\n", machine().describe_context(), state);
m_cia_0_irq = state;
update_int2();
@@ -1103,10 +1097,9 @@ void amiga_state::cia_1_port_a_write(uint8_t data)
}
}
-WRITE_LINE_MEMBER( amiga_state::cia_1_irq )
+void amiga_state::cia_1_irq(int state)
{
- if (LOG_CIA)
- logerror("%s: cia_1_irq: %d\n", machine().describe_context(), state);
+ LOGMASKED(LOG_CIA, "%s: cia_1_irq: %d\n", machine().describe_context(), state);
m_cia_1_irq = state;
update_int6();
@@ -1126,7 +1119,7 @@ void amiga_state::ocs_map(address_map &map)
// map(0x000, 0x001).r(FUNC(amiga_state::bltddat_r));
// map(0x002, 0x003).r(FUNC(amiga_state::dmaconr_r));
map(0x004, 0x005).r(FUNC(amiga_state::vposr_r));
-// map(0x006, 0x007).r(FUNC(amiga_state::vhposr_r));
+ map(0x006, 0x007).r(FUNC(amiga_state::vhposr_r));
// map(0x008, 0x009).r(FUNC(amiga_state::dskdatr_r));
// TODO: verify if JOYxDAT really belongs to Denise (???)
// map(0x00a, 0x00b).r(FUNC(amiga_state::joydat_r<0>));
@@ -1271,6 +1264,11 @@ u16 amiga_state::vposr_r()
return res;
}
+u16 amiga_state::vhposr_r()
+{
+ return amiga_gethvpos() & 0xffff;
+}
+
void amiga_state::vposw_w(u16 data)
{
// TODO: data actually resync the screen?
@@ -1287,7 +1285,7 @@ void amiga_state::bplcon0_w(u16 data)
if ((data & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) == (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2))
{
/* planes go from 0 to 6, inclusive */
- popmessage( "This game is doing funky planes stuff. (planes > 6, %04x)", data );
+ popmessage( "bplcon0_w: setting up planes > 6, %04x", data );
data &= ~BPLCON0_BPU0;
}
CUSTOM_REG(REG_BPLCON0) = data;
@@ -1303,8 +1301,7 @@ uint16_t amiga_state::custom_chip_r(offs_t offset)
{
uint16_t temp;
- if (LOG_CUSTOM)
- logerror("%06X:read from custom %s\n", m_maincpu->pc(), s_custom_reg_names[offset & 0xff]);
+ LOGMASKED(LOG_CUSTOM, "%06X:read from custom %s\n", m_maincpu->pc(), s_custom_reg_names[offset & 0xff]);
switch (offset & 0xff)
{
@@ -1318,9 +1315,8 @@ uint16_t amiga_state::custom_chip_r(offs_t offset)
return amiga_gethvpos() & 0xffff;
case REG_SERDATR:
- if (LOG_SERIAL)
- logerror("r SERDATR: %04x\n", CUSTOM_REG(REG_SERDATR));
-
+ if (!machine().side_effects_disabled())
+ LOGMASKED(LOG_SERIAL, "r SERDATR: %04x\n", CUSTOM_REG(REG_SERDATR));
return CUSTOM_REG(REG_SERDATR);
case REG_JOY0DAT:
@@ -1391,7 +1387,7 @@ uint16_t amiga_state::custom_chip_r(offs_t offset)
return m_fdc->adkcon_r();
case REG_DSKDATR:
- popmessage("DSKDAT R, contact MAMEdev");
+ popmessage("DSKDAT R");
break;
}
@@ -1403,8 +1399,7 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
uint16_t temp;
offset &= 0xff;
- if (LOG_CUSTOM)
- logerror("%06X:write to custom %s = %04X\n", m_maincpu->pc(), s_custom_reg_names[offset & 0xff], data);
+ LOGMASKED(LOG_CUSTOM, "%06X:write to custom %s = %04X\n", m_maincpu->pc(), s_custom_reg_names[offset & 0xff], data);
switch (offset)
{
@@ -1416,7 +1411,7 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
return;
case REG_DSKDAT:
- popmessage("DSKDAT W %04x, contact MAMEdev",data);
+ popmessage("DSKDAT W %04x",data);
break;
case REG_DSKSYNC:
@@ -1448,9 +1443,7 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
break;
case REG_SERDAT:
- if (LOG_SERIAL)
- logerror("w SERDAT: %04x\n", data);
-
+ LOGMASKED(LOG_SERIAL, "w SERDAT: %04x\n", data);
CUSTOM_REG(REG_SERDAT) = data;
// transmit shift register currently empty?
@@ -1474,9 +1467,7 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
return;
case REG_SERPER:
- if (LOG_SERIAL)
- logerror("w SERPER: %04x\n", data);
-
+ LOGMASKED(LOG_SERIAL, "w SERPER: %04x\n", data);
CUSTOM_REG(REG_SERPER) = data;
serial_adjust();
@@ -1516,7 +1507,7 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
}
break;
- // OCS and AGA versions of Soccer Kid explicitly writes blitter addresses way beyond chip RAM
+ // soccerkd (OCS) and sockid_a (AGA) explicitly writes blitter addresses way beyond chip RAM
// This is clearly deterministic: it draws an individual empty tile scattered across playfield
// (which also collides on top of it)
case REG_BLTAPTH: case REG_BLTBPTH: case REG_BLTCPTH: case REG_BLTDPTH:
@@ -1585,11 +1576,15 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
data = (data & INTENA_SETCLR) ? (CUSTOM_REG(offset) | (data & 0x7fff)) : (CUSTOM_REG(offset) & ~(data & 0x7fff));
CUSTOM_REG(offset) = data;
if (temp & INTENA_SETCLR)
- // if we're enabling irq's, delay a bit
+ {
+ /* if we're enabling irq's, delay a bit */
m_irq_timer->adjust(m_maincpu->cycles_to_attotime(AMIGA_IRQ_DELAY_CYCLES));
+ }
else
- // if we're disabling irq's, process right away
+ {
+ /* if we're disabling irq's, process right away */
update_irqs();
+ }
break;
case REG_INTREQ:
@@ -1610,11 +1605,15 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
CUSTOM_REG(offset) = data;
if (temp & INTENA_SETCLR)
- // if we're generating irq's, delay a bit
+ {
+ /* if we're generating irq's, delay a bit */
m_irq_timer->adjust(m_maincpu->cycles_to_attotime(AMIGA_IRQ_DELAY_CYCLES));
+ }
else
- // if we're clearing irq's, process right away
+ {
+ /* if we're clearing irq's, process right away */
update_irqs();
+ }
break;
case REG_ADKCON:
@@ -1822,7 +1821,7 @@ void amiga_state::rx_write(int level)
CUSTOM_REG(REG_SERDATR) |= level << 11;
}
-WRITE_LINE_MEMBER( amiga_state::rs232_rx_w )
+void amiga_state::rs232_rx_w(int state)
{
rx_write(state);
@@ -1831,22 +1830,22 @@ WRITE_LINE_MEMBER( amiga_state::rs232_rx_w )
serial_adjust();
}
-WRITE_LINE_MEMBER( amiga_state::rs232_dcd_w )
+void amiga_state::rs232_dcd_w(int state)
{
m_rs232_dcd = state;
}
-WRITE_LINE_MEMBER( amiga_state::rs232_dsr_w )
+void amiga_state::rs232_dsr_w(int state)
{
m_rs232_dsr = state;
}
-WRITE_LINE_MEMBER( amiga_state::rs232_ri_w )
+void amiga_state::rs232_ri_w(int state)
{
m_rs232_ri = state;
}
-WRITE_LINE_MEMBER( amiga_state::rs232_cts_w )
+void amiga_state::rs232_cts_w(int state)
{
m_rs232_cts = state;
}