trunk/src/mess/video/a7800.c
| r22865 | r22866 | |
| 35 | 35 | |
| 36 | 36 | /********** Maria ***********/ |
| 37 | 37 | |
| 38 | | #define DPPH 0x2c |
| 39 | | #define DPPL 0x30 |
| 40 | | |
| 41 | 38 | /*************************************************************************** |
| 42 | 39 | |
| 43 | 40 | Start the video hardware emulation. |
| r22865 | r22866 | |
| 125 | 122 | unsigned int graph_adr,data_addr; |
| 126 | 123 | int width,pal,ind; |
| 127 | 124 | UINT8 hpos; |
| 128 | | int xpos; |
| 129 | 125 | unsigned int dl; |
| 130 | | int x, d, c, i, j, pixel_cell, cells; |
| 126 | int x, d, c, i, pixel_cell, cells; |
| 131 | 127 | int maria_cycles; |
| 132 | 128 | |
| 133 | 129 | maria_cycles = 0; |
| 134 | 130 | cells = 0; |
| 135 | 131 | |
| 136 | | /* clear active line ram buffer */ |
| 137 | | for (i = 0; i < 160; i++) |
| 138 | | m_line_ram[m_active_buffer][i] = 0; |
| 139 | | |
| 140 | 132 | /* Process this DLL entry */ |
| 141 | 133 | dl = m_maria_dl; |
| 142 | 134 | |
| r22865 | r22866 | |
| 168 | 160 | maria_cycles += 8; |
| 169 | 161 | } |
| 170 | 162 | |
| 171 | | /*logerror("%x DL: ADR=%x width=%x hpos=%x pal=%x mode=%x ind=%x\n",m_screen->vpos(),graph_adr,width,hpos,pal,mode,ind );*/ |
| 163 | /*logerror("%x DL: ADR=%x width=%x hpos=%x pal=%x mode=%x ind=%x\n",m_screen->vpos(),graph_adr,width,hpos,pal,m_maria_write_mode,ind );*/ |
| 172 | 164 | |
| 173 | 165 | for (x=0; x<width; x++) |
| 174 | 166 | { |
| r22865 | r22866 | |
| 176 | 168 | if (ind) |
| 177 | 169 | { |
| 178 | 170 | c = READ_MEM(graph_adr + x) & 0xFF; |
| 179 | | maria_cycles += 3; // 3 Maria cycles |
| 171 | maria_cycles += 3; |
| 180 | 172 | data_addr = (m_maria_charbase | c) + (m_maria_offset << 8); |
| 181 | 173 | if (is_holey(data_addr)) |
| 182 | 174 | continue; |
| r22865 | r22866 | |
| 186 | 178 | hpos += cells; |
| 187 | 179 | cells = write_line_ram(data_addr+1, hpos, pal); |
| 188 | 180 | hpos += cells; |
| 181 | maria_cycles += 6; |
| 189 | 182 | } |
| 190 | 183 | else |
| 191 | 184 | { |
| 192 | 185 | cells = write_line_ram(data_addr, hpos, pal); |
| 193 | 186 | hpos += cells; |
| 187 | maria_cycles += 3; |
| 194 | 188 | } |
| 195 | 189 | } |
| 196 | 190 | else // direct mode |
| r22865 | r22866 | |
| 200 | 194 | continue; |
| 201 | 195 | cells = write_line_ram(data_addr, hpos, pal); |
| 202 | 196 | hpos += cells; |
| 197 | maria_cycles += 3; |
| 203 | 198 | } |
| 204 | 199 | } |
| 205 | 200 | } |
| 206 | | |
| 207 | | /* render scanline */ |
| 201 | m_maincpu->eat_cycles(maria_cycles/4); // Maria clock rate is 4 times that of CPU |
| 202 | |
| 203 | // draw line buffer to screen |
| 208 | 204 | m_active_buffer = !m_active_buffer; // switch buffers |
| 209 | 205 | UINT16 *scanline; |
| 210 | 206 | scanline = &m_bitmap.pix16(m_screen->vpos()); |
| 211 | | for (i = 0; i < 320; i++) |
| 212 | | scanline[i] = m_maria_palette[0]; |
| 213 | 207 | |
| 214 | | xpos = 0; |
| 215 | | i=0; |
| 216 | 208 | |
| 217 | | while ( i<160 ) |
| 218 | | |
| 219 | | switch (m_maria_rm | m_maria_write_mode) |
| 209 | for ( i = 0; i<160; i++ ) |
| 210 | { |
| 211 | switch (m_maria_rm) |
| 220 | 212 | { |
| 221 | | case 0x00: /* 160A (160x2) */ |
| 222 | | case 0x01: /* 160A (160x2) */ |
| 223 | | for (j = 0; j<4; j++, xpos+=2) |
| 224 | | { |
| 225 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
| 226 | | scanline[xpos] = m_maria_palette[pixel_cell]; |
| 227 | | scanline[xpos+1] = m_maria_palette[pixel_cell]; |
| 228 | | } |
| 229 | | i += 4; |
| 213 | case 0x00: /* 160A, 160B */ |
| 214 | case 0x01: /* 160A, 160B */ |
| 215 | pixel_cell = m_line_ram[m_active_buffer][i]; |
| 216 | scanline[2*i] = m_maria_palette[pixel_cell]; |
| 217 | scanline[2*i+1] = m_maria_palette[pixel_cell]; |
| 230 | 218 | break; |
| 231 | 219 | |
| 232 | | case 0x02: /* 320D used by Jinks! */ |
| 233 | | for (j = 0; j<4; j++, xpos+=2) |
| 234 | | { |
| 235 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
| 236 | | d = (pixel_cell & 0x10) | (pixel_cell & 0x02) | ((pixel_cell >> 3) & 1); |
| 237 | | scanline[xpos] = m_maria_palette[d]; |
| 238 | | |
| 239 | | d = (pixel_cell & 0x10) | ((pixel_cell << 1) & 0x02) | ((pixel_cell >> 2) & 1); |
| 240 | | scanline[xpos+1] = m_maria_palette[d]; |
| 241 | | } |
| 242 | | i += 4; |
| 220 | case 0x02: /* 320B, 320D */ |
| 221 | pixel_cell = m_line_ram[m_active_buffer][i]; |
| 222 | d = (pixel_cell & 0x10) | (pixel_cell & 0x02) | ((pixel_cell >> 3) & 1); // b4 0 0 b1 b3 |
| 223 | scanline[2*i] = m_maria_palette[d]; |
| 224 | d = (pixel_cell & 0x10) | ((pixel_cell << 1) & 0x02) | ((pixel_cell >> 2) & 1); // b4 0 0 b0 b2 |
| 225 | scanline[2*i+1] = m_maria_palette[d]; |
| 243 | 226 | break; |
| 244 | 227 | |
| 245 | | case 0x03: /* MODE 320A */ |
| 246 | | for (j = 0; j<4; j++, xpos+=2) |
| 247 | | { |
| 248 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
| 249 | | d = (pixel_cell & 0x1C) | (pixel_cell & 0x02); |
| 250 | | scanline[xpos] = m_maria_palette[d]; |
| 251 | | |
| 252 | | d = (pixel_cell & 0x1C) | ((pixel_cell << 1) & 0x02); |
| 253 | | scanline[xpos+1] = m_maria_palette[d]; |
| 254 | | } |
| 255 | | i += 4; |
| 228 | case 0x03: /* 320A, 320C */ |
| 229 | pixel_cell = m_line_ram[m_active_buffer][i]; |
| 230 | d = (pixel_cell & 0x1C) | (pixel_cell & 0x02); // b4 b3 b2 b1 0 |
| 231 | scanline[2*i] = m_maria_palette[d]; |
| 232 | d = (pixel_cell & 0x1C) | ((pixel_cell << 1) & 0x02); // b4 b3 b2 b0 0 |
| 233 | scanline[2*i+1] = m_maria_palette[d]; |
| 256 | 234 | break; |
| 235 | } |
| 236 | } |
| 257 | 237 | |
| 258 | | case 0x04: /* 160B (160x4) */ |
| 259 | | case 0x05: /* 160B (160x4) */ |
| 260 | | for (j = 0; j<2; j++, xpos+=2) |
| 261 | | { |
| 262 | | d = m_line_ram[m_active_buffer][i+j]; |
| 263 | | scanline[xpos] = m_maria_palette[d]; |
| 264 | | scanline[xpos+1] = m_maria_palette[d]; |
| 265 | | } |
| 266 | | i += 2; |
| 267 | | break; |
| 268 | | |
| 269 | | case 0x06: /* MODE 320B */ |
| 270 | | for (j = 0; j<2; j++, xpos+=2) |
| 271 | | { |
| 272 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
| 273 | | |
| 274 | | d = (pixel_cell & 0x10) | (pixel_cell & 0x02) | ((pixel_cell >> 3) & 1); |
| 275 | | scanline[xpos] = m_maria_palette[d]; |
| 276 | | |
| 277 | | d = (pixel_cell & 0x10) | ((pixel_cell << 1) & 0x02) | ((pixel_cell >> 2) & 1); |
| 278 | | scanline[xpos+1] = m_maria_palette[d]; |
| 279 | | } |
| 280 | | i += 2; |
| 281 | | break; |
| 282 | | |
| 283 | | case 0x07: /* MODE 320C */ |
| 284 | | for (j = 0; j<2; j++, xpos+=2) |
| 285 | | { |
| 286 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
| 287 | | |
| 288 | | d = pixel_cell & 0x1E; |
| 289 | | scanline[xpos] = m_maria_palette[d]; |
| 290 | | |
| 291 | | d = (pixel_cell & 0x1C) | ((pixel_cell & 0x01) << 1); |
| 292 | | scanline[xpos+1] = m_maria_palette[d]; |
| 293 | | } |
| 294 | | i += 2; |
| 295 | | break; |
| 296 | | |
| 297 | | } /* endswitch (mode) */ |
| 298 | | |
| 299 | | m_maincpu->adjust_icount(-maria_cycles/4); // Maria clock rate is 4 times that of CPU |
| 238 | for(i=0; i<160; i++) // buffer automaticaly cleared once displayed |
| 239 | m_line_ram[m_active_buffer][i] = 0; |
| 300 | 240 | } |
| 301 | 241 | |
| 302 | 242 | |
| 303 | 243 | |
| 304 | 244 | TIMER_DEVICE_CALLBACK_MEMBER(a7800_state::a7800_interrupt) |
| 305 | 245 | { |
| 246 | // DMA Begins 7 cycles after hblank |
| 306 | 247 | machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(7), timer_expired_delegate(FUNC(a7800_state::a7800_maria_startdma),this)); |
| 307 | 248 | if( m_maria_wsync ) |
| 308 | 249 | { |
| r22865 | r22866 | |
| 337 | 278 | m_maria_dl = (READ_MEM(m_maria_dll+1) << 8) | READ_MEM(m_maria_dll+2); |
| 338 | 279 | m_maria_offset = READ_MEM(m_maria_dll) & 0x0f; |
| 339 | 280 | m_maria_holey = (READ_MEM(m_maria_dll) & 0x60) >> 5; |
| 340 | | logerror("holey %d", m_maria_holey); |
| 341 | | if ( READ_MEM(m_maria_dll) & 0x80 ) |
| 342 | | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 343 | | m_maincpu->adjust_icount(-6); // 24 Maria cycles minimum (DMA startup + shutdown list-list fetch) |
| 281 | m_maria_nmi = READ_MEM(m_maria_dll) & 0x80; |
| 282 | m_maincpu->eat_cycles(6); // 24 Maria cycles minimum (DMA startup + shutdown list-list fetch) |
| 344 | 283 | /* logerror("DLL=%x\n",m_maria_dll); */ |
| 345 | | /* logerror("DLL: DL = %x dllctrl = %x\n",m_maria_dl,ROM[m_maria_dll]); */ |
| 346 | 284 | } |
| 347 | 285 | |
| 348 | 286 | |
| r22865 | r22866 | |
| 356 | 294 | m_maria_dl = (READ_MEM(m_maria_dll+1) << 8) | READ_MEM(m_maria_dll+2); |
| 357 | 295 | m_maria_offset = READ_MEM(m_maria_dll) & 0x0f; |
| 358 | 296 | m_maria_holey = (READ_MEM(m_maria_dll) & 0x60) >> 5; |
| 359 | | logerror("holey %d", m_maria_holey); |
| 360 | | if ( READ_MEM(m_maria_dll) & 0x80 ) |
| 361 | | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 362 | | m_maincpu->adjust_icount(-5); // 20 Maria cycles (DMA startup + shutdown) |
| 297 | m_maincpu->eat_cycles(5); // 20 Maria cycles (DMA startup + shutdown) |
| 298 | if ( READ_MEM(m_maria_dll & 0x10) ) |
| 299 | logerror("dll bit 5 set!\n"); |
| 300 | m_maria_nmi = READ_MEM(m_maria_dll) & 0x80; |
| 363 | 301 | } |
| 364 | 302 | else |
| 365 | 303 | { |
| 366 | 304 | m_maria_offset--; |
| 367 | 305 | } |
| 368 | 306 | } |
| 307 | |
| 308 | if( m_maria_nmi ) |
| 309 | { |
| 310 | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 311 | m_maria_nmi = 0; |
| 312 | } |
| 369 | 313 | } |
| 370 | 314 | |
| 371 | 315 | /*************************************************************************** |
| r22865 | r22866 | |
| 406 | 350 | switch (offset) |
| 407 | 351 | { |
| 408 | 352 | case 0x00: |
| 409 | | // 0x04 etc. necessary for 320 modes (pixels with color of 00 should display as background color) |
| 353 | // all color ram addresses with 00 for their least significant bits point to the background color |
| 410 | 354 | for (i = 0; i<8; i++) |
| 411 | 355 | m_maria_palette[4*i] = data; |
| 412 | 356 | break; |