trunk/src/mess/drivers/pve500.c
| r31100 | r31101 | |
| 8 | 8 | Driver by Felipe Correa da Silva Sanches <juca@members.fsf.org> |
| 9 | 9 | Technical info at https://www.garoa.net.br/wiki/PVE-500 |
| 10 | 10 | |
| 11 | Notes: |
| 12 | One can induce the self-diagnose by booting the device holding LEARN and P2-RESET buttons togheter |
| 13 | With the default keyboard map, this can be done by holding keys L and S while pressing F3. |
| 14 | (Don't forget to unlock the keyboard by using the UI TOGGLE key) |
| 15 | |
| 16 | This self-diagnose routine displays the value C817, which is the checksum value of the subcpu ROM |
| 17 | and afterwards it displays the following message: |
| 18 | |
| 19 | SELFdIAG Error___ _F3 F3_CtC3c |
| 20 | |
| 21 | which means it detected an error in the CTC circuitry (it means we're emulating it wrong!) |
| 22 | F3 is the coordinate of the subcpu EEPROM chip in the PCB. |
| 23 | |
| 24 | According to the service manual, this error code means: "ICF3 CTC CH-3 counter operation failure (No interruption)" |
| 25 | |
| 26 | Known issues: |
| 27 | There's still an annoying blinking in the 7-seg display. |
| 28 | |
| 11 | 29 | Changelog: |
| 12 | 30 | |
| 31 | 2014 JUN 24 [Felipe Sanches]: |
| 32 | * figured out the multiplexing signals for the 7seg display |
| 33 | |
| 34 | 2014 JUN 23 [Felipe Sanches]: |
| 35 | * hooked-up the RS422 ports |
| 36 | |
| 13 | 37 | 2014 JAN 14 [Felipe Sanches]: |
| 14 | 38 | * Initial driver skeleton |
| 15 | 39 | */ |
| 16 | 40 | |
| 41 | #define LOG_7SEG_DISPLAY_SIGNALS 0 |
| 42 | #define DEBUGGING_INDUCE_SELFDIAGNOSE 0 |
| 43 | |
| 17 | 44 | #include "emu.h" |
| 18 | 45 | #include "cpu/z80/tmpz84c015.h" |
| 19 | 46 | #include "sound/beep.h" |
| r31100 | r31101 | |
| 203 | 230 | io_LE = 0; |
| 204 | 231 | io_SEL = 0; |
| 205 | 232 | io_KY = 0; |
| 206 | | |
| 207 | | for (int i=0; i<27; i++) |
| 208 | | output_set_digit_value(i, 0x00); |
| 209 | 233 | } |
| 210 | 234 | |
| 211 | 235 | void pve500_state::machine_reset() |
| r31100 | r31101 | |
| 217 | 241 | |
| 218 | 242 | READ8_MEMBER(pve500_state::dualport_ram_left_r) |
| 219 | 243 | { |
| 220 | | printf("dualport_ram: Left READ\n"); |
| 244 | //printf("dualport_ram: Left READ\n"); |
| 221 | 245 | m_subcpu->trg1(1); //(INT_Right) |
| 222 | 246 | return dualport_7FE_data; |
| 223 | 247 | } |
| 224 | 248 | |
| 225 | 249 | WRITE8_MEMBER(pve500_state::dualport_ram_left_w) |
| 226 | 250 | { |
| 227 | | printf("dualport_ram: Left WRITE\n"); |
| 251 | //printf("dualport_ram: Left WRITE\n"); |
| 228 | 252 | dualport_7FF_data = data; |
| 229 | 253 | m_subcpu->trg1(0); //(INT_Right) |
| 230 | 254 | } |
| 231 | 255 | |
| 232 | 256 | READ8_MEMBER(pve500_state::dualport_ram_right_r) |
| 233 | 257 | { |
| 234 | | printf("dualport_ram: Right READ\n"); |
| 258 | //printf("dualport_ram: Right READ\n"); |
| 235 | 259 | m_maincpu->trg1(1); //(INT_Left) |
| 236 | 260 | return dualport_7FF_data; |
| 237 | 261 | } |
| 238 | 262 | |
| 239 | 263 | WRITE8_MEMBER(pve500_state::dualport_ram_right_w) |
| 240 | 264 | { |
| 241 | | printf("dualport_ram: Right WRITE\n"); |
| 265 | //printf("dualport_ram: Right WRITE\n"); |
| 242 | 266 | dualport_7FE_data = data; |
| 243 | 267 | m_maincpu->trg1(0); //(INT_Left) |
| 244 | 268 | } |
| 245 | 269 | |
| 246 | 270 | READ8_MEMBER(pve500_state::io_expander_r) |
| 247 | 271 | { |
| 248 | | printf("READ IO_EXPANDER_PORT%c\n", 'A'+offset); |
| 272 | // printf("READ IO_EXPANDER_PORT%c\n", 'A'+offset); |
| 249 | 273 | switch (offset){ |
| 250 | 274 | case IO_EXPANDER_PORTA: |
| 251 | 275 | return io_SC; |
| r31100 | r31101 | |
| 253 | 277 | return io_LE; |
| 254 | 278 | case IO_EXPANDER_PORTC: |
| 255 | 279 | io_KY = 0x00; |
| 256 | | if (io_SC & 0x01) io_KY |= ioport("SCAN0")->read(); |
| 257 | | if (io_SC & 0x02) io_KY |= ioport("SCAN1")->read(); |
| 258 | | if (io_SC & 0x04) io_KY |= ioport("SCAN2")->read(); |
| 259 | | if (io_SC & 0x08) io_KY |= ioport("SCAN3")->read(); |
| 260 | | if (io_SC & 0x10) io_KY |= ioport("SCAN4")->read(); |
| 261 | | if (io_SC & 0x20) io_KY |= ioport("SCAN5")->read(); |
| 262 | | if (io_SC & 0x40) io_KY |= ioport("SCAN6")->read(); |
| 263 | | if (io_SC & 0x80) io_KY |= ioport("SCAN7")->read(); |
| 280 | if (!BIT(io_SC, 0)) io_KY |= ioport("SCAN0")->read(); |
| 281 | if (!BIT(io_SC, 1)) io_KY |= ioport("SCAN1")->read(); |
| 282 | if (!BIT(io_SC, 2)) io_KY |= ioport("SCAN2")->read(); |
| 283 | if (!BIT(io_SC, 3)) io_KY |= ioport("SCAN3")->read(); |
| 284 | if (!BIT(io_SC, 4)) io_KY |= ioport("SCAN4")->read(); |
| 285 | if (!BIT(io_SC, 5)) io_KY |= ioport("SCAN5")->read(); |
| 286 | if (!BIT(io_SC, 6)) io_KY |= ioport("SCAN6")->read(); |
| 287 | if (!BIT(io_SC, 7)) io_KY |= ioport("SCAN7")->read(); |
| 288 | #if DEBUGGING_INDUCE_SELFDIAGNOSE |
| 289 | io_KY = 0x42; //according to procedure described in the service manual |
| 290 | #endif |
| 264 | 291 | return io_KY; |
| 265 | 292 | case IO_EXPANDER_PORTD: |
| 266 | 293 | return io_LD; |
| r31100 | r31101 | |
| 273 | 300 | |
| 274 | 301 | WRITE8_MEMBER(pve500_state::io_expander_w) |
| 275 | 302 | { |
| 303 | static int LD_data[4]; |
| 304 | int swap[4] = {2,1,0,3}; |
| 276 | 305 | switch (offset){ |
| 277 | 306 | case IO_EXPANDER_PORTA: |
| 278 | | printf("io_expander_w: PORTA (io_SC=%02X)\n", data); |
| 307 | #if LOG_7SEG_DISPLAY_SIGNALS |
| 308 | printf("io_expander_w: PORTA (io_SC=%02X)\n", data); |
| 309 | #endif |
| 279 | 310 | io_SC = data; |
| 311 | |
| 312 | for (int j=0; j<8; j++){ |
| 313 | if (!BIT(io_SC,j)){ |
| 314 | for (int i=0; i<4; i++) |
| 315 | output_set_digit_value(8*swap[i] + j, LD_data[i]); |
| 316 | } |
| 317 | } |
| 280 | 318 | break; |
| 281 | 319 | case IO_EXPANDER_PORTB: |
| 320 | #if LOG_7SEG_DISPLAY_SIGNALS |
| 282 | 321 | printf("io_expander_w: PORTB (io_LE=%02X)\n", data); |
| 322 | #endif |
| 283 | 323 | io_LE = data; |
| 284 | 324 | break; |
| 285 | 325 | case IO_EXPANDER_PORTC: |
| 326 | #if LOG_7SEG_DISPLAY_SIGNALS |
| 286 | 327 | printf("io_expander_w: PORTC (io_KY=%02X)\n", data); |
| 328 | #endif |
| 287 | 329 | io_KY = data; |
| 288 | 330 | break; |
| 289 | 331 | case IO_EXPANDER_PORTD: |
| 332 | #if LOG_7SEG_DISPLAY_SIGNALS |
| 290 | 333 | printf("io_expander_w: PORTD (io_LD=%02X)\n", data); |
| 334 | #endif |
| 291 | 335 | io_LD = data; |
| 292 | 336 | break; |
| 293 | 337 | case IO_EXPANDER_PORTE: |
| 338 | #if LOG_7SEG_DISPLAY_SIGNALS |
| 339 | printf("io_expander_w PORTE (io_SEL=%02X)\n", data); |
| 340 | #endif |
| 294 | 341 | io_SEL = data; |
| 295 | | printf("io_expander_w PORTE (io_SEL=%02X)\n", data); |
| 296 | 342 | for (int i=0; i<4; i++){ |
| 297 | | if (io_SEL & (1 << i)){ |
| 298 | | for (int j=0; j<8; j++){ |
| 299 | | if (io_SC & (1<<j)){ |
| 300 | | output_set_digit_value(8*i + j, BITSWAP8(io_LD & 0x7F, 7, 0, 1, 2, 3, 4, 5, 6)); |
| 301 | | } |
| 302 | | } |
| 343 | if (BIT(io_SEL, i)){ |
| 344 | LD_data[i] = 0x7F & BITSWAP8(io_LD ^ 0xFF, 7, 0, 1, 2, 3, 4, 5, 6); |
| 303 | 345 | } |
| 304 | 346 | } |
| 305 | 347 | break; |