/************************************************************************ Eolith Ghost Hardware driver 1. CPU - 16/32bit RISC Microprocessor(ARM920T CPU core) - Separate 16KB Instruction and 16KB Data Cache - Operating Frequency : Up to 203MHz 2. MEMORY - Main Memory : 32Mbytes(Maximum 128Mbytes) SDRAM - NAND FLASH : 16M,32M, 64M, 128M, 256Mbytes 3. VIDEO - RGB (5:6:5) format - Supports 1,2,4 or 8 bpp(bit-per-pixel) palette color displays - Supports 16 bpp non-palette true-color displays - Supports multiple screen size Typical actual screen size : 320*240, 640*480 Maximum virtual screen size is 4Mbytes Maximum virtual screen size in 64K color mode : 2048*1024 - Rendering Performance : 480 Objects per sec.(256*256 sprite) 4. SOUND Internal Audio Engine or External System Available TDA1519(Philips)Stereo Power AMP - Internal Audio Engine : 1-ch IIS-bus for audio interface Serial, 8-/16-bit per channel data transfers 128 Bytes (64-Byte + 64-Byte) FIFO for Tx/Rx - External System(Option) : General MIDI Chipset QDSP1000 MIDI 16th Channel(32 Poly) using as Effect Effect EPROM : 512Kbyte or 1Mbyte MIDI Background Music EPROM:512Kbyte 5. Board Feature - JAMMA Standard ( Application of PACK TYPE ) : 1P,2P ? Joystick (Up, Down, Left, Right), 4 Push Buttons, Start Button - 1P,2P ? Coin, Coin Counter - On Board Service Button, On Board Test Button - Photo Gun : 1P, 2P Photo Gun (or Light Pen) (Option) - ETC : Security System Available Multi I/O Port Available Coin Counter Available Gun Shooting Effect Available (Option) Hopper, Ticket Counter, Prize System (Option) 6. Develoment - On-chip ICEbreaker debug support with JTAG-based debugging solution - MultiICE, OPENICE etc. - Compiler : ADS, SDT */ #include "driver.h" #include "cpu/arm7/arm7core.h" static UINT32 *system_memory; static UINT32 *flash_regs; static UINT32 *lcd_control; static UINT32 *io_port; //static UINT32 fifoh[16]; //static UINT32 fifol[12]; static struct lcd_config { int screen_type; int bpp_mode; int lcd_bank; int lcd_base_u; int lcd_base_sel; int line_val; int hoz_val; int off_size; int page_width; } lcd; static READ32_HANDLER( r1 ) { // int pc = activecpu_get_pc(); // if(pc != 0x9a0 && pc != 0x7b4) printf("r1 @ %X\n",pc); return 1; } static READ32_HANDLER( r2 ) { // int pc = activecpu_get_pc(); // if(pc != 0xd64 && pc != 0xd3c ) printf("r2 @ %X\n",pc); return 2; } static UINT32 flash_addr = 0; static int flash_addr_step = 0; #define ADDR_STEP_CONFIG 4 static WRITE32_HANDLER( flash_reg_w ) { static int old[3]; COMBINE_DATA(&flash_regs[offset]); if(old[offset] != flash_regs[offset]) { old[offset] = flash_regs[offset]; // printf("reg %d) %02X\n",offset,old[offset] = flash_regs[offset]); // logerror("reg %d) %02X\n",offset,old[offset] = flash_regs[offset]); } switch(offset) { case 0: break; case 1: break; case 2: switch(flash_addr_step) { case 0: flash_addr = data << 0; break; case 1: flash_addr |= data << 8; break; case 2: flash_addr |= data << 16; break; case 3: flash_addr |= data << 24; break; } if(flash_addr_step == (ADDR_STEP_CONFIG - 1)) { flash_addr <<=1; } flash_addr_step = (flash_addr_step + 1) % ADDR_STEP_CONFIG; break; } } static READ32_HANDLER( flash_reg_r ) { // always read back what it's written? return flash_regs[offset]; } static READ32_HANDLER( flash_r ) { UINT8 *flash = (UINT8 *)memory_region(REGION_USER1); UINT8 value = flash[flash_addr]; flash_addr = (flash_addr + 1) % memory_region_length(REGION_USER1); return value; } static READ32_HANDLER( flash_ecc_r ) { //TODO return 0; } static WRITE32_HANDLER( debug_w ) { #if 1 mame_printf_debug("%c",data & 0xff); //debug texts #endif } /* a) cpu #0 (PC=000007D0): unmapped program memory dword read from 4E000014 & 000000FF b) cpu #0 (PC=000007D8): unmapped program memory dword read from 4E000014 & 0000FF00 c) cpu #0 (PC=000007E0): unmapped program memory dword read from 4E000014 & 00FF0000 1) read flash @ 0812 2) read flash @ 0813 3) read flash @ 0814 4) read flash @ 0815 5) read flash @ 0816 6) read flash @ 0817 a == 1 b == 2 c == 3 6 == 0xff */ // PC: 574 check -> jumps to execute code from ram /* Power management: Normal, Idle, Slow & Power-off 4-ch 16 bit PWM ( Pulse Width Modulation), & 1-ch 16-bit timer for OS RTC : 32.768 KHz, alarm interrupt GPIO :117 (multiplexed I/O) 3-ch UARTs 4 ch DMA Controllers 8-ch 10-bit A/D (Max. 500KSPS), including TSP Controller TFT LCD/STN LCD Controller (16bit, 640?480 maximum) 16-bit Watch-dog Timer 1-ch IIC-Bus Interface IIS-Bus Interface Screen Size: up to 640 x 480 2-ch SPI (Synchronous Serial I/O) SD Host/MMC (Multi Media Card) Interface USB Host/Device Interface Debug & TEST NAND Flash Controller (4KB internal buffer) 24-ch external interrupts Controller (Wake-up source 16-ch) */ static READ32_HANDLER( lcd_control_r ) { switch(offset) { case 0x00/4: { int line_val = video_screen_get_vpos(0) & 0x3ff; return (lcd_control[offset] & ~(0x3ff << 18)) | ((lcd.line_val - line_val) << 18); } case 0x10/4: { //TODO: VSTATUS, HSTATUS static int VSTATUS = 0; VSTATUS ^= 0x18000; return (lcd_control[offset] & ~0x18000) | VSTATUS; } default: { return lcd_control[offset]; } } } static WRITE32_HANDLER( lcd_control_w ) { COMBINE_DATA(&lcd_control[offset]); switch(offset) { case 0x00/4: { int line_val = video_screen_get_vpos(0) & 0x3ff; int bpp_mode = (lcd_control[offset] & 0x1e) >> 1; int screen_type = (lcd_control[offset] & 0x60) >> 5; lcd.screen_type = screen_type; lcd.bpp_mode = bpp_mode; if(bpp_mode != 12) printf("bpp mode= %d\n",bpp_mode); lcd_control[offset] = (lcd_control[offset] & ~(0x3ff << 18)) | ((lcd.line_val - line_val) << 18); break; } case 0x04/4: { int line_val = (lcd_control[offset] >> 14) & 0x3ff; lcd.line_val = line_val; break; } case 0x08/4: { int hoz_val = (lcd_control[offset] >> 8) & 0x3ff; lcd.hoz_val = hoz_val; break; } case 0x10/4: { /* int frm565 = (lcd_control[offset] >> 11) & 1; int inv_vd = (lcd_control[offset] >> 7) & 1; int bs_swp = (lcd_control[offset] >> 1) & 1; int hw_swp = (lcd_control[offset] >> 0) & 1; */ break; } case 0x14/4: { int lcd_bank = (lcd_control[offset] >> 21) & 0x1ff; int lcd_base_u = (lcd_control[offset] >> 0) & 0x1fffff; lcd.lcd_bank = lcd_bank; lcd.lcd_base_u = lcd_base_u; break; } case 0x18/4: { int lcd_base_sel = (lcd_control[offset] >> 0) & 0x1fffff; lcd.lcd_base_sel = lcd_base_sel; break; } case 0x1c/4: { int off_size = (lcd_control[offset] >> 11) & 0x7ff; int page_width = (lcd_control[offset] >> 0) & 0x7ff; lcd.off_size = off_size; lcd.page_width = page_width; break; } } } static READ32_HANDLER( io_port_r ) { switch(offset) { case 0x64/4: { static int input = 0; input ^= 0x20; // bits from 15-0 can be configured as input/output/... //return input; return (io_port[offset] & ~0x20) | input; } default: { return io_port[offset]; } } } static WRITE32_HANDLER( io_port_w ) { COMBINE_DATA(&io_port[offset]); } static ADDRESS_MAP_START( bballoon_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x00000000, 0x00000fff) AM_ROM AM_REGION(REGION_USER1, 0) AM_RANGE(0x30000000, 0x31ffffff) AM_RAM AM_BASE(&system_memory) AM_RANGE(0x40000000, 0x40000fff) AM_ROM AM_REGION(REGION_USER1, 0) // mirror? seems so AM_RANGE(0x48000000, 0x48000033) AM_RAM // memory controller AM_RANGE(0x4d000000, 0x4d00001f) AM_READWRITE(lcd_control_r,lcd_control_w) AM_BASE(&lcd_control) AM_RANGE(0x4e000000, 0x4e00000b) AM_READWRITE(flash_reg_r, flash_reg_w) AM_BASE(&flash_regs) AM_RANGE(0x4e00000c, 0x4e00000f) AM_READ(flash_r) AM_RANGE(0x4e000010, 0x4e000013) AM_READ(r1) AM_RANGE(0x4e000014, 0x4e000017) AM_READ(flash_ecc_r) AM_RANGE(0x50000010, 0x50000013) AM_READ(r2) AM_RANGE(0x50000020, 0x50000023) AM_WRITE(debug_w) //AM_RANGE(0x51000040, 0x51000043) AM_READ() // a timer... AM_RANGE(0x56000000, 0x56000093) AM_READWRITE(io_port_r, io_port_w) AM_BASE(&io_port) ADDRESS_MAP_END INPUT_PORTS_START( bballoon ) INPUT_PORTS_END static int irq_en = 0; VIDEO_START( bballoon ) { } static int b=0; VIDEO_UPDATE( bballoon ) { if(input_code_pressed_once(KEYCODE_Q)) { irq_en ^= 1; printf("en = %d\n",irq_en); } if(input_code_pressed_once(KEYCODE_W)) { printf("b = %d\n",++b); } if(input_code_pressed_once(KEYCODE_E)) { printf("b = %d\n",--b); } if(lcd_control[0] & 1) { // output enabled //bballoon setup //TFT 16bpp //5:6:5 format //normal //bs swap disabled //hw swap enabled int start_addr = (lcd.lcd_bank << 22) - 0x30000000; if(start_addr > 0x1ffffff) printf("max = %X\n",start_addr); else { //printf("addr = %X\n",start_addr + lcd.lcd_base_u); UINT32* videoram = system_memory + start_addr/4 + lcd.lcd_base_u/4 + 0x10000*b; int x,y,count; // probably wrong... count = 0; for (y=0;y <= cliprect->max_y;y++) { for (x=0;x <= cliprect->max_x/2;x+=2) { UINT32 color; UINT32 b; UINT32 g; UINT32 r; color = (videoram[count] >> 16) & 0xffff; b = (color & 0x001f) << 3; g = (color & 0x07e0) >> 2; r = (color & 0xf800) >> 6; *BITMAP_ADDR32(bitmap, y, x*2+0) = b | (g<<8) | (r<<16); color = videoram[count] & 0xffff; b = (color & 0x001f) << 3; g = (color & 0x07e0) >> 2; r = (color & 0xf800) >> 6; *BITMAP_ADDR32(bitmap, y, x*2+1) = b | (g<<8) | (r<<16); count++; } } } } else { // output disabled } return 0; } INTERRUPT_GEN( bballoon_interrupt ) { if(irq_en) cpunum_set_input_line(0, ARM7_IRQ_LINE, PULSE_LINE); //cpunum_set_input_line(0, ARM7_FIRQ_LINE, PULSE_LINE); irq_en = 0; } static MACHINE_DRIVER_START( bballoon ) /* basic machine hardware */ MDRV_CPU_ADD(ARM7, 24000000) MDRV_CPU_PROGRAM_MAP(bballoon_map,0) MDRV_CPU_VBLANK_INT(bballoon_interrupt,1) MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_VBLANK_TIME(DEFAULT_REAL_60HZ_VBLANK_DURATION) MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB15) MDRV_SCREEN_SIZE(1024, 1024) MDRV_SCREEN_VISIBLE_AREA(0, 319, 0, 239) MDRV_PALETTE_LENGTH(256) MDRV_VIDEO_START(bballoon) MDRV_VIDEO_UPDATE(bballoon) /* sound hardware */ MACHINE_DRIVER_END /* Balloon & Balloon Eolith, 2003 PCB Layout ---------- GHOST Ver1.1 2003.03.28 |---------------------------------------------| |TDA1519A B2.U20 LED RESET | | QS1000 | |DA1311A 24MHz LED| | | | | | |---------| | | QS1001A.U17 |ARM 312 | | |J |SAMSUNG | | |A B1.U16 |S3C2410 | IC42S16800 | |M | | | |M |---------| | |A | | IC42S16800 | | 12MHz | | M24CL16-S | | | | | | * FLASH.U1| | SERVICE | |DSW1 TEST | |---------------------------------------------| Notes: * - Unknown SOIC20 chip, surface scratched FLASH.U1 - Samsung K9F5608U0B 256MBit NAND FlashROM (TSOP48) U16 - 27C801 8MBit EPROM U20 - 29F040 EEPROM IC42S16800 - ISSI IC42S16800 4(2)M x 8(16) Bits x 4 Banks (128MBit) SDRAM */ ROM_START( bballoon ) ROM_REGION( 0x2000000, REGION_USER1, 0 ) /* ARM 32 bit code */ ROM_LOAD( "flash.u1", 0x000000, 0x2000000, CRC(73285634) SHA1(4d0210c1bebdf3113a99978ffbcd77d6ee854168) ) // banked every 0x10000 bytes ? ROM_REGION( 0x080000, REGION_USER2, 0 ) ROM_LOAD( "b2.u20", 0x000000, 0x080000, CRC(0a12334c) SHA1(535b5b34f28435517218100d70147d87809f485a) ) ROM_REGION( 0x100000, REGION_SOUND2, 0 ) // sound wave ROM_LOAD( "b1.u16", 0x000000, 0x100000, CRC(c42c1c85) SHA1(e1f49d556ffd6bc27142a7784c3bb8e37999857d) ) ROM_END DRIVER_INIT( bballoon ) { UINT8 *flash = (UINT8 *)memory_region(REGION_USER1); // nop flash ECC checks flash[0x844+0] = 0x00; flash[0x844+1] = 0x00; flash[0x844+2] = 0xA0; flash[0x844+3] = 0xE1; flash[0x850+0] = 0x00; flash[0x850+1] = 0x00; flash[0x850+2] = 0xA0; flash[0x850+3] = 0xE1; flash[0x860+0] = 0x00; flash[0x860+1] = 0x00; flash[0x860+2] = 0xA0; flash[0x860+3] = 0xE1; flash[0x86c+0] = 0x00; flash[0x86c+1] = 0x00; flash[0x86c+2] = 0xA0; flash[0x86c+3] = 0xE1; } GAME( 2003, bballoon, 0, bballoon, bballoon, bballoon, ROT0, "Eolith", "Balloon & Balloon", GAME_NO_SOUND | GAME_NOT_WORKING )