mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
bbc: fdc intrq/drq causes nmi
This commit is contained in:
parent
113afc9877
commit
d6f99fa63f
@ -864,7 +864,7 @@ static MACHINE_CONFIG_DERIVED( bbcb, bbca )
|
||||
|
||||
/* fdc */
|
||||
MCFG_DEVICE_ADD("i8271" , I8271 , 0)
|
||||
MCFG_I8271_IRQ_CALLBACK(WRITELINE(bbc_state, bbc_i8271_interrupt))
|
||||
MCFG_I8271_IRQ_CALLBACK(INPUTLINE("maincpu", INPUT_LINE_NMI))
|
||||
MCFG_I8271_HDL_CALLBACK(WRITELINE(bbc_state, motor_w))
|
||||
MCFG_I8271_OPT_CALLBACK(WRITELINE(bbc_state, side_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD("i8271:0", bbc_floppies_525, "qd", bbc_state::floppy_formats_bbc)
|
||||
@ -889,8 +889,8 @@ static MACHINE_CONFIG_DERIVED(bbcb1770, bbcb)
|
||||
MCFG_DEVICE_REMOVE("i8271")
|
||||
|
||||
MCFG_WD1770_ADD("wd1770", XTAL_16MHz / 2)
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_state, bbc_wd177x_intrq_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_state, bbc_wd177x_drq_w))
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_state, fdc_intrq_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_state, fdc_drq_w))
|
||||
|
||||
MCFG_FLOPPY_DRIVE_ADD("wd1770:0", bbc_floppies_525, "qd", bbc_state::floppy_formats_bbcm)
|
||||
MCFG_FLOPPY_DRIVE_SOUND(true)
|
||||
@ -1166,8 +1166,8 @@ static MACHINE_CONFIG_START( bbcm, bbc_state )
|
||||
|
||||
/* fdc */
|
||||
MCFG_WD1770_ADD("wd1770", XTAL_16MHz / 2)
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_state, bbc_wd177x_intrq_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_state, bbc_wd177x_drq_w))
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_state, fdc_intrq_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_state, fdc_drq_w))
|
||||
|
||||
MCFG_FLOPPY_DRIVE_ADD("wd1770:0", bbc_floppies_525, "qd", bbc_state::floppy_formats_bbcm)
|
||||
MCFG_FLOPPY_DRIVE_SOUND(true)
|
||||
@ -1271,8 +1271,8 @@ static MACHINE_CONFIG_DERIVED( bbcmc, bbcm )
|
||||
MCFG_DEVICE_REMOVE("wd1770")
|
||||
|
||||
MCFG_WD1772_ADD("wd1772", XTAL_16MHz / 2)
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_state, bbc_wd177x_intrq_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_state, bbc_wd177x_drq_w))
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_state, fdc_intrq_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_state, fdc_drq_w))
|
||||
|
||||
MCFG_FLOPPY_DRIVE_ADD("wd1772:0", bbc_floppies_35, "qd", bbc_state::floppy_formats_bbcmc)
|
||||
MCFG_FLOPPY_DRIVE_SOUND(true)
|
||||
|
@ -154,8 +154,6 @@ public:
|
||||
DECLARE_READ8_MEMBER(bbcb_via_user_read_portb);
|
||||
DECLARE_WRITE8_MEMBER(bbcb_via_user_write_portb);
|
||||
DECLARE_WRITE_LINE_MEMBER(bbcb_via_user_irq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(bbc_wd177x_intrq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(bbc_wd177x_drq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(bbc_vsync);
|
||||
void update_acia_rxd();
|
||||
void update_acia_dcd();
|
||||
@ -166,7 +164,8 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER(write_dcd_serial);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_cts_serial);
|
||||
DECLARE_INPUT_CHANGED_MEMBER( trigger_reset );
|
||||
DECLARE_WRITE_LINE_MEMBER(bbc_i8271_interrupt);
|
||||
DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(fdc_drq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(motor_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(side_w);
|
||||
|
||||
@ -344,21 +343,13 @@ public: // HACK FOR MC6845
|
||||
emu_timer *m_tape_timer;
|
||||
|
||||
|
||||
/**************************************
|
||||
i8271 disc control
|
||||
***************************************/
|
||||
|
||||
int m_previous_i8271_int_state; // 8271 interrupt status
|
||||
|
||||
/**************************************
|
||||
WD1770 disc control
|
||||
***************************************/
|
||||
|
||||
int m_drive_control;
|
||||
int m_wd177x_irq_state;
|
||||
int m_wd177x_drq_state;
|
||||
int m_previous_wd177x_int_state;
|
||||
int m_wd177x_int_enabled;
|
||||
int m_fdc_irq;
|
||||
int m_fdc_drq;
|
||||
|
||||
/**************************************
|
||||
Video Code
|
||||
@ -409,7 +400,7 @@ public: // HACK FOR MC6845
|
||||
int m_videoULA_palette1[16];
|
||||
int *m_videoULA_palette_lookup;
|
||||
|
||||
void bbcbp_setvideoshadow(int vdusel);
|
||||
void bbc_setvideoshadow(int vdusel);
|
||||
void common_init(int memorySize);
|
||||
void set_pixel_lookup();
|
||||
void set_cursor(bbc_state *state);
|
||||
@ -422,10 +413,9 @@ public: // HACK FOR MC6845
|
||||
int bbc_keyboard(address_space &space, int data);
|
||||
void bbcb_IC32_initialise(bbc_state *state);
|
||||
void MC146818_set(address_space &space);
|
||||
void bbc_TMSint(int status);
|
||||
void MC6850_Receive_Clock(int new_clock);
|
||||
void BBC_Cassette_motor(unsigned char status);
|
||||
void bbc_update_fdq_int(int state);
|
||||
void bbc_update_nmi();
|
||||
unsigned int calculate_video_address(int ma,int ra);
|
||||
required_device<palette_device> m_palette;
|
||||
};
|
||||
|
@ -136,7 +136,7 @@ WRITE8_MEMBER(bbc_state::bbc_page_selectbp_w)
|
||||
{
|
||||
//the video display should now use this flag to display the shadow ram memory
|
||||
m_vdusel=BIT(data,7);
|
||||
bbcbp_setvideoshadow(m_vdusel);
|
||||
bbc_setvideoshadow(m_vdusel);
|
||||
//need to make the video display do a full screen refresh for the new memory area
|
||||
m_bank2->set_base(m_region_maincpu->base() + 0x3000);
|
||||
}
|
||||
@ -349,7 +349,7 @@ WRITE8_MEMBER(bbc_state::bbcm_ACCCON_write)
|
||||
m_bank7->set_base(m_region_os->base());
|
||||
}
|
||||
|
||||
bbcbp_setvideoshadow(m_ACCCON_D);
|
||||
bbc_setvideoshadow(m_ACCCON_D);
|
||||
|
||||
|
||||
if (m_ACCCON_X)
|
||||
@ -1424,27 +1424,6 @@ WRITE_LINE_MEMBER(bbc_state::write_acia_clock)
|
||||
***************************************/
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(bbc_state::bbc_i8271_interrupt)
|
||||
{
|
||||
/* I'm assuming that the nmi is edge triggered */
|
||||
/* a interrupt from the fdc will cause a change in line state, and
|
||||
the nmi will be triggered, but when the state changes because the int
|
||||
is cleared this will not cause another nmi */
|
||||
/* I'll emulate it like this to be sure */
|
||||
|
||||
if (state != m_previous_i8271_int_state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
/* I'll pulse it because if I used hold-line I'm not sure
|
||||
it would clear - to be checked */
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
m_previous_i8271_int_state = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(bbc_state::motor_w)
|
||||
{
|
||||
m_i8271->subdevice<floppy_connector>("0")->get_device()->mon_w(!state);
|
||||
@ -1463,6 +1442,38 @@ WRITE_LINE_MEMBER(bbc_state::side_w)
|
||||
***************************************/
|
||||
|
||||
|
||||
/* wd177x_IRQ_SET and latch bit 4 (nmi_enable) are NAND'ED together
|
||||
wd177x_DRQ_SET and latch bit 4 (nmi_enable) are NAND'ED together
|
||||
the output of the above two NAND gates are then OR'ED together and sent to the 6502 NMI line.
|
||||
DRQ and IRQ are active low outputs from wd177x. We use wd177x_DRQ_SET for DRQ = 0,
|
||||
and wd177x_DRQ_CLR for DRQ = 1. Similarly wd177x_IRQ_SET for IRQ = 0 and wd177x_IRQ_CLR
|
||||
for IRQ = 1.
|
||||
|
||||
The above means that if IRQ or DRQ are set, a interrupt should be generated.
|
||||
The nmi_enable decides if interrupts are actually triggered.
|
||||
The nmi is edge triggered, and triggers on a +ve edge.
|
||||
*/
|
||||
|
||||
|
||||
void bbc_state::bbc_update_nmi()
|
||||
{
|
||||
if (m_fdc_irq || m_fdc_drq)
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(bbc_state::fdc_intrq_w)
|
||||
{
|
||||
m_fdc_irq = state;
|
||||
bbc_update_nmi();
|
||||
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(bbc_state::fdc_drq_w)
|
||||
{
|
||||
m_fdc_drq = state;
|
||||
bbc_update_nmi();
|
||||
}
|
||||
|
||||
/*
|
||||
B/ B+ drive control:
|
||||
|
||||
@ -1477,67 +1488,6 @@ WRITE_LINE_MEMBER(bbc_state::side_w)
|
||||
0 Drive select 0.
|
||||
*/
|
||||
|
||||
/*
|
||||
density select
|
||||
single density is as the 8271 disc format
|
||||
double density is as the 8271 disc format but with 16 sectors per track
|
||||
*/
|
||||
|
||||
|
||||
/* wd177x_IRQ_SET and latch bit 4 (nmi_enable) are NAND'ED together
|
||||
wd177x_DRQ_SET and latch bit 4 (nmi_enable) are NAND'ED together
|
||||
the output of the above two NAND gates are then OR'ED together and sent to the 6502 NMI line.
|
||||
DRQ and IRQ are active low outputs from wd177x. We use wd177x_DRQ_SET for DRQ = 0,
|
||||
and wd177x_DRQ_CLR for DRQ = 1. Similarly wd177x_IRQ_SET for IRQ = 0 and wd177x_IRQ_CLR
|
||||
for IRQ = 1.
|
||||
|
||||
The above means that if IRQ or DRQ are set, a interrupt should be generated.
|
||||
The nmi_enable decides if interrupts are actually triggered.
|
||||
The nmi is edge triggered, and triggers on a +ve edge.
|
||||
*/
|
||||
|
||||
void bbc_state::bbc_update_fdq_int(int state)
|
||||
{
|
||||
int bbc_state;
|
||||
|
||||
/* if drq or irq is set, and interrupt is enabled */
|
||||
if ((m_wd177x_irq_state || m_wd177x_drq_state) && (m_wd177x_int_enabled))
|
||||
{
|
||||
/* int trigger */
|
||||
bbc_state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do not trigger int */
|
||||
bbc_state = 0;
|
||||
}
|
||||
/* nmi is edge triggered, and triggers when the state goes from clear->set.
|
||||
Here we are checking this transition before triggering the nmi */
|
||||
if (bbc_state != m_previous_wd177x_int_state)
|
||||
{
|
||||
if (bbc_state)
|
||||
{
|
||||
/* I'll pulse it because if I used hold-line I'm not sure
|
||||
it would clear - to be checked */
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
m_previous_wd177x_int_state = bbc_state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(bbc_state::bbc_wd177x_intrq_w)
|
||||
{
|
||||
m_wd177x_irq_state = state;
|
||||
bbc_update_fdq_int(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(bbc_state::bbc_wd177x_drq_w)
|
||||
{
|
||||
m_wd177x_drq_state = state;
|
||||
bbc_update_fdq_int(state);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(bbc_state::bbc_wd1770_status_w)
|
||||
{
|
||||
floppy_image_device *floppy = NULL;
|
||||
@ -1558,14 +1508,21 @@ WRITE8_MEMBER(bbc_state::bbc_wd1770_status_w)
|
||||
|
||||
// bit 5: reset
|
||||
if (!BIT(data, 5)) m_wd1770->soft_reset();
|
||||
|
||||
// bit 4: interrupt enable
|
||||
m_wd177x_int_enabled = !BIT(data, 4);
|
||||
}
|
||||
|
||||
/***************************************
|
||||
BBC MASTER DISC SUPPORT
|
||||
***************************************/
|
||||
/*
|
||||
Master drive control:
|
||||
|
||||
Bit Meaning
|
||||
-----------------
|
||||
7,6 Not used.
|
||||
5 Double density select (0 = double, 1 = single).
|
||||
4 Side select (0 = side 0, 1 = side 1).
|
||||
3 Drive select 2.
|
||||
2 Reset drive controller chip. (0 = reset controller, 1 = no reset)
|
||||
1 Drive select 1.
|
||||
0 Drive select 0.
|
||||
*/
|
||||
|
||||
READ8_MEMBER(bbc_state::bbcm_wd177xl_read)
|
||||
{
|
||||
@ -1593,8 +1550,6 @@ WRITE8_MEMBER(bbc_state::bbcm_wd1770l_write)
|
||||
|
||||
// bit 2: reset
|
||||
if (!BIT(data, 2)) m_wd1770->soft_reset();
|
||||
|
||||
m_wd177x_int_enabled = 1;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(bbc_state::bbcm_wd1772l_write)
|
||||
@ -1618,8 +1573,6 @@ WRITE8_MEMBER(bbc_state::bbcm_wd1772l_write)
|
||||
|
||||
// bit 2: reset
|
||||
if (!BIT(data, 2)) m_wd1772->soft_reset();
|
||||
|
||||
m_wd177x_int_enabled = 1;
|
||||
}
|
||||
|
||||
/**************************************
|
||||
@ -1797,8 +1750,6 @@ MACHINE_RESET_MEMBER(bbc_state, bbca)
|
||||
MACHINE_START_MEMBER(bbc_state, bbcb)
|
||||
{
|
||||
m_mc6850_clock = 0;
|
||||
m_previous_i8271_int_state=0;
|
||||
m_previous_wd177x_int_state=1;
|
||||
bbc_setup_banks(m_bank4, 16, 0, 0x4000);
|
||||
}
|
||||
|
||||
@ -1833,14 +1784,12 @@ MACHINE_RESET_MEMBER(bbc_state, bbcbp)
|
||||
{
|
||||
m_Speech = 1;
|
||||
m_bank1->set_base(m_region_maincpu->base());
|
||||
m_bank2->set_base(m_region_maincpu->base() + 0x03000); /* bank 2 screen/shadow ram from 3000 to 7fff */
|
||||
m_bank2->set_base(m_region_maincpu->base() + 0x3000); /* bank 2 screen/shadow ram from 3000 to 7fff */
|
||||
m_bank4->set_entry(0);
|
||||
m_bank6->set_entry(0);
|
||||
m_bank7->set_base(m_region_os->base()); /* bank 7 points at the OS rom from c000 to ffff */
|
||||
m_bank7->set_base(m_region_os->base()); /* bank 7 points at the OS rom from c000 to ffff */
|
||||
|
||||
bbcb_IC32_initialise(this);
|
||||
|
||||
m_previous_wd177x_int_state=1;
|
||||
}
|
||||
|
||||
|
||||
@ -1868,6 +1817,4 @@ MACHINE_RESET_MEMBER(bbc_state, bbcm)
|
||||
m_bank7->set_base(m_region_os->base()); /* bank 6 OS rom of RAM from c000 to dfff */
|
||||
|
||||
bbcb_IC32_initialise(this);
|
||||
|
||||
m_previous_wd177x_int_state=1;
|
||||
}
|
||||
|
@ -272,10 +272,13 @@ WRITE_LINE_MEMBER(bbc_state::bbc_vsync)
|
||||
}
|
||||
|
||||
|
||||
/**** BBC B+ Shadow Ram change ****/
|
||||
/**** BBC B+/Master Shadow Ram change ****/
|
||||
|
||||
void bbc_state::bbcbp_setvideoshadow(int vdusel)
|
||||
void bbc_state::bbc_setvideoshadow(int vdusel)
|
||||
{
|
||||
// LYNNE lives at 0xb000 in our map, but the offset we use here is 0x8000
|
||||
// as the video circuitry will already be looking at 0x3000 or so above
|
||||
// the offset.
|
||||
if (vdusel)
|
||||
m_BBC_Video_RAM = m_region_maincpu->base()+0x8000;
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user