trunk/src/mess/drivers/univac.c
| r30695 | r30696 | |
| 13 | 13 | buttons. Thus the user can have two sessions open at once, to different |
| 14 | 14 | mainframes or applications. |
| 15 | 15 | |
| 16 | Sound is a beeper. |
| 17 | |
| 18 | This driver is all guesswork; Unisys never released technical info |
| 19 | to customers. All parts on the PCBs have internal Unisys part numbers |
| 20 | instead of the manufacturer's numbers. |
| 21 | |
| 16 | 22 | ****************************************************************************/ |
| 17 | 23 | |
| 18 | 24 | #include "emu.h" |
| 19 | 25 | #include "cpu/z80/z80.h" |
| 26 | #include "cpu/z80/z80daisy.h" |
| 27 | #include "machine/nvram.h" |
| 28 | #include "machine/z80ctc.h" |
| 29 | #include "machine/z80dart.h" |
| 20 | 30 | |
| 21 | 31 | |
| 22 | 32 | class univac_state : public driver_device |
| 23 | 33 | { |
| 24 | 34 | public: |
| 25 | 35 | univac_state(const machine_config &mconfig, device_type type, const char *tag) |
| 26 | | : driver_device(mconfig, type, tag), |
| 27 | | m_maincpu(*this, "maincpu") |
| 36 | : driver_device(mconfig, type, tag) |
| 37 | , m_maincpu(*this, "maincpu") |
| 38 | , m_p_videoram(*this, "videoram") |
| 39 | , m_nvram(*this, "nvram") |
| 40 | , m_ctc(*this, "ctc") |
| 41 | , m_dart(*this, "dart") |
| 28 | 42 | { } |
| 29 | 43 | |
| 30 | | required_device<cpu_device> m_maincpu; |
| 31 | | DECLARE_READ8_MEMBER( uts20_vram_r ); |
| 32 | | DECLARE_WRITE8_MEMBER( uts20_vram_w ); |
| 33 | | DECLARE_WRITE8_MEMBER( uts20_43_w ); |
| 44 | DECLARE_READ8_MEMBER(vram_r); |
| 45 | DECLARE_WRITE8_MEMBER(vram_w); |
| 46 | DECLARE_WRITE8_MEMBER(port43_w); |
| 47 | INTERRUPT_GEN_MEMBER(vblank_irq); |
| 48 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 49 | private: |
| 34 | 50 | const UINT8 *m_p_chargen; |
| 35 | 51 | bool m_screen_num; |
| 36 | 52 | UINT8 m_framecnt; |
| 53 | virtual void machine_start(); |
| 37 | 54 | virtual void machine_reset(); |
| 38 | | virtual void video_start(); |
| 39 | | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 55 | required_device<cpu_device> m_maincpu; |
| 56 | required_shared_ptr<UINT8> m_p_videoram; |
| 57 | required_device<nvram_device> m_nvram; |
| 58 | required_device<z80ctc_device> m_ctc; |
| 59 | required_device<z80dart_device> m_dart; |
| 40 | 60 | }; |
| 41 | 61 | |
| 42 | 62 | |
| 43 | 63 | |
| 44 | | WRITE8_MEMBER( univac_state::uts20_43_w ) |
| 64 | WRITE8_MEMBER( univac_state::port43_w ) |
| 45 | 65 | { |
| 46 | | m_screen_num = data & 1; |
| 66 | m_screen_num = BIT(data, 0); |
| 47 | 67 | } |
| 48 | 68 | |
| 49 | | READ8_MEMBER( univac_state::uts20_vram_r ) |
| 69 | READ8_MEMBER( univac_state::vram_r ) |
| 50 | 70 | { |
| 51 | | UINT8 *RAM = memregion("maincpu")->base(); |
| 52 | | return RAM[offset | ((m_screen_num) ? 0xe000 : 0xc000)]; |
| 71 | offs_t offs = (offset & 0x1fff) ^ (BIT(offset, 13) ? 0x2000 : 0) ^ (m_screen_num ? 0x2000 : 0); |
| 72 | return m_p_videoram[offs]; |
| 53 | 73 | } |
| 54 | 74 | |
| 55 | | WRITE8_MEMBER( univac_state::uts20_vram_w ) |
| 75 | WRITE8_MEMBER( univac_state::vram_w ) |
| 56 | 76 | { |
| 57 | | UINT8 *RAM = memregion("maincpu")->base(); |
| 58 | | RAM[offset | ((m_screen_num) ? 0xe000 : 0xc000)] = data; |
| 77 | offs_t offs = (offset & 0x1fff) ^ (BIT(offset, 13) ? 0x2000 : 0) ^ (m_screen_num ? 0x2000 : 0); |
| 78 | m_p_videoram[offs] = data; |
| 59 | 79 | } |
| 60 | 80 | |
| 61 | 81 | |
| 62 | 82 | static ADDRESS_MAP_START(uts20_mem, AS_PROGRAM, 8, univac_state) |
| 63 | 83 | ADDRESS_MAP_UNMAP_HIGH |
| 64 | | AM_RANGE( 0x0000, 0x4fff ) AM_ROM |
| 65 | | AM_RANGE( 0x5000, 0x7fff ) AM_RAM AM_REGION("maincpu", 0x5000) |
| 66 | | AM_RANGE( 0x8000, 0x9fff ) AM_READWRITE(uts20_vram_r,uts20_vram_w) |
| 67 | | AM_RANGE( 0xa000, 0xffff ) AM_RAM AM_REGION("maincpu", 0xa000) |
| 84 | AM_RANGE( 0x0000, 0x4fff ) AM_ROM AM_REGION("roms", 0) |
| 85 | AM_RANGE( 0x8000, 0xbfff ) AM_READWRITE(vram_r,vram_w) |
| 86 | AM_RANGE( 0xc000, 0xffff ) AM_RAM AM_SHARE("videoram") |
| 68 | 87 | ADDRESS_MAP_END |
| 69 | 88 | |
| 70 | 89 | static ADDRESS_MAP_START( uts20_io, AS_IO, 8, univac_state) |
| 71 | 90 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 72 | 91 | ADDRESS_MAP_UNMAP_HIGH |
| 73 | | AM_RANGE( 0x43, 0x43 ) AM_WRITE(uts20_43_w) |
| 92 | //AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("dart", z80dart_device, ba_cd_r, ba_cd_w) |
| 93 | AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("dart", z80dart_device, cd_ba_r, cd_ba_w) // ?? no idea |
| 94 | AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) |
| 95 | AM_RANGE(0x43, 0x43) AM_WRITE(port43_w) |
| 96 | AM_RANGE(0x80, 0xbf) AM_RAM AM_SHARE("nvram") |
| 74 | 97 | ADDRESS_MAP_END |
| 75 | 98 | |
| 76 | 99 | /* Input ports */ |
| r30695 | r30696 | |
| 78 | 101 | INPUT_PORTS_END |
| 79 | 102 | |
| 80 | 103 | |
| 81 | | void univac_state::machine_reset() |
| 104 | void univac_state::machine_start() |
| 82 | 105 | { |
| 83 | | m_screen_num = 0; |
| 106 | // D7DC and D7DD are checked for valid RID and SID (usually 21 and 51) if not valid then NVRAM gets initialised. |
| 84 | 107 | } |
| 85 | 108 | |
| 86 | | void univac_state::video_start() |
| 109 | void univac_state::machine_reset() |
| 87 | 110 | { |
| 111 | m_screen_num = 0; |
| 88 | 112 | m_p_chargen = memregion("chargen")->base(); |
| 89 | 113 | } |
| 90 | 114 | |
| 91 | 115 | UINT32 univac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 92 | 116 | { |
| 117 | // this is used to get the ctc to pass the test |
| 118 | bool state = BIT(m_framecnt,0); |
| 119 | m_ctc->trg0(state); |
| 120 | m_ctc->trg1(state); |
| 121 | m_ctc->trg2(state); |
| 122 | m_ctc->trg3(state); |
| 123 | |
| 93 | 124 | UINT8 y,ra,chr,gfx; |
| 94 | 125 | UINT16 sy=0,ma=0,x; |
| 95 | | UINT8 *videoram = memregion("maincpu")->base()+((m_screen_num) ? 0xe000 : 0xc000); |
| 126 | UINT8 *videoram = m_p_videoram;//+(m_screen_num ? 0x2000 : 0); |
| 96 | 127 | |
| 97 | 128 | m_framecnt++; |
| 98 | 129 | |
| r30695 | r30696 | |
| 104 | 135 | |
| 105 | 136 | for (x = ma; x < ma + 80; x++) |
| 106 | 137 | { |
| 107 | | gfx = 0; |
| 138 | chr = videoram[x]; |
| 108 | 139 | |
| 109 | | if (ra < 9) |
| 110 | | { |
| 111 | | chr = videoram[x]; |
| 140 | /* Take care of 'corner' characters */ |
| 141 | if (((chr == 0x1c) || (chr == 0x1d)) && (m_framecnt & 16)) |
| 142 | chr = 0x20; |
| 112 | 143 | |
| 113 | | /* Take care of flashing characters */ |
| 114 | | if ((chr & 0x80) && (m_framecnt & 8)) |
| 115 | | chr = 0x20; |
| 144 | gfx = (ra ? m_p_chargen[((chr & 0x7f)<<4) | (ra-1) ] : 0) ^ (BIT(chr, 7) ? 0xff : 0); |
| 116 | 145 | |
| 117 | | chr &= 0x7f; |
| 118 | | |
| 119 | | gfx = m_p_chargen[(chr<<4) | ra ]; |
| 120 | | } |
| 121 | | |
| 122 | 146 | /* Display a scanline of a character */ |
| 123 | 147 | *p++ = BIT(gfx, 7); |
| 124 | 148 | *p++ = BIT(gfx, 6); |
| r30695 | r30696 | |
| 135 | 159 | return 0; |
| 136 | 160 | } |
| 137 | 161 | |
| 162 | static const z80_daisy_config daisy_chain[] = |
| 163 | { |
| 164 | { "dart" }, |
| 165 | { "ctc" }, |
| 166 | { NULL } |
| 167 | }; |
| 168 | |
| 138 | 169 | static MACHINE_CONFIG_START( uts20, univac_state ) |
| 139 | 170 | /* basic machine hardware */ |
| 140 | | MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) |
| 171 | MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) // unknown clock |
| 141 | 172 | MCFG_CPU_PROGRAM_MAP(uts20_mem) |
| 142 | 173 | MCFG_CPU_IO_MAP(uts20_io) |
| 174 | MCFG_CPU_CONFIG(daisy_chain) |
| 143 | 175 | |
| 144 | 176 | /* video hardware */ |
| 145 | 177 | MCFG_SCREEN_ADD("screen", RASTER) |
| r30695 | r30696 | |
| 149 | 181 | MCFG_SCREEN_SIZE(640, 250) |
| 150 | 182 | MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 249) |
| 151 | 183 | MCFG_SCREEN_PALETTE("palette") |
| 184 | MCFG_PALETTE_ADD_MONOCHROME_GREEN("palette") |
| 152 | 185 | |
| 153 | | MCFG_PALETTE_ADD_BLACK_AND_WHITE("palette") |
| 186 | MCFG_NVRAM_ADD_1FILL("nvram") |
| 187 | MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_4MHz) |
| 188 | MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) |
| 189 | MCFG_Z80DART_ADD("dart", XTAL_4MHz, 0, 0, 0, 0 ) |
| 190 | MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) |
| 154 | 191 | MACHINE_CONFIG_END |
| 155 | 192 | |
| 156 | 193 | |
| 157 | 194 | /* ROM definition */ |
| 158 | 195 | ROM_START( uts20 ) |
| 159 | | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 196 | ROM_REGION( 0x5000, "roms", ROMREGION_ERASEFF ) |
| 160 | 197 | ROM_LOAD( "uts20a.rom", 0x0000, 0x1000, CRC(1a7b4b4e) SHA1(c3732e25b4b7c7a80172e3fe55c77b923cf511eb) ) |
| 161 | 198 | ROM_LOAD( "uts20b.rom", 0x1000, 0x1000, CRC(7f8de87b) SHA1(a85f404ad9d560df831cc3e651a4b45e4ed30130) ) |
| 162 | 199 | ROM_LOAD( "uts20c.rom", 0x2000, 0x1000, CRC(4e334705) SHA1(ff1a730551b42f29d20af8ecc4495fd30567d35b) ) |
| 163 | 200 | ROM_LOAD( "uts20d.rom", 0x3000, 0x1000, CRC(76757cf7) SHA1(b0509d9a35366b21955f83ec3685163844c4dbf1) ) |
| 164 | 201 | ROM_LOAD( "uts20e.rom", 0x4000, 0x1000, CRC(0dfc8062) SHA1(cd681020bfb4829d4cebaf1b5bf618e67b55bda3) ) |
| 202 | ROM_FILL(0x2bd,1,0xaf) // test 2 |
| 203 | ROM_FILL(0x3c1,2,0xaf) // test 5 |
| 204 | ROM_FILL(0x928,1,0) |
| 165 | 205 | |
| 166 | 206 | /* character generator not dumped, using the one from 'c10' for now */ |
| 167 | 207 | ROM_REGION( 0x2000, "chargen", 0 ) |
| r30695 | r30696 | |
| 170 | 210 | |
| 171 | 211 | /* Driver */ |
| 172 | 212 | |
| 173 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 174 | | COMP( 198?, uts20, 0, 0, uts20, uts20, driver_device, 0, "Sperry Univac", "UTS-20", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 213 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |
| 214 | COMP( 1980, uts20, 0, 0, uts20, uts20, driver_device, 0, "Sperry Univac", "UTS-20", GAME_NOT_WORKING | GAME_NO_SOUND) |