| Previous | 15994 Revisions | Next |
| r8764 Thursday 12th August, 2010 at 10:00:41 UTC by MooglyGuy |
|---|
| Massive Super A'Can re-write using the pre-existing driver as a base: - Issue: Sprites are wrong. Harmony is looking into it. - Added sprite masking. - Added scanline-based tilemap rendering. - Began implementing sound CPU comms, currently disabled behind a #define. - Added scanline-based IRQ triggering, possibly still wrong. - Corrected off-by-one in sprite DMA. - Brought rendering entirely into the driver by eliminating drawgfx calls. |
| [src/mess/drivers] | supracan.c |
| r8763 | r8764 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | Skeleton driver file for Super A'Can console. | |
| 4 | 3 | |
| 5 | The system unit contains a reset button. | |
| 4 | Funtech Super A'Can | |
| 5 | ------------------- | |
| 6 | 6 | |
| 7 | Controllers: | |
| 8 | - 4 directional buttons | |
| 9 | - A, B, X, Y, buttons | |
| 10 | - Start, select buttons | |
| 11 | - L, R shoulder buttons | |
| 7 | Preliminary driver by Angelo Salese | |
| 8 | Improvements by Harmony | |
| 12 | 9 | |
| 13 | f00000 - bit 15 is probably vblank bit. | |
| 14 | 10 | |
| 15 | Known unemulated graphical effects: | |
| 16 | - The green blob of the A'Can logo should slide out from beneath the word | |
| 17 | "A'Can"; | |
| 18 | - Unemulated 1bpp ROZ mode, used by the Super A'Can BIOS logo; | |
| 19 | - Priorities; | |
| 20 | - Boom Zoo: missing window effect applied on sprites; | |
| 21 | - C.U.G.: gameplay backgrounds are broken (wrong tile bank); | |
| 22 | - C.U.G.: roz paging is wrong; | |
| 23 | - Sango Fighter: Missing rowscroll effect; | |
| 24 | - Sango Fighter: sprites have some bad gaps of black; | |
| 25 | - Sango Fighter: Missing black masking on the top-down edges of the screen on gameplay? | |
| 26 | - Sango Fighter: intro looks bogus, dunno what's supposed to draw... | |
| 27 | - Speedy Dragon: backgrounds are broken (wrong tile bank) | |
| 28 | - Super Taiwanese Baseball League: Missing window effect applied on a tilemap; | |
| 29 | - Super Taiwanese Baseball League: Unemulated paging mode; | |
| 30 | - Super Dragon Force: priority issues with the text; | |
| 31 | - Super Dragon Force: wrong ysize on character select screen; | |
| 32 | - The Son of Evil: has problems with irq mask | |
| 33 | - The Son of Evil: has many gfx artifacts | |
| 11 | ******************************************************************************* | |
| 34 | 12 | |
| 35 | baseball game debug trick: | |
| 36 | wpset e90020,1f,w | |
| 37 | do pc=5ac40 | |
| 38 | ... | |
| 39 | do pc=5acd4 | |
| 40 | wpclear | |
| 41 | bp 0269E4 | |
| 42 | [ff7be4] <- 0x269ec | |
| 43 | bpclear | |
| 13 | INFO: | |
| 44 | 14 | |
| 45 | ||
| 15 | The system unit contains a reset button. | |
| 46 | 16 | |
| 47 | There are 6 interrupt sources on the 6502 side, all of which use the IRQ line. | |
| 48 | The register at 0x411 is bitmapped to indicate what source(s) are active. | |
| 49 | In priority order from most to least important, they are: | |
| 17 | Controllers: | |
| 18 | - 4 directional buttons | |
| 19 | - A, B, X, Y, buttons | |
| 20 | - Start, select buttons | |
| 21 | - L, R shoulder buttons | |
| 50 | 22 | |
| 51 | 411 value How acked Notes | |
| 52 | 0x40 read reg 0x16 of sound chip likely timer. snd regs 0x16/0x17 are time constant, write 0 to reg 0x9f to start | |
| 53 | 0x04 read at 0x405 latch 1? 0xcd is magic value | |
| 54 | 0x08 read at 0x404 latch 2? 0xcd is magic value | |
| 55 | 0x10 read at 0x409 unknown, dispatched but not used in startup 6502 code | |
| 56 | 0x20 read at 0x40a possible periodic like vblank? | |
| 57 | 0x80 read reg 0x14 of sound chip depends on reg 0x14 of sound chip & 0x40: if not set writes 0x8f to reg 0x14, | |
| 58 | otherwise writes 0x4f to reg 0x14 and performs additional processing | |
| 23 | STATUS: | |
| 59 | 24 | |
| 25 | The driver is begging for a re-write or at least a split into video/supracan.c. It will happen eventually. | |
| 26 | ||
| 27 | Sound CPU comms and sound chip are completely unknown. | |
| 28 | ||
| 29 | There are 6 interrupt sources on the 6502 side, all of which use the IRQ line. | |
| 30 | The register at 0x411 is bitmapped to indicate what source(s) are active. | |
| 31 | In priority order from most to least important, they are: | |
| 32 | ||
| 33 | 411 value How acked Notes | |
| 34 | 0x40 read reg 0x16 of sound chip likely timer. snd regs 0x16/0x17 are time constant, write 0 to reg 0x9f to start | |
| 35 | 0x04 read at 0x405 latch 1? 0xcd is magic value | |
| 36 | 0x08 read at 0x404 latch 2? 0xcd is magic value | |
| 37 | 0x10 read at 0x409 unknown, dispatched but not used in startup 6502 code | |
| 38 | 0x20 read at 0x40a possible periodic like vblank? | |
| 39 | 0x80 read reg 0x14 of sound chip depends on reg 0x14 of sound chip & 0x40: if not set writes 0x8f to reg 0x14, | |
| 40 | otherwise writes 0x4f to reg 0x14 and performs additional processing | |
| 41 | ||
| 42 | Known unemulated graphical effects and issues: | |
| 43 | - All: Sprites are currently very broken for an unknown reason. | |
| 44 | - All: Sprite sizing is still imperfect. | |
| 45 | - All: Sprites need to be converted to use scanline rendering for proper clipping. | |
| 46 | - All: Improperly-emulated 1bpp ROZ mode, used by the Super A'Can BIOS logo. | |
| 47 | - All: Unimplemented ROZ scaling tables, used by the Super A'Can BIOS logo and Speedy Dragon intro, among others. | |
| 48 | - All: Priorities are largely unknown. | |
| 49 | - C.U.G.: Gameplay backgrounds are broken. | |
| 50 | - Sango Fighter: Possible missing masking on the upper edges of the screen during gameplay. | |
| 51 | - Speedy Dragon: Backgrounds are broken (wrong tile bank/region). | |
| 52 | - Super Taiwanese Baseball League: Does not boot for unknown reasons. | |
| 53 | - Super Taiwanese Baseball League: Missing window effect applied on tilemaps? | |
| 54 | - The Son of Evil: Does not boot for unknown reasons. | |
| 55 | - The Son of Evil: Many graphical issues. | |
| 56 | ||
| 57 | DEBUG TRICKS: | |
| 58 | ||
| 59 | baseball game debug trick: | |
| 60 | wpset e90020,1f,w | |
| 61 | do pc=5ac40 | |
| 62 | ... | |
| 63 | do pc=5acd4 | |
| 64 | wpclear | |
| 65 | bp 0269E4 | |
| 66 | [ff7be4] <- 0x269ec | |
| 67 | bpclear | |
| 68 | ||
| 60 | 69 | ***************************************************************************/ |
| 61 | 70 | |
| 62 | 71 | #include "emu.h" |
| r8763 | r8764 | |
| 65 | 74 | #include "devices/cartslot.h" |
| 66 | 75 | #include "debugger.h" |
| 67 | 76 | |
| 68 | #define D | |
| 77 | #define SOUNDCP | |
| 69 | 78 | |
| 79 | #define DRAW_DEBUG_ROZ (0) | |
| 80 | ||
| 81 | #define DRAW_DEBUG_UNK_SPRITE (0) | |
| 82 | ||
| 83 | #define DEBUG_PRIORITY (0) | |
| 84 | #define DEBUG_PRIORITY_INDEX (0) // 0-3 | |
| 85 | ||
| 86 | #define VERBOSE_LEVEL (0) | |
| 87 | ||
| 88 | #define ENABLE_VERBOSE_LOG (0) | |
| 89 | ||
| 70 | 90 | typedef struct _acan_dma_regs_t acan_dma_regs_t; |
| 71 | 91 | struct _acan_dma_regs_t |
| 72 | 92 | { |
| r8763 | r8764 | |
| 92 | 112 | public: |
| 93 | 113 | static driver_data_t *alloc(running_machine &machine) { return auto_alloc_clear(&machine, supracan_state(machine)); } |
| 94 | 114 | |
| 95 | supracan_state(running_machine &machine) | |
| 96 | : driver_data_t(machine) { } | |
| 115 | supracan_state(running_machine &machine) : driver_data_t(machine) | |
| 116 | { | |
| 117 | m6502_reset = 0; | |
| 118 | } | |
| 97 | 119 | |
| 98 | 120 | acan_dma_regs_t acan_dma_regs; |
| 99 | 121 | acan_sprdma_regs_t acan_sprdma_regs; |
| 100 | 122 | |
| 101 | 123 | UINT16 m6502_reset; |
| 102 | 124 | UINT8 *soundram; |
| 103 | UINT16 *soundram_16; | |
| 125 | UINT8 soundlatch; | |
| 126 | UINT8 soundcpu_irq_src; | |
| 127 | UINT8 sound_irq_enable_reg; | |
| 128 | UINT8 sound_irq_source_reg; | |
| 129 | UINT8 sound_cpu_68k_irq_reg; | |
| 130 | ||
| 104 | 131 | emu_timer *video_timer; |
| 132 | emu_timer *hbl_timer; | |
| 133 | emu_timer *line_on_timer; | |
| 134 | emu_timer *line_off_timer; | |
| 105 | 135 | UINT16 *vram; |
| 106 | UINT16 spr_limit; | |
| 107 | UINT16 spr_yline; | |
| 108 | UINT32 spr_base_addr; | |
| 109 | UINT8 spr_flags; | |
| 110 | UINT32 tilemap_base_addr[4]; | |
| 111 | int tilemap_scrollx[4],tilemap_scrolly[4]; | |
| 136 | UINT8 bg_color; | |
| 137 | ||
| 138 | bitmap_t *sprite_final_bitmap; | |
| 139 | UINT8 sprite_pri[1024*1024]; | |
| 140 | UINT16 sprite_count; | |
| 141 | UINT32 sprite_base_addr; | |
| 142 | UINT8 sprite_flags; | |
| 143 | ||
| 144 | bitmap_t *tilemap_bitmap[3]; | |
| 145 | bitmap_t *tilemap_final_bitmap[3]; | |
| 146 | UINT8 tilemap_pri[3][1024*1024]; | |
| 147 | UINT8 tilemap_final_pri[3][320*240]; | |
| 148 | UINT32 tilemap_base_addr[3]; | |
| 149 | int tilemap_scrollx[3]; | |
| 150 | int tilemap_scrolly[3]; | |
| 112 | 151 | UINT16 video_flags; |
| 113 | UINT16 tilemap_flags[4],tilemap_mode[4]; | |
| 152 | UINT16 tilemap_flags[3]; | |
| 153 | UINT16 tilemap_mode[3]; | |
| 114 | 154 | UINT16 irq_mask; |
| 155 | UINT16 hbl_mask; | |
| 115 | 156 | |
| 116 | 157 | bitmap_t *roz_bitmap; |
| 117 | 158 | bitmap_t *roz_final_bitmap; |
| 159 | UINT8 roz_pri[1024*1024]; | |
| 160 | UINT8 roz_final_pri[320*240]; | |
| 118 | 161 | UINT32 roz_base_addr; |
| 119 | 162 | UINT16 roz_mode; |
| 120 | 163 | UINT32 roz_scrollx; |
| r8763 | r8764 | |
| 132 | 175 | INT32 roz_cy; |
| 133 | 176 | |
| 134 | 177 | UINT16 video_regs[256]; |
| 178 | ||
| 179 | bool hack_68k_to_6502_access; | |
| 135 | 180 | }; |
| 136 | 181 | |
| 137 | static READ16_HANDLER( supracan_unk1_r ); | |
| 138 | static WRITE16_HANDLER( supracan_soundram_w ); | |
| 182 | static READ16_HANDLER( supracan_68k_soundram_r ); | |
| 183 | static WRITE16_HANDLER( supracan_68k_soundram_w ); | |
| 184 | static READ16_HANDLER( supracan_sound_r ); | |
| 139 | 185 | static WRITE16_HANDLER( supracan_sound_w ); |
| 140 | 186 | static READ16_HANDLER( supracan_video_r ); |
| 141 | 187 | static WRITE16_HANDLER( supracan_video_w ); |
| 142 | static WRITE16_HANDLER( supracan_char_w ); | |
| 143 | 188 | |
| 144 | #define VERBOSE_LEVEL (99) | |
| 145 | ||
| 146 | #define ENABLE_VERBOSE_LOG (1) | |
| 147 | ||
| 148 | 189 | #if ENABLE_VERBOSE_LOG |
| 149 | INLINE void verboselog(running_machine *machine, int n_level, const char *s_fmt, ...) | |
| 190 | INLINE void verboselog(const char *tag, running_machine *machine, int n_level, const char *s_fmt, ...) | |
| 150 | 191 | { |
| 151 | 192 | if( VERBOSE_LEVEL >= n_level ) |
| 152 | 193 | { |
| r8763 | r8764 | |
| 155 | 196 | va_start( v, s_fmt ); |
| 156 | 197 | vsprintf( buf, s_fmt, v ); |
| 157 | 198 | va_end( v ); |
| 158 | logerror( "%06x: %s", cpu_get_pc(machine->device( | |
| 199 | logerror( "%06x: %s: %s", cpu_get_pc(machine->device(t | |
| 159 | 200 | } |
| 160 | 201 | } |
| 202 | ||
| 161 | 203 | #else |
| 162 | #define verboselog(x,y,z,...) | |
| 204 | #define verboselog(w,x,y,z,...) | |
| 163 | 205 | #endif |
| 164 | 206 | |
| 165 | 207 | static VIDEO_START( supracan ) |
| 166 | 208 | { |
| 209 | // crash debug: printf("A"); fflush(stdout); | |
| 167 | 210 | supracan_state *state = machine->driver_data<supracan_state>(); |
| 168 | state->roz_bitmap = auto_bitmap_alloc(machine, 1024, 512, BITMAP_FORMAT_INDEXED16); | |
| 169 | state->roz_final_bitmap = auto_bitmap_alloc(machine, 1024, 512, BITMAP_FORMAT_INDEXED16); | |
| 211 | state->roz_bitmap = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16); | |
| 212 | state->roz_final_bitmap = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16); | |
| 213 | state->tilemap_bitmap[0] = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16); | |
| 214 | state->tilemap_bitmap[1] = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16); | |
| 215 | state->tilemap_bitmap[2] = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16); | |
| 216 | state->tilemap_final_bitmap[0] = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16); | |
| 217 | state->tilemap_final_bitmap[1] = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16); | |
| 218 | state->tilemap_final_bitmap[2] = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16); | |
| 219 | state->sprite_final_bitmap = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16); | |
| 170 | 220 | } |
| 171 | 221 | |
| 172 | static | |
| 222 | static UINT16 fetch_8bpp_tile_ | |
| 173 | 223 | { |
| 174 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 224 | // crash debug: printf("B"); fflush(stdout); | |
| 225 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 226 | UINT16 *supracan_vram = state->vram; | |
| 227 | ||
| 228 | if(xflip) x = 7 - x; | |
| 229 | if(yflip) y = 7 - y; | |
| 230 | ||
| 231 | UINT32 address = (tile * 8 * 8 + y * 8 + x) >> 1; | |
| 232 | UINT8 shift = (x & 1) ? 0 : 8; | |
| 233 | ||
| 234 | return (supracan_vram[address] >> shift) & 0x00ff; | |
| 235 | } | |
| 236 | ||
| 237 | static UINT16 fetch_4bpp_tile_pixel(running_machine *machine, int tile, int palette, bool xflip, bool yflip, int x, int y) | |
| 238 | { | |
| 239 | // crash debug: printf("C"); fflush(stdout); | |
| 240 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 241 | UINT16 *supracan_vram = state->vram; | |
| 242 | ||
| 243 | if(xflip) x = 7 - x; | |
| 244 | if(yflip) y = 7 - y; | |
| 245 | ||
| 246 | UINT32 address = (tile * 8 * 4 + y * 4 + (x >> 1)) >> 1; | |
| 247 | UINT8 shift = (3 - (x & 3)) * 4; | |
| 248 | ||
| 249 | return (palette << 4) | ((supracan_vram[address] >> shift) & 0x000f); | |
| 250 | } | |
| 251 | ||
| 252 | static UINT16 fetch_2bpp_tile_pixel(running_machine *machine, int tile, int palette, bool xflip, bool yflip, int x, int y) | |
| 253 | { | |
| 254 | // crash debug: printf("D"); fflush(stdout); | |
| 255 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 256 | UINT16 *supracan_vram = state->vram; | |
| 257 | ||
| 258 | if(xflip) x = 7 - x; | |
| 259 | if(yflip) y = 7 - y; | |
| 260 | ||
| 261 | UINT32 address = (tile * 8 * 2 + y * 2 + (x >> 2)) >> 1; | |
| 262 | UINT8 shift = (7 - (x & 7)) * 2; | |
| 263 | ||
| 264 | return (palette << 2) | ((supracan_vram[address] >> shift) & 0x0003); | |
| 265 | } | |
| 266 | ||
| 267 | static void draw_tile(running_machine *machine, UINT8* primap, bitmap_t *bitmap, const rectangle *cliprect, int tile, int palette, bool xflip, bool yflip, int x, int y, int priority, int depth, int mask) | |
| 268 | { | |
| 269 | // crash debug: printf("E"); fflush(stdout); | |
| 270 | for(int tiley = 0; tiley < 8; tiley++) | |
| 271 | { | |
| 272 | for(int tilex = 0; tilex < 8; tilex++) | |
| 273 | { | |
| 274 | UINT16 pixel = 0; | |
| 275 | switch(depth) | |
| 276 | { | |
| 277 | case 0: // 8bpp | |
| 278 | pixel = fetch_8bpp_tile_pixel(machine, tile, palette, xflip, yflip, tilex, tiley); | |
| 279 | break; | |
| 280 | case 1: // 4bpp | |
| 281 | pixel = fetch_4bpp_tile_pixel(machine, tile, palette, xflip, yflip, tilex, tiley); | |
| 282 | if((pixel & 0x0f) == 0) | |
| 283 | { | |
| 284 | pixel = 0; | |
| 285 | } | |
| 286 | break; | |
| 287 | case 2: // 2bpp | |
| 288 | pixel = fetch_2bpp_tile_pixel(machine, tile, palette, xflip, yflip, tilex, tiley); | |
| 289 | if((pixel & 0x03) == 0) | |
| 290 | { | |
| 291 | pixel = 0; | |
| 292 | } | |
| 293 | break; | |
| 294 | default: | |
| 295 | fatalerror("Unsupported bit depth for draw_tile\n"); | |
| 296 | break; | |
| 297 | } | |
| 298 | ||
| 299 | int total_x = x + tilex; | |
| 300 | int total_y = y + tiley; | |
| 301 | if((cliprect != NULL && total_x >= cliprect->min_x && total_y >= cliprect->min_y && total_x < cliprect->max_x && total_y < cliprect->max_y) || cliprect == NULL) | |
| 302 | { | |
| 303 | if(pixel) | |
| 304 | { | |
| 305 | switch(mask) | |
| 306 | { | |
| 307 | case 0: // Default | |
| 308 | *BITMAP_ADDR16(bitmap, total_y, total_x) = pixel; | |
| 309 | primap[total_y*1024 + total_x] = (UINT8)priority; | |
| 310 | break; | |
| 311 | case 1: // Mask against previous alpha | |
| 312 | if(*BITMAP_ADDR16(bitmap, total_y, total_x) & 0x8000) | |
| 313 | { | |
| 314 | *BITMAP_ADDR16(bitmap, total_y, total_x) = pixel | 0x8000; | |
| 315 | primap[total_y*1024 + total_x] = (UINT8)priority; | |
| 316 | } | |
| 317 | break; | |
| 318 | case 2: // Write to alpha | |
| 319 | *BITMAP_ADDR16(bitmap, total_y, total_x) |= 0x8000; | |
| 320 | break; | |
| 321 | case 3: // Clear mask | |
| 322 | *BITMAP_ADDR16(bitmap, total_y, total_x) &= 0x7fff; | |
| 323 | break; | |
| 324 | } | |
| 325 | } | |
| 326 | } | |
| 327 | } | |
| 328 | } | |
| 329 | } | |
| 330 | ||
| 331 | static void draw_tilemap_scanline(running_machine *machine, UINT16 *scanline, UINT8 *priline, int ypos, int layer) | |
| 332 | { | |
| 333 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 334 | ||
| 335 | if((!(state->video_flags & 0x80) && layer == 0) || | |
| 336 | (!(state->video_flags & 0x40) && layer == 1) || | |
| 337 | (!(state->video_flags & 0x20) && layer == 2)) | |
| 338 | { | |
| 339 | for(int x = 0; x < 320; x++) | |
| 340 | { | |
| 341 | priline[x] = 8; | |
| 342 | scanline[x] = 0; | |
| 343 | } | |
| 344 | return; | |
| 345 | } | |
| 346 | ||
| 347 | int width = 32; | |
| 348 | int height = 32; | |
| 349 | switch(state->tilemap_flags[layer] & 0x0f00) | |
| 350 | { | |
| 351 | case 0x600: | |
| 352 | width = 64; | |
| 353 | break; | |
| 354 | ||
| 355 | case 0xa00: | |
| 356 | width = 128; | |
| 357 | break; | |
| 358 | ||
| 359 | case 0xc00: | |
| 360 | width = 64; | |
| 361 | height = 64; | |
| 362 | break; | |
| 363 | ||
| 364 | default: | |
| 365 | //verboselog("maincpu", machine, 0, "Unsupported tilemap size: %04x\n", state->tilemap_flags[layer] & 0x0f00); | |
| 366 | break; | |
| 367 | } | |
| 368 | ||
| 369 | int scrollx = state->tilemap_scrollx[layer]; | |
| 370 | int scrolly = state->tilemap_scrolly[layer]; | |
| 371 | scrollx |= (scrollx & 0x800) ? 0xfffff000 : 0; | |
| 372 | scrolly |= (scrolly & 0x800) ? 0xfffff000 : 0; | |
| 373 | ||
| 374 | int gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12; | |
| 375 | ||
| 376 | int region = 1; | |
| 377 | UINT16 tile_bank = 0; | |
| 378 | UINT16 palette_bank = 0; | |
| 379 | switch(gfx_mode) | |
| 380 | { | |
| 381 | case 7: | |
| 382 | region = 2; | |
| 383 | tile_bank = 0x1c00; | |
| 384 | palette_bank = 0x00; | |
| 385 | break; | |
| 386 | ||
| 387 | case 4: | |
| 388 | region = 1; | |
| 389 | tile_bank = 0x800; | |
| 390 | palette_bank = 0x00; | |
| 391 | break; | |
| 392 | ||
| 393 | case 2: | |
| 394 | region = 1; | |
| 395 | tile_bank = 0x400; | |
| 396 | palette_bank = 0x00; | |
| 397 | break; | |
| 398 | ||
| 399 | case 0: | |
| 400 | region = 1; | |
| 401 | tile_bank = 0; | |
| 402 | palette_bank = 0x00; | |
| 403 | break; | |
| 404 | ||
| 405 | default: | |
| 406 | verboselog("maincpu", machine, 0, "Unsupported tilemap mode: %d\n", (state->tilemap_flags[layer] & 0x7000) >> 12); | |
| 407 | break; | |
| 408 | } | |
| 409 | ||
| 410 | int wrapped_x = scrollx; | |
| 411 | int wrapped_y = ypos + scrolly; | |
| 412 | ||
| 413 | if(state->tilemap_flags[layer] & 0x20) | |
| 414 | { | |
| 415 | while(wrapped_y >= height*8) wrapped_y -= height*8; | |
| 416 | while(wrapped_y < 0) wrapped_y += height*8; | |
| 417 | } | |
| 418 | else | |
| 419 | { | |
| 420 | if(wrapped_y < 0 || wrapped_y >= height*8) | |
| 421 | { | |
| 422 | for(int x = 0; x < 320; x++) | |
| 423 | { | |
| 424 | scanline[x] = 0; | |
| 425 | priline[x] = 8; | |
| 426 | } | |
| 427 | return; | |
| 428 | } | |
| 429 | } | |
| 430 | ||
| 431 | UINT16 *src = BITMAP_ADDR16(state->tilemap_bitmap[layer], wrapped_y, 0); | |
| 432 | UINT8 *srcpri = &state->tilemap_pri[layer][1024*wrapped_y]; | |
| 433 | ||
| 434 | if(state->tilemap_flags[layer] & 0x20) | |
| 435 | { | |
| 436 | while(wrapped_x >= width*8) wrapped_x -= width*8; | |
| 437 | while(wrapped_x < 0) wrapped_x += width*8; | |
| 438 | ||
| 439 | for(int x = 0; x < 320; x++) | |
| 440 | { | |
| 441 | scanline[x] = src[wrapped_x] ? src[wrapped_x] : scanline[x]; | |
| 442 | priline[x] = src[wrapped_x] ? srcpri[wrapped_x] : 8; | |
| 443 | wrapped_x++; | |
| 444 | while(wrapped_x >= width*8) wrapped_x -= width*8; | |
| 445 | } | |
| 446 | } | |
| 447 | else | |
| 448 | { | |
| 449 | for(int x = 0; x < 320; x++) | |
| 450 | { | |
| 451 | if(wrapped_x >= 0 && wrapped_x < width*8) | |
| 452 | { | |
| 453 | scanline[x] = src[wrapped_x] ? src[wrapped_x] : scanline[x]; | |
| 454 | priline[x] = src[wrapped_x] ? srcpri[wrapped_x] : 8; | |
| 455 | } | |
| 456 | else | |
| 457 | { | |
| 458 | scanline[x] = scanline[x]; | |
| 459 | priline[x] = 8; | |
| 460 | } | |
| 461 | wrapped_x++; | |
| 462 | } | |
| 463 | } | |
| 464 | } | |
| 465 | ||
| 466 | static void draw_tilemap(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int layer) | |
| 467 | { | |
| 468 | /*crash debug: printf("F"); fflush(stdout); */ | |
| 469 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 175 | 470 | UINT16 *supracan_vram = state->vram; |
| 176 | UINT32 count; | |
| 177 | int x,y; | |
| 178 | int scrollx,scrolly; | |
| 179 | int region; | |
| 180 | int gfx_mode; | |
| 181 | int xsize,ysize; | |
| 182 | UINT16 tile_bank,pal_bank; | |
| 183 | 471 | |
| 184 | count = (state->tilemap_base_addr[layer]); | |
| 472 | UINT32 count = (state->tilemap_base_addr[layer]); | |
| 185 | 473 | |
| 474 | int xsize = 32; | |
| 475 | int ysize = 32; | |
| 186 | 476 | switch(state->tilemap_flags[layer] & 0x0f00) |
| 187 | 477 | { |
| 188 | case 0x600: xsize = 64; ysize = 32; break; | |
| 189 | case 0xa00: xsize = 128; ysize = 32; break; | |
| 190 | case 0xc00: xsize = 64; ysize = 64; break; | |
| 191 | default: xsize = 32; ysize = 32; break; | |
| 478 | case 0x600: | |
| 479 | xsize = 64; | |
| 480 | ysize = 32; | |
| 481 | break; | |
| 482 | ||
| 483 | case 0xa00: | |
| 484 | xsize = 128; | |
| 485 | ysize = 32; | |
| 486 | break; | |
| 487 | ||
| 488 | case 0xc00: | |
| 489 | xsize = 64; | |
| 490 | ysize = 64; | |
| 491 | break; | |
| 492 | ||
| 493 | default: | |
| 494 | verboselog("maincpu", machine, 0, "Unsupported tilemap size for layer %d: %04x\n", layer, state->tilemap_flags[layer] & 0x0f00); | |
| 495 | break; | |
| 192 | 496 | } |
| 193 | 497 | |
| 194 | scrollx = state->tilemap_scrollx[layer]; | |
| 195 | scrolly = state->tilemap_scrolly[layer]; | |
| 498 | UINT8 priority = ((state->tilemap_flags[layer] >> 12) & 7) + 1; | |
| 499 | ||
| 500 | int scrollx = state->tilemap_scrollx[layer]; | |
| 501 | int scrolly = state->tilemap_scrolly[layer]; | |
| 196 | 502 | scrollx |= (scrollx & 0x800) ? 0xfffff000 : 0; |
| 197 | 503 | scrolly |= (scrolly & 0x800) ? 0xfffff000 : 0; |
| 198 | 504 | |
| 199 | gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12; | |
| 505 | int gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12; | |
| 200 | 506 | |
| 507 | int region = 1; | |
| 508 | UINT16 tile_bank = 0; | |
| 509 | UINT16 palette_bank = 0; | |
| 201 | 510 | switch(gfx_mode) |
| 202 | 511 | { |
| 203 | case 7: region = 2; tile_bank = 0x1c00; pal_bank = 0x00; break; | |
| 204 | case 4: region = 1; tile_bank = 0x800; pal_bank = 0x00; break; | |
| 205 | case 2: region = 1; tile_bank = 0x400; pal_bank = 0x00; break; | |
| 206 | case 0: region = 1; tile_bank = 0; pal_bank = 0x00; break; | |
| 207 | default: region = 1; tile_bank = 0; pal_bank = 0x00; break; | |
| 512 | case 7: | |
| 513 | region = 2; | |
| 514 | tile_bank = 0x1c00; | |
| 515 | palette_bank = 0x00; | |
| 516 | break; | |
| 517 | ||
| 518 | case 4: | |
| 519 | region = 1; | |
| 520 | tile_bank = 0x800; | |
| 521 | palette_bank = 0x00; | |
| 522 | break; | |
| 523 | ||
| 524 | case 2: | |
| 525 | region = 1; | |
| 526 | tile_bank = 0x400; | |
| 527 | palette_bank = 0x00; | |
| 528 | break; | |
| 529 | ||
| 530 | case 0: | |
| 531 | region = 1; | |
| 532 | tile_bank = 0; | |
| 533 | palette_bank = 0x00; | |
| 534 | break; | |
| 535 | ||
| 536 | default: | |
| 537 | verboselog("maincpu", machine, 0, "Unsupported tilemap mode: %d\n", (state->tilemap_flags[layer] & 0x7000) >> 12); | |
| 538 | break; | |
| 208 | 539 | } |
| 209 | 540 | |
| 210 | for (y=0;y<ysize;y++) | |
| 211 | { | |
| 212 | for (x=0;x<xsize;x++) | |
| 213 | { | |
| 214 | int tile, flipx, flipy, pal; | |
| 215 | tile = (supracan_vram[count] & 0x03ff) + tile_bank; | |
| 216 | flipx = (supracan_vram[count] & 0x0800) ? 1 : 0; | |
| 217 | flipy = (supracan_vram[count] & 0x0400) ? 1 : 0; | |
| 218 | pal = ((supracan_vram[count] & 0xf000) >> 12) + pal_bank; | |
| 541 | if(state->tilemap_flags[layer] & 0x20) | |
| 542 | { | |
| 543 | bitmap_fill(state->tilemap_bitmap[layer], NULL, 0); | |
| 219 | 544 | |
| 220 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx,(y*8)-scrolly,0); | |
| 221 | if(state->tilemap_flags[layer] & 0x20) //wrap-around enable | |
| 222 | { | |
| 223 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx+xsize*8,(y*8)-scrolly,0); | |
| 224 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx,(y*8)-scrolly+ysize*8,0); | |
| 225 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx+xsize*8,(y*8)-scrolly+ysize*8,0); | |
| 226 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx-xsize*8,(y*8)-scrolly,0); | |
| 227 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx,(y*8)-scrolly-ysize*8,0); | |
| 228 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx-xsize*8,(y*8)-scrolly-ysize*8,0); | |
| 229 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx+xsize*8,(y*8)-scrolly-ysize*8,0); | |
| 230 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx-xsize*8,(y*8)-scrolly+ysize*8,0); | |
| 231 | } | |
| 232 | count++; | |
| 233 | } | |
| 234 | } | |
| 545 | for(int y = 0; y < ysize; y++) | |
| 546 | { | |
| 547 | for(int x = 0; x < xsize; x++) | |
| 548 | { | |
| 549 | int tile = (supracan_vram[count] & 0x03ff) + tile_bank; | |
| 550 | int flipx = (supracan_vram[count] & 0x0800) ? 1 : 0; | |
| 551 | int flipy = (supracan_vram[count] & 0x0400) ? 1 : 0; | |
| 552 | int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank; | |
| 553 | ||
| 554 | draw_tile(machine, state->tilemap_pri[layer], bitmap, NULL, tile, palette, flipx, flipy, x*8, y*8, priority, region, 0); | |
| 555 | ||
| 556 | count++; | |
| 557 | } | |
| 558 | } | |
| 559 | } | |
| 560 | else | |
| 561 | { | |
| 562 | bitmap_fill(state->tilemap_bitmap[layer], NULL, 0); | |
| 563 | ||
| 564 | for(int y = 0; y < ysize; y++) | |
| 565 | { | |
| 566 | for(int x = 0; x < xsize; x++) | |
| 567 | { | |
| 568 | int tile = (supracan_vram[count] & 0x03ff) + tile_bank; | |
| 569 | int flipx = (supracan_vram[count] & 0x0800) ? 1 : 0; | |
| 570 | int flipy = (supracan_vram[count] & 0x0400) ? 1 : 0; | |
| 571 | int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank; | |
| 572 | ||
| 573 | draw_tile(machine, state->tilemap_pri[layer], bitmap, cliprect, tile, palette, flipx, flipy, x*8/*-scrollx*/, y*8/*-scrolly*/, priority, region, 0); | |
| 574 | ||
| 575 | count++; | |
| 576 | } | |
| 577 | } | |
| 578 | } | |
| 235 | 579 | } |
| 236 | 580 | |
| 237 | /* probably similar to the regular tilemap layers with extra features */ | |
| 238 | /* 0x0402 Boom Zoo */ | |
| 239 | /* 0x2603 / 0x6623 Super Dragon Force */ | |
| 240 | /* 0x4020 BIOS logo */ | |
| 241 | /* */ | |
| 242 | static void draw_roz_bitmap_scanline(running_machine *machine, bitmap_t *roz_bitmap, UINT16 *scanline, int ypos, INT32 X, INT32 Y, INT32 PA, INT32 PB, INT32 PC, INT32 PD, INT32 *currentx, INT32 *currenty, int changed) | |
| 581 | static void draw_roz_bitmap_scanline(running_machine *machine, bitmap_t *roz_bitmap, UINT16 *scanline, UINT8 *priline, int ypos, INT32 X, INT32 Y, INT32 PA, INT32 PB, INT32 PC, INT32 PD, INT32 *currentx, INT32 *currenty, int changed) | |
| 243 | 582 | { |
| 583 | // crash debug: printf("G"); fflush(stdout); | |
| 244 | 584 | supracan_state *state = machine->driver_data<supracan_state>(); |
| 245 | 585 | |
| 246 | 586 | INT32 sx = 0; |
| r8763 | r8764 | |
| 254 | 594 | default: sx = 32*8; sy = 32*8; break; |
| 255 | 595 | } |
| 256 | 596 | |
| 597 | if((state->roz_mode & 3) == 0) | |
| 598 | { | |
| 599 | sx = 64; | |
| 600 | sy = 32; | |
| 601 | } | |
| 602 | ||
| 257 | 603 | if (X & 0x08000000) X |= 0xf0000000; |
| 258 | 604 | if (Y & 0x08000000) Y |= 0xf0000000; |
| 259 | 605 | if (PA & 0x8000) PA |= 0xffff0000; |
| r8763 | r8764 | |
| 308 | 654 | while(pixy >= sy) pixy -= sy; |
| 309 | 655 | |
| 310 | 656 | scanline[x] = *BITMAP_ADDR16(roz_bitmap, pixy, pixx); |
| 657 | priline[x] = state->roz_pri[pixy*1024 + pixx]; | |
| 311 | 658 | } |
| 312 | 659 | else |
| 313 | 660 | { |
| 314 | 661 | if(pixx >= 0 && pixy >= 0 && pixx < sx && pixy < sy) |
| 315 | 662 | { |
| 316 | 663 | scanline[x] = *BITMAP_ADDR16(roz_bitmap, pixy, pixx); |
| 664 | priline[x] = state->roz_pri[pixy*1024 + pixx]; | |
| 317 | 665 | } |
| 318 | 666 | } |
| 319 | 667 | |
| r8763 | r8764 | |
| 327 | 675 | state->roz_changed = 0; |
| 328 | 676 | } |
| 329 | 677 | |
| 678 | static void draw_roz_bitmap(running_machine *machine, const rectangle *cliprect) | |
| 679 | { | |
| 680 | // crash debug: printf("H"); fflush(stdout); | |
| 681 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 682 | UINT16 *supracan_vram = state->vram; | |
| 683 | UINT32 addr = state->roz_tile_bank << 1; | |
| 684 | ||
| 685 | const int ysize = 32; | |
| 686 | bitmap_t *roz_bitmap = state->roz_bitmap; | |
| 687 | for (int y = 0; y < ysize; y++) | |
| 688 | { | |
| 689 | UINT32 plane_word_msw[2]; | |
| 690 | UINT32 plane_word_lsw[2]; | |
| 691 | plane_word_msw[0] = ((UINT32)supracan_vram[addr + (y * 8) + 0] << 16) | supracan_vram[addr + (y * 8) + 1]; | |
| 692 | plane_word_lsw[0] = ((UINT32)supracan_vram[addr + (y * 8) + 2] << 16) | supracan_vram[addr + (y * 8) + 3]; | |
| 693 | plane_word_msw[1] = ((UINT32)supracan_vram[addr + (y * 8) + 4] << 16) | supracan_vram[addr + (y * 8) + 5]; | |
| 694 | plane_word_lsw[1] = ((UINT32)supracan_vram[addr + (y * 8) + 6] << 16) | supracan_vram[addr + (y * 8) + 7]; | |
| 695 | for (int x = 0; x < 32; x++) | |
| 696 | { | |
| 697 | UINT8 bit = BIT(plane_word_msw[0], 31-x);// | BIT(plane_word_msw[1], 31-x); | |
| 698 | if(bit) | |
| 699 | { | |
| 700 | *BITMAP_ADDR16(roz_bitmap, y, x) = bit; | |
| 701 | state->roz_pri[y*1024 + x] = (state->roz_mode >> 12) & 7; | |
| 702 | } | |
| 703 | } | |
| 704 | for (int x = 0; x < 32; x++) | |
| 705 | { | |
| 706 | UINT8 bit = BIT(plane_word_lsw[0], 31-x);// | BIT(plane_word_lsw[1], 31-x) | |
| 707 | if(bit) | |
| 708 | { | |
| 709 | *BITMAP_ADDR16(roz_bitmap, y, x+32) = bit; | |
| 710 | state->roz_pri[y*1024 + x + 32] = (state->roz_mode >> 12) & 7; | |
| 711 | } | |
| 712 | } | |
| 713 | } | |
| 714 | } | |
| 715 | ||
| 330 | 716 | static void draw_roz(running_machine *machine, const rectangle *cliprect) |
| 331 | 717 | { |
| 718 | // crash debug: printf("I"); fflush(stdout); | |
| 332 | 719 | supracan_state *state = machine->driver_data<supracan_state>(); |
| 333 | 720 | UINT16 *supracan_vram = state->vram; |
| 334 | 721 | UINT32 roz_base_addr = state->roz_base_addr; |
| 335 | 722 | int region = 0; |
| 336 | 723 | UINT16 tile_bank = 0; |
| 337 | // int gfx_mode; | |
| 338 | 724 | |
| 339 | 725 | switch(state->roz_mode & 3) //FIXME: fix gfx bpp order |
| 340 | 726 | { |
| 341 | case 0: return;//region = 2; tile_bank = (state->roz_tile_bank & 0xf000) >> 3; break; | |
| 342 | case 1: region = 2; break; | |
| 343 | case 2: region = 1; tile_bank = (state->roz_tile_bank & 0xf000) >> 3; break; | |
| 344 | case 3: region = 0; break; | |
| 727 | case 0: | |
| 728 | return draw_roz_bitmap(machine, cliprect); | |
| 729 | ||
| 730 | case 1: | |
| 731 | region = 2; | |
| 732 | tile_bank = (state->roz_tile_bank & 0xf000) >> 3; | |
| 733 | break; | |
| 734 | ||
| 735 | case 2: | |
| 736 | region = 1; | |
| 737 | tile_bank = (state->roz_tile_bank & 0xf000) >> 3; | |
| 738 | break; | |
| 739 | ||
| 740 | case 3: | |
| 741 | region = 0; | |
| 742 | tile_bank = (state->roz_tile_bank & 0xf000) >> 3; | |
| 743 | break; | |
| 345 | 744 | } |
| 346 | 745 | |
| 347 | 746 | int xsize = 32; |
| 348 | 747 | int ysize = 32; |
| 349 | 748 | switch(state->roz_mode & 0x0f00) |
| 350 | 749 | { |
| 351 | case 0x600: xsize = 64; ysize = 32; break; | |
| 352 | case 0xa00: xsize = 128; ysize = 32; break; | |
| 353 | case 0xc00: xsize = 64; ysize = 64; break; | |
| 354 | default: xsize = 32; ysize = 32; break; | |
| 750 | case 0x600: | |
| 751 | xsize = 64; | |
| 752 | ysize = 32; | |
| 753 | break; | |
| 754 | ||
| 755 | case 0xa00: | |
| 756 | xsize = 128; | |
| 757 | ysize = 32; | |
| 758 | break; | |
| 759 | ||
| 760 | case 0xc00: | |
| 761 | xsize = 64; | |
| 762 | ysize = 64; | |
| 763 | break; | |
| 764 | ||
| 765 | default: | |
| 766 | xsize = 32; | |
| 767 | ysize = 32; | |
| 768 | break; | |
| 355 | 769 | } |
| 356 | 770 | |
| 357 | UINT32 count = (0); | |
| 771 | UINT32 count = 0; | |
| 772 | UINT8 priority = ((state->roz_mode >> 12) & 7) + 1; | |
| 358 | 773 | |
| 359 | 774 | bitmap_t *roz_bitmap = state->roz_bitmap; |
| 360 | 775 | for (int y = 0; y < ysize; y++) |
| 361 | 776 | { |
| 362 | 777 | for (int x = 0; x < xsize; x++) |
| 363 | 778 | { |
| 364 | int tile, flipx, flipy, pal; | |
| 365 | tile = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x03ff) | tile_bank; | |
| 366 | flipx = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0800) ? 1 : 0; | |
| 367 | flipy = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0400) ? 1 : 0; | |
| 368 | pal = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0xf000) >> 12; | |
| 779 | int tile = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x03ff) | tile_bank; | |
| 780 | bool flipx = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0800) ? true : false; | |
| 781 | bool flipy = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0400) ? true : false; | |
| 782 | int palette = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0xf000) >> 12; | |
| 369 | 783 | |
| 370 | draw | |
| 784 | draw | |
| 371 | 785 | |
| 372 | 786 | count++; |
| 373 | 787 | } |
| r8763 | r8764 | |
| 376 | 790 | |
| 377 | 791 | static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect) |
| 378 | 792 | { |
| 379 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 793 | // crash debug: printf("J"); fflush(stdout); | |
| 794 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 380 | 795 | UINT16 *supracan_vram = state->vram; |
| 381 | int x, y; | |
| 382 | int xtile, ytile; | |
| 383 | int xsize, ysize; | |
| 384 | int bank; | |
| 385 | int spr_offs; | |
| 386 | int col; | |
| 387 | int i; | |
| 388 | int spr_base; | |
| 389 | int hflip,vflip; | |
| 390 | int region; | |
| 391 | //UINT8 *sprdata = (UINT8*)(&supracan_vram[0x1d000/2]); | |
| 392 | 796 | |
| 393 | spr_base = state->spr_base_addr; | |
| 394 | region = (state->spr_flags & 1) ? 0 : 1; //8bpp : 4bpp | |
| 797 | #if !(DRAW_DEBUG_UNK_SPRITE) | |
| 798 | int region = (state->sprite_flags & 1) ? 0 : 1; //8bpp : 4bpp | |
| 799 | #endif | |
| 395 | 800 | |
| 396 | /* | |
| 397 | [0] | |
| 398 | ---h hhh- ---- ---- Y size | |
| 399 | ---- ---y yyyy yyyy Y offset | |
| 400 | [1] | |
| 401 | bbbb ---- ---- ---- sprite offset bank | |
| 402 | ---- d--- ---- ---- horizontal direction | |
| 403 | ---- ---- ---- -www X size | |
| 404 | [2] | |
| 405 | zzz- ---- ---- ---- X shrinking | |
| 406 | ---- ---x xxxx xxxx X offset | |
| 407 | [3] | |
| 408 | oooo oooo oooo oooo sprite pointer | |
| 409 | */ | |
| 801 | // [0] | |
| 802 | // ---h hhh- ---- ---- Y size | |
| 803 | // ---- ---y yyyy yyyy Y offset | |
| 804 | // [1] | |
| 805 | // bbbb ---- ---- ---- sprite offset bank | |
| 806 | // ---- h--- ---- ---- horizontal flip | |
| 807 | // ---- -v-- ---- ---- vertical flip | |
| 808 | // ---- --mm ---- ---- masking | |
| 809 | // ---- ---- ---- -www X size | |
| 810 | // [2] | |
| 811 | // zzz- uuu- ---- ---- unknown | |
| 812 | // ---- ---x xxxx xxxx X offset | |
| 813 | // [3] | |
| 814 | // oooo oooo oooo oooo sprite pointer | |
| 410 | 815 | |
| 411 | for(i=spr_base/2;i<(spr_base+(state->spr_limit*8))/2;i+=4) | |
| 816 | UINT32 start_word = (state->sprite_base_addr >> 1) + 0 * 4; | |
| 817 | UINT32 end_word = start_word + state->sprite_count * 4; | |
| 818 | for(int i = start_word; i < end_word; i += 4) | |
| 412 | 819 | { |
| 413 | x = supracan_vram[i+2] & 0x01ff; | |
| 414 | y = supracan_vram[i+0] & 0x01ff; | |
| 415 | spr_offs = supracan_vram[i+3] << 2; | |
| 416 | bank = (supracan_vram[i+1] & 0xf000) >> 12; | |
| 417 | hflip = (supracan_vram[i+1] & 0x0800) ? 1 : 0; | |
| 418 | vflip = (supracan_vram[i+1] & 0x0400) ? 1 : 0; | |
| 820 | int x = supracan_vram[i+2] & 0x01ff; | |
| 821 | int y = supracan_vram[i+0] & 0x01ff; | |
| 822 | int sprite_offset = supracan_vram[i+3] << 2; | |
| 823 | int bank = (supracan_vram[i+1] & 0xf000) >> 12; | |
| 824 | int mask = (supracan_vram[i+1] & 0x0300) >> 8; | |
| 825 | bool hflip = (supracan_vram[i+1] & 0x0800) ? true : false; | |
| 826 | bool vflip = (supracan_vram[i+1] & 0x0400) ? true : false; | |
| 827 | #if !(DRAW_DEBUG_UNK_SPRITE) | |
| 828 | UINT8 priority = ((supracan_vram[i+0] >> 12) & 7) + 1; | |
| 829 | #endif | |
| 830 | while(x > cliprect->max_x) | |
| 831 | { | |
| 832 | x -= 0x200; | |
| 833 | } | |
| 419 | 834 | |
| 420 | if(x > cliprect->max_x) | |
| 421 | x-=0x200; | |
| 422 | if(y > cliprect->max_y) | |
| 423 | y-=0x200; | |
| 835 | while(y > cliprect->max_y) | |
| 836 | { | |
| 837 | y -= 0x200; | |
| 838 | } | |
| 424 | 839 | |
| 425 | 840 | if(supracan_vram[i+3] != 0) |
| 426 | 841 | { |
| 427 | xsize = 1 << (supracan_vram[i+1] & 7); | |
| 428 | ysize = ((supracan_vram[i+0] & 0x1e00) >> 9)+1; | |
| 842 | int xsize = 1 << (supracan_vram[i+1] & 7); | |
| 843 | int ysize = ((supracan_vram[i+0] & 0x1e00) >> 9)+1; | |
| 844 | //int ysize = (((supracan_vram[i+0] & 0x0600) >> 9) + 1) * (1 << ((supracan_vram[i+0] & 0x1800) >> 11)); | |
| 845 | //if(supracan_vram[i+2] & 0x2000) ysize = xsize; | |
| 846 | //int ysize = ((supracan_vram[i+2] & 0x1e00) >> 9)+1; | |
| 429 | 847 | |
| 430 | 848 | if(vflip) |
| 431 | 849 | { |
| 432 | for(ytile = (ysize - 1); ytile >= 0; ytile--) | |
| 850 | for(int ytile = (ysize - 1); ytile >= 0; ytile--) | |
| 433 | 851 | { |
| 434 | 852 | if(hflip) |
| 435 | 853 | { |
| 436 | for(xtile = (xsize - 1); xtile >= 0; xtile--) | |
| 854 | for(int xtile = (xsize - 1); xtile >= 0; xtile--) | |
| 437 | 855 | { |
| 438 | ||
| 856 | UINT16 data = supracan_vram[sprite_offset/2+ytile*xsize+xtile]; | |
| 439 | 857 | int tile = (bank * 0x200) + (data & 0x03ff); |
| 440 | int xflip = (data & 0x0800) ? 0 : 1; | |
| 441 | int yflip = (data & 0x0400) ? 0 : 1; | |
| 442 | col = (data & 0xf000) >> 12; | |
| 443 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,col,xflip,yflip,x+((xsize - 1) - xtile)*8,y+((ysize - 1) - ytile)*8,0); | |
| 858 | bool xflip = (data & 0x0800) ? false : true; | |
| 859 | bool yflip = (data & 0x0400) ? false : true; | |
| 860 | int palette = (data & 0xf000) >> 12; | |
| 861 | ||
| 862 | #if !(DRAW_DEBUG_UNK_SPRITE) | |
| 863 | draw_tile(machine, state->sprite_pri, bitmap, cliprect, tile, palette, xflip, yflip, x+xtile*8, y+ytile*8, priority, region, mask); | |
| 864 | #else | |
| 865 | tile = 0; | |
| 866 | xflip = false; | |
| 867 | yflip = false; | |
| 868 | palette = 0; | |
| 869 | for(int ypix = 0; ypix < 8; ypix++) | |
| 870 | { | |
| 871 | for(int xpix = 0; xpix < 8; xpix++) | |
| 872 | { | |
| 873 | if((y + ytile*8 + ypix) < 240 && | |
| 874 | (y + ytile*8 + ypix) >= 0 && | |
| 875 | (x + xtile*8 + xpix) < 320 && | |
| 876 | (x + xtile*8 + xpix) >= 0) | |
| 877 | { | |
| 878 | *BITMAP_ADDR16(bitmap, y + ytile*8 + ypix, x + xtile*8 + xpix) = supracan_vram[i+2] >> 9; | |
| 879 | } | |
| 880 | } | |
| 881 | } | |
| 882 | #endif | |
| 444 | 883 | } |
| 445 | 884 | } |
| 446 | 885 | else |
| 447 | 886 | { |
| 448 | for(xtile = 0; xtile < xsize; xtile++) | |
| 887 | for(int xtile = 0; xtile < xsize; xtile++) | |
| 449 | 888 | { |
| 450 | ||
| 889 | UINT16 data = supracan_vram[sprite_offset/2+ytile*xsize+xtile]; | |
| 451 | 890 | int tile = (bank * 0x200) + (data & 0x03ff); |
| 452 | int xflip = (data & 0x0800) ? 1 : 0; | |
| 453 | int yflip = (data & 0x0400) ? 0 : 1; | |
| 454 | col = (data & 0xf000) >> 12; | |
| 455 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,col,xflip,yflip,x+xtile*8,y+((ysize - 1) - ytile)*8,0); | |
| 891 | bool xflip = (data & 0x0800) ? true : false; | |
| 892 | bool yflip = (data & 0x0400) ? false : true; | |
| 893 | int palette = (data & 0xf000) >> 12; | |
| 894 | ||
| 895 | #if !(DRAW_DEBUG_UNK_SPRITE) | |
| 896 | draw_tile(machine, state->sprite_pri, bitmap, cliprect, tile, palette, xflip, yflip, x+xtile*8, y+((ysize - 1) - ytile)*8, priority, region, mask); | |
| 897 | #else | |
| 898 | tile = 0; | |
| 899 | xflip = false; | |
| 900 | yflip = false; | |
| 901 | palette = 0; | |
| 902 | for(int ypix = 0; ypix < 8; ypix++) | |
| 903 | { | |
| 904 | for(int xpix = 0; xpix < 8; xpix++) | |
| 905 | { | |
| 906 | if((y + ytile*8 + ypix) < 240 && | |
| 907 | (y + ytile*8 + ypix) >= 0 && | |
| 908 | (x + xtile*8 + xpix) < 320 && | |
| 909 | (x + xtile*8 + xpix) >= 0) | |
| 910 | { | |
| 911 | *BITMAP_ADDR16(bitmap, y + ytile*8 + ypix, x + xtile*8 + xpix) = supracan_vram[i+2] >> 9; | |
| 912 | } | |
| 913 | } | |
| 914 | } | |
| 915 | #endif | |
| 456 | 916 | } |
| 457 | 917 | } |
| 458 | 918 | } |
| 459 | 919 | } |
| 460 | 920 | else |
| 461 | 921 | { |
| 462 | for(ytile = 0; ytile < ysize; ytile++) | |
| 922 | for(int ytile = 0; ytile < ysize; ytile++) | |
| 463 | 923 | { |
| 464 | 924 | if(hflip) |
| 465 | 925 | { |
| 466 | for(xtile = (xsize - 1); xtile >= 0; xtile--) | |
| 926 | for(int xtile = (xsize - 1); xtile >= 0; xtile--) | |
| 467 | 927 | { |
| 468 | ||
| 928 | UINT16 data = supracan_vram[sprite_offset/2+ytile*xsize+xtile]; | |
| 469 | 929 | int tile = (bank * 0x200) + (data & 0x03ff); |
| 470 | int xflip = (data & 0x0800) ? 0 : 1; | |
| 471 | int yflip = (data & 0x0400) ? 1 : 0; | |
| 472 | col = (data & 0xf000) >> 12; | |
| 473 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,col,xflip,yflip,x+((xsize - 1) - xtile)*8,y+ytile*8,0); | |
| 930 | bool xflip = (data & 0x0800) ? false : true; | |
| 931 | bool yflip = (data & 0x0400) ? true : false; | |
| 932 | int palette = (data & 0xf000) >> 12; | |
| 933 | ||
| 934 | #if !(DRAW_DEBUG_UNK_SPRITE) | |
| 935 | draw_tile(machine, state->sprite_pri, bitmap, cliprect, tile, palette, xflip, yflip, x+((xsize - 1) - xtile)*8, y+ytile*8, priority, region, mask); | |
| 936 | #else | |
| 937 | tile = 0; | |
| 938 | xflip = false; | |
| 939 | yflip = false; | |
| 940 | palette = 0; | |
| 941 | for(int ypix = 0; ypix < 8; ypix++) | |
| 942 | { | |
| 943 | for(int xpix = 0; xpix < 8; xpix++) | |
| 944 | { | |
| 945 | if((y + ytile*8 + ypix) < 240 && | |
| 946 | (y + ytile*8 + ypix) >= 0 && | |
| 947 | (x + xtile*8 + xpix) < 320 && | |
| 948 | (x + xtile*8 + xpix) >= 0) | |
| 949 | { | |
| 950 | *BITMAP_ADDR16(bitmap, y + ytile*8 + ypix, x + xtile*8 + xpix) = supracan_vram[i+2] >> 9; | |
| 951 | } | |
| 952 | } | |
| 953 | } | |
| 954 | #endif | |
| 474 | 955 | } |
| 475 | 956 | } |
| 476 | 957 | else |
| 477 | 958 | { |
| 478 | for(xtile = 0; xtile < xsize; xtile++) | |
| 959 | for(int xtile = 0; xtile < xsize; xtile++) | |
| 479 | 960 | { |
| 480 | ||
| 961 | UINT16 data = supracan_vram[sprite_offset/2+ytile*xsize+xtile]; | |
| 481 | 962 | int tile = (bank * 0x200) + (data & 0x03ff); |
| 482 | int xflip = (data & 0x0800) ? 1 : 0; | |
| 483 | int yflip = (data & 0x0400) ? 1 : 0; | |
| 484 | col = (data & 0xf000) >> 12; | |
| 485 | drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,col,xflip,yflip,x+xtile*8,y+ytile*8,0); | |
| 963 | bool xflip = (data & 0x0800) ? true : false; | |
| 964 | bool yflip = (data & 0x0400) ? true : false; | |
| 965 | int palette = (data & 0xf000) >> 12; | |
| 966 | ||
| 967 | #if !(DRAW_DEBUG_UNK_SPRITE) | |
| 968 | draw_tile(machine, state->sprite_pri, bitmap, cliprect, tile, palette, xflip, yflip, x + xtile * 8, y + ytile * 8, priority, region, mask); | |
| 969 | #else | |
| 970 | tile = 0; | |
| 971 | xflip = false; | |
| 972 | yflip = false; | |
| 973 | palette = 0; | |
| 974 | for(int ypix = 0; ypix < 8; ypix++) | |
| 975 | { | |
| 976 | for(int xpix = 0; xpix < 8; xpix++) | |
| 977 | { | |
| 978 | if((y + ytile*8 + ypix) < 240 && | |
| 979 | (y + ytile*8 + ypix) >= 0 && | |
| 980 | (x + xtile*8 + xpix) < 320 && | |
| 981 | (x + xtile*8 + xpix) >= 0) | |
| 982 | { | |
| 983 | *BITMAP_ADDR16(bitmap, y + ytile*8 + ypix, x + xtile*8 + xpix) = supracan_vram[i+2] >> 9; | |
| 984 | } | |
| 985 | } | |
| 986 | } | |
| 987 | #endif | |
| 486 | 988 | } |
| 487 | 989 | } |
| 488 | 990 | } |
| r8763 | r8764 | |
| 505 | 1007 | INT32 temp = supracan_vram[state->roz_unk_base1 + y*2] << 16; |
| 506 | 1008 | temp |= supracan_vram[state->roz_unk_base1 + y*2 + 1]; |
| 507 | 1009 | x = ((float)temp / 65536.0f) * 128.0f; |
| 508 | if(x > -160 && x < 160) | |
| 509 | { | |
| 510 | *BITMAP_ADDR16(bitmap, y, (int)x + 160) = 2; | |
| 511 | } | |
| 512 | ||
| 513 | 1010 | temp = supracan_vram[state->roz_unk_base2 + y*2] << 16; |
| 514 | 1011 | temp |= supracan_vram[state->roz_unk_base2 + y*2 + 1]; |
| 515 | x = ((float)temp / 65536.0f) * 128.0f; | |
| 516 | if(x > -160 && x < 160) | |
| 1012 | float y = ((float)temp / 65536.0f) * 128.0f; | |
| 1013 | if(x >= -160 && x < 160 && y >= -112 && y < 112) | |
| 517 | 1014 | { |
| 518 | *BITMAP_ADDR16(bitmap, y, (int)x + 160) = | |
| 1015 | *BITMAP_ADDR16(bitmap, (int)y + 112, (int)x + 160) = 2; | |
| 519 | 1016 | } |
| 520 | 1017 | } |
| 521 | 1018 | } |
| r8763 | r8764 | |
| 523 | 1020 | |
| 524 | 1021 | static VIDEO_UPDATE( supracan ) |
| 525 | 1022 | { |
| 526 | supracan_state *state = screen->machine->driver_data<supracan_state>(); | |
| 1023 | // crash debug: printf("K"); fflush(stdout); | |
| 1024 | supracan_state *state = (supracan_state *)screen->machine->driver_data<supracan_state>(); | |
| 527 | 1025 | |
| 528 | ||
| 1026 | bitmap_fill(bitmap, cliprect, state->bg_color); | |
| 529 | 1027 | |
| 530 | #if 0 | |
| 531 | { | |
| 532 | count = 0x4400/2; | |
| 1028 | bitmap_fill(state->sprite_final_bitmap, cliprect, 0); | |
| 1029 | memset(state->sprite_pri, 8, 1024*1024 * sizeof(UINT8)); | |
| 533 | 1030 | |
| 534 | for (y=0;y<64;y++) | |
| 535 | { | |
| 536 | for (x = 0; x < 64; x += 16) | |
| 537 | { | |
| 538 | static UINT16 dot_data; | |
| 1031 | // VIDEO FLAGS ROZ MODE TILEMAP FLAGS | |
| 1032 | // | |
| 1033 | // Bit Bit Bit | |
| 1034 | // 15-9: Unknown 15-13: Priority? 15-13: Priority? | |
| 1035 | // 8: X ht. (256/320) 12: Unknown 12: Unknown | |
| 1036 | // 7: Tilemap 0 enable 11-8: Dims 11-8: Dims | |
| 1037 | // 6: Tilemap 1 enable 7-6: Unknown 7-6: Unknown | |
| 1038 | // 5: Tilemap 2 enable? 5: Wrap 5: Wrap | |
| 1039 | // 3: Sprite enable 4-2: Unknown 4-2: Unknown | |
| 1040 | // 2: ROZ enable 1-0: Bit Depth 1-0: Bit Depth | |
| 1041 | // 1-0: Unknown | |
| 539 | 1042 | |
| 540 | dot_data = supracan_vram[count] ^ 0xffff; | |
| 1043 | // Video Flags ROZ Mode Tilemap 0 Tilemap 1 Tilemap 2 VF Unk0 | |
| 1044 | // A'Can logo: 120e: 0001 0010 0000 1110 4020: 0100 0000 0010 0000 4620 ---- ---- 0x09 | |
| 1045 | // Boomzoo Intro: 9a82: 1001 1010 1000 0010 0402: 0000 0100 0000 0010 6400 6400 4400 0x4d | |
| 1046 | // Boomzoo Title: 9acc: 1001 1010 1100 1100 0402: 0000 0100 0000 0010 6400 6400 4400 0x4d | |
| 1047 | // C.U.G. Intro: 11c8: 0001 0001 1100 1000 0402: 0000 0100 0000 0010 2400 4400 6400 0x08 | |
| 1048 | // C.U.G. Title: 11cc: 0001 0001 1100 1100 0602: 0000 0110 0000 0010 2600 4600 ---- 0x08 | |
| 1049 | // Speedy Dragon Logo: 0388: 0000 0011 1000 1000 4020: 0100 0000 0010 0000 6c20 6c20 2600 0x01 | |
| 1050 | // Speedy Dragon Title: 038c: 0000 0011 1000 1100 2603: 0010 0110 0000 0011 6c20 2c20 2600 0x01 | |
| 1051 | // Sango Fighter Intro: 03c8: 0000 0011 1100 1000 ----: ---- ---- ---- ---- 6c20 4620 ---- 0x01 | |
| 1052 | // Sango Fighter Game: 03ce: 0000 0011 1100 1110 0622: 0000 0110 0010 0010 2620 4620 ---- 0x01 | |
| 541 | 1053 | |
| 542 | *BITMAP_ADDR16(bitmap, y, 128+x+ 0) = ((dot_data >> 15) & 0x0001) + 0x20; | |
| 543 | *BITMAP_ADDR16(bitmap, y, 128+x+ 1) = ((dot_data >> 14) & 0x0001) + 0x20; | |
| 544 | *BITMAP_ADDR16(bitmap, y, 128+x+ 2) = ((dot_data >> 13) & 0x0001) + 0x20; | |
| 545 | *BITMAP_ADDR16(bitmap, y, 128+x+ 3) = ((dot_data >> 12) & 0x0001) + 0x20; | |
| 546 | *BITMAP_ADDR16(bitmap, y, 128+x+ 4) = ((dot_data >> 11) & 0x0001) + 0x20; | |
| 547 | *BITMAP_ADDR16(bitmap, y, 128+x+ 5) = ((dot_data >> 10) & 0x0001) + 0x20; | |
| 548 | *BITMAP_ADDR16(bitmap, y, 128+x+ 6) = ((dot_data >> 9) & 0x0001) + 0x20; | |
| 549 | *BITMAP_ADDR16(bitmap, y, 128+x+ 7) = ((dot_data >> 8) & 0x0001) + 0x20; | |
| 550 | *BITMAP_ADDR16(bitmap, y, 128+x+ 8) = ((dot_data >> 7) & 0x0001) + 0x20; | |
| 551 | *BITMAP_ADDR16(bitmap, y, 128+x+ 9) = ((dot_data >> 6) & 0x0001) + 0x20; | |
| 552 | *BITMAP_ADDR16(bitmap, y, 128+x+10) = ((dot_data >> 5) & 0x0001) + 0x20; | |
| 553 | *BITMAP_ADDR16(bitmap, y, 128+x+11) = ((dot_data >> 4) & 0x0001) + 0x20; | |
| 554 | *BITMAP_ADDR16(bitmap, y, 128+x+12) = ((dot_data >> 3) & 0x0001) + 0x20; | |
| 555 | *BITMAP_ADDR16(bitmap, y, 128+x+13) = ((dot_data >> 2) & 0x0001) + 0x20; | |
| 556 | *BITMAP_ADDR16(bitmap, y, 128+x+14) = ((dot_data >> 1) & 0x0001) + 0x20; | |
| 557 | *BITMAP_ADDR16(bitmap, y, 128+x+15) = ((dot_data >> 0) & 0x0001) + 0x20; | |
| 558 | count++; | |
| 559 | } | |
| 560 | } | |
| 561 | } | |
| 562 | #endif | |
| 1054 | if(state->video_flags & 0x08) | |
| 1055 | { | |
| 1056 | draw_sprites(screen->machine, state->sprite_final_bitmap, cliprect); | |
| 1057 | } | |
| 563 | 1058 | |
| 564 | if(state->video_flags & 0x20) //guess, not tested | |
| 565 | draw_tilemap(screen->machine,bitmap,cliprect,2); | |
| 1059 | for(int y = 0; y < 240; y++) | |
| 1060 | { | |
| 1061 | for(int x = 0; x < 320; x++) | |
| 1062 | { | |
| 566 | 1063 | |
| 567 | int pri_order[3] = { 0, 0, 0 }; | |
| 568 | int pri_index[3] = { 0, 1, 2 }; | |
| 1064 | #if !(DEBUG_PRIORITY) | |
| 1065 | /* Harmony 7/27: THIS CODE IS KNOWN TO BE COMPLETELY WRONG. DO NOT USE IT AS-IS IN A STANDALONE EMULATOR. */ | |
| 1066 | int pri_order[3] = { 0, 0, 0 }; | |
| 1067 | bitmap_t *bitmaps[3] = { state->tilemap_final_bitmap[0], state->tilemap_final_bitmap[1], state->tilemap_final_bitmap[2] }; | |
| 569 | 1068 | |
| 570 | pri_order[0] = state->tilemap_flags[0] >> 13; | |
| 571 | pri_order[1] = state->tilemap_flags[1] >> 13; | |
| 572 | pri_order[2] = state->roz_mode >> 13; | |
| 1069 | pri_order[0] = state->tilemap_final_pri[0][y*320 + x]; | |
| 1070 | pri_order[1] = state->tilemap_final_pri[1][y*320 + x]; | |
| 1071 | pri_order[2] = state->tilemap_final_pri[2][y*320 + x]; | |
| 573 | 1072 | |
| 574 | // Evil bubble sort, but who cares, it's 3 entries long... | |
| 575 | for(int i1 = 0; i1 < 3; i1++) | |
| 576 | { | |
| 577 | for(int i2 = i1; i2 < 3; i2++) | |
| 578 | { | |
| 579 | if(pri_order[i2] > pri_order[i1]) | |
| 1073 | int current_priority = 8; | |
| 1074 | for(int index = 0; index < 3; index++) | |
| 580 | 1075 | { |
| 581 | int temp = pri_order[i1]; | |
| 582 | pri_order[i1] = pri_order[i2]; | |
| 583 | pri_order[i2] = temp; | |
| 1076 | UINT16 pixel = *BITMAP_ADDR16(bitmaps[index], y, x) & 0x7fff; | |
| 1077 | if(pixel) | |
| 1078 | { | |
| 1079 | if(pri_order[index] < current_priority ) | |
| 1080 | { | |
| 1081 | *BITMAP_ADDR16(bitmap, y, x) = pixel; | |
| 1082 | current_priority = pri_order[index]; | |
| 1083 | } | |
| 1084 | } | |
| 1085 | } | |
| 584 | 1086 | |
| 585 | temp = pri_index[i1]; | |
| 586 | pri_index[i1] = pri_index[i2]; | |
| 587 | pri_index[i2] = temp; | |
| 1087 | UINT16 pixel = *BITMAP_ADDR16(state->roz_final_bitmap, y, x) & 0x7fff; | |
| 1088 | if(pixel) | |
| 1089 | { | |
| 1090 | *BITMAP_ADDR16(bitmap, y, x) = pixel; | |
| 588 | 1091 | } |
| 589 | } | |
| 590 | } | |
| 591 | 1092 | |
| 592 | for(int index = 0; index < 3; index++) | |
| 593 | { | |
| 594 | switch(pri_index[index]) | |
| 595 | { | |
| 596 | case 0: | |
| 597 | if(state->video_flags & 0x80) | |
| 598 | { | |
| 599 | draw_tilemap(screen->machine,bitmap,cliprect, 0); | |
| 600 | } | |
| 601 | break; | |
| 602 | case 1: | |
| 603 | if(state->video_flags & 0x40) | |
| 604 | { | |
| 605 | draw_tilemap(screen->machine,bitmap,cliprect, 1); | |
| 606 | } | |
| 607 | break; | |
| 608 | case 2: | |
| 609 | copybitmap_trans(bitmap,state->roz_final_bitmap,0,0,0,0,cliprect,0); | |
| 610 | break; | |
| 1093 | pixel = *BITMAP_ADDR16(state->sprite_final_bitmap, y, x) & 0x7fff; | |
| 1094 | if(pixel) | |
| 1095 | { | |
| 1096 | *BITMAP_ADDR16(bitmap, y, x) = pixel; | |
| 1097 | } | |
| 1098 | #else | |
| 1099 | switch(0) | |
| 1100 | { | |
| 1101 | case 0: | |
| 1102 | *BITMAP_ADDR16(bitmap, y, x) = state->tilemap_pri[0][1024*y + x] + 2; | |
| 1103 | break; | |
| 1104 | case 1: | |
| 1105 | *BITMAP_ADDR16(bitmap, y, x) = state->tilemap_pri[1][1024*y + x] + 2; | |
| 1106 | break; | |
| 1107 | case 2: | |
| 1108 | *BITMAP_ADDR16(bitmap, y, x) = state->sprite_pri[1024*y + x] + 2; | |
| 1109 | break; | |
| 1110 | case 3: | |
| 1111 | *BITMAP_ADDR16(bitmap, y, x) = state->roz_pri[1024*y + x] + 2; | |
| 1112 | break; | |
| 1113 | } | |
| 1114 | #endif | |
| 611 | 1115 | } |
| 612 | 1116 | } |
| 613 | 1117 | |
| 614 | if(state->video_flags & 8) | |
| 615 | draw_sprites(screen->machine,bitmap,cliprect); | |
| 616 | ||
| 617 | 1118 | #if DRAW_DEBUG_ROZ |
| 618 | 1119 | draw_debug_roz(screen->machine,bitmap); |
| 619 | 1120 | #endif |
| r8763 | r8764 | |
| 624 | 1125 | |
| 625 | 1126 | static WRITE16_HANDLER( supracan_dma_w ) |
| 626 | 1127 | { |
| 627 | supracan_state *state = space->machine->driver_data<supracan_state>(); | |
| 1128 | // crash debug: printf("L"); fflush(stdout); | |
| 1129 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 628 | 1130 | acan_dma_regs_t *acan_dma_regs = &state->acan_dma_regs; |
| 629 | int i; | |
| 630 | int ch; | |
| 1131 | int ch = (offset < 0x10/2) ? 0 : 1; | |
| 631 | 1132 | |
| 632 | ch = (offset < 0x10/2) ? 0 : 1; | |
| 633 | ||
| 634 | 1133 | switch(offset) |
| 635 | 1134 | { |
| 636 | 1135 | case 0x00/2: // Source address MSW |
| 637 | 1136 | case 0x10/2: |
| 1137 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: source msw %d: %04x\n", ch, data); | |
| 638 | 1138 | acan_dma_regs->source[ch] &= 0x0000ffff; |
| 639 | 1139 | acan_dma_regs->source[ch] |= data << 16; |
| 640 | 1140 | break; |
| 641 | 1141 | case 0x02/2: // Source address LSW |
| 642 | 1142 | case 0x12/2: |
| 1143 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: source lsw %d: %04x\n", ch, data); | |
| 643 | 1144 | acan_dma_regs->source[ch] &= 0xffff0000; |
| 644 | 1145 | acan_dma_regs->source[ch] |= data; |
| 645 | 1146 | break; |
| 646 | 1147 | case 0x04/2: // Destination address MSW |
| 647 | 1148 | case 0x14/2: |
| 1149 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: dest msw %d: %04x\n", ch, data); | |
| 648 | 1150 | acan_dma_regs->dest[ch] &= 0x0000ffff; |
| 649 | 1151 | acan_dma_regs->dest[ch] |= data << 16; |
| 650 | 1152 | break; |
| 651 | 1153 | case 0x06/2: // Destination address LSW |
| 652 | 1154 | case 0x16/2: |
| 1155 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: dest lsw %d: %04x\n", ch, data); | |
| 653 | 1156 | acan_dma_regs->dest[ch] &= 0xffff0000; |
| 654 | 1157 | acan_dma_regs->dest[ch] |= data; |
| 655 | 1158 | break; |
| 656 | 1159 | case 0x08/2: // Byte count |
| 657 | 1160 | case 0x18/2: |
| 1161 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: count %d: %04x\n", ch, data); | |
| 658 | 1162 | acan_dma_regs->count[ch] = data; |
| 659 | 1163 | break; |
| 660 | 1164 | case 0x0a/2: // Control |
| 661 | 1165 | case 0x1a/2: |
| 662 | //if(acan_dma_regs.dest != 0xf00200) | |
| 663 | //printf("%08x %08x %02x %04x\n",acan_dma_regs->source[ch],acan_dma_regs->dest[ch],acan_dma_regs->count[ch] + 1,data); | |
| 1166 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: control %d: %04x\n", ch, data); | |
| 664 | 1167 | if(data & 0x8800) |
| 665 | 1168 | { |
| 666 | //if(data != 0x9800 && data != 0x8800) | |
| 667 | //{ | |
| 668 | // fatalerror("%04x",data); | |
| 669 | //} | |
| 670 | 1169 | // if(data & 0x2000) |
| 671 | 1170 | // acan_dma_regs->source-=2; |
| 672 | //verboselog(space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1, data); | |
| 1171 | //verboselog("maincpu", space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1, data); | |
| 673 | 1172 | |
| 674 | for(i = 0; i <= acan_dma_regs->count[ch]; i++) | |
| 1173 | for(int i = 0; i <= acan_dma_regs->count[ch]; i++) | |
| 675 | 1174 | { |
| 676 | 1175 | if(data & 0x1000) |
| 677 | 1176 | { |
| r8763 | r8764 | |
| 692 | 1191 | } |
| 693 | 1192 | else if(data != 0x0000) // fake DMA, used by C.U.G. |
| 694 | 1193 | { |
| 695 | verboselog(space->machine, 0, "supracan_dma_w: Unknown DMA kickoff value of %04x (other regs %08x, %08x, %d)\n", data, acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1); | |
| 1194 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: Unknown DMA kickoff value of %04x (other regs %08x, %08x, %d)\n", data, acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1); | |
| 696 | 1195 | fatalerror("supracan_dma_w: Unknown DMA kickoff value of %04x (other regs %08x, %08x, %d)",data, acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1); |
| 697 | 1196 | } |
| 698 | 1197 | break; |
| 1198 | default: | |
| 1199 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: Unknown register: %08x = %04x & %04x\n", 0xe90020 + (offset << 1), data, mem_mask); | |
| 1200 | break; | |
| 699 | 1201 | } |
| 700 | 1202 | } |
| 701 | 1203 | |
| r8763 | r8764 | |
| 703 | 1205 | AM_RANGE( 0x000000, 0x3fffff ) AM_ROM AM_REGION( "cart", 0 ) |
| 704 | 1206 | AM_RANGE( 0xe80200, 0xe80201 ) AM_READ_PORT("P1") |
| 705 | 1207 | AM_RANGE( 0xe80202, 0xe80203 ) AM_READ_PORT("P2") |
| 706 | // AM_RANGE( 0xe80204, 0xe80205 ) AM_READ( supracan_unk1_r ) //or'ed with player 2 inputs, why? | |
| 707 | 1208 | AM_RANGE( 0xe80208, 0xe80209 ) AM_READ_PORT("P3") |
| 708 | 1209 | AM_RANGE( 0xe8020c, 0xe8020d ) AM_READ_PORT("P4") |
| 709 | AM_RANGE( 0xe80300, 0xe80301 ) AM_READ( supracan_unk1_r ) | |
| 710 | AM_RANGE( 0xe81000, 0xe8ffff ) AM_RAM_WRITE( supracan_soundram_w ) AM_BASE_MEMBER(supracan_state,soundram_16) | |
| 711 | AM_RANGE( 0xe90000, 0xe9001f ) AM_WRITE( supracan_sound_w ) | |
| 1210 | AM_RANGE( 0xe80000, 0xe8ffff ) AM_READWRITE( supracan_68k_soundram_r, supracan_68k_soundram_w ) | |
| 1211 | AM_RANGE( 0xe90000, 0xe9001f ) AM_READWRITE( supracan_sound_r, supracan_sound_w ) | |
| 712 | 1212 | AM_RANGE( 0xe90020, 0xe9003f ) AM_WRITE( supracan_dma_w ) |
| 713 | 1213 | AM_RANGE( 0xf00000, 0xf001ff ) AM_READWRITE( supracan_video_r, supracan_video_w ) |
| 714 | AM_RANGE( 0xf00200, 0xf003ff ) AM_RAM_WRITE(paletteram16_xBBBBBGGGGGRRRRR_word_w) AM_BASE_GENERIC(paletteram) | |
| 715 | AM_RANGE( 0xf40000, 0xf5ffff ) AM_RAM_WRITE(supracan_char_w) AM_BASE_MEMBER(supracan_state,vram) /* Unknown, some data gets copied here during boot */ | |
| 716 | // AM_RANGE( 0xf44000, 0xf441ff ) AM_RAM AM_BASE_MEMBER(supracan_state,rozpal) /* clut data for the ROZ? */ | |
| 717 | // AM_RANGE( 0xf44600, 0xf44fff ) AM_RAM /* Unknown, stuff gets written here. Zoom table?? */ | |
| 718 | AM_RANGE( 0xfc0000, 0xfcffff ) AM_MIRROR(0x30000) AM_RAM /* System work ram */ | |
| 1214 | AM_RANGE( 0xf00200, 0xf003ff ) AM_RAM_WRITE(paletteram16_xBBBBBGGGGGRRRRR_word_w) AM_BASE_GENERIC(paletteram) | |
| 1215 | AM_RANGE( 0xf40000, 0xf5ffff ) AM_RAM AM_BASE_MEMBER(supracan_state,vram) | |
| 1216 | AM_RANGE( 0xfc0000, 0xfdffff ) AM_MIRROR(0x30000) AM_RAM /* System work ram */ | |
| 719 | 1217 | ADDRESS_MAP_END |
| 720 | 1218 | |
| 1219 | static READ8_HANDLER( supracan_6502_soundmem_r ) | |
| 1220 | { | |
| 1221 | // crash debug: printf("M"); fflush(stdout); | |
| 1222 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 1223 | UINT8 data = state->soundram[offset]; | |
| 721 | 1224 | |
| 722 | static ADDRESS_MAP_START( supracan_sound_mem, ADDRESS_SPACE_PROGRAM, 8 ) | |
| 723 | AM_RANGE( 0x0000, 0x03ff ) AM_RAM | |
| 724 | AM_RANGE( 0x0411, 0x0411 ) AM_READ(soundlatch_r) | |
| 725 | AM_RANGE( 0x0420, 0x0420 ) AM_READNOP //AM_READ(status) | |
| 726 | AM_RANGE( 0x0420, 0x0420 ) AM_WRITENOP //AM_WRITE(data) | |
| 727 | AM_RANGE( 0x0422, 0x0422 ) AM_WRITENOP //AM_WRITE(address) | |
| 728 | AM_RANGE( 0x1000, 0xffff ) AM_RAM AM_BASE_MEMBER(supracan_state,soundram ) | |
| 729 | ADDRESS_MAP_END | |
| 1225 | switch(offset) | |
| 1226 | { | |
| 1227 | #if SOUNDCPU_BOOT_HACK | |
| 1228 | case 0x300: // HACK to make games think the sound CPU is always reporting 'OK'. | |
| 1229 | return 0xff; | |
| 1230 | #endif | |
| 730 | 1231 | |
| 731 | static WRITE16_HANDLER( supracan_char_w ) | |
| 732 | { | |
| 733 | supracan_state *state = space->machine->driver_data<supracan_state>(); | |
| 734 | UINT16 *supracan_vram = state->vram; | |
| 1232 | case 0x410: // Sound IRQ enable | |
| 1233 | data = state->sound_irq_enable_reg; | |
| 1234 | if(!space->debugger_access) verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 0, "supracan_soundreg_r: IRQ enable: %04x\n", data); | |
| 1235 | if(!space->debugger_access) | |
| 1236 | { | |
| 1237 | if(state->sound_irq_enable_reg & state->sound_irq_source_reg) | |
| 1238 | { | |
| 1239 | cpu_set_input_line(space->machine->device("soundcpu"), 0, ASSERT_LINE); | |
| 1240 | } | |
| 1241 | else | |
| 1242 | { | |
| 1243 | cpu_set_input_line(space->machine->device("soundcpu"), 0, CLEAR_LINE); | |
| 1244 | } | |
| 1245 | } | |
| 1246 | break; | |
| 1247 | case 0x411: // Sound IRQ source | |
| 1248 | data = state->sound_irq_source_reg; | |
| 1249 | state->sound_irq_source_reg = 0; | |
| 1250 | if(!space->debugger_access) verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 3, "supracan_soundreg_r: IRQ source: %04x\n", data); | |
| 1251 | if(!space->debugger_access) | |
| 1252 | { | |
| 1253 | cpu_set_input_line(space->machine->device("soundcpu"), 0, CLEAR_LINE); | |
| 1254 | } | |
| 1255 | break; | |
| 1256 | case 0x420: | |
| 1257 | if(!space->debugger_access) verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 3, "supracan_soundreg_r: Sound hardware status? (not yet implemented): %02x\n", 0); | |
| 1258 | break; | |
| 1259 | case 0x422: | |
| 1260 | if(!space->debugger_access) verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 3, "supracan_soundreg_r: Sound hardware data? (not yet implemented): %02x\n", 0); | |
| 1261 | break; | |
| 1262 | case 0x404: | |
| 1263 | case 0x405: | |
| 1264 | case 0x409: | |
| 1265 | case 0x414: | |
| 1266 | case 0x416: | |
| 1267 | // Intentional fall-through | |
| 1268 | default: | |
| 1269 | if(offset >= 0x300 && offset < 0x500) | |
| 1270 | { | |
| 1271 | if(!space->debugger_access) verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 0, "supracan_soundreg_r: Unknown register %04x\n", offset); | |
| 1272 | } | |
| 1273 | break; | |
| 1274 | } | |
| 735 | 1275 | |
| 736 | COMBINE_DATA(&supracan_vram[offset]); | |
| 1276 | return data; | |
| 1277 | } | |
| 737 | 1278 | |
| 738 | { | |
| 739 | UINT8 *gfx = memory_region(space->machine, "ram_gfx"); | |
| 1279 | static WRITE8_HANDLER( supracan_6502_soundmem_w ) | |
| 1280 | { | |
| 1281 | // crash debug: printf("N"); fflush(stdout); | |
| 1282 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 740 | 1283 | |
| 741 | gfx[offset*2+0] = (supracan_vram[offset] & 0xff00) >> 8; | |
| 742 | gfx[offset*2+1] = (supracan_vram[offset] & 0x00ff) >> 0; | |
| 743 | ||
| 744 | gfx_element_mark_dirty(space->machine->gfx[0], offset/32); | |
| 745 | gfx_element_mark_dirty(space->machine->gfx[1], offset/16); | |
| 746 | gfx_element_mark_dirty(space->machine->gfx[2], offset/8); | |
| 747 | } | |
| 1284 | switch(offset) | |
| 1285 | { | |
| 1286 | case 0x407: | |
| 1287 | if(state->sound_cpu_68k_irq_reg &~ data) | |
| 1288 | { | |
| 1289 | verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 0, "supracan_soundreg_w: sound_cpu_68k_irq_reg: %04x: Triggering M68k IRQ\n", data); | |
| 1290 | cpu_set_input_line(space->machine->device("maincpu"), 7, HOLD_LINE); | |
| 1291 | } | |
| 1292 | else | |
| 1293 | { | |
| 1294 | verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 0, "supracan_soundreg_w: sound_cpu_68k_irq_reg: %04x\n", data); | |
| 1295 | } | |
| 1296 | state->sound_cpu_68k_irq_reg = data; | |
| 1297 | break; | |
| 1298 | case 0x410: | |
| 1299 | state->sound_irq_enable_reg = data; | |
| 1300 | verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 0, "supracan_soundreg_w: IRQ enable: %02x\n", data); | |
| 1301 | break; | |
| 1302 | case 0x420: | |
| 1303 | verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 3, "supracan_soundreg_w: Sound hardware reg data? (not yet implemented): %02x\n", data); | |
| 1304 | break; | |
| 1305 | case 0x422: | |
| 1306 | verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 3, "supracan_soundreg_w: Sound hardware reg addr? (not yet implemented): %02x\n", data); | |
| 1307 | break; | |
| 1308 | default: | |
| 1309 | if(offset >= 0x300 && offset < 0x500) | |
| 1310 | { | |
| 1311 | verboselog(state->hack_68k_to_6502_access ? "maincpu" : "soundcpu", space->machine, 0, "supracan_soundreg_w: Unknown register %04x = %02x\n", offset, data); | |
| 1312 | } | |
| 1313 | state->soundram[offset] = data; | |
| 1314 | break; | |
| 1315 | } | |
| 748 | 1316 | } |
| 749 | 1317 | |
| 1318 | static ADDRESS_MAP_START( supracan_sound_mem, ADDRESS_SPACE_PROGRAM, 8 ) | |
| 1319 | AM_RANGE( 0x0000, 0xffff ) AM_READWRITE(supracan_6502_soundmem_r, supracan_6502_soundmem_w) AM_BASE_MEMBER(supracan_state, soundram) | |
| 1320 | ADDRESS_MAP_END | |
| 1321 | ||
| 750 | 1322 | static INPUT_PORTS_START( supracan ) |
| 751 | 1323 | PORT_START("P1") |
| 752 | 1324 | PORT_DIPNAME( 0x01, 0x00, "SYSTEM" ) |
| r8763 | r8764 | |
| 879 | 1451 | } |
| 880 | 1452 | |
| 881 | 1453 | |
| 882 | static WRITE16_HANDLER( supracan_soundram_w ) | |
| 1454 | static WRITE16_HANDLER( supracan_68k_soundram_w ) | |
| 883 | 1455 | { |
| 884 | supracan_state *state = space->machine->driver_data<supracan_state>(); | |
| 1456 | // crash debug: printf("P"); fflush(stdout); | |
| 1457 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 885 | 1458 | |
| 886 | state->soundram_16[offset] = data; | |
| 1459 | state->soundram[offset*2 + 1] = data & 0xff; | |
| 1460 | state->soundram[offset*2 + 0] = data >> 8; | |
| 887 | 1461 | |
| 888 | state->soundram[offset*2 + 1] = data & 0xff; | |
| 889 | state->soundram[offset*2 + 0] = data >> 8; | |
| 1462 | if(offset*2 < 0x500 && offset*2 >= 0x300) | |
| 1463 | { | |
| 1464 | if(mem_mask & 0xff00) | |
| 1465 | { | |
| 1466 | state->hack_68k_to_6502_access = true; | |
| 1467 | supracan_6502_soundmem_w(space, offset*2, data >> 8); | |
| 1468 | state->hack_68k_to_6502_access = false; | |
| 1469 | } | |
| 1470 | if(mem_mask & 0x00ff) | |
| 1471 | { | |
| 1472 | state->hack_68k_to_6502_access = true; | |
| 1473 | supracan_6502_soundmem_w(space, offset*2 + 1, data & 0xff); | |
| 1474 | state->hack_68k_to_6502_access = false; | |
| 1475 | } | |
| 1476 | } | |
| 890 | 1477 | } |
| 891 | 1478 | |
| 1479 | static READ16_HANDLER( supracan_68k_soundram_r ) | |
| 1480 | { | |
| 1481 | // crash debug: printf("Q"); fflush(stdout); | |
| 1482 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 892 | 1483 | |
| 893 | static READ16_HANDLER( supracan_unk1_r ) | |
| 1484 | UINT16 val = state->soundram[offset*2 + 0] << 8; | |
| 1485 | val |= state->soundram[offset*2 + 1]; | |
| 1486 | ||
| 1487 | if(offset*2 >= 0x300 && offset*2 < 0x500) | |
| 1488 | { | |
| 1489 | val = 0; | |
| 1490 | if(mem_mask & 0xff00) | |
| 1491 | { | |
| 1492 | state->hack_68k_to_6502_access = true; | |
| 1493 | val |= supracan_6502_soundmem_r(space, offset*2) << 8; | |
| 1494 | state->hack_68k_to_6502_access = false; | |
| 1495 | } | |
| 1496 | if(mem_mask & 0x00ff) | |
| 1497 | { | |
| 1498 | state->hack_68k_to_6502_access = true; | |
| 1499 | val |= supracan_6502_soundmem_r(space, offset*2 + 1); | |
| 1500 | state->hack_68k_to_6502_access = false; | |
| 1501 | } | |
| 1502 | } | |
| 1503 | ||
| 1504 | return val; | |
| 1505 | } | |
| 1506 | ||
| 1507 | static READ16_HANDLER( supracan_sound_r ) | |
| 894 | 1508 | { |
| 895 | /* No idea what hardware this is connected to. */ | |
| 896 | return 0xffff; | |
| 1509 | // crash debug: printf("R"); fflush(stdout); | |
| 1510 | //supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 1511 | UINT16 data = 0; | |
| 1512 | ||
| 1513 | switch( offset ) | |
| 1514 | { | |
| 1515 | default: | |
| 1516 | verboselog("maincpu", space->machine, 0, "supracan_sound_r: Unknown register: (%08x) & %04x\n", 0xe90000 + (offset << 1), mem_mask); | |
| 1517 | break; | |
| 1518 | } | |
| 1519 | ||
| 1520 | return data; | |
| 897 | 1521 | } |
| 898 | 1522 | |
| 899 | ||
| 900 | 1523 | static WRITE16_HANDLER( supracan_sound_w ) |
| 901 | 1524 | { |
| 902 | supracan_state *state = space->machine->driver_data<supracan_state>(); | |
| 1525 | // crash debug: printf("S"); fflush(stdout); | |
| 1526 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 903 | 1527 | |
| 904 | 1528 | switch ( offset ) |
| 905 | 1529 | { |
| 906 | case 0x000a/2: | |
| 907 | //soundlatch_w(space, 0, (data & 0xff00) >> 8); | |
| 908 | //cputag_set_input_line(space->machine, "soundcpu", 0, HOLD_LINE); | |
| 909 | break; | |
| 910 | 1530 | case 0x001c/2: /* Sound cpu control. Bit 0 tied to sound cpu RESET line */ |
| 911 | if | |
| 1531 | if | |
| 912 | 1532 | { |
| 913 | if | |
| 1533 | if | |
| 914 | 1534 | { |
| 915 | 1535 | /* Reset and enable the sound cpu */ |
| 916 | //cputag_set_input_line(space->machine, "soundcpu", INPUT_LINE_HALT, CLEAR_LINE); | |
| 917 | //space->machine->device("soundcpu")->reset(); | |
| 1536 | #if !(SOUNDCPU_BOOT_HACK) | |
| 1537 | cputag_set_input_line(space->machine, "soundcpu", INPUT_LINE_HALT, CLEAR_LINE); | |
| 1538 | devtag_get_device(space->machine, "soundcpu")->reset(); | |
| 1539 | #endif | |
| 918 | 1540 | } |
| 1541 | state->m6502_reset = data & 0x01; | |
| 919 | 1542 | } |
| 920 | 1543 | else |
| 921 | 1544 | { |
| 922 | 1545 | /* Halt the sound cpu */ |
| 923 | 1546 | cputag_set_input_line(space->machine, "soundcpu", INPUT_LINE_HALT, ASSERT_LINE); |
| 924 | 1547 | } |
| 925 | ||
| 1548 | verboselog("maincpu", space->machin | |
| 926 | 1549 | break; |
| 927 | 1550 | default: |
| 928 | ||
| 1551 | verboselog("maincpu", space->machine, 0, "supracan_sound_w: U | |
| 929 | 1552 | break; |
| 930 | 1553 | } |
| 931 | 1554 | } |
| r8763 | r8764 | |
| 933 | 1556 | |
| 934 | 1557 | static READ16_HANDLER( supracan_video_r ) |
| 935 | 1558 | { |
| 936 | supracan_state *state = space->machine->driver_data<supracan_state>(); | |
| 1559 | // crash debug: printf("T"); fflush(stdout); | |
| 1560 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 937 | 1561 | UINT16 data = state->video_regs[offset]; |
| 938 | 1562 | |
| 939 | 1563 | switch(offset) |
| 940 | 1564 | { |
| 941 | case 0: // VBlank flag | |
| 1565 | case 0x00/2: // Video IRQ flags | |
| 1566 | if(!space->debugger_access) | |
| 1567 | { | |
| 1568 | cpu_set_input_line(space->machine->device("maincpu"), 7, CLEAR_LINE); | |
| 1569 | } | |
| 942 | 1570 | break; |
| 1571 | case 0x02/2: // Current scanline | |
| 1572 | break; | |
| 943 | 1573 | default: |
| 944 | ||
| 1574 | if(!space->debugger_access) verboselog("maincpu", space->machine, 0, "supracan_video_r: Unknown register: %08x (%04x & %04x)\n", 0xf00000 + (offset << 1), data, mem_mask); | |
| 945 | 1575 | break; |
| 946 | 1576 | } |
| 947 | 1577 | |
| 948 | 1578 | return data; |
| 949 | 1579 | } |
| 950 | 1580 | |
| 1581 | static TIMER_CALLBACK( supracan_hbl_callback ) | |
| 1582 | { | |
| 1583 | // crash debug: printf("U"); fflush(stdout); | |
| 1584 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 951 | 1585 | |
| 1586 | timer_adjust_oneshot(state->hbl_timer, attotime_never, 0); | |
| 1587 | } | |
| 1588 | ||
| 1589 | static TIMER_CALLBACK( supracan_line_on_callback ) | |
| 1590 | { | |
| 1591 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1592 | ||
| 1593 | cpu_set_input_line(machine->device("maincpu"), 5, HOLD_LINE); | |
| 1594 | ||
| 1595 | timer_adjust_oneshot(state->line_on_timer, attotime_never, 0); | |
| 1596 | } | |
| 1597 | ||
| 1598 | static TIMER_CALLBACK( supracan_line_off_callback ) | |
| 1599 | { | |
| 1600 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1601 | ||
| 1602 | cpu_set_input_line(machine->device("maincpu"), 5, CLEAR_LINE); | |
| 1603 | ||
| 1604 | timer_adjust_oneshot(state->line_on_timer, attotime_never, 0); | |
| 1605 | } | |
| 1606 | ||
| 952 | 1607 | static TIMER_CALLBACK( supracan_video_callback ) |
| 953 | 1608 | { |
| 954 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1609 | // crash debug: printf("V"); fflush(stdout); | |
| 1610 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 955 | 1611 | int vpos = machine->primary_screen->vpos(); |
| 956 | 1612 | |
| 1613 | state->video_regs[0] &= ~0x0002; | |
| 1614 | ||
| 957 | 1615 | switch( vpos ) |
| 958 | 1616 | { |
| 959 | 1617 | case 0: |
| r8763 | r8764 | |
| 961 | 1619 | break; |
| 962 | 1620 | case 240: |
| 963 | 1621 | state->video_regs[0] |= 0x8000; |
| 1622 | if(state->irq_mask & 1) | |
| 1623 | { | |
| 1624 | verboselog("maincpu", machine, 0, "Triggering VBL IRQ\n"); | |
| 1625 | cpu_set_input_line(machine->device("maincpu"), 7, HOLD_LINE); | |
| 1626 | } | |
| 964 | 1627 | break; |
| 965 | ||
| 1628 | } | |
| 966 | 1629 | |
| 1630 | state->video_regs[1] = machine->primary_screen->vpos(); | |
| 1631 | ||
| 967 | 1632 | if (vpos == 0) |
| 968 | 1633 | { |
| 969 | 1634 | bitmap_fill(state->roz_final_bitmap, &machine->primary_screen->visible_area(), 0); |
| 970 | 1635 | bitmap_fill(state->roz_bitmap, &machine->primary_screen->visible_area(), 0); |
| 1636 | bitmap_fill(state->tilemap_bitmap[0], NULL, 0); | |
| 1637 | bitmap_fill(state->tilemap_bitmap[1], NULL, 0); | |
| 1638 | bitmap_fill(state->tilemap_bitmap[2], NULL, 0); | |
| 1639 | bitmap_fill(state->tilemap_final_bitmap[0], NULL, 0); | |
| 1640 | bitmap_fill(state->tilemap_final_bitmap[1], NULL, 0); | |
| 1641 | bitmap_fill(state->tilemap_final_bitmap[2], NULL, 0); | |
| 1642 | //memset(state->roz_pri, 8, 1024*1024 * sizeof(UINT8) ); | |
| 1643 | //memset(state->tilemap_pri[0], 8, 1024*1024 * sizeof(UINT8)); | |
| 1644 | //memset(state->tilemap_pri[1], 8, 1024*1024 * sizeof(UINT8)); | |
| 1645 | //memset(state->tilemap_pri[2], 8, 1024*1024 * sizeof(UINT8)); | |
| 1646 | //memset(state->tilemap_final_pri[0], 8, 320*240 * sizeof(UINT8)); | |
| 1647 | //memset(state->tilemap_final_pri[1], 8, 320*240 * sizeof(UINT8)); | |
| 1648 | //memset(state->tilemap_final_pri[2], 8, 320*240 * sizeof(UINT8)); | |
| 971 | 1649 | if(state->video_flags & 4) |
| 972 | 1650 | { |
| 973 | 1651 | draw_roz(machine, &machine->primary_screen->visible_area()); |
| 974 | 1652 | } |
| 1653 | ||
| 1654 | if(state->video_flags & 0x80) | |
| 1655 | { | |
| 1656 | draw_tilemap(machine, state->tilemap_bitmap[0], &machine->primary_screen->visible_area(), 0); | |
| 1657 | } | |
| 1658 | ||
| 1659 | if(state->video_flags & 0x40) | |
| 1660 | { | |
| 1661 | draw_tilemap(machine, state->tilemap_bitmap[1], &machine->primary_screen->visible_area(), 1); | |
| 1662 | } | |
| 1663 | ||
| 1664 | if(state->video_flags & 0x20) | |
| 1665 | { | |
| 1666 | draw_tilemap(machine, state->tilemap_bitmap[2], &machine->primary_screen->visible_area(), 2); | |
| 1667 | } | |
| 975 | 1668 | } |
| 976 | 1669 | |
| 977 | 1670 | if (vpos < 240) |
| 978 | 1671 | { |
| 979 | 1672 | UINT16 *scandata = BITMAP_ADDR16(state->roz_final_bitmap, vpos, 0); |
| 980 | draw_roz_bitmap_scanline(machine, state->roz_bitmap, scandata, vpos, state->roz_scrollx, state->roz_scrolly, state->roz_coeffa, state->roz_coeffb, state->roz_coeffc, state->roz_coeffd, &state->roz_cx, &state->roz_cy, state->roz_changed); | |
| 1673 | UINT8 *pridata = &state->roz_final_pri[vpos*320]; | |
| 1674 | draw_roz_bitmap_scanline(machine, state->roz_bitmap, scandata, pridata, vpos, state->roz_scrollx, state->roz_scrolly, state->roz_coeffa, state->roz_coeffb, state->roz_coeffc, state->roz_coeffd, &state->roz_cx, &state->roz_cy, state->roz_changed); | |
| 1675 | ||
| 1676 | for(int index = 0; index < 3; index++) | |
| 1677 | { | |
| 1678 | if(state->video_flags & (0x80 >> index) ) | |
| 1679 | { | |
| 1680 | scandata = BITMAP_ADDR16(state->tilemap_final_bitmap[index], vpos, 0); | |
| 1681 | pridata = &state->tilemap_final_pri[index][vpos*320]; | |
| 1682 | draw_tilemap_scanline(machine, scandata, pridata, vpos, index); | |
| 1683 | } | |
| 1684 | } | |
| 981 | 1685 | } |
| 982 | 1686 | |
| 983 | timer_adjust_oneshot( state->video_timer, machine->primary_screen->time_until_pos( ( vpos + 1 ) & 0xff, 0 ), 0 ); | |
| 1687 | timer_adjust_oneshot( state->hbl_timer, machine->primary_screen->time_until_pos( vpos, 320 ), 0 ); | |
| 1688 | timer_adjust_oneshot( state->video_timer, machine->primary_screen->time_until_pos( ( vpos + 1 ) % 256, 0 ), 0 ); | |
| 984 | 1689 | } |
| 985 | 1690 | |
| 986 | /* | |
| 987 | 0x188/0x18a is global x/y offset for the roz? | |
| 988 | ||
| 989 | f00018 is src | |
| 990 | f00012 is dst | |
| 991 | f0001c / f00016 are flags of some sort | |
| 992 | f00010 is the size | |
| 993 | f0001e is the trigger | |
| 994 | */ | |
| 995 | 1691 | static WRITE16_HANDLER( supracan_video_w ) |
| 996 | 1692 | { |
| 997 | supracan_state *state = space->machine->driver_data<supracan_state>(); | |
| 1693 | // crash debug: printf("W"); fflush(stdout); | |
| 1694 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); | |
| 998 | 1695 | acan_sprdma_regs_t *acan_sprdma_regs = &state->acan_sprdma_regs; |
| 999 | 1696 | int i; |
| 1000 | 1697 | |
| 1001 | 1698 | switch(offset) |
| 1002 | 1699 | { |
| 1003 | 1700 | case 0x10/2: // Byte count |
| 1701 | verboselog("maincpu", space->machine, 0, "sprite dma word count: %04x\n", data); | |
| 1004 | 1702 | acan_sprdma_regs->count = data; |
| 1005 | 1703 | break; |
| 1006 | 1704 | case 0x12/2: // Destination address MSW |
| 1007 | 1705 | acan_sprdma_regs->dst &= 0x0000ffff; |
| 1008 | 1706 | acan_sprdma_regs->dst |= data << 16; |
| 1707 | verboselog("maincpu", space->machine, 0, "sprite dma dest msw: %04x\n", data); | |
| 1009 | 1708 | break; |
| 1010 | 1709 | case 0x14/2: // Destination address LSW |
| 1011 | 1710 | acan_sprdma_regs->dst &= 0xffff0000; |
| 1012 | 1711 | acan_sprdma_regs->dst |= data; |
| 1712 | verboselog("maincpu", space->machine, 0, "sprite dma dest lsw: %04x\n", data); | |
| 1013 | 1713 | break; |
| 1014 | 1714 | case 0x16/2: // Source word increment |
| 1715 | verboselog("maincpu", space->machine, 0, "sprite dma dest word inc: %04x\n", data); | |
| 1015 | 1716 | acan_sprdma_regs->dst_inc = data; |
| 1016 | 1717 | break; |
| 1017 | 1718 | case 0x18/2: // Source address MSW |
| 1018 | 1719 | acan_sprdma_regs->src &= 0x0000ffff; |
| 1019 | 1720 | acan_sprdma_regs->src |= data << 16; |
| 1721 | verboselog("maincpu", space->machine, 0, "sprite dma src msw: %04x\n", data); | |
| 1020 | 1722 | break; |
| 1021 | 1723 | case 0x1a/2: // Source address LSW |
| 1724 | verboselog("maincpu", space->machine, 0, "sprite dma src lsw: %04x\n", data); | |
| 1022 | 1725 | acan_sprdma_regs->src &= 0xffff0000; |
| 1023 | 1726 | acan_sprdma_regs->src |= data; |
| 1024 | 1727 | break; |
| 1025 | 1728 | case 0x1c/2: // Source word increment |
| 1729 | verboselog("maincpu", space->machine, 0, "sprite dma src word inc: %04x\n", data); | |
| 1026 | 1730 | acan_sprdma_regs->src_inc = data; |
| 1027 | 1731 | break; |
| 1028 | 1732 | case 0x1e/2: |
| 1029 | //printf("* %08x %08x %04x %04x\n",acan_sprdma_regs->src,acan_sprdma_regs->dst,acan_sprdma_regs->count,data); | |
| 1030 | //verboselog(space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_sprdma_regs->src, acan_sprdma_regs->dst, acan_sprdma_regs->count + 1, data); | |
| 1733 | verboselog("maincpu", space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_sprdma_regs->src, acan_sprdma_regs->dst, acan_sprdma_regs->count, data); | |
| 1031 | 1734 | |
| 1032 | 1735 | /* TODO: what's 0x2000 and 0x4000 for? */ |
| 1033 | 1736 | if(data & 0x8000) |
| 1034 | 1737 | { |
| 1035 | 1738 | if(data & 0x2000 || data & 0x4000) |
| 1739 | { | |
| 1036 | 1740 | acan_sprdma_regs->dst |= 0xf40000; |
| 1741 | } | |
| 1037 | 1742 | |
| 1038 | for(i = 0; i <= acan_sprdma_regs->count; i++) | |
| 1743 | if(data & 0x2000) | |
| 1744 | { | |
| 1745 | //acan_sprdma_regs->count <<= 1; | |
| 1746 | } | |
| 1747 | ||
| 1748 | for(i = 0; i < acan_sprdma_regs->count; i++) | |
| 1039 | 1749 | { |
| 1040 | 1750 | if(data & 0x0100) //dma 0x00 fill (or fixed value?) |
| 1041 | 1751 | { |
| r8763 | r8764 | |
| 1053 | 1763 | } |
| 1054 | 1764 | else |
| 1055 | 1765 | { |
| 1056 | ||
| 1766 | ||
| 1057 | 1767 | } |
| 1058 | 1768 | break; |
| 1059 | 1769 | case 0x08/2: |
| 1060 | 1770 | { |
| 1061 | verboselog(space->machine, | |
| 1771 | verboselog("maincpu", space->machine, 3, "video_flags = %04x\n", data); | |
| 1062 | 1772 | state->video_flags = data; |
| 1063 | 1773 | |
| 1064 | 1774 | rectangle visarea = space->machine->primary_screen->visible_area(); |
| r8763 | r8764 | |
| 1069 | 1779 | space->machine->primary_screen->configure(348, 256, visarea, space->machine->primary_screen->frame_period().attoseconds); |
| 1070 | 1780 | } |
| 1071 | 1781 | break; |
| 1072 | case 0x20/2: state->spr_base_addr = data << 2; break; | |
| 1073 | case 0x22/2: state->spr_limit = data+1; break; | |
| 1074 | case 0x24/2: state->spr_yline = data; verboselog(space->machine, 0, "spr_yline = %04x\n", data); break; | |
| 1075 | case 0x26/2: state->spr_flags = data; verboselog(space->machine, 0, "spr_flags = %04x\n", data); break; | |
| 1076 | case 0x100/2: state->tilemap_flags[0] = data; verboselog(space->machine, 0, "tilemap_flags[0] = %04x\n", data); break; | |
| 1077 | case 0x104/2: state->tilemap_scrollx[0] = data; verboselog(space->machine, 0, "tilemap_scrollx[0] = %04x\n", data); break; | |
| 1078 | case 0x106/2: state->tilemap_scrolly[0] = data; verboselog(space->machine, 0, "tilemap_scrolly[0] = %04x\n", data); break; | |
| 1079 | case 0x108/2: state->tilemap_base_addr[0] = (data) << 1; verboselog(space->machine, 0, "tilemap_base_addr[0] = %05x\n", data << 2); break; | |
| 1080 | case 0x10a/2: state->tilemap_mode[0] = data; verboselog(space->machine, 0, "tilemap_mode[0] = %04x\n", data); break; | |
| 1081 | case 0x120/2: state->tilemap_flags[1] = data; verboselog(space->machine, 0, "tilemap_flags[1] = %04x\n", data); break; | |
| 1082 | case 0x124/2: state->tilemap_scrollx[1] = data; verboselog(space->machine, 0, "tilemap_scrollx[1] = %04x\n", data); break; | |
| 1083 | case 0x126/2: state->tilemap_scrolly[1] = data; verboselog(space->machine, 0, "tilemap_scrolly[1] = %04x\n", data); break; | |
| 1084 | case 0x128/2: state->tilemap_base_addr[1] = (data) << 1; verboselog(space->machine, 0, "tilemap_base_addr[1] = %05x\n", data << 2); break; | |
| 1085 | case 0x12a/2: state->tilemap_mode[1] = data; verboselog(space->machine, 0, "tilemap_mode[1] = %04x\n", data); break; | |
| 1086 | case 0x140/2: state->tilemap_flags[2] = data; verboselog(space->machine, 0, "tilemap_flags[2] = %04x\n", data); break; | |
| 1087 | case 0x144/2: state->tilemap_scrollx[2] = data; verboselog(space->machine, 0, "tilemap_scrollx[2] = %04x\n", data); break; | |
| 1088 | case 0x146/2: state->tilemap_scrolly[2] = data; verboselog(space->machine, 0, "tilemap_scrolly[2] = %04x\n", data); break; | |
| 1089 | case 0x148/2: state->tilemap_base_addr[2] = (data) << 1; verboselog(space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 2); verboselog(space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 1); break; | |
| 1090 | case 0x14a/2: state->tilemap_mode[2] = data; verboselog(space->machine, 0, "tilemap_mode[2] = %04x\n", data); break; | |
| 1782 | case 0x0a/2: | |
| 1783 | { | |
| 1784 | verboselog("maincpu", space->machine, 0, "IRQ Trigger? = %04x\n", data); | |
| 1785 | if(data & 0x8000) | |
| 1786 | { | |
| 1787 | timer_adjust_oneshot(state->line_on_timer, space->machine->primary_screen->time_until_pos(data & 0x00ff, 0), 0); | |
| 1788 | } | |
| 1789 | else | |
| 1790 | { | |
| 1791 | timer_adjust_oneshot(state->line_on_timer, attotime_never, 0); | |
| 1792 | } | |
| 1793 | } | |
| 1794 | break; | |
| 1091 | 1795 | |
| 1092 | /* 0x180-0x19f are roz tilemap related regs */ | |
| 1093 | case 0x180/2: state->roz_mode = data; verboselog(space->machine, 5, "roz_mode = %04x\n", data); break; | |
| 1796 | case 0x0c/2: | |
| 1797 | { | |
| 1798 | verboselog("maincpu", space->machine, 0, "IRQ De-Trigger? = %04x\n", data); | |
| 1799 | if(data & 0x8000) | |
| 1800 | { | |
| 1801 | timer_adjust_oneshot(state->line_off_timer, space->machine->primary_screen->time_until_pos(data & 0x00ff, 0), 0); | |
| 1802 | } | |
| 1803 | else | |
| 1804 | { | |
| 1805 | timer_adjust_oneshot(state->line_off_timer, attotime_never, 0); | |
| 1806 | } | |
| 1807 | } | |
| 1808 | break; | |
| 1809 | ||
| 1810 | /* Sprites */ | |
| 1811 | case 0x20/2: state->sprite_base_addr = data << 2; verboselog("maincpu", space->machine, 0, "sprite_base_addr = %04x\n", data); break; | |
| 1812 | case 0x22/2: state->sprite_count = data+1; verboselog("maincpu", space->machine, 0, "sprite_count = %d\n", data+1); break; | |
| 1813 | case 0x26/2: state->sprite_flags = data; verboselog("maincpu", space->machine, 0, "sprite_flags = %04x\n", data); break; | |
| 1814 | ||
| 1815 | /* Tilemap 0 */ | |
| 1816 | case 0x100/2: state->tilemap_flags[0] = data; verboselog("maincpu", space->machine, 3, "tilemap_flags[0] = %04x\n", data); break; | |
| 1817 | case 0x104/2: state->tilemap_scrollx[0] = data; verboselog("maincpu", space->machine, 3, "tilemap_scrollx[0] = %04x\n", data); break; | |
| 1818 | case 0x106/2: state->tilemap_scrolly[0] = data; verboselog("maincpu", space->machine, 3, "tilemap_scrolly[0] = %04x\n", data); break; | |
| 1819 | case 0x108/2: state->tilemap_base_addr[0] = (data) << 1; verboselog("maincpu", space->machine, 3, "tilemap_base_addr[0] = %05x\n", data << 2); break; | |
| 1820 | case 0x10a/2: state->tilemap_mode[0] = data; verboselog("maincpu", space->machine, 3, "tilemap_mode[0] = %04x\n", data); break; | |
| 1821 | ||
| 1822 | /* Tilemap 1 */ | |
| 1823 | case 0x120/2: state->tilemap_flags[1] = data; verboselog("maincpu", space->machine, 3, "tilemap_flags[1] = %04x\n", data); break; | |
| 1824 | case 0x124/2: state->tilemap_scrollx[1] = data; verboselog("maincpu", space->machine, 3, "tilemap_scrollx[1] = %04x\n", data); break; | |
| 1825 | case 0x126/2: state->tilemap_scrolly[1] = data; verboselog("maincpu", space->machine, 3, "tilemap_scrolly[1] = %04x\n", data); break; | |
| 1826 | case 0x128/2: state->tilemap_base_addr[1] = (data) << 1; verboselog("maincpu", space->machine, 3, "tilemap_base_addr[1] = %05x\n", data << 2); break; | |
| 1827 | case 0x12a/2: state->tilemap_mode[1] = data; verboselog("maincpu", space->machine, 3, "tilemap_mode[1] = %04x\n", data); break; | |
| 1828 | ||
| 1829 | /* Tilemap 2? */ | |
| 1830 | case 0x140/2: state->tilemap_flags[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_flags[2] = %04x\n", data); break; | |
| 1831 | case 0x144/2: state->tilemap_scrollx[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_scrollx[2] = %04x\n", data); break; | |
| 1832 | case 0x146/2: state->tilemap_scrolly[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_scrolly[2] = %04x\n", data); break; | |
| 1833 | case 0x148/2: state->tilemap_base_addr[2] = (data) << 1; verboselog("maincpu", space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 2); verboselog("maincpu", space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 1); break; | |
| 1834 | case 0x14a/2: state->tilemap_mode[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_mode[2] = %04x\n", data); break; | |
| 1835 | ||
| 1836 | /* ROZ */ | |
| 1837 | case 0x180/2: state->roz_mode = data; verboselog("maincpu", space->machine, 3, "roz_mode = %04x\n", data); break; | |
| 1094 | 1838 | case 0x184/2: state->roz_scrollx = (data << 16) | (state->roz_scrollx & 0xffff); state->roz_changed |= 1; break; |
| 1095 | 1839 | case 0x186/2: state->roz_scrollx = (data) | (state->roz_scrollx & 0xffff0000); state->roz_changed |= 1; break; |
| 1096 | 1840 | case 0x188/2: state->roz_scrolly = (data << 16) | (state->roz_scrolly & 0xffff); state->roz_changed |= 2; break; |
| r8763 | r8764 | |
| 1099 | 1843 | case 0x18e/2: state->roz_coeffb = data; break; |
| 1100 | 1844 | case 0x190/2: state->roz_coeffc = data; break; |
| 1101 | 1845 | case 0x192/2: state->roz_coeffd = data; break; |
| 1102 | case 0x194/2: state->roz_base_addr = (data) << 1; verboselog(space->machine, 5, "roz_base_addr = %05x\n", data << 2); break; | |
| 1103 | case 0x196/2: state->roz_tile_bank = data; verboselog(space->machine, 5, "roz_tile_bank = %04x\n", data); break; //tile bank | |
| 1104 | case 0x198/2: verboselog(space->machine, 0, "roz_unk_base0 = %05x\n", data << 2); state->roz_unk_base0 = data << 1; break; | |
| 1105 | case 0x19a/2: verboselog(space->machine, 0, "roz_unk_base1 = %05x\n", data << 2); state->roz_unk_base1 = data << 1; break; | |
| 1106 | case 0x19e/2: verboselog(space->machine, 0, "roz_unk_base2 = %05x\n", data << 2); state->roz_unk_base2 = data << 1; break; | |
| 1846 | case 0x194/2: state->roz_base_addr = (data) << 1; verboselog("maincpu", space->machine, 3, "roz_base_addr = %05x\n", data << 2); break; | |
| 1847 | case 0x196/2: state->roz_tile_bank = data; verboselog("maincpu", space->machine, 3, "roz_tile_bank = %04x\n", data); break; //tile bank | |
| 1848 | case 0x198/2: state->roz_unk_base0 = data << 1; verboselog("maincpu", space->machine, 3, "roz_unk_base0 = %05x\n", data << 2); break; | |
| 1849 | case 0x19a/2: state->roz_unk_base1 = data << 1; verboselog("maincpu", space->machine, 3, "roz_unk_base1 = %05x\n", data << 2); break; | |
| 1850 | case 0x19e/2: state->roz_unk_base2 = data << 1; verboselog("maincpu", space->machine, 3, "roz_unk_base2 = %05x\n", data << 2); break; | |
| 1107 | 1851 | |
| 1852 | case 0x1d0/2: state->bg_color = data & 0x00ff; verboselog("maincpu", space->machine, 3, "bg_color = %02x\n", data & 0x00ff); break; | |
| 1853 | ||
| 1108 | 1854 | case 0x1f0/2: //FIXME: this register is mostly not understood |
| 1109 | state->irq_mask = (data & 8) ? 0 : 1; | |
| 1855 | state->irq_mask = data;//(data & 8) ? 0 : 1; | |
| 1856 | /* | |
| 1857 | if(!state->irq_mask && !state->hbl_mask) | |
| 1858 | { | |
| 1859 | cpu_set_input_line(devtag_get_device(space->machine, "maincpu"), 7, CLEAR_LINE); | |
| 1860 | } | |
| 1861 | */ | |
| 1862 | verboselog("maincpu", space->machine, 3, "irq_mask = %04x\n", data); | |
| 1110 | 1863 | break; |
| 1111 | 1864 | default: |
| 1112 | verboselog(space->machine, 0, "supracan_video_w: Unknown register: %08x = %04x & %04x\n", 0xf00000 + (offset << 1), data, mem_mask); | |
| 1865 | verboselog("maincpu", space->machine, 0, "supracan_video_w: Unknown register: %08x = %04x & %04x\n", 0xf00000 + (offset << 1), data, mem_mask); | |
| 1113 | 1866 | break; |
| 1114 | 1867 | } |
| 1115 | 1868 | state->video_regs[offset] = data; |
| r8763 | r8764 | |
| 1118 | 1871 | |
| 1119 | 1872 | static DEVICE_IMAGE_LOAD( supracan_cart ) |
| 1120 | 1873 | { |
| 1121 | UINT8 *cart = memory_region(image.device().machine, "cart"); | |
| 1874 | // crash debug: printf("X"); fflush(stdout); | |
| 1875 | UINT8 *cart = memory_region(image.device().machine, "cart"); | |
| 1122 | 1876 | UINT32 size; |
| 1123 | 1877 | |
| 1124 | ||
| 1878 | if (image.software_entry() == NULL) | |
| 1125 | 1879 | { |
| 1126 | ||
| 1880 | size = image.length(); | |
| 1127 | 1881 | |
| 1128 | 1882 | if (size > 0x400000) |
| 1129 | 1883 | { |
| 1130 | 1884 | image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); |
| 1131 | ||
| 1885 | return IMAGE_INIT_FAIL; | |
| 1132 | 1886 | } |
| 1133 | 1887 | |
| 1134 | if (image.fread( | |
| 1888 | if (image.fread( | |
| 1135 | 1889 | { |
| 1136 | 1890 | image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read from file"); |
| 1137 | ||
| 1891 | return IMAGE_INIT_FAIL; | |
| 1138 | 1892 | } |
| 1139 | 1893 | } |
| 1140 | 1894 | else |
| r8763 | r8764 | |
| 1143 | 1897 | memcpy(cart, image.get_software_region("rom"), size); |
| 1144 | 1898 | } |
| 1145 | 1899 | |
| 1146 | ||
| 1900 | return IMAGE_INIT_PASS; | |
| 1147 | 1901 | } |
| 1148 | 1902 | |
| 1149 | 1903 | |
| 1150 | 1904 | static MACHINE_START( supracan ) |
| 1151 | 1905 | { |
| 1152 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1906 | // crash debug: printf("Y"); fflush(stdout); | |
| 1907 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1153 | 1908 | |
| 1154 | 1909 | state->video_timer = timer_alloc( machine, supracan_video_callback, NULL ); |
| 1910 | state->hbl_timer = timer_alloc( machine, supracan_hbl_callback, NULL ); | |
| 1911 | state->line_on_timer = timer_alloc( machine, supracan_line_on_callback, NULL ); | |
| 1912 | state->line_off_timer = timer_alloc( machine, supracan_line_off_callback, NULL ); | |
| 1155 | 1913 | } |
| 1156 | 1914 | |
| 1157 | 1915 | |
| 1158 | 1916 | static MACHINE_RESET( supracan ) |
| 1159 | 1917 | { |
| 1160 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1918 | // crash debug: printf("Z"); fflush(stdout); | |
| 1919 | supracan_state *state = machine->driver_data<supracan_state>(); | |
| 1161 | 1920 | |
| 1162 | 1921 | cputag_set_input_line(machine, "soundcpu", INPUT_LINE_HALT, ASSERT_LINE); |
| 1163 | timer_adjust_oneshot( state->video_timer, machine->primary_screen->time_until_pos(0, 0 ), 0 ); | |
| 1922 | ||
| 1923 | timer_adjust_oneshot( state->video_timer, machine->primary_screen->time_until_pos( 0, 0 ), 0 ); | |
| 1164 | 1924 | state->irq_mask = 0; |
| 1165 | 1925 | } |
| 1166 | 1926 | |
| 1927 | /* gfxdecode is retained for reference purposes but not otherwise used by the driver */ | |
| 1928 | #ifdef UNUSED_CODE | |
| 1167 | 1929 | static const gfx_layout supracan_gfx8bpp = |
| 1168 | 1930 | { |
| 1169 | 1931 | 8,8, |
| r8763 | r8764 | |
| 1202 | 1964 | GFXDECODE_ENTRY( "ram_gfx", 0, supracan_gfx4bpp, 0, 0x10 ) |
| 1203 | 1965 | GFXDECODE_ENTRY( "ram_gfx", 0, supracan_gfx2bpp, 0, 0x40 ) |
| 1204 | 1966 | GFXDECODE_END |
| 1967 | #endif | |
| 1205 | 1968 | |
| 1206 | 1969 | static INTERRUPT_GEN( supracan_irq ) |
| 1207 | 1970 | { |
| 1208 | supracan_state *state = device->machine->driver_data<supracan_state>(); | |
| 1971 | /* | |
| 1972 | supracan_state *state = (supracan_state *)device->machine->driver_data<supracan_state>(); | |
| 1209 | 1973 | |
| 1210 | 1974 | if(state->irq_mask) |
| 1975 | { | |
| 1211 | 1976 | cpu_set_input_line(device, 7, HOLD_LINE); |
| 1977 | } | |
| 1978 | */ | |
| 1212 | 1979 | } |
| 1213 | 1980 | |
| 1981 | static INTERRUPT_GEN( supracan_sound_irq ) | |
| 1982 | { | |
| 1983 | supracan_state *state = (supracan_state *)device->machine->driver_data<supracan_state>(); | |
| 1984 | ||
| 1985 | cpu_set_input_line(device, 0, HOLD_LINE); | |
| 1986 | state->sound_irq_source_reg |= 0x80; | |
| 1987 | } | |
| 1988 | ||
| 1214 | 1989 | static MACHINE_DRIVER_START( supracan ) |
| 1215 | 1990 | |
| 1216 | 1991 | MDRV_DRIVER_DATA( supracan_state ) |
| r8763 | r8764 | |
| 1221 | 1996 | |
| 1222 | 1997 | MDRV_CPU_ADD( "soundcpu", M6502, XTAL_3_579545MHz ) /* TODO: Verfiy actual clock */ |
| 1223 | 1998 | MDRV_CPU_PROGRAM_MAP( supracan_sound_mem ) |
| 1999 | MDRV_CPU_VBLANK_INT("screen", supracan_sound_irq) | |
| 1224 | 2000 | |
| 2001 | #if !(SOUNDCPU_BOOT_HACK) | |
| 2002 | MDRV_QUANTUM_PERFECT_CPU("maincpu") | |
| 2003 | MDRV_QUANTUM_PERFECT_CPU("soundcpu") | |
| 2004 | #endif | |
| 2005 | ||
| 1225 | 2006 | MDRV_MACHINE_START( supracan ) |
| 1226 | 2007 | MDRV_MACHINE_RESET( supracan ) |
| 1227 | 2008 | |
| r8763 | r8764 | |
| 1231 | 2012 | |
| 1232 | 2013 | MDRV_PALETTE_LENGTH( 32768 ) |
| 1233 | 2014 | MDRV_PALETTE_INIT( supracan ) |
| 1234 | MDRV_GFXDECODE( supracan ) | |
| 1235 | 2015 | |
| 1236 | 2016 | MDRV_CARTSLOT_ADD("cart") |
| 1237 | 2017 | MDRV_CARTSLOT_EXTENSION_LIST("bin") |
| r8763 | r8764 | |
| 1255 | 2035 | |
| 1256 | 2036 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 1257 | 2037 | CONS( 1995, supracan, 0, 0, supracan, supracan, 0, "Funtech Entertainment", "Super A'Can", GAME_NO_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) |
| 1258 | ||
| 1259 |
| Previous | 15994 Revisions | Next |