// license:LGPL-2.1+ // copyright-holders:Angelo Salese, David Haywood /****************************************************************************************************** System H1 (c) 1994 Sega Driver by David Haywood, Angelo Salese and Tomasz Slanina special thanks to Guru for references and HW advices Games on this system include Cool Riders and Aqua Stage. This system is interesting in that it makes use of an RLE compression scheme, which is not something common for Sega hardware, there is a patent for it ( 6,141,122 ) http://www.google.com/patents/US6141122 TODO: - Understand what the 0x400000c reads on SH-2 really do. - improve sound emulation - i8237 purpose is unknown (missing ROM for comms?). - verify zooming etc. our current algorithm is a bit ugly for text ======================================================================================================= Cool Riders Sega 1994 This game runs on SYSTEM-H1 hardware. The hardware seems overly complex for a 2D bike racing game? The design of the PCB is very similar to vanilla Model 2 (i.e. Daytona etc). However instead of fully custom-badged chips, many of the custom chips are off-the-shelf Hitachi/Toshiba gate-arrays. PCB Layouts ----------- SYSTEM-H1 ROM BD 171-6516C 837-9623 834-11482 (sticker) |--------------------------------------------------------------| | IC17 IC18 IC5 IC10 | | | | IC15 IC16 IC4 IC9 | | | | IC13 IC14 IC3 IC8 | | | | IC11 IC12 IC2 IC7 | | | | IC31 IC32 IC1 IC6 | | | | IC29 IC30 | |JP1-JP8 | | LED 32.500MHz CN1 JP9-JP12 CN2 | |--------------------------------------------------------------| Notes: CN1/2 - Connectors joining to CPU board JP1-8 - Jumpers to set ROM sizes JP1-4 set to 1-2 JP5-8 set to 2-3 JP9-12 - Jumpers to set ROM sizes JP9 set to 1-2 JP10-12 open (no jumpers) but JP12 pin 2 tied to JP10 pin 1 IC* - IC29-IC32 are 27C4002 EPROM IC1-IC10 are DIP42 32M mask ROM IC11-IC18 are DIP42 16M mask ROM SYSTEM-H1 COMMUNICATION-BD 171-6849B 837-10942 |----------------------------------| | CN2 | | 74F74 74F245 MB84256 | | 74F373 74F245 MB84256 | |MB89237A CN1 | | | | 74F138 74F04 74F125 | | | | 74F157 74F161 74F02 | | | | 74F04 74F74 74F86 TX| |MB89374 | | 74F02 74F160 RX| | SN75179 | | JP1 JP2 JP3 | | LED CN3 | |----------------------------------| Notes: (All IC's shown) CN1/2 - Connectors joining to CPU board CN3 - Connector joining to Filter board RX/TX - Optical cable connections for network (not used) JP* - 3x 2-pin jumpers. JP1 shorted, other jumpers open MB84256 - Fujitsu MB84256 32k x8 SRAM (NDIP28) MB89374 - Fujitsu MB89374 Data Link Controller (SDIP42) MB89237A- Fujitsu MB89237A 8-Bit Proprietary DMAC (?) (DIP40) SN75179 - Texas Instruments SN75179 Differential Driver and Receiver Pair (DIP8) SYSTEM-H1 CPU BD 171-6651A 837-10389 837-11481 (sticker) |--------------------------------------------------------------| | EPR-17662.IC12| | | | |--------| |--------| | | |SEGA | |SEGA | FM1208S SEC_CONN | | |315-5758| |315-5757| CN2 CN1 | | | | | | |------| CN10| | |--------| |--------| |SH7032| | |CN8 | | | | |------| | | | | PAL1 JP1 JP4 JP6 JP2 | | PAL2 JP3 JP5 MB3771 | | 28MHz 32MHz PC910 A1603C | | DSW1 DAN803 | |HM5241605 |--------| |--------| DAP803 | |HM5241605 PAL3 |SEGA | |SEGA | | | |315-5687| |315-5687| 315-5649| | | | | | | | |-----| TMP68HC000N-16|--------| |--------| | | |SH2 | 514270 514270 | | | | CN12 A1603C | |CN7|-----| MB84256 TDA1386 TL062 CN11| | 22.579MHz CN14 | | MB84256 | | | | TDA1386 TL062 | |--------------------------------------------------------------| Notes: 22.579MHz - This OSC is tied to pin 1 of a 74AC04 logic chip. The output from that (pin 2) is tied directly to both 315-5687 chips on pin 14. Therefore the clock input of the YMF292's is 22.579MHz 514270 - Hitachi HM514270AJ-7 256k x16 DRAM (SOJ40) 68000 - Clock 16.00MHz [32/2] A1603C - NEC uPA1603C Monolithic N-Channel Power MOS FET Array (DIP16) CN7/8 - Connectors joining to ROM board (above) CN10/11 - Connectors joining to Filter board CN12/14 - Connectors for (possible) extra sound board (not used) DAN803 - Diotec Semiconductor DAN803 Small Signal Diode Array with common anodes (SIL9) DAP803 - Diotec Semiconductor DAP803 Small Signal Diode Array with common cathodes (SIL9) DSW1 - 4-position DIP switch. All OFF EPR-17662 - Toshiba TC57H1025 1M EPROM (DIP40) FM1208S - RAMTRON FM1208S 4k (512 bytes x8) Nonvolatile Ferroelectric RAM (SOIC24) HM5241605 - Hitachi HM5241605 4M (256k x 16 x 2 banks) SDRAM (SSOP50) JP1-6 - Jumpers. JP2 open. JP5 1-2. All others 2-3 MB3771 - Fujitsu MB3771 Master Reset IC (SOIC8) MB84256 - Fujitsu MB84256 32k x8 SRAM (SOP28) PAL1 - GAL16V8B also marked '315-5800' (DIP20) PAL2 - GAL16V8B also marked '315-5802' (DIP20) PAL3 - GAL16V8B also marked '315-5801' (DIP20) PC910 - Sharp PC910 opto-isolator (DIP8) SEC_CONN - Sega security-board connector (not used) SH7032 - Hitachi HD6417032F20 ROMless SH1 CPU (QFP112). Clock input 16.00MHz on pin 71 SH2 - Hitachi HD6417095 SH2 CPU (QFP144). Clock input 28.00MHz on pin 118 TDA1386 - Philips TDA1386T Noise Shaping Filter DAC (SOP24) TL062 - Texas Instruments TL062 Low Power JFET Input Operational Amplifier (SOIC8) Sega Custom - 315-5757 (QFP160) 315-5758 (QFP168) also marked 'HG62G035R26F' 315-5649 (QFP100) custom I/O chip (also used on Model 2A/2B/2C, but NOT vanilla Model 2) 315-5687 (QFP128 x2) also marked 'YMF292-F' (also used on Model 2A/2B/2C and ST-V) Syncs - Horizontal 24.24506kHz Vertical 57.0426Hz SYSTEM-H1 VIDEO BD 171-6514F 837-9621 |--------------------------------------------------------------| | CN2 | | JP4| | |--------| TC55328 D431008| | |--------| HM514270 |SEGA | TC55328 D431008| | |SEGA | HM514270 |315-5697| JP3| |CN1 |315-5691| TC55328 HM514270 | | D431008 D431008| | | | TC55328 HM514270 |--------| D431008 D431008| | |--------| JP2| | JP1| | 315-5698 315-5648 | | |------------| | | | SEGA | 50MHz | | | 315-5692 | 315-5696 315-5648 | | | | CN9| |LED |------------| | |40MHz |--------| 315-5696 315-5648 | | |SEGA | | | PAL1 |315-5693| | |CN4 | | 315-5695 315-5695 315-5648 | ||--------||--------| | ||SEGA | | ||315-5694||--------| M5M411860 M5M411860 M5M411860 M5M411860 | || ||SEGA | M5M411860 M5M411860 M5M411860 M5M411860 | ||--------||315-5693| M5M411860 M5M411860 M5M411860 M5M411860 | | PAL2 | | M5M411860 M5M411860 M5M411860 M5M411860 | | |--------| | |--------------------------------------------------------------| Notes: CN9 - Connector joining to Filter board CN1/2/4 - Connectors joining to CPU board JP1/2/3/4 - 4x 3-pin jumpers. All set to 1-2 D431008 - NEC D431008 128k x8 SRAM (SOJ32) HM514270 - Hitachi HM514270AJ7 256k x16 DRAM (SOJ40) M5M411860 - Mitsubishi M5M411860TP435SF00-7 DRAM with fast page mode, 64k-words x 18 bits per word (maybe?) (TSOP42) TC55328 - Toshiba TC55328AJ-15 32k x8 SRAM (SOJ24) PAL1 - GAL16V8B also marked '315-5803' (DIP20) PAL2 - GAL16V8B also marked '315-5864' (DIP20) Sega Custom - 315-5648 (QFP64, x4) 315-5691 also marked 'HG62S0791R17F' (QFP208) 315-5692 also marked 'HG51B152FD' (QFP256) 315-5693 also marked 'HG62G019R16F' (QFP168, x3) 315-5694 (QFP208) 315-5695 (QFP100, x2) 315-5696 (QFP120, x2) 315-5697 (QFP208) 315-5698 (QFP144) ******************************************************************************************************* Note: This hardware appears to have been designed as a test-bed for a new RLE based compression system used by the zooming sprites. It is possible that Sega planned on using this for ST-V, but decided against it. Video/CPU part numbers give an interesting insight, since video hardware # sits between Model 1 & Model 2. Year on System PCB PCB # PALs --------------------------------------------------------- System32 1990 837-7428 315-5441 315-5442 SysMulti32 1992 837-8676 315-5596 Model 1 1992 837-8886 315-5546 315-5483 315-5484 Model 2 1994 837-10071 315-5737 315-5741 Model 2A 1994 837-10848 315-5737 315-5815 STV 1994 837-10934 315-5833 H1 (CPU) 1994 837-10389 315-5800 315-5801 315-5802 H1 (Video) 1994 837-9621 315-5803 315-5864 NOTE: While the hardware and title screen might list 1994 as a copyright, MAME uses 1995 due to the abudance of evidence in trade journals and even it's own service manuals showing the year as 1995. References: Arcade game magazine called 'Gamest' show released on 04.28.1995 VGL (Ultimate Video Game List published by AMP group) - year is printed as '94(4.95)' Sega Arcade History (published by Enterbrain) is '1995/4'. ******************************************************************************************************/ /* some Sprite compression notes from Charles and Andrew OK so here's what we know. Andrew and I were playing with the ROMs and Guru traced out connections on the board at the time: The ten graphics ROMs are IC1-IC10. Each is 16 bits, and all have a common enable and common A20 input. All data lines are unique; nothing is shared. There are two independent address buses: - One drives A0-A19 of IC1-IC5 - The other drives A0-A19 of IC6-IC10 So the ROMs are arranged as 4,194,304 x 160-bit words (very wide), and are divided into two banks of 2,097,152 x 160-bit words per bank, where the common A20 input selects which bank is currently being used. This bank bit may not come from the graphics hardware and could just be a spare I/O pin on some other chip, we don't know. Then, within the current bank selected, the video chip can generate independent addresses for IC1-5 and IC6-10 in parallel, so that it can read 80 bits from IC1-5 at one address, and 80 bits from IC6-10 at another address simultaneously. Or it can drive the same address and read a 160-bit word at once. Regardless both addresses are restricted to the same bank as defined through A20. */ // http://www.nicozon.net/watch/sm7834644 (first part is Aqua Stage video?) // http://www.system16.com/hardware.php?id=841 has a picture of Aqua Stage showing the wide aspect #include "emu.h" #include "cpu/m68000/m68000.h" #include "cpu/sh/sh2.h" #include "machine/nvram.h" #include "machine/timer.h" #include "machine/315_5649.h" #include "sound/scsp.h" #include "emupal.h" #include "rendlay.h" #include "screen.h" #include "speaker.h" #include "aquastge.lh" #define CLIPMAXX_FULL (496-1) #define CLIPMAXY_FULL (384-1) #define CLIPMINX_FULL (0) #define CLIPMINY_FULL (0) class coolridr_state : public driver_device { public: coolridr_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_textBytesToWrite(0x00), m_blitterSerialCount(0x00), m_blitterMode(0x00), m_textOffset(0x0000), m_maincpu(*this, "maincpu"), m_subcpu(*this,"sub"), m_soundcpu(*this,"soundcpu"), //m_dmac(*this, "i8237"), m_framebuffer_vram(*this, "fb_vram"), m_txt_vram(*this, "txt_vram"), m_txt_blit(*this, "txt_blit"), m_workram_h(*this, "workrah"), m_sound_dma(*this, "sound_dma"), m_soundram(*this, "soundram%u", 1U), m_rom(*this, "share1"), m_compressedgfx(*this, "compressedgfx"), m_io_config(*this, "CONFIG"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), m_screen(*this, "screen") { } // Blitter state uint16_t m_textBytesToWrite; int16_t m_blitterSerialCount; uint8_t m_blitterMode; uint8_t m_blittype; uint16_t m_blitterAddr; uint16_t m_textOffset; uint32_t m_blitterClearMode; int16_t m_blitterClearCount; std::unique_ptr m_fadedpals; // store the blit params here uint32_t m_spriteblit[12]; uint32_t m_vregs_address; uint32_t m_clipvals[2][3]; uint8_t m_clipblitterMode[2]; // hack required_device m_maincpu; required_device m_subcpu; required_device m_soundcpu; //required_device m_dmac; required_shared_ptr m_framebuffer_vram; required_shared_ptr m_txt_vram; required_shared_ptr m_txt_blit; required_shared_ptr m_workram_h; required_shared_ptr m_sound_dma; required_shared_ptr_array m_soundram; required_shared_ptr m_rom; required_region_ptr m_compressedgfx; required_ioport m_io_config; required_device m_gfxdecode; required_device m_palette; required_device m_screen; bitmap_ind16 m_temp_bitmap_sprites[2]; //bitmap_ind16 m_zbuffer_bitmap[2]; bitmap_ind16 m_screen_bitmap[2]; uint8_t m_an_mux_data; uint8_t m_sound_data, m_sound_fifo; std::unique_ptr m_expanded_10bit_gfx; std::unique_ptr m_rearranged_16bit_gfx; uint32_t get_20bit_data(uint32_t romoffset, int _20bitwordnum); uint16_t get_10bit_data(uint32_t romoffset, int _10bitwordnum); uint32_t sound_dma_r(offs_t offset); void sound_dma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); uint32_t unk_blit_r(offs_t offset); void unk_blit_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); void blit_mode_w(uint32_t data); void blit_data_w(address_space &space, uint32_t data); void fb_mode_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); void fb_data_w(offs_t offset, uint32_t data); void dma_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask = ~0); template uint16_t soundram_r(offs_t offset); template void soundram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void lamps_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER(scsp1_to_sh1_irq); DECLARE_WRITE_LINE_MEMBER(scsp2_to_sh1_irq); void sound_to_sh1_w(uint8_t data); void init_coolridr(); void init_aquastge(); virtual void machine_start() override; virtual void machine_reset() override; virtual void video_start() override; uint32_t m_colbase; void coolriders_drawgfx_opaque(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty); void coolriders_drawgfx_transpen(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty, uint32_t transpen); void draw_bg_coolridr(bitmap_ind16 &bitmap, const rectangle &cliprect, int which); template uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void blit_current_sprite(address_space &space); TIMER_DEVICE_CALLBACK_MEMBER(interrupt_main); TIMER_DEVICE_CALLBACK_MEMBER(interrupt_sub); void scsp_irq(offs_t offset, uint8_t data); void dma_transfer( address_space &space, uint16_t dma_index ); int m_debug_randompal; std::unique_ptr m_vram; std::unique_ptr m_pcgram; std::unique_ptr m_palram; int m_gfx_index; int m_color_bank; struct { uint32_t setting; uint8_t gradient; }m_rgb_ctrl[2]; uint32_t m_pen_fill[2]; osd_work_queue * m_work_queue[2]; // work queue, one per screen static void *draw_object_threaded(void *param, int threadid); int m_usethreads; struct cool_render_object { cool_render_object(coolridr_state &s) : state(s), colbase(s.m_colbase) { std::copy(std::begin(s.m_spriteblit), std::end(s.m_spriteblit), std::begin(spriteblit)); } std::unique_ptr indirect_tiles; std::unique_ptr indirect_zoom; uint32_t spriteblit[12]; bitmap_ind16* drawbitmap = nullptr; //bitmap_ind16* zbitmap = nullptr; uint16_t zpri = 0; uint8_t blittype = 0; coolridr_state& state; uint32_t clipvals[3]; int screen = 0; int colbase; }; std::unique_ptr []> m_cool_render_object_list[2]; int m_listcount[2]; // the decode cache mechansim is an optimization // we know all gfx are in ROM, and that calling the RLE decompression every time they're used is slow, so we cache the decoded tiles // and objects after they're used, for future re-use, quite handy with a driving game. #define DECODECACHE_NUMOBJECTCACHES (128) #define DECODECACHE_NUMSPRITETILES (16*16) // decode cache struct objectcache { // these needs to be all the elements actually going to affect the decode of an individual tile for any given object uint32_t lastromoffset; uint16_t lastused_flipx; uint16_t lastused_flipy; uint32_t lastblit_rotate; uint32_t lastb1mode; uint32_t lastb1colorNumber; uint32_t lastb2colorNumber; uint32_t lastb2altpenmask; uint16_t lastused_hCellCount; uint16_t lastused_vCellCount; int repeatcount; struct dectile { uint16_t tempshape_multi[16*16]; bool tempshape_multi_decoded; bool is_blank; }; dectile tiles[DECODECACHE_NUMSPRITETILES]; }; struct objcachemanager { int current_object; objectcache objcache[DECODECACHE_NUMOBJECTCACHES]; // fallback decode buffer for certain cases (indirect sprites, sprites too big for our buffer..) uint16_t tempshape[16*16]; }; objcachemanager m_decode[2]; void aquastge(machine_config &config); void coolridr(machine_config &config); void coolridr_h1_map(address_map &map); void aquastge_h1_map(address_map &map); void aquastge_submap(address_map &map); void coolridr_submap(address_map &map); void system_h1_map(address_map &map); void system_h1_submap(address_map &map); void system_h1_sound_map(address_map &map); template void scsp_map(address_map &map); }; #define PRINT_BLIT_STUFF \ printf("type blit %08x %08x(%d, %03x) %08x(%02x, %03x) %08x(%06x) %08x(%08x, %d, %d, %d) %08x(%d,%d) %04x %04x %04x %04x %08x %08x %d %d\n", blit0, blit1_unused,b1mode,b1colorNumber, blit2_unused,b2tpen,b2colorNumber, blit3_unused,b3romoffset, blit4_unused, blit4blendlevel, blit_flipy,blit_rotate, blit_flipx, blit5_unused, indirect_tile_enable, indirect_zoom_enable, vCellCount, hCellCount, vZoom, hZoom, blit10, textlookup, vPosition, hPosition); /* video */ #define VRAM_SIZE 0x100000 static const gfx_layout h1_tile_layout = { 16,16, 0x1000, 8, { STEP8(0,1) }, { STEP16(0,8) }, { STEP16(0,8*16) }, 16*128 }; void coolridr_state::video_start() { /* find first empty slot to decode gfx */ for (m_gfx_index = 0; m_gfx_index < MAX_GFX_ELEMENTS; m_gfx_index++) if (m_gfxdecode->gfx(m_gfx_index) == nullptr) break; m_fadedpals = make_unique_clear(0x8000); m_vram = make_unique_clear(VRAM_SIZE); m_pcgram = make_unique_clear(VRAM_SIZE); m_palram = make_unique_clear(VRAM_SIZE); m_cool_render_object_list[0] = std::make_unique []>(1000000); m_listcount[0] = 0; m_cool_render_object_list[1] = std::make_unique []>(1000000); m_listcount[1] = 0; m_screen->register_screen_bitmap(m_temp_bitmap_sprites[0]); m_screen->register_screen_bitmap(m_temp_bitmap_sprites[1]); //m_screen->register_screen_bitmap(m_zbuffer_bitmap[0]); //m_screen->register_screen_bitmap(m_zbuffer_bitmap[1]); m_screen->register_screen_bitmap(m_screen_bitmap[0]); m_screen->register_screen_bitmap(m_screen_bitmap[1]); m_gfxdecode->set_gfx(m_gfx_index, std::make_unique(m_palette, h1_tile_layout, m_pcgram.get(), 0, 8, 0)); m_debug_randompal = 9; save_pointer(NAME(m_fadedpals), 0x8000); save_pointer(NAME(m_vram), VRAM_SIZE); save_pointer(NAME(m_pcgram), VRAM_SIZE); save_pointer(NAME(m_palram), VRAM_SIZE); } /* vregs are setted up with one of DMA commands (see below) 0x3e09b80 screen 1 base, 0x3e9bc0 screen 2 base [+0x1c] ---- ---- ---- ---- ---- ---- ---- -xxx tile offset start * 0x8000 [+0x2c] ---- -xxx xxxx xxxx ---- --yy yyyy yyyy scrolling registers [+0x34] 1111 1111 2222 2222 3333 3333 4444 4444 - Almost surely Sega "map" registers [+0x38] 5555 5555 6666 6666 7777 7777 8888 8888 / [+0x3c] x--- ---- ---- ---- xxxx xxxx xxxx xxxx 0x11b8 on bike select, 0xffffffff otherwise, transparent pen value? (everything else is unknown at current time) */ #define COOLRIDERS_DRAWGFX_CORE(PIXEL_TYPE, COOL_PIXEL_OP) \ do { \ do { \ const uint8_t *srcdata; \ int32_t destendx, destendy; \ int32_t srcx, srcy; \ int32_t curx, cury; \ int32_t dy; \ \ assert(dest.valid()); \ assert(gfx != nullptr); \ assert(dest.cliprect().contains(cliprect)); \ assert(code < gfx->elements()); \ \ /* ignore empty/invalid cliprects */ \ if (cliprect.empty()) \ break; \ \ /* compute final pixel in X and exit if we are entirely clipped */ \ destendx = destx + gfx->width() - 1; \ if (destx > cliprect.max_x || destendx < cliprect.min_x) \ break; \ \ /* apply left clip */ \ srcx = 0; \ if (destx < cliprect.min_x) \ { \ srcx = cliprect.min_x - destx; \ destx = cliprect.min_x; \ } \ \ /* apply right clip */ \ if (destendx > cliprect.max_x) \ destendx = cliprect.max_x; \ \ /* compute final pixel in Y and exit if we are entirely clipped */ \ destendy = desty + gfx->height() - 1; \ if (desty > cliprect.max_y || destendy < cliprect.min_y) \ break; \ \ /* apply top clip */ \ srcy = 0; \ if (desty < cliprect.min_y) \ { \ srcy = cliprect.min_y - desty; \ desty = cliprect.min_y; \ } \ \ /* apply bottom clip */ \ if (destendy > cliprect.max_y) \ destendy = cliprect.max_y; \ \ /* apply X flipping */ \ if (flipx) \ srcx = gfx->width() - 1 - srcx; \ \ /* apply Y flipping */ \ dy = gfx->rowbytes(); \ if (flipy) \ { \ srcy = gfx->height() - 1 - srcy; \ dy = -dy; \ } \ \ /* fetch the source data */ \ srcdata = gfx->get_data(code); \ \ /* compute how many blocks of 4 pixels we have */ \ uint32_t numblocks = (destendx + 1 - destx) / 4; \ uint32_t leftovers = (destendx + 1 - destx) - 4 * numblocks; \ \ /* adjust srcdata to point to the first source pixel of the row */ \ srcdata += srcy * gfx->rowbytes() + srcx; \ \ /* non-flipped 8bpp case */ \ if (!flipx) \ { \ /* iterate over pixels in Y */ \ for (cury = desty; cury <= destendy; cury++) \ { \ PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ const uint8_t *srcptr = srcdata; \ srcdata += dy; \ \ /* iterate over unrolled blocks of 4 */ \ for (curx = 0; curx < numblocks; curx++) \ { \ COOL_PIXEL_OP(destptr[0], srcptr[0]); \ COOL_PIXEL_OP(destptr[1], srcptr[1]); \ COOL_PIXEL_OP(destptr[2], srcptr[2]); \ COOL_PIXEL_OP(destptr[3], srcptr[3]); \ \ srcptr += 4; \ destptr += 4; \ } \ \ /* iterate over leftover pixels */ \ for (curx = 0; curx < leftovers; curx++) \ { \ COOL_PIXEL_OP(destptr[0], srcptr[0]); \ srcptr++; \ destptr++; \ } \ } \ } \ \ /* flipped 8bpp case */ \ else \ { \ /* iterate over pixels in Y */ \ for (cury = desty; cury <= destendy; cury++) \ { \ PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ const uint8_t *srcptr = srcdata; \ srcdata += dy; \ \ /* iterate over unrolled blocks of 4 */ \ for (curx = 0; curx < numblocks; curx++) \ { \ COOL_PIXEL_OP(destptr[0], srcptr[ 0]); \ COOL_PIXEL_OP(destptr[1], srcptr[-1]); \ COOL_PIXEL_OP(destptr[2], srcptr[-2]); \ COOL_PIXEL_OP(destptr[3], srcptr[-3]); \ \ srcptr -= 4; \ destptr += 4; \ } \ \ /* iterate over leftover pixels */ \ for (curx = 0; curx < leftovers; curx++) \ { \ COOL_PIXEL_OP(destptr[0], srcptr[0]); \ srcptr--; \ destptr++; \ } \ } \ } \ } while (0); \ } while (0) #define COOLRIDERS_PIXEL_OP_REMAP_OPAQUE(DEST, SOURCE) \ do \ { \ (DEST) = paldata[SOURCE]; \ } \ while (0) #define COOLRIDERS_PIXEL_OP_REMAP_TRANSPEN(DEST, SOURCE) \ do \ { \ uint32_t srcdata = (SOURCE); \ if (srcdata != transpen) \ (DEST) = paldata[srcdata]; \ } \ while (0) void coolridr_state::coolriders_drawgfx_opaque(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty) { const uint16_t *paldata = &m_palram[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())]; code %= gfx->elements(); COOLRIDERS_DRAWGFX_CORE(uint16_t, COOLRIDERS_PIXEL_OP_REMAP_OPAQUE); } void coolridr_state::coolriders_drawgfx_transpen(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty, uint32_t transpen) { // special case invalid pens to opaque if (transpen > 0xff) return coolriders_drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty); // use pen usage to optimize code %= gfx->elements(); if (gfx->has_pen_usage()) { // fully transparent; do nothing uint32_t usage = gfx->pen_usage(code); if ((usage & ~(1 << transpen)) == 0) return; // fully opaque; draw as such if ((usage & (1 << transpen)) == 0) return coolriders_drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty); } // render const uint16_t *paldata = &m_palram[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())] ; COOLRIDERS_DRAWGFX_CORE(uint16_t, COOLRIDERS_PIXEL_OP_REMAP_TRANSPEN); } void coolridr_state::draw_bg_coolridr(bitmap_ind16 &bitmap, const rectangle &cliprect, int which) { int bg_r,bg_g,bg_b; address_space &space = m_maincpu->space(AS_PROGRAM); if(m_pen_fill[which]) { #if 0 /* logic here is a bit of a guess. - should probably be 555 like everything else.. or we are going to have to have a rgb32 bitmap? */ bg_r = (((m_pen_fill[which] >> 16) & 0x7f) << 1) | (((m_pen_fill[which] >> 16) & 0x80) >> 7); bg_g = (((m_pen_fill[which] >> 8) & 0x7f) << 1) | (((m_pen_fill[which] >> 8) & 0x80) >> 7); bg_b = (((m_pen_fill[which] >> 0) & 0x7f) << 1) | (((m_pen_fill[which] >> 0) & 0x80) >> 7); bitmap.fill(rgb_t(0xff,bg_r,bg_g,bg_b),cliprect); #endif bg_r = (((m_pen_fill[which] >> 16) & 0x78) >> 2) | (((m_pen_fill[which] >> 16) & 0x80) >> 7); bg_g = (((m_pen_fill[which] >> 8) & 0x78) >> 2) | (((m_pen_fill[which] >> 8) & 0x80) >> 7); bg_b = (((m_pen_fill[which] >> 0) & 0x78) >> 2) | (((m_pen_fill[which] >> 0) & 0x80) >> 7); bitmap.fill( (bg_r<<10) | (bg_g << 5) | bg_b ,cliprect); } else { uint8_t transpen_setting; gfx_element *gfx = m_gfxdecode->gfx(m_gfx_index); #define VREG(_offs) \ space.read_dword(m_vregs_address+_offs+which*0x40) uint16_t const scrollx = (VREG(0x2c) >> 16) & 0x7ff; uint16_t const scrolly = VREG(0x2c) & 0x3ff; uint32_t const base_offset = (VREG(0x1c) * 0x8000)/2; m_color_bank = which * 2; /* TODO: the whole transpen logic might be incorrect */ transpen_setting = (VREG(0x3c) & 0x80000000) >> 31; bg_r = (VREG(0x3c) >> 10) & 0x1f; bg_g = (VREG(0x3c) >> 5) & 0x1f; bg_b = (VREG(0x3c) >> 0) & 0x1f; bitmap.fill(VREG(0x3c),cliprect); uint16_t basey = ((scrolly + cliprect.top()) & 0x3ff) >> 4; for (int y = cliprect.top() >> 4; y <= (cliprect.bottom() + 15) >> 4; y++) { uint16_t basex = ((scrollx + cliprect.left()) & 0x7ff) >> 4; for (int x = cliprect.left() >> 4; x <= (cliprect.right() + 15) >> 4; x++) { uint16_t const vram_data = (m_vram[((basex&0x7f)+((basey&0x3f)*0x80)+base_offset)&0x07ffff] & 0xffff); uint16_t const color = m_color_bank + ((vram_data & 0x800) >> 11) * 4; /* bike select enables bits 15-12, pretty sure one of these is tile bank (because there's a solid pen on 0x3ff / 0x7ff). */ uint16_t const tile = (vram_data & 0x7ff) | ((vram_data & 0x8000) >> 4); coolriders_drawgfx_transpen(bitmap,cliprect,gfx,tile,color,0,0,(x*16)-(scrollx&0xf),(y*16)-(scrolly&0xf),transpen_setting ? -1 : 0); basex++; } basey++; } } } template uint32_t coolridr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { if(m_rgb_ctrl[Screen].gradient) { if( (m_rgb_ctrl[Screen].setting == 0x1240) || (m_rgb_ctrl[Screen].setting == 0x920) || (m_rgb_ctrl[Screen].setting == 0x800) ) { } else { popmessage("%08x %08x",m_rgb_ctrl[Screen].setting,m_rgb_ctrl[Screen].gradient); } } #if 0 if (machine().input().code_pressed_once(KEYCODE_W)) { m_debug_randompal++; popmessage("%02x",m_debug_randompal); } if (machine().input().code_pressed_once(KEYCODE_Q)) { m_debug_randompal--; popmessage("%02x",m_debug_randompal); } #endif // there are probably better ways to do this for (int i = 0; i < 0x8000; i++) { int r = (i >> 10)&0x1f; int g = (i >> 5)&0x1f; int b = (i >> 0)&0x1f; if(m_rgb_ctrl[Screen].gradient) { /* fade-in / outs */ if(m_rgb_ctrl[Screen].setting == 0x1240) { r -= m_rgb_ctrl[Screen].gradient; g -= m_rgb_ctrl[Screen].gradient; b -= m_rgb_ctrl[Screen].gradient; if(r < 0) { r = 0; } if(g < 0) { g = 0; } if(b < 0) { b = 0; } } else if(m_rgb_ctrl[Screen].setting == 0x920) /* at bike select / outside tunnels, addition */ { r += m_rgb_ctrl[Screen].gradient; g += m_rgb_ctrl[Screen].gradient; b += m_rgb_ctrl[Screen].gradient; if(r > 0x1f) { r = 0x1f; } if(g > 0x1f) { g = 0x1f; } if(b > 0x1f) { b = 0x1f; } } else if(m_rgb_ctrl[Screen].setting == 0x800) /* when you get hit TODO: algo might be different. */ { r += m_rgb_ctrl[Screen].gradient; g -= m_rgb_ctrl[Screen].gradient; b -= m_rgb_ctrl[Screen].gradient; if(r > 0x1f) { r = 0x1f; } if(g < 0) { g = 0; } if(b < 0) { b = 0; } } } m_fadedpals[i] = (r<<10|g<<5|b); } for (int y = cliprect.top(); y <= cliprect.bottom(); y++) { uint16_t* linesrc = &m_screen_bitmap[Screen].pix16(y); uint16_t* linedest = &bitmap.pix16(y); for (int x = cliprect.left(); x<= cliprect.right(); x++) { linedest[x] = m_fadedpals[linesrc[x]]; } } return 0; } /* end video */ #define RLE_BLOCK(writeaddrxor) \ /* skip the decoding if it's the same tile as last time! */ \ if (!current_decoded) \ { \ lastSpriteNumber = 0xffffffff; /* this optimization is currently broken, so hack it to be disabled here */ \ if (spriteNumber != lastSpriteNumber) \ { \ blankcount = 256;\ lastSpriteNumber = spriteNumber; \ \ int i = 1;/* skip first 10 bits for now */ \ int data_written = 0; \ \ while (data_written<256) \ { \ \ const uint16_t compdata = expanded_10bit_gfx[ (b3romoffset) + spriteNumber + i]; \ \ if (((compdata & 0x300) == 0x000) || ((compdata & 0x300) == 0x100)) /* 3bpp */ \ { \ /* mm ccrr rrr0 */ \ int encodelength = (compdata & 0x03e)>>1; \ const uint16_t rledata = rearranged_16bit_gfx[color_offs + ((compdata & 0x1c0) >> 6)]; \ /* guess, blank tiles have the following form */ \ /* 00120 (00000024,0) | 010 03f */ \ if (compdata&1) encodelength = 255; \ \ while (data_written<256 && encodelength >=0) \ { \ tempshape[data_written^writeaddrxor] = rledata; \ if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ encodelength--; \ data_written++; \ } \ } \ else if ((compdata & 0x300) == 0x200) /* 6bpp */ \ { \ /* mm cccc ccrr */ \ int encodelength = (compdata & 0x003); \ const uint16_t rledata = rearranged_16bit_gfx[color_offs + ((compdata & 0x0fc) >> 2) + 8]; \ while (data_written<256 && encodelength >=0) \ { \ tempshape[data_written^writeaddrxor] = rledata; /* + 0x8 crt test, most of red, green, start of blue */ \ if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ encodelength--; \ data_written++; \ } \ } \ else /* 8bpp */ \ { \ /* mm cccc cccc */ \ uint16_t rawdat = (compdata & 0x0ff); \ if (b1mode && (rawdat > (b2altpenmask + 0x48))) /* does this have to be turned on by b1mode? road ends up with some bad pixels otherwise but maybe the calc is wrong... does it affect the other colour depths too? */ \ tempshape[data_written^writeaddrxor] = rearranged_16bit_gfx[color_offs2 + (rawdat )+0x48]; /* bike wheels + brake light */ \ else \ tempshape[data_written^writeaddrxor] = rearranged_16bit_gfx[color_offs + (rawdat )+0x48]; /* +0x48 crt test end of blue, start of white */ \ if (tempshape[data_written^writeaddrxor]==0x8000) blankcount--; \ data_written++; \ } \ \ i++; \ } \ if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) \ { \ object->state.m_decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded = true; \ if (blankcount==0) \ object->state.m_decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = true; \ else \ object->state.m_decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = false; \ /* if (object->screen==0) printf("marking offset %04x as decoded (sprite number %08x ptr %08x)\n", v*used_hCellCount + h, spriteNumber, ((uint64_t)(void*)tempshape)&0xffffffff);*/ \ } \ } \ } #define CHECK_DECODE \ if (used_flipy) \ { \ if (used_flipx) \ { \ RLE_BLOCK(0xff) \ } \ else \ { \ RLE_BLOCK(0xf0) \ } \ } \ else \ { if (used_flipx) \ { \ RLE_BLOCK(0x0f) \ } \ else \ { \ RLE_BLOCK(0x00) \ } \ } \ if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) \ { \ if (object->state.m_decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank == true) \ continue; \ } \ else \ if (blankcount==0) continue; #define GET_SPRITE_NUMBER \ int lookupnum; \ /* with this bit enabled the tile numbers gets looked up using 'data' (which would be blit11) (eg 03f40000 for startup text) */ \ /* this allows text strings to be written as 8-bit ascii in one area (using command 0x10), and drawn using multi-width sprites */ \ if (indirect_tile_enable) \ { \ /* this doesn't handle the various flip modes.. */ \ lookupnum = object->indirect_tiles[h + (v*used_hCellCount)]; \ } \ else \ { \ if (!blit_rotate) \ { \ if (!used_flipy) \ { \ if (!used_flipx) \ lookupnum = h + (v*used_hCellCount); \ else \ lookupnum = (used_hCellCount-h-1) + (v*used_hCellCount); \ } \ else \ { \ if (!used_flipx) \ lookupnum = h + ((used_vCellCount-v-1)*used_hCellCount); \ else \ lookupnum = (used_hCellCount-h-1) + ((used_vCellCount-v-1)*used_hCellCount); \ } \ } \ else \ { \ if (!used_flipy) \ { \ if (!used_flipx) \ lookupnum = v + (h*used_vCellCount); \ else \ lookupnum = (used_vCellCount-v-1) + (h*used_vCellCount); \ } \ else \ { \ if (!used_flipx) \ lookupnum = v + ((used_hCellCount-h-1)*used_vCellCount); \ else \ lookupnum = (used_vCellCount-v-1) + ((used_hCellCount-h-1)*used_vCellCount); \ } \ } \ } \ uint32_t spriteNumber = (expanded_10bit_gfx[ (b3romoffset) + (lookupnum<<1) +0 ] << 10) | (expanded_10bit_gfx[ (b3romoffset) + (lookupnum<<1) + 1 ]); #define DO_XCLIP_REAL \ if (drawx>clipmaxX) { break; } \ if (drawxindirect_zoom[v*16+realy]; \ uint16_t hZoomHere = hZoom + (dword>>16); \ if (!hZoomHere) { drawy++; continue; } \ /* bit 0x8000 does get set too, but only on some lines, might have another meaning? */ \ int linescroll = dword&0x7fff; \ if (linescroll & 0x4000) linescroll -= 0x8000; \ int hPositionTable = linescroll + hPositionx; \ /* DON'T use the table hZoom in this calc? (road..) */ \ int sizex = used_hCellCount * 16 * hZoom; \ hPositionTable *= 0x40; \ switch (hOrigin & 3) \ { \ case 0: \ /* left */ \ break; \ case 1: \ hPositionTable -= sizex / 2; \ /* middle? */ \ break; \ case 2: \ hPositionTable -= sizex-1; \ /* right? */ \ break; \ case 3: \ /* invalid? */ \ break; \ } #define YXLOOP \ int drawy = pixelOffsetY; \ for (int y = 0; y < blockhigh; y++) \ { \ int realy = ((y*incy)>>21); \ GET_CURRENT_LINESCROLLZOOM \ const int pixelOffsetX = ((hPositionTable) + (h* 16 * hZoomHere)) / 0x40; \ const int pixelOffsetnextX = ((hPositionTable) + ((h+1)* 16 * hZoomHere)) / 0x40; \ if (drawy>clipmaxY) { break; }; \ if (drawypix16(drawy); \ /* zline = &object->zbitmap->pix16(drawy); */ \ int blockwide = pixelOffsetnextX-pixelOffsetX; \ if (pixelOffsetX+blockwide clipmaxX) { drawy++; continue; } \ if (pixelOffsetX>=clipminX && pixelOffsetX+blockwide>21); \ GET_PIX; \ DRAW_PIX; \ } \ } \ else \ { \ uint32_t incx = 0x8000000 / hZoomHere; \ int drawx = pixelOffsetX; \ for (int x = 0; x < blockwide; x++) \ { \ DO_XCLIP_REAL \ int realx = ((x*incx)>>21); \ GET_PIX; \ DRAW_PIX; \ } \ } \ drawy++; \ } #define YXLOOP_NO_LINEZOOM \ for (int y = 0; y < blockhigh; y++) \ { \ int realy = ((y*incy)>>21); \ const int drawy = pixelOffsetY+y; \ if ((drawy>clipmaxY) || (drawypix16(drawy); \ /* zline = &object->zbitmap->pix16(drawy); */ \ int drawx = pixelOffsetX; \ for (int x = 0; x < blockwide; x++) \ { \ DO_XCLIP \ int realx = ((x*incx)>>21); \ GET_PIX; \ DRAW_PIX \ } \ } #define YXLOOP_NO_ZOOM \ for (int realy = 0; realy < 16; realy++) \ { \ const int drawy = pixelOffsetY+realy; \ if ((drawy>clipmaxY) || (drawypix16(drawy); \ /* zline = &object->zbitmap->pix16(drawy); */ \ int drawx = pixelOffsetX; \ for (int realx = 0; realx < 16; realx++) \ { \ DO_XCLIP \ GET_PIX; \ DRAW_PIX \ } \ } /* the two tables that the patent claims are located at: 0x1ec800 0x1f0000 0x3ec800 0x3f0000 of each rom ... ROM 1 + 2 gives the full palette data for each pixel, in even/odd order. TODO: fix anything that isn't text. */ #define DRAW_PIX \ /* I think 0x8000 is ALWAYS transparent */ \ /* values < 0x8000 have no alpha effect to them */ \ if (pix < 0x8000) \ { \ /*if (object->zpri < zline[drawx])*/ \ { \ { \ line[drawx] = pix&0x7fff; \ /*zline[drawx] = object->zpri;*/ \ } \ } \ } \ /* values > 0x8000 have blending */ \ else if (pix > 0x8000) \ { \ /* a blend level of 0x8 (real register value 0x7 but we added one so we can shift instead of divide in code below) seems to be the same as solid, it is set on most parts of the road and during the 'lovemachine' animation in attract when the heart should be hidden */ \ /* if (object->zpri < zline[drawx]) */ \ { \ if (blit4blendlevelinv==0x0) \ { \ line[drawx] = pix&0x7fff; \ /* zline[drawx] = object->zpri; */ \ } \ else \ { \ uint16_t source = line[drawx]; \ int src_r = ((source>>10)&0x1f) * blit4blendlevelinv; \ int src_g = ((source>>5)&0x1f) * blit4blendlevelinv; \ int src_b = ((source>>0)&0x1f) * blit4blendlevelinv; \ int dest_r = ((pix>>10)&0x1f) * blit4blendlevel; \ int dest_g = ((pix>>5)&0x1f) * blit4blendlevel; \ int dest_b = ((pix>>0)&0x1f) * blit4blendlevel; \ line[drawx] = (((src_r+dest_r)>>3)<<10) | (((src_g+dest_g)>>3)<<5) | (((src_b+dest_b)>>3)<<0); \ /* zline[drawx] = object->zpri; */ \ } \ } \ } \ drawx++; //object->rearranged_16bit_gfx //object->expanded_10bit_gfx #define GET_PIX_ROTATED \ uint16_t pix = tempshape[realx*16+realy]; #define GET_PIX_NORMAL \ uint16_t pix = tempshape[realy*16+realx]; void *coolridr_state::draw_object_threaded(void *param, int threadid) { const std::unique_ptr object(reinterpret_cast(param)); bitmap_ind16* drawbitmap = object->drawbitmap; /************* object->spriteblit[3] *************/ uint32_t blit3_unused = object->spriteblit[3] & 0xffe00000; uint32_t b3romoffset = (object->spriteblit[3] & 0x001fffff)*16; if (blit3_unused) printf("unknown bits in blit word %d - %08x\n", 3, blit3_unused); /************* object->spriteblit[5] *************/ uint32_t blit5_unused = object->spriteblit[5]&0xfffefffe; // this might enable the text indirection thing? int indirect_tile_enable = (object->spriteblit[5] & 0x00010000)>>16; int indirect_zoom_enable = (object->spriteblit[5] & 0x00000001); if (blit5_unused) printf("unknown bits in blit word %d - %08x\n", 5, blit5_unused); // 00010000 (text) // 00000001 (other) uint16_t* rearranged_16bit_gfx = object->state.m_rearranged_16bit_gfx.get(); uint16_t* expanded_10bit_gfx = object->state.m_expanded_10bit_gfx.get(); int16_t clipminX = CLIPMINX_FULL; int16_t clipmaxX = CLIPMAXX_FULL; int16_t clipminY = CLIPMINY_FULL; int16_t clipmaxY = CLIPMAXY_FULL; /************* object->spriteblit[1] *************/ // 000u0ccc - c = colour? u = 0/1 uint32_t blit1_unused = object->spriteblit[1] & 0xfffef800; uint32_t b1mode = (object->spriteblit[1] & 0x00010000)>>16; uint32_t b1colorNumber = (object->spriteblit[1] & 0x000007ff); // Probably more bits if (blit1_unused!=0) printf("blit1 unknown bits set %08x\n", object->spriteblit[1]); if (b1mode) { // b1colorNumber = object->state.machine().rand()&0xfff; } /************* object->spriteblit[3] *************/ // seems to be more complex than just transparency uint32_t blit2_unused = object->spriteblit[2]&0xff80f800; uint32_t b2altpenmask = (object->spriteblit[2] & 0x007f0000)>>16; uint32_t b2colorNumber = (object->spriteblit[2] & 0x000007ff); if (b2colorNumber != b1colorNumber) { // b1colorNumber = machine().rand()&0xfff; } // if(b1colorNumber > 0x60 || b2colorNumber) // printf("%08x %08x\n",b1colorNumber,b2colorNumber); if (blit2_unused!=0) printf("blit1 unknown bits set %08x\n", object->spriteblit[2]); if (b1mode) { if (b2altpenmask != 0x7f) printf("b1mode 1, b2altpenmask!=0x7f\n"); } else { // 0x01/0x02 trips in rare cases (start of one of the attract levels) maybe this is some kind of alpha instead? if ((b2altpenmask != 0x00) && (b2altpenmask != 0x01) && (b2altpenmask != 0x02)) printf("b1mode 0, b2altpenmask!=0x00,0x01 or 0x02 (is %02x)\n", b2altpenmask); } // 00??0uuu // ?? seems to be 00 or 7f, set depending on b1mode // uuu, at least 11 bits used, maybe 12 usually the same as blit1_unused? leftover? /************* object->spriteblit[4] *************/ uint32_t blit4_unused = object->spriteblit[4] & 0xf8fefeee; uint16_t blit4blendlevel = (object->spriteblit[4] & 0x07000000)>>24; uint16_t blit4blendlevelinv = blit4blendlevel^0x7; blit4blendlevel+=1; // make our maths easier later (not sure about accuracy) //object->zpri = 7-blit4; // unknown bits in blit word 4 - 00000010 - australia (and various other times) uint32_t blit_flipx = object->spriteblit[4] & 0x00000001; uint32_t blit_flipy = (object->spriteblit[4] & 0x00000100)>>8; uint32_t blit_rotate = (object->spriteblit[4] & 0x00010000)>>16; //uint32_t b4_unk = object->spriteblit[4] & 0x00000010; if (blit4_unused) printf("unknown bits in blit word %d - %08x\n", 4, blit4_unused); // ---- -111 ---- ---r ---- ---y ---z ---x // 1 = used bits? (unknown purpose.. might be object colour mode) // x = x-flip // y = y-flip // r = rotate 90 degrees // z = ??? set very occasionally, often at the start of stages, might relate to the clipping done at the same time? // this might affect blending logic / amount when 0x8000 palette bit is set, and maybe even z-behavior // 7 = road, player bike etc.? possibly a 'do not blend' (solid) flag of sorts because the road has 0x8000 palette bit set... // 6 = smoke frome player bike, waves on west indies, waterfalls on niagra, occasional bits of road? // 5 = clouds // 4 = shadows and some HUD elements, occassional bit of road, some firework effects, all bg elements in the coolriders of coolriders (including reaper) // 3 = front coloured jets // 2 = middle coloured jets // 1 = last few coloured trails from the jets at the start, occassional bit of road // 0 = some HUD elements, title screen, tunnels? road during coolriders of.. (this doesn't have 0x8000 set) // note the road always has 0x8000 bit set in the palette. I *think* this is because they do a gradual blend of some kind between the road types // see the number of transitional road bits which have various values above set if (blit4blendlevel==object->state.m_debug_randompal) { b1colorNumber = object->state.machine().rand()&0xfff; } /************* object->spriteblit[6] *************/ uint16_t vCellCount = (object->spriteblit[6] & 0x03ff0000) >> 16; uint16_t hCellCount = (object->spriteblit[6] & 0x000003ff); /************* object->spriteblit[7] *************/ uint16_t vOrigin = (object->spriteblit[7] & 0x00030000) >> 16; uint16_t hOrigin = (object->spriteblit[7] & 0x00000003); uint16_t OriginUnused = (object->spriteblit[7] & 0xfffcfffc); if (blit5_unused) printf("unknown bits in blit word %d - %08x\n", 7, OriginUnused); //printf("%04x %04x\n", vOrigin, hOrigin); /************* object->spriteblit[8] *************/ uint16_t vZoom = (object->spriteblit[8] & 0xffff0000) >> 16; uint16_t hZoom = (object->spriteblit[8] & 0x0000ffff); // if we have no vertical zoom value there's no point in going any further // because there are no known vertical indirect modes if (!vZoom) return nullptr; /************* object->spriteblit[9] *************/ int vPosition = (object->spriteblit[9] & 0xffff0000) >> 16; int hPositionx = (object->spriteblit[9] & 0x0000ffff); if (hPositionx & 0x8000) hPositionx -= 0x10000; if (vPosition & 0x8000) vPosition -= 0x10000; /************* object->spriteblit[10] *************/ // pointer to per-line zoom and scroll data for sprites //uint32_t blit10 = 0; // we've cached the data here already /************* object->spriteblit[11] *************/ //uint32_t textlookup = 0; // we've cached the data here already /* sample data from attract mode 'filmstrip' you can see it's screen regions at least, gets enabled in certain game situations too interestingly there is a bit to determine the screen number this applies to, even if that should already be implied from m_blitterMode screen 1 clipping(?) unknown sprite list type 1 - 00000001 003f00f0 027801f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 03e001f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 000700e3 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 010c01f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 027401f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 03dc01f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 000700df 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 010801f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 027001f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 03d801f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 000700db 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 010401f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 019c01f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 030401f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 00070007 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 0030016f 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 screen 2 clipping unknown sprite list type 1 - 00000001 003f00f0 039803f7 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 050003f7 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 02070203 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 022c036b 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 039403f7 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 04fc03f7 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 020701ff 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 02280367 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 039003f7 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 04f803f7 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 020701fb 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 003f00f0 02240363 00000207 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 NOTE, we only copy across [1] [2] and [3] as [0] [1] and [2] the 3rd dword seems to be some kind of offset, it's 0x207 on the 2nd screen, and the actual x-clip rects are also higher on that screen? note this is practically the same format as the sysh1_fb_data_w commands.. between stages (screen 1) unknown sprite list type 1 - 00000001 000000a4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a5 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a8 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000a9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ab 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ac 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ae 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000af 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b2 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b5 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b8 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000b9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ba 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000bc 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000bd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000be 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c0 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c2 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c5 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c8 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000c9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000cb 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000cc 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ce 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000cf 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d2 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d5 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d5 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d7 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d7 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d8 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000db 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000db 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000dc 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000dd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000dd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000de 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e0 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e2 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e7 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e8 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ea 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000eb 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ed 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ee 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f0 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f7 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fa 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fc 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fe 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fe 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fc 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fc 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fa 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000fa 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f8 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f6 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f3 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000f1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000ee 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000eb 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e9 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e7 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e4 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000e1 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000dd 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000da 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d7 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 000000d5 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ending unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 unknown sprite list type 1 - 00000001 0000017f 000701f7 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 romania unknown sprite list type 1 - 00000001 00000001 00000001 00000007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 */ // how does this really work? there's more to it // used in film strip attract mode, and between stages if (object->clipvals[2] & 0x0000007) // clearly this isn't the enable flag, probably just enabled until next frame / it gets disabled { // these go negative when things scroll off the left in attract mode int16_t minx = ((object->clipvals[1]&0xffff0000)>>16) - (((object->clipvals[2]&0x0000ffff)>>0)); int16_t maxx = ((object->clipvals[1]&0x0000ffff)>>0) - (((object->clipvals[2]&0x0000ffff)>>0)); int16_t miny = ((object->clipvals[0]&0xffff0000)>>16); // maybe subtract the top 16 bits of clipvals[2], but not used? int16_t maxy = ((object->clipvals[0]&0x0000ffff)>>0); clipminX = minx -1; if (clipminXCLIPMAXX_FULL) clipminX = CLIPMAXX_FULL; clipmaxX = maxx; if (clipmaxXCLIPMAXX_FULL) clipmaxX = CLIPMAXX_FULL; if (clipminX>clipmaxX) clipminX = clipmaxX; clipminY = miny -1; if (clipminYCLIPMAXY_FULL) clipminY = CLIPMAXY_FULL; clipmaxY = maxy; if (clipmaxYCLIPMAXY_FULL) clipmaxY = CLIPMAXY_FULL; if (clipminY>clipmaxY) clipminY = clipmaxY; //b1colorNumber = object->state.machine().rand()&0xfff; } /* DRAW */ uint16_t used_hCellCount = hCellCount; uint16_t used_vCellCount = vCellCount; uint16_t used_flipx = blit_flipx; uint16_t used_flipy = blit_flipy; if (blit_rotate) { used_hCellCount = vCellCount; used_vCellCount = hCellCount; used_flipx = blit_flipy; used_flipy = blit_flipx; // do the zoom params rotate? } // SPRITES / BLITS // for text objects this is an address containing the 8-bit tile numbers to use for ASCII text // I guess the tiles are decoded by a DMA operation earlier, from the compressed ROM? // we also use this to trigger the actual draw operation int size = used_hCellCount * used_vCellCount; uint16_t* tempshape; int screen = object->screen; int use_object = 0; if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) { int found = -1; for (int k=0;kstate.m_decode[screen].objcache[k].lastromoffset == b3romoffset)) && ((object->state.m_decode[screen].objcache[k].lastused_flipx == used_flipx)) && ((object->state.m_decode[screen].objcache[k].lastused_flipy == used_flipy)) && ((object->state.m_decode[screen].objcache[k].lastblit_rotate == blit_rotate)) && ((object->state.m_decode[screen].objcache[k].lastb1mode == b1mode)) && ((object->state.m_decode[screen].objcache[k].lastb1colorNumber == b1colorNumber)) && ((object->state.m_decode[screen].objcache[k].lastb2colorNumber == b2colorNumber)) && ((object->state.m_decode[screen].objcache[k].lastused_hCellCount == used_hCellCount)) && ((object->state.m_decode[screen].objcache[k].lastused_vCellCount == used_vCellCount)) && ((object->state.m_decode[screen].objcache[k].lastb2altpenmask == b2altpenmask))) { found = k; break; } } if (found != -1) { object->state.m_decode[screen].objcache[found].repeatcount++; use_object = found; } else { use_object = object->state.m_decode[screen].current_object; // dirty the cache for (int i=0;istate.m_decode[screen].objcache[use_object].tiles[i].tempshape_multi_decoded = false; object->state.m_decode[screen].objcache[use_object].lastromoffset = b3romoffset; object->state.m_decode[screen].objcache[use_object].lastused_flipx = used_flipx; object->state.m_decode[screen].objcache[use_object].lastused_flipy = used_flipy; object->state.m_decode[screen].objcache[use_object].lastblit_rotate = blit_rotate; object->state.m_decode[screen].objcache[use_object].lastb1mode = b1mode; object->state.m_decode[screen].objcache[use_object].lastb1colorNumber = b1colorNumber; object->state.m_decode[screen].objcache[use_object].lastb2colorNumber = b2colorNumber; object->state.m_decode[screen].objcache[use_object].lastused_hCellCount = used_hCellCount; object->state.m_decode[screen].objcache[use_object].lastused_vCellCount = used_vCellCount; object->state.m_decode[screen].objcache[use_object].lastb2altpenmask = b2altpenmask; object->state.m_decode[screen].objcache[use_object].repeatcount = 0; object->state.m_decode[screen].current_object++; if (object->state.m_decode[screen].current_object >= DECODECACHE_NUMOBJECTCACHES) object->state.m_decode[screen].current_object = 0; } } int sizey = used_vCellCount * 16 * vZoom; vPosition *= 0x40; switch (vOrigin & 3) { case 0: // top break; case 1: vPosition -= sizey / 2 ; // middle? break; case 2: vPosition -= sizey; // bottom? break; case 3: // invalid? break; } // Splat some sprites for (int v = 0; v < used_vCellCount; v++) { const int pixelOffsetY = ((vPosition) + (v* 16 * vZoom)) / 0x40; const int pixelOffsetnextY = ((vPosition) + ((v+1)* 16 * vZoom)) / 0x40; int blockhigh = pixelOffsetnextY - pixelOffsetY; if (pixelOffsetY+blockhigh<0) continue; if (pixelOffsetY>clipmaxY) { v = used_vCellCount; continue; } // I don't know, the Rainbow is a non-zoomed sprite and won't link unless you move one half // (fixed in the hOrigin handling instead) //if (used_flipx) // hPositionx -= 1; int hPosition = 0; if (!indirect_zoom_enable) { int sizex = used_hCellCount * 16 * hZoom; hPosition = hPositionx * 0x40; switch (hOrigin & 3) { case 0: // left break; case 1: hPosition -= sizex / 2; // middle? break; case 2: hPosition -= sizex-1; // right? break; case 3: // invalid? break; } } uint32_t lastSpriteNumber = 0xffffffff; uint16_t blankcount = 0; int color_offs = (object->colbase + (b1colorNumber & 0x7ff))*0x40 * 5; /* yes, * 5 */ \ int color_offs2 = (object->colbase + (b2colorNumber & 0x7ff))*0x40 * 5; for (int h = 0; h < used_hCellCount; h++) { int current_decoded = false; if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) { tempshape = object->state.m_decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi; current_decoded = object->state.m_decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded; /* if (object->screen==0) { if (current_decoded) printf("setting temp shape to %04x tile is marked as decoded %08x \n", v*used_hCellCount + h, ((uint64_t)(void*)tempshape)&0xffffffff); else printf("setting temp shape to %04x tile is marked as NOT decoded %08x \n", v*used_hCellCount + h, ((uint64_t)(void*)tempshape)&0xffffffff); } */ } else { //if (object->screen==0) printf("using base tempshape\n"); tempshape = object->state.m_decode[screen].tempshape; } uint32_t incy = 0x8000000 / vZoom; // DEBUG: Draw 16x16 block uint16_t* line; //uint16_t* zline; if (indirect_zoom_enable) { GET_SPRITE_NUMBER CHECK_DECODE if (blit_rotate) { #define GET_PIX GET_PIX_ROTATED YXLOOP #undef GET_PIX } else // no rotate { #define GET_PIX GET_PIX_NORMAL YXLOOP #undef GET_PIX } } else // no indirect zoom { if (!hZoom) { // abort, but make sure we clean up goto end; } if ((hZoom==0x40) && (vZoom==0x40)) // non-zoomed { const int pixelOffsetX = ((hPosition/0x40) + (h* 16)); if (pixelOffsetX+16 < clipminX) continue; if (pixelOffsetX>clipmaxX) continue; GET_SPRITE_NUMBER CHECK_DECODE if (pixelOffsetX>=clipminX && pixelOffsetX+16spriteblit[8] & 0x0000ffff); if (pixelOffsetX+blockwide < clipminX) continue; if (pixelOffsetX>clipmaxX) continue; GET_SPRITE_NUMBER CHECK_DECODE if (pixelOffsetX>=clipminX && pixelOffsetX+blockwidepen(0); // Serialized 32-bit words in order of appearance: // 0: 00000000 - unknown, 0x00000000 or 0x00000001, 0 seems to be regular sprite, 1 seems to change meaning of below, possible clip area? // 1: 00010000 - unknown, color mode? (7bpp select?) set on player bike object // 1: 00000xxx - "Color Number" (all bits or just lower 16/8?) // 2: 007f0000 - unknown, transpen? set to 0x7f whenever the 'color mode' bit in (1) is set, otherwise 0 // 2: 00000xxx - unknown, usually a copy of color number, leftover? // 3: 001fffff - offset to compressed data? (it's 0 on text objects tho, but maybe the ascii tiles are a special decode to go with the indirect mode) // 4: 07000000 - unknown (draw mode?) // 4: 00010000 - unknown (set on a few object) // 4: 00000100 - y-flip? // 4: 00000001 - x-flip? // 5: 00010000 - enable indirect text tile lookup // 5: 00000001 - enable line-zoom(?) lookup (road) // 6: vvvv---- - "Vertical Cell Count" // 6: ----hhhh - "Horizontal Cell Count" // 7: 00030003 - "Vertical|Horizontal Origin point" // 8: 00ff00ff - "Vertical|Horizontal Zoom Ratios" // 9: xxxx---- - "Display Vertical Position" // 9: ----yyyy - "Display Horizontal Position" // 10: 00000000 - unknown : always seems to be zero - NO, for some things (not text) it's also a reference to 3f40000 region like #11 // 11: ........ - indirect tile mode ram address (used for text) // first parse the bits /************* m_spriteblit[0] *************/ // set to 0x00000001 on some objects during the 'film strip' part of attract, otherwise 0 // those objects don't seem visible anyway so might have some special meaning // this is also set at times during the game // // the sprites with 1 set appear to have 0x00000000 in everything after the 4th write (blit4 and above) // so likely have some other meaning and are NOT regular sprite data uint32_t blit0 = m_spriteblit[0]; if (blit0==0) { // normal } else if (blit0==1) { if (m_blitterMode&0x80) { // HACK... // the end sequences do this.. 4f / af cliprects //(mode 4f) unknown sprite list type 1 - 0054 0105 0059 0198 (00540105 0060019f 00000007) //(mode 50) unknown sprite list type 1 - 0000 017f 0000 01f0 (0000017f 000701f7 00000007) // THEN writes the sprite that needs to be clipped(!) // this ends up disabling the cliprect before the sprite that actually needs it // // all other cliprect blits seem to be written after mode 50, so this hack just prevents // writes with a higher value than the last one from taking effect, fixing the ending... // especially noticeable with 'LoveMachine' // (mode 4f) unknown sprite list type 1 - 0054 0105 0059 0198 (00540105 0060019f 00000007) // (mode 50) unknown sprite list type 1 - 0000 017f 0000 01f0 (0000017f 000701f7 00000007) // said ending also ends up drawing a red bar under the image, which isn't clipped out and // is sent before the clip window anyway(?)... // lightning also needs clipping (doesn't have the red bar problem) // (mode 4f) unknown sprite list type 1 - 0054 0105 0059 0198 (00540105 0060019f 00000007) if (m_clipblitterMode[1] >= m_blitterMode) { m_clipvals[1][0] = m_spriteblit[1]; m_clipvals[1][1] = m_spriteblit[2]; m_clipvals[1][2] = m_spriteblit[3]; m_clipblitterMode[1] = m_blitterMode; } } else { if (m_clipblitterMode[0] >= m_blitterMode) { m_clipvals[0][0] = m_spriteblit[1]; m_clipvals[0][1] = m_spriteblit[2]; m_clipvals[0][2] = m_spriteblit[3]; m_clipblitterMode[0] = m_blitterMode; } //printf("(mode %02x) unknown sprite list type 1 - %04x %04x %04x %04x (%08x %08x %08x)\n", m_blitterMode, (m_spriteblit[1]&0xffff0000)>>16,(m_spriteblit[1]&0x0000ffff)>>0, ((m_spriteblit[2]&0xffff0000)>>16)-((m_spriteblit[3]&0x0000ffff)>>0),((m_spriteblit[2]&0x0000ffff)>>0)-((m_spriteblit[3]&0x0000ffff)>>0), m_spriteblit[1],m_spriteblit[2],m_spriteblit[3]); } // abort early return; } else { printf("unknown blit0 value %08x\n", blit0); // abort early return; } std::unique_ptr testobject(new cool_render_object(*this)); // cache some values that are looked up from RAM to be safe.. alternatively we could stall the rendering if they get written to, but they're a direct memory pointer.. int test_indirect_tile_enable = (m_spriteblit[5] & 0x00010000)>>16; if (test_indirect_tile_enable) { uint32_t test_textlookup = m_spriteblit[11]; uint16_t test_hCellCount = (m_spriteblit[6] & 0x00003ff); uint16_t test_vCellCount = (m_spriteblit[6] & 0x03ff0000) >> 16; int bytes = test_vCellCount*test_hCellCount; testobject->indirect_tiles = std::make_unique(bytes); for (int i=0;iindirect_tiles[i] = space.read_byte(test_textlookup + i); } } else { testobject->indirect_tiles = nullptr; } int test_indirect_zoom_enable = (m_spriteblit[5] & 0x00000001); if (test_indirect_zoom_enable) { uint32_t test_blit10 = m_spriteblit[10]; uint16_t test_vCellCount = (m_spriteblit[6] & 0x03ff0000) >> 16; int bytes = test_vCellCount * 4 * 16; testobject->indirect_zoom = std::make_unique(bytes/4); for (int i=0;iindirect_zoom[i] = space.read_dword(test_blit10 + i*4); } } else { testobject->indirect_zoom = nullptr; } testobject->zpri = m_blitterAddr | m_blittype<<12; testobject->blittype = m_blittype; #if 0 osd_work_queue *queue; #endif // which queue, which bitmap if (m_blitterMode == 0x30 || m_blitterMode == 0x40 || m_blitterMode == 0x4f || m_blitterMode == 0x50 || m_blitterMode == 0x60) { testobject->drawbitmap = &m_temp_bitmap_sprites[0]; /* testobject->zbitmap = &m_zbuffer_bitmap[0]; */ // pass these from the type 1 writes testobject->clipvals[0] = m_clipvals[0][0]; testobject->clipvals[1] = m_clipvals[0][1]; testobject->clipvals[2] = m_clipvals[0][2]; testobject->screen = 0; #if 0 queue = m_work_queue[0]; #endif } else // 0x90, 0xa0, 0xaf, 0xb0, 0xc0 { testobject->drawbitmap = &m_temp_bitmap_sprites[1]; /* testobject->zbitmap = &m_zbuffer_bitmap[1]; */ // pass these from the type 1 writes testobject->clipvals[0] = m_clipvals[1][0]; testobject->clipvals[1] = m_clipvals[1][1]; testobject->clipvals[2] = m_clipvals[1][2]; testobject->screen = 1; #if 0 queue = m_work_queue[1]; #endif } #if 0 if (m_usethreads) { osd_work_item_queue(queue, draw_object_threaded, testobject.release(), WORK_ITEM_FLAG_AUTO_RELEASE); } else { draw_object_threaded(testobject.release(), 0); } #else if (m_blitterMode == 0x30 || m_blitterMode == 0x40 || m_blitterMode == 0x4f || m_blitterMode == 0x50 || m_blitterMode == 0x60) { if (m_listcount[0]<1000000) { m_cool_render_object_list[0][m_listcount[0]] = std::move(testobject); m_listcount[0]++; } else { popmessage("m_listcount[0] overflow!\n"); } } else { if (m_listcount[1]<1000000) { m_cool_render_object_list[1][m_listcount[1]] = std::move(testobject); m_listcount[1]++; } else { popmessage("m_listcount[1] overflow!\n"); } } #endif } void coolridr_state::blit_mode_w(uint32_t data) { m_blitterMode = (data & 0x00ff0000) >> 16; if (m_blitterMode == 0xf4) { // Some sort of addressing state. // In the case of text, simply writes 4 characters per 32-bit word. // These values may be loaded into RAM somewhere as they are written. // The number of characters is determined by the upper-most 8 bits. m_textBytesToWrite = (data & 0xff000000) >> 24; m_textOffset = (data & 0x0000ffff); m_blitterSerialCount = 0; // this is ONLY used when there is text on the screen //printf("set mode %08x\n", data); } else if (m_blitterMode == 0x30 || m_blitterMode == 0x40 || m_blitterMode == 0x4f || m_blitterMode == 0x50 || m_blitterMode == 0x60 || m_blitterMode == 0x90 || m_blitterMode == 0xa0 || m_blitterMode == 0xaf || m_blitterMode == 0xb0 || m_blitterMode == 0xc0) { // 4f / af are used to send the clipping window during the end sequence, I don't know if the 'f' bit has any special meaning // we need a hack for the blit window to set by them to work at all // The blitter function(s). // After this is set a fixed count of 11 32-bit words are sent to the data register. // The lower word always seems to be 0x0001 and the upper byte always 0xac. m_blitterSerialCount = 0; if (m_blitterMode>=0x80) m_blittype = m_blitterMode - 0x90; else m_blittype = m_blitterMode - 0x30; m_blittype>>=4; m_blitterAddr = data & 0x00000fff; // maybe it's actually treated like RAM, and blittermode determines the nature of the write (forward inc, backward inc, no inc etc.) // the m_blitterAddr when used does increase by 6 each time // not seen this triggered if ((data & 0xff000000) != 0xac000000) printf("blitter mode set without upper bits equal 0xac000000\n"); // i've seen this triggered once or twice // might be there are more z-bits, or it's just overflowing when there are too many sprites // also set on the 4f/af cliprect during the ending //if (data & 0x0000f000) // printf("blitter mode with mask 0x0000f000 (%08x)\n", data & 0x0000f000); //if (m_blitterMode<0x80) printf("blitter set screen %d mode %02x addr? %04x\n", (data&0x00800000)>>23, ((data & 0x00ff0000)>>16)-0x30, data & 0x00000fff); // form 0xacMM-xxx ac = fixed value for this mode? MM = modes above. -xxx = some kind of offset? but it doesn't increment for each blit like the textOffset / paletteOffset stuff, investigate } else if (m_blitterMode == 0x10) { // Could be a full clear of VRAM? for(uint32_t vramAddr = 0x3f40000; vramAddr < 0x3f4ffff; vramAddr+=4) m_maincpu->space(AS_PROGRAM).write_dword(vramAddr, 0x00000000); m_blitterSerialCount = 0; } else if (m_blitterMode == 0xe0) { // uploads palettes... // does NOT upload the palette for the WDUD screen when set to US mode this way.. m_blitterSerialCount = 0; m_textOffset = (data & 0x0000ffff); // printf("set e0 %08x\n", data); } else { printf("set unknown blit mode %02x\n", m_blitterMode); } } void coolridr_state::blit_data_w(address_space &space, uint32_t data) { if (m_blitterMode == 0xf4) { // Uploads a series of bytes that index into the encoded sprite table const size_t memOffset = 0x03f40000 + m_textOffset + m_blitterSerialCount; space.write_dword(memOffset, data); m_blitterSerialCount += 0x04; } else if (m_blitterMode == 0x30 || m_blitterMode == 0x40 || m_blitterMode == 0x4f || m_blitterMode == 0x50 || m_blitterMode == 0x60 || m_blitterMode == 0x90 || m_blitterMode == 0xa0 || m_blitterMode == 0xaf || m_blitterMode == 0xb0 || m_blitterMode == 0xc0) { // Serialized counts if (m_blitterSerialCount < 12) { m_spriteblit[m_blitterSerialCount] = data; m_blitterSerialCount++; } else { printf("more than 11 dwords (%d) in blit?\n", m_blitterSerialCount); } // use the 11th blit write also as the trigger if (m_blitterSerialCount == 12) { blit_current_sprite(space); } } // ?? else if (m_blitterMode == 0x10) // at startup { //printf("blit mode %02x %02x %08x\n", m_blitterMode, m_blitterSerialCount, data); m_blitterSerialCount++; //blit mode 10 00 00000003 //blit mode 10 01 00000002 //blit mode 10 02 00007b20 << this is the palette base for the sprites (but not in aquastage where it gets set to 0x210 and colbase is 0?) ( m_colbase ) //blit mode 10 00 00000002 //blit mode 10 01 00000001 //blit mode 10 02 00040204 //blit mode 10 03 00000000 } else if (m_blitterMode == 0xe0) // when going into game (in units of 0x10 writes) { // it writes the palette for the bgs here, with fade effects? // is this the only way for the tile colours to be actually used, or does this just go to memory somewhere too? //printf("blit mode %02x %02x %08x\n", m_blitterMode, m_blitterSerialCount, data); // maybe should write to a different address, see dma hack in other code const size_t memOffset = 0x3c00000 + m_textOffset + m_blitterSerialCount; space.write_dword(memOffset, data); m_blitterSerialCount += 0x04; } else { printf("unk blit mode %02x\n", m_blitterMode); } } void coolridr_state::fb_mode_w(offs_t offset, uint32_t data, uint32_t mem_mask) { /* This does the fb display/clear phases of blitter data processed in the previous frame. And yes, game effectively runs at 30 Hz (because data processing happens on even frames, actual display transfer happens on odd frames). screen 1 8c200000 06 00000001 07 0000017f 07 Y range (upper start, lower end) 000701f7 07 X range (upper start, lower end) 00000007 07 enable? screen 2 8c800000 06 00000001 07 0000017f 07 020703f7 07 00000207 07 enable plus clear? */ COMBINE_DATA(&m_blitterClearMode); /* if(m_blitterClearMode != 0x8c200000 && m_blitterClearMode != 0x8c800000) printf("Blitter Clear used with param %08x\n",m_blitterClearMode); */ m_blitterClearCount = 0; } void coolridr_state::fb_data_w(offs_t offset, uint32_t data) { if(m_blitterClearCount == 0) { if(data != 1) printf("Blitter Clear Count == 0 used with param %08x\n",data); } else if(m_blitterClearCount == 1) { if(data != 0x17f) printf("Blitter Clear Count == 1 used with param %08x\n",data); } else if(m_blitterClearCount == 2) { /* if(data != 0x000701f7 && m_txt_blit[offset] != 0x020703f7) printf("Blitter Clear Count == 2 used with param %08x\n",data); */ } else if(m_blitterClearCount == 3) { if(data != 0x00000007 && data != 0x00000207) printf("Blitter Clear Count == 3 used with param %08x\n",data); { const rectangle& visarea = m_screen->visible_area(); if(m_blitterClearMode == 0x8c200000) { // wait for our sprite rendering to finish osd_work_queue_wait(m_work_queue[0], osd_ticks_per_second() * 100); // copy our old buffer to the actual screen copybitmap(m_screen_bitmap[0], m_temp_bitmap_sprites[0], 0, 0, 0, 0, visarea); //m_temp_bitmap_sprites[1].fill(0xff000000, visarea); // render the tilemap to the backbuffer, ready for having sprites drawn on it draw_bg_coolridr(m_temp_bitmap_sprites[0], visarea, 0); // wipe the z-buffer ready for the sprites /* m_zbuffer_bitmap[0].fill(0xffff, visarea); */ // almost certainly wrong m_clipvals[0][0] = 0; m_clipvals[0][1] = 0; m_clipvals[0][2] = 0; m_clipblitterMode[0] = 0xff; /* bubble sort, might be something better to use instead */ for (int pass = 0 ; pass < (m_listcount[0] - 1); pass++) { for (int elem2 = 0 ; elem2 < m_listcount[0] - pass - 1; elem2++) { if (m_cool_render_object_list[0][elem2]->zpri > m_cool_render_object_list[0][elem2+1]->zpri) std::swap(m_cool_render_object_list[0][elem2], m_cool_render_object_list[0][elem2+1]); } } for (int i=m_listcount[0]-1;i>=0;i--) { if (m_usethreads) { osd_work_item_queue(m_work_queue[0], draw_object_threaded, m_cool_render_object_list[0][i].release(), WORK_ITEM_FLAG_AUTO_RELEASE); } else { draw_object_threaded((void*)m_cool_render_object_list[0][i].release(), 0); } } m_listcount[0] = 0; } else if(m_blitterClearMode == 0x8c800000) { // wait for our sprite rendering to finish osd_work_queue_wait(m_work_queue[1], osd_ticks_per_second() * 100); // copy our old buffer to the actual screen copybitmap(m_screen_bitmap[1], m_temp_bitmap_sprites[1], 0, 0, 0, 0, visarea); //m_temp_bitmap_sprites[1].fill(0xff000000, visarea); // render the tilemap to the backbuffer, ready for having sprites drawn on it draw_bg_coolridr(m_temp_bitmap_sprites[1], visarea, 1); // wipe the z-buffer ready for the sprites /* m_zbuffer_bitmap[1].fill(0xffff, visarea); */ // almost certainly wrong m_clipvals[1][0] = 0; m_clipvals[1][1] = 0; m_clipvals[1][2] = 0; m_clipblitterMode[1] = 0xff; /* bubble sort, might be something better to use instead */ for (int pass = 0 ; pass < (m_listcount[1] - 1); pass++) { for (int elem2 = 0 ; elem2 < m_listcount[1] - pass - 1; elem2++) { if (m_cool_render_object_list[1][elem2]->zpri > m_cool_render_object_list[1][elem2+1]->zpri) std::swap(m_cool_render_object_list[1][elem2], m_cool_render_object_list[1][elem2+1]); } } for (int i=m_listcount[1]-1;i>=0;i--) { if (m_usethreads) { osd_work_item_queue(m_work_queue[1], draw_object_threaded, m_cool_render_object_list[1][i].release(), WORK_ITEM_FLAG_AUTO_RELEASE); } else { draw_object_threaded((void*)m_cool_render_object_list[1][i].release(), 0); } } m_listcount[1] = 0; } //printf("frame\n"); } } else { printf("Blitter Clear Count == %02x used with param %08x\n",m_blitterClearCount,m_txt_blit[offset]); } m_blitterClearCount++; } uint32_t coolridr_state::unk_blit_r(offs_t offset) { // if(offset == 0x0c/4) // TODO return m_txt_blit[offset]; } void coolridr_state::unk_blit_w(offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(&m_txt_blit[offset]); switch(offset) { default: { printf("sysh1_unk_blit_w unhandled offset %04x %08x %08x\n", offset, data, mem_mask); } break; case 0x01: { // writes on startup // sysh1_unk_blit_w unhandled offset 0001 01010101 ffffffff } break; case 0x02: { // writes 3d0dxxxx / 3d0exxxx before a level start.. offset for a transfer read at 0x400000c, stored in work RAM H //printf("sysh1_unk_blit_w unhandled offset %04x %08x %08x\n", offset, data, mem_mask); } break; } } void coolridr_state::dma_transfer( address_space &space, uint16_t dma_index ) { uint32_t src = 0,dst = 0,size = 0; uint8_t end_dma_mark; uint8_t cmd; end_dma_mark = 0; do{ cmd = (m_framebuffer_vram[(0+dma_index)/4] & 0xfc000000) >> 24; switch(cmd) { case 0x00: /* end of list marker */ //printf("end of list reached\n"); end_dma_mark = 1; break; case 0xc0: /* to internal buffer VRAM */ src = (m_framebuffer_vram[(0+dma_index)/4] & 0x03ffffff); dst = (m_framebuffer_vram[(4+dma_index)/4]); size = m_framebuffer_vram[(8+dma_index)/4]; printf("%08x %08x %04x\n",src,dst,size); if(dst & 0xfff00001) printf("unk values to %02x dst %08x\n",cmd,dst); dst &= 0x000ffffe; dst >>= 1; for(int i=0;igfx(m_gfx_index)->mark_dirty(dst/256); dst++; src++; } dma_index+=0xc; break; case 0xe0: /* to palette RAM */ src = (m_framebuffer_vram[(0+dma_index)/4] & 0x03ffffff); dst = (m_framebuffer_vram[(4+dma_index)/4]); size = m_framebuffer_vram[(8+dma_index)/4]; /* Note: there are also some reads at 0x3e00000. This tells us that the DMA thing actually mirrors at 0x3c00000 too. */ if(dst & 0xfff00001) printf("unk values to %02x dst %08x\n",cmd,dst); dst &= 0x000ffffe; dst >>= 1; for(int i=0;i> 2] = m_framebuffer_vram[(0+dma_index)/4] & 0xffffff; dma_index+=4; break; case 0x40: /* screen 1 - almost certainly RGB brightness (at least bits 4 - 0) */ case 0x44: /* screen 2 / */ m_rgb_ctrl[(cmd & 4) >> 2].setting = m_framebuffer_vram[(0+dma_index)/4] & 0xffffe0; m_rgb_ctrl[(cmd & 4) >> 2].gradient = m_framebuffer_vram[(0+dma_index)/4] & 0x1f; dma_index+=4; break; default: printf("%02x %08x\n",cmd,m_framebuffer_vram[(0+dma_index)/4]); dma_index+=4; break; } }while(!end_dma_mark ); } void coolridr_state::dma_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(&m_framebuffer_vram[offset]); if(offset*4 == 0x000) { /* enable */ if((m_framebuffer_vram[offset] & 0xff000000) == 0x0f000000) dma_transfer(space, m_framebuffer_vram[offset] & 0xffff); } } void coolridr_state::system_h1_map(address_map &map) { map(0x00000000, 0x001fffff).rom().share("share1").nopw(); map(0x01000000, 0x01ffffff).rom().region("gfx_data", 0x0000000); map(0x03f40000, 0x03f4ffff).ram().share("txt_vram");//text tilemap + "lineram" map(0x04000000, 0x0400000f).rw(FUNC(coolridr_state::unk_blit_r), FUNC(coolridr_state::unk_blit_w)).share("txt_blit"); map(0x04000010, 0x04000013).w(FUNC(coolridr_state::blit_mode_w)); map(0x04000014, 0x04000017).w(FUNC(coolridr_state::blit_data_w)); map(0x04000018, 0x0400001b).w(FUNC(coolridr_state::fb_mode_w)); map(0x0400001c, 0x0400001f).w(FUNC(coolridr_state::fb_data_w)); map(0x06000000, 0x060fffff).ram().share("workrah"); map(0x20000000, 0x201fffff).rom().share("share1"); map(0x60000000, 0x600003ff).nopw(); } void coolridr_state::coolridr_h1_map(address_map &map) { system_h1_map(map); map(0x03c00000, 0x03c1ffff).mirror(0x00200000).ram().w(FUNC(coolridr_state::dma_w)).share("fb_vram"); /* mostly mapped at 0x03e00000 */ map(0x03f00000, 0x03f0ffff).ram().share("share3"); /*Communication area RAM*/ } void coolridr_state::aquastge_h1_map(address_map &map) { system_h1_map(map); map(0x03c00000, 0x03c0ffff).mirror(0x00200000).ram().w(FUNC(coolridr_state::dma_w)).share("fb_vram"); /* mostly mapped at 0x03e00000 */ map(0x03f50000, 0x03f5ffff).ram(); // video registers map(0x03e10000, 0x03e1ffff).ram().share("share3"); /*Communication area RAM*/ map(0x03f00000, 0x03f0ffff).ram(); /*Communication area RAM*/ } template uint16_t coolridr_state::soundram_r(offs_t offset) { return m_soundram[Chip][offset]; } template void coolridr_state::soundram_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&m_soundram[Chip][offset]); } void coolridr_state::lamps_w(uint8_t data) { /* x--- ---- P2 Music select Lamp -x-- ---- P1 Music select Lamp --x- ---- P2 Race Leader Lamp ---x ---- P1 Race Leader Lamp ---- x--- P2 Start Lamp ---- -x-- P1 Start Lamp ---- ---x (used in game?) */ } uint32_t coolridr_state::sound_dma_r(offs_t offset) { if(offset == 8) { //popmessage("%02x",m_sound_data); /* Checked in irq routine --x- ---- second SCSP ---x ---- first SCSP */ return m_sound_data; } if(offset == 2 || offset == 6) // DMA status return 0; printf("%08x\n",offset); return m_sound_dma[offset]; } void coolridr_state::sound_dma_w(offs_t offset, uint32_t data, uint32_t mem_mask) { address_space &main_space = m_maincpu->space(AS_PROGRAM); address_space &sound_space = m_soundcpu->space(AS_PROGRAM); //printf("%08x %08x\n",offset*4,m_h1_unk[offset]); if(offset == 8) { //probably writing to upper word disables m68k, to lower word enables it m_soundcpu->set_input_line(INPUT_LINE_RESET, (data) ? ASSERT_LINE : CLEAR_LINE); return; } if(offset == 2) { if(data & 1 && (!(m_sound_dma[2] & 1))) // 0 -> 1 transition enables DMA { uint32_t src = m_sound_dma[0]; uint32_t dst = m_sound_dma[1]; uint32_t size = (m_sound_dma[2]>>16)*0x40; //printf("%08x %08x %08x %02x\n",src,dst,size,m_sound_fifo); for(int i = 0;i < size; i+=2) { sound_space.write_word(dst,main_space.read_word(src)); src+=2; dst+=2; } } } if(offset == 6) { if(data & 1 && (!(m_sound_dma[6] & 1))) // 0 -> 1 transition enables DMA { uint32_t src = m_sound_dma[4]; uint32_t dst = m_sound_dma[5]; uint32_t size = (m_sound_dma[6]>>16)*0x40; //printf("%08x %08x %08x %02x\n",src,dst,size,m_sound_fifo); for(int i = 0;i < size; i+=2) { sound_space.write_word(dst,main_space.read_word(src)); src+=2; dst+=2; } } } COMBINE_DATA(&m_sound_dma[offset]); } void coolridr_state::system_h1_submap(address_map &map) { map(0x00000000, 0x0001ffff).rom(); // note: SH7032 only supports 64KB map(0x01000000, 0x0100ffff).ram(); //communication RAM map(0x03000000, 0x0307ffff).rw(FUNC(coolridr_state::soundram_r<0>), FUNC(coolridr_state::soundram_w<0>)); //.share("soundram1"); map(0x03100000, 0x03100fff).rw("scsp1", FUNC(scsp_device::read), FUNC(scsp_device::write)); map(0x03200000, 0x0327ffff).rw(FUNC(coolridr_state::soundram_r<1>), FUNC(coolridr_state::soundram_w<1>)); //.share("soundram2"); map(0x03300000, 0x03300fff).rw("scsp2", FUNC(scsp_device::read), FUNC(scsp_device::write)); map(0x04000000, 0x0400003f).rw(FUNC(coolridr_state::sound_dma_r), FUNC(coolridr_state::sound_dma_w)).share("sound_dma"); // map(0x04200000, 0x0420003f).ram(); /* unknown */ map(0x05000000, 0x05000fff).ram(); // map(0x05fffe00, 0x05ffffff).rw(FUNC(coolridr_state::sh7032_r), FUNC(coolridr_state::sh7032_w)); // SH-7032H internal i/o map(0x06000000, 0x060001ff).ram().share("nvram"); // backup RAM map(0x06100000, 0x0610001f).rw("io", FUNC(sega_315_5649_device::read), FUNC(sega_315_5649_device::write)).umask32(0x00ff00ff); map(0x06200000, 0x06200fff).ram(); //network related? map(0x07ffe000, 0x07ffffff).ram(); // On-Chip RAM (actually mapped at 0x0fffe000-0x0fffffff) } void coolridr_state::coolridr_submap(address_map &map) { system_h1_submap(map); map(0x05200000, 0x052001ff).ram(); map(0x05300000, 0x0530ffff).ram().share("share3"); /*Communication area RAM*/ } void coolridr_state::aquastge_submap(address_map &map) { system_h1_submap(map); map(0x05200000, 0x0520ffff).ram(); map(0x05210000, 0x0521ffff).ram().share("share3"); /*Communication area RAM*/ map(0x05220000, 0x0537ffff).ram(); map(0x06000200, 0x06000207).nopw(); // program bug? } /* TODO: what is this for, volume mixing? MIDI? */ void coolridr_state::sound_to_sh1_w(uint8_t data) { m_sound_fifo = data; } void coolridr_state::system_h1_sound_map(address_map &map) { map(0x000000, 0x07ffff).ram().share("soundram1"); map(0x100000, 0x100fff).rw("scsp1", FUNC(scsp_device::read), FUNC(scsp_device::write)); map(0x200000, 0x27ffff).ram().share("soundram2"); map(0x300000, 0x300fff).rw("scsp2", FUNC(scsp_device::read), FUNC(scsp_device::write)); map(0x800000, 0x80ffff).mirror(0x200000).ram(); map(0x900001, 0x900001).w(FUNC(coolridr_state::sound_to_sh1_w)); } template void coolridr_state::scsp_map(address_map &map) { map(0x000000, 0x07ffff).ram().share(m_soundram[Chip]); } static GFXDECODE_START( gfx_coolridr ) // GFXDECODE_ENTRY( nullptr, 0, tiles16x16_layout, 0, 0x100 ) GFXDECODE_END static INPUT_PORTS_START( coolridr ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_NAME("P1 Coin") PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("P2 Coin") PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("P1 Service Switch") PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("P1 Start") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("P2 Start") PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("P2 Service Switch") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P1") PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Music <<") PORT_CODE(KEYCODE_Z) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Music >>") PORT_CODE(KEYCODE_X) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Shift Up") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Shift Down") PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P2") PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Music <<") PORT_CODE(KEYCODE_N) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Music >>") PORT_CODE(KEYCODE_M) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Shift Up") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Shift Down") PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("AN0") PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(60) PORT_PLAYER(1) PORT_NAME("P1 Handle Bar") PORT_START("AN1") PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(60) PORT_PLAYER(1) PORT_NAME("P1 Throttle") PORT_REVERSE PORT_START("AN2") PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(60) PORT_PLAYER(1) PORT_NAME("P1 Brake") PORT_REVERSE PORT_START("AN4") PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(60) PORT_PLAYER(2) PORT_NAME("P2 Handle Bar") PORT_START("AN5") PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(60) PORT_PLAYER(2) PORT_NAME("P2 Throttle") PORT_REVERSE PORT_START("AN6") PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(60) PORT_PLAYER(2) PORT_NAME("P2 Brake") PORT_REVERSE // driver debug PORT_START("CONFIG") PORT_CONFNAME( 0x01, 0x01, "Use Threading Code" ) PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) PORT_CONFSETTING( 0x01, DEF_STR( On ) ) INPUT_PORTS_END static INPUT_PORTS_START( aquastge ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_NAME("P1 Coin") PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("P2 Coin") PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("P1 Service Switch") PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("P1 Start") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("P2 Start") PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("P2 Service Switch") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("IN1") PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) // driver debug PORT_START("CONFIG") PORT_CONFNAME( 0x01, 0x01, "Use Threading Code" ) PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) PORT_CONFSETTING( 0x01, DEF_STR( On ) ) INPUT_PORTS_END // IRQs 4 & 6 are valid on SH-2 TIMER_DEVICE_CALLBACK_MEMBER(coolridr_state::interrupt_main) { int scanline = param; if(scanline == 384) m_maincpu->set_input_line(4, HOLD_LINE); if(scanline == 0) m_maincpu->set_input_line(6, HOLD_LINE); } TIMER_DEVICE_CALLBACK_MEMBER(coolridr_state::interrupt_sub) { int scanline = param; /* 0xa: reads from 0x4000000 (sound irq) */ /* 0xc: reads from inputs (so presumably V-Blank) */ /* 0xe: tries to r/w to 0x62***** area (network irq?) */ if(scanline == 384) m_subcpu->set_input_line(0xc, HOLD_LINE); } #define READ_COMPRESSED_ROM(chip) \ m_compressedgfx[(chip)*0x400000 + romoffset] << 8 | m_compressedgfx[(chip)*0x0400000 + romoffset +1]; // this helps you feth the 20bit words from an address in the compressed data uint32_t coolridr_state::get_20bit_data(uint32_t romoffset, int _20bitwordnum) { uint16_t testvalue, testvalue2; int temp = _20bitwordnum & 3; int inc = 0; if (_20bitwordnum&4) inc = 5; romoffset += (_20bitwordnum>>3)*2; if (temp==0) { testvalue = READ_COMPRESSED_ROM(0+inc); testvalue2 = READ_COMPRESSED_ROM(1+inc); return (testvalue << 4) | (testvalue2 & 0xf000) >> 12; } else if (temp==1) { testvalue = READ_COMPRESSED_ROM(1+inc); testvalue2 = READ_COMPRESSED_ROM(2+inc); return ((testvalue & 0x0fff) << 8) | (testvalue2 & 0xff00) >> 8; } else if (temp==2) { testvalue = READ_COMPRESSED_ROM(2+inc); testvalue2 = READ_COMPRESSED_ROM(3+inc); return ((testvalue & 0x00ff) << 12) | (testvalue2 & 0xfff0) >> 4; } else // temp == 3 { testvalue = READ_COMPRESSED_ROM(3+inc); testvalue2 = READ_COMPRESSED_ROM(4+inc); return ((testvalue & 0x000f) << 16) | (testvalue2); } } uint16_t coolridr_state::get_10bit_data(uint32_t romoffset, int _10bitwordnum) { uint32_t data = get_20bit_data(romoffset, _10bitwordnum>>1); if (_10bitwordnum&1) return data & 0x3ff; else return (data>>10) & 0x3ff; } void coolridr_state::machine_start() { size_t size = m_compressedgfx.length(); // we're expanding 10bit packed data to 16bits(10 used) m_expanded_10bit_gfx = std::make_unique(((size/10)*16)/2); for (int i=0;i<(0x800000*8)/2;i++) { m_expanded_10bit_gfx[i] = get_10bit_data( 0, i); } // do a rearranged version too with just the 16-bit words in a different order, palettes seem to // be referenced this way?! m_rearranged_16bit_gfx = std::make_unique(size/2); uint16_t* compressed = (uint16_t*)&m_compressedgfx[0]; int count = 0; for (int i=0;i> 8); m_rearranged_16bit_gfx[count+1] = ((compressed[i+((0x0400000/2)*1)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*1)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+2] = ((compressed[i+((0x0400000/2)*2)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*2)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+3] = ((compressed[i+((0x0400000/2)*3)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*3)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+4] = ((compressed[i+((0x0400000/2)*4)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*4)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+5] = ((compressed[i+((0x0400000/2)*5)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*5)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+6] = ((compressed[i+((0x0400000/2)*6)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*6)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+7] = ((compressed[i+((0x0400000/2)*7)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*7)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+8] = ((compressed[i+((0x0400000/2)*8)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*8)]&0xff00) >> 8); m_rearranged_16bit_gfx[count+9] = ((compressed[i+((0x0400000/2)*9)]&0x00ff) << 8) | ((compressed[i+((0x0400000/2)*9)]&0xff00) >> 8); count+=10; } if (0) { FILE *fp; char filename[256]; sprintf(filename,"expanded_%s_gfx", machine().system().name); fp=fopen(filename, "w+b"); if (fp) { for (int i=0;i<(0x800000*8);i++) { fwrite((uint8_t*)m_expanded_10bit_gfx.get()+(i^1), 1, 1, fp); } fclose(fp); } } m_work_queue[0] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); m_work_queue[1] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); m_decode[0].current_object = 0; m_decode[1].current_object = 0; save_item(NAME(m_sound_data)); save_item(NAME(m_sound_fifo)); } void coolridr_state::machine_reset() { m_soundcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_usethreads = m_io_config->read()&1; } void coolridr_state::scsp_irq(offs_t offset, uint8_t data) { m_soundcpu->set_input_line(offset, data); } WRITE_LINE_MEMBER(coolridr_state::scsp1_to_sh1_irq) { m_subcpu->set_input_line(0xe, (state) ? ASSERT_LINE : CLEAR_LINE); if(state) m_sound_data |= 0x10; else m_sound_data &= ~0x10; } WRITE_LINE_MEMBER(coolridr_state::scsp2_to_sh1_irq) { m_subcpu->set_input_line(0xe, (state) ? ASSERT_LINE : CLEAR_LINE); if(state) m_sound_data |= 0x20; else m_sound_data &= ~0x20; } #define MAIN_CLOCK XTAL(28'636'363) void coolridr_state::coolridr(machine_config &config) { SH2(config, m_maincpu, MAIN_CLOCK); // 28 MHz m_maincpu->set_addrmap(AS_PROGRAM, &coolridr_state::coolridr_h1_map); TIMER(config, "scantimer").configure_scanline(FUNC(coolridr_state::interrupt_main), "screen", 0, 1); M68000(config, m_soundcpu, 22579000/2); // 22.579 MHz XTAL / 2 = 11.2895 MHz m_soundcpu->set_addrmap(AS_PROGRAM, &coolridr_state::system_h1_sound_map); SH1(config, m_subcpu, 16000000); // SH7032 HD6417032F20!! 16 MHz m_subcpu->set_addrmap(AS_PROGRAM, &coolridr_state::coolridr_submap); TIMER(config, "scantimer2").configure_scanline(FUNC(coolridr_state::interrupt_sub), "screen", 0, 1); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); sega_315_5649_device &io(SEGA_315_5649(config, "io", 0)); io.out_pb_callback().set(FUNC(coolridr_state::lamps_w)); io.in_pc_callback().set_ioport("IN0"); io.in_pd_callback().set_ioport("P1"); io.in_pe_callback().set_ioport("P2"); io.an_port_callback<0>().set_ioport("AN0"); io.an_port_callback<1>().set_ioport("AN1"); io.an_port_callback<2>().set_ioport("AN2"); io.an_port_callback<4>().set_ioport("AN4"); io.an_port_callback<5>().set_ioport("AN5"); io.an_port_callback<6>().set_ioport("AN6"); GFXDECODE(config, m_gfxdecode, m_palette, gfx_coolridr); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); m_screen->set_size(640, 512); m_screen->set_visarea(CLIPMINX_FULL,CLIPMAXX_FULL, CLIPMINY_FULL, CLIPMAXY_FULL); m_screen->set_screen_update(FUNC(coolridr_state::screen_update<0>)); m_screen->set_palette(m_palette); screen_device &screen2(SCREEN(config, "screen2", SCREEN_TYPE_RASTER)); screen2.set_refresh_hz(60); screen2.set_size(640, 512); screen2.set_visarea(CLIPMINX_FULL,CLIPMAXX_FULL, CLIPMINY_FULL, CLIPMAXY_FULL); screen2.set_screen_update(FUNC(coolridr_state::screen_update<1>)); screen2.set_palette(m_palette); PALETTE(config, m_palette, palette_device::RGB_555); config.set_default_layout(layout_dualhsxs); SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); scsp_device &scsp1(SCSP(config, "scsp1", 22579000)); // 22.579 MHz XTAL scsp1.set_addrmap(0, &coolridr_state::scsp_map<0>); scsp1.irq_cb().set(FUNC(coolridr_state::scsp_irq)); scsp1.main_irq_cb().set(FUNC(coolridr_state::scsp1_to_sh1_irq)); scsp1.add_route(0, "lspeaker", 1.0); scsp1.add_route(1, "rspeaker", 1.0); scsp_device &scsp2(SCSP(config, "scsp2", 22579000)); // 22.579 MHz XTAL scsp2.set_addrmap(0, &coolridr_state::scsp_map<1>); scsp2.main_irq_cb().set(FUNC(coolridr_state::scsp2_to_sh1_irq)); scsp2.add_route(0, "lspeaker", 1.0); scsp2.add_route(1, "rspeaker", 1.0); } void coolridr_state::aquastge(machine_config &config) { coolridr(config); m_maincpu->set_addrmap(AS_PROGRAM, &coolridr_state::aquastge_h1_map); m_subcpu->set_addrmap(AS_PROGRAM, &coolridr_state::aquastge_submap); sega_315_5649_device &io(SEGA_315_5649(config.replace(), "io", 0)); io.in_pc_callback().set_ioport("IN0"); io.in_pd_callback().set_ioport("IN1"); } ROM_START( coolridr ) ROM_REGION( 0x200000, "maincpu", 0 ) /* SH2 code */ ROM_LOAD32_WORD_SWAP( "ep17659.30", 0x0000000, 0x080000, CRC(473027b0) SHA1(acaa212869dd79550235171b9f054e82750f74c3) ) ROM_LOAD32_WORD_SWAP( "ep17658.29", 0x0000002, 0x080000, CRC(7ecfdfcc) SHA1(97cb3e6cf9764c8db06de12e4e958148818ef737) ) ROM_LOAD32_WORD_SWAP( "ep17661.32", 0x0100000, 0x080000, CRC(81a7d90b) SHA1(99f8c3e75b94dd1b60455c26dc38ce08db82fe32) ) ROM_LOAD32_WORD_SWAP( "ep17660.31", 0x0100002, 0x080000, CRC(27b7a507) SHA1(4c28b1d18d75630a73194b5d4fd166f3b647c595) ) /* Page 12 of the service manual states that these 4 regions are tested, so I believe that they are read by the SH-2 */ ROM_REGION32_BE( 0x1000000, "gfx_data", 0 ) /* SH2 code */ ROM_LOAD32_WORD_SWAP( "mp17650.11", 0x0000002, 0x0200000, CRC(0ccc84a1) SHA1(65951685b0c8073f6bd1cf9959e1b4d0fc6031d8) ) ROM_LOAD32_WORD_SWAP( "mp17651.12", 0x0000000, 0x0200000, CRC(25fd7dde) SHA1(a1c3f3d947ce20fbf61ea7ab235259be9b7d35a8) ) ROM_LOAD32_WORD_SWAP( "mp17652.13", 0x0400002, 0x0200000, CRC(be9b4d05) SHA1(0252ba647434f69d6eacb4efc6f55e6af534c7c5) ) ROM_LOAD32_WORD_SWAP( "mp17653.14", 0x0400000, 0x0200000, CRC(64d1406d) SHA1(779dbbf42a14a6be1de9afbae5bbb18f8f36ceb3) ) ROM_LOAD32_WORD_SWAP( "mp17654.15", 0x0800002, 0x0200000, CRC(5dee5cba) SHA1(6e6ec8574bdd35cc27903fc45f0d4a36ce9df103) ) ROM_LOAD32_WORD_SWAP( "mp17655.16", 0x0800000, 0x0200000, CRC(02903cf2) SHA1(16d555fda144e0f1b62b428e9158a0e8ebf7084e) ) ROM_LOAD32_WORD_SWAP( "mp17656.17", 0x0c00002, 0x0200000, CRC(945c89e3) SHA1(8776d74f73898d948aae3c446d7c710ad0407603) ) ROM_LOAD32_WORD_SWAP( "mp17657.18", 0x0c00000, 0x0200000, CRC(74676b1f) SHA1(b4a9003a052bde93bebfa4bef9e8dff65003c3b2) ) ROM_REGION( 0x100000, "sub", 0 ) /* SH1 */ ROM_LOAD16_WORD_SWAP( "ep17662.12", 0x000000, 0x020000, CRC(50d66b1f) SHA1(f7b7f2f5b403a13b162f941c338a3e1207762a0b) ) /* these are compressed sprite data */ ROM_REGION( 0x2800000, "compressedgfx", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "mpr-17644.ic5", 0x0000000, 0x0400000, CRC(80199c79) SHA1(e525d8ee9f9176101629853e50cca73b02b16a38) ) // 0004 ROM_LOAD16_WORD_SWAP( "mpr-17643.ic4", 0x0400000, 0x0400000, CRC(5100f23b) SHA1(659c2300399ff1cbd24fb1eb18cfd6c26e06fd96) ) // 9000 ROM_LOAD16_WORD_SWAP( "mpr-17642.ic3", 0x0800000, 0x0400000, CRC(1a5bcc73) SHA1(a7df04c0a326323ea185db5f55b3e0449d76c535) ) // 4900 ROM_LOAD16_WORD_SWAP( "mpr-17641.ic2", 0x0c00000, 0x0400000, CRC(fccc3dae) SHA1(0df7fd8b1110ba9063dc4dc40301267229cb9a35) ) // 0490 ROM_LOAD16_WORD_SWAP( "mpr-17640.ic1", 0x1000000, 0x0400000, CRC(981e3e69) SHA1(d242055e0359ec4b5fac4676b2f974fbc974cc68) ) // 0049 ROM_LOAD16_WORD_SWAP( "mpr-17649.ic10",0x1400000, 0x0400000, CRC(618c47ae) SHA1(5b69ad36fcf8e70d34c3b2fc71412ce953c5ceb3) ) // 0004 ROM_LOAD16_WORD_SWAP( "mpr-17648.ic9", 0x1800000, 0x0400000, CRC(bf184cce) SHA1(62c004ea279f9a649d21426369336c2e1f9d24da) ) // 9000 ROM_LOAD16_WORD_SWAP( "mpr-17647.ic8", 0x1c00000, 0x0400000, CRC(9dd9330c) SHA1(c91a7f497c1f4bd283bd683b06dff88893724d51) ) // 4900 ROM_LOAD16_WORD_SWAP( "mpr-17646.ic7", 0x2000000, 0x0400000, CRC(b77eb2ad) SHA1(b832c0f1798aca39adba840d56ae96a75346670a) ) // 0490 ROM_LOAD16_WORD_SWAP( "mpr-17645.ic6", 0x2400000, 0x0400000, CRC(56968d07) SHA1(e88c3d66ea05affb4681a25d155f097bd1b5a84b) ) // 0049 ROM_END /* Aqua Stage (Coin pusher) PCB: 833-12000 AQUA STAGE */ ROM_START( aquastge ) ROM_REGION( 0x200000, "maincpu", 0 ) /* SH2 code */ ROM_LOAD32_WORD_SWAP( "epr-18280.ic30", 0x0000000, 0x080000, CRC(4038352a) SHA1(fe951592e2462c701c740da4ec77435ae3026eab) ) ROM_LOAD32_WORD_SWAP( "epr-18279.ic29", 0x0000002, 0x080000, CRC(9697cbcd) SHA1(4afa9a3f85b9d4483dafae8a98526ae32abd7103) ) ROM_LOAD32_WORD_SWAP( "epr-18282.ic32", 0x0100000, 0x080000, CRC(53684dd8) SHA1(59759f6e3f815280a2406cc2133fc46e673cc76a)) ROM_LOAD32_WORD_SWAP( "epr-18281.ic31", 0x0100002, 0x080000, CRC(f1233190) SHA1(471578c9343ac7198d73bee73975656c52e0bc5d) ) /* Page 12 of the service manual states that these 4 regions are tested, so I believe that they are read by the SH-2 */ ROM_REGION32_BE( 0x1000000, "gfx_data", ROMREGION_ERASEFF ) /* SH2 code */ ROM_LOAD32_WORD_SWAP( "mpr-18283.ic17", 0x0c00002, 0x0200000, CRC(f42e2e72) SHA1(caf8733b6888ee718032c55f64da14590353517e) ) ROM_RELOAD(0x0000002, 0x0200000) ROM_LOAD32_WORD_SWAP( "mpr-18284.ic18", 0x0c00000, 0x0200000, CRC(5fdf3c1f) SHA1(9976fe4afc3234eecbaf47a2e0f951b6fe1cb5f5) ) ROM_RELOAD(0x0000000, 0x0200000) ROM_REGION( 0x100000, "sub", 0 ) /* SH1 */ ROM_LOAD16_WORD_SWAP( "epr-18278.ic12", 0x000000, 0x020000, CRC(e601132a) SHA1(bed103ef2e0dfa8bb485d93d661142b82c23088b) ) /* these are compressed sprite data */ ROM_REGION( 0x2800000, "compressedgfx", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "mpr-18289.ic5", 0x0000000, 0x0200000, CRC(fb212692) SHA1(da2f77564e718276c66b0f02e72a97d7b3653c35) ) // 0004 ROM_LOAD16_WORD_SWAP( "mpr-18288.ic4", 0x0400000, 0x0200000, CRC(558c82ee) SHA1(e2ae4f2e81c7360eedd1b18e36d1f6ca6c015fee) ) // 9000 ROM_LOAD16_WORD_SWAP( "mpr-18287.ic3", 0x0800000, 0x0200000, CRC(bf8743d8) SHA1(8d0e0691ec062f1939db8f6b75edb92d34417f81) ) // 4900 ROM_LOAD16_WORD_SWAP( "mpr-18286.ic2", 0x0c00000, 0x0200000, CRC(3eb95e9a) SHA1(d565e5f353327e16f7ead2251fd9a503bf46e210) ) // 0490 ROM_LOAD16_WORD_SWAP( "mpr-18285.ic1", 0x1000000, 0x0200000, CRC(8390453c) SHA1(e7d3a6579d9805a71b954bb248a2da749e9d9d38) ) // 0049 ROM_LOAD16_WORD_SWAP( "mpr-18294.ic10",0x1400000, 0x0200000, CRC(341ebd4a) SHA1(9d9a1c09d81a50132edcc18a99266416683f4ff6) ) // 0004 ROM_LOAD16_WORD_SWAP( "mpr-18293.ic9", 0x1800000, 0x0200000, CRC(f76bc076) SHA1(f5a8f9bd26b2e8533a1fbf8da6938373df971749)) // 9000 ROM_LOAD16_WORD_SWAP( "mpr-18292.ic8", 0x1c00000, 0x0200000, CRC(59a713f9) SHA1(388b833fa6fb930f26c80674606505ec80668a16) ) // 4900 ROM_LOAD16_WORD_SWAP( "mpr-18291.ic7", 0x2000000, 0x0200000, CRC(b6c167bd) SHA1(4990bae50e8804b2e1048aa5c64b086e8427073f) ) // 0490 ROM_LOAD16_WORD_SWAP( "mpr-18290.ic6", 0x2400000, 0x0200000, CRC(11f7adb0) SHA1(a72f9892f93506456edc7ffc66224446a58ca38b) ) // 0049 ROM_END void coolridr_state::init_coolridr() { m_maincpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); m_subcpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); m_colbase = 0x7b20; // work around the hack when mapping the workram directly m_maincpu->sh2drc_add_fastram(0x06000000, 0x060fffff, 0, &m_workram_h[0]); m_maincpu->sh2drc_add_fastram(0x00000000, 0x001fffff, 1, &m_rom[0]); m_maincpu->sh2drc_add_fastram(0x20000000, 0x201fffff, 1, &m_rom[0]); } void coolridr_state::init_aquastge() { m_maincpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); m_subcpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); m_colbase = 0; } GAME( 1995, coolridr, 0, coolridr, coolridr, coolridr_state, init_coolridr, ROT0, "Sega", "Cool Riders", MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN ) // region is set in test mode, this set is for Japan, USA and Export (all regions) GAMEL( 1995, aquastge, 0, aquastge, aquastge, coolridr_state, init_aquastge, ROT0, "Sega", "Aqua Stage", MACHINE_NOT_WORKING, layout_aquastge)