trunk/src/mess/drivers/geniusiq.c
| r19342 | r19343 | |
| 15 | 15 | 00200000 RAM (256K) |
| 16 | 16 | 00400000 Flash memory (128K) |
| 17 | 17 | 00600000 Some memory mapped hardware |
| 18 | | ???????? Cartridge port |
| 18 | 00a00000 Cartridge port |
| 19 | 19 | |
| 20 | 20 | TODO: |
| 21 | 21 | - Sound |
| 22 | | - Cartridge |
| 22 | - Flash cartridge |
| 23 | 23 | - Dump the MCU and rewrites everything using low-level emulation |
| 24 | 24 | - Check with different countries ROMs |
| 25 | 25 | |
| r19342 | r19343 | |
| 187 | 187 | #include "emu.h" |
| 188 | 188 | #include "cpu/m68000/m68000.h" |
| 189 | 189 | #include "machine/intelfsh.h" |
| 190 | #include "imagedev/cartslot.h" |
| 190 | 191 | |
| 191 | 192 | |
| 192 | 193 | #define KEYBOARD_QUEUE_SIZE 0x80 |
| r19342 | r19343 | |
| 194 | 195 | class geniusiq_state : public driver_device |
| 195 | 196 | { |
| 196 | 197 | public: |
| 198 | enum |
| 199 | { |
| 200 | IQ128_ROM_CART = 0x00, |
| 201 | IQ128_ROMLESS1_CART = 0x01, |
| 202 | IQ128_ROMLESS2_CART = 0x02, |
| 203 | IQ128_NO_CART = 0x03 |
| 204 | }; |
| 205 | |
| 197 | 206 | geniusiq_state(const machine_config &mconfig, device_type type, const char *tag) |
| 198 | 207 | : driver_device(mconfig, type, tag), |
| 199 | 208 | m_maincpu(*this, "maincpu"), |
| 200 | 209 | m_flash(*this, "flash"), |
| 201 | 210 | m_vram(*this, "vram"), |
| 202 | | m_mouse_gfx(*this, "mouse_gfx") |
| 211 | m_mouse_gfx(*this, "mouse_gfx"), |
| 212 | m_cart_state(IQ128_NO_CART) |
| 203 | 213 | { } |
| 204 | 214 | |
| 205 | 215 | required_device<cpu_device> m_maincpu; |
| 206 | 216 | required_device<intelfsh8_device> m_flash; |
| 207 | 217 | required_shared_ptr<UINT16> m_vram; |
| 208 | 218 | required_shared_ptr<UINT16> m_mouse_gfx; |
| 219 | |
| 220 | virtual void machine_start(); |
| 209 | 221 | virtual void machine_reset(); |
| 210 | 222 | virtual void palette_init(); |
| 211 | 223 | virtual UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 224 | |
| 212 | 225 | DECLARE_READ8_MEMBER(flash_r); |
| 213 | 226 | DECLARE_WRITE8_MEMBER(flash_w); |
| 214 | 227 | DECLARE_READ16_MEMBER(input_r); |
| r19342 | r19343 | |
| 220 | 233 | DECLARE_WRITE16_MEMBER(gfx_color_w); |
| 221 | 234 | DECLARE_WRITE16_MEMBER(gfx_idx_w); |
| 222 | 235 | void queue_input(UINT16 data); |
| 236 | DECLARE_READ16_MEMBER(cart_state_r); |
| 237 | int cart_load(device_image_interface &image); |
| 238 | void cart_unload(device_image_interface &image); |
| 223 | 239 | |
| 224 | 240 | DECLARE_READ16_MEMBER(unk0_r) { return 0; } |
| 225 | 241 | DECLARE_READ16_MEMBER(unk_r) { return machine().rand(); } |
| r19342 | r19343 | |
| 233 | 249 | UINT8 m_mouse_posy; |
| 234 | 250 | UINT16 m_mouse_gfx_posx; |
| 235 | 251 | UINT16 m_mouse_gfx_posy; |
| 252 | UINT8 * m_cart; |
| 253 | UINT8 m_cart_state; |
| 236 | 254 | struct |
| 237 | 255 | { |
| 238 | 256 | UINT16 buffer[KEYBOARD_QUEUE_SIZE]; |
| r19342 | r19343 | |
| 330 | 348 | m_flash->write(offset, data); |
| 331 | 349 | } |
| 332 | 350 | |
| 351 | READ16_MEMBER( geniusiq_state::cart_state_r ) |
| 352 | { |
| 353 | return m_cart_state; |
| 354 | } |
| 355 | |
| 333 | 356 | WRITE16_MEMBER( geniusiq_state::mouse_pos_w ) |
| 334 | 357 | { |
| 335 | 358 | if (offset) |
| r19342 | r19343 | |
| 461 | 484 | //AM_RANGE(0x600600, 0x600605) // sound ?? |
| 462 | 485 | AM_RANGE(0x600606, 0x600609) AM_WRITE(gfx_base_w) |
| 463 | 486 | AM_RANGE(0x60060a, 0x60060b) AM_WRITE(gfx_idx_w) |
| 464 | | AM_RANGE(0x600802, 0x600803) AM_READ_PORT("CART") // cartridge state |
| 487 | AM_RANGE(0x600802, 0x600803) AM_READ(cart_state_r) // cartridge state |
| 465 | 488 | AM_RANGE(0x600108, 0x600109) AM_READ(unk0_r) // read before run a BASIC program |
| 466 | 489 | AM_RANGE(0x600918, 0x600919) AM_READ(unk0_r) // loop at start if bit 0 is set |
| 467 | 490 | AM_RANGE(0x601008, 0x601009) AM_READ(unk_r) // unknown, read at start and expect that bit 2 changes several times before continue |
| r19342 | r19343 | |
| 470 | 493 | AM_RANGE(0x60101c, 0x60101f) AM_WRITE(gfx_color_w) |
| 471 | 494 | AM_RANGE(0x601060, 0x601063) AM_WRITE(mouse_pos_w) |
| 472 | 495 | AM_RANGE(0x601100, 0x6011ff) AM_RAM AM_SHARE("mouse_gfx") // mouse cursor gfx (24x16) |
| 473 | | //AM_RANGE(0xa00000, 0xa?????) // cartridge ?? |
| 496 | AM_RANGE(0xa00000, 0xafffff) AM_REGION("cart", 0) // cartridge |
| 474 | 497 | // 0x600000 : some memory mapped hardware |
| 475 | 498 | ADDRESS_MAP_END |
| 476 | 499 | |
| r19342 | r19343 | |
| 629 | 652 | PORT_START("MOUSE") |
| 630 | 653 | PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Mouse Button 2") PORT_CODE(MOUSECODE_BUTTON2) PORT_CHANGED_MEMBER( DEVICE_SELF, geniusiq_state, send_mouse_input, 0 ) |
| 631 | 654 | PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Mouse Button 1") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER( DEVICE_SELF, geniusiq_state, send_mouse_input, 0 ) |
| 632 | | |
| 633 | | PORT_START("CART") |
| 634 | | PORT_CONFNAME( 0x03, 0x03, "Cartridge" ) |
| 635 | | PORT_CONFSETTING( 0x00, "ROM/Flash cartridge" ) // check for cartridge header at 0xa00000 |
| 636 | | PORT_CONFSETTING( 0x01, "Cartouche I" ) |
| 637 | | PORT_CONFSETTING( 0x02, "Cartouche II" ) |
| 638 | | PORT_CONFSETTING( 0x03, "No cartridge" ) |
| 639 | 655 | INPUT_PORTS_END |
| 640 | 656 | |
| 641 | 657 | |
| r19342 | r19343 | |
| 681 | 697 | PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_A ) PORT_CHAR('a') PORT_CHAR('A') PORT_CHANGED_MEMBER( DEVICE_SELF, geniusiq_state, send_input, 0x64 ) |
| 682 | 698 | PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_Q ) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHANGED_MEMBER( DEVICE_SELF, geniusiq_state, send_input, 0x65 ) |
| 683 | 699 | PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_1 ) PORT_CHAR('1') PORT_CHAR('!') PORT_CHANGED_MEMBER( DEVICE_SELF, geniusiq_state, send_input, 0x66 ) |
| 684 | | |
| 685 | | PORT_MODIFY("CART") |
| 686 | | PORT_CONFNAME( 0x03, 0x03, "Cartridge" ) |
| 687 | | PORT_CONFSETTING( 0x00, "ROM/Flash cartridge" ) // check for cartridge header at 0xa00000 |
| 688 | | PORT_CONFSETTING( 0x01, "Fit in Naturwissenschaften" ) |
| 689 | | PORT_CONFSETTING( 0x02, "No cartridge" ) |
| 690 | | PORT_CONFSETTING( 0x03, "No cartridge" ) |
| 691 | 700 | INPUT_PORTS_END |
| 692 | 701 | |
| 693 | 702 | static INPUT_PORTS_START( gl8008cx ) |
| 694 | 703 | INPUT_PORTS_END |
| 695 | 704 | |
| 705 | void geniusiq_state::machine_start() |
| 706 | { |
| 707 | m_cart = (UINT8*)(*memregion("cart")); |
| 708 | } |
| 709 | |
| 696 | 710 | void geniusiq_state::machine_reset() |
| 697 | 711 | { |
| 698 | 712 | m_keyboard.head = m_keyboard.tail = 0; |
| r19342 | r19343 | |
| 707 | 721 | m_mouse_gfx_posy = 0; |
| 708 | 722 | } |
| 709 | 723 | |
| 724 | int geniusiq_state::cart_load(device_image_interface &image) |
| 725 | { |
| 726 | if (image.software_entry() == NULL) |
| 727 | { |
| 728 | UINT32 size = image.length(); |
| 729 | if (image.fread(m_cart, size) != size) |
| 730 | return IMAGE_INIT_FAIL; |
| 731 | |
| 732 | m_cart_state = IQ128_ROM_CART; |
| 733 | } |
| 734 | else |
| 735 | { |
| 736 | UINT32 size = image.get_software_region_length("rom"); |
| 737 | if (size > 1) |
| 738 | memcpy(m_cart, image.get_software_region("rom"), size); |
| 739 | |
| 740 | const char *pcb_type = image.get_feature("pcb_type"); |
| 741 | if (pcb_type) |
| 742 | { |
| 743 | if (!strcmp(pcb_type, "romless1")) |
| 744 | m_cart_state = IQ128_ROMLESS1_CART; |
| 745 | else if (!strcmp(pcb_type, "romless2")) |
| 746 | m_cart_state = IQ128_ROMLESS2_CART; |
| 747 | else if (!strcmp(pcb_type, "rom")) |
| 748 | m_cart_state = IQ128_ROM_CART; |
| 749 | } |
| 750 | else |
| 751 | { |
| 752 | m_cart_state = IQ128_ROM_CART; |
| 753 | } |
| 754 | } |
| 755 | |
| 756 | return IMAGE_INIT_PASS; |
| 757 | } |
| 758 | |
| 759 | void geniusiq_state::cart_unload(device_image_interface &image) |
| 760 | { |
| 761 | memset(m_cart, 0xff, memregion("cart")->bytes()); |
| 762 | m_cart_state = IQ128_NO_CART; |
| 763 | } |
| 764 | |
| 765 | static DEVICE_IMAGE_LOAD(iq128_cart) |
| 766 | { |
| 767 | return image.device().machine().driver_data<geniusiq_state>()->cart_load(image); |
| 768 | } |
| 769 | |
| 770 | static DEVICE_IMAGE_UNLOAD(iq128_cart) |
| 771 | { |
| 772 | image.device().machine().driver_data<geniusiq_state>()->cart_unload(image); |
| 773 | } |
| 774 | |
| 710 | 775 | static MACHINE_CONFIG_START( iq128, geniusiq_state ) |
| 711 | 776 | /* basic machine hardware */ |
| 712 | 777 | MCFG_CPU_ADD("maincpu", M68000, XTAL_32MHz/2) // The main crystal is at 32MHz, not sure whats the CPU freq |
| r19342 | r19343 | |
| 724 | 789 | |
| 725 | 790 | /* internal flash */ |
| 726 | 791 | MCFG_AMD_29F010_ADD("flash") |
| 792 | |
| 793 | /* cartridge */ |
| 794 | MCFG_CARTSLOT_ADD("cart") |
| 795 | MCFG_CARTSLOT_EXTENSION_LIST("bin") |
| 796 | MCFG_CARTSLOT_NOT_MANDATORY |
| 797 | MCFG_CARTSLOT_LOAD(iq128_cart) |
| 798 | MCFG_CARTSLOT_UNLOAD(iq128_cart) |
| 799 | MCFG_CARTSLOT_INTERFACE("iq128_cart") |
| 800 | |
| 801 | /* Software lists */ |
| 802 | MCFG_SOFTWARE_LIST_ADD("cart_list", "iq128") |
| 727 | 803 | MACHINE_CONFIG_END |
| 728 | 804 | |
| 729 | 805 | static MACHINE_CONFIG_DERIVED( iqtv512, iq128 ) |
| r19342 | r19343 | |
| 751 | 827 | ROM_START( iq128 ) |
| 752 | 828 | ROM_REGION(0x200000, "maincpu", 0) |
| 753 | 829 | ROM_LOAD( "27-5947-00.bin", 0x0000, 0x200000, CRC(a98fc3ff) SHA1(de76a5898182bd0180bd2b3e34c4502f0918a3fa) ) |
| 830 | |
| 831 | ROM_REGION(0x100000, "cart", ROMREGION_ERASEFF) |
| 754 | 832 | ROM_END |
| 755 | 833 | |
| 756 | 834 | ROM_START( iq128_fr ) |
| 757 | 835 | ROM_REGION(0x200000, "maincpu", 0) |
| 758 | 836 | ROM_LOAD( "geniusiq.bin", 0x0000, 0x200000, CRC(9b06cbf1) SHA1(b9438494a9575f78117c0033761f899e3c14e292) ) |
| 837 | |
| 838 | ROM_REGION(0x100000, "cart", ROMREGION_ERASEFF) |
| 759 | 839 | ROM_END |
| 760 | 840 | |
| 761 | 841 | ROM_START( iqtv512 ) |
| 762 | 842 | ROM_REGION(0x200000, "maincpu", 0) |
| 763 | 843 | ROM_LOAD( "27-06171-000.bin", 0x0000, 0x200000, CRC(2597af70) SHA1(9db8151a84517407d380424410b6fa0003ceb1eb) ) |
| 844 | |
| 845 | ROM_REGION(0x100000, "cart", ROMREGION_ERASEFF) |
| 764 | 846 | ROM_END |
| 765 | 847 | |
| 766 | 848 | ROM_START( gl8008cx ) |