| Previous | 15994 Revisions | Next |
| r8045 Saturday 15th May, 2010 at 08:44:02 UTC by Fabio Priuli |
|---|
| srcclean'd the MESS tree |
| [src/mess] | climess.c image.c infomess.c messdriv.c softlist.c |
| [src/mess/audio] | t6721.c ted7360.c upd1771.c |
| [src/mess/devices] | aescart.c messram.c ti99_hd.c ti99_hd.h ti99cart.c |
| [src/mess/drivers] | abc80x.c advision.c alesis.c arcadia.c at.c atom.c c16.c c64.c cd2650.c cgc7900.c chaos.c dc.c dm7000.c dolphin.c elektor.c fmtowns.c genesis.c geneve.c gmaster.c hec2hrp.c instruct.c interact.c intv.c jaguar.c lynx.c m20.c mtx.c mz2500.c n64.c nes.c ngp.c pasogo.c pc.c pegasus.c phc25.c pipbug.c pk8020.c pv1000.c pv9234.c px8.c radio86.c rmnimbus.c scv.c sg1000.c snes.c special.c spectrum.c svision.c swtpc.c sys2900.c tandy2k.c ti99_4p.c ti99_4x.c ti99_8.c trs80m2.c ut88.c vboy.c victor9k.c vidbrain.c vt240.c wswan.c x1.c z80dev.c |
| [src/mess/formats] | atarist_dsk.c atom_atm.c atom_tap.c cbm_snqk.c cbm_snqk.h d64_dsk.c fdi_dsk.c flopimg.c nes_dsk.c ti99_dsk.c trs_cmd.c wavfile.c |
| [src/mess/includes] | nes.h rmnimbus.h |
| [src/mess/machine] | 64h156.c 64h156.h 8530scc.c 99_dsk.c ac1.c amstrad.c apple2.c c1541.c c16.c c2040.c conkort.c gamecom.c gb.c genesis.c geneve.c lynx.c mac.c mc6852.c mtx.c nes.c nes_ines.c nes_mmc.c pce.c rmnimbus.c rs232.c smc92x4.c smc92x4.h snescart.c ti99_4x.c ti99_4x.h ti99pcod.c wd17xx.c |
| [src/mess/osd/winui] | messui.c propertiesms.c |
| [src/mess/tools/imgtool/modules] | fat.c |
| [src/mess/tools/imgtool/windows] | secview.c |
| [src/mess/tools/messdocs] | messdocs.c |
| [src/mess/video] | cgc7900.c crt9007.c crt9007.h fmtowns.c mbee.c odyssey2.c pegasus.c |
| r8044 | r8045 | |
|---|---|---|
| 113 | 113 | info_listsoftware - output the list of |
| 114 | 114 | software supported by a given game or set of |
| 115 | 115 | games |
| 116 | ||
| 116 | TODO: Add all information read from the source files | |
| 117 | 117 | Possible improvement: use a sorted list for |
| 118 | 118 | identifying duplicate lists. |
| 119 | 119 | -------------------------------------------------*/ |
| r8044 | r8045 | |
|---|---|---|
| 87 | 87 | struct _ti99_multicart_state |
| 88 | 88 | { |
| 89 | 89 | /* Reserves space for all cartridges. This is also used in the legacy |
| 90 | ||
| 90 | cartridge system, but only for slot 0. */ | |
| 91 | 91 | cartridge_t cartridge[NUMBER_OF_CARTRIDGE_SLOTS]; |
| 92 | 92 | |
| 93 | 93 | /* Determines which slot is currently active. This value is changed when there |
| 94 | ||
| 94 | are accesses to other GROM base addresses. */ | |
| 95 | 95 | int active_slot; |
| 96 | 96 | |
| 97 | 97 | /* Used in order to enforce a special slot. This value is retrieved |
| 98 | from the dipswitch setting. A value of -1 means automatic, that is, | |
| 99 | the grom base switch is used. Values 0 .. max refer to the | |
| 100 | respective slot. */ | |
| 98 | from the dipswitch setting. A value of -1 means automatic, that is, | |
| 99 | the grom base switch is used. Values 0 .. max refer to the | |
| 100 | respective slot. */ | |
| 101 | 101 | int fixed_slot; |
| 102 | 102 | |
| 103 | 103 | /* Holds the highest index of a cartridge being plugged in plus one. |
| 104 | If we only have one cartridge inserted, we don't want to get a | |
| 105 | selection option, so we just mirror the memory contents. */ | |
| 104 | If we only have one cartridge inserted, we don't want to get a | |
| 105 | selection option, so we just mirror the memory contents. */ | |
| 106 | 106 | int next_free_slot; |
| 107 | 107 | |
| 108 | 108 | /* Counts the number of slots which currently contain legacy format |
| 109 | ||
| 109 | cartridge images. */ | |
| 110 | 110 | int legacy_slots; |
| 111 | 111 | |
| 112 | 112 | /* Counts the number of slots which currently contain new format |
| 113 | ||
| 113 | cartridge images. */ | |
| 114 | 114 | int multi_slots; |
| 115 | 115 | |
| 116 | 116 | /* Legacy mode. Stores the slot number where the cartridge part is mounted. |
| 117 | ||
| 117 | Index is from slotc_type_t. */ | |
| 118 | 118 | int legacy_slotnumber[5]; |
| 119 | 119 | |
| 120 | 120 | /* current address pointer for the active GROM in port (16 bits) */ |
| r8044 | r8045 | |
| 123 | 123 | UINT8 grom_buffer; |
| 124 | 124 | |
| 125 | 125 | /* internal flip-flops that are set after the first access to the GROM |
| 126 | address so that next access is mapped to the LSB, and cleared after each | |
| 127 | data access */ | |
| 126 | address so that next access is mapped to the LSB, and cleared after each | |
| 127 | data access */ | |
| 128 | 128 | char raddr_LSB, waddr_LSB; |
| 129 | 129 | }; |
| 130 | 130 | typedef struct _ti99_multicart_state ti99_multicart_state; |
| r8044 | r8045 | |
| 280 | 280 | } |
| 281 | 281 | |
| 282 | 282 | /* |
| 283 | ||
| 283 | Set the address pointer value or write to GRAM (if available). | |
| 284 | 284 | */ |
| 285 | 285 | WRITE8_DEVICE_HANDLER(ti99_cartridge_grom_w) |
| 286 | 286 | { |
| 287 | 287 | ti99_multicart_state *cartslots = (ti99_multicart_state *)device->token; |
| 288 | 288 | |
| 289 | 289 | /* Set the cart slot. Note that the port must be adjusted for 16-bit |
| 290 | systems, i.e. it should be shifted left by 1. | |
| 291 | // 1001 1wbb bbbb bbr0 | |
| 292 | */ | |
| 290 | systems, i.e. it should be shifted left by 1. | |
| 291 | // 1001 1wbb bbbb bbr0 | |
| 292 | */ | |
| 293 | 293 | cartridge_slot_set(device, (offset>>2) & 0x00ff); |
| 294 | 294 | |
| 295 | 295 | if (offset & 0x0002) |
| r8044 | r8045 | |
| 300 | 300 | } |
| 301 | 301 | |
| 302 | 302 | /* |
| 303 | Deliver the local address pointer value. Note that this must be | |
| 304 | in sync with the console. | |
| 303 | Deliver the local address pointer value. Note that this must be | |
| 304 | in sync with the console. | |
| 305 | 305 | */ |
| 306 | 306 | static UINT8 grom_read_address(ti99_multicart_state *cartslots) |
| 307 | 307 | { |
| 308 | 308 | UINT8 reply; |
| 309 | 309 | /* When reading, reset the hi/lo flag byte for writing. |
| 310 | ||
| 310 | TODO: Verify this with a real machine. */ | |
| 311 | 311 | cartslots->waddr_LSB = FALSE; |
| 312 | 312 | |
| 313 | 313 | /* Address reading is done in two steps; first, the high byte |
| 314 | ||
| 314 | is transferred, then the low byte. */ | |
| 315 | 315 | if (cartslots->raddr_LSB) |
| 316 | 316 | { |
| 317 | 317 | /* second pass */ |
| r8044 | r8045 | |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | 330 | /* |
| 331 | GROM access. Accesses the GROMs in the cartridge. GROM memory is | |
| 332 | accessed serially via a set of ports. The GRMWA port (bank 0: 0x9c02) | |
| 333 | takes two consecutive byte writes which represent the high and low byte | |
| 334 | of the memory address in the GROM space. Once set, bytes can be read | |
| 335 | by repeated read accesses on the GRMRD port (bank 0: 0x9800). The | |
| 336 | address pointer advances on each read. The pointer wraps at the end | |
| 337 | of each GROM chip memory space, i.e. every 8KiB. | |
| 338 | This function takes the current GROM address minus 0x6000 which is the | |
| 339 | lowest address for cartridge GROMs. Lower addresses access GROMs in the | |
| 340 | console only, which appear in all banks. | |
| 341 | Note that the GROM access mechanism is identical for all cartridge | |
| 342 | types. | |
| 331 | GROM access. Accesses the GROMs in the cartridge. GROM memory is | |
| 332 | accessed serially via a set of ports. The GRMWA port (bank 0: 0x9c02) | |
| 333 | takes two consecutive byte writes which represent the high and low byte | |
| 334 | of the memory address in the GROM space. Once set, bytes can be read | |
| 335 | by repeated read accesses on the GRMRD port (bank 0: 0x9800). The | |
| 336 | address pointer advances on each read. The pointer wraps at the end | |
| 337 | of each GROM chip memory space, i.e. every 8KiB. | |
| 338 | This function takes the current GROM address minus 0x6000 which is the | |
| 339 | lowest address for cartridge GROMs. Lower addresses access GROMs in the | |
| 340 | console only, which appear in all banks. | |
| 341 | Note that the GROM access mechanism is identical for all cartridge | |
| 342 | types. | |
| 343 | 343 | */ |
| 344 | 344 | READ8_DEVICE_HANDLER(ti99_cartridge_grom_r) |
| 345 | 345 | { |
| r8044 | r8045 | |
| 349 | 349 | ti99_multicart_state *cartslots = (ti99_multicart_state *)device->token; |
| 350 | 350 | |
| 351 | 351 | /* Set the cart slot. Note that the port must be adjusted for 16-bit |
| 352 | systems, i.e. it should be shifted left by 1. | |
| 353 | 1001 1wbb bbbb bbr0 | |
| 354 | */ | |
| 352 | systems, i.e. it should be shifted left by 1. | |
| 353 | 1001 1wbb bbbb bbr0 | |
| 354 | */ | |
| 355 | 355 | cartridge_slot_set(device, (offset>>2) & 0x00ff); |
| 356 | 356 | |
| 357 | 357 | if (offset & 0x0002) |
| r8044 | r8045 | |
| 363 | 363 | |
| 364 | 364 | slot = cartslots->active_slot; |
| 365 | 365 | /* |
| 366 | This fixes a minor issue: The selection mechanism of the console | |
| 367 | concludes that there are multiple cartridges plugged in when it | |
| 368 | checks the different GROM bases and finds different data. Empty | |
| 369 | slots should return 0 at all addresses, but when we have only | |
| 370 | one cartridge, this entails that the second cartridge is | |
| 371 | different (all zeros), and so we get a meaningless selection | |
| 372 | option between cartridge 1 and 1 and 1 ... | |
| 366 | This fixes a minor issue: The selection mechanism of the console | |
| 367 | concludes that there are multiple cartridges plugged in when it | |
| 368 | checks the different GROM bases and finds different data. Empty | |
| 369 | slots should return 0 at all addresses, but when we have only | |
| 370 | one cartridge, this entails that the second cartridge is | |
| 371 | different (all zeros), and so we get a meaningless selection | |
| 372 | option between cartridge 1 and 1 and 1 ... | |
| 373 | 373 | |
| 374 | So if next_free_slot==1, we have one cartridge in slot 0. | |
| 375 | In that case we trick the OS to believe that the addressed | |
| 376 | cartridge appears at all locations which causes it to assume a | |
| 377 | standard single cartslot. | |
| 378 | */ | |
| 374 | So if next_free_slot==1, we have one cartridge in slot 0. | |
| 375 | In that case we trick the OS to believe that the addressed | |
| 376 | cartridge appears at all locations which causes it to assume a | |
| 377 | standard single cartslot. | |
| 378 | */ | |
| 379 | 379 | if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1) |
| 380 | 380 | slot=0; |
| 381 | 381 | |
| r8044 | r8045 | |
| 387 | 387 | if ((cartridge->grom_size>0) && (cartridge->pcb!=NULL)) |
| 388 | 388 | { |
| 389 | 389 | /* This is the reason why we need the image size: Read |
| 390 | ||
| 390 | access beyond the image size must be detected. */ | |
| 391 | 391 | /* TODO: replace this using a bitmap of the available GROMs */ |
| 392 | 392 | if ((cartslots->grom_address < 0x6000) || (cartslots->grom_address > (cartridge->grom_size+0x6000))) |
| 393 | 393 | value = 0; |
| r8044 | r8045 | |
| 405 | 405 | value = 0; |
| 406 | 406 | //printf("Empty socket at address G(%d)>%04x\n", slot, cartslots->grom_address); |
| 407 | 407 | } |
| 408 | // | |
| 408 | // printf("GROM address (cart) = %04x, reply = %02x\n", cartslots->grom_address, value); | |
| 409 | 409 | /* The program counter wraps at each GROM chip size (8K), |
| 410 | ||
| 410 | so 0x5fff + 1 = 0x4000. */ | |
| 411 | 411 | cartslots->grom_address = ((cartslots->grom_address + 1) & 0x1FFF) | (cartslots->grom_address & 0xE000); |
| 412 | 412 | |
| 413 | 413 | /* Reset the read and write address flipflops. */ |
| r8044 | r8045 | |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | 419 | /* |
| 420 | Find the index of the cartridge name. We assume the format | |
| 421 | <name><number>, i.e. the number is the longest string from the right | |
| 422 | which can be interpreted as a number. | |
| 420 | Find the index of the cartridge name. We assume the format | |
| 421 | <name><number>, i.e. the number is the longest string from the right | |
| 422 | which can be interpreted as a number. | |
| 423 | 423 | */ |
| 424 | 424 | static int get_index_from_tagname(running_device *image) |
| 425 | 425 | { |
| r8044 | r8045 | |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | /* |
| 436 | ||
| 436 | Common routine to assemble cartridges from resources. | |
| 437 | 437 | */ |
| 438 | 438 | static cartridge_t *assemble_common(running_device *cartslot) |
| 439 | 439 | { |
| r8044 | r8045 | |
| 457 | 457 | cartridge = &cartslots->cartridge[slotnumber]; |
| 458 | 458 | |
| 459 | 459 | /* Get the socket which is retrieved by the multicart instance in |
| 460 | ||
| 460 | the state of the cartslot instance. */ | |
| 461 | 461 | socketcont = cartslot_get_socket(cartslot, "grom_socket"); |
| 462 | 462 | reslength = cartslot_get_resource_length(cartslot, "grom_socket"); |
| 463 | 463 | if (socketcont != NULL) |
| r8044 | r8045 | |
| 623 | 623 | */ |
| 624 | 624 | static int assemble_std(running_device *image) |
| 625 | 625 | { |
| 626 | // | |
| 626 | // cartridge_t *cart; | |
| 627 | 627 | // printf("assemble_std, %s\n", image->tag); |
| 628 | 628 | /*cart = */assemble_common(image); |
| 629 | 629 | |
| r8044 | r8045 | |
| 1295 | 1295 | |
| 1296 | 1296 | static int assemble_mbx(running_device *image) |
| 1297 | 1297 | { |
| 1298 | // | |
| 1298 | // cartridge_t *cart; | |
| 1299 | 1299 | |
| 1300 | 1300 | // printf("assemble_mbx, %s\n", image->tag); |
| 1301 | 1301 | /*cart = */assemble_common(image); |
| r8044 | r8045 | |
| 2015 | 2015 | |
| 2016 | 2016 | /* try opening this as a multicart */ |
| 2017 | 2017 | /* This line requires that cartslot_t be included in cartslot.h, |
| 2018 | otherwise one cannot make use of multicart handling within such a | |
| 2019 | custom LOAD function. */ | |
| 2018 | otherwise one cannot make use of multicart handling within such a | |
| 2019 | custom LOAD function. */ | |
| 2020 | 2020 | multicart_open_error me = multicart_open(image_filename(image), image->machine->gamedrv->name, MULTICART_FLAGS_LOAD_RESOURCES, &cart->mc); |
| 2021 | 2021 | |
| 2022 | 2022 | /* Now that we have loaded the image files, let the PCB put them all |
| 2023 | together. This means we put the images in a structure which allows | |
| 2024 | for a quick access by the memory handlers. Every PCB defines an | |
| 2025 | own assembly method. */ | |
| 2023 | together. This means we put the images in a structure which allows | |
| 2024 | for a quick access by the memory handlers. Every PCB defines an | |
| 2025 | own assembly method. */ | |
| 2026 | 2026 | if (me == MCERR_NONE) |
| 2027 | 2027 | result = pcb->assemble(image); |
| 2028 | 2028 | else |
| 2029 | 2029 | fatalerror("Error loading multicart: %s\n", multicart_error_text(me)); |
| 2030 | 2030 | |
| 2031 | 2031 | /* This is for legacy support. If we have no multicart left |
| 2032 | ||
| 2032 | but there are still legacy dumps, we switch to legacy mode. */ | |
| 2033 | 2033 | if (result != INIT_FAIL) |
| 2034 | 2034 | cartslots->multi_slots++; |
| 2035 | 2035 | } |
| r8044 | r8045 | |
| 2127 | 2127 | if (cartridge->grom_size>0) |
| 2128 | 2128 | { |
| 2129 | 2129 | /* This is the reason why we need the image size: Read |
| 2130 | ||
| 2130 | access beyond the image size must be detected. */ | |
| 2131 | 2131 | if ((cartslots->grom_address < 0x6000) || (cartslots->grom_address > (cartridge->grom_size+0x6000))) |
| 2132 | 2132 | return 0; |
| 2133 | 2133 | |
| r8044 | r8045 | |
| 2136 | 2136 | cartslots->grom_buffer = cartridge->grom_ptr[cartslots->grom_address-0x6000]; |
| 2137 | 2137 | // printf("GROM address = %04x, reply = %02x\n", console_GROMs.addr, reply>>8); |
| 2138 | 2138 | /* The program counter wraps at each GROM chip size (8K), |
| 2139 | ||
| 2139 | so 0x5fff + 1 = 0x4000. */ | |
| 2140 | 2140 | cartslots->grom_address = ((cartslots->grom_address + 1) & 0x1FFF) | (cartslots->grom_address & 0xE000); |
| 2141 | 2141 | |
| 2142 | 2142 | /* Reset the read and write address flipflops. */ |
| r8044 | r8045 | |
| 2703 | 2703 | static DEVICE_RESET(ti99_multicart) |
| 2704 | 2704 | { |
| 2705 | 2705 | /* Consider to propagate RESET to cartridges. |
| 2706 | However, schematics do not reveal any pin for resetting a cartridge; | |
| 2707 | the reset line is an input used when plugging in a cartridge. */ | |
| 2706 | However, schematics do not reveal any pin for resetting a cartridge; | |
| 2707 | the reset line is an input used when plugging in a cartridge. */ | |
| 2708 | 2708 | |
| 2709 | 2709 | /* Allows to manually lock the cartslot system to a specific slot. |
| 2710 | ||
| 2710 | We take slot numbers from 0 (automatic mode) to the maximum. */ | |
| 2711 | 2711 | |
| 2712 | 2712 | ti99_multicart_state *cartslots = (ti99_multicart_state *)device->token; |
| 2713 | 2713 | int slotnumber = input_port_read(device->machine, "CARTSLOT"); |
| r8044 | r8045 | |
| 2739 | 2739 | return 0; |
| 2740 | 2740 | |
| 2741 | 2741 | /* Same as above (GROM read): If there is only one cartridge there |
| 2742 | is no use of trying other banks. There is one issue with the | |
| 2743 | selection mechanism: When the console probes the GROM banks and | |
| 2744 | we have a ROM-only cartridge plugged in, it checks bank 0 and bank 1, | |
| 2745 | finds no GROM, and then fails to dummy-check bank 0 again which would | |
| 2746 | have set our cartridge expander to slot 0. But in slot 1 there is no | |
| 2747 | ROM cartridge, so nothing shows up in the selection list. We work | |
| 2748 | around this with the following line. */ | |
| 2742 | is no use of trying other banks. There is one issue with the | |
| 2743 | selection mechanism: When the console probes the GROM banks and | |
| 2744 | we have a ROM-only cartridge plugged in, it checks bank 0 and bank 1, | |
| 2745 | finds no GROM, and then fails to dummy-check bank 0 again which would | |
| 2746 | have set our cartridge expander to slot 0. But in slot 1 there is no | |
| 2747 | ROM cartridge, so nothing shows up in the selection list. We work | |
| 2748 | around this with the following line. */ | |
| 2749 | 2749 | if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1) |
| 2750 | 2750 | slot=0; |
| 2751 | 2751 | |
| r8044 | r8045 | |
| 2780 | 2780 | } |
| 2781 | 2781 | |
| 2782 | 2782 | /* |
| 2783 | Accesses the ROM regions of the cartridge for writing. | |
| 2784 | This is the area from 0x6000 to 0x7fff. Each cartridge is reponsible | |
| 2785 | for all kinds of magic which is done inside this area. Specifically, | |
| 2786 | writing is often used to swap banks for subsequent reads. The actual | |
| 2787 | effect of writing (beyond setting values in a RAM chip) are | |
| 2788 | cartridge-specific and must be handled within the cartridge pcb. | |
| 2789 | The currently set GROM bank determines which cartridge is actually | |
| 2790 | accessed, also for ROM reads. | |
| 2783 | Accesses the ROM regions of the cartridge for writing. | |
| 2784 | This is the area from 0x6000 to 0x7fff. Each cartridge is reponsible | |
| 2785 | for all kinds of magic which is done inside this area. Specifically, | |
| 2786 | writing is often used to swap banks for subsequent reads. The actual | |
| 2787 | effect of writing (beyond setting values in a RAM chip) are | |
| 2788 | cartridge-specific and must be handled within the cartridge pcb. | |
| 2789 | The currently set GROM bank determines which cartridge is actually | |
| 2790 | accessed, also for ROM reads. | |
| 2791 | 2791 | */ |
| 2792 | 2792 | WRITE16_DEVICE_HANDLER( ti99_multicart_w ) |
| 2793 | 2793 | { |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /************************************************************************* |
| 2 | 2 | |
| 3 | Hard disk support | |
| 4 | ||
| 5 | This device wraps the plain image device as that device does not allow | |
| 6 | for internal states (like head position) | |
| 7 | The plain device is a subdevice ("drive") of this device, so we | |
| 8 | get names like "mfmhd0:drive" | |
| 3 | Hard disk support | |
| 9 | 4 | |
| 10 | Michael Zapf, April 2010 | |
| 11 | ||
| 5 | This device wraps the plain image device as that device does not allow | |
| 6 | for internal states (like head position) | |
| 7 | The plain device is a subdevice ("drive") of this device, so we | |
| 8 | get names like "mfmhd0:drive" | |
| 9 | ||
| 10 | Michael Zapf, April 2010 | |
| 11 | ||
| 12 | 12 | **************************************************************************/ |
| 13 | 13 | |
| 14 | 14 | #include "emu.h" |
| r8044 | r8045 | |
| 18 | 18 | |
| 19 | 19 | #include "ti99_hd.h" |
| 20 | 20 | |
| 21 | typedef struct _mfmhd | |
| 21 | typedef struct _mfmhd | |
| 22 | 22 | { |
| 23 | 23 | int current_cylinder; |
| 24 | 24 | int current_head; |
| r8044 | r8045 | |
| 42 | 42 | #endif |
| 43 | 43 | |
| 44 | 44 | /* |
| 45 | ||
| 45 | Returns the linear sector number, given the CHS data. | |
| 46 | 46 | */ |
| 47 | 47 | static int harddisk_chs_to_lba(hard_disk_file *hdfile, int cylinder, int head, int sector, UINT32 *lba) |
| 48 | 48 | { |
| 49 | 49 | const hard_disk_info *info; |
| 50 | ||
| 51 | if ( hdfile != NULL) | |
| 50 | ||
| 51 | if ( hdfile != NULL) | |
| 52 | 52 | { |
| 53 | 53 | info = hard_disk_get_info(hdfile); |
| 54 | 54 | |
| 55 | if ( (cylinder >= info->cylinders) || | |
| 56 | (head >= info->heads) || | |
| 55 | if ( (cylinder >= info->cylinders) || | |
| 56 | (head >= info->heads) || | |
| 57 | 57 | (sector >= info->sectors)) |
| 58 | 58 | return FALSE; |
| 59 | ||
| 59 | ||
| 60 | 60 | *lba = (cylinder * info->heads + head) |
| 61 | * info->sectors | |
| 61 | * info->sectors | |
| 62 | 62 | + sector; |
| 63 | 63 | return TRUE; |
| 64 | 64 | } |
| r8044 | r8045 | |
| 75 | 75 | |
| 76 | 76 | *sector_length = 256; |
| 77 | 77 | *buf = (UINT8 *)malloc(*sector_length); |
| 78 | ||
| 78 | ||
| 79 | 79 | if (cylinder != hd->current_cylinder) |
| 80 | { | |
| 80 | { | |
| 81 | 81 | return; |
| 82 | 82 | } |
| 83 | ||
| 83 | ||
| 84 | 84 | if (file==NULL) |
| 85 | 85 | { |
| 86 | 86 | hd->status &= ~MFMHD_READY; |
| r8044 | r8045 | |
| 121 | 121 | hd->status |= MFMHD_WRFAULT; |
| 122 | 122 | return; |
| 123 | 123 | } |
| 124 | ||
| 124 | ||
| 125 | 125 | if (!hard_disk_write(file, lba, buf)) |
| 126 | 126 | { |
| 127 | 127 | hd->status &= ~MFMHD_READY; |
| 128 | 128 | hd->status |= MFMHD_WRFAULT; |
| 129 | 129 | return; |
| 130 | 130 | } |
| 131 | ||
| 131 | ||
| 132 | 132 | hd->status |= MFMHD_READY; |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | 135 | #define TI99HD_BLOCKNOTFOUND -1 |
| 136 | 136 | |
| 137 | 137 | /* |
| 138 | Searches a block containing number * byte, starting at the given | |
| 139 | position. Returns the position of the first byte of the block. | |
| 138 | Searches a block containing number * byte, starting at the given | |
| 139 | position. Returns the position of the first byte of the block. | |
| 140 | 140 | */ |
| 141 | 141 | static int find_block(const UINT8 *buffer, int start, int stop, UINT8 byte, size_t number) |
| 142 | 142 | { |
| r8044 | r8045 | |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | /* |
| 165 | Reads a complete track. We have to rebuild the gaps. This is basically | |
| 166 | done in the same way as in the SDF format in ti99_dsk. | |
| 167 | ||
| 168 | WARNING: This function is untested! We need to create a suitable | |
| 169 | application program for the TI which makes use of it. | |
| 165 | Reads a complete track. We have to rebuild the gaps. This is basically | |
| 166 | done in the same way as in the SDF format in ti99_dsk. | |
| 167 | ||
| 168 | WARNING: This function is untested! We need to create a suitable | |
| 169 | application program for the TI which makes use of it. | |
| 170 | 170 | */ |
| 171 | 171 | void ti99_mfm_harddisk_read_track(running_device *harddisk, int head, UINT8 **pbuffer, int *data_count) |
| 172 | 172 | { |
| r8044 | r8045 | |
| 174 | 174 | running_device *drive = harddisk->subdevice("drive"); |
| 175 | 175 | |
| 176 | 176 | /* We assume an interleave of 3 for 32 sectors. */ |
| 177 | int step = 3; | |
| 177 | int step = 3; | |
| 178 | 178 | UINT32 lba; |
| 179 | 179 | int i; |
| 180 | 180 | |
| r8044 | r8045 | |
| 197 | 197 | hd->status &= ~MFMHD_READY; |
| 198 | 198 | return; |
| 199 | 199 | } |
| 200 | ||
| 200 | ||
| 201 | 201 | info = hard_disk_get_info(file); |
| 202 | 202 | |
| 203 | 203 | count = info->sectors; |
| 204 | 204 | size = info->sectorbytes/128; |
| 205 | ||
| 205 | ||
| 206 | 206 | *data_count = gap1 + count*(sync+12+gap2+sync+size*128+gap3)+gap4; |
| 207 | ||
| 207 | ||
| 208 | 208 | UINT8 *trackdata = (UINT8*)malloc(*data_count); |
| 209 | ||
| 209 | ||
| 210 | 210 | /* Write lead-in. */ |
| 211 | 211 | memset(trackdata, 0x4e, gap1); |
| 212 | 212 | |
| 213 | 213 | position += gap1; |
| 214 | 214 | for (i=0; i < info->sectors; i++) |
| 215 | 215 | { |
| 216 | sector = (i*step) % info->sectors; | |
| 216 | sector = (i*step) % info->sectors; | |
| 217 | 217 | memset(&trackdata[position], 0x00, sync); |
| 218 | 218 | position += 10; |
| 219 | ||
| 220 | /* Write sync */ | |
| 219 | ||
| 220 | /* Write sync */ | |
| 221 | 221 | trackdata[position++] = 0xa1; |
| 222 | 222 | |
| 223 | 223 | /* Write IDAM */ |
| 224 | trackdata[position++] = cylinder_to_ident(hd->current_cylinder); | |
| 224 | trackdata[position++] = cylinder_to_ident(hd->current_cylinder); | |
| 225 | 225 | trackdata[position++] = hd->current_cylinder; |
| 226 | 226 | trackdata[position++] = head; |
| 227 | 227 | trackdata[position++] = sector; |
| 228 | 228 | trackdata[position++] = (size==1)? 0x00 : (0x01 << (size-1)); |
| 229 | ||
| 229 | ||
| 230 | 230 | /* Set CRC16 */ |
| 231 | 231 | crc = ccitt_crc16(0xffff, &trackdata[position-5], 5); |
| 232 | 232 | trackdata[position++] = (crc>>8)&0xff; |
| 233 | 233 | trackdata[position++] = crc & 0xff; |
| 234 | ||
| 234 | ||
| 235 | 235 | /* Write Gap2 */ |
| 236 | 236 | memset(&trackdata[position], 0x4e, gap2); |
| 237 | 237 | position += gap2; |
| r8044 | r8045 | |
| 243 | 243 | |
| 244 | 244 | /* Write DAM */ |
| 245 | 245 | trackdata[position++] = 0xfb; |
| 246 | ||
| 246 | ||
| 247 | 247 | /* Locate the sector content in the image and load it. */ |
| 248 | ||
| 248 | ||
| 249 | 249 | if (!harddisk_chs_to_lba(file, hd->current_cylinder, head, sector, &lba)) |
| 250 | 250 | { |
| 251 | 251 | hd->status &= ~MFMHD_READY; |
| 252 | 252 | free(trackdata); |
| 253 | 253 | return; |
| 254 | 254 | } |
| 255 | ||
| 255 | ||
| 256 | 256 | if (!hard_disk_read(file, lba, &trackdata[position])) |
| 257 | 257 | { |
| 258 | 258 | hd->status &= ~MFMHD_READY; |
| 259 | 259 | free(trackdata); |
| 260 | 260 | return; |
| 261 | 261 | } |
| 262 | ||
| 262 | ||
| 263 | 263 | position += size; |
| 264 | ||
| 264 | ||
| 265 | 265 | /* Set CRC16. Includes the address mark. */ |
| 266 | 266 | crc = ccitt_crc16(0xffff, &trackdata[position-size-1], size+1); |
| 267 | 267 | trackdata[position++] = (crc>>8)&0xff; |
| 268 | 268 | trackdata[position++] = crc & 0xff; |
| 269 | ||
| 270 | /* Write remaining 3 bytes which would have been used for ECC. */ | |
| 269 | ||
| 270 | /* Write remaining 3 bytes which would have been used for ECC. */ | |
| 271 | 271 | memset(&trackdata[position], 0x00, 3); |
| 272 | 272 | position += 3; |
| 273 | ||
| 273 | ||
| 274 | 274 | /* Write Gap3 */ |
| 275 | 275 | memset(&trackdata[position], 0x4e, gap3); |
| 276 | 276 | position += gap3; |
| r8044 | r8045 | |
| 280 | 280 | position += gap4; |
| 281 | 281 | |
| 282 | 282 | *pbuffer = trackdata; |
| 283 | ||
| 283 | ||
| 284 | 284 | /* Remember to free the buffer! Except when an error has occured, |
| 285 | ||
| 285 | the function returns a newly allocated buffer. */ | |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | 288 | /* |
| 289 | Writes a track to the image. We need to isolate the sector contents. | |
| 290 | This is basically done in the same way as in the SDF format in ti99_dsk. | |
| 289 | Writes a track to the image. We need to isolate the sector contents. | |
| 290 | This is basically done in the same way as in the SDF format in ti99_dsk. | |
| 291 | 291 | */ |
| 292 | 292 | void ti99_mfm_harddisk_write_track(running_device *harddisk, int head, UINT8 *track_image, int data_count) |
| 293 | 293 | { |
| r8044 | r8045 | |
| 296 | 296 | UINT8 wident, whead = 0, wsector = 0, wsize; |
| 297 | 297 | UINT16 wcyl = 0; |
| 298 | 298 | int state; |
| 299 | ||
| 299 | ||
| 300 | 300 | /* Only search in the first 100 bytes for the start. */ |
| 301 | 301 | int gap1 = 16; |
| 302 | 302 | int sync = 13; |
| 303 | ||
| 303 | ||
| 304 | 304 | UINT32 lba; |
| 305 | 305 | mfmhd_state *hd = (mfmhd_state *)harddisk->token; |
| 306 | 306 | running_device *drive = harddisk->subdevice("drive"); |
| r8044 | r8045 | |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | 317 | current_pos = find_block(track_image, 0, 100, 0x4e, gap1); |
| 318 | ||
| 318 | ||
| 319 | 319 | /* In case of defect formats, we continue as far as possible. This |
| 320 | ||
| 320 | may lead to sectors not being written. */ | |
| 321 | 321 | if (current_pos==TI99HD_BLOCKNOTFOUND) |
| 322 | 322 | { |
| 323 | 323 | logerror("ti99_hd Cannot find gap1 for cylinder %d, head %d.\n", hd->current_cylinder, head); |
| r8044 | r8045 | |
| 328 | 328 | /* Get behind GAP1 */ |
| 329 | 329 | current_pos += gap1; |
| 330 | 330 | found = FALSE; |
| 331 | ||
| 331 | ||
| 332 | 332 | while (current_pos < data_count) |
| 333 | 333 | { |
| 334 | 334 | /* We must find the address block to determine the sector. */ |
| r8044 | r8045 | |
| 342 | 342 | } |
| 343 | 343 | found = TRUE; |
| 344 | 344 | |
| 345 | new_pos = new_pos + sync; /* skip sync bytes */ | |
| 345 | new_pos = new_pos + sync; /* skip sync bytes */ | |
| 346 | 346 | |
| 347 | 347 | if (track_image[new_pos]==0xa1) |
| 348 | 348 | { |
| r8044 | r8045 | |
| 367 | 367 | new_pos = find_block(track_image, current_pos, data_count, 0x00, sync); |
| 368 | 368 | current_pos = new_pos + sync; |
| 369 | 369 | if (track_image[current_pos]==0xa1) |
| 370 | { | |
| 370 | { | |
| 371 | 371 | current_pos += 2; |
| 372 | 372 | state = hard_disk_write(file, lba, track_image+current_pos); |
| 373 | 373 | if (state==0) |
| r8044 | r8045 | |
| 382 | 382 | else |
| 383 | 383 | { |
| 384 | 384 | logerror("ti99_hd Cannot find DAM for cylinder %d, head %d, sector %d.\n", wcyl, whead, wsector); |
| 385 | return; | |
| 385 | return; | |
| 386 | 386 | } |
| 387 | 387 | } |
| 388 | 388 | else |
| r8044 | r8045 | |
| 393 | 393 | else |
| 394 | 394 | { |
| 395 | 395 | printf("ti99_hd Cannot find IDAM for cylinder %d, head %d, sector %d.\n", wcyl, whead, wsector); |
| 396 | return; | |
| 396 | return; | |
| 397 | 397 | } |
| 398 | 398 | } |
| 399 | 399 | } |
| r8044 | r8045 | |
| 405 | 405 | mfmhd_state *hd = (mfmhd_state *)harddisk->token; |
| 406 | 406 | drive = harddisk->subdevice("drive"); |
| 407 | 407 | hard_disk_file *file = mess_hd_get_hard_disk_file(drive); |
| 408 | ||
| 408 | ||
| 409 | 409 | if (file!=NULL) |
| 410 | 410 | status |= MFMHD_READY; |
| 411 | 411 | |
| 412 | 412 | if (hd->current_cylinder==0) |
| 413 | 413 | status |= MFMHD_TRACK00; |
| 414 | ||
| 414 | ||
| 415 | 415 | if (!hd->seeking) |
| 416 | 416 | status |= MFMHD_SEEKCOMP; |
| 417 | ||
| 417 | ||
| 418 | 418 | if (hd->id_index == 0) |
| 419 | 419 | status |= MFMHD_INDEX; |
| 420 | ||
| 420 | ||
| 421 | 421 | hd->status = status; |
| 422 | 422 | return status; |
| 423 | 423 | } |
| r8044 | r8045 | |
| 429 | 429 | const hard_disk_info *info; |
| 430 | 430 | hard_disk_file *file = mess_hd_get_hard_disk_file(drive); |
| 431 | 431 | |
| 432 | if (file==NULL) return; | |
| 433 | ||
| 432 | if (file==NULL) return; | |
| 433 | ||
| 434 | 434 | info = hard_disk_get_info(file); |
| 435 | 435 | |
| 436 | 436 | hd->seeking = TRUE; |
| r8044 | r8045 | |
| 445 | 445 | if (hd->current_cylinder < info->cylinders) |
| 446 | 446 | hd->current_cylinder++; |
| 447 | 447 | } |
| 448 | ||
| 448 | ||
| 449 | 449 | hd->seeking = FALSE; |
| 450 | 450 | } |
| 451 | 451 | |
| r8044 | r8045 | |
| 463 | 463 | hd->status &= ~MFMHD_READY; |
| 464 | 464 | return; |
| 465 | 465 | } |
| 466 | ||
| 466 | ||
| 467 | 467 | info = hard_disk_get_info(file); |
| 468 | ||
| 468 | ||
| 469 | 469 | hd->current_head = head; |
| 470 | ||
| 470 | ||
| 471 | 471 | /* TODO: implement an interleave suitable for the number of sectors in the track. */ |
| 472 | 472 | hd->id_index = (hd->id_index + interleave) % info->sectors; |
| 473 | ||
| 473 | ||
| 474 | 474 | /* build a new info block. */ |
| 475 | 475 | id->C = hd->current_cylinder; |
| 476 | 476 | id->H = hd->current_head; |
| r8044 | r8045 | |
|---|---|---|
| 13 | 13 | /* typedef struct _mfmhd_config mfmhd_config; |
| 14 | 14 | struct _mfmhd_config |
| 15 | 15 | { |
| 16 | device_start_func device_start; | |
| 17 | device_image_load_func device_load; | |
| 18 | device_image_unload_func device_unload; | |
| 16 | device_start_func device_start; | |
| 17 | device_image_load_func device_load; | |
| 18 | device_image_unload_func device_unload; | |
| 19 | 19 | }; */ |
| 20 | 20 | |
| 21 | 21 | /* Accessor functions */ |
| r8044 | r8045 | |
| 42 | 42 | |
| 43 | 43 | |
| 44 | 44 | /* |
| 45 | MDRV_MFMHD_START(mfmhd) \ | |
| 46 | MDRV_MFMHD_LOAD(mfmhd) \ | |
| 47 | MDRV_MFMHD_UNLOAD(mfmhd) | |
| 45 | MDRV_MFMHD_START(mfmhd) \ | |
| 46 | MDRV_MFMHD_LOAD(mfmhd) \ | |
| 47 | MDRV_MFMHD_UNLOAD(mfmhd) | |
| 48 | 48 | */ |
| r8044 | r8045 | |
|---|---|---|
| 197 | 197 | for (j=0;j<size;j++) { |
| 198 | 198 | if (p[j]==',') p[j]=0; |
| 199 | 199 | } |
| 200 | ||
| 200 | ||
| 201 | 201 | /* try to parse each option */ |
| 202 | 202 | while(p <= e) |
| 203 | 203 | { |
| r8044 | r8045 | |
|---|---|---|
| 258 | 258 | */ |
| 259 | 259 | static int assemble_std(running_machine *machine, running_device *image) |
| 260 | 260 | { |
| 261 | // | |
| 261 | // aescartridge_t *cart; | |
| 262 | 262 | // printf("assemble_std, %s\n", image->tag); |
| 263 | 263 | /*cart = */assemble_common(machine, image); |
| 264 | 264 | |
| r8044 | r8045 | |
| 274 | 274 | */ |
| 275 | 275 | static int disassemble_std(running_device *image) |
| 276 | 276 | { |
| 277 | // | |
| 277 | // int slotnumber; | |
| 278 | 278 | // int i; |
| 279 | // aescartridge_t *cart; | |
| 280 | // running_device *cartsys = image->owner; | |
| 281 | // aes_multicart_t *cartslots = (aes_multicart_t *)cartsys->token; | |
| 279 | // aescartridge_t *cart; | |
| 280 | // running_device *cartsys = image->owner; | |
| 281 | // aes_multicart_t *cartslots = (aes_multicart_t *)cartsys->token; | |
| 282 | 282 | |
| 283 | // | |
| 283 | // slotnumber = get_index_from_tagname(image)-1; | |
| 284 | 284 | // printf("Disassemble cartridge %d\n", slotnumber); |
| 285 | 285 | #if 0 |
| 286 | 286 | /* Search the highest remaining cartridge. */ |
| r8044 | r8045 | |
| 299 | 299 | } |
| 300 | 300 | #endif |
| 301 | 301 | /* Do we have RAM? If so, swap the bytes (undo the BIG_ENDIANIZE) */ |
| 302 | // | |
| 302 | // cart = &cartslots->cartridge[slotnumber]; | |
| 303 | 303 | |
| 304 | 304 | // clear_slot(cartsys, slotnumber); |
| 305 | 305 |
| r8044 | r8045 | |
|---|---|---|
| 154 | 154 | |
| 155 | 155 | |
| 156 | 156 | /*------------------------------------------------- |
| 157 | software_name_split | |
| 158 | helper; splits a software_list:software:part | |
| 157 | software_name_split | |
| 158 | helper; splits a software_list:software:part | |
| 159 | 159 | string into seperate software_list, software, |
| 160 | 160 | and part strings. |
| 161 | 161 | |
| 162 | 162 | str1:str2:str3 => swlist_name - str1, swname - str2, swpart - str3 |
| 163 | str1:str2 => swlist_name - NULL, swname - str1, swpart - str2 | |
| 164 | str1 => swlist_name - NULL, swname - str1, swpart - NULL | |
| 163 | str1:str2 => swlist_name - NULL, swname - str1, swpart - str2 | |
| 164 | str1 => swlist_name - NULL, swname - str1, swpart - NULL | |
| 165 | 165 | |
| 166 | 166 | swlist_namem, swnane and swpart will be global_alloc'ed |
| 167 | 167 | from the global pool. So they should be global_free'ed |
| r8044 | r8045 | |
| 737 | 737 | if (filerr != FILERR_NONE) |
| 738 | 738 | goto error; |
| 739 | 739 | |
| 740 | // if (is_preload) | |
| 741 | // software_list_parse(swlist, swlist->error_proc, NULL); | |
| 740 | // if (is_preload) | |
| 741 | // software_list_parse(swlist, swlist->error_proc, NULL); | |
| 742 | 742 | |
| 743 | 743 | return swlist; |
| 744 | 744 | |
| r8044 | r8045 | |
| 757 | 757 | { |
| 758 | 758 | if (swlist == NULL) |
| 759 | 759 | return; |
| 760 | ||
| 760 | ||
| 761 | 761 | if (swlist->file) |
| 762 | 762 | mame_fclose(swlist->file); |
| 763 | 763 | pool_free_lib(swlist->pool); |
| r8044 | r8045 | |
| 973 | 973 | software_info_ptr = software_list_find( software_list_ptr, swname ); |
| 974 | 974 | |
| 975 | 975 | if ( software_info_ptr ) |
| 976 | { | |
| 976 | { | |
| 977 | 977 | software_part_ptr = software_find_part( software_info_ptr, swpart, interface ); |
| 978 | 978 | } |
| 979 | 979 | } |
| r8044 | r8045 | |
| 1077 | 1077 | { |
| 1078 | 1078 | if (swlist->list_name[i]) |
| 1079 | 1079 | { |
| 1080 | if (mame_options() == NULL) | |
| 1080 | if (mame_options() == NULL) | |
| 1081 | 1081 | return FALSE; |
| 1082 | ||
| 1082 | ||
| 1083 | 1083 | software_list *list = software_list_open(mame_options(), swlist->list_name[i], FALSE, NULL); |
| 1084 | 1084 | |
| 1085 | 1085 | /* if no .xml list is found, then return (this happens e.g. if you moved/renamed the xml list) */ |
| 1086 | if (list == NULL) | |
| 1086 | if (list == NULL) | |
| 1087 | 1087 | return FALSE; |
| 1088 | 1088 | |
| 1089 | 1089 | for (software_info *swinfo = software_list_first(list); swinfo != NULL; swinfo = software_list_next(list)) |
| r8044 | r8045 | |
| 1099 | 1099 | mame_printf_error("%s: %s has no description\n", swlist->list_name[i], swinfo->shortname); |
| 1100 | 1100 | return TRUE; |
| 1101 | 1101 | } |
| 1102 | ||
| 1102 | ||
| 1103 | 1103 | /* Did we lost any year? */ |
| 1104 | 1104 | if (swinfo->year == NULL) |
| 1105 | 1105 | { |
| 1106 | 1106 | mame_printf_error("%s: %s has no year\n", swlist->list_name[i], swinfo->shortname); |
| 1107 | 1107 | return TRUE; |
| 1108 | 1108 | } |
| 1109 | ||
| 1109 | ||
| 1110 | 1110 | /* Did we lost any publisher? */ |
| 1111 | 1111 | if (swinfo->publisher == NULL) |
| 1112 | 1112 | { |
| 1113 | 1113 | mame_printf_error("%s: %s has no publisher\n", swlist->list_name[i], swinfo->shortname); |
| 1114 | 1114 | return TRUE; |
| 1115 | 1115 | } |
| 1116 | ||
| 1116 | ||
| 1117 | 1117 | /* Second, since the xml is fine, run additional checks: */ |
| 1118 | 1118 | |
| 1119 | 1119 | /* check for duplicate names */ |
| r8044 | r8045 | |
| 1123 | 1123 | mame_printf_error("%s: %s is a duplicate name (%s)\n", swlist->list_name[i], swinfo->shortname, match->shortname); |
| 1124 | 1124 | error = TRUE; |
| 1125 | 1125 | } |
| 1126 | ||
| 1126 | ||
| 1127 | 1127 | /* check for duplicate descriptions */ |
| 1128 | 1128 | if (descriptions.add(swinfo->longname, swinfo, FALSE) == TMERR_DUPLICATE) |
| 1129 | 1129 | { |
| r8044 | r8045 | |
| 1131 | 1131 | mame_printf_error("%s: %s is a duplicate description (%s)\n", swlist->list_name[i], swinfo->longname, match->longname); |
| 1132 | 1132 | error = TRUE; |
| 1133 | 1133 | } |
| 1134 | ||
| 1134 | ||
| 1135 | 1135 | if (swinfo->parentname != NULL) |
| 1136 | 1136 | is_clone = 1; |
| 1137 | ||
| 1137 | ||
| 1138 | 1138 | /* make sure the driver name is 8 chars or less */ |
| 1139 | 1139 | if ((is_clone && strlen(swinfo->shortname) > NAME_LEN_CLONE) || ((!is_clone) && strlen(swinfo->shortname) > NAME_LEN_PARENT)) |
| 1140 | 1140 | { |
| r8044 | r8045 | |
| 1142 | 1142 | is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); |
| 1143 | 1143 | error = TRUE; |
| 1144 | 1144 | } |
| 1145 | ||
| 1145 | ||
| 1146 | 1146 | /* make sure the year is only digits, '?' or '+' */ |
| 1147 | 1147 | for (s = swinfo->year; *s; s++) |
| 1148 | 1148 | if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') |
| r8044 | r8045 | |
| 1159 | 1159 | } |
| 1160 | 1160 | } |
| 1161 | 1161 | return error; |
| 1162 | } | |
| 1162 | } | |
| 1163 | 1163 | |
| 1164 | 1164 | DEVICE_GET_INFO( software_list ) |
| 1165 | 1165 | { |
| r8044 | r8045 | |
|---|---|---|
| 2 | 2 | #include <windows.h> |
| 3 | 3 | #include <ctype.h> |
| 4 | 4 | #include <tchar.h> |
| 5 | #include <shlwapi.h> | |
| 5 | #include <shlwapi.h> | |
| 6 | 6 | #include <stdio.h> |
| 7 | 7 | #include <ctype.h> |
| 8 | 8 | |
| r8044 | r8045 | |
| 139 | 139 | if (tempstr) |
| 140 | 140 | osd_free(tempstr); |
| 141 | 141 | return filerr; |
| 142 | } | |
| 142 | } | |
| 143 | 143 | |
| 144 | 144 | |
| 145 | 145 | //============================================================ |
| r8044 | r8045 | |
| 153 | 153 | return win_error_to_mame_file_error(GetLastError()); |
| 154 | 154 | |
| 155 | 155 | return FILERR_NONE; |
| 156 | } | |
| 156 | } | |
| 157 | 157 | |
| 158 | 158 | /*************************************************************************** |
| 159 | 159 | CORE IMPLEMENTATION |
| r8044 | r8045 | |
|---|---|---|
| 257 | 257 | err = read_sector_data(dialog, new_track, new_head, new_sector); |
| 258 | 258 | // TODO: this causes a stack overflow |
| 259 | 259 | //if (err) |
| 260 | // | |
| 260 | // set_sector_text(dialog); | |
| 261 | 261 | } |
| 262 | 262 | } |
| 263 | 263 |
| r8044 | r8045 | |
|---|---|---|
| 1519 | 1519 | |
| 1520 | 1520 | /* move existing entries forward */ |
| 1521 | 1521 | memmove(new_created_entry + 32, created_entry, created_entry_len); |
| 1522 | ||
| 1523 | if (created_entry) free(created_entry); | |
| 1522 | ||
| 1523 | if (created_entry) free(created_entry); | |
| 1524 | 1524 | created_entry = new_created_entry; |
| 1525 | 1525 | created_entry_len += 32; |
| 1526 | 1526 |
| r8044 | r8045 | |
|---|---|---|
| 115 | 115 | { |
| 116 | 116 | t6721_state *t6721 = (t6721_state *)ptr; |
| 117 | 117 | |
| 118 | if (!t6721->playing) | |
| 118 | if (!t6721->playing) | |
| 119 | 119 | return; |
| 120 | 120 | |
| 121 | if (t6721->sample_timeindex < 8000 / 50) | |
| 121 | if (t6721->sample_timeindex < 8000 / 50) | |
| 122 | 122 | { |
| 123 | 123 | t6721->sample_timeindex++; |
| 124 | } | |
| 125 | else | |
| 124 | } | |
| 125 | else | |
| 126 | 126 | { |
| 127 | 127 | t6721->end_of_sample = (memcmp(t6721->sample_data, "\xff\xff\xff\xff\xff\xff", 6) == 0); |
| 128 | 128 | |
| r8044 | r8045 | |
| 137 | 137 | |
| 138 | 138 | DBG_LOG(2, "364", ("port write %.2x %.2x\n", offset, data)); |
| 139 | 139 | |
| 140 | switch (offset) | |
| 140 | switch (offset) | |
| 141 | 141 | { |
| 142 | 142 | case 0: |
| 143 | if (data & 0x80) | |
| 143 | if (data & 0x80) | |
| 144 | 144 | { |
| 145 | switch (t6721->command_state) | |
| 145 | switch (t6721->command_state) | |
| 146 | 146 | { |
| 147 | 147 | case 0: |
| 148 | switch (t6721->command_data) | |
| 148 | switch (t6721->command_data) | |
| 149 | 149 | { |
| 150 | 150 | case 9: case 0xb: |
| 151 | 151 | t6721->playing = 0; |
| r8044 | r8045 | |
| 178 | 178 | t6721->command_state = 0; |
| 179 | 179 | break; |
| 180 | 180 | } |
| 181 | } | |
| 182 | else | |
| 181 | } | |
| 182 | else | |
| 183 | 183 | { |
| 184 | 184 | t6721->command_data = data; |
| 185 | 185 | } |
| r8044 | r8045 | |
| 212 | 212 | t6721_state *t6721 = get_safe_token(device); |
| 213 | 213 | |
| 214 | 214 | int data = 0xff; |
| 215 | switch (offset) | |
| 215 | switch (offset) | |
| 216 | 216 | { |
| 217 | 217 | case 1: |
| 218 | 218 | data = t6721->state; |
| 219 | 219 | data = 1; |
| 220 | if (!t6721->end_of_sample) | |
| 220 | if (!t6721->end_of_sample) | |
| 221 | 221 | { |
| 222 | 222 | data |= 0x41; |
| 223 | if (!t6721->busy) | |
| 223 | if (!t6721->busy) | |
| 224 | 224 | data |= 0x81; |
| 225 | 225 | } |
| 226 | 226 | break; |
| r8044 | r8045 | |
|---|---|---|
| 512 | 512 | assert(device != NULL); |
| 513 | 513 | assert(device->type == SOUND); |
| 514 | 514 | assert(sound_get_type(device) == TED7360); |
| 515 | ||
| 515 | ||
| 516 | 516 | return (const ted7360_interface *) device->baseconfig().static_config; |
| 517 | 517 | } |
| 518 | 518 | |
| r8044 | r8045 | |
| 1286 | 1286 | |
| 1287 | 1287 | if (TONE1_ON) |
| 1288 | 1288 | { |
| 1289 | if (ted7360->tone1pos <= ted7360->tone1samples / 2 || !TONE_ON) | |
| 1289 | if (ted7360->tone1pos <= ted7360->tone1samples / 2 || !TONE_ON) | |
| 1290 | 1290 | v += 0x2ff; // depends on the volume between sound and noise |
| 1291 | 1291 | |
| 1292 | 1292 | ted7360->tone1pos++; |
| 1293 | 1293 | |
| 1294 | if (ted7360->tone1pos > ted7360->tone1samples) | |
| 1294 | if (ted7360->tone1pos > ted7360->tone1samples) | |
| 1295 | 1295 | ted7360->tone1pos = 0; |
| 1296 | 1296 | } |
| 1297 | 1297 | |
| r8044 | r8045 | |
| 1299 | 1299 | { |
| 1300 | 1300 | if (TONE2_ON) |
| 1301 | 1301 | { /*higher priority ?! */ |
| 1302 | if (ted7360->tone2pos <= ted7360->tone2samples / 2 || !TONE_ON) | |
| 1302 | if (ted7360->tone2pos <= ted7360->tone2samples / 2 || !TONE_ON) | |
| 1303 | 1303 | v += 0x2ff; |
| 1304 | 1304 | |
| 1305 | 1305 | ted7360->tone2pos++; |
| 1306 | 1306 | |
| 1307 | if (ted7360->tone2pos > ted7360->tone2samples) | |
| 1307 | if (ted7360->tone2pos > ted7360->tone2samples) | |
| 1308 | 1308 | ted7360->tone2pos = 0; |
| 1309 | 1309 | } |
| 1310 | 1310 | else |
| r8044 | r8045 | |
|---|---|---|
| 11 | 11 | Ive seen mentions of a 006, 011 and 015 on part miner sites. |
| 12 | 12 | Since the chip generates tones using embeded wavetables, |
| 13 | 13 | it is probable other sounds are possible and were made for other embeded systems. |
| 14 | Its anyone's guess at this point in which products. | |
| 15 | ||
| 14 | Its anyone's guess at this point in which products. | |
| 15 | ||
| 16 | 16 | upd17XXX devices are typically 4bit NEC MCUs, so it wouldnt be a stretch to |
| 17 | say that this chip is part of that lot. | |
| 17 | say that this chip is part of that lot. | |
| 18 | 18 | Maybe mask roms 006,011 and 015 dont generate audio at all. |
| 19 | 19 | |
| 20 | 20 | Used pinout in the SCV: |
| r8044 | r8045 | |
| 66 | 66 | |
| 67 | 67 | #define LOG 0 |
| 68 | 68 | |
| 69 | #define MAX_PACKET_SIZE 0x8000 | |
| 69 | #define MAX_PACKET_SIZE 0x8000 | |
| 70 | 70 | |
| 71 | 71 | |
| 72 | 72 | size_t g_count = 0; |
| r8044 | r8045 | |
| 232 | 232 | }break; |
| 233 | 233 | |
| 234 | 234 | case 0x1F: |
| 235 | { | |
| 235 | { | |
| 236 | 236 | //6Khz(ish) DIGI playback |
| 237 | ||
| 237 | ||
| 238 | 238 | //end capture |
| 239 | 239 | if (state->packet[state->index-2] == 0xFE && |
| 240 | 240 | state->packet[state->index-1] == 0x00){ |
| r8044 | r8045 | |
| 248 | 248 | }break; |
| 249 | 249 | |
| 250 | 250 | //garbage: wipe stack |
| 251 | default: | |
| 251 | default: | |
| 252 | 252 | state->index = 0; |
| 253 | 253 | break; |
| 254 | 254 | } |
| r8044 | r8045 | |
| 261 | 261 | |
| 262 | 262 | //RESET upon HIGH |
| 263 | 263 | if (state != upd1771->pc3){ |
| 264 | ||
| 264 | ||
| 265 | 265 | upd1771->index = 0; |
| 266 | 266 | upd1771->packet[0]=0; |
| 267 | 267 | } |
| r8044 | r8045 | |
|---|---|---|
| 414 | 414 | if (that_device->get_config_int(DEVINFO_INT_IMAGE_TYPE) == type) |
| 415 | 415 | count++; |
| 416 | 416 | } |
| 417 | ||
| 417 | ||
| 418 | 418 | |
| 419 | 419 | /* need to number if there is more than one device */ |
| 420 | 420 | if (count > 1) |
| r8044 | r8045 | |
|---|---|---|
| 115 | 115 | fprintf(out, "\t\t<ramoption>%u</ramoption>\n", messram_parse_string(p)); |
| 116 | 116 | p += strlen(p); |
| 117 | 117 | if (p == e) |
| 118 | break; | |
| 118 | break; | |
| 119 | 119 | p += 1; |
| 120 | 120 | } |
| 121 | 121 |
| r8044 | r8045 | |
|---|---|---|
| 4 | 4 | video hardware |
| 5 | 5 | Juergen Buchmueller <pullmoll@t-online.de>, Dec 1999 |
| 6 | 6 | |
| 7 | ||
| 7 | Tests of keyboard. Start mbeeic. | |
| 8 | 8 | |
| 9 | 1. Load ASTEROIDS PLUS, stay in attract mode, hold down spacebar, | |
| 10 | it should only fire bullets. If it sometimes starts turning, | |
| 11 | thrusting or using the shield, then there is a problem. | |
| 9 | 1. Load ASTEROIDS PLUS, stay in attract mode, hold down spacebar, | |
| 10 | it should only fire bullets. If it sometimes starts turning, | |
| 11 | thrusting or using the shield, then there is a problem. | |
| 12 | 12 | |
| 13 | 2. Load SCAVENGER and make sure it doesn't go to the next level | |
| 14 | until you find the Exit. | |
| 13 | 2. Load SCAVENGER and make sure it doesn't go to the next level | |
| 14 | until you find the Exit. | |
| 15 | 15 | |
| 16 | 3. At the Basic prompt, type in EDASM press enter. At the memory size | |
| 17 | prompt press enter. Now, make sure the keyboard works properly. | |
| 16 | 3. At the Basic prompt, type in EDASM press enter. At the memory size | |
| 17 | prompt press enter. Now, make sure the keyboard works properly. | |
| 18 | 18 | |
| 19 | 19 | |
| 20 | The keyboard can be accessed either by using the transparent-mode | |
| 21 | registers, or by monitoring the lightpen registers, or by monitoring | |
| 22 | the lightpen strobe bit in the status register. | |
| 20 | The keyboard can be accessed either by using the transparent-mode | |
| 21 | registers, or by monitoring the lightpen registers, or by monitoring | |
| 22 | the lightpen strobe bit in the status register. | |
| 23 | 23 | |
| 24 | Edasm is an example of the latter; it is therefore necessary to do a | |
| 25 | keyboard scan whenever the status is read. | |
| 24 | Edasm is an example of the latter; it is therefore necessary to do a | |
| 25 | keyboard scan whenever the status is read. | |
| 26 | 26 | |
| 27 | 27 | ****************************************************************************/ |
| 28 | 28 |
| r8044 | r8045 | |
|---|---|---|
| 9 | 9 | |
| 10 | 10 | /* |
| 11 | 11 | |
| 12 | ||
| 12 | TODO: | |
| 13 | 13 | |
| 14 | - interrupts | |
| 15 | - status register | |
| 16 | - reset | |
| 17 | - DMA mode (currently forcing to non-DMA mode) | |
| 18 | - cursor/blank skew | |
| 19 | - sequential breaks | |
| 20 | - interlaced mode | |
| 21 | - smooth scroll | |
| 22 | - page blank | |
| 23 | - double height cursor | |
| 24 | - row attributes | |
| 25 | - pin configuration | |
| 26 | - operation modes 0,4,7 | |
| 27 | - address modes 1,2,3 | |
| 28 | - light pen | |
| 29 | - state saving | |
| 14 | - interrupts | |
| 15 | - status register | |
| 16 | - reset | |
| 17 | - DMA mode (currently forcing to non-DMA mode) | |
| 18 | - cursor/blank skew | |
| 19 | - sequential breaks | |
| 20 | - interlaced mode | |
| 21 | - smooth scroll | |
| 22 | - page blank | |
| 23 | - double height cursor | |
| 24 | - row attributes | |
| 25 | - pin configuration | |
| 26 | - operation modes 0,4,7 | |
| 27 | - address modes 1,2,3 | |
| 28 | - light pen | |
| 29 | - state saving | |
| 30 | 30 | |
| 31 | 31 | */ |
| 32 | 32 | |
| r8044 | r8045 | |
| 183 | 183 | #define STATUS_VERTICAL_RETRACE 0x40 |
| 184 | 184 | #define STATUS_LIGHT_PEN_UPDATE 0x20 |
| 185 | 185 | #define STATUS_ODD_EVEN 0x04 |
| 186 | #define STATUS_FRAME_TIMER_OCCURRED 0x01 | |
| 186 | #define STATUS_FRAME_TIMER_OCCURRED 0x01 | |
| 187 | 187 | |
| 188 | 188 | /*************************************************************************** |
| 189 | 189 | TYPE DEFINITIONS |
| r8044 | r8045 | |
| 308 | 308 | static void recompute_parameters(running_device *device) |
| 309 | 309 | { |
| 310 | 310 | crt9007_t *crt9007 = get_safe_token(device); |
| 311 | ||
| 311 | ||
| 312 | 312 | /* check that necessary registers have been loaded */ |
| 313 | 313 | if (!HAS_VALID_PARAMETERS) return; |
| 314 | 314 | |
| r8044 | r8045 | |
| 410 | 410 | recompute_parameters(device); |
| 411 | 411 | if (LOG) logerror("CRT9007 '%s' Characters per Horizontal Period: %u\n", device->tag(), CHARACTERS_PER_HORIZONTAL_PERIOD); |
| 412 | 412 | break; |
| 413 | ||
| 413 | ||
| 414 | 414 | case 0x01: |
| 415 | 415 | recompute_parameters(device); |
| 416 | 416 | if (LOG) logerror("CRT9007 '%s' Characters per Data Row: %u\n", device->tag(), CHARACTERS_PER_DATA_ROW); |
| r8044 | r8045 | |
| 438 | 438 | |
| 439 | 439 | case 0x06: |
| 440 | 440 | recompute_parameters(device); |
| 441 | if (LOG) | |
| 441 | if (LOG) | |
| 442 | 442 | { |
| 443 | 443 | logerror("CRT9007 '%s' Pin Configuration: %u\n", device->tag(), PIN_CONFIGURATION); |
| 444 | 444 | logerror("CRT9007 '%s' Cursor Skew: %u\n", device->tag(), CURSOR_SKEW); |
| r8044 | r8045 | |
| 622 | 622 | int sy = (y - min_y) / SCAN_LINES_PER_DATA_ROW; |
| 623 | 623 | int cursor_x = (sy == VERTICAL_CURSOR) ? HORIZONTAL_CURSOR : -1; |
| 624 | 624 | UINT16 addr = TABLE_START + (sy * CHARACTERS_PER_DATA_ROW); |
| 625 | // UINT8 data = devcb_call_read8(&crt9007->in_vd_func, addr); | |
| 626 | ||
| 625 | // UINT8 data = devcb_call_read8(&crt9007->in_vd_func, addr); | |
| 626 | ||
| 627 | 627 | crt9007->draw_scanline_func(device, bitmap, cliprect, addr, sl, 0, y, crt9007->hfp, CHARACTERS_PER_DATA_ROW, cursor_x); |
| 628 | 628 | |
| 629 | 629 | addr++; |
| r8044 | r8045 | |
| 666 | 666 | crt9007->hsync_timer = timer_alloc(device->machine, hsync_tick, (void *)device); |
| 667 | 667 | |
| 668 | 668 | /* register for state saving */ |
| 669 | // | |
| 669 | // state_save_register_device_item(device, 0, crt9007->); | |
| 670 | 670 | } |
| 671 | 671 | |
| 672 | 672 | /*------------------------------------------------- |
| r8044 | r8045 | |
| 675 | 675 | |
| 676 | 676 | static DEVICE_RESET( crt9007 ) |
| 677 | 677 | { |
| 678 | // | |
| 678 | // crt9007_t *crt9007 = (crt9007_t *)device->token; | |
| 679 | 679 | } |
| 680 | 680 | |
| 681 | 681 | /*------------------------------------------------- |
| r8044 | r8045 | |
|---|---|---|
| 59 | 59 | { |
| 60 | 60 | /* |
| 61 | 61 | |
| 62 | bit signal description | |
| 63 | ||
| 64 | 0 _VERT vertical retrace (0=vblank) | |
| 65 | 1 interlace (1=first field, 0=second field) | |
| 66 | 2 _HG horizontal retrace (0=hblank) | |
| 67 | 3 1 | |
| 68 | 4 1 | |
| 69 | 5 1 | |
| 70 | 6 1 | |
| 71 | 7 1 | |
| 72 | 8 1 | |
| 73 | 9 1 | |
| 74 | 10 1 | |
| 75 | 11 1 | |
| 76 | 12 1 | |
| 77 | 13 1 | |
| 78 | 14 1 | |
| 79 | 15 1 | |
| 62 | bit signal description | |
| 80 | 63 | |
| 81 | */ | |
| 64 | 0 _VERT vertical retrace (0=vblank) | |
| 65 | 1 interlace (1=first field, 0=second field) | |
| 66 | 2 _HG horizontal retrace (0=hblank) | |
| 67 | 3 1 | |
| 68 | 4 1 | |
| 69 | 5 1 | |
| 70 | 6 1 | |
| 71 | 7 1 | |
| 72 | 8 1 | |
| 73 | 9 1 | |
| 74 | 10 1 | |
| 75 | 11 1 | |
| 76 | 12 1 | |
| 77 | 13 1 | |
| 78 | 14 1 | |
| 79 | 15 1 | |
| 82 | 80 | |
| 81 | */ | |
| 82 | ||
| 83 | 83 | return 0xffff; |
| 84 | 84 | } |
| 85 | 85 | |
| r8044 | r8045 | |
| 102 | 102 | UINT8 b = data & 0xff; |
| 103 | 103 | UINT8 g = (data >> 8) & 0xff; |
| 104 | 104 | UINT8 r = (data >> 16) & 0xff; |
| 105 | ||
| 105 | ||
| 106 | 106 | palette_set_color_rgb(machine, i + 8, r, g, b); |
| 107 | 107 | } |
| 108 | 108 | } |
| r8044 | r8045 | |
| 241 | 241 | ***************************************************************************/ |
| 242 | 242 | |
| 243 | 243 | /*------------------------------------------------- |
| 244 | ||
| 244 | MACHINE_DRIVER( cgc7900_video ) | |
| 245 | 245 | -------------------------------------------------*/ |
| 246 | 246 | |
| 247 | 247 | MACHINE_DRIVER_START( cgc7900_video ) |
| r8044 | r8045 | |
| 251 | 251 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 252 | 252 | MDRV_SCREEN_SIZE(1024, 768) |
| 253 | 253 | MDRV_SCREEN_VISIBLE_AREA(0, 1024-1, 0, 768-1) |
| 254 | ||
| 254 | ||
| 255 | 255 | MDRV_GFXDECODE(cgc7900) |
| 256 | 256 | |
| 257 | 257 | MDRV_PALETTE_LENGTH(8+256) /* 8 overlay colors + 256 bitmap colors */ |
| r8044 | r8045 | |
|---|---|---|
| 68 | 68 | |
| 69 | 69 | devcb_write_line out_hs_func; |
| 70 | 70 | devcb_write_line out_vs_func; |
| 71 | /* | |
| 72 | devcb_write_line out_cblank_func; | |
| 73 | devcb_write_line out_vblank_func; | |
| 71 | /* | |
| 72 | devcb_write_line out_cblank_func; | |
| 73 | devcb_write_line out_vblank_func; | |
| 74 | 74 | |
| 75 | devcb_write_line out_vlt_func; | |
| 76 | devcb_write_line out_curs_func; | |
| 77 | devcb_write_line out_drb_func; | |
| 75 | devcb_write_line out_vlt_func; | |
| 76 | devcb_write_line out_curs_func; | |
| 77 | devcb_write_line out_drb_func; | |
| 78 | 78 | |
| 79 | devcb_write_line out_slg_func; | |
| 80 | devcb_write_line out_sld_func; | |
| 79 | devcb_write_line out_slg_func; | |
| 80 | devcb_write_line out_sld_func; | |
| 81 | 81 | */ |
| 82 | 82 | devcb_read8 in_vd_func; |
| 83 | 83 | devcb_write8 out_vd_func; |
| r8044 | r8045 | |
|---|---|---|
| 356 | 356 | { |
| 357 | 357 | if(towns_mainmem_enable != 0) |
| 358 | 358 | return messram_get_ptr(devtag_get_device(space->machine, "messram"))[offset+0xcff80]; |
| 359 | ||
| 359 | ||
| 360 | 360 | return towns_video_cff80_r(space,offset); |
| 361 | 361 | } |
| 362 | 362 | |
| r8044 | r8045 | |
| 381 | 381 | { |
| 382 | 382 | UINT8 ret = 0; |
| 383 | 383 | UINT16 xpos,ypos; |
| 384 | ||
| 384 | ||
| 385 | 385 | switch(offset) |
| 386 | 386 | { |
| 387 | 387 | case 0x00: |
| 388 | 388 | return towns_crtc_sel; |
| 389 | 389 | case 0x02: |
| 390 | // | |
| 390 | // logerror("CRTC: reading register %i (0x442) [%04x]\n",towns_crtc_sel,towns_crtc_reg[towns_crtc_sel]); | |
| 391 | 391 | if(towns_crtc_sel == 30) |
| 392 | 392 | return 0x00; |
| 393 | 393 | return towns_crtc_reg[towns_crtc_sel] & 0x00ff; |
| 394 | 394 | case 0x03: |
| 395 | // | |
| 395 | // logerror("CRTC: reading register %i (0x443) [%04x]\n",towns_crtc_sel,towns_crtc_reg[towns_crtc_sel]); | |
| 396 | 396 | if(towns_crtc_sel == 30) |
| 397 | 397 | { |
| 398 | 398 | // check video position |
| 399 | 399 | xpos = video_screen_get_hpos(space->machine->primary_screen); |
| 400 | 400 | ypos = video_screen_get_vpos(space->machine->primary_screen); |
| 401 | ||
| 401 | ||
| 402 | 402 | if(xpos < (towns_crtc_reg[0] & 0xfe)) |
| 403 | 403 | ret |= 0x02; |
| 404 | 404 | if(ypos < (towns_crtc_reg[6] & 0x1f)) |
| r8044 | r8045 | |
| 411 | 411 | ret |= 0x40; |
| 412 | 412 | if(ypos < towns_crtc_layerscr[1].max_y && ypos > towns_crtc_layerscr[1].min_y) |
| 413 | 413 | ret |= 0x80; |
| 414 | ||
| 414 | ||
| 415 | 415 | return ret; |
| 416 | 416 | } |
| 417 | 417 | return (towns_crtc_reg[towns_crtc_sel] & 0xff00) >> 8; |
| r8044 | r8045 | |
| 426 | 426 | towns_dpmd_flag = 0; |
| 427 | 427 | ret |= 0x80; |
| 428 | 428 | } |
| 429 | ret |= (towns_vblank_flag ? 0x02 : 0x00); // TODO: figure out just what this bit is... | |
| 429 | ret |= (towns_vblank_flag ? 0x02 : 0x00); // TODO: figure out just what this bit is... | |
| 430 | 430 | return ret; |
| 431 | 431 | case 0x10: |
| 432 | 432 | return towns_sprite_sel; |
| r8044 | r8045 | |
| 447 | 447 | towns_crtc_sel = data; |
| 448 | 448 | break; |
| 449 | 449 | case 0x02: |
| 450 | // | |
| 450 | // logerror("CRTC: writing register %i (0x442) [%02x]\n",towns_crtc_sel,data); | |
| 451 | 451 | towns_crtc_reg[towns_crtc_sel] = |
| 452 | 452 | (towns_crtc_reg[towns_crtc_sel] & 0xff00) | data; |
| 453 | 453 | towns_crtc_refresh_mode(space->machine); |
| 454 | 454 | break; |
| 455 | 455 | case 0x03: |
| 456 | // | |
| 456 | // logerror("CRTC: writing register %i (0x443) [%02x]\n",towns_crtc_sel,data); | |
| 457 | 457 | towns_crtc_reg[towns_crtc_sel] = |
| 458 | 458 | (towns_crtc_reg[towns_crtc_sel] & 0x00ff) | (data << 8); |
| 459 | 459 | towns_crtc_refresh_mode(space->machine); |
| r8044 | r8045 | |
| 539 | 539 | case 0x10: // "sub status register" |
| 540 | 540 | // check video position |
| 541 | 541 | xpos = video_screen_get_hpos(space->machine->primary_screen); |
| 542 | ||
| 542 | ||
| 543 | 543 | if(xpos < towns_crtc_layerscr[0].max_x && xpos > towns_crtc_layerscr[0].min_x) |
| 544 | 544 | ret |= 0x02; |
| 545 | 545 | if(towns_vblank_flag) |
| r8044 | r8045 | |
| 578 | 578 | towns_dpmd_flag = 1; |
| 579 | 579 | break; |
| 580 | 580 | case 0x10: |
| 581 | towns_layer_ctrl = data; | |
| 581 | towns_layer_ctrl = data; | |
| 582 | 582 | break; |
| 583 | 583 | } |
| 584 | 584 | //logerror("VID: wrote 0x%02x to port %04x\n",data,offset+0xfd90); |
| r8044 | r8045 | |
| 1439 | 1439 | } |
| 1440 | 1440 | |
| 1441 | 1441 | /*#ifdef SPR_DEBUG |
| 1442 | if(input_code_pressed(screen->machine,KEYCODE_O)) | |
| 1443 | pshift+=0x80; | |
| 1444 | if(input_code_pressed(screen->machine,KEYCODE_I)) | |
| 1445 | pshift-=0x80; | |
| 1446 | popmessage("Pixel shift = %08x",pshift); | |
| 1442 | if(input_code_pressed(screen->machine,KEYCODE_O)) | |
| 1443 | pshift+=0x80; | |
| 1444 | if(input_code_pressed(screen->machine,KEYCODE_I)) | |
| 1445 | pshift-=0x80; | |
| 1446 | popmessage("Pixel shift = %08x",pshift); | |
| 1447 | 1447 | #endif*/ |
| 1448 | 1448 | |
| 1449 | 1449 | #ifdef CRTC_REG_DISP |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | The Aamber Pegasus uses a MCM66710P, which is functionally | |
| 4 | equivalent to the MCM6571. Some code here is copied from poly88. | |
| 3 | The Aamber Pegasus uses a MCM66710P, which is functionally | |
| 4 | equivalent to the MCM6571. Some code here is copied from poly88. | |
| 5 | 5 | |
| 6 | Note that datasheet is incorrect for the number "9", line 57 below. | |
| 7 | The first byte is really 0x3E rather than 0x3F, confirmed on real | |
| 8 | hardware. | |
| 6 | Note that datasheet is incorrect for the number "9", line 57 below. | |
| 7 | The first byte is really 0x3E rather than 0x3F, confirmed on real | |
| 8 | hardware. | |
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 | ****************************************************************************/ |
| r8044 | r8045 | |
|---|---|---|
| 310 | 310 | if ( vpos < start_vblank ) |
| 311 | 311 | { |
| 312 | 312 | rectangle rect; |
| 313 | //int | |
| 313 | //int sprite_width[4] = { 8, 8, 8, 8 }; | |
| 314 | 314 | int i; |
| 315 | 315 | |
| 316 | 316 | control_status &= ~ 0x01; |
| r8044 | r8045 | |
|---|---|---|
| 111 | 111 | UINT8 battery_data[NES_BATTERY_SIZE]; |
| 112 | 112 | |
| 113 | 113 | /***** Mapper-related variables *****/ |
| 114 | ||
| 114 | ||
| 115 | 115 | // common ones |
| 116 | 116 | int IRQ_enable, IRQ_enable_latch; |
| 117 | 117 | UINT16 IRQ_count, IRQ_count_latch; |
| r8044 | r8045 | |
| 120 | 120 | UINT8 IRQ_status; |
| 121 | 121 | UINT8 IRQ_mode; |
| 122 | 122 | int mult1, mult2; |
| 123 | ||
| 123 | ||
| 124 | 124 | UINT8 mmc_chr_source; // This is set at init to CHRROM or CHRRAM. a few mappers can swap between |
| 125 | 125 | // the two (this is done in the specific handlers). |
| 126 | ||
| 126 | ||
| 127 | 127 | UINT8 mmc_cmd1, mmc_cmd2; // These represent registers where the mapper writes important values |
| 128 | 128 | UINT8 mmc_count; // This is used as counter in mappers like 1 and 45 |
| 129 | ||
| 129 | ||
| 130 | 130 | int mmc_prg_base, mmc_prg_mask; // MMC3 based multigame carts select a block of banks by using these (and then act like normal MMC3), |
| 131 | 131 | int mmc_chr_base, mmc_chr_mask; // while MMC3 and clones (mapper 118 & 119) simply set them as 0 and 0xff resp. |
| 132 | ||
| 132 | ||
| 133 | 133 | UINT8 prg_bank[4]; // Many mappers writes only some bits of the selected bank (for both PRG and CHR), |
| 134 | 134 | UINT8 vrom_bank[16]; // hence these are handy to latch bank values. |
| 135 | 135 | |
| 136 | 136 | UINT8 extra_bank[16]; // some MMC3 clone have 2 series of PRG/CHR banks... |
| 137 | 137 | // we collect them all here: first 4 elements PRG banks, then 6/8 CHR banks |
| 138 | ||
| 138 | ||
| 139 | 139 | /***** NES-cart related *****/ |
| 140 | 140 | |
| 141 | 141 | /* load-time cart variables which remain constant */ |
| r8044 | r8045 | |
| 143 | 143 | UINT8 battery; |
| 144 | 144 | UINT16 prg_chunks; // a recently dumped multigame cart has 256 chunks of both PRG & CHR! |
| 145 | 145 | UINT16 chr_chunks; |
| 146 | ||
| 146 | ||
| 147 | 147 | UINT8 format; // 1 = iNES, 2 = UNIF |
| 148 | ||
| 148 | ||
| 149 | 149 | /* system variables which don't change at run-time */ |
| 150 | 150 | UINT16 mapper; // for iNES |
| 151 | 151 | const char *board; // for UNIF |
| r8044 | r8045 | |
| 153 | 153 | UINT8 hard_mirroring; |
| 154 | 154 | UINT8 slow_banking; |
| 155 | 155 | UINT8 crc_hack; // this is needed to detect different boards sharing the same Mappers (shame on .nes format) |
| 156 | ||
| 157 | ||
| 156 | ||
| 157 | ||
| 158 | 158 | /***** FDS-floppy related *****/ |
| 159 | 159 | |
| 160 | 160 | UINT8 *fds_data; |
| 161 | 161 | UINT8 fds_sides; |
| 162 | 162 | UINT8 *fds_ram; |
| 163 | ||
| 163 | ||
| 164 | 164 | /* Variables which can change */ |
| 165 | 165 | UINT8 fds_motor_on; |
| 166 | 166 | UINT8 fds_door_closed; |
| r8044 | r8045 | |
|---|---|---|
| 67 | 67 | #define EXTERNAL_INT_MOUSE_YU 0x88 |
| 68 | 68 | #define EXTERNAL_INT_MOUSE_YD 0x89 |
| 69 | 69 | #define EXTERNAL_INT_MOUSE_XL 0x8A |
| 70 | #define EXTERNAL_INT_MOUSE_XR 0x8B | |
| 70 | #define EXTERNAL_INT_MOUSE_XR 0x8B | |
| 71 | 71 | #define EXTERNAL_INT_PC8031_8C 0x8c |
| 72 | 72 | #define EXTERNAL_INT_PC8031_8E 0x8E |
| 73 | 73 | #define EXTERNAL_INT_PC8031_8F 0x8F |
| r8044 | r8045 | |
|---|---|---|
| 1693 | 1693 | DRIVER( z80dev ) |
| 1694 | 1694 | DRIVER( pegasus ) |
| 1695 | 1695 | DRIVER( pegasusm ) |
| 1696 | ||
| 1696 | ||
| 1697 | 1697 | #endif /* DRIVER_RECURSIVE */ |
| r8044 | r8045 | |
|---|---|---|
| 849 | 849 | SoftwarePicker_AddFile(GetDlgItem(GetMainWindow(), IDC_SWLIST), utf8_filename); |
| 850 | 850 | osd_free(utf8_filename); |
| 851 | 851 | } |
| 852 | ||
| 852 | ||
| 853 | 853 | machine_config_free(config); |
| 854 | 854 | } |
| 855 | 855 | |
| r8044 | r8045 | |
| 926 | 926 | |
| 927 | 927 | /* If software folder exists, use it instead */ |
| 928 | 928 | zippath_combine(&as, dst, "software"); |
| 929 | if (osd_opendir(astring_c(&as))) | |
| 929 | if (osd_opendir(astring_c(&as))) | |
| 930 | 930 | { |
| 931 | 931 | osd_free(t_s); |
| 932 | 932 | t_s = tstring_from_utf8(astring_c(&as)); |
| r8044 | r8045 | |
| 939 | 939 | SetupImageTypes(config, imagetypes, ARRAY_LENGTH(imagetypes), TRUE, dev); |
| 940 | 940 | bResult = CommonFileImageDialog(t_s, GetOpenFileName, pszFilename, config, imagetypes); |
| 941 | 941 | CleanupImageTypes(imagetypes, ARRAY_LENGTH(imagetypes)); |
| 942 | ||
| 942 | ||
| 943 | 943 | osd_free(t_s); |
| 944 | 944 | |
| 945 | 945 | return bResult; |
| r8044 | r8045 | |
| 997 | 997 | |
| 998 | 998 | /* If software folder exists, use it instead */ |
| 999 | 999 | zippath_combine(&as, dst, "software"); |
| 1000 | if (osd_opendir(astring_c(&as))) | |
| 1000 | if (osd_opendir(astring_c(&as))) | |
| 1001 | 1001 | { |
| 1002 | 1002 | osd_free(t_s); |
| 1003 | 1003 | t_s = tstring_from_utf8(astring_c(&as)); |
| r8044 | r8045 | |
| 1009 | 1009 | SetupImageTypes(config, imagetypes, ARRAY_LENGTH(imagetypes), TRUE, dev); |
| 1010 | 1010 | bResult = CommonFileImageDialog(t_s, GetSaveFileName, pszFilename, config, imagetypes); |
| 1011 | 1011 | CleanupImageTypes(imagetypes, ARRAY_LENGTH(imagetypes)); |
| 1012 | ||
| 1012 | ||
| 1013 | 1013 | osd_free(t_s); |
| 1014 | 1014 | |
| 1015 | 1015 | return bResult; |
| r8044 | r8045 | |
|---|---|---|
| 434 | 434 | |
| 435 | 435 | (void)ComboBox_InsertString(control, i, win_tstring_strdup(t_ramstring)); |
| 436 | 436 | (void)ComboBox_SetItemData(control, i, ram); |
| 437 | ||
| 437 | ||
| 438 | 438 | osd_free(t_ramstring); |
| 439 | 439 | } |
| 440 | 440 | if (config->extra_options != NULL) |
| r8044 | r8045 | |
| 447 | 447 | for (j=0;j<size;j++) { |
| 448 | 448 | if (p[j]==',') p[j]=0; |
| 449 | 449 | } |
| 450 | ||
| 450 | ||
| 451 | 451 | /* try to parse each option */ |
| 452 | 452 | while(p <= e) |
| 453 | 453 | { |
| r8044 | r8045 | |
| 474 | 474 | p+= strlen(p); |
| 475 | 475 | if (p == e) |
| 476 | 476 | break; |
| 477 | ||
| 477 | ||
| 478 | 478 | p += 1; |
| 479 | 479 | } |
| 480 | 480 |
| r8044 | r8045 | |
|---|---|---|
| 72 | 72 | Slow Controller |
| 73 | 73 | --------------- |
| 74 | 74 | |
| 75 | ||
| 75 | - Z80 IN instruction needs to halt in mid air for this controller to ever work (the first data byte of disk sector is read too early) | |
| 76 | 76 | |
| 77 | wd17xx_command_w $88 READ_SEC | |
| 78 | wd17xx_data_r: (no new data) $00 (data_count 0) | |
| 79 | WAIT | |
| 80 | wd179x: Read Sector callback. | |
| 81 | sector found! C:$00 H:$00 R:$0b N:$01 | |
| 82 | wd17xx_data_r: $FF (data_count 256) | |
| 83 | WAIT | |
| 77 | wd17xx_command_w $88 READ_SEC | |
| 78 | wd17xx_data_r: (no new data) $00 (data_count 0) | |
| 79 | WAIT | |
| 80 | wd179x: Read Sector callback. | |
| 81 | sector found! C:$00 H:$00 R:$0b N:$01 | |
| 82 | wd17xx_data_r: $FF (data_count 256) | |
| 83 | WAIT | |
| 84 | 84 | |
| 85 | 85 | - copy protection device (sends sector header bytes to CPU? DDEN is serial clock? code checks for either $b6 or $f7) |
| 86 | 86 | |
| 87 | 06F8: ld a,$2F ; SEEK | |
| 88 | 06FA: out ($BC),a | |
| 89 | 06FC: push af | |
| 90 | 06FD: push bc | |
| 91 | 06FE: ld bc,$0724 | |
| 92 | 0701: push bc | |
| 93 | 0702: ld b,$07 | |
| 94 | 0704: rr a | |
| 95 | 0706: call $073F | |
| 96 | 073F: DB 7E in a,($7E) ; PIO PORT B | |
| 97 | 0741: EE 08 xor $08 ; DDEN | |
| 98 | 0743: D3 7E out ($7E),a | |
| 99 | 0745: EE 08 xor $08 | |
| 100 | 0747: D3 7E out ($7E),a | |
| 101 | 0749: DB 7E in a,($7E) | |
| 102 | 074B: 1F rra | |
| 103 | 074C: 1F rra | |
| 104 | 074D: 1F rra | |
| 105 | 074E: CB 11 rl c | |
| 106 | 0750: 79 ld a,c | |
| 107 | 0751: C9 ret | |
| 108 | 0709: djnz $0703 <-- jumps to middle of instruction! | |
| 109 | 0703: rlca | |
| 110 | 0704: rr a | |
| 111 | 0706: call $073F | |
| 112 | ||
| 87 | 06F8: ld a,$2F ; SEEK | |
| 88 | 06FA: out ($BC),a | |
| 89 | 06FC: push af | |
| 90 | 06FD: push bc | |
| 91 | 06FE: ld bc,$0724 | |
| 92 | 0701: push bc | |
| 93 | 0702: ld b,$07 | |
| 94 | 0704: rr a | |
| 95 | 0706: call $073F | |
| 96 | 073F: DB 7E in a,($7E) ; PIO PORT B | |
| 97 | 0741: EE 08 xor $08 ; DDEN | |
| 98 | 0743: D3 7E out ($7E),a | |
| 99 | 0745: EE 08 xor $08 | |
| 100 | 0747: D3 7E out ($7E),a | |
| 101 | 0749: DB 7E in a,($7E) | |
| 102 | 074B: 1F rra | |
| 103 | 074C: 1F rra | |
| 104 | 074D: 1F rra | |
| 105 | 074E: CB 11 rl c | |
| 106 | 0750: 79 ld a,c | |
| 107 | 0751: C9 ret | |
| 108 | 0709: djnz $0703 <-- jumps to middle of instruction! | |
| 109 | 0703: rlca | |
| 110 | 0704: rr a | |
| 111 | 0706: call $073F | |
| 112 | ||
| 113 | 113 | - FD1791 HLD/HLT callbacks |
| 114 | 114 | - DS/DD SS/DS jumpers |
| 115 | 115 | - S1-S5 jumpers |
| 116 | 116 | |
| 117 | 117 | Fast Controller |
| 118 | 118 | --------------- |
| 119 | ||
| 119 | - CPU is in HALT waiting for the FDC interrupt after commands | |
| 120 | 120 | |
| 121 | 121 | */ |
| 122 | 122 | |
| r8044 | r8045 | |
| 294 | 294 | { |
| 295 | 295 | /* |
| 296 | 296 | |
| 297 | bit signal | |
| 297 | bit signal description | |
| 298 | 298 | |
| 299 | 299 | 0 SEL 0 |
| 300 | 300 | 1 SEL 1 |
| r8044 | r8045 | |
| 321 | 321 | floppy_drive_set_ready_state(conkort->image1, 1, 1); |
| 322 | 322 | |
| 323 | 323 | /* disk side selection */ |
| 324 | // | |
| 324 | // wd17xx_set_side(device, BIT(data, 4)); | |
| 325 | 325 | |
| 326 | 326 | /* wait enable */ |
| 327 | 327 | conkort->wait_enable = BIT(data, 6); |
| r8044 | r8045 | |
| 606 | 606 | |
| 607 | 607 | bit description |
| 608 | 608 | |
| 609 | 0 !(_DS0 & _DS1) single/double sided (0=SS, 1=DS) | |
| 610 | 1 !(_DD0 & _DD1) single/double density (0=DS, 1=DD) | |
| 609 | 0 !(_DS0 & _DS1) single/double sided (0=SS, 1=DS) | |
| 610 | 1 !(_DD0 & _DD1) single/double density (0=DS, 1=DD) | |
| 611 | 611 | 2 8B pin 10 |
| 612 | 3 FDC _DDEN double density enable | |
| 613 | 4 _R/BS radial/binary drive select | |
| 614 | 5 FDC HLT head load timing | |
| 615 | 6 FDC _HDLD head load | |
| 616 | 7 FDC IRQ interrupt request | |
| 612 | 3 FDC _DDEN double density enable | |
| 613 | 4 _R/BS radial/binary drive select | |
| 614 | 5 FDC HLT head load timing | |
| 615 | 6 FDC _HDLD head load | |
| 616 | 7 FDC IRQ interrupt request | |
| 617 | 617 | |
| 618 | 618 | */ |
| 619 | 619 | |
| r8044 | r8045 | |
| 622 | 622 | UINT8 data = 4; |
| 623 | 623 | |
| 624 | 624 | /* single/double sided drive */ |
| 625 | // | |
| 625 | // data |= 0x01; | |
| 626 | 626 | |
| 627 | 627 | /* single/double density drive */ |
| 628 | 628 | data |= 0x02; |
| r8044 | r8045 | |
| 631 | 631 | data |= 0x10; |
| 632 | 632 | |
| 633 | 633 | /* head load */ |
| 634 | // | |
| 634 | // data |= wd17xx_hdld_r(device) << 6; | |
| 635 | 635 | data |= 0x40; |
| 636 | 636 | |
| 637 | 637 | /* FDC interrupt request */ |
| r8044 | r8045 | |
| 644 | 644 | { |
| 645 | 645 | /* |
| 646 | 646 | |
| 647 | bit signal | |
| 647 | bit signal description | |
| 648 | 648 | |
| 649 | 0 !(_DS0 & _DS1) single/double sided (0=SS, 1=DS) | |
| 650 | 1 !(_DD0 & _DD1) single/double density (0=DS, 1=DD) | |
| 649 | 0 !(_DS0 & _DS1) single/double sided (0=SS, 1=DS) | |
| 650 | 1 !(_DD0 & _DD1) single/double density (0=DS, 1=DD) | |
| 651 | 651 | 2 8B pin 10 |
| 652 | 3 FDC _DDEN double density enable | |
| 653 | 4 _R/BS radial/binary drive select | |
| 654 | 5 FDC HLT head load timing | |
| 655 | 6 FDC _HDLD head load | |
| 656 | 7 FDC IRQ interrupt request | |
| 652 | 3 FDC _DDEN double density enable | |
| 653 | 4 _R/BS radial/binary drive select | |
| 654 | 5 FDC HLT head load timing | |
| 655 | 6 FDC _HDLD head load | |
| 656 | 7 FDC IRQ interrupt request | |
| 657 | 657 | |
| 658 | 658 | */ |
| 659 | 659 | |
| r8044 | r8045 | |
| 663 | 663 | wd17xx_dden_w(conkort->fd1791, BIT(data, 3)); |
| 664 | 664 | |
| 665 | 665 | /* head load timing */ |
| 666 | // | |
| 666 | // wd17xx_hlt_w(conkort->fd1791, BIT(data, 5)); | |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | 669 | static Z80PIO_INTERFACE( conkort_pio_intf ) |
| r8044 | r8045 | |
| 689 | 689 | |
| 690 | 690 | DMA Transfer Programs |
| 691 | 691 | |
| 692 | READ DAM | |
| 693 | -------- | |
| 692 | READ DAM | |
| 693 | -------- | |
| 694 | 694 | 7D 45 21 05 00 C3 14 28 95 6B 02 8A CF 01 AF CF 87 |
| 695 | 695 | |
| 696 | 7D transfer mode, port A -> port B, port A starting address follows, block length follows | |
| 697 | 45 port A starting address low byte = 45 | |
| 698 | 21 port A starting address high byte = 21 | |
| 699 | 05 block length low byte = 05 | |
| 700 | 00 block length high byte = 00 | |
| 696 | 7D transfer mode, port A -> port B, port A starting address follows, block length follows | |
| 697 | 45 port A starting address low byte = 45 | |
| 698 | 21 port A starting address high byte = 21 | |
| 699 | 05 block length low byte = 05 | |
| 700 | 00 block length high byte = 00 | |
| 701 | 701 | C3 reset |
| 702 | 702 | 14 port A is memory, port A address increments |
| 703 | 703 | 28 port B is I/O, port B address fixed |
| r8044 | r8045 | |
| 711 | 711 | CF load |
| 712 | 712 | 87 enable DMA |
| 713 | 713 | |
| 714 | ?? | |
| 715 | -- | |
| 714 | ?? | |
| 715 | -- | |
| 716 | 716 | C3 14 28 95 7B 02 8A CF 05 AF CF 87 |
| 717 | 717 | |
| 718 | 718 | C3 reset |
| r8044 | r8045 | |
| 728 | 728 | CF load |
| 729 | 729 | 87 enable DMA |
| 730 | 730 | |
| 731 | ?? | |
| 732 | -- | |
| 731 | ?? | |
| 732 | -- | |
| 733 | 733 | C3 91 40 8A AB |
| 734 | 734 | |
| 735 | 735 | C3 reset |
| r8044 | r8045 | |
| 933 | 933 | slow_t *conkort = get_safe_token_slow(device); |
| 934 | 934 | |
| 935 | 935 | conkort->cpu->reset(); |
| 936 | ||
| 936 | ||
| 937 | 937 | conkort->cs = 0; |
| 938 | 938 | } |
| 939 | 939 |
| r8044 | r8045 | |
|---|---|---|
| 1675 | 1675 | } |
| 1676 | 1676 | else |
| 1677 | 1677 | memcpy(gb_driver_data.gb_cart, image_get_software_region(image, "rom") + load_start, filesize); |
| 1678 | ||
| 1678 | ||
| 1679 | 1679 | gb_header = gb_driver_data.gb_cart; |
| 1680 | 1680 | gb_driver_data.ROMBank00 = 0; |
| 1681 | 1681 | |
| r8044 | r8045 | |
| 1830 | 1830 | { |
| 1831 | 1831 | logerror("Warning loading cartridge: Checksum is wrong."); |
| 1832 | 1832 | } |
| 1833 | ||
| 1833 | ||
| 1834 | 1834 | /* Initialize ROMMap pointers */ |
| 1835 | 1835 | for (I = 0; I < gb_driver_data.ROMBanks; I++) |
| 1836 | 1836 | { |
| 1837 | 1837 | gb_driver_data.ROMMap[I] = gb_driver_data.gb_cart + (I * 0x4000); |
| 1838 | 1838 | } |
| 1839 | ||
| 1839 | ||
| 1840 | 1840 | /* |
| 1841 | 1841 | Handle odd-sized cartridges (72,80,96 banks) |
| 1842 | 1842 | ROMBanks ROMMask |
| r8044 | r8045 | |
| 1853 | 1853 | } |
| 1854 | 1854 | gb_driver_data.ROMMask = I - 1; |
| 1855 | 1855 | } |
| 1856 | ||
| 1856 | ||
| 1857 | 1857 | /* Fill out the remaining rom bank pointers, if any. */ |
| 1858 | 1858 | for ( ; I < MAX_ROMBANK; I++) |
| 1859 | 1859 | { |
| 1860 | 1860 | gb_driver_data.ROMMap[I] = gb_driver_data.ROMMap[I & gb_driver_data.ROMMask]; |
| 1861 | 1861 | } |
| 1862 | ||
| 1862 | ||
| 1863 | 1863 | /* Log cart information */ |
| 1864 | 1864 | { |
| 1865 | 1865 | const char *P; |
| 1866 | 1866 | char S[50]; |
| 1867 | 1867 | static const int ramsize[8] = { 0, 2, 8, 32, 128, 64, 0, 0 }; |
| 1868 | ||
| 1869 | 1868 | |
| 1869 | ||
| 1870 | 1870 | strncpy (S, (char *)&gb_header[0x0134], 16); |
| 1871 | 1871 | S[16] = '\0'; |
| 1872 | 1872 | logerror("Cart Information\n"); |
| r8044 | r8045 | |
| 2210 | 2210 | |
| 2211 | 2211 | DEVICE_IMAGE_LOAD(megaduck_cart) |
| 2212 | 2212 | { |
| 2213 | int I; | |
| 2213 | int I; | |
| 2214 | 2214 | UINT32 filesize; |
| 2215 | 2215 | |
| 2216 | 2216 | for (I = 0; I < MAX_ROMBANK; I++) |
| r8044 | r8045 | |
| 2228 | 2228 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Invalid rom file size"); |
| 2229 | 2229 | return INIT_FAIL; |
| 2230 | 2230 | } |
| 2231 | ||
| 2231 | ||
| 2232 | 2232 | gb_driver_data.ROMBanks = filesize / 0x4000; |
| 2233 | 2233 | |
| 2234 | 2234 | /* Claim memory */ |
| r8044 | r8045 | |
|---|---|---|
| 154 | 154 | init state of the emulator. During the normal operation, only the |
| 155 | 155 | reset routines are used. |
| 156 | 156 | */ |
| 157 | // TODO: Check that: | |
| 157 | // TODO: Check that: floppy_mon_w(w->drive, CLEAR_LINE); | |
| 158 | 158 | |
| 159 | 159 | void ti99_floppy_controllers_init_all(running_machine *machine) |
| 160 | 160 | { |
| r8044 | r8045 | |
| 199 | 199 | motor_on = 0; |
| 200 | 200 | |
| 201 | 201 | ti99_set_80_track_drives(FALSE); |
| 202 | ||
| 202 | ||
| 203 | 203 | set_all_geometries(machine, FLOPPY_DRIVE_DS_40); |
| 204 | ||
| 204 | ||
| 205 | 205 | ti99_peb_set_card_handlers(0x1100, & fdc_handlers); |
| 206 | 206 | if (fdc) { |
| 207 | 207 | wd17xx_reset(fdc); /* resets the fdc */ |
| r8044 | r8045 | |
| 329 | 329 | static READ8_HANDLER(fdc_mem_r) |
| 330 | 330 | { |
| 331 | 331 | running_device *fdc = devtag_get_device(space->machine, "wd179x"); |
| 332 | ||
| 333 | /* only use the even addresses from 1ff0 to 1ff6. | |
| 334 | Note that data is inverted. */ | |
| 332 | ||
| 333 | /* only use the even addresses from 1ff0 to 1ff6. | |
| 334 | Note that data is inverted. */ | |
| 335 | 335 | if (offset >= 0x1ff0 && (offset & 0x09)==0) |
| 336 | 336 | return wd17xx_r(fdc, (offset >> 1)&0x03) ^ 0xff; |
| 337 | 337 | else |
| r8044 | r8045 | |
| 345 | 345 | { |
| 346 | 346 | running_device *fdc = devtag_get_device(space->machine, "wd179x"); |
| 347 | 347 | |
| 348 | /* only use the even addresses from 1ff8 to 1ffe. | |
| 349 | Note that data is inverted. */ | |
| 348 | /* only use the even addresses from 1ff8 to 1ffe. | |
| 349 | Note that data is inverted. */ | |
| 350 | 350 | if (offset >= 0x1ff0 && (offset & 0x09)==0x08) |
| 351 | 351 | wd17xx_w(fdc, (offset >> 1)&0x03, data ^ 0xff); |
| 352 | 352 | } |
| r8044 | r8045 | |
| 393 | 393 | motor_on = 0; |
| 394 | 394 | |
| 395 | 395 | ti99_set_80_track_drives(FALSE); |
| 396 | ||
| 396 | ||
| 397 | 397 | set_all_geometries(machine, FLOPPY_DRIVE_DS_40); |
| 398 | 398 | |
| 399 | 399 | ti99_peb_set_card_handlers(0x1100, & ccfdc_handlers); |
| r8044 | r8045 | |
| 615 | 615 | motor_on = 0; |
| 616 | 616 | |
| 617 | 617 | ti99_set_80_track_drives(FALSE); |
| 618 | ||
| 618 | ||
| 619 | 619 | set_all_geometries(machine, FLOPPY_DRIVE_DS_40); |
| 620 | 620 | |
| 621 | 621 | ti99_peb_set_card_handlers(0x1100, & bwg_handlers); |
| r8044 | r8045 | |
| 932 | 932 | } |
| 933 | 933 | |
| 934 | 934 | /* |
| 935 | Select the HFDC hard disk unit | |
| 936 | This function implements the selection logic on the PCB (outside the | |
| 937 | controller chip) | |
| 938 | The HDC9234 allows up to four drives to be selected by the select lines. | |
| 939 | This is not enough for controlling four floppy drives and three hard | |
| 940 | drives, so the user programmable outputs are used to select the floppy | |
| 941 | drives. This selection happens completely outside of the controller, | |
| 942 | so we must implement it here. | |
| 935 | Select the HFDC hard disk unit | |
| 936 | This function implements the selection logic on the PCB (outside the | |
| 937 | controller chip) | |
| 938 | The HDC9234 allows up to four drives to be selected by the select lines. | |
| 939 | This is not enough for controlling four floppy drives and three hard | |
| 940 | drives, so the user programmable outputs are used to select the floppy | |
| 941 | drives. This selection happens completely outside of the controller, | |
| 942 | so we must implement it here. | |
| 943 | 943 | */ |
| 944 | 944 | |
| 945 | 945 | static running_device *hfdc_current_harddisk(void) |
| r8044 | r8045 | |
| 948 | 948 | disk_unit = line_to_index((output1_latch>>4)&0x0f, HFDC_MAX_HARD); |
| 949 | 949 | |
| 950 | 950 | /* The HFDC does not use disk_unit=0. The first HD has index 1. */ |
| 951 | /* if (disk_unit>=0) printf("Select hard disk %d\n", disk_unit); | |
| 952 | else printf("No hard disk selected\n"); | |
| 951 | /* if (disk_unit>=0) printf("Select hard disk %d\n", disk_unit); | |
| 952 | else printf("No hard disk selected\n"); | |
| 953 | 953 | */ |
| 954 | 954 | return harddisk_unit[disk_unit]; |
| 955 | 955 | } |
| 956 | 956 | |
| 957 | 957 | /* |
| 958 | Select the HFDC floppy disk unit | |
| 959 | This function implements the selection logic on the PCB (outside the | |
| 960 | controller chip) | |
| 958 | Select the HFDC floppy disk unit | |
| 959 | This function implements the selection logic on the PCB (outside the | |
| 960 | controller chip) | |
| 961 | 961 | */ |
| 962 | 962 | |
| 963 | 963 | static running_device *hfdc_current_floppy(void) |
| 964 | { | |
| 964 | { | |
| 965 | 965 | int disk_unit = -1; |
| 966 | 966 | disk_unit = line_to_index(output1_latch & 0x0f, HFDC_MAX_FLOPPY); |
| 967 | 967 | |
| 968 | 968 | if (disk_unit<0) |
| 969 | 969 | { |
| 970 | // | |
| 970 | // printf("No unit selected\n"); | |
| 971 | 971 | return NULL; |
| 972 | 972 | } |
| 973 | 973 | |
| 974 | // printf("Select floppy disk %d (output1=%02x)\n", index, output1_latch); | |
| 974 | // printf("Select floppy disk %d (output1=%02x)\n", index, output1_latch); | |
| 975 | 975 | return floppy_unit[disk_unit]; |
| 976 | } | |
| 976 | } | |
| 977 | 977 | |
| 978 | 978 | /* |
| 979 | 979 | Called whenever the state of the sms9234 interrupt pin changes. |
| r8044 | r8045 | |
| 1050 | 1050 | if (floppy_wpt_r(drive) == CLEAR_LINE) |
| 1051 | 1051 | reply |= DS_WRPROT; |
| 1052 | 1052 | |
| 1053 | /* if (image_exists(disk_img)) */ | |
| 1053 | /* if (image_exists(disk_img)) */ | |
| 1054 | 1054 | |
| 1055 | 1055 | reply |= DS_READY; /* Floppies don't have a READY line; line is pulled up */ |
| 1056 | 1056 | reply |= DS_SKCOM; /* Same here. */ |
| r8044 | r8045 | |
| 1060 | 1060 | UINT8 state; |
| 1061 | 1061 | drive = hfdc_current_harddisk(); |
| 1062 | 1062 | state = ti99_mfm_harddisk_status(drive); |
| 1063 | if (state & MFMHD_TRACK00) | |
| 1063 | if (state & MFMHD_TRACK00) | |
| 1064 | 1064 | reply |= DS_TRK00; |
| 1065 | 1065 | if (state & MFMHD_SEEKCOMP) |
| 1066 | 1066 | reply |= DS_SKCOM; |
| r8044 | r8045 | |
| 1080 | 1080 | static UINT8 hfdc_dma_read_callback(void) |
| 1081 | 1081 | { |
| 1082 | 1082 | UINT8 value = hfdc_ram[dma_address & 0x7fff]; |
| 1083 | dma_address++; | |
| 1083 | dma_address++; | |
| 1084 | 1084 | return value; |
| 1085 | 1085 | } |
| 1086 | 1086 | |
| r8044 | r8045 | |
| 1093 | 1093 | dma_address++; |
| 1094 | 1094 | } |
| 1095 | 1095 | |
| 1096 | /* | |
| 1097 | Preliminary MFM harddisk interface. | |
| 1096 | /* | |
| 1097 | Preliminary MFM harddisk interface. | |
| 1098 | 1098 | */ |
| 1099 | 1099 | static void hfdc_harddisk_get_next_id(int head, chrn_id_hd *id) |
| 1100 | 1100 | { |
| r8044 | r8045 | |
| 1119 | 1119 | { |
| 1120 | 1120 | running_device *harddisk = hfdc_current_harddisk(); |
| 1121 | 1121 | if (harddisk != NULL) |
| 1122 | ti99_mfm_harddisk_write_sector(harddisk, cylinder, head, sector, buf, sector_length); | |
| 1122 | ti99_mfm_harddisk_write_sector(harddisk, cylinder, head, sector, buf, sector_length); | |
| 1123 | 1123 | } |
| 1124 | 1124 | |
| 1125 | 1125 | static void hfdc_harddisk_read_track(int head, UINT8 **buffer, int *data_count) |
| r8044 | r8045 | |
| 1144 | 1144 | running_device *device = devtag_get_device(machine, "smc92x4"); |
| 1145 | 1145 | const char *flopname[] = {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3}; |
| 1146 | 1146 | const char *hardname[] = {MFMHD_0, MFMHD_1, MFMHD_2}; |
| 1147 | ||
| 1147 | ||
| 1148 | 1148 | int i; |
| 1149 | ||
| 1149 | ||
| 1150 | 1150 | ti99_disk_DSR = memory_region(machine, region_dsr) + offset_hfdc_dsr; |
| 1151 | 1151 | hfdc_ram = memory_region(machine, region_dsr) + offset_hfdc_ram; |
| 1152 | 1152 | hfdc_ram_offset[0] = hfdc_ram_offset[1] = hfdc_ram_offset[2] = 0; |
| r8044 | r8045 | |
| 1162 | 1162 | |
| 1163 | 1163 | ti99_peb_set_card_handlers(0x1100, & hfdc_handlers); |
| 1164 | 1164 | |
| 1165 | if ((input_port_read(machine, "DISKCTRL") & DISK_HFDC) | |
| 1166 | && (input_port_read(machine, "HFDCDIP")&0x55)) | |
| 1165 | if ((input_port_read(machine, "DISKCTRL") & DISK_HFDC) | |
| 1166 | && (input_port_read(machine, "HFDCDIP")&0x55)) | |
| 1167 | 1167 | ti99_set_80_track_drives(TRUE); |
| 1168 | 1168 | else |
| 1169 | 1169 | ti99_set_80_track_drives(FALSE); |
| 1170 | ||
| 1170 | ||
| 1171 | 1171 | smc92x4_set_timing(device, input_port_read(machine, "DRVSPD")); |
| 1172 | ||
| 1172 | ||
| 1173 | 1173 | set_all_geometries(machine, FLOPPY_DRIVE_DS_80); |
| 1174 | 1174 | |
| 1175 | /* Connect floppy drives to controller. Note that *this* is the | |
| 1176 | controller, not the controller chip. The pcb contains a select | |
| 1177 | logic. | |
| 1178 | TODO: Turn this implementation into a device so that this is | |
| 1179 | correctly modelled. | |
| 1180 | */ | |
| 1175 | /* Connect floppy drives to controller. Note that *this* is the | |
| 1176 | controller, not the controller chip. The pcb contains a select | |
| 1177 | logic. | |
| 1178 | TODO: Turn this implementation into a device so that this is | |
| 1179 | correctly modelled. | |
| 1180 | */ | |
| 1181 | 1181 | for (i = 0; i < 4; i++) |
| 1182 | 1182 | { |
| 1183 | 1183 | if (device->owner != NULL) |
| r8044 | r8045 | |
| 1185 | 1185 | floppy_unit[i] = device->owner->subdevice(flopname[i]); |
| 1186 | 1186 | if (floppy_unit[i]==NULL) |
| 1187 | 1187 | { |
| 1188 | floppy_unit[i] = devtag_get_device(device->machine, flopname[i]); | |
| 1188 | floppy_unit[i] = devtag_get_device(device->machine, flopname[i]); | |
| 1189 | 1189 | } |
| 1190 | 1190 | } |
| 1191 | 1191 | else |
| 1192 | 1192 | { |
| 1193 | floppy_unit[i] = devtag_get_device(device->machine, flopname[i]); | |
| 1193 | floppy_unit[i] = devtag_get_device(device->machine, flopname[i]); | |
| 1194 | 1194 | } |
| 1195 | 1195 | |
| 1196 | if (floppy_unit[i]!=NULL) | |
| 1196 | if (floppy_unit[i]!=NULL) | |
| 1197 | 1197 | { |
| 1198 | 1198 | floppy_drive_set_controller(floppy_unit[i], device); |
| 1199 | // | |
| 1199 | // floppy_drive_set_index_pulse_callback(floppy_unit[i], smc92x4_index_pulse_callback); | |
| 1200 | 1200 | floppy_drive_set_rpm(floppy_unit[i], 300.); |
| 1201 | 1201 | } |
| 1202 | else | |
| 1202 | else | |
| 1203 | 1203 | { |
| 1204 | 1204 | logerror("99_dsk: Image %s is null\n", flopname[i]); |
| 1205 | 1205 | } |
| r8044 | r8045 | |
| 1211 | 1211 | harddisk_unit[i] = devtag_get_device(device->machine, hardname[i-1]); |
| 1212 | 1212 | } |
| 1213 | 1213 | harddisk_unit[0] = NULL; |
| 1214 | ||
| 1214 | ||
| 1215 | 1215 | if (device) { |
| 1216 | 1216 | smc92x4_reset(device); |
| 1217 | 1217 | } |
| r8044 | r8045 | |
| 1224 | 1224 | DEVCB_LINE(ti99_hfdc_dip_w), |
| 1225 | 1225 | DEVCB_HANDLER(ti99_hfdc_auxbus_out), |
| 1226 | 1226 | DEVCB_LINE(ti99_hfdc_auxbus_in), |
| 1227 | ||
| 1227 | ||
| 1228 | 1228 | hfdc_current_floppy, |
| 1229 | 1229 | hfdc_dma_read_callback, |
| 1230 | 1230 | hfdc_dma_write_callback, |
| r8044 | r8045 | |
| 1241 | 1241 | int mycheck = 0; |
| 1242 | 1242 | |
| 1243 | 1243 | /* |
| 1244 | Read disk CRU interface | |
| 1245 | HFDC manual p. 44 | |
| 1246 | ||
| 1247 | CRU Select=0 | |
| 1248 | CRU rel. address Definition | |
| 1249 | 00 Disk controller interrupt | |
| 1250 | 02 Motor status | |
| 1251 | 04 DMA in progress | |
| 1252 | ||
| 1253 | Note that the cru line settings on the board do not match the | |
| 1254 | description. 02 and 04 switch positions. Similarly, the dip switches | |
| 1255 | for the drive configurations are not correctly enumerated in the manual. | |
| 1256 | ||
| 1257 | CRU Select=1 | |
| 1258 | CRU rel. address Definition | |
| 1259 | 00 Switch 4 status \_ drive 2 config | |
| 1260 | 02 Switch 3 status / | |
| 1261 | 04 Switch 2 status \_ drive 1 config | |
| 1262 | 06 Switch 1 status / | |
| 1263 | 08 Switch 8 status \_ drive 4 config | |
| 1264 | 0A Switch 7 status / | |
| 1265 | 0C Switch 6 status \_ drive 3 config | |
| 1266 | 0E Switch 5 status / | |
| 1267 | ||
| 1268 | config: 00 = 9/16/18 sectors, 40 tracks, 16 msec | |
| 1269 | 10 = 9/16/18 sectors, 40 tracks, 8 msec | |
| 1270 | 01 = 9/16/18 sectors, 80 tracks, 2 msec | |
| 1271 | 11 = 36 sectors, 80 tracks, 2 msec | |
| 1244 | Read disk CRU interface | |
| 1245 | HFDC manual p. 44 | |
| 1246 | ||
| 1247 | CRU Select=0 | |
| 1248 | CRU rel. address Definition | |
| 1249 | 00 Disk controller interrupt | |
| 1250 | 02 Motor status | |
| 1251 | 04 DMA in progress | |
| 1252 | ||
| 1253 | Note that the cru line settings on the board do not match the | |
| 1254 | description. 02 and 04 switch positions. Similarly, the dip switches | |
| 1255 | for the drive configurations are not correctly enumerated in the manual. | |
| 1256 | ||
| 1257 | CRU Select=1 | |
| 1258 | CRU rel. address Definition | |
| 1259 | 00 Switch 4 status \_ drive 2 config | |
| 1260 | 02 Switch 3 status / | |
| 1261 | 04 Switch 2 status \_ drive 1 config | |
| 1262 | 06 Switch 1 status / | |
| 1263 | 08 Switch 8 status \_ drive 4 config | |
| 1264 | 0A Switch 7 status / | |
| 1265 | 0C Switch 6 status \_ drive 3 config | |
| 1266 | 0E Switch 5 status / | |
| 1267 | ||
| 1268 | config: 00 = 9/16/18 sectors, 40 tracks, 16 msec | |
| 1269 | 10 = 9/16/18 sectors, 40 tracks, 8 msec | |
| 1270 | 01 = 9/16/18 sectors, 80 tracks, 2 msec | |
| 1271 | 11 = 36 sectors, 80 tracks, 2 msec | |
| 1272 | 1272 | */ |
| 1273 | 1273 | static int hfdc_cru_r(running_machine *machine, int offset) |
| 1274 | 1274 | { |
| r8044 | r8045 | |
| 1279 | 1279 | if (cru_sel) |
| 1280 | 1280 | { |
| 1281 | 1281 | /* DIP switches. Logic levels are inverted (on->0, off->1). CRU |
| 1282 | bit order is the reverse of DIP-switch order, too (dip 1 -> bit 7, | |
| 1283 | dip 8 -> bit 0). | |
| 1284 | ||
| 1285 | MZ: 00 should not be used since there is a bug in the | |
| 1286 | DSR of the HFDC which causes problems with SD disks | |
| 1287 | (controller tries DD and then fails to fall back to SD) */ | |
| 1288 | ||
| 1282 | bit order is the reverse of DIP-switch order, too (dip 1 -> bit 7, | |
| 1283 | dip 8 -> bit 0). | |
| 1284 | ||
| 1285 | MZ: 00 should not be used since there is a bug in the | |
| 1286 | DSR of the HFDC which causes problems with SD disks | |
| 1287 | (controller tries DD and then fails to fall back to SD) */ | |
| 1288 | ||
| 1289 | 1289 | reply = ~(input_port_read(machine, "HFDCDIP")); |
| 1290 | // | |
| 1290 | // printf("hfdc cru read 7-0 = %02x\n", reply); | |
| 1291 | 1291 | } |
| 1292 | 1292 | else |
| 1293 | 1293 | { |
| 1294 | 1294 | reply = 0; |
| 1295 | /* if (hfdc_irq_state) | |
| 1296 | reply |= 1; | |
| 1297 | if (motor_on) | |
| 1298 | reply |= 2; | |
| 1299 | if (hfdc_dma_in_progress) | |
| 1300 | reply |= 4;*/ | |
| 1301 | ||
| 1295 | /* if (hfdc_irq_state) | |
| 1296 | reply |= 1; | |
| 1297 | if (motor_on) | |
| 1298 | reply |= 2; | |
| 1299 | if (hfdc_dma_in_progress) | |
| 1300 | reply |= 4;*/ | |
| 1301 | ||
| 1302 | 1302 | if (hfdc_irq_state) |
| 1303 | 1303 | reply |= 0x01; |
| 1304 | 1304 | if (hfdc_dip_state) |
| 1305 | reply |= 0x02; | |
| 1305 | reply |= 0x02; | |
| 1306 | 1306 | if (motor_on) |
| 1307 | 1307 | reply |= 0x04; |
| 1308 | // | |
| 1308 | // printf("hfdc cru read 7-0 = %02x\n", reply); | |
| 1309 | 1309 | |
| 1310 | 1310 | } |
| 1311 | 1311 | } |
| 1312 | 1312 | else /* CRU bits 8+ */ |
| 1313 | 1313 | reply = 0; |
| 1314 | // | |
| 1314 | // printf("hfdc cru read %d = %d\n", offset, reply); | |
| 1315 | 1315 | |
| 1316 | 1316 | return reply; |
| 1317 | 1317 | } |
| 1318 | 1318 | |
| 1319 | 1319 | |
| 1320 | 1320 | /* |
| 1321 | Write disk CRU interface | |
| 1322 | HFDC manual p. 43 | |
| 1323 | ||
| 1324 | CRU rel. address Definition Active | |
| 1325 | 00 Device Service Routine Select HIGH | |
| 1326 | 02 Reset to controller chip LOW | |
| 1327 | 04 Floppy Motor on / CD0 HIGH | |
| 1328 | 06 ROM page select 0 / CD1 | |
| 1329 | 08 ROM page select 1 / CRU input select | |
| 1330 | 12/4/6/8/A RAM page select at 0x5400 | |
| 1331 | 1C/E/0/2/4 RAM page select at 0x5800 | |
| 1332 | 26/8/A/C/E RAM page select at 0x5C00 | |
| 1333 | ||
| 1334 | CD0 and CD1 are Clock Divider selections for the Floppy Data Separator (FDC9216) | |
| 1321 | Write disk CRU interface | |
| 1322 | HFDC manual p. 43 | |
| 1323 | ||
| 1324 | CRU rel. address Definition Active | |
| 1325 | 00 Device Service Routine Select HIGH | |
| 1326 | 02 Reset to controller chip LOW | |
| 1327 | 04 Floppy Motor on / CD0 HIGH | |
| 1328 | 06 ROM page select 0 / CD1 | |
| 1329 | 08 ROM page select 1 / CRU input select | |
| 1330 | 12/4/6/8/A RAM page select at 0x5400 | |
| 1331 | 1C/E/0/2/4 RAM page select at 0x5800 | |
| 1332 | 26/8/A/C/E RAM page select at 0x5C00 | |
| 1333 | ||
| 1334 | CD0 and CD1 are Clock Divider selections for the Floppy Data Separator (FDC9216) | |
| 1335 | 1335 | */ |
| 1336 | 1336 | static void hfdc_cru_w(running_machine *machine, int offset, int data) |
| 1337 | { | |
| 1337 | { | |
| 1338 | 1338 | switch (offset) |
| 1339 | 1339 | { |
| 1340 | 1340 | case 0: |
| r8044 | r8045 | |
| 1403 | 1403 | hfdc_ram_offset[(offset-9)/5] &= ~(0x400 << ((offset-9)%5)); |
| 1404 | 1404 | break; |
| 1405 | 1405 | } |
| 1406 | // | |
| 1406 | // printf("hfdc cru write bit %d = %d\n", offset, data); | |
| 1407 | 1407 | } |
| 1408 | 1408 | |
| 1409 | 1409 | |
| 1410 | 1410 | /* |
| 1411 | read a byte in disk DSR space | |
| 1412 | HFDC manual, p. 44 | |
| 1413 | Memory map as seen by the 99/4A PEB | |
| 1414 | ||
| 1415 | 0x4000 - 0x4fbf one of four possible ROM pages | |
| 1416 | 0x4fc0 - 0x4fcf tape select | |
| 1417 | 0x4fd0 - 0x4fdf disk controller select | |
| 1418 | 0x4fe0 - 0x4fff time chip select | |
| 1419 | ||
| 1420 | 0x5000 - 0x53ff static RAM page 0x10 | |
| 1421 | 0x5400 - 0x57ff static RAM page any of 32 pages | |
| 1422 | 0x5800 - 0x5bff static RAM page any of 32 pages | |
| 1423 | 0x5c00 - 0x5fff static RAM page any of 32 pages | |
| 1411 | read a byte in disk DSR space | |
| 1412 | HFDC manual, p. 44 | |
| 1413 | Memory map as seen by the 99/4A PEB | |
| 1414 | ||
| 1415 | 0x4000 - 0x4fbf one of four possible ROM pages | |
| 1416 | 0x4fc0 - 0x4fcf tape select | |
| 1417 | 0x4fd0 - 0x4fdf disk controller select | |
| 1418 | 0x4fe0 - 0x4fff time chip select | |
| 1419 | ||
| 1420 | 0x5000 - 0x53ff static RAM page 0x10 | |
| 1421 | 0x5400 - 0x57ff static RAM page any of 32 pages | |
| 1422 | 0x5800 - 0x5bff static RAM page any of 32 pages | |
| 1423 | 0x5c00 - 0x5fff static RAM page any of 32 pages | |
| 1424 | 1424 | */ |
| 1425 | 1425 | static READ8_HANDLER(hfdc_mem_r) |
| 1426 | 1426 | { |
| r8044 | r8045 | |
| 1431 | 1431 | /* dsr ROM */ |
| 1432 | 1432 | return ti99_disk_DSR[hfdc_rom_offset+offset]; |
| 1433 | 1433 | } |
| 1434 | ||
| 1434 | ||
| 1435 | 1435 | if (offset >= 0xfc0 && offset <= 0x0fcf) |
| 1436 | 1436 | { |
| 1437 | 1437 | /* tape controller */ |
| r8044 | r8045 | |
| 1443 | 1443 | { |
| 1444 | 1444 | /* Disk controller. Note that the odd addresses are ignored and |
| 1445 | 1445 | the addresses used for the write ports are also masked away |
| 1446 | since the write operations in the ti99 system are always | |
| 1446 | since the write operations in the ti99 system are always | |
| 1447 | 1447 | accompanied by read operations before. |
| 1448 | 1448 | */ |
| 1449 | if ((offset & 3) == 0x00) | |
| 1449 | if ((offset & 3) == 0x00) | |
| 1450 | 1450 | { |
| 1451 | | |
| 1451 | | |
| 1452 | 1452 | } |
| 1453 | 1453 | else return 0; |
| 1454 | 1454 | } |
| r8044 | r8045 | |
| 1468 | 1468 | /* ram page >08 (hfdc manual says >10) */ |
| 1469 | 1469 | return hfdc_ram[0x2000+(offset-0x1000)]; |
| 1470 | 1470 | } |
| 1471 | ||
| 1471 | ||
| 1472 | 1472 | /* The remaining space is ram with mapper: |
| 1473 | 1400, 1800, 1c00 are the three banks; get the pointer | |
| 1474 | plus the offset within the bank | |
| 1475 | */ | |
| 1473 | 1400, 1800, 1c00 are the three banks; get the pointer | |
| 1474 | plus the offset within the bank | |
| 1475 | */ | |
| 1476 | 1476 | return hfdc_ram[hfdc_ram_offset[(offset-0x1400) >> 10] + (offset & 0x3ff)]; |
| 1477 | 1477 | } |
| 1478 | 1478 | |
| r8044 | r8045 | |
| 1489 | 1489 | logerror("99_dsk: Writing to HFDC ROM ignored (access to offset %04x)\n", offset); |
| 1490 | 1490 | return; |
| 1491 | 1491 | } |
| 1492 | ||
| 1492 | ||
| 1493 | 1493 | if (offset >= 0xfc0 && offset <= 0x0fcf) |
| 1494 | 1494 | { |
| 1495 | 1495 | /* tape controller */ |
| r8044 | r8045 | |
| 1502 | 1502 | /* Disk controller. Note that the odd addresses are ignored. */ |
| 1503 | 1503 | if ((offset & 3) == 0x02) /* 0x0fd2 and 0x0fd6 */ |
| 1504 | 1504 | { |
| 1505 | | |
| 1505 | | |
| 1506 | 1506 | } |
| 1507 | 1507 | return; |
| 1508 | 1508 | } |
| r8044 | r8045 | |
| 1524 | 1524 | hfdc_ram[0x2000+(offset-0x1000)] = data; |
| 1525 | 1525 | return; |
| 1526 | 1526 | } |
| 1527 | ||
| 1527 | ||
| 1528 | 1528 | /* The remaining space is ram with mapper: |
| 1529 | 1400, 1800, 1c00 are the three banks; get the pointer | |
| 1530 | plus the offset within the bank | |
| 1531 | */ | |
| 1532 | // if ((offset&0x0f)==0) printf("\n"); | |
| 1533 | // printf("%02x ", data); | |
| 1534 | ||
| 1529 | 1400, 1800, 1c00 are the three banks; get the pointer | |
| 1530 | plus the offset within the bank | |
| 1531 | */ | |
| 1532 | // if ((offset&0x0f)==0) printf("\n"); | |
| 1533 | // printf("%02x ", data); | |
| 1534 | ||
| 1535 | 1535 | hfdc_ram[hfdc_ram_offset[(offset-0x1400) >> 10] + (offset & 0x3ff)] = data; |
| 1536 | 1536 | } |
| r8044 | r8045 | |
|---|---|---|
| 734 | 734 | } |
| 735 | 735 | else |
| 736 | 736 | memcpy(cartridge1 + load_offset, image_get_software_region(image, "rom"), filesize); |
| 737 | ||
| 737 | ||
| 738 | 738 | if (filesize < 0x010000) { memcpy(cartridge1 + 0x008000, cartridge1, 0x008000); } /* ->64KB */ |
| 739 | 739 | if (filesize < 0x020000) { memcpy(cartridge1 + 0x010000, cartridge1, 0x010000); } /* ->128KB */ |
| 740 | 740 | if (filesize < 0x040000) { memcpy(cartridge1 + 0x020000, cartridge1, 0x020000); } /* ->256KB */ |
| r8044 | r8045 | |
|---|---|---|
| 36 | 36 | IRQ_B_EXT |
| 37 | 37 | } SCCIRQType; |
| 38 | 38 | |
| 39 | typedef struct | |
| 39 | typedef struct | |
| 40 | 40 | { |
| 41 | 41 | int txIRQEnable; |
| 42 | 42 | int rxIRQEnable; |
| r8044 | r8045 | |
| 133 | 133 | scc->IRQType = IRQ_NONE; |
| 134 | 134 | scc->MasterIRQEnable = 0; |
| 135 | 135 | scc->IRQV = 0; |
| 136 | ||
| 136 | ||
| 137 | 137 | scc8530_initchannel(scc, 0); |
| 138 | 138 | scc8530_initchannel(scc, 1); |
| 139 | 139 | scc8530_resetchannel(scc, 0); |
| r8044 | r8045 | |
| 199 | 199 | scc->IRQType = IRQ_NONE; |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | // printf("SCC: irqstat %d, last %d\n", irqstat, scc->lastIRQStat); | |
| 203 | // printf("ch0: en %d pd %d ch1: en %d pd %d\n", scc->channel[0].txIRQEnable, scc->channel[0].txIRQPending, scc->channel[1].txIRQEnable, scc->channel[1].txIRQPending); | |
| 202 | // printf("SCC: irqstat %d, last %d\n", irqstat, scc->lastIRQStat); | |
| 203 | // printf("ch0: en %d pd %d ch1: en %d pd %d\n", scc->channel[0].txIRQEnable, scc->channel[0].txIRQPending, scc->channel[1].txIRQEnable, scc->channel[1].txIRQPending); | |
| 204 | 204 | |
| 205 | 205 | // don't spam the driver with unnecessary transitions |
| 206 | 206 | if (irqstat != scc->lastIRQStat) |
| r8044 | r8045 | |
| 321 | 321 | break; |
| 322 | 322 | |
| 323 | 323 | case 5: // Tx parameters and controls |
| 324 | // | |
| 324 | // printf("ch %d TxEnable = %d [%02x]\n", ch, data & 8, data); | |
| 325 | 325 | pChan->txEnable = data & 8; |
| 326 | 326 | break; |
| 327 | 327 | |
| r8044 | r8045 | |
| 352 | 352 | scc->IRQType = IRQ_NONE; |
| 353 | 353 | scc->MasterIRQEnable = 0; |
| 354 | 354 | scc->IRQV = 0; |
| 355 | ||
| 355 | ||
| 356 | 356 | scc8530_initchannel(scc, 0); |
| 357 | 357 | scc8530_initchannel(scc, 1); |
| 358 | 358 | scc8530_resetchannel(scc, 0); |
| r8044 | r8045 | |
| 361 | 361 | // make sure we stop yanking the IRQ line if we were |
| 362 | 362 | scc_updateirqs(device); |
| 363 | 363 | break; |
| 364 | ||
| 364 | ||
| 365 | 365 | } |
| 366 | 366 | break; |
| 367 | 367 | |
| 368 | 368 | case 10: // misc transmitter/receiver control bits |
| 369 | case 11: // clock mode control | |
| 370 | case 12: // lower byte of baud rate gen | |
| 369 | case 11: // clock mode control | |
| 370 | case 12: // lower byte of baud rate gen | |
| 371 | 371 | case 13: // upper byte of baud rate gen |
| 372 | 372 | break; |
| 373 | 373 |
| r8044 | r8045 | |
|---|---|---|
| 13 | 13 | |
| 14 | 14 | - 2040 DOS 1 FDC rom (jumps to 104d while getting block header) |
| 15 | 15 | |
| 16 | FE70: jsr $104D | |
| 17 | 104D: m6502_brk#$00 | |
| 16 | FE70: jsr $104D | |
| 17 | 104D: m6502_brk#$00 | |
| 18 | 18 | |
| 19 | 19 | - Micropolis 8x50 stepper motor is same as 4040, except it takes 4 pulses to step a track instead of 1 |
| 20 | 20 | - error/activity LEDs |
| r8044 | r8045 | |
|---|---|---|
| 483 | 483 | |
| 484 | 484 | #if 0 |
| 485 | 485 | // FIXME |
| 486 | // in very old MESS versions, we had these handlers to enable SID writes to 0xd400. | |
| 486 | // in very old MESS versions, we had these handlers to enable SID writes to 0xd400. | |
| 487 | 487 | // would a real SID Card allow for this? If not, this should be removed completely |
| 488 | 488 | static WRITE8_HANDLER( c16_sidcart_16k ) |
| 489 | 489 | { |
| r8044 | r8045 | |
|---|---|---|
| 210 | 210 | { |
| 211 | 211 | assert(device != NULL); |
| 212 | 212 | assert(device->token != NULL); |
| 213 | assert((device->type == C1540) || (device->type == C1541) || (device->type == C1541C) || (device->type == C1541II) || | |
| 213 | assert((device->type == C1540) || (device->type == C1541) || (device->type == C1541C) || (device->type == C1541II) || | |
| 214 | 214 | (device->type == SX1541) || (device->type == OC118) || (device->type == C2031)); |
| 215 | 215 | return (c1541_t *)device->token; |
| 216 | 216 | } |
| r8044 | r8045 | |
| 218 | 218 | INLINE c1541_config *get_safe_config(running_device *device) |
| 219 | 219 | { |
| 220 | 220 | assert(device != NULL); |
| 221 | assert((device->type == C1540) || (device->type == C1541) || (device->type == C1541C) || (device->type == C1541II) || | |
| 221 | assert((device->type == C1540) || (device->type == C1541) || (device->type == C1541C) || (device->type == C1541II) || | |
| 222 | 222 | (device->type == SX1541) || (device->type == OC118) || (device->type == C2031)); |
| 223 | 223 | return (c1541_config *)device->baseconfig().inline_config; |
| 224 | 224 | } |
| r8044 | r8045 | |
|---|---|---|
| 3564 | 3564 | memcpy(chunklen, temp_copy + offset, 4); |
| 3565 | 3565 | bytes_to_read -= 4; |
| 3566 | 3566 | offset += 4; |
| 3567 | ||
| 3567 | ||
| 3568 | 3568 | // calculate little-endian value, just to be sure |
| 3569 | 3569 | chunksize = chunklen[0] + (chunklen[1] << 8) + (chunklen[2] << 16) + (chunklen[3] << 24); |
| 3570 | ||
| 3570 | ||
| 3571 | 3571 | if (strncmp(chunkid, "cb", 2) == 0) |
| 3572 | 3572 | { |
| 3573 | 3573 | // load chunk into RAM |
| r8044 | r8045 | |
| 3580 | 3580 | { |
| 3581 | 3581 | // clear RAM block |
| 3582 | 3582 | memset(mem + 0x4000 * ramblock, 0, 0x4000); |
| 3583 | ||
| 3583 | ||
| 3584 | 3584 | // load block into ROM area |
| 3585 | 3585 | if (chunksize > 16384) |
| 3586 | 3586 | chunksize = 16384; |
| r8044 | r8045 | |
|---|---|---|
| 122 | 122 | 2010-02-04 Phill Harvey-Smith |
| 123 | 123 | - Added multiple sector write as the RM Nimbus needs it. |
| 124 | 124 | |
| 125 | 2010-March-22 Curt Coder: | |
| 126 | - Implemented immediate and index pulse interrupts. | |
| 125 | 2010-March-22 Curt Coder: | |
| 126 | - Implemented immediate and index pulse interrupts. | |
| 127 | 127 | |
| 128 | 128 | TODO: |
| 129 | 129 | - Multiple record write |
| r8044 | r8045 | |
| 574 | 574 | #endif |
| 575 | 575 | |
| 576 | 576 | /* Get the size in bytes of the current track. For real hardware this |
| 577 | may vary per system in small degree, and there even for each track | |
| 578 | and head, so we should not assume a fixed value here. | |
| 579 | As we are using a buffered track writing, we have to find out how long | |
| 580 | the track will become. The only object which can tell us is the | |
| 581 | selected format. | |
| 582 | */ | |
| 577 | may vary per system in small degree, and there even for each track | |
| 578 | and head, so we should not assume a fixed value here. | |
| 579 | As we are using a buffered track writing, we have to find out how long | |
| 580 | the track will become. The only object which can tell us is the | |
| 581 | selected format. | |
| 582 | */ | |
| 583 | 583 | w->data_count = 0; |
| 584 | 584 | floppy = flopimg_get_image(w->drive); |
| 585 | 585 | if (floppy != NULL) |
| r8044 | r8045 | |
| 731 | 731 | } |
| 732 | 732 | #endif |
| 733 | 733 | /* Determine the track size. We cannot allow different sizes in this |
| 734 | ||
| 734 | design (see above, write_track). */ | |
| 735 | 735 | w->data_count = 0; |
| 736 | 736 | floppy = flopimg_get_image(w->drive); |
| 737 | 737 | if (floppy != NULL) |
| r8044 | r8045 | |
|---|---|---|
| 119 | 119 | |
| 120 | 120 | static DEVICE_START( c64h156 ) |
| 121 | 121 | { |
| 122 | // | |
| 122 | // c64h156_t *c64h156 = get_safe_token(device); | |
| 123 | 123 | |
| 124 | 124 | /* allocate data timer */ |
| 125 | // | |
| 125 | // c64h156->bit_timer = timer_alloc(device->machine, bit_tick, (void *)device); | |
| 126 | 126 | |
| 127 | 127 | /* register for state saving */ |
| 128 | // | |
| 128 | // state_save_register_device_item(device, 0, c64h156->); | |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | /*------------------------------------------------- |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /********************************************************************** |
| 2 | 2 | |
| 3 | 3 | Commodore 64H165 Gate Array emulation |
| 4 | ||
| 5 | Used in 1541B/1541C/1541-II/1571 | |
| 6 | 4 | |
| 5 | Used in 1541B/1541C/1541-II/1571 | |
| 6 | ||
| 7 | 7 | Copyright MESS Team. |
| 8 | 8 | Visit http://mamedev.org for licensing and usage restrictions. |
| 9 | 9 | |
| r8044 | r8045 | |
| 30 | 30 | OE 19 | | 22 ATNA |
| 31 | 31 | _ACCL 20 |_____________| 21 OSC |
| 32 | 32 | |
| 33 | ||
| 33 | _____ _____ | |
| 34 | 34 | TEST 1 |* \_/ | 42 _BYTE |
| 35 | 35 | YB0 2 | | 41 SOE |
| 36 | 36 | YB1 3 | | 40 B |
| r8044 | r8045 | |
|---|---|---|
| 2212 | 2212 | { |
| 2213 | 2213 | case MODEL_MAC_PORTABLE: |
| 2214 | 2214 | case MODEL_MAC_PB100: |
| 2215 | // printf("Read PM data %x\n", mac->pm_data_recv); | |
| 2216 | return mac->pm_data_recv; | |
| 2215 | // printf("Read PM data %x\n", mac->pm_data_recv); | |
| 2216 | return mac->pm_data_recv; | |
| 2217 | 2217 | |
| 2218 | 2218 | case MODEL_MAC_CLASSIC: |
| 2219 | 2219 | case MODEL_MAC_II: |
| r8044 | r8045 | |
| 2257 | 2257 | // portable/PB100 is pretty different |
| 2258 | 2258 | if (mac->mac_model >= MODEL_MAC_PORTABLE && mac->mac_model <= MODEL_MAC_PB100) |
| 2259 | 2259 | { |
| 2260 | // | |
| 2260 | // printf("Read VIA B: PM_ACK %x\n", mac->pm_ack); | |
| 2261 | 2261 | val = 0x80 | mac->pm_ack; // SCC wait/request |
| 2262 | 2262 | } |
| 2263 | 2263 | else |
| r8044 | r8045 | |
| 2353 | 2353 | mac_enable_sound(sound, (data & 0x80) == 0); |
| 2354 | 2354 | sony_set_sel_line(fdc,(data & 0x20) >> 5); |
| 2355 | 2355 | mac->mac_drive_select = ((data & 0x10) >> 4); |
| 2356 | // | |
| 2356 | // printf("PM_REQ = %x, was %x\n", data & 1, mac->pm_req); | |
| 2357 | 2357 | mac->pm_req = data & 1; |
| 2358 | 2358 | return; |
| 2359 | 2359 | } |
| r8044 | r8045 | |
|---|---|---|
| 75 | 75 | { |
| 76 | 76 | /* |
| 77 | 77 | |
| 78 | ||
| 78 | bit description | |
| 79 | 79 | |
| 80 | 0 | |
| 81 | 1 RTTY receive | |
| 82 | 2 RTTY transmit | |
| 83 | 3 RTTY PTT | |
| 84 | 4 | |
| 85 | 5 | |
| 86 | 6 cassette out | |
| 87 | 7 cassette in | |
| 80 | 0 | |
| 81 | 1 RTTY receive | |
| 82 | 2 RTTY transmit | |
| 83 | 3 RTTY PTT | |
| 84 | 4 | |
| 85 | 5 | |
| 86 | 6 cassette out | |
| 87 | 7 cassette in | |
| 88 | 88 | |
| 89 | ||
| 89 | */ | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | Z80PIO_INTERFACE( ac1_z80pio_intf ) |
| r8044 | r8045 | |
|---|---|---|
| 152 | 152 | int nes_ppu_vidaccess( running_device *device, int address, int data ) |
| 153 | 153 | { |
| 154 | 154 | nes_state *state = (nes_state *)device->machine->driver_data; |
| 155 | ||
| 155 | ||
| 156 | 156 | /* TODO: this is a bit of a hack, needed to get Argus, ASO, etc to work */ |
| 157 | 157 | /* but, B-Wings, submath (j) seem to use this location differently... */ |
| 158 | 158 | if (state->chr_chunks && (address & 0x3fff) < 0x2000) |
| r8044 | r8045 | |
| 259 | 259 | static void nes_machine_stop( running_machine *machine ) |
| 260 | 260 | { |
| 261 | 261 | nes_state *state = (nes_state *)machine->driver_data; |
| 262 | ||
| 262 | ||
| 263 | 263 | /* Write out the battery file if necessary */ |
| 264 | 264 | if (state->battery) |
| 265 | 265 | image_battery_save(state->cart, state->battery_ram, NES_BATTERY_SIZE); |
| r8044 | r8045 | |
| 493 | 493 | /* Unfortunately, many .unf files have been released as .nes, so we cannot rely on extensions only */ |
| 494 | 494 | memset(magic, '\0', sizeof(magic)); |
| 495 | 495 | image_fread(image, magic, 4); |
| 496 | ||
| 496 | ||
| 497 | 497 | if ((magic[0] == 'N') && (magic[1] == 'E') && (magic[2] == 'S')) /* If header starts with 'NES' it is iNES */ |
| 498 | 498 | { |
| 499 | 499 | state->format = 1; // we use this to select between mapper_reset / unif_reset |
| 500 | ||
| 500 | ||
| 501 | 501 | mapinfo = image_extrainfo(image); |
| 502 | ||
| 502 | ||
| 503 | 503 | if (mapinfo) |
| 504 | 504 | { |
| 505 | 505 | if (4 == sscanf(mapinfo,"%d %d %d %d", &mapint1, &mapint2, &mapint3, &mapint4)) |
| r8044 | r8045 | |
| 521 | 521 | { |
| 522 | 522 | logerror("NES: No extrainfo found\n"); |
| 523 | 523 | } |
| 524 | ||
| 524 | ||
| 525 | 525 | if (!goodcrcinfo) |
| 526 | 526 | { |
| 527 | 527 | // image_extrainfo() resets the file position back to start. |
| 528 | 528 | // Let's skip past the magic header once again. |
| 529 | 529 | image_fseek(image, 4, SEEK_SET); |
| 530 | ||
| 530 | ||
| 531 | 531 | image_fread(image, &state->prg_chunks, 1); |
| 532 | 532 | image_fread(image, &state->chr_chunks, 1); |
| 533 | 533 | /* Read the first ROM option byte (offset 6) */ |
| 534 | 534 | image_fread(image, &m, 1); |
| 535 | ||
| 535 | ||
| 536 | 536 | /* Interpret the iNES header flags */ |
| 537 | 537 | state->mapper = (m & 0xf0) >> 4; |
| 538 | 538 | local_options = m & 0x0f; |
| 539 | ||
| 539 | ||
| 540 | 540 | /* Read the second ROM option byte (offset 7) */ |
| 541 | 541 | image_fread(image, &m, 1); |
| 542 | ||
| 542 | ||
| 543 | 543 | /* Check for skanky headers */ |
| 544 | 544 | image_fread(image, &skank, 8); |
| 545 | ||
| 545 | ||
| 546 | 546 | /* If the header has junk in the unused bytes, assume the extra mapper byte is also invalid */ |
| 547 | 547 | /* We only check the first 4 unused bytes for now */ |
| 548 | 548 | for (i = 0; i < 4; i ++) |
| r8044 | r8045 | |
| 554 | 554 | } |
| 555 | 555 | } |
| 556 | 556 | logerror("\n"); |
| 557 | ||
| 557 | ||
| 558 | 558 | state->mapper = state->mapper | (m & 0xf0); |
| 559 | 559 | } |
| 560 | ||
| 560 | ||
| 561 | 561 | state->hard_mirroring = local_options & 0x01; |
| 562 | 562 | state->battery = local_options & 0x02; |
| 563 | 563 | state->trainer = local_options & 0x04; |
| 564 | 564 | state->four_screen_vram = local_options & 0x08; |
| 565 | ||
| 565 | ||
| 566 | 566 | if (state->battery) |
| 567 | 567 | logerror("-- Battery found\n"); |
| 568 | ||
| 568 | ||
| 569 | 569 | if (state->trainer) |
| 570 | 570 | logerror("-- Trainer found\n"); |
| 571 | ||
| 571 | ||
| 572 | 572 | if (state->four_screen_vram) |
| 573 | 573 | logerror("-- 4-screen VRAM\n"); |
| 574 | ||
| 574 | ||
| 575 | 575 | /* Free the regions that were allocated by the ROM loader */ |
| 576 | 576 | memory_region_free(image->machine, "maincpu"); |
| 577 | 577 | memory_region_free(image->machine, "gfx1"); |
| 578 | ||
| 578 | ||
| 579 | 579 | /* Allocate them again with the proper size */ |
| 580 | 580 | memory_region_alloc(image->machine, "maincpu", 0x10000 + (state->prg_chunks + 1) * 0x4000, 0); |
| 581 | 581 | if (state->chr_chunks) |
| 582 | 582 | memory_region_alloc(image->machine, "gfx1", state->chr_chunks * 0x2000, 0); |
| 583 | ||
| 583 | ||
| 584 | 584 | state->rom = memory_region(image->machine, "maincpu"); |
| 585 | 585 | state->vrom = memory_region(image->machine, "gfx1"); |
| 586 | 586 | state->vram = memory_region(image->machine, "gfx2"); |
| 587 | 587 | state->wram = memory_region(image->machine, "user1"); |
| 588 | ||
| 588 | ||
| 589 | 589 | /* Position past the header */ |
| 590 | 590 | image_fseek(image, 16, SEEK_SET); |
| 591 | ||
| 591 | ||
| 592 | 592 | /* Load the 0x200 byte trainer at 0x7000 if it exists */ |
| 593 | 593 | if (state->trainer) |
| 594 | 594 | image_fread(image, &state->wram[0x1000], 0x200); |
| 595 | ||
| 595 | ||
| 596 | 596 | /* Read in the program chunks */ |
| 597 | 597 | if (state->prg_chunks == 1) |
| 598 | 598 | { |
| r8044 | r8045 | |
| 602 | 602 | } |
| 603 | 603 | else |
| 604 | 604 | image_fread(image, &state->rom[0x10000], 0x4000 * state->prg_chunks); |
| 605 | ||
| 605 | ||
| 606 | 606 | #if SPLIT_PRG |
| 607 | 607 | { |
| 608 | 608 | FILE *prgout; |
| 609 | 609 | char outname[255]; |
| 610 | ||
| 610 | ||
| 611 | 611 | sprintf(outname, "%s.prg", image_filename(image)); |
| 612 | 612 | prgout = fopen(outname, "wb"); |
| 613 | 613 | if (prgout) |
| r8044 | r8045 | |
| 619 | 619 | fclose(prgout); |
| 620 | 620 | } |
| 621 | 621 | #endif |
| 622 | ||
| 622 | ||
| 623 | 623 | logerror("**\n"); |
| 624 | 624 | logerror("Mapper: %d\n", state->mapper); |
| 625 | 625 | logerror("PRG chunks: %02x, size: %06x\n", state->prg_chunks, 0x4000 * state->prg_chunks); |
| 626 | 626 | // printf("Mapper: %d\n", state->mapper); |
| 627 | 627 | // printf("PRG chunks: %02x, size: %06x\n", state->prg_chunks, 0x4000 * state->prg_chunks); |
| 628 | ||
| 628 | ||
| 629 | 629 | /* Read in any chr chunks */ |
| 630 | 630 | if (state->chr_chunks > 0) |
| 631 | 631 | { |
| r8044 | r8045 | |
| 633 | 633 | if (state->mapper == 2) |
| 634 | 634 | logerror("Warning: VROM has been found in VRAM-based mapper. Either the mapper is set wrong or the ROM image is incorrect.\n"); |
| 635 | 635 | } |
| 636 | ||
| 636 | ||
| 637 | 637 | #if SPLIT_CHR |
| 638 | 638 | { |
| 639 | 639 | FILE *chrout; |
| 640 | 640 | char outname[255]; |
| 641 | ||
| 641 | ||
| 642 | 642 | sprintf(outname, "%s.chr", image_filename(image)); |
| 643 | 643 | chrout= fopen(outname, "wb"); |
| 644 | 644 | if (chrout) |
| r8044 | r8045 | |
| 649 | 649 | fclose(chrout); |
| 650 | 650 | } |
| 651 | 651 | #endif |
| 652 | ||
| 652 | ||
| 653 | 653 | logerror("CHR chunks: %02x, size: %06x\n", state->chr_chunks, 0x4000 * state->chr_chunks); |
| 654 | 654 | logerror("**\n"); |
| 655 | 655 | // printf("CHR chunks: %02x, size: %06x\n", state->chr_chunks, 0x4000 * state->chr_chunks); |
| 656 | 656 | // printf("**\n"); |
| 657 | ||
| 657 | ||
| 658 | 658 | /* Attempt to load a battery file for this ROM. If successful, we */ |
| 659 | 659 | /* must wait until later to move it to the system memory. */ |
| 660 | 660 | if (state->battery) |
| 661 | 661 | image_battery_load(image, state->battery_data, NES_BATTERY_SIZE, 0x00); |
| 662 | ||
| 662 | ||
| 663 | 663 | } |
| 664 | 664 | else if ((magic[0] == 'U') && (magic[1] == 'N') && (magic[2] == 'I') && (magic[3] == 'F')) /* If header starts with 'UNIF' it is UNIF */ |
| 665 | 665 | { |
| r8044 | r8045 | |
| 673 | 673 | UINT32 size = image_length(image); |
| 674 | 674 | const unif *unif_board; |
| 675 | 675 | int mapr_chunk_found = 0; |
| 676 | ||
| 676 | ||
| 677 | 677 | state->format = 2; // we use this to select between mapper_reset / unif_reset |
| 678 | ||
| 678 | ||
| 679 | 679 | image_fread(image, &buffer, 4); |
| 680 | 680 | unif_ver = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 681 | 681 | logerror("UNIF file found, version %d\n", unif_ver); |
| 682 | ||
| 682 | ||
| 683 | 683 | if (size <= 0x20) |
| 684 | 684 | { |
| 685 | 685 | logerror("%s only contains the UNIF header and no data.\n", image_filename(image)); |
| 686 | 686 | return INIT_FAIL; |
| 687 | 687 | } |
| 688 | ||
| 688 | ||
| 689 | 689 | do |
| 690 | 690 | { |
| 691 | 691 | image_fseek(image, read_length, SEEK_SET); |
| 692 | ||
| 692 | ||
| 693 | 693 | memset(magic2, '\0', sizeof(magic2)); |
| 694 | 694 | image_fread(image, &magic2, 4); |
| 695 | ||
| 695 | ||
| 696 | 696 | #if 0 |
| 697 | 697 | // unfortunately, the MAPR chunk is not always the first chunk (see Super 24-in-1) |
| 698 | 698 | /* Preliminary checks: the first chunk MUST be MAPR! */ |
| 699 | 699 | if (read_length == 0x20 && ((magic2[0] != 'M') || (magic2[1] != 'A') || (magic2[2] != 'P') || (magic2[3] != 'R'))) |
| 700 | 700 | fatalerror("First chunk of data in UNIF should be [MAPR]. Check if your image has been corrupted\n"); |
| 701 | ||
| 701 | ||
| 702 | 702 | /* Preliminary checks: multiple MAPR chunks are FORBIDDEN! */ |
| 703 | 703 | if (read_length > 0x20 && ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R'))) |
| 704 | 704 | fatalerror("UNIF should not have multiple [MAPR] chunks. Check if your image has been corrupted\n"); |
| 705 | 705 | #endif |
| 706 | ||
| 706 | ||
| 707 | 707 | /* we first run through the whole image to find a [MAPR] chunk */ |
| 708 | 708 | /* when found, we set mapr_chunk_found=1 and we go back to load other chunks! */ |
| 709 | 709 | if (!mapr_chunk_found) |
| r8044 | r8045 | |
| 714 | 714 | logerror("[MAPR] chunk found: "); |
| 715 | 715 | image_fread(image, &buffer, 4); |
| 716 | 716 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 717 | ||
| 717 | ||
| 718 | 718 | if (chunk_length <= 0x20) |
| 719 | 719 | image_fread(image, &unif_mapr, chunk_length); |
| 720 | ||
| 720 | ||
| 721 | 721 | unif_board = nes_unif_lookup(unif_mapr); |
| 722 | 722 | logerror("%s\n", unif_mapr); |
| 723 | ||
| 723 | ||
| 724 | 724 | if (unif_board == NULL) |
| 725 | 725 | { |
| 726 | 726 | fatalerror("Unsupported UNIF board %s.\n", unif_mapr); |
| 727 | 727 | // logerror("Unsupported UNIF board %s.\n", unif_mapr); |
| 728 | 728 | } |
| 729 | ||
| 729 | ||
| 730 | 730 | state->mapper = 0; // this allows us to set up memory handlers without duplicating code (for the moment) |
| 731 | 731 | state->board = unif_board->board; |
| 732 | 732 | state->prg_chunks = unif_board->prgrom; |
| r8044 | r8045 | |
| 734 | 734 | state->battery = unif_board->wram; // we should implement WRAM banks... |
| 735 | 735 | // state->hard_mirroring = unif_board->nt; |
| 736 | 736 | // state->four_screen_vram = ; |
| 737 | ||
| 737 | ||
| 738 | 738 | /* Free the regions that were allocated by the ROM loader */ |
| 739 | 739 | memory_region_free(image->machine, "maincpu"); |
| 740 | 740 | memory_region_free(image->machine, "gfx1"); |
| 741 | ||
| 741 | ||
| 742 | 742 | /* Allocate them again with the proper size */ |
| 743 | 743 | memory_region_alloc(image->machine, "maincpu", 0x10000 + (state->prg_chunks + 1) * 0x4000, 0); |
| 744 | 744 | if (state->chr_chunks) |
| 745 | 745 | memory_region_alloc(image->machine, "gfx1", state->chr_chunks * 0x2000, 0); |
| 746 | ||
| 746 | ||
| 747 | 747 | state->rom = memory_region(image->machine, "maincpu"); |
| 748 | 748 | state->vrom = memory_region(image->machine, "gfx1"); |
| 749 | 749 | state->vram = memory_region(image->machine, "gfx2"); |
| 750 | 750 | state->wram = memory_region(image->machine, "user1"); |
| 751 | ||
| 751 | ||
| 752 | 752 | /* for validation purposes */ |
| 753 | 753 | prg_left = unif_board->prgrom * 0x4000; |
| 754 | 754 | chr_left = unif_board->chrrom * 0x2000; |
| 755 | ||
| 755 | ||
| 756 | 756 | /* now that we found the MAPR chunk, we can go back to load other chunks */ |
| 757 | 757 | image_fseek(image, 0x20, SEEK_SET); |
| 758 | 758 | read_length = 0x20; |
| r8044 | r8045 | |
| 762 | 762 | logerror("Skip this chunk. We need a [MAPR] chunk before anything else.\n"); |
| 763 | 763 | image_fread(image, &buffer, 4); |
| 764 | 764 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 765 | ||
| 765 | ||
| 766 | 766 | read_length += (chunk_length + 8); |
| 767 | 767 | } |
| 768 | 768 | } |
| r8044 | r8045 | |
| 776 | 776 | logerror("[MAPR] chunk found (in the 2nd run). Already loaded.\n"); |
| 777 | 777 | image_fread(image, &buffer, 4); |
| 778 | 778 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 779 | ||
| 779 | ||
| 780 | 780 | read_length += (chunk_length + 8); |
| 781 | 781 | } |
| 782 | 782 | else if ((magic2[0] == 'R') && (magic2[1] == 'E') && (magic2[2] == 'A') && (magic2[3] == 'D')) |
| r8044 | r8045 | |
| 784 | 784 | logerror("[READ] chunk found. No support yet.\n"); |
| 785 | 785 | image_fread(image, &buffer, 4); |
| 786 | 786 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 787 | ||
| 787 | ||
| 788 | 788 | read_length += (chunk_length + 8); |
| 789 | 789 | } |
| 790 | 790 | else if ((magic2[0] == 'N') && (magic2[1] == 'A') && (magic2[2] == 'M') && (magic2[3] == 'E')) |
| r8044 | r8045 | |
| 792 | 792 | logerror("[NAME] chunk found. No support yet.\n"); |
| 793 | 793 | image_fread(image, &buffer, 4); |
| 794 | 794 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 795 | ||
| 795 | ||
| 796 | 796 | read_length += (chunk_length + 8); |
| 797 | 797 | } |
| 798 | 798 | else if ((magic2[0] == 'W') && (magic2[1] == 'R') && (magic2[2] == 'T') && (magic2[3] == 'R')) |
| r8044 | r8045 | |
| 800 | 800 | logerror("[WRTR] chunk found. No support yet.\n"); |
| 801 | 801 | image_fread(image, &buffer, 4); |
| 802 | 802 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 803 | ||
| 803 | ||
| 804 | 804 | read_length += (chunk_length + 8); |
| 805 | 805 | } |
| 806 | 806 | else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'C') && (magic2[3] == 'I')) |
| r8044 | r8045 | |
| 808 | 808 | logerror("[TVCI] chunk found. No support yet.\n"); |
| 809 | 809 | image_fread(image, &buffer, 4); |
| 810 | 810 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 811 | ||
| 811 | ||
| 812 | 812 | read_length += (chunk_length + 8); |
| 813 | 813 | } |
| 814 | 814 | else if ((magic2[0] == 'D') && (magic2[1] == 'I') && (magic2[2] == 'N') && (magic2[3] == 'F')) |
| r8044 | r8045 | |
| 816 | 816 | logerror("[DINF] chunk found. No support yet.\n"); |
| 817 | 817 | image_fread(image, &buffer, 4); |
| 818 | 818 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 819 | ||
| 819 | ||
| 820 | 820 | read_length += (chunk_length + 8); |
| 821 | 821 | } |
| 822 | 822 | else if ((magic2[0] == 'C') && (magic2[1] == 'T') && (magic2[2] == 'R') && (magic2[3] == 'L')) |
| r8044 | r8045 | |
| 824 | 824 | logerror("[CTRL] chunk found. No support yet.\n"); |
| 825 | 825 | image_fread(image, &buffer, 4); |
| 826 | 826 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 827 | ||
| 827 | ||
| 828 | 828 | read_length += (chunk_length + 8); |
| 829 | 829 | } |
| 830 | 830 | else if ((magic2[0] == 'B') && (magic2[1] == 'A') && (magic2[2] == 'T') && (magic2[3] == 'R')) |
| r8044 | r8045 | |
| 832 | 832 | logerror("[BATR] chunk found. No support yet.\n"); |
| 833 | 833 | image_fread(image, &buffer, 4); |
| 834 | 834 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 835 | ||
| 835 | ||
| 836 | 836 | read_length += (chunk_length + 8); |
| 837 | 837 | } |
| 838 | 838 | else if ((magic2[0] == 'V') && (magic2[1] == 'R') && (magic2[2] == 'O') && (magic2[3] == 'R')) |
| r8044 | r8045 | |
| 840 | 840 | logerror("[VROR] chunk found. No support yet.\n"); |
| 841 | 841 | image_fread(image, &buffer, 4); |
| 842 | 842 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 843 | ||
| 843 | ||
| 844 | 844 | read_length += (chunk_length + 8); |
| 845 | 845 | } |
| 846 | 846 | else if ((magic2[0] == 'M') && (magic2[1] == 'I') && (magic2[2] == 'R') && (magic2[3] == 'R')) |
| r8044 | r8045 | |
| 848 | 848 | logerror("[MIRR] chunk found. No support yet.\n"); |
| 849 | 849 | image_fread(image, &buffer, 4); |
| 850 | 850 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 851 | ||
| 851 | ||
| 852 | 852 | read_length += (chunk_length + 8); |
| 853 | 853 | } |
| 854 | 854 | else if ((magic2[0] == 'P') && (magic2[1] == 'C') && (magic2[2] == 'K')) |
| r8044 | r8045 | |
| 856 | 856 | logerror("[PCK%c] chunk found. No support yet.\n", magic2[3]); |
| 857 | 857 | image_fread(image, &buffer, 4); |
| 858 | 858 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 859 | ||
| 859 | ||
| 860 | 860 | read_length += (chunk_length + 8); |
| 861 | 861 | } |
| 862 | 862 | else if ((magic2[0] == 'C') && (magic2[1] == 'C') && (magic2[2] == 'K')) |
| r8044 | r8045 | |
| 864 | 864 | logerror("[CCK%c] chunk found. No support yet.\n", magic2[3]); |
| 865 | 865 | image_fread(image, &buffer, 4); |
| 866 | 866 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 867 | ||
| 867 | ||
| 868 | 868 | read_length += (chunk_length + 8); |
| 869 | 869 | } |
| 870 | 870 | else if ((magic2[0] == 'P') && (magic2[1] == 'R') && (magic2[2] == 'G')) |
| r8044 | r8045 | |
| 872 | 872 | logerror("[PRG%c] chunk found. ", magic2[3]); |
| 873 | 873 | image_fread(image, &buffer, 4); |
| 874 | 874 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 875 | ||
| 875 | ||
| 876 | 876 | logerror("It consists of %d 16K-blocks.\n", chunk_length / 0x4000); |
| 877 | 877 | /* Validation */ |
| 878 | 878 | prg_left -= chunk_length; |
| 879 | 879 | if (prg_left < 0) |
| 880 | 880 | fatalerror("PRG chunks larger than expected by board %s!\n", unif_mapr); |
| 881 | ||
| 881 | ||
| 882 | 882 | /* Read in the program chunks */ |
| 883 | 883 | if (state->prg_chunks == 1) |
| 884 | 884 | { |
| r8044 | r8045 | |
| 888 | 888 | } |
| 889 | 889 | else |
| 890 | 890 | image_fread(image, &state->rom[0x10000 + prg_start], chunk_length); |
| 891 | ||
| 891 | ||
| 892 | 892 | prg_start += chunk_length; |
| 893 | 893 | read_length += (chunk_length + 8); |
| 894 | 894 | } |
| r8044 | r8045 | |
| 897 | 897 | logerror("[CHR%c] chunk found. ", magic2[3]); |
| 898 | 898 | image_fread(image, &buffer, 4); |
| 899 | 899 | chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); |
| 900 | ||
| 900 | ||
| 901 | 901 | logerror("It consists of %d 8K-blocks.\n", chunk_length / 0x2000); |
| 902 | 902 | /* validation */ |
| 903 | 903 | chr_left -= chunk_length; |
| 904 | 904 | if (chr_left < 0) |
| 905 | 905 | fatalerror("CHR chunks larger than expected by board %s!\n", unif_mapr); |
| 906 | ||
| 906 | ||
| 907 | 907 | /* Read in the vrom chunks */ |
| 908 | 908 | image_fread(image, state->vrom + chr_start, chunk_length); |
| 909 | ||
| 909 | ||
| 910 | 910 | chr_start += chunk_length; |
| 911 | 911 | read_length += (chunk_length + 8); |
| 912 | 912 | } |
| r8044 | r8045 | |
| 917 | 917 | } |
| 918 | 918 | } |
| 919 | 919 | } while (size > read_length); |
| 920 | ||
| 920 | ||
| 921 | 921 | if (!mapr_chunk_found ) |
| 922 | 922 | fatalerror("UNIF should have a [MAPR] chunk to work. Check if your image has been corrupted\n"); |
| 923 | ||
| 923 | ||
| 924 | 924 | logerror("UNIF support is only very preliminary.\n"); |
| 925 | 925 | } |
| 926 | 926 | else |
| r8044 | r8045 | |
| 952 | 952 | |
| 953 | 953 | if (chr_size) |
| 954 | 954 | memory_region_alloc(image->machine, "gfx1", chr_size, 0); |
| 955 | ||
| 955 | ||
| 956 | 956 | state->rom = memory_region(image->machine, "maincpu"); |
| 957 | 957 | state->vrom = memory_region(image->machine, "gfx1"); |
| 958 | 958 | state->vram = memory_region(image->machine, "gfx2"); |
| r8044 | r8045 | |
| 973 | 973 | state->mapper = 4; // this should depend on the 'feature' field of the .xml file |
| 974 | 974 | state->battery = 0; // presence of a battery should be read from .xml feature |
| 975 | 975 | |
| 976 | // FIXME: we need to handle the remaining variables. on the short term, we might | |
| 977 | // create a table for the various mappers (based on the 'feature' value in xml), | |
| 976 | // FIXME: we need to handle the remaining variables. on the short term, we might | |
| 977 | // create a table for the various mappers (based on the 'feature' value in xml), | |
| 978 | 978 | // but on the long term we need to rework the whole emulation to first use the |
| 979 | 979 | // xml list and have mappers and unif boards to fall back to particular 'feature' |
| 980 | 980 | // values! |
| r8044 | r8045 | |
| 983 | 983 | //state->hard_mirroring = ; |
| 984 | 984 | //state->trainer = ; |
| 985 | 985 | //state->four_screen_vram = ; |
| 986 | ||
| 986 | ||
| 987 | 987 | /* Attempt to load a battery file for this ROM. If successful, we */ |
| 988 | 988 | /* must wait until later to move it to the system memory. */ |
| 989 | 989 | if (state->battery) |
| 990 | 990 | image_battery_load(image, state->battery_data, NES_BATTERY_SIZE, 0x00); |
| 991 | 991 | } |
| 992 | ||
| 992 | ||
| 993 | 993 | return INIT_PASS; |
| 994 | 994 | } |
| 995 | 995 |
| r8044 | r8045 | |
|---|---|---|
| 210 | 210 | |
| 211 | 211 | WRITE8_HANDLER( nes_chr_w ) |
| 212 | 212 | { |
| 213 | nes_state *state = (nes_state *)space->machine->driver_data; | |
| 213 | nes_state *state = (nes_state *)space->machine->driver_data; | |
| 214 | 214 | int bank = offset >> 10; |
| 215 | 215 | |
| 216 | 216 | if (state->chr_map[bank].source == CHRRAM) |
| r8044 | r8045 | |
| 287 | 287 | WRITE8_HANDLER( nes_mid_mapper_w ) |
| 288 | 288 | { |
| 289 | 289 | nes_state *state = (nes_state *)space->machine->driver_data; |
| 290 | ||
| 290 | ||
| 291 | 291 | if (state->mmc_write_mid) |
| 292 | 292 | (*state->mmc_write_mid)(space, offset, data); |
| 293 | 293 | else if (state->mid_ram_enable) |
| r8044 | r8045 | |
|---|---|---|
| 1945 | 1945 | UINT8 *rom = memory_region(image->machine, "user1"); |
| 1946 | 1946 | UINT32 size; |
| 1947 | 1947 | UINT8 header[0x40]; |
| 1948 | ||
| 1948 | ||
| 1949 | 1949 | if (image_software_entry(image) == NULL) |
| 1950 | 1950 | { |
| 1951 | 1951 | const char *filetype; |
| r8044 | r8045 | |
| 2001 | 2001 | { |
| 2002 | 2002 | size = image_get_software_region_length(image, "rom"); |
| 2003 | 2003 | |
| 2004 | /* here we assume images to be in .lnx format and to have an header. | |
| 2005 | we should eventually remove them, though! */ | |
| 2004 | /* here we assume images to be in .lnx format and to have an header. | |
| 2005 | we should eventually remove them, though! */ | |
| 2006 | 2006 | memcpy(header, image_get_software_region(image, "rom"), 0x40); |
| 2007 | ||
| 2007 | ||
| 2008 | 2008 | /* Check the image */ |
| 2009 | 2009 | if (lynx_verify_cart((char*)header, LYNX_CART) == IMAGE_VERIFY_FAIL) |
| 2010 | 2010 | return INIT_FAIL; |
| 2011 | ||
| 2011 | ||
| 2012 | 2012 | /* 2008-10 FP: According to Handy source these should be page_size_bank0. Are we using |
| 2013 | it correctly in MESS? Moreover, the next two values should be page_size_bank1. We should | |
| 2014 | implement this as well */ | |
| 2013 | it correctly in MESS? Moreover, the next two values should be page_size_bank1. We should | |
| 2014 | implement this as well */ | |
| 2015 | 2015 | lynx_granularity = header[4] | (header[5] << 8); |
| 2016 | ||
| 2016 | ||
| 2017 | 2017 | logerror ("%s %dkb cartridge with %dbyte granularity from %s\n", |
| 2018 | 2018 | header + 10, size / 1024, lynx_granularity, header + 42); |
| 2019 | ||
| 2019 | ||
| 2020 | 2020 | size -= 0x40; |
| 2021 | 2021 | memcpy(rom, image_get_software_region(image, "rom") + 0x40, size); |
| 2022 | 2022 | } |
| r8044 | r8045 | |
|---|---|---|
| 542 | 542 | offset &= 0x1fff; |
| 543 | 543 | |
| 544 | 544 | /* Although we could have 128K boot ROM (page f0...ff), the stock |
| 545 | Geneve only has 16K. The address is incompletely decoded, so page | |
| 546 | f0 is mirrored on all even pages up to fe, and f1 is mirrored on | |
| 547 | f3, f5, ... ff. | |
| 548 | Currently, MESS is delivered with the 16K ROM only. So for the time | |
| 549 | being, we won't lose much if we mask the page bits. | |
| 550 | Michael Zapf, 2008-01-23 | |
| 551 | */ | |
| 545 | Geneve only has 16K. The address is incompletely decoded, so page | |
| 546 | f0 is mirrored on all even pages up to fe, and f1 is mirrored on | |
| 547 | f3, f5, ... ff. | |
| 548 | Currently, MESS is delivered with the 16K ROM only. So for the time | |
| 549 | being, we won't lose much if we mask the page bits. | |
| 550 | Michael Zapf, 2008-01-23 | |
| 551 | */ | |
| 552 | 552 | if (page > 0xf1) page &= 0xf1; |
| 553 | 553 | |
| 554 | 554 | switch (page) |
| r8044 | r8045 | |
| 556 | 556 | case 0xf0: |
| 557 | 557 | case 0xf1: |
| 558 | 558 | /* Boot ROM */ |
| 559 | if (input_port_read(space->machine, "BOOTROM")==BOOT_V09) | |
| 559 | if (input_port_read(space->machine, "BOOTROM")==BOOT_V09) | |
| 560 | 560 | return AROM_ptr[(page-0xf0)*0x2000 + offset]; |
| 561 | else | |
| 561 | else | |
| 562 | 562 | return ROM_ptr[(page-0xf0)*0x2000 + offset]; |
| 563 | 563 | |
| 564 | 564 | case 0xe8: |
| r8044 | r8045 | |
|---|---|---|
| 1487 | 1487 | if (state->IRQ_count <= 114) |
| 1488 | 1488 | { |
| 1489 | 1489 | cpu_set_input_line(state->maincpu, M6502_IRQ_LINE, HOLD_LINE); |
| 1490 | state->IRQ_count = (0xffff - 114 + state->IRQ_count); | |
| 1490 | state->IRQ_count = (0xffff - 114 + state->IRQ_count); | |
| 1491 | 1491 | } |
| 1492 | 1492 | state->IRQ_count -= 114; |
| 1493 | 1493 | } |
| r8044 | r8045 | |
| 1658 | 1658 | else if (state->IRQ_count < 114) |
| 1659 | 1659 | { |
| 1660 | 1660 | cpu_set_input_line(state->maincpu, M6502_IRQ_LINE, HOLD_LINE); |
| 1661 | state->IRQ_count = (0xffff - 114 + state->IRQ_count); | |
| 1661 | state->IRQ_count = (0xffff - 114 + state->IRQ_count); | |
| 1662 | 1662 | } |
| 1663 | 1663 | else |
| 1664 | 1664 | state->IRQ_count -= 114; |
| r8044 | r8045 | |
|---|---|---|
| 116 | 116 | { |
| 117 | 117 | UINT8 reply; |
| 118 | 118 | /* GROMs are buffered. Data is retrieved from a buffer, |
| 119 | while the buffer is replaced with the next cell | |
| 120 | content. */ | |
| 119 | while the buffer is replaced with the next cell | |
| 120 | content. */ | |
| 121 | 121 | reply = pcode_GROMs.buf; |
| 122 | ||
| 122 | ||
| 123 | 123 | /* Get next value, put it in buffer. Note that the |
| 124 | ||
| 124 | GROM wraps at 8K boundaries. */ | |
| 125 | 125 | pcode_GROMs.buf = pcode_GROMs.data_ptr[pcode_GROMs.addr]; |
| 126 | ||
| 126 | ||
| 127 | 127 | /* The program counter wraps at each GROM chip size (8K), |
| 128 | ||
| 128 | so 0x5fff + 1 = 0x4000. */ | |
| 129 | 129 | pcode_GROMs.addr = ((pcode_GROMs.addr + 1) & 0x1FFF) | (pcode_GROMs.addr & 0xE000); |
| 130 | ||
| 130 | ||
| 131 | 131 | /* Reset the read and write address flipflops. */ |
| 132 | 132 | pcode_GROMs.raddr_LSB = pcode_GROMs.waddr_LSB = FALSE; |
| 133 | ||
| 133 | ||
| 134 | 134 | return reply; |
| 135 | 135 | } |
| 136 | 136 | |
| r8044 | r8045 | |
| 265 | 265 | switch (offset) |
| 266 | 266 | { |
| 267 | 267 | /* GROMs only answer at even addresses. The odd addresses are |
| 268 | ||
| 268 | undefined, so we can as well just ignore these cases. */ | |
| 269 | 269 | case 0x1bfc: |
| 270 | 270 | case 0x1bfe: |
| 271 | 271 | reply = ti99_pcode_grom_r(space, offset); |
| r8044 | r8045 | |
| 277 | 277 | break; |
| 278 | 278 | default: |
| 279 | 279 | /* Accesses ROM 4764 (2*4K) |
| 280 | We have two banks here which are activated according | |
| 281 | to the setting of CRU bit 4 | |
| 282 | */ | |
| 280 | We have two banks here which are activated according | |
| 281 | to the setting of CRU bit 4 | |
| 282 | */ | |
| 283 | 283 | reply = (bank_select==0)? ti99_pcode_rom1[offset-0x1000] : ti99_pcode_rom2[offset-0x1000]; |
| 284 | 284 | } |
| 285 | 285 | } |
| r8044 | r8045 | |
|---|---|---|
| 59 | 59 | { |
| 60 | 60 | /* |
| 61 | 61 | |
| 62 | ||
| 62 | bit description | |
| 63 | 63 | |
| 64 | 0 P0 | |
| 65 | 1 P1 | |
| 66 | 2 P2 | |
| 67 | 3 P3 | |
| 68 | 4 R0 | |
| 69 | 5 R1 | |
| 70 | 6 R2 | |
| 71 | 7 RELCPMH | |
| 64 | 0 P0 | |
| 65 | 1 P1 | |
| 66 | 2 P2 | |
| 67 | 3 P3 | |
| 68 | 4 R0 | |
| 69 | 5 R1 | |
| 70 | 6 R2 | |
| 71 | 7 RELCPMH | |
| 72 | 72 | |
| 73 | ||
| 73 | */ | |
| 74 | 74 | |
| 75 | 75 | const address_space *program = cputag_get_address_space(machine, Z80_TAG, ADDRESS_SPACE_PROGRAM); |
| 76 | 76 | running_device *messram = devtag_get_device(machine, "messram"); |
| r8044 | r8045 | |
| 149 | 149 | { |
| 150 | 150 | /* |
| 151 | 151 | |
| 152 | ||
| 152 | bit description | |
| 153 | 153 | |
| 154 | 0 BUSY | |
| 155 | 1 ERROR | |
| 156 | 2 PE | |
| 157 | 3 SLCT | |
| 158 | 4 | |
| 159 | 5 | |
| 160 | 6 | |
| 161 | 7 | |
| 154 | 0 BUSY | |
| 155 | 1 ERROR | |
| 156 | 2 PE | |
| 157 | 3 SLCT | |
| 158 | 4 | |
| 159 | 5 | |
| 160 | 6 | |
| 161 | 7 | |
| 162 | 162 | |
| 163 | ||
| 163 | */ | |
| 164 | 164 | |
| 165 | 165 | UINT8 data = 0; |
| 166 | 166 | |
| r8044 | r8045 | |
| 247 | 247 | { |
| 248 | 248 | /* |
| 249 | 249 | |
| 250 | ||
| 250 | bit description | |
| 251 | 251 | |
| 252 | 0 A8 | |
| 253 | 1 A9 | |
| 254 | 2 A10 | |
| 255 | 3 | |
| 256 | 4 | |
| 257 | 5 attribute memory write enable | |
| 258 | 6 ASCII memory write enable | |
| 259 | 7 cycle (0=read/1=write) | |
| 252 | 0 A8 | |
| 253 | 1 A9 | |
| 254 | 2 A10 | |
| 255 | 3 | |
| 256 | 4 | |
| 257 | 5 attribute memory write enable | |
| 258 | 6 ASCII memory write enable | |
| 259 | 7 cycle (0=read/1=write) | |
| 260 | 260 | |
| 261 | ||
| 261 | */ | |
| 262 | 262 | } |
| 263 | 263 | else |
| 264 | 264 | { |
| 265 | 265 | /* |
| 266 | 266 | |
| 267 | ||
| 267 | bit description | |
| 268 | 268 | |
| 269 | 0 A0 | |
| 270 | 1 A1 | |
| 271 | 2 A2 | |
| 272 | 3 A3 | |
| 273 | 4 A4 | |
| 274 | 5 A5 | |
| 275 | 6 A6 | |
| 276 | 7 A7 | |
| 269 | 0 A0 | |
| 270 | 1 A1 | |
| 271 | 2 A2 | |
| 272 | 3 A3 | |
| 273 | 4 A4 | |
| 274 | 5 A5 | |
| 275 | 6 A6 | |
| 276 | 7 A7 | |
| 277 | 277 | |
| 278 | ||
| 278 | */ | |
| 279 | 279 | } |
| 280 | 280 | } |
| 281 | 281 | |
| r8044 | r8045 | |
| 313 | 313 | { |
| 314 | 314 | /* |
| 315 | 315 | |
| 316 | ||
| 316 | bit description | |
| 317 | 317 | |
| 318 | 0 | |
| 319 | 1 | |
| 320 | 2 | |
| 321 | 3 | |
| 322 | 4 | |
| 323 | 5 | |
| 324 | 6 | |
| 325 | 7 | |
| 318 | 0 | |
| 319 | 1 | |
| 320 | 2 | |
| 321 | 3 | |
| 322 | 4 | |
| 323 | 5 | |
| 324 | 6 | |
| 325 | 7 | |
| 326 | 326 | |
| 327 | ||
| 327 | */ | |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | 330 | /*************************************************************************** |
| r8044 | r8045 | |
|---|---|---|
| 9 | 9 | |
| 10 | 10 | /* |
| 11 | 11 | |
| 12 | ||
| 12 | TODO: | |
| 13 | 13 | |
| 14 | - FIFO | |
| 15 | - receive | |
| 16 | - transmit | |
| 17 | - parity | |
| 18 | - 1-sync-character mode | |
| 19 | - 2-sync-character mode | |
| 20 | - external sync mode | |
| 21 | - interrupts | |
| 14 | - FIFO | |
| 15 | - receive | |
| 16 | - transmit | |
| 17 | - parity | |
| 18 | - 1-sync-character mode | |
| 19 | - 2-sync-character mode | |
| 20 | - external sync mode | |
| 21 | - interrupts | |
| 22 | 22 | |
| 23 | 23 | */ |
| 24 | 24 | |
| r8044 | r8045 | |
| 229 | 229 | if (data & C1_RX_RS) |
| 230 | 230 | { |
| 231 | 231 | /* When Rx Rs is set, it clears the receiver |
| 232 | control logic, sync logic, error logic, Rx Data FIFO Control, | |
| 233 | Parity Error status bit, and DCD interrupt. The Receiver Shift | |
| 234 | Register is set to ones. | |
| 235 | */ | |
| 232 | control logic, sync logic, error logic, Rx Data FIFO Control, | |
| 233 | Parity Error status bit, and DCD interrupt. The Receiver Shift | |
| 234 | Register is set to ones. | |
| 235 | */ | |
| 236 | 236 | |
| 237 | 237 | if (LOG) logerror("MC6852 '%s' Receiver Reset\n", device->tag()); |
| 238 | 238 | |
| r8044 | r8045 | |
| 244 | 244 | if (data & C1_TX_RS) |
| 245 | 245 | { |
| 246 | 246 | /* When Tx Rs is set, it clears the transmitter |
| 247 | control section, Transmitter Shift Register, Tx Data FIFO | |
| 248 | Control (the Tx Data FIFO can be reloaded after one E clock | |
| 249 | pulse), the Transmitter Underflow status bit, and the CTS interrupt, | |
| 250 | and inhibits the TDRA status bit (in the one-sync-character | |
| 251 | and two-sync-character modes).*/ | |
| 247 | control section, Transmitter Shift Register, Tx Data FIFO | |
| 248 | Control (the Tx Data FIFO can be reloaded after one E clock | |
| 249 | pulse), the Transmitter Underflow status bit, and the CTS interrupt, | |
| 250 | and inhibits the TDRA status bit (in the one-sync-character | |
| 251 | and two-sync-character modes).*/ | |
| 252 | 252 | |
| 253 | 253 | if (LOG) logerror("MC6852 '%s' Transmitter Reset\n", device->tag()); |
| 254 | 254 | |
| r8044 | r8045 | |
| 307 | 307 | |
| 308 | 308 | /*------------------------------------------------- |
| 309 | 309 | mc685mc6852_sm_dtr_r2_dcd_w - sync match / |
| 310 | ||
| 310 | data terminal ready | |
| 311 | 311 | -------------------------------------------------*/ |
| 312 | 312 | |
| 313 | 313 | READ_LINE_DEVICE_HANDLER( mc6852_sm_dtr_r ) |
| r8044 | r8045 | |
|---|---|---|
| 163 | 163 | UINT8 reg418; |
| 164 | 164 | |
| 165 | 165 | UINT8 drq_ff; |
| 166 | UINT8 int_ff; | |
| 166 | UINT8 int_ff; | |
| 167 | 167 | } nimbus_drives; |
| 168 | 168 | |
| 169 | 169 | |
| r8044 | r8045 | |
| 197 | 197 | UINT8 last_playmode; |
| 198 | 198 | |
| 199 | 199 | /* Mouse/Joystick */ |
| 200 | ||
| 201 | typedef struct | |
| 200 | ||
| 201 | typedef struct | |
| 202 | 202 | { |
| 203 | 203 | UINT8 mouse_px; |
| 204 | 204 | UINT8 mouse_py; |
| 205 | ||
| 205 | ||
| 206 | 206 | UINT8 mouse_x; |
| 207 | 207 | UINT8 mouse_y; |
| 208 | 208 | UINT8 mouse_pc; |
| 209 | 209 | UINT8 mouse_pcx; |
| 210 | 210 | UINT8 mouse_pcy; |
| 211 | ||
| 211 | ||
| 212 | 212 | UINT8 intstate_x; |
| 213 | 213 | UINT8 intstate_y; |
| 214 | ||
| 214 | ||
| 215 | 215 | UINT8 reg0a4; |
| 216 | ||
| 216 | ||
| 217 | 217 | emu_timer *mouse_timer; |
| 218 | 218 | } _mouse_joy_state; |
| 219 | 219 | |
| r8044 | r8045 | |
| 505 | 505 | if(i186.intr.ext[intno] & EXTINT_CTRL_CASCADE) |
| 506 | 506 | i186.intr.ext_vector[intno]=vector; |
| 507 | 507 | } |
| 508 | ||
| 508 | ||
| 509 | 509 | // Turn on the requested request bit and handle interrupt |
| 510 | 510 | i186.intr.request |= (0x010 << intno); |
| 511 | 511 | update_interrupt_state(machine); |
| r8044 | r8045 | |
| 1334 | 1334 | |
| 1335 | 1335 | keyboard.keyscan_timer=timer_alloc(machine, keyscan_callback, NULL); |
| 1336 | 1336 | nimbus_mouse.mouse_timer=timer_alloc(machine, mouse_callback, NULL); |
| 1337 | ||
| 1337 | ||
| 1338 | 1338 | /* setup debug commands */ |
| 1339 | 1339 | if (machine->debug_flags & DEBUG_FLAG_ENABLED) |
| 1340 | 1340 | { |
| r8044 | r8045 | |
| 2194 | 2194 | if(iou_reg092 & DISK_INT_ENABLE) |
| 2195 | 2195 | { |
| 2196 | 2196 | nimbus_drives.int_ff=state; |
| 2197 | ||
| 2197 | ||
| 2198 | 2198 | if(state) |
| 2199 | 2199 | external_int(machine,0,EXTERNAL_INT_DISK); |
| 2200 | 2200 | } |
| r8044 | r8045 | |
| 2673 | 2673 | |
| 2674 | 2674 | last_playmode=MSM5205_S48_4B; |
| 2675 | 2675 | msm5205_playmode_w(msm5205,last_playmode); |
| 2676 | ||
| 2676 | ||
| 2677 | 2677 | ay8910_a=0; |
| 2678 | 2678 | } |
| 2679 | 2679 | |
| r8044 | r8045 | |
| 2709 | 2709 | running_device *msm5205 = devtag_get_device(space->machine, MSM5205_TAG); |
| 2710 | 2710 | |
| 2711 | 2711 | msm5205_data_w(msm5205, data); |
| 2712 | ||
| 2712 | ||
| 2713 | 2713 | // Mouse code needs a copy of this. |
| 2714 | 2714 | ay8910_a=data; |
| 2715 | 2715 | } |
| r8044 | r8045 | |
| 2759 | 2759 | { |
| 2760 | 2760 | UINT8 x = 0; |
| 2761 | 2761 | UINT8 y = 0; |
| 2762 | // int pc=cpu_get_pc(devtag_get_device(machine,MAINCPU_TAG)); | |
| 2763 | ||
| 2762 | // int pc=cpu_get_pc(devtag_get_device(machine,MAINCPU_TAG)); | |
| 2763 | ||
| 2764 | 2764 | UINT8 intstate_x; |
| 2765 | 2765 | UINT8 intstate_y; |
| 2766 | 2766 | int xint; |
| 2767 | 2767 | int yint; |
| 2768 | ||
| 2768 | ||
| 2769 | 2769 | _mouse_joy_state *state = &nimbus_mouse; |
| 2770 | 2770 | |
| 2771 | ||
| 2771 | ||
| 2772 | 2772 | state->reg0a4 = input_port_read(machine, MOUSE_BUTTON_TAG) | 0xC0; |
| 2773 | 2773 | x = input_port_read(machine, MOUSEX_TAG); |
| 2774 | 2774 | y = input_port_read(machine, MOUSEY_TAG); |
| r8044 | r8045 | |
| 2779 | 2779 | UINT8 myb; |
| 2780 | 2780 | |
| 2781 | 2781 | //logerror("poll_mouse()\n"); |
| 2782 | ||
| 2782 | ||
| 2783 | 2783 | if (x == state->mouse_x) |
| 2784 | 2784 | { |
| 2785 | 2785 | state->mouse_px = MOUSE_PHASE_STATIC; |
| r8044 | r8045 | |
| 2813 | 2813 | case MOUSE_PHASE_NEGATIVE : state->mouse_pcx--; break; |
| 2814 | 2814 | } |
| 2815 | 2815 | state->mouse_pcx &= 0x03; |
| 2816 | ||
| 2816 | ||
| 2817 | 2817 | switch (state->mouse_py) |
| 2818 | 2818 | { |
| 2819 | 2819 | case MOUSE_PHASE_STATIC : break; |
| 2820 | 2820 | case MOUSE_PHASE_POSITIVE : state->mouse_pcy++; break; |
| 2821 | 2821 | case MOUSE_PHASE_NEGATIVE : state->mouse_pcy--; break; |
| 2822 | 2822 | } |
| 2823 | state->mouse_pcy &= 0x03; | |
| 2823 | state->mouse_pcy &= 0x03; | |
| 2824 | 2824 | |
| 2825 | // | |
| 2825 | // mxb = MOUSE_XYB[state->mouse_px][state->mouse_pcx]; // XB | |
| 2826 | 2826 | // mxa = MOUSE_XYA[state->mouse_px][state->mouse_pcx]; // XA |
| 2827 | // mya = MOUSE_XYA[state->mouse_py][state->mouse_pcy]; // YA | |
| 2828 | // myb = MOUSE_XYB[state->mouse_py][state->mouse_pcy]; // YB | |
| 2829 | ||
| 2827 | // mya = MOUSE_XYA[state->mouse_py][state->mouse_pcy]; // YA | |
| 2828 | // myb = MOUSE_XYB[state->mouse_py][state->mouse_pcy]; // YB | |
| 2829 | ||
| 2830 | 2830 | mxb = MOUSE_XYB[1][state->mouse_pcx]; // XB |
| 2831 | 2831 | mxa = MOUSE_XYA[1][state->mouse_pcx]; // XA |
| 2832 | 2832 | mya = MOUSE_XYA[1][state->mouse_pcy]; // YA |
| 2833 | 2833 | myb = MOUSE_XYB[1][state->mouse_pcy]; // YB |
| 2834 | ||
| 2834 | ||
| 2835 | 2835 | if ((state->mouse_py!=MOUSE_PHASE_STATIC) || (state->mouse_px!=MOUSE_PHASE_STATIC)) |
| 2836 | 2836 | { |
| 2837 | 2837 | // logerror("state->mouse_px=%02X, state->mouse_py=%02X, state->mouse_pcx=%02X, state->mouse_pcy=%02X\n", |
| 2838 | 2838 | // state->mouse_px,state->mouse_py,state->mouse_pcx,state->mouse_pcy); |
| 2839 | ||
| 2839 | ||
| 2840 | 2840 | // logerror("mxb=%02x, mxa=%02X (mxb ^ mxa)=%02X, (ay8910_a & 0xC0)=%02X, (mxb ^ mxa) ^ ((ay8910_a & 0x80) >> 7)=%02X\n", |
| 2841 | 2841 | // mxb,mxa, (mxb ^ mxa) , (ay8910_a & 0xC0), (mxb ^ mxa) ^ ((ay8910_a & 0x40) >> 6)); |
| 2842 | 2842 | } |
| 2843 | ||
| 2843 | ||
| 2844 | 2844 | intstate_x = (mxb ^ mxa) ^ ((ay8910_a & 0x40) >> 6); |
| 2845 | 2845 | intstate_y = (myb ^ mya) ^ ((ay8910_a & 0x80) >> 7); |
| 2846 | ||
| 2846 | ||
| 2847 | 2847 | if (MOUSE_INT_ENABLED()) |
| 2848 | 2848 | { |
| 2849 | 2849 | if ((intstate_x==1) && (state->intstate_x==0)) |
| 2850 | 2850 | // if (intstate_x!=state->intstate_x) |
| 2851 | 2851 | { |
| 2852 | ||
| 2852 | ||
| 2853 | 2853 | xint=mxa ? EXTERNAL_INT_MOUSE_XR : EXTERNAL_INT_MOUSE_XL; |
| 2854 | ||
| 2854 | ||
| 2855 | 2855 | external_int(machine,0,xint); |
| 2856 | ||
| 2856 | ||
| 2857 | 2857 | // logerror("Xint:%02X, mxb=%02X\n",xint,mxb); |
| 2858 | 2858 | } |
| 2859 | 2859 | |
| r8044 | r8045 | |
| 2861 | 2861 | // if (intstate_y!=state->intstate_y) |
| 2862 | 2862 | { |
| 2863 | 2863 | yint=myb ? EXTERNAL_INT_MOUSE_YU : EXTERNAL_INT_MOUSE_YD; |
| 2864 | ||
| 2864 | ||
| 2865 | 2865 | external_int(machine,0,yint); |
| 2866 | 2866 | // logerror("Yint:%02X, myb=%02X\n",yint,myb); |
| 2867 | } | |
| 2867 | } | |
| 2868 | 2868 | } |
| 2869 | 2869 | else |
| 2870 | { | |
| 2870 | { | |
| 2871 | 2871 | state->reg0a4 &= 0xF0; |
| 2872 | 2872 | state->reg0a4 |= ( mxb & 0x01) << 3; // XB |
| 2873 | 2873 | state->reg0a4 |= (!mxb & 0x01) << 2; // XA |
| 2874 | 2874 | state->reg0a4 |= (!myb & 0x01) << 1; // YA |
| 2875 | 2875 | state->reg0a4 |= ( myb & 0x01) << 0; // YB |
| 2876 | 2876 | } |
| 2877 | ||
| 2877 | ||
| 2878 | 2878 | state->mouse_x = x; |
| 2879 | 2879 | state->mouse_y = y; |
| 2880 | ||
| 2880 | ||
| 2881 | 2881 | if ((state->mouse_py!=MOUSE_PHASE_STATIC) || (state->mouse_px!=MOUSE_PHASE_STATIC)) |
| 2882 | 2882 | { |
| 2883 | 2883 | // logerror("pc=%05X, reg0a4=%02X, reg092=%02X, ay_a=%02X, x=%02X, y=%02X, px=%02X, py=%02X, intstate_x=%02X, intstate_y=%02X\n", |
| 2884 | 2884 | // pc,state->reg0a4,iou_reg092,ay8910_a,state->mouse_x,state->mouse_y,state->mouse_px,state->mouse_py,intstate_x,intstate_y); |
| 2885 | 2885 | } |
| 2886 | ||
| 2886 | ||
| 2887 | 2887 | state->intstate_x=intstate_x; |
| 2888 | 2888 | state->intstate_y=intstate_y; |
| 2889 | 2889 | } |
| r8044 | r8045 | |
| 2905 | 2905 | |
| 2906 | 2906 | */ |
| 2907 | 2907 | UINT8 result; |
| 2908 | // int pc=cpu_get_pc(devtag_get_device(space->machine,MAINCPU_TAG)); | |
| 2909 | ||
| 2908 | // int pc=cpu_get_pc(devtag_get_device(space->machine,MAINCPU_TAG)); | |
| 2909 | ||
| 2910 | 2910 | _mouse_joy_state *state = &nimbus_mouse; |
| 2911 | 2911 | |
| 2912 | 2912 | if (input_port_read(space->machine, "config") & 0x01) |
| r8044 | r8045 | |
|---|---|---|
| 114 | 114 | rs232->dcd = state; |
| 115 | 115 | |
| 116 | 116 | if (LOG) logerror("RS232 '%s' DCD %u\n", device->tag(), state); |
| 117 | ||
| 117 | ||
| 118 | 118 | //devcb_call_write_line(&rs232->dte.out_dcd_func, state); |
| 119 | 119 | } |
| 120 | 120 | |
| r8044 | r8045 | |
| 130 | 130 | rs232_t *rs232 = get_safe_token(device); |
| 131 | 131 | |
| 132 | 132 | rs232->dtr = state; |
| 133 | ||
| 133 | ||
| 134 | 134 | if (LOG) logerror("RS232 '%s' DTR %u\n", device->tag(), state); |
| 135 | 135 | |
| 136 | 136 | //devcb_call_write_line(&rs232->dce.out_dtr_func, state); |
| r8044 | r8045 | |
| 148 | 148 | rs232_t *rs232 = get_safe_token(device); |
| 149 | 149 | |
| 150 | 150 | rs232->dsr = state; |
| 151 | ||
| 151 | ||
| 152 | 152 | if (LOG) logerror("RS232 '%s' DSR %u\n", device->tag(), state); |
| 153 | 153 | |
| 154 | 154 | //devcb_call_write_line(&rs232->dte.out_dsr_func, state); |
| r8044 | r8045 | |
| 166 | 166 | rs232_t *rs232 = get_safe_token(device); |
| 167 | 167 | |
| 168 | 168 | rs232->rts = state; |
| 169 | ||
| 169 | ||
| 170 | 170 | if (LOG) logerror("RS232 '%s' RTS %u\n", device->tag(), state); |
| 171 | 171 | |
| 172 | 172 | //devcb_call_write_line(&rs232->dce.out_rts_func, state); |
| r8044 | r8045 | |
| 186 | 186 | rs232->cts = state; |
| 187 | 187 | |
| 188 | 188 | if (LOG) logerror("RS232 '%s' CTS %u\n", device->tag(), state); |
| 189 | ||
| 189 | ||
| 190 | 190 | //devcb_call_write_line(&rs232->dte.out_cts_func, state); |
| 191 | 191 | } |
| 192 | 192 | |
| r8044 | r8045 | |
| 204 | 204 | rs232->ri = state; |
| 205 | 205 | |
| 206 | 206 | if (LOG) logerror("RS232 '%s' RI %u\n", device->tag(), state); |
| 207 | ||
| 207 | ||
| 208 | 208 | //devcb_call_write_line(&rs232->dte.out_ri_func, state); |
| 209 | 209 | } |
| 210 | 210 |
| r8044 | r8045 | |
|---|---|---|
| 359 | 359 | snes_rom_size = image_length(image); |
| 360 | 360 | else |
| 361 | 361 | snes_rom_size = image_get_software_region_length(image, "rom"); |
| 362 | ||
| 362 | ||
| 363 | 363 | /* Check for a header (512 bytes) */ |
| 364 | 364 | offset = 512; |
| 365 | 365 | if (image_software_entry(image) == NULL) |
| r8044 | r8045 | |
| 402 | 402 | { |
| 403 | 403 | memcpy(temp_buffer, image_get_software_region(image, "rom") + offset, 0x40ffff); |
| 404 | 404 | } |
| 405 | ||
| 405 | ||
| 406 | 406 | /* Now to determine if this is a lo-ROM, a hi-ROM or an extended lo/hi-ROM */ |
| 407 | 407 | valid_mode20 = snes_validate_infoblock(temp_buffer, 0x007fc0); |
| 408 | 408 | valid_mode21 = snes_validate_infoblock(temp_buffer, 0x00ffc0); |
| r8044 | r8045 | |
| 442 | 442 | image_fread(image, ROM, snes_rom_size - offset); |
| 443 | 443 | else |
| 444 | 444 | memcpy(ROM, image_get_software_region(image, "rom") + offset, snes_rom_size - offset); |
| 445 | ||
| 445 | ||
| 446 | 446 | if (SNES_CART_DEBUG) printf("size %08X\n", snes_rom_size - offset); |
| 447 | 447 | |
| 448 | 448 | /* FIXME: Insert crc check here */ |
| r8044 | r8045 | |
|---|---|---|
| 187 | 187 | { |
| 188 | 188 | rh = apple2_c1xx_r; |
| 189 | 189 | } |
| 190 | else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x300) | |
| 190 | else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x300) | |
| 191 | 191 | { // slots 4-7 |
| 192 | 192 | rh = apple2_c4xx_r; |
| 193 | 193 | } |
| r8044 | r8045 | |
| 271 | 271 | { |
| 272 | 272 | wh = apple2_c1xx_w; |
| 273 | 273 | } |
| 274 | else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x300) | |
| 274 | else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x300) | |
| 275 | 275 | { // slots 4-7 |
| 276 | 276 | wh = apple2_c4xx_w; |
| 277 | 277 | } |
| r8044 | r8045 | |
|---|---|---|
| 1231 | 1231 | sram_detected = 0; |
| 1232 | 1232 | genesis_sram_start = genesis_sram_end = 0; |
| 1233 | 1233 | has_serial_eeprom = 0; |
| 1234 | ||
| 1234 | ||
| 1235 | 1235 | /* check if cart has battery save */ |
| 1236 | ||
| 1236 | ||
| 1237 | 1237 | /* For games using SRAM, unfortunately there are ROMs without info |
| 1238 | about it in header. The solution adopted is do the mapping anyway, | |
| 1239 | then active SRAM later if the game will access it. */ | |
| 1240 | ||
| 1238 | about it in header. The solution adopted is do the mapping anyway, | |
| 1239 | then active SRAM later if the game will access it. */ | |
| 1240 | ||
| 1241 | 1241 | if (ROM[0x1b1] == 'R' && ROM[0x1b0] == 'A') |
| 1242 | 1242 | { |
| 1243 | 1243 | /* SRAM info found in header */ |
| 1244 | 1244 | genesis_sram_start = (ROM[0x1b5] << 24 | ROM[0x1b4] << 16 | ROM[0x1b7] << 8 | ROM[0x1b6]); |
| 1245 | 1245 | genesis_sram_end = (ROM[0x1b9] << 24 | ROM[0x1b8] << 16 | ROM[0x1bb] << 8 | ROM[0x1ba]); |
| 1246 | ||
| 1246 | ||
| 1247 | 1247 | if ((genesis_sram_start > genesis_sram_end) || ((genesis_sram_end - genesis_sram_start) >= 0x10000)) // we assume at most 64k of SRAM (HazeMD uses at most 64k). is this correct? |
| 1248 | 1248 | genesis_sram_end = genesis_sram_start + 0x0FFFF; |
| 1249 | ||
| 1249 | ||
| 1250 | 1250 | /* for some games using serial EEPROM, difference between SRAM |
| 1251 | ||
| 1251 | end to start is 0 or 1. Currently EEPROM is not emulated. */ | |
| 1252 | 1252 | if ((genesis_sram_end - genesis_sram_start) < 2) |
| 1253 | 1253 | has_serial_eeprom = 1; |
| 1254 | 1254 | else |
| r8044 | r8045 | |
| 1260 | 1260 | genesis_sram_start = 0x200000; |
| 1261 | 1261 | genesis_sram_end = genesis_sram_start + 0xffff; |
| 1262 | 1262 | } |
| 1263 | ||
| 1263 | ||
| 1264 | 1264 | if (genesis_sram_start & 1) |
| 1265 | 1265 | genesis_sram_start -= 1; |
| 1266 | ||
| 1266 | ||
| 1267 | 1267 | if (!(genesis_sram_end & 1)) |
| 1268 | 1268 | genesis_sram_end += 1; |
| 1269 | ||
| 1269 | ||
| 1270 | 1270 | /* calculate backup RAM location */ |
| 1271 | 1271 | megadriv_backupram = (UINT16*) (ROM + (genesis_sram_start & 0x3fffff)); |
| 1272 | ||
| 1272 | ||
| 1273 | 1273 | /* Until serial EEPROM is emulated, clears one byte at beginning of |
| 1274 | backup RAM, but only if the value is 0xFFFF, to not break MLBPA Sports | |
| 1275 | Talk Baseball. With this hack some games at least run (NBA Jam, Evander | |
| 1276 | Holyfield's Real Deal Boxing, Greatest Heavyweights of the Ring) */ | |
| 1274 | backup RAM, but only if the value is 0xFFFF, to not break MLBPA Sports | |
| 1275 | Talk Baseball. With this hack some games at least run (NBA Jam, Evander | |
| 1276 | Holyfield's Real Deal Boxing, Greatest Heavyweights of the Ring) */ | |
| 1277 | 1277 | if (has_serial_eeprom && megadriv_backupram[0] == 0xffff) |
| 1278 | 1278 | megadriv_backupram[0] = 0xff00; |
| 1279 | ||
| 1279 | ||
| 1280 | 1280 | if (sram_detected) |
| 1281 | 1281 | logerror("SRAM detected from header: starting location %X - SRAM Length %X\n", genesis_sram_start, genesis_sram_end - genesis_sram_start + 1); |
| 1282 | ||
| 1282 | ||
| 1283 | 1283 | return INIT_PASS; |
| 1284 | 1284 | } |
| 1285 | 1285 | |
| r8044 | r8045 | |
| 1307 | 1307 | UINT16 *ROM16; |
| 1308 | 1308 | UINT32 *ROM32; |
| 1309 | 1309 | int i; |
| 1310 | ||
| 1310 | ||
| 1311 | 1311 | if (image_software_entry(image) == NULL) |
| 1312 | 1312 | { |
| 1313 | 1313 | length = image_length(image); |
| r8044 | r8045 | |
| 1326 | 1326 | ROM16 = (UINT16 *) memory_region(image->machine, "gamecart"); |
| 1327 | 1327 | for (i = 0; i < length; i += 2) |
| 1328 | 1328 | ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); |
| 1329 | ||
| 1329 | ||
| 1330 | 1330 | ROM32 = (UINT32 *) memory_region(image->machine, "gamecart_sh2"); |
| 1331 | 1331 | for (i = 0; i < length; i += 4) |
| 1332 | 1332 | ROM32[i / 4] = pick_integer_be(temp_copy, i, 4); |
| 1333 | ||
| 1333 | ||
| 1334 | 1334 | ROM16 = (UINT16 *) memory_region(image->machine, "maincpu"); |
| 1335 | 1335 | for (i = 0x100; i < length; i += 2) |
| 1336 | 1336 | ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); |
| 1337 | ||
| 1337 | ||
| 1338 | 1338 | auto_free(image->machine, temp_copy); |
| 1339 | 1339 | |
| 1340 | 1340 | return INIT_PASS; |
| r8044 | r8045 | |
|---|---|---|
| 125 | 125 | size = image_length(image); |
| 126 | 126 | else |
| 127 | 127 | size = image_get_software_region_length(image, "rom"); |
| 128 | ||
| 128 | ||
| 129 | 129 | /* handle header accordingly */ |
| 130 | 130 | if ((size / 512) & 1) |
| 131 | 131 | { |
| r8044 | r8045 | |
| 148 | 148 | memcpy(ROM, image_get_software_region(image, "rom") + offset, size); |
| 149 | 149 | extrainfo = NULL; |
| 150 | 150 | } |
| 151 | ||
| 151 | ||
| 152 | 152 | if (extrainfo) |
| 153 | 153 | { |
| 154 | 154 | logerror("extrainfo: %s\n", extrainfo); |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ||
| 2 | HDC9224 and HDC9234 Hard and Floppy Disk Controller (HFDC) | |
| 3 | 3 | |
| 4 | This controller handles MFM and FM encoded floppy disks and hard disks. | |
| 5 | The SMC9224 is used in some DEC systems. The HDC9234 is used in the | |
| 6 | Myarc HFDC card for the TI99/4a. The main difference between the two | |
| 7 | chips is the way the ECC bytes are computed; there are differences in | |
| 8 | the way seek times are computed, too. | |
| 9 | ||
| 10 | References: | |
| 11 | * SMC HDC9234 preliminary data book (1988) | |
| 12 | ||
| 13 | Michael Zapf, April 2010 | |
| 4 | This controller handles MFM and FM encoded floppy disks and hard disks. | |
| 5 | The SMC9224 is used in some DEC systems. The HDC9234 is used in the | |
| 6 | Myarc HFDC card for the TI99/4a. The main difference between the two | |
| 7 | chips is the way the ECC bytes are computed; there are differences in | |
| 8 | the way seek times are computed, too. | |
| 14 | 9 | |
| 15 | First version by Raphael Nabet, 2003 | |
| 10 | References: | |
| 11 | * SMC HDC9234 preliminary data book (1988) | |
| 12 | ||
| 13 | Michael Zapf, April 2010 | |
| 14 | ||
| 15 | First version by Raphael Nabet, 2003 | |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | 18 | #include "emu.h" |
| r8044 | r8045 | |
| 70 | 70 | #define CS_PRESDRV 0x03 /* present drive selected */ |
| 71 | 71 | |
| 72 | 72 | /* |
| 73 | ||
| 73 | Definition of bits in the Mode register | |
| 74 | 74 | */ |
| 75 | 75 | #define MO_TYPE 0x80 /* Hard disk (1) or floppy (0) */ |
| 76 | 76 | #define MO_CRCECC 0x60 /* Values for CRC/ECC handling */ |
| r8044 | r8045 | |
| 79 | 79 | #define MO_STEPRATE 0x07 /* Step rates */ |
| 80 | 80 | |
| 81 | 81 | /* |
| 82 | ||
| 82 | hfdc state structure | |
| 83 | 83 | |
| 84 | status | |
| 85 | ab7 ecc error | |
| 86 | ab6 index pulse | |
| 87 | ab5 seek complete | |
| 88 | ab4 track 0 | |
| 89 | ab3 user-defined | |
| 90 | ab2 write-protected | |
| 91 | ab1 drive ready | |
| 92 | ab0 write fault | |
| 93 | ||
| 94 | output1 | |
| 95 | ab7 drive select 3 | |
| 96 | ab6 drive select 2 | |
| 97 | ab5 drive select 1 | |
| 98 | ab4 drive select 0 | |
| 99 | ab3 programmable outputs | |
| 100 | ab2 programmable outputs | |
| 101 | ab1 programmable outputs | |
| 102 | ab0 programmable outputs | |
| 103 | ||
| 104 | output2 | |
| 105 | ab7 drive select 3* (active low, used for tape operations) | |
| 106 | ab6 reduce write current | |
| 107 | ab5 step direction | |
| 108 | ab4 step pulse | |
| 109 | ab3 desired head 3 | |
| 110 | ab2 desired head 2 | |
| 111 | ab1 desired head 1 | |
| 112 | ab0 desired head 0 | |
| 84 | status | |
| 85 | ab7 ecc error | |
| 86 | ab6 index pulse | |
| 87 | ab5 seek complete | |
| 88 | ab4 track 0 | |
| 89 | ab3 user-defined | |
| 90 | ab2 write-protected | |
| 91 | ab1 drive ready | |
| 92 | ab0 write fault | |
| 93 | ||
| 94 | output1 | |
| 95 | ab7 drive select 3 | |
| 96 | ab6 drive select 2 | |
| 97 | ab5 drive select 1 | |
| 98 | ab4 drive select 0 | |
| 99 | ab3 programmable outputs | |
| 100 | ab2 programmable outputs | |
| 101 | ab1 programmable outputs | |
| 102 | ab0 programmable outputs | |
| 103 | ||
| 104 | output2 | |
| 105 | ab7 drive select 3* (active low, used for tape operations) | |
| 106 | ab6 reduce write current | |
| 107 | ab5 step direction | |
| 108 | ab4 step pulse | |
| 109 | ab3 desired head 3 | |
| 110 | ab2 desired head 2 | |
| 111 | ab1 desired head 1 | |
| 112 | ab0 desired head 0 | |
| 113 | 113 | */ |
| 114 | 114 | |
| 115 | 115 | #define OUT1_DRVSEL3 0x80 |
| r8044 | r8045 | |
| 125 | 125 | #define OUT2_HEADSEL1 0x02 |
| 126 | 126 | #define OUT2_HEADSEL0 0x01 |
| 127 | 127 | |
| 128 | #define DRIVE_TYPE | |
| 128 | #define DRIVE_TYPE | |
| 129 | 129 | #define TYPE_AT 0x00 |
| 130 | 130 | #define TYPE_FLOPPY 0x02 /* for testing on any floppy type */ |
| 131 | #define TYPE_FLOPPY8 0x02 | |
| 132 | #define TYPE_FLOPPY5 0x03 | |
| 131 | #define TYPE_FLOPPY8 0x02 | |
| 132 | #define TYPE_FLOPPY5 0x03 | |
| 133 | 133 | |
| 134 | 134 | #define MAX_SECTOR_LEN 256 |
| 135 | 135 | |
| 136 | 136 | #define FORMAT_LONG FALSE |
| 137 | 137 | |
| 138 | #define ERROR 0 | |
| 139 | #define DONE 1 | |
| 138 | #define ERROR 0 | |
| 139 | #define DONE 1 | |
| 140 | 140 | #define AGAIN 2 |
| 141 | 141 | #define UNDEF 3 |
| 142 | 142 | |
| 143 | 143 | typedef struct _smc92x4_state |
| 144 | 144 | { |
| 145 | devcb_resolved_write_line out_intrq_func; /* INT line */ | |
| 146 | devcb_resolved_write_line out_dip_func; /* DMA in progress line */ | |
| 147 | devcb_resolved_write8 out_auxbus_func; /* AB0-7 lines (using S0,S1 as address) */ | |
| 145 | devcb_resolved_write_line out_intrq_func; /* INT line */ | |
| 146 | devcb_resolved_write_line out_dip_func; /* DMA in progress line */ | |
| 147 | devcb_resolved_write8 out_auxbus_func; /* AB0-7 lines (using S0,S1 as address) */ | |
| 148 | 148 | devcb_resolved_read_line in_auxbus_func; /* AB0-7 lines (only single case) */ |
| 149 | 149 | |
| 150 | 150 | UINT8 output1; /* UDC-internal register "output1" */ |
| 151 | 151 | UINT8 output2; /* UDC-internal register "output2" */ |
| 152 | ||
| 152 | ||
| 153 | 153 | int selected_drive_type; |
| 154 | /* We need to store the types, although this is not the case in the | |
| 155 | real hardware. The reason is that poll_drives wants to select the drives | |
| 156 | without knowing their kinds. In reality this does not matter, since we | |
| 157 | only check for the seek_complete line, but in our case, floppy and | |
| 158 | harddrive are pretty different, and we need to know which one to check. */ | |
| 154 | /* We need to store the types, although this is not the case in the | |
| 155 | real hardware. The reason is that poll_drives wants to select the drives | |
| 156 | without knowing their kinds. In reality this does not matter, since we | |
| 157 | only check for the seek_complete line, but in our case, floppy and | |
| 158 | harddrive are pretty different, and we need to know which one to check. */ | |
| 159 | 159 | int types[4]; |
| 160 | 160 | int head_load_delay_enable; |
| 161 | 161 | int register_pointer; |
| 162 | ||
| 163 | UINT8 register_r[12]; | |
| 164 | UINT8 register_w[12]; | |
| 165 | 162 | |
| 163 | UINT8 register_r[12]; | |
| 164 | UINT8 register_w[12]; | |
| 165 | ||
| 166 | 166 | /* timers to delay execution/completion of commands */ |
| 167 | 167 | emu_timer *timer_data, *timer_rs, *timer_ws, *timer_seek, *timer_track; |
| 168 | 168 | |
| 169 | 169 | /* Flag which determines whether to use realistic timing. */ |
| 170 | 170 | int use_real_timing; |
| 171 | ||
| 171 | ||
| 172 | 172 | /* Required to store the current iteration within restore. */ |
| 173 | 173 | int seek_count; |
| 174 | ||
| 174 | ||
| 175 | 175 | /* Recent command. */ |
| 176 | 176 | UINT8 command; |
| 177 | ||
| 177 | ||
| 178 | 178 | /* Stores the step direction. */ |
| 179 | 179 | int step_direction; |
| 180 | ||
| 180 | ||
| 181 | 181 | /* Stores the buffered flag. */ |
| 182 | 182 | int buffered; |
| 183 | ||
| 183 | ||
| 184 | 184 | /* Stores the recent id field. */ |
| 185 | 185 | chrn_id_hd recent_id; |
| 186 | ||
| 186 | ||
| 187 | 187 | /* Indicates whether an ID has been found. */ |
| 188 | 188 | int found_id; |
| 189 | ||
| 189 | ||
| 190 | 190 | /* Indicates whether we are already past the seek_id phase in read/write sector. */ |
| 191 | 191 | int after_seek; |
| 192 | ||
| 192 | ||
| 193 | 193 | /* Determines whether the command will be continued. */ |
| 194 | int to_be_continued; | |
| 195 | ||
| 194 | int to_be_continued; | |
| 195 | ||
| 196 | 196 | /* Pointer to interface */ |
| 197 | 197 | const smc92x4_interface *intf; |
| 198 | ||
| 198 | ||
| 199 | 199 | } smc92x4_state; |
| 200 | 200 | |
| 201 | /* | |
| 202 | Step rates in microseconds for MFM. This is set in the mode register, | |
| 203 | bits 0-2. Single density doubles all values. | |
| 201 | /* | |
| 202 | Step rates in microseconds for MFM. This is set in the mode register, | |
| 203 | bits 0-2. Single density doubles all values. | |
| 204 | 204 | */ |
| 205 | static const int step_hd[] = { 22, 50, 100, 200, 400, 800, 1600, 3200 }; | |
| 206 | static const int step_flop8[] = { 218, 500, 1000, 2000, 4000, 8000, 16000, 32000 }; | |
| 207 | static const int step_flop5[] = { 436, 1000, 2000, 4000, 8000, 16000, 32000, 64000 }; | |
| 205 | static const int step_hd[] = { 22, 50, 100, 200, 400, 800, 1600, 3200 }; | |
| 206 | static const int step_flop8[] = { 218, 500, 1000, 2000, 4000, 8000, 16000, 32000 }; | |
| 207 | static const int step_flop5[] = { 436, 1000, 2000, 4000, 8000, 16000, 32000, 64000 }; | |
| 208 | 208 | |
| 209 | /* | |
| 210 | 0.2 seconds for a revolution (300 rpm), +50% average waiting for index | |
| 211 | hole. Should be properly done with the index hole detection; we're | |
| 212 | simulating this with a timer for now. | |
| 209 | /* | |
| 210 | 0.2 seconds for a revolution (300 rpm), +50% average waiting for index | |
| 211 | hole. Should be properly done with the index hole detection; we're | |
| 212 | simulating this with a timer for now. | |
| 213 | 213 | */ |
| 214 | #define TRACKTIME_FLOPPY 300000 | |
| 215 | #define TRACKTIME_HD 1000 | |
| 214 | #define TRACKTIME_FLOPPY 300000 | |
| 215 | #define TRACKTIME_HD 1000 | |
| 216 | 216 | |
| 217 | 217 | /* |
| 218 | Register names of the HDC. The left part is the set of write registers, | |
| 219 | while the right part are the read registers. | |
| 218 | Register names of the HDC. The left part is the set of write registers, | |
| 219 | while the right part are the read registers. | |
| 220 | 220 | */ |
| 221 | enum | |
| 221 | enum | |
| 222 | 222 | { |
| 223 | DMA7_0=0, | |
| 224 | DMA15_8=1, | |
| 225 | DMA23_16=2, | |
| 226 | DESIRED_SECTOR=3, | |
| 227 | DESIRED_HEAD=4, CURRENT_HEAD=4, | |
| 228 | DESIRED_CYLINDER=5, CURRENT_CYLINDER=5, | |
| 229 | SECTOR_COUNT=6, CURRENT_IDENT=6, | |
| 230 | RETRY_COUNT=7, TEMP_STORAGE2=7, | |
| 223 | DMA7_0=0, | |
| 224 | DMA15_8=1, | |
| 225 | DMA23_16=2, | |
| 226 | DESIRED_SECTOR=3, | |
| 227 | DESIRED_HEAD=4, CURRENT_HEAD=4, | |
| 228 | DESIRED_CYLINDER=5, CURRENT_CYLINDER=5, | |
| 229 | SECTOR_COUNT=6, CURRENT_IDENT=6, | |
| 230 | RETRY_COUNT=7, TEMP_STORAGE2=7, | |
| 231 | 231 | MODE=8, CHIP_STATUS=8, |
| 232 | INT_COMM_TERM=9, DRIVE_STATUS=9, | |
| 233 | DATA_DELAY=10, DATA=10, | |
| 232 | INT_COMM_TERM=9, DRIVE_STATUS=9, | |
| 233 | DATA_DELAY=10, DATA=10, | |
| 234 | 234 | COMMAND=11, INT_STATUS=11 |
| 235 | 235 | }; |
| 236 | 236 | |
| r8044 | r8045 | |
| 319 | 319 | //assert(! (w->status & ST_DONE)) |
| 320 | 320 | smc92x4_state *w = get_safe_token(device); |
| 321 | 321 | //printf("smc92x4 command %02x done, flags=%02x\n", w->command, flags); |
| 322 | ||
| 322 | ||
| 323 | 323 | w->register_r[INT_STATUS] |= ST_DONE; |
| 324 | 324 | w->register_r[INT_STATUS] &= ~ST_TERMCOD; /* clear the previously set flags */ |
| 325 | 325 | w->register_r[INT_STATUS] |= flags; |
| 326 | 326 | |
| 327 | /* sm92x4 spec, p. 6 */ | |
| 327 | /* sm92x4 spec, p. 6 */ | |
| 328 | 328 | if (w->register_w[INT_COMM_TERM] & TC_INTDONE) |
| 329 | 329 | smc92x4_set_interrupt(device); |
| 330 | 330 | } |
| 331 | 331 | |
| 332 | 332 | /* |
| 333 | ||
| 333 | Preserve previously set termination code | |
| 334 | 334 | */ |
| 335 | 335 | static void set_command_done(running_device *device) |
| 336 | 336 | { |
| r8044 | r8045 | |
| 340 | 340 | |
| 341 | 341 | w->register_r[INT_STATUS] |= ST_DONE; |
| 342 | 342 | |
| 343 | /* sm92x4 spec, p. 6 */ | |
| 343 | /* sm92x4 spec, p. 6 */ | |
| 344 | 344 | if (w->register_w[INT_COMM_TERM] & TC_INTDONE) |
| 345 | 345 | smc92x4_set_interrupt(device); |
| 346 | 346 | } |
| r8044 | r8045 | |
| 358 | 358 | } |
| 359 | 359 | |
| 360 | 360 | /* |
| 361 | Sets the DMA address on the external counter. This counter is attached | |
| 362 | to the auxiliary bus on the PCB. | |
| 361 | Sets the DMA address on the external counter. This counter is attached | |
| 362 | to the auxiliary bus on the PCB. | |
| 363 | 363 | */ |
| 364 | 364 | static void set_dma_address(running_device *device, int pos2316, int pos1508, int pos0700) |
| 365 | { | |
| 365 | { | |
| 366 | 366 | smc92x4_state *w = get_safe_token(device); |
| 367 | 367 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_DMA_ADDR, w->register_r[pos2316]); |
| 368 | 368 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_DMA_ADDR, w->register_r[pos1508]); |
| 369 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_DMA_ADDR, w->register_r[pos0700]); | |
| 369 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_DMA_ADDR, w->register_r[pos0700]); | |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | static void dma_add_offset(running_device *device, int offset) |
| r8044 | r8045 | |
| 374 | 374 | smc92x4_state *w = get_safe_token(device); |
| 375 | 375 | int dma_address = (w->register_w[DMA23_16]<<16) + (w->register_w[DMA15_8]<<8) + w->register_w[DMA7_0]; |
| 376 | 376 | dma_address += offset; |
| 377 | ||
| 377 | ||
| 378 | 378 | w->register_w[DMA23_16] = w->register_r[DMA23_16] = (dma_address & 0xff0000)>>16; |
| 379 | 379 | w->register_w[DMA15_8] = w->register_r[DMA15_8] = (dma_address & 0x00ff00)>>8; |
| 380 | 380 | w->register_w[DMA7_0] = w->register_r[DMA7_0] = (dma_address & 0x0000ff); |
| 381 | 381 | } |
| 382 | 382 | |
| 383 | /* | |
| 384 | Get the state from outside and latch it in the register. | |
| 385 | There should be a bus driver on the PCB which provides the signals from | |
| 386 | both the hard and floppy drives during S0=S1=0 and STB*=0 times via the | |
| 387 | auxiliary bus. | |
| 383 | /* | |
| 384 | Get the state from outside and latch it in the register. | |
| 385 | There should be a bus driver on the PCB which provides the signals from | |
| 386 | both the hard and floppy drives during S0=S1=0 and STB*=0 times via the | |
| 387 | auxiliary bus. | |
| 388 | 388 | */ |
| 389 | 389 | static void sync_status_in(running_device *device) |
| 390 | 390 | { |
| 391 | 391 | UINT8 prev; |
| 392 | 392 | smc92x4_state *w = get_safe_token(device); |
| 393 | 393 | |
| 394 | prev = w->register_r[DRIVE_STATUS]; | |
| 394 | prev = w->register_r[DRIVE_STATUS]; | |
| 395 | 395 | w->register_r[DRIVE_STATUS] = devcb_call_read_line(&w->in_auxbus_func); |
| 396 | 396 | |
| 397 | 397 | /* Raise interrupt if ready changes. TODO: Check this more closely. */ |
| 398 | // | |
| 398 | // printf("disk status = %02x\n", reply); | |
| 399 | 399 | if (((w->register_r[DRIVE_STATUS] & DS_READY) != (prev & DS_READY)) |
| 400 | 400 | & (w->register_r[INT_STATUS] & ST_RDYCHNG)) |
| 401 | 401 | { |
| r8044 | r8045 | |
| 404 | 404 | } |
| 405 | 405 | |
| 406 | 406 | /* |
| 407 | Push the output registers over the auxiliary bus. It is expected that | |
| 408 | the PCB contains latches to store the values. | |
| 407 | Push the output registers over the auxiliary bus. It is expected that | |
| 408 | the PCB contains latches to store the values. | |
| 409 | 409 | */ |
| 410 | static void sync_latches_out(running_device *device) | |
| 410 | static void sync_latches_out(running_device *device) | |
| 411 | 411 | { |
| 412 | 412 | smc92x4_state *w = get_safe_token(device); |
| 413 | w->output1 = (w->output1 & 0xf0) | (w->register_w[RETRY_COUNT]&0x0f); | |
| 413 | w->output1 = (w->output1 & 0xf0) | (w->register_w[RETRY_COUNT]&0x0f); | |
| 414 | 414 | |
| 415 | 415 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_OUTPUT1, w->output1); |
| 416 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_OUTPUT2, w->output2); | |
| 416 | devcb_call_write8(&w->out_auxbus_func, OUTPUT_OUTPUT2, w->output2); | |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | 419 | /************************************************************* |
| 420 | ||
| 420 | Timed requests and callbacks | |
| 421 | 421 | *************************************************************/ |
| 422 | 422 | #if 0 |
| 423 | 423 | /* setup a timed data request - data request will be triggered in a few usecs time */ |
| r8044 | r8045 | |
| 425 | 425 | { |
| 426 | 426 | smc92x4_state *w = get_safe_token(device); |
| 427 | 427 | int time = controller_set_to_single_density(device)? 128 : 32; |
| 428 | ||
| 428 | ||
| 429 | 429 | if (!w->use_real_timing) |
| 430 | 430 | time = 1; |
| 431 | ||
| 431 | ||
| 432 | 432 | /* set new timer */ |
| 433 | 433 | timer_adjust_oneshot(w->timer_data, ATTOTIME_IN_USEC(time, 0)); |
| 434 | 434 | } |
| r8044 | r8045 | |
| 464 | 464 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 465 | 465 | time = (controller_set_to_single_density(device))? 30000 : 15000; |
| 466 | 466 | else |
| 467 | time = 1000; | |
| 467 | time = 1000; | |
| 468 | 468 | |
| 469 | 469 | if (!w->use_real_timing) |
| 470 | 470 | time = 1; |
| r8044 | r8045 | |
| 473 | 473 | w->to_be_continued = TRUE; |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | /* | |
| 477 | Set up a timed track read/write | |
| 476 | /* | |
| 477 | Set up a timed track read/write | |
| 478 | 478 | */ |
| 479 | 479 | static void smc92x4_timed_track_request(running_device *device) |
| 480 | 480 | { |
| 481 | 481 | smc92x4_state *w = get_safe_token(device); |
| 482 | 482 | int time = 0; |
| 483 | ||
| 483 | ||
| 484 | 484 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 485 | 485 | time = TRACKTIME_FLOPPY; |
| 486 | 486 | else |
| 487 | 487 | time = TRACKTIME_HD; |
| 488 | ||
| 488 | ||
| 489 | 489 | if (!w->use_real_timing) |
| 490 | 490 | time = 1; |
| 491 | 491 | |
| 492 | 492 | timer_adjust_oneshot(w->timer_track, ATTOTIME_IN_USEC(time), 0); |
| 493 | ||
| 493 | ||
| 494 | 494 | w->to_be_continued = TRUE; |
| 495 | 495 | } |
| 496 | 496 | |
| 497 | /* | |
| 498 | Set up a timed track seek | |
| 497 | /* | |
| 498 | Set up a timed track seek | |
| 499 | 499 | */ |
| 500 | 500 | static void smc92x4_timed_seek_request(running_device *device) |
| 501 | 501 | { |
| r8044 | r8045 | |
| 504 | 504 | |
| 505 | 505 | int index = w->register_w[MODE] & MO_STEPRATE; |
| 506 | 506 | int fm = controller_set_to_single_density(device); |
| 507 | ||
| 507 | ||
| 508 | 508 | /* Get seek time. */ |
| 509 | 509 | if ((w->selected_drive_type & DRIVE_TYPE) == TYPE_FLOPPY8) |
| 510 | 510 | time = step_flop8[index]; |
| 511 | 511 | |
| 512 | 512 | else if ((w->selected_drive_type & DRIVE_TYPE) == TYPE_FLOPPY5) |
| 513 | time = step_flop5[index]; | |
| 514 | else | |
| 513 | time = step_flop5[index]; | |
| 514 | else | |
| 515 | 515 | time = step_hd[index]; |
| 516 | 516 | |
| 517 | if (fm) | |
| 517 | if (fm) | |
| 518 | 518 | time = time * 2; |
| 519 | ||
| 519 | ||
| 520 | 520 | if (!w->use_real_timing) |
| 521 | 521 | { |
| 522 | 522 | logerror("smc92x4 info: Disk access without delays\n"); |
| 523 | time = 1; | |
| 523 | time = 1; | |
| 524 | 524 | } |
| 525 | ||
| 525 | ||
| 526 | 526 | timer_adjust_oneshot(w->timer_seek, ATTOTIME_IN_USEC(time), 0); |
| 527 | 527 | w->to_be_continued = TRUE; |
| 528 | 528 | } |
| r8044 | r8045 | |
| 530 | 530 | #if 0 |
| 531 | 531 | static TIMER_CALLBACK(smc92x4_data_callback) |
| 532 | 532 | { |
| 533 | /* running_device *device = (running_device *)ptr; | |
| 534 | smc92x4_state *w = get_safe_token(device); */ | |
| 533 | /* running_device *device = (running_device *)ptr; | |
| 534 | smc92x4_state *w = get_safe_token(device); */ | |
| 535 | 535 | } |
| 536 | 536 | #endif |
| 537 | 537 | |
| 538 | 538 | static TIMER_CALLBACK(smc92x4_read_sector_callback) |
| 539 | 539 | { |
| 540 | 540 | running_device *device = (running_device *)ptr; |
| 541 | smc92x4_state *w = get_safe_token(device); | |
| 541 | smc92x4_state *w = get_safe_token(device); | |
| 542 | 542 | int transfer_enabled = w->command & 0x01; |
| 543 | 543 | |
| 544 | 544 | /* Now read the sector. */ |
| r8044 | r8045 | |
| 550 | 550 | static TIMER_CALLBACK(smc92x4_write_sector_callback) |
| 551 | 551 | { |
| 552 | 552 | running_device *device = (running_device *)ptr; |
| 553 | smc92x4_state *w = get_safe_token(device); | |
| 553 | smc92x4_state *w = get_safe_token(device); | |
| 554 | 554 | int deldata = w->command & 0x10; |
| 555 | 555 | int redcur = w->command & 0x08; |
| 556 | 556 | int precomp = w->command & 0x07; |
| r8044 | r8045 | |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | 568 | /* |
| 569 | Callback for track access. Nothing interesting here, just used for | |
| 570 | delaying. | |
| 569 | Callback for track access. Nothing interesting here, just used for | |
| 570 | delaying. | |
| 571 | 571 | */ |
| 572 | 572 | static TIMER_CALLBACK(smc92x4_track_callback) |
| 573 | 573 | { |
| r8044 | r8045 | |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | 579 | /* |
| 580 | ||
| 580 | Callback for seek request. | |
| 581 | 581 | */ |
| 582 | 582 | static TIMER_CALLBACK(smc92x4_seek_callback) |
| 583 | 583 | { |
| 584 | 584 | running_device *device = (running_device *)ptr; |
| 585 | 585 | smc92x4_state *w = get_safe_token(device); |
| 586 | 586 | running_device *current_floppy = NULL; |
| 587 | /* int buffered = ((w->register_w[MODE] & MO_STEPRATE)==0); */ | |
| 588 | /* int buffered = (w->command & 0x01); */ | |
| 587 | /* int buffered = ((w->register_w[MODE] & MO_STEPRATE)==0); */ | |
| 588 | /* int buffered = (w->command & 0x01); */ | |
| 589 | 589 | |
| 590 | 590 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 591 | 591 | { |
| r8044 | r8045 | |
| 604 | 604 | else |
| 605 | 605 | { |
| 606 | 606 | // printf("smc92x4 step harddisk direction %d\n", w->step_direction); |
| 607 | (*w->intf->mfmhd_seek)(w->step_direction); | |
| 608 | } | |
| 607 | (*w->intf->mfmhd_seek)(w->step_direction); | |
| 608 | } | |
| 609 | 609 | sync_status_in(device); |
| 610 | 610 | |
| 611 | 611 | smc92x4_process_after_callback(device); |
| 612 | 612 | } |
| 613 | 613 | |
| 614 | 614 | /********************************************************************* |
| 615 | ||
| 615 | Common functions | |
| 616 | 616 | *********************************************************************/ |
| 617 | 617 | |
| 618 | 618 | /* |
| 619 | Calculate the ident byte from the cylinder. The specification does not | |
| 620 | define idents beyond cylinder 1023, but formatting programs seem to | |
| 621 | continue with 0xfd for cylinders between 1024 and 2047. | |
| 619 | Calculate the ident byte from the cylinder. The specification does not | |
| 620 | define idents beyond cylinder 1023, but formatting programs seem to | |
| 621 | continue with 0xfd for cylinders between 1024 and 2047. | |
| 622 | 622 | */ |
| 623 | 623 | UINT8 cylinder_to_ident(int cylinder) |
| 624 | 624 | { |
| r8044 | r8045 | |
| 630 | 630 | } |
| 631 | 631 | |
| 632 | 632 | /* |
| 633 | Calculate the offset from the ident. This is only useful for AT drives; | |
| 634 | these drives cannot have more than 1024 cylinders. | |
| 633 | Calculate the offset from the ident. This is only useful for AT drives; | |
| 634 | these drives cannot have more than 1024 cylinders. | |
| 635 | 635 | */ |
| 636 | 636 | static int ident_to_cylinder(UINT8 ident) |
| 637 | 637 | { |
| r8044 | r8045 | |
| 646 | 646 | } |
| 647 | 647 | |
| 648 | 648 | /* |
| 649 | ||
| 649 | Common function to set the read registers from the recently read id. | |
| 650 | 650 | */ |
| 651 | 651 | static void update_id_regs(running_device *device, chrn_id_hd id) |
| 652 | 652 | { |
| 653 | /* Flags for current head register. Note that the sizes are not in | |
| 654 | sequence (128, 256, 512, 1024). This is only interesting for AT | |
| 655 | mode. */ | |
| 653 | /* Flags for current head register. Note that the sizes are not in | |
| 654 | sequence (128, 256, 512, 1024). This is only interesting for AT | |
| 655 | mode. */ | |
| 656 | 656 | UINT8 sizeflag[] = { 0x60, 0x00, 0x20, 0x40 }; |
| 657 | 657 | smc92x4_state *w = get_safe_token(device); |
| 658 | 658 | |
| r8044 | r8045 | |
| 660 | 660 | |
| 661 | 661 | w->register_r[CURRENT_HEAD] = id.H & 0x0f; |
| 662 | 662 | |
| 663 | if (id.flags & BAD_SECTOR) | |
| 663 | if (id.flags & BAD_SECTOR) | |
| 664 | 664 | w->register_r[CURRENT_HEAD] |= 0x80; |
| 665 | 665 | |
| 666 | if ((w->selected_drive_type & DRIVE_TYPE) == TYPE_AT) | |
| 666 | if ((w->selected_drive_type & DRIVE_TYPE) == TYPE_AT) | |
| 667 | 667 | w->register_r[CURRENT_HEAD] |= sizeflag[id.N]; |
| 668 | 668 | else |
| 669 | 669 | w->register_r[CURRENT_HEAD] |= ((id.C & 0x700)>>4); |
| r8044 | r8045 | |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | 674 | /* |
| 675 | ||
| 675 | Common procedure: read_id_field (as described in the specification) | |
| 676 | 676 | */ |
| 677 | 677 | static void read_id_field(running_device *device, int *steps, int *direction, chrn_id_hd *id) |
| 678 | 678 | { |
| r8044 | r8045 | |
| 681 | 681 | int found = FALSE; |
| 682 | 682 | sync_latches_out(device); |
| 683 | 683 | sync_status_in(device); |
| 684 | ||
| 685 | /* Set command termination code. The error code is set first, and | |
| 686 | on success, it is cleared. */ | |
| 684 | ||
| 685 | /* Set command termination code. The error code is set first, and | |
| 686 | on success, it is cleared. */ | |
| 687 | 687 | w->register_r[INT_STATUS] |= ST_TC_RDIDERR; |
| 688 | ||
| 688 | ||
| 689 | 689 | /* Try to find an ID field. */ |
| 690 | 690 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 691 | 691 | { |
| r8044 | r8045 | |
| 697 | 697 | w->register_r[CHIP_STATUS] |= CS_SYNCERR; |
| 698 | 698 | return; |
| 699 | 699 | } |
| 700 | ||
| 700 | ||
| 701 | 701 | /* Check whether image and controller are set to the same density. */ |
| 702 | 702 | if ((image_is_single_density(disk_img) && controller_set_to_single_density(device)) |
| 703 | 703 | || (!image_is_single_density(disk_img) && !controller_set_to_single_density(device)) |
| r8044 | r8045 | |
| 712 | 712 | } |
| 713 | 713 | sync_status_in(device); |
| 714 | 714 | |
| 715 | if (!found) | |
| 715 | if (!found) | |
| 716 | 716 | { |
| 717 | 717 | logerror("smc92x4 error: read_id_field (floppy): sync error\n"); |
| 718 | 718 | w->register_r[CHIP_STATUS] |= CS_SYNCERR; |
| r8044 | r8045 | |
| 730 | 730 | return; |
| 731 | 731 | } |
| 732 | 732 | } |
| 733 | ||
| 733 | ||
| 734 | 734 | w->register_r[CHIP_STATUS] &= ~CS_SYNCERR; |
| 735 | ||
| 735 | ||
| 736 | 736 | /* Update the registers. */ |
| 737 | 737 | update_id_regs(device, *id); |
| 738 | ||
| 738 | ||
| 739 | 739 | if (id->flags & BAD_CRC) |
| 740 | 740 | { |
| 741 | 741 | w->register_r[CHIP_STATUS] |= CS_CRCERR; |
| 742 | 742 | return; |
| 743 | 743 | } |
| 744 | ||
| 745 | /* Calculate the steps. */ | |
| 744 | ||
| 745 | /* Calculate the steps. */ | |
| 746 | 746 | if ((w->selected_drive_type & DRIVE_TYPE) == TYPE_AT) |
| 747 | 747 | { |
| 748 | /* Note: the spec says CURRENT_REGISTER, but that seems wrong. */ | |
| 748 | /* Note: the spec says CURRENT_REGISTER, but that seems wrong. */ | |
| 749 | 749 | des_cylinder = ((w->register_r[DATA] & 0x03)<<8) | w->register_w[DESIRED_CYLINDER]; |
| 750 | cur_cylinder = ident_to_cylinder(w->register_r[CURRENT_IDENT]) + w->register_r[CURRENT_CYLINDER]; | |
| 750 | cur_cylinder = ident_to_cylinder(w->register_r[CURRENT_IDENT]) + w->register_r[CURRENT_CYLINDER]; | |
| 751 | 751 | } |
| 752 | 752 | else |
| 753 | 753 | { |
| 754 | 754 | des_cylinder = ((w->register_w[DESIRED_HEAD] & 0x70)<<4) | w->register_w[DESIRED_CYLINDER]; |
| 755 | 755 | cur_cylinder = ((w->register_r[CURRENT_HEAD] & 0x70)<<4) | w->register_r[CURRENT_CYLINDER]; |
| 756 | 756 | } |
| 757 | ||
| 757 | ||
| 758 | 758 | if (des_cylinder >= cur_cylinder) |
| 759 | 759 | { |
| 760 | 760 | *steps = des_cylinder - cur_cylinder; |
| r8044 | r8045 | |
| 766 | 766 | *direction = -1; |
| 767 | 767 | } |
| 768 | 768 | |
| 769 | //printf("smc92x4 seek required: %d steps\n", *steps); | |
| 770 | ||
| 769 | //printf("smc92x4 seek required: %d steps\n", *steps); | |
| 770 | ||
| 771 | 771 | w->register_r[INT_STATUS] &= ~ST_TC_RDIDERR; |
| 772 | 772 | return; |
| 773 | 773 | } |
| 774 | 774 | |
| 775 | 775 | /* |
| 776 | ||
| 776 | Common procedure: verify (as described in the specification) | |
| 777 | 777 | */ |
| 778 | 778 | static int verify(running_device *device, chrn_id_hd *id, int check_sector) |
| 779 | 779 | { |
| r8044 | r8045 | |
| 783 | 783 | int found = FALSE; |
| 784 | 784 | int foundsect = FALSE; |
| 785 | 785 | int des_cylinder = 0; |
| 786 | ||
| 787 | /* Set command termination code. The error code is set first, and | |
| 788 | on success, it is cleared. */ | |
| 786 | ||
| 787 | /* Set command termination code. The error code is set first, and | |
| 788 | on success, it is cleared. */ | |
| 789 | 789 | w->register_r[INT_STATUS] |= ST_TC_SEEKERR; |
| 790 | ||
| 790 | ||
| 791 | 791 | while (pass < maxtry && !foundsect) |
| 792 | 792 | { |
| 793 | 793 | pass++; |
| r8044 | r8045 | |
| 816 | 816 | return ERROR; |
| 817 | 817 | } |
| 818 | 818 | } |
| 819 | ||
| 819 | ||
| 820 | 820 | w->register_r[CHIP_STATUS] &= ~CS_SYNCERR; |
| 821 | ||
| 821 | ||
| 822 | 822 | /* Compare with the desired sector ID. */ |
| 823 | 823 | if ((w->selected_drive_type & DRIVE_TYPE) == TYPE_AT) |
| 824 | 824 | { |
| 825 | /* Note: the spec says CURRENT_CYLINDER, but that seems wrong. */ | |
| 825 | /* Note: the spec says CURRENT_CYLINDER, but that seems wrong. */ | |
| 826 | 826 | des_cylinder = ((w->register_r[DATA] & 0x03)<<8) | w->register_w[DESIRED_CYLINDER]; |
| 827 | 827 | } |
| 828 | 828 | else |
| 829 | 829 | { |
| 830 | 830 | des_cylinder = ((w->register_w[DESIRED_HEAD] & 0x70)<<4) | w->register_w[DESIRED_CYLINDER]; |
| 831 | 831 | } |
| 832 | // printf("smc92x4 check id: current = (%d,%d,%d), required = (%d,%d,%d)\n", id->C, id->H, id->R, des_cylinder, w->register_w[DESIRED_HEAD] & 0x0f, w->register_w[DESIRED_SECTOR]); | |
| 833 | if ((des_cylinder == id->C) | |
| 832 | // printf("smc92x4 check id: current = (%d,%d,%d), required = (%d,%d,%d)\n", id->C, id->H, id->R, des_cylinder, w->register_w[DESIRED_HEAD] & 0x0f, w->register_w[DESIRED_SECTOR]); | |
| 833 | if ((des_cylinder == id->C) | |
| 834 | 834 | && ((w->register_w[DESIRED_HEAD] & 0x0f) == id->H)) |
| 835 | 835 | { |
| 836 | 836 | if (!check_sector || (w->register_w[DESIRED_SECTOR] == id->R)) |
| 837 | 837 | foundsect = TRUE; |
| 838 | 838 | } |
| 839 | } | |
| 839 | } | |
| 840 | 840 | if (!foundsect) |
| 841 | 841 | { |
| 842 | 842 | w->register_r[CHIP_STATUS] |= CS_COMPERR; |
| 843 | 843 | logerror("smc92x4 error: verify: sector not found, seek error (desired cyl=%d/sec=%d, current cyl=%d/sec=%d)\n", des_cylinder, w->register_w[DESIRED_SECTOR], id->C, id->R); |
| 844 | 844 | return ERROR; |
| 845 | 845 | } |
| 846 | ||
| 846 | ||
| 847 | 847 | w->register_r[INT_STATUS] &= ~ST_TC_SEEKERR; |
| 848 | 848 | return DONE; |
| 849 | 849 | } |
| 850 | 850 | |
| 851 | 851 | /* |
| 852 | ||
| 852 | Common procedure: data_transfer(read) (as described in the specification) | |
| 853 | 853 | */ |
| 854 | 854 | static void data_transfer_read(running_device *device, chrn_id_hd id, int transfer_enable) |
| 855 | 855 | { |
| 856 | 856 | int i, retry, sector_len; |
| 857 | 857 | smc92x4_state *w = get_safe_token(device); |
| 858 | running_device *current_floppy = NULL; | |
| 859 | ||
| 858 | running_device *current_floppy = NULL; | |
| 859 | ||
| 860 | 860 | int sector_data_id; |
| 861 | 861 | UINT8 *buf; |
| 862 | ||
| 862 | ||
| 863 | 863 | sync_latches_out(device); |
| 864 | 864 | sync_status_in(device); |
| 865 | ||
| 865 | ||
| 866 | 866 | current_floppy = (*w->intf->current_floppy)(); |
| 867 | 867 | |
| 868 | /* Set command termination code. The error code is set first, and | |
| 869 | on success, it is cleared. */ | |
| 868 | /* Set command termination code. The error code is set first, and | |
| 869 | on success, it is cleared. */ | |
| 870 | 870 | w->register_r[INT_STATUS] |= ST_TC_DATAERR; |
| 871 | ||
| 871 | ||
| 872 | 872 | /* Save the value. Note that the retry count is only in the first four |
| 873 | bits, and it is stored in one's complement. In this implementation | |
| 874 | we don't work with it. */ | |
| 873 | bits, and it is stored in one's complement. In this implementation | |
| 874 | we don't work with it. */ | |
| 875 | 875 | retry = w->register_w[RETRY_COUNT]; |
| 876 | ||
| 876 | ||
| 877 | 877 | /* We are already at the correct sector (found by the verify sequence) */ |
| 878 | ||
| 878 | ||
| 879 | 879 | /* Find the data sync mark. Easy, we assume it has been found. */ |
| 880 | ||
| 880 | ||
| 881 | 881 | if (id.flags & ID_FLAG_DELETED_DATA) |
| 882 | 882 | w->register_r[CHIP_STATUS] |= CS_DELDATA; |
| 883 | 883 | else |
| 884 | 884 | w->register_r[CHIP_STATUS] &= ~CS_DELDATA; |
| 885 | ||
| 885 | ||
| 886 | 886 | /* Found. Now update the current cylinder/head registers. */ |
| 887 | 887 | update_id_regs(device, id); |
| 888 | ||
| 888 | ||
| 889 | 889 | /* Initiate the DMA. We assume the DMARQ is positive. */ |
| 890 | w->register_r[INT_STATUS] &= ~ST_OVRUN; | |
| 890 | w->register_r[INT_STATUS] &= ~ST_OVRUN; | |
| 891 | 891 | |
| 892 | 892 | sector_len = 1 << (id.N+7); |
| 893 | 893 | sector_data_id = id.data_id; |
| 894 | ||
| 894 | ||
| 895 | 895 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 896 | 896 | { |
| 897 | 897 | buf = (UINT8 *)malloc(sector_len); |
| r8044 | r8045 | |
| 903 | 903 | (*w->intf->mfmhd_read_sector)(id.C, id.H, id.R, &buf, §or_len); |
| 904 | 904 | } |
| 905 | 905 | sync_status_in(device); |
| 906 | ||
| 906 | ||
| 907 | 907 | if (transfer_enable) |
| 908 | 908 | { |
| 909 | 909 | /* Copy via DMA into controller RAM. */ |
| 910 | 910 | set_dma_address(device, DMA23_16, DMA15_8, DMA7_0); |
| 911 | ||
| 911 | ||
| 912 | 912 | smc92x4_set_dip(device, TRUE); |
| 913 | 913 | for (i=0; i < sector_len; i++) |
| 914 | 914 | { |
| r8044 | r8045 | |
| 922 | 922 | w->register_r[CHIP_STATUS] &= ~CS_RETREQ; |
| 923 | 923 | w->register_r[CHIP_STATUS] &= ~CS_CRCERR; |
| 924 | 924 | w->register_r[CHIP_STATUS] &= ~CS_ECCATT; |
| 925 | ||
| 925 | ||
| 926 | 926 | /* Update the DMA registers. */ |
| 927 | 927 | if (transfer_enable) |
| 928 | 928 | dma_add_offset(device, sector_len); |
| r8044 | r8045 | |
| 932 | 932 | |
| 933 | 933 | /* Clear the error bits. */ |
| 934 | 934 | w->register_r[INT_STATUS] &= ~ST_TC_DATAERR; |
| 935 | ||
| 935 | ||
| 936 | 936 | if (w->register_w[SECTOR_COUNT] == 0) |
| 937 | 937 | return; |
| 938 | ||
| 938 | ||
| 939 | 939 | /* Else this is a multi-sector operation. */ |
| 940 | w->register_w[DESIRED_SECTOR] = | |
| 941 | w->register_r[DESIRED_SECTOR] = | |
| 940 | w->register_w[DESIRED_SECTOR] = | |
| 941 | w->register_r[DESIRED_SECTOR] = | |
| 942 | 942 | (w->register_w[DESIRED_SECTOR]+1) & 0xff; |
| 943 | ||
| 943 | ||
| 944 | 944 | /* Reinitialize retry count. */ |
| 945 | 945 | w->register_w[RETRY_COUNT] = retry; |
| 946 | 946 | } |
| 947 | 947 | |
| 948 | 948 | /* |
| 949 | ||
| 949 | Common procedure: data_transfer(write) (as described in the specification) | |
| 950 | 950 | */ |
| 951 | 951 | static void data_transfer_write(running_device *device, chrn_id_hd id, int deldata, int redcur, int precomp, int write_long) |
| 952 | 952 | { |
| r8044 | r8045 | |
| 955 | 955 | running_device *current_floppy = NULL; |
| 956 | 956 | UINT8 *buf; |
| 957 | 957 | int sector_data_id; |
| 958 | ||
| 958 | ||
| 959 | 959 | sync_latches_out(device); |
| 960 | 960 | sync_status_in(device); |
| 961 | ||
| 961 | ||
| 962 | 962 | current_floppy = (*w->intf->current_floppy)(); |
| 963 | ||
| 964 | /* Set command termination code. The error code is set first, and | |
| 965 | on success, it is cleared. */ | |
| 963 | ||
| 964 | /* Set command termination code. The error code is set first, and | |
| 965 | on success, it is cleared. */ | |
| 966 | 966 | w->register_r[INT_STATUS] |= ST_TC_DATAERR; |
| 967 | ||
| 967 | ||
| 968 | 968 | /* Save the value. Note that the retry count is only in the first four |
| 969 | bits, and it is stored in one's complement. In this implementation | |
| 970 | we don't work with it. */ | |
| 969 | bits, and it is stored in one's complement. In this implementation | |
| 970 | we don't work with it. */ | |
| 971 | 971 | retry = w->register_w[RETRY_COUNT]; |
| 972 | ||
| 972 | ||
| 973 | 973 | /* Initiate the DMA. We assume the DMARQ is positive. */ |
| 974 | w->register_r[INT_STATUS] &= ~ST_OVRUN; | |
| 974 | w->register_r[INT_STATUS] &= ~ST_OVRUN; | |
| 975 | 975 | |
| 976 | 976 | sector_len = 1 << (id.N+7); |
| 977 | 977 | sector_data_id = id.data_id; |
| 978 | ||
| 978 | ||
| 979 | 979 | buf = (UINT8 *)malloc(sector_len); |
| 980 | 980 | |
| 981 | 981 | /* Copy via DMA from controller RAM. */ |
| 982 | 982 | set_dma_address(device, DMA23_16, DMA15_8, DMA7_0); |
| 983 | ||
| 983 | ||
| 984 | 984 | smc92x4_set_dip(device, TRUE); |
| 985 | 985 | for (i=0; i<sector_len; i++) |
| 986 | 986 | { |
| 987 | 987 | buf[i] = (*w->intf->dma_read_callback)(); |
| 988 | 988 | } |
| 989 | 989 | smc92x4_set_dip(device, FALSE); |
| 990 | ||
| 990 | ||
| 991 | 991 | if (write_long) |
| 992 | 992 | { |
| 993 | 993 | logerror("smc92x4 write sector: Write_long not supported. Performing a normal write.\n"); |
| 994 | 994 | } |
| 995 | ||
| 995 | ||
| 996 | 996 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 997 | 997 | { |
| 998 | 998 | floppy_drive_write_sector_data(current_floppy, id.H, sector_data_id, (char *) buf, sector_len, FALSE); |
| r8044 | r8045 | |
| 1003 | 1003 | } |
| 1004 | 1004 | free(buf); |
| 1005 | 1005 | sync_status_in(device); |
| 1006 | ||
| 1006 | ||
| 1007 | 1007 | w->register_r[CHIP_STATUS] &= ~CS_RETREQ; |
| 1008 | 1008 | w->register_r[CHIP_STATUS] &= ~CS_CRCERR; |
| 1009 | 1009 | w->register_r[CHIP_STATUS] &= ~CS_ECCATT; |
| 1010 | ||
| 1010 | ||
| 1011 | 1011 | /* Update the DMA registers. */ |
| 1012 | 1012 | dma_add_offset(device, sector_len); |
| 1013 | 1013 | |
| r8044 | r8045 | |
| 1016 | 1016 | |
| 1017 | 1017 | /* Clear the error bits. */ |
| 1018 | 1018 | w->register_r[INT_STATUS] &= ~ST_TC_DATAERR; |
| 1019 | ||
| 1019 | ||
| 1020 | 1020 | if (w->register_w[SECTOR_COUNT] == 0) |
| 1021 | 1021 | return; |
| 1022 | ||
| 1022 | ||
| 1023 | 1023 | /* Else this is a multi-sector operation. */ |
| 1024 | w->register_w[DESIRED_SECTOR] = | |
| 1025 | w->register_r[DESIRED_SECTOR] = | |
| 1024 | w->register_w[DESIRED_SECTOR] = | |
| 1025 | w->register_r[DESIRED_SECTOR] = | |
| 1026 | 1026 | (w->register_w[DESIRED_SECTOR]+1) & 0xff; |
| 1027 | ||
| 1027 | ||
| 1028 | 1028 | /* Reinitialize retry count. */ |
| 1029 | 1029 | w->register_w[RETRY_COUNT] = retry; |
| 1030 | 1030 | } |
| r8044 | r8045 | |
| 1033 | 1033 | static void write_sectors_continue(running_device *device); |
| 1034 | 1034 | |
| 1035 | 1035 | /* |
| 1036 | Read sectors physical / logical. Physical means that the first, the | |
| 1037 | second, the third sector appearing under the head will be read. These | |
| 1038 | sectors are usually not in logical sequence. The ordering depends on | |
| 1039 | the interleave pattern. | |
| 1036 | Read sectors physical / logical. Physical means that the first, the | |
| 1037 | second, the third sector appearing under the head will be read. These | |
| 1038 | sectors are usually not in logical sequence. The ordering depends on | |
| 1039 | the interleave pattern. | |
| 1040 | 1040 | */ |
| 1041 | 1041 | static void read_write_sectors(running_device *device) |
| 1042 | 1042 | { |
| r8044 | r8045 | |
| 1045 | 1045 | int logical = w->command & 0x04; |
| 1046 | 1046 | int implied_seek_disabled = w->command & 0x02; /* for read */ |
| 1047 | 1047 | int write = (w->command & 0x80); |
| 1048 | ||
| 1048 | ||
| 1049 | 1049 | w->after_seek = FALSE; |
| 1050 | ||
| 1050 | ||
| 1051 | 1051 | w->to_be_continued = FALSE; |
| 1052 | ||
| 1052 | ||
| 1053 | 1053 | if (write) /* write sectors */ |
| 1054 | 1054 | { |
| 1055 | 1055 | logical = w->command & 0x20; |
| 1056 | 1056 | implied_seek_disabled = w->command & 0x40; |
| 1057 | 1057 | } |
| 1058 | ||
| 1059 | if (!logical) | |
| 1058 | ||
| 1059 | if (!logical) | |
| 1060 | 1060 | implied_seek_disabled = FALSE; |
| 1061 | ||
| 1061 | ||
| 1062 | 1062 | if (!w->found_id) |
| 1063 | 1063 | { |
| 1064 | 1064 | /* First start. */ |
| 1065 | 1065 | read_id_field(device, &w->seek_count, &w->step_direction, &w->recent_id); |
| 1066 | 1066 | } |
| 1067 | ||
| 1067 | ||
| 1068 | 1068 | if ((w->register_r[INT_STATUS] & ST_TC_DATAERR) == ST_TC_SUCCESS) |
| 1069 | { | |
| 1069 | { | |
| 1070 | 1070 | w->found_id = TRUE; |
| 1071 | 1071 | /* Perform the seek for the cylinder. */ |
| 1072 | 1072 | if (!implied_seek_disabled && w->seek_count > 0) |
| r8044 | r8045 | |
| 1080 | 1080 | else |
| 1081 | 1081 | read_sectors_continue(device); |
| 1082 | 1082 | } |
| 1083 | ||
| 1083 | ||
| 1084 | 1084 | } |
| 1085 | 1085 | else |
| 1086 | 1086 | { |
| r8044 | r8045 | |
| 1117 | 1117 | { |
| 1118 | 1118 | logerror("smc92x4 error: data error during sector read: INTSTATUS=%02x\n", w->register_r[INT_STATUS]); |
| 1119 | 1119 | set_command_done(device, ST_TC_DATAERR); |
| 1120 | return; | |
| 1120 | return; | |
| 1121 | 1121 | } |
| 1122 | 1122 | } |
| 1123 | 1123 | |
| 1124 | 1124 | w->to_be_continued = FALSE; |
| 1125 | ||
| 1125 | ||
| 1126 | 1126 | /* Wait for SEEK_COMPLETE. We assume the signal has appeared. */ |
| 1127 | ||
| 1127 | ||
| 1128 | 1128 | if (w->register_w[SECTOR_COUNT] > 0 /* && !(w->register_r[DRIVE_STATUS] & DS_INDEX) */) |
| 1129 | 1129 | { |
| 1130 | 1130 | /* Call the verify sequence. */ |
| r8044 | r8045 | |
| 1137 | 1137 | } |
| 1138 | 1138 | |
| 1139 | 1139 | /* For read physical, only verify the first sector. */ |
| 1140 | if (!logical) | |
| 1140 | if (!logical) | |
| 1141 | 1141 | check_sector = FALSE; |
| 1142 | ||
| 1142 | ||
| 1143 | 1143 | if (w->recent_id.flags & BAD_SECTOR) |
| 1144 | 1144 | { |
| 1145 | 1145 | logerror("smc92x4 error: Bad sector, seek error\n"); |
| r8044 | r8045 | |
| 1147 | 1147 | } |
| 1148 | 1148 | else |
| 1149 | 1149 | { |
| 1150 | /* printf("smc92x4 read sectors CYL=%02x, HEA=%02x, SEC=%02x, MOD=%02x, CNT=%02x, TRY=%02x\n", | |
| 1151 | w->register_w[DESIRED_CYLINDER], | |
| 1152 | w->register_w[DESIRED_HEAD], | |
| 1153 | w->register_w[DESIRED_SECTOR], | |
| 1154 | w->register_w[MODE], | |
| 1155 | w->register_w[SECTOR_COUNT], | |
| 1156 | w->register_w[RETRY_COUNT]); */ | |
| 1150 | /* printf("smc92x4 read sectors CYL=%02x, HEA=%02x, SEC=%02x, MOD=%02x, CNT=%02x, TRY=%02x\n", | |
| 1151 | w->register_w[DESIRED_CYLINDER], | |
| 1152 | w->register_w[DESIRED_HEAD], | |
| 1153 | w->register_w[DESIRED_SECTOR], | |
| 1154 | w->register_w[MODE], | |
| 1155 | w->register_w[SECTOR_COUNT], | |
| 1156 | w->register_w[RETRY_COUNT]); */ | |
| 1157 | 1157 | smc92x4_timed_sector_read_request(device); |
| 1158 | 1158 | } |
| 1159 | 1159 | } |
| r8044 | r8045 | |
| 1171 | 1171 | int check_sector = TRUE; /* always check the first sector */ |
| 1172 | 1172 | int state = AGAIN; |
| 1173 | 1173 | int logical = w->command & 0x20; |
| 1174 | ||
| 1174 | ||
| 1175 | 1175 | /* Needed for the two ways of re-entry: during the seek process, and during sector write */ |
| 1176 | 1176 | if (!w->after_seek) |
| 1177 | 1177 | { |
| r8044 | r8045 | |
| 1191 | 1191 | { |
| 1192 | 1192 | logerror("smc92x4 error: data error during sector write\n"); |
| 1193 | 1193 | set_command_done(device, ST_TC_DATAERR); |
| 1194 | return; | |
| 1194 | return; | |
| 1195 | 1195 | } |
| 1196 | 1196 | } |
| 1197 | ||
| 1197 | ||
| 1198 | 1198 | w->to_be_continued = FALSE; |
| 1199 | 1199 | |
| 1200 | 1200 | if ((w->register_w[RETRY_COUNT] & 0xf0)!= 0xf0) |
| 1201 | 1201 | logerror("smc92x4 warn: RETRY_COUNT in write sector should be set to 0. Ignored.\n"); |
| 1202 | 1202 | |
| 1203 | /* Wait for SEEK_COMPLETE. We assume the signal has appeared. */ | |
| 1203 | /* Wait for SEEK_COMPLETE. We assume the signal has appeared. */ | |
| 1204 | 1204 | if (w->register_w[SECTOR_COUNT] > 0) |
| 1205 | 1205 | { |
| 1206 | 1206 | /* Call the verify sequence. */ |
| r8044 | r8045 | |
| 1212 | 1212 | } |
| 1213 | 1213 | |
| 1214 | 1214 | /* For write physical, only verify the first sector. */ |
| 1215 | if (!logical) | |
| 1215 | if (!logical) | |
| 1216 | 1216 | check_sector = FALSE; |
| 1217 | 1217 | |
| 1218 | /* printf("smc92x4 write sectors CYL=%02x, HEA=%02x, SEC=%02x, MOD=%02x, CNT=%02x, TRY=%02x\n", | |
| 1219 | w->register_w[DESIRED_CYLINDER], | |
| 1220 | w->register_w[DESIRED_HEAD], | |
| 1221 | w->register_w[DESIRED_SECTOR], | |
| 1222 | w->register_w[MODE], | |
| 1223 | w->register_w[SECTOR_COUNT], | |
| 1224 | w->register_w[RETRY_COUNT]); */ | |
| 1218 | /* printf("smc92x4 write sectors CYL=%02x, HEA=%02x, SEC=%02x, MOD=%02x, CNT=%02x, TRY=%02x\n", | |
| 1219 | w->register_w[DESIRED_CYLINDER], | |
| 1220 | w->register_w[DESIRED_HEAD], | |
| 1221 | w->register_w[DESIRED_SECTOR], | |
| 1222 | w->register_w[MODE], | |
| 1223 | w->register_w[SECTOR_COUNT], | |
| 1224 | w->register_w[RETRY_COUNT]); */ | |
| 1225 | 1225 | smc92x4_timed_sector_write_request(device); |
| 1226 | 1226 | } |
| 1227 | 1227 | else |
| r8044 | r8045 | |
| 1232 | 1232 | } |
| 1233 | 1233 | |
| 1234 | 1234 | /********************************************************************* |
| 1235 | ||
| 1235 | Command implementations | |
| 1236 | 1236 | *********************************************************************/ |
| 1237 | 1237 | |
| 1238 | 1238 | /* |
| r8044 | r8045 | |
| 1241 | 1241 | static void restore_drive(running_device *device) |
| 1242 | 1242 | { |
| 1243 | 1243 | smc92x4_state *w = get_safe_token(device); |
| 1244 | ||
| 1244 | ||
| 1245 | 1245 | /* TODO: int_after_seek_complete required for buffered seeks */ |
| 1246 | 1246 | sync_status_in(device); |
| 1247 | 1247 | |
| r8044 | r8045 | |
| 1251 | 1251 | w->register_r[INT_STATUS] |= ST_TC_SEEKERR; |
| 1252 | 1252 | return; |
| 1253 | 1253 | } |
| 1254 | ||
| 1254 | ||
| 1255 | 1255 | if (w->register_r[DRIVE_STATUS] & DS_TRK00) |
| 1256 | 1256 | { |
| 1257 | 1257 | w->register_r[INT_STATUS] |= ST_TC_SUCCESS; |
| 1258 | 1258 | /* Issue interrupt */ |
| 1259 | 1259 | smc92x4_set_interrupt(device); |
| 1260 | return; | |
| 1260 | return; | |
| 1261 | 1261 | } |
| 1262 | 1262 | |
| 1263 | 1263 | w->step_direction = -1; |
| r8044 | r8045 | |
| 1269 | 1269 | smc92x4_state *w = get_safe_token(device); |
| 1270 | 1270 | |
| 1271 | 1271 | w->seek_count++; |
| 1272 | ||
| 1272 | ||
| 1273 | 1273 | /* Next iteration */ |
| 1274 | restore_drive(device); | |
| 1274 | restore_drive(device); | |
| 1275 | 1275 | |
| 1276 | 1276 | w->to_be_continued = FALSE; |
| 1277 | 1277 | } |
| 1278 | 1278 | |
| 1279 | 1279 | /* |
| 1280 | Handle the step command. Note that the CURRENT_CYLINDER register is not | |
| 1281 | updated (this would break the format procedure). | |
| 1280 | Handle the step command. Note that the CURRENT_CYLINDER register is not | |
| 1281 | updated (this would break the format procedure). | |
| 1282 | 1282 | */ |
| 1283 | 1283 | static void step_in_out(running_device *device) |
| 1284 | 1284 | { |
| 1285 | 1285 | smc92x4_state *w = get_safe_token(device); |
| 1286 | 1286 | int direction = (w->command & 0x02)? -1 : +1; |
| 1287 | 1287 | /* bit 0: 0 -> command ends after last seek pulse, 1 -> command |
| 1288 | ||
| 1288 | ends when the drive asserts the seek complete pin */ | |
| 1289 | 1289 | int buffered = w->command & 0x01; |
| 1290 | ||
| 1290 | ||
| 1291 | 1291 | w->step_direction = direction; |
| 1292 | 1292 | w->buffered = buffered; |
| 1293 | 1293 | |
| r8044 | r8045 | |
| 1307 | 1307 | static void drive_select(running_device *device, int drive); |
| 1308 | 1308 | |
| 1309 | 1309 | /* |
| 1310 | Poll drives | |
| 1311 | This command is used to find out which drive has complete a buffered | |
| 1312 | seek (RESTORE, SEEK IN/OUT with BUFFERED set to one) | |
| 1310 | Poll drives | |
| 1311 | This command is used to find out which drive has complete a buffered | |
| 1312 | seek (RESTORE, SEEK IN/OUT with BUFFERED set to one) | |
| 1313 | 1313 | */ |
| 1314 | 1314 | static void poll_drives(running_device *device) |
| 1315 | 1315 | { |
| r8044 | r8045 | |
| 1317 | 1317 | smc92x4_state *w = get_safe_token(device); |
| 1318 | 1318 | int i; |
| 1319 | 1319 | int flags = w->command & 0x0f; |
| 1320 | ||
| 1320 | ||
| 1321 | 1321 | /* Spec is unclear: Do we continue to poll the drives after we have checked each |
| 1322 | 1322 | one for the first time? We are not interested in locking up the emulator, so |
| 1323 | 1323 | we decide to poll only once. */ |
| r8044 | r8045 | |
| 1339 | 1339 | { |
| 1340 | 1340 | smc92x4_state *w = get_safe_token(device); |
| 1341 | 1341 | |
| 1342 | w->output1 = (0x10 << (driveparm & 0x03)) | (w->register_w[RETRY_COUNT]&0x0f); | |
| 1342 | w->output1 = (0x10 << (driveparm & 0x03)) | (w->register_w[RETRY_COUNT]&0x0f); | |
| 1343 | 1343 | w->selected_drive_type = (driveparm>>2) & 0x03; |
| 1344 | 1344 | w->head_load_delay_enable = (driveparm>>4)&0x01; |
| 1345 | ||
| 1345 | ||
| 1346 | 1346 | /* We need to store the type of the drive for the poll_drives command |
| 1347 | ||
| 1347 | to be able to correctly select the device (floppy or hard disk). */ | |
| 1348 | 1348 | w->types[driveparm&0x03] = w->selected_drive_type; |
| 1349 | 1349 | |
| 1350 | /* Copy the DMA registers to registers CURRENT_HEAD, CURRENT_CYLINDER, | |
| 1351 | and CURRENT_IDENT. This is required during formatting (p. 14) as the | |
| 1352 | format command reuses the registers for formatting parameters. */ | |
| 1350 | /* Copy the DMA registers to registers CURRENT_HEAD, CURRENT_CYLINDER, | |
| 1351 | and CURRENT_IDENT. This is required during formatting (p. 14) as the | |
| 1352 | format command reuses the registers for formatting parameters. */ | |
| 1353 | 1353 | w->register_r[CURRENT_HEAD] = w->register_r[DMA7_0]; |
| 1354 | 1354 | w->register_r[CURRENT_CYLINDER] = w->register_r[DMA15_8]; |
| 1355 | 1355 | w->register_r[CURRENT_IDENT] = w->register_r[DMA23_16]; |
| 1356 | ||
| 1356 | ||
| 1357 | 1357 | sync_latches_out(device); |
| 1358 | 1358 | sync_status_in(device); |
| 1359 | 1359 | } |
| 1360 | 1360 | |
| 1361 | 1361 | /* |
| 1362 | ||
| 1362 | Command SEEK/READID | |
| 1363 | 1363 | */ |
| 1364 | 1364 | static void seek_read_id(running_device *device) |
| 1365 | 1365 | { |
| 1366 | 1366 | smc92x4_state *w = get_safe_token(device); |
| 1367 | 1367 | int step_enable = (w->command & 0x04); |
| 1368 | 1368 | int verify_id = (w->command & 0x01); |
| 1369 | int wait = (w->command & 0x02); | |
| 1369 | int wait = (w->command & 0x02); | |
| 1370 | 1370 | |
| 1371 | 1371 | w->to_be_continued = FALSE; |
| 1372 | ||
| 1372 | ||
| 1373 | 1373 | if (!w->found_id) |
| 1374 | 1374 | { |
| 1375 | 1375 | /* First start. */ |
| 1376 | 1376 | read_id_field(device, &w->seek_count, &w->step_direction, &w->recent_id); |
| 1377 | 1377 | w->found_id = TRUE; |
| 1378 | 1378 | } |
| 1379 | ||
| 1379 | ||
| 1380 | 1380 | if ((w->register_r[INT_STATUS] & ST_TC_DATAERR) == ST_TC_SUCCESS) |
| 1381 | { | |
| 1381 | { | |
| 1382 | 1382 | /* Perform the seek for the cylinder. */ |
| 1383 | 1383 | if (step_enable && w->seek_count > 0) |
| 1384 | 1384 | { |
| r8044 | r8045 | |
| 1388 | 1388 | { |
| 1389 | 1389 | if (wait) |
| 1390 | 1390 | logerror("smc92x4:seed_read_id: Waiting for seek_complete not implemented.\n"); |
| 1391 | ||
| 1391 | ||
| 1392 | 1392 | if (verify_id) |
| 1393 | 1393 | { |
| 1394 | 1394 | verify(device, &w->recent_id, TRUE); |
| r8044 | r8045 | |
| 1410 | 1410 | } |
| 1411 | 1411 | |
| 1412 | 1412 | /* |
| 1413 | Formats a track starting from the detection of an index mark until the | |
| 1414 | detection of another index mark. | |
| 1415 | The formatting is done exclusively by the controller; user programs may | |
| 1416 | set parameters for gaps and interleaving. | |
| 1413 | Formats a track starting from the detection of an index mark until the | |
| 1414 | detection of another index mark. | |
| 1415 | The formatting is done exclusively by the controller; user programs may | |
| 1416 | set parameters for gaps and interleaving. | |
| 1417 | 1417 | |
| 1418 | 1. Before starting the command, the user program must have set up a | |
| 1419 | sector sequence table in the controller RAM (located on the PCB): | |
| 1420 | (ident, cylinder, head, sector1, size) (5 bytes) | |
| 1421 | (ident, cylinder, head, sector2, size) | |
| 1422 | (ident, cylinder, head, sector3, size) | |
| 1423 | ... | |
| 1424 | ident is not required for floppy FM operation. size is not required | |
| 1425 | for IBM AT-compatible hard disks. | |
| 1426 | ||
| 1427 | 2. The DMA registers must point to the beginning of the table | |
| 1428 | ||
| 1429 | 3. DRIVE_SELECT must be executed (which moves DMA regs to CUR_HEAD ...) | |
| 1430 | ||
| 1431 | 4. DESIRED_HEAD register must be loaded | |
| 1432 | ||
| 1433 | 5. The following setup must be done: | |
| 1434 | ||
| 1435 | GAP 0 size DMA7_0 (2s comp) | |
| 1436 | GAP 1 size DMA15_8 (2s comp) | |
| 1437 | GAP 2 size DMA23_16 (2s comp) | |
| 1438 | GAP 3 size DESIRED_SECTOR (2s comp) | |
| 1439 | Sync size DESIRED_CYLINDER (1s comp) | |
| 1440 | Sector count SECTOR_COUNT (1s comp) | |
| 1441 | Sector size multiple RETRY_COUNT (1s comp) | |
| 1418 | 1. Before starting the command, the user program must have set up a | |
| 1419 | sector sequence table in the controller RAM (located on the PCB): | |
| 1420 | (ident, cylinder, head, sector1, size) (5 bytes) | |
| 1421 | (ident, cylinder, head, sector2, size) | |
| 1422 | (ident, cylinder, head, sector3, size) | |
| 1423 | ... | |
| 1424 | ident is not required for floppy FM operation. size is not required | |
| 1425 | for IBM AT-compatible hard disks. | |
| 1442 | 1426 | |
| 1443 | GAP4 is variable and fills the rest of the track until the next | |
| 1444 | index hole. Usually we have 247 bytes for FM and 598 for MFM. | |
| 1445 | ||
| 1446 | 6. The step rate and density must be loaded into the MODE register | |
| 1427 | 2. The DMA registers must point to the beginning of the table | |
| 1447 | 1428 | |
| 1448 | ||
| 1429 | 3. DRIVE_SELECT | |
| 1449 | 1430 | |
| 1450 | 8. Now this command may be started. | |
| 1451 | ||
| 1452 | All data bytes of a sector are filled with 0xe5. The gaps will be filled | |
| 1453 | with 0x4e (MFM) or 0xff (FM). | |
| 1454 | ||
| 1455 | To format another track, the sector id table must be updated, and steps | |
| 1456 | 7 and 8 must be repeated. If the DESIRED_HEAD register must be updated, | |
| 1457 | the complete setup process must be done. | |
| 1458 | ||
| 1459 | Options: Command = 011m rppp | |
| 1460 | m = set data mark (0 = set deleted) | |
| 1461 | r = current (1 = reduced) | |
| 1462 | ppp = precompensation (for sector size = (2^ppp) * 128; ppp<4 for floppy ) | |
| 1463 | ||
| 1464 | =============== | |
| 1465 | ||
| 1466 | One deviation from the specification: The TI-99 family uses the SDF | |
| 1467 | and TDF formats. The TDF formats complies with the formats produced | |
| 1468 | by the standard TI disk controller. It does not use index address marks. | |
| 1469 | So we could integrate a translation in ti99_dsk when writing to disk, | |
| 1470 | but when reading, how can ti99_dsk know whether to blow up the format | |
| 1471 | to full length for this controller or keep it as is for the other | |
| 1472 | controller? Unless someone comes up with a better idea, we implement | |
| 1473 | an "undocumented" option in this controller, allowing to create a | |
| 1474 | different track layout. | |
| 1475 | ||
| 1476 | So there are two layouts for the floppy track: | |
| 1477 | ||
| 1478 | - full format, including the index address mark, according to the | |
| 1479 | specification | |
| 1480 | ||
| 1481 | - short format without index AM which matches the PC99 format used | |
| 1482 | for the TI-99 family. | |
| 1483 | ||
| 1484 | The formats are determined by setting the flag in the smc92x4 | |
| 1485 | interface structure. | |
| 1431 | 4. DESIRED_HEAD register must be loaded | |
| 1432 | ||
| 1433 | 5. The following setup must be done: | |
| 1434 | ||
| 1435 | GAP 0 size DMA7_0 (2s comp) | |
| 1436 | GAP 1 size DMA15_8 (2s comp) | |
| 1437 | GAP 2 size DMA23_16 (2s comp) | |
| 1438 | GAP 3 size DESIRED_SECTOR (2s comp) | |
| 1439 | Sync size DESIRED_CYLINDER (1s comp) | |
| 1440 | Sector count SECTOR_COUNT (1s comp) | |
| 1441 | Sector size multiple RETRY_COUNT (1s comp) | |
| 1442 | ||
| 1443 | GAP4 is variable and fills the rest of the track until the next | |
| 1444 | index hole. Usually we have 247 bytes for FM and 598 for MFM. | |
| 1445 | ||
| 1446 | 6. The step rate and density must be loaded into the MODE register | |
| 1447 | ||
| 1448 | 7. The drive must be stepped to the desired track. | |
| 1449 | ||
| 1450 | 8. Now this command may be started. | |
| 1451 | ||
| 1452 | All data bytes of a sector are filled with 0xe5. The gaps will be filled | |
| 1453 | with 0x4e (MFM) or 0xff (FM). | |
| 1454 | ||
| 1455 | To format another track, the sector id table must be updated, and steps | |
| 1456 | 7 and 8 must be repeated. If the DESIRED_HEAD register must be updated, | |
| 1457 | the complete setup process must be done. | |
| 1458 | ||
| 1459 | Options: Command = 011m rppp | |
| 1460 | m = set data mark (0 = set deleted) | |
| 1461 | r = current (1 = reduced) | |
| 1462 | ppp = precompensation (for sector size = (2^ppp) * 128; ppp<4 for floppy ) | |
| 1463 | ||
| 1464 | =============== | |
| 1465 | ||
| 1466 | One deviation from the specification: The TI-99 family uses the SDF | |
| 1467 | and TDF formats. The TDF formats complies with the formats produced | |
| 1468 | by the standard TI disk controller. It does not use index address marks. | |
| 1469 | So we could integrate a translation in ti99_dsk when writing to disk, | |
| 1470 | but when reading, how can ti99_dsk know whether to blow up the format | |
| 1471 | to full length for this controller or keep it as is for the other | |
| 1472 | controller? Unless someone comes up with a better idea, we implement | |
| 1473 | an "undocumented" option in this controller, allowing to create a | |
| 1474 | different track layout. | |
| 1475 | ||
| 1476 | So there are two layouts for the floppy track: | |
| 1477 | ||
| 1478 | - full format, including the index address mark, according to the | |
| 1479 | specification | |
| 1480 | ||
| 1481 | - short format without index AM which matches the PC99 format used | |
| 1482 | for the TI-99 family. | |
| 1483 | ||
| 1484 | The formats are determined by setting the flag in the smc92x4 | |
| 1485 | interface structure. | |
| 1486 | 1486 | */ |
| 1487 | 1487 | static void format_floppy_track(running_device *device, int flags) |
| 1488 | 1488 | { |
| r8044 | r8045 | |
| 1494 | 1494 | int gap0, gap1, gap2, gap3, gap4, sync1, sync2, count, size, fm; |
| 1495 | 1495 | int gap_byte, pre_gap, crc, mark, inam; |
| 1496 | 1496 | UINT8 curr_ident, curr_cyl, curr_head, curr_sect, curr_size; |
| 1497 | ||
| 1497 | ||
| 1498 | 1498 | int normal_data_mark = flags & 0x10; |
| 1499 | ||
| 1500 | UINT8 *buffer; | |
| 1501 | 1499 | |
| 1500 | UINT8 *buffer; | |
| 1501 | ||
| 1502 | 1502 | /* Determine the track size. We cannot allow different sizes in this |
| 1503 | ||
| 1503 | design. */ | |
| 1504 | 1504 | int data_count = 0; |
| 1505 | 1505 | |
| 1506 | 1506 | sync_status_in(device); |
| 1507 | ||
| 1507 | ||
| 1508 | 1508 | current_floppy = (*w->intf->current_floppy)(); |
| 1509 | 1509 | floppy = flopimg_get_image(current_floppy); |
| 1510 | 1510 | |
| 1511 | 1511 | if (floppy != NULL) |
| 1512 | 1512 | data_count = floppy_get_track_size(floppy, 0, 0); |
| 1513 | ||
| 1513 | ||
| 1514 | 1514 | if (data_count==0) |
| 1515 | 1515 | { |
| 1516 | 1516 | if (controller_set_to_single_density(device)) |
| r8044 | r8045 | |
| 1518 | 1518 | else |
| 1519 | 1519 | data_count = TRKSIZE_DD; |
| 1520 | 1520 | } |
| 1521 | ||
| 1521 | ||
| 1522 | 1522 | /* Build buffer */ |
| 1523 | 1523 | buffer = (UINT8*)malloc(data_count); |
| 1524 | ||
| 1524 | ||
| 1525 | 1525 | fm = controller_set_to_single_density(device); |
| 1526 | ||
| 1526 | ||
| 1527 | 1527 | sync2 = (~w->register_w[DESIRED_CYLINDER])&0xff; |
| 1528 | 1528 | gap2 = (-w->register_w[DMA23_16])&0xff; |
| 1529 | 1529 | count = (~w->register_w[SECTOR_COUNT])&0xff; |
| r8044 | r8045 | |
| 1531 | 1531 | gap_byte = (fm)? 0xff : 0x4e; |
| 1532 | 1532 | |
| 1533 | 1533 | if (w->intf->full_track_layout) |
| 1534 | { | |
| 1534 | { | |
| 1535 | 1535 | /* Including the index AM. */ |
| 1536 | 1536 | gap0 = (-w->register_w[DMA7_0])&0xff; |
| 1537 | 1537 | gap1 = (-w->register_w[DMA15_8])&0xff; |
| r8044 | r8045 | |
| 1552 | 1552 | sync1 = (fm)? 6 : 10; |
| 1553 | 1553 | inam = 0; |
| 1554 | 1554 | } |
| 1555 | ||
| 1555 | ||
| 1556 | 1556 | index = 0; |
| 1557 | 1557 | |
| 1558 | 1558 | mark = (fm)? 10 : 16; /* ID/DAM + A1 + CRC */ |
| 1559 | ||
| 1559 | ||
| 1560 | 1560 | exp_size = gap0 + inam + gap1 + count*(sync1 + mark + gap2 + sync2 + size*128 + gap3) + gap4; |
| 1561 | ||
| 1561 | ||
| 1562 | 1562 | if (exp_size != data_count) |
| 1563 | logerror("smc92x4 warn: The current track length in the image (%d) does not match the new track length (%d). Keeping the old length. This will break the image (sorry).\n", data_count, exp_size); | |
| 1564 | ||
| 1563 | logerror("smc92x4 warn: The current track length in the image (%d) does not match the new track length (%d). Keeping the old length. This will break the image (sorry).\n", data_count, exp_size); | |
| 1564 | ||
| 1565 | 1565 | /* use the backup registers set up during drive_select */ |
| 1566 | set_dma_address(device, CURRENT_IDENT, CURRENT_CYLINDER, CURRENT_HEAD); | |
| 1566 | set_dma_address(device, CURRENT_IDENT, CURRENT_CYLINDER, CURRENT_HEAD); | |
| 1567 | 1567 | |
| 1568 | 1568 | memset(&buffer[index], pre_gap, gap0); |
| 1569 | 1569 | index += gap0; |
| r8044 | r8045 | |
| 1576 | 1576 | if (!fm) |
| 1577 | 1577 | { |
| 1578 | 1578 | memset(&buffer[index], 0xc2, 3); |
| 1579 | index += 3; | |
| 1579 | index += 3; | |
| 1580 | 1580 | } |
| 1581 | 1581 | memset(&buffer[index], gap_byte, gap1); |
| 1582 | index += gap1; | |
| 1582 | index += gap1; | |
| 1583 | 1583 | } |
| 1584 | ||
| 1584 | ||
| 1585 | 1585 | /* for each sector */ |
| 1586 | 1586 | for (j=0; j < count; j++) |
| 1587 | 1587 | { |
| r8044 | r8045 | |
| 1627 | 1627 | memset(&buffer[index], 0xa1, 3); |
| 1628 | 1628 | index += 3; |
| 1629 | 1629 | } |
| 1630 | ||
| 1630 | ||
| 1631 | 1631 | if (normal_data_mark) buffer[index++] = 0xfb; |
| 1632 | 1632 | else buffer[index++] = 0xf8; |
| 1633 | 1633 | |
| r8044 | r8045 | |
| 1652 | 1652 | } |
| 1653 | 1653 | |
| 1654 | 1654 | /* |
| 1655 | Create the track layout of a MFM hard disk. Like floppy disks, | |
| 1656 | MFM hard disks are interfaced on a track base, that is, we have to | |
| 1657 | create a complete track layout. | |
| 1658 | ||
| 1659 | For more explanations see the comments to format_floppy_track. | |
| 1655 | Create the track layout of a MFM hard disk. Like floppy disks, | |
| 1656 | MFM hard disks are interfaced on a track base, that is, we have to | |
| 1657 | create a complete track layout. | |
| 1658 | ||
| 1659 | For more explanations see the comments to format_floppy_track. | |
| 1660 | 1660 | */ |
| 1661 | 1661 | static void format_harddisk_track(running_device *device, int flags) |
| 1662 | 1662 | { |
| r8044 | r8045 | |
| 1667 | 1667 | |
| 1668 | 1668 | int normal_data_mark = flags & 0x10; |
| 1669 | 1669 | int data_count=0; |
| 1670 | ||
| 1671 | UINT8 *buffer; | |
| 1672 | 1670 | |
| 1671 | UINT8 *buffer; | |
| 1672 | ||
| 1673 | 1673 | sync_status_in(device); |
| 1674 | ||
| 1674 | ||
| 1675 | 1675 | /* Build buffer */ |
| 1676 | 1676 | gap0 = (-w->register_w[DMA7_0])&0xff; |
| 1677 | 1677 | gap1 = (-w->register_w[DMA15_8])&0xff; |
| r8044 | r8045 | |
| 1684 | 1684 | size = (~w->register_w[RETRY_COUNT])&0xff; |
| 1685 | 1685 | |
| 1686 | 1686 | data_count = gap1 + count*(sync+12+gap2+sync+size*128+gap3)+gap4; |
| 1687 | ||
| 1687 | ||
| 1688 | 1688 | buffer = (UINT8*)malloc(data_count); |
| 1689 | ||
| 1689 | ||
| 1690 | 1690 | index = 0; |
| 1691 | 1691 | fm = controller_set_to_single_density(device); |
| 1692 | 1692 | gap_byte = 0x4e; |
| 1693 | ||
| 1693 | ||
| 1694 | 1694 | /* use the backup registers set up during drive_select */ |
| 1695 | set_dma_address(device, CURRENT_IDENT, CURRENT_CYLINDER, CURRENT_HEAD); | |
| 1695 | set_dma_address(device, CURRENT_IDENT, CURRENT_CYLINDER, CURRENT_HEAD); | |
| 1696 | 1696 | |
| 1697 | 1697 | for (i=0; i < gap1; i++) buffer[index++] = gap_byte; |
| 1698 | 1698 | |
| r8044 | r8045 | |
| 1715 | 1715 | buffer[index++] = curr_head; |
| 1716 | 1716 | buffer[index++] = curr_sect; |
| 1717 | 1717 | buffer[index++] = curr_size; |
| 1718 | ||
| 1718 | ||
| 1719 | 1719 | /* Calculate CRC16 (5 bytes for ID) */ |
| 1720 | 1720 | crc = ccitt_crc16(0xffff, &buffer[index-5], 5); |
| 1721 | 1721 | buffer[index++] = (crc>>8)&0xff; |
| r8044 | r8045 | |
| 1724 | 1724 | /* GAP 2 */ |
| 1725 | 1725 | for (i=0; i < gap2; i++) buffer[index++] = gap_byte; |
| 1726 | 1726 | for (i=0; i < sync; i++) buffer[index++] = 0x00; |
| 1727 | ||
| 1727 | ||
| 1728 | 1728 | buffer[index++] = 0xa1; |
| 1729 | ||
| 1729 | ||
| 1730 | 1730 | if (normal_data_mark) buffer[index++] = 0xfb; |
| 1731 | 1731 | else buffer[index++] = 0xf8; |
| 1732 | 1732 | |
| r8044 | r8045 | |
| 1737 | 1737 | crc = ccitt_crc16(0xffff, &buffer[index-128*size-1], 128*size+1); |
| 1738 | 1738 | buffer[index++] = (crc>>8)&0xff; |
| 1739 | 1739 | buffer[index++] = crc & 0xff; |
| 1740 | ||
| 1740 | ||
| 1741 | 1741 | /* GAP 3 */ |
| 1742 | 1742 | for (i=0; i < 3; i++) buffer[index++] = 0; /* check that, unclear in spec */ |
| 1743 | 1743 | for (i=0; i < gap3 - 3; i++) buffer[index++] = gap_byte; |
| 1744 | 1744 | } |
| 1745 | 1745 | /* GAP 4 */ |
| 1746 | 1746 | for (i=0; i < gap4; i++) buffer[index++] = gap_byte; |
| 1747 | ||
| 1747 | ||
| 1748 | 1748 | (*w->intf->mfmhd_write_track)(w->register_w[DESIRED_HEAD]&0x0f, buffer, data_count); |
| 1749 | 1749 | free(buffer); |
| 1750 | sync_status_in(device); | |
| 1750 | sync_status_in(device); | |
| 1751 | 1751 | } |
| 1752 | 1752 | |
| 1753 | 1753 | /* |
| 1754 | Read a floppy track. | |
| 1755 | A complete track is read at the position of the head. It reads the | |
| 1756 | track from one index pulse to the next index pulse. (Note that the | |
| 1757 | spec talks about "index mark" and "signal from the drive" which is | |
| 1758 | a bit confusing, since the index AM is behind Gap0, the index hole | |
| 1759 | is before Gap0. We should check with a real device. Also, it does not | |
| 1760 | speak about the head, so we assume the head is set in the DESIRED_HEAD | |
| 1761 | register.) | |
| 1762 | ||
| 1763 | TODO: The TDF format does not support index marks. Need to define TDF | |
| 1764 | in a more flexible way. Also consider format variations. | |
| 1765 | (Hint: Do a check for the standard "IBM" format. Should probably do | |
| 1766 | a translation from IBM to PC99 and back. Requires to parse the track | |
| 1767 | image before. Need to decide whether we generally translate to the IBM | |
| 1768 | format or generally to the PC99 format between controller and format. | |
| 1769 | Format is the image is always PC99.) | |
| 1754 | Read a floppy track. | |
| 1755 | A complete track is read at the position of the head. It reads the | |
| 1756 | track from one index pulse to the next index pulse. (Note that the | |
| 1757 | spec talks about "index mark" and "signal from the drive" which is | |
| 1758 | a bit confusing, since the index AM is behind Gap0, the index hole | |
| 1759 | is before Gap0. We should check with a real device. Also, it does not | |
| 1760 | speak about the head, so we assume the head is set in the DESIRED_HEAD | |
| 1761 | register.) | |
| 1762 | ||
| 1763 | TODO: The TDF format does not support index marks. Need to define TDF | |
| 1764 | in a more flexible way. Also consider format variations. | |
| 1765 | (Hint: Do a check for the standard "IBM" format. Should probably do | |
| 1766 | a translation from IBM to PC99 and back. Requires to parse the track | |
| 1767 | image before. Need to decide whether we generally translate to the IBM | |
| 1768 | format or generally to the PC99 format between controller and format. | |
| 1769 | Format is the image is always PC99.) | |
| 1770 | 1770 | */ |
| 1771 | 1771 | static void read_floppy_track(running_device *device, int transfer_only_ids) |
| 1772 | 1772 | { |
| r8044 | r8045 | |
| 1775 | 1775 | |
| 1776 | 1776 | floppy_image *floppy; |
| 1777 | 1777 | /* Determine the track size. We cannot allow different sizes in this |
| 1778 | ||
| 1778 | design. */ | |
| 1779 | 1779 | int data_count = 0; |
| 1780 | 1780 | int i; |
| 1781 | 1781 | UINT8 *buffer; |
| 1782 | ||
| 1782 | ||
| 1783 | 1783 | sync_latches_out(device); |
| 1784 | ||
| 1784 | ||
| 1785 | 1785 | floppy = flopimg_get_image(current_floppy); |
| 1786 | 1786 | |
| 1787 | 1787 | /* Determine the track size. We cannot allow different sizes in this |
| 1788 | ||
| 1788 | design. */ | |
| 1789 | 1789 | if (floppy != NULL) |
| 1790 | 1790 | data_count = floppy_get_track_size(floppy, 0, 0); |
| 1791 | ||
| 1791 | ||
| 1792 | 1792 | if (data_count==0) |
| 1793 | 1793 | { |
| 1794 | 1794 | if (controller_set_to_single_density(device)) |
| r8044 | r8045 | |
| 1796 | 1796 | else |
| 1797 | 1797 | data_count = TRKSIZE_DD; |
| 1798 | 1798 | } |
| 1799 | ||
| 1799 | ||
| 1800 | 1800 | buffer = (UINT8*)malloc(data_count); |
| 1801 | ||
| 1801 | ||
| 1802 | 1802 | floppy_drive_read_track_data_info_buffer( current_floppy, w->register_w[DESIRED_HEAD]&0x0f, (char *)buffer, &data_count); |
| 1803 | 1803 | sync_status_in(device); |
| 1804 | ||
| 1804 | ||
| 1805 | 1805 | /* Transfer the buffer to the external memory. We assume the memory |
| 1806 | pointer has been set appropriately in the registers. */ | |
| 1807 | set_dma_address(device, DMA23_16, DMA15_8, DMA7_0); | |
| 1806 | pointer has been set appropriately in the registers. */ | |
| 1807 | set_dma_address(device, DMA23_16, DMA15_8, DMA7_0); | |
| 1808 | 1808 | |
| 1809 | 1809 | if (transfer_only_ids) |
| 1810 | 1810 | { |
| r8044 | r8045 | |
| 1817 | 1817 | (*w->intf->dma_write_callback)(buffer[i]); |
| 1818 | 1818 | } |
| 1819 | 1819 | smc92x4_set_dip(device, FALSE); |
| 1820 | ||
| 1821 | free(buffer); | |
| 1820 | ||
| 1821 | free(buffer); | |
| 1822 | 1822 | } |
| 1823 | 1823 | |
| 1824 | 1824 | static void read_harddisk_track(running_device *device, int transfer_only_ids) |
| r8044 | r8045 | |
| 1826 | 1826 | smc92x4_state *w = get_safe_token(device); |
| 1827 | 1827 | |
| 1828 | 1828 | /* Determine the track size. We cannot allow different sizes in this |
| 1829 | ||
| 1829 | design. */ | |
| 1830 | 1830 | int i; |
| 1831 | 1831 | UINT8 *buffer; |
| 1832 | 1832 | int data_count=0; |
| 1833 | 1833 | |
| 1834 | 1834 | sync_latches_out(device); |
| 1835 | ||
| 1836 | /* buffer and data_count are allocated and set by the function. */ | |
| 1835 | ||
| 1836 | /* buffer and data_count are allocated and set by the function. */ | |
| 1837 | 1837 | (*w->intf->mfmhd_read_track)(w->register_w[DESIRED_HEAD]&0x0f, &buffer, &data_count); |
| 1838 | 1838 | sync_status_in(device); |
| 1839 | 1839 | |
| 1840 | 1840 | /* Transfer the buffer to the external memory. We assume the memory |
| 1841 | pointer has been set appropriately in the registers. */ | |
| 1842 | set_dma_address(device, DMA23_16, DMA15_8, DMA7_0); | |
| 1841 | pointer has been set appropriately in the registers. */ | |
| 1842 | set_dma_address(device, DMA23_16, DMA15_8, DMA7_0); | |
| 1843 | 1843 | |
| 1844 | 1844 | if (transfer_only_ids) |
| 1845 | 1845 | { |
| r8044 | r8045 | |
| 1852 | 1852 | (*w->intf->dma_write_callback)(buffer[i]); |
| 1853 | 1853 | } |
| 1854 | 1854 | smc92x4_set_dip(device, FALSE); |
| 1855 | ||
| 1856 | free(buffer); | |
| 1855 | ||
| 1856 | free(buffer); | |
| 1857 | 1857 | } |
| 1858 | 1858 | |
| 1859 | 1859 | |
| r8044 | r8045 | |
| 1861 | 1861 | { |
| 1862 | 1862 | smc92x4_state *w = get_safe_token(device); |
| 1863 | 1863 | int transfer_only_ids = w->command & 0x01; |
| 1864 | ||
| 1864 | ||
| 1865 | 1865 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 1866 | 1866 | { |
| 1867 | 1867 | read_floppy_track(device, transfer_only_ids); |
| r8044 | r8045 | |
| 1870 | 1870 | { |
| 1871 | 1871 | read_harddisk_track(device, transfer_only_ids); |
| 1872 | 1872 | } |
| 1873 | ||
| 1873 | ||
| 1874 | 1874 | smc92x4_timed_track_request(device); |
| 1875 | 1875 | } |
| 1876 | 1876 | |
| r8044 | r8045 | |
| 1885 | 1885 | { |
| 1886 | 1886 | smc92x4_state *w = get_safe_token(device); |
| 1887 | 1887 | int flags = w->command & 0x1f; |
| 1888 | ||
| 1888 | ||
| 1889 | 1889 | if (w->selected_drive_type & TYPE_FLOPPY) |
| 1890 | 1890 | format_floppy_track(device, flags); |
| 1891 | 1891 | else |
| r8044 | r8045 | |
| 1898 | 1898 | { |
| 1899 | 1899 | smc92x4_state *w = get_safe_token(device); |
| 1900 | 1900 | w->to_be_continued = FALSE; |
| 1901 | set_command_done(device, ST_TC_SUCCESS); | |
| 1901 | set_command_done(device, ST_TC_SUCCESS); | |
| 1902 | 1902 | } |
| 1903 | 1903 | |
| 1904 | 1904 | /* |
| 1905 | ||
| 1905 | Continue to process after callback | |
| 1906 | 1906 | */ |
| 1907 | 1907 | static void smc92x4_process_after_callback(running_device *device) |
| 1908 | 1908 | { |
| r8044 | r8045 | |
| 1921 | 1921 | seek_read_id_continue(device); |
| 1922 | 1922 | } |
| 1923 | 1923 | else if ((opcode >= 0x58 && opcode <= 0x59)||(opcode >= 0x5C && opcode <= 0x5f)) |
| 1924 | { | |
| 1924 | { | |
| 1925 | 1925 | read_sectors_continue(device); |
| 1926 | } | |
| 1926 | } | |
| 1927 | 1927 | else if (opcode >= 0x5a && opcode <= 0x5b) |
| 1928 | { | |
| 1928 | { | |
| 1929 | 1929 | read_track_continue(device); |
| 1930 | } | |
| 1930 | } | |
| 1931 | 1931 | else if (opcode >= 0x60 && opcode <= 0x7f) |
| 1932 | 1932 | { |
| 1933 | 1933 | format_track_continue(device); |
| 1934 | 1934 | } |
| 1935 | else if (opcode >= 0x80) | |
| 1935 | else if (opcode >= 0x80) | |
| 1936 | 1936 | { |
| 1937 | 1937 | write_sectors_continue(device); |
| 1938 | 1938 | } |
| r8044 | r8045 | |
| 1948 | 1948 | static void smc92x4_process_command(running_device *device, UINT8 opcode) |
| 1949 | 1949 | { |
| 1950 | 1950 | smc92x4_state *w = get_safe_token(device); |
| 1951 | ||
| 1951 | ||
| 1952 | 1952 | //logerror("smc92x4 process command %02x\n", opcode); |
| 1953 | 1953 | if (w->to_be_continued) |
| 1954 | 1954 | { |
| r8044 | r8045 | |
| 1959 | 1959 | w->register_r[INT_STATUS] &= ~(ST_DONE | ST_BADSECT); |
| 1960 | 1960 | |
| 1961 | 1961 | /* Reset interrupt line (not explicitly mentioned in spec, but seems |
| 1962 | ||
| 1962 | reasonable) */ | |
| 1963 | 1963 | smc92x4_clear_interrupt(device); |
| 1964 | 1964 | w->register_r[INT_STATUS] &= ~(ST_INTPEND | ST_RDYCHNG); |
| 1965 | ||
| 1965 | ||
| 1966 | 1966 | w->command = opcode; |
| 1967 | 1967 | w->found_id = FALSE; |
| 1968 | 1968 | w->seek_count = 0; |
| 1969 | ||
| 1969 | ||
| 1970 | 1970 | if (opcode == 0x00) |
| 1971 | 1971 | { |
| 1972 | 1972 | /* RESET */ |
| r8044 | r8045 | |
| 1989 | 1989 | { |
| 1990 | 1990 | /* RESTORE DRIVE */ |
| 1991 | 1991 | /* bit 0: 0 -> command ends after last seek pulse, 1 -> command |
| 1992 | ||
| 1992 | ends when the drive asserts the seek complete pin */ | |
| 1993 | 1993 | logerror("smc92x4 restore command %X\n", opcode); |
| 1994 | 1994 | restore_drive(device); |
| 1995 | 1995 | } |
| r8044 | r8045 | |
| 2021 | 2021 | /* SETREGPTR */ |
| 2022 | 2022 | logerror("smc92x4 setregptr command %X\n", opcode); |
| 2023 | 2023 | w->register_pointer = opcode & 0xf; |
| 2024 | /* Spec does not say anything about the effect of setting an | |
| 2025 | invalid value (only "care should be taken") */ | |
| 2024 | /* Spec does not say anything about the effect of setting an | |
| 2025 | invalid value (only "care should be taken") */ | |
| 2026 | 2026 | if (w->register_pointer > 10) |
| 2027 | 2027 | { |
| 2028 | 2028 | logerror("smc92x4 error: set register pointer: Invalid register number: %d. Setting to 10.\n", w->register_pointer); |
| r8044 | r8045 | |
| 2038 | 2038 | else if ((opcode >= 0x58 && opcode <= 0x59) |
| 2039 | 2039 | || (opcode >= 0x5C && opcode <= 0x5f) |
| 2040 | 2040 | || (opcode >= 0x80)) |
| 2041 | { | |
| 2041 | { | |
| 2042 | 2042 | /* READ/WRITE SECTORS PHYSICAL/LOGICAL */ |
| 2043 | 2043 | logerror("smc92x4 read/write sector command %X\n", opcode); |
| 2044 | 2044 | read_write_sectors(device); |
| 2045 | } | |
| 2045 | } | |
| 2046 | 2046 | else if (opcode >= 0x5A && opcode <= 0x5b) |
| 2047 | { | |
| 2047 | { | |
| 2048 | 2048 | /* READ TRACK */ |
| 2049 | 2049 | logerror("smc92x4 read track command %X\n", opcode); |
| 2050 | 2050 | read_track(device); |
| 2051 | } | |
| 2051 | } | |
| 2052 | 2052 | else if (opcode >= 0x60 && opcode <= 0x7f) |
| 2053 | 2053 | { |
| 2054 | 2054 | /* FORMAT TRACK */ |
| r8044 | r8045 | |
| 2059 | 2059 | { |
| 2060 | 2060 | logerror("smc92x4 warn: Invalid command %x, ignored\n", opcode); |
| 2061 | 2061 | } |
| 2062 | ||
| 2063 | if (!w->to_be_continued) | |
| 2062 | ||
| 2063 | if (!w->to_be_continued) | |
| 2064 | 2064 | set_command_done(device); |
| 2065 | 2065 | } |
| 2066 | 2066 | |
| r8044 | r8045 | |
| 2069 | 2069 | ****************************************************************************/ |
| 2070 | 2070 | |
| 2071 | 2071 | /* |
| 2072 | Read a byte of data from a smc92x4 controller | |
| 2073 | The address (offset) encodes the C/D* line (command and /data) | |
| 2072 | Read a byte of data from a smc92x4 controller | |
| 2073 | The address (offset) encodes the C/D* line (command and /data) | |
| 2074 | 2074 | */ |
| 2075 | 2075 | READ8_DEVICE_HANDLER( smc92x4_r ) |
| 2076 | 2076 | { |
| 2077 | 2077 | UINT8 reply = 0; |
| 2078 | 2078 | smc92x4_state *w = get_safe_token(device); |
| 2079 | ||
| 2079 | ||
| 2080 | 2080 | if ((offset & 1) == 0) |
| 2081 | 2081 | { |
| 2082 | 2082 | /* data register */ |
| r8044 | r8045 | |
| 2084 | 2084 | // printf("smc92x4 register_r[%d] -> %02x\n", w->register_pointer, reply); |
| 2085 | 2085 | |
| 2086 | 2086 | /* Autoincrement until DATA is reached. */ |
| 2087 | if (w->register_pointer < DATA) | |
| 2087 | if (w->register_pointer < DATA) | |
| 2088 | 2088 | w->register_pointer++; |
| 2089 | 2089 | } |
| 2090 | 2090 | else |
| 2091 | 2091 | { |
| 2092 | 2092 | /* status register */ |
| 2093 | 2093 | reply = w->register_r[INT_STATUS]; |
| 2094 | /* Spec (p.3) : The interrupt pin is reset to its inactive state | |
| 2095 | when the UDC interrupt status register is read. */ | |
| 2094 | /* Spec (p.3) : The interrupt pin is reset to its inactive state | |
| 2095 | when the UDC interrupt status register is read. */ | |
| 2096 | 2096 | // printf("smc92x4 interrupt status read = %02x\n", reply); |
| 2097 | 2097 | smc92x4_clear_interrupt(device); |
| 2098 | 2098 | /* Clear the bits due to int status register read. */ |
| r8044 | r8045 | |
| 2102 | 2102 | } |
| 2103 | 2103 | |
| 2104 | 2104 | /* |
| 2105 | Write a byte to a smc99x4 controller | |
| 2106 | The address (offset) encodes the C/D* line (command and /data) | |
| 2105 | Write a byte to a smc99x4 controller | |
| 2106 | The address (offset) encodes the C/D* line (command and /data) | |
| 2107 | 2107 | */ |
| 2108 | 2108 | WRITE8_DEVICE_HANDLER( smc92x4_w ) |
| 2109 | 2109 | { |
| r8044 | r8045 | |
| 2116 | 2116 | // printf("smc92x4 register_w[%d] <- %X\n", w->register_pointer, data); |
| 2117 | 2117 | w->register_w[w->register_pointer] = data; |
| 2118 | 2118 | |
| 2119 | /* The DMA registers and the sector register for read and | |
| 2120 | write are identical. */ | |
| 2121 | if (w->register_pointer < DESIRED_HEAD) | |
| 2119 | /* The DMA registers and the sector register for read and | |
| 2120 | write are identical. */ | |
| 2121 | if (w->register_pointer < DESIRED_HEAD) | |
| 2122 | 2122 | w->register_r[w->register_pointer] = data; |
| 2123 | ||
| 2123 | ||
| 2124 | 2124 | /* Autoincrement until DATA is reached. */ |
| 2125 | if (w->register_pointer < DATA) | |
| 2126 | w->register_pointer++; | |
| 2125 | if (w->register_pointer < DATA) | |
| 2126 | w->register_pointer++; | |
| 2127 | 2127 | } |
| 2128 | 2128 | else |
| 2129 | 2129 | { |
| r8044 | r8045 | |
| 2142 | 2142 | { |
| 2143 | 2143 | smc92x4_state *w = get_safe_token(device); |
| 2144 | 2144 | assert(device->baseconfig().static_config != NULL); |
| 2145 | ||
| 2145 | ||
| 2146 | 2146 | w->intf = (const smc92x4_interface*)device->baseconfig().static_config; |
| 2147 | 2147 | devcb_resolve_write_line(&w->out_intrq_func, &w->intf->out_intrq_func, device); |
| 2148 | 2148 | devcb_resolve_write_line(&w->out_dip_func, &w->intf->out_dip_func, device); |
| 2149 | 2149 | devcb_resolve_write8(&w->out_auxbus_func, &w->intf->out_auxbus_func, device); |
| 2150 | 2150 | devcb_resolve_read_line(&w->in_auxbus_func, &w->intf->in_auxbus_func, device); |
| 2151 | ||
| 2151 | ||
| 2152 | 2152 | /* allocate timers */ |
| 2153 | 2153 | /* |
| 2154 | ||
| 2154 | w->timer_data = timer_alloc(device->machine, smc92x4_data_callback, (void *)device); */ | |
| 2155 | 2155 | w->timer_rs = timer_alloc(device->machine, smc92x4_read_sector_callback, (void *)device); |
| 2156 | 2156 | w->timer_ws = timer_alloc(device->machine, smc92x4_write_sector_callback, (void *)device); |
| 2157 | 2157 | w->timer_track = timer_alloc(device->machine, smc92x4_track_callback, (void *)device); |
| 2158 | 2158 | w->timer_seek = timer_alloc(device->machine, smc92x4_seek_callback, (void *)device); |
| 2159 | ||
| 2159 | ||
| 2160 | 2160 | w->use_real_timing = TRUE; |
| 2161 | 2161 | } |
| 2162 | 2162 | |
| r8044 | r8045 | |
| 2165 | 2165 | smc92x4_state *w = get_safe_token(device); |
| 2166 | 2166 | smc92x4_clear_interrupt(device); |
| 2167 | 2167 | smc92x4_set_dip(device, FALSE); |
| 2168 | ||
| 2169 | for (int i=0; i<11; i++) | |
| 2168 | ||
| 2169 | for (int i=0; i<11; i++) | |
| 2170 | 2170 | w->register_r[i] = w->register_w[i] = 0; |
| 2171 | 2171 | } |
| 2172 | 2172 | |
| r8044 | r8045 | |
| 2178 | 2178 | void smc92x4_set_timing(running_device *device, int realistic) |
| 2179 | 2179 | { |
| 2180 | 2180 | smc92x4_state *w = get_safe_token(device); |
| 2181 | w->use_real_timing = realistic; | |
| 2181 | w->use_real_timing = realistic; | |
| 2182 | 2182 | } |
| 2183 | 2183 | |
| 2184 | 2184 | /*************************************************************************** |
| r8044 | r8045 | |
|---|---|---|
| 427 | 427 | { |
| 428 | 428 | if (gfxparm != 0) |
| 429 | 429 | TMS9928A_configure(gfxparm); |
| 430 | ||
| 430 | ||
| 431 | 431 | /* Initialize all. Actually, at this point, we don't know |
| 432 | 432 | how the switches are set. Later we use the configuration switches to |
| 433 | 433 | determine which one to use. */ |
| r8044 | r8045 | |
| 436 | 436 | ti99_ide_init(machine); |
| 437 | 437 | ti99_hsgpl_init(machine); |
| 438 | 438 | ti99_usbsm_init(machine); |
| 439 | ||
| 439 | ||
| 440 | 440 | /* Find the cartslot device and cache it. This is a string search, |
| 441 | ||
| 441 | and we don't want to repeat it on each memory access. */ | |
| 442 | 442 | cartslots = devtag_get_device(machine, "ti99_multicart"); |
| 443 | 443 | assert(cartslots != NULL); |
| 444 | 444 | } |
| r8044 | r8045 | |
| 505 | 505 | xRAM_kind = RAM_99_4P; |
| 506 | 506 | else |
| 507 | 507 | xRAM_kind = input_port_read(machine, "RAM"); |
| 508 | ||
| 508 | ||
| 509 | 509 | if (ti99_model == model_99_8) |
| 510 | 510 | has_speech = TRUE; |
| 511 | 511 | else |
| 512 | 512 | has_speech = input_port_read(machine, "SPEECH"); |
| 513 | ||
| 513 | ||
| 514 | 514 | has_ide = input_port_read(machine, "HDCTRL") & HD_IDE; |
| 515 | 515 | has_rs232 = input_port_read(machine, "SERIAL") & SERIAL_TI; |
| 516 | 516 | |
| r8044 | r8045 | |
| 518 | 518 | has_handset = input_port_read(machine, "HCI") & HCI_IR; |
| 519 | 519 | else |
| 520 | 520 | has_handset = FALSE; |
| 521 | ||
| 521 | ||
| 522 | 522 | if (ti99_model == model_99_4p) |
| 523 | 523 | has_hsgpl = TRUE; |
| 524 | 524 | else |
| r8044 | r8045 | |
| 894 | 894 | if (! tms5220_readyq_r()) |
| 895 | 895 | { |
| 896 | 896 | /* Weirdly enough, we are always seeing some problems even though |
| 897 | ||
| 897 | everything is working fine. */ | |
| 898 | 898 | attotime time_to_ready = double_to_attotime(tms5220_time_to_ready()); |
| 899 | 899 | logerror("ti99/4a speech says aaargh!\n"); |
| 900 | 900 | logerror("(time to ready: %f -> %d)\n", time_to_ready, (int) ceil(3000000*time_to_ready)); |
| r8044 | r8045 | |
| 909 | 909 | static WRITE16_HANDLER ( ti99_wspeech_w ) |
| 910 | 910 | { |
| 911 | 911 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-(54+3)); /* this is just an approx. minimum, it can be much more */ |
| 912 | ||
| 912 | ||
| 913 | 913 | #if 1 |
| 914 | 914 | /* the stupid design of the tms5220 core means that ready is cleared when |
| 915 | there are 15 bytes in FIFO. It should be 16. Of course, if it were the | |
| 916 | case, we would need to store the value on the bus, which would be more | |
| 917 | complex. */ | |
| 915 | there are 15 bytes in FIFO. It should be 16. Of course, if it were the | |
| 916 | case, we would need to store the value on the bus, which would be more | |
| 917 | complex. */ | |
| 918 | 918 | if (! tms5220_readyq_r(devtag_get_device(space->machine, "tms5220"))) |
| 919 | 919 | { |
| 920 | 920 | attotime time_to_ready = double_to_attotime(tms5220_time_to_ready(devtag_get_device(space->machine, "tms5220"))); |
| 921 | 921 | int cycles_to_ready = cputag_attotime_to_clocks(space->machine, "maincpu", time_to_ready); |
| 922 | ||
| 922 | ||
| 923 | 923 | logerror("time to ready: %f -> %d\n", attotime_to_double(time_to_ready), (int) cycles_to_ready); |
| 924 | ||
| 924 | ||
| 925 | 925 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-cycles_to_ready); |
| 926 | 926 | timer_set(space->machine, attotime_zero, NULL, 0, /*speech_kludge_callback*/NULL); |
| 927 | 927 | } |
| 928 | 928 | #endif |
| 929 | ||
| 929 | ||
| 930 | 930 | tms5220_data_w(devtag_get_device(space->machine, "tms5220"), offset, (data >> 8) & 0xff); |
| 931 | 931 | } |
| 932 | 932 | |
| r8044 | r8045 | |
| 934 | 934 | { |
| 935 | 935 | UINT8 reply = 0, replycart; |
| 936 | 936 | int override_console = FALSE; /* for future extension */ |
| 937 | ||
| 937 | ||
| 938 | 938 | if (console_GROMs.addr < 0x6000) |
| 939 | 939 | { |
| 940 | 940 | /* GROMs are buffered. Data is retrieved from a buffer, |
| 941 | while the buffer is replaced with the next cell | |
| 942 | content. */ | |
| 941 | while the buffer is replaced with the next cell | |
| 942 | content. */ | |
| 943 | 943 | reply = console_GROMs.buf; |
| 944 | ||
| 944 | ||
| 945 | 945 | /* Get next value, put it in buffer. Note that the |
| 946 | ||
| 946 | GROM wraps at 8K boundaries. */ | |
| 947 | 947 | console_GROMs.buf = console_GROMs.data_ptr[console_GROMs.addr]; |
| 948 | // | |
| 948 | // printf("GROM address (cons) = %04x, offset = %04x, reply = %02x\n", console_GROMs.addr, offset, reply); | |
| 949 | 949 | } |
| 950 | 950 | |
| 951 | 951 | /* The address pointer in the cartridge system is updated by this call. |
| 952 | We pretend to do a data read, so we mask away the address bit in the | |
| 953 | offset. */ | |
| 952 | We pretend to do a data read, so we mask away the address bit in the | |
| 953 | offset. */ | |
| 954 | 954 | replycart = ti99_cartridge_grom_r(cartslots, offset&0xfffc); |
| 955 | ||
| 955 | ||
| 956 | 956 | if (console_GROMs.addr >= 0x6000 || override_console) |
| 957 | 957 | { |
| 958 | 958 | reply = replycart; |
| 959 | 959 | } |
| 960 | 960 | |
| 961 | /* Each GROM chip has its own counter, so we update all of them even | |
| 962 | when we do not access them. */ | |
| 961 | /* Each GROM chip has its own counter, so we update all of them even | |
| 962 | when we do not access them. */ | |
| 963 | 963 | /* The program counter wraps at each GROM chip size (8K), |
| 964 | ||
| 964 | so 0x5fff + 1 = 0x4000. */ | |
| 965 | 965 | console_GROMs.addr = ((console_GROMs.addr + 1) & 0x1FFF) | (console_GROMs.addr & 0xE000); |
| 966 | ||
| 966 | ||
| 967 | 967 | /* Reset the read and write address flipflops. */ |
| 968 | 968 | console_GROMs.raddr_LSB = console_GROMs.waddr_LSB = FALSE; |
| 969 | ||
| 969 | ||
| 970 | 970 | return reply; |
| 971 | 971 | } |
| 972 | 972 | |
| r8044 | r8045 | |
| 976 | 976 | READ16_HANDLER ( ti99_grom_r ) |
| 977 | 977 | { |
| 978 | 978 | UINT16 reply, replycart; |
| 979 | ||
| 979 | ||
| 980 | 980 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-4 /*20+3*/); /* from 4 to 23? */ |
| 981 | 981 | // cpu_spinuntil_time(space->machine->firstcpu, ATTOTIME_IN_USEC(6)); |
| 982 | ||
| 982 | ||
| 983 | 983 | /* This implementation features a multislot cartridge system which |
| 984 | is based on multiple GROM base addresses. The standard base | |
| 985 | is >9800 (slot 0). When we access the port >9804, we switch to | |
| 986 | slot 1, >9808 is slot 2, ... >983C is slot 15. Although theoretically | |
| 987 | we could address up to 256 banks, the TI operating system does not | |
| 988 | check more than 16 banks. | |
| 989 | Cartridges may also contain ROMs which need to be banked | |
| 990 | simultaneously. We use the cartridge slot number to swap the ROM at | |
| 991 | >6000, or RAM if available. I don't know whether this is the way | |
| 992 | Texas Instruments envisaged it in the OS, but it is the only | |
| 993 | plausible way to allow for GROM+ROM cartridges. | |
| 994 | Note that some cartridges may have programming flaws which only | |
| 995 | appear when the cartridge is used in a higher-numbered slot. | |
| 996 | Parsec is one example which only runs in slot 0 as the | |
| 997 | programmers hard-coded an access to GROM port 0. Note: This *may* | |
| 998 | be worked around if we make sure that switching only occurs | |
| 999 | when the address is set, not when data is read or written. But | |
| 1000 | it's not clear whether this has unwanted side effects. | |
| 1001 | */ | |
| 1002 | ||
| 984 | is based on multiple GROM base addresses. The standard base | |
| 985 | is >9800 (slot 0). When we access the port >9804, we switch to | |
| 986 | slot 1, >9808 is slot 2, ... >983C is slot 15. Although theoretically | |
| 987 | we could address up to 256 banks, the TI operating system does not | |
| 988 | check more than 16 banks. | |
| 989 | Cartridges may also contain ROMs which need to be banked | |
| 990 | simultaneously. We use the cartridge slot number to swap the ROM at | |
| 991 | >6000, or RAM if available. I don't know whether this is the way | |
| 992 | Texas Instruments envisaged it in the OS, but it is the only | |
| 993 | plausible way to allow for GROM+ROM cartridges. | |
| 994 | Note that some cartridges may have programming flaws which only | |
| 995 | appear when the cartridge is used in a higher-numbered slot. | |
| 996 | Parsec is one example which only runs in slot 0 as the | |
| 997 | programmers hard-coded an access to GROM port 0. Note: This *may* | |
| 998 | be worked around if we make sure that switching only occurs | |
| 999 | when the address is set, not when data is read or written. But | |
| 1000 | it's not clear whether this has unwanted side effects. | |
| 1001 | */ | |
| 1002 | ||
| 1003 | 1003 | if (offset & 1) |
| 1004 | 1004 | { /* Read GROM address |
| 1005 | We only have one GROM program counter for the console GROMs | |
| 1006 | and all cartridge GROMs in all banks(!). Hardware | |
| 1007 | implementations must take this into account as well. Thus, | |
| 1008 | we use a structure here in the console, rather than separate | |
| 1009 | counters in each GROM chip. */ | |
| 1005 | We only have one GROM program counter for the console GROMs | |
| 1006 | and all cartridge GROMs in all banks(!). Hardware | |
| 1007 | implementations must take this into account as well. Thus, | |
| 1008 | we use a structure here in the console, rather than separate | |
| 1009 | counters in each GROM chip. */ | |
| 1010 | 1010 | |
| 1011 | 1011 | /* We call the cartridge system here, but we ignore the |
| 1012 | ||
| 1012 | value. This is done to sync the flags. */ | |
| 1013 | 1013 | replycart = ti99_cartridge_grom_r(cartslots, (offset<<1))<<8; |
| 1014 | ||
| 1014 | ||
| 1015 | 1015 | /* When reading, reset the hi/lo flag byte for writing. |
| 1016 | ||
| 1016 | TODO: Verify this with a real machine. */ | |
| 1017 | 1017 | console_GROMs.waddr_LSB = FALSE; |
| 1018 | ||
| 1018 | ||
| 1019 | 1019 | /* Address reading is done in two steps; first, the high byte |
| 1020 | ||
| 1020 | is transferred, then the low byte. */ | |
| 1021 | 1021 | if (console_GROMs.raddr_LSB) |
| 1022 | 1022 | { |
| 1023 | 1023 | /* second pass */ |
| r8044 | r8045 | |
| 1037 | 1037 | { |
| 1038 | 1038 | /* Read GROM data */ |
| 1039 | 1039 | /* Note that we shift the GROM port address to accomodate for |
| 1040 | ||
| 1040 | 8-bit and 16-bit systems. */ | |
| 1041 | 1041 | reply = ((UINT16)GROM_dataread(offset<<1)) << 8; |
| 1042 | 1042 | } |
| 1043 | ||
| 1043 | ||
| 1044 | 1044 | if (hsgpl_crdena) |
| 1045 | 1045 | /* hsgpl buffers are stronger than console GROM buffers */ |
| 1046 | 1046 | reply = ti99_hsgpl_gpl_r(space, offset, mem_mask); |
| 1047 | ||
| 1047 | ||
| 1048 | 1048 | return reply; |
| 1049 | 1049 | } |
| 1050 | 1050 | |
| 1051 | 1051 | /* |
| 1052 | ||
| 1052 | GPL write | |
| 1053 | 1053 | */ |
| 1054 | 1054 | WRITE16_HANDLER ( ti99_grom_w ) |
| 1055 | 1055 | { |
| 1056 | 1056 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-4/*20+3*/); /* from 4 to 23? */ |
| 1057 | 1057 | // cpu_spinuntil_time(space->machine->firstcpu, ATTOTIME_IN_USEC(6)); |
| 1058 | ||
| 1058 | ||
| 1059 | 1059 | if (offset & 1) |
| 1060 | 1060 | { |
| 1061 | 1061 | ti99_cartridge_grom_w(cartslots, (offset<<1), (data>>8)&0xff); |
| r8044 | r8045 | |
| 1063 | 1063 | /* write GROM address */ |
| 1064 | 1064 | /* see comments above */ |
| 1065 | 1065 | console_GROMs.raddr_LSB = FALSE; |
| 1066 | ||
| 1066 | ||
| 1067 | 1067 | /* Implements the internal flipflop. |
| 1068 | The Editor/Assembler manuals says that the current address | |
| 1069 | plus one is returned. This effect is properly emulated | |
| 1070 | as we are using a read-ahead buffer. | |
| 1071 | */ | |
| 1068 | The Editor/Assembler manuals says that the current address | |
| 1069 | plus one is returned. This effect is properly emulated | |
| 1070 | as we are using a read-ahead buffer. | |
| 1071 | */ | |
| 1072 | 1072 | if (console_GROMs.waddr_LSB) |
| 1073 | 1073 | { |
| 1074 | 1074 | /* Accept low byte (2nd write) */ |
| 1075 | 1075 | console_GROMs.addr = (console_GROMs.addr & 0xFF00) | ((data >> 8) & 0xFF); |
| 1076 | ||
| 1076 | ||
| 1077 | 1077 | /* Setting the address causes a new read, putting the |
| 1078 | ||
| 1078 | value into the buffer. We don't need the value here. */ | |
| 1079 | 1079 | GROM_dataread(offset<<1); |
| 1080 | 1080 | console_GROMs.waddr_LSB = FALSE; |
| 1081 | 1081 | } |
| r8044 | r8045 | |
| 1091 | 1091 | /* write GROM data */ |
| 1092 | 1092 | /* the console GROMs are always affected */ |
| 1093 | 1093 | /* BTW, console GROMs are never GRAMs, therefore there is no |
| 1094 | need to actually write anything, so we just read ahead | |
| 1095 | TODO: There could be cartridges with GRAM, so this must be | |
| 1096 | fixed. | |
| 1097 | */ | |
| 1094 | need to actually write anything, so we just read ahead | |
| 1095 | TODO: There could be cartridges with GRAM, so this must be | |
| 1096 | fixed. | |
| 1097 | */ | |
| 1098 | 1098 | GROM_dataread(offset<<1); |
| 1099 | 1099 | console_GROMs.raddr_LSB = console_GROMs.waddr_LSB = FALSE; |
| 1100 | 1100 | } |
| 1101 | ||
| 1101 | ||
| 1102 | 1102 | if (hsgpl_crdena) |
| 1103 | 1103 | ti99_hsgpl_gpl_w(space, offset, data, mem_mask); |
| 1104 | 1104 | } |
| r8044 | r8045 | |
| 1178 | 1178 | { |
| 1179 | 1179 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-4); /* HSGPL is located on 8-bit bus? */ |
| 1180 | 1180 | // cpu_spinuntil_time(space->machine->firstcpu, ATTOTIME_IN_USEC(6)); |
| 1181 | ||
| 1181 | ||
| 1182 | 1182 | return /*hsgpl_crdena ?*/ ti99_hsgpl_gpl_r(space, offset, mem_mask) /*: 0*/; |
| 1183 | 1183 | } |
| 1184 | 1184 | |
| r8044 | r8045 | |
| 1189 | 1189 | { |
| 1190 | 1190 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-4); /* HSGPL is located on 8-bit bus? */ |
| 1191 | 1191 | // cpu_spinuntil_time(space->machine->firstcpu, ATTOTIME_IN_USEC(6)); |
| 1192 | ||
| 1192 | ||
| 1193 | 1193 | /*if (hsgpl_crdena)*/ |
| 1194 | 1194 | ti99_hsgpl_gpl_w(space, offset, data, mem_mask); |
| 1195 | 1195 | } |
| r8044 | r8045 | |
| 1206 | 1206 | int page = offset >> 12; |
| 1207 | 1207 | UINT32 mapper_reg; |
| 1208 | 1208 | UINT8 reply = 0; |
| 1209 | ||
| 1209 | ||
| 1210 | 1210 | if (ti99_8_enable_rom_and_ports) |
| 1211 | 1211 | { |
| 1212 | 1212 | /* This is only important for address access 0000-1fff and |
| 1213 | ||
| 1213 | 8000-9fff. Outside, the mapper mode is used. */ | |
| 1214 | 1214 | if ((offset >= 0x0000) && (offset < 0x2000)) |
| 1215 | 1215 | { |
| 1216 | 1216 | /* ROM */ |
| r8044 | r8045 | |
| 1227 | 1227 | /* RAM: >8000 - >83ff */ |
| 1228 | 1228 | reply = sRAM_ptr_8[offset & 0x1fff]; |
| 1229 | 1229 | break; |
| 1230 | ||
| 1230 | ||
| 1231 | 1231 | case 1: |
| 1232 | 1232 | /* >8400 - >840f: sound (cannot read) |
| 1233 | ||
| 1233 | >8410 - >87ff: SRAM */ | |
| 1234 | 1234 | if (offset >= 0x8410) |
| 1235 | 1235 | reply = sRAM_ptr_8[offset & 0x1fff]; |
| 1236 | 1236 | break; |
| 1237 | ||
| 1237 | ||
| 1238 | 1238 | case 2: |
| 1239 | 1239 | /* VDP read + mapper status */ |
| 1240 | 1240 | if (offset < 0x8810) |
| r8044 | r8045 | |
| 1256 | 1256 | ti99_8_mapper_status = 0; |
| 1257 | 1257 | } |
| 1258 | 1258 | break; |
| 1259 | ||
| 1259 | ||
| 1260 | 1260 | case 4: |
| 1261 | 1261 | /* speech read: >9000 */ |
| 1262 | 1262 | if (! (offset & 1)) |
| r8044 | r8045 | |
| 1265 | 1265 | reply = tms5220_status_r(devtag_get_device(space->machine, "tms5220"), 0); |
| 1266 | 1266 | } |
| 1267 | 1267 | break; |
| 1268 | ||
| 1268 | ||
| 1269 | 1269 | case 6: |
| 1270 | 1270 | /* GROM read: >9800 */ |
| 1271 | 1271 | if (! (offset & 1)) |
| 1272 | 1272 | reply = ti99_grom_r8(space, offset); |
| 1273 | 1273 | break; |
| 1274 | ||
| 1274 | ||
| 1275 | 1275 | default: |
| 1276 | 1276 | logerror("unmapped read offs=%d\n", (int) offset); |
| 1277 | 1277 | break; |
| r8044 | r8045 | |
| 1279 | 1279 | return reply; |
| 1280 | 1280 | } |
| 1281 | 1281 | } |
| 1282 | ||
| 1282 | ||
| 1283 | 1283 | mapper_reg = ti99_8_mapper_regs[page]; |
| 1284 | 1284 | offset = (mapper_reg + (offset & 0x0fff)) & 0x00ffffff; |
| 1285 | ||
| 1285 | ||
| 1286 | 1286 | #if 0 |
| 1287 | 1287 | /* test read protect */ |
| 1288 | 1288 | if (mapper_reg & 0x20000000) |
| 1289 | 1289 | ; |
| 1290 | ||
| 1290 | ||
| 1291 | 1291 | /* test execute protect */ |
| 1292 | 1292 | if (mapper_reg & 0x40000000) |
| 1293 | 1293 | ; |
| 1294 | 1294 | #endif |
| 1295 | ||
| 1295 | ||
| 1296 | 1296 | if (offset < 0x010000) |
| 1297 | 1297 | /* Read RAM */ |
| 1298 | 1298 | reply = xRAM_ptr_8[offset]; |
| 1299 | ||
| 1299 | ||
| 1300 | 1300 | if (offset >= 0xff0000) |
| 1301 | 1301 | { |
| 1302 | 1302 | switch ((offset >> 13) & 7) |
| r8044 | r8045 | |
| 1313 | 1313 | /* ffe000 - ffffff: ? */ |
| 1314 | 1314 | logerror("unmapped read page=%d offs=%d\n", (int) page, (int) offset); |
| 1315 | 1315 | break; |
| 1316 | ||
| 1316 | ||
| 1317 | 1317 | case 2: |
| 1318 | 1318 | /* ff4000 - ff5fff: DSR space */ |
| 1319 | 1319 | reply = ti99_8_peb_r(space, offset & 0x1fff); |
| 1320 | 1320 | break; |
| 1321 | ||
| 1321 | ||
| 1322 | 1322 | case 3: |
| 1323 | 1323 | /* ff6000 - ff7fff: cartridge ROM space */ |
| 1324 | 1324 | offset &= 0x1fff; |
| 1325 | ||
| 1325 | ||
| 1326 | 1326 | /* We do not support hsgpl here because it is a 16 bit |
| 1327 | ||
| 1327 | system. Just check the cartridges. */ | |
| 1328 | 1328 | reply = ti99_multicart8_r(multicart8, offset); |
| 1329 | 1329 | break; |
| 1330 | ||
| 1330 | ||
| 1331 | 1331 | case 5: |
| 1332 | 1332 | /* ffa000 - ffbfff: >2000 ROM (ROM1) */ |
| 1333 | 1333 | reply = ROM1_ptr_8[offset & 0x1fff]; |
| 1334 | 1334 | break; |
| 1335 | ||
| 1335 | ||
| 1336 | 1336 | case 6: |
| 1337 | 1337 | /* ffc000 - ffdfff: >6000 ROM */ |
| 1338 | 1338 | reply = ROM3_ptr_8[offset & 0x1fff]; |
| 1339 | 1339 | break; |
| 1340 | 1340 | } |
| 1341 | 1341 | } |
| 1342 | ||
| 1342 | ||
| 1343 | 1343 | return reply; |
| 1344 | 1344 | } |
| 1345 | 1345 | |
| r8044 | r8045 | |
| 1423 | 1423 | if (! (offset & 1)) |
| 1424 | 1424 | { |
| 1425 | 1425 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-48*4); /* this is just an approx. minimum, it can be much more */ |
| 1426 | ||
| 1426 | ||
| 1427 | 1427 | /* the stupid design of the tms5220 core means that ready is cleared when |
| 1428 | there are 15 bytes in FIFO. It should be 16. Of course, if it were the | |
| 1429 | case, we would need to store the value on the bus, which would be more | |
| 1430 | complex. */ | |
| 1428 | there are 15 bytes in FIFO. It should be 16. Of course, if it were the | |
| 1429 | case, we would need to store the value on the bus, which would be more | |
| 1430 | complex. */ | |
| 1431 | 1431 | if (! tms5220_readyq_r(devtag_get_device(space->machine, "tms5220"))) |
| 1432 | 1432 | { |
| 1433 | 1433 | attotime time_to_ready = double_to_attotime(tms5220_time_to_ready(devtag_get_device(space->machine, "tms5220"))); |
| 1434 | 1434 | double d = cputag_attotime_to_clocks(space->machine, "maincpu", time_to_ready); |
| 1435 | 1435 | int cycles_to_ready = ((int) (d + 3)) & ~3; |
| 1436 | ||
| 1436 | ||
| 1437 | 1437 | logerror("time to ready: %f -> %d\n", attotime_to_double(time_to_ready) |
| 1438 | 1438 | , (int) cycles_to_ready); |
| 1439 | ||
| 1439 | ||
| 1440 | 1440 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-cycles_to_ready); |
| 1441 | 1441 | timer_set(space->machine, attotime_zero, NULL, 0, /*speech_kludge_callback*/NULL); |
| 1442 | 1442 | } |
| 1443 | ||
| 1443 | ||
| 1444 | 1444 | tms5220_data_w(devtag_get_device(space->machine, "tms5220"), offset, data); |
| 1445 | 1445 | } |
| 1446 | 1446 | break; |
| 1447 | ||
| 1447 | ||
| 1448 | 1448 | case 7: |
| 1449 | 1449 | /* GPL write */ |
| 1450 | 1450 | if (! (offset & 1)) |
| 1451 | 1451 | ti99_grom_w8(space, offset, data); |
| 1452 | 1452 | break; |
| 1453 | ||
| 1453 | ||
| 1454 | 1454 | default: |
| 1455 | 1455 | logerror("unmapped write offs=%d data=%d\n", (int) offset, (int) data); |
| 1456 | 1456 | break; |
| r8044 | r8045 | |
| 1568 | 1568 | if (handset_buflen == 1) |
| 1569 | 1569 | { |
| 1570 | 1570 | /* Unless I am missing something, the third and last nybble of the |
| 1571 | message is not acknowledged by the DSR in any way, and the first nybble | |
| 1572 | of next message is not requested for either, so we need to decide on | |
| 1573 | our own when we can post a new event. Currently, we wait for 1000us | |
| 1574 | after the DSR acknowledges the second nybble. */ | |
| 1571 | message is not acknowledged by the DSR in any way, and the first nybble | |
| 1572 | of next message is not requested for either, so we need to decide on | |
| 1573 | our own when we can post a new event. Currently, we wait for 1000us | |
| 1574 | after the DSR acknowledges the second nybble. */ | |
| 1575 | 1575 | timer_set(machine, ATTOTIME_IN_USEC(1000), NULL, 0, ti99_handset_ack_callback); |
| 1576 | 1576 | } |
| 1577 | 1577 | |
| r8044 | r8045 | |
| 1634 | 1634 | |
| 1635 | 1635 | /* read current key state */ |
| 1636 | 1636 | key_buf = ( input_port_read(machine, keynames[num]) | (input_port_read(machine, keynames[num + 1]) << 16) ) >> (4*num); |
| 1637 | ||
| 1637 | ||
| 1638 | 1638 | /* If a key was previously pressed, this key was not shift, and this key is |
| 1639 | ||
| 1639 | still down, then don't change the current key press. */ | |
| 1640 | 1640 | if (previous_key[num] && (previous_key[num] != 0x24) |
| 1641 | 1641 | && (key_buf & (1 << (previous_key[num] & 0x1f)))) |
| 1642 | 1642 | { |
| r8044 | r8045 | |
| 1647 | 1647 | else |
| 1648 | 1648 | { |
| 1649 | 1649 | /* the shift modifier state has changed: we need to update the |
| 1650 | ||
| 1650 | keyboard state */ | |
| 1651 | 1651 | if (key_buf & 0x0008) |
| 1652 | 1652 | { /* shift has been pressed down */ |
| 1653 | 1653 | previous_key[num] = current_key = previous_key[num] | 0x20; |
| r8044 | r8045 | |
| 1658 | 1658 | } |
| 1659 | 1659 | /* post message */ |
| 1660 | 1660 | ti99_handset_post_message(machine, (((unsigned) current_key) << 4) | (num << 1)); |
| 1661 | ||
| 1661 | ||
| 1662 | 1662 | return TRUE; |
| 1663 | 1663 | } |
| 1664 | ||
| 1664 | ||
| 1665 | 1665 | } |
| 1666 | ||
| 1666 | ||
| 1667 | 1667 | current_key = 0; /* default value if no key is down */ |
| 1668 | 1668 | for (i=0; i<20; i++) |
| 1669 | 1669 | { |
| r8044 | r8045 | |
| 1675 | 1675 | |
| 1676 | 1676 | if (current_key != 0x24) |
| 1677 | 1677 | /* If this is the shift key, any other key we may find will |
| 1678 | have higher priority; otherwise, we may exit the loop and keep | |
| 1679 | the key we have just found. */ | |
| 1678 | have higher priority; otherwise, we may exit the loop and keep | |
| 1679 | the key we have just found. */ | |
| 1680 | 1680 | break; |
| 1681 | 1681 | } |
| 1682 | 1682 | } |
| 1683 | ||
| 1683 | ||
| 1684 | 1684 | if (current_key != previous_key[num]) |
| 1685 | 1685 | { |
| 1686 | 1686 | previous_key[num] = current_key; |
| r8044 | r8045 | |
| 1733 | 1733 | |
| 1734 | 1734 | /* set sign */ |
| 1735 | 1735 | /* note that we set the sign if the joystick position is 0 to work |
| 1736 | ||
| 1736 | around a bug in the ti99/4 ROMs */ | |
| 1737 | 1737 | if (current_joy_x <= 0) |
| 1738 | 1738 | { |
| 1739 | 1739 | message |= 0x040; |
| r8044 | r8045 | |
| 1812 | 1812 | static void mecmouse_select(int selnow, int stick1, int stick2) |
| 1813 | 1813 | { |
| 1814 | 1814 | /* The Mechatronic mouse is connected to the joystick port and occupies |
| 1815 | both joystick select lines and the switch lines. From these five | |
| 1816 | lines, left/right/down are used for the motion (i.e. 3 motion steps | |
| 1817 | for positive and four for negative motion and one for rest), | |
| 1818 | the fire line is used for the secondary mouse button, and the up | |
| 1819 | line is used for the primary button. | |
| 1820 | The mouse motion is delivered by the same lines for both directions; | |
| 1821 | this requires swapping the axes. According to the source code of | |
| 1822 | the accompanying mouse driver, the readout of the current axis is | |
| 1823 | done by selecting joystick 1, then joystick 2. The axis swapping is | |
| 1824 | achieved by selecting stick 1 again. When selecting stick 2, the | |
| 1825 | second axis is seen on the input lines. | |
| 1826 | Interrupting this sequence will lead to swapped axes. This is | |
| 1827 | prevented by resetting the toggle when the mouse is deselected | |
| 1828 | (neither 1 nor 2 are selected). | |
| 1829 | ||
| 1830 | The joystick lines are selected as follows: | |
| 1831 | TI-99/4: Stick 1: P4=1, P3=0, P2=1 (5) | |
| 1832 | Stick 2: P4=1, P3=1, P2=0 (6) | |
| 1833 | ||
| 1834 | TI-99/4A: Stick 1: P4=1, P3=1, P2=0 (6) | |
| 1835 | Stick 2: P4=1, P3=1, P2=1 (7) | |
| 1836 | ||
| 1837 | TI-99/8: Stick 1: P3=1, P2=1, P1=1, P0=0 (14) | |
| 1838 | Stick 2: P3=1, P2=1, P1=1, P0=1 (15) | |
| 1839 | ||
| 1840 | Geneve: n/a, has own mouse handling via v9938 | |
| 1841 | ||
| 1842 | As we can only deliver at max 3 steps positive and 4 steps negative, | |
| 1843 | we split the delta so that subsequent queries add up to the actual | |
| 1844 | delta. That is, one delta of +10 yields a 3+3+3+1. | |
| 1845 | ||
| 1846 | mecmouse_x holds the current delta to be counted down for x | |
| 1847 | (y accordingly) | |
| 1848 | ||
| 1849 | mecmouse_x_buf is the current step count reported to CRU | |
| 1850 | ||
| 1851 | Michael Zapf, 2008-01-22 | |
| 1852 | */ | |
| 1815 | both joystick select lines and the switch lines. From these five | |
| 1816 | lines, left/right/down are used for the motion (i.e. 3 motion steps | |
| 1817 | for positive and four for negative motion and one for rest), | |
| 1818 | the fire line is used for the secondary mouse button, and the up | |
| 1819 | line is used for the primary button. | |
| 1820 | The mouse motion is delivered by the same lines for both directions; | |
| 1821 | this requires swapping the axes. According to the source code of | |
| 1822 | the accompanying mouse driver, the readout of the current axis is | |
| 1823 | done by selecting joystick 1, then joystick 2. The axis swapping is | |
| 1824 | achieved by selecting stick 1 again. When selecting stick 2, the | |
| 1825 | second axis is seen on the input lines. | |
| 1826 | Interrupting this sequence will lead to swapped axes. This is | |
| 1827 | prevented by resetting the toggle when the mouse is deselected | |
| 1828 | (neither 1 nor 2 are selected). | |
| 1853 | 1829 | |
| 1830 | The joystick lines are selected as follows: | |
| 1831 | TI-99/4: Stick 1: P4=1, P3=0, P2=1 (5) | |
| 1832 | Stick 2: P4=1, P3=1, P2=0 (6) | |
| 1833 | ||
| 1834 | TI-99/4A: Stick 1: P4=1, P3=1, P2=0 (6) | |
| 1835 | Stick 2: P4=1, P3=1, P2=1 (7) | |
| 1836 | ||
| 1837 | TI-99/8: Stick 1: P3=1, P2=1, P1=1, P0=0 (14) | |
| 1838 | Stick 2: P3=1, P2=1, P1=1, P0=1 (15) | |
| 1839 | ||
| 1840 | Geneve: n/a, has own mouse handling via v9938 | |
| 1841 | ||
| 1842 | As we can only deliver at max 3 steps positive and 4 steps negative, | |
| 1843 | we split the delta so that subsequent queries add up to the actual | |
| 1844 | delta. That is, one delta of +10 yields a 3+3+3+1. | |
| 1845 | ||
| 1846 | mecmouse_x holds the current delta to be counted down for x | |
| 1847 | (y accordingly) | |
| 1848 | ||
| 1849 | mecmouse_x_buf is the current step count reported to CRU | |
| 1850 | ||
| 1851 | Michael Zapf, 2008-01-22 | |
| 1852 | */ | |
| 1853 | ||
| 1854 | 1854 | if (selnow==stick2) { |
| 1855 | 1855 | if (mecmouse_sel==stick1) { |
| 1856 | 1856 | if (! mecmouse_read_y) |
| r8044 | r8045 | |
| 2013 | 2013 | if (intreq) |
| 2014 | 2014 | { |
| 2015 | 2015 | /* On TI99, TMS9900 IC0-3 lines are not connected to TMS9901, |
| 2016 | ||
| 2016 | * but hard-wired to force level 1 interrupts */ | |
| 2017 | 2017 | cputag_set_input_line_and_vector(device->machine, "maincpu", 0, ASSERT_LINE, 1); /* interrupt it, baby */ |
| 2018 | 2018 | } |
| 2019 | 2019 | else |
| r8044 | r8045 | |
| 2562 | 2562 | } |
| 2563 | 2563 | |
| 2564 | 2564 | /* write CRU bit: |
| 2565 | bit0: enable/disable mapper registers in DSR space, | |
| 2566 | bit1: enable/disable address mapping */ | |
| 2565 | bit0: enable/disable mapper registers in DSR space, | |
| 2566 | bit1: enable/disable address mapping */ | |
| 2567 | 2567 | static void sAMS_cru_w(running_machine *machine, int offset, int data) |
| 2568 | 2568 | { |
| 2569 | 2569 | if (offset == 1) |
| r8044 | r8045 | |
| 2587 | 2587 | { |
| 2588 | 2588 | cpu_adjust_icount(devtag_get_device(space->machine, "maincpu"),-4); |
| 2589 | 2589 | // cpu_spinuntil_time(space->machine->firstcpu, ATTOTIME_IN_USEC(6)); |
| 2590 | ||
| 2590 | ||
| 2591 | 2591 | if (sAMS_mapper_on) |
| 2592 | 2592 | return xRAM_ptr[(offset&0x7ff)+sAMSlookup[(0x1000+offset)>>11]]; |
| 2593 | 2593 | else |
| r8044 | r8045 | |
|---|---|---|
| 3 | 3 | #ifndef SMC92X4 |
| 4 | 4 | #define SMC92X4 DEVICE_GET_INFO_NAME(smc92x4) |
| 5 | 5 | |
| 6 | #define INPUT_STATUS | |
| 6 | #define INPUT_STATUS | |
| 7 | 7 | #define OUTPUT_DMA_ADDR 0x01 |
| 8 | #define OUTPUT_OUTPUT1 0x02 | |
| 9 | #define OUTPUT_OUTPUT2 0x03 | |
| 8 | #define OUTPUT_OUTPUT1 0x02 | |
| 9 | #define OUTPUT_OUTPUT2 0x03 | |
| 10 | 10 | |
| 11 | #define MFMHD_TRACK00 | |
| 11 | #define MFMHD_TRACK00 | |
| 12 | 12 | #define MFMHD_SEEKCOMP 0x40 |
| 13 | 13 | #define MFMHD_WRFAULT 0x20 |
| 14 | 14 | #define MFMHD_READY 0x10 |
| 15 | 15 | #define MFMHD_INDEX 0x08 |
| 16 | 16 | |
| 17 | #define BAD_SECTOR | |
| 17 | #define BAD_SECTOR | |
| 18 | 18 | #define BAD_CRC 0x2000 |
| 19 | 19 | |
| 20 | 20 | /* |
| r8044 | r8045 | |
| 30 | 30 | #define DS_WRFAULT 0x01 /* write fault */ |
| 31 | 31 | |
| 32 | 32 | /* |
| 33 | Needed to adapt to higher cylinder numbers. Floppies do not have such | |
| 34 | high numbers. | |
| 33 | Needed to adapt to higher cylinder numbers. Floppies do not have such | |
| 34 | high numbers. | |
| 35 | 35 | */ |
| 36 | 36 | typedef struct chrn_id_hd |
| 37 | 37 | { |
| r8044 | r8045 | |
| 46 | 46 | typedef struct _smc92x4_interface |
| 47 | 47 | { |
| 48 | 48 | /* Disk format support. This flag allows to choose between the full |
| 49 | FM/MFM format and an abbreviated track layout. The difference results | |
| 50 | from legal variations of the layout. This is not part of | |
| 51 | the smc92x4 specification, but it allows to keep the image format | |
| 52 | simple without too much case checking. Should be removed as soon as | |
| 53 | the respective disk formats support the full format. */ | |
| 49 | FM/MFM format and an abbreviated track layout. The difference results | |
| 50 | from legal variations of the layout. This is not part of | |
| 51 | the smc92x4 specification, but it allows to keep the image format | |
| 52 | simple without too much case checking. Should be removed as soon as | |
| 53 | the respective disk formats support the full format. */ | |
| 54 | 54 | int full_track_layout; |
| 55 | 55 | |
| 56 | /* Interrupt line. To be connected with the controller PCB. */ | |
| 56 | /* Interrupt line. To be connected with the controller PCB. */ | |
| 57 | 57 | devcb_write_line out_intrq_func; |
| 58 | 58 | |
| 59 | /* DMA in progress line. To be connected with the controller PCB. */ | |
| 59 | /* DMA in progress line. To be connected with the controller PCB. */ | |
| 60 | 60 | devcb_write_line out_dip_func; |
| 61 | 61 | |
| 62 | 62 | /* Auxiliary Bus. These 8 lines need to be connected to external latches |
| 63 | and to a counter circuitry which works together with the external RAM. | |
| 64 | We use the S0/S1 lines as address lines. | |
| 65 | */ | |
| 63 | and to a counter circuitry which works together with the external RAM. | |
| 64 | We use the S0/S1 lines as address lines. | |
| 65 | */ | |
| 66 | 66 | devcb_write8 out_auxbus_func; |
| 67 | ||
| 68 | /* Auxiliary Bus. This is only used for S0=S1=0, so we need no address | |
| 69 | lines and consider this line just as a line with 256 states. */ | |
| 67 | ||
| 68 | /* Auxiliary Bus. This is only used for S0=S1=0, so we need no address | |
| 69 | lines and consider this line just as a line with 256 states. */ | |
| 70 | 70 | devcb_read_line in_auxbus_func; |
| 71 | 71 | |
| 72 | 72 | /* Get the currently selected floppy disk. This is determined by the |
| 73 | circuitry on the controller board, not within the controller itself. | |
| 74 | */ | |
| 73 | circuitry on the controller board, not within the controller itself. | |
| 74 | */ | |
| 75 | 75 | running_device *(*current_floppy)(void); |
| 76 | 76 | |
| 77 | 77 | /* Callback to read the contents of the external RAM via the data bus. |
| 78 | Note that the address must be set and automatically increased | |
| 79 | by external circuitry. */ | |
| 78 | Note that the address must be set and automatically increased | |
| 79 | by external circuitry. */ | |
| 80 | 80 | UINT8 (*dma_read_callback)(void); |
| 81 | ||
| 81 | ||
| 82 | 82 | /* Callback to write the contents of the external RAM via the data bus. |
| 83 | Note that the address must be set and automatically increased | |
| 84 | by external circuitry. */ | |
| 83 | Note that the address must be set and automatically increased | |
| 84 | by external circuitry. */ | |
| 85 | 85 | void (*dma_write_callback)(UINT8 data); |
| 86 | 86 | |
| 87 | 87 | /* Preliminary MFM hard disk interface. Gets next id. */ |
| 88 | 88 | void (*mfmhd_get_next_id)(int head, chrn_id_hd *id); |
| 89 | 89 | |
| 90 | 90 | /* Preliminary MFM hard disk interface. Performs a seek. */ |
| 91 | void (*mfmhd_seek)(int direction); | |
| 91 | void (*mfmhd_seek)(int direction); | |
| 92 | 92 | |
| 93 | 93 | /* Preliminary MFM hard disk interface. Reads a sector. */ |
| 94 | void (*mfmhd_read_sector)(int cylinder, int head, int sector, UINT8 **buf, int *sector_length); | |
| 94 | void (*mfmhd_read_sector)(int cylinder, int head, int sector, UINT8 **buf, int *sector_length); | |
| 95 | 95 | |
| 96 | 96 | /* Preliminary MFM hard disk interface. Writes a sector. */ |
| 97 | void (*mfmhd_write_sector)(int cylinder, int head, int sector, UINT8 *buf, int sector_length); | |
| 97 | void (*mfmhd_write_sector)(int cylinder, int head, int sector, UINT8 *buf, int sector_length); | |
| 98 | 98 | |
| 99 | 99 | /* Preliminary MFM hard disk interface. Reads a track. */ |
| 100 | void (*mfmhd_read_track)(int head, UINT8 **buffer, int *data_count); | |
| 100 | void (*mfmhd_read_track)(int head, UINT8 **buffer, int *data_count); | |
| 101 | 101 | |
| 102 | 102 | /* Preliminary MFM hard disk interface. Writes a track. */ |
| 103 | void (*mfmhd_write_track)(int head, UINT8 *buffer, int data_count); | |
| 103 | void (*mfmhd_write_track)(int head, UINT8 *buffer, int data_count); | |
| 104 | 104 | } smc92x4_interface; |
| 105 | 105 | |
| 106 | 106 | /* device interface */ |
| r8044 | r8045 | |
| 120 | 120 | #define MDRV_SMC92X4_ADD(_tag, _intrf) \ |
| 121 | 121 | MDRV_DEVICE_ADD(_tag, SMC92X4, 0) \ |
| 122 | 122 | MDRV_DEVICE_CONFIG(_intrf) |
| 123 | ||
| 123 | ||
| 124 | 124 | #endif |
| r8044 | r8045 | |
|---|---|---|
| 127 | 127 | #endif |
| 128 | 128 | |
| 129 | 129 | /* |
| 130 | ||
| 130 | Configuration values | |
| 131 | 131 | */ |
| 132 | 132 | enum |
| 133 | 133 | { |
| r8044 | r8045 | |
| 146 | 146 | { |
| 147 | 147 | DISK_NONE = 0, |
| 148 | 148 | DISK_TIFDC, |
| 149 | DISK_BWG, | |
| 149 | DISK_BWG, | |
| 150 | 150 | DISK_HFDC, |
| 151 | 151 | DISK_CC |
| 152 | 152 | }; |
| r8044 | r8045 | |
| 191 | 191 | |
| 192 | 192 | |
| 193 | 193 | /* Cartridge types */ |
| 194 | enum | |
| 194 | enum | |
| 195 | 195 | { |
| 196 | 196 | STANDARD, |
| 197 | 197 | EXBAS, |
| r8044 | r8045 | |
|---|---|---|
| 44 | 44 | /* the image has no header, hence let's trust the extension and load the file */ |
| 45 | 45 | *vote = 100; |
| 46 | 46 | } |
| 47 | ||
| 47 | ||
| 48 | 48 | return FLOPPY_ERROR_SUCCESS; |
| 49 | 49 | } |
| 50 | 50 |
| r8044 | r8045 | |
|---|---|---|
| 744 | 744 | fmt = floppy_callbacks(floppy); |
| 745 | 745 | if (!fmt->get_track_size) |
| 746 | 746 | return 0; |
| 747 | ||
| 747 | ||
| 748 | 748 | return fmt->get_track_size(floppy, head, track); |
| 749 | 749 | } |
| 750 | 750 |
| r8044 | r8045 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | TODO: |
| 12 | 12 | |
| 13 | - fix MAX_ERROR_SECTORS, it is too small for d80/d82 | |
| 14 | - write to disk | |
| 13 | - fix MAX_ERROR_SECTORS, it is too small for d80/d82 | |
| 14 | - write to disk | |
| 15 | 15 | - disk errors 24, 25, 26, 28, 74 |
| 16 | 16 | - variable gaps |
| 17 | 17 | |
| r8044 | r8045 | |
| 266 | 266 | |
| 267 | 267 | /*------------------------------------------------- |
| 268 | 268 | get_sector_error_code - returns the error |
| 269 | ||
| 269 | code for the given sector | |
| 270 | 270 | -------------------------------------------------*/ |
| 271 | 271 | |
| 272 | 272 | static int get_sector_error_code(floppy_image *floppy, int head, int dos_track, int sector) |
| r8044 | r8045 | |
| 498 | 498 | |
| 499 | 499 | if (sector_error == ERROR_23) |
| 500 | 500 | sector_checksum ^= 0xff; |
| 501 | ||
| 501 | ||
| 502 | 502 | /* |
| 503 | 503 | $00 - data block ID ($07) |
| 504 | 504 | $01-100 - 256 bytes sector data |
| r8044 | r8045 | |
|---|---|---|
| 38 | 38 | { |
| 39 | 39 | /* |
| 40 | 40 | |
| 41 | ||
| 41 | The format for the .ATM files is as follows: | |
| 42 | 42 | |
| 43 | Offset Size Description | |
| 44 | ------ -------- ----------------------------------------------------------- | |
| 45 | 0000h 16 BYTEs ATOM filename (if less than 16 BYTEs, rest is 00h bytes) | |
| 46 | 0010h WORD Start address for load | |
| 47 | 0012h WORD Execution address | |
| 48 | 0014h WORD Size of data in BYTEs | |
| 49 | 0016h Size Data | |
| 43 | Offset Size Description | |
| 44 | ------ -------- ----------------------------------------------------------- | |
| 45 | 0000h 16 BYTEs ATOM filename (if less than 16 BYTEs, rest is 00h bytes) | |
| 46 | 0010h WORD Start address for load | |
| 47 | 0012h WORD Execution address | |
| 48 | 0014h WORD Size of data in BYTEs | |
| 49 | 0016h Size Data | |
| 50 | 50 | |
| 51 | */ | |
| 52 | ||
| 51 | */ | |
| 52 | ||
| 53 | 53 | UINT8 header[0x16] = { 0 }; |
| 54 | 54 | |
| 55 | 55 | image_fread(image, header, 0x16); |
| r8044 | r8045 | |
|---|---|---|
| 11 | 11 | |
| 12 | 12 | /* |
| 13 | 13 | |
| 14 | ||
| 14 | TODO: | |
| 15 | 15 | |
| 16 | - MSA format | |
| 17 | - STT format | |
| 18 | - DIM format | |
| 16 | - MSA format | |
| 17 | - STT format | |
| 18 | - DIM format | |
| 19 | 19 | |
| 20 | 20 | */ |
| 21 | 21 | |
| r8044 | r8045 | |
| 68 | 68 | |
| 69 | 69 | FLOPPY_OPTIONS_START( atarist ) |
| 70 | 70 | FLOPPY_OPTION( atarist, "st", "Atari ST floppy disk image", atarist_st_identify, atarist_st_construct, NULL ) |
| 71 | /* FLOPPY_OPTION( atarist, "stt", "Atari ST floppy disk image", atarist_stt_identify, atarist_stt_construct, NULL ) | |
| 72 | FLOPPY_OPTION( atarist, "msa", "Atari ST floppy disk image", atarist_msa_identify, atarist_msa_construct, NULL ) | |
| 73 | FLOPPY_OPTION( atarist, "dim", "Atari ST floppy disk image", atarist_dim_identify, atarist_dim_construct, NULL )*/ | |
| 71 | /* FLOPPY_OPTION( atarist, "stt", "Atari ST floppy disk image", atarist_stt_identify, atarist_stt_construct, NULL ) | |
| 72 | FLOPPY_OPTION( atarist, "msa", "Atari ST floppy disk image", atarist_msa_identify, atarist_msa_construct, NULL ) | |
| 73 | FLOPPY_OPTION( atarist, "dim", "Atari ST floppy disk image", atarist_dim_identify, atarist_dim_construct, NULL )*/ | |
| 74 | 74 | FLOPPY_OPTIONS_END |
| r8044 | r8045 | |
|---|---|---|
| 8 | 8 | |
| 9 | 9 | /* |
| 10 | 10 | |
| 11 | ||
| 11 | http://beebwiki.jonripley.com/Acorn_cassette_format#Atom | |
| 12 | 12 | |
| 13 | The Atom supports the System series format (as a 'nameless file') and its own format. The data consists of files separated | |
| 14 | by carrier breaks and the appropriate leaders and trailers, and further subdivided into blocks separated by inter-block gaps. | |
| 15 | An Atom block consists of the following sequence of bytes: | |
| 13 | The Atom supports the System series format (as a 'nameless file') and its own format. The data consists of files separated | |
| 14 | by carrier breaks and the appropriate leaders and trailers, and further subdivided into blocks separated by inter-block gaps. | |
| 15 | An Atom block consists of the following sequence of bytes: | |
| 16 | 16 | |
| 17 | Four synchronisation bytes (&2A). | |
| 18 | File name (one to thirteen characters). | |
| 19 | One end of file name marker byte (&0D). | |
| 20 | Block flag, one byte. | |
| 21 | Block number, two bytes, high byte first. | |
| 22 | Data block length ? 1, one byte. | |
| 23 | Execution address, two bytes, high byte first. | |
| 24 | Load address, two bytes, high byte first. | |
| 25 | Data, 0 to 256 bytes. | |
| 26 | Checksum, one byte. | |
| 17 | Four synchronisation bytes (&2A). | |
| 18 | File name (one to thirteen characters). | |
| 19 | One end of file name marker byte (&0D). | |
| 20 | Block flag, one byte. | |
| 21 | Block number, two bytes, high byte first. | |
| 22 | Data block length ? 1, one byte. | |
| 23 | Execution address, two bytes, high byte first. | |
| 24 | Load address, two bytes, high byte first. | |
| 25 | Data, 0 to 256 bytes. | |
| 26 | Checksum, one byte. | |
| 27 | 27 | |
| 28 | ||
| 28 | The block flag is set as follows: | |
| 29 | 29 | |
| 30 | Bit 7 is set if this block is not the last block of a file. | |
| 31 | Bit 6 is set if the block contains data. If clear then the 'data block length' field is invalid. | |
| 32 | Bit 5 is set if this block is not the first block of a file. | |
| 33 | Bits 4 to 0 are undefined. Normally their contents are: | |
| 34 | in the first block, bits 15 to 11 of the end address (=1 + the last address saved in the file); | |
| 35 | in subsequent blocks, bits 6 to 2 of the previous block flag. | |
| 36 | ||
| 37 | The checksum is a simple sum (modulo 256) of all bytes from the start of the filename to the end of the data. | |
| 30 | Bit 7 is set if this block is not the last block of a file. | |
| 31 | Bit 6 is set if the block contains data. If clear then the 'data block length' field is invalid. | |
| 32 | Bit 5 is set if this block is not the first block of a file. | |
| 33 | Bits 4 to 0 are undefined. Normally their contents are: | |
| 34 | in the first block, bits 15 to 11 of the end address (=1 + the last address saved in the file); | |
| 35 | in subsequent blocks, bits 6 to 2 of the previous block flag. | |
| 38 | 36 | |
| 37 | The checksum is a simple sum (modulo 256) of all bytes from the start of the filename to the end of the data. | |
| 38 | ||
| 39 | 39 | */ |
| 40 | 40 | |
| 41 | 41 | #include "emu.h" |
| r8044 | r8045 | |
| 128 | 128 | CassetteFormat atom_tap_cassette_format |
| 129 | 129 | -------------------------------------------------*/ |
| 130 | 130 | |
| 131 | const struct CassetteFormat atom_tap_format = | |
| 131 | const struct CassetteFormat atom_tap_format = | |
| 132 | 132 | { |
| 133 | 133 | "tap", |
| 134 | 134 | atom_tap_identify, |
| r8044 | r8045 | |
|---|---|---|
| 282 | 282 | } |
| 283 | 283 | |
| 284 | 284 | cassette_close(cassette); |
| 285 | ||
| 285 | ||
| 286 | 286 | fclose(f); |
| 287 | 287 | } |
| 288 | 288 | #endif |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*********************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | CBM Quickloads |
| 4 | ||
| 4 | ||
| 5 | 5 | ***********************************************/ |
| 6 | 6 | |
| 7 | 7 | #include "emu.h" |
| r8044 | r8045 | |
| 16 | 16 | UINT16 address = 0; |
| 17 | 17 | int i; |
| 18 | 18 | const address_space *space = cpu_get_address_space(image->machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 19 | ||
| 19 | ||
| 20 | 20 | if (!file_type) |
| 21 | 21 | goto error; |
| 22 | ||
| 22 | ||
| 23 | 23 | if (!mame_stricmp(file_type, "prg")) |
| 24 | 24 | { |
| 25 | 25 | /* prg files */ |
| r8044 | r8045 | |
| 48 | 48 | { |
| 49 | 49 | goto error; |
| 50 | 50 | } |
| 51 | ||
| 51 | ||
| 52 | 52 | image_fread(image, &address, 2); |
| 53 | 53 | address = LITTLE_ENDIANIZE_INT16(address); |
| 54 | 54 | if (!mame_stricmp(file_type, "t64")) |
| 55 | 55 | address = 2049; |
| 56 | 56 | snapshot_size -= 2; |
| 57 | ||
| 57 | ||
| 58 | 58 | data = (UINT8*)malloc(snapshot_size); |
| 59 | 59 | if (!data) |
| 60 | 60 | goto error; |
| 61 | ||
| 61 | ||
| 62 | 62 | bytesread = image_fread(image, data, snapshot_size); |
| 63 | 63 | if (bytesread != snapshot_size) |
| 64 | 64 | goto error; |
| 65 | ||
| 65 | ||
| 66 | 66 | for (i = 0; i < snapshot_size; i++) |
| 67 | 67 | memory_write_byte(space, address + i + offset, data[i]); |
| 68 | ||
| 68 | ||
| 69 | 69 | cbm_sethiaddress(image->machine, address + snapshot_size); |
| 70 | 70 | free(data); |
| 71 | 71 | return INIT_PASS; |
| 72 | ||
| 72 | ||
| 73 | 73 | error: |
| 74 | 74 | if (data) |
| 75 | 75 | free(data); |
| r8044 | r8045 | |
| 79 | 79 | static void cbm_quick_sethiaddress( running_machine *machine, UINT16 hiaddress ) |
| 80 | 80 | { |
| 81 | 81 | const address_space *space = cpu_get_address_space(machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 82 | ||
| 82 | ||
| 83 | 83 | memory_write_byte(space, 0x31, hiaddress & 0xff); |
| 84 | 84 | memory_write_byte(space, 0x2f, hiaddress & 0xff); |
| 85 | 85 | memory_write_byte(space, 0x2d, hiaddress & 0xff); |
| r8044 | r8045 | |
| 106 | 106 | static void cbm_pet_quick_sethiaddress( running_machine *machine, UINT16 hiaddress ) |
| 107 | 107 | { |
| 108 | 108 | const address_space *space = cpu_get_address_space(machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 109 | ||
| 109 | ||
| 110 | 110 | memory_write_byte(space, 0x2e, hiaddress & 0xff); |
| 111 | 111 | memory_write_byte(space, 0x2c, hiaddress & 0xff); |
| 112 | 112 | memory_write_byte(space, 0x2a, hiaddress & 0xff); |
| r8044 | r8045 | |
| 123 | 123 | static void cbm_pet1_quick_sethiaddress(running_machine *machine, UINT16 hiaddress) |
| 124 | 124 | { |
| 125 | 125 | const address_space *space = cpu_get_address_space(machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 126 | ||
| 126 | ||
| 127 | 127 | memory_write_byte(space, 0x80, hiaddress & 0xff); |
| 128 | 128 | memory_write_byte(space, 0x7e, hiaddress & 0xff); |
| 129 | 129 | memory_write_byte(space, 0x7c, hiaddress & 0xff); |
| r8044 | r8045 | |
| 140 | 140 | static void cbmb_quick_sethiaddress(running_machine *machine, UINT16 hiaddress) |
| 141 | 141 | { |
| 142 | 142 | const address_space *space = cpu_get_address_space(machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 143 | ||
| 143 | ||
| 144 | 144 | memory_write_byte(space, 0xf0046, hiaddress & 0xff); |
| 145 | 145 | memory_write_byte(space, 0xf0047, hiaddress >> 8); |
| 146 | 146 | } |
| r8044 | r8045 | |
| 158 | 158 | static void cbm_c65_quick_sethiaddress( running_machine *machine, UINT16 hiaddress ) |
| 159 | 159 | { |
| 160 | 160 | const address_space *space = cpu_get_address_space(machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 161 | ||
| 161 | ||
| 162 | 162 | memory_write_byte(space, 0x82, hiaddress & 0xff); |
| 163 | 163 | memory_write_byte(space, 0x83, hiaddress >> 8); |
| 164 | 164 | } |
| r8044 | r8045 | |
|---|---|---|
| 84 | 84 | #define TI99_IDAM_LENGTH 7 |
| 85 | 85 | |
| 86 | 86 | /* |
| 87 | Determines whether we are using 80 track drives. This variable is | |
| 88 | necessary unless we get information about the dip | |
| 89 | switch settings. It is set from 99_dsk.c, currenly the only client. | |
| 87 | Determines whether we are using 80 track drives. This variable is | |
| 88 | necessary unless we get information about the dip | |
| 89 | switch settings. It is set from 99_dsk.c, currenly the only client. | |
| 90 | 90 | */ |
| 91 | 91 | static int use_80_track_drives = FALSE; |
| 92 | 92 | |
| r8044 | r8045 | |
| 110 | 110 | }; |
| 111 | 111 | |
| 112 | 112 | /* |
| 113 | Parametrizes the format to use 80 track drives. For TI systems we | |
| 114 | need to be able to emulate 40 track drives and 80 track drives. | |
| 115 | This is set in the configuration, but the format has no direct access. | |
| 116 | So as a preliminary solution we use this global function which sets the | |
| 117 | flag. This function is called by the controllers defined in 99_dsk. | |
| 113 | Parametrizes the format to use 80 track drives. For TI systems we | |
| 114 | need to be able to emulate 40 track drives and 80 track drives. | |
| 115 | This is set in the configuration, but the format has no direct access. | |
| 116 | So as a preliminary solution we use this global function which sets the | |
| 117 | flag. This function is called by the controllers defined in 99_dsk. | |
| 118 | 118 | */ |
| 119 | 119 | void ti99_set_80_track_drives(int use80) |
| 120 | 120 | { |
| r8044 | r8045 | |
| 645 | 645 | int imgtrack = track; |
| 646 | 646 | |
| 647 | 647 | /* Find out if we are going to write an FM or MFM track. Caution: The |
| 648 | original TI controller is known to have a bug in the formatting | |
| 649 | routine (using a MOVB instead of a MOV instruction when setting the | |
| 650 | pointer to the track data), outputting false bytes at the | |
| 651 | beginning of the track. So we don't rely on absolute positions | |
| 652 | (neither does the controller). | |
| 653 | */ | |
| 648 | original TI controller is known to have a bug in the formatting | |
| 649 | routine (using a MOVB instead of a MOV instruction when setting the | |
| 650 | pointer to the track data), outputting false bytes at the | |
| 651 | beginning of the track. So we don't rely on absolute positions | |
| 652 | (neither does the controller). | |
| 653 | */ | |
| 654 | 654 | track_image = (UINT8*)buffer; |
| 655 | 655 | |
| 656 | 656 | if (use_80_track_drives && tag->tracks<=40) |
| r8044 | r8045 | |
| 663 | 663 | gap1 = 10; |
| 664 | 664 | gap2 = 12; |
| 665 | 665 | is_fm = FALSE; |
| 666 | ||
| 666 | ||
| 667 | 667 | current_pos = find_block(track_image, 0, 100, 0x4e, leadin); |
| 668 | ||
| 668 | ||
| 669 | 669 | /* In case of defect formats, we continue as far as possible. This |
| 670 | ||
| 670 | may lead to sectors not being written. */ | |
| 671 | 671 | if (current_pos==TI99DSK_BLOCKNOTFOUND) |
| 672 | 672 | { |
| 673 | 673 | /* Not MFM, possibly FM image */ |
| r8044 | r8045 | |
| 740 | 740 | else |
| 741 | 741 | { |
| 742 | 742 | /* else the sector head data do not match the |
| 743 | ||
| 743 | current track and head. Ignore the sector. */ | |
| 744 | 744 | logerror("Wrong track: wtrack=%d, imgtrack=%d, whead=%d, imghead=%d\n",wtrack,imgtrack, whead,head); |
| 745 | 745 | } |
| 746 | 746 | } |
| r8044 | r8045 | |
| 1273 | 1273 | floppy_image_read(floppy, buffer, track_offset, buflen); |
| 1274 | 1274 | |
| 1275 | 1275 | /* Rebuild the CRCs. PC99 did not store the CRC but put |
| 1276 | F7F7 in its place. | |
| 1277 | The first CRC is at position IDAM + 5 | |
| 1278 | The second CRC is at position IDAM + 0x119 (FM) or +0x12d (MFM) | |
| 1279 | All this is repeated for each sector in the track | |
| 1280 | */ | |
| 1276 | F7F7 in its place. | |
| 1277 | The first CRC is at position IDAM + 5 | |
| 1278 | The second CRC is at position IDAM + 0x119 (FM) or +0x12d (MFM) | |
| 1279 | All this is repeated for each sector in the track | |
| 1280 | */ | |
| 1281 | 1281 | if (determine_offset(tag->format, track_data, &first_idam)==FLOPPY_ERROR_SEEKERROR) |
| 1282 | 1282 | return FLOPPY_ERROR_SEEKERROR; |
| 1283 | 1283 | |
| r8044 | r8045 | |
| 1288 | 1288 | if (byte == TI99_IDAM) |
| 1289 | 1289 | { |
| 1290 | 1290 | /* Do we have a valid CRCs already? Then this image |
| 1291 | already contains proper CRCs handling. Do not | |
| 1292 | recreate them. */ | |
| 1291 | already contains proper CRCs handling. Do not | |
| 1292 | recreate them. */ | |
| 1293 | 1293 | if (track_data[i+5] != 0xf7 || track_data[i+6] != 0xf7) |
| 1294 | 1294 | return FLOPPY_ERROR_SUCCESS; |
| 1295 | 1295 | |
| r8044 | r8045 | |
| 1348 | 1348 | return err; |
| 1349 | 1349 | |
| 1350 | 1350 | /* According to the TDF format, we don't need the CRC but replace it |
| 1351 | with F7F7. For now we keep it and see whether PC99 can cope with | |
| 1352 | that. (Otherwise we would have to copy the const buffer). */ | |
| 1351 | with F7F7. For now we keep it and see whether PC99 can cope with | |
| 1352 | that. (Otherwise we would have to copy the const buffer). */ | |
| 1353 | 1353 | floppy_image_write(floppy, buffer, offset + track_offset, buflen); |
| 1354 | 1354 | return FLOPPY_ERROR_SUCCESS; |
| 1355 | 1355 | } |
| r8044 | r8045 | |
| 1370 | 1370 | */ |
| 1371 | 1371 | |
| 1372 | 1372 | /* |
| 1373 | Get a sector from a track. This function takes a complete track, | |
| 1374 | searches for the sector, and passes a pointer to the sector contents | |
| 1375 | back. | |
| 1376 | As the original TI controller creates bad bytes at the start of a track | |
| 1377 | we do *not* assume a simple layout. The strategy is to search the | |
| 1378 | lead-in of the track, and from this offset, step through the track | |
| 1379 | in search for the sector. Since we do not have index marks (we cannot | |
| 1380 | distinguish them from ordinary data, as we do not store the clock), we | |
| 1381 | do not attempt to detect IDAM or DAM. | |
| 1373 | Get a sector from a track. This function takes a complete track, | |
| 1374 | searches for the sector, and passes a pointer to the sector contents | |
| 1375 | back. | |
| 1376 | As the original TI controller creates bad bytes at the start of a track | |
| 1377 | we do *not* assume a simple layout. The strategy is to search the | |
| 1378 | lead-in of the track, and from this offset, step through the track | |
| 1379 | in search for the sector. Since we do not have index marks (we cannot | |
| 1380 | distinguish them from ordinary data, as we do not store the clock), we | |
| 1381 | do not attempt to detect IDAM or DAM. | |
| 1382 | 1382 | */ |
| 1383 | 1383 | static floperr_t ti99_tdf_seek_sector_in_track(floppy_image *floppy, int head, int track, int sector, UINT8 *track_data, UINT8 **sector_data) |
| 1384 | 1384 | { |
| r8044 | r8045 | |
| 1457 | 1457 | } |
| 1458 | 1458 | |
| 1459 | 1459 | /* |
| 1460 | Writes a sector into the track. Note that the indexed_write method | |
| 1461 | may be used instead of this method, according to the implementation | |
| 1462 | of flopimg/flopdrv. | |
| 1460 | Writes a sector into the track. Note that the indexed_write method | |
| 1461 | may be used instead of this method, according to the implementation | |
| 1462 | of flopimg/flopdrv. | |
| 1463 | 1463 | */ |
| 1464 | 1464 | static floperr_t ti99_tdf_write_sector(floppy_image *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam) |
| 1465 | 1465 | { |
| r8044 | r8045 | |
| 1709 | 1709 | } |
| 1710 | 1710 | |
| 1711 | 1711 | /* |
| 1712 | Required for ReadAddress command. This function gets the 1st, 2nd, 3rd, | |
| 1713 | sector (and so on) from the track, not sector 1, 2, 3. That is, the | |
| 1714 | returned sector info depends on the interleave and the start sector. | |
| 1712 | Required for ReadAddress command. This function gets the 1st, 2nd, 3rd, | |
| 1713 | sector (and so on) from the track, not sector 1, 2, 3. That is, the | |
| 1714 | returned sector info depends on the interleave and the start sector. | |
| 1715 | 1715 | */ |
| 1716 | 1716 | static floperr_t ti99_tdf_get_indexed_sector_info(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags) |
| 1717 | 1717 | { |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*********************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | CBM Quickloads |
| 4 | ||
| 4 | ||
| 5 | 5 | ***********************************************/ |
| 6 | 6 | |
| 7 | 7 | #ifndef __CBM_SNQK_H__ |
| r8044 | r8045 | |
|---|---|---|
| 119 | 119 | UINT8 minsize[3]; |
| 120 | 120 | UINT8 maxsize[3]; |
| 121 | 121 | UINT8 indexsize[3]; |
| 122 | // UINT8 averagedt[averagesz]; | |
| 123 | // UINT8 mindata[minsize]; | |
| 124 | // UINT8 maxdata[maxsize]; | |
| 125 | // UINT8 indexdata[indexsize]; | |
| 122 | // UINT8 averagedt[averagesz]; | |
| 123 | // UINT8 mindata[minsize]; | |
| 124 | // UINT8 maxdata[maxsize]; | |
| 125 | // UINT8 indexdata[indexsize]; | |
| 126 | 126 | }; |
| 127 | 127 | |
| 128 | 128 | /*************************************************************************** |
| r8044 | r8045 | |
| 160 | 160 | /* |
| 161 | 161 | static UINT32 fdi_get_sector_offset(floppy_image* floppy, int head, int track, int sector) |
| 162 | 162 | { |
| 163 | ||
| 163 | return 0; | |
| 164 | 164 | } |
| 165 | 165 | */ |
| 166 | 166 | static floperr_t fdi_get_indexed_sector_info(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags) |
| r8044 | r8045 | |
| 238 | 238 | tag->version = header.version[0]; |
| 239 | 239 | tag->tracks = pick_integer_be(header.ltrack, 0, 2) + 1; |
| 240 | 240 | tag->heads = header.lhead + 1; |
| 241 | ||
| 241 | ||
| 242 | 242 | if (LOG) |
| 243 | 243 | { |
| 244 | 244 | logerror("FDI creator: %s\n", header.creator); |
| r8044 | r8045 | |
| 279 | 279 | callbacks->get_sector_length = fdi_get_sector_length; |
| 280 | 280 | callbacks->read_sector = fdi_read_sector; |
| 281 | 281 | callbacks->read_indexed_sector = fdi_read_indexed_sector; |
| 282 | // | |
| 282 | // callbacks->write_track = fdi_write_track; | |
| 283 | 283 | callbacks->write_sector = fdi_write_sector; |
| 284 | 284 | callbacks->write_indexed_sector = fdi_write_indexed_sector; |
| 285 | 285 | callbacks->get_indexed_sector_info = fdi_get_indexed_sector_info; |
| r8044 | r8045 | |
|---|---|---|
| 36 | 36 | QUICKLOAD_LOAD( trs80_cmd ) |
| 37 | 37 | { |
| 38 | 38 | const address_space *program = cpu_get_address_space(image->machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 39 | ||
| 39 | ||
| 40 | 40 | UINT8 type, length; |
| 41 | 41 | UINT8 data[0x100]; |
| 42 | 42 | UINT8 addr[2]; |
| r8044 | r8045 | |
|---|---|---|
| 701 | 701 | RAM[i+1] = j[2]; |
| 702 | 702 | RAM[i+2] = j[1]; |
| 703 | 703 | RAM[i+3] = j[0]; |
| 704 | } | |
| 704 | } | |
| 705 | 705 | } |
| 706 | 706 | |
| 707 | 707 | static DRIVER_INIT( jaguar ) |
| r8044 | r8045 | |
| 785 | 785 | size = image_length(image); |
| 786 | 786 | |
| 787 | 787 | /* .rom files load & run at 802000 */ |
| 788 | if (!mame_stricmp(image_filetype(image), "rom")) | |
| 788 | if (!mame_stricmp(image_filetype(image), "rom")) | |
| 789 | 789 | { |
| 790 | 790 | load_offset = 0x2000; // fix load address |
| 791 | 791 | cart_base[0x101]=0x802000; // fix exec address |
| r8044 | r8045 | |
|---|---|---|
| 228 | 228 | PORT_CONFSETTING( 0x01, "TI SD Floppy Controller" ) |
| 229 | 229 | PORT_CONFSETTING( 0x02, "SNUG BwG Controller" ) |
| 230 | 230 | PORT_CONFSETTING( 0x03, "Myarc HFDC" ) |
| 231 | // | |
| 231 | // PORT_CONFSETTING( 0x04, "Corcomp" ) | |
| 232 | 232 | |
| 233 | 233 | PORT_START( "HDCTRL" ) |
| 234 | 234 | PORT_CONFNAME( 0x03, 0x00, "HD controller" ) |
| 235 | 235 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 236 | 236 | PORT_CONFSETTING( 0x01, "Nouspikel IDE Controller" ) |
| 237 | // | |
| 237 | // PORT_CONFSETTING( 0x02, "WHTech SCSI Controller" ) | |
| 238 | 238 | PORT_CONFNAME( 0x08, 0x00, "USB-SM card" ) |
| 239 | 239 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 240 | 240 | PORT_CONFSETTING( 0x08, DEF_STR( On ) ) |
| r8044 | r8045 | |
| 243 | 243 | PORT_CONFNAME( 0x03, 0x00, "Serial/Parallel interface" ) |
| 244 | 244 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 245 | 245 | PORT_CONFSETTING( 0x01, "TI RS-232 card" ) |
| 246 | ||
| 246 | ||
| 247 | 247 | PORT_START( "EXTCARD" ) |
| 248 | 248 | PORT_CONFNAME( 0x01, 0x00, "HSGPL extension" ) |
| 249 | 249 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| r8044 | r8045 | |
| 256 | 256 | PORT_CONFNAME( 0x01, 0x00, "Mouse support" ) |
| 257 | 257 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 258 | 258 | PORT_CONFSETTING( 0x01, "Mechatronics Mouse" ) |
| 259 | ||
| 259 | ||
| 260 | 260 | PORT_START( "CARTSLOT" ) |
| 261 | 261 | PORT_CONFNAME( 0x07, 0x00, "Cartridge slot" ) |
| 262 | 262 | PORT_CONFSETTING( 0x00, "Auto" ) |
| r8044 | r8045 | |
| 264 | 264 | PORT_CONFSETTING( 0x02, "Slot 2" ) |
| 265 | 265 | PORT_CONFSETTING( 0x03, "Slot 3" ) |
| 266 | 266 | PORT_CONFSETTING( 0x04, "Slot 4" ) |
| 267 | // | |
| 267 | // PORT_CONFSETTING( 0x05, "GRAM Kracker" ) | |
| 268 | 268 | |
| 269 | 269 | PORT_START( "HFDCDIP" ) |
| 270 | 270 | PORT_DIPNAME( 0x03, 0x02, "HFDC drive config" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| 271 | 271 | PORT_DIPSETTING( 0x00, "40 track, 16 ms") |
| 272 | 272 | PORT_DIPSETTING( 0x01, "40 track, 8 ms") |
| 273 | 273 | PORT_DIPSETTING( 0x02, "80 track, 2 ms") |
| 274 | PORT_DIPSETTING( 0x03, "80 track HD, 2 ms") | |
| 274 | PORT_DIPSETTING( 0x03, "80 track HD, 2 ms") | |
| 275 | 275 | |
| 276 | 276 | PORT_START( "DRVSPD" ) |
| 277 | 277 | PORT_DIPNAME( 0x01, 0x01, "Floppy and HD speed" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| r8044 | r8045 | |
| 562 | 562 | /* devices */ |
| 563 | 563 | MDRV_IDE_CONTROLLER_ADD( "ide", ti99_ide_interrupt ) |
| 564 | 564 | |
| 565 | // | |
| 565 | // MDRV_IMPORT_FROM( smc92x4_hd ) | |
| 566 | 566 | |
| 567 | 567 | MDRV_IDE_HARDDISK_ADD( "ide_harddisk" ) |
| 568 | 568 | MDRV_RTC65271_ADD("ide_rtc", ti99_clk_interrupt_callback) |
| r8044 | r8045 | |
| 617 | 617 | /* devices */ |
| 618 | 618 | MDRV_IDE_CONTROLLER_ADD( "ide", ti99_ide_interrupt ) /* FIXME */ |
| 619 | 619 | |
| 620 | // | |
| 620 | // MDRV_IMPORT_FROM( smc92x4_hd ) | |
| 621 | 621 | |
| 622 | 622 | MDRV_IDE_HARDDISK_ADD( "ide_harddisk" ) |
| 623 | 623 | MDRV_RTC65271_ADD("ide_rtc", ti99_clk_interrupt_callback) |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | pipbug |
| 4 | 4 | |
| 5 | 5 | 08/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 12 | 12 | static ADDRESS_MAP_START(pipbug_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 13 | 13 | ADDRESS_MAP_UNMAP_HIGH |
| 14 | 14 | AM_RANGE( 0x0000, 0x03ff) AM_ROM |
| 15 | AM_RANGE( 0x0400, 0x7fff) AM_RAM | |
| 15 | AM_RANGE( 0x0400, 0x7fff) AM_RAM | |
| 16 | 16 | ADDRESS_MAP_END |
| 17 | 17 | |
| 18 | 18 | static ADDRESS_MAP_START( pipbug_io , ADDRESS_SPACE_IO, 8) |
| 19 | ADDRESS_MAP_UNMAP_HIGH | |
| 19 | ADDRESS_MAP_UNMAP_HIGH | |
| 20 | 20 | ADDRESS_MAP_END |
| 21 | 21 | |
| 22 | 22 | /* Input ports */ |
| r8044 | r8045 | |
| 24 | 24 | INPUT_PORTS_END |
| 25 | 25 | |
| 26 | 26 | |
| 27 | static MACHINE_RESET(pipbug) | |
| 28 | { | |
| 27 | static MACHINE_RESET(pipbug) | |
| 28 | { | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | static VIDEO_START( pipbug ) |
| r8044 | r8045 | |
| 41 | 41 | /* basic machine hardware */ |
| 42 | 42 | MDRV_CPU_ADD("maincpu",S2650, XTAL_1MHz) |
| 43 | 43 | MDRV_CPU_PROGRAM_MAP(pipbug_mem) |
| 44 | MDRV_CPU_IO_MAP(pipbug_io) | |
| 44 | MDRV_CPU_IO_MAP(pipbug_io) | |
| 45 | 45 | |
| 46 | 46 | MDRV_MACHINE_RESET(pipbug) |
| 47 | ||
| 47 | ||
| 48 | 48 | /* video hardware */ |
| 49 | 49 | MDRV_SCREEN_ADD("screen", RASTER) |
| 50 | 50 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 68 | 68 | /* Driver */ |
| 69 | 69 | |
| 70 | 70 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 71 | COMP( 1979, pipbug, 0, 0, | |
| 71 | COMP( 1979, pipbug, 0, 0, | |
| 72 | 72 |
| r8044 | r8045 | |
|---|---|---|
| 877 | 877 | { |
| 878 | 878 | UINT8 *rom = memory_region(space->machine, "cart_img"); |
| 879 | 879 | |
| 880 | // | |
| 880 | // printf("%06x\n",rom_index[0]<<16|rom_index[1]<<8|rom_index[2]<<0); | |
| 881 | 881 | |
| 882 | 882 | return rom[rom_index[0]<<16|rom_index[1]<<8|rom_index[2]<<0]; |
| 883 | 883 | } |
| r8044 | r8045 | |
| 1958 | 1958 | { |
| 1959 | 1959 | { "x1kb" }, |
| 1960 | 1960 | { "ctc" }, |
| 1961 | ||
| 1961 | ||
| 1962 | 1962 | // { "sio" }, |
| 1963 | 1963 | { NULL } |
| 1964 | 1964 | }; |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | dolphin |
| 4 | 4 | |
| 5 | 5 | 08/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 12 | 12 | static ADDRESS_MAP_START(dolphin_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 13 | 13 | ADDRESS_MAP_UNMAP_HIGH |
| 14 | 14 | AM_RANGE( 0x0000, 0x00ff) AM_ROM |
| 15 | AM_RANGE( 0x0100, 0x7fff) AM_RAM | |
| 15 | AM_RANGE( 0x0100, 0x7fff) AM_RAM | |
| 16 | 16 | ADDRESS_MAP_END |
| 17 | 17 | |
| 18 | 18 | static ADDRESS_MAP_START( dolphin_io , ADDRESS_SPACE_IO, 8) |
| r8044 | r8045 | |
| 24 | 24 | INPUT_PORTS_END |
| 25 | 25 | |
| 26 | 26 | |
| 27 | static MACHINE_RESET(dolphin) | |
| 28 | { | |
| 27 | static MACHINE_RESET(dolphin) | |
| 28 | { | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | static VIDEO_START( dolphin ) |
| r8044 | r8045 | |
| 41 | 41 | /* basic machine hardware */ |
| 42 | 42 | MDRV_CPU_ADD("maincpu",S2650, XTAL_1MHz) |
| 43 | 43 | MDRV_CPU_PROGRAM_MAP(dolphin_mem) |
| 44 | MDRV_CPU_IO_MAP(dolphin_io) | |
| 44 | MDRV_CPU_IO_MAP(dolphin_io) | |
| 45 | 45 | |
| 46 | 46 | MDRV_MACHINE_RESET(dolphin) |
| 47 | ||
| 47 | ||
| 48 | 48 | /* video hardware */ |
| 49 | 49 | MDRV_SCREEN_ADD("screen", RASTER) |
| 50 | 50 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 68 | 68 | /* Driver */ |
| 69 | 69 | |
| 70 | 70 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 71 | COMP( 1979, dolphin, 0, 0, | |
| 71 | COMP( 1979, dolphin, 0, 0, | |
| 72 | 72 |
| r8044 | r8045 | |
|---|---|---|
| 383 | 383 | MDRV_CPU_PROGRAM_MAP(radio86rom_mem) |
| 384 | 384 | |
| 385 | 385 | MDRV_I8255A_ADD( "ppi8255_2", radio86_ppi8255_interface_2 ) |
| 386 | ||
| 386 | ||
| 387 | 387 | MDRV_CARTSLOT_ADD("cart") |
| 388 | 388 | MDRV_CARTSLOT_EXTENSION_LIST("bin,rom") |
| 389 | 389 | MDRV_CARTSLOT_NOT_MANDATORY |
| r8044 | r8045 | |
|---|---|---|
| 64 | 64 | static DEVICE_IMAGE_LOAD( advision_cart ) |
| 65 | 65 | { |
| 66 | 66 | UINT32 size; |
| 67 | ||
| 67 | ||
| 68 | 68 | if (image_software_entry(image) == NULL) |
| 69 | 69 | { |
| 70 | 70 | size = image_length(image); |
| r8044 | r8045 | |
| 74 | 74 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); |
| 75 | 75 | return INIT_FAIL; |
| 76 | 76 | } |
| 77 | ||
| 77 | ||
| 78 | 78 | if (image_fread(image, memory_region(image->machine, I8048_TAG), size) != size) |
| 79 | 79 | { |
| 80 | 80 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Unable to fully read from file"); |
| 81 | 81 | return INIT_FAIL; |
| 82 | 82 | } |
| 83 | ||
| 83 | ||
| 84 | 84 | } |
| 85 | 85 | else |
| 86 | 86 | { |
| r8044 | r8045 | |
|---|---|---|
| 150 | 150 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Option") PORT_CODE(KEYCODE_O) |
| 151 | 151 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Select") |
| 152 | 152 | // PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_R) Not implemented |
| 153 | ||
| 153 | ||
| 154 | 154 | PORT_START("controller1_col1") |
| 155 | 155 | PORT_BIT( 0xf0, 0xf0, IPT_UNUSED) |
| 156 | 156 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P1 Keypad 1") PORT_CODE(KEYCODE_1_PAD) |
| r8044 | r8045 | |
| 466 | 466 | if (image_software_entry(image) == NULL) |
| 467 | 467 | { |
| 468 | 468 | size = image_length(image); |
| 469 | ||
| 469 | ||
| 470 | 470 | if (size > memory_region_length(image->machine, "maincpu")) |
| 471 | 471 | size = memory_region_length(image->machine, "maincpu"); |
| 472 | ||
| 472 | ||
| 473 | 473 | if (image_fread(image, rom, size) != size) |
| 474 | 474 | return INIT_FAIL; |
| 475 | 475 | } |
| r8044 | r8045 | |
| 478 | 478 | size = image_get_software_region_length(image, "rom"); |
| 479 | 479 | memcpy(rom, image_get_software_region(image, "rom"), size); |
| 480 | 480 | } |
| 481 | ||
| 481 | ||
| 482 | 482 | if (size > 0x1000) |
| 483 | 483 | memmove(rom + 0x2000, rom + 0x1000, size - 0x1000); |
| 484 | ||
| 484 | ||
| 485 | 485 | if (size > 0x2000) |
| 486 | 486 | memmove(rom + 0x4000, rom + 0x3000, size - 0x2000); |
| 487 | 487 | |
| r8044 | r8045 | |
| 489 | 489 | // golf cartridge support |
| 490 | 490 | // 4kbyte at 0x0000 |
| 491 | 491 | // 2kbyte at 0x4000 |
| 492 | if (size <= 0x2000) | |
| 492 | if (size <= 0x2000) | |
| 493 | 493 | memcpy(rom + 0x4000, rom + 0x2000, 0x1000); |
| 494 | 494 | #else |
| 495 | 495 | /* this is a testpatch for the golf cartridge |
| r8044 | r8045 | |
| 522 | 522 | { 0x20ec,0x42,0x22 } |
| 523 | 523 | }; |
| 524 | 524 | |
| 525 | for (i = 0; i < ARRAY_LENGTH(patch); i++) | |
| 525 | for (i = 0; i < ARRAY_LENGTH(patch); i++) | |
| 526 | 526 | { |
| 527 | 527 | assert(rom[patch[i].address] == patch[i].old); |
| 528 | 528 | rom[patch[i].address] = patch[i].new; |
| r8044 | r8045 | |
|---|---|---|
| 62 | 62 | AM_RANGE( 0x40000, 0x41fff ) AM_ROM AM_REGION("maincpu",0x10000) //mirror |
| 63 | 63 | |
| 64 | 64 | AM_RANGE( 0x30000, 0x33fff ) AM_RAM AM_BASE(&m20_vram)//base vram |
| 65 | // AM_RANGE( 0x34000, 0x37fff ) AM_RAM //extra vram for bitmap mode | |
| 66 | // AM_RANGE( 0x20000, 0x2???? ) //work RAM? | |
| 65 | // AM_RANGE( 0x34000, 0x37fff ) AM_RAM //extra vram for bitmap mode | |
| 66 | // AM_RANGE( 0x20000, 0x2???? ) //work RAM? | |
| 67 | 67 | // |
| 68 | 68 | ADDRESS_MAP_END |
| 69 | 69 |
| r8044 | r8045 | |
|---|---|---|
| 182 | 182 | ------------------------ |
| 183 | 183 | |
| 184 | 184 | ZX Interface 1 |
| 185 | up to 8 Microdrives | |
| 186 | 1 RS-232 port | |
| 187 | 2 ZX Network ports - http://scratchpad.wikia.com/wiki/ZX_Net | |
| 185 | up to 8 Microdrives | |
| 186 | 1 RS-232 port | |
| 187 | 2 ZX Network ports - http://scratchpad.wikia.com/wiki/ZX_Net | |
| 188 | 188 | |
| 189 | 189 | Opus Discovery |
| 190 | up to 2 Disk drives | |
| 191 | 1 Centronics port | |
| 192 | 1 Joystick port (Kempston) | |
| 190 | up to 2 Disk drives | |
| 191 | 1 Centronics port | |
| 192 | 1 Joystick port (Kempston) | |
| 193 | 193 | |
| 194 | 194 | DISCiPLE Interface |
| 195 | up to 2 Disk drives | |
| 196 | 1 Centronics port | |
| 197 | 2 Joystick ports (RH: Sinclair/Kempston, LH: Sinclair) | |
| 198 | 2 ZX Network ports | |
| 195 | up to 2 Disk drives | |
| 196 | 1 Centronics port | |
| 197 | 2 Joystick ports (RH: Sinclair/Kempston, LH: Sinclair) | |
| 198 | 2 ZX Network ports | |
| 199 | 199 | |
| 200 | 200 | Plus D Interface |
| 201 | up to 2 Disk drives | |
| 202 | 1 Centronics port | |
| 201 | up to 2 Disk drives | |
| 202 | 1 Centronics port | |
| 203 | 203 | |
| 204 | 204 | Rotronics Wafadrive |
| 205 | 2 "Stringy" drives | |
| 206 | 1 RS-232 port | |
| 207 | 1 Centronics port | |
| 205 | 2 "Stringy" drives | |
| 206 | 1 RS-232 port | |
| 207 | 1 Centronics port | |
| 208 | 208 | |
| 209 | 209 | Kempston Disc Interface |
| 210 | ||
| 210 | up to 4 Disk drives (KDOS) | |
| 211 | 211 | |
| 212 | 212 | Beta 128 Disk Interface |
| 213 | ||
| 213 | up to 4 Disk drives (TR-DOS) | |
| 214 | 214 | |
| 215 | 215 | Philips Disc ROM |
| 216 | ||
| 216 | ??? | |
| 217 | 217 | |
| 218 | 218 | ---------------- |
| 219 | 219 | Game controllers |
| 220 | 220 | ---------------- |
| 221 | 221 | |
| 222 | 222 | ZX Interface 2 |
| 223 | 2 Joystick ports (Sinclair) | |
| 224 | 1 ROM slot | |
| 223 | 2 Joystick ports (Sinclair) | |
| 224 | 1 ROM slot | |
| 225 | 225 | |
| 226 | 226 | Kempston Interface |
| 227 | ||
| 227 | 1 Joystick port (Kempston) | |
| 228 | 228 | |
| 229 | 229 | Protek/AGF/Cursor Interface |
| 230 | ||
| 230 | 1 Joystick port (Protek) | |
| 231 | 231 | |
| 232 | 232 | Fuller Box |
| 233 | 1 Joystick port (Fuller) | |
| 234 | 1 G1-AY-3-8912 sound chip - the chip is identical to the one present on the 128 model, | |
| 235 | but the I/O ports are different: http://scratchpad.wikia.com/wiki/AY-3-8912(a) and | |
| 236 | http://scratchpad.wikia.com/wiki/Timex_2000_series#Sound_Chip | |
| 233 | 1 Joystick port (Fuller) | |
| 234 | 1 G1-AY-3-8912 sound chip - the chip is identical to the one present on the 128 model, | |
| 235 | but the I/O ports are different: http://scratchpad.wikia.com/wiki/AY-3-8912(a) and | |
| 236 | http://scratchpad.wikia.com/wiki/Timex_2000_series#Sound_Chip | |
| 237 | 237 | |
| 238 | 238 | Mikro-Plus Interface |
| 239 | 1 Joystick port (Mikrogen) | |
| 240 | 1 ROM slot - http://www.worldofspectrum.org/showmag.cgi?mag=Crash/Issue19/Pages/Crash1900020.jpg | |
| 239 | 1 Joystick port (Mikrogen) | |
| 240 | 1 ROM slot - http://www.worldofspectrum.org/showmag.cgi?mag=Crash/Issue19/Pages/Crash1900020.jpg | |
| 241 | 241 | |
| 242 | 242 | ------------ |
| 243 | 243 | Misc devices |
| r8044 | r8045 | |
| 255 | 255 | Speech synthesis thru allophones (SP0256-AL2) |
| 256 | 256 | |
| 257 | 257 | MGT Messenger |
| 258 | Allows connection between ZX Spectrum and SAM Coup | |
| 258 | Allows connection between ZX Spectrum and SAM Coup?? | |
| 259 | 259 | |
| 260 | 260 | Soft-ROM |
| 261 | 261 | A development system board - http://www.wearmouth.demon.co.uk/softrom.htm |
| r8044 | r8045 | |
| 437 | 437 | static ADDRESS_MAP_START (spectrum_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 438 | 438 | AM_RANGE(0x0000, 0x3fff) AM_ROM |
| 439 | 439 | AM_RANGE(0x4000, 0x5aff) AM_RAM AM_BASE_MEMBER(spectrum_state,video_ram) |
| 440 | // AM_RANGE(0x5b00, 0x7fff) AM_RAM | |
| 441 | // AM_RANGE(0x8000, 0xffff) AM_RAM | |
| 440 | // AM_RANGE(0x5b00, 0x7fff) AM_RAM | |
| 441 | // AM_RANGE(0x8000, 0xffff) AM_RAM | |
| 442 | 442 | ADDRESS_MAP_END |
| 443 | 443 | |
| 444 | 444 | /* ports are not decoded full. |
| r8044 | r8045 | |
|---|---|---|
| 824 | 824 | { |
| 825 | 825 | UINT32 size; |
| 826 | 826 | UINT8 *ptr = memory_region(image->machine, Z80_TAG); |
| 827 | ||
| 827 | ||
| 828 | 828 | if (image_software_entry(image) == NULL) |
| 829 | 829 | { |
| 830 | 830 | size = image_length(image); |
| r8044 | r8045 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | /* |
| 12 | 12 | |
| 13 | ||
| 13 | TODO: | |
| 14 | 14 | |
| 15 | - dumps of the internal ROMs | |
| 16 | - uPD7508 CPU core | |
| 17 | - keyboard | |
| 18 | - cassette | |
| 19 | - display | |
| 20 | - jumpers | |
| 21 | - ROM capsule | |
| 22 | - uPD7001 | |
| 23 | - RAM disk (64K/128K RAM, Z80, 4K ROM) | |
| 24 | - modem (82C55) | |
| 25 | - Multi-Unit (60K RAM, ROM capsule, modem, 82C55) | |
| 26 | - attach PF-10s | |
| 15 | - dumps of the internal ROMs | |
| 16 | - uPD7508 CPU core | |
| 17 | - keyboard | |
| 18 | - cassette | |
| 19 | - display | |
| 20 | - jumpers | |
| 21 | - ROM capsule | |
| 22 | - uPD7001 | |
| 23 | - RAM disk (64K/128K RAM, Z80, 4K ROM) | |
| 24 | - modem (82C55) | |
| 25 | - Multi-Unit (60K RAM, ROM capsule, modem, 82C55) | |
| 26 | - attach PF-10s | |
| 27 | 27 | |
| 28 | 28 | */ |
| 29 | 29 | |
| r8044 | r8045 | |
| 132 | 132 | case GAH40M_ICRL_C: |
| 133 | 133 | /* |
| 134 | 134 | |
| 135 | ||
| 135 | bit signal description | |
| 136 | 136 | |
| 137 | 0 ICR0 | |
| 138 | 1 ICR1 | |
| 139 | 2 ICR2 | |
| 140 | 3 ICR3 | |
| 141 | 4 ICR4 | |
| 142 | 5 ICR5 | |
| 143 | 6 ICR6 | |
| 144 | 7 ICR7 | |
| 137 | 0 ICR0 | |
| 138 | 1 ICR1 | |
| 139 | 2 ICR2 | |
| 140 | 3 ICR3 | |
| 141 | 4 ICR4 | |
| 142 | 5 ICR5 | |
| 143 | 6 ICR6 | |
| 144 | 7 ICR7 | |
| 145 | 145 | |
| 146 | ||
| 146 | */ | |
| 147 | 147 | break; |
| 148 | 148 | |
| 149 | 149 | case GAH40M_ICRH_C: |
| 150 | 150 | /* |
| 151 | 151 | |
| 152 | ||
| 152 | bit signal description | |
| 153 | 153 | |
| 154 | 0 ICR8 | |
| 155 | 1 ICR9 | |
| 156 | 2 ICR10 | |
| 157 | 3 ICR11 | |
| 158 | 4 ICR12 | |
| 159 | 5 ICR13 | |
| 160 | 6 ICR14 | |
| 161 | 7 ICR15 | |
| 154 | 0 ICR8 | |
| 155 | 1 ICR9 | |
| 156 | 2 ICR10 | |
| 157 | 3 ICR11 | |
| 158 | 4 ICR12 | |
| 159 | 5 ICR13 | |
| 160 | 6 ICR14 | |
| 161 | 7 ICR15 | |
| 162 | 162 | |
| 163 | ||
| 163 | */ | |
| 164 | 164 | break; |
| 165 | 165 | |
| 166 | 166 | case GAH40M_ICRL_B: |
| 167 | 167 | /* |
| 168 | 168 | |
| 169 | ||
| 169 | bit signal description | |
| 170 | 170 | |
| 171 | 0 ICR0 | |
| 172 | 1 ICR1 | |
| 173 | 2 ICR2 | |
| 174 | 3 ICR3 | |
| 175 | 4 ICR4 | |
| 176 | 5 ICR5 | |
| 177 | 6 ICR6 | |
| 178 | 7 ICR7 | |
| 171 | 0 ICR0 | |
| 172 | 1 ICR1 | |
| 173 | 2 ICR2 | |
| 174 | 3 ICR3 | |
| 175 | 4 ICR4 | |
| 176 | 5 ICR5 | |
| 177 | 6 ICR6 | |
| 178 | 7 ICR7 | |
| 179 | 179 | |
| 180 | ||
| 180 | */ | |
| 181 | 181 | break; |
| 182 | 182 | |
| 183 | 183 | case GAH40M_ICRH_B: |
| 184 | 184 | /* |
| 185 | 185 | |
| 186 | ||
| 186 | bit signal description | |
| 187 | 187 | |
| 188 | 0 ICR8 | |
| 189 | 1 ICR9 | |
| 190 | 2 ICR10 | |
| 191 | 3 ICR11 | |
| 192 | 4 ICR12 | |
| 193 | 5 ICR13 | |
| 194 | 6 ICR14 | |
| 195 | 7 ICR15 | |
| 188 | 0 ICR8 | |
| 189 | 1 ICR9 | |
| 190 | 2 ICR10 | |
| 191 | 3 ICR11 | |
| 192 | 4 ICR12 | |
| 193 | 5 ICR13 | |
| 194 | 6 ICR14 | |
| 195 | 7 ICR15 | |
| 196 | 196 | |
| 197 | ||
| 197 | */ | |
| 198 | 198 | break; |
| 199 | 199 | |
| 200 | 200 | case GAH40M_ISR: |
| 201 | 201 | /* |
| 202 | 202 | |
| 203 | ||
| 203 | bit signal description | |
| 204 | 204 | |
| 205 | 0 INT0 7508 interrupt (INT 7508) | |
| 206 | 1 INT1 82C51 interrupt (INT 82C51) | |
| 207 | 2 INT2 6303 interrupt (INT 6303) | |
| 208 | 3 INT3 input capture flag timer (CF) | |
| 209 | 4 INT4 overflow flag timer (OVF) | |
| 210 | 5 INT5 external interrupt (INTEXT) | |
| 211 | 6 | |
| 212 | 7 | |
| 205 | 0 INT0 7508 interrupt (INT 7508) | |
| 206 | 1 INT1 82C51 interrupt (INT 82C51) | |
| 207 | 2 INT2 6303 interrupt (INT 6303) | |
| 208 | 3 INT3 input capture flag timer (CF) | |
| 209 | 4 INT4 overflow flag timer (OVF) | |
| 210 | 5 INT5 external interrupt (INTEXT) | |
| 211 | 6 | |
| 212 | 7 | |
| 213 | 213 | |
| 214 | ||
| 214 | */ | |
| 215 | 215 | break; |
| 216 | 216 | |
| 217 | 217 | case GAH40M_STR: |
| 218 | 218 | /* |
| 219 | 219 | |
| 220 | ||
| 220 | bit signal description | |
| 221 | 221 | |
| 222 | 0 _BANK0 | |
| 223 | 1 BRDT barcode reader data timer | |
| 224 | 2 RDY ready (SIO) | |
| 225 | 3 RDYSIO SIO ready (SIO) | |
| 226 | 4 | |
| 227 | 5 | |
| 228 | 6 | |
| 229 | 7 | |
| 222 | 0 _BANK0 | |
| 223 | 1 BRDT barcode reader data timer | |
| 224 | 2 RDY ready (SIO) | |
| 225 | 3 RDYSIO SIO ready (SIO) | |
| 226 | 4 | |
| 227 | 5 | |
| 228 | 6 | |
| 229 | 7 | |
| 230 | 230 | |
| 231 | ||
| 231 | */ | |
| 232 | 232 | break; |
| 233 | 233 | |
| 234 | 234 | case GAH40M_SIOR: |
| 235 | 235 | /* |
| 236 | 236 | |
| 237 | ||
| 237 | bit signal description | |
| 238 | 238 | |
| 239 | 0 SIO0 | |
| 240 | 1 SIO1 | |
| 241 | 2 SIO2 | |
| 242 | 3 SIO3 | |
| 243 | 4 SIO4 | |
| 244 | 5 SIO5 | |
| 245 | 6 SIO6 | |
| 246 | 7 SIO7 | |
| 239 | 0 SIO0 | |
| 240 | 1 SIO1 | |
| 241 | 2 SIO2 | |
| 242 | 3 SIO3 | |
| 243 | 4 SIO4 | |
| 244 | 5 SIO5 | |
| 245 | 6 SIO6 | |
| 246 | 7 SIO7 | |
| 247 | 247 | |
| 248 | ||
| 248 | */ | |
| 249 | 249 | break; |
| 250 | 250 | |
| 251 | 251 | case GAH40M_IVR: |
| 252 | 252 | /* |
| 253 | 253 | |
| 254 | ||
| 254 | bit description | |
| 255 | 255 | |
| 256 | 0 0 | |
| 257 | 1 vect 1 | |
| 258 | 2 vect 2 | |
| 259 | 3 vect 3 | |
| 260 | 4 1 | |
| 261 | 5 1 | |
| 262 | 6 1 | |
| 263 | 7 1 | |
| 256 | 0 0 | |
| 257 | 1 vect 1 | |
| 258 | 2 vect 2 | |
| 259 | 3 vect 3 | |
| 260 | 4 1 | |
| 261 | 5 1 | |
| 262 | 6 1 | |
| 263 | 7 1 | |
| 264 | 264 | |
| 265 | ||
| 265 | */ | |
| 266 | 266 | break; |
| 267 | 267 | } |
| 268 | 268 | |
| r8044 | r8045 | |
| 282 | 282 | case GAH40M_CTLR1: |
| 283 | 283 | /* |
| 284 | 284 | |
| 285 | ||
| 285 | bit signal description | |
| 286 | 286 | |
| 287 | 0 _BANK0 bank switching | |
| 288 | 1 BCK0 barcode mode select 0 timer (down) | |
| 289 | 2 BCK1 barcode mode select 1 timer (up) | |
| 290 | 3 SWBCD barcode reader switch timer | |
| 291 | 4 BRG0 bad rate generator select 0 timer | |
| 292 | 5 BRG1 bad rate generator select 1 timer | |
| 293 | 6 BRG2 bad rate generator select 2 timer | |
| 294 | 7 BRG3 bad rate generator select 3 timer | |
| 287 | 0 _BANK0 bank switching | |
| 288 | 1 BCK0 barcode mode select 0 timer (down) | |
| 289 | 2 BCK1 barcode mode select 1 timer (up) | |
| 290 | 3 SWBCD barcode reader switch timer | |
| 291 | 4 BRG0 bad rate generator select 0 timer | |
| 292 | 5 BRG1 bad rate generator select 1 timer | |
| 293 | 6 BRG2 bad rate generator select 2 timer | |
| 294 | 7 BRG3 bad rate generator select 3 timer | |
| 295 | 295 | |
| 296 | ||
| 296 | */ | |
| 297 | 297 | |
| 298 | 298 | state->bank0 = BIT(data, 0); |
| 299 | 299 | bankswitch(space->machine); |
| r8044 | r8045 | |
| 302 | 302 | case GAH40M_CMDR: |
| 303 | 303 | /* |
| 304 | 304 | |
| 305 | ||
| 305 | bit description | |
| 306 | 306 | |
| 307 | 0 set RDYSIOFF (pulse) | |
| 308 | 1 reset RDYSIOFF (pulse) | |
| 309 | 2 reset OVF (pulse) | |
| 310 | 3 | |
| 311 | 4 | |
| 312 | 5 | |
| 313 | 6 | |
| 314 | 7 | |
| 307 | 0 set RDYSIOFF (pulse) | |
| 308 | 1 reset RDYSIOFF (pulse) | |
| 309 | 2 reset OVF (pulse) | |
| 310 | 3 | |
| 311 | 4 | |
| 312 | 5 | |
| 313 | 6 | |
| 314 | 7 | |
| 315 | 315 | |
| 316 | ||
| 316 | */ | |
| 317 | 317 | break; |
| 318 | 318 | |
| 319 | 319 | case GAH40M_CTLR2: |
| 320 | 320 | /* |
| 321 | 321 | |
| 322 | ||
| 322 | bit signal description | |
| 323 | 323 | |
| 324 | 0 LED0 LED | |
| 325 | 1 LED1 LED | |
| 326 | 2 LED2 LED | |
| 327 | 3 SWRS RS-232C switch | |
| 328 | 4 INHRS inhibit RS-232C | |
| 329 | 5 AUX external auxiliary output | |
| 330 | 6 | |
| 331 | 7 | |
| 324 | 0 LED0 LED | |
| 325 | 1 LED1 LED | |
| 326 | 2 LED2 LED | |
| 327 | 3 SWRS RS-232C switch | |
| 328 | 4 INHRS inhibit RS-232C | |
| 329 | 5 AUX external auxiliary output | |
| 330 | 6 | |
| 331 | 7 | |
| 332 | 332 | |
| 333 | ||
| 333 | */ | |
| 334 | 334 | |
| 335 | 335 | output_set_value("led_0", BIT(data, 0)); |
| 336 | 336 | output_set_value("led_1", BIT(data, 1)); |
| r8044 | r8045 | |
| 340 | 340 | case GAH40M_IER: |
| 341 | 341 | /* |
| 342 | 342 | |
| 343 | ||
| 343 | bit signal description | |
| 344 | 344 | |
| 345 | 0 IER0 INT 7508 enable | |
| 346 | 1 IER1 INT 82C51 enable | |
| 347 | 2 IER2 INT 6303 enable | |
| 348 | 3 IER3 INTICF enable | |
| 349 | 4 IER4 INTOVF enable | |
| 350 | 5 IER5 INTEXT enable | |
| 351 | 6 | |
| 352 | 7 | |
| 345 | 0 IER0 INT 7508 enable | |
| 346 | 1 IER1 INT 82C51 enable | |
| 347 | 2 IER2 INT 6303 enable | |
| 348 | 3 IER3 INTICF enable | |
| 349 | 4 IER4 INTOVF enable | |
| 350 | 5 IER5 INTEXT enable | |
| 351 | 6 | |
| 352 | 7 | |
| 353 | 353 | |
| 354 | ||
| 354 | */ | |
| 355 | 355 | |
| 356 | 356 | state->ier = data; |
| 357 | 357 | break; |
| r8044 | r8045 | |
| 359 | 359 | case GAH40M_SIOR: |
| 360 | 360 | /* |
| 361 | 361 | |
| 362 | ||
| 362 | bit signal description | |
| 363 | 363 | |
| 364 | 0 SIO0 | |
| 365 | 1 SIO1 | |
| 366 | 2 SIO2 | |
| 367 | 3 SIO3 | |
| 368 | 4 SIO4 | |
| 369 | 5 SIO5 | |
| 370 | 6 SIO6 | |
| 371 | 7 SIO7 | |
| 364 | 0 SIO0 | |
| 365 | 1 SIO1 | |
| 366 | 2 SIO2 | |
| 367 | 3 SIO3 | |
| 368 | 4 SIO4 | |
| 369 | 5 SIO5 | |
| 370 | 6 SIO6 | |
| 371 | 7 SIO7 | |
| 372 | 372 | |
| 373 | ||
| 373 | */ | |
| 374 | 374 | |
| 375 | 375 | state->sio = data; |
| 376 | 376 | break; |
| r8044 | r8045 | |
| 421 | 421 | case 1: /* command register */ |
| 422 | 422 | /* |
| 423 | 423 | |
| 424 | ||
| 424 | bit signal description | |
| 425 | 425 | |
| 426 | 0 SW PR PROM power switch | |
| 427 | 1 SW MCT microcassette power switch | |
| 428 | 2 MTA microcassette drive motor control signal A | |
| 429 | 3 MTB microcassette drive motor control signal B | |
| 430 | 4 MTC microcassette drive motor control signal C | |
| 431 | 5 | |
| 432 | 6 _FAST | |
| 433 | 7 _STOP CNT | |
| 426 | 0 SW PR PROM power switch | |
| 427 | 1 SW MCT microcassette power switch | |
| 428 | 2 MTA microcassette drive motor control signal A | |
| 429 | 3 MTB microcassette drive motor control signal B | |
| 430 | 4 MTC microcassette drive motor control signal C | |
| 431 | 5 | |
| 432 | 6 _FAST | |
| 433 | 7 _STOP CNT | |
| 434 | 434 | |
| 435 | ||
| 435 | */ | |
| 436 | 436 | |
| 437 | 437 | state->swpr = BIT(data, 0); |
| 438 | 438 | break; |
| r8044 | r8045 | |
| 550 | 550 | static ADDRESS_MAP_START( px8_slave_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 551 | 551 | ADDRESS_MAP_UNMAP_HIGH |
| 552 | 552 | AM_RANGE(0x0020, 0x0023) AM_READWRITE(gah40s_r, gah40s_w) |
| 553 | // | |
| 553 | // AM_RANGE(0x0024, 0x0027) AM_DEVREADWRITE(SED1320_TAG, ) | |
| 554 | 554 | AM_RANGE(0x0028, 0x0028) AM_WRITE(gah40s_ier_w) |
| 555 | 555 | AM_RANGE(0x8000, 0x97ff) AM_RAM AM_BASE_MEMBER(px8_state, video_ram) |
| 556 | 556 | AM_RANGE(0x9800, 0xefff) AM_NOP |
| r8044 | r8045 | |
| 563 | 563 | |
| 564 | 564 | static ADDRESS_MAP_START( px8_slave_io, ADDRESS_SPACE_IO, 8 ) |
| 565 | 565 | ADDRESS_MAP_UNMAP_HIGH |
| 566 | // AM_RANGE(M6803_PORT1, M6803_PORT1) | |
| 567 | // AM_RANGE(M6803_PORT2, M6803_PORT2) | |
| 568 | // AM_RANGE(M6803_PORT3, M6803_PORT3) | |
| 569 | // AM_RANGE(M6803_PORT4, M6803_PORT4) | |
| 566 | // AM_RANGE(M6803_PORT1, M6803_PORT1) | |
| 567 | // AM_RANGE(M6803_PORT2, M6803_PORT2) | |
| 568 | // AM_RANGE(M6803_PORT3, M6803_PORT3) | |
| 569 | // AM_RANGE(M6803_PORT4, M6803_PORT4) | |
| 570 | 570 | ADDRESS_MAP_END |
| 571 | 571 | |
| 572 | 572 | /*------------------------------------------------- |
| r8044 | r8045 | |
| 574 | 574 | -------------------------------------------------*/ |
| 575 | 575 | |
| 576 | 576 | static ADDRESS_MAP_START( px8_sub_io, ADDRESS_SPACE_IO, 8 ) |
| 577 | // | |
| 577 | // AM_RANGE(0x00, 0x00) AM_READWRITE() | |
| 578 | 578 | AM_RANGE(0x01, 0x01) AM_READ(krtn_0_3_r) |
| 579 | // | |
| 579 | // AM_RANGE(0x02, 0x02) AM_WRITE() | |
| 580 | 580 | AM_RANGE(0x03, 0x03) AM_WRITE(ksc_w) |
| 581 | // | |
| 581 | // AM_RANGE(0x04, 0x04) AM_WRITE() | |
| 582 | 582 | AM_RANGE(0x05, 0x05) AM_READ(krtn_4_7_r) |
| 583 | // AM_RANGE(0x06, 0x06) AM_READ() | |
| 584 | // AM_RANGE(0x07, 0x07) AM_WRITE() | |
| 583 | // AM_RANGE(0x06, 0x06) AM_READ() | |
| 584 | // AM_RANGE(0x07, 0x07) AM_WRITE() | |
| 585 | 585 | ADDRESS_MAP_END |
| 586 | 586 | |
| 587 | 587 | /*************************************************************************** |
| r8044 | r8045 | |
| 865 | 865 | |
| 866 | 866 | /* sub CPU (uPD7508) */ |
| 867 | 867 | // MDRV_CPU_ADD(UPD7508_TAG, UPD7508, 200000) /* 200 kHz */ |
| 868 | // MDRV_CPU_IO_MAP(px8_sub_io) | |
| 869 | // MDRV_CPU_FLAGS(CPU_DISABLE) | |
| 868 | // MDRV_CPU_IO_MAP(px8_sub_io) | |
| 869 | // MDRV_CPU_FLAGS(CPU_DISABLE) | |
| 870 | 870 | |
| 871 | 871 | MDRV_MACHINE_START(px8) |
| 872 | 872 | MDRV_MACHINE_RESET(px8) |
| r8044 | r8045 | |
| 937 | 937 | SYSTEM DRIVERS |
| 938 | 938 | ***************************************************************************/ |
| 939 | 939 | |
| 940 | /* YEAR NAME | |
| 940 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ | |
| 941 | 941 | COMP( 1984, px8, 0, 0, px8, px8, 0, "Epson", "PX-8", GAME_NOT_WORKING ) |
| r8044 | r8045 | |
|---|---|---|
| 8 | 8 | |
| 9 | 9 | /* |
| 10 | 10 | |
| 11 | ||
| 11 | http://www.geocities.jp/sanyo_phc_25/ | |
| 12 | 12 | |
| 13 | Z80 @ 4 MHz | |
| 14 | MC6847 video | |
| 15 | 3x 8KB bios ROM | |
| 16 | 1x 4KB chargen ROM | |
| 17 | 16KB RAM | |
| 18 | 6KB video RAM | |
| 13 | Z80 @ 4 MHz | |
| 14 | MC6847 video | |
| 15 | 3x 8KB bios ROM | |
| 16 | 1x 4KB chargen ROM | |
| 17 | 16KB RAM | |
| 18 | 6KB video RAM | |
| 19 | 19 | |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | 22 | /* |
| 23 | 23 | |
| 24 | ||
| 24 | TODO: | |
| 25 | 25 | |
| 26 | - MC6847 mode selection lines | |
| 27 | - tune cassette trigger level | |
| 28 | - accurate video timing | |
| 26 | - MC6847 mode selection lines | |
| 27 | - tune cassette trigger level | |
| 28 | - accurate video timing | |
| 29 | 29 | |
| 30 | 30 | */ |
| 31 | 31 | |
| r8044 | r8045 | |
| 44 | 44 | { |
| 45 | 45 | /* |
| 46 | 46 | |
| 47 | ||
| 47 | bit description | |
| 48 | 48 | |
| 49 | 0 | |
| 50 | 1 | |
| 51 | 2 | |
| 52 | 3 | |
| 53 | 4 vertical sync | |
| 54 | 5 cassette read | |
| 55 | 6 centronics busy | |
| 56 | 7 horizontal sync | |
| 49 | 0 | |
| 50 | 1 | |
| 51 | 2 | |
| 52 | 3 | |
| 53 | 4 vertical sync | |
| 54 | 5 cassette read | |
| 55 | 6 centronics busy | |
| 56 | 7 horizontal sync | |
| 57 | 57 | |
| 58 | ||
| 58 | */ | |
| 59 | 59 | |
| 60 | 60 | phc25_state *state = (phc25_state *)space->machine->driver_data; |
| 61 | 61 | |
| r8044 | r8045 | |
| 80 | 80 | { |
| 81 | 81 | /* |
| 82 | 82 | |
| 83 | ||
| 83 | bit description | |
| 84 | 84 | |
| 85 | 0 cassette output | |
| 86 | 1 cassette motor | |
| 87 | 2 MC6847 INT/EXT | |
| 88 | 3 centronics strobe | |
| 89 | 4 | |
| 90 | 5 MC6847 | |
| 91 | 6 MC6847 | |
| 92 | 7 MC6847 A/G | |
| 85 | 0 cassette output | |
| 86 | 1 cassette motor | |
| 87 | 2 MC6847 INT/EXT | |
| 88 | 3 centronics strobe | |
| 89 | 4 | |
| 90 | 5 MC6847 | |
| 91 | 6 MC6847 | |
| 92 | 7 MC6847 A/G | |
| 93 | 93 | |
| 94 | ||
| 94 | */ | |
| 95 | 95 | |
| 96 | 96 | phc25_state *state = (phc25_state *)space->machine->driver_data; |
| 97 | 97 | |
| r8044 | r8045 | |
| 146 | 146 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') |
| 147 | 147 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') |
| 148 | 148 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') |
| 149 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) | |
| 149 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) | |
| 150 | 150 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 151 | 151 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') |
| 152 | 152 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) // unlabeled key |
| r8044 | r8045 | |
| 215 | 215 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') |
| 216 | 216 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') |
| 217 | 217 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') |
| 218 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') | |
| 218 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') | |
| 219 | 219 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 220 | 220 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') |
| 221 | 221 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') |
| r8044 | r8045 | |
| 344 | 344 | state->cassette = devtag_get_device(machine, CASSETTE_TAG); |
| 345 | 345 | |
| 346 | 346 | /* register for state saving */ |
| 347 | // | |
| 347 | // state_save_register_global(machine, state->); | |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | 350 | /* Machine Driver */ |
| r8044 | r8045 | |
| 371 | 371 | /* devices */ |
| 372 | 372 | MDRV_CASSETTE_ADD(CASSETTE_TAG, phc25_cassette_config) |
| 373 | 373 | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics) |
| 374 | ||
| 374 | ||
| 375 | 375 | /* internal ram */ |
| 376 | 376 | MDRV_RAM_ADD("messram") |
| 377 | 377 | MDRV_RAM_DEFAULT_SIZE("16K") |
| r8044 | r8045 | |
| 438 | 438 | |
| 439 | 439 | /* Driver */ |
| 440 | 440 | |
| 441 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME | |
| 441 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ | |
| 442 | 442 | COMP( 1983, phc25, 0, 0, pal, phc25, 0, "Sanyo", "PHC-25 (Europe)", GAME_NOT_WORKING ) |
| 443 | 443 | COMP( 1983, phc25j, phc25, 0, ntsc, phc25j, 0, "Sanyo", "PHC-25 (Japan)", GAME_NOT_WORKING ) |
| r8044 | r8045 | |
|---|---|---|
| 292 | 292 | PORT_CONFNAME( 0x01, 0x00, "SID Card Address") |
| 293 | 293 | PORT_CONFSETTING( 0x00, "0xfd40" ) |
| 294 | 294 | PORT_CONFSETTING( 0x01, "0xfe80" ) |
| 295 | #if 0 | |
| 295 | #if 0 | |
| 296 | 296 | PORT_CONFNAME( 0x02, 0x00, "Enable SID writes to 0xd400") |
| 297 | 297 | PORT_CONFSETTING( 0x00, DEF_STR( No ) ) |
| 298 | 298 | PORT_CONFSETTING( 0x02, DEF_STR( Yes ) ) |
| r8044 | r8045 | |
| 307 | 307 | PORT_CONFNAME( 0x01, 0x00, "SID Card Address") |
| 308 | 308 | PORT_CONFSETTING( 0x00, "0xfd40" ) |
| 309 | 309 | PORT_CONFSETTING( 0x01, "0xfe80" ) |
| 310 | #if 0 | |
| 310 | #if 0 | |
| 311 | 311 | PORT_CONFNAME( 0x02, 0x00, "Enable SID writes to 0xd400") |
| 312 | 312 | PORT_CONFSETTING( 0x00, DEF_STR( No ) ) |
| 313 | 313 | PORT_CONFSETTING( 0x02, DEF_STR( Yes ) ) |
| r8044 | r8045 | |
| 374 | 374 | { |
| 375 | 375 | int i; |
| 376 | 376 | |
| 377 | for (i = 0; i < sizeof(ted7360_palette) / 3; i++) | |
| 377 | for (i = 0; i < sizeof(ted7360_palette) / 3; i++) | |
| 378 | 378 | palette_set_color_rgb(machine, i, ted7360_palette[i * 3], ted7360_palette[i * 3 + 1], ted7360_palette[i * 3 + 2]); |
| 379 | 379 | } |
| 380 | 380 |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | chaos |
| 4 | 4 | |
| 5 | 5 | 08/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 25 | 25 | INPUT_PORTS_END |
| 26 | 26 | |
| 27 | 27 | |
| 28 | static MACHINE_RESET(chaos) | |
| 29 | { | |
| 28 | static MACHINE_RESET(chaos) | |
| 29 | { | |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | static VIDEO_START( chaos ) |
| r8044 | r8045 | |
| 42 | 42 | /* basic machine hardware */ |
| 43 | 43 | MDRV_CPU_ADD("maincpu",S2650, XTAL_1MHz) |
| 44 | 44 | MDRV_CPU_PROGRAM_MAP(chaos_mem) |
| 45 | MDRV_CPU_IO_MAP(chaos_io) | |
| 45 | MDRV_CPU_IO_MAP(chaos_io) | |
| 46 | 46 | |
| 47 | 47 | MDRV_MACHINE_RESET(chaos) |
| 48 | ||
| 48 | ||
| 49 | 49 | /* video hardware */ |
| 50 | 50 | MDRV_SCREEN_ADD("screen", RASTER) |
| 51 | 51 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 72 | 72 | /* Driver */ |
| 73 | 73 | |
| 74 | 74 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 75 | COMP( 1983, chaos, 0, 0, chaos, | |
| 75 | COMP( 1983, chaos, 0, 0, chaos, | |
| 76 | 76 |
| r8044 | r8045 | |
|---|---|---|
| 964 | 964 | ROM_LOAD16_BYTE( "cpu-card_27c256_016.rom", 0xf0001, 0x8000, CRC(bc3924d6) SHA1(596be415e6c2bc4ff30a187f146664531565712c)) |
| 965 | 965 | ROM_LOAD16_BYTE( "video-card_573rf6( 2764)_040.rom", 0xc0001, 0x2000, CRC(a3ece315) SHA1(e800e11c3b1b6fcaf41bfb7d4058a9d34fdd2b3f)) |
| 966 | 966 | ROM_LOAD16_BYTE( "video-card_573rf6( 2764)_041.rom", 0xc0000, 0x2000, CRC(b0a2ba7f) SHA1(c8160e8bc97cd391558f1dddd3fd3ec4a19d030c)) |
| 967 | ||
| 967 | ||
| 968 | 968 | ROM_REGION(0x08100, "gfx1", 0) |
| 969 | 969 | ROM_LOAD("cga.chr", 0x00000, 0x01000, CRC(42009069) SHA1(ed08559ce2d7f97f68b9f540bddad5b6295294dd)) |
| 970 | 970 | |
| 971 | 971 | ROM_REGION(0x50000, "gfx2", ROMREGION_ERASE00) |
| 972 | ||
| 972 | ||
| 973 | 973 | /* 8042 keyboard controller */ |
| 974 | 974 | ROM_REGION( 0x0800, "kbdc8042", 0 ) |
| 975 | 975 | ROM_LOAD("1503033.bin", 0x0000, 0x0800, CRC(5a81c0d2) SHA1(0100f8789fb4de74706ae7f9473a12ec2b9bd729)) |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | Chromatics CGC 7900 |
| 4 | 4 | |
| 5 | 5 | 05/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 8 | 8 | |
| 9 | 9 | /* |
| 10 | 10 | |
| 11 | ||
| 11 | TODO: | |
| 12 | 12 | |
| 13 | - does not boot | |
| 14 | - interrupts | |
| 15 | - vsync interrupt | |
| 16 | - map ROM to 000000-000007 at boot | |
| 17 | - floppy | |
| 18 | - bitmap display | |
| 19 | - Z mode read/write | |
| 20 | - color status write | |
| 21 | - bitmap roll | |
| 22 | - overlay roll | |
| 23 | - keyboard | |
| 24 | - joystick | |
| 25 | - light pen | |
| 26 | - memory parity | |
| 27 | - sync | |
| 28 | - disk DMA | |
| 29 | - PIO DMA | |
| 30 | - serial port controller | |
| 31 | - HVG | |
| 32 | - OMTI Series 10 SCSI controller (8" Winchester HD) | |
| 13 | - does not boot | |
| 14 | - interrupts | |
| 15 | - vsync interrupt | |
| 16 | - map ROM to 000000-000007 at boot | |
| 17 | - floppy | |
| 18 | - bitmap display | |
| 19 | - Z mode read/write | |
| 20 | - color status write | |
| 21 | - bitmap roll | |
| 22 | - overlay roll | |
| 23 | - keyboard | |
| 24 | - joystick | |
| 25 | - light pen | |
| 26 | - memory parity | |
| 27 | - sync | |
| 28 | - disk DMA | |
| 29 | - PIO DMA | |
| 30 | - serial port controller | |
| 31 | - HVG | |
| 32 | - OMTI Series 10 SCSI controller (8" Winchester HD) | |
| 33 | 33 | |
| 34 | 34 | */ |
| 35 | 35 | |
| r8044 | r8045 | |
| 81 | 81 | { |
| 82 | 82 | /* |
| 83 | 83 | |
| 84 | bit description | |
| 85 | ||
| 86 | 0 key data bit 0 | |
| 87 | 1 key data bit 1 | |
| 88 | 2 key data bit 2 | |
| 89 | 3 key data bit 3 | |
| 90 | 4 key data bit 4 | |
| 91 | 5 key data bit 5 | |
| 92 | 6 key data bit 6 | |
| 93 | 7 key data bit 7 | |
| 94 | 8 SHIFT key | |
| 95 | 9 CTRL key | |
| 96 | 10 M1 key | |
| 97 | 11 M2 key | |
| 98 | 12 | |
| 99 | 13 | |
| 100 | 14 | |
| 101 | 15 | |
| 84 | bit description | |
| 102 | 85 | |
| 103 | */ | |
| 86 | 0 key data bit 0 | |
| 87 | 1 key data bit 1 | |
| 88 | 2 key data bit 2 | |
| 89 | 3 key data bit 3 | |
| 90 | 4 key data bit 4 | |
| 91 | 5 key data bit 5 | |
| 92 | 6 key data bit 6 | |
| 93 | 7 key data bit 7 | |
| 94 | 8 SHIFT key | |
| 95 | 9 CTRL key | |
| 96 | 10 M1 key | |
| 97 | 11 M2 key | |
| 98 | 12 | |
| 99 | 13 | |
| 100 | 14 | |
| 101 | 15 | |
| 104 | 102 | |
| 103 | */ | |
| 104 | ||
| 105 | 105 | return 0; |
| 106 | 106 | } |
| 107 | 107 | |
| r8044 | r8045 | |
| 113 | 113 | { |
| 114 | 114 | /* |
| 115 | 115 | |
| 116 | bit description | |
| 117 | ||
| 118 | 0 LED select bit 0 | |
| 119 | 1 LED select bit 1 | |
| 120 | 2 LED select bit 2 | |
| 121 | 3 LED select bit 3 | |
| 122 | 4 LED select bit 4 | |
| 123 | 5 | |
| 124 | 6 | |
| 125 | 7 LED switch (1=on, 0=off) | |
| 126 | 8 | |
| 127 | 9 | |
| 128 | 10 | |
| 129 | 11 | |
| 130 | 12 | |
| 131 | 13 | |
| 132 | 14 | |
| 133 | 15 | |
| 116 | bit description | |
| 134 | 117 | |
| 135 | */ | |
| 118 | 0 LED select bit 0 | |
| 119 | 1 LED select bit 1 | |
| 120 | 2 LED select bit 2 | |
| 121 | 3 LED select bit 3 | |
| 122 | 4 LED select bit 4 | |
| 123 | 5 | |
| 124 | 6 | |
| 125 | 7 LED switch (1=on, 0=off) | |
| 126 | 8 | |
| 127 | 9 | |
| 128 | 10 | |
| 129 | 11 | |
| 130 | 12 | |
| 131 | 13 | |
| 132 | 14 | |
| 133 | 15 | |
| 134 | ||
| 135 | */ | |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | 138 | /*------------------------------------------------- |
| r8044 | r8045 | |
| 143 | 143 | { |
| 144 | 144 | /* |
| 145 | 145 | |
| 146 | bit description | |
| 147 | ||
| 148 | 0 real time clock | |
| 149 | 1 RS-449 Tx ready | |
| 150 | 2 BINT 2 | |
| 151 | 3 RS-232 Tx ready | |
| 152 | 4 disk | |
| 153 | 5 BINT 3 | |
| 154 | 6 bezel keys | |
| 155 | 7 keyboard | |
| 156 | 8 RS-449 Rx ready | |
| 157 | 9 light pen | |
| 158 | 10 BINT 4 | |
| 159 | 11 joystick | |
| 160 | 12 vertical retrace | |
| 161 | 13 BINT 5 | |
| 162 | 14 BINT 1 | |
| 163 | 15 RS-232 Rx ready | |
| 146 | bit description | |
| 164 | 147 | |
| 165 | */ | |
| 148 | 0 real time clock | |
| 149 | 1 RS-449 Tx ready | |
| 150 | 2 BINT 2 | |
| 151 | 3 RS-232 Tx ready | |
| 152 | 4 disk | |
| 153 | 5 BINT 3 | |
| 154 | 6 bezel keys | |
| 155 | 7 keyboard | |
| 156 | 8 RS-449 Rx ready | |
| 157 | 9 light pen | |
| 158 | 10 BINT 4 | |
| 159 | 11 joystick | |
| 160 | 12 vertical retrace | |
| 161 | 13 BINT 5 | |
| 162 | 14 BINT 1 | |
| 163 | 15 RS-232 Rx ready | |
| 166 | 164 | |
| 165 | */ | |
| 166 | ||
| 167 | 167 | cgc7900_state *state = (cgc7900_state *)space->machine->driver_data; |
| 168 | 168 | |
| 169 | 169 | state->int_mask = data; |
| r8044 | r8045 | |
| 193 | 193 | { |
| 194 | 194 | /* |
| 195 | 195 | |
| 196 | bit signal description | |
| 197 | ||
| 198 | 0 _I/O input/output | |
| 199 | 1 _REQ request | |
| 200 | 2 _BSY busy | |
| 201 | 3 C/_D control/data | |
| 202 | 4 _MSG message | |
| 203 | 5 _RDY ready | |
| 204 | 6 | |
| 205 | 7 | |
| 206 | 8 | |
| 207 | 9 | |
| 208 | 10 | |
| 209 | 11 | |
| 210 | 12 | |
| 211 | 13 | |
| 212 | 14 | |
| 213 | 15 | |
| 196 | bit signal description | |
| 214 | 197 | |
| 215 | */ | |
| 198 | 0 _I/O input/output | |
| 199 | 1 _REQ request | |
| 200 | 2 _BSY busy | |
| 201 | 3 C/_D control/data | |
| 202 | 4 _MSG message | |
| 203 | 5 _RDY ready | |
| 204 | 6 | |
| 205 | 7 | |
| 206 | 8 | |
| 207 | 9 | |
| 208 | 10 | |
| 209 | 11 | |
| 210 | 12 | |
| 211 | 13 | |
| 212 | 14 | |
| 213 | 15 | |
| 216 | 214 | |
| 215 | */ | |
| 216 | ||
| 217 | 217 | return 0xffff - 0x04; |
| 218 | 218 | } |
| 219 | 219 | |
| r8044 | r8045 | |
| 236 | 236 | static ADDRESS_MAP_START( cgc7900_mem, ADDRESS_SPACE_PROGRAM, 16 ) |
| 237 | 237 | ADDRESS_MAP_UNMAP_HIGH |
| 238 | 238 | AM_RANGE(0x000000, 0x1fffff) AM_RAM AM_BASE(&chrom_ram) |
| 239 | AM_RANGE(0x800000, 0x80ffff) AM_ROM AM_REGION(M68000_TAG, 0) | |
| 239 | AM_RANGE(0x800000, 0x80ffff) AM_ROM AM_REGION(M68000_TAG, 0) | |
| 240 | 240 | AM_RANGE(0xa00000, 0xbfffff) AM_READWRITE(cgc7900_z_mode_r, cgc7900_z_mode_w) |
| 241 | 241 | AM_RANGE(0xc00000, 0xdfffff) AM_RAM AM_BASE_MEMBER(cgc7900_state, plane_ram) |
| 242 | 242 | AM_RANGE(0xe00000, 0xe1ffff) AM_WRITE(cgc7900_color_status_w) |
| 243 | // | |
| 243 | // AM_RANGE(0xe20000, 0xe23fff) Raster Processor | |
| 244 | 244 | AM_RANGE(0xe30000, 0xe303ff) AM_RAM AM_BASE_MEMBER(cgc7900_state, clut_ram) |
| 245 | 245 | AM_RANGE(0xe38000, 0xe3bfff) AM_RAM AM_BASE_MEMBER(cgc7900_state, overlay_ram) |
| 246 | 246 | AM_RANGE(0xe40000, 0xe40001) AM_RAM AM_BASE_MEMBER(cgc7900_state, roll_bitmap) |
| r8044 | r8045 | |
| 256 | 256 | AM_RANGE(0xe40018, 0xe40019) AM_RAM AM_BASE_MEMBER(cgc7900_state, color_status_bg) |
| 257 | 257 | AM_RANGE(0xe4001a, 0xe4001b) AM_RAM AM_BASE_MEMBER(cgc7900_state, roll_overlay) |
| 258 | 258 | AM_RANGE(0xe4001c, 0xe40fff) AM_RAM |
| 259 | // AM_RANGE(0xefc440, 0xefc441) HVG Load X | |
| 260 | // AM_RANGE(0xefc442, 0xefc443) HVG Load Y | |
| 261 | // AM_RANGE(0xefc444, 0xefc445) HVG Load dX | |
| 262 | // AM_RANGE(0xefc446, 0xefc447) HVG Load dY | |
| 263 | // AM_RANGE(0xefc448, 0xefc449) HVG Load Pixel Color | |
| 264 | // AM_RANGE(0xefc44a, 0xefc44b) HVG Load Trip | |
| 259 | // AM_RANGE(0xefc440, 0xefc441) HVG Load X | |
| 260 | // AM_RANGE(0xefc442, 0xefc443) HVG Load Y | |
| 261 | // AM_RANGE(0xefc444, 0xefc445) HVG Load dX | |
| 262 | // AM_RANGE(0xefc446, 0xefc447) HVG Load dY | |
| 263 | // AM_RANGE(0xefc448, 0xefc449) HVG Load Pixel Color | |
| 264 | // AM_RANGE(0xefc44a, 0xefc44b) HVG Load Trip | |
| 265 | 265 | AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8(INS8251_0_TAG, msm8251_data_r, msm8251_data_w, 0xff00) |
| 266 | 266 | AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE8(INS8251_0_TAG, msm8251_status_r, msm8251_control_w, 0xff00) |
| 267 | 267 | AM_RANGE(0xff8040, 0xff8041) AM_DEVREADWRITE8(INS8251_1_TAG, msm8251_data_r, msm8251_data_w, 0xff00) |
| 268 | 268 | AM_RANGE(0xff8042, 0xff8043) AM_DEVREADWRITE8(INS8251_1_TAG, msm8251_status_r, msm8251_control_w, 0xff00) |
| 269 | 269 | AM_RANGE(0xff8080, 0xff8081) AM_READWRITE(keyboard_r, keyboard_w) |
| 270 | // AM_RANGE(0xff80c6, 0xff80c7) Joystick X axis | |
| 271 | // AM_RANGE(0xff80ca, 0xff80cb) Joystick Y axis | |
| 272 | // AM_RANGE(0xff80cc, 0xff80cd) Joystick Z axis | |
| 270 | // AM_RANGE(0xff80c6, 0xff80c7) Joystick X axis | |
| 271 | // AM_RANGE(0xff80ca, 0xff80cb) Joystick Y axis | |
| 272 | // AM_RANGE(0xff80cc, 0xff80cd) Joystick Z axis | |
| 273 | 273 | AM_RANGE(0xff8100, 0xff8101) AM_READWRITE(disk_data_r, disk_data_w) |
| 274 | 274 | AM_RANGE(0xff8120, 0xff8121) AM_READWRITE(disk_status_r, disk_command_w) |
| 275 | 275 | AM_RANGE(0xff8140, 0xff8141) AM_READ_PORT("BEZEL") |
| 276 | // AM_RANGE(0xff8180, 0xff8181) AM_DEVWRITE8(K1135A_TAG, k1135a_w, 0xff00) Baud rate generator | |
| 277 | // AM_RANGE(0xff81c0, 0xff81ff) AM_DEVREADWRITE8(MM58167_TAG, mm58167_r, mm58167_w, 0xff00) | |
| 276 | // AM_RANGE(0xff8180, 0xff8181) AM_DEVWRITE8(K1135A_TAG, k1135a_w, 0xff00) Baud rate generator | |
| 277 | // AM_RANGE(0xff81c0, 0xff81ff) AM_DEVREADWRITE8(MM58167_TAG, mm58167_r, mm58167_w, 0xff00) | |
| 278 | 278 | AM_RANGE(0xff8200, 0xff8201) AM_WRITE(interrupt_mask_w) |
| 279 | // AM_RANGE(0xff8240, 0xff8241) Light Pen enable | |
| 280 | // AM_RANGE(0xff8242, 0xff8243) Light Pen X value | |
| 281 | // AM_RANGE(0xff8244, 0xff8245) Light Pen Y value | |
| 282 | // AM_RANGE(0xff8246, 0xff8247) Buffer memory parity check | |
| 283 | // AM_RANGE(0xff8248, 0xff8249) Buffer memory parity set/reset | |
| 279 | // AM_RANGE(0xff8240, 0xff8241) Light Pen enable | |
| 280 | // AM_RANGE(0xff8242, 0xff8243) Light Pen X value | |
| 281 | // AM_RANGE(0xff8244, 0xff8245) Light Pen Y value | |
| 282 | // AM_RANGE(0xff8246, 0xff8247) Buffer memory parity check | |
| 283 | // AM_RANGE(0xff8248, 0xff8249) Buffer memory parity set/reset | |
| 284 | 284 | AM_RANGE(0xff824a, 0xff824b) AM_READ(cgc7900_sync_r) |
| 285 | 285 | AM_RANGE(0xff83c0, 0xff83c1) AM_DEVWRITE8(AY8910_TAG, ay8910_address_w, 0xff00) |
| 286 | 286 | AM_RANGE(0xff83c2, 0xff83c3) AM_DEVREAD8(AY8910_TAG, ay8910_r, 0xff00) |
| 287 | 287 | AM_RANGE(0xff83c4, 0xff83c5) AM_DEVWRITE8(AY8910_TAG, ay8910_data_w, 0xff00) |
| 288 | // AM_RANGE(0xff8500, 0xff8501) Disk DMA Command Register | |
| 289 | // AM_RANGE(0xff8502, 0xff8503) Disk DMA Address Register | |
| 290 | // AM_RANGE(0xff8507, 0xff8507) Disk DMA Control/Status Register | |
| 288 | // AM_RANGE(0xff8500, 0xff8501) Disk DMA Command Register | |
| 289 | // AM_RANGE(0xff8502, 0xff8503) Disk DMA Address Register | |
| 290 | // AM_RANGE(0xff8507, 0xff8507) Disk DMA Control/Status Register | |
| 291 | 291 | ADDRESS_MAP_END |
| 292 | 292 | |
| 293 | 293 | /*------------------------------------------------- |
| r8044 | r8045 | |
| 303 | 303 | -------------------------------------------------*/ |
| 304 | 304 | |
| 305 | 305 | static ADDRESS_MAP_START( keyboard_io, ADDRESS_SPACE_IO, 8 ) |
| 306 | /* AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) | |
| 307 | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) | |
| 308 | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) | |
| 309 | AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS)*/ | |
| 306 | /* AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) | |
| 307 | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) | |
| 308 | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) | |
| 309 | AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS)*/ | |
| 310 | 310 | ADDRESS_MAP_END |
| 311 | 311 | |
| 312 | 312 | /*************************************************************************** |
| r8044 | r8045 | |
| 404 | 404 | MACHINE_RESET( cgc7900 ) |
| 405 | 405 | -------------------------------------------------*/ |
| 406 | 406 | |
| 407 | static MACHINE_RESET(cgc7900) | |
| 407 | static MACHINE_RESET(cgc7900) | |
| 408 | 408 | { |
| 409 | 409 | UINT8* user1 = memory_region(machine, M68000_TAG); |
| 410 | 410 | |
| r8044 | r8045 | |
| 428 | 428 | MDRV_CPU_ADD(M68000_TAG, M68000, XTAL_28_48MHz/4) |
| 429 | 429 | MDRV_CPU_PROGRAM_MAP(cgc7900_mem) |
| 430 | 430 | |
| 431 | /* | |
| 431 | /* MDRV_CPU_ADD(I8035_TAG, I8035, 1000000) | |
| 432 | 432 | MDRV_CPU_PROGRAM_MAP(keyboard_mem) |
| 433 | ||
| 433 | MDRV_CPU_IO_MAP(keyboard_io)*/ | |
| 434 | 434 | |
| 435 | /* | |
| 435 | /* MDRV_CPU_ADD(AM2910_TAG, AM2910, XTAL_17_36MHz) | |
| 436 | 436 | MDRV_CPU_PROGRAM_MAP(omti10_mem)*/ |
| 437 | 437 | |
| 438 | 438 | MDRV_MACHINE_START(cgc7900) |
| 439 | 439 | MDRV_MACHINE_RESET(cgc7900) |
| 440 | ||
| 440 | ||
| 441 | 441 | /* video hardware */ |
| 442 | 442 | MDRV_IMPORT_FROM(cgc7900_video) |
| 443 | 443 | |
| r8044 | r8045 | |
| 471 | 471 | ROM_LOAD16_BYTE( "210258 80ak even b2f6 mon 1.3.ue15", 0xa000, 0x1000, CRC(ec5a1250) SHA1(ffef73d35f172ac610b35bdf729d51eb6f9346ba) ) |
| 472 | 472 | ROM_LOAD16_BYTE( "210259 80ak odd cd66 mon 1.3.uf15", 0xa001, 0x1000, CRC(61eb43c6) SHA1(baaae0b787798147da453aac1f815589ea4ed921) ) |
| 473 | 473 | ROM_LOAD16_BYTE( "210244 80c even ce40 dos 1.6b.ue13", 0xc000, 0x1000, CRC(3b64e4cb) SHA1(71b28d160b101ea6165e602ff1c54272b7b30ece) ) |
| 474 | ROM_LOAD16_BYTE( "210245 80c odd 1ac3 dos 1.6b.uf13", 0xc001, 0x1000, CRC(0b6539ca) SHA1(d49e6d3307e5d634a412fd80b59492f31e29f7e0) ) | |
| 474 | ROM_LOAD16_BYTE( "210245 80c odd 1ac3 dos 1.6b.uf13", 0xc001, 0x1000, CRC(0b6539ca) SHA1(d49e6d3307e5d634a412fd80b59492f31e29f7e0) ) | |
| 475 | 475 | ROM_LOAD16_BYTE( "210290 idris even rel3 sum 0cce.ue12", 0xe000, 0x1000, CRC(07065772) SHA1(620ea5d55021e5c38efc010722ddbd852cd49e39) ) |
| 476 | 476 | ROM_LOAD16_BYTE( "210291 idris odd rel3 sum 5d11.uf12", 0xe001, 0x1000, CRC(d81b30da) SHA1(228f9b4e39d430ce4aaa81ea63f4516a51e6d001) ) |
| 477 | 477 | |
| 478 | 478 | ROM_REGION( 0x800, "i8035", 0 ) |
| 479 | 479 | ROM_LOAD( "keyboard controller i8035", 0x0000, 0x0800, NO_DUMP ) |
| 480 | ||
| 480 | ||
| 481 | 481 | ROM_REGION( 0x800, "gfx1", 0 ) |
| 482 | 482 | ROM_LOAD( "norm chrset 4b40.ua13", 0x0000, 0x0400, CRC(55eb7b87) SHA1(768cea80597e7396d9e26f8cd09e6b480a526fce) ) |
| 483 | 483 | ROM_LOAD( "alt 46a7.ua14", 0x0400, 0x0400, CRC(be22b7e4) SHA1(83ef252c7fab33b4d3821a3049b89d044df35de8) ) |
| r8044 | r8045 | |
| 503 | 503 | SYSTEM DRIVERS |
| 504 | 504 | ***************************************************************************/ |
| 505 | 505 | |
| 506 | /* YEAR NAME | |
| 506 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ | |
| 507 | 507 | COMP( 1980, cgc7900, 0, 0, cgc7900, cgc7900, 0, "Chromatics", "CGC 7900", GAME_NOT_WORKING) |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | Z80 dev board (uknown) |
| 4 | ||
| 5 | http://retro.hansotten.nl/index.php?page=z80-dev-kit | |
| 6 | 4 | |
| 5 | http://retro.hansotten.nl/index.php?page=z80-dev-kit | |
| 6 | ||
| 7 | 7 | 23/04/2010 Skeleton driver. |
| 8 | 8 | |
| 9 | 9 | ****************************************************************************/ |
| r8044 | r8045 | |
| 26 | 26 | INPUT_PORTS_END |
| 27 | 27 | |
| 28 | 28 | |
| 29 | static MACHINE_RESET(z80dev) | |
| 30 | { | |
| 29 | static MACHINE_RESET(z80dev) | |
| 30 | { | |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | static VIDEO_START( z80dev ) |
| r8044 | r8045 | |
| 43 | 43 | /* basic machine hardware */ |
| 44 | 44 | MDRV_CPU_ADD("maincpu",Z80, XTAL_4MHz) |
| 45 | 45 | MDRV_CPU_PROGRAM_MAP(z80dev_mem) |
| 46 | MDRV_CPU_IO_MAP(z80dev_io) | |
| 46 | MDRV_CPU_IO_MAP(z80dev_io) | |
| 47 | 47 | |
| 48 | 48 | MDRV_MACHINE_RESET(z80dev) |
| 49 | ||
| 49 | ||
| 50 | 50 | /* video hardware */ |
| 51 | 51 | MDRV_SCREEN_ADD("screen", RASTER) |
| 52 | 52 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 70 | 70 | /* Driver */ |
| 71 | 71 | |
| 72 | 72 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 73 | COMP( 198?, z80dev, 0, 0, | |
| 73 | COMP( 198?, z80dev, 0, 0, | |
| 74 | 74 |
| r8044 | r8045 | |
|---|---|---|
| 936 | 936 | |
| 937 | 937 | static ABCBUS_DAISY( abc802_abcbus_daisy ) |
| 938 | 938 | { |
| 939 | // | |
| 939 | // { LUXOR_55_21046_ABCBUS("abc830") }, won't boot with this enabled | |
| 940 | 940 | { NULL } |
| 941 | 941 | }; |
| 942 | 942 |
| r8044 | r8045 | |
|---|---|---|
| 50 | 50 | * 0x0200-0f: Floppy controller (MB8877A) |
| 51 | 51 | * 0x0400 : Video / CRTC (unknown) |
| 52 | 52 | * 0x0404 : Disable VRAM, CMOS, memory-mapped I/O (everything in low memory except the BIOS) |
| 53 | * 0x0440-5f: Video / CRTC | |
| 53 | * 0x0440-5f: Video / CRTC | |
| 54 | 54 | * 0x0480 RW: bit 1 = disable BIOS ROM |
| 55 | * 0x04c0-cf: CD-ROM controller | |
| 55 | * 0x04c0-cf: CD-ROM controller | |
| 56 | 56 | * 0x04d5 : Sound mute |
| 57 | 57 | * 0x04d8 : YM3438 control port A / status |
| 58 | 58 | * 0x04da : YM3438 data port A / status |
| r8044 | r8045 | |
| 789 | 789 | if((porttype & 0x0f) == 0x01) |
| 790 | 790 | { |
| 791 | 791 | extra1 = input_port_read(space->machine,"joy1_ex"); |
| 792 | ||
| 792 | ||
| 793 | 793 | if(towns_pad_mask & 0x10) |
| 794 | 794 | ret |= (input_port_read(space->machine,"joy1") & 0x3f) | 0x00000040; |
| 795 | 795 | else |
| 796 | 796 | ret |= (input_port_read(space->machine,"joy1") & 0x0f) | 0x00000030; |
| 797 | ||
| 797 | ||
| 798 | 798 | if(extra1 & 0x01) // Run button = left+right |
| 799 | 799 | ret &= ~0x0000000c; |
| 800 | 800 | if(extra1 & 0x02) // Select button = up+down |
| 801 | 801 | ret &= ~0x00000003; |
| 802 | ||
| 802 | ||
| 803 | 803 | if((extra1 & 0x10) && (towns_pad_mask & 0x01)) |
| 804 | 804 | ret &= ~0x00000010; |
| 805 | 805 | if((extra1 & 0x20) && (towns_pad_mask & 0x02)) |
| r8044 | r8045 | |
| 813 | 813 | ret |= ((input_port_read(space->machine,"joy2") & 0x3f) << 16) | 0x00400000; |
| 814 | 814 | else |
| 815 | 815 | ret |= ((input_port_read(space->machine,"joy2") & 0x0f) << 16) | 0x00300000; |
| 816 | ||
| 816 | ||
| 817 | 817 | if(extra2 & 0x01) |
| 818 | 818 | ret &= ~0x000c0000; |
| 819 | 819 | if(extra2 & 0x02) |
| r8044 | r8045 | |
| 846 | 846 | if(towns_mouse_output < MOUSE_Y_LOW) |
| 847 | 847 | ret |= 0x0000000f; |
| 848 | 848 | } |
| 849 | ||
| 849 | ||
| 850 | 850 | // button states are always visible |
| 851 | 851 | state = input_port_read(space->machine,"mouse1"); |
| 852 | 852 | if(!(state & 0x01)) |
| r8044 | r8045 | |
| 855 | 855 | ret |= 0x00000020; |
| 856 | 856 | if(towns_pad_mask & 0x10) |
| 857 | 857 | ret |= 0x00000040; |
| 858 | } | |
| 858 | } | |
| 859 | 859 | if((porttype & 0xf0) == 0x20) // mouse |
| 860 | 860 | { |
| 861 | 861 | switch(towns_mouse_output) |
| r8044 | r8045 | |
| 878 | 878 | if(towns_mouse_output < MOUSE_Y_LOW) |
| 879 | 879 | ret |= 0x000f0000; |
| 880 | 880 | } |
| 881 | ||
| 881 | ||
| 882 | 882 | // button states are always visible |
| 883 | 883 | state = input_port_read(space->machine,"mouse1"); |
| 884 | 884 | if(!(state & 0x01)) |
| r8044 | r8045 | |
| 887 | 887 | ret |= 0x00200000; |
| 888 | 888 | if(towns_pad_mask & 0x20) |
| 889 | 889 | ret |= 0x00400000; |
| 890 | } | |
| 891 | ||
| 890 | } | |
| 891 | ||
| 892 | 892 | return ret; |
| 893 | 893 | } |
| 894 | 894 | |
| r8044 | r8045 | |
| 897 | 897 | static UINT8 prev; |
| 898 | 898 | static UINT8 prev_x,prev_y; |
| 899 | 899 | UINT8 current_x,current_y; |
| 900 | UINT32 type = input_port_read(space->machine,"ctrltype"); | |
| 901 | ||
| 900 | UINT32 type = input_port_read(space->machine,"ctrltype"); | |
| 901 | ||
| 902 | 902 | if(ACCESSING_BITS_16_23) |
| 903 | 903 | { |
| 904 | 904 | towns_pad_mask = (data & 0x00ff0000) >> 16; |
| r8044 | r8045 | |
| 2094 | 2094 | PORT_BIT(0x00000020,IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(2) PORT_CATEGORY(21) |
| 2095 | 2095 | PORT_BIT(0x00000040,IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CATEGORY(21) |
| 2096 | 2096 | PORT_BIT(0x00000080,IP_ACTIVE_HIGH, IPT_UNUSED) PORT_CATEGORY(21) |
| 2097 | ||
| 2097 | ||
| 2098 | 2098 | PORT_START("mouse1") // buttons |
| 2099 | ||
| 2099 | ||
| 2100 | 2100 | PORT_BIT( 0x00000002, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2) |
| 2101 | ||
| 2101 | ||
| 2102 | 2102 | PORT_START("mouse2") // X-axis |
| 2103 | 2103 | PORT_BIT( 0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) |
| 2104 | 2104 |
| r8044 | r8045 | |
|---|---|---|
| 2 | 2 | |
| 3 | 3 | Sharp MZ-2500 (c) 1985 Sharp Corporation |
| 4 | 4 | |
| 5 | ||
| 5 | preliminary driver by Angelo Salese | |
| 6 | 6 | |
| 7 | 7 | memory map: |
| 8 | 8 | |
| r8044 | r8045 | |
| 18 | 18 | |
| 19 | 19 | start-up vblank irq is rst $28 (0xef), this system has mixed im 0 and im 2 (!) |
| 20 | 20 | |
| 21 | ||
| 21 | after some time, clear work ram [$919] to 0 ... something to do with irqs? | |
| 22 | 22 | |
| 23 | currently emulation speed crawls a lot when you use the debugger, | |
| 24 | comment out lines 983/984 of emu/memory.c for the time being. | |
| 23 | currently emulation speed crawls a lot when you use the debugger, | |
| 24 | comment out lines 983/984 of emu/memory.c for the time being. | |
| 25 | 25 | |
| 26 | 26 | ****************************************************************************/ |
| 27 | 27 | |
| r8044 | r8045 | |
| 53 | 53 | { |
| 54 | 54 | UINT8 *vram = memory_region(screen->machine, "maincpu"); |
| 55 | 55 | int x,y,count; |
| 56 | // | |
| 56 | // gfx_element *gfx;// = screen->machine->gfx[0]; | |
| 57 | 57 | |
| 58 | 58 | count = 0x70000; |
| 59 | 59 | |
| r8044 | r8045 | |
| 208 | 208 | |
| 209 | 209 | static WRITE8_HANDLER( mz2500_bank_data_w ) |
| 210 | 210 | { |
| 211 | // UINT8 *ROM = memory_region(space->machine, "maincpu"); | |
| 212 | // static const char *const bank_name[] = { "bank0", "bank1", "bank2", "bank3", "bank4", "bank5", "bank6", "bank7" }; | |
| 211 | // UINT8 *ROM = memory_region(space->machine, "maincpu"); | |
| 212 | // static const char *const bank_name[] = { "bank0", "bank1", "bank2", "bank3", "bank4", "bank5", "bank6", "bank7" }; | |
| 213 | 213 | |
| 214 | 214 | bank_val[bank_addr] = data & 0x3f; |
| 215 | 215 | |
| 216 | // if((data*2) >= 0x70) | |
| 217 | // printf("%s %02x\n",bank_name[bank_addr],bank_val[bank_addr]*2); | |
| 216 | // if((data*2) >= 0x70) | |
| 217 | // printf("%s %02x\n",bank_name[bank_addr],bank_val[bank_addr]*2); | |
| 218 | 218 | |
| 219 | // | |
| 219 | // memory_set_bankptr(space->machine, bank_name[bank_addr], &ROM[bank_val[bank_addr]*0x2000]); | |
| 220 | 220 | |
| 221 | 221 | bank_addr++; |
| 222 | 222 | bank_addr&=7; |
| r8044 | r8045 | |
| 259 | 259 | { |
| 260 | 260 | irq_sel = data; |
| 261 | 261 | // FIXME: bit 0-3 are irq masks? |
| 262 | // | |
| 262 | // printf("%02x\n",irq_sel); | |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | 265 | static WRITE8_HANDLER( mz2500_irq_data_w ) |
| r8044 | r8045 | |
| 392 | 392 | |
| 393 | 393 | static WRITE8_HANDLER( mz2500_rom_w ) |
| 394 | 394 | { |
| 395 | // | |
| 395 | // printf("%02x\n",data); | |
| 396 | 396 | rom_index = (data << 8) | (rom_index & 0xff00ff); |
| 397 | 397 | //printf("%02x\n",data); |
| 398 | 398 | } |
| 399 | 399 | |
| 400 | 400 | static ADDRESS_MAP_START(mz2500_io, ADDRESS_SPACE_IO, 8) |
| 401 | 401 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 402 | // AM_RANGE(0x60, 0x63) AM_WRITE(w3100a_w) | |
| 403 | // AM_RANGE(0x63, 0x63) AM_READ(w3100a_r) | |
| 404 | // AM_RANGE(0xa0, 0xa3) AM_READWRITE(sio_r,sio_w) | |
| 405 | // AM_RANGE(0xa4, 0xa5) AM_READWRITE(sasi_r, sasi_w) | |
| 402 | // AM_RANGE(0x60, 0x63) AM_WRITE(w3100a_w) | |
| 403 | // AM_RANGE(0x63, 0x63) AM_READ(w3100a_r) | |
| 404 | // AM_RANGE(0xa0, 0xa3) AM_READWRITE(sio_r,sio_w) | |
| 405 | // AM_RANGE(0xa4, 0xa5) AM_READWRITE(sasi_r, sasi_w) | |
| 406 | 406 | AM_RANGE(0xa8, 0xa8) AM_WRITE(mz2500_rom_w) |
| 407 | 407 | AM_RANGE(0xa9, 0xa9) AM_READ(mz2500_rom_r) |
| 408 | // AM_RANGE(0xac, 0xad) AM_WRITE(emm_w) | |
| 409 | // AM_RANGE(0xad, 0xad) AM_READ(emm_r) | |
| 410 | // AM_RANGE(0xae, 0xae) AM_WRITE(crtc_w) | |
| 411 | // AM_RANGE(0xb0, 0xb3) AM_READWRITE(sio_r,sio_w) | |
| 408 | // AM_RANGE(0xac, 0xad) AM_WRITE(emm_w) | |
| 409 | // AM_RANGE(0xad, 0xad) AM_READ(emm_r) | |
| 410 | // AM_RANGE(0xae, 0xae) AM_WRITE(crtc_w) | |
| 411 | // AM_RANGE(0xb0, 0xb3) AM_READWRITE(sio_r,sio_w) | |
| 412 | 412 | AM_RANGE(0xb4, 0xb4) AM_READWRITE(mz2500_bank_addr_r,mz2500_bank_addr_w) |
| 413 | 413 | AM_RANGE(0xb5, 0xb5) AM_READWRITE(mz2500_bank_data_r,mz2500_bank_data_w) |
| 414 | // AM_RANGE(0xb8, 0xb9) AM_READWRITE(kanji_r,kanji_w) | |
| 415 | // AM_RANGE(0xbc, 0xbd) AM_READWRITE(crtc_r,crtc_w) | |
| 414 | // AM_RANGE(0xb8, 0xb9) AM_READWRITE(kanji_r,kanji_w) | |
| 415 | // AM_RANGE(0xbc, 0xbd) AM_READWRITE(crtc_r,crtc_w) | |
| 416 | 416 | AM_RANGE(0xc6, 0xc6) AM_WRITE(mz2500_irq_sel_w) |
| 417 | 417 | AM_RANGE(0xc7, 0xc7) AM_WRITE(mz2500_irq_data_w) |
| 418 | 418 | AM_RANGE(0xc8, 0xc9) AM_DEVREADWRITE("ym", ym2203_r, ym2203_w) |
| 419 | // AM_RANGE(0xca, 0xca) AM_READWRITE(voice_r,voice_w) | |
| 420 | // AM_RANGE(0xcc, 0xcc) AM_READWRITE(calendar_r,calendar_w) | |
| 421 | // AM_RANGE(0xce, 0xce) AM_WRITE(mz2500_dictionary_bank_w) | |
| 419 | // AM_RANGE(0xca, 0xca) AM_READWRITE(voice_r,voice_w) | |
| 420 | // AM_RANGE(0xcc, 0xcc) AM_READWRITE(calendar_r,calendar_w) | |
| 421 | // AM_RANGE(0xce, 0xce) AM_WRITE(mz2500_dictionary_bank_w) | |
| 422 | 422 | AM_RANGE(0xcf, 0xcf) AM_WRITE(mz2500_kanji_bank_w) |
| 423 | 423 | AM_RANGE(0xd8, 0xdb) AM_DEVREADWRITE("mb8877a", wd17xx_r, wd17xx_w) |
| 424 | 424 | AM_RANGE(0xdc, 0xdd) AM_WRITE(mz2500_fdc_w) |
| 425 | 425 | AM_RANGE(0xe0, 0xe1) AM_DEVREADWRITE("z80pio_0", z80pio_c_r, z80pio_c_w) |
| 426 | 426 | AM_RANGE(0xe2, 0xe3) AM_DEVREADWRITE("z80pio_0", z80pio_d_r, z80pio_d_w) |
| 427 | // | |
| 427 | // AM_RANGE(0xe4, 0xe7) AM_READWRITE(pit_r,pit_w) | |
| 428 | 428 | AM_RANGE(0xe8, 0xe9) AM_DEVREADWRITE("z80pio_1", z80pio_c_r, z80pio_c_w) |
| 429 | 429 | AM_RANGE(0xea, 0xeb) AM_DEVREADWRITE("z80pio_1", z80pio_d_r, z80pio_d_w) |
| 430 | // AM_RANGE(0xef, 0xef) AM_READWRITE(joystick_r,joystick_w) | |
| 431 | // AM_RANGE(0xf0, 0xf3) AM_WRITE(timer_w) | |
| 430 | // AM_RANGE(0xef, 0xef) AM_READWRITE(joystick_r,joystick_w) | |
| 431 | // AM_RANGE(0xf0, 0xf3) AM_WRITE(timer_w) | |
| 432 | 432 | AM_RANGE(0xf4, 0xf7) AM_READ(mz2500_crtc_r) AM_WRITE(mz2500_crtc_w) |
| 433 | // | |
| 433 | // AM_RANGE(0xf8, 0xf9) AM_READWRITE(extrom_r,extrom_w) | |
| 434 | 434 | ADDRESS_MAP_END |
| 435 | 435 | |
| 436 | 436 | /* Input ports */ |
| r8044 | r8045 | |
| 504 | 504 | bank_val[6] = 0x06; |
| 505 | 505 | bank_val[7] = 0x07; |
| 506 | 506 | |
| 507 | /* memory_set_bankptr(machine, "bank0", &ROM[bank_val[0]*0x2000]); | |
| 508 | memory_set_bankptr(machine, "bank1", &ROM[bank_val[1]*0x2000]); | |
| 509 | memory_set_bankptr(machine, "bank2", &ROM[bank_val[2]*0x2000]); | |
| 510 | memory_set_bankptr(machine, "bank3", &ROM[bank_val[3]*0x2000]); | |
| 511 | memory_set_bankptr(machine, "bank4", &ROM[bank_val[4]*0x2000]); | |
| 512 | memory_set_bankptr(machine, "bank5", &ROM[bank_val[5]*0x2000]); | |
| 513 | memory_set_bankptr(machine, "bank6", &ROM[bank_val[6]*0x2000]); | |
| 514 | memory_set_bankptr(machine, "bank7", &ROM[bank_val[7]*0x2000]);*/ | |
| 507 | /* memory_set_bankptr(machine, "bank0", &ROM[bank_val[0]*0x2000]); | |
| 508 | memory_set_bankptr(machine, "bank1", &ROM[bank_val[1]*0x2000]); | |
| 509 | memory_set_bankptr(machine, "bank2", &ROM[bank_val[2]*0x2000]); | |
| 510 | memory_set_bankptr(machine, "bank3", &ROM[bank_val[3]*0x2000]); | |
| 511 | memory_set_bankptr(machine, "bank4", &ROM[bank_val[4]*0x2000]); | |
| 512 | memory_set_bankptr(machine, "bank5", &ROM[bank_val[5]*0x2000]); | |
| 513 | memory_set_bankptr(machine, "bank6", &ROM[bank_val[6]*0x2000]); | |
| 514 | memory_set_bankptr(machine, "bank7", &ROM[bank_val[7]*0x2000]);*/ | |
| 515 | 515 | |
| 516 | 516 | irq_vector[0] = 0xef; /* RST 28h - vblank */ |
| 517 | 517 | |
| r8044 | r8045 | |
| 573 | 573 | |
| 574 | 574 | static WRITE8_DEVICE_HANDLER( mz2500_pio1_porta_w ) |
| 575 | 575 | { |
| 576 | // | |
| 576 | // printf("%02x\n",data); | |
| 577 | 577 | text_col_size = (data & 0x20) ? 80 : 40; |
| 578 | 578 | } |
| 579 | 579 | |
| r8044 | r8045 | |
| 672 | 672 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 673 | 673 | MDRV_SCREEN_RAW_PARAMS(XTAL_17_73447MHz/2, 568, 0, 40*8, 312, 0, 25*8) |
| 674 | 674 | MDRV_PALETTE_LENGTH(256*2) |
| 675 | // | |
| 675 | // MDRV_PALETTE_INIT(black_and_white) | |
| 676 | 676 | |
| 677 | 677 | MDRV_GFXDECODE(mz2500) |
| 678 | 678 |
| r8044 | r8045 | |
|---|---|---|
| 220 | 220 | static DEVICE_IMAGE_LOAD( gmaster_cart ) |
| 221 | 221 | { |
| 222 | 222 | UINT32 size; |
| 223 | ||
| 223 | ||
| 224 | 224 | if (image_software_entry(image) == NULL) |
| 225 | 225 | { |
| 226 | 226 | size = image_length(image); |
| 227 | ||
| 227 | ||
| 228 | 228 | if (size > (memory_region_length(image->machine, "maincpu") - 0x8000)) |
| 229 | 229 | { |
| 230 | 230 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); |
| 231 | 231 | return INIT_FAIL; |
| 232 | 232 | } |
| 233 | ||
| 233 | ||
| 234 | 234 | if (image_fread(image, memory_region(image->machine, "maincpu") + 0x8000, size) != size) |
| 235 | 235 | { |
| 236 | 236 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Unable to fully read from file"); |
| 237 | 237 | return INIT_FAIL; |
| 238 | 238 | } |
| 239 | ||
| 239 | ||
| 240 | 240 | } |
| 241 | 241 | else |
| 242 | 242 | { |
| r8044 | r8045 | |
|---|---|---|
| 4 | 4 | |
| 5 | 5 | 12/05/2009 Skeleton driver. |
| 6 | 6 | |
| 7 | Great info at http://www.goliathindustries.com/vb/ | |
| 7 | Great info at http://www.goliathindustries.com/vb/ | |
| 8 | 8 | and http://www.vr32.de/modules/dokuwiki/doku.php? |
| 9 | 9 | |
| 10 | 10 | ****************************************************************************/ |
| r8044 | r8045 | |
| 673 | 673 | { |
| 674 | 674 | UINT32 size; |
| 675 | 675 | UINT8 *ptr = memory_region(image->machine, "user1"); |
| 676 | ||
| 676 | ||
| 677 | 677 | if (image_software_entry(image) == NULL) |
| 678 | 678 | { |
| 679 | 679 | size = image_length(image); |
| r8044 | r8045 | |
| 685 | 685 | size = image_get_software_region_length(image, "rom"); |
| 686 | 686 | memcpy(ptr, image_get_software_region(image, "rom"), size); |
| 687 | 687 | } |
| 688 | ||
| 688 | ||
| 689 | 689 | return INIT_PASS; |
| 690 | 690 | } |
| 691 | 691 |
| r8044 | r8045 | |
|---|---|---|
| 3 | 3 | Interact Family Computer |
| 4 | 4 | |
| 5 | 5 | 12/05/2009 Skeleton driver - Micko |
| 6 | ||
| 6 | 31/05/2009 Added notes - Robbbert | |
| 7 | 7 | |
| 8 | 8 | This was made by Interact Company of Ann Arbor, Michigan. However, |
| 9 | 9 | just after launch, the company collapsed. The liquidator, Protecto, |
| r8044 | r8045 | |
|---|---|---|
| 8 | 8 | |
| 9 | 9 | /* |
| 10 | 10 | |
| 11 | ||
| 11 | TODO: | |
| 12 | 12 | |
| 13 | - 80186 | |
| 14 | - CRT9007 | |
| 15 | - keyboard ROM | |
| 16 | - hires graphics board | |
| 17 | - floppy 720K DSQD | |
| 18 | - DMA | |
| 19 | - WD1010 | |
| 20 | - hard disk | |
| 21 | - mouse | |
| 22 | - save state | |
| 13 | - 80186 | |
| 14 | - CRT9007 | |
| 15 | - keyboard ROM | |
| 16 | - hires graphics board | |
| 17 | - floppy 720K DSQD | |
| 18 | - DMA | |
| 19 | - WD1010 | |
| 20 | - hard disk | |
| 21 | - mouse | |
| 22 | - save state | |
| 23 | 23 | |
| 24 | 24 | */ |
| 25 | 25 | |
| r8044 | r8045 | |
| 51 | 51 | { |
| 52 | 52 | /* |
| 53 | 53 | |
| 54 | ||
| 54 | bit signal description | |
| 55 | 55 | |
| 56 | 0 RS-232 ring indicator | |
| 57 | 1 RS-232 carrier detect | |
| 58 | 2 | |
| 59 | 3 | |
| 60 | 4 | |
| 61 | 5 | |
| 62 | 6 | |
| 63 | 7 _ACLOW | |
| 56 | 0 RS-232 ring indicator | |
| 57 | 1 RS-232 carrier detect | |
| 58 | 2 | |
| 59 | 3 | |
| 60 | 4 | |
| 61 | 5 | |
| 62 | 6 | |
| 63 | 7 _ACLOW | |
| 64 | 64 | |
| 65 | ||
| 65 | */ | |
| 66 | 66 | |
| 67 | 67 | return 0x80; |
| 68 | 68 | } |
| r8044 | r8045 | |
| 71 | 71 | { |
| 72 | 72 | /* |
| 73 | 73 | |
| 74 | ||
| 74 | bit signal description | |
| 75 | 75 | |
| 76 | 0 KBEN keyboard enable | |
| 77 | 1 EXTCLK external baud rate clock | |
| 78 | 2 SPKRGATE enable periodic speaker output | |
| 79 | 3 SPKRDATA direct output to speaker | |
| 80 | 4 RFRQGATE enable refresh and baud rate clocks | |
| 81 | 5 _FDCRESET reset 8272 | |
| 82 | 6 TMRIN0 enable 80186 timer 0 | |
| 83 | 7 TMRIN1 enable 80186 timer 1 | |
| 76 | 0 KBEN keyboard enable | |
| 77 | 1 EXTCLK external baud rate clock | |
| 78 | 2 SPKRGATE enable periodic speaker output | |
| 79 | 3 SPKRDATA direct output to speaker | |
| 80 | 4 RFRQGATE enable refresh and baud rate clocks | |
| 81 | 5 _FDCRESET reset 8272 | |
| 82 | 6 TMRIN0 enable 80186 timer 0 | |
| 83 | 7 TMRIN1 enable 80186 timer 1 | |
| 84 | 84 | |
| 85 | ||
| 85 | */ | |
| 86 | 86 | |
| 87 | 87 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 88 | 88 | |
| r8044 | r8045 | |
| 115 | 115 | { |
| 116 | 116 | /* |
| 117 | 117 | |
| 118 | ||
| 118 | bit description | |
| 119 | 119 | |
| 120 | 0 DMA channel 0 enable | |
| 121 | 1 DMA channel 1 enable | |
| 122 | 2 DMA channel 2 enable | |
| 123 | 3 DMA channel 3 enable | |
| 124 | 4 DMA channel 0 select | |
| 125 | 5 DMA channel 1 select | |
| 126 | 6 DMA channel 2 select | |
| 127 | 7 DMA channel 3 select | |
| 120 | 0 DMA channel 0 enable | |
| 121 | 1 DMA channel 1 enable | |
| 122 | 2 DMA channel 2 enable | |
| 123 | 3 DMA channel 3 enable | |
| 124 | 4 DMA channel 0 select | |
| 125 | 5 DMA channel 1 select | |
| 126 | 6 DMA channel 2 select | |
| 127 | 7 DMA channel 3 select | |
| 128 | 128 | |
| 129 | ||
| 129 | */ | |
| 130 | 130 | |
| 131 | 131 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 132 | 132 | |
| r8044 | r8045 | |
| 168 | 168 | { |
| 169 | 169 | /* |
| 170 | 170 | |
| 171 | ||
| 171 | bit signal description | |
| 172 | 172 | |
| 173 | 8 A15 A15 of video access | |
| 174 | 9 A16 A16 of video access | |
| 175 | 10 A17 A17 of video access | |
| 176 | 11 A18 A18 of video access | |
| 177 | 12 A19 A19 of video access | |
| 178 | 13 CLKSPD clock speed (0 = 22.4 MHz, 1 = 28 MHz) | |
| 179 | 14 CLKCNT dots/char (0 = 10 [800x400], 1 = 8 [640x400]) | |
| 180 | 15 VIDOUTS selects the video source for display on monochrome monitor | |
| 173 | 8 A15 A15 of video access | |
| 174 | 9 A16 A16 of video access | |
| 175 | 10 A17 A17 of video access | |
| 176 | 11 A18 A18 of video access | |
| 177 | 12 A19 A19 of video access | |
| 178 | 13 CLKSPD clock speed (0 = 22.4 MHz, 1 = 28 MHz) | |
| 179 | 14 CLKCNT dots/char (0 = 10 [800x400], 1 = 8 [640x400]) | |
| 180 | 15 VIDOUTS selects the video source for display on monochrome monitor | |
| 181 | 181 | |
| 182 | ||
| 182 | */ | |
| 183 | 183 | |
| 184 | 184 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 185 | 185 | |
| r8044 | r8045 | |
| 202 | 202 | { |
| 203 | 203 | /* |
| 204 | 204 | |
| 205 | ||
| 205 | bit description | |
| 206 | 206 | |
| 207 | 0 X0 | |
| 208 | 1 X1 | |
| 209 | 2 X2 | |
| 210 | 3 X3 | |
| 211 | 4 X4 | |
| 212 | 5 X5 | |
| 213 | 6 X6 | |
| 214 | 7 X7 | |
| 207 | 0 X0 | |
| 208 | 1 X1 | |
| 209 | 2 X2 | |
| 210 | 3 X3 | |
| 211 | 4 X4 | |
| 212 | 5 X5 | |
| 213 | 6 X6 | |
| 214 | 7 X7 | |
| 215 | 215 | |
| 216 | ||
| 216 | */ | |
| 217 | 217 | |
| 218 | 218 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 219 | 219 | |
| r8044 | r8045 | |
| 239 | 239 | { |
| 240 | 240 | /* |
| 241 | 241 | |
| 242 | ||
| 242 | bit description | |
| 243 | 243 | |
| 244 | 0 Y0 | |
| 245 | 1 Y1 | |
| 246 | 2 Y2 | |
| 247 | 3 Y3 | |
| 248 | 4 Y4 | |
| 249 | 5 Y5 | |
| 250 | 6 Y6 | |
| 251 | 7 Y7 | |
| 244 | 0 Y0 | |
| 245 | 1 Y1 | |
| 246 | 2 Y2 | |
| 247 | 3 Y3 | |
| 248 | 4 Y4 | |
| 249 | 5 Y5 | |
| 250 | 6 Y6 | |
| 251 | 7 Y7 | |
| 252 | 252 | |
| 253 | ||
| 253 | */ | |
| 254 | 254 | |
| 255 | 255 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 256 | 256 | |
| r8044 | r8045 | |
| 262 | 262 | { |
| 263 | 263 | /* |
| 264 | 264 | |
| 265 | ||
| 265 | bit description | |
| 266 | 266 | |
| 267 | 0 Y8 | |
| 268 | 1 Y9 | |
| 269 | 2 Y10 | |
| 270 | 3 Y11 | |
| 271 | 4 LED 2 | |
| 272 | 5 LED 1 | |
| 273 | 6 | |
| 274 | 7 | |
| 267 | 0 Y8 | |
| 268 | 1 Y9 | |
| 269 | 2 Y10 | |
| 270 | 3 Y11 | |
| 271 | 4 LED 2 | |
| 272 | 5 LED 1 | |
| 273 | 6 | |
| 274 | 7 | |
| 275 | 275 | |
| 276 | ||
| 276 | */ | |
| 277 | 277 | |
| 278 | 278 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 279 | 279 | |
| r8044 | r8045 | |
| 285 | 285 | |
| 286 | 286 | static ADDRESS_MAP_START( tandy2k_mem, ADDRESS_SPACE_PROGRAM, 16 ) |
| 287 | 287 | ADDRESS_MAP_UNMAP_HIGH |
| 288 | // AM_RANGE(0x00000, 0xdffff) AM_RAM | |
| 289 | // AM_RANGE(0xe0000, 0xf7fff) AM_RAM // hires graphics | |
| 288 | // AM_RANGE(0x00000, 0xdffff) AM_RAM | |
| 289 | // AM_RANGE(0xe0000, 0xf7fff) AM_RAM // hires graphics | |
| 290 | 290 | AM_RANGE(0xf8000, 0xfbfff) AM_RAM AM_BASE_MEMBER(tandy2k_state, char_ram) |
| 291 | 291 | AM_RANGE(0xfc000, 0xfdfff) AM_MIRROR(0x2000) AM_ROM AM_REGION(I80186_TAG, 0) |
| 292 | 292 | ADDRESS_MAP_END |
| r8044 | r8045 | |
| 306 | 306 | AM_RANGE(0x00080, 0x00081) AM_DEVREADWRITE8(I8272A_TAG, upd765_dack_r, upd765_dack_w, 0x00ff) |
| 307 | 307 | AM_RANGE(0x00100, 0x0017f) AM_DEVREADWRITE8(CRT9007_TAG, crt9007_r, crt9007_w, 0x00ff) |
| 308 | 308 | AM_RANGE(0x00100, 0x0017f) AM_WRITE8(addr_ctrl_w, 0xff00) |
| 309 | // AM_RANGE(0x00180, 0x00180) AM_READ8(hires_status_r, 0x00ff) | |
| 310 | // AM_RANGE(0x00180, 0x001bf) AM_WRITE(hires_palette_w) | |
| 311 | // AM_RANGE(0x001a0, 0x001a0) AM_READ8(hires_plane_w, 0x00ff) | |
| 312 | // AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(i186_internal_port_r, i186_internal_port_w) | |
| 309 | // AM_RANGE(0x00180, 0x00180) AM_READ8(hires_status_r, 0x00ff) | |
| 310 | // AM_RANGE(0x00180, 0x001bf) AM_WRITE(hires_palette_w) | |
| 311 | // AM_RANGE(0x001a0, 0x001a0) AM_READ8(hires_plane_w, 0x00ff) | |
| 312 | // AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(i186_internal_port_r, i186_internal_port_w) | |
| 313 | 313 | ADDRESS_MAP_END |
| 314 | 314 | |
| 315 | 315 | static ADDRESS_MAP_START( tandy2k_hd_io, ADDRESS_SPACE_IO, 16 ) |
| 316 | 316 | AM_IMPORT_FROM(tandy2k_io) |
| 317 | // AM_RANGE(0x000e0, 0x000ff) AM_WRITE8(hdc_dack_w, 0x00ff) | |
| 318 | // AM_RANGE(0x0026c, 0x0026d) AM_DEVREADWRITE8(WD1010_TAG, hdc_reset_r, hdc_reset_w, 0x00ff) | |
| 319 | // AM_RANGE(0x0026e, 0x0027f) AM_DEVREADWRITE8(WD1010_TAG, wd1010_r, wd1010_w, 0x00ff) | |
| 317 | // AM_RANGE(0x000e0, 0x000ff) AM_WRITE8(hdc_dack_w, 0x00ff) | |
| 318 | // AM_RANGE(0x0026c, 0x0026d) AM_DEVREADWRITE8(WD1010_TAG, hdc_reset_r, hdc_reset_w, 0x00ff) | |
| 319 | // AM_RANGE(0x0026e, 0x0027f) AM_DEVREADWRITE8(WD1010_TAG, wd1010_r, wd1010_w, 0x00ff) | |
| 320 | 320 | ADDRESS_MAP_END |
| 321 | 321 | |
| 322 | 322 | static ADDRESS_MAP_START( keyboard_io, ADDRESS_SPACE_IO, 8 ) |
| r8044 | r8045 | |
| 590 | 590 | { |
| 591 | 591 | /* |
| 592 | 592 | |
| 593 | ||
| 593 | bit signal description | |
| 594 | 594 | |
| 595 | 0 LPRIN0 auxiliary input 0 | |
| 596 | 1 LPRIN1 auxiliary input 1 | |
| 597 | 2 LPRIN2 auxiliary input 2 | |
| 598 | 3 _LPRACK acknowledge | |
| 599 | 4 _LPRFLT fault | |
| 600 | 5 _LPRSEL select | |
| 601 | 6 LPRPAEM paper empty | |
| 602 | 7 LPRBSY busy | |
| 595 | 0 LPRIN0 auxiliary input 0 | |
| 596 | 1 LPRIN1 auxiliary input 1 | |
| 597 | 2 LPRIN2 auxiliary input 2 | |
| 598 | 3 _LPRACK acknowledge | |
| 599 | 4 _LPRFLT fault | |
| 600 | 5 _LPRSEL select | |
| 601 | 6 LPRPAEM paper empty | |
| 602 | 7 LPRBSY busy | |
| 603 | 603 | |
| 604 | ||
| 604 | */ | |
| 605 | 605 | |
| 606 | 606 | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data; |
| 607 | 607 | |
| r8044 | r8045 | |
| 643 | 643 | { |
| 644 | 644 | /* |
| 645 | 645 | |
| 646 | ||
| 646 | bit signal description | |
| 647 | 647 | |
| 648 | 0 port A direction | |
| 649 | 1 port B input select bit 0 | |
| 650 | 2 port B input select bit 1 | |
| 651 | 3 LPRINT13 interrupt | |
| 652 | 4 STROBE IN | |
| 653 | 5 INBUFFULL | |
| 654 | 6 _LPRACK | |
| 655 | 7 _LPRDATSTB | |
| 648 | 0 port A direction | |
| 649 | 1 port B input select bit 0 | |
| 650 | 2 port B input select bit 1 | |
| 651 | 3 LPRINT13 interrupt | |
| 652 | 4 STROBE IN | |
| 653 | 5 INBUFFULL | |
| 654 | 6 _LPRACK | |
| 655 | 7 _LPRDATSTB | |
| 656 | 656 | |
| 657 | ||
| 657 | */ | |
| 658 | 658 | |
| 659 | 659 | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data; |
| 660 | 660 | |
| r8044 | r8045 | |
| 682 | 682 | |
| 683 | 683 | /* |
| 684 | 684 | |
| 685 | IR0 MEMINT00 | |
| 686 | IR1 TMOINT01 | |
| 687 | IR2 SERINT02 | |
| 688 | IR3 BUSINT03 | |
| 689 | IR4 FLDINT04 | |
| 690 | IR5 BUSINT05 | |
| 691 | IR6 HDCINT06 | |
| 692 | IR7 BUSINT07 | |
| 685 | IR0 MEMINT00 | |
| 686 | IR1 TMOINT01 | |
| 687 | IR2 SERINT02 | |
| 688 | IR3 BUSINT03 | |
| 689 | IR4 FLDINT04 | |
| 690 | IR5 BUSINT05 | |
| 691 | IR6 HDCINT06 | |
| 692 | IR7 BUSINT07 | |
| 693 | 693 | |
| 694 | 694 | */ |
| 695 | 695 | |
| r8044 | r8045 | |
| 700 | 700 | |
| 701 | 701 | /* |
| 702 | 702 | |
| 703 | IR0 KBDINT10 | |
| 704 | IR1 VIDINT11 | |
| 705 | IR2 RATINT12 | |
| 706 | IR3 LPRINT13 | |
| 707 | IR4 MCPINT14 | |
| 708 | IR5 MEMINT15 | |
| 709 | IR6 DMEINT16 | |
| 710 | IR7 BUSINT17 | |
| 703 | IR0 KBDINT10 | |
| 704 | IR1 VIDINT11 | |
| 705 | IR2 RATINT12 | |
| 706 | IR3 LPRINT13 | |
| 707 | IR4 MCPINT14 | |
| 708 | IR5 MEMINT15 | |
| 709 | IR6 DMEINT16 | |
| 710 | IR7 BUSINT17 | |
| 711 | 711 | |
| 712 | 712 | */ |
| 713 | 713 | |
| r8044 | r8045 | |
| 785 | 785 | rom[0x1f17] = 0x90; |
| 786 | 786 | |
| 787 | 787 | /* register for state saving */ |
| 788 | // | |
| 788 | // state_save_register_global(machine, state->); | |
| 789 | 789 | } |
| 790 | 790 | |
| 791 | 791 | static MACHINE_RESET( tandy2k ) |
| r8044 | r8045 | |
| 802 | 802 | MDRV_CPU_PROGRAM_MAP(tandy2k_mem) |
| 803 | 803 | MDRV_CPU_IO_MAP(tandy2k_io) |
| 804 | 804 | |
| 805 | // MDRV_CPU_ADD(I8048_TAG, I8048, 1000000) // ? | |
| 806 | // MDRV_CPU_IO_MAP(keyboard_io) | |
| 805 | // MDRV_CPU_ADD(I8048_TAG, I8048, 1000000) // ? | |
| 806 | // MDRV_CPU_IO_MAP(keyboard_io) | |
| 807 | 807 | |
| 808 | 808 | MDRV_MACHINE_START(tandy2k) |
| 809 | 809 | MDRV_MACHINE_RESET(tandy2k) |
| r8044 | r8045 | |
| 869 | 869 | |
| 870 | 870 | /* System Drivers */ |
| 871 | 871 | |
| 872 | /* YEAR NAME PARENT | |
| 872 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ | |
| 873 | 873 | COMP( 1983, tandy2k, 0, 0, tandy2k, tandy2k, 0, "Tandy Radio Shack", "Tandy 2000", GAME_NOT_WORKING) |
| 874 | 874 | COMP( 1983, tandy2khd, tandy2k, 0, tandy2k_hd, tandy2k, 0, "Tandy Radio Shack", "Tandy 2000HD", GAME_NOT_WORKING) |
| r8044 | r8045 | |
|---|---|---|
| 2 | 2 | |
| 3 | 3 | VideoBrain FamilyComputer |
| 4 | 4 | |
| 5 | http://www.atariprotos.com/othersystems/videobrain/videobrain.htm | |
| 6 | http://www.seanriddle.com/vbinfo.html | |
| 7 | http://www.seanriddle.com/videobrain.html | |
| 5 | http://www.atariprotos.com/othersystems/videobrain/videobrain.htm | |
| 6 | http://www.seanriddle.com/vbinfo.html | |
| 7 | http://www.seanriddle.com/videobrain.html | |
| 8 | 8 | |
| 9 | 9 | 07/04/2009 Skeleton driver. |
| 10 | 10 | |
| r8044 | r8045 | |
| 12 | 12 | |
| 13 | 13 | /* |
| 14 | 14 | |
| 15 | ||
| 15 | TODO: | |
| 16 | 16 | |
| 17 | - SMI 3853 | |
| 18 | - colors | |
| 19 | - low resolution mode | |
| 20 | - discrete sound | |
| 21 | - joystick scan timer 555 | |
| 22 | - reset on cartridge eject | |
| 23 | - expander 1 (cassette, RS-232) | |
| 24 | - expander 2 (modem) | |
| 17 | - SMI 3853 | |
| 18 | - colors | |
| 19 | - low resolution mode | |
| 20 | - discrete sound | |
| 21 | - joystick scan timer 555 | |
| 22 | - reset on cartridge eject | |
| 23 | - expander 1 (cassette, RS-232) | |
| 24 | - expander 2 (modem) | |
| 25 | 25 | |
| 26 | 26 | */ |
| 27 | 27 | |
| r8044 | r8045 | |
| 73 | 73 | case 0xf7: |
| 74 | 74 | /* |
| 75 | 75 | |
| 76 | ||
| 76 | bit description | |
| 77 | 77 | |
| 78 | 0 | |
| 79 | 1 | |
| 80 | 2 | |
| 81 | 3 | |
| 82 | 4 keyboard column 8 | |
| 83 | 5 | |
| 84 | 6 | |
| 85 | 7 | |
| 78 | 0 | |
| 79 | 1 | |
| 80 | 2 | |
| 81 | 3 | |
| 82 | 4 keyboard column 8 | |
| 83 | 5 | |
| 84 | 6 | |
| 85 | 7 | |
| 86 | 86 | |
| 87 | ||
| 87 | */ | |
| 88 | 88 | |
| 89 | 89 | state->uv201_31 = BIT(data, 4); |
| 90 | 90 | break; |
| r8044 | r8045 | |
| 103 | 103 | { |
| 104 | 104 | /* |
| 105 | 105 | |
| 106 | ||
| 106 | bit description | |
| 107 | 107 | |
| 108 | 0 keyboard column 0, sound data 0 | |
| 109 | 1 keyboard column 1, sound data 1 | |
| 110 | 2 keyboard column 2 | |
| 111 | 3 keyboard column 3 | |
| 112 | 4 keyboard column 4 | |
| 113 | 5 keyboard column 5 | |
| 114 | 6 keyboard column 6 | |
| 115 | 7 keyboard column 7 | |
| 108 | 0 keyboard column 0, sound data 0 | |
| 109 | 1 keyboard column 1, sound data 1 | |
| 110 | 2 keyboard column 2 | |
| 111 | 3 keyboard column 3 | |
| 112 | 4 keyboard column 4 | |
| 113 | 5 keyboard column 5 | |
| 114 | 6 keyboard column 6 | |
| 115 | 7 keyboard column 7 | |
| 116 | 116 | |
| 117 | ||
| 117 | */ | |
| 118 | 118 | |
| 119 | 119 | vidbrain_state *state = (vidbrain_state *)space->machine->driver_data; |
| 120 | 120 | |
| r8044 | r8045 | |
| 129 | 129 | { |
| 130 | 130 | /* |
| 131 | 131 | |
| 132 | ||
| 132 | bit description | |
| 133 | 133 | |
| 134 | 0 keyboard row 0 | |
| 135 | 1 keyboard row 1 | |
| 136 | 2 keyboard row 2 | |
| 137 | 3 keyboard row 3 | |
| 138 | 4 | |
| 139 | 5 | |
| 140 | 6 | |
| 141 | 7 | |
| 134 | 0 keyboard row 0 | |
| 135 | 1 keyboard row 1 | |
| 136 | 2 keyboard row 2 | |
| 137 | 3 keyboard row 3 | |
| 138 | 4 | |
| 139 | 5 | |
| 140 | 6 | |
| 141 | 7 | |
| 142 | 142 | |
| 143 | ||
| 143 | */ | |
| 144 | 144 | |
| 145 | 145 | vidbrain_state *state = (vidbrain_state *)space->machine->driver_data; |
| 146 | 146 | |
| r8044 | r8045 | |
| 167 | 167 | { |
| 168 | 168 | /* |
| 169 | 169 | |
| 170 | ||
| 170 | bit description | |
| 171 | 171 | |
| 172 | 0 | |
| 173 | 1 | |
| 174 | 2 | |
| 175 | 3 | |
| 176 | 4 sound clock | |
| 177 | 5 | |
| 178 | 6 | |
| 179 | 7 joystick enable | |
| 172 | 0 | |
| 173 | 1 | |
| 174 | 2 | |
| 175 | 3 | |
| 176 | 4 sound clock | |
| 177 | 5 | |
| 178 | 6 | |
| 179 | 7 joystick enable | |
| 180 | 180 | |
| 181 | ||
| 181 | */ | |
| 182 | 182 | |
| 183 | 183 | vidbrain_state *state = (vidbrain_state *)space->machine->driver_data; |
| 184 | 184 | |
| r8044 | r8045 | |
| 337 | 337 | |
| 338 | 338 | static PALETTE_INIT( vidbrain ) |
| 339 | 339 | { |
| 340 | palette_set_color_rgb(machine, 0, 0x00, 0x00, 0x00 ); // | |
| 340 | palette_set_color_rgb(machine, 0, 0x00, 0x00, 0x00 ); // | |
| 341 | 341 | palette_set_color_rgb(machine, 1, 0xff, 0x00, 0x00 ); // red |
| 342 | palette_set_color_rgb(machine, 2, 0x00, 0xff, 0x00 ); // | |
| 343 | palette_set_color_rgb(machine, 3, 0xff, 0xff, 0x00 ); // | |
| 342 | palette_set_color_rgb(machine, 2, 0x00, 0xff, 0x00 ); // | |
| 343 | palette_set_color_rgb(machine, 3, 0xff, 0xff, 0x00 ); // | |
| 344 | 344 | palette_set_color_rgb(machine, 4, 0x00, 0x00, 0xff ); // blue |
| 345 | palette_set_color_rgb(machine, 5, 0xff, 0x00, 0xff ); // | |
| 346 | palette_set_color_rgb(machine, 6, 0x00, 0xff, 0xff ); // | |
| 347 | palette_set_color_rgb(machine, 7, 0xff, 0xff, 0xff ); // | |
| 345 | palette_set_color_rgb(machine, 5, 0xff, 0x00, 0xff ); // | |
| 346 | palette_set_color_rgb(machine, 6, 0x00, 0xff, 0xff ); // | |
| 347 | palette_set_color_rgb(machine, 7, 0xff, 0xff, 0xff ); // | |
| 348 | 348 | |
| 349 | palette_set_color_rgb(machine, 8, 0x00, 0x00, 0x00 ); // | |
| 349 | palette_set_color_rgb(machine, 8, 0x00, 0x00, 0x00 ); // | |
| 350 | 350 | palette_set_color_rgb(machine, 9, 0x80, 0x00, 0x00 ); // red |
| 351 | palette_set_color_rgb(machine, 10, 0x00, 0x80, 0x00 ); // | |
| 352 | palette_set_color_rgb(machine, 11, 0x80, 0x80, 0x00 ); // | |
| 351 | palette_set_color_rgb(machine, 10, 0x00, 0x80, 0x00 ); // | |
| 352 | palette_set_color_rgb(machine, 11, 0x80, 0x80, 0x00 ); // | |
| 353 | 353 | palette_set_color_rgb(machine, 12, 0x00, 0x00, 0x80 ); // blue |
| 354 | palette_set_color_rgb(machine, 13, 0x80, 0x00, 0x80 ); // | |
| 355 | palette_set_color_rgb(machine, 14, 0x00, 0x80, 0x80 ); // | |
| 356 | palette_set_color_rgb(machine, 15, 0x80, 0x80, 0x80 ); // | |
| 354 | palette_set_color_rgb(machine, 13, 0x80, 0x00, 0x80 ); // | |
| 355 | palette_set_color_rgb(machine, 14, 0x00, 0x80, 0x80 ); // | |
| 356 | palette_set_color_rgb(machine, 15, 0x80, 0x80, 0x80 ); // | |
| 357 | 357 | } |
| 358 | 358 | |
| 359 | 359 | /*------------------------------------------------- |
| r8044 | r8045 | |
| 448 | 448 | }; |
| 449 | 449 | |
| 450 | 450 | /*------------------------------------------------- |
| 451 | ||
| 451 | cart loading (+ software list) | |
| 452 | 452 | -------------------------------------------------*/ |
| 453 | 453 | |
| 454 | 454 | static DEVICE_IMAGE_LOAD( vidbrain_cart ) |
| 455 | 455 | { |
| 456 | 456 | UINT32 size; |
| 457 | 457 | UINT8 *ptr = memory_region(image->machine, F3850_TAG) + 0x1000; |
| 458 | ||
| 458 | ||
| 459 | 459 | if (image_software_entry(image) == NULL) |
| 460 | 460 | { |
| 461 | 461 | size = image_length(image); |
| r8044 | r8045 | |
| 467 | 467 | size = image_get_software_region_length(image, "rom"); |
| 468 | 468 | memcpy(ptr, image_get_software_region(image, "rom"), size); |
| 469 | 469 | } |
| 470 | ||
| 470 | ||
| 471 | 471 | return INIT_PASS; |
| 472 | 472 | } |
| 473 | 473 | |
| r8044 | r8045 | |
| 565 | 565 | SYSTEM DRIVERS |
| 566 | 566 | ***************************************************************************/ |
| 567 | 567 | |
| 568 | /* YEAR NAME | |
| 568 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ | |
| 569 | 569 | COMP( 1977, vidbrain, 0, 0, vidbrain, vidbrain, 0, "VideoBrain Computer Company", "VideoBrain FamilyComputer", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| r8044 | r8045 | |
|---|---|---|
| 112 | 112 | } |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | static PALETTE_INIT( wscolor ) | |
| 115 | static PALETTE_INIT( wscolor ) | |
| 116 | 116 | { |
| 117 | 117 | int i; |
| 118 | for (i = 0; i < 4096; i++) | |
| 118 | for (i = 0; i < 4096; i++) | |
| 119 | 119 | { |
| 120 | 120 | int r = (i & 0x0f00) >> 8; |
| 121 | 121 | int g = (i & 0x00f0) >> 4; |
| r8044 | r8045 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | TODO: |
| 12 | 12 | |
| 13 | - TRSDOS does not accept any date | |
| 14 | - CP/M does halts after typing EX | |
| 15 | - wd17xx.c thinks the drive is always ready | |
| 13 | - TRSDOS does not accept any date | |
| 14 | - CP/M does halts after typing EX | |
| 15 | - wd17xx.c thinks the drive is always ready | |
| 16 | 16 | - keyboard CPU ROM |
| 17 | 17 | - graphics board |
| 18 | 18 | |
| r8044 | r8045 | |
| 1051 | 1051 | MDRV_IMPORT_FROM(trs80m2) |
| 1052 | 1052 | |
| 1053 | 1053 | /* basic machine hardware */ |
| 1054 | // MDRV_CPU_ADD(M68000_TAG, M68000, 6000000) | |
| 1055 | // MDRV_CPU_PROGRAM_MAP(m68000_mem) | |
| 1054 | // MDRV_CPU_ADD(M68000_TAG, M68000, 6000000) | |
| 1055 | // MDRV_CPU_PROGRAM_MAP(m68000_mem) | |
| 1056 | 1056 | |
| 1057 | 1057 | /* video hardware */ |
| 1058 | 1058 | MDRV_PALETTE_INIT(monochrome_green) |
| r8044 | r8045 | |
|---|---|---|
| 173 | 173 | { |
| 174 | 174 | UINT8 *cart = memory_region(image->machine, "cart"); |
| 175 | 175 | UINT32 size; |
| 176 | ||
| 176 | ||
| 177 | 177 | if (image_software_entry(image) == NULL) |
| 178 | 178 | size = image_length(image); |
| 179 | 179 | else |
| 180 | 180 | size = image_get_software_region_length(image, "rom"); |
| 181 | ||
| 182 | 181 | |
| 182 | ||
| 183 | 183 | if (size != 0x2000 && size != 0x4000) |
| 184 | 184 | { |
| 185 | 185 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); |
| r8044 | r8045 | |
| 196 | 196 | } |
| 197 | 197 | else |
| 198 | 198 | memcpy(cart, image_get_software_region(image, "rom"), size); |
| 199 | ||
| 200 | 199 | |
| 200 | ||
| 201 | 201 | /* Mirror 8KB rom */ |
| 202 | 202 | if (size == 0x2000) |
| 203 | 203 | memcpy(cart + 0x2000, cart, 0x2000); |
| r8044 | r8045 | |
|---|---|---|
| 677 | 677 | filesize = image_get_software_region_length(image, "rom"); |
| 678 | 678 | memcpy(memory_region(image->machine, "cart"), image_get_software_region(image, "rom"), filesize); |
| 679 | 679 | } |
| 680 | ||
| 680 | ||
| 681 | 681 | state->flash_chip[0].manufacturer_id = 0x98; |
| 682 | 682 | switch( filesize ) |
| 683 | 683 | { |
| r8044 | r8045 | |
|---|---|---|
| 234 | 234 | MDRV_CARTSLOT_ADD("cart") |
| 235 | 235 | MDRV_CARTSLOT_EXTENSION_LIST("nes,unf") |
| 236 | 236 | MDRV_CARTSLOT_MANDATORY |
| 237 | // | |
| 237 | // MDRV_CARTSLOT_INTERFACE("nes_cart") | |
| 238 | 238 | MDRV_CARTSLOT_LOAD(nes_cart) |
| 239 | 239 | MDRV_CARTSLOT_PARTIALHASH(nes_partialhash) |
| 240 | // | |
| 240 | // MDRV_SOFTWARE_LIST_ADD("nes") | |
| 241 | 241 | MACHINE_DRIVER_END |
| 242 | 242 | |
| 243 | 243 | static MACHINE_DRIVER_START( nespal ) |
| r8044 | r8045 | |
|---|---|---|
| 80 | 80 | /* Driver */ |
| 81 | 81 | |
| 82 | 82 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 83 | COMP( 1997, pv9234, 0, 0, | |
| 83 | COMP( 1997, pv9234, 0, 0, | |
| 84 | 84 |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | DEC VT240 |
| 4 | 4 | |
| 5 | 5 | 31/03/2010 Skeleton driver. |
| r8044 | r8045 | |
| 29 | 29 | INPUT_PORTS_END |
| 30 | 30 | |
| 31 | 31 | |
| 32 | static MACHINE_RESET(vt240) | |
| 33 | { | |
| 32 | static MACHINE_RESET(vt240) | |
| 33 | { | |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | static VIDEO_START( vt240 ) |
| r8044 | r8045 | |
| 46 | 46 | /* basic machine hardware */ |
| 47 | 47 | MDRV_CPU_ADD("maincpu", 8085A, XTAL_16MHz / 4) |
| 48 | 48 | MDRV_CPU_PROGRAM_MAP(vt240_mem) |
| 49 | MDRV_CPU_IO_MAP(vt240_io) | |
| 49 | MDRV_CPU_IO_MAP(vt240_io) | |
| 50 | 50 | |
| 51 | 51 | MDRV_MACHINE_RESET(vt240) |
| 52 | ||
| 52 | ||
| 53 | 53 | /* video hardware */ |
| 54 | 54 | MDRV_SCREEN_ADD("screen", RASTER) |
| 55 | 55 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 74 | 74 | ROM_REGION( 0x20000, "subcpu", ROMREGION_ERASEFF ) |
| 75 | 75 | ROM_LOAD16_BYTE( "029.bin", 0x00000, 0x8000, CRC(4a6db217) SHA1(47637325609ea19ffab61fe31e2700d72fa50729)) |
| 76 | 76 | ROM_LOAD16_BYTE( "031.bin", 0x00001, 0x8000, CRC(47129579) SHA1(39de9e2e26f90c5da5e72a09ff361c1a94b9008a)) |
| 77 | ||
| 78 | ROM_LOAD16_BYTE( "030.bin", 0x10000, 0x8000, CRC(05fd7b75) SHA1(2ad8c14e76accfa1b9b8748c58e9ebbc28844a47)) | |
| 77 | ||
| 78 | ROM_LOAD16_BYTE( "030.bin", 0x10000, 0x8000, CRC(05fd7b75) SHA1(2ad8c14e76accfa1b9b8748c58e9ebbc28844a47)) | |
| 79 | 79 | ROM_LOAD16_BYTE( "032.bin", 0x10001, 0x8000, CRC(e81d93c4) SHA1(982412a7a6e65d6f6b4f66bd093e54ee16f31384)) |
| 80 | 80 | ROM_END |
| 81 | 81 | |
| r8044 | r8045 | |
| 84 | 84 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT CONFIG COMPANY FULLNAME FLAGS */ |
| 85 | 85 | //COMP( 1983, vt240, 0, 0, vt220, vt220, 0, "DEC", "VT240", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 86 | 86 | //COMP( 1983, vt241, 0, 0, vt220, vt220, 0, "DEC", "VT241", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 87 | COMP( 1983, mc7105, 0, 0, | |
| 87 | COMP( 1983, mc7105, 0, 0, | |
| 88 | 88 |
| r8044 | r8045 | |
|---|---|---|
| 46 | 46 | { |
| 47 | 47 | if (cpu_get_pc(space->cpu)==0xc0ba52a) |
| 48 | 48 | cpu_spinuntil_time(space->cpu, ATTOTIME_IN_USEC(2500)); |
| 49 | // | |
| 49 | // cpu_spinuntil_int(space->cpu); | |
| 50 | 50 | |
| 51 | 51 | return dc_ram[0x2303b0/8]; |
| 52 | 52 | } |
| r8044 | r8045 | |
| 55 | 55 | { |
| 56 | 56 | if (cpu_get_pc(space->cpu)==0xc0bac62) |
| 57 | 57 | cpu_spinuntil_time(space->cpu, ATTOTIME_IN_USEC(2500)); |
| 58 | // | |
| 58 | // cpu_spinuntil_int(space->cpu); | |
| 59 | 59 | |
| 60 | 60 | return dc_ram[0x2302f8/8]; |
| 61 | 61 | } |
| r8044 | r8045 | |
|---|---|---|
| 523 | 523 | size = image_get_software_region_length(image, "rom"); |
| 524 | 524 | memcpy(user, image_get_software_region(image, "rom"), size); |
| 525 | 525 | } |
| 526 | ||
| 526 | ||
| 527 | 527 | return INIT_PASS; |
| 528 | 528 | } |
| 529 | 529 |
| r8044 | r8045 | |
|---|---|---|
| 4 | 4 | |
| 5 | 5 | 12/05/2009 Skeleton driver. |
| 6 | 6 | |
| 7 | The system contains 4 S100 boards, 2 8" floppies, enormous power supply, | |
| 8 | 1/4" thick mother board, 4 RS232 I/F boards, and an Australian made | |
| 9 | "Computer Patch Board". | |
| 10 | The S100 boards that make up the unit are: | |
| 11 | CPU board - Model CPC2810 Rev D | |
| 12 | The board has a Z80A CPU, CTC, PIO, DART and SIO. | |
| 13 | U16 (24 pin) is missing (boot EPROM?). | |
| 14 | It has a lot of jumpers and an 8 way DIP switch. | |
| 15 | Memory board - Model HDM2800 Rev B | |
| 16 | This contains 18 4164's and a lot of logic. | |
| 17 | Again, a lot of jumpers, and several banks of links. | |
| 18 | Also contains 2 Motorola chips I cannot identify, | |
| 19 | MC3480P (24 pin) and MC3242AP (28 pin). | |
| 20 | (I have searched the Motorola site and the Chip | |
| 21 | Directory; nothing even close.) | |
| 22 | Disk Controller board - Model FDC2800 Rev D | |
| 23 | This board is damaged. The small voltage regulators | |
| 24 | for +/- 12V have been fried. | |
| 25 | Also, 3 sockets are empty - U1 and U38 (16 pin) | |
| 26 | appear to be spares, and U10 (14 pin). | |
| 27 | 8 port Serial I/O board - Model INO2808 Rev C | |
| 28 | Room for 8 8251 USART's. | |
| 29 | I have traced out this board and managed to get it | |
| 30 | working in another S100 system. | |
| 31 | The "Computer Patch Board" seems to provide some sort of watch dog | |
| 32 | facility. | |
| 7 | The system contains 4 S100 boards, 2 8" floppies, enormous power supply, | |
| 8 | 1/4" thick mother board, 4 RS232 I/F boards, and an Australian made | |
| 9 | "Computer Patch Board". | |
| 10 | The S100 boards that make up the unit are: | |
| 11 | CPU board - Model CPC2810 Rev D | |
| 12 | The board has a Z80A CPU, CTC, PIO, DART and SIO. | |
| 13 | U16 (24 pin) is missing (boot EPROM?). | |
| 14 | It has a lot of jumpers and an 8 way DIP switch. | |
| 15 | Memory board - Model HDM2800 Rev B | |
| 16 | This contains 18 4164's and a lot of logic. | |
| 17 | Again, a lot of jumpers, and several banks of links. | |
| 18 | Also contains 2 Motorola chips I cannot identify, | |
| 19 | MC3480P (24 pin) and MC3242AP (28 pin). | |
| 20 | (I have searched the Motorola site and the Chip | |
| 21 | Directory; nothing even close.) | |
| 22 | Disk Controller board - Model FDC2800 Rev D | |
| 23 | This board is damaged. The small voltage regulators | |
| 24 | for +/- 12V have been fried. | |
| 25 | Also, 3 sockets are empty - U1 and U38 (16 pin) | |
| 26 | appear to be spares, and U10 (14 pin). | |
| 27 | 8 port Serial I/O board - Model INO2808 Rev C | |
| 28 | Room for 8 8251 USART's. | |
| 29 | I have traced out this board and managed to get it | |
| 30 | working in another S100 system. | |
| 31 | The "Computer Patch Board" seems to provide some sort of watch dog | |
| 32 | facility. | |
| 33 | 33 | |
| 34 | 34 | ****************************************************************************/ |
| 35 | 35 |
| r8044 | r8045 | |
|---|---|---|
| 162 | 162 | |
| 163 | 163 | if (image_fread(image, data, length) != length) |
| 164 | 164 | { |
| 165 | free(data); | |
| 165 | free(data); | |
| 166 | 166 | return INIT_FAIL; |
| 167 | 167 | } |
| 168 | 168 |
| r8044 | r8045 | |
|---|---|---|
| 115 | 115 | length = image_get_software_region_length(image, "rom"); |
| 116 | 116 | memcpy(cart, image_get_software_region(image, "rom"), length); |
| 117 | 117 | } |
| 118 | ||
| 118 | ||
| 119 | 119 | if (cart[0] == 0x37 && cart[1] == 0x80) |
| 120 | 120 | { |
| 121 | 121 | for (i = 0; i < length; i += 4) |
| r8044 | r8045 | |
|---|---|---|
| 266 | 266 | PORT_CONFSETTING( 0x01, "TI SD Floppy Controller" ) |
| 267 | 267 | PORT_CONFSETTING( 0x02, "SNUG BwG Controller" ) |
| 268 | 268 | PORT_CONFSETTING( 0x03, "Myarc HFDC" ) |
| 269 | // | |
| 269 | // PORT_CONFSETTING( 0x04, "Corcomp" ) | |
| 270 | 270 | |
| 271 | 271 | PORT_START( "HDCTRL" ) |
| 272 | 272 | PORT_CONFNAME( 0x03, 0x00, "HD controller" ) |
| 273 | 273 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 274 | 274 | PORT_CONFSETTING( 0x01, "Nouspikel IDE Controller" ) |
| 275 | // | |
| 275 | // PORT_CONFSETTING( 0x02, "WHTech SCSI Controller" ) | |
| 276 | 276 | PORT_CONFNAME( 0x08, 0x00, "USB-SM card" ) |
| 277 | 277 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 278 | 278 | PORT_CONFSETTING( 0x08, DEF_STR( On ) ) |
| r8044 | r8045 | |
| 288 | 288 | PORT_DIPSETTING( 0xaa, "40 track, 8 ms") |
| 289 | 289 | PORT_DIPSETTING( 0x55, "80 track, 2 ms") |
| 290 | 290 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") |
| 291 | ||
| 291 | ||
| 292 | 292 | PORT_START( "DRVSPD" ) |
| 293 | 293 | PORT_DIPNAME( 0x01, 0x01, "Floppy and HD speed" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| 294 | 294 | PORT_DIPSETTING( 0x00, "No delay") |
| 295 | 295 | PORT_DIPSETTING( 0x01, "Realistic") |
| 296 | ||
| 296 | ||
| 297 | 297 | PORT_START("JOY") /* col 1: "wired handset 1" (= joystick 1) */ |
| 298 | 298 | PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_UP/*, "(1UP)", CODE_NONE, OSD_JOY_UP*/) PORT_PLAYER(1) |
| 299 | 299 | PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN/*, "(1DOWN)", CODE_NONE, OSD_JOY_DOWN, 0*/) PORT_PLAYER(1) |
| r8044 | r8045 | |
|---|---|---|
| 2 | 2 | |
| 3 | 3 | Victor 9000 |
| 4 | 4 | |
| 5 | - very exciting hardware, disk controller is a direct descendant | |
| 6 | of the Commodore drives (designed by Chuck Peddle) | |
| 5 | - very exciting hardware, disk controller is a direct descendant | |
| 6 | of the Commodore drives (designed by Chuck Peddle) | |
| 7 | 7 | |
| 8 | 8 | Skeleton driver |
| 9 | 9 | |
| r8044 | r8045 | |
| 11 | 11 | |
| 12 | 12 | /* |
| 13 | 13 | |
| 14 | ||
| 14 | TODO: | |
| 15 | 15 | |
| 16 | - floppy 8048 | |
| 17 | - keyboard | |
| 18 | - add HD46505S variant to mc6845.c | |
| 19 | - hires graphics | |
| 20 | - character attributes | |
| 21 | - brightness/contrast | |
| 22 | - MC6852 | |
| 23 | - codec sound | |
| 16 | - floppy 8048 | |
| 17 | - keyboard | |
| 18 | - add HD46505S variant to mc6845.c | |
| 19 | - hires graphics | |
| 20 | - character attributes | |
| 21 | - brightness/contrast | |
| 22 | - MC6852 | |
| 23 | - codec sound | |
| 24 | 24 | |
| 25 | 25 | */ |
| 26 | 26 | |
| r8044 | r8045 | |
| 43 | 43 | /* Memory Maps */ |
| 44 | 44 | |
| 45 | 45 | static ADDRESS_MAP_START( victor9k_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 46 | // | |
| 46 | // AM_RANGE(0x00000, 0xdffff) AM_RAM | |
| 47 | 47 | AM_RANGE(0xe0000, 0xe0001) AM_DEVREADWRITE(I8259A_TAG, pic8259_r, pic8259_w) |
| 48 | 48 | AM_RANGE(0xe0020, 0xe0023) AM_DEVREADWRITE(I8253_TAG, pit8253_r, pit8253_w) |
| 49 | 49 | AM_RANGE(0xe0040, 0xe0043) AM_DEVREADWRITE(UPD7201_TAG, upd7201_cd_ba_r, upd7201_cd_ba_w) |
| r8044 | r8045 | |
| 192 | 192 | |
| 193 | 193 | /* |
| 194 | 194 | |
| 195 | ||
| 195 | pin signal description | |
| 196 | 196 | |
| 197 | IR0 SYN sync detect | |
| 198 | IR1 COMM serial communications (7201) | |
| 199 | IR2 TIMER 8253 timer | |
| 200 | IR3 PARALLEL all 6522 IRQ (including disk) | |
| 201 | IR4 IR4 expansion IR4 | |
| 202 | IR5 IR5 expansion IR5 | |
| 203 | IR6 KBINT keyboard data ready | |
| 204 | IR7 VINT vertical sync or nonspecific interrupt | |
| 197 | IR0 SYN sync detect | |
| 198 | IR1 COMM serial communications (7201) | |
| 199 | IR2 TIMER 8253 timer | |
| 200 | IR3 PARALLEL all 6522 IRQ (including disk) | |
| 201 | IR4 IR4 expansion IR4 | |
| 202 | IR5 IR5 expansion IR5 | |
| 203 | IR6 KBINT keyboard data ready | |
| 204 | IR7 VINT vertical sync or nonspecific interrupt | |
| 205 | 205 | |
| 206 | 206 | */ |
| 207 | 207 | |
| r8044 | r8045 | |
| 676 | 676 | PB0 L1MS0 |
| 677 | 677 | PB1 L1MS1 |
| 678 | 678 | PB2 L1MS2 |
| 679 | PB3 | |
| 679 | PB3 L1MS3 | |
| 680 | 680 | PB4 ST1A |
| 681 | 681 | PB5 ST1B |
| 682 | 682 | PB6 ST1C |
| r8044 | r8045 | |
| 1006 | 1006 | MDRV_CPU_ADD(I8048_TAG, I8048, XTAL_30MHz/6) |
| 1007 | 1007 | MDRV_CPU_IO_MAP(floppy_io) |
| 1008 | 1008 | |
| 1009 | // MDRV_CPU_ADD(I8022_TAG, I8022, 100000) | |
| 1010 | // MDRV_CPU_IO_MAP(keyboard_io) | |
| 1009 | // MDRV_CPU_ADD(I8022_TAG, I8022, 100000) | |
| 1010 | // MDRV_CPU_IO_MAP(keyboard_io) | |
| 1011 | 1011 | |
| 1012 | 1012 | MDRV_MACHINE_START(victor9k) |
| 1013 | 1013 | |
| r8044 | r8045 | |
| 1076 | 1076 | |
| 1077 | 1077 | /* System Drivers */ |
| 1078 | 1078 | |
| 1079 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY | |
| 1079 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ | |
| 1080 | 1080 | COMP( 1982, victor9k, 0, 0, victor9k, victor9k, 0, "Victor Business Products", "Victor 9000", GAME_NOT_WORKING ) |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | instruct |
| 4 | 4 | |
| 5 | 5 | 08/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 12 | 12 | static ADDRESS_MAP_START(instruct_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 13 | 13 | ADDRESS_MAP_UNMAP_HIGH |
| 14 | 14 | AM_RANGE( 0x0000, 0x07ff) AM_ROM |
| 15 | AM_RANGE( 0x0800, 0x7fff) AM_RAM | |
| 15 | AM_RANGE( 0x0800, 0x7fff) AM_RAM | |
| 16 | 16 | ADDRESS_MAP_END |
| 17 | 17 | |
| 18 | 18 | static ADDRESS_MAP_START( instruct_io , ADDRESS_SPACE_IO, 8) |
| r8044 | r8045 | |
| 24 | 24 | INPUT_PORTS_END |
| 25 | 25 | |
| 26 | 26 | |
| 27 | static MACHINE_RESET(instruct) | |
| 28 | { | |
| 27 | static MACHINE_RESET(instruct) | |
| 28 | { | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | static VIDEO_START( instruct ) |
| r8044 | r8045 | |
| 41 | 41 | /* basic machine hardware */ |
| 42 | 42 | MDRV_CPU_ADD("maincpu",S2650, XTAL_1MHz) |
| 43 | 43 | MDRV_CPU_PROGRAM_MAP(instruct_mem) |
| 44 | MDRV_CPU_IO_MAP(instruct_io) | |
| 44 | MDRV_CPU_IO_MAP(instruct_io) | |
| 45 | 45 | |
| 46 | 46 | MDRV_MACHINE_RESET(instruct) |
| 47 | ||
| 47 | ||
| 48 | 48 | /* video hardware */ |
| 49 | 49 | MDRV_SCREEN_ADD("screen", RASTER) |
| 50 | 50 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 68 | 68 | /* Driver */ |
| 69 | 69 | |
| 70 | 70 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 71 | COMP( 1978, instruct, 0, 0, | |
| 71 | COMP( 1978, instruct, 0, 0, | |
| 72 | 72 |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | Alesis HR-16 and SR-16 drum machines |
| 4 | 4 | |
| 5 | 5 | 06/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 36 | 36 | INPUT_PORTS_END |
| 37 | 37 | |
| 38 | 38 | |
| 39 | static MACHINE_RESET(alesis) | |
| 40 | { | |
| 39 | static MACHINE_RESET(alesis) | |
| 40 | { | |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | static VIDEO_START( alesis ) |
| r8044 | r8045 | |
| 53 | 53 | /* basic machine hardware */ |
| 54 | 54 | MDRV_CPU_ADD("maincpu",I8031, XTAL_12MHz) |
| 55 | 55 | MDRV_CPU_PROGRAM_MAP(hr16_mem) |
| 56 | MDRV_CPU_IO_MAP(hr16_io) | |
| 56 | MDRV_CPU_IO_MAP(hr16_io) | |
| 57 | 57 | |
| 58 | 58 | MDRV_MACHINE_RESET(alesis) |
| 59 | ||
| 59 | ||
| 60 | 60 | /* video hardware */ |
| 61 | 61 | MDRV_SCREEN_ADD("screen", RASTER) |
| 62 | 62 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 75 | 75 | /* basic machine hardware */ |
| 76 | 76 | MDRV_CPU_ADD("maincpu",I8031, XTAL_12MHz) |
| 77 | 77 | MDRV_CPU_PROGRAM_MAP(sr16_mem) |
| 78 | MDRV_CPU_IO_MAP(sr16_io) | |
| 78 | MDRV_CPU_IO_MAP(sr16_io) | |
| 79 | 79 | |
| 80 | 80 | MDRV_MACHINE_RESET(alesis) |
| 81 | ||
| 81 | ||
| 82 | 82 | /* video hardware */ |
| 83 | 83 | MDRV_SCREEN_ADD("screen", RASTER) |
| 84 | 84 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 109 | 109 | ROM_END |
| 110 | 110 | |
| 111 | 111 | ROM_START( hr16b ) |
| 112 | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) | |
| 112 | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) | |
| 113 | 113 | |
| 114 | 114 | ROM_REGION( 0x10000, "user1", ROMREGION_ERASEFF ) |
| 115 | 115 | // version 2.00 |
| r8044 | r8045 | |
| 127 | 127 | |
| 128 | 128 | ROM_REGION( 0x100000, "sounddata", ROMREGION_ERASEFF ) |
| 129 | 129 | ROM_LOAD( "sr16.u5", 0x00000, 0x80000, CRC(8bb25cfa) SHA1(273ad59d017b54a7e8d5e1ec61c8cd807a0e4af3)) |
| 130 | ROM_LOAD( "sr16.u6", 0x80000, 0x80000, CRC(6da96987) SHA1(3ec8627d440bc73841e1408a19def09a8b0b77f7)) | |
| 130 | ROM_LOAD( "sr16.u6", 0x80000, 0x80000, CRC(6da96987) SHA1(3ec8627d440bc73841e1408a19def09a8b0b77f7)) | |
| 131 | 131 | ROM_END |
| 132 | 132 | |
| 133 | 133 |
| r8044 | r8045 | |
|---|---|---|
| 54 | 54 | The atom driver in MESS uses the original memory area. |
| 55 | 55 | |
| 56 | 56 | |
| 57 | ||
| 57 | http://www.xs4all.nl/~fjkraan/comp/atom/index.html | |
| 58 | 58 | |
| 59 | 59 | ***************************************************************************/ |
| 60 | 60 | |
| 61 | 61 | /* |
| 62 | 62 | |
| 63 | ||
| 63 | TODO: | |
| 64 | 64 | |
| 65 | - ERROR repeats ad infinitum | |
| 66 | - display should be monochrome | |
| 67 | - ram expansion | |
| 68 | - tap files | |
| 69 | - mouse | |
| 70 | - move eprom box roms to software list | |
| 71 | - color card | |
| 72 | - CP/M card | |
| 73 | - speech synthesis card (SPO256 connected to VIA) | |
| 65 | - ERROR repeats ad infinitum | |
| 66 | - display should be monochrome | |
| 67 | - ram expansion | |
| 68 | - tap files | |
| 69 | - mouse | |
| 70 | - move eprom box roms to software list | |
| 71 | - color card | |
| 72 | - CP/M card | |
| 73 | - speech synthesis card (SPO256 connected to VIA) | |
| 74 | 74 | |
| 75 | 75 | */ |
| 76 | 76 | |
| r8044 | r8045 | |
| 327 | 327 | { |
| 328 | 328 | /* |
| 329 | 329 | |
| 330 | ||
| 330 | bit description | |
| 331 | 331 | |
| 332 | 0 keyboard column 0 | |
| 333 | 1 keyboard column 1 | |
| 334 | 2 keyboard column 2 | |
| 335 | 3 keyboard column 3 | |
| 336 | 4 MC6847 A/G | |
| 337 | 5 MC6847 GM0 | |
| 338 | 6 MC6847 GM1 | |
| 339 | 7 MC6847 GM2 | |
| 332 | 0 keyboard column 0 | |
| 333 | 1 keyboard column 1 | |
| 334 | 2 keyboard column 2 | |
| 335 | 3 keyboard column 3 | |
| 336 | 4 MC6847 A/G | |
| 337 | 5 MC6847 GM0 | |
| 338 | 6 MC6847 GM1 | |
| 339 | 7 MC6847 GM2 | |
| 340 | 340 | |
| 341 | ||
| 341 | */ | |
| 342 | 342 | |
| 343 | 343 | atom_state *state = (atom_state *)device->machine->driver_data; |
| 344 | 344 | |
| r8044 | r8045 | |
| 356 | 356 | { |
| 357 | 357 | /* |
| 358 | 358 | |
| 359 | ||
| 359 | bit description | |
| 360 | 360 | |
| 361 | 0 keyboard row 0 | |
| 362 | 1 keyboard row 1 | |
| 363 | 2 keyboard row 2 | |
| 364 | 3 keyboard row 3 | |
| 365 | 4 keyboard row 4 | |
| 366 | 5 keyboard row 5 | |
| 367 | 6 keyboard CTRL | |
| 368 | 7 keyboard SFT | |
| 361 | 0 keyboard row 0 | |
| 362 | 1 keyboard row 1 | |
| 363 | 2 keyboard row 2 | |
| 364 | 3 keyboard row 3 | |
| 365 | 4 keyboard row 4 | |
| 366 | 5 keyboard row 5 | |
| 367 | 6 keyboard CTRL | |
| 368 | 7 keyboard SFT | |
| 369 | 369 | |
| 370 | ||
| 370 | */ | |
| 371 | 371 | |
| 372 | 372 | atom_state *state = (atom_state *)device->machine->driver_data; |
| 373 | 373 | UINT8 data = 0xff; |
| r8044 | r8045 | |
| 395 | 395 | { |
| 396 | 396 | /* |
| 397 | 397 | |
| 398 | ||
| 398 | bit description | |
| 399 | 399 | |
| 400 | 0 O/P 1, cassette output 0 | |
| 401 | 1 O/P 2, cassette output 1 | |
| 402 | 2 O/P 3, speaker output | |
| 403 | 3 O/P 4, MC6847 CSS | |
| 404 | 4 2400 Hz input | |
| 405 | 5 cassette input | |
| 406 | 6 keyboard RPT | |
| 407 | 7 MC6847 FS | |
| 400 | 0 O/P 1, cassette output 0 | |
| 401 | 1 O/P 2, cassette output 1 | |
| 402 | 2 O/P 3, speaker output | |
| 403 | 3 O/P 4, MC6847 CSS | |
| 404 | 4 2400 Hz input | |
| 405 | 5 cassette input | |
| 406 | 6 keyboard RPT | |
| 407 | 7 MC6847 FS | |
| 408 | 408 | |
| 409 | ||
| 409 | */ | |
| 410 | 410 | |
| 411 | 411 | atom_state *state = (atom_state *)device->machine->driver_data; |
| 412 | 412 | |
| r8044 | r8045 | |
| 431 | 431 | { |
| 432 | 432 | /* |
| 433 | 433 | |
| 434 | ||
| 434 | bit description | |
| 435 | 435 | |
| 436 | 0 O/P 1, cassette output 0 | |
| 437 | 1 O/P 2, cassette output 1 | |
| 438 | 2 O/P 3, speaker output | |
| 439 | 3 O/P 4, MC6847 CSS | |
| 440 | 4 2400 Hz input | |
| 441 | 5 cassette input | |
| 442 | 6 keyboard RPT | |
| 443 | 7 MC6847 FS | |
| 436 | 0 O/P 1, cassette output 0 | |
| 437 | 1 O/P 2, cassette output 1 | |
| 438 | 2 O/P 3, speaker output | |
| 439 | 3 O/P 4, MC6847 CSS | |
| 440 | 4 2400 Hz input | |
| 441 | 5 cassette input | |
| 442 | 6 keyboard RPT | |
| 443 | 7 MC6847 FS | |
| 444 | 444 | |
| 445 | ||
| 445 | */ | |
| 446 | 446 | |
| 447 | 447 | atom_state *state = (atom_state *)device->machine->driver_data; |
| 448 | 448 | |
| r8044 | r8045 | |
| 798 | 798 | ROM_CONTINUE( 0x3000, 0x1000 ) |
| 799 | 799 | ROM_LOAD( "afloat.ic21", 0x1000, 0x1000, CRC(81d86af7) SHA1(ebcde5b36cb3a3344567cbba4c7b9fde015f4802) ) |
| 800 | 800 | ROM_LOAD( "dosrom.u15", 0x2000, 0x1000, CRC(c431a9b7) SHA1(71ea0a4b8d9c3caf9718fc7cc279f4306a23b39c) ) |
| 801 | ||
| 801 | ||
| 802 | 802 | ROM_REGION( 0x10000, "a000", 0 ) |
| 803 | 803 | ROM_CART_LOAD( "rom0", 0x0000, 0x1000, ROM_MIRROR ) |
| 804 | 804 | ROM_CART_LOAD( "rom1", 0x1000, 0x1000, ROM_MIRROR ) |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | elektor |
| 4 | 4 | |
| 5 | 5 | 08/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 12 | 12 | static ADDRESS_MAP_START(elektor_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 13 | 13 | ADDRESS_MAP_UNMAP_HIGH |
| 14 | 14 | AM_RANGE( 0x0000, 0x07ff) AM_ROM |
| 15 | AM_RANGE( 0x0800, 0x7fff) AM_RAM | |
| 15 | AM_RANGE( 0x0800, 0x7fff) AM_RAM | |
| 16 | 16 | ADDRESS_MAP_END |
| 17 | 17 | |
| 18 | 18 | static ADDRESS_MAP_START( elektor_io , ADDRESS_SPACE_IO, 8) |
| r8044 | r8045 | |
| 24 | 24 | INPUT_PORTS_END |
| 25 | 25 | |
| 26 | 26 | |
| 27 | static MACHINE_RESET(elektor) | |
| 28 | { | |
| 27 | static MACHINE_RESET(elektor) | |
| 28 | { | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | static VIDEO_START( elektor ) |
| r8044 | r8045 | |
| 41 | 41 | /* basic machine hardware */ |
| 42 | 42 | MDRV_CPU_ADD("maincpu",S2650, XTAL_1MHz) |
| 43 | 43 | MDRV_CPU_PROGRAM_MAP(elektor_mem) |
| 44 | MDRV_CPU_IO_MAP(elektor_io) | |
| 44 | MDRV_CPU_IO_MAP(elektor_io) | |
| 45 | 45 | |
| 46 | 46 | MDRV_MACHINE_RESET(elektor) |
| 47 | ||
| 47 | ||
| 48 | 48 | /* video hardware */ |
| 49 | 49 | MDRV_SCREEN_ADD("screen", RASTER) |
| 50 | 50 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 68 | 68 | /* Driver */ |
| 69 | 69 | |
| 70 | 70 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 71 | COMP( 1979, elektor, 0, 0, | |
| 71 | COMP( 1979, elektor, 0, 0, | |
| 72 | 72 |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | Dream Multimedia Dreambox 7000/5620/500 |
| 4 | 4 | |
| 5 | 5 | 20/03/2010 Skeleton driver. |
| 6 | 6 | |
| 7 | ||
| 8 | DM7000 - CPU STB04500 at 252 MHz | |
| 9 | RAM 64MB | |
| 10 | Flash 8MB | |
| 11 | 1 x DVB-S | |
| 12 | 1 x IDE interface | |
| 13 | 1 x Common Interface (CI) | |
| 14 | 1 x Compact flash | |
| 15 | 2 x Smart card reader | |
| 16 | 1 x USB | |
| 17 | 1 x RS232 | |
| 18 | 1 x LAN 100Mbit/s | |
| 19 | 1 x LCD display | |
| 20 | ||
| 21 | DM56x0 - CPU STB04500 at 252 MHz | |
| 22 | RAM 64MB | |
| 23 | Flash 8MB | |
| 24 | 1 x DVB-S | |
| 25 | 2 x Common Interface (CI) | |
| 26 | 1 x Smart card reader | |
| 27 | 1 x LAN 100Mbit/s (just on 5620) | |
| 28 | 1 x LCD display | |
| 29 | ||
| 30 | DM500 - CPU STBx25xx at 252 MHz | |
| 31 | RAM 96MB | |
| 32 | Flash 32MB | |
| 33 | 1 x DVB-S | |
| 34 | 1 x Smart card reader | |
| 35 | 1 x LAN 100Mbit/s | |
| 36 | ||
| 7 | ||
| 8 | DM7000 - CPU STB04500 at 252 MHz | |
| 9 | RAM 64MB | |
| 10 | Flash 8MB | |
| 11 | 1 x DVB-S | |
| 12 | 1 x IDE interface | |
| 13 | 1 x Common Interface (CI) | |
| 14 | 1 x Compact flash | |
| 15 | 2 x Smart card reader | |
| 16 | 1 x USB | |
| 17 | 1 x RS232 | |
| 18 | 1 x LAN 100Mbit/s | |
| 19 | 1 x LCD display | |
| 20 | ||
| 21 | DM56x0 - CPU STB04500 at 252 MHz | |
| 22 | RAM 64MB | |
| 23 | Flash 8MB | |
| 24 | 1 x DVB-S | |
| 25 | 2 x Common Interface (CI) | |
| 26 | 1 x Smart card reader | |
| 27 | 1 x LAN 100Mbit/s (just on 5620) | |
| 28 | 1 x LCD display | |
| 29 | ||
| 30 | DM500 - CPU STBx25xx at 252 MHz | |
| 31 | RAM 96MB | |
| 32 | Flash 32MB | |
| 33 | 1 x DVB-S | |
| 34 | 1 x Smart card reader | |
| 35 | 1 x LAN 100Mbit/s | |
| 36 | ||
| 37 | 37 | ****************************************************************************/ |
| 38 | 38 | |
| 39 | 39 | #include "emu.h" |
| r8044 | r8045 | |
| 58 | 58 | 400d 000x modem |
| 59 | 59 | */ |
| 60 | 60 | static ADDRESS_MAP_START( dm7000_mem, ADDRESS_SPACE_PROGRAM, 32 ) |
| 61 | ADDRESS_MAP_UNMAP_HIGH | |
| 61 | ADDRESS_MAP_UNMAP_HIGH | |
| 62 | 62 | AM_RANGE(0x00000000, 0x01ffffff) AM_RAM // RAM page 0 - 32MB |
| 63 | 63 | AM_RANGE(0x20000000, 0x21ffffff) AM_RAM // RAM page 1 - 32MB |
| 64 | 64 | AM_RANGE(0xfffe0000, 0xffffffff) AM_ROM AM_REGION("user1",0) |
| r8044 | r8045 | |
| 69 | 69 | INPUT_PORTS_END |
| 70 | 70 | |
| 71 | 71 | |
| 72 | static MACHINE_RESET(dm7000) | |
| 73 | { | |
| 72 | static MACHINE_RESET(dm7000) | |
| 73 | { | |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | static VIDEO_START( dm7000 ) |
| r8044 | r8045 | |
| 88 | 88 | MDRV_CPU_PROGRAM_MAP(dm7000_mem) |
| 89 | 89 | |
| 90 | 90 | MDRV_MACHINE_RESET(dm7000) |
| 91 | ||
| 91 | ||
| 92 | 92 | /* video hardware */ |
| 93 | 93 | MDRV_SCREEN_ADD("screen", RASTER) |
| 94 | 94 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 124 | 124 | /* Driver */ |
| 125 | 125 | |
| 126 | 126 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 127 | COMP( 2003, dm7000, 0, 0, dm7000, dm7000, 0, "Dream Multimedia", "Dreambox 7000", GAME_NOT_WORKING | GAME_NO_SOUND) | |
| 128 | COMP( 2004, dm5620, dm7000, 0, dm7000, dm7000, 0, "Dream Multimedia", "Dreambox 5620", GAME_NOT_WORKING | GAME_NO_SOUND) | |
| 129 | COMP( 2006, dm500, dm7000, 0, dm7000, dm7000, 0, "Dream Multimedia", "Dreambox 500", GAME_NOT_WORKING | GAME_NO_SOUND) | |
| 127 | COMP( 2003, dm7000, 0, 0, dm7000, dm7000, 0, "Dream Multimedia", "Dreambox 7000", GAME_NOT_WORKING | GAME_NO_SOUND) | |
| 128 | COMP( 2004, dm5620, dm7000, 0, dm7000, dm7000, 0, "Dream Multimedia", "Dreambox 5620", GAME_NOT_WORKING | GAME_NO_SOUND) | |
| 129 | COMP( 2006, dm500, dm7000, 0, dm7000, dm7000, 0, "Dream Multimedia", "Dreambox 500", GAME_NOT_WORKING | GAME_NO_SOUND) | |
| 130 | 130 |
| r8044 | r8045 | |
|---|---|---|
| 80 | 80 | ADDRESS_MAP_END |
| 81 | 81 | |
| 82 | 82 | static ADDRESS_MAP_START( spc_map, ADDRESS_SPACE_PROGRAM, 8) |
| 83 | AM_RANGE(0x0000, 0x00ef) AM_DEVREADWRITE("spc700", spc_ram_r, spc_ram_w) /* lower 32k ram */ | |
| 84 | AM_RANGE(0x00f0, 0x00ff) AM_DEVREADWRITE("spc700", spc_io_r, spc_io_w) /* spc io */ | |
| 83 | AM_RANGE(0x0000, 0x00ef) AM_DEVREADWRITE("spc700", spc_ram_r, spc_ram_w) /* lower 32k ram */ | |
| 84 | AM_RANGE(0x00f0, 0x00ff) AM_DEVREADWRITE("spc700", spc_io_r, spc_io_w) /* spc io */ | |
| 85 | 85 | AM_RANGE(0x0100, 0xffff) AM_DEVWRITE("spc700", spc_ram_100_w) |
| 86 | 86 | AM_RANGE(0x0100, 0xffbf) AM_DEVREAD("spc700", spc_ram_100_r) |
| 87 | 87 | AM_RANGE(0xffc0, 0xffff) AM_DEVREAD("spc700", spc_ipl_r) |
| r8044 | r8045 | |
| 279 | 279 | PORT_CATEGORY_ITEM( 0x01, "Gamepad", 11 ) |
| 280 | 280 | PORT_CATEGORY_ITEM( 0x02, "Mouse", 12 ) |
| 281 | 281 | PORT_CATEGORY_ITEM( 0x03, "Superscope", 13 ) |
| 282 | // PORT_CATEGORY_ITEM( 0x04, "Justfier", 14 ) | |
| 283 | // PORT_CATEGORY_ITEM( 0x05, "Multitap", 15 ) | |
| 282 | // PORT_CATEGORY_ITEM( 0x04, "Justfier", 14 ) | |
| 283 | // PORT_CATEGORY_ITEM( 0x05, "Multitap", 15 ) | |
| 284 | 284 | PORT_CATEGORY_CLASS( 0xf0, 0x10, "P2 Controller") |
| 285 | 285 | PORT_CATEGORY_ITEM( 0x00, "Unconnected", 20 ) |
| 286 | 286 | PORT_CATEGORY_ITEM( 0x10, "Gamepad", 21 ) |
| 287 | 287 | PORT_CATEGORY_ITEM( 0x20, "Mouse", 22 ) |
| 288 | 288 | PORT_CATEGORY_ITEM( 0x30, "Superscope", 23 ) |
| 289 | // PORT_CATEGORY_ITEM( 0x40, "Justfier", 24 ) | |
| 290 | // PORT_CATEGORY_ITEM( 0x50, "Multitap", 25 ) | |
| 289 | // PORT_CATEGORY_ITEM( 0x40, "Justfier", 24 ) | |
| 290 | // PORT_CATEGORY_ITEM( 0x50, "Multitap", 25 ) | |
| 291 | 291 | |
| 292 | 292 | PORT_INCLUDE(snes_joypads) |
| 293 | 293 | PORT_INCLUDE(snes_mouse) |
| r8044 | r8045 | |
| 514 | 514 | state->scope[port].pause_lock = 0; |
| 515 | 515 | |
| 516 | 516 | /* If we have pressed fire or cursor and we are on-screen and SuperScope is in Port2, then latch video signal. |
| 517 | Notice that we only latch Port2 because its IOBit pin is connected to bit7 of the IO Port, while Port1 has | |
| 518 | IOBit pin connected to bit6 of the IO Port, and the latter is not detected by the H/V Counters. In other | |
| 519 | words, you can connect SuperScope to Port1, but there is no way SNES could detect its on-screen position */ | |
| 517 | Notice that we only latch Port2 because its IOBit pin is connected to bit7 of the IO Port, while Port1 has | |
| 518 | IOBit pin connected to bit6 of the IO Port, and the latter is not detected by the H/V Counters. In other | |
| 519 | words, you can connect SuperScope to Port1, but there is no way SNES could detect its on-screen position */ | |
| 520 | 520 | if ((state->scope[port].buttons & 0xc0) && !(state->scope[port].buttons & 0x02) && port == 1) |
| 521 | 521 | snes_gun_latch(machine, state->scope[port].x, state->scope[port].y); |
| 522 | 522 |
| r8044 | r8045 | |
|---|---|---|
| 7 | 7 | Hector MX40c |
| 8 | 8 | Hector MX80c |
| 9 | 9 | |
| 10 | These machines can load and run cassettes for the interact / hector1. | |
| 11 | hec2hr - press 2 then 1 | |
| 12 | hec2hrp - press 2 then 1 | |
| 13 | hec2hrx - press 5 then 1 | |
| 14 | hec2mx40 - press 5 then 1 | |
| 15 | hec2mx80 - not compatible | |
| 16 | victor - press R then L | |
| 10 | These machines can load and run cassettes for the interact / hector1. | |
| 11 | hec2hr - press 2 then 1 | |
| 12 | hec2hrp - press 2 then 1 | |
| 13 | hec2hrx - press 5 then 1 | |
| 14 | hec2mx40 - press 5 then 1 | |
| 15 | hec2mx80 - not compatible | |
| 16 | victor - press R then L | |
| 17 | 17 | |
| 18 | 18 | 12/05/2009 Skeleton driver - Micko |
| 19 | 19 |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 2 | ||
| 3 | 3 | cd2650 |
| 4 | 4 | |
| 5 | 5 | 08/04/2010 Skeleton driver. |
| r8044 | r8045 | |
| 12 | 12 | static ADDRESS_MAP_START(cd2650_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 13 | 13 | ADDRESS_MAP_UNMAP_HIGH |
| 14 | 14 | AM_RANGE( 0x0000, 0x03ff) AM_ROM |
| 15 | AM_RANGE( 0x0400, 0x7fff) AM_RAM | |
| 15 | AM_RANGE( 0x0400, 0x7fff) AM_RAM | |
| 16 | 16 | ADDRESS_MAP_END |
| 17 | 17 | |
| 18 | 18 | static ADDRESS_MAP_START( cd2650_io , ADDRESS_SPACE_IO, 8) |
| r8044 | r8045 | |
| 24 | 24 | INPUT_PORTS_END |
| 25 | 25 | |
| 26 | 26 | |
| 27 | static MACHINE_RESET(cd2650) | |
| 28 | { | |
| 27 | static MACHINE_RESET(cd2650) | |
| 28 | { | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | static VIDEO_START( cd2650 ) |
| r8044 | r8045 | |
| 41 | 41 | /* basic machine hardware */ |
| 42 | 42 | MDRV_CPU_ADD("maincpu",S2650, XTAL_1MHz) |
| 43 | 43 | MDRV_CPU_PROGRAM_MAP(cd2650_mem) |
| 44 | MDRV_CPU_IO_MAP(cd2650_io) | |
| 44 | MDRV_CPU_IO_MAP(cd2650_io) | |
| 45 | 45 | |
| 46 | 46 | MDRV_MACHINE_RESET(cd2650) |
| 47 | ||
| 47 | ||
| 48 | 48 | /* video hardware */ |
| 49 | 49 | MDRV_SCREEN_ADD("screen", RASTER) |
| 50 | 50 | MDRV_SCREEN_REFRESH_RATE(50) |
| r8044 | r8045 | |
| 68 | 68 | /* Driver */ |
| 69 | 69 | |
| 70 | 70 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 71 | COMP( 1977, cd2650, 0, 0, | |
| 71 | COMP( 1977, cd2650, 0, 0, | |
| 72 | 72 |
| r8044 | r8045 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | ||
| 3 | Aamber Pegasus computer (New Zealand) | |
| 4 | 2 | |
| 5 | ||
| 3 | A | |
| 6 | 4 | |
| 7 | Each copy of the monitor rom was made for an individual machine. | |
| 8 | The early bios versions checked that it was running on that | |
| 9 | particular computer. | |
| 5 | http://web.mac.com/lord_philip/aamber_pegasus/Aamber_Pegasus.html | |
| 10 | 6 | |
| 11 | This computer has no sound. | |
| 7 | Each copy of the monitor rom was made for an individual machine. | |
| 8 | The early bios versions checked that it was running on that | |
| 9 | particular computer. | |
| 12 | 10 | |
| 13 | The usual way of loading a new rom was to plug it into the board. | |
| 14 | We have replaced this with cartslots, to save having to recompile | |
| 15 | whenever a new rom is found. Single rom programs will usually work in | |
| 16 | any slot (if it is going to work at all). A working rom will appear | |
| 17 | in the menu. Press the first letter to run it. | |
| 11 | This computer has no sound. | |
| 18 | 12 | |
| 19 | If a machine language program is loaded via cassette, do it in the | |
| 20 | Monitor (L command), when loaded press Enter, and it will be in the | |
| 21 | menu. | |
| 13 | The usual way of loading a new rom was to plug it into the board. | |
| 14 | We have replaced this with cartslots, to save having to recompile | |
| 15 | whenever a new rom is found. Single rom programs will usually work in | |
| 16 | any slot (if it is going to work at all). A working rom will appear | |
| 17 | in the menu. Press the first letter to run it. | |
| 22 | 18 | |
| 23 | Basic cassettes are loaded in the usual way, that is, start Basic, | |
| 24 | type LOAD, press Enter. When done, RUN or LIST as needed. | |
| 19 | If a machine language program is loaded via cassette, do it in the | |
| 20 | Monitor (L command), when loaded press Enter, and it will be in the | |
| 21 | menu. | |
| 25 | 22 | |
| 26 | TO DO: | |
| 27 | - Identify which rom slots the multi-rom programs should be fitted to. | |
| 28 | - Work on the other non-working programs | |
| 23 | Basic cassettes are loaded in the usual way, that is, start Basic, | |
| 24 | type LOAD, press Enter. When done, RUN or LIST as needed. | |
| 29 | 25 | |
| 26 | TO DO: | |
| 27 | - Identify which rom slots the multi-rom programs should be fitted to. | |
| 28 | - Work on the other non-working programs | |
| 29 | ||
| 30 | 30 | ****************************************************************************/ |
| 31 | 31 | |
| 32 | 32 | #include "emu.h" |
| r8044 | r8045 | |
| 72 | 72 | |
| 73 | 73 | static WRITE8_DEVICE_HANDLER( pegasus_controls ) |
| 74 | 74 | { |
| 75 | /* d0,d2 - not emulated | |
| 76 | d0 - Blank - Video blanking | |
| 77 | d1 - Char - select character rom or ram | |
| 78 | d2 - Page - enables writing to video ram | |
| 79 | d3 - Asc - Select which half of the keyboard to read | |
| 75 | /* d0,d2 - not emulated | |
| 76 | d0 - Blank - Video blanking | |
| 77 | d1 - Char - select character rom or ram | |
| 78 | d2 - Page - enables writing to video ram | |
| 79 | d3 - Asc - Select which half of the keyboard to read | |
| 80 | 80 | */ |
| 81 | 81 | |
| 82 | 82 | pegasus_control_bits = data; |
| r8044 | r8045 | |
| 105 | 105 | |
| 106 | 106 | static WRITE8_HANDLER( pegasus_pcg_w ) |
| 107 | 107 | { |
| 108 | // | |
| 108 | // if (pegasus_control_bits & 2) | |
| 109 | 109 | { |
| 110 | 110 | UINT8 code = pegasus_video_ram[offset] & 0x7f; |
| 111 | 111 | FNT[(code << 4) | (~pegasus_kbd_row & 15)] = data; |
| r8044 | r8045 | |
| 271 | 271 | }; |
| 272 | 272 | |
| 273 | 273 | /* An encrypted single rom starts with 02, decrypted with 20. Not sure what |
| 274 | ||
| 274 | multipart roms will have. */ | |
| 275 | 275 | static void pegasus_decrypt_rom( running_machine *machine, UINT16 addr ) |
| 276 | 276 | { |
| 277 | 277 | UINT8 b, *ROM = memory_region(machine, "maincpu"); |
| r8044 | r8045 | |
| 424 | 424 | /* Driver */ |
| 425 | 425 | |
| 426 | 426 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 427 | COMP( 1981, pegasus, 0, 0, pegasus, pegasus, pegasus, "Technosys", "Aamber Pegasus", GAME_NO_SOUND_HW ) | |
| 428 | COMP( 1981, pegasusm, pegasus, 0, pegasusm, pegasus, pegasus, "Technosys", "Aamber Pegasus with RAM expansion unit", GAME_NO_SOUND_HW ) | |
| 427 | COMP( 1981, pegasus, 0, 0, pegasus, pegasus, pegasus, "Technosys", "Aamber Pegasus", GAME_NO_SOUND_HW ) | |
| 428 | COMP( 1981, pegasusm, pegasus, 0, pegasusm, pegasus, pegasus, "Technosys", "Aamber Pegasus with RAM expansion unit", GAME_NO_SOUND_HW ) | |
| 429 | 429 |
| r8044 | r8045 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | TODO: |
| 12 | 12 | |
| 13 | - cassette | |
| 14 | - cartridges | |
| 15 | - SDX/FDX floppy | |
| 16 | - HDX hard disk | |
| 17 | - HRX high resolution graphics | |
| 18 | - CBM (all RAM) mode | |
| 19 | - "Silicon" disks | |
| 20 | - Multi Effect Video Wall | |
| 13 | - cassette | |
| 14 | - cartridges | |
| 15 | - SDX/FDX floppy | |
| 16 | - HDX hard disk | |
| 17 | - HRX high resolution graphics | |
| 18 | - CBM (all RAM) mode | |
| 19 | - "Silicon" disks | |
| 20 | - Multi Effect Video Wall | |
| 21 | 21 | |
| 22 | 22 | */ |
| 23 | 23 | |
| r8044 | r8045 | |
| 63 | 63 | AM_RANGE(0x04, 0x04) AM_DEVREADWRITE(CENTRONICS_TAG, mtx_prt_r, centronics_data_w) |
| 64 | 64 | AM_RANGE(0x05, 0x05) AM_READWRITE(mtx_key_lo_r, mtx_sense_w) |
| 65 | 65 | AM_RANGE(0x06, 0x06) AM_READWRITE(mtx_key_hi_r, mtx_sound_latch_w) |
| 66 | // | |
| 66 | // AM_RANGE(0x07, 0x07) PIO | |
| 67 | 67 | AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_r, z80ctc_w) |
| 68 | 68 | AM_RANGE(0x30, 0x31) AM_WRITE(hrx_address_w) |
| 69 | 69 | AM_RANGE(0x32, 0x32) AM_READWRITE(hrx_data_r, hrx_data_w) |
| 70 | 70 | AM_RANGE(0x33, 0x33) AM_READWRITE(hrx_attr_r, hrx_attr_w) |
| 71 | // AM_RANGE(0x38, 0x38) AM_DEVWRITE(MC6845_TAG, mc6845_address_w) | |
| 72 | // AM_RANGE(0x39, 0x39) AM_DEVWRITE(MC6845_TAG, mc6845_register_r, mc6845_register_w) | |
| 73 | /* AM_RANGE(0x40, 0x43) AM_DEVREADWRITE(FD1791_TAG, wd17xx_r, wd17xx_w) | |
| 74 | AM_RANGE(0x44, 0x44) AM_READWRITE(fdx_status_r, fdx_control_w) | |
| 75 | AM_RANGE(0x45, 0x45) AM_WRITE(fdx_drv_sel_w) | |
| 76 | AM_RANGE(0x46, 0x46) AM_WRITE(fdx_dma_lo_w) | |
| 77 | AM_RANGE(0x47, 0x47) AM_WRITE(fdx_dma_hi_w)*/ | |
| 71 | // AM_RANGE(0x38, 0x38) AM_DEVWRITE(MC6845_TAG, mc6845_address_w) | |
| 72 | // AM_RANGE(0x39, 0x39) AM_DEVWRITE(MC6845_TAG, mc6845_register_r, mc6845_register_w) | |
| 73 | /* AM_RANGE(0x40, 0x43) AM_DEVREADWRITE(FD1791_TAG, wd17xx_r, wd17xx_w) | |
| 74 | AM_RANGE(0x44, 0x44) AM_READWRITE(fdx_status_r, fdx_control_w) | |
| 75 | AM_RANGE(0x45, 0x45) AM_WRITE(fdx_drv_sel_w) | |
| 76 | AM_RANGE(0x46, 0x46) AM_WRITE(fdx_dma_lo_w) | |
| 77 | AM_RANGE(0x47, 0x47) AM_WRITE(fdx_dma_hi_w)*/ | |
| 78 | 78 | ADDRESS_MAP_END |
| 79 | 79 | |
| 80 | 80 | /*------------------------------------------------- |
| r8044 | r8045 | |
|---|---|---|
| 178 | 178 | |
| 179 | 179 | PORT_START("IN3") /* Left Player Controller Starts Here */ |
| 180 | 180 | |
| 181 | PORT_START("IN4") | |
| 181 | PORT_START("IN4") | |
| 182 | 182 | |
| 183 | PORT_START("IN5") | |
| 183 | PORT_START("IN5") | |
| 184 | 184 | INPUT_PORTS_END |
| 185 | 185 | |
| 186 | 186 | /* |
| r8044 | r8045 | |
|---|---|---|
| 591 | 591 | /* Driver */ |
| 592 | 592 | |
| 593 | 593 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 594 | COMP( 1985, special, 0, 0, special, special, special, "<unknown>", "Specialist", 0) | |
| 595 | COMP( 1985, specialm, special,0, special, special, special, "<unknown>", "Specialist M", 0) | |
| 596 | COMP( 1985, specialp, special,0, specialp, specialp, special, "<unknown>", "Specialist + hires graph", 0) | |
| 597 | COMP( 1985, lik, special,0, special, lik, special, "<unknown>", "Lik", 0) | |
| 598 | COMP( 1985, specimx, special,0, specimx, specimx, 0, "<unknown>", "Specialist MX", 0) | |
| 599 | COMP( 1994, erik, special,0, erik, special, erik, "<unknown>", "Erik", 0) | |
| 594 | COMP( 1985, special, 0, 0, special, special, special, "<unknown>", "Specialist", 0) | |
| 595 | COMP( 1985, specialm, special,0, special, special, special, "<unknown>", "Specialist M", 0) | |
| 596 | COMP( 1985, specialp, special,0, specialp, specialp, special, "<unknown>", "Specialist + hires graph", 0) | |
| 597 | COMP( 1985, lik, special,0, special, lik, special, "<unknown>", "Lik", 0) | |
| 598 | COMP( 1985, specimx, special,0, specimx, specimx, 0, "<unknown>", "Specialist MX", 0) | |
| 599 | COMP( 1994, erik, special,0, erik, special, erik, "<unknown>", "Erik", 0) |
| r8044 | r8045 | |
|---|---|---|
| 393 | 393 | |
| 394 | 394 | Only tree 'bins' of values are obviously captured |
| 395 | 395 | 25 ish |
| 396 | 330 ish | |
| 396 | 330 ish | |
| 397 | 397 | 520 ish. |
| 398 | 398 | |
| 399 | 399 | Quamtizing/scaling/rounding between 0 and 255 we thus get: |
| 400 | 400 | |
| 401 | ||
| 401 | */ | |
| 402 | 402 | palette_set_color_rgb( machine, 0, 0, 0, 155); |
| 403 | 403 | palette_set_color_rgb( machine, 1, 0, 0, 0); |
| 404 | 404 | palette_set_color_rgb( machine, 2, 0, 0, 255); |
| r8044 | r8045 | |
|---|---|---|
| 243 | 243 | //PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') |
| 244 | 244 | //PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP+") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') |
| 245 | 245 | //PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') |
| 246 | ||
| 246 | ||
| 247 | 247 | PORT_START(JOYSTICK0_TAG) |
| 248 | 248 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY // XB |
| 249 | 249 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY // XA |
| r8044 | r8045 | |
| 253 | 253 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) |
| 254 | 254 | |
| 255 | 255 | PORT_START(MOUSE_BUTTON_TAG) /* Mouse buttons */ |
| 256 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Mouse Button 2") PORT_CODE(MOUSECODE_BUTTON2) | |
| 257 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Mouse Button 1") PORT_CODE(MOUSECODE_BUTTON1) | |
| 256 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Mouse Button 2") PORT_CODE(MOUSECODE_BUTTON2) | |
| 257 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Mouse Button 1") PORT_CODE(MOUSECODE_BUTTON1) | |
| 258 | 258 | |
| 259 | 259 | PORT_START(MOUSEX_TAG) /* Mouse - X AXIS */ |
| 260 | 260 | PORT_BIT( 0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) |
| r8044 | r8045 | |
| 350 | 350 | MDRV_SOUND_CONFIG(msm5205_config) |
| 351 | 351 | |
| 352 | 352 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, MONO_TAG, 0.75) |
| 353 | ||
| 354 | ||
| 353 | ||
| 354 | ||
| 355 | 355 | MACHINE_DRIVER_END |
| 356 | 356 | |
| 357 | 357 |
| r8044 | r8045 | |
|---|---|---|
| 239 | 239 | /* Driver */ |
| 240 | 240 | |
| 241 | 241 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 242 | COMP( 1989, ut88mini, 0, 0, ut88mini, ut88mini, ut88mini, "<unknown>", "UT-88 mini", GAME_NO_SOUND) | |
| 243 | COMP( 1989, ut88, ut88mini,0, ut88, ut88, ut88, "<unknown>", "UT-88", 0) | |
| 242 | COMP( 1989, ut88mini, 0, 0, ut88mini, ut88mini, ut88mini, "<unknown>", "UT-88 mini", GAME_NO_SOUND) | |
| 243 | COMP( 1989, ut88, ut88mini,0, ut88, ut88, ut88, "<unknown>", "UT-88", 0) |
| r8044 | r8045 | |
|---|---|---|
| 461 | 461 | UINT32 size; |
| 462 | 462 | UINT8 *temp_copy; |
| 463 | 463 | int mirror, i; |
| 464 | ||
| 464 | ||
| 465 | 465 | if (image_software_entry(image) == NULL) |
| 466 | 466 | { |
| 467 | 467 | size = image_length(image); |
| r8044 | r8045 | |
| 473 | 473 | auto_free(image->machine, temp_copy); |
| 474 | 474 | return INIT_FAIL; |
| 475 | 475 | } |
| 476 | ||
| 476 | ||
| 477 | 477 | if (image_fread(image, temp_copy, size) != size) |
| 478 | 478 | { |
| 479 | 479 | image_seterror(image, IMAGE_ERROR_UNSPECIFIED, "Unable to fully read from file"); |
| r8044 | r8045 | |
|---|---|---|
| 903 | 903 | ROMX_LOAD( "jiffydos sx64.ud3", 0x12000, 0x2000, CRC(2b5a88f5) SHA1(942c2150123dc30f40b3df6086132ef0a3c43948), ROM_BIOS(2) ) |
| 904 | 904 | ROM_SYSTEM_BIOS(2, "1541flash", "1541 FLASH!" ) |
| 905 | 905 | ROMX_LOAD( "1541 flash.ud3", 0x12000, 0x2000, CRC(0a1c9b85) SHA1(0bfcaab0ae453b663a6e01cd59a9764805419e00), ROM_BIOS(3) ) |
| 906 | ||
| 906 | ||
| 907 | 907 | ROM_LOAD( "901225-01.ud1", 0x14000, 0x1000, CRC(ec4272ee) SHA1(adc7c31e18c7c7413d54802ef2f4193da14711aa) ) |
| 908 | 908 | |
| 909 | 909 | ROM_REGION( 0x80000, "cart", ROMREGION_ERASE00 ) |
| r8044 | r8045 | |
|---|---|---|
| 450 | 450 | |
| 451 | 451 | ROM_START( 32x ) |
| 452 | 452 | ROM_REGION16_BE( 0x400000, "gamecart", ROMREGION_ERASE00 ) /* 68000 Code */ |
| 453 | // | |
| 453 | // ROM_CART_LOAD("cart", 0x000000, 0x400000, ROM_NOMIRROR) | |
| 454 | 454 | |
| 455 | 455 | ROM_REGION32_BE( 0x400000, "gamecart_sh2", ROMREGION_ERASE00 ) /* Copy for the SH2 */ |
| 456 | // | |
| 456 | // ROM_CART_LOAD("cart", 0x000000, 0x400000, ROM_NOMIRROR) | |
| 457 | 457 | |
| 458 | 458 | ROM_REGION16_BE( 0x400000, "32x_68k_bios", 0 ) /* 68000 Code */ |
| 459 | 459 | ROM_LOAD( "32x_g_bios.bin", 0x000000, 0x000100, CRC(5c12eae8) SHA1(dbebd76a448447cb6e524ac3cb0fd19fc065d944) ) |
| 460 | 460 | |
| 461 | 461 | ROM_REGION16_BE( 0x400000, "maincpu", ROMREGION_ERASE00 ) |
| 462 | 462 | // temp, rom should only be visible here when one of the regs is set, tempo needs it |
| 463 | // | |
| 463 | // ROM_CART_LOAD("cart", 0x000000, 0x400000, ROM_NOMIRROR) | |
| 464 | 464 | ROM_COPY( "32x_68k_bios", 0x0, 0x0, 0x100) |
| 465 | 465 | |
| 466 | 466 | ROM_REGION( 0x400000, "32x_master_sh2", 0 ) /* SH2 Code */ |
| r8044 | r8045 | |
|---|---|---|
| 4 | 4 | |
| 5 | 5 | 10/12/2009 Skeleton driver. |
| 6 | 6 | |
| 7 | ||
| 7 | http://www.swtpc.com/mholley/swtpc_6800.htm | |
| 8 | 8 | |
| 9 | 9 | ****************************************************************************/ |
| 10 | 10 |
| r8044 | r8045 | |
|---|---|---|
| 115 | 115 | PORT_CONFSETTING( 0x01, "TI SD Floppy Controller" ) |
| 116 | 116 | PORT_CONFSETTING( 0x02, "SNUG BwG Controller" ) |
| 117 | 117 | PORT_CONFSETTING( 0x03, "Myarc HFDC" ) |
| 118 | // | |
| 118 | // PORT_CONFSETTING( 0x04, "Corcomp" ) | |
| 119 | 119 | |
| 120 | 120 | PORT_START( "HDCTRL" ) |
| 121 | 121 | PORT_CONFNAME( 0x03, 0x00, "HD controller" ) |
| 122 | 122 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 123 | 123 | PORT_CONFSETTING( 0x01, "Nouspikel IDE Controller" ) |
| 124 | // | |
| 124 | // PORT_CONFSETTING( 0x02, "WHTech SCSI Controller" ) | |
| 125 | 125 | PORT_CONFNAME( 0x08, 0x00, "USB-SM card" ) |
| 126 | 126 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 127 | 127 | PORT_CONFSETTING( 0x08, DEF_STR( On ) ) |
| r8044 | r8045 | |
| 130 | 130 | PORT_CONFNAME( 0x03, 0x00, "Serial/Parallel interface" ) |
| 131 | 131 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 132 | 132 | PORT_CONFSETTING( 0x01, "TI RS-232 card" ) |
| 133 | ||
| 133 | ||
| 134 | 134 | PORT_START( "EXTCARD" ) |
| 135 | 135 | PORT_CONFNAME( 0x02, 0x00, "P-Code card" ) |
| 136 | 136 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| r8044 | r8045 | |
| 146 | 146 | PORT_DIPSETTING( 0x00, "40 track, 16 ms") |
| 147 | 147 | PORT_DIPSETTING( 0xaa, "40 track, 8 ms") |
| 148 | 148 | PORT_DIPSETTING( 0x55, "80 track, 2 ms") |
| 149 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") | |
| 149 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") | |
| 150 | 150 | |
| 151 | 151 | PORT_START( "DRVSPD" ) |
| 152 | 152 | PORT_DIPNAME( 0x01, 0x01, "Floppy and HD speed" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| r8044 | r8045 | |
|---|---|---|
| 2562 | 2562 | |
| 2563 | 2563 | /* europc */ |
| 2564 | 2564 | ROM_LOAD("50145", 0xf8000, 0x8000, CRC(1775a11d)) // V2.07 |
| 2565 | // | |
| 2565 | // ROM_LOAD("eurobios.bin", 0xf8000, 0x8000, CRC(52185223)) scrap | |
| 2566 | 2566 | /* cga, hercules character set */ |
| 2567 | 2567 | ROM_LOAD("50146", 0x00000, 0x02000, CRC(1305dcf5)) //D1.0 |
| 2568 | 2568 | |
| r8044 | r8045 | |
| 2938 | 2938 | and trace-marked "|||CIM0286 ECA2466 // 94V-O" on the back. |
| 2939 | 2939 | */ |
| 2940 | 2940 | // ROM_REGION(0x4000,"gfx2", 0) |
| 2941 | // ROM_LOAD("1504161.u11", 0x00000, 0x2000, CRC(d9246cf5) SHA1(2eaed495893a4e6649b04d10dada7b5ef4abd140)) /* silkscreen: "AMI 8613MAJ // 9591-041 // S2364B // 1504161 // PHILIPPINES" - Purpose: Pixels 0 thru 7 of built-in 3270 terminal font*/ | |
| 2942 | // ROM_LOAD("1504162.u26", 0x02000, 0x2000, CRC(59e1dc32) SHA1(337b5cced203345a5acfb02532d6b5f526902ee7)) /* silkscreen: "AMI 8607MAH // 9591-042 // S2364B // 1504162 // PHILIPPINES" - Purpose: Pixel 8 of built-in 3270 terminal font*/ | |
| 2941 | // ROM_LOAD("1504161.u11", 0x00000, 0x2000, CRC(d9246cf5) SHA1(2eaed495893a4e6649b04d10dada7b5ef4abd140)) /* silkscreen: "AMI 8613MAJ // 9591-041 // S2364B // 1504161 // PHILIPPINES" - Purpose: Pixels 0 thru 7 of built-in 3270 terminal font*/ | |
| 2942 | // ROM_LOAD("1504162.u26", 0x02000, 0x2000, CRC(59e1dc32) SHA1(337b5cced203345a5acfb02532d6b5f526902ee7)) /* silkscreen: "AMI 8607MAH // 9591-042 // S2364B // 1504162 // PHILIPPINES" - Purpose: Pixel 8 of built-in 3270 terminal font*/ | |
| 2943 | 2943 | ROM_END |
| 2944 | 2944 | |
| 2945 | 2945 | |
| r8044 | r8045 | |
| 2968 | 2968 | V1.2:5EA8 V1.2:A058 |
| 2969 | 2969 | */ |
| 2970 | 2970 | ROM_START( pc200 ) |
| 2971 | // | |
| 2971 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 2972 | 2972 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 2973 | 2973 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| 2974 | 2974 | // special bios at 0xe0000 !? |
| r8044 | r8045 | |
| 2985 | 2985 | |
| 2986 | 2986 | |
| 2987 | 2987 | ROM_START( pc20 ) |
| 2988 | // | |
| 2988 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 2989 | 2989 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 2990 | 2990 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| 2991 | 2991 | |
| r8044 | r8045 | |
| 3002 | 3002 | |
| 3003 | 3003 | |
| 3004 | 3004 | ROM_START( ppc512 ) |
| 3005 | // | |
| 3005 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 3006 | 3006 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 3007 | 3007 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| 3008 | 3008 | // special bios at 0xe0000 !? |
| r8044 | r8045 | |
| 3015 | 3015 | |
| 3016 | 3016 | |
| 3017 | 3017 | ROM_START( ppc640 ) |
| 3018 | // | |
| 3018 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 3019 | 3019 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 3020 | 3020 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| 3021 | 3021 | // special bios at 0xe0000 !? |
| r8044 | r8045 | |
| 3028 | 3028 | |
| 3029 | 3029 | |
| 3030 | 3030 | ROM_START( pc1512 ) |
| 3031 | // | |
| 3031 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 3032 | 3032 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 3033 | 3033 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| 3034 | 3034 | ROM_LOAD16_BYTE("40044.v1", 0xfc001, 0x2000, CRC(668fcc94) SHA1(74002f5cc542df442eec9e2e7a18db3598d8c482)) // v1 |
| r8044 | r8045 | |
| 3039 | 3039 | |
| 3040 | 3040 | |
| 3041 | 3041 | ROM_START( pc1512v2 ) |
| 3042 | // | |
| 3042 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 3043 | 3043 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 3044 | 3044 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| 3045 | 3045 | ROM_LOAD16_BYTE("40043.v2", 0xfc001, 0x2000, CRC(d2d4d2de) SHA1(c376fd1ad23025081ae16c7949e88eea7f56e1bb)) // v2 |
| r8044 | r8045 | |
| 3050 | 3050 | |
| 3051 | 3051 | |
| 3052 | 3052 | ROM_START( pc1640 ) |
| 3053 | // | |
| 3053 | // ROM_REGION(0x100000,"maincpu", 0) | |
| 3054 | 3054 | ROM_REGION16_LE(0x100000,"maincpu", 0) |
| 3055 | 3055 | ROM_LOAD("40100", 0xc0000, 0x8000, CRC(d2d1f1ae) SHA1(98302006ee38a17c09bd75504cc18c0649174e33)) /* Internal Graphics Adapter ROM */ |
| 3056 | 3056 | ROM_LOAD("wdbios.rom", 0xc8000, 0x02000, CRC(8e9e2bd4) SHA1(601d7ceab282394ebab50763c267e915a6a2166a)) /* WDC IDE Superbios 2.0 (06/28/89) Expansion Rom C8000-C9FFF */ |
| r8044 | r8045 | |
|---|---|---|
| 127 | 127 | PORT_CONFSETTING( 0x01, "TI SD Floppy Controller" ) |
| 128 | 128 | PORT_CONFSETTING( 0x02, "SNUG BwG Controller" ) |
| 129 | 129 | PORT_CONFSETTING( 0x03, "Myarc HFDC" ) |
| 130 | // | |
| 130 | // PORT_CONFSETTING( 0x04, "Corcomp" ) | |
| 131 | 131 | |
| 132 | 132 | PORT_START( "HDCTRL" ) |
| 133 | 133 | PORT_CONFNAME( 0x03, 0x00, "HD controller" ) |
| 134 | 134 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 135 | 135 | PORT_CONFSETTING( 0x01, "Nouspikel IDE Controller" ) |
| 136 | // | |
| 136 | // PORT_CONFSETTING( 0x02, "WHTech SCSI Controller" ) | |
| 137 | 137 | PORT_CONFNAME( 0x04, 0x00, "USB-SM card" ) |
| 138 | 138 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 139 | 139 | PORT_CONFSETTING( 0x04, DEF_STR( On ) ) |
| r8044 | r8045 | |
| 142 | 142 | PORT_CONFNAME( 0x03, 0x00, "Serial/Parallel interface" ) |
| 143 | 143 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 144 | 144 | PORT_CONFSETTING( 0x01, "TI RS-232 card" ) |
| 145 | ||
| 145 | ||
| 146 | 146 | PORT_START( "EXTCARD" ) |
| 147 | 147 | PORT_CONFNAME( 0x01, 0x00, "HSGPL extension" ) |
| 148 | 148 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| r8044 | r8045 | |
| 155 | 155 | PORT_CONFNAME( 0x01, 0x00, "Mouse support" ) |
| 156 | 156 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 157 | 157 | PORT_CONFSETTING( 0x01, "Mechatronics Mouse" ) |
| 158 | ||
| 158 | ||
| 159 | 159 | PORT_START( "CARTSLOT" ) |
| 160 | 160 | PORT_CONFNAME( 0x07, 0x00, "Cartridge slot" ) |
| 161 | 161 | PORT_CONFSETTING( 0x00, "Auto" ) |
| r8044 | r8045 | |
| 163 | 163 | PORT_CONFSETTING( 0x02, "Slot 2" ) |
| 164 | 164 | PORT_CONFSETTING( 0x03, "Slot 3" ) |
| 165 | 165 | PORT_CONFSETTING( 0x04, "Slot 4" ) |
| 166 | // | |
| 166 | // PORT_CONFSETTING( 0x05, "GRAM Kracker" ) | |
| 167 | 167 | |
| 168 | 168 | PORT_START( "HFDCDIP" ) |
| 169 | 169 | PORT_DIPNAME( 0xff, 0x55, "HFDC drive config" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| 170 | 170 | PORT_DIPSETTING( 0x00, "40 track, 16 ms") |
| 171 | 171 | PORT_DIPSETTING( 0xaa, "40 track, 8 ms") |
| 172 | 172 | PORT_DIPSETTING( 0x55, "80 track, 2 ms") |
| 173 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") | |
| 173 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") | |
| 174 | 174 | |
| 175 | 175 | PORT_START( "DRVSPD" ) |
| 176 | 176 | PORT_DIPNAME( 0x01, 0x01, "Floppy and HD speed" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| r8044 | r8045 | |
| 300 | 300 | PORT_CONFSETTING( 0x01, "TI SD Floppy Controller" ) |
| 301 | 301 | PORT_CONFSETTING( 0x02, "SNUG BwG Controller" ) |
| 302 | 302 | PORT_CONFSETTING( 0x03, "Myarc HFDC" ) |
| 303 | // | |
| 303 | // PORT_CONFSETTING( 0x04, "Corcomp" ) | |
| 304 | 304 | |
| 305 | 305 | PORT_START( "HDCTRL" ) |
| 306 | 306 | PORT_CONFNAME( 0x03, 0x00, "HD controller" ) |
| 307 | 307 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 308 | 308 | PORT_CONFSETTING( 0x01, "Nouspikel IDE Controller" ) |
| 309 | // | |
| 309 | // PORT_CONFSETTING( 0x02, "WHTech SCSI Controller" ) | |
| 310 | 310 | PORT_CONFNAME( 0x08, 0x00, "USB-SM card" ) |
| 311 | 311 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 312 | 312 | PORT_CONFSETTING( 0x08, DEF_STR( On ) ) |
| r8044 | r8045 | |
| 315 | 315 | PORT_CONFNAME( 0x03, 0x00, "Serial/Parallel interface" ) |
| 316 | 316 | PORT_CONFSETTING( 0x00, DEF_STR( None ) ) |
| 317 | 317 | PORT_CONFSETTING( 0x01, "TI RS-232 card" ) |
| 318 | ||
| 318 | ||
| 319 | 319 | PORT_START( "EXTCARD" ) |
| 320 | 320 | PORT_CONFNAME( 0x01, 0x00, "HSGPL extension" ) |
| 321 | 321 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| r8044 | r8045 | |
| 330 | 330 | PORT_CONFSETTING( 0x01, "Mechatronics Mouse" ) |
| 331 | 331 | PORT_CONFNAME( 0x04, 0x00, "IR Handset" ) |
| 332 | 332 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) |
| 333 | PORT_CONFSETTING( 0x04, DEF_STR( On ) ) | |
| 334 | ||
| 333 | PORT_CONFSETTING( 0x04, DEF_STR( On ) ) | |
| 334 | ||
| 335 | 335 | PORT_START( "CARTSLOT" ) |
| 336 | 336 | PORT_CONFNAME( 0x07, 0x00, "Cartridge slot" ) |
| 337 | 337 | PORT_CONFSETTING( 0x00, "Auto" ) |
| r8044 | r8045 | |
| 339 | 339 | PORT_CONFSETTING( 0x02, "Slot 2" ) |
| 340 | 340 | PORT_CONFSETTING( 0x03, "Slot 3" ) |
| 341 | 341 | PORT_CONFSETTING( 0x04, "Slot 4" ) |
| 342 | // | |
| 342 | // PORT_CONFSETTING( 0x05, "GRAM Kracker" ) | |
| 343 | 343 | |
| 344 | 344 | PORT_START( "HFDCDIP" ) |
| 345 | 345 | PORT_DIPNAME( 0xff, 0x55, "HFDC drive config" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| 346 | 346 | PORT_DIPSETTING( 0x00, "40 track, 16 ms") |
| 347 | 347 | PORT_DIPSETTING( 0xaa, "40 track, 8 ms") |
| 348 | 348 | PORT_DIPSETTING( 0x55, "80 track, 2 ms") |
| 349 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") | |
| 349 | PORT_DIPSETTING( 0xff, "80 track HD, 2 ms") | |
| 350 | 350 | |
| 351 | 351 | PORT_START( "DRVSPD" ) |
| 352 | 352 | PORT_DIPNAME( 0x01, 0x01, "Floppy and HD speed" ) PORT_CONDITION( "DISKCTRL", 0x07, PORTCOND_EQUALS, 0x03 ) |
| 353 | 353 | PORT_DIPSETTING( 0x00, "No delay") |
| 354 | 354 | PORT_DIPSETTING( 0x01, "Realistic") |
| 355 | ||
| 355 | ||
| 356 | 356 | /* 3 ports for mouse */ |
| 357 | 357 | PORT_START("MOUSEX") /* Mouse - X AXIS */ |
| 358 | 358 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) |
| r8044 | r8045 | |
| 719 | 719 | |
| 720 | 720 | MDRV_FLOPPY_4_DRIVES_ADD(ti99_4_floppy_config) |
| 721 | 721 | MDRV_MFMHD_3_DRIVES_ADD() |
| 722 | ||
| 722 | ||
| 723 | 723 | MDRV_TI99_CARTRIDGE_ADD("ti99_multicart") |
| 724 | 724 | |
| 725 | 725 | MDRV_SMARTMEDIA_ADD("smartmedia") |
| r8044 | r8045 | |
| 888 | 888 | |
| 889 | 889 | MDRV_SMARTMEDIA_ADD("smartmedia") |
| 890 | 890 | |
| 891 | MDRV_TI99_4_RS232_CARD_ADD("rs232") | |
| 891 | MDRV_TI99_4_RS232_CARD_ADD("rs232") | |
| 892 | 892 | MACHINE_DRIVER_END |
| 893 | 893 | |
| 894 | 894 | |
| r8044 | r8045 | |
| 943 | 943 | /* to be moved to controller */ |
| 944 | 944 | MDRV_WD179X_ADD("wd179x", ti99_wd17xx_interface ) |
| 945 | 945 | MDRV_SMC92X4_ADD("smc92x4", ti99_smc92x4_interface ) |
| 946 | ||
| 946 | ||
| 947 | 947 | MDRV_FLOPPY_4_DRIVES_ADD(ti99_4_floppy_config) |
| 948 | 948 | MDRV_MFMHD_3_DRIVES_ADD() |
| 949 | 949 |
| r8044 | r8045 | |
|---|---|---|
| 284 | 284 | /* Driver */ |
| 285 | 285 | |
| 286 | 286 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 287 | COMP( 1987, korvet, 0, | |
| 287 | COMP( 1987, korvet, 0, | |
| 288 | 288 | COMP( 1987, neiva, korvet, 0, pk8020, pk8020, 0, "<unknown>", "PK8020 Neiva", 0) |
| 289 | 289 | COMP( 1987, kontur, korvet, 0, pk8020, pk8020, 0, "<unknown>", "PK8020 Kontur", 0) |
| Previous | 15994 Revisions | Next |