branches/alto2/src/emu/cpu/alto2/a2disp.c
| r26419 | r26420 | |
| 226 | 226 | 0xffc0,0xffc3,0xffcc,0xffcf,0xfff0,0xfff3,0xfffc,0xffff |
| 227 | 227 | }; |
| 228 | 228 | |
| 229 | #define HLC1 ((m_dsp.hlc >> 0) & 1) //!< horizontal line counter bit 0 (mid of the scanline) |
| 230 | #define HLC2 ((m_dsp.hlc >> 1) & 1) //!< horizontal line counter bit 1 |
| 231 | #define HLC4 ((m_dsp.hlc >> 2) & 1) //!< horizontal line counter bit 2 |
| 232 | #define HLC8 ((m_dsp.hlc >> 3) & 1) //!< horizontal line counter bit 3 |
| 233 | #define HLC16 ((m_dsp.hlc >> 4) & 1) //!< horizontal line counter bit 4 |
| 234 | #define HLC32 ((m_dsp.hlc >> 5) & 1) //!< horizontal line counter bit 5 |
| 235 | #define HLC64 ((m_dsp.hlc >> 6) & 1) //!< horizontal line counter bit 6 |
| 236 | #define HLC128 ((m_dsp.hlc >> 7) & 1) //!< horizontal line counter bit 7 |
| 237 | #define HLC256 ((m_dsp.hlc >> 8) & 1) //!< horizontal line counter bit 8 |
| 238 | #define HLC512 ((m_dsp.hlc >> 9) & 1) //!< horizontal line counter bit 9 |
| 239 | #define HLC1024 ((m_dsp.hlc >> 10) & 1) //!< horizontal line counter bit 10 (odd/even field) |
| 240 | |
| 241 | #define GET_SETMODE_SPEEDY(mode) X_RDBITS(mode,16,0,0) //!< get the pixel clock speed from a SETMODE<- bus value |
| 242 | #define GET_SETMODE_INVERSE(mode) X_RDBITS(mode,16,1,1) //!< get the inverse video flag from a SETMODE<- bus value |
| 243 | |
| 244 | //!< helper to extract A3-A0 from a PROM a63 value |
| 245 | #define A63_NEXT(n) ((n >> 2) & 017) |
| 246 | |
| 229 | 247 | //! update the internal bitmap to a byte array |
| 230 | | void alto2_cpu_device::update_bitmap_word(int x, int y, UINT16 word) |
| 248 | void alto2_cpu_device::update_bitmap_word(UINT16* bitmap, int x, int y, UINT16 word) |
| 231 | 249 | { |
| 232 | | UINT8* pix = m_dsp.scanline[y] + x; |
| 250 | /* mixing with the cursor */ |
| 251 | if (x == m_dsp.curxpos + 0) |
| 252 | word ^= m_dsp.cursor0; |
| 253 | if (x == m_dsp.curxpos + 1) |
| 254 | word ^= m_dsp.cursor1; |
| 255 | if (word == bitmap[x]) |
| 256 | return; |
| 257 | bitmap[x] = word; |
| 258 | UINT8* pix = m_dsp.scanline[y] + x * 16; |
| 233 | 259 | *pix++ = (word >> 15) & 1; |
| 234 | 260 | *pix++ = (word >> 14) & 1; |
| 235 | 261 | *pix++ = (word >> 13) & 1; |
| r26419 | r26420 | |
| 248 | 274 | *pix++ = (word >> 0) & 1; |
| 249 | 275 | } |
| 250 | 276 | |
| 251 | | #define HLC1 ((m_dsp.hlc >> 0) & 1) //!< horizontal line counter bit 0 (mid of the scanline) |
| 252 | | #define HLC2 ((m_dsp.hlc >> 1) & 1) //!< horizontal line counter bit 1 |
| 253 | | #define HLC4 ((m_dsp.hlc >> 2) & 1) //!< horizontal line counter bit 2 |
| 254 | | #define HLC8 ((m_dsp.hlc >> 3) & 1) //!< horizontal line counter bit 3 |
| 255 | | #define HLC16 ((m_dsp.hlc >> 4) & 1) //!< horizontal line counter bit 4 |
| 256 | | #define HLC32 ((m_dsp.hlc >> 5) & 1) //!< horizontal line counter bit 5 |
| 257 | | #define HLC64 ((m_dsp.hlc >> 6) & 1) //!< horizontal line counter bit 6 |
| 258 | | #define HLC128 ((m_dsp.hlc >> 7) & 1) //!< horizontal line counter bit 7 |
| 259 | | #define HLC256 ((m_dsp.hlc >> 8) & 1) //!< horizontal line counter bit 8 |
| 260 | | #define HLC512 ((m_dsp.hlc >> 9) & 1) //!< horizontal line counter bit 9 |
| 261 | | #define HLC1024 ((m_dsp.hlc >> 10) & 1) //!< horizontal line counter bit 10 (odd/even field) |
| 262 | | |
| 263 | | #define GET_SETMODE_SPEEDY(mode) X_RDBITS(mode,16,0,0) //!< get the pixel clock speed from a SETMODE<- bus value |
| 264 | | #define GET_SETMODE_INVERSE(mode) X_RDBITS(mode,16,1,1) //!< get the inverse video flag from a SETMODE<- bus value |
| 265 | | |
| 266 | | //!< helper to extract A3-A0 from a PROM a63 value |
| 267 | | #define A63_NEXT(n) ((n >> 2) & 017) |
| 268 | | |
| 269 | 277 | /** |
| 270 | 278 | * @brief unload the next word from the display FIFO and shift it to the screen |
| 271 | 279 | */ |
| r26419 | r26420 | |
| 279 | 287 | m_unload_time = -1; |
| 280 | 288 | return; |
| 281 | 289 | } |
| 282 | | UINT16* scanline = m_dsp.raw_bitmap + y * ALTO2_DISPLAY_SCANLINE_WORDS; |
| 283 | | UINT32 word = m_dsp.inverse; |
| 284 | | UINT8 a38 = m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr]; |
| 290 | UINT16* bitmap = m_dsp.raw_bitmap + y * ALTO2_DISPLAY_SCANLINE_WORDS; |
| 291 | UINT16 word = m_dsp.inverse; |
| 292 | UINT8 a38 = m_disp_a38[m_dsp.ra * 16 + m_dsp.wa]; |
| 285 | 293 | if (FIFO_MBEMPTY(a38)) |
| 286 | 294 | { |
| 287 | 295 | LOG((LOG_DISPL,1, " DSP FIFO underrun y:%d x:%d\n", y, x)); |
| 288 | 296 | } |
| 289 | 297 | else |
| 290 | 298 | { |
| 291 | | word ^= m_dsp.fifo[m_dsp.fifo_rd]; |
| 292 | | m_dsp.fifo_rd = (m_dsp.fifo_rd + 1) % ALTO2_DISPLAY_FIFO; |
| 299 | word ^= m_dsp.fifo[m_dsp.ra]; |
| 300 | m_dsp.ra = (m_dsp.ra + 1) % ALTO2_DISPLAY_FIFO; |
| 293 | 301 | LOG((LOG_DISPL,3, " DSP pull %04x from FIFO[%02o] y:%d x:%d\n", |
| 294 | | word, (m_dsp.fifo_rd - 1) & (ALTO2_DISPLAY_FIFO - 1), y, x)); |
| 302 | word, (m_dsp.ra - 1) & (ALTO2_DISPLAY_FIFO - 1), y, x)); |
| 295 | 303 | } |
| 296 | 304 | |
| 297 | 305 | if (m_dsp.halfclock) |
| 298 | 306 | { |
| 299 | 307 | UINT16 word1 = double_bits[word / 256]; |
| 300 | 308 | UINT16 word2 = double_bits[word % 256]; |
| 301 | | /* mixing with the cursor */ |
| 302 | | if (x == m_dsp.curword + 0) |
| 303 | | word1 ^= m_dsp.curdata >> 16; |
| 304 | | if (x == m_dsp.curword + 1) |
| 305 | | word1 ^= m_dsp.curdata & 0177777; |
| 306 | | if (word1 != scanline[x]) |
| 307 | | { |
| 308 | | scanline[x] = word1; |
| 309 | | update_bitmap_word(16 * x, y, word1); |
| 310 | | } |
| 309 | update_bitmap_word(bitmap, x, y, word1); |
| 311 | 310 | x++; |
| 312 | 311 | if (x < ALTO2_DISPLAY_VISIBLE_WORDS) |
| 313 | 312 | { |
| 314 | | /* mixing with the cursor */ |
| 315 | | if (x == m_dsp.curword + 0) |
| 316 | | word2 ^= m_dsp.curdata >> 16; |
| 317 | | if (x == m_dsp.curword + 1) |
| 318 | | word2 ^= m_dsp.curdata & 0177777; |
| 319 | | if (word2 != scanline[x]) |
| 320 | | { |
| 321 | | scanline[x] = word2; |
| 322 | | update_bitmap_word(16 * x, y, word2); |
| 323 | | } |
| 313 | update_bitmap_word(bitmap, x, y, word2); |
| 324 | 314 | x++; |
| 325 | 315 | } |
| 326 | 316 | m_unload_time += ALTO2_DISPLAY_BITTIME(32); |
| 327 | 317 | } |
| 328 | 318 | else |
| 329 | 319 | { |
| 330 | | /* mixing with the cursor */ |
| 331 | | if (x == m_dsp.curword + 0) |
| 332 | | word ^= m_dsp.curdata >> 16; |
| 333 | | if (x == m_dsp.curword + 1) |
| 334 | | word ^= m_dsp.curdata & 0177777; |
| 335 | | if (word != scanline[x]) |
| 336 | | { |
| 337 | | scanline[x] = word; |
| 338 | | update_bitmap_word(16 * x, y, word); |
| 339 | | } |
| 320 | update_bitmap_word(bitmap, x, y, word); |
| 340 | 321 | x++; |
| 341 | 322 | m_unload_time += ALTO2_DISPLAY_BITTIME(16); |
| 342 | 323 | } |
| r26419 | r26420 | |
| 445 | 426 | * if DHT is not blocked, and if the buffer is not full, DWT wakeups |
| 446 | 427 | * are generated. |
| 447 | 428 | */ |
| 448 | | UINT8 a38 = m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr]; |
| 429 | UINT8 a38 = m_disp_a38[m_dsp.ra * 16 + m_dsp.wa]; |
| 449 | 430 | if (!m_dsp.dwt_blocks && !m_dsp.dht_blocks && !FIFO_STOPWAKE(a38)) |
| 450 | 431 | { |
| 451 | 432 | m_task_wakeup |= 1 << task_dwt; |
| r26419 | r26420 | |
| 473 | 454 | * flip-flop at the beginning of horizontal retrace for |
| 474 | 455 | * every scanline. |
| 475 | 456 | */ |
| 476 | | m_dsp.fifo_wr = 0; |
| 477 | | m_dsp.fifo_rd = 0; |
| 457 | m_dsp.wa = 0; |
| 458 | m_dsp.ra = 0; |
| 478 | 459 | m_dsp.dwt_blocks = false; |
| 479 | 460 | // now take the new values from the last SETMODE← |
| 480 | 461 | m_dsp.inverse = GET_SETMODE_INVERSE(m_dsp.setmode) ? 0xffff : 0x0000; |
| 481 | | m_dsp.halfclock = GET_SETMODE_SPEEDY(m_dsp.setmode); |
| 462 | m_dsp.halfclock = GET_SETMODE_SPEEDY(m_dsp.setmode) ? true : false; |
| 482 | 463 | // stop the CPU execution loop from calling unload_word() |
| 483 | 464 | m_unload_time = -1; |
| 484 | 465 | } |
| r26419 | r26420 | |
| 532 | 513 | void alto2_cpu_device::init_disp() |
| 533 | 514 | { |
| 534 | 515 | memset(&m_dsp, 0, sizeof(m_dsp)); |
| 516 | save_item(NAME(m_dsp.state)); |
| 535 | 517 | save_item(NAME(m_dsp.hlc)); |
| 536 | | save_item(NAME(m_dsp.a63)); |
| 537 | | save_item(NAME(m_dsp.a66)); |
| 538 | 518 | save_item(NAME(m_dsp.setmode)); |
| 539 | 519 | save_item(NAME(m_dsp.inverse)); |
| 540 | 520 | save_item(NAME(m_dsp.halfclock)); |
| 541 | | save_item(NAME(m_dsp.clr)); |
| 542 | 521 | save_item(NAME(m_dsp.fifo)); |
| 543 | | save_item(NAME(m_dsp.fifo_wr)); |
| 544 | | save_item(NAME(m_dsp.fifo_rd)); |
| 522 | save_item(NAME(m_dsp.wa)); |
| 523 | save_item(NAME(m_dsp.ra)); |
| 524 | save_item(NAME(m_dsp.a63)); |
| 525 | save_item(NAME(m_dsp.a66)); |
| 545 | 526 | save_item(NAME(m_dsp.dht_blocks)); |
| 546 | 527 | save_item(NAME(m_dsp.dwt_blocks)); |
| 547 | 528 | save_item(NAME(m_dsp.curt_blocks)); |
| r26419 | r26420 | |
| 549 | 530 | save_item(NAME(m_dsp.vblank)); |
| 550 | 531 | save_item(NAME(m_dsp.xpreg)); |
| 551 | 532 | save_item(NAME(m_dsp.csr)); |
| 552 | | save_item(NAME(m_dsp.curword)); |
| 553 | | save_item(NAME(m_dsp.curdata)); |
| 533 | save_item(NAME(m_dsp.curxpos)); |
| 534 | save_item(NAME(m_dsp.cursor0)); |
| 535 | save_item(NAME(m_dsp.cursor1)); |
| 554 | 536 | |
| 555 | 537 | m_disp_a38 = prom_load(machine(), &pl_displ_a38, memregion("displ_a38")->base()); |
| 556 | 538 | m_disp_a63 = prom_load(machine(), &pl_displ_a63, memregion("displ_a63")->base()); |
| r26419 | r26420 | |
| 580 | 562 | m_dsp.a66 = 0; |
| 581 | 563 | m_dsp.setmode = 0; |
| 582 | 564 | m_dsp.inverse = 0; |
| 583 | | m_dsp.halfclock = 0; |
| 584 | | m_dsp.clr = 0; |
| 585 | | m_dsp.fifo_wr = 0; |
| 586 | | m_dsp.fifo_rd = 0; |
| 565 | m_dsp.halfclock = false; |
| 566 | m_dsp.wa = 0; |
| 567 | m_dsp.ra = 0; |
| 587 | 568 | m_dsp.dht_blocks = false; |
| 588 | 569 | m_dsp.dwt_blocks = false; |
| 589 | 570 | m_dsp.curt_blocks = false; |
| r26419 | r26420 | |
| 591 | 572 | m_dsp.vblank = 0; |
| 592 | 573 | m_dsp.xpreg = 0; |
| 593 | 574 | m_dsp.csr = 0; |
| 594 | | m_dsp.curword = 0; |
| 595 | | m_dsp.curdata = 0; |
| 575 | m_dsp.curxpos = 0; |
| 576 | m_dsp.cursor0 = 0; |
| 577 | m_dsp.cursor1 = 0; |
| 596 | 578 | memset(m_dsp.raw_bitmap, 0, sizeof(UINT16) * ALTO2_DISPLAY_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS); |
| 597 | 579 | for (int y = 0; y < ALTO2_DISPLAY_HEIGHT; y++) |
| 598 | 580 | memset(m_dsp.scanline[y], 0, sizeof(UINT8) * ALTO2_DISPLAY_TOTAL_WIDTH); |
branches/alto2/src/emu/cpu/alto2/a2disp.h
| r26419 | r26420 | |
| 174 | 174 | #ifndef _A2DISP_H_ |
| 175 | 175 | #define _A2DISP_H_ |
| 176 | 176 | struct { |
| 177 | | UINT8 state; //!< current state of the display_state_machine() |
| 177 | UINT16 state; //!< current state of the display_state_machine() |
| 178 | 178 | UINT16 hlc; //!< horizontal line counter |
| 179 | | UINT8 a63; //!< most recent value read from the PROM a63 |
| 180 | | UINT8 a66; //!< most recent value read from the PROM a66 |
| 181 | 179 | UINT16 setmode; //!< value written by last SETMODE<- |
| 182 | 180 | UINT16 inverse; //!< set to 0xffff if line is inverse, 0x0000 otherwise |
| 183 | | UINT8 halfclock; //!< set 0 for normal pixel clock, 1 for half pixel clock |
| 184 | | UINT8 clr; //!< set non-zero if any of VBLANK or HBLANK is active (a39a 74S08) |
| 181 | bool halfclock; //!< set 0 for normal pixel clock, 1 for half pixel clock |
| 185 | 182 | UINT16 fifo[ALTO2_DISPLAY_FIFO]; //!< display word fifo |
| 186 | | UINT8 fifo_wr; //!< fifo input pointer (4-bit) |
| 187 | | UINT8 fifo_rd; //!< fifo output pointer (4-bit) |
| 183 | UINT8 wa; //!< fifo input pointer (write address; 4-bit) |
| 184 | UINT8 ra; //!< fifo output pointer (read address; 4-bit) |
| 185 | UINT8 a63; //!< most recent value read from the PROM a63 |
| 186 | UINT8 a66; //!< most recent value read from the PROM a66 |
| 188 | 187 | bool dht_blocks; //!< set non-zero, if the DHT executed BLOCK |
| 189 | 188 | bool dwt_blocks; //!< set non-zero, if the DWT executed BLOCK |
| 190 | 189 | bool curt_blocks; //!< set non-zero, if the CURT executed BLOCK |
| r26419 | r26420 | |
| 192 | 191 | UINT16 vblank; //!< most recent HLC with VBLANK still high (11-bit) |
| 193 | 192 | UINT16 xpreg; //!< cursor cursor x position register (10-bit) |
| 194 | 193 | UINT16 csr; //!< cursor shift register (16-bit) |
| 195 | | UINT32 curword; //!< helper: first cursor word in current scanline |
| 196 | | UINT32 curdata; //!< helper: shifted cursor data (32-bit) |
| 194 | UINT32 curxpos; //!< helper: first cursor word in scanline |
| 195 | UINT16 cursor0; //!< helper: shifted cursor data for left word |
| 196 | UINT16 cursor1; //!< helper: shifted cursor data for right word |
| 197 | 197 | UINT16 *raw_bitmap; //!< array of words of the raw bitmap that is displayed |
| 198 | 198 | UINT8 **scanline; //!< array of scanlines with 1 byte per pixel |
| 199 | 199 | bitmap_ind16 *bitmap; //!< MAME bitmap with 16 bit indices |
| r26419 | r26420 | |
| 286 | 286 | disp_a66_VBLANK_EVEN = (1 << 3) //!< Q4 (010) is VBLANK for the even field (with H1024=0) |
| 287 | 287 | }; |
| 288 | 288 | |
| 289 | | void update_bitmap_word(int x, int y, UINT16 word); //!< update a word in the screen bitmap |
| 289 | void update_bitmap_word(UINT16* bitmap, int x, int y, UINT16 word); //!< update a word in the screen bitmap |
| 290 | 290 | void unload_word(); //!< unload the next word from the display FIFO and shift it to the screen |
| 291 | 291 | void display_state_machine(); //!< function called by the CPU to enter the next display state |
| 292 | 292 | |