diff options
Diffstat (limited to 'src/mame/drivers/bfcobra.cpp')
-rw-r--r-- | src/mame/drivers/bfcobra.cpp | 1857 |
1 files changed, 0 insertions, 1857 deletions
diff --git a/src/mame/drivers/bfcobra.cpp b/src/mame/drivers/bfcobra.cpp deleted file mode 100644 index f7d172f221b..00000000000 --- a/src/mame/drivers/bfcobra.cpp +++ /dev/null @@ -1,1857 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Philip Bennett, Anonymous -/****************************************************************************** - - Bell-Fruit Cobra I/II and Viper Hardware - - driver by Phil Bennett and Anonymous - - Games supported: - * A Question of Sport [2 sets] - * Beeline (non-working - missing disk) - * Every Second Counts - * Inquizitor (Viper hardware, non-working - missing disk) - * Quizvaders - * Treble Top - - Other games on this hardware: - * Brain Box - * Quintoon alt. version (Cobra II/Cyclone hardware) - - Notes: - - The hardware is based on a chipset known as 'Flare One', developed - by Flare Technology. It consists of a 16-bit DSP (intended for sound - synthesis and 3D maths), an 8bpp blitter and a video controller, driven - by a Z80. - - Flare One would evolve to become 'Slipstream', used by the unreleased - Konix Multisystem console. - - The Flare One chipset is implemented as four Texas Instruments ASICs, - each an 84 pin PLCC package: - - CF30204, CF30205, CF30206 (DSP) and CF30207. - - The hardware using this chipset is as follows: - - Viper - ===== - - A video expansion PCB for Scorpion I? - On some PCB revisions there is audio output circuitry connected to the DSP. - Viper uses a WD1772 type floppy disk controller. - - Cobra I - ======= - - A combination of Viper and Scorpion I hardware on a single PCB. - Cobra uses an NEC '765 type FDC. Later revisions have no DSP. - - Cobra II (Cyclone) - ================== - - A compact video expansion board for Scorpion II. - The Z80 is replaced by a Z180 and there is no Flare DSP or FDC - - - To do: - - * Complete blitter emulation - * Cobra II support - * Hook up additional inputs, EM meters, lamps etc - - Known issues: - - * All games bar qos: NVRAM not saved - - * Viper does not have a colour palette - the Flare chipset drives RGB direct. - To fix this I set default values in the palette when the machine is initialised - * CPU execution rate is wrong, the hardware adds 1 TCycle to each access which is unaccounted for. - * Plane priority is probably wrong but it's only used in Treble Top. - * Blitter loop counts and step are wrong - they are 9 bit counts, not 8. - * Blitter emulation doesn't support hi-res mode (needed for Inquizitor) - -******************************************************************************/ - -#include "emu.h" -#include "cpu/m6809/m6809.h" -#include "cpu/z80/z80.h" -#include "machine/6850acia.h" -#include "machine/clock.h" -#include "machine/meters.h" -#include "machine/nvram.h" -#include "sound/ay8910.h" -#include "sound/upd7759.h" -#include "video/ramdac.h" -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - - -/* - Defines -*/ -#define Z80_XTAL 5910000 /* Unconfirmed */ -#define M6809_XTAL 4000000 /* Unconfirmed */ - - - -/*************************************************************************** - - Split into video\cobra.c ! - -***************************************************************************/ - -union ADDR_REG -{ -#ifdef LSB_FIRST - struct { uint16_t loword, hiword ; } as16bit; - struct { uint8_t addr0, addr1, addr2; } as8bit; -#else - struct { uint16_t hiword, loword ; } as16bit; - struct { uint8_t addr2, addr1, addr0; } as8bit; -#endif - uint32_t addr; -}; - -/* Blitter register flag bits */ -#define CMD_RUN 0x01 -#define CMD_COLST 0x02 -#define CMD_PARRD 0x04 /* Never used? */ -#define CMD_SRCUP 0x08 -#define CMD_DSTUP 0x10 -#define CMD_LT0 0x20 -#define CMD_LT1 0x40 -#define CMD_LINEDRAW 0x80 - - -/* All unconfirmed */ -//#define SRCDST_CMP 0x10 -//#define SRCDST_WRAP 0x20 -//#define SRCDST_SIGN 0x40 -#define SRCDST_A_1 0x80 /* This might be correct for line drawing? */ - -/* These appear to be correct */ -#define MODE_SSIGN 0x80 -#define MODE_DSIGN 0x40 -#define MODE_YFRAC 0x20 -#define MODE_BITTOBYTE 0x04 -#define MODE_PALREMAP 0x10 - -#define CMPFUNC_LT 0x01 -#define CMPFUNC_EQ 0x02 -#define CMPFUNC_GT 0x04 -#define CMPFUNC_BEQ 0x08 -#define CMPFUNC_LOG0 0x10 -#define CMPFUNC_LOG1 0x20 -#define CMPFUNC_LOG2 0x40 -#define CMPFUNC_LOG3 0x80 - -/* - Blitter state -*/ -struct bf_blitter_t -{ - ADDR_REG program; - - uint8_t control; - uint8_t status; - - uint8_t command; - ADDR_REG source; - ADDR_REG dest; - uint8_t modectl; - uint8_t compfunc; - uint8_t outercnt; - - uint8_t innercnt; - uint8_t step; - uint8_t pattern; -}; - -#define LOOPTYPE ( ( blitter.command&0x60 ) >> 5 ) - -struct fdc_t -{ - uint8_t MSR; - - int side; - int track; - int sector; - int number; - int stop_track; - int setup_read; - - int byte_pos; - int offset; - - int phase; - int next_phase; - int cmd_len; - int cmd_cnt; - int res_len; - int res_cnt; - uint8_t cmd[10]; - uint8_t results[8]; -}; - - -#define BLUE_0 0 -#define BLUE_1 1 -#define BLUE_2 2 -#define BLUE_3 3 -#define GREEN_0 ( 0 << 2 ) -#define GREEN_1 ( 1 << 2 ) -#define GREEN_2 ( 2 << 2 ) -#define GREEN_3 ( 3 << 2 ) -#define GREEN_4 ( 4 << 2 ) -#define GREEN_5 ( 5 << 2 ) -#define GREEN_6 ( 6 << 2 ) -#define GREEN_7 ( 7 << 2 ) -#define RED_0 ( 0 << 5 ) -#define RED_1 ( 1 << 5 ) -#define RED_2 ( 2 << 5 ) -#define RED_3 ( 3 << 5 ) -#define RED_4 ( 4 << 5 ) -#define RED_5 ( 5 << 5 ) -#define RED_6 ( 6 << 5 ) -#define RED_7 ( 7 << 5 ) - -class bfcobra_state : public driver_device -{ -public: - bfcobra_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_audiocpu(*this, "audiocpu"), - m_acia6850_0(*this, "acia6850_0"), - m_acia6850_1(*this, "acia6850_1"), - m_acia6850_2(*this, "acia6850_2"), - m_upd7759(*this, "upd"), - m_palette(*this, "palette"), - m_meters(*this, "meters") - { - } - - void init_bfcobra(); - void bfcobra(machine_config &config); - -protected: - DECLARE_READ8_MEMBER(chipset_r); - DECLARE_WRITE8_MEMBER(chipset_w); - DECLARE_WRITE8_MEMBER(rombank_w); - DECLARE_READ8_MEMBER(fdctrl_r); - DECLARE_READ8_MEMBER(fddata_r); - DECLARE_WRITE8_MEMBER(fdctrl_w); - DECLARE_READ8_MEMBER(int_latch_r); - DECLARE_READ8_MEMBER(meter_r); - DECLARE_WRITE8_MEMBER(meter_w); - DECLARE_READ8_MEMBER(latch_r); - DECLARE_WRITE8_MEMBER(latch_w); - DECLARE_READ8_MEMBER(upd_r); - DECLARE_WRITE8_MEMBER(upd_w); - DECLARE_WRITE_LINE_MEMBER(z80_acia_irq); - DECLARE_WRITE_LINE_MEMBER(m6809_data_irq); - DECLARE_WRITE_LINE_MEMBER(data_acia_tx_w); - DECLARE_WRITE_LINE_MEMBER(write_acia_clock); - virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_bfcobra(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(timer_irq); - INTERRUPT_GEN_MEMBER(vblank_gen); - void RunBlit(address_space &space); - void update_irqs(); - void reset_fdc(); - void exec_w_phase(uint8_t data); - void init_ram(); - void command_phase(struct fdc_t &fdc, uint8_t data); - inline uint8_t* blitter_get_addr(uint32_t addr); - inline void z80_bank(int num, int data); - - void m6809_prog_map(address_map &map); - void ramdac_map(address_map &map); - void z80_io_map(address_map &map); - void z80_prog_map(address_map &map); - -private: - uint8_t m_bank_data[4]; - std::unique_ptr<uint8_t[]> m_work_ram; - std::unique_ptr<uint8_t[]> m_video_ram; - uint8_t m_h_scroll; - uint8_t m_v_scroll; - uint8_t m_flip_8; - uint8_t m_flip_22; - uint8_t m_videomode; - uint8_t m_data_r; - uint8_t m_data_t; - int m_irq_state; - int m_acia_irq; - int m_vblank_irq; - int m_blitter_irq; - uint8_t m_z80_int; - uint8_t m_z80_inten; - uint32_t m_meter_latch; - uint32_t m_mux_input; - uint32_t m_mux_outputlatch; - uint8_t m_col4bit[16]; - uint8_t m_col3bit[16]; - uint8_t m_col8bit[256]; - uint8_t m_col7bit[256]; - uint8_t m_col6bit[256]; - struct bf_blitter_t m_blitter; - struct fdc_t m_fdc; - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - required_device<acia6850_device> m_acia6850_0; - required_device<acia6850_device> m_acia6850_1; - required_device<acia6850_device> m_acia6850_2; - required_device<upd7759_device> m_upd7759; - required_device<palette_device> m_palette; - required_device<meters_device> m_meters; -}; - - -static const uint8_t col4bit_default[16]= -{ - BLUE_0 | GREEN_0 | RED_0, - BLUE_1, - GREEN_2, - BLUE_1 | GREEN_2, - RED_2, - RED_2 | BLUE_1, - RED_2 | GREEN_2, - RED_2 | GREEN_2 | BLUE_1, - BLUE_2 | GREEN_5 | RED_5, - BLUE_3, - GREEN_7, - BLUE_3 | GREEN_7, - RED_7, - RED_7 | BLUE_3, - RED_7 | GREEN_7, - RED_7 | GREEN_7 | BLUE_3 -}; - -static const uint8_t col3bit_default[16]= -{ - 0, - BLUE_3, - GREEN_7, - BLUE_3 | GREEN_7, - RED_7, - RED_7 | BLUE_3, - RED_7 | GREEN_7, - RED_7 | GREEN_7 | BLUE_3, - 0, - BLUE_3, - GREEN_7, - BLUE_3 | GREEN_7, - RED_7, - RED_7 | BLUE_3, - RED_7 | GREEN_7, - RED_7 | GREEN_7 | BLUE_3 -}; - -static const uint8_t col76index[] = {0, 2, 4, 7}; - - -void bfcobra_state::video_start() -{ - int i; - - memcpy(m_col4bit, col4bit_default, sizeof(m_col4bit)); - memcpy(m_col3bit, col3bit_default, sizeof(m_col3bit)); - for (i = 0; i < 256; ++i) - { - uint8_t col; - - m_col8bit[i] = i; - col = i & 0x7f; - col = (col & 0x1f) | (col76index[ ( (col & 0x60) >> 5 ) & 3] << 5); - m_col7bit[i] = col; - - col = (col & 3) | (col76index[( (col & 0x0c) >> 2) & 3] << 2 ) | - (col76index[( (col & 0x30) >> 4) & 3] << 5 ); - m_col6bit[i] = col; - } -} - -uint32_t bfcobra_state::screen_update_bfcobra(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - int x, y; - uint8_t *src; - uint32_t *dest; - uint32_t offset; - uint8_t *hirescol; - uint8_t *lorescol; - - /* Select screen has to be programmed into two registers */ - /* No idea what happens if the registers are different */ - if (m_flip_8 & 0x40 && m_flip_22 & 0x40) - offset = 0x10000; - else - offset = 0; - - if(m_videomode & 0x20) - { - hirescol = m_col3bit; - lorescol = m_col7bit; - } - else if(m_videomode & 0x40) - { - hirescol = m_col4bit; - lorescol = m_col6bit; - } - else - { - hirescol = m_col4bit; - lorescol = m_col8bit; - } - - for (y = cliprect.top(); y <= cliprect.bottom(); ++y) - { - uint16_t y_offset = (y + m_v_scroll) * 256; - src = &m_video_ram[offset + y_offset]; - dest = &bitmap.pix32(y); - - for (x = cliprect.left(); x <= cliprect.right() / 2; ++x) - { - uint8_t x_offset = x + m_h_scroll; - uint8_t pen = *(src + x_offset); - - if ( ( m_videomode & 0x81 ) == 1 || (m_videomode & 0x80 && pen & 0x80) ) - { - *dest++ = m_palette->pen(hirescol[pen & 0x0f]); - *dest++ = m_palette->pen(hirescol[(pen >> 4) & 0x0f]); - } - else - { - *dest++ = m_palette->pen(lorescol[pen]); - *dest++ = m_palette->pen(lorescol[pen]); - } - } - } - - return 0; -} - -uint8_t* bfcobra_state::blitter_get_addr(uint32_t addr) -{ - if (addr < 0x10000) - { - /* Is this region fixed? */ - return (uint8_t*)(memregion("user1")->base() + addr); - } - else if(addr < 0x20000) - { - addr &= 0xffff; - addr += (m_bank_data[0] & 1) ? 0x10000 : 0; - - return (uint8_t*)(memregion("user1")->base() + addr + ((m_bank_data[0] >> 1) * 0x20000)); - } - else if (addr >= 0x20000 && addr < 0x40000) - { - return (uint8_t*)&m_video_ram[addr - 0x20000]; - } - else - { - return (uint8_t*)&m_work_ram[addr - 0x40000]; - } -} - - -/* - This is based this on the Slipstream technical reference manual. - The Flare One blitter is a simpler design with slightly different parameters - and will require hardware tests to figure everything out correctly. -*/ -void bfcobra_state::RunBlit(address_space &space) -{ -#define BLITPRG_READ(x) blitter.x = *(blitter_get_addr(blitter.program.addr++)) - - struct bf_blitter_t &blitter = m_blitter; - int cycles_used = 0; - - - do - { - uint8_t srcdata = 0; - uint8_t dstdata = 0; - - /* Read the blitter command */ - BLITPRG_READ(source.as8bit.addr0); - BLITPRG_READ(source.as8bit.addr1); - BLITPRG_READ(source.as8bit.addr2); - BLITPRG_READ(dest.as8bit.addr0); - BLITPRG_READ(dest.as8bit.addr1); - BLITPRG_READ(dest.as8bit.addr2); - BLITPRG_READ(modectl); - BLITPRG_READ(compfunc); - BLITPRG_READ(outercnt); - BLITPRG_READ(innercnt); - BLITPRG_READ(step); - BLITPRG_READ(pattern); - -#if 0 - /* This debug is now wrong ! */ - if (DEBUG_BLITTER) - { - osd_printf_debug("\n%s:Blitter: Running command from 0x%.5x\n\n", device->machine().describe_context(), blitter.program.addr - 12); - osd_printf_debug("Command Reg %.2x", blitter.command); - osd_printf_debug(" %s %s %s %s %s %s %s\n", - blitter.command & CMD_RUN ? "RUN" : " ", - blitter.command & CMD_COLST ? "COLST" : " ", - blitter.command & CMD_PARRD ? "PARRD" : " ", - blitter.command & CMD_SRCUP ? "SRCUP" : " ", - blitter.command & CMD_DSTUP ? "DSTUP" : " "); - - osd_printf_debug("Src Address Byte 0 %.2x\n", blitter.source.as8bit.addr0); - osd_printf_debug("Src Address Byte 1 %.2x\n", blitter.source.as8bit.addr1); - osd_printf_debug("Src Control %.2x\n", blitter.source.as8bit.addr2); - osd_printf_debug(" Src Address %.5x\n", blitter.source.addr & 0xfffff); - osd_printf_debug("Dest Address Byte 0 %.2x\n", blitter.dest.as8bit.addr0); - osd_printf_debug("Dest Address Byte 1 %.2x\n", blitter.dest.as8bit.addr1); - osd_printf_debug("Dest Control %.2x\n", blitter.dest.as8bit.addr2); - osd_printf_debug(" Dst. Address %.5x\n", blitter.dest.addr & 0xfffff); - osd_printf_debug("Mode Control %.2x", blitter.modectl); - osd_printf_debug(" %s\n", blitter.modectl & MODE_BITTOBYTE ? "BIT_TO_BYTE" : ""); - - osd_printf_debug("Comp. and LFU %.2x\n", blitter.compfunc); - osd_printf_debug("Outer Loop Count %.2x (%d)\n", blitter.outercnt, blitter.outercnt); - osd_printf_debug("Inner Loop Count %.2x (%d)\n", blitter.innercnt, blitter.innercnt); - osd_printf_debug("Step Value %.2x\n", blitter.step); - osd_printf_debug("Pattern Byte %.2x\n", blitter.pattern); - } -#endif - - /* Ignore these writes */ - if (blitter.dest.addr == 0) - return; - - /* Begin outer loop */ - for (;;) - { - uint8_t innercnt = blitter.innercnt; - dstdata = blitter.pattern; - - if (blitter.command & CMD_LINEDRAW) - { - do - { - if (blitter.modectl & MODE_YFRAC) - { - if (blitter.modectl & MODE_SSIGN ) - blitter.dest.as8bit.addr0--; - else - blitter.dest.as8bit.addr0++; - } - else - { - if (blitter.modectl & MODE_DSIGN ) - blitter.dest.as8bit.addr1--; - else - blitter.dest.as8bit.addr1++; - } - if( blitter.source.as8bit.addr0 < blitter.step ) - { - blitter.source.as8bit.addr0 -= blitter.step ; - blitter.source.as8bit.addr0 += blitter.source.as8bit.addr1; - - if ( blitter.modectl & MODE_YFRAC ) - { - if (blitter.modectl & MODE_DSIGN ) - blitter.dest.as8bit.addr1--; - else - blitter.dest.as8bit.addr1++; - } - else - { - if (blitter.modectl & MODE_SSIGN ) - blitter.dest.as8bit.addr0--; - else - blitter.dest.as8bit.addr0++; - } - } - else - { - blitter.source.as8bit.addr0 -= blitter.step; - } - - *blitter_get_addr( blitter.dest.addr) = blitter.pattern; - cycles_used++; - - } while (--innercnt); - } - else do - { - uint8_t inhibit = 0; - - /* TODO: Set this correctly */ - uint8_t result = blitter.pattern; - - if (LOOPTYPE == 3 && innercnt == blitter.innercnt) - { - srcdata = *(blitter_get_addr( blitter.source.addr & 0xfffff)); - blitter.source.as16bit.loword++; - cycles_used++; - } - - /* Enable source address read and increment? */ - if (!(blitter.modectl & (MODE_BITTOBYTE | MODE_PALREMAP))) - { - if (LOOPTYPE == 0 || LOOPTYPE == 1) - { - srcdata = *(blitter_get_addr( blitter.source.addr & 0xfffff)); - cycles_used++; - - if (blitter.modectl & MODE_SSIGN) - blitter.source.as16bit.loword-- ; - else - blitter.source.as16bit.loword++; - - result = srcdata; - } - } - - /* Read destination pixel? */ - if (LOOPTYPE == 0) - { - dstdata = *blitter_get_addr( blitter.dest.addr & 0xfffff); - cycles_used++; - } - - /* Inhibit depending on the bit selected by the inner count */ - - /* Switch on comparator type? */ - if (blitter.modectl & MODE_BITTOBYTE) - { - inhibit = !(srcdata & (1 << (8 - innercnt))); - } - - if (blitter.compfunc & CMPFUNC_BEQ) - { - if (srcdata == blitter.pattern) - { - inhibit = 1; - - /* TODO: Resume from inhibit? */ - if (blitter.command & CMD_COLST) - return; - } - } - if (blitter.compfunc & CMPFUNC_LT) - { - /* Might be wrong */ - if ((srcdata & 0xc0) < (dstdata & 0xc0)) - { - inhibit = 1; - - /* TODO: Resume from inhibit? */ - if (blitter.command & CMD_COLST) - return; - } - } - if (blitter.compfunc & CMPFUNC_EQ) - { - if ((srcdata & 0xc0) == (dstdata & 0xc0)) - { - inhibit = 1; - - /* TODO: Resume from inhibit? */ - if (blitter.command & CMD_COLST) - return; - } - } - if (blitter.compfunc & CMPFUNC_GT) - { - /* Might be wrong */ - if ((srcdata & 0xc0) > (dstdata & 0xc0)) - { - inhibit = 1; - - /* TODO: Resume from inhibit? */ - if (blitter.command & CMD_COLST) - return; - } - } - - /* Write the data if not inhibited */ - if (!inhibit) - { - if (blitter.modectl == MODE_PALREMAP) - { - /* - In this mode, the source points to a 256 entry lookup table. - The existing destination pixel is used as a lookup - into the table and the colours is replaced. - */ - uint8_t dest = *blitter_get_addr( blitter.dest.addr); - uint8_t newcol = *(blitter_get_addr( (blitter.source.addr + dest) & 0xfffff)); - - *blitter_get_addr( blitter.dest.addr) = newcol; - cycles_used += 3; - } - else - { - uint8_t final_result = 0; - - if (blitter.compfunc & CMPFUNC_LOG3) - final_result |= result & dstdata; - - if (blitter.compfunc & CMPFUNC_LOG2) - final_result |= result & ~dstdata; - - if (blitter.compfunc & CMPFUNC_LOG1) - final_result |= ~result & dstdata; - - if (blitter.compfunc & CMPFUNC_LOG0) - final_result |= ~result & ~dstdata; - - *blitter_get_addr( blitter.dest.addr) = final_result; - cycles_used++; - } - } - - /* Update destination address */ - if (blitter.modectl & MODE_DSIGN) - blitter.dest.as16bit.loword--; - else - blitter.dest.as16bit.loword++; - - } while (--innercnt); - - if (!--blitter.outercnt) - { - break; - } - else - { - if (blitter.command & CMD_DSTUP) - blitter.dest.as16bit.loword += blitter.step; - - if (blitter.command & CMD_SRCUP) - blitter.source.as16bit.loword += blitter.step; - - if (blitter.command & CMD_PARRD) - { - BLITPRG_READ(innercnt); - BLITPRG_READ(step); - BLITPRG_READ(pattern); - } - } - } - - /* Read next command header */ - BLITPRG_READ(command); - - } while (blitter.command & CMD_RUN); - - /* Burn Z80 cycles while blitter is in operation */ - space.device().execute().spin_until_time(attotime::from_nsec( (1000000000 / Z80_XTAL)*cycles_used * 2 ) ); -} - -/*************************************************************************** - - Flare One Register Map - - 01 Bank control for Z80 region 0x4000-0x7fff (16kB) WR - 02 Bank control for Z80 region 0x8000-0xbfff (16kB) WR - 03 Bank control for Z80 region 0xc000-0xffff (16kB) WR - - 06 Interrupt status....................................WR - 07 Interrupt ack.......................................WR - Writing here sets the line number that vertical interrupt is generated at. - cmd1, bit2 is the 9th bit of the line number - ???? Written with 0x21 - 08 cmd1 WR * bit 6 = screen select - bit2 = 9th bit of vertical interrupt line number - bit6 = 1 = select screen 1 else screen 0 - 09 cmd2 Linked with c001...............................W * bit 0 = 1 = hires - bit0=1=hi res else lo res (as long as bit7 is 0) - bit5=mask msb of each pixel - bit6=mask 2 msbits of each lores pixel - bit7=1=variable resolution - resolution is set by bit 7 of each vram byte. bit7=1=2 hires pixels - 0A ???? Written with 0 and 1...........................W - color of border - - 0B Horizontal frame buffer scroll .....................W - 0C Vertical frame buffer scroll .......................W - - 0D Colour hold colour..................................W - 0E Palette value for hi-res magenta....................W - 0F Palette value for hi-res yellow?....................W - 14 ....................................................W - - 18 Blitter program low byte............................WR - 19 Blitter program middle byte.........................W - 1A Blitter program high byte...........................W - 1B Blitter command?....................................W - 1C Blitter status?......................................R - 20 Blitter control register............................W - - 22 ???? Linked with C002...............................W - Mask of 20 - - Joystick: xxx1 11xx R - ? (polled on tight loop): x1xx xxxx R - - 40: ROM bank select.....................................W - -***************************************************************************/ - -void bfcobra_state::update_irqs() -{ - int newstate = m_blitter_irq || m_vblank_irq || m_acia_irq; - - if (newstate != m_irq_state) - { - m_irq_state = newstate; - m_maincpu->set_input_line(0, m_irq_state ? ASSERT_LINE : CLEAR_LINE); - } -} - -READ8_MEMBER(bfcobra_state::chipset_r) -{ - uint8_t val = 0xff; - - switch(offset) - { - case 1: - case 2: - case 3: - { - val = m_bank_data[offset]; - break; - } - case 6: - { - /* TODO */ - val = m_vblank_irq << 4; - break; - } - case 7: - { - m_vblank_irq = 0; - val = 0x1; - - /* TODO */ - update_irqs(); - break; - } - case 0x1C: - { - /* Blitter status ? */ - val = 0; - break; - } - case 0x20: - { - /* Seems correct - used during RLE pic decoding */ - val = m_blitter.dest.as8bit.addr0; - break; - } - case 0x22: - { - val = 0x40 | ioport("JOYSTICK")->read(); - break; - } - default: - { - osd_printf_debug("Flare One unknown read: 0x%.2x (PC:0x%.4x)\n", offset, m_maincpu->pcbase()); - } - } - - return val; -} - -WRITE8_MEMBER(bfcobra_state::chipset_w) -{ - switch (offset) - { - case 0x01: - case 0x02: - case 0x03: - { - if (data > 0x3f) - popmessage("%x: Unusual bank access (%x)\n", m_maincpu->pcbase(), data); - - data &= 0x3f; - m_bank_data[offset] = data; - z80_bank(offset, data); - break; - } - - case 0x08: - { - m_flip_8 = data; - break; - } - case 9: - m_videomode = data; - break; - - case 0x0B: - { - m_h_scroll = data; - break; - } - case 0x0C: - { - m_v_scroll = data; - break; - } - case 0x0E: - { - m_col4bit[5] = data; - m_col3bit[5] = data; - m_col3bit[5 + 8] = data; - break; - } - case 0x0f: - { - m_col4bit[6] = data; - m_col3bit[6] = data; - m_col3bit[6 + 8] = data; - break; - } - case 0x18: - { - m_blitter.program.as8bit.addr0 = data; - break; - } - case 0x19: - { - m_blitter.program.as8bit.addr1 = data; - break; - } - case 0x1A: - { - m_blitter.program.as8bit.addr2 = data; - break; - } - case 0x20: - { - m_blitter.command = data; - - if (data & CMD_RUN) - RunBlit(space); - else - osd_printf_debug("Blitter stopped by IO.\n"); - - break; - } - case 0x22: - { - m_flip_22 = data; - break; - } - default: - { - osd_printf_debug("Flare One unknown write: 0x%.2x with 0x%.2x (PC:0x%.4x)\n", offset, data, m_maincpu->pcbase()); - } - } -} - -void bfcobra_state::z80_bank(int num, int data) -{ - static const char * const bank_names[] = { "bank1", "bank2", "bank3" }; - - if (data < 0x08) - { - uint32_t offset = ((m_bank_data[0] >> 1) * 0x20000) + ((0x4000 * data) ^ ((m_bank_data[0] & 1) ? 0 : 0x10000)); - - membank(bank_names[num - 1])->set_base(memregion("user1")->base() + offset); - } - else if (data < 0x10) - { - membank(bank_names[num - 1])->set_base(&m_video_ram[(data - 0x08) * 0x4000]); - } - else - { - membank(bank_names[num - 1])->set_base(&m_work_ram[(data - 0x10) * 0x4000]); - } -} - -WRITE8_MEMBER(bfcobra_state::rombank_w) -{ - m_bank_data[0] = data; - z80_bank(1, m_bank_data[1]); - z80_bank(2, m_bank_data[2]); - z80_bank(3, m_bank_data[3]); -} - - - -/*************************************************************************** - - Split into machine\cobra.c ! - - Alternatively chuck it all away and borrow the MESS implementation - because it's a million times better. - -***************************************************************************/ - - -/* - WD37C656C-PL (or equivalent) Floppy Disk Controller -*/ - -enum fdc_phase -{ - COMMAND, - EXECUTION_R, - EXECUTION_W, - RESULTS -}; - -enum command -{ - SENSE_DRIVE_STATUS = 0, - READ_A_TRACK = 2, - SPECIFY = 3, - WRITE_DATA = 5, - READ_DATA = 6, - RECALIBRATE = 7, - SENSE_INTERRUPT_STATUS = 8, - WRITE_DELETED_DATA = 9, - READ_ID = 10, - FORMAT_TRACK = 13, - READ_DELETED_DATA = 14, - SEEK = 15, - SCAN_EQUAL = 17, - SCAN_LOW_OR_EQUAL = 25, - SCAN_HIGH_OR_EQUAL = 29 -}; - -void bfcobra_state::reset_fdc() -{ - memset(&m_fdc, 0, sizeof(m_fdc)); - - m_fdc.MSR = 0x80; - m_fdc.phase = COMMAND; -} - -READ8_MEMBER(bfcobra_state::fdctrl_r) -{ - uint8_t val = 0; - - val = m_fdc.MSR; - - return val; -} - -READ8_MEMBER(bfcobra_state::fddata_r) -{ - struct fdc_t &fdc = m_fdc; - #define BPS 1024 - #define SPT 10 - #define BPT 1024*10 - - uint8_t val = 0; - - if (fdc.phase == EXECUTION_R) - { - switch (fdc.cmd[0] & 0x1f) - { - /* Specify */ - case READ_DATA: - { - if (fdc.setup_read) - { - fdc.track = fdc.cmd[2]; - fdc.side = fdc.cmd[3]; - fdc.sector = fdc.cmd[4]; - fdc.number = fdc.cmd[5]; - fdc.stop_track = fdc.cmd[6]; - //int GPL = fdc.cmd[7]; - //int DTL = fdc.cmd[8]; - - fdc.setup_read = 0; - fdc.byte_pos = 0; - } - - fdc.offset = (BPT * fdc.track*2) + (fdc.side ? BPT : 0) + (BPS * (fdc.sector-1)) + fdc.byte_pos++; - val = *(memregion("user2")->base() + fdc.offset); - - /* Move on to next sector? */ - if (fdc.byte_pos == 1024) - { - fdc.byte_pos = 0; - - if (fdc.sector == fdc.stop_track || ++fdc.sector == 11) - { - /* End of read operation */ - fdc.MSR = 0xd0; - fdc.phase = RESULTS; - - fdc.results[0] = 0; - fdc.results[1] = 0; - fdc.results[2] = 0; - - fdc.results[3] = 0; - fdc.results[4] = 0; - fdc.results[5] = 0; - fdc.results[6] = 0; - } - } - break; - } - } - } - else if (fdc.phase == RESULTS) - { - val = fdc.results[fdc.res_cnt++]; - - if (fdc.res_cnt == fdc.res_len) - { - fdc.phase = COMMAND; - fdc.res_cnt = 0; - fdc.MSR &= ~0x40; - } - } - - return val; -} - -WRITE8_MEMBER(bfcobra_state::fdctrl_w) -{ - struct fdc_t &fdc = m_fdc; - switch (fdc.phase) - { - case COMMAND: - { - command_phase(fdc, data); - break; - } - case EXECUTION_W: - { - exec_w_phase(data); - break; - } - default: - { - osd_printf_debug("Unknown FDC phase?!"); - } - } -} - -void bfcobra_state::command_phase(struct fdc_t &fdc, uint8_t data) -{ - if (fdc.cmd_cnt == 0) - { - fdc.cmd[0] = data; - - fdc.cmd_cnt = 1; - - switch (data & 0x1f) - { - /* Specify */ - case READ_DATA: - { -// osd_printf_debug("Read data\n"); - fdc.cmd_len = 9; - fdc.res_len = 7; - fdc.next_phase = EXECUTION_R; - fdc.setup_read = 1; - break; - } - case SPECIFY: - { -// osd_printf_debug("Specify\n"); - fdc.cmd_len = 3; - fdc.res_len = 0; - fdc.next_phase = COMMAND; - break; - } - case RECALIBRATE: - { -// osd_printf_debug("Recalibrate\n"); - fdc.cmd_len = 2; - fdc.res_len = 0; - fdc.next_phase = COMMAND; - //fdc.MSR |= 0x40; - break; - } - case SENSE_INTERRUPT_STATUS: - { -// osd_printf_debug("Sense interrupt status\n"); - fdc.cmd_len = 1; - fdc.res_len = 2; - fdc.phase = RESULTS; - - fdc.results[0] = 0; - fdc.results[1] = 0; - - fdc.cmd_cnt = 0; - fdc.MSR |= 0x40; - break; - } - case SEEK: - { -// osd_printf_debug("Seek\n"); - fdc.cmd_len = 3; - fdc.res_len = 0; - fdc.next_phase = COMMAND; - break; - } - default: - { -// osd_printf_debug("%x\n",data & 0x1f); - } - } - } - else - { - fdc.cmd[fdc.cmd_cnt++] = data; - //osd_printf_debug(" %x\n",data); - } - - if (fdc.cmd_cnt == fdc.cmd_len) - { - fdc.phase = fdc.next_phase; - fdc.cmd_cnt = 0; - - if ((fdc.cmd[0] & 0x1f) == READ_DATA) - fdc.MSR = 0xf0; - } -} - -#ifdef UNUSED_FUNCTION -uint8_t bfcobra_state::exec_r_phase(void) -{ - return 0; -} -#endif - -void bfcobra_state::exec_w_phase(uint8_t data) -{ -} - -#ifdef UNUSED_FUNCTION -uint8_t bfcobra_state::results_phase(void) -{ - return 0; -} - -WRITE8_MEMBER(bfcobra_state::fd_op_w) -{ -} - -WRITE8_MEMBER(bfcobra_state::fd_ctrl_w) -{ -} -#endif - -void bfcobra_state::machine_reset() -{ - unsigned int pal; - - for (pal = 0; pal < 256; ++pal) - { - m_palette->set_pen_color(pal, pal3bit((pal>>5)&7), pal3bit((pal>>2)&7), pal2bit(pal&3)); - } - - m_bank_data[0] = 1; - reset_fdc(); - - m_irq_state = m_blitter_irq = m_vblank_irq = m_acia_irq = 0; -} - -/*************************************************************************** - - Cobra I/Viper Z80 Memory Map - -***************************************************************************/ - -void bfcobra_state::z80_prog_map(address_map &map) -{ - map(0x0000, 0x3fff).bankr("bank4"); - map(0x4000, 0x7fff).bankrw("bank1"); - map(0x8000, 0xbfff).bankrw("bank2"); - map(0xc000, 0xffff).bankrw("bank3"); -} - -void bfcobra_state::z80_io_map(address_map &map) -{ -map.global_mask(0xff); - map(0x00, 0x23).rw(FUNC(bfcobra_state::chipset_r), FUNC(bfcobra_state::chipset_w)); - map(0x24, 0x25).w(m_acia6850_0, FUNC(acia6850_device::write)); - map(0x26, 0x27).r(m_acia6850_0, FUNC(acia6850_device::read)); - map(0x30, 0x30).r(FUNC(bfcobra_state::fdctrl_r)); - map(0x31, 0x31).rw(FUNC(bfcobra_state::fddata_r), FUNC(bfcobra_state::fdctrl_w)); - map(0x40, 0x40).w(FUNC(bfcobra_state::rombank_w)); - map(0x50, 0x50).w("ramdac", FUNC(ramdac_device::index_w)); - map(0x51, 0x51).rw("ramdac", FUNC(ramdac_device::pal_r), FUNC(ramdac_device::pal_w)); - map(0x52, 0x52).w("ramdac", FUNC(ramdac_device::mask_w)); - map(0x53, 0x53).w("ramdac", FUNC(ramdac_device::index_r_w)); -} - - -void bfcobra_state::ramdac_map(address_map &map) -{ - map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb666_w)); -} - - -/*************************************************************************** - - Cobra I/Viper 6809 Memory Map - - Cobra I has these components: - - EF68B50P - For communication with Z80 - EF68B50P - For data retrieval - AY38912A - UPD7759C - BFM1090 (CF30056) - 'TEXAS' I/O chip, lamps and misc - BFM1095 (CF30057) - 'TEXAS' I/O chip, handles switches - BFM1071 - 6809 Address decoding and bus control - - /IRQ provided by EF68850P at IC38 - /FIRQ connected to meter current sensing circuitry - - TODO: Calculate watchdog timer period. - -***************************************************************************/ - -/* TODO */ -READ8_MEMBER(bfcobra_state::int_latch_r) -{ - return 2 | 1; -} - -/* TODO */ -READ8_MEMBER(bfcobra_state::meter_r) -{ - return m_meter_latch; -} - -/* TODO: This is borrowed from Scorpion 1 */ -WRITE8_MEMBER(bfcobra_state::meter_w) -{ - int i; - int changed = m_meter_latch ^ data; - - m_meter_latch = data; - - /* - When a meter is triggered, the current drawn is sensed. If a meter - is connected, the /FIRQ line will be pulsed. - */ - for (i = 0; i < 8; i++) - { - if (changed & (1 << i)) - { - m_meters->update(i, data & (1 << i) ); - m_audiocpu->set_input_line(M6809_FIRQ_LINE, HOLD_LINE); - } - } -} - -/* TODO */ -READ8_MEMBER(bfcobra_state::latch_r) -{ - return m_mux_input; -} - -WRITE8_MEMBER(bfcobra_state::latch_w) -{ - /* TODO: This is borrowed from Scorpion 1 */ - switch(offset) - { - case 0: - { - int changed = m_mux_outputlatch ^ data; - static const char *const port[] = { "STROBE0", "STROBE1", "STROBE2", "STROBE3", "STROBE4", "STROBE5", "STROBE6", "STROBE7" }; - - m_mux_outputlatch = data; - - /* Clock has changed */ - if (changed & 0x08) - { - int input_strobe = data & 0x7; - - /* Clock is low */ - if (!(data & 0x08)) - m_mux_input = ioport(port[input_strobe])->read(); - } - break; - } - case 1: - { -// strobe_data_l = data; - break; - } - case 2: - { -// strobe_data_h = data; - break; - } - } -} - -READ8_MEMBER(bfcobra_state::upd_r) -{ - return 2 | m_upd7759->busy_r(); -} - -WRITE8_MEMBER(bfcobra_state::upd_w) -{ - m_upd7759->reset_w(BIT(data, 7)); - m_upd7759->port_w(data & 0x3f); - m_upd7759->start_w(!BIT(data, 6)); -} - -void bfcobra_state::m6809_prog_map(address_map &map) -{ - map(0x0000, 0x1fff).ram().share("nvram"); - map(0x2000, 0x2000).ram(); // W 'B', 6F - map(0x2200, 0x2200).ram(); // W 'F' - map(0x2600, 0x2600).rw(FUNC(bfcobra_state::meter_r), FUNC(bfcobra_state::meter_w)); - map(0x2800, 0x2800).ram(); // W - map(0x2a00, 0x2a02).rw(FUNC(bfcobra_state::latch_r), FUNC(bfcobra_state::latch_w)); - map(0x2e00, 0x2e00).r(FUNC(bfcobra_state::int_latch_r)); - map(0x3001, 0x3001).w("aysnd", FUNC(ay8910_device::data_w)); - map(0x3201, 0x3201).w("aysnd", FUNC(ay8910_device::address_w)); - map(0x3404, 0x3405).rw(m_acia6850_1, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); - map(0x3406, 0x3407).rw(m_acia6850_2, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); -// map(0x3408, 0x3408).noprw(); -// map(0x340a, 0x340a).noprw(); -// map(0x3600, 0x3600).noprw(); - map(0x3801, 0x3801).rw(FUNC(bfcobra_state::upd_r), FUNC(bfcobra_state::upd_w)); - map(0x8000, 0xffff).rom(); - map(0xf000, 0xf000).nopw(); /* Watchdog */ -} - -static INPUT_PORTS_START( bfcobra ) - PORT_START("STROBE0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_NAME("Coin: 10p") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_NAME("Coin: 20p") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) PORT_NAME("Coin: 50p") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN4 ) PORT_NAME("Coin: 1 pound") - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Green Test?") PORT_CODE(KEYCODE_F1) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Red Test?") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("STROBE1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Pass") PORT_CODE(KEYCODE_A) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Continue") PORT_CODE(KEYCODE_S) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Collect") PORT_CODE(KEYCODE_D) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("Start") - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Bonus") PORT_CODE(KEYCODE_F) -// PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) -// PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 ) -// PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON3 ) - - PORT_START("STROBE2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("<A") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("<B") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("<C") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("A>") - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_NAME("B>") - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON10 ) PORT_NAME("C>") - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - - PORT_START("STROBE3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_INTERLOCK) PORT_NAME("Cash box door") PORT_CODE(KEYCODE_Y) PORT_TOGGLE - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Front Door? (resets)") PORT_CODE(KEYCODE_T) PORT_TOGGLE - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Refill Key") PORT_CODE(KEYCODE_R) PORT_TOGGLE - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - - PORT_START("STROBE4") - PORT_BIT( 0xFF, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - - PORT_START("STROBE5") - PORT_BIT( 0xFF, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - - PORT_START("STROBE6") - PORT_DIPNAME( 0x01, 0x00, "DIL09" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, "DIL10" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, "DIL11" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, "DIL12" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x00, "DIL13" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, "DIL14" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, "DIL15" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - - PORT_START("STROBE7") - PORT_DIPNAME( 0x01, 0x00, "DIL02" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, "DIL03" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, "DIL04" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, "DIL05" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x00, "DIL06" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, "DIL07" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, "DIL08" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - - PORT_START("JOYSTICK") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) -INPUT_PORTS_END - -/* - Allocate work RAM and video RAM shared by the Z80 and chipset. -*/ -void bfcobra_state::init_ram() -{ - /* 768kB work RAM */ - m_work_ram = make_unique_clear<uint8_t[]>(0xC0000); - - /* 128kB video RAM */ - m_video_ram = make_unique_clear<uint8_t[]>(0x20000); -} - - -WRITE_LINE_MEMBER(bfcobra_state::z80_acia_irq) -{ - m_acia_irq = state; - update_irqs(); -} - - -WRITE_LINE_MEMBER(bfcobra_state::m6809_data_irq) -{ - m_audiocpu->set_input_line(M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); -} - - -WRITE_LINE_MEMBER(bfcobra_state::data_acia_tx_w) -{ - m_data_t = state; -} - - -WRITE_LINE_MEMBER(bfcobra_state::write_acia_clock) -{ - m_acia6850_0->write_txc(state); - m_acia6850_0->write_rxc(state); - m_acia6850_1->write_txc(state); - m_acia6850_1->write_rxc(state); - m_acia6850_2->write_txc(state); - m_acia6850_2->write_rxc(state); -} - - -/* TODO: Driver vs Machine Init */ -void bfcobra_state::init_bfcobra() -{ - /* - 6809 ROM address and data lines are scrambled. - This is the same scrambling as Scorpion 2. - */ - static const uint8_t datalookup[] = { 1, 3, 5, 6, 4, 2, 0, 7 }; - static const uint8_t addrlookup[] = { 11, 12, 0, 2, 3, 5, 7, 9, 8, 6, 1, 4, 10, 13, 14 }; - - std::vector<uint8_t> tmp(0x8000); - uint8_t *rom = memregion("audiocpu")->base() + 0x8000; - memcpy(&tmp[0], rom, 0x8000); - - for (uint32_t i = 0; i < 0x8000; i++) - { - uint8_t val = tmp[i]; - - uint8_t data = 0; - for (uint8_t x = 0; x < 8; x ++) - data |= ((val >> x) & 1) << datalookup[x]; - - uint16_t addr = 0; - for (uint8_t x = 0; x < 15; x ++) - addr |= ((i >> x) & 1) << addrlookup[x]; - - rom[addr] = data; - } - - init_ram(); - - m_bank_data[0] = 1; - m_bank_data[1] = 0; - m_bank_data[2] = 0; - m_bank_data[3] = 0; - - /* Fixed 16kB ROM region */ - membank("bank4")->set_base(memregion("user1")->base()); - - /* TODO: Properly sort out the data ACIA */ - m_acia6850_2->write_rxd(1); - - /* Finish this */ - save_item(NAME(m_data_r)); - save_item(NAME(m_data_t)); - save_item(NAME(m_h_scroll)); - save_item(NAME(m_v_scroll)); - save_item(NAME(m_flip_8)); - save_item(NAME(m_flip_22)); - save_item(NAME(m_z80_int)); - save_item(NAME(m_z80_inten)); - save_item(NAME(m_bank_data)); - save_pointer(NAME(m_work_ram), 0xc0000); - save_pointer(NAME(m_video_ram), 0x20000); -} - -/* TODO */ -INTERRUPT_GEN_MEMBER(bfcobra_state::timer_irq) -{ - device.execute().set_input_line(M6809_IRQ_LINE, HOLD_LINE); -} - -/* TODO */ -INTERRUPT_GEN_MEMBER(bfcobra_state::vblank_gen) -{ - m_vblank_irq = 1; - update_irqs(); -} - -void bfcobra_state::bfcobra(machine_config &config) -{ - Z80(config, m_maincpu, Z80_XTAL); - m_maincpu->set_addrmap(AS_PROGRAM, &bfcobra_state::z80_prog_map); - m_maincpu->set_addrmap(AS_IO, &bfcobra_state::z80_io_map); - m_maincpu->set_vblank_int("screen", FUNC(bfcobra_state::vblank_gen)); - - MC6809(config, m_audiocpu, M6809_XTAL); // MC6809P - m_audiocpu->set_addrmap(AS_PROGRAM, &bfcobra_state::m6809_prog_map); - m_audiocpu->set_periodic_int(FUNC(bfcobra_state::timer_irq), attotime::from_hz(1000)); - - NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); - - - /* TODO */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); - screen.set_size(512, 256); - screen.set_visarea_full(); - screen.set_screen_update(FUNC(bfcobra_state::screen_update_bfcobra)); - - PALETTE(config, m_palette).set_entries(256); - - ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette)); // MUSIC Semiconductor TR9C1710 RAMDAC or equivalent - ramdac.set_addrmap(0, &bfcobra_state::ramdac_map); - ramdac.set_split_read(1); - - SPEAKER(config, "mono").front_center(); - - AY8910(config, "aysnd", M6809_XTAL / 4).add_route(ALL_OUTPUTS, "mono", 0.20); - - UPD7759(config, m_upd7759).add_route(ALL_OUTPUTS, "mono", 0.40); - - /* ACIAs */ - ACIA6850(config, m_acia6850_0, 0); - m_acia6850_0->txd_handler().set(m_acia6850_1, FUNC(acia6850_device::write_rxd)); - m_acia6850_0->irq_handler().set(FUNC(bfcobra_state::z80_acia_irq)); - - ACIA6850(config, m_acia6850_1, 0); - m_acia6850_1->txd_handler().set(m_acia6850_0, FUNC(acia6850_device::write_rxd)); - - ACIA6850(config, m_acia6850_2, 0); - m_acia6850_2->txd_handler().set(FUNC(bfcobra_state::data_acia_tx_w)); - m_acia6850_2->irq_handler().set(FUNC(bfcobra_state::m6809_data_irq)); - - clock_device &acia_clock(CLOCK(config, "acia_clock", 31250*16)); // What are the correct ACIA clocks ? - acia_clock.signal_handler().set(FUNC(bfcobra_state::write_acia_clock)); - - METERS(config, m_meters, 0).set_number(8); -} - -/*************************************************************************** - - Game driver(s) - - Note: Two different versions of each 6809 ROM exist: standard and protocol - It appears sets can be a combination of disk images, 6809 and Z80 ROMs! - -***************************************************************************/ - -ROM_START( inquiztr ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "inq6809", 0x08000, 0x08000, CRC(ae996600) SHA1(f360399e77b81399d910770fa8106c196f04363c) ) - - ROM_REGION( 0x20000, "user1", 0 ) - ROM_LOAD( "9576002.bin", 0x00000, 0x10000, CRC(5b8c8a04) SHA1(af5328fee79c370f45bff36f534aaf50964b6900) ) - - ROM_REGION( 0x20000, "altuser1", 0 ) - ROM_LOAD( "9576028.bin", 0x10000, 0x10000, CRC(2d85682c) SHA1(baec47bff4b8beef5afbb737dc57b22bf93ebcf8) ) - - // these look quite different.. (like they belong together) but booting with these gives a checksum error (banking?) - ROM_LOAD( "inqvypp1", 0x00000, 0x010000, CRC(9bac8c6e) SHA1(15e24d60c2f3997e637694f60daa552b22628766) ) - ROM_LOAD( "inqvypp2", 0x10000, 0x010000, CRC(f9cd196c) SHA1(0ac31d87462cbee6f41e19aefe740d876910bdf5) ) - - ROM_REGION( 0x1c2000, "user2", 0 ) - ROM_LOAD( "inqdisk.img", 0x000000, 0x1c2000, NO_DUMP ) -ROM_END - - - - -ROM_START( escounts ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "esc12int", 0x08000, 0x08000, CRC(741a1fe6) SHA1(e741d0ae0d2f11036a358120381e4b0df4a560a1) ) - - ROM_REGION( 0x10000, "altrevs", 0 ) - ROM_LOAD( "bfm_esc.bin", 0x08000, 0x08000, CRC(27acb5a5) SHA1(da50d650ab6456d61d0fb7f89247f2040b4bb9a8) ) - ROM_LOAD( "escint1b", 0x08000, 0x08000, CRC(fde413c9) SHA1(18724a1b771ba4c72e571c356591c5be32948d7a) ) - - ROM_REGION( 0x10000, "user1", 0 ) - ROM_LOAD( "esccobpa", 0x00000, 0x10000, CRC(d8eadeb7) SHA1(9b94f1454e6a17bf8321b0ef4ddd0ed1a56150f7) ) - - /* 95-100-207 */ - ROM_REGION( 0x190000, "user2", 0 ) - ROM_LOAD( "escdisk4.img", 0x000000, 0x190000, CRC(24156e0f) SHA1(e163daa8effadd93ace2bc2ba1af0f4a190abd7f) ) -ROM_END - -ROM_START( trebltop ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "95740078.bin", 0x08000, 0x08000, CRC(aca1980b) SHA1(3d4ed1dc545cc80f56d7daa13028fb10a12a718b) ) - - ROM_REGION( 0x10000, "altrevs", 0 ) - ROM_LOAD( "ttopint", 0x08000, 0x08000, CRC(cc798f90) SHA1(c3f541ebbb3a2c29cc4f00bbd47e289bcff50ecb) ) - - ROM_REGION( 0x20000, "user1", 0 ) - ROM_LOAD( "95760031.bin", 0x00000, 0x10000, CRC(8e75edb8) SHA1(0aaa3834d5ac20f92bdf1f2b8f1eb71854469cbe) ) - ROM_LOAD( "95760021.bin", 0x10000, 0x10000, CRC(f42016c0) SHA1(7067d018cb4bdcfba777267fb01cddf44e4216c3) ) - - ROM_REGION( 0x1c2000, "user2", 0 ) - ROM_LOAD( "ttdisk1.img", 0x000000, 0x190000, CRC(b2003228) SHA1(5eb49f05137cdd404f22948d39aa79c1518c06eb) ) - - ROM_REGION( 0x20000, "upd", 0 ) - ROM_LOAD( "95000172.bin", 0x00000, 0x10000, CRC(e85367a5) SHA1(695fd95ddeecdb16602f7b0f075cf5128a2fb808) ) - ROM_LOAD( "95000173.bin", 0x10000, 0x10000, CRC(8bda2c5e) SHA1(79aab5a2af7a5add5fe9132dc13bcc3705c6faf3) ) -ROM_END - -ROM_START( beeline ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "bln12int.a", 0x08000, 0x08000, CRC(cb97905e) SHA1(9725156bf64e53a56bc0f90795d4b07db41d059e) ) - - ROM_REGION( 0x10000, "altrevs", 0 ) - ROM_LOAD( "beeint12", 0x8000, 0x008000, CRC(0a77d0be) SHA1(8e55e7b4eb85cc2521d8fdf7ede02131ed80372e) ) - - - ROM_REGION( 0x20000, "user1", 0 ) - ROM_LOAD( "blncob.pa", 0x00000, 0x10000, CRC(8abc0017) SHA1(ecf6e7a4021b35295eb9bb9aed1b88fff27ffbd1) ) - ROM_LOAD( "blncob.pb", 0x10000, 0x10000, CRC(feb121fe) SHA1(e83bfd6db00a3264e5076f257e261a1cb4605a83) ) - - ROM_REGION( 0x1c2000, "user2", 0 ) - ROM_LOAD( "beedisk.img", 0x000000, 0x1c2000, NO_DUMP ) -ROM_END - -ROM_START( quizvadr ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "q6809.bin", 0x08000, 0x8000, CRC(a74dff10) SHA1(87578694a022dc3d7ade9cc76d387c1ae5fc74d9) ) - - ROM_REGION( 0x10000, "altrevs", 0 ) - ROM_LOAD( "qvadrint", 0x08000, 0x08000, CRC(4c729943) SHA1(ab4e0fb6cfc66540ea1e9e36eebdf85f65c5fd2a) ) - - ROM_REGION( 0x200000, "user1", 0 ) - ROM_LOAD( "5947011r.0", 0x000000, 0x80000, CRC(cac43c97) SHA1(3af529cd0f8ec57dd3596f5bca7b9c74cff171e4) ) - ROM_LOAD( "5947011r.1", 0x080000, 0x80000, CRC(120018dc) SHA1(cd153d2b7ed535b04dbcaf189d2fc96fe3c5b466) ) - ROM_LOAD( "5947011r.2", 0x100000, 0x80000, CRC(689b3b5a) SHA1(ea32d18acfd380de822efff4f2c95ce9873a33a2) ) - ROM_LOAD( "5947011r.3", 0x180000, 0x80000, CRC(c38dafeb) SHA1(d693387a5c3cde34c9d581f81a08a5fbc6f753f2) ) - - ROM_REGION( 0x20000, "upd", 0 ) - ROM_LOAD( "185snd2.bin", 0x00000, 0x10000, CRC(e36eccc2) SHA1(cfd8ca4c71528ea4e229074016240681b6de37cd) ) - ROM_LOAD( "184snd1.bin", 0x10000, 0x10000, CRC(aac058e8) SHA1(39e59ad9524130fc3bd8d46e1aa78bc4daf04e39) ) -ROM_END - -ROM_START( qos ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "39360107.bin", 0x08000, 0x8000, CRC(20844655) SHA1(b67c7f7bbabf6d5139b8ad8cbb5f8cc3f28e9cc7) ) - - ROM_REGION( 0x200000, "user1", 0 ) - ROM_LOAD( "95000338.rm0", 0x000000, 0x80000, CRC(96918aae) SHA1(849ce7b8eccc89c45aacc840a73935f95788a141) ) - ROM_LOAD( "95000339.rm1", 0x080000, 0x80000, CRC(b4c6dcc0) SHA1(56d8761766dfbd5b0e71f8c3ca575e88f1bc9929) ) - ROM_LOAD( "95000340.rm2", 0x100000, 0x80000, CRC(66d121fd) SHA1(ac65cc0ac6b0a41e78a3159c21ee44f765bdb5c8) ) - ROM_LOAD( "95000341.rm3", 0x180000, 0x80000, CRC(ef13658d) SHA1(240bc589900214eac79c91a531f254a9ac2f4ef6) ) - - ROM_REGION( 0x20000, "upd", 0 ) - ROM_LOAD( "snd1_218.ic7", 0x00000, 0x10000, CRC(061f496d) SHA1(653d16454d909c034191813b37d14010da7258c6) ) - ROM_LOAD( "snd2_219.ic8", 0x10000, 0x10000, CRC(d7874a47) SHA1(5bbd4040c7c0299e8cc135e6c6cd05370b260e9b) ) -ROM_END - -ROM_START( qosa ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "qos_nondata_68f4.bin", 0x08000, 0x8000, CRC(5f40005a) SHA1(180017acf6b432bc135d1090099fdf99f1e3583a) ) - - ROM_REGION( 0x200000, "user1", 0 ) - ROM_LOAD( "95000338.rm0", 0x000000, 0x80000, CRC(96918aae) SHA1(849ce7b8eccc89c45aacc840a73935f95788a141) ) - ROM_LOAD( "95000339.rm1", 0x080000, 0x80000, CRC(b4c6dcc0) SHA1(56d8761766dfbd5b0e71f8c3ca575e88f1bc9929) ) - ROM_LOAD( "95000340.rm2", 0x100000, 0x80000, CRC(66d121fd) SHA1(ac65cc0ac6b0a41e78a3159c21ee44f765bdb5c8) ) - ROM_LOAD( "95000341.rm3", 0x180000, 0x80000, CRC(ef13658d) SHA1(240bc589900214eac79c91a531f254a9ac2f4ef6) ) - - ROM_REGION( 0x20000, "upd", 0 ) - ROM_LOAD( "snd1_218.ic7", 0x00000, 0x10000, CRC(061f496d) SHA1(653d16454d909c034191813b37d14010da7258c6) ) - ROM_LOAD( "snd2_219.ic8", 0x10000, 0x10000, CRC(d7874a47) SHA1(5bbd4040c7c0299e8cc135e6c6cd05370b260e9b) ) -ROM_END - -ROM_START( qosb ) - ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "95740599.bin", 0x08000, 0x8000, CRC(bf1e321f) SHA1(51f18620f22ba2a1b110954284ddf00614d51a0e) ) - - ROM_REGION( 0x200000, "user1", 0 ) - ROM_LOAD( "rom0_306.bin", 0x000000, 0x80000, CRC(c26c8f83) SHA1(6949027e1fe241cbb2e1cbbce18e47bcb0d84550) ) - ROM_LOAD( "rom1_307.bin", 0x080000, 0x80000, CRC(94611c03) SHA1(81f545ff96ff3d44285315400da94d870c89f896) ) - ROM_LOAD( "rom2_308.bin", 0x100000, 0x80000, CRC(f5572726) SHA1(e109265c5571d21213a6f405a13459e7bc6699bc) ) - ROM_LOAD( "rom3_309.bin", 0x180000, 0x80000, CRC(1b5edfa8) SHA1(348488debd4aa52f064e351ed0c082274da1db2b) ) - - ROM_REGION( 0x20000, "upd", 0 ) - ROM_LOAD( "snd1_218.ic7", 0x00000, 0x10000, CRC(061f496d) SHA1(653d16454d909c034191813b37d14010da7258c6) ) - ROM_LOAD( "snd2_219.ic8", 0x10000, 0x10000, CRC(d7874a47) SHA1(5bbd4040c7c0299e8cc135e6c6cd05370b260e9b) ) - - /* there is a set close to this with - - ROM_LOAD( "qosrom0", 0x0000, 0x080000, CRC(4f150634) SHA1(beb1d3c212b189f3baa08fe454e83f30108be08e) ) - qosrom1 = rom1_307.bin qosb A Question of Sport (39-960-089) - ROM_LOAD( "qosrom2", 0x0000, 0x080000, CRC(c39737db) SHA1(ccfdb19dab3af064db44e6022248aef98749bc97) ) - ROM_LOAD( "qosrom3", 0x0000, 0x080000, CRC(785b8ff9) SHA1(61b31e0e60c31ecb4b179bfe008a96155d939709) ) - ROM_LOAD( "qossnd1", 0x0000, 0x010000, CRC(888a29f8) SHA1(0e5aa9db54e783708ece1e8c7bffb10d994ab384) ) - - but it simply looks like a bad dump, rom3 is an alt 'rom 2' and the others are mostly the same as qosb - */ - -ROM_END - - -GAME( 1989, inquiztr, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Inquizitor", MACHINE_NOT_WORKING ) -GAME( 1990, escounts, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Every Second Counts (39-360-053)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1991, trebltop, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Treble Top (39-360-070)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1991, beeline, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Beeline (39-360-075)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1991, quizvadr, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Quizvaders (39-360-078)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1992, qos, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "A Question of Sport (set 1, 39-960-107)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1992, qosa, qos, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "A Question of Sport (set 2, 39-960-099)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1992, qosb, qos, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "A Question of Sport (set 3, 39-960-089)", MACHINE_IMPERFECT_GRAPHICS ) |