src/mess/drivers/socrates.c
| r15737 | r15738 | |
| 12 | 12 | add waitstates for ram access (lack of this causes the system to run way too fast) |
| 13 | 13 | find and hook up any timers/interrupt controls |
| 14 | 14 | switch cartridges over to a CART system rather than abusing BIOS |
| 15 | keyboard IR decoder MCU is HLE'd for now, needs decap and cpu core (it is rather tms1000 or CIC-like) |
| 15 | 16 | |
| 16 | 17 | |
| 17 | | |
| 18 | 18 | Socrates Educational Video System |
| 19 | 19 | FFFF|----------------| |
| 20 | 20 | | RAM (window 1) | |
| r15737 | r15738 | |
| 80 | 80 | { |
| 81 | 81 | public: |
| 82 | 82 | socrates_state(const machine_config &mconfig, device_type type, const char *tag) |
| 83 | | : driver_device(mconfig, type, tag) { } |
| 83 | : driver_device(mconfig, type, tag), |
| 84 | m_maincpu(*this, "maincpu"), |
| 85 | m_screen(*this, "screen"), |
| 86 | m_sound(*this, "soc_snd") |
| 87 | { } |
| 88 | required_device<cpu_device> m_maincpu; |
| 89 | required_device<screen_device> m_screen; |
| 90 | required_device<device_t> m_sound; |
| 84 | 91 | |
| 85 | 92 | rgb_t m_palette[256]; |
| 86 | 93 | |
| r15737 | r15738 | |
| 92 | 99 | UINT8 m_kb_latch_low[2]; |
| 93 | 100 | UINT8 m_kb_latch_high[2]; |
| 94 | 101 | UINT8 m_kb_latch_mouse; |
| 102 | UINT8 m_kbmcu_rscount; // how many pokes the kbmcu has taken in the last frame |
| 95 | 103 | UINT8 m_io40_latch; // what was last written to speech reg (for open bus)? |
| 96 | 104 | UINT8 m_hblankstate; // are we in hblank? |
| 97 | 105 | UINT8 m_vblankstate; // are we in vblank? |
| r15737 | r15738 | |
| 106 | 114 | DECLARE_READ8_MEMBER(socrates_ram_bank_r); |
| 107 | 115 | DECLARE_WRITE8_MEMBER(socrates_ram_bank_w); |
| 108 | 116 | DECLARE_READ8_MEMBER(read_f3); |
| 109 | | DECLARE_WRITE8_MEMBER(unknownlatch_30); |
| 117 | DECLARE_WRITE8_MEMBER(kbmcu_strobe); |
| 110 | 118 | DECLARE_READ8_MEMBER(status_and_speech); |
| 111 | 119 | DECLARE_WRITE8_MEMBER(speech_command); |
| 112 | 120 | DECLARE_READ8_MEMBER(socrates_keyboard_low_r); |
| r15737 | r15738 | |
| 207 | 215 | state->m_kb_latch_low[1] = 0x00; |
| 208 | 216 | state->m_kb_latch_high[1] = 0x01; |
| 209 | 217 | state->m_kb_latch_mouse = 0; |
| 218 | state->m_kbmcu_rscount = 0; |
| 210 | 219 | state->m_io40_latch = 0; |
| 211 | 220 | state->m_hblankstate = 0; |
| 212 | 221 | state->m_vblankstate = 0; |
| r15737 | r15738 | |
| 231 | 240 | |
| 232 | 241 | READ8_MEMBER(socrates_state::socrates_rom_bank_r) |
| 233 | 242 | { |
| 234 | | UINT8 data = 0xFF; |
| 235 | | data = m_rom_bank; |
| 236 | | return data; |
| 243 | return m_rom_bank; |
| 237 | 244 | } |
| 238 | 245 | |
| 239 | 246 | WRITE8_MEMBER(socrates_state::socrates_rom_bank_w) |
| r15737 | r15738 | |
| 244 | 251 | |
| 245 | 252 | READ8_MEMBER(socrates_state::socrates_ram_bank_r) |
| 246 | 253 | { |
| 247 | | UINT8 data = 0xFF; |
| 248 | | data = m_ram_bank; |
| 249 | | return data; |
| 254 | return m_ram_bank; |
| 250 | 255 | } |
| 251 | 256 | |
| 252 | 257 | WRITE8_MEMBER(socrates_state::socrates_ram_bank_w) |
| r15737 | r15738 | |
| 260 | 265 | return 0xF3; |
| 261 | 266 | } |
| 262 | 267 | |
| 263 | | WRITE8_MEMBER(socrates_state::unknownlatch_30)// writes to i/o 0x3x do SOMETHING, possibly waitstate related (may halt cpu until vblank start?) or involve status reg bit 6 |
| 268 | WRITE8_MEMBER(socrates_state::kbmcu_strobe) // strobe the keyboard MCU |
| 264 | 269 | { |
| 265 | | //logerror("write to i/o 0x30, data %x\n", data); // too annoying to leave enabled |
| 270 | //logerror("0x%04X: kbmcu written with %02X!\n", cpu_get_pc(m_maincpu), data); //if (cpu_get_pc(m_maincpu) != 0x31D) |
| 271 | // if two writes happen within one frame, reset the keyboard latches |
| 272 | m_kbmcu_rscount++; |
| 273 | if (m_kbmcu_rscount > 1) |
| 274 | { |
| 275 | m_kb_latch_low[0] = 0x00; |
| 276 | m_kb_latch_high[0] = 0x01; |
| 277 | m_kb_latch_low[1] = 0x00; |
| 278 | m_kb_latch_high[1] = 0x01; |
| 279 | m_kb_latch_mouse = 0; |
| 280 | } |
| 266 | 281 | } |
| 267 | 282 | |
| 268 | 283 | READ8_MEMBER(socrates_state::status_and_speech)// read 0x4x, some sort of status reg |
| r15737 | r15738 | |
| 279 | 294 | UINT8 *speechromext = memregion("speechext")->base(); |
| 280 | 295 | int temp = 0; |
| 281 | 296 | temp |= (m_speech_running)?0x80:0; |
| 282 | | temp |= 0x40; // unknown |
| 297 | temp |= 0x40; // unknown, possibly IR mcu busy |
| 283 | 298 | temp |= (m_vblankstate)?0:0x20; |
| 284 | 299 | temp |= (m_hblankstate)?0:0x10; |
| 285 | 300 | switch(m_io40_latch&0xF0) // what was last opcode sent? |
| r15737 | r15738 | |
| 688 | 703 | 0x21 - W - msb offset of screen display |
| 689 | 704 | resulting screen line is one of 512 total offsets on 128-byte boundaries in the whole 64k ram |
| 690 | 705 | */ |
| 691 | | AM_RANGE(0x30, 0x30) AM_READWRITE(read_f3, unknownlatch_30) AM_MIRROR (0xf) /* unknown, write only. may relate to waitstate timing? */ |
| 706 | AM_RANGE(0x30, 0x30) AM_READWRITE(read_f3, kbmcu_strobe) AM_MIRROR (0xf) /* resets the keyboard IR decoder MCU */ |
| 692 | 707 | AM_RANGE(0x40, 0x40) AM_READWRITE(status_and_speech, speech_command ) AM_MIRROR(0xf) /* reads status register for vblank/hblank/speech, also reads and writes speech module */ |
| 693 | 708 | AM_RANGE(0x50, 0x50) AM_READWRITE(socrates_keyboard_low_r, socrates_keyboard_clear) AM_MIRROR(0xE) /* Keyboard keycode low, latched on keypress, can be unlatched by writing anything here */ |
| 694 | 709 | AM_RANGE(0x51, 0x51) AM_READWRITE(socrates_keyboard_high_r, socrates_keyboard_clear) AM_MIRROR(0xE) /* Keyboard keycode high, latched as above, unlatches same as above */ |
| r15737 | r15738 | |
| 900 | 915 | device->machine().scheduler().timer_set(downcast<cpu_device *>(device)->cycles_to_attotime(44), FUNC(clear_irq_cb)); |
| 901 | 916 | // 44 is a complete and total guess, need to properly measure how many clocks/microseconds the int line is high for. |
| 902 | 917 | state->m_vblankstate = 1; |
| 918 | state->m_kbmcu_rscount = 0; // clear the mcu poke count |
| 903 | 919 | } |
| 904 | 920 | |
| 905 | 921 | static MACHINE_CONFIG_START( socrates, socrates_state ) |
| r15737 | r15738 | |
| 995 | 1011 | |
| 996 | 1012 | ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */ |
| 997 | 1013 | |
| 1014 | ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF) |
| 1015 | ROM_LOAD("tmp42c40p1844.bin", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */ |
| 1016 | |
| 998 | 1017 | /* english speech cart has a green QC sticker */ |
| 999 | 1018 | ROM_REGION(0x2000, "speechint", ROMREGION_ERASE00) // speech data inside of the speech chip; fill with 00, if no speech cart is present socrates will see this |
| 1000 | 1019 | ROM_LOAD_OPTIONAL("speech_internal.bin", 0x0000, 0x2000, CRC(edc1fb3f) SHA1(78b4631fc3b1c038e14911047f9edd6c4e8bae58)) // 8k on the speech chip itself |
| r15737 | r15738 | |
| 1014 | 1033 | |
| 1015 | 1034 | ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */ |
| 1016 | 1035 | |
| 1036 | ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF) |
| 1037 | ROM_LOAD("tmp42c40p1844.bin", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */ |
| 1038 | |
| 1017 | 1039 | ROM_REGION(0x2000, "speechint", ROMREGION_ERASE00) // speech data inside of the speech chip; fill with 00, if no speech cart is present socrates will see this |
| 1018 | 1040 | ROM_LOAD_OPTIONAL("speech_fra_internal.bin", 0x0000, 0x2000, BAD_DUMP CRC(edc1fb3f) SHA1(78b4631fc3b1c038e14911047f9edd6c4e8bae58)) // probably same on french and english speech carts |
| 1019 | 1041 | |