src/mess/machine/pokemini.c
| r2828 | r2829 | |
| 7 | 7 | |
| 8 | 8 | |
| 9 | 9 | #include "driver.h" |
| 10 | #include "sound/speaker.h" |
| 11 | #include "machine/i2cmem.h" |
| 10 | 12 | #include "includes/pokemini.h" |
| 11 | 13 | #include "cpu/minx/minx.h" |
| 12 | 14 | |
| r2828 | r2829 | |
| 189 | 191 | |
| 190 | 192 | if ( vector ) |
| 191 | 193 | { |
| 192 | | logerror("Triggering IRQ with vector %02x\n", vector ); |
| 194 | //logerror("Triggering IRQ with vector %02x\n", vector ); |
| 193 | 195 | /* Trigger interrupt and set vector */ |
| 194 | 196 | cpunum_set_input_line_and_vector( machine, 0, 0, ASSERT_LINE, vector ); |
| 195 | 197 | } |
| r2828 | r2829 | |
| 200 | 202 | } |
| 201 | 203 | |
| 202 | 204 | |
| 205 | static void pokemini_update_sound( running_machine *machine ) |
| 206 | { |
| 207 | /* Check if sound should be muted */ |
| 208 | if ( pm_reg[0x70] & 0x03 ) |
| 209 | { |
| 210 | speaker_level_w( 0, 0 ); |
| 211 | } |
| 212 | else |
| 213 | { |
| 214 | static const int levels[4] = { 0, 1, 1, 2 }; |
| 215 | int level = levels[ pm_reg[0x71] & 0x03 ]; |
| 216 | |
| 217 | // if ( ( ( pm_reg[0x48] & 0x80 ) && ( pm_reg[0x4E] | ( pm_reg[0x4F] << 8 ) ) > ( pm_reg[0x4C] | ( pm_reg[0x4D] << 8 ) ) ) |
| 218 | // || ( ( pm_reg[0x48] & 0x80 ) && pm_reg[0x4F] > pm_reg[0x4D] ) ) |
| 219 | // { |
| 220 | level = 0; |
| 221 | // } |
| 222 | |
| 223 | speaker_level_w( 0, level ); |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | |
| 203 | 228 | static TIMER_CALLBACK(pokemini_seconds_timer_callback) |
| 204 | 229 | { |
| 205 | 230 | if ( pm_reg[0x08] & 0x01 ) |
| r2828 | r2829 | |
| 356 | 381 | pm_reg[0x4E] = pm_reg[0x4A]; |
| 357 | 382 | } |
| 358 | 383 | } |
| 384 | |
| 385 | if ( pm_reg[0x48] & 0x80 ) |
| 386 | { |
| 387 | if ( ( pm_reg[0x4E] == pm_reg[0x4C] ) && ( pm_reg[0x4F] == pm_reg[0x4D] ) ) |
| 388 | { |
| 389 | pm_reg[0x27] |= 0x01; |
| 390 | pokemini_check_irqs( machine ); |
| 391 | } |
| 392 | pokemini_update_sound( machine ); |
| 393 | } |
| 359 | 394 | } |
| 360 | 395 | |
| 361 | 396 | |
| r2828 | r2829 | |
| 369 | 404 | pokemini_check_irqs( machine ); |
| 370 | 405 | pm_reg[0x4F] = pm_reg[0x4B]; |
| 371 | 406 | } |
| 407 | |
| 408 | if ( ! ( pm_reg[0x48] & 0x80 ) ) |
| 409 | { |
| 410 | if( pm_reg[0x4F] == pm_reg[0x4D] ) |
| 411 | { |
| 412 | pm_reg[0x27] |= 0x01; |
| 413 | pokemini_check_irqs( machine ); |
| 414 | } |
| 415 | pokemini_update_sound( machine ); |
| 416 | } |
| 372 | 417 | } |
| 373 | 418 | |
| 374 | 419 | |
| r2828 | r2829 | |
| 377 | 422 | static const int timer_to_cycles_fast[8] = { 2, 8, 32, 64, 128, 256, 1024, 4096 }; |
| 378 | 423 | static const int timer_to_cycles_slow[8] = { 128, 256, 512, 1024, 2048, 4096, 8192, 16384 }; |
| 379 | 424 | |
| 380 | | logerror( "%0X: Write to hardware address: %02X, %02X\n", activecpu_get_pc(), offset, data ); |
| 425 | //logerror( "%0X: Write to hardware address: %02X, %02X\n", activecpu_get_pc(), offset, data ); |
| 381 | 426 | |
| 382 | 427 | switch( offset ) |
| 383 | 428 | { |
| r2828 | r2829 | |
| 1076 | 1121 | { |
| 1077 | 1122 | timer_enable( timers.timer3_hi, 0 ); |
| 1078 | 1123 | } |
| 1124 | pm_reg[0x48] = data; |
| 1125 | pokemini_update_sound( machine ); |
| 1079 | 1126 | break; |
| 1080 | 1127 | case 0x49: /* Timer 3 control 2 |
| 1081 | 1128 | Bit 0 R/W Unknown |
| r2828 | r2829 | |
| 1100 | 1147 | { |
| 1101 | 1148 | timer_enable( timers.timer3_hi, 0 ); |
| 1102 | 1149 | } |
| 1150 | pm_reg[0x49] = data; |
| 1151 | pokemini_update_sound( machine ); |
| 1103 | 1152 | break; |
| 1104 | 1153 | case 0x4A: /* Timer 3 preset value (low) |
| 1105 | 1154 | Bit 0-7 R/W Timer 3 preset value bit 0-7 |
| 1106 | 1155 | */ |
| 1156 | pm_reg[0x4A] = data; |
| 1157 | pokemini_update_sound( machine ); |
| 1107 | 1158 | break; |
| 1108 | 1159 | case 0x4B: /* Timer 3 preset value (high) |
| 1109 | 1160 | Bit 0-7 R/W Timer 3 preset value bit 8-15 |
| 1110 | 1161 | */ |
| 1162 | pm_reg[0x4B] = data; |
| 1163 | pokemini_update_sound( machine ); |
| 1111 | 1164 | break; |
| 1112 | 1165 | case 0x4C: /* Timer 3 sound-pivot (low) |
| 1113 | 1166 | Bit 0-7 R/W Timer 3 sound-pivot value bit 0-7 |
| 1114 | 1167 | */ |
| 1168 | pm_reg[0x4C] = data; |
| 1169 | pokemini_update_sound( machine ); |
| 1170 | break; |
| 1115 | 1171 | case 0x4D: /* Timer 3 sound-pivot (high) |
| 1116 | 1172 | Bit 0-7 R/W Timer 3 sound-pivot value bit 8-15 |
| 1117 | 1173 | |
| r2828 | r2829 | |
| 1120 | 1176 | Pulse-Width of 50% = Half of preset-value |
| 1121 | 1177 | Pulse-Width of 100% = Same as preset-value |
| 1122 | 1178 | */ |
| 1123 | | logerror( "%0X: Write to unknown hardware address: %02X, %02X\n", activecpu_get_pc(), offset, data ); |
| 1179 | pm_reg[0x4D] = data; |
| 1180 | pokemini_update_sound( machine ); |
| 1124 | 1181 | break; |
| 1125 | 1182 | case 0x4E: /* Timer 3 counter (low), read only |
| 1126 | 1183 | Bit 0-7 R/W Timer 3 counter value bit 0-7 |
| r2828 | r2829 | |
| 1151 | 1208 | Bit 6 R/W Unknown |
| 1152 | 1209 | Bit 7 R/W Unknown |
| 1153 | 1210 | */ |
| 1211 | break; |
| 1154 | 1212 | case 0x61: /* I/O peripheral status control |
| 1155 | 1213 | Bit 0 R/W IR received bit (if device not selected: 0) |
| 1156 | 1214 | Bit 1 R/W IR transmit (if device not selected: 0) |
| r2828 | r2829 | |
| 1161 | 1219 | Bit 6 Always 1 |
| 1162 | 1220 | Bit 7 R/W IR received bit (mirror, if device not selected: 0) |
| 1163 | 1221 | */ |
| 1222 | if ( pm_reg[0x60] & 0x04 ) |
| 1223 | i2cmem_write( 0, I2CMEM_SDA, ( data & 0x04 ) ? 1 : 0 ); |
| 1224 | |
| 1225 | if ( pm_reg[0x60] & 0x08 ) |
| 1226 | i2cmem_write( 0, I2CMEM_SCL, ( data & 0x08 ) ? 1 : 0 ); |
| 1227 | break; |
| 1228 | case 0x70: /* Sound related */ |
| 1229 | pm_reg[0x70] = data; |
| 1230 | pokemini_update_sound( machine ); |
| 1231 | break; |
| 1164 | 1232 | case 0x71: /* Sound volume |
| 1165 | 1233 | Bit 0-1 R/W Sound volume |
| 1166 | 1234 | 00 - 0% |
| r2828 | r2829 | |
| 1170 | 1238 | Bit 2 R/W Always set to 0 |
| 1171 | 1239 | Bit 3-7 Unused |
| 1172 | 1240 | */ |
| 1173 | | logerror( "%0X: Write to unknown hardware address: %02X, %02X\n", activecpu_get_pc(), offset, data ); |
| 1241 | pm_reg[0x71] = data; |
| 1242 | pokemini_update_sound( machine ); |
| 1174 | 1243 | break; |
| 1175 | 1244 | case 0x80: /* LCD control |
| 1176 | 1245 | Bit 0 R/W Invert colors; 0 - normal, 1 - inverted |
| r2828 | r2829 | |
| 1307 | 1376 | |
| 1308 | 1377 | READ8_HANDLER( pokemini_hwreg_r ) |
| 1309 | 1378 | { |
| 1379 | UINT8 data = pm_reg[offset]; |
| 1380 | |
| 1310 | 1381 | switch( offset ) |
| 1311 | 1382 | { |
| 1312 | 1383 | case 0x52: return input_port_read(machine, "INPUTS"); |
| 1384 | case 0x61: |
| 1385 | if ( ! ( pm_reg[0x60] & 0x04 ) ) |
| 1386 | { |
| 1387 | data = ( data & ~ 0x04 ) | ( i2cmem_read( 0, I2CMEM_SDA ) ? 0x04 : 0x00 ); |
| 1388 | } |
| 1389 | |
| 1390 | if ( ! ( pm_reg[0x60] & 0x08 ) ) |
| 1391 | { |
| 1392 | data &= ~0x08; |
| 1393 | } |
| 1394 | break; |
| 1313 | 1395 | case 0x81: return ( pm_reg[offset] & 0x0F ) | ( prc.frame_count << 4 ); |
| 1314 | 1396 | case 0x8A: return prc.count; |
| 1315 | 1397 | } |
| 1316 | | return pm_reg[offset]; |
| 1398 | return data; |
| 1317 | 1399 | } |
| 1318 | 1400 | |
| 1319 | 1401 | DEVICE_START( pokemini_cart ) |
| r2828 | r2829 | |
| 1356 | 1438 | { |
| 1357 | 1439 | prc.count++; |
| 1358 | 1440 | |
| 1359 | | logerror("prc.count is %02x\n", prc.count); |
| 1360 | 1441 | /* Check for overflow */ |
| 1361 | 1442 | if ( prc.count >= 0x42 ) |
| 1362 | 1443 | { |
src/mess/drivers/pokemini.c
| r2828 | r2829 | |
| 8 | 8 | ********************************************************************/ |
| 9 | 9 | |
| 10 | 10 | #include "driver.h" |
| 11 | #include "sound/speaker.h" |
| 12 | #include "machine/i2cmem.h" |
| 11 | 13 | #include "includes/pokemini.h" |
| 12 | 14 | #include "cpu/minx/minx.h" |
| 13 | 15 | #include "devices/cartslot.h" |
| r2828 | r2829 | |
| 51 | 53 | } |
| 52 | 54 | |
| 53 | 55 | |
| 56 | static const struct Speaker_interface speaker_interface = |
| 57 | { |
| 58 | 3, /* optional: number of different levels */ |
| 59 | NULL /* optional: level lookup table */ |
| 60 | }; |
| 61 | |
| 62 | |
| 54 | 63 | static MACHINE_DRIVER_START( pokemini ) |
| 55 | 64 | /* basic machine hardware */ |
| 56 | 65 | MDRV_CPU_ADD_TAG( "main", MINX, 4000000 ) |
| r2828 | r2829 | |
| 60 | 69 | |
| 61 | 70 | MDRV_MACHINE_RESET( pokemini ) |
| 62 | 71 | |
| 72 | MDRV_NVRAM_HANDLER( i2cmem_0 ) |
| 73 | |
| 63 | 74 | /* video hardware */ |
| 64 | 75 | MDRV_VIDEO_START( generic_bitmapped ) |
| 65 | 76 | MDRV_VIDEO_UPDATE( generic_bitmapped ) |
| r2828 | r2829 | |
| 74 | 85 | MDRV_SCREEN_REFRESH_RATE( 72 ) |
| 75 | 86 | |
| 76 | 87 | /* sound hardware */ |
| 77 | | #if 0 |
| 78 | | MDRV_SPEAKER_STANDARD_STEREO( "left", "right" ) |
| 79 | | MDRV_SOUND_ROUTE( 0, "left", 0.50 ) |
| 80 | | MDRV_SOUND_ROUTE( 0, "right", 0.50 ) |
| 81 | | #endif |
| 88 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 89 | MDRV_SOUND_ADD(SPEAKER, 0) |
| 90 | MDRV_SOUND_CONFIG(speaker_interface) |
| 91 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 82 | 92 | MACHINE_DRIVER_END |
| 83 | 93 | |
| 84 | 94 | |
| 95 | static DRIVER_INIT( pokemini ) |
| 96 | { |
| 97 | i2cmem_init( 0, I2CMEM_SLAVE_ADDRESS, 0, 0x2000, NULL); |
| 98 | } |
| 99 | |
| 100 | |
| 85 | 101 | static void pokemini_cartslot_getinfo( const mess_device_class *devclass, UINT32 state, union devinfo *info ) |
| 86 | 102 | { |
| 87 | 103 | switch( state ) |
| r2828 | r2829 | |
| 107 | 123 | ROM_END |
| 108 | 124 | |
| 109 | 125 | |
| 110 | | CONS( 1999, pokemini, 0, 0, pokemini, pokemini, 0, pokemini, "Nintendo", "Pokemon Mini", GAME_NOT_WORKING ) |
| 126 | CONS( 1999, pokemini, 0, 0, pokemini, pokemini, pokemini, pokemini, "Nintendo", "Pokemon Mini", GAME_NOT_WORKING ) |
| 111 | 127 | |