src/mess/machine/cbmb.c
| r3150 | r3151 | |
| 20 | 20 | |
| 21 | 21 | #include "includes/cbmb.h" |
| 22 | 22 | |
| 23 | #include "devices/cartslot.h" |
| 24 | |
| 23 | 25 | /* 2008-05 FP: Were these added as a reminder to add configs of |
| 24 | 26 | drivers 8 & 9 as in pet.c ? */ |
| 25 | 27 | #define IEEE8ON 0 |
| r3150 | r3151 | |
| 30 | 32 | /* keyboard lines */ |
| 31 | 33 | static int cbmb_keyline_a, cbmb_keyline_b, cbmb_keyline_c; |
| 32 | 34 | |
| 33 | | static int cbm500=0; |
| 35 | static int cbm500 = 0; |
| 34 | 36 | static int cbm700; |
| 35 | 37 | static int cbm_ntsc; |
| 36 | 38 | UINT8 *cbmb_basic; |
| r3150 | r3151 | |
| 63 | 65 | */ |
| 64 | 66 | static int cbmb_tpi0_port_a_r(void) |
| 65 | 67 | { |
| 66 | | int data=0; |
| 67 | | if (cbm_ieee_nrfd_r()) data|=0x80; |
| 68 | | if (cbm_ieee_ndac_r()) data|=0x40; |
| 69 | | if (cbm_ieee_eoi_r()) data|=0x20; |
| 70 | | if (cbm_ieee_dav_r()) data|=0x10; |
| 71 | | if (cbm_ieee_atn_r()) data|=8; |
| 72 | | /* if (cbm_ieee_ren_r()) data|=4; */ |
| 68 | int data = 0; |
| 69 | if (cbm_ieee_nrfd_r()) data |= 0x80; |
| 70 | if (cbm_ieee_ndac_r()) data |= 0x40; |
| 71 | if (cbm_ieee_eoi_r()) data |= 0x20; |
| 72 | if (cbm_ieee_dav_r()) data |= 0x10; |
| 73 | if (cbm_ieee_atn_r()) data |= 0x08; |
| 74 | /* if (cbm_ieee_ren_r()) data |= 0x04; */ |
| 73 | 75 | return data; |
| 74 | 76 | } |
| 75 | 77 | |
| 76 | 78 | static void cbmb_tpi0_port_a_w(int data) |
| 77 | 79 | { |
| 78 | | cbm_ieee_nrfd_w(0,data&0x80); |
| 79 | | cbm_ieee_ndac_w(0,data&0x40); |
| 80 | | cbm_ieee_eoi_w(0,data&0x20); |
| 81 | | cbm_ieee_dav_w(0,data&0x10); |
| 82 | | cbm_ieee_atn_w(0,data&8); |
| 83 | | /* cbm_ieee_ren_w(0,data&4); */ |
| 84 | | logerror("cbm ieee %d %d\n",data&2, data&1); |
| 80 | cbm_ieee_nrfd_w(0, data & 0x80); |
| 81 | cbm_ieee_ndac_w(0, data & 0x40); |
| 82 | cbm_ieee_eoi_w(0, data & 0x20); |
| 83 | cbm_ieee_dav_w(0, data & 0x10); |
| 84 | cbm_ieee_atn_w(0, data & 0x08); |
| 85 | /* cbm_ieee_ren_w(0, data & 0x04); */ |
| 86 | logerror("cbm ieee %d %d\n", data & 0x02, data & 0x01); |
| 85 | 87 | } |
| 86 | 88 | |
| 87 | 89 | /* tpi at 0xfdf00 |
| r3150 | r3151 | |
| 115 | 117 | { |
| 116 | 118 | int data = 0; |
| 117 | 119 | |
| 118 | | if (!(cbmb_keyline_c & 1)) |
| 120 | if (!(cbmb_keyline_c & 0x01)) |
| 119 | 121 | data |= input_port_read(Machine, "ROW0"); |
| 120 | | if (!(cbmb_keyline_c & 2)) |
| 122 | |
| 123 | if (!(cbmb_keyline_c & 0x02)) |
| 121 | 124 | data |= input_port_read(Machine, "ROW2"); |
| 122 | | if (!(cbmb_keyline_c & 4)) |
| 125 | |
| 126 | if (!(cbmb_keyline_c & 0x04)) |
| 123 | 127 | data |= input_port_read(Machine, "ROW4"); |
| 124 | | if (!(cbmb_keyline_c & 8)) |
| 128 | |
| 129 | if (!(cbmb_keyline_c & 0x08)) |
| 125 | 130 | data |= input_port_read(Machine, "ROW6"); |
| 131 | |
| 126 | 132 | if (!(cbmb_keyline_c & 0x10)) |
| 127 | 133 | data |= input_port_read(Machine, "ROW8"); |
| 134 | |
| 128 | 135 | if (!(cbmb_keyline_c & 0x20)) |
| 129 | 136 | data |= input_port_read(Machine, "ROW10"); |
| 130 | 137 | |
| 131 | | return data^0xff; |
| 138 | return data ^0xff; |
| 132 | 139 | } |
| 133 | 140 | |
| 134 | 141 | static int cbmb_keyboard_line_b(void) |
| 135 | 142 | { |
| 136 | | int data=0; |
| 143 | int data = 0; |
| 137 | 144 | |
| 138 | | if (!(cbmb_keyline_c & 1)) |
| 145 | if (!(cbmb_keyline_c & 0x01)) |
| 139 | 146 | data |= input_port_read(Machine, "ROW1"); |
| 140 | | if (!(cbmb_keyline_c & 2)) |
| 147 | |
| 148 | if (!(cbmb_keyline_c & 0x02)) |
| 141 | 149 | data |= input_port_read(Machine, "ROW3"); |
| 142 | | if (!(cbmb_keyline_c & 4)) |
| 150 | |
| 151 | if (!(cbmb_keyline_c & 0x04)) |
| 143 | 152 | data |= input_port_read(Machine, "ROW5"); |
| 144 | | if (!(cbmb_keyline_c & 8)) |
| 153 | |
| 154 | if (!(cbmb_keyline_c & 0x08)) |
| 145 | 155 | data |= input_port_read(Machine, "ROW7"); |
| 156 | |
| 146 | 157 | if (!(cbmb_keyline_c & 0x10)) |
| 147 | 158 | data |= input_port_read(Machine, "ROW9") | ((input_port_read(Machine, "SPECIAL") & 0x04) ? 1 : 0 ); |
| 159 | |
| 148 | 160 | if (!(cbmb_keyline_c & 0x20)) |
| 149 | 161 | data |= input_port_read(Machine, "ROW11"); |
| 150 | 162 | |
| 151 | | return data^0xff; |
| 163 | return data ^0xff; |
| 152 | 164 | } |
| 153 | 165 | |
| 154 | 166 | static int cbmb_keyboard_line_c(void) |
| 155 | 167 | { |
| 156 | | int data=0; |
| 168 | int data = 0; |
| 157 | 169 | |
| 158 | | if ( (input_port_read(Machine, "ROW0") & ~cbmb_keyline_a)|| |
| 159 | | (input_port_read(Machine, "ROW1") & ~cbmb_keyline_b)) |
| 160 | | data |= 1; |
| 161 | | if ( (input_port_read(Machine, "ROW2") & ~cbmb_keyline_a)|| |
| 162 | | (input_port_read(Machine, "ROW3") & ~cbmb_keyline_b)) |
| 163 | | data |= 2; |
| 164 | | if ( (input_port_read(Machine, "ROW4") & ~cbmb_keyline_a)|| |
| 165 | | (input_port_read(Machine, "ROW5") & ~cbmb_keyline_b)) |
| 166 | | data |= 4; |
| 167 | | if ( (input_port_read(Machine, "ROW6") & ~cbmb_keyline_a)|| |
| 168 | | (input_port_read(Machine, "ROW7") & ~cbmb_keyline_b)) |
| 169 | | data |= 8; |
| 170 | | if ( (input_port_read(Machine, "ROW8") & ~cbmb_keyline_a)|| |
| 171 | | ((input_port_read(Machine, "ROW9")|((input_port_read(Machine, "SPECIAL") & 0x04) ? 1 : 0)) & ~cbmb_keyline_b)) |
| 170 | if ((input_port_read(Machine, "ROW0") & ~cbmb_keyline_a) || |
| 171 | (input_port_read(Machine, "ROW1") & ~cbmb_keyline_b)) |
| 172 | data |= 0x01; |
| 173 | |
| 174 | if ((input_port_read(Machine, "ROW2") & ~cbmb_keyline_a) || |
| 175 | (input_port_read(Machine, "ROW3") & ~cbmb_keyline_b)) |
| 176 | data |= 0x02; |
| 177 | |
| 178 | if ((input_port_read(Machine, "ROW4") & ~cbmb_keyline_a) || |
| 179 | (input_port_read(Machine, "ROW5") & ~cbmb_keyline_b)) |
| 180 | data |= 0x04; |
| 181 | |
| 182 | if ((input_port_read(Machine, "ROW6") & ~cbmb_keyline_a) || |
| 183 | (input_port_read(Machine, "ROW7") & ~cbmb_keyline_b)) |
| 184 | data |= 0x08; |
| 185 | |
| 186 | if ((input_port_read(Machine, "ROW8") & ~cbmb_keyline_a) || |
| 187 | ((input_port_read(Machine, "ROW9") | ((input_port_read(Machine, "SPECIAL") & 0x04) ? 1 : 0)) & ~cbmb_keyline_b)) |
| 172 | 188 | data |= 0x10; |
| 173 | | if ( (input_port_read(Machine, "ROW10") & ~cbmb_keyline_a)|| |
| 174 | | (input_port_read(Machine, "ROW11") & ~cbmb_keyline_b)) |
| 189 | |
| 190 | if ((input_port_read(Machine, "ROW10") & ~cbmb_keyline_a) || |
| 191 | (input_port_read(Machine, "ROW11") & ~cbmb_keyline_b)) |
| 175 | 192 | data |= 0x20; |
| 176 | 193 | |
| 177 | 194 | if (!cbm500) |
| 178 | 195 | { |
| 179 | 196 | if (!cbm_ntsc) |
| 180 | 197 | data |= 0x40; |
| 198 | |
| 181 | 199 | if (!cbm700) |
| 182 | 200 | data |= 0x80; |
| 183 | 201 | } |
| 184 | | return data^0xff; |
| 202 | return data ^0xff; |
| 185 | 203 | } |
| 186 | 204 | |
| 187 | 205 | static void cbmb_irq (running_machine *machine, int level) |
| r3150 | r3151 | |
| 217 | 235 | |
| 218 | 236 | static void cbmb_tpi6525_0_irq2_level( running_machine *machine, int level ) |
| 219 | 237 | { |
| 220 | | tpi6525_0_irq2_level( machine, level ); |
| 238 | tpi6525_0_irq2_level(machine, level); |
| 221 | 239 | } |
| 222 | 240 | |
| 223 | 241 | static const cia6526_interface cbmb_cia = |
| r3150 | r3151 | |
| 234 | 252 | |
| 235 | 253 | WRITE8_HANDLER ( cbmb_colorram_w ) |
| 236 | 254 | { |
| 237 | | cbmb_colorram[offset]=data|0xf0; |
| 255 | cbmb_colorram[offset] = data | 0xf0; |
| 238 | 256 | } |
| 239 | 257 | |
| 240 | 258 | static int cbmb_dma_read(int offset) |
| 241 | 259 | { |
| 242 | | if (offset>=0x1000) |
| 243 | | return cbmb_videoram[offset&0x3ff]; |
| 260 | if (offset >= 0x1000) |
| 261 | return cbmb_videoram[offset & 0x3ff]; |
| 244 | 262 | else |
| 245 | | return cbmb_chargen[offset&0xfff]; |
| 263 | return cbmb_chargen[offset & 0xfff]; |
| 246 | 264 | } |
| 247 | 265 | |
| 248 | 266 | static int cbmb_dma_read_color(int offset) |
| 249 | 267 | { |
| 250 | | return cbmb_colorram[offset&0x3ff]; |
| 268 | return cbmb_colorram[offset & 0x3ff]; |
| 251 | 269 | } |
| 252 | 270 | |
| 253 | 271 | static void cbmb_change_font(running_machine *machine, int level) |
| r3150 | r3151 | |
| 257 | 275 | |
| 258 | 276 | static void cbmb_common_driver_init(running_machine *machine) |
| 259 | 277 | { |
| 260 | | cbmb_chargen=memory_region(machine, "main")+0x100000; |
| 278 | cbmb_chargen=memory_region(machine, "main") + 0x100000; |
| 261 | 279 | /* memset(c64_memory, 0, 0xfd00); */ |
| 262 | 280 | |
| 263 | 281 | cia_config(machine, 0, &cbmb_cia); |
| 264 | 282 | |
| 265 | | tpi6525[0].a.read=cbmb_tpi0_port_a_r; |
| 266 | | tpi6525[0].a.output=cbmb_tpi0_port_a_w; |
| 267 | | tpi6525[0].ca.output=cbmb_change_font; |
| 268 | | tpi6525[0].interrupt.output=cbmb_irq; |
| 269 | | tpi6525[1].a.read=cbmb_keyboard_line_a; |
| 270 | | tpi6525[1].b.read=cbmb_keyboard_line_b; |
| 271 | | tpi6525[1].c.read=cbmb_keyboard_line_c; |
| 272 | | tpi6525[1].a.output=cbmb_keyboard_line_select_a; |
| 273 | | tpi6525[1].b.output=cbmb_keyboard_line_select_b; |
| 274 | | tpi6525[1].c.output=cbmb_keyboard_line_select_c; |
| 283 | tpi6525[0].a.read = cbmb_tpi0_port_a_r; |
| 284 | tpi6525[0].a.output = cbmb_tpi0_port_a_w; |
| 285 | tpi6525[0].ca.output = cbmb_change_font; |
| 286 | tpi6525[0].interrupt.output = cbmb_irq; |
| 287 | tpi6525[1].a.read = cbmb_keyboard_line_a; |
| 288 | tpi6525[1].b.read = cbmb_keyboard_line_b; |
| 289 | tpi6525[1].c.read = cbmb_keyboard_line_c; |
| 290 | tpi6525[1].a.output = cbmb_keyboard_line_select_a; |
| 291 | tpi6525[1].b.output = cbmb_keyboard_line_select_b; |
| 292 | tpi6525[1].c.output = cbmb_keyboard_line_select_c; |
| 293 | |
| 275 | 294 | timer_pulse(ATTOTIME_IN_MSEC(10), NULL, 0, cbmb_frame_interrupt); |
| 276 | 295 | |
| 277 | 296 | cbm500 = 0; |
| r3150 | r3151 | |
| 310 | 329 | DRIVER_INIT( cbm500 ) |
| 311 | 330 | { |
| 312 | 331 | cbmb_common_driver_init(machine); |
| 313 | | cbm500=1; |
| 332 | cbm500 = 1; |
| 314 | 333 | cbm_ntsc = 1; |
| 315 | | vic6567_init (0, 0, cbmb_dma_read, cbmb_dma_read_color, NULL); |
| 334 | vic6567_init(0, 0, cbmb_dma_read, cbmb_dma_read_color, NULL); |
| 316 | 335 | } |
| 317 | 336 | |
| 318 | 337 | MACHINE_RESET( cbmb ) |
| r3150 | r3151 | |
| 324 | 343 | |
| 325 | 344 | cbm_drive_0_config (IEEE8ON ? IEEE : 0, 8); |
| 326 | 345 | cbm_drive_1_config (IEEE9ON ? IEEE : 0, 9); |
| 327 | | cbmb_rom_load(); |
| 328 | 346 | } |
| 329 | 347 | |
| 330 | | void cbmb_rom_load(void) |
| 331 | | { |
| 332 | | int i; |
| 333 | 348 | |
| 334 | | for (i=0; (i<sizeof(cbm_rom)/sizeof(cbm_rom[0])) |
| 335 | | &&(cbm_rom[i].size!=0); i++) { |
| 336 | | memcpy(cbmb_memory+cbm_rom[i].addr+0xf0000, cbm_rom[i].chip, cbm_rom[i].size); |
| 337 | | } |
| 338 | | } |
| 339 | | |
| 340 | 349 | static TIMER_CALLBACK(cbmb_frame_interrupt) |
| 341 | 350 | { |
| 342 | 351 | static int level = 0; |
| 352 | #if 0 |
| 353 | int controller1 = input_port_read(Machine, "DSW0") & 0xe000; |
| 354 | int controller2 = input_port_read(Machine, "DSW0") & 0x0e00; |
| 355 | #endif |
| 343 | 356 | |
| 344 | 357 | tpi6525_0_irq0_level(machine, level); |
| 345 | | level=!level; |
| 358 | level = !level; |
| 346 | 359 | if (level) return ; |
| 347 | 360 | |
| 348 | 361 | #if 0 |
| 349 | 362 | value = 0xff; |
| 350 | | if ( ((input_port_read(machine, "DSW0") & 0xe000 ) == 0x2000) || ((input_port_read(machine, "DSW0") & 0xe000 ) == 0x6000) ) |
| 363 | switch(controller1) |
| 351 | 364 | { |
| 352 | | value &= ~(input_port_read(machine, "JOY0") & 0x1f); |
| 353 | | } |
| 354 | | else if (input_port_read(machine, "DSW0") & 0xe000 ) == 0x4000) |
| 355 | | { |
| 356 | | if (input_port_read(machine, "PADDLE1") & 0x100) |
| 357 | | value &= ~8; |
| 358 | | if (input_port_read(machine, "PADDLE0") & 0x100) |
| 359 | | value &= ~4; |
| 360 | | } |
| 361 | | else if (( input_port_read(machine, "DSW0") & 0xe000 ) == 0x8000 ) |
| 362 | | { |
| 363 | | if (input_port_read(machine, "TRACKIPT") & 0x02) |
| 365 | case 0x2000: |
| 366 | case 0x6000: |
| 367 | value &= ~(input_port_read(machine, "JOY0") & 0x1f); /* Joy0 Directions + Button 1 */ |
| 368 | break; |
| 369 | |
| 370 | case 0x4000: |
| 371 | if (input_port_read(machine, "PADDLE1") & 0x100) /* Paddle1 Button */ |
| 372 | value &= ~0x08; |
| 373 | if (input_port_read(machine, "PADDLE0") & 0x100) /* Paddle0 Button */ |
| 374 | value &= ~0x04; |
| 375 | break; |
| 376 | |
| 377 | case 0x8000: |
| 378 | if (input_port_read(machine, "TRACKIPT") & 0x02) /* Mouse Button Left */ |
| 364 | 379 | value &= ~0x10; |
| 365 | | if (input_port_read(machine, "TRACKIPT") & 0x01) |
| 366 | | value &= ~1; |
| 380 | if (input_port_read(machine, "TRACKIPT") & 0x01) /* Mouse Button Right */ |
| 381 | value &= ~0x01; |
| 382 | break; |
| 383 | |
| 384 | case 0xa000: |
| 385 | break; |
| 386 | |
| 387 | default: |
| 388 | logerror("Invalid Controller 1 Setting %d\n", controller1); |
| 389 | break; |
| 367 | 390 | } |
| 391 | |
| 368 | 392 | cbmb_keyline[8] = value; |
| 369 | 393 | |
| 370 | 394 | value = 0xff; |
| 371 | | if ( ((input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0200) || ((input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0600) ) |
| 395 | switch(controller2) |
| 372 | 396 | { |
| 373 | | value &= ~(input_port_read(machine, "JOY1") & 0x1f); // joy2: everything but button2 |
| 374 | | } |
| 375 | | else if (input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0400) // pad3-4 |
| 376 | | { |
| 377 | | if (input_port_read(machine, "PADDLE3") & 0x100) |
| 378 | | value &= ~8; |
| 379 | | if (input_port_read(machine, "PADDLE2") & 0x100) |
| 380 | | value &= ~4; |
| 381 | | } |
| 382 | | else if (( input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0800 ) //mouse2 |
| 383 | | { |
| 384 | | if (input_port_read(machine, "TRACKIPT") & 0x02) //mouse2_button1 = mouse1_button1 |
| 397 | case 0x0200: |
| 398 | case 0x0600: |
| 399 | value &= ~(input_port_read(machine, "JOY1") & 0x1f); /* Joy1 Directions + Button 1 */ |
| 400 | break; |
| 401 | |
| 402 | case 0x0400: |
| 403 | if (input_port_read(machine, "PADDLE3") & 0x100) /* Paddle3 Button */ |
| 404 | value &= ~0x08; |
| 405 | if (input_port_read(machine, "PADDLE2") & 0x100) /* Paddle2 Button */ |
| 406 | value &= ~0x04; |
| 407 | break; |
| 408 | |
| 409 | case 0x0800: |
| 410 | if (input_port_read(machine, "TRACKIPT") & 0x02) /* Mouse Button Left */ |
| 385 | 411 | value &= ~0x10; |
| 386 | | if (input_port_read(machine, "TRACKIPT") & 0x01) //mouse2_button2 = mouse1_button2 |
| 387 | | value &= ~1; |
| 412 | if (input_port_read(machine, "TRACKIPT") & 0x01) /* Mouse Button Right */ |
| 413 | value &= ~0x01; |
| 414 | break; |
| 415 | |
| 416 | default: |
| 417 | logerror("Invalid Controller 2 Setting %d\n", controller2); |
| 418 | break; |
| 388 | 419 | } |
| 389 | | } |
| 420 | |
| 390 | 421 | cbmb_keyline[9] = value; |
| 391 | 422 | #endif |
| 392 | 423 | |
| r3150 | r3151 | |
| 397 | 428 | set_led_status (0, input_port_read(machine, "DSW0") & 0x100 ? 1 : 0); /*KB_NUMLOCK_FLAG */ |
| 398 | 429 | #endif |
| 399 | 430 | } |
| 431 | |
| 432 | |
| 433 | /*********************************************** |
| 434 | |
| 435 | CBM Business Computers Cartridges |
| 436 | |
| 437 | ***********************************************/ |
| 438 | |
| 439 | |
| 440 | static CBM_ROM cbmb_cbm_cart[0x20]= { {0} }; |
| 441 | |
| 442 | static DEVICE_IMAGE_LOAD(cbmb_cart) |
| 443 | { |
| 444 | int size = image_length(image), test; |
| 445 | const char *filetype; |
| 446 | int address = 0; |
| 447 | |
| 448 | filetype = image_filetype(image); |
| 449 | |
| 450 | if (!mame_stricmp (filetype, "crt")) |
| 451 | { |
| 452 | /* We temporarily remove .crt loading. Previous versions directly used |
| 453 | the same routines used to load C64 .crt file, but I seriously doubt the |
| 454 | formats are compatible. While waiting for confirmation about .crt dumps |
| 455 | for CBMB machines, we simply do not load .crt files */ |
| 456 | } |
| 457 | else |
| 458 | { |
| 459 | /* Assign loading address according to extension */ |
| 460 | if (!mame_stricmp (filetype, "10")) |
| 461 | address = 0x1000; |
| 462 | |
| 463 | else if (!mame_stricmp (filetype, "20")) |
| 464 | address = 0x2000; |
| 465 | |
| 466 | else if (!mame_stricmp (filetype, "40")) |
| 467 | address = 0x4000; |
| 468 | |
| 469 | else if (!mame_stricmp (filetype, "60")) |
| 470 | address = 0x6000; |
| 471 | |
| 472 | logerror("Loading cart %s at %.4x size:%.4x\n", image_filename(image), address, size); |
| 473 | |
| 474 | /* Does cart contain any data? */ |
| 475 | cbmb_cbm_cart[0].chip = (UINT8*) image_malloc(image, size); |
| 476 | if (!cbmb_cbm_cart[0].chip) |
| 477 | return INIT_FAIL; |
| 478 | |
| 479 | /* Store data, address & size */ |
| 480 | cbmb_cbm_cart[0].addr = address; |
| 481 | cbmb_cbm_cart[0].size = size; |
| 482 | test = image_fread(image, cbmb_cbm_cart[0].chip, cbmb_cbm_cart[0].size); |
| 483 | |
| 484 | if (test != cbmb_cbm_cart[0].size) |
| 485 | return INIT_FAIL; |
| 486 | } |
| 487 | |
| 488 | /* Finally load the cart */ |
| 489 | // This could be needed with .crt support |
| 490 | // for (i = 0; (i < sizeof(pet_cbm_cart) / sizeof(pet_cbm_cart[0])) && (pet_cbm_cart[i].size != 0); i++) |
| 491 | // memcpy(cbmb_memory + cbmb_cbm_cart[i].addr + 0xf0000, cbmb_cbm_cart[i].chip, cbmb_cbm_cart[i].size); |
| 492 | memcpy(cbmb_memory + cbmb_cbm_cart[0].addr + 0xf0000, cbmb_cbm_cart[0].chip, cbmb_cbm_cart[0].size); |
| 493 | |
| 494 | return INIT_PASS; |
| 495 | } |
| 496 | |
| 497 | void cbmb_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 498 | { |
| 499 | switch(state) |
| 500 | { |
| 501 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 502 | case MESS_DEVINFO_INT_COUNT: info->i = 2; break; |
| 503 | |
| 504 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 505 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "crt,10,20,40,60"); break; |
| 506 | |
| 507 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 508 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(cbmb_cart); break; |
| 509 | |
| 510 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 511 | } |
| 512 | } |
src/mess/machine/pet.c
| r3150 | r3151 | |
| 17 | 17 | |
| 18 | 18 | #include "includes/pet.h" |
| 19 | 19 | |
| 20 | #include "devices/cartslot.h" |
| 21 | |
| 20 | 22 | /* keyboard lines */ |
| 21 | | static int pet_basic1=0; /* basic version 1 for quickloader */ |
| 22 | | static int superpet=0; |
| 23 | | static int cbm8096=0; |
| 23 | static int pet_basic1 = 0; /* basic version 1 for quickloader */ |
| 24 | static int superpet = 0; |
| 25 | static int cbm8096 = 0; |
| 24 | 26 | static int pet_keyline_select; |
| 25 | 27 | |
| 26 | | int pet_font=0; |
| 28 | int pet_font = 0; |
| 27 | 29 | UINT8 *pet_memory; |
| 28 | 30 | UINT8 *superpet_memory; |
| 29 | 31 | UINT8 *pet_videoram; |
| r3150 | r3151 | |
| 63 | 65 | */ |
| 64 | 66 | static READ8_HANDLER ( pet_pia0_port_a_read ) |
| 65 | 67 | { |
| 66 | | int data=0xf0 | pet_keyline_select; |
| 67 | | if (!cbm_ieee_eoi_r()) data&=~0x40; |
| 68 | int data = 0xf0 | pet_keyline_select; |
| 69 | |
| 70 | if (!cbm_ieee_eoi_r()) |
| 71 | data&=~0x40; |
| 68 | 72 | return data; |
| 69 | 73 | } |
| 70 | 74 | |
| r3150 | r3151 | |
| 80 | 84 | static const char *keynames[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", |
| 81 | 85 | "ROW5", "ROW6", "ROW7", "ROW8", "ROW9" }; |
| 82 | 86 | |
| 83 | | if ( pet_keyline_select < 10 ) |
| 87 | if (pet_keyline_select < 10) |
| 84 | 88 | { |
| 85 | 89 | data = input_port_read(machine, keynames[pet_keyline_select]); |
| 86 | 90 | /* Check for left-shift lock */ |
| 87 | | if ( pet_keyline_select == 8 && ( input_port_read(machine, "SPECIAL") & 0x80 ) ) |
| 88 | | { |
| 89 | | data &= 0xFE; |
| 90 | | } |
| 91 | if ((pet_keyline_select == 8) && (input_port_read(machine, "SPECIAL") & 0x80)) |
| 92 | data &= 0xfe; |
| 91 | 93 | } |
| 92 | 94 | return data; |
| 93 | 95 | } |
| r3150 | r3151 | |
| 99 | 101 | static const char *keynames[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", |
| 100 | 102 | "ROW5", "ROW6", "ROW7", "ROW8", "ROW9" }; |
| 101 | 103 | |
| 102 | | if ( pet_keyline_select < 10 ) |
| 104 | if (pet_keyline_select < 10) |
| 103 | 105 | { |
| 104 | 106 | data = input_port_read(machine, keynames[pet_keyline_select]); |
| 105 | 107 | /* Check for left-shift lock */ |
| r3150 | r3151 | |
| 107 | 109 | /* While waiting for confirmation from docs, we add a workaround here. */ |
| 108 | 110 | if (superpet) |
| 109 | 111 | { |
| 110 | | if (pet_keyline_select == 6 && !(input_port_read(machine, "SPECIAL") & 0x80)) |
| 111 | | { |
| 112 | | data &= 0xFE; |
| 113 | | } |
| 112 | if ((pet_keyline_select == 6) && !(input_port_read(machine, "SPECIAL") & 0x80)) |
| 113 | data &= 0xfe; |
| 114 | 114 | } |
| 115 | 115 | else |
| 116 | 116 | { |
| 117 | | if (pet_keyline_select == 6 && (input_port_read(machine, "SPECIAL") & 0x80)) |
| 118 | | { |
| 119 | | data &= 0xFE; |
| 120 | | } |
| 117 | if ((pet_keyline_select == 6) && (input_port_read(machine, "SPECIAL") & 0x80)) |
| 118 | data &= 0xfe; |
| 121 | 119 | } |
| 122 | 120 | } |
| 123 | 121 | return data; |
| r3150 | r3151 | |
| 167 | 165 | |
| 168 | 166 | static WRITE8_HANDLER ( pet_pia1_ca2_write ) |
| 169 | 167 | { |
| 170 | | cbm_ieee_ndac_w(0,data); |
| 168 | cbm_ieee_ndac_w(0, data); |
| 171 | 169 | } |
| 172 | 170 | |
| 173 | 171 | static WRITE8_HANDLER ( pet_pia1_cb2_write ) |
| 174 | 172 | { |
| 175 | | cbm_ieee_dav_w(0,data); |
| 173 | cbm_ieee_dav_w(0, data); |
| 176 | 174 | } |
| 177 | 175 | |
| 178 | 176 | static READ8_HANDLER ( pet_pia1_cb1_read ) |
| r3150 | r3151 | |
| 229 | 227 | static WRITE8_HANDLER( pet_address_line_11 ) |
| 230 | 228 | { |
| 231 | 229 | DBG_LOG (1, "address line", ("%d\n", data)); |
| 232 | | if (data) pet_font|=1; |
| 233 | | else pet_font&=~1; |
| 230 | if (data) pet_font |= 1; |
| 231 | else pet_font &= ~1; |
| 234 | 232 | } |
| 235 | 233 | |
| 236 | 234 | /* userport, cassettes, rest ieee488 |
| r3150 | r3151 | |
| 252 | 250 | */ |
| 253 | 251 | static READ8_HANDLER( pet_via_port_b_r ) |
| 254 | 252 | { |
| 255 | | UINT8 data=0; |
| 256 | | if (cbm_ieee_ndac_r()) data|=1; |
| 257 | | if (cbm_ieee_nrfd_r()) data|=0x40; |
| 258 | | if (cbm_ieee_dav_r()) data|=0x80; |
| 253 | UINT8 data = 0; |
| 254 | |
| 255 | if (cbm_ieee_ndac_r()) data |= 1; |
| 256 | |
| 257 | if (cbm_ieee_nrfd_r()) data |= 0x40; |
| 258 | |
| 259 | if (cbm_ieee_dav_r()) data |= 0x80; |
| 260 | |
| 259 | 261 | return data; |
| 260 | 262 | } |
| 261 | 263 | |
| 262 | 264 | static WRITE8_HANDLER( pet_via_port_b_w ) |
| 263 | 265 | { |
| 264 | | cbm_ieee_nrfd_w(0, data&2); |
| 265 | | cbm_ieee_atn_w(0, data&4); |
| 266 | cbm_ieee_nrfd_w(0, data & 2); |
| 267 | cbm_ieee_atn_w(0, data & 4); |
| 266 | 268 | } |
| 267 | 269 | |
| 268 | 270 | |
| r3150 | r3151 | |
| 286 | 288 | |
| 287 | 289 | static WRITE8_HANDLER(cbm8096_io_w) |
| 288 | 290 | { |
| 289 | | if (offset<0x10) ; |
| 290 | | else if (offset<0x14) pia_0_w(machine, offset&3,data); |
| 291 | | else if (offset<0x20) ; |
| 292 | | else if (offset<0x24) pia_1_w(machine, offset&3,data); |
| 293 | | else if (offset<0x40) ; |
| 294 | | else if (offset<0x50) via_0_w(machine, offset&0xf,data); |
| 295 | | else if (offset<0x80) ; |
| 291 | if (offset < 0x10) ; |
| 292 | else if (offset < 0x14) pia_0_w(machine, offset & 3, data); |
| 293 | else if (offset < 0x20) ; |
| 294 | else if (offset < 0x24) pia_1_w(machine, offset & 3, data); |
| 295 | else if (offset < 0x40) ; |
| 296 | else if (offset < 0x50) via_0_w(machine, offset & 0xf, data); |
| 297 | else if (offset < 0x80) ; |
| 296 | 298 | else if (offset == 0x80) pet_mc6845_address_w(machine, offset, data); |
| 297 | 299 | else if (offset == 0x81) pet_mc6845_register_w(machine, offset, data); |
| 298 | 300 | } |
| 299 | 301 | |
| 300 | 302 | static READ8_HANDLER(cbm8096_io_r) |
| 301 | 303 | { |
| 302 | | int data=0xff; |
| 303 | | if (offset<0x10) ; |
| 304 | | else if (offset<0x14) data=pia_0_r(machine, offset&3); |
| 305 | | else if (offset<0x20) ; |
| 306 | | else if (offset<0x24) data=pia_1_r(machine, offset&3); |
| 307 | | else if (offset<0x40) ; |
| 308 | | else if (offset<0x50) data=via_0_r(machine, offset&0xf); |
| 309 | | else if (offset<0x80) ; |
| 310 | | else if (offset == 0x81) data=pet_mc6845_register_r(machine, offset); |
| 304 | int data = 0xff; |
| 305 | if (offset < 0x10) ; |
| 306 | else if (offset < 0x14) data = pia_0_r(machine, offset & 3); |
| 307 | else if (offset < 0x20) ; |
| 308 | else if (offset < 0x24) data = pia_1_r(machine, offset & 3); |
| 309 | else if (offset < 0x40) ; |
| 310 | else if (offset < 0x50) data = via_0_r(machine, offset & 0xf); |
| 311 | else if (offset < 0x80) ; |
| 312 | else if (offset == 0x81) data = pet_mc6845_register_r(machine, offset); |
| 311 | 313 | return data; |
| 312 | 314 | } |
| 313 | 315 | |
| r3150 | r3151 | |
| 331 | 333 | read8_machine_func rh; |
| 332 | 334 | write8_machine_func wh; |
| 333 | 335 | |
| 334 | | if (data&0x80) |
| 336 | if (data & 0x80) |
| 335 | 337 | { |
| 336 | | if (data&0x40) |
| 338 | if (data & 0x40) |
| 337 | 339 | { |
| 338 | 340 | rh = cbm8096_io_r; |
| 339 | 341 | wh = cbm8096_io_w; |
| r3150 | r3151 | |
| 341 | 343 | else |
| 342 | 344 | { |
| 343 | 345 | rh = SMH_BANK7; |
| 344 | | if (!(data&2)) |
| 346 | if (!(data & 2)) |
| 345 | 347 | wh = SMH_BANK7; |
| 346 | 348 | else |
| 347 | 349 | wh = SMH_NOP; |
| r3150 | r3151 | |
| 353 | 355 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xf000, 0xffef, 0, 0, (data & 2) == 0 ? SMH_BANK8 : SMH_NOP); |
| 354 | 356 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xfff1, 0xffff, 0, 0, (data & 2) == 0 ? SMH_BANK9 : SMH_NOP); |
| 355 | 357 | |
| 356 | | if (data&0x20) |
| 358 | if (data & 0x20) |
| 357 | 359 | { |
| 358 | 360 | pet80_bank1_base = pet_memory + 0x8000; |
| 359 | 361 | memory_set_bankptr(1, pet80_bank1_base); |
| r3150 | r3151 | |
| 361 | 363 | } |
| 362 | 364 | else |
| 363 | 365 | { |
| 364 | | if (!(data&1)) |
| 366 | if (!(data & 1)) |
| 365 | 367 | wh = SMH_BANK1; |
| 366 | 368 | else |
| 367 | 369 | wh = SMH_NOP; |
| r3150 | r3151 | |
| 373 | 375 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xb000, 0xbfff, 0, 0, (data & 1) == 0 ? SMH_BANK4 : SMH_NOP); |
| 374 | 376 | |
| 375 | 377 | |
| 376 | | if (data&4) { |
| 377 | | if (!(data&0x20)) { |
| 378 | if (data & 4) |
| 379 | { |
| 380 | if (!(data & 0x20)) |
| 381 | { |
| 378 | 382 | pet80_bank1_base = pet_memory + 0x14000; |
| 379 | | memory_set_bankptr(1,pet80_bank1_base); |
| 383 | memory_set_bankptr(1, pet80_bank1_base); |
| 380 | 384 | } |
| 381 | | memory_set_bankptr(2,pet_memory+0x15000); |
| 382 | | memory_set_bankptr(3,pet_memory+0x16000); |
| 383 | | memory_set_bankptr(4,pet_memory+0x17000); |
| 384 | | } else { |
| 385 | | if (!(data&0x20)) { |
| 385 | memory_set_bankptr(2, pet_memory + 0x15000); |
| 386 | memory_set_bankptr(3, pet_memory + 0x16000); |
| 387 | memory_set_bankptr(4, pet_memory + 0x17000); |
| 388 | } |
| 389 | else |
| 390 | { |
| 391 | if (!(data & 0x20)) |
| 392 | { |
| 386 | 393 | pet80_bank1_base = pet_memory + 0x10000; |
| 387 | | memory_set_bankptr(1,pet80_bank1_base); |
| 394 | memory_set_bankptr(1, pet80_bank1_base); |
| 388 | 395 | } |
| 389 | | memory_set_bankptr(2,pet_memory+0x11000); |
| 390 | | memory_set_bankptr(3,pet_memory+0x12000); |
| 391 | | memory_set_bankptr(4,pet_memory+0x13000); |
| 396 | memory_set_bankptr(2, pet_memory + 0x11000); |
| 397 | memory_set_bankptr(3, pet_memory + 0x12000); |
| 398 | memory_set_bankptr(4, pet_memory + 0x13000); |
| 392 | 399 | } |
| 393 | | if (data&8) { |
| 394 | | if (!(data&0x40)) { |
| 395 | | memory_set_bankptr(7,pet_memory+0x1e800); |
| 400 | |
| 401 | if (data & 8) |
| 402 | { |
| 403 | if (!(data & 0x40)) |
| 404 | { |
| 405 | memory_set_bankptr(7, pet_memory + 0x1e800); |
| 396 | 406 | } |
| 397 | | memory_set_bankptr(6, pet_memory+0x1c000); |
| 398 | | memory_set_bankptr(8, pet_memory+0x1f000); |
| 399 | | memory_set_bankptr(9, pet_memory+0x1fff1); |
| 400 | | } else { |
| 401 | | if (!(data&0x40)) { |
| 402 | | memory_set_bankptr(7,pet_memory+0x1a800); |
| 407 | memory_set_bankptr(6, pet_memory + 0x1c000); |
| 408 | memory_set_bankptr(8, pet_memory + 0x1f000); |
| 409 | memory_set_bankptr(9, pet_memory + 0x1fff1); |
| 410 | } |
| 411 | else |
| 412 | { |
| 413 | if (!(data & 0x40)) |
| 414 | { |
| 415 | memory_set_bankptr(7, pet_memory+ 0x1a800); |
| 403 | 416 | } |
| 404 | | memory_set_bankptr(6, pet_memory+0x18000); |
| 405 | | memory_set_bankptr(8, pet_memory+0x1b000); |
| 406 | | memory_set_bankptr(9, pet_memory+0x1bff1); |
| 417 | memory_set_bankptr(6, pet_memory + 0x18000); |
| 418 | memory_set_bankptr(8, pet_memory + 0x1b000); |
| 419 | memory_set_bankptr(9, pet_memory + 0x1bff1); |
| 407 | 420 | } |
| 408 | 421 | } |
| 409 | 422 | else |
| r3150 | r3151 | |
| 418 | 431 | memory_set_bankptr(3, pet_memory + 0xa000); |
| 419 | 432 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xa000, 0xafff, 0, 0, SMH_UNMAP); |
| 420 | 433 | |
| 421 | | memory_set_bankptr(4,pet_memory+0xb000); |
| 434 | memory_set_bankptr(4, pet_memory + 0xb000); |
| 422 | 435 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xb000, 0xbfff, 0, 0, SMH_UNMAP); |
| 423 | 436 | |
| 424 | | memory_set_bankptr(6,pet_memory+0xc000); |
| 437 | memory_set_bankptr(6, pet_memory + 0xc000); |
| 425 | 438 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xc000, 0xe7ff, 0, 0, SMH_UNMAP); |
| 426 | 439 | |
| 427 | 440 | memory_install_read8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xe800, 0xefff, 0, 0, cbm8096_io_r); |
| 428 | 441 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xe800, 0xefff, 0, 0, cbm8096_io_w); |
| 429 | 442 | |
| 430 | | memory_set_bankptr(8,pet_memory+0xf000); |
| 443 | memory_set_bankptr(8, pet_memory + 0xf000); |
| 431 | 444 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xf000, 0xffef, 0, 0, SMH_UNMAP); |
| 432 | 445 | |
| 433 | | memory_set_bankptr(9,pet_memory+0xfff1); |
| 446 | memory_set_bankptr(9, pet_memory + 0xfff1); |
| 434 | 447 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xfff1, 0xffff, 0, 0, SMH_UNMAP); |
| 435 | 448 | } |
| 436 | 449 | } |
| r3150 | r3151 | |
| 470 | 483 | |
| 471 | 484 | static TIMER_CALLBACK(pet_interrupt) |
| 472 | 485 | { |
| 473 | | static int level=0; |
| 486 | static int level = 0; |
| 474 | 487 | |
| 475 | | pia_0_cb1_w(machine, 0,level); |
| 476 | | level=!level; |
| 488 | pia_0_cb1_w(machine, 0, level); |
| 489 | level = !level; |
| 477 | 490 | } |
| 478 | 491 | |
| 479 | 492 | static void pet_common_driver_init(running_machine *machine) |
| r3150 | r3151 | |
| 572 | 585 | if (superpet) |
| 573 | 586 | { |
| 574 | 587 | spet.rom = 0; |
| 575 | | if (input_port_read(machine, "CFG") & 4) |
| 588 | if (input_port_read(machine, "CFG") & 0x04) |
| 576 | 589 | { |
| 577 | 590 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, 1); |
| 578 | 591 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, 0); |
| r3150 | r3151 | |
| 588 | 601 | |
| 589 | 602 | if (cbm8096) |
| 590 | 603 | { |
| 591 | | if (input_port_read(machine, "CFG") & 8) |
| 604 | if (input_port_read(machine, "CFG") & 0x08) |
| 592 | 605 | { |
| 593 | 606 | memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xfff0, 0xfff0, 0, 0, cbm8096_w); |
| 594 | 607 | } |
| r3150 | r3151 | |
| 601 | 614 | |
| 602 | 615 | cbm_drive_0_config (input_port_read(machine, "CFG") & 2 ? IEEE : 0, 8); |
| 603 | 616 | cbm_drive_1_config (input_port_read(machine, "CFG") & 1 ? IEEE : 0, 9); |
| 604 | | |
| 605 | | pet_rom_load(); |
| 606 | 617 | } |
| 607 | 618 | |
| 608 | 619 | |
| 609 | | |
| 610 | | void pet_rom_load(void) |
| 611 | | { |
| 612 | | int i; |
| 613 | | |
| 614 | | for (i=0; (i<sizeof(cbm_rom)/sizeof(cbm_rom[0])) |
| 615 | | &&(cbm_rom[i].size!=0); i++) { |
| 616 | | memcpy(pet_memory+cbm_rom[i].addr, cbm_rom[i].chip, cbm_rom[i].size); |
| 617 | | } |
| 618 | | } |
| 619 | | |
| 620 | 620 | INTERRUPT_GEN( pet_frame_interrupt ) |
| 621 | 621 | { |
| 622 | 622 | if (superpet) |
| 623 | 623 | { |
| 624 | | if (input_port_read(machine, "CFG") & 4) |
| 624 | if (input_port_read(machine, "CFG") & 0x04) |
| 625 | 625 | { |
| 626 | 626 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, 1); |
| 627 | 627 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, 0); |
| r3150 | r3151 | |
| 637 | 637 | |
| 638 | 638 | set_led_status (1, input_port_read(machine, "SPECIAL") & 0x80 ? 1 : 0); /*KB_CAPSLOCK_FLAG */ |
| 639 | 639 | } |
| 640 | |
| 641 | |
| 642 | /*********************************************** |
| 643 | |
| 644 | PET Cartridges |
| 645 | |
| 646 | ***********************************************/ |
| 647 | |
| 648 | |
| 649 | static CBM_ROM pet_cbm_cart[0x20] = { {0} }; |
| 650 | |
| 651 | |
| 652 | static DEVICE_IMAGE_LOAD(pet_cart) |
| 653 | { |
| 654 | int size = image_length(image), test; |
| 655 | const char *filetype; |
| 656 | int address = 0; |
| 657 | |
| 658 | filetype = image_filetype(image); |
| 659 | |
| 660 | if (!mame_stricmp (filetype, "crt")) |
| 661 | { |
| 662 | /* We temporarily remove .crt loading. Previous versions directly used |
| 663 | the same routines used to load C64 .crt file, but I seriously doubt the |
| 664 | formats are compatible. While waiting for confirmation about .crt dumps |
| 665 | for PET machines, we simply do not load .crt files */ |
| 666 | } |
| 667 | else |
| 668 | { |
| 669 | /* Assign loading address according to extension */ |
| 670 | if (!mame_stricmp (filetype, "a0")) |
| 671 | address = 0xa000; |
| 672 | |
| 673 | else if (!mame_stricmp (filetype, "b0")) |
| 674 | address = 0xb000; |
| 675 | |
| 676 | logerror("Loading cart %s at %.4x size:%.4x\n", image_filename(image), address, size); |
| 677 | |
| 678 | /* Does cart contain any data? */ |
| 679 | pet_cbm_cart[0].chip = (UINT8*) image_malloc(image, size); |
| 680 | if (!pet_cbm_cart[0].chip) |
| 681 | return INIT_FAIL; |
| 682 | |
| 683 | /* Store data, address & size */ |
| 684 | pet_cbm_cart[0].addr = address; |
| 685 | pet_cbm_cart[0].size = size; |
| 686 | test = image_fread(image, pet_cbm_cart[0].chip, pet_cbm_cart[0].size); |
| 687 | |
| 688 | if (test != pet_cbm_cart[0].size) |
| 689 | return INIT_FAIL; |
| 690 | } |
| 691 | |
| 692 | /* Finally load the cart */ |
| 693 | // This could be needed with .crt support |
| 694 | // for (i = 0; (i < sizeof(pet_cbm_cart) / sizeof(pet_cbm_cart[0])) && (pet_cbm_cart[i].size != 0); i++) |
| 695 | // memcpy(pet_memory + pet_cbm_cart[i].addr, pet_cbm_cart[i].chip, pet_cbm_cart[i].size); |
| 696 | memcpy(pet_memory + pet_cbm_cart[0].addr, pet_cbm_cart[0].chip, pet_cbm_cart[0].size); |
| 697 | |
| 698 | return INIT_PASS; |
| 699 | } |
| 700 | |
| 701 | |
| 702 | void pet_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 703 | { |
| 704 | switch(state) |
| 705 | { |
| 706 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 707 | case MESS_DEVINFO_INT_COUNT: info->i = 2; break; |
| 708 | |
| 709 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 710 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "crt,a0,b0"); break; |
| 711 | |
| 712 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 713 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(pet_cart); break; |
| 714 | |
| 715 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 716 | } |
| 717 | } |
| 718 | |
| 719 | void pet4_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 720 | { |
| 721 | switch(state) |
| 722 | { |
| 723 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 724 | case MESS_DEVINFO_INT_COUNT: info->i = 2; break; |
| 725 | |
| 726 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 727 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "crt,a0"); break; |
| 728 | |
| 729 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 730 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(pet_cart); break; |
| 731 | |
| 732 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 733 | } |
| 734 | } |
src/mess/machine/c16.c
| r3150 | r3151 | |
| 23 | 23 | #include "includes/c16.h" |
| 24 | 24 | |
| 25 | 25 | #include "devices/cassette.h" |
| 26 | #include "devices/cartslot.h" |
| 26 | 27 | |
| 27 | 28 | static UINT8 keyline[10] = |
| 28 | 29 | { |
| r3150 | r3151 | |
| 55 | 56 | static UINT8 *c16_memory_28000; |
| 56 | 57 | static UINT8 *c16_memory_2c000; |
| 57 | 58 | |
| 58 | | static int c16_rom_load(const device_config *img); |
| 59 | | |
| 60 | 59 | static UINT8 read_cfg0(running_machine *machine) |
| 61 | 60 | { |
| 62 | 61 | UINT8 result; |
| r3150 | r3151 | |
| 120 | 119 | int dat, atn, clk; |
| 121 | 120 | |
| 122 | 121 | /* bit zero then output 0 */ |
| 123 | | cbm_serial_atn_write (atn = !(data & 4)); |
| 124 | | cbm_serial_clock_write (clk = !(data & 2)); |
| 125 | | cbm_serial_data_write (dat = !(data & 1)); |
| 122 | cbm_serial_atn_write (atn = !(data & 0x04)); |
| 123 | cbm_serial_clock_write (clk = !(data & 0x02)); |
| 124 | cbm_serial_data_write (dat = !(data & 0x01)); |
| 126 | 125 | |
| 127 | | // vc20_tape_write (!(data & 2)); // CASSETTE_RECORD not implemented yet |
| 126 | // vc20_tape_write (!(data & 0x02)); // CASSETTE_RECORD not implemented yet |
| 128 | 127 | } |
| 129 | 128 | |
| 130 | 129 | UINT8 c16_m7501_port_read(void) |
| 131 | 130 | { |
| 132 | | UINT8 data = 0xFF; |
| 131 | UINT8 data = 0xff; |
| 133 | 132 | UINT8 c16_port7501 = (UINT8) cpunum_get_info_int(0, CPUINFO_INT_M6510_PORT); |
| 134 | 133 | |
| 135 | 134 | if ((c16_port7501 & 0x01) || !cbm_serial_data_read()) |
| r3150 | r3151 | |
| 170 | 169 | memory_set_bankptr (2, rom + 0x28000); |
| 171 | 170 | break; |
| 172 | 171 | } |
| 172 | |
| 173 | 173 | switch (highrom) |
| 174 | 174 | { |
| 175 | 175 | case 0: |
| r3150 | r3151 | |
| 213 | 213 | * 1 1 c2 high */ |
| 214 | 214 | WRITE8_HANDLER(c16_select_roms) |
| 215 | 215 | { |
| 216 | | lowrom = offset & 3; |
| 217 | | highrom = (offset & 0xc) >> 2; |
| 216 | lowrom = offset & 0x03; |
| 217 | highrom = (offset & 0x0c) >> 2; |
| 218 | 218 | if (ted7360_rom) |
| 219 | 219 | c16_bankswitch(machine); |
| 220 | 220 | } |
| r3150 | r3151 | |
| 232 | 232 | { |
| 233 | 233 | int value = 0xff; |
| 234 | 234 | |
| 235 | | if (!(port6529 & 1)) |
| 235 | if (!(port6529 & 0x01)) |
| 236 | 236 | value &= keyline[0]; |
| 237 | | if (!(port6529 & 2)) |
| 237 | |
| 238 | if (!(port6529 & 0x02)) |
| 238 | 239 | value &= keyline[1]; |
| 239 | | if (!(port6529 & 4)) |
| 240 | |
| 241 | if (!(port6529 & 0x04)) |
| 240 | 242 | value &= keyline[2]; |
| 241 | | if (!(port6529 & 8)) |
| 243 | |
| 244 | if (!(port6529 & 0x08)) |
| 242 | 245 | value &= keyline[3]; |
| 246 | |
| 243 | 247 | if (!(port6529 & 0x10)) |
| 244 | 248 | value &= keyline[4]; |
| 249 | |
| 245 | 250 | if (!(port6529 & 0x20)) |
| 246 | 251 | value &= keyline[5]; |
| 252 | |
| 247 | 253 | if (!(port6529 & 0x40)) |
| 248 | 254 | value &= keyline[6]; |
| 255 | |
| 249 | 256 | if (!(port6529 & 0x80)) |
| 250 | 257 | value &= keyline[7]; |
| 251 | 258 | |
| 252 | 259 | /* looks like joy 0 needs dataline2 low |
| 253 | 260 | * and joy 1 needs dataline1 low |
| 254 | 261 | * write to 0xff08 (value on databus) reloads latches */ |
| 255 | | if (!(databus & 4)) { |
| 262 | if (!(databus & 0x04)) |
| 256 | 263 | value &= keyline[8]; |
| 257 | | } |
| 258 | | if (!(databus & 2)) { |
| 264 | |
| 265 | if (!(databus & 0x02)) |
| 259 | 266 | value &= keyline[9]; |
| 260 | | } |
| 267 | |
| 261 | 268 | return value; |
| 262 | 269 | } |
| 263 | 270 | |
| r3150 | r3151 | |
| 298 | 305 | |
| 299 | 306 | READ8_HANDLER(plus4_6529_port_r) |
| 300 | 307 | { |
| 301 | | int data = 0; |
| 308 | int data = 0x00; |
| 302 | 309 | |
| 303 | 310 | if (!((cassette_get_state(image_from_devtype_and_index(IO_CASSETTE, 0)) & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY)) |
| 304 | | data |= 4; |
| 311 | data |= 0x04; |
| 305 | 312 | return data; |
| 306 | 313 | } |
| 307 | 314 | |
| 308 | 315 | READ8_HANDLER(c16_fd1x_r) |
| 309 | 316 | { |
| 310 | | int data = 0; |
| 317 | int data = 0x00; |
| 311 | 318 | |
| 312 | 319 | if (!((cassette_get_state(image_from_devtype_and_index(IO_CASSETTE, 0)) & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY)) |
| 313 | | data |= 4; |
| 320 | data |= 0x04; |
| 314 | 321 | return data; |
| 315 | 322 | } |
| 316 | 323 | |
| r3150 | r3151 | |
| 353 | 360 | */ |
| 354 | 361 | WRITE8_HANDLER(c16_6551_port_w) |
| 355 | 362 | { |
| 356 | | offset &= 3; |
| 363 | offset &= 0x03; |
| 357 | 364 | DBG_LOG (3, "6551", ("port write %.2x %.2x\n", offset, data)); |
| 358 | 365 | port6529 = data; |
| 359 | 366 | } |
| 360 | 367 | |
| 361 | 368 | READ8_HANDLER(c16_6551_port_r) |
| 362 | 369 | { |
| 363 | | int data = 0; |
| 370 | int data = 0x00; |
| 364 | 371 | |
| 365 | | offset &= 3; |
| 372 | offset &= 0x03; |
| 366 | 373 | DBG_LOG (3, "6551", ("port read %.2x %.2x\n", offset, data)); |
| 367 | 374 | return data; |
| 368 | 375 | } |
| r3150 | r3151 | |
| 379 | 386 | { /* rom address in rom */ |
| 380 | 387 | if ((offset >= 0xfc00) && (offset < 0xfd00)) |
| 381 | 388 | return c16_memory_10000[offset]; |
| 389 | |
| 382 | 390 | switch (highrom) |
| 383 | 391 | { |
| 384 | | case 0: |
| 385 | | return c16_memory_10000[offset & 0x7fff]; |
| 386 | | case 1: |
| 387 | | return c16_memory_18000[offset & 0x7fff]; |
| 388 | | case 2: |
| 389 | | return c16_memory_20000[offset & 0x7fff]; |
| 390 | | case 3: |
| 391 | | return c16_memory_28000[offset & 0x7fff]; |
| 392 | case 0: |
| 393 | return c16_memory_10000[offset & 0x7fff]; |
| 394 | case 1: |
| 395 | return c16_memory_18000[offset & 0x7fff]; |
| 396 | case 2: |
| 397 | return c16_memory_20000[offset & 0x7fff]; |
| 398 | case 3: |
| 399 | return c16_memory_28000[offset & 0x7fff]; |
| 392 | 400 | } |
| 393 | 401 | } |
| 394 | 402 | if (offset >= 0x8000) |
| 395 | 403 | { /* rom address in rom */ |
| 396 | 404 | switch (lowrom) |
| 397 | 405 | { |
| 398 | | case 0: |
| 399 | | return c16_memory_10000[offset & 0x7fff]; |
| 400 | | case 1: |
| 401 | | return c16_memory_18000[offset & 0x7fff]; |
| 402 | | case 2: |
| 403 | | return c16_memory_20000[offset & 0x7fff]; |
| 404 | | case 3: |
| 405 | | return c16_memory_28000[offset & 0x7fff]; |
| 406 | case 0: |
| 407 | return c16_memory_10000[offset & 0x7fff]; |
| 408 | case 1: |
| 409 | return c16_memory_18000[offset & 0x7fff]; |
| 410 | case 2: |
| 411 | return c16_memory_20000[offset & 0x7fff]; |
| 412 | case 3: |
| 413 | return c16_memory_28000[offset & 0x7fff]; |
| 406 | 414 | } |
| 407 | 415 | } |
| 408 | 416 | |
| r3150 | r3151 | |
| 438 | 446 | |
| 439 | 447 | if ((read_cfg0(machine) & 0xc0 ) == 0x40) /* C1551 */ |
| 440 | 448 | { |
| 441 | | tpi6525[2].a.read=c1551x_0_read_data; |
| 442 | | tpi6525[2].a.output=c1551x_0_write_data; |
| 443 | | tpi6525[2].b.read=c1551x_0_read_status; |
| 444 | | tpi6525[2].c.read=c1551x_0_read_handshake; |
| 445 | | tpi6525[2].c.output=c1551x_0_write_handshake; |
| 449 | tpi6525[2].a.read = c1551x_0_read_data; |
| 450 | tpi6525[2].a.output = c1551x_0_write_data; |
| 451 | tpi6525[2].b.read = c1551x_0_read_status; |
| 452 | tpi6525[2].c.read = c1551x_0_read_handshake; |
| 453 | tpi6525[2].c.output = c1551x_0_write_handshake; |
| 446 | 454 | } |
| 447 | 455 | else |
| 448 | 456 | { |
| 449 | | tpi6525[2].a.read=c1551_0_read_data; |
| 450 | | tpi6525[2].a.output=c1551_0_write_data; |
| 451 | | tpi6525[2].b.read=c1551_0_read_status; |
| 452 | | tpi6525[2].c.read=c1551_0_read_handshake; |
| 453 | | tpi6525[2].c.output=c1551_0_write_handshake; |
| 457 | tpi6525[2].a.read = c1551_0_read_data; |
| 458 | tpi6525[2].a.output = c1551_0_write_data; |
| 459 | tpi6525[2].b.read = c1551_0_read_status; |
| 460 | tpi6525[2].c.read = c1551_0_read_handshake; |
| 461 | tpi6525[2].c.output = c1551_0_write_handshake; |
| 454 | 462 | } |
| 455 | 463 | |
| 456 | | tpi6525[3].a.read=c1551_1_read_data; |
| 457 | | tpi6525[3].a.output=c1551_1_write_data; |
| 458 | | tpi6525[3].b.read=c1551_1_read_status; |
| 459 | | tpi6525[3].c.read=c1551_1_read_handshake; |
| 460 | | tpi6525[3].c.output=c1551_1_write_handshake; |
| 464 | tpi6525[3].a.read = c1551_1_read_data; |
| 465 | tpi6525[3].a.output = c1551_1_write_data; |
| 466 | tpi6525[3].b.read = c1551_1_read_status; |
| 467 | tpi6525[3].c.read = c1551_1_read_handshake; |
| 468 | tpi6525[3].c.output = c1551_1_write_handshake; |
| 461 | 469 | |
| 462 | 470 | rom = memory_region(machine, "main"); |
| 471 | |
| 463 | 472 | c16_memory_10000 = rom + 0x10000; |
| 464 | 473 | c16_memory_14000 = rom + 0x14000; |
| 465 | 474 | c16_memory_18000 = rom + 0x18000; |
| r3150 | r3151 | |
| 472 | 481 | /* need to recognice non available tia6523's (iec8/9) */ |
| 473 | 482 | memset(mess_ram + (0xfdc0 % mess_ram_size), 0xff, 0x40); |
| 474 | 483 | |
| 475 | | |
| 476 | 484 | memset(mess_ram + (0xfd40 % mess_ram_size), 0xff, 0x20); |
| 477 | 485 | |
| 478 | 486 | if ((read_cfg0(machine) & 0xc0 ) == 0x40) /* C1551 */ |
| r3150 | r3151 | |
| 493 | 501 | |
| 494 | 502 | MACHINE_RESET( c16 ) |
| 495 | 503 | { |
| 496 | | int i; |
| 497 | | |
| 498 | 504 | tpi6525_2_reset(); |
| 499 | 505 | tpi6525_3_reset(); |
| 500 | 506 | c364_speech_init(); |
| r3150 | r3151 | |
| 576 | 582 | #endif |
| 577 | 583 | |
| 578 | 584 | cbm_serial_reset_write (0); |
| 579 | | |
| 580 | | for (i = 0; i < 2; i++) |
| 581 | | { |
| 582 | | const device_config *image = image_from_devtype_and_index(IO_CARTSLOT, i); |
| 583 | | if (image_exists(image)) |
| 584 | | c16_rom_load(image); |
| 585 | | } |
| 586 | 585 | } |
| 587 | 586 | |
| 588 | | static int c16_rom_id(const device_config *image) |
| 589 | | { |
| 590 | | /* magic lowrom at offset 7: $43 $42 $4d */ |
| 591 | | /* if at offset 6 stands 1 it will immediatly jumped to offset 0 (0x8000) */ |
| 592 | | int retval = 0; |
| 593 | | char magic[] = {0x43, 0x42, 0x4d}, buffer[sizeof (magic)]; |
| 594 | | const char *name = image_filename(image); |
| 595 | | char *cp; |
| 596 | 587 | |
| 597 | | logerror("c16_rom_id %s\n", name); |
| 598 | | retval = 0; |
| 599 | | |
| 600 | | image_fseek (image, 7, SEEK_SET); |
| 601 | | image_fread (image, buffer, sizeof (magic)); |
| 602 | | |
| 603 | | if (memcmp (magic, buffer, sizeof (magic)) == 0) |
| 604 | | { |
| 605 | | retval = 1; |
| 606 | | } |
| 607 | | else if ((cp = strrchr (name, '.')) != NULL) |
| 608 | | { |
| 609 | | if ((mame_stricmp (cp + 1, "rom") == 0) || (mame_stricmp (cp + 1, "prg") == 0) |
| 610 | | || (mame_stricmp (cp + 1, "bin") == 0) |
| 611 | | || (mame_stricmp (cp + 1, "lo") == 0) || (mame_stricmp (cp + 1, "hi") == 0)) |
| 612 | | retval = 1; |
| 613 | | } |
| 614 | | |
| 615 | | if (retval) |
| 616 | | logerror("rom %s recognized\n", name); |
| 617 | | else |
| 618 | | logerror("rom %s not recognized\n", name); |
| 619 | | return retval; |
| 620 | | } |
| 621 | | |
| 622 | | DEVICE_IMAGE_LOAD(c16_rom) |
| 623 | | { |
| 624 | | return (!c16_rom_id(image)) ? INIT_FAIL : INIT_PASS; |
| 625 | | } |
| 626 | | |
| 627 | | static int c16_rom_load(const device_config *image) |
| 628 | | { |
| 629 | | UINT8 *mem = memory_region(image->machine, "main"); |
| 630 | | int size, read_; |
| 631 | | const char *filetype; |
| 632 | | static unsigned int addr = 0; |
| 633 | | |
| 634 | | if (!c16_rom_id(image)) |
| 635 | | return 1; |
| 636 | | |
| 637 | | size = image_length (image); |
| 638 | | |
| 639 | | filetype = image_filetype(image); |
| 640 | | if (filetype && !mame_stricmp (filetype, "prg")) |
| 641 | | { |
| 642 | | unsigned short in; |
| 643 | | |
| 644 | | image_fread(image, &in, 2); |
| 645 | | in = LITTLE_ENDIANIZE_INT16(in); |
| 646 | | logerror("rom prg %.4x\n", in); |
| 647 | | addr = in + 0x20000; |
| 648 | | size -= 2; |
| 649 | | } |
| 650 | | if (addr == 0) |
| 651 | | { |
| 652 | | addr = 0x20000; |
| 653 | | } |
| 654 | | logerror("loading rom at %.5x size:%.4x\n", addr, size); |
| 655 | | read_ = image_fread (image, mem + addr, size); |
| 656 | | addr += size; |
| 657 | | if (read_ != size) |
| 658 | | return 1; |
| 659 | | return 0; |
| 660 | | } |
| 661 | | |
| 662 | 588 | INTERRUPT_GEN( c16_frame_interrupt ) |
| 663 | 589 | { |
| 664 | 590 | int value, i; |
| r3150 | r3151 | |
| 715 | 641 | set_led_status (1, input_port_read(machine, "SPECIAL") & 0x80 ? 1 : 0); /*KB_CAPSLOCK_FLAG */ |
| 716 | 642 | set_led_status (0, input_port_read(machine, "SPECIAL") & 0x40 ? 1 : 0); /*KB_NUMLOCK_FLAG */ |
| 717 | 643 | } |
| 644 | |
| 645 | |
| 646 | /*********************************************** |
| 647 | |
| 648 | C16 Cartridges |
| 649 | |
| 650 | ***********************************************/ |
| 651 | |
| 652 | DEVICE_IMAGE_LOAD(c16_cart) |
| 653 | { |
| 654 | UINT8 *mem = memory_region(image->machine, "main"); |
| 655 | int size = image_length (image), test; |
| 656 | const char *filetype; |
| 657 | int address = 0; |
| 658 | |
| 659 | /* magic lowrom at offset 7: $43 $42 $4d */ |
| 660 | /* if at offset 6 stands 1 it will immediatly jumped to offset 0 (0x8000) */ |
| 661 | static const unsigned char magic[] = {0x43, 0x42, 0x4d}; |
| 662 | unsigned char buffer[sizeof (magic)]; |
| 663 | |
| 664 | image_fseek (image, 7, SEEK_SET); |
| 665 | image_fread (image, buffer, sizeof (magic)); |
| 666 | image_fseek (image, 0, SEEK_SET); |
| 667 | |
| 668 | /* Check if our cart has the magic string, and set its loading address */ |
| 669 | if (!memcmp (buffer, magic, sizeof (magic))) |
| 670 | address = 0x20000; |
| 671 | |
| 672 | /* Give a loading address to non .bin / non .rom carts as well */ |
| 673 | filetype = image_filetype(image); |
| 674 | |
| 675 | /* We would support .hi and .lo files, but currently I'm not sure where to load them. |
| 676 | We simply load them at 0x20000 at this stage, even if it's probably wrong! |
| 677 | It could also well be that they both need to be loaded at the same time, but this |
| 678 | is now impossible since I reduced to 1 the number of cart slots. |
| 679 | More investigations are in order if any .hi, .lo dump would surface! */ |
| 680 | if (!mame_stricmp (filetype, "hi")) |
| 681 | address = 0x20000; /* FIX ME! */ |
| 682 | |
| 683 | else if (!mame_stricmp (filetype, "lo")) |
| 684 | address = 0x20000; /* FIX ME! */ |
| 685 | |
| 686 | /* As a last try, give a reasonable loading address also to .bin/.rom without the magic string */ |
| 687 | else if (!address) |
| 688 | { |
| 689 | logerror("Cart %s does not contain the magic string: it may be loaded at the wrong memory address!\n", image_filename(image)); |
| 690 | address = 0x20000; |
| 691 | } |
| 692 | |
| 693 | logerror("Loading cart %s at %.5x size:%.4x\n", image_filename(image), address, size); |
| 694 | |
| 695 | /* Finally load the cart */ |
| 696 | test = image_fread (image, mem + address, size); |
| 697 | |
| 698 | if (test != size) |
| 699 | return INIT_FAIL; |
| 700 | |
| 701 | return INIT_PASS; |
| 702 | } |
| 703 | |
| 704 | void c16_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 705 | { |
| 706 | switch(state) |
| 707 | { |
| 708 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 709 | case MESS_DEVINFO_INT_COUNT: info->i = 1; break; |
| 710 | |
| 711 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 712 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(c16_cart); break; |
| 713 | |
| 714 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 715 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "bin,rom,hi,lo"); break; |
| 716 | |
| 717 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 718 | } |
| 719 | } |
src/mess/machine/vc20.c
| r3150 | r3151 | |
| 28 | 28 | #include "includes/vc20.h" |
| 29 | 29 | |
| 30 | 30 | #include "devices/cassette.h" |
| 31 | #include "devices/cartslot.h" |
| 31 | 32 | |
| 32 | 33 | |
| 33 | 34 | static UINT8 keyboard[8] = |
| r3150 | r3151 | |
| 68 | 69 | |
| 69 | 70 | static READ8_HANDLER( vc20_via0_read_ca1 ) |
| 70 | 71 | { |
| 71 | | return ! ( input_port_read(machine, "SPECIAL") & 0x02 ); |
| 72 | return !( input_port_read(machine, "SPECIAL") & 0x02 ); |
| 72 | 73 | } |
| 73 | 74 | |
| 74 | 75 | static READ8_HANDLER( vc20_via0_read_ca2 ) |
| r3150 | r3151 | |
| 102 | 103 | /* to short to be recognized normally */ |
| 103 | 104 | /* should be reduced to about 1 or 2 microseconds */ |
| 104 | 105 | /* if ((input_port_read(machine, "CFG") & 0x20 ) && (input_port_read(machine, "JOY") & 0x40) ) // i.e. LIGHTPEN_BUTTON |
| 105 | | value&=~0x20; */ |
| 106 | value &= ~0x20; */ |
| 106 | 107 | if (!serial_clock || !cbm_serial_clock_read ()) |
| 107 | | value &= ~1; |
| 108 | value &= ~0x01; |
| 108 | 109 | if (!serial_data || !cbm_serial_data_read ()) |
| 109 | | value &= ~2; |
| 110 | value &= ~0x02; |
| 110 | 111 | |
| 111 | 112 | if ((cassette_get_state(image_from_devtype_and_index(IO_CASSETTE, 0)) & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) |
| 112 | 113 | value &= ~0x40; |
| r3150 | r3151 | |
| 184 | 185 | { |
| 185 | 186 | UINT8 value = 0xff; |
| 186 | 187 | |
| 187 | | if (!(via1_porta&0x80)) { |
| 188 | | UINT8 t=0xff; |
| 189 | | if (!(keyboard[7]&0x80)) t&=~0x80; |
| 190 | | if (!(keyboard[6]&0x80)) t&=~0x40; |
| 191 | | if (!(keyboard[5]&0x80)) t&=~0x20; |
| 192 | | if (!(keyboard[4]&0x80)) t&=~0x10; |
| 193 | | if (!(keyboard[3]&0x80)) t&=~0x08; |
| 194 | | if (!(keyboard[2]&0x80)) t&=~0x04; |
| 195 | | if (!(keyboard[1]&0x80)) t&=~0x02; |
| 196 | | if (!(keyboard[0]&0x80)) t&=~0x01; |
| 197 | | value &=t; |
| 188 | if (!(via1_porta & 0x80)) |
| 189 | { |
| 190 | UINT8 t = 0xff; |
| 191 | if (!(keyboard[7] & 0x80)) t &= ~0x80; |
| 192 | if (!(keyboard[6] & 0x80)) t &= ~0x40; |
| 193 | if (!(keyboard[5] & 0x80)) t &= ~0x20; |
| 194 | if (!(keyboard[4] & 0x80)) t &= ~0x10; |
| 195 | if (!(keyboard[3] & 0x80)) t &= ~0x08; |
| 196 | if (!(keyboard[2] & 0x80)) t &= ~0x04; |
| 197 | if (!(keyboard[1] & 0x80)) t &= ~0x02; |
| 198 | if (!(keyboard[0] & 0x80)) t &= ~0x01; |
| 199 | value &= t; |
| 198 | 200 | } |
| 199 | | if (!(via1_porta&0x40)) { |
| 200 | | UINT8 t=0xff; |
| 201 | | if (!(keyboard[7]&0x40)) t&=~0x80; |
| 202 | | if (!(keyboard[6]&0x40)) t&=~0x40; |
| 203 | | if (!(keyboard[5]&0x40)) t&=~0x20; |
| 204 | | if (!(keyboard[4]&0x40)) t&=~0x10; |
| 205 | | if (!(keyboard[3]&0x40)) t&=~0x08; |
| 206 | | if (!(keyboard[2]&0x40)) t&=~0x04; |
| 207 | | if (!(keyboard[1]&0x40)) t&=~0x02; |
| 208 | | if (!(keyboard[0]&0x40)) t&=~0x01; |
| 209 | | value &=t; |
| 201 | |
| 202 | if (!(via1_porta & 0x40)) |
| 203 | { |
| 204 | UINT8 t = 0xff; |
| 205 | if (!(keyboard[7] & 0x40)) t &= ~0x80; |
| 206 | if (!(keyboard[6] & 0x40)) t &= ~0x40; |
| 207 | if (!(keyboard[5] & 0x40)) t &= ~0x20; |
| 208 | if (!(keyboard[4] & 0x40)) t &= ~0x10; |
| 209 | if (!(keyboard[3] & 0x40)) t &= ~0x08; |
| 210 | if (!(keyboard[2] & 0x40)) t &= ~0x04; |
| 211 | if (!(keyboard[1] & 0x40)) t &= ~0x02; |
| 212 | if (!(keyboard[0] & 0x40)) t &= ~0x01; |
| 213 | value &= t; |
| 210 | 214 | } |
| 211 | | if (!(via1_porta&0x20)) { |
| 212 | | UINT8 t=0xff; |
| 213 | | if (!(keyboard[7]&0x20)) t&=~0x80; |
| 214 | | if (!(keyboard[6]&0x20)) t&=~0x40; |
| 215 | | if (!(keyboard[5]&0x20)) t&=~0x20; |
| 216 | | if (!(keyboard[4]&0x20)) t&=~0x10; |
| 217 | | if (!(keyboard[3]&0x20)) t&=~0x08; |
| 218 | | if (!(keyboard[2]&0x20)) t&=~0x04; |
| 219 | | if (!(keyboard[1]&0x20)) t&=~0x02; |
| 220 | | if (!(keyboard[0]&0x20)) t&=~0x01; |
| 221 | | value &=t; |
| 215 | |
| 216 | if (!(via1_porta & 0x20)) |
| 217 | { |
| 218 | UINT8 t = 0xff; |
| 219 | if (!(keyboard[7] & 0x20)) t &= ~0x80; |
| 220 | if (!(keyboard[6] & 0x20)) t &= ~0x40; |
| 221 | if (!(keyboard[5] & 0x20)) t &= ~0x20; |
| 222 | if (!(keyboard[4] & 0x20)) t &= ~0x10; |
| 223 | if (!(keyboard[3] & 0x20)) t &= ~0x08; |
| 224 | if (!(keyboard[2] & 0x20)) t &= ~0x04; |
| 225 | if (!(keyboard[1] & 0x20)) t &= ~0x02; |
| 226 | if (!(keyboard[0] & 0x20)) t &= ~0x01; |
| 227 | value &= t; |
| 222 | 228 | } |
| 223 | | if (!(via1_porta&0x10)) { |
| 224 | | UINT8 t=0xff; |
| 225 | | if (!(keyboard[7]&0x10)) t&=~0x80; |
| 226 | | if (!(keyboard[6]&0x10)) t&=~0x40; |
| 227 | | if (!(keyboard[5]&0x10)) t&=~0x20; |
| 228 | | if (!(keyboard[4]&0x10)) t&=~0x10; |
| 229 | | if (!(keyboard[3]&0x10)) t&=~0x08; |
| 230 | | if (!(keyboard[2]&0x10)) t&=~0x04; |
| 231 | | if (!(keyboard[1]&0x10)) t&=~0x02; |
| 232 | | if (!(keyboard[0]&0x10)) t&=~0x01; |
| 233 | | value &=t; |
| 229 | |
| 230 | if (!(via1_porta & 0x10)) |
| 231 | { |
| 232 | UINT8 t = 0xff; |
| 233 | if (!(keyboard[7] & 0x10)) t &= ~0x80; |
| 234 | if (!(keyboard[6] & 0x10)) t &= ~0x40; |
| 235 | if (!(keyboard[5] & 0x10)) t &= ~0x20; |
| 236 | if (!(keyboard[4] & 0x10)) t &= ~0x10; |
| 237 | if (!(keyboard[3] & 0x10)) t &= ~0x08; |
| 238 | if (!(keyboard[2] & 0x10)) t &= ~0x04; |
| 239 | if (!(keyboard[1] & 0x10)) t &= ~0x02; |
| 240 | if (!(keyboard[0] & 0x10)) t &= ~0x01; |
| 241 | value &= t; |
| 234 | 242 | } |
| 235 | | if (!(via1_porta&0x08)) { |
| 236 | | UINT8 t=0xff; |
| 237 | | if (!(keyboard[7]&0x08)) t&=~0x80; |
| 238 | | if (!(keyboard[6]&0x08)) t&=~0x40; |
| 239 | | if (!(keyboard[5]&0x08)) t&=~0x20; |
| 240 | | if (!(keyboard[4]&0x08)) t&=~0x10; |
| 241 | | if (!(keyboard[3]&0x08)) t&=~0x08; |
| 242 | | if (!(keyboard[2]&0x08)) t&=~0x04; |
| 243 | | if (!(keyboard[1]&0x08)) t&=~0x02; |
| 244 | | if (!(keyboard[0]&0x08)) t&=~0x01; |
| 245 | | value &=t; |
| 243 | |
| 244 | if (!(via1_porta & 0x08)) |
| 245 | { |
| 246 | UINT8 t = 0xff; |
| 247 | if (!(keyboard[7] & 0x08)) t &= ~0x80; |
| 248 | if (!(keyboard[6] & 0x08)) t &= ~0x40; |
| 249 | if (!(keyboard[5] & 0x08)) t &= ~0x20; |
| 250 | if (!(keyboard[4] & 0x08)) t &= ~0x10; |
| 251 | if (!(keyboard[3] & 0x08)) t &= ~0x08; |
| 252 | if (!(keyboard[2] & 0x08)) t &= ~0x04; |
| 253 | if (!(keyboard[1] & 0x08)) t &= ~0x02; |
| 254 | if (!(keyboard[0] & 0x08)) t &= ~0x01; |
| 255 | value &= t; |
| 246 | 256 | } |
| 247 | | if (!(via1_porta&0x04)) { |
| 248 | | UINT8 t=0xff; |
| 249 | | if (!(keyboard[7]&0x04)) t&=~0x80; |
| 250 | | if (!(keyboard[6]&0x04)) t&=~0x40; |
| 251 | | if (!(keyboard[5]&0x04)) t&=~0x20; |
| 252 | | if (!(keyboard[4]&0x04)) t&=~0x10; |
| 253 | | if (!(keyboard[3]&0x04)) t&=~0x08; |
| 254 | | if (!(keyboard[2]&0x04)) t&=~0x04; |
| 255 | | if (!(keyboard[1]&0x04)) t&=~0x02; |
| 256 | | if (!(keyboard[0]&0x04)) t&=~0x01; |
| 257 | | value &=t; |
| 257 | |
| 258 | if (!(via1_porta & 0x04)) |
| 259 | { |
| 260 | UINT8 t = 0xff; |
| 261 | if (!(keyboard[7] & 0x04)) t &= ~0x80; |
| 262 | if (!(keyboard[6] & 0x04)) t &= ~0x40; |
| 263 | if (!(keyboard[5] & 0x04)) t &= ~0x20; |
| 264 | if (!(keyboard[4] & 0x04)) t &= ~0x10; |
| 265 | if (!(keyboard[3] & 0x04)) t &= ~0x08; |
| 266 | if (!(keyboard[2] & 0x04)) t &= ~0x04; |
| 267 | if (!(keyboard[1] & 0x04)) t &= ~0x02; |
| 268 | if (!(keyboard[0] & 0x04)) t &= ~0x01; |
| 269 | value &= t; |
| 258 | 270 | } |
| 259 | | if (!(via1_porta&0x02)) { |
| 260 | | UINT8 t=0xff; |
| 261 | | if (!(keyboard[7]&0x02)) t&=~0x80; |
| 262 | | if (!(keyboard[6]&0x02)) t&=~0x40; |
| 263 | | if (!(keyboard[5]&0x02)) t&=~0x20; |
| 264 | | if (!(keyboard[4]&0x02)) t&=~0x10; |
| 265 | | if (!(keyboard[3]&0x02)) t&=~0x08; |
| 266 | | if (!(keyboard[2]&0x02)) t&=~0x04; |
| 267 | | if (!(keyboard[1]&0x02)) t&=~0x02; |
| 268 | | if (!(keyboard[0]&0x02)) t&=~0x01; |
| 269 | | value &=t; |
| 271 | |
| 272 | if (!(via1_porta & 0x02)) |
| 273 | { |
| 274 | UINT8 t = 0xff; |
| 275 | if (!(keyboard[7] & 0x02)) t &= ~0x80; |
| 276 | if (!(keyboard[6] & 0x02)) t &= ~0x40; |
| 277 | if (!(keyboard[5] & 0x02)) t &= ~0x20; |
| 278 | if (!(keyboard[4] & 0x02)) t &= ~0x10; |
| 279 | if (!(keyboard[3] & 0x02)) t &= ~0x08; |
| 280 | if (!(keyboard[2] & 0x02)) t &= ~0x04; |
| 281 | if (!(keyboard[1] & 0x02)) t &= ~0x02; |
| 282 | if (!(keyboard[0] & 0x02)) t &= ~0x01; |
| 283 | value &= t; |
| 270 | 284 | } |
| 271 | | if (!(via1_porta&0x01)) { |
| 272 | | UINT8 t=0xff; |
| 273 | | if (!(keyboard[7]&0x01)) t&=~0x80; |
| 274 | | if (!(keyboard[6]&0x01)) t&=~0x40; |
| 275 | | if (!(keyboard[5]&0x01)) t&=~0x20; |
| 276 | | if (!(keyboard[4]&0x01)) t&=~0x10; |
| 277 | | if (!(keyboard[3]&0x01)) t&=~0x08; |
| 278 | | if (!(keyboard[2]&0x01)) t&=~0x04; |
| 279 | | if (!(keyboard[1]&0x01)) t&=~0x02; |
| 280 | | if (!(keyboard[0]&0x01)) t&=~0x01; |
| 281 | | value &=t; |
| 285 | |
| 286 | if (!(via1_porta & 0x01)) |
| 287 | { |
| 288 | UINT8 t = 0xff; |
| 289 | if (!(keyboard[7] & 0x01)) t &= ~0x80; |
| 290 | if (!(keyboard[6] & 0x01)) t &= ~0x40; |
| 291 | if (!(keyboard[5] & 0x01)) t &= ~0x20; |
| 292 | if (!(keyboard[4] & 0x01)) t &= ~0x10; |
| 293 | if (!(keyboard[3] & 0x01)) t &= ~0x08; |
| 294 | if (!(keyboard[2] & 0x01)) t &= ~0x04; |
| 295 | if (!(keyboard[1] & 0x01)) t &= ~0x02; |
| 296 | if (!(keyboard[0] & 0x01)) t &= ~0x01; |
| 297 | value &= t; |
| 282 | 298 | } |
| 283 | 299 | |
| 284 | 300 | value &= ~(input_port_read(machine, "JOY") & 0x80); |
| r3150 | r3151 | |
| 295 | 311 | static WRITE8_HANDLER( vc20_via1_write_portb ) |
| 296 | 312 | { |
| 297 | 313 | /* logerror("via1_write_portb: $%02X\n", data); */ |
| 298 | | // vc20_tape_write (data & 8 ? 1 : 0); // CASSETTE_RECORD not implemeted yet! |
| 314 | // vc20_tape_write (data & 0x08 ? 1 : 0); // CASSETTE_RECORD not implemeted yet! |
| 299 | 315 | via1_portb = data; |
| 300 | 316 | } |
| 301 | 317 | |
| r3150 | r3151 | |
| 323 | 339 | */ |
| 324 | 340 | static READ8_HANDLER( vc20_via4_read_portb ) |
| 325 | 341 | { |
| 326 | | UINT8 data=0; |
| 327 | | if (cbm_ieee_eoi_r()) data|=8; |
| 328 | | if (cbm_ieee_dav_r()) data|=0x10; |
| 329 | | if (cbm_ieee_nrfd_r()) data|=0x20; |
| 330 | | if (cbm_ieee_ndac_r()) data|=0x40; |
| 331 | | if (cbm_ieee_atn_r()) data|=0x80; |
| 342 | UINT8 data = 0; |
| 343 | if (cbm_ieee_eoi_r()) data |= 0x08; |
| 344 | if (cbm_ieee_dav_r()) data |= 0x10; |
| 345 | if (cbm_ieee_nrfd_r()) data |= 0x20; |
| 346 | if (cbm_ieee_ndac_r()) data |= 0x40; |
| 347 | if (cbm_ieee_atn_r()) data |= 0x80; |
| 332 | 348 | return data; |
| 333 | 349 | } |
| 334 | 350 | |
| 335 | 351 | static WRITE8_HANDLER( vc20_via4_write_portb ) |
| 336 | 352 | { |
| 337 | | cbm_ieee_dav_w(0,data&1); |
| 338 | | cbm_ieee_nrfd_w(0,data&2); |
| 339 | | cbm_ieee_ndac_w(0,data&4); |
| 353 | cbm_ieee_dav_w(0, data & 0x01); |
| 354 | cbm_ieee_nrfd_w(0, data & 0x02); |
| 355 | cbm_ieee_ndac_w(0, data & 0x04); |
| 340 | 356 | } |
| 341 | 357 | |
| 342 | 358 | /* ieee 6522 number 2 (via5) |
| r3150 | r3151 | |
| 348 | 364 | */ |
| 349 | 365 | static WRITE8_HANDLER( vc20_via5_write_porta ) |
| 350 | 366 | { |
| 351 | | cbm_ieee_data_w(0,data); |
| 367 | cbm_ieee_data_w(0, data); |
| 352 | 368 | } |
| 353 | 369 | |
| 354 | 370 | static READ8_HANDLER( vc20_via5_read_portb ) |
| r3150 | r3151 | |
| 358 | 374 | |
| 359 | 375 | static WRITE8_HANDLER( vc20_via5_write_ca2 ) |
| 360 | 376 | { |
| 361 | | cbm_ieee_atn_w(0,data); |
| 377 | cbm_ieee_atn_w(0, data); |
| 362 | 378 | } |
| 363 | 379 | |
| 364 | 380 | static READ8_HANDLER( vc20_via5_read_cb1 ) |
| r3150 | r3151 | |
| 368 | 384 | |
| 369 | 385 | static WRITE8_HANDLER( vc20_via5_write_cb2 ) |
| 370 | 386 | { |
| 371 | | cbm_ieee_eoi_w(0,data); |
| 387 | cbm_ieee_eoi_w(0, data); |
| 372 | 388 | } |
| 373 | 389 | |
| 374 | 390 | static const struct via6522_interface via0 = |
| r3150 | r3151 | |
| 452 | 468 | return program_read_byte(VIC6560ADDR2VC20ADDR (offset)); |
| 453 | 469 | } |
| 454 | 470 | |
| 455 | | WRITE8_HANDLER( vc20_0400_w ) { |
| 456 | | if ( mess_ram_size >= 8 * 1024 ) { |
| 471 | WRITE8_HANDLER( vc20_0400_w ) |
| 472 | { |
| 473 | if ( mess_ram_size >= 8 * 1024 ) |
| 474 | { |
| 457 | 475 | mess_ram[ 0x0400 + offset ] = data; |
| 458 | 476 | } |
| 459 | 477 | } |
| 460 | 478 | |
| 461 | | WRITE8_HANDLER( vc20_2000_w ) { |
| 462 | | if ( ( mess_ram_size >= 16 * 1024 ) && vc20_rom_2000 == NULL ) { |
| 479 | WRITE8_HANDLER( vc20_2000_w ) |
| 480 | { |
| 481 | if ( ( mess_ram_size >= 16 * 1024 ) && vc20_rom_2000 == NULL ) |
| 482 | { |
| 463 | 483 | mess_ram[ 0x2000 + offset ] = data; |
| 464 | 484 | } |
| 465 | 485 | } |
| 466 | 486 | |
| 467 | | WRITE8_HANDLER( vc20_4000_w ) { |
| 468 | | if ( ( mess_ram_size >= 24 * 1024 ) && vc20_rom_4000 == NULL ) { |
| 487 | WRITE8_HANDLER( vc20_4000_w ) |
| 488 | { |
| 489 | if ( ( mess_ram_size >= 24 * 1024 ) && vc20_rom_4000 == NULL ) |
| 490 | { |
| 469 | 491 | mess_ram[ 0x4000 + offset ] = data; |
| 470 | 492 | } |
| 471 | 493 | } |
| 472 | 494 | |
| 473 | | WRITE8_HANDLER( vc20_6000_w ) { |
| 474 | | if ( ( mess_ram_size >= 32 * 1024 ) && vc20_rom_6000 == NULL ) { |
| 495 | WRITE8_HANDLER( vc20_6000_w ) |
| 496 | { |
| 497 | if ( ( mess_ram_size >= 32 * 1024 ) && vc20_rom_6000 == NULL ) |
| 498 | { |
| 475 | 499 | mess_ram[ 0x6000 + offset ] = data; |
| 476 | 500 | } |
| 477 | 501 | } |
| r3150 | r3151 | |
| 479 | 503 | |
| 480 | 504 | static void vc20_memory_init(running_machine *machine) |
| 481 | 505 | { |
| 482 | | static int inited=0; |
| 506 | static int inited = 0; |
| 483 | 507 | UINT8 *memory = memory_region (machine, "main"); |
| 484 | 508 | |
| 485 | 509 | if (inited) return; |
| r3150 | r3151 | |
| 489 | 513 | 2114 1kbx4 ram at non used color ram area 0x9400 */ |
| 490 | 514 | |
| 491 | 515 | memset(memory, 0, 0x400); |
| 492 | | memset(memory+0x1000, 0, 0x1000); |
| 516 | memset(memory + 0x1000, 0, 0x1000); |
| 493 | 517 | |
| 494 | | memory[0x288]=0xff;// makes ae's graphics look correctly |
| 495 | | memory[0xd]=0xff; // for moneywars |
| 496 | | memory[0x1046]=0xff; // for jelly monsters, cosmic cruncher; |
| 518 | memory[0x288] = 0xff; // makes ae's graphics look correctly |
| 519 | memory[0xd] = 0xff; // for moneywars |
| 520 | memory[0x1046] = 0xff; // for jelly monsters, cosmic cruncher; |
| 497 | 521 | |
| 498 | 522 | #if 0 |
| 499 | 523 | /* 2114 poweron ? 64 x 0xff, 64x 0, and so on */ |
| 500 | 524 | for (i = 0; i < 0x400; i += 0x40) |
| 501 | 525 | { |
| 502 | 526 | memset (memory + i, i & 0x40 ? 0 : 0xff, 0x40); |
| 503 | | memset (memory+0x9400 + i, 0xf0 | (i & 0x40 ? 0 : 0xf), 0x40); |
| 527 | memset (memory + 0x9400 + i, 0xf0 | (i & 0x40 ? 0 : 0xf), 0x40); |
| 504 | 528 | } |
| 505 | 529 | // this would be the straight forward memory init for |
| 506 | 530 | // non cost reduced vic20 (2114 rams) |
| 507 | | for (i=0x1000;i<0x2000;i+=0x40) memset(memory+i,i&0x40?0:0xff,0x40); |
| 531 | for (i = 0x1000; i < 0x2000; i += 0x40) |
| 532 | memset(memory + i, i & 0x40 ? 0 : 0xff, 0x40); |
| 508 | 533 | #endif |
| 509 | 534 | |
| 510 | 535 | /* clears ieee cartrige rom */ |
| 511 | 536 | /* memset (memory + 0xa000, 0xff, 0x2000); */ |
| 512 | 537 | |
| 513 | | inited=1; |
| 538 | inited = 1; |
| 514 | 539 | } |
| 515 | 540 | |
| 516 | 541 | |
| 517 | | TIMER_CALLBACK( vc20_tape_timer ) |
| 542 | static TIMER_CALLBACK( vic20_tape_timer ) |
| 518 | 543 | { |
| 519 | 544 | UINT8 data = (cassette_input(image_from_devtype_and_index(IO_CASSETTE, 0)) > +0.0) ? 1 : 0; |
| 520 | 545 | via_1_ca1_w(machine, 0, data); |
| r3150 | r3151 | |
| 527 | 552 | #endif |
| 528 | 553 | vc20_memory_init(machine); |
| 529 | 554 | |
| 530 | | datasette_timer = timer_alloc(vc20_tape_timer, NULL); |
| 555 | datasette_timer = timer_alloc(vic20_tape_timer, NULL); |
| 531 | 556 | |
| 532 | 557 | #ifdef VC1541 |
| 533 | 558 | vc1541_config (0, 0, &vc1541); |
| r3150 | r3151 | |
| 535 | 560 | via_config (0, &via0); |
| 536 | 561 | via_config (1, &via1); |
| 537 | 562 | |
| 538 | | /* Set up memory banks */ |
| 539 | | memory_set_bankptr( 1, ( ( mess_ram_size >= 8 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x0400 ); |
| 540 | | memory_set_bankptr( 2, vc20_rom_2000 ? vc20_rom_2000 : ( ( ( mess_ram_size >= 16 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x2000 ) ); |
| 541 | | memory_set_bankptr( 3, vc20_rom_4000 ? vc20_rom_4000 : ( ( ( mess_ram_size >= 24 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x4000 ) ); |
| 542 | | memory_set_bankptr( 4, vc20_rom_6000 ? vc20_rom_6000 : ( ( ( mess_ram_size >= 32 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x6000 ) ); |
| 543 | | memory_set_bankptr( 5, vc20_rom_a000 ? vc20_rom_a000 : ( memory_region(machine, "main") + 0xa000 ) ); |
| 544 | 563 | } |
| 545 | 564 | |
| 546 | 565 | |
| r3150 | r3151 | |
| 558 | 577 | |
| 559 | 578 | DRIVER_INIT( vic1001 ) |
| 560 | 579 | { |
| 561 | | DRIVER_INIT_CALL(vic20); |
| 580 | DRIVER_INIT_CALL( vic20 ); |
| 562 | 581 | } |
| 563 | 582 | |
| 564 | 583 | DRIVER_INIT( vic20i ) |
| 565 | 584 | { |
| 566 | | ieee=1; |
| 585 | ieee = 1; |
| 567 | 586 | vc20_common_driver_init (machine); |
| 568 | 587 | vic6560_init (vic6560_dma_read, vic6560_dma_read_color); |
| 569 | 588 | via_config (4, &via4); |
| r3150 | r3151 | |
| 571 | 590 | cbm_ieee_open(); |
| 572 | 591 | } |
| 573 | 592 | |
| 574 | | MACHINE_RESET( vc20 ) |
| 593 | MACHINE_RESET( vic20 ) |
| 575 | 594 | { |
| 576 | 595 | cbm_serial_reset_write (0); |
| 577 | 596 | #ifdef VC1541 |
| 578 | 597 | vc1541_reset (); |
| 579 | 598 | #endif |
| 580 | | if (ieee) { |
| 599 | |
| 600 | if (ieee) |
| 601 | { |
| 581 | 602 | cbm_drive_0_config (IEEE, 8); |
| 582 | 603 | cbm_drive_1_config (IEEE, 9); |
| 583 | | } else { |
| 604 | } |
| 605 | else |
| 606 | { |
| 584 | 607 | cbm_drive_0_config (SERIAL, 8); |
| 585 | 608 | cbm_drive_1_config (SERIAL, 9); |
| 586 | 609 | } |
| 610 | |
| 587 | 611 | via_reset (); |
| 588 | | via_0_ca1_w(machine, 0, vc20_via0_read_ca1(machine, 0) ); |
| 612 | via_0_ca1_w(machine, 0, vc20_via0_read_ca1(machine, 0)); |
| 613 | |
| 614 | /* Set up memory banks */ |
| 615 | memory_set_bankptr( 1, ( ( mess_ram_size >= 8 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x0400 ); |
| 616 | memory_set_bankptr( 2, vc20_rom_2000 ? vc20_rom_2000 : ( ( ( mess_ram_size >= 16 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x2000 ) ); |
| 617 | memory_set_bankptr( 3, vc20_rom_4000 ? vc20_rom_4000 : ( ( ( mess_ram_size >= 24 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x4000 ) ); |
| 618 | memory_set_bankptr( 4, vc20_rom_6000 ? vc20_rom_6000 : ( ( ( mess_ram_size >= 32 * 1024 ) ? mess_ram : memory_region(machine, "main") ) + 0x6000 ) ); |
| 619 | memory_set_bankptr( 5, vc20_rom_a000 ? vc20_rom_a000 : ( memory_region(machine, "main") + 0xa000 ) ); |
| 589 | 620 | } |
| 590 | 621 | |
| 591 | | static int vc20_rom_id(const device_config *image) |
| 622 | |
| 623 | INTERRUPT_GEN( vic20_frame_interrupt ) |
| 592 | 624 | { |
| 593 | | static const unsigned char magic[] = |
| 594 | | {0x41, 0x30, 0x20, 0xc3, 0xc2, 0xcd}; /* A0 CBM at 0xa004 (module offset 4) */ |
| 595 | | unsigned char buffer[sizeof (magic)]; |
| 596 | | const char *cp; |
| 597 | | int retval; |
| 625 | via_0_ca1_w(machine, 0, vc20_via0_read_ca1 (machine, 0)); |
| 626 | keyboard[0] = input_port_read(machine, "ROW0"); |
| 627 | keyboard[1] = input_port_read(machine, "ROW1"); |
| 628 | keyboard[2] = input_port_read(machine, "ROW2"); |
| 629 | keyboard[3] = input_port_read(machine, "ROW3"); |
| 630 | keyboard[4] = input_port_read(machine, "ROW4"); |
| 631 | keyboard[5] = input_port_read(machine, "ROW5"); |
| 632 | keyboard[6] = input_port_read(machine, "ROW6"); |
| 633 | keyboard[7] = input_port_read(machine, "ROW7"); |
| 598 | 634 | |
| 599 | | logerror("vc20_rom_id %s\n", image_filename(image)); |
| 635 | set_led_status (1, input_port_read(machine, "SPECIAL") & 0x01 ? 1 : 0); /*KB_CAPSLOCK_FLAG */ |
| 636 | } |
| 600 | 637 | |
| 601 | | retval = 0; |
| 602 | 638 | |
| 603 | | image_fseek (image, 4, SEEK_SET); |
| 604 | | image_fread (image, buffer, sizeof (magic)); |
| 639 | /*********************************************** |
| 605 | 640 | |
| 606 | | if (!memcmp (buffer, magic, sizeof (magic))) |
| 607 | | retval = 1; |
| 641 | VIC20 Cartridges |
| 608 | 642 | |
| 609 | | cp = image_filetype(image); |
| 610 | | if (cp) |
| 611 | | { |
| 612 | | if ((mame_stricmp (cp, "a0") == 0) |
| 613 | | || (mame_stricmp (cp, "20") == 0) |
| 614 | | || (mame_stricmp (cp, "40") == 0) |
| 615 | | || (mame_stricmp (cp, "60") == 0) |
| 616 | | || (mame_stricmp (cp, "bin") == 0) |
| 617 | | || (mame_stricmp (cp, "rom") == 0) |
| 618 | | || (mame_stricmp (cp, "prg") == 0)) |
| 619 | | retval = 1; |
| 620 | | } |
| 643 | ***********************************************/ |
| 621 | 644 | |
| 622 | | if (retval) |
| 623 | | logerror("rom %s recognized\n", image_filename(image)); |
| 624 | | else |
| 625 | | logerror("rom %s not recognized\n", image_filename(image)); |
| 626 | | |
| 627 | | return retval; |
| 628 | | } |
| 629 | | |
| 630 | | DEVICE_START(vc20_rom) |
| 645 | DEVICE_START(vic20_cart) |
| 631 | 646 | { |
| 632 | 647 | vc20_memory_init(device->machine); |
| 633 | 648 | vc20_rom_2000 = NULL; |
| r3150 | r3151 | |
| 636 | 651 | vc20_rom_a000 = NULL; |
| 637 | 652 | } |
| 638 | 653 | |
| 639 | | DEVICE_IMAGE_LOAD(vc20_rom) |
| 654 | DEVICE_IMAGE_LOAD(vic20_cart) |
| 640 | 655 | { |
| 641 | | int size, read_; |
| 642 | | const char *cp; |
| 643 | | int addr = 0; |
| 656 | int size = image_length(image), test; |
| 657 | const char *filetype; |
| 658 | const char *tag; |
| 659 | int address = 0; |
| 644 | 660 | |
| 645 | | if (!vc20_rom_id(image)) |
| 646 | | return 1; |
| 647 | | image_fseek(image, 0, SEEK_SET); |
| 661 | static const unsigned char magic[] = {0x41, 0x30, 0x20, 0xc3, 0xc2, 0xcd}; /* A0 CBM at 0xa004 (module offset 4) */ |
| 662 | unsigned char buffer[sizeof (magic)]; |
| 648 | 663 | |
| 649 | | size = image_length(image); |
| 664 | image_fseek (image, 4, SEEK_SET); |
| 665 | image_fread (image, buffer, sizeof (magic)); |
| 666 | image_fseek (image, 0, SEEK_SET); |
| 650 | 667 | |
| 651 | | cp = image_filetype(image); |
| 652 | | if (cp) |
| 668 | /* Check if our cart has the magic string, and set its loading address according to its size */ |
| 669 | if (!memcmp (buffer, magic, sizeof (magic))) |
| 670 | address = (size == 0x4000) ? 0x4000 : 0xa000; |
| 671 | |
| 672 | /* Give a loading address to non .bin / non .rom carts as well */ |
| 673 | /* We support .a0, .20, .40 and .60 files */ |
| 674 | filetype = image_filetype(image); |
| 675 | |
| 676 | if (!mame_stricmp (filetype, "a0")) |
| 677 | address = 0xa000; |
| 678 | |
| 679 | else if (!mame_stricmp (filetype, "20")) |
| 680 | address = 0x2000; |
| 681 | |
| 682 | else if (!mame_stricmp (filetype, "40")) |
| 683 | address = 0x4000; |
| 684 | |
| 685 | else if (!mame_stricmp (filetype, "60")) |
| 686 | address = 0x6000; |
| 687 | |
| 688 | /* As a last try, give a reasonable loading address also to .bin/.rom without the magic string */ |
| 689 | else if (!address) |
| 653 | 690 | { |
| 654 | | if ((cp[0] != 0) && (cp[1] == '0') && (cp[2] == 0)) |
| 655 | | { |
| 656 | | switch (toupper (cp[0])) |
| 691 | logerror("Cart %s does not contain the magic string: it may be loaded at the wrong memory address!\n", image_filename(image)); |
| 692 | address = (size == 0x4000) ? 0x4000 : 0xa000; |
| 693 | } |
| 694 | |
| 695 | /* Decide the memory region we will load the cart in, to avoid problems when multiple carts need to be loaded */ |
| 696 | tag = (image_index_in_device(image)) ? "user2" : "user1"; |
| 697 | |
| 698 | logerror("Loading cart %s at %.4x size:%.4x\n", image_filename(image), address, size); |
| 699 | |
| 700 | /* Finally load the cart */ |
| 701 | test = image_fread(image, memory_region_alloc( image->machine, tag, ( size & 0x1FFF ) ? ( size + 0x2000 ) : size, 0 ), size); |
| 702 | |
| 703 | if (test != size) |
| 704 | return INIT_FAIL; |
| 705 | |
| 706 | /* Perform banking for the cartridge, based on the prescribed address */ |
| 707 | switch( address ) |
| 708 | { |
| 709 | case 0x2000: |
| 710 | vc20_rom_2000 = memory_region(image->machine, tag); |
| 711 | break; |
| 712 | |
| 713 | case 0x4000: |
| 714 | vc20_rom_4000 = memory_region(image->machine, tag); |
| 715 | if ( size > 0x2000 ) |
| 657 | 716 | { |
| 658 | | case 'A': |
| 659 | | addr = 0xa000; |
| 660 | | break; |
| 661 | | case '2': |
| 662 | | addr = 0x2000; |
| 663 | | break; |
| 664 | | case '4': |
| 665 | | addr = 0x4000; |
| 666 | | break; |
| 667 | | case '6': |
| 668 | | addr = 0x6000; |
| 669 | | break; |
| 717 | vc20_rom_6000 = memory_region(image->machine, tag) + 0x2000; |
| 670 | 718 | } |
| 671 | | } |
| 672 | | else |
| 673 | | { |
| 674 | | if (mame_stricmp (cp, "prg") == 0) |
| 675 | | { |
| 676 | | unsigned short in; |
| 719 | break; |
| 677 | 720 | |
| 678 | | image_fread(image, &in, 2); |
| 679 | | in = LITTLE_ENDIANIZE_INT16(in); |
| 680 | | logerror("rom prg %.4x\n", in); |
| 681 | | addr = in; |
| 682 | | size -= 2; |
| 683 | | } |
| 684 | | } |
| 721 | case 0x6000: |
| 722 | vc20_rom_6000 = memory_region(image->machine, tag); |
| 723 | break; |
| 724 | |
| 725 | case 0xa000: |
| 726 | vc20_rom_a000 = memory_region(image->machine, tag); |
| 727 | break; |
| 685 | 728 | } |
| 686 | | if (addr == 0) |
| 687 | | { |
| 688 | | if (size == 0x4000) |
| 689 | | { /* I think rom at 0x4000 */ |
| 690 | | addr = 0x4000; |
| 691 | | } |
| 692 | | else |
| 693 | | { |
| 694 | | addr = 0xa000; |
| 695 | | } |
| 696 | | } |
| 697 | 729 | |
| 698 | | logerror("loading rom %s at %.4x size:%.4x\n",image_filename(image), addr, size); |
| 699 | | read_ = image_fread(image, memory_region_alloc( image->machine, "user1", ( size & 0x1FFF ) ? ( size + 0x2000 ) : size, 0 ), size); |
| 700 | | if (read_ != size) |
| 701 | | return 1; |
| 702 | | |
| 703 | | /* Perform banking for the cartridge */ |
| 704 | | switch( addr ) { |
| 705 | | case 0x2000: |
| 706 | | vc20_rom_2000 = memory_region(image->machine, "user1" ); |
| 707 | | break; |
| 708 | | case 0x4000: |
| 709 | | vc20_rom_4000 = memory_region(image->machine, "user1" ); |
| 710 | | if ( size > 0x2000 ) { |
| 711 | | vc20_rom_6000 = memory_region(image->machine, "user1" ) + 0x2000; |
| 712 | | } |
| 713 | | break; |
| 714 | | case 0x6000: |
| 715 | | vc20_rom_6000 = memory_region(image->machine, "user1" ); |
| 716 | | break; |
| 717 | | case 0xa000: |
| 718 | | vc20_rom_a000 = memory_region(image->machine, "user1" ); |
| 719 | | break; |
| 720 | | } |
| 721 | | return 0; |
| 730 | return INIT_PASS; |
| 722 | 731 | } |
| 723 | 732 | |
| 724 | | INTERRUPT_GEN( vc20_frame_interrupt ) |
| 733 | |
| 734 | void vic20_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 725 | 735 | { |
| 726 | | via_0_ca1_w(machine, 0, vc20_via0_read_ca1 (machine, 0)); |
| 727 | | keyboard[0] = input_port_read(machine, "ROW0"); |
| 728 | | keyboard[1] = input_port_read(machine, "ROW1"); |
| 729 | | keyboard[2] = input_port_read(machine, "ROW2"); |
| 730 | | keyboard[3] = input_port_read(machine, "ROW3"); |
| 731 | | keyboard[4] = input_port_read(machine, "ROW4"); |
| 732 | | keyboard[5] = input_port_read(machine, "ROW5"); |
| 733 | | keyboard[6] = input_port_read(machine, "ROW6"); |
| 734 | | keyboard[7] = input_port_read(machine, "ROW7"); |
| 736 | switch(state) |
| 737 | { |
| 738 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 739 | case MESS_DEVINFO_INT_COUNT: info->i = 2; break; |
| 735 | 740 | |
| 736 | | set_led_status (1, input_port_read(machine, "SPECIAL") & 0x01 ? 1 : 0); /*KB_CAPSLOCK_FLAG */ |
| 741 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 742 | case MESS_DEVINFO_PTR_START: info->start = DEVICE_START_NAME(vic20_cart); break; |
| 743 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(vic20_cart); break; |
| 744 | |
| 745 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 746 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "rom,bin,a0,20,40,60"); break; |
| 747 | |
| 748 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 749 | } |
| 737 | 750 | } |
src/mess/machine/c64.c
| r3150 | r3151 | |
| 18 | 18 | |
| 19 | 19 | TODO: |
| 20 | 20 | * write to tape |
| 21 | | * FFW & REW |
| 22 | 21 | * support for .tap files |
| 23 | | * fix implementation for other CBM machines |
| 24 | 22 | */ |
| 25 | 23 | |
| 26 | 24 | #include "driver.h" |
| r3150 | r3151 | |
| 42 | 40 | #include "includes/c128.h" /* we need c128_bankswitch_64 in MACHINE_START */ |
| 43 | 41 | |
| 44 | 42 | #include "devices/cassette.h" |
| 43 | #include "devices/cartslot.h" |
| 45 | 44 | |
| 46 | 45 | unsigned char c65_keyline = { 0xff }; |
| 47 | 46 | UINT8 c65_6511_port=0xff; |
| r3150 | r3151 | |
| 67 | 66 | UINT8 *c64_basic; |
| 68 | 67 | UINT8 *c64_kernal; |
| 69 | 68 | UINT8 *c64_chargen; |
| 70 | | UINT8 *c64_roml=0; |
| 71 | | UINT8 *c64_romh=0; |
| 69 | UINT8 *c64_roml = 0; |
| 70 | UINT8 *c64_romh = 0; |
| 72 | 71 | static UINT8 *c64_io_mirror = NULL; |
| 73 | 72 | |
| 74 | 73 | static UINT8 c64_port_data; |
| 75 | 74 | |
| 76 | | static UINT8 *roml=0, *romh=0; |
| 75 | static UINT8 *roml = 0, *romh = 0; |
| 77 | 76 | static int ultimax = 0; |
| 78 | 77 | int c64_tape_on = 1; |
| 79 | 78 | static int c64_cia1_on = 1; |
| 80 | | static UINT8 cartridge = 0; |
| 81 | 79 | static int c64_io_enabled = 0; |
| 82 | 80 | |
| 83 | | static enum |
| 84 | | { |
| 85 | | CartridgeAuto = 0, |
| 86 | | CartridgeUltimax, |
| 87 | | CartridgeC64 |
| 88 | | } |
| 89 | | cartridgetype = CartridgeAuto; |
| 90 | 81 | |
| 91 | 82 | static UINT8 serial_clock, serial_data, serial_atn; |
| 92 | 83 | static UINT8 vicirq = 0; |
| r3150 | r3151 | |
| 110 | 101 | { |
| 111 | 102 | if (is_c128(machine)) |
| 112 | 103 | { |
| 113 | | if (cpu_getactivecpu()==0) |
| 104 | if (cpu_getactivecpu() == 0) |
| 114 | 105 | { |
| 115 | 106 | /* z80 */ |
| 116 | 107 | cpunum_set_input_line(machine, 0, INPUT_LINE_NMI, (input_port_read(machine, "SPECIAL") & 0x80) || cia1irq); |
| r3150 | r3151 | |
| 152 | 143 | UINT8 value = 0xff; |
| 153 | 144 | UINT8 cia0portb = cia_get_output_b(0); |
| 154 | 145 | |
| 155 | | if (!(cia0portb&0x80)) |
| 146 | if (!(cia0portb & 0x80)) |
| 156 | 147 | { |
| 157 | | UINT8 t=0xff; |
| 158 | | if (!(c64_keyline[7]&0x80)) t&=~0x80; |
| 159 | | if (!(c64_keyline[6]&0x80)) t&=~0x40; |
| 160 | | if (!(c64_keyline[5]&0x80)) t&=~0x20; |
| 161 | | if (!(c64_keyline[4]&0x80)) t&=~0x10; |
| 162 | | if (!(c64_keyline[3]&0x80)) t&=~0x08; |
| 163 | | if (!(c64_keyline[2]&0x80)) t&=~0x04; |
| 164 | | if (!(c64_keyline[1]&0x80)) t&=~0x02; |
| 165 | | if (!(c64_keyline[0]&0x80)) t&=~0x01; |
| 166 | | value &=t; |
| 148 | UINT8 t = 0xff; |
| 149 | if (!(c64_keyline[7] & 0x80)) t &= ~0x80; |
| 150 | if (!(c64_keyline[6] & 0x80)) t &= ~0x40; |
| 151 | if (!(c64_keyline[5] & 0x80)) t &= ~0x20; |
| 152 | if (!(c64_keyline[4] & 0x80)) t &= ~0x10; |
| 153 | if (!(c64_keyline[3] & 0x80)) t &= ~0x08; |
| 154 | if (!(c64_keyline[2] & 0x80)) t &= ~0x04; |
| 155 | if (!(c64_keyline[1] & 0x80)) t &= ~0x02; |
| 156 | if (!(c64_keyline[0] & 0x80)) t &= ~0x01; |
| 157 | value &= t; |
| 167 | 158 | } |
| 168 | | if (!(cia0portb&0x40)) |
| 159 | |
| 160 | if (!(cia0portb & 0x40)) |
| 169 | 161 | { |
| 170 | | UINT8 t=0xff; |
| 171 | | if (!(c64_keyline[7]&0x40)) t&=~0x80; |
| 172 | | if (!(c64_keyline[6]&0x40)) t&=~0x40; |
| 173 | | if (!(c64_keyline[5]&0x40)) t&=~0x20; |
| 174 | | if (!(c64_keyline[4]&0x40)) t&=~0x10; |
| 175 | | if (!(c64_keyline[3]&0x40)) t&=~0x08; |
| 176 | | if (!(c64_keyline[2]&0x40)) t&=~0x04; |
| 177 | | if (!(c64_keyline[1]&0x40)) t&=~0x02; |
| 178 | | if (!(c64_keyline[0]&0x40)) t&=~0x01; |
| 179 | | value &=t; |
| 162 | UINT8 t = 0xff; |
| 163 | if (!(c64_keyline[7] & 0x40)) t &= ~0x80; |
| 164 | if (!(c64_keyline[6] & 0x40)) t &= ~0x40; |
| 165 | if (!(c64_keyline[5] & 0x40)) t &= ~0x20; |
| 166 | if (!(c64_keyline[4] & 0x40)) t &= ~0x10; |
| 167 | if (!(c64_keyline[3] & 0x40)) t &= ~0x08; |
| 168 | if (!(c64_keyline[2] & 0x40)) t &= ~0x04; |
| 169 | if (!(c64_keyline[1] & 0x40)) t &= ~0x02; |
| 170 | if (!(c64_keyline[0] & 0x40)) t &= ~0x01; |
| 171 | value &= t; |
| 180 | 172 | } |
| 181 | | if (!(cia0portb&0x20)) |
| 173 | |
| 174 | if (!(cia0portb & 0x20)) |
| 182 | 175 | { |
| 183 | | UINT8 t=0xff; |
| 184 | | if (!(c64_keyline[7]&0x20)) t&=~0x80; |
| 185 | | if (!(c64_keyline[6]&0x20)) t&=~0x40; |
| 186 | | if (!(c64_keyline[5]&0x20)) t&=~0x20; |
| 187 | | if (!(c64_keyline[4]&0x20)) t&=~0x10; |
| 188 | | if (!(c64_keyline[3]&0x20)) t&=~0x08; |
| 189 | | if (!(c64_keyline[2]&0x20)) t&=~0x04; |
| 190 | | if (!(c64_keyline[1]&0x20)) t&=~0x02; |
| 191 | | if (!(c64_keyline[0]&0x20)) t&=~0x01; |
| 192 | | value &=t; |
| 176 | UINT8 t = 0xff; |
| 177 | if (!(c64_keyline[7] & 0x20)) t &= ~0x80; |
| 178 | if (!(c64_keyline[6] & 0x20)) t &= ~0x40; |
| 179 | if (!(c64_keyline[5] & 0x20)) t &= ~0x20; |
| 180 | if (!(c64_keyline[4] & 0x20)) t &= ~0x10; |
| 181 | if (!(c64_keyline[3] & 0x20)) t &= ~0x08; |
| 182 | if (!(c64_keyline[2] & 0x20)) t &= ~0x04; |
| 183 | if (!(c64_keyline[1] & 0x20)) t &= ~0x02; |
| 184 | if (!(c64_keyline[0] & 0x20)) t &= ~0x01; |
| 185 | value &= t; |
| 193 | 186 | } |
| 194 | | if (!(cia0portb&0x10)) |
| 187 | |
| 188 | if (!(cia0portb & 0x10)) |
| 195 | 189 | { |
| 196 | | UINT8 t=0xff; |
| 197 | | if (!(c64_keyline[7]&0x10)) t&=~0x80; |
| 198 | | if (!(c64_keyline[6]&0x10)) t&=~0x40; |
| 199 | | if (!(c64_keyline[5]&0x10)) t&=~0x20; |
| 200 | | if (!(c64_keyline[4]&0x10)) t&=~0x10; |
| 201 | | if (!(c64_keyline[3]&0x10)) t&=~0x08; |
| 202 | | if (!(c64_keyline[2]&0x10)) t&=~0x04; |
| 203 | | if (!(c64_keyline[1]&0x10)) t&=~0x02; |
| 204 | | if (!(c64_keyline[0]&0x10)) t&=~0x01; |
| 205 | | value &=t; |
| 190 | UINT8 t = 0xff; |
| 191 | if (!(c64_keyline[7] & 0x10)) t &= ~0x80; |
| 192 | if (!(c64_keyline[6] & 0x10)) t &= ~0x40; |
| 193 | if (!(c64_keyline[5] & 0x10)) t &= ~0x20; |
| 194 | if (!(c64_keyline[4] & 0x10)) t &= ~0x10; |
| 195 | if (!(c64_keyline[3] & 0x10)) t &= ~0x08; |
| 196 | if (!(c64_keyline[2] & 0x10)) t &= ~0x04; |
| 197 | if (!(c64_keyline[1] & 0x10)) t &= ~0x02; |
| 198 | if (!(c64_keyline[0] & 0x10)) t &= ~0x01; |
| 199 | value &= t; |
| 206 | 200 | } |
| 207 | | if (!(cia0portb&0x08)) |
| 201 | |
| 202 | if (!(cia0portb & 0x08)) |
| 208 | 203 | { |
| 209 | | UINT8 t=0xff; |
| 210 | | if (!(c64_keyline[7]&0x08)) t&=~0x80; |
| 211 | | if (!(c64_keyline[6]&0x08)) t&=~0x40; |
| 212 | | if (!(c64_keyline[5]&0x08)) t&=~0x20; |
| 213 | | if (!(c64_keyline[4]&0x08)) t&=~0x10; |
| 214 | | if (!(c64_keyline[3]&0x08)) t&=~0x08; |
| 215 | | if (!(c64_keyline[2]&0x08)) t&=~0x04; |
| 216 | | if (!(c64_keyline[1]&0x08)) t&=~0x02; |
| 217 | | if (!(c64_keyline[0]&0x08)) t&=~0x01; |
| 218 | | value &=t; |
| 204 | UINT8 t = 0xff; |
| 205 | if (!(c64_keyline[7] & 0x08)) t &= ~0x80; |
| 206 | if (!(c64_keyline[6] & 0x08)) t &= ~0x40; |
| 207 | if (!(c64_keyline[5] & 0x08)) t &= ~0x20; |
| 208 | if (!(c64_keyline[4] & 0x08)) t &= ~0x10; |
| 209 | if (!(c64_keyline[3] & 0x08)) t &= ~0x08; |
| 210 | if (!(c64_keyline[2] & 0x08)) t &= ~0x04; |
| 211 | if (!(c64_keyline[1] & 0x08)) t &= ~0x02; |
| 212 | if (!(c64_keyline[0] & 0x08)) t &= ~0x01; |
| 213 | value &= t; |
| 219 | 214 | } |
| 220 | | if (!(cia0portb&0x04)) |
| 215 | |
| 216 | if (!(cia0portb & 0x04)) |
| 221 | 217 | { |
| 222 | | UINT8 t=0xff; |
| 223 | | if (!(c64_keyline[7]&0x04)) t&=~0x80; |
| 224 | | if (!(c64_keyline[6]&0x04)) t&=~0x40; |
| 225 | | if (!(c64_keyline[5]&0x04)) t&=~0x20; |
| 226 | | if (!(c64_keyline[4]&0x04)) t&=~0x10; |
| 227 | | if (!(c64_keyline[3]&0x04)) t&=~0x08; |
| 228 | | if (!(c64_keyline[2]&0x04)) t&=~0x04; |
| 229 | | if (!(c64_keyline[1]&0x04)) t&=~0x02; |
| 230 | | if (!(c64_keyline[0]&0x04)) t&=~0x01; |
| 231 | | value &=t; |
| 218 | UINT8 t = 0xff; |
| 219 | if (!(c64_keyline[7] & 0x04)) t &= ~0x80; |
| 220 | if (!(c64_keyline[6] & 0x04)) t &= ~0x40; |
| 221 | if (!(c64_keyline[5] & 0x04)) t &= ~0x20; |
| 222 | if (!(c64_keyline[4] & 0x04)) t &= ~0x10; |
| 223 | if (!(c64_keyline[3] & 0x04)) t &= ~0x08; |
| 224 | if (!(c64_keyline[2] & 0x04)) t &= ~0x04; |
| 225 | if (!(c64_keyline[1] & 0x04)) t &= ~0x02; |
| 226 | if (!(c64_keyline[0] & 0x04)) t &= ~0x01; |
| 227 | value &= t; |
| 232 | 228 | } |
| 233 | | if (!(cia0portb&0x02)) |
| 229 | |
| 230 | if (!(cia0portb & 0x02)) |
| 234 | 231 | { |
| 235 | | UINT8 t=0xff; |
| 236 | | if (!(c64_keyline[7]&0x02)) t&=~0x80; |
| 237 | | if (!(c64_keyline[6]&0x02)) t&=~0x40; |
| 238 | | if (!(c64_keyline[5]&0x02)) t&=~0x20; |
| 239 | | if (!(c64_keyline[4]&0x02)) t&=~0x10; |
| 240 | | if (!(c64_keyline[3]&0x02)) t&=~0x08; |
| 241 | | if (!(c64_keyline[2]&0x02)) t&=~0x04; |
| 242 | | if (!(c64_keyline[1]&0x02)) t&=~0x02; |
| 243 | | if (!(c64_keyline[0]&0x02)) t&=~0x01; |
| 244 | | value &=t; |
| 232 | UINT8 t = 0xff; |
| 233 | if (!(c64_keyline[7] & 0x02)) t &= ~0x80; |
| 234 | if (!(c64_keyline[6] & 0x02)) t &= ~0x40; |
| 235 | if (!(c64_keyline[5] & 0x02)) t &= ~0x20; |
| 236 | if (!(c64_keyline[4] & 0x02)) t &= ~0x10; |
| 237 | if (!(c64_keyline[3] & 0x02)) t &= ~0x08; |
| 238 | if (!(c64_keyline[2] & 0x02)) t &= ~0x04; |
| 239 | if (!(c64_keyline[1] & 0x02)) t &= ~0x02; |
| 240 | if (!(c64_keyline[0] & 0x02)) t &= ~0x01; |
| 241 | value &= t; |
| 245 | 242 | } |
| 246 | | if (!(cia0portb&0x01)) |
| 243 | |
| 244 | if (!(cia0portb & 0x01)) |
| 247 | 245 | { |
| 248 | | UINT8 t=0xff; |
| 249 | | if (!(c64_keyline[7]&0x01)) t&=~0x80; |
| 250 | | if (!(c64_keyline[6]&0x01)) t&=~0x40; |
| 251 | | if (!(c64_keyline[5]&0x01)) t&=~0x20; |
| 252 | | if (!(c64_keyline[4]&0x01)) t&=~0x10; |
| 253 | | if (!(c64_keyline[3]&0x01)) t&=~0x08; |
| 254 | | if (!(c64_keyline[2]&0x01)) t&=~0x04; |
| 255 | | if (!(c64_keyline[1]&0x01)) t&=~0x02; |
| 256 | | if (!(c64_keyline[0]&0x01)) t&=~0x01; |
| 257 | | value &=t; |
| 246 | UINT8 t = 0xff; |
| 247 | if (!(c64_keyline[7] & 0x01)) t &= ~0x80; |
| 248 | if (!(c64_keyline[6] & 0x01)) t &= ~0x40; |
| 249 | if (!(c64_keyline[5] & 0x01)) t &= ~0x20; |
| 250 | if (!(c64_keyline[4] & 0x01)) t &= ~0x10; |
| 251 | if (!(c64_keyline[3] & 0x01)) t &= ~0x08; |
| 252 | if (!(c64_keyline[2] & 0x01)) t &= ~0x04; |
| 253 | if (!(c64_keyline[1] & 0x01)) t &= ~0x02; |
| 254 | if (!(c64_keyline[0] & 0x01)) t &= ~0x01; |
| 255 | value &= t; |
| 258 | 256 | } |
| 259 | 257 | |
| 260 | 258 | if ( input_port_read(Machine, "DSW0") & 0x0100 ) |
| r3150 | r3151 | |
| 295 | 293 | } |
| 296 | 294 | if (is_c65(Machine)) |
| 297 | 295 | { |
| 298 | | if (!(c65_6511_port&2)) |
| 299 | | value&=c65_keyline; |
| 296 | if (!(c65_6511_port & 0x02)) |
| 297 | value &= c65_keyline; |
| 300 | 298 | } |
| 301 | 299 | |
| 302 | 300 | return value; |
| r3150 | r3151 | |
| 316 | 314 | DBG_LOG (3, "mos6510", ("irq %s\n", level ? "start" : "end")); |
| 317 | 315 | if (is_c128(machine)) |
| 318 | 316 | { |
| 319 | | if (0&&(cpu_getactivecpu()==0)) |
| 317 | if (0 && (cpu_getactivecpu() == 0)) |
| 320 | 318 | { |
| 321 | 319 | cpunum_set_input_line(machine, 0, 0, level); |
| 322 | 320 | } |
| r3150 | r3151 | |
| 378 | 376 | |
| 379 | 377 | if (!serial_clock || !cbm_serial_clock_read ()) |
| 380 | 378 | value &= ~0x40; |
| 379 | |
| 381 | 380 | if (!serial_data || !cbm_serial_data_read ()) |
| 382 | 381 | value &= ~0x80; |
| 382 | |
| 383 | 383 | return value; |
| 384 | 384 | } |
| 385 | 385 | |
| r3150 | r3151 | |
| 389 | 389 | |
| 390 | 390 | cbm_serial_clock_write (serial_clock = !(data & 0x10)); |
| 391 | 391 | cbm_serial_data_write (serial_data = !(data & 0x20)); |
| 392 | | cbm_serial_atn_write (serial_atn = !(data & 8)); |
| 393 | | c64_vicaddr = c64_memory + helper[data & 3]; |
| 392 | cbm_serial_atn_write (serial_atn = !(data & 0x08)); |
| 393 | c64_vicaddr = c64_memory + helper[data & 0x03]; |
| 394 | 394 | if (is_c128(Machine)) |
| 395 | 395 | { |
| 396 | | c128_vicaddr = c64_memory + helper[data & 3] + c128_va1617; |
| 396 | c128_vicaddr = c64_memory + helper[data & 0x03] + c128_va1617; |
| 397 | 397 | } |
| 398 | 398 | } |
| 399 | 399 | |
| r3150 | r3151 | |
| 476 | 476 | { |
| 477 | 477 | if (offset < 0x400) |
| 478 | 478 | return vic2_port_r (machine, offset & 0x3ff); |
| 479 | |
| 479 | 480 | else if (offset < 0x800) |
| 480 | 481 | return sid6581_0_port_r (machine, offset & 0x3ff); |
| 482 | |
| 481 | 483 | else if (offset < 0xc00) |
| 482 | 484 | return c64_colorram[offset & 0x3ff]; |
| 485 | |
| 483 | 486 | else if (offset == 0xc00) |
| 484 | 487 | { |
| 485 | 488 | cia_set_port_mask_value(0, 0, input_port_read(machine, "DSW0") & 0x0100 ? c64_keyline[8] : c64_keyline[9] ); |
| 486 | 489 | return cia_0_r(machine, offset); |
| 487 | 490 | } |
| 491 | |
| 488 | 492 | else if (offset == 0xc01) |
| 489 | 493 | { |
| 490 | 494 | cia_set_port_mask_value(0, 1, input_port_read(machine, "DSW0") & 0x0100 ? c64_keyline[9] : c64_keyline[8] ); |
| 491 | 495 | return cia_0_r(machine, offset); |
| 492 | 496 | } |
| 497 | |
| 493 | 498 | else if (offset < 0xd00) |
| 494 | 499 | return cia_0_r(machine, offset); |
| 500 | |
| 495 | 501 | else if (c64_cia1_on && (offset < 0xe00)) |
| 496 | 502 | return cia_1_r(machine, offset); |
| 503 | |
| 497 | 504 | DBG_LOG (1, "io read", ("%.3x\n", offset)); |
| 505 | |
| 498 | 506 | return 0xff; |
| 499 | 507 | } |
| 500 | 508 | |
| r3150 | r3151 | |
| 636 | 644 | loram = (data & 1) ? 1 : 0; |
| 637 | 645 | hiram = (data & 2) ? 1 : 0; |
| 638 | 646 | charen = (data & 4) ? 1 : 0; |
| 647 | logerror("Bankswitch mode || charen, ultimax\n"); |
| 648 | logerror("%d, %d, %d, %d || %d, %d \n", loram, hiram, c64_game, c64_exrom, charen, ultimax_mode); |
| 639 | 649 | |
| 640 | 650 | if (ultimax_mode) |
| 641 | 651 | { |
| r3150 | r3151 | |
| 784 | 794 | running_machine *machine = Machine; |
| 785 | 795 | UINT8 data = c64_port_data; |
| 786 | 796 | |
| 787 | | if ((cassette_get_state(image_from_devtype_and_index(IO_CASSETTE, 0)) & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) |
| 788 | | data &= ~0x10; |
| 789 | | else |
| 790 | | data |= 0x10; |
| 797 | if (c64_tape_on) |
| 798 | { |
| 799 | if ((cassette_get_state(image_from_devtype_and_index(IO_CASSETTE, 0)) & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) |
| 800 | data &= ~0x10; |
| 801 | else |
| 802 | data |= 0x10; |
| 803 | } |
| 791 | 804 | |
| 792 | 805 | if (is_c65(machine)) |
| 793 | 806 | { |
| r3150 | r3151 | |
| 804 | 817 | |
| 805 | 818 | int c64_paddle_read (int which) |
| 806 | 819 | { |
| 807 | | int pot1=0xff, pot2=0xff, pot3=0xff, pot4=0xff, temp; |
| 820 | int pot1 = 0xff, pot2 = 0xff, pot3 = 0xff, pot4 = 0xff, temp; |
| 808 | 821 | UINT8 cia0porta = cia_get_output_a(0); |
| 822 | int controller = input_port_read(Machine, "DSW0") & 0x0e00; |
| 809 | 823 | |
| 810 | | if ((input_port_read(Machine, "DSW0") & 0x0e00 ) == 0x0400) /* Paddle_2 and Paddle_3 */ |
| 824 | if (which) |
| 811 | 825 | { |
| 812 | | if (which) |
| 813 | | pot4 = (input_port_read(Machine, "PADDLE3") & 0xff); |
| 814 | | else |
| 815 | | pot3 = (input_port_read(Machine, "PADDLE2") & 0xff); |
| 826 | switch (controller) |
| 827 | { |
| 828 | case 0x0400: |
| 829 | pot4 = (input_port_read(Machine, "PADDLE3") & 0xff); |
| 830 | break; |
| 831 | |
| 832 | case 0x0600: |
| 833 | if (input_port_read(Machine, "JOY1") & 0x20) /* Joy1 Button 2 */ |
| 834 | pot4 = 0x00; |
| 835 | break; |
| 836 | |
| 837 | case 0x0800: |
| 838 | pot4 = input_port_read(Machine, "TRACKY"); |
| 839 | break; |
| 840 | |
| 841 | case 0x4000: |
| 842 | pot2 = (input_port_read(Machine, "PADDLE1") & 0xff); |
| 843 | break; |
| 844 | |
| 845 | case 0x6000: |
| 846 | if (input_port_read(Machine, "JOY0") & 0x20) /* Joy0 Button 2 */ |
| 847 | pot1 = 0x00; |
| 848 | break; |
| 849 | |
| 850 | case 0x8000: |
| 851 | pot2 = input_port_read(Machine, "TRACKY"); |
| 852 | break; |
| 853 | |
| 854 | case 0xa000: |
| 855 | break; |
| 856 | |
| 857 | default: |
| 858 | logerror("Invalid Controller Setting %d\n", controller); |
| 859 | break; |
| 860 | } |
| 816 | 861 | } |
| 817 | | if (( (input_port_read(Machine, "DSW0") & 0x0e00) == 0x0600 ) && which) /* 2 Buttons Joystick_2 */ |
| 862 | else |
| 818 | 863 | { |
| 819 | | if (input_port_read(Machine, "JOY1") & 0x20 ) |
| 820 | | pot4 = 0x00; |
| 864 | switch (controller) |
| 865 | { |
| 866 | case 0x0400: |
| 867 | pot3 = (input_port_read(Machine, "PADDLE2") & 0xff); |
| 868 | break; |
| 869 | |
| 870 | case 0x0800: |
| 871 | pot3 = input_port_read(Machine, "TRACKX"); |
| 872 | break; |
| 873 | |
| 874 | case 0x4000: |
| 875 | pot1 = (input_port_read(Machine, "PADDLE0") & 0xff); |
| 876 | break; |
| 877 | |
| 878 | case 0x8000: |
| 879 | pot1 = input_port_read(Machine, "TRACKX"); |
| 880 | break; |
| 881 | |
| 882 | case 0x0600: |
| 883 | case 0x6000: |
| 884 | case 0xa000: |
| 885 | break; |
| 886 | |
| 887 | default: |
| 888 | logerror("Invalid Controller Setting %d\n", controller); |
| 889 | break; |
| 890 | } |
| 821 | 891 | } |
| 822 | | if ( (input_port_read(Machine, "DSW0") & 0x0e00) == 0x0800 ) /* Mouse_2 */ |
| 892 | |
| 893 | if (input_port_read(Machine, "DSW0") & 0x0100) /* Swap */ |
| 823 | 894 | { |
| 824 | | if (which) |
| 825 | | pot4 = input_port_read(Machine, "TRACKY"); |
| 826 | | else |
| 827 | | pot3 = input_port_read(Machine, "TRACKX"); |
| 828 | | } |
| 829 | | if ((input_port_read(Machine, "DSW0") & 0xe000 ) == 0x4000) /* Paddle_0 & Paddle_1 */ |
| 830 | | { |
| 831 | | if (which) |
| 832 | | pot2 = (input_port_read(Machine, "PADDLE1") & 0xff); |
| 833 | | else |
| 834 | | pot1 = (input_port_read(Machine, "PADDLE0") & 0xff); |
| 835 | | } |
| 836 | | if (( (input_port_read(Machine, "DSW0") & 0xe000) == 0x6000 ) && which) /* 2 Buttons Joystick_1 */ |
| 837 | | { |
| 838 | | if (input_port_read(Machine, "JOY0") & 0x20 ) |
| 839 | | pot1 = 0x00; |
| 840 | | } |
| 841 | | if (( input_port_read(Machine, "DSW0") & 0xe000 ) == 0x8000 ) /* Mouse_1 */ |
| 842 | | { |
| 843 | | if (which) |
| 844 | | pot2 = input_port_read(Machine, "TRACKY"); |
| 845 | | else |
| 846 | | pot1 = input_port_read(Machine, "TRACKX"); |
| 847 | | } |
| 848 | | if (input_port_read(Machine, "DSW0") & 0x0100) /* Swap */ |
| 849 | | { |
| 850 | 895 | temp = pot1; pot1 = pot2; pot2 = pot1; |
| 851 | 896 | temp = pot3; pot3 = pot4; pot4 = pot3; |
| 852 | 897 | } |
| 853 | | switch (cia0porta & 0xc0) { |
| 898 | |
| 899 | switch (cia0porta & 0xc0) |
| 900 | { |
| 854 | 901 | case 0x40: |
| 855 | | if (which) return pot2; |
| 856 | | return pot1; |
| 902 | return which ? pot2 : pot1; |
| 903 | |
| 857 | 904 | case 0x80: |
| 858 | | if (which) return pot4; |
| 859 | | return pot3; |
| 905 | return which ? pot4 : pot3; |
| 906 | |
| 860 | 907 | default: |
| 861 | 908 | return 0; |
| 862 | 909 | } |
| r3150 | r3151 | |
| 877 | 924 | * a15 and a14 portlines |
| 878 | 925 | * 0x1000-0x1fff, 0x9000-0x9fff char rom |
| 879 | 926 | */ |
| 880 | | static int c64_dma_read (int offset) |
| 927 | static int c64_dma_read( int offset ) |
| 881 | 928 | { |
| 882 | 929 | if (!c64_game && c64_exrom) |
| 883 | 930 | { |
| 884 | 931 | if (offset < 0x3000) |
| 885 | 932 | return c64_memory[offset]; |
| 933 | |
| 886 | 934 | return c64_romh[offset & 0x1fff]; |
| 887 | 935 | } |
| 936 | |
| 888 | 937 | if (((c64_vicaddr - c64_memory + offset) & 0x7000) == 0x1000) |
| 889 | 938 | return c64_chargen[offset & 0xfff]; |
| 939 | |
| 890 | 940 | return c64_vicaddr[offset]; |
| 891 | 941 | } |
| 892 | 942 | |
| 893 | | static int c64_dma_read_ultimax (int offset) |
| 943 | static int c64_dma_read_ultimax( int offset ) |
| 894 | 944 | { |
| 895 | 945 | if (offset < 0x3000) |
| 896 | 946 | return c64_memory[offset]; |
| 947 | |
| 897 | 948 | return c64_romh[offset & 0x1fff]; |
| 898 | 949 | } |
| 899 | 950 | |
| 900 | | static int c64_dma_read_color (int offset) |
| 951 | static int c64_dma_read_color( int offset ) |
| 901 | 952 | { |
| 902 | 953 | return c64_colorram[offset & 0x3ff] & 0xf; |
| 903 | 954 | } |
| r3150 | r3151 | |
| 1005 | 1056 | cbm_drive_1_config (SERIAL, is_c65(machine) ? 11 : 9); |
| 1006 | 1057 | serial_clock = serial_data = serial_atn = 1; |
| 1007 | 1058 | } |
| 1059 | |
| 1008 | 1060 | c64_vicaddr = c64_memory; |
| 1009 | 1061 | vicirq = 0; |
| 1010 | 1062 | } |
| r3150 | r3151 | |
| 1035 | 1087 | return address; |
| 1036 | 1088 | } |
| 1037 | 1089 | |
| 1090 | |
| 1038 | 1091 | MACHINE_START( c64 ) |
| 1039 | 1092 | { |
| 1040 | 1093 | c64_port_data = 0x17; |
| r3150 | r3151 | |
| 1042 | 1095 | c64_io_mirror = auto_malloc( 0x1000 ); |
| 1043 | 1096 | c64_common_init_machine (machine); |
| 1044 | 1097 | |
| 1045 | | c64_rom_recognition (); |
| 1046 | | c64_rom_load(machine); |
| 1047 | | |
| 1048 | 1098 | if (is_c128(machine)) |
| 1049 | 1099 | c128_bankswitch_64(machine, 1); |
| 1100 | |
| 1050 | 1101 | if (!ultimax) |
| 1051 | 1102 | c64_bankswitch(machine, 1); |
| 1103 | |
| 1052 | 1104 | memory_set_opbase_handler( 0, c64_opbase ); |
| 1053 | 1105 | } |
| 1054 | 1106 | |
| 1055 | 1107 | |
| 1056 | | |
| 1057 | | #define BETWEEN(value1,value2,bottom,top) \ |
| 1058 | | ( ((value2)>=(bottom))&&((value1)<(top)) ) |
| 1059 | | |
| 1060 | | void c64_rom_recognition (void) |
| 1061 | | { |
| 1062 | | int i; |
| 1063 | | |
| 1064 | | cartridgetype=CartridgeAuto; |
| 1065 | | |
| 1066 | | for (i=0; (i<sizeof(cbm_rom)/sizeof(cbm_rom[0])) && (cbm_rom[i].size!=0); i++) |
| 1067 | | { |
| 1068 | | cartridge=1; |
| 1069 | | if ( BETWEEN(0xa000, 0xbfff, cbm_rom[i].addr, cbm_rom[i].addr+cbm_rom[i].size) ) |
| 1070 | | { |
| 1071 | | cartridgetype=CartridgeC64; |
| 1072 | | } |
| 1073 | | else if ( BETWEEN(0xe000, 0xffff, cbm_rom[i].addr, cbm_rom[i].addr+cbm_rom[i].size) ) |
| 1074 | | { |
| 1075 | | cartridgetype=CartridgeUltimax; |
| 1076 | | } |
| 1077 | | } |
| 1078 | | } |
| 1079 | | |
| 1080 | | void c64_rom_load(running_machine *machine) |
| 1081 | | { |
| 1082 | | int i; |
| 1083 | | |
| 1084 | | c64_exrom = 1; |
| 1085 | | c64_game = 1; |
| 1086 | | if (cartridge) |
| 1087 | | { |
| 1088 | | if (((input_port_read(machine, "CFG") & 0x1c ) == 0) && (cartridgetype == CartridgeAuto)) // AUTO_MODULE |
| 1089 | | { |
| 1090 | | logerror("Cartridge type not recognized using machine type\n"); |
| 1091 | | } |
| 1092 | | |
| 1093 | | if (((input_port_read(machine, "CFG") & 0x1c ) == 8) && (cartridgetype == CartridgeUltimax))// C64_MODULE |
| 1094 | | { |
| 1095 | | logerror("Cartridge could be ultimax type!?\n"); |
| 1096 | | } |
| 1097 | | |
| 1098 | | if (((input_port_read(machine, "CFG") & 0x1c ) == 4) && (cartridgetype == CartridgeC64)) // ULTIMAX_MODULE |
| 1099 | | { |
| 1100 | | logerror("Cartridge could be c64 type!?\n"); |
| 1101 | | } |
| 1102 | | |
| 1103 | | if ((input_port_read(machine, "CFG") & 0x1c ) == 8) // C64_MODULE |
| 1104 | | cartridgetype = CartridgeC64; |
| 1105 | | |
| 1106 | | else if ((input_port_read(machine, "CFG") & 0x1c ) == 4) // ULTIMAX_MODULE |
| 1107 | | cartridgetype = CartridgeUltimax; |
| 1108 | | |
| 1109 | | if ((cbm_c64_exrom!=-1)&&(cbm_c64_game!=-1)) |
| 1110 | | { |
| 1111 | | c64_exrom=cbm_c64_exrom; |
| 1112 | | c64_game=cbm_c64_game; |
| 1113 | | } |
| 1114 | | |
| 1115 | | else if (ultimax || (cartridgetype == CartridgeUltimax)) |
| 1116 | | { |
| 1117 | | c64_game = 0; |
| 1118 | | } |
| 1119 | | |
| 1120 | | else |
| 1121 | | { |
| 1122 | | c64_exrom = 0; |
| 1123 | | } |
| 1124 | | |
| 1125 | | if (ultimax) |
| 1126 | | { |
| 1127 | | for (i=0; (i<sizeof(cbm_rom)/sizeof(cbm_rom[0])) |
| 1128 | | &&(cbm_rom[i].size!=0); i++) |
| 1129 | | { |
| 1130 | | if (cbm_rom[i].addr==CBM_ROM_ADDR_LO) |
| 1131 | | { |
| 1132 | | memcpy(c64_memory+0x8000+0x2000-cbm_rom[i].size, |
| 1133 | | cbm_rom[i].chip, cbm_rom[i].size); |
| 1134 | | } |
| 1135 | | else if ((cbm_rom[i].addr==CBM_ROM_ADDR_HI) |
| 1136 | | ||(cbm_rom[i].addr==CBM_ROM_ADDR_UNKNOWN)) |
| 1137 | | { |
| 1138 | | memcpy(c64_memory+0xe000+0x2000-cbm_rom[i].size, |
| 1139 | | cbm_rom[i].chip, cbm_rom[i].size); |
| 1140 | | } |
| 1141 | | else |
| 1142 | | { |
| 1143 | | memcpy(c64_memory+cbm_rom[i].addr, cbm_rom[i].chip, |
| 1144 | | cbm_rom[i].size); |
| 1145 | | } |
| 1146 | | } |
| 1147 | | } |
| 1148 | | |
| 1149 | | else /*if ((cartridgetype == CartridgeC64) || (cartridgetype == CartridgeUltimax) )*/ |
| 1150 | | { |
| 1151 | | roml=c64_roml; |
| 1152 | | romh=c64_romh; |
| 1153 | | memset(roml, 0, 0x2000); |
| 1154 | | memset(romh, 0, 0x2000); |
| 1155 | | for (i=0; (i<sizeof(cbm_rom)/sizeof(cbm_rom[0])) && (cbm_rom[i].size!=0); i++) |
| 1156 | | { |
| 1157 | | if ((cbm_rom[i].addr==CBM_ROM_ADDR_UNKNOWN) ||(cbm_rom[i].addr==CBM_ROM_ADDR_LO) ) |
| 1158 | | { |
| 1159 | | memcpy(roml+0x2000-cbm_rom[i].size, cbm_rom[i].chip, cbm_rom[i].size); |
| 1160 | | } |
| 1161 | | else if ( ((cartridgetype == CartridgeC64) && (cbm_rom[i].addr == CBM_ROM_ADDR_HI)) |
| 1162 | | ||((cartridgetype == CartridgeUltimax) && (cbm_rom[i].addr == CBM_ROM_ADDR_HI)) ) |
| 1163 | | { |
| 1164 | | memcpy(romh+0x2000-cbm_rom[i].size, cbm_rom[i].chip, cbm_rom[i].size); |
| 1165 | | } |
| 1166 | | else if (cbm_rom[i].addr<0xc000) |
| 1167 | | { |
| 1168 | | memcpy(roml+cbm_rom[i].addr-0x8000, cbm_rom[i].chip, cbm_rom[i].size); |
| 1169 | | } |
| 1170 | | else |
| 1171 | | { |
| 1172 | | memcpy(romh+cbm_rom[i].addr-0xe000, cbm_rom[i].chip, cbm_rom[i].size); |
| 1173 | | } |
| 1174 | | } |
| 1175 | | } |
| 1176 | | } |
| 1177 | | } |
| 1178 | | |
| 1179 | 1108 | INTERRUPT_GEN( c64_frame_interrupt ) |
| 1180 | 1109 | { |
| 1181 | | static int monitor=-1; |
| 1110 | static int monitor = -1; |
| 1182 | 1111 | int value, i; |
| 1112 | int controller1 = input_port_read(Machine, "DSW0") & 0xe000; |
| 1113 | int controller2 = input_port_read(Machine, "DSW0") & 0x0e00; |
| 1183 | 1114 | static const char *c64ports[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7" }; |
| 1184 | 1115 | static const char *c128ports[] = { "KP0", "KP1", "KP2" }; |
| 1185 | 1116 | |
| r3150 | r3151 | |
| 1213 | 1144 | c64_keyline[i] = value; |
| 1214 | 1145 | } |
| 1215 | 1146 | |
| 1147 | |
| 1216 | 1148 | value = 0xff; |
| 1217 | | if ( ((input_port_read(machine, "DSW0") & 0xe000 ) == 0x2000) || ((input_port_read(machine, "DSW0") & 0xe000 ) == 0x6000) ) |
| 1149 | switch(controller1) |
| 1218 | 1150 | { |
| 1219 | | value &= ~(input_port_read(machine, "JOY0") & 0x1f); |
| 1220 | | } |
| 1221 | | else if ((input_port_read(machine, "DSW0") & 0xe000 ) == 0x4000) |
| 1222 | | { |
| 1223 | | if (input_port_read(machine, "PADDLE1") & 0x100) |
| 1224 | | value &= ~8; |
| 1225 | | if (input_port_read(machine, "PADDLE0") & 0x100) |
| 1226 | | value &= ~4; |
| 1227 | | } |
| 1228 | | else if (( input_port_read(machine, "DSW0") & 0xe000 ) == 0x8000 ) |
| 1229 | | { |
| 1230 | | if (input_port_read(machine, "TRACKIPT") & 0x02) |
| 1151 | case 0x2000: |
| 1152 | case 0x6000: |
| 1153 | value &= ~(input_port_read(machine, "JOY0") & 0x1f); /* Joy0 Directions + Button 1 */ |
| 1154 | break; |
| 1155 | |
| 1156 | case 0x4000: |
| 1157 | if (input_port_read(machine, "PADDLE1") & 0x100) /* Paddle1 Button */ |
| 1158 | value &= ~0x08; |
| 1159 | if (input_port_read(machine, "PADDLE0") & 0x100) /* Paddle0 Button */ |
| 1160 | value &= ~0x04; |
| 1161 | break; |
| 1162 | |
| 1163 | case 0x8000: |
| 1164 | if (input_port_read(machine, "TRACKIPT") & 0x02) /* Mouse Button Left */ |
| 1231 | 1165 | value &= ~0x10; |
| 1232 | | if (input_port_read(machine, "TRACKIPT") & 0x01) |
| 1233 | | value &= ~1; |
| 1166 | if (input_port_read(machine, "TRACKIPT") & 0x01) /* Mouse Button Right */ |
| 1167 | value &= ~0x01; |
| 1168 | break; |
| 1169 | |
| 1170 | case 0xa000: |
| 1171 | break; |
| 1172 | |
| 1173 | default: |
| 1174 | logerror("Invalid Controller 1 Setting %d\n", controller1); |
| 1175 | break; |
| 1234 | 1176 | } |
| 1177 | |
| 1235 | 1178 | c64_keyline[8] = value; |
| 1236 | 1179 | |
| 1180 | |
| 1237 | 1181 | value = 0xff; |
| 1238 | | if ( ((input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0200) || ((input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0600) ) |
| 1182 | switch(controller2) |
| 1239 | 1183 | { |
| 1240 | | value &= ~(input_port_read(machine, "JOY1") & 0x1f); |
| 1241 | | } |
| 1242 | | else if ((input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0400) |
| 1243 | | { |
| 1244 | | if (input_port_read(machine, "PADDLE3") & 0x100) |
| 1245 | | value &= ~8; |
| 1246 | | if (input_port_read(machine, "PADDLE2") & 0x100) |
| 1247 | | value &= ~4; |
| 1248 | | } |
| 1249 | | else if (( input_port_read(machine, "DSW0") & 0x0e00 ) == 0x0800 ) |
| 1250 | | { |
| 1251 | | if (input_port_read(machine, "TRACKIPT") & 0x02) |
| 1184 | case 0x0200: |
| 1185 | case 0x0600: |
| 1186 | value &= ~(input_port_read(machine, "JOY1") & 0x1f); /* Joy1 Directions + Button 1 */ |
| 1187 | break; |
| 1188 | |
| 1189 | case 0x0400: |
| 1190 | if (input_port_read(machine, "PADDLE3") & 0x100) /* Paddle3 Button */ |
| 1191 | value &= ~0x08; |
| 1192 | if (input_port_read(machine, "PADDLE2") & 0x100) /* Paddle2 Button */ |
| 1193 | value &= ~0x04; |
| 1194 | break; |
| 1195 | |
| 1196 | case 0x0800: |
| 1197 | if (input_port_read(machine, "TRACKIPT") & 0x02) /* Mouse Button Left */ |
| 1252 | 1198 | value &= ~0x10; |
| 1253 | | if (input_port_read(machine, "TRACKIPT") & 0x01) |
| 1254 | | value &= ~1; |
| 1199 | if (input_port_read(machine, "TRACKIPT") & 0x01) /* Mouse Button Right */ |
| 1200 | value &= ~0x01; |
| 1201 | break; |
| 1202 | |
| 1203 | default: |
| 1204 | logerror("Invalid Controller 2 Setting %d\n", controller2); |
| 1205 | break; |
| 1255 | 1206 | } |
| 1207 | |
| 1256 | 1208 | c64_keyline[9] = value; |
| 1257 | 1209 | |
| 1258 | 1210 | /* C128 only : keypad input ports */ |
| r3150 | r3151 | |
| 1280 | 1232 | set_led_status (1, input_port_read(machine, "SPECIAL") & 0x40 ? 1 : 0); /*KB_CAPSLOCK_FLAG */ |
| 1281 | 1233 | set_led_status (0, input_port_read(machine, "DSW0") & 0x0100 ? 1 : 0); /*KB_NUMLOCK_FLAG */ |
| 1282 | 1234 | } |
| 1235 | |
| 1236 | |
| 1237 | /*********************************************** |
| 1238 | |
| 1239 | C64 Cartridges |
| 1240 | |
| 1241 | ***********************************************/ |
| 1242 | |
| 1243 | /* Info based on http://ist.uwaterloo.ca/~schepers/formats/CRT.TXT */ |
| 1244 | /* Please refer to the webpage for the latest version and for a very |
| 1245 | complete listing of various cart types and their bankswitch tricks */ |
| 1246 | /* |
| 1247 | Cartridge files were introduced in the CCS64 emulator, written by Per |
| 1248 | Hakan Sundell, and use the ".CRT" file extension. This format was created |
| 1249 | to handle the various ROM cartridges that exist, such as Action Replay, the |
| 1250 | Power cartridge, and the Final Cartridge. |
| 1251 | |
| 1252 | Normal game cartridges can load into several different memory ranges |
| 1253 | ($8000-9FFF, $A000-BFFF or $E000-FFFF). Newer utility and freezer |
| 1254 | cartridges were less intrusive, hiding themselves until called upon, and |
| 1255 | still others used bank-switching techniques to allow much larger ROM's than |
| 1256 | normal. Because of these "stealthing" and bank-switching methods, a special |
| 1257 | cartridge format was necessary, to let the emulator know where the |
| 1258 | cartridge should reside, the control line states to enable it and any |
| 1259 | special hardware features it uses. |
| 1260 | |
| 1261 | (...) |
| 1262 | |
| 1263 | [ A .CRT file consists of |
| 1264 | |
| 1265 | $0000-0040 : Header of the whole .crt files |
| 1266 | $0040-EOF : Blocks of data |
| 1267 | |
| 1268 | Each block of data, called 'CHIP', can be of variable size. The first |
| 1269 | 0x10 bytes of each CHIP block is the block header, and it contains various |
| 1270 | informations on the block itself, as its size (both with and without the |
| 1271 | header), the loading address and an index to identify which memory bank |
| 1272 | the data must be loaded to. FP ] |
| 1273 | |
| 1274 | .CRT header description |
| 1275 | ----------------------- |
| 1276 | |
| 1277 | Bytes: $0000-000F - 16-byte cartridge signature "C64 CARTRIDGE" (padded |
| 1278 | with space characters) |
| 1279 | 0010-0013 - File header length ($00000040, in high/low format, |
| 1280 | calculated from offset $0000). The default (also the |
| 1281 | minimum) value is $40. Some cartridges exist which |
| 1282 | show a value of $00000020 which is wrong. |
| 1283 | 0014-0015 - Cartridge version (high/low, presently 01.00) |
| 1284 | 0016-0017 - Cartridge hardware type ($0000, high/low) |
| 1285 | 0018 - Cartridge port EXROM line status |
| 1286 | 0 - inactive |
| 1287 | 1 - active |
| 1288 | 0019 - Cartridge port GAME line status |
| 1289 | 0 - inactive |
| 1290 | 1 - active |
| 1291 | 001A-001F - Reserved for future use |
| 1292 | 0020-003F - 32-byte cartridge name "CCSMON" (uppercase, padded |
| 1293 | with null characters) |
| 1294 | 0040-xxxx - Cartridge contents (called CHIP PACKETS, as there can |
| 1295 | be more than one per CRT file). See below for a |
| 1296 | breakdown of the CHIP format. |
| 1297 | |
| 1298 | CHIP content description |
| 1299 | ------------------------ |
| 1300 | |
| 1301 | [ Addresses shifted back to $0000. FP ] |
| 1302 | |
| 1303 | Bytes: $0000-0003 - Contained ROM signature "CHIP" (note there can be more |
| 1304 | than one image in a .CRT file) |
| 1305 | 0004-0007 - Total packet length (ROM image size and |
| 1306 | header combined) (high/low format) |
| 1307 | 0008-0009 - Chip type |
| 1308 | 0 - ROM |
| 1309 | 1 - RAM, no ROM data |
| 1310 | 2 - Flash ROM |
| 1311 | 000A-000B - Bank number |
| 1312 | 000C-000D - Starting load address (high/low format) |
| 1313 | 000E-000F - ROM image size in bytes (high/low format, typically |
| 1314 | $2000 or $4000) |
| 1315 | 0010-xxxx - ROM data |
| 1316 | |
| 1317 | |
| 1318 | */ |
| 1319 | |
| 1320 | static CBM_ROM c64_cbm_cart[0x20] = { {0} }; |
| 1321 | static INT8 cbm_c64_game; |
| 1322 | static INT8 cbm_c64_exrom; |
| 1323 | |
| 1324 | static DEVICE_IMAGE_UNLOAD(c64_cart) |
| 1325 | { |
| 1326 | int index = image_index_in_device(image); |
| 1327 | c64_cbm_cart[index].size = 0; |
| 1328 | c64_cbm_cart[index].chip = 0; |
| 1329 | } |
| 1330 | |
| 1331 | static DEVICE_START(c64_cart) |
| 1332 | { |
| 1333 | int index = image_index_in_device(device); |
| 1334 | if (index == 0) |
| 1335 | { |
| 1336 | cbm_c64_game = -1; |
| 1337 | cbm_c64_exrom = -1; |
| 1338 | } |
| 1339 | } |
| 1340 | |
| 1341 | /* Hardware Types for C64 carts */ |
| 1342 | enum { |
| 1343 | GENERIC_CRT = 0, /* 00 - Normal cartridge */ |
| 1344 | ACTION_REPLAY, /* 01 - Action Replay */ |
| 1345 | KCS_PC, /* 02 - KCS Power Cartridge */ |
| 1346 | FINAL_CART_III, /* 03 - Final Cartridge III */ |
| 1347 | SIMONS_BASIC, /* 04 - Simons Basic */ |
| 1348 | OCEAN_1, /* 05 - Ocean type 1 (1) */ |
| 1349 | EXPERT, /* 06 - Expert Cartridge */ |
| 1350 | FUN_PLAY, /* 07 - Fun Play, Power Play */ |
| 1351 | SUPER_GAMES, /* 08 - Super Games */ |
| 1352 | ATOMIC_POWER, /* 09 - Atomic Power */ |
| 1353 | EPYX_FASTLOAD, /* 10 - Epyx Fastload */ |
| 1354 | WESTERMANN, /* 11 - Westermann Learning */ |
| 1355 | REX, /* 12 - Rex Utility */ |
| 1356 | FINAL_CART_I, /* 13 - Final Cartridge I */ |
| 1357 | MAGIC_FORMEL, /* 14 - Magic Formel */ |
| 1358 | C64GS, /* 15 - C64 Game System, System 3 */ |
| 1359 | WARPSPEED, /* 16 - WarpSpeed */ |
| 1360 | DINAMIC, /* 17 - Dinamic (2) */ |
| 1361 | ZAXXON, /* 18 - Zaxxon, Super Zaxxon (SEGA) */ |
| 1362 | DOMARK, /* 19 - Magic Desk, Domark, HES Australia */ |
| 1363 | SUPER_SNAP_5, /* 20 - Super Snapshot 5 */ |
| 1364 | COMAL_80, /* 21 - Comal-80 */ |
| 1365 | STRUCT_BASIC, /* 22 - Structured Basic */ |
| 1366 | ROSS, /* 23 - Ross */ |
| 1367 | DELA_EP64, /* 24 - Dela EP64 */ |
| 1368 | DELA_EP7X8, /* 25 - Dela EP7x8 */ |
| 1369 | DELA_EP256, /* 26 - Dela EP256 */ |
| 1370 | REX_EP256, /* 27 - Rex EP256 */ |
| 1371 | MIKRO_ASSMBLR, /* 28 - Mikro Assembler */ |
| 1372 | REAL_FC_I, /* 29 - (3) */ |
| 1373 | ACTION_REPLAY_4, /* 30 - Action Replay 4 */ |
| 1374 | STARDOS, /* 31 - StarDOS */ |
| 1375 | /* |
| 1376 | (1) Ocean type 1 includes Navy Seals, Robocop 2 & 3, Shadow of |
| 1377 | the Beast, Toki, Terminator 2 and more. Both 256 and 128 Kb images. |
| 1378 | (2) Dinamic includes Narco Police and more. |
| 1379 | (3) Type 29 is reserved for the real Final Cartridge I, the one |
| 1380 | above (Type 13) will become Final Cartridge II. */ |
| 1381 | /**************************************** |
| 1382 | Vice also defines the following types: |
| 1383 | #define CARTRIDGE_ACTION_REPLAY3 -29 |
| 1384 | #define CARTRIDGE_IEEE488 -11 |
| 1385 | #define CARTRIDGE_IDE64 -7 |
| 1386 | #define CARTRIDGE_RETRO_REPLAY -5 |
| 1387 | #define CARTRIDGE_SUPER_SNAPSHOT -4 |
| 1388 | |
| 1389 | Can we support these as well? |
| 1390 | *****************************************/ |
| 1391 | }; |
| 1392 | |
| 1393 | static DEVICE_IMAGE_LOAD(c64_cart) |
| 1394 | { |
| 1395 | int size = image_length(image), test, i; |
| 1396 | const char *filetype; |
| 1397 | int address = 0; |
| 1398 | |
| 1399 | filetype = image_filetype(image); |
| 1400 | |
| 1401 | /* We support .crt files */ |
| 1402 | if (!mame_stricmp (filetype, "crt")) |
| 1403 | { |
| 1404 | int j; |
| 1405 | unsigned short cart_type; |
| 1406 | |
| 1407 | for (i=0; (i<sizeof(c64_cbm_cart) / sizeof(c64_cbm_cart[0])) && (c64_cbm_cart[i].size!=0); i++) |
| 1408 | ; |
| 1409 | |
| 1410 | if (i >= sizeof(c64_cbm_cart) / sizeof(c64_cbm_cart[0])) |
| 1411 | return INIT_FAIL; |
| 1412 | |
| 1413 | /* Start to parse the .crt header */ |
| 1414 | /* 0x16-0x17 is Hardware type */ |
| 1415 | image_fseek(image, 0x16, SEEK_SET); |
| 1416 | image_fread(image, &cart_type, 2); |
| 1417 | cart_type = BIG_ENDIANIZE_INT16(cart_type); |
| 1418 | |
| 1419 | /* If it is unsupported cart type, warn the user */ |
| 1420 | switch (cart_type) |
| 1421 | { |
| 1422 | case GENERIC_CRT: |
| 1423 | break; |
| 1424 | |
| 1425 | default: |
| 1426 | logerror("Currently unsupported cart type (Type %d)\n", cart_type); |
| 1427 | break; |
| 1428 | } |
| 1429 | |
| 1430 | /* 0x18 is EXROM */ |
| 1431 | image_fseek(image, 0x18, SEEK_SET); |
| 1432 | image_fread(image, &cbm_c64_exrom, 1); |
| 1433 | |
| 1434 | /* 0x19 is GAME */ |
| 1435 | image_fread(image, &cbm_c64_game, 1); |
| 1436 | |
| 1437 | /* We can pass to the data: it starts from 0x40 */ |
| 1438 | image_fseek(image, 0x40, SEEK_SET); |
| 1439 | j = 0x40; |
| 1440 | |
| 1441 | logerror("Loading cart %s size:%.4x\n", image_filename(image), size); |
| 1442 | logerror("Header info: EXROM %d, GAME %d, Cart Type %d \n", cbm_c64_exrom, cbm_c64_game, cart_type); |
| 1443 | |
| 1444 | |
| 1445 | /* Data in a .crt image are organized in blocks called 'CHIP': |
| 1446 | each 'CHIP' consists of a 0x10 header, which contains the |
| 1447 | actual size of the block, the loading address and info on |
| 1448 | the bankswitch, followed by the actual data */ |
| 1449 | while (j < size) |
| 1450 | { |
| 1451 | unsigned short chip_size, chip_bank_index, chip_data_size; |
| 1452 | unsigned char buffer[10]; |
| 1453 | |
| 1454 | /* Start to parse the CHIP header */ |
| 1455 | /* First 4 bytes are the string 'CHIP' */ |
| 1456 | image_fread(image, buffer, 6); |
| 1457 | |
| 1458 | /* 0x06-0x07 is the size of the CHIP block (header + data) */ |
| 1459 | image_fread(image, &chip_size, 2); |
| 1460 | chip_size = BIG_ENDIANIZE_INT16(chip_size); |
| 1461 | |
| 1462 | /* 0x08-0x09 chip type (ROM, RAM + no ROM, Flash ROM) */ |
| 1463 | image_fread(image, buffer + 6, 2); |
| 1464 | |
| 1465 | /* 0x0a-0x0b is the bank number of the CHIP block */ |
| 1466 | /* We currently don't use this, but it is needed to support more cart types. */ |
| 1467 | image_fread(image, &chip_bank_index, 2); |
| 1468 | chip_bank_index = BIG_ENDIANIZE_INT16(chip_bank_index); |
| 1469 | |
| 1470 | /* 0x0c-0x0d is the loading address of the CHIP block */ |
| 1471 | image_fread(image, &address, 2); |
| 1472 | address = BIG_ENDIANIZE_INT16(address); |
| 1473 | |
| 1474 | /* 0x0e-0x0f is the data size of the CHIP block (without header) */ |
| 1475 | image_fread(image, &chip_data_size, 2); |
| 1476 | chip_data_size = BIG_ENDIANIZE_INT16(chip_data_size); |
| 1477 | |
| 1478 | /* Print out the CHIP header! */ |
| 1479 | logerror("%.4s %.2x %.2x %.4x %.2x %.2x %.4x %.4x:%.4x\n", |
| 1480 | buffer, buffer[4], buffer[5], chip_size, |
| 1481 | buffer[6], buffer[7], chip_bank_index, |
| 1482 | address, chip_data_size); |
| 1483 | logerror("Loading CHIP data at %.4x size:%.4x\n", address, chip_data_size); |
| 1484 | |
| 1485 | /* Does CHIP contain any data? */ |
| 1486 | c64_cbm_cart[i].chip = (UINT8*) image_malloc(image, chip_data_size); |
| 1487 | if (!c64_cbm_cart[i].chip) |
| 1488 | return INIT_FAIL; |
| 1489 | |
| 1490 | /* Store data, address & size of the CHIP block */ |
| 1491 | c64_cbm_cart[i].addr = address; |
| 1492 | c64_cbm_cart[i].size = chip_data_size; |
| 1493 | test = image_fread(image, c64_cbm_cart[i].chip, chip_data_size); |
| 1494 | |
| 1495 | if (test != chip_data_size) |
| 1496 | return INIT_FAIL; |
| 1497 | |
| 1498 | /* Advance to the next CHIP block */ |
| 1499 | i++; |
| 1500 | j += chip_size; |
| 1501 | } |
| 1502 | } |
| 1503 | |
| 1504 | /* We also support .80 files for c64 & .e0/.f0 for max */ |
| 1505 | else |
| 1506 | { |
| 1507 | /* Assign loading address according to extension */ |
| 1508 | if (!mame_stricmp (filetype, "80")) |
| 1509 | address = 0x8000; |
| 1510 | |
| 1511 | if (!mame_stricmp (filetype, "e0")) |
| 1512 | address = 0xe000; |
| 1513 | |
| 1514 | if (!mame_stricmp (filetype, "f0")) |
| 1515 | address = 0xf000; |
| 1516 | |
| 1517 | logerror("loading %s rom at %.4x size:%.4x\n", image_filename(image), address, size); |
| 1518 | |
| 1519 | /* Does cart contain any data? */ |
| 1520 | c64_cbm_cart[0].chip = (UINT8*) image_malloc(image, size); |
| 1521 | if (!c64_cbm_cart[0].chip) |
| 1522 | return INIT_FAIL; |
| 1523 | |
| 1524 | /* Store data, address & size */ |
| 1525 | c64_cbm_cart[0].addr = address; |
| 1526 | c64_cbm_cart[0].size = size; |
| 1527 | test = image_fread(image, c64_cbm_cart[0].chip, c64_cbm_cart[0].size); |
| 1528 | |
| 1529 | if (test != c64_cbm_cart[0].size) |
| 1530 | return INIT_FAIL; |
| 1531 | } |
| 1532 | |
| 1533 | /* If we load a .crt file, use EXROM & GAME from the header! */ |
| 1534 | if ((cbm_c64_exrom != -1) && (cbm_c64_game != -1)) |
| 1535 | { |
| 1536 | c64_exrom = cbm_c64_exrom; |
| 1537 | c64_game = cbm_c64_game; |
| 1538 | } |
| 1539 | |
| 1540 | /* Finally load the cart */ |
| 1541 | if (ultimax) |
| 1542 | { |
| 1543 | for (i=0; (i < sizeof(c64_cbm_cart) / sizeof(c64_cbm_cart[0])) && (c64_cbm_cart[i].size != 0); i++) |
| 1544 | memcpy(c64_memory + c64_cbm_cart[i].addr, c64_cbm_cart[i].chip, c64_cbm_cart[i].size); |
| 1545 | } |
| 1546 | |
| 1547 | else |
| 1548 | { |
| 1549 | roml = c64_roml; |
| 1550 | romh = c64_romh; |
| 1551 | |
| 1552 | memset(roml, 0, 0x2000); |
| 1553 | memset(romh, 0, 0x2000); |
| 1554 | |
| 1555 | for (i=0; (i < sizeof(c64_cbm_cart) / sizeof(c64_cbm_cart[0])) && (c64_cbm_cart[i].size != 0); i++) |
| 1556 | { |
| 1557 | if (c64_cbm_cart[i].addr < 0xc000) |
| 1558 | memcpy(roml + c64_cbm_cart[i].addr - 0x8000, c64_cbm_cart[i].chip, c64_cbm_cart[i].size); |
| 1559 | |
| 1560 | else |
| 1561 | memcpy(romh + c64_cbm_cart[i].addr - 0xe000, c64_cbm_cart[i].chip, c64_cbm_cart[i].size); |
| 1562 | } |
| 1563 | } |
| 1564 | |
| 1565 | return INIT_PASS; |
| 1566 | } |
| 1567 | |
| 1568 | void c64_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 1569 | { |
| 1570 | switch(state) |
| 1571 | { |
| 1572 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 1573 | case MESS_DEVINFO_INT_COUNT: info->i = 2; break; |
| 1574 | |
| 1575 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 1576 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "crt,80"); break; |
| 1577 | |
| 1578 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 1579 | case MESS_DEVINFO_PTR_START: info->start = DEVICE_START_NAME(c64_cart); break; |
| 1580 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(c64_cart); break; |
| 1581 | case MESS_DEVINFO_PTR_UNLOAD: info->unload = DEVICE_IMAGE_UNLOAD_NAME(c64_cart); break; |
| 1582 | |
| 1583 | default: cartslot_device_getinfo(devclass, state, info); |
| 1584 | } |
| 1585 | } |
| 1586 | |
| 1587 | void ultimax_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info) |
| 1588 | { |
| 1589 | switch(state) |
| 1590 | { |
| 1591 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 1592 | case MESS_DEVINFO_INT_COUNT: info->i = 1; break; |
| 1593 | case MESS_DEVINFO_INT_MUST_BE_LOADED: info->i = 1; break; |
| 1594 | |
| 1595 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 1596 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "crt,e0,f0"); break; |
| 1597 | |
| 1598 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 1599 | case MESS_DEVINFO_PTR_START: info->start = DEVICE_START_NAME(c64_cart); break; |
| 1600 | case MESS_DEVINFO_PTR_LOAD: info->load = DEVICE_IMAGE_LOAD_NAME(c64_cart); break; |
| 1601 | case MESS_DEVINFO_PTR_UNLOAD: info->unload = DEVICE_IMAGE_UNLOAD_NAME(c64_cart); break; |
| 1602 | |
| 1603 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 1604 | } |
| 1605 | } |