diff options
Diffstat (limited to 'src/mess/drivers/phunsy.c')
-rw-r--r-- | src/mess/drivers/phunsy.c | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/src/mess/drivers/phunsy.c b/src/mess/drivers/phunsy.c new file mode 100644 index 00000000000..1c6a2767c23 --- /dev/null +++ b/src/mess/drivers/phunsy.c @@ -0,0 +1,349 @@ +/*************************************************************************** + + PHUNSY (Philipse Universal System) + + 04/11/2010 Skeleton driver. + + http://www.tubedata.info/phunsy/index.html + + Cassette added 2012-05-24 + Baud Rate ~ 6000 baud + W command to save data, eg 800-8FFW + R command to read data, eg 1100R to load the file at 1100, + or R to load the file where it came from. + The tape must already be playing the leader when you press the Enter + key, or it errors immediately. + +****************************************************************************/ + +#include "emu.h" +#include "cpu/s2650/s2650.h" +#include "machine/keyboard.h" +#include "sound/speaker.h" +#include "imagedev/cassette.h" +#include "sound/wave.h" + +#define MACHINE_RESET_MEMBER(name) void name::machine_reset() +#define VIDEO_START_MEMBER(name) void name::video_start() +#define SCREEN_UPDATE16_MEMBER(name) UINT32 name::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) + +#define LOG 1 + + +class phunsy_state : public driver_device +{ +public: + phunsy_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_speaker(*this, SPEAKER_TAG), + m_cass(*this, CASSETTE_TAG), + m_videoram(*this, "videoram") { } + + DECLARE_READ8_MEMBER( phunsy_data_r ); + DECLARE_WRITE8_MEMBER( phunsy_1800_w ); + DECLARE_WRITE8_MEMBER( phunsy_ctrl_w ); + DECLARE_WRITE8_MEMBER( phunsy_data_w ); + DECLARE_WRITE8_MEMBER( kbd_put ); + DECLARE_READ8_MEMBER(cass_r); + DECLARE_WRITE8_MEMBER(cass_w); + const UINT8 *m_p_chargen; + UINT8 m_data_out; + UINT8 m_keyboard_input; + UINT8 m_q_bank; + UINT8 m_u_bank; + UINT8 m_ram_1800[0x800]; + virtual void machine_reset(); + virtual void video_start(); + UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + required_device<cpu_device> m_maincpu; + required_device<device_t> m_speaker; + required_device<cassette_image_device> m_cass; + required_shared_ptr<UINT8> m_videoram; +}; + + +WRITE8_MEMBER( phunsy_state::phunsy_1800_w ) +{ + if ( m_u_bank == 0 ) + m_ram_1800[offset] = data; +} + +WRITE8_MEMBER( phunsy_state::cass_w ) +{ + m_cass->output(BIT(data, 0) ? -1.0 : +1.0); +} + +READ8_MEMBER( phunsy_state::cass_r ) +{ + return (m_cass->input() > 0.03) ? 0 : 1; +} + +static ADDRESS_MAP_START(phunsy_mem, AS_PROGRAM, 8, phunsy_state) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE( 0x0000, 0x07ff) AM_ROM + AM_RANGE( 0x0800, 0x0fff) AM_RAM + AM_RANGE( 0x1000, 0x17ff) AM_RAM AM_SHARE("videoram") // Video RAM + AM_RANGE( 0x1800, 0x1fff) AM_RAM_WRITE( phunsy_1800_w ) AM_ROMBANK("bank1") // Banked RAM/ROM + AM_RANGE( 0x4000, 0xffff) AM_RAMBANK("bank2") // Banked RAM +ADDRESS_MAP_END + + +WRITE8_MEMBER( phunsy_state::phunsy_ctrl_w ) +{ + if (LOG) + logerror("%s: phunsy_ctrl_w %02x\n", machine().describe_context(), data); + + m_u_bank = data >> 4; + m_q_bank = data & 0x0F; + + switch( m_u_bank ) + { + case 0x00: /* RAM */ + membank( "bank1" )->set_base( m_ram_1800 ); + break; + case 0x01: /* MDCR program */ + case 0x02: /* Disassembler */ + case 0x03: /* Label handler */ + membank( "bank1" )->set_base( memregion("maincpu")->base() + ( 0x800 * m_u_bank ) ); + break; + default: /* Not used */ + break; + } + + membank( "bank2" )->set_base( memregion("ram_4000")->base() + 0x4000 * m_q_bank ); +} + + +WRITE8_MEMBER( phunsy_state::phunsy_data_w ) +{ + if (LOG) + logerror("%s: phunsy_data_w %02x\n", machine().describe_context(), data); + + m_data_out = data; + + /* b0 - TTY out */ + /* b1 - select MDCR / keyboard */ + /* b2 - Clear keyboard strobe signal */ + if ( data & 0x04 ) + { + m_keyboard_input |= 0x80; + } + + /* b3 - speaker output (manual says it is bit 1)*/ + speaker_level_w(m_speaker, BIT(data, 1)); + + /* b4 - -REV MDCR output */ + /* b5 - -FWD MDCR output */ + /* b6 - -WCD MDCR output */ + /* b7 - WDA MDCR output */ +} + + +READ8_MEMBER( phunsy_state::phunsy_data_r ) +{ + UINT8 data; + + if (LOG) + logerror("%s: phunsy_data_r\n", machine().describe_context()); + + if ( m_data_out & 0x02 ) + { + /* MDCR selected */ + /* b0 - TTY input */ + /* b1 - SK1 switch input */ + /* b2 - SK2 switch input */ + /* b3 - -WEN MDCR input */ + /* b4 - -CIP MDCR input */ + /* b5 - -BET MDCR input */ + /* b6 - RDA MDCR input */ + /* b7 - RDC MDCR input */ + data = 0xFF; + } + else + { + /* Keyboard selected */ + /* b0-b6 - ASCII code from keyboard */ + /* b7 - strobe signal */ + data = m_keyboard_input; + } + + return data; +} + + +static ADDRESS_MAP_START( phunsy_io, AS_IO, 8, phunsy_state) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE( S2650_CTRL_PORT, S2650_CTRL_PORT ) AM_WRITE( phunsy_ctrl_w ) + AM_RANGE( S2650_DATA_PORT,S2650_DATA_PORT) AM_READWRITE( phunsy_data_r, phunsy_data_w ) + AM_RANGE(S2650_SENSE_PORT, S2650_FO_PORT) AM_READWRITE(cass_r, cass_w) +ADDRESS_MAP_END + + +/* Input ports */ +static INPUT_PORTS_START( phunsy ) +INPUT_PORTS_END + + +WRITE8_MEMBER( phunsy_state::kbd_put ) +{ + if (data) + m_keyboard_input = data; +} + + +static ASCII_KEYBOARD_INTERFACE( keyboard_intf ) +{ + DEVCB_DRIVER_MEMBER(phunsy_state, kbd_put) +}; + + +MACHINE_RESET_MEMBER(phunsy_state) +{ + membank( "bank1" )->set_base( m_ram_1800 ); + membank( "bank2" )->set_base( memregion("ram_4000")->base() ); + + m_u_bank = 0; + m_q_bank = 0; + m_keyboard_input = 0xFF; +} + + +static PALETTE_INIT( phunsy ) +{ + for ( int i = 0; i < 8; i++ ) + { + int j = ( i << 5 ) | ( i << 2 ) | ( i >> 1 ); + + palette_set_color_rgb( machine, i, j, j, j ); + } +} + + +VIDEO_START_MEMBER( phunsy_state ) +{ + m_p_chargen = memregion( "chargen" )->base(); +} + + +SCREEN_UPDATE16_MEMBER( phunsy_state ) +{ + UINT8 y,ra,chr,gfx,col; + UINT16 sy=0,ma=0,x; + + for (y = 0; y < 32; y++) + { + for (ra = 0; ra < 8; ra++) + { + UINT16 *p = &bitmap.pix16(sy++); + + for (x = ma; x < ma+64; x++) + { + chr = m_videoram[x]; + + if (BIT(chr, 7)) + { + /* Graphics mode */ + gfx = 0; + col = ( chr >> 4 ) & 7; + if ( (BIT(chr, 0) && (!BIT(ra, 2))) || (BIT(chr, 2) && (BIT(ra, 2))) ) + gfx = 0x38; + if ( (BIT(chr, 1) && (!BIT(ra, 2))) || (BIT(chr, 3) && (BIT(ra, 2))) ) + gfx |= 7; + } + else + { + /* ASCII mode */ + gfx = m_p_chargen[(chr<<3) | ra]; + col = 7; + } + + /* Display a scanline of a character (6 pixels) */ + *p++ = BIT( gfx, 5 ) ? col : 0; + *p++ = BIT( gfx, 4 ) ? col : 0; + *p++ = BIT( gfx, 3 ) ? col : 0; + *p++ = BIT( gfx, 2 ) ? col : 0; + *p++ = BIT( gfx, 1 ) ? col : 0; + *p++ = BIT( gfx, 0 ) ? col : 0; + } + } + ma+=64; + } + return 0; +} + +/* F4 Character Displayer */ +static const gfx_layout phunsy_charlayout = +{ + 5, 7, /* 6 x 8 characters */ + 128, /* 128 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 3, 4, 5, 6, 7 }, + /* y offsets */ + { 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, + 8*8 /* every char takes 8 bytes */ +}; + +static GFXDECODE_START( phunsy ) + GFXDECODE_ENTRY( "chargen", 0x0000, phunsy_charlayout, 1, 3 ) +GFXDECODE_END + + +static MACHINE_CONFIG_START( phunsy, phunsy_state ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu",S2650, XTAL_1MHz) + MCFG_CPU_PROGRAM_MAP(phunsy_mem) + MCFG_CPU_IO_MAP(phunsy_io) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + /* Display (page 12 of pdf) + - 8Mhz clock + - 64 6 pixel characters on a line. + - 16us not active, 48us active: ( 64 * 6 ) * 60 / 48 => 480 pixels wide + - 313 line display of which 256 are displayed. + */ + MCFG_SCREEN_RAW_PARAMS(XTAL_8MHz, 480, 0, 64*6, 313, 0, 256) + MCFG_SCREEN_UPDATE_DRIVER(phunsy_state, screen_update) + MCFG_GFXDECODE(phunsy) + MCFG_PALETTE_LENGTH(8) + MCFG_PALETTE_INIT(phunsy) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_WAVE_ADD(WAVE_TAG, CASSETTE_TAG) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) + MCFG_SOUND_ADD(SPEAKER_TAG, SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + + /* Devices */ + MCFG_ASCII_KEYBOARD_ADD(KEYBOARD_TAG, keyboard_intf) + MCFG_CASSETTE_ADD( CASSETTE_TAG, default_cassette_interface ) +MACHINE_CONFIG_END + + +/* ROM definition */ +ROM_START( phunsy ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "phunsy_bios.bin", 0x0000, 0x0800, CRC(a789e82e) SHA1(b1c130ab2b3c139fd16ddc5dc7bdcaf7a9957d02)) + ROM_LOAD( "pdcr.bin", 0x0800, 0x0800, CRC(74bf9d0a) SHA1(8d2f673615215947f033571f1221c6aa99c537e9)) + ROM_LOAD( "dass.bin", 0x1000, 0x0800, CRC(13380140) SHA1(a999201cb414abbf1e10a7fcc1789e3e000a5ef1)) + ROM_LOAD( "labhnd.bin", 0x1800, 0x0800, CRC(1d5a106b) SHA1(a20d09e32e21cf14db8254cbdd1d691556b473f0)) + + ROM_REGION( 0x0400, "chargen", ROMREGION_ERASEFF ) + ROM_LOAD( "ph_char1.bin", 0x0200, 0x0100, CRC(a7e567fc) SHA1(b18aae0a2d4f92f5a7e22640719bbc4652f3f4ee)) + ROM_CONTINUE(0x0100, 0x0100) + ROM_LOAD( "ph_char2.bin", 0x0000, 0x0100, CRC(3d5786d3) SHA1(8cf87d83be0b5e4becfa9fd6e05b01250a2feb3b)) + ROM_CONTINUE(0x0300, 0x0100) + + /* 16 x 16KB RAM banks */ + ROM_REGION( 0x40000, "ram_4000", ROMREGION_ERASEFF ) +ROM_END + +/* Driver */ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ +COMP( 1980, phunsy, 0, 0, phunsy, phunsy, driver_device, 0, "J.F.P. Philipse", "PHUNSY", GAME_NOT_WORKING ) + |