diff options
| author | 2015-09-30 17:21:14 +0200 | |
|---|---|---|
| committer | 2015-09-30 17:21:14 +0200 | |
| commit | 1fc48ce120a376c288daeeed98daccecf1b60d7b (patch) | |
| tree | 72cefcede17f3a27fa8256b43bfac9756db82312 /src/mess/machine/bbc.c | |
| parent | 87a576c55501bd7125b51ca786a010229669df0e (diff) | |
move mess into mame (nw)
Diffstat (limited to 'src/mess/machine/bbc.c')
| -rw-r--r-- | src/mess/machine/bbc.c | 1861 |
1 files changed, 0 insertions, 1861 deletions
diff --git a/src/mess/machine/bbc.c b/src/mess/machine/bbc.c deleted file mode 100644 index 3ffefc8a585..00000000000 --- a/src/mess/machine/bbc.c +++ /dev/null @@ -1,1861 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Gordon Jefferyes, Nigel Barnes -/****************************************************************************** - BBC Model B - - MESS Driver By: - - Gordon Jefferyes - mess_bbc@romvault.com - Nigel Barnes - ngbarnes@hotmail.com - -******************************************************************************/ - -#include <ctype.h> -#include "emu.h" -#include "cpu/m6502/m6502.h" -#include "sound/tms5220.h" -#include "machine/6522via.h" -#include "machine/wd_fdc.h" -#include "imagedev/flopdrv.h" -#include "includes/bbc.h" -#include "machine/mc146818.h" -#include "bus/centronics/ctronics.h" -#include "imagedev/cassette.h" - - -void bbc_state::check_interrupts() -{ - m_maincpu->set_input_line(M6502_IRQ_LINE, m_via_system_irq || m_via_user_irq || m_acia_irq || m_ACCCON_IRR); -} - -/************************* -Model A memory handling functions -*************************/ - -/* for the model A just address the 4 on board ROM sockets */ -WRITE8_MEMBER(bbc_state::bbc_page_selecta_w) -{ - m_bank4->set_entry(data & 0x03); -} - - -WRITE8_MEMBER(bbc_state::bbc_memorya1_w) -{ - m_region_maincpu->base()[offset]=data; -} - -/************************* -Model B memory handling functions -*************************/ - -/* the model B address all 16 of the ROM sockets */ -WRITE8_MEMBER(bbc_state::bbc_page_selectb_w) -{ - m_rombank = data & 0x0f; - m_bank4->set_entry(m_rombank); -} - - -WRITE8_MEMBER(bbc_state::bbc_memoryb3_w) -{ - if (m_ram->size() == 32*1024) - { - m_region_maincpu->base()[offset + 0x4000] = data; - } - else - { - m_region_maincpu->base()[offset] = data; - } -} - -/* I have setup 3 types of sideways ram: -0: none -1: 128K (bank 8 to 15) Solidisc sideways ram userport bank latch -2: 64K (banks 4 to 7) for Acorn sideways ram FE30 bank latch -3: 128K (banks 8 to 15) for Acown sideways ram FE30 bank latch -*/ -static const unsigned short bbc_SWRAMtype1[16]={0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1}; -static const unsigned short bbc_SWRAMtype2[16]={0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}; -static const unsigned short bbc_SWRAMtype3[16]={0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1}; - -WRITE8_MEMBER(bbc_state::bbc_memoryb4_w) -{ - switch (m_SWRAMtype) - { - case 1: if (bbc_SWRAMtype1[m_userport]) m_region_opt->base()[(m_userport << 14) + offset] = data; - case 2: if (bbc_SWRAMtype2[m_rombank]) m_region_opt->base()[(m_rombank << 14) + offset] = data; - case 3: if (bbc_SWRAMtype3[m_rombank]) m_region_opt->base()[(m_rombank << 14) + offset] = data; - } -} - -/****************************************/ -/* BBC B Plus memory handling function */ -/****************************************/ - - -/* this function should return true if - the instruction is in the VDU driver address ranged - these are set when: - PC is in the range c000 to dfff - or if pagedRAM set and PC is in the range a000 to afff -*/ -int bbc_state::vdudriverset() -{ - int PC; - PC = machine().device("maincpu")->safe_pc(); // this needs to be set to the 6502 program counter - return (((PC >= 0xc000) && (PC <= 0xdfff)) || ((m_pagedRAM) && ((PC >= 0xa000) && (PC <= 0xafff)))); -} - - -/* the model B Plus addresses all 16 of the ROM sockets plus the extra 12K of ram at 0x8000 - and 20K of shadow ram at 0x3000 */ -WRITE8_MEMBER(bbc_state::bbc_page_selectbp_w) -{ - if ((offset&0x04)==0) - { - m_pagedRAM = (data >> 7) & 0x01; - m_rombank = data & 0x0f; - - if (m_pagedRAM) - { - /* if paged ram then set 8000 to afff to read from the ram 8000 to afff */ - m_bank4->set_entry(0x10); - } - else - { - /* if paged rom then set the rom to be read from 8000 to afff */ - m_bank4->set_entry(m_rombank); - }; - - /* set the rom to be read from b000 to bfff */ - m_bank6->set_entry(m_rombank); - } - else - { - //the video display should now use this flag to display the shadow ram memory - m_vdusel=(data>>7)&0x01; - bbcbp_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); - } -} - - -/* write to the normal memory from 0x0000 to 0x2fff - the writes to this memory are just done the normal - way */ - -WRITE8_MEMBER(bbc_state::bbc_memorybp1_w) -{ - m_region_maincpu->base()[offset]=data; -} - - -/* the next two function handle reads and write to the shadow video ram area - between 0x3000 and 0x7fff - - when vdusel is set high the video display uses the shadow ram memory - the processor only reads and write to the shadow ram when vdusel is set - and when the instruction being executed is stored in a set range of memory - addresses known as the VDU driver instructions. -*/ - - -DIRECT_UPDATE_MEMBER(bbc_state::bbcbp_direct_handler) -{ - UINT8 *RAM = m_region_maincpu->base(); - if (m_vdusel == 0) - { - // not in shadow ram mode so just read normal ram - m_bank2->set_base(RAM + 0x3000); - } - else - { - if (vdudriverset()) - { - // if VDUDriver set then read from shadow ram - m_bank2->set_base(RAM + 0xb000); - } - else - { - // else read from normal ram - m_bank2->set_base(RAM + 0x3000); - } - } - return address; -} - - -WRITE8_MEMBER(bbc_state::bbc_memorybp2_w) -{ - UINT8 *RAM = m_region_maincpu->base(); - if (m_vdusel==0) - { - // not in shadow ram mode so just write to normal ram - RAM[offset + 0x3000] = data; - } - else - { - if (vdudriverset()) - { - // if VDUDriver set then write to shadow ram - RAM[offset + 0xb000] = data; - } - else - { - // else write to normal ram - RAM[offset + 0x3000] = data; - } - } -} - - -/* if the pagedRAM is set write to RAM between 0x8000 to 0xafff -otherwise this area contains ROM so no write is required */ -WRITE8_MEMBER(bbc_state::bbc_memorybp4_w) -{ - if (m_pagedRAM) - { - m_region_maincpu->base()[offset+0x8000]=data; - } -} - - -/* the BBC B plus 128K had extra ram mapped in replacing the -rom bank 0,1,c and d. -The function memorybp3_128_w handles memory writes from 0x8000 to 0xafff -which could either be sideways ROM, paged RAM, or sideways RAM. -The function memorybp4_128_w handles memory writes from 0xb000 to 0xbfff -which could either be sideways ROM or sideways RAM */ - - -static const unsigned short bbc_b_plus_sideways_ram_banks[16]={ 1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0 }; - - -WRITE8_MEMBER(bbc_state::bbc_memorybp4_128_w) -{ - if (m_pagedRAM) - { - m_region_maincpu->base()[offset+0x8000]=data; - } - else - { - if (bbc_b_plus_sideways_ram_banks[m_rombank]) - { - m_region_opt->base()[offset+(m_rombank<<14)]=data; - } - } -} - -WRITE8_MEMBER(bbc_state::bbc_memorybp6_128_w) -{ - if (bbc_b_plus_sideways_ram_banks[m_rombank]) - { - m_region_opt->base()[offset+(m_rombank<<14)+0x3000]=data; - } -} - - - -/****************************************/ -/* BBC Master functions */ -/****************************************/ - -/* -ROMSEL - &FE30 write Only -B7 RAM 1=Page in ANDY &8000-&8FFF - 0=Page in ROM &8000-&8FFF -B6 Not Used -B5 Not Used -B4 Not Used -B3-B0 Rom/Ram Bank Select - -ACCCON - -b7 IRR 1=Causes an IRQ to the processor -b6 TST 1=Selects &FC00-&FEFF read from OS-ROM -b5 IFJ 1=Internal 1MHz bus - 0=External 1MHz bus -b4 ITU 1=Internal Tube - 0=External Tube -b3 Y 1=Read/Write HAZEL &C000-&DFFF RAM - 0=Read/Write ROM &C000-&DFFF OS-ROM -b2 X 1=Read/Write LYNNE - 0=Read/WRITE main memory &3000-&8000 -b1 E 1=Causes shadow if VDU code - 0=Main all the time -b0 D 1=Display LYNNE as screen - 0=Display main RAM screen - -ACCCON is a read/write register - -HAZEL is the 8K of RAM used by the MOS, filing system, and other Roms at &C000-&DFFF - -ANDY is the name of the 4K of RAM used by the MOS at &8000-&8FFF - -b7:This causes an IRQ to occur. If you set this bit, you must write a routine on IRQ2V to clear it. - -b6:If set, this switches in the ROM at &FD00-&FEFF for reading, writes to these addresses are still directed to the I/O -The MOS will not work properly with this but set. the Masters OS uses this feature to place some of the reset code in this area, -which is run at powerup. - -b3:If set, access to &C000-&DFFF are directed to HAZEL, an 8K bank of RAM. IF clear, then operating system ROM is read. - -b2:If set, read/write access to &3000-&7FFF are directed to the LYNNE, the shadow screen RAM. If clear access is made to the main RAM. - -b1:If set, when the program counter is between &C000 and &DFFF, read/write access is directed to the LYNNE shadow RAM. -if the program counter is anywhere else main ram is accessed. - -*/ - - -READ8_MEMBER(bbc_state::bbcm_ACCCON_read) -{ - logerror("ACCCON read %d\n",offset); - return m_ACCCON; -} - -WRITE8_MEMBER(bbc_state::bbcm_ACCCON_write) -{ - int tempIRR; - m_ACCCON=data; - - logerror("ACCCON write %d %d \n",offset,data); - - tempIRR=m_ACCCON_IRR; - - m_ACCCON_IRR=(data>>7)&1; - m_ACCCON_TST=(data>>6)&1; - m_ACCCON_IFJ=(data>>5)&1; - m_ACCCON_ITU=(data>>4)&1; - m_ACCCON_Y =(data>>3)&1; - m_ACCCON_X =(data>>2)&1; - m_ACCCON_E =(data>>1)&1; - m_ACCCON_D =(data>>0)&1; - - if (tempIRR!=m_ACCCON_IRR) - { - check_interrupts(); - } - - if (m_ACCCON_Y) - { - m_bank7->set_base(m_region_maincpu->base() + 0x9000); - } - else - { - m_bank7->set_base(m_region_os->base()); - } - - bbcbp_setvideoshadow(m_ACCCON_D); - - - if (m_ACCCON_X) - { - m_bank2->set_base(m_region_maincpu->base() + 0xb000); - } - else - { - m_bank2->set_base(m_region_maincpu->base() + 0x3000); - } - - /* ACCCON_TST controls paging of rom reads in the 0xFC00-0xFEFF region */ - /* if 0 the I/O is paged for both reads and writes */ - /* if 1 the ROM is paged in for reads but writes still go to I/O */ - if (m_ACCCON_TST) - { - m_bank8->set_base(m_region_os->base() + 0x3c00); - space.install_read_bank(0xfc00, 0xfeff, "bank8"); - } - else - { - space.install_read_handler(0xfc00, 0xfeff, read8_delegate(FUNC(bbc_state::bbcm_r),this)); - } -} - - -int bbc_state::bbcm_vdudriverset() -{ - int PC; - PC = machine().device("maincpu")->safe_pc(); - return ((PC >= 0xc000) && (PC <= 0xdfff)); -} - - -WRITE8_MEMBER(bbc_state::page_selectbm_w) -{ - m_pagedRAM = (data & 0x80) >> 7; - m_rombank = data & 0x0f; - - if (m_pagedRAM) - { - m_bank4->set_entry(0x10); - m_bank5->set_entry(m_rombank); - } - else - { - m_bank4->set_entry(m_rombank); - m_bank5->set_entry(m_rombank); - } -} - - - -WRITE8_MEMBER(bbc_state::bbc_memorybm1_w) -{ - m_region_maincpu->base()[offset] = data; -} - - -DIRECT_UPDATE_MEMBER(bbc_state::bbcm_direct_handler) -{ - if (m_ACCCON_X) - { - m_bank2->set_base(m_region_maincpu->base() + 0xb000); - } - else - { - if (m_ACCCON_E && bbcm_vdudriverset()) - { - m_bank2->set_base(m_region_maincpu->base() + 0xb000); - } - else - { - m_bank2->set_base(m_region_maincpu->base() + 0x3000); - } - } - - return address; -} - - - -WRITE8_MEMBER(bbc_state::bbc_memorybm2_w) -{ - UINT8 *RAM = m_region_maincpu->base(); - if (m_ACCCON_X) - { - RAM[offset + 0xb000] = data; - } - else - { - if (m_ACCCON_E && bbcm_vdudriverset()) - { - RAM[offset + 0xb000] = data; - } - else - { - RAM[offset + 0x3000] = data; - } - } -} - -static const unsigned short bbc_master_sideways_ram_banks[16]= -{ - 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0 -}; - - -WRITE8_MEMBER(bbc_state::bbc_memorybm4_w) -{ - if (m_pagedRAM) - { - m_region_maincpu->base()[offset+0x8000] = data; - } - else - { - if (bbc_master_sideways_ram_banks[m_rombank]) - { - m_region_opt->base()[offset+(m_rombank<<14)] = data; - } - } -} - - -WRITE8_MEMBER(bbc_state::bbc_memorybm5_w) -{ - if (bbc_master_sideways_ram_banks[m_rombank]) - { - m_region_opt->base()[offset+(m_rombank<<14)+0x1000] = data; - } -} - - -WRITE8_MEMBER(bbc_state::bbc_memorybm7_w) -{ - if (m_ACCCON_Y) - { - m_region_maincpu->base()[offset+0x9000] = data; - } -} - - - -/****************************************************************************** -&FC00-&FCFF FRED -&FC00-&FC03 Byte-Wide Expansion RAM -&FC08-&FC0F Ample M2000 MIDI Interface (see also FCF0) -&FC10-&FC13 Teletext -&FC14-&FC1F Prestel -&FC20-&FC27 IEEE 488 Interface -&FC28-&FC2F Acorn Expansion, currently unused -&FC30-&FC3F Cambridge Ring Interface -&FC40-&FC47 Winchester Disc Interface -&FC48-&FC7F Acorn Expansion, currently unused -&FC80-&FC8F Test Hardware -&FC90-&FCBF Acorn Expansion, currently unused -&FCC0-&FCFE User Applications -&FCF0-&FCF7 JGH/ETI MIDI Control (see also FC08) -&FCFC-&FCFF Page-Wide Expansion RAM - -&FD00-&FDFF JIM -&FD00-&FDFF Page-wide expansion RAM window -&FD40-&FD4F Torch SASI/SCSI Hard Drive Access -&FDFE-&FDFF Reset Test vector - -&FE00-&FEFF SHEILA Read Write -&FE00-&FE07 6845 CRTC Video controller Video Controller 8 ( 2 bytes x 4 ) -&FE08-&FE0F 6850 ACIA Serial controller Serial Controller 8 ( 2 bytes x 4 ) -&FE10-&FE17 Serial ULA - Serial system chip 8 ( 1 byte x 8 ) -&FE18-&FE1F uPD7002 A to D converter A to D converter 8 ( 4 bytes x 2 ) -&FE20-&FE23 Video ULA - Video system chip 4 ( 2 bytes x 2 ) -&FE24-&FE27 FDC Latch 1770 Control latch 1770 Control latch 4 ( 1 byte x 4 ) -&FE28-&FE2F 1770 registers 1770 Disc Controller 1770 Disc Controller 8 ( 4 bytes x 2 ) -&FE30-&FE33 ROMSEL - ROM Select 4 ( 1 byte x 4 ) -&FE34-&3FE7 ACCCON ACCCON select reg. ACCCON select reg 4 ( 1 byte x 4 ) -&FE38-&FE3F NC - - -&FE40-&FE5F 6522 VIA SYSTEM VIA SYSTEM VIA 32 (16 bytes x 2 ) 1MHz -&FE60-&FE7F 6522 VIA USER VIA USER VIA 32 (16 bytes x 2 ) 1MHz -&FE80-&FE9F 8271 registers 8271 Disk Controller 8271 Disk Controller -&FEA0-&FEBF 68B54 ADLC ECONET controller ECONET controller 32 ( 4 bytes x 8 ) 2MHz -&FEC0-&FEDF 6854 ADLC ECONET controller ECONET controller 32 ( 4 bytes x 8 ) 2MHz -&FEE0-&FEFF Tube ULA Tube system interface Tube system interface 32 (32 bytes x 1 ) 2MHz -******************************************************************************/ - -READ8_MEMBER(bbc_state::bbcm_r) -{ - long myo; - - if (offset<=0x0ff) /* FRED */ - { - return 0xff; - }; - - if ((offset>=0x100) && (offset<=0x1ff)) /* JIM */ - { - return 0xff; - }; - - if ((offset>=0x200) && (offset<=0x2ff)) /* SHEILA */ - { - myo = offset-0x200; - if ((myo>=0x00) && (myo<=0x06) && (myo+0x01) & 1) return m_mc6845->status_r(space, myo-0x00); /* Video controller */ - if ((myo>=0x01) && (myo<=0x07) && (myo & 1)) return m_mc6845->register_r(space, myo-0x01); - if ((myo>=0x08) && (myo<=0x0e) && (myo+0x01) & 1) return m_acia ? m_acia->status_r(space, myo-0x08) : 0xfe; /* Serial controller */ - if ((myo>=0x09) && (myo<=0x0f) && (myo & 1)) return m_acia ? m_acia->data_r(space, myo-0x09) : 0xfe; - if ((myo>=0x10) && (myo<=0x17)) return 0xfe; /* Serial System Chip */ - if ((myo>=0x18) && (myo<=0x1f)) return m_upd7002 ? m_upd7002->read(space, myo-0x18) : 0xfe; /* A to D converter */ - if ((myo>=0x20) && (myo<=0x23)) return 0xfe; /* VideoULA */ - if ((myo>=0x24) && (myo<=0x27)) return bbcm_wd177xl_read(space, myo - 0x24); /* 177x Control Latch */ - if ((myo>=0x28) && (myo<=0x2f) && (m_wd1770)) return m_wd1770->read(space, myo-0x28); /* 1770 Controller */ - if ((myo>=0x28) && (myo<=0x2f) && (m_wd1772)) return m_wd1772->read(space, myo-0x28); /* 1772 Controller */ - if ((myo>=0x28) && (myo<=0x2f)) return 0xfe; /* No Controller */ - if ((myo>=0x30) && (myo<=0x33)) return 0xfe; - if ((myo>=0x34) && (myo<=0x37)) return bbcm_ACCCON_read(space, myo-0x34); /* ACCCON */ - if ((myo>=0x38) && (myo<=0x3f)) return 0xfe; /* NC ?? */ - if ((myo>=0x40) && (myo<=0x5f)) return m_via6522_0->read(space, myo-0x40); - if ((myo>=0x60) && (myo<=0x7f)) return m_via6522_1 ? m_via6522_1->read(space, myo-0x60) : 0xfe; - if ((myo>=0x80) && (myo<=0x9f)) return 0xfe; - if ((myo>=0xa0) && (myo<=0xbf)) return m_adlc ? m_adlc->read(space, myo & 0x03) : 0xfe; - if ((myo>=0xc0) && (myo<=0xdf)) return 0xfe; - if ((myo>=0xe0) && (myo<=0xff)) return 0xfe; - } - return 0xfe; -} - -WRITE8_MEMBER(bbc_state::bbcm_w) -{ - long myo; - - if ((offset>=0x200) && (offset<=0x2ff)) /* SHEILA */ - { - myo=offset-0x200; - if ((myo>=0x00) && (myo<=0x06) && (myo+0x01) & 1) m_mc6845->address_w(space, myo-0x00, data); /* Video Controller */ - if ((myo>=0x01) && (myo<=0x07) && (myo & 1)) m_mc6845->register_w(space, myo-0x01, data); - if ((myo>=0x08) && (myo<=0x0e) && (myo+0x01) & 1) if (m_acia) m_acia->control_w(space, myo-0x08, data); /* Serial controller */ - if ((myo>=0x09) && (myo<=0x0f) && (myo & 1)) if (m_acia) m_acia->data_w(space, myo-0x09, data); - if ((myo>=0x10) && (myo<=0x17)) bbc_SerialULA_w(space, myo-0x10, data); /* Serial System Chip */ - if ((myo>=0x18) && (myo<=0x1f) && (m_upd7002)) m_upd7002->write(space, myo-0x18, data); /* A to D converter */ - if ((myo>=0x20) && (myo<=0x23)) bbc_videoULA_w(space, myo-0x20, data); /* VideoULA */ - if ((myo>=0x24) && (myo<=0x27) && (m_wd1770)) bbcm_wd1770l_write(space, myo-0x24, data); /* disc control latch */ - if ((myo>=0x28) && (myo<=0x2f) && (m_wd1770)) m_wd1770->write(space, myo-0x28, data); /* 1770 Controller */ - if ((myo>=0x24) && (myo<=0x27) && (m_wd1772)) bbcm_wd1772l_write(space, myo-0x24, data); /* disc control latch */ - if ((myo>=0x28) && (myo<=0x2f) && (m_wd1772)) m_wd1772->write(space, myo-0x28, data); /* 1772 Controller */ - if ((myo>=0x30) && (myo<=0x33)) page_selectbm_w(space, myo-0x30, data); /* ROMSEL */ - if ((myo>=0x34) && (myo<=0x37)) bbcm_ACCCON_write(space, myo-0x34, data); /* ACCCON */ - //if ((myo>=0x38) && (myo<=0x3f)) /* NC ?? */ - if ((myo>=0x40) && (myo<=0x5f)) m_via6522_0->write(space, myo-0x40, data); - if ((myo>=0x60) && (myo<=0x7f) && (m_via6522_1)) m_via6522_1->write(space, myo-0x60, data); - //if ((myo>=0x80) && (myo<=0x9f)) - if ((myo>=0xa0) && (myo<=0xbf) && (m_adlc)) m_adlc->write(space, myo & 0x03, data); - //if ((myo>=0xc0) && (myo<=0xdf)) - //if ((myo>=0xe0) && (myo<=0xff)) - } -} - - -/****************************************************************************** - -System VIA 6522 - -PA0-PA7 -Port A forms a slow data bus to the keyboard sound and speech processors -PortA Keyboard -D0 Pin 8 -D1 Pin 9 -D2 Pin 10 -D3 Pin 11 -D4 Pin 5 -D5 Pin 6 -D6 Pin 7 -D7 Pin 12 - -PB0-PB2 outputs ---------------- -These 3 outputs form the address to an 8 bit addressable latch. -(IC32 74LS259) - -PB3 output ----------- -This output holds the data to be written to the selected -addressable latch bit. - -PB4 and PB5 inputs ------------------- -These are the inputs from the joystick FIRE buttons. They are -normally at logic 1 with no button pressed and change to 0 -when a button is pressed. - -PB6 and PB7 inputs from the speech processor (model B and B+) -------------------------------------------------------------- -PB6 is the speech processor 'ready' output and PB7 is from the -speech processor 'interrupt' output. - -PB6 and PB7 outputs to Master CMOS RAM/RTC ------------------------------------------- -PB6 operates the 146818 chip enable when set to '1'. PB7 operates -the 146818 address strobe line. - -CA1 input ---------- -This is the vertical sync input from the 6845. CA1 is set up to -interrupt the 6502 every 20ms (50Hz) as a vertical sync from -the video circuitry is detected. The operation system changes -the display flash colours on this interrupt so that they occur -during the screen blanking period. ----------------------------------------------------------------- -This is required for a lot of time function within the machine -and must be triggered every 20ms. (Should check at some point -how this 20ms signal is made, and see if none standard shaped -screen modes change this time period.) - -CB1 input ---------- -The CB1 input is the end of conversion (EOC) signal from the -7002 analogue to digital converter. It can be used to interrupt -the 6502 whenever a conversion is complete. - -CA2 input ---------- -This input comes from the keyboard circuit, and is used to -generate an interrupt whenever a key is pressed. See the -keyboard circuit section for more details. - -CB2 input ---------- -This is the light pen strobe signal (LPSTB) from the light pen. -If also connects to the 6845 video processor, -CB2 can be programmed to interrupt the processor whenever -a light pen strobe occurs. ----------------------------------------------------------------- -CB2 is not needed in the initial emulation -and should be set to logic low, should be mapped through to -a light pen emulator later. - -IRQ output -This connects to the IRQ line of the 6502 - - -The addressable latch -This 8 bit addressable latch is operated from port B lines 0-3. -PB0-PB2 are set to the required address of the output bit to be set. -PB3 is set to the value which should be programmed at that bit. -The function of the 8 output bits from this latch are:- - -B0 - Write Enable to the sound generator IC -B1 - READ select on the speech processor -B2 - WRITE select on the speech processor -B3 - Keyboard write enable -B4,B5 - these two outputs define the number to be added to the -start of screen address in hardware to control hardware scrolling:- -Mode Size Start of screen Number to add B5 B4 -0,1,2 20K &3000 12K 1 1 -3 16K &4000 16K 0 0 -4,5 10K &5800 (or &1800) 22K 1 0 -6 8K &6000 (or &2000) 24K 0 1 -B6 - Operates the CAPS lock LED (Pin 17 keyboard connector) -B7 - Operates the SHIFT lock LED (Pin 16 keyboard connector) -******************************************************************************/ - - -INTERRUPT_GEN_MEMBER(bbc_state::bbcb_keyscan) -{ - static const char *const colnames[] = { - "COL0", "COL1", "COL2", "COL3", "COL4", - "COL5", "COL6", "COL7", "COL8", "COL9", - "COL10", "COL11", "COL12" - }; - - /* only do auto scan if keyboard is not enabled */ - if (m_b3_keyboard == 1) - { - /* KBD IC1 4 bit addressable counter */ - /* KBD IC3 4 to 10 line decoder */ - /* keyboard not enabled so increment counter */ - m_column = (m_column + 1) % 16; - - if (m_column < 13) - { - /* KBD IC4 8 input NAND gate */ - /* set the value of via_system ca2, by checking for any keys - being pressed on the selected m_column */ - if ((ioport(colnames[m_column])->read() | 0x01) != 0xff) - { - m_via6522_0->write_ca2(1); - } - else - { - m_via6522_0->write_ca2(0); - } - } - else - { - m_via6522_0->write_ca2(0); - } - } -} - - -int bbc_state::bbc_keyboard(address_space &space, int data) -{ - int bit; - int row; - int res; - static const char *const colnames[] = { - "COL0", "COL1", "COL2", "COL3", "COL4", - "COL5", "COL6", "COL7", "COL8", "COL9", - "COL10", "COL11", "COL12" - }; - - m_column = data & 0x0f; - row = (data>>4) & 0x07; - - bit = 0; - - if (m_column < 13) - { - res = ioport(colnames[m_column])->read(); - } - else - { - res = 0xff; - } - - /* Normal keyboard result */ - if ((res & (1<<row)) == 0) - { - bit = 1; - } - - if ((res | 1) != 0xff) - { - m_via6522_0->write_ca2(1); - } - else - { - m_via6522_0->write_ca2(0); - } - - return (data & 0x7f) | (bit<<7); -} - - -void bbc_state::bbcb_IC32_initialise(bbc_state *state) -{ - m_b0_sound=0x01; // Write Enable to the sound generator IC - m_b1_speech_read=0x01; // READ select on the speech processor - m_b2_speech_write=0x01; // WRITE select on the speech processor - m_b3_keyboard=0x01; // Keyboard write enable - m_b4_video0=0x01; // These two outputs define the number to be added to the start of screen address - m_b5_video1=0x01; // in hardware to control hardware scrolling - m_b6_caps_lock_led=0x01; // Operates the CAPS lock LED - m_b7_shift_lock_led=0x01; // Operates the SHIFT lock LED -} - - -/* This the BBC Masters Real Time Clock and NVRAM IC */ -void bbc_state::MC146818_set(address_space &space) -{ - //logerror ("146181 WR=%d DS=%d AS=%d CE=%d \n",m_MC146818_WR,m_MC146818_DS,m_MC146818_AS,m_MC146818_CE); - //mc146818_device *rtc = space.machine().device<mc146818_device>("rtc"); - - // if chip enabled - if (m_MC146818_CE) - { - // if data select is set then access the data in the 146818 - if (m_MC146818_DS) - { - if (m_MC146818_WR) - { - m_via_system_porta = m_rtc->read(space, 1); - //logerror("read 146818 data %d \n",m_via_system_porta); - } - else - { - m_rtc->write(space, 1, m_via_system_porta); - //logerror("write 146818 data %d \n",m_via_system_porta); - } - } - - // if address select is set then set the address in the 146818 - if (m_MC146818_AS) - { - m_rtc->write(space, 0, m_via_system_porta); - //logerror("write 146818 address %d \n",m_via_system_porta); - } - } -} - - -WRITE8_MEMBER(bbc_state::bbcb_via_system_write_porta) -{ - //logerror("SYSTEM write porta %d\n",data); - - m_via_system_porta = data; - if (m_b0_sound == 0) - { - //logerror("Doing an unsafe write to the sound chip %d \n",data); - if (m_sn) m_sn->write(space, 0, m_via_system_porta); - } - if (m_b1_speech_read == 0) - { - if (m_tms) m_via_system_porta = m_tms->status_r(space, 0); - //logerror("Doing an unsafe read to the speech chip %d \n",m_via_system_porta); - } - if (m_b2_speech_write == 0) - { - //logerror("Doing an unsafe write to the speech chip %d \n",data); - if (m_tms) m_tms->data_w(space, 0, m_via_system_porta); - } - if (m_b3_keyboard == 0) - { - //logerror("Doing an unsafe write to the keyboard %d \n",data); - m_via_system_porta = bbc_keyboard(space, m_via_system_porta); - } - if (m_rtc) MC146818_set(space); -} - - -WRITE8_MEMBER(bbc_state::bbcb_via_system_write_portb) -{ - int bit, value; - bit = data & 0x07; - value = (data >> 3) & 0x01; - - //logerror("SYSTEM write portb %d %d %d\n",data,bit,value); - - if (value) - { - switch (bit) - { - case 0: - if (m_b0_sound == 0) - { - m_b0_sound = 1; - } - break; - case 1: - if (m_rtc && m_MC146818_WR == 0) - { - /* BBC Master has NVRAM Here */ - m_MC146818_WR = 1; - MC146818_set(space); - } - else - { - if (m_b1_speech_read == 0) - { - /* VSP TMS 5220 */ - m_b1_speech_read = 1; - //logerror("Speech read select TRUE\n"); - if (m_tms) m_tms->rsq_w(TRUE); - } - } - break; - case 2: - if (m_rtc && m_MC146818_DS == 0) - { - /* BBC Master has NVRAM Here */ - m_MC146818_DS = 1; - MC146818_set(space); - } - else - { - if (m_b2_speech_write == 0) - { - /* VSP TMS 5220 */ - m_b2_speech_write = 1; - //logerror("Speech write select TRUE\n"); - if (m_tms) m_tms->wsq_w(TRUE); - } - } - break; - case 3: - if (m_b3_keyboard == 0) - { - m_b3_keyboard = 1; - } - break; - case 4: - if (m_b4_video0 == 0) - { - m_b4_video0 = 1; - } - break; - case 5: - if (m_b5_video1 == 0) - { - m_b5_video1 = 1; - } - break; - case 6: - if (m_b6_caps_lock_led == 0) - { - m_b6_caps_lock_led = 1; - /* call caps lock led update */ - output_set_value("capslock_led", m_b6_caps_lock_led); - } - break; - case 7: - if (m_b7_shift_lock_led == 0) - { - m_b7_shift_lock_led = 1; - /* call shift lock led update */ - output_set_value("shiftlock_led", m_b7_shift_lock_led); - } - break; - } - } - else - { - switch (bit) - { - case 0: - if (m_b0_sound == 1) - { - m_b0_sound = 0; - if (m_sn) m_sn->write(space, 0, m_via_system_porta); - } - break; - case 1: - if (m_rtc && m_MC146818_WR == 1) - { - /* BBC Master has NVRAM Here */ - m_MC146818_WR = 0; - MC146818_set(space); - } - else - { - if (m_b1_speech_read == 1) - { - /* VSP TMS 5220 */ - m_b1_speech_read = 0; - //logerror("Speech read select FALSE\n"); - if (m_tms) m_tms->rsq_w(FALSE); - } - } - break; - case 2: - if (m_rtc && m_MC146818_DS == 1) - { - /* BBC Master has NVRAM Here */ - m_MC146818_DS = 0; - MC146818_set(space); - } - else - { - if (m_b2_speech_write == 1) - { - /* VSP TMS 5220 */ - m_b2_speech_write = 0; - //logerror("Speech write select FALSE\n"); - if (m_tms) m_tms->wsq_w(FALSE); - } - } - break; - case 3: - if (m_b3_keyboard == 1) - { - m_b3_keyboard = 0; - /* *** call keyboard enabled *** */ - m_via_system_porta = bbc_keyboard(space, m_via_system_porta); - } - break; - case 4: - if (m_b4_video0 == 1) - { - m_b4_video0 = 0; - } - break; - case 5: - if (m_b5_video1 == 1) - { - m_b5_video1 = 0; - } - break; - case 6: - if (m_b6_caps_lock_led == 1) - { - m_b6_caps_lock_led = 0; - /* call caps lock led update */ - output_set_value("capslock_led", m_b6_caps_lock_led); - } - break; - case 7: - if (m_b7_shift_lock_led == 1) - { - m_b7_shift_lock_led = 0; - /* call shift lock led update */ - output_set_value("shiftlock_led", m_b7_shift_lock_led); - } - break; - } - } - - - if (m_rtc) - { - //set the Address Select - if (m_MC146818_AS != ((data>>7)&1)) - { - m_MC146818_AS=(data>>7)&1; - MC146818_set(space); - } - - //if CE changes - if (m_MC146818_CE != ((data>>6)&1)) - { - m_MC146818_CE=(data>>6)&1; - MC146818_set(space); - } - } -} - - -READ8_MEMBER(bbc_state::bbcb_via_system_read_porta) -{ - //logerror("SYSTEM read porta %d\n",m_via_system_porta); - return m_via_system_porta; -} - - -READ8_MEMBER(bbc_state::bbcb_via_system_read_portb) -{ - // D4 of portb is joystick fire button 1 - // D5 of portb is joystick fire button 2 - // D6 VSPINT - // D7 VSPRDY - int TMSint = m_tms ? m_tms->intq_r() : 0; - int TMSrdy = m_tms ? m_tms->readyq_r() : 0; - //logerror("TMSint %d\n",TMSint); - //logerror("TMSrdy %d\n",TMSrdy); - return (0xf | ioport("IN0")->read() | (!TMSrdy << 7) | (!TMSint << 6)); -} - - -WRITE_LINE_MEMBER(bbc_state::bbcb_via_system_irq_w) -{ - m_via_system_irq = state; - - check_interrupts(); -} - -/********************************************************************** -USER VIA -Port A output is buffered before being connected to the printer connector. -This means that they can only be operated as output lines. -CA1 is pulled high by a 4K7 resistor. CA1 normally acts as an acknowledge -line when a printer is used. CA2 is buffered so that it has become an open -collector output only. It usually acts as the printer strobe line. -***********************************************************************/ - -/* USER VIA 6522 port B is connected to the BBC user port */ -READ8_MEMBER(bbc_state::bbcb_via_user_read_portb) -{ - return 0xff; -} - -WRITE8_MEMBER(bbc_state::bbcb_via_user_write_portb) -{ - m_userport = data; -} - -WRITE_LINE_MEMBER(bbc_state::bbcb_via_user_irq_w) -{ - m_via_user_irq = state; - - check_interrupts(); -} - - -/************************************** -BBC Joystick Support -**************************************/ - -UPD7002_GET_ANALOGUE(bbc_state::BBC_get_analogue_input) -{ - switch (channel_number) - { - case 0: - return ((0xff - m_joy0->read()) << 8); - case 1: - return ((0xff - m_joy1->read()) << 8); - case 2: - return ((0xff - m_joy2->read()) << 8); - case 3: - return ((0xff - m_joy3->read()) << 8); - } - - return 0; -} - -UPD7002_EOC(bbc_state::BBC_uPD7002_EOC) -{ - m_via6522_0->write_cb1(data); -} - -/*************************************** - BBC 2C199 Serial Interface Cassette -****************************************/ - - -void bbc_state::MC6850_Receive_Clock(int new_clock) -{ - m_rxd_cass = new_clock; - update_acia_rxd(); - - // - // Somehow the "serial processor" generates 16 clock signals towards - // the 6850. Exact details are unknown, faking it with the following - // loop. - // - for (int i = 0; i < 16; i++ ) - { - m_acia->write_rxc(1); - m_acia->write_rxc(0); - } -} - -TIMER_CALLBACK_MEMBER(bbc_state::bbc_tape_timer_cb) -{ - if ( m_cass_out_enabled ) - { - // 0 = 18-18 18-17-1 - // 1 = 9-9-9-9 9-9-9-8-1 - - switch ( m_cass_out_samples_to_go ) - { - case 0: - if ( m_cass_out_phase == 0 ) - { - // get bit value - m_cass_out_bit = m_txd; - if ( m_cass_out_bit ) - { - m_cass_out_phase = 3; - m_cass_out_samples_to_go = 9; - } - else - { - m_cass_out_phase = 1; - m_cass_out_samples_to_go = 18; - } - m_cassette->output( +1.0 ); - } - else - { - // switch phase - m_cass_out_phase--; - m_cass_out_samples_to_go = m_cass_out_bit ? 9 : 18; - m_cassette->output( ( m_cass_out_phase & 1 ) ? +1.0 : -1.0 ); - } - break; - case 1: - if ( m_cass_out_phase == 0 ) - { - m_cassette->output( 0.0 ); - } - break; - } - - m_cass_out_samples_to_go--; - } - else - { - double dev_val = m_cassette->input(); - - // look for edges on the cassette wave - if (((dev_val>=0.0) && (m_last_dev_val<0.0)) || ((dev_val<0.0) && (m_last_dev_val>=0.0))) - { - if (m_wav_len>(9*3)) - { - //this is too long to receive anything so reset the serial IC. This is a hack, this should be done as a timer in the MC6850 code. - logerror ("Cassette length %d\n",m_wav_len); - m_nr_high_tones = 0; - m_dcd_cass = 0; - update_acia_dcd(); - m_len0=0; - m_len1=0; - m_len2=0; - m_len3=0; - m_wav_len=0; - } - - m_len3=m_len2; - m_len2=m_len1; - m_len1=m_len0; - m_len0=m_wav_len; - - m_wav_len=0; - logerror ("cassette %d %d %d %d\n",m_len3,m_len2,m_len1,m_len0); - - if ((m_len0+m_len1)>=(18+18-5)) - { - /* Clock a 0 onto the serial line */ - logerror("Serial value 0\n"); - m_nr_high_tones = 0; - m_dcd_cass = 0; - update_acia_dcd(); - MC6850_Receive_Clock(0); - m_len0=0; - m_len1=0; - m_len2=0; - m_len3=0; - } - - if (((m_len0+m_len1+m_len2+m_len3)<=41) && (m_len3!=0)) - { - /* Clock a 1 onto the serial line */ - logerror("Serial value 1\n"); - m_nr_high_tones++; - if ( m_nr_high_tones > 100 ) - { - m_dcd_cass = 1; - update_acia_dcd(); - } - MC6850_Receive_Clock(1); - m_len0=0; - m_len1=0; - m_len2=0; - m_len3=0; - } - } - - m_wav_len++; - m_last_dev_val=dev_val; - } -} - -WRITE_LINE_MEMBER( bbc_state::write_rxd_serial ) -{ - m_rxd_serial = state; - update_acia_rxd(); -} - -void bbc_state::update_acia_rxd() -{ - m_acia->write_rxd(( m_serproc_data & 0x40 ) ? m_rxd_serial : m_rxd_cass); -} - - -WRITE_LINE_MEMBER( bbc_state::write_dcd_serial ) -{ - m_dcd_serial = state; - update_acia_dcd(); -} - -void bbc_state::update_acia_dcd() -{ - m_acia->write_dcd(( m_serproc_data & 0x40 ) ? m_dcd_serial : m_dcd_cass); -} - - -WRITE_LINE_MEMBER( bbc_state::write_cts_serial ) -{ - m_cts_serial = state; - update_acia_cts(); -} - -void bbc_state::update_acia_cts() -{ - m_acia->write_cts(( m_serproc_data & 0x40 ) ? m_cts_serial : 0); -} - - -WRITE_LINE_MEMBER( bbc_state::bbc_rts_w ) -{ - if ( m_serproc_data & 0x40 ) - { - m_rs232->write_rts(state); - m_cass_out_enabled = 0; - } - else - { - m_cass_out_enabled = state ? 0 : 1; - } -} - - -WRITE_LINE_MEMBER( bbc_state::bbc_txd_w ) -{ - if ( m_serproc_data & 0x40 ) - { - m_rs232->write_txd(state); - } - else - { - m_txd = state; - } -} - - -void bbc_state::BBC_Cassette_motor(unsigned char status) -{ - if (status) - { - m_cassette->change_state(CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); - m_tape_timer->adjust(attotime::zero, 0, attotime::from_hz(44100)); - } - else - { - m_cassette->change_state(CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); - m_tape_timer->reset(); - m_len0 = 0; - m_len1 = 0; - m_len2 = 0; - m_len3 = 0; - m_wav_len = 0; - m_cass_out_phase = 0; - m_cass_out_samples_to_go = 4; - } - output_set_value("motor_led", !status); -} - - -// -// Serial processor control -// x--- ---- - Motor OFF(0)/ON(1) -// -x-- ---- - Cassette(0)/RS243 input(1) -// --xx x--- - Receive baud rate generator control -// ---- -xxx - Transmit baud rate generator control -// These possible settings apply to both the receive -// and transmit baud generator control bits: -// 000 - 16MHz / 13 / 1 - 19200 baud -// 001 - 16MHz / 13 / 16 - 1200 baud -// 010 - 16MHz / 13 / 4 - 4800 baud -// 011 - 16MHz / 13 / 128 - 150 baud -// 100 - 16MHz / 13 / 2 - 9600 baud -// 101 - 16MHz / 13 / 64 - 300 baud -// 110 - 16MHz / 13 / 8 - 2400 baud -// 110 - 16MHz / 13 / 256 - 75 baud -// -WRITE8_MEMBER(bbc_state::bbc_SerialULA_w) -{ - static const int serial_clocks[8] = - { - 1, // 000 - 16, // 001 - 4, // 010 - 128, // 011 - 2, // 100 - 64, // 101 - 8, // 110 - 256 // 111 - }; - - m_serproc_data = data; - update_acia_rxd(); - update_acia_dcd(); - update_acia_cts(); - if (m_cassette) BBC_Cassette_motor(m_serproc_data & 0x80); - - // Set transmit clock rate - m_acia_clock->set_clock_scale( (double) 1 / serial_clocks[ data & 0x07 ] ); -} - -WRITE_LINE_MEMBER(bbc_state::write_acia_clock) -{ - m_acia->write_txc(state); - - if (m_serproc_data & 0x40) - m_acia->write_rxc(state); -} - -/************************************** - i8271 disc control function -***************************************/ - - -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); - m_i8271->subdevice<floppy_connector>("1")->get_device()->mon_w(!state); -} - - -/************************************** - WD1770 disc control function -***************************************/ - - -/* - B/ B+ drive control: - - Bit Meaning - ----------------- - 7,6 Not used. - 5 Reset drive controller chip. (0 = reset controller, 1 = no reset) - 4 Interrupt Enable (0 = enable int, 1 = disable int) - 3 Double density select (0 = double, 1 = single). - 2 Side select (0 = side 0, 1 = side 1). - 1 Drive select 1. - 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_177x_IntEnabled)) - { - /* 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; - - m_drive_control = data; - logerror("Drive control %d \n", data); - - // bit 5: reset - if (!BIT(data, 5)) m_wd1770->reset(); - - // bit 0, 1: drive select - if (BIT(data, 0)) floppy = m_wd1770->subdevice<floppy_connector>("0")->get_device(); - if (BIT(data, 1)) floppy = m_wd1770->subdevice<floppy_connector>("1")->get_device(); - m_wd1770->set_floppy(floppy); - - // bit 2: side select - if (floppy) - floppy->ss_w(BIT(data, 2)); - - // bit 3: density - m_wd1770->dden_w(BIT(data, 3)); - - // bit 4: interrupt enable - m_177x_IntEnabled = !BIT(data, 4); -} - -/*************************************** -BBC MASTER DISC SUPPORT -***************************************/ - -READ8_MEMBER(bbc_state::bbcm_wd177xl_read) -{ - return m_drive_control; -} - -WRITE8_MEMBER(bbc_state::bbcm_wd1770l_write) -{ - floppy_image_device *floppy = NULL; - - m_drive_control = data; - //logerror("Drive control %d \n", data); - - // bit 2: reset - if (!BIT(data, 2)) m_wd1770->reset(); - - // bit 0, 1, 3: drive select - if (BIT(data, 0)) floppy = m_wd1770->subdevice<floppy_connector>("0")->get_device(); - if (BIT(data, 1)) floppy = m_wd1770->subdevice<floppy_connector>("1")->get_device(); - if (BIT(data, 3)) floppy = m_wd1770->subdevice<floppy_connector>("2")->get_device(); - m_wd1770->set_floppy(floppy); - - // bit 4: side select - if (floppy) - floppy->ss_w(BIT(data, 4)); - - // bit 5: density - m_wd1770->dden_w(BIT(data, 5)); - - m_177x_IntEnabled = 1; -} - -WRITE8_MEMBER(bbc_state::bbcm_wd1772l_write) -{ - floppy_image_device *floppy = NULL; - - m_drive_control = data; - //logerror("Drive control %d \n", data); - - // bit 2: reset - if (!BIT(data, 2)) m_wd1772->reset(); - - // bit 0, 1, 3: drive select - if (BIT(data, 0)) floppy = m_wd1772->subdevice<floppy_connector>("0")->get_device(); - if (BIT(data, 1)) floppy = m_wd1772->subdevice<floppy_connector>("1")->get_device(); - if (BIT(data, 3)) floppy = m_wd1772->subdevice<floppy_connector>("2")->get_device(); - m_wd1772->set_floppy(floppy); - - // bit 4: side select - if (floppy) - floppy->ss_w(BIT(data, 4)); - - // bit 5: density - m_wd1772->dden_w(BIT(data, 5)); - - m_177x_IntEnabled = 1; -} - -/************************************** - BBC B Rom loading functions -***************************************/ - -int bbc_state::bbc_load_cart(device_image_interface &image, generic_slot_device *slot) -{ - UINT32 size = slot->common_get_size("rom"); - - if (size != 0x2000 && size != 0x4000) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); - return IMAGE_INIT_FAIL; - } - - slot->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - slot->common_load_rom(slot->get_rom_base(), size, "rom"); - - return IMAGE_INIT_PASS; -} - -/************************************** - BBC Master Rom loading functions -***************************************/ - -int bbc_state::bbcm_load_cart(device_image_interface &image, generic_slot_device *slot) -{ - if (image.software_entry() == NULL) - { - UINT32 filesize = image.length(); - - if (filesize != 0x8000) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); - return IMAGE_INIT_FAIL; - } - - slot->rom_alloc(filesize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - image.fread(slot->get_rom_base(), filesize); - return IMAGE_INIT_PASS; - } - else - { - UINT32 size_lo = image.get_software_region_length("lorom"); - UINT32 size_hi = image.get_software_region_length("uprom"); - - if (size_lo + size_hi != 0x8000) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); - return IMAGE_INIT_FAIL; - } - - slot->rom_alloc(size_lo + size_hi, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - memcpy(slot->get_rom_base() + 0, image.get_software_region("uprom"), size_hi); - memcpy(slot->get_rom_base() + size_hi, image.get_software_region("lorom"), size_lo); - } - - return IMAGE_INIT_PASS; -} - - -/************************************** - Machine Initialisation functions -***************************************/ - -DRIVER_INIT_MEMBER(bbc_state,bbc) -{ - m_rxd_cass = 0; - m_nr_high_tones = 0; - m_serproc_data = 0; - m_cass_out_enabled = 0; - m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bbc_state::bbc_tape_timer_cb),this)); - - /* vertical sync pulse from video circuit */ - m_via6522_0->write_ca1(1); - - /* light pen strobe detect (not emulated) */ - m_via6522_0->write_cb2(1); -} - -// setup pointers for optional EPROMs -void bbc_state::bbc_setup_banks(memory_bank *membank, int banks, UINT32 shift, UINT32 size) -{ - std::string region_tag; - memory_region *tmp_reg; - UINT8 *eprom[4]; - if (m_exp1 && (tmp_reg = memregion(region_tag.assign(m_exp1->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) - eprom[0] = tmp_reg->base() + shift; - else - eprom[0] = m_region_opt->base() + 0x0000 + shift; - if (m_exp2 && (tmp_reg = memregion(region_tag.assign(m_exp2->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) - eprom[1] = tmp_reg->base() + shift; - else - eprom[1] = m_region_opt->base() + 0x4000 + shift; - if (m_exp3 && (tmp_reg = memregion(region_tag.assign(m_exp3->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) - eprom[2] = tmp_reg->base() + shift; - else - eprom[2] = m_region_opt->base() + 0x8000 + shift; - if (m_exp4 && (tmp_reg = memregion(region_tag.assign(m_exp4->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) - eprom[3] = tmp_reg->base() + shift; - else - eprom[3] = m_region_opt->base() + 0xc000 + shift; - - membank->configure_entries(0, 1, eprom[0], size); - membank->configure_entries(1, 1, eprom[1], size); - membank->configure_entries(2, 1, eprom[2], size); - membank->configure_entries(3, 1, eprom[3], size); - - if (banks > 4) - { - for (int i = 0; i < banks - 4; i++) - membank->configure_entries(i + 4, 1, m_region_opt->base() + 0x10000 + shift + i * 0x4000, size); - } -} - -void bbc_state::bbcm_setup_banks(memory_bank *membank, int banks, UINT32 shift, UINT32 size) -{ - std::string region_tag; - memory_region *tmp_reg; - UINT8 *eprom[2]; - if (m_exp1 && (tmp_reg = memregion(region_tag.assign(m_exp1->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) - eprom[0] = tmp_reg->base() + shift; - else - eprom[0] = m_region_opt->base() + 0x0000 + shift; - if (m_exp2 && (tmp_reg = memregion(region_tag.assign(m_exp2->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) - eprom[1] = tmp_reg->base() + shift; - else - eprom[1] = m_region_opt->base() + 0x8000 + shift; - - membank->configure_entries(0, 1, eprom[0], size); - membank->configure_entries(1, 1, eprom[0] + 0x4000, size); - membank->configure_entries(2, 1, eprom[1], size); - membank->configure_entries(3, 1, eprom[1] + 0x4000, size); - - if (banks > 4) - { - for (int i = 0; i < banks - 4; i++) - membank->configure_entries(i + 4, 1, m_region_opt->base() + 0x10000 + shift + i * 0x4000, size); - } -} - -MACHINE_START_MEMBER(bbc_state, bbca) -{ - bbc_setup_banks(m_bank4, 4, 0, 0x4000); -} - -MACHINE_RESET_MEMBER(bbc_state, bbca) -{ - UINT8 *RAM = m_region_maincpu->base(); - - m_bank1->set_base(RAM); - if (m_ram->size() == 32*1024) - { - /* 32K Model A */ - m_bank3->set_base(RAM + 0x4000); - m_memorySize=32; - } - else - { - /* 16K just repeat the lower 16K*/ - m_bank3->set_base(RAM); - m_memorySize=16; - } - - m_bank4->set_entry(0); - m_bank7->set_base(m_region_os->base()); /* bank 7 points at the OS rom from c000 to ffff */ - - bbcb_IC32_initialise(this); -} - -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); -} - -MACHINE_RESET_MEMBER(bbc_state, bbcb) -{ - UINT8 *RAM = m_region_maincpu->base(); - m_Speech = (ioport("BBCCONFIG")->read() >> 0) & 0x01; - m_SWRAMtype = (ioport("BBCCONFIG")->read() >> 3) & 0x03; - m_bank1->set_base(RAM); - m_bank3->set_base(RAM + 0x4000); - m_memorySize=32; - - m_bank4->set_entry(0); - m_bank7->set_base(m_region_os->base()); /* bank 7 points at the OS rom from c000 to ffff */ - - bbcb_IC32_initialise(this); -} - - -MACHINE_START_MEMBER(bbc_state, bbcbp) -{ - m_mc6850_clock = 0; - - m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(bbc_state::bbcbp_direct_handler), this)); - - bbc_setup_banks(m_bank4, 16, 0, 0x3000); - m_bank4->configure_entries(16, 1, m_region_maincpu->base() + 0x8000, 0x3000); // additional bank for paged ram - bbc_setup_banks(m_bank6, 16, 0x3000, 0x1000); -} - -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_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 */ - - bbcb_IC32_initialise(this); - - m_previous_wd177x_int_state=1; -} - - -MACHINE_START_MEMBER(bbc_state, bbcm) -{ - m_mc6850_clock = 0; - - m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(bbc_state::bbcm_direct_handler), this)); - - bbcm_setup_banks(m_bank4, 16, 0, 0x1000); - m_bank4->configure_entries(16, 1, m_region_maincpu->base() + 0x8000, 0x1000); // additional bank for paged ram - bbcm_setup_banks(m_bank5, 16, 0x1000, 0x3000); - - /* Set ROM/IO bank to point to rom */ - m_bank8->set_base(m_region_os->base() + 0x3c00); - m_maincpu->space(AS_PROGRAM).install_read_bank(0xfc00, 0xfeff, "bank8"); -} - -MACHINE_RESET_MEMBER(bbc_state, bbcm) -{ - m_bank1->set_base(m_region_maincpu->base()); /* bank 1 regular lower ram from 0000 to 2fff */ - m_bank2->set_base(m_region_maincpu->base() + 0x3000); /* bank 2 screen/shadow ram from 3000 to 7fff */ - m_bank4->set_entry(0); - m_bank5->set_entry(0); - 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; -} |
