bbc: fdc intrq/drq causes nmi

This commit is contained in:
Nigel Barnes 2015-10-25 12:21:52 +00:00
parent 113afc9877
commit d6f99fa63f
4 changed files with 67 additions and 127 deletions

View File

@ -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)

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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