branches/alto2/src/emu/cpu/alto2/a2disp.c
| r26335 | r26336 | |
| 32 | 32 | * </PRE> |
| 33 | 33 | */ |
| 34 | 34 | |
| 35 | //! PROM a38 bit O1 is STOPWAKE' (stop DWT if bit is zero) |
| 36 | #define FIFO_STOPWAKE(a38) (0 == (a38 & disp_a38_STOPWAKE) ? true : false) |
| 37 | |
| 38 | //! PROM a38 bit O3 is MBEMPTY' (FIFO is empty if bit is zero) |
| 39 | #define FIFO_MBEMPTY(a38) (0 == (a38 & disp_a38_MBEMPTY) ? true : false) |
| 40 | |
| 35 | 41 | /** |
| 36 | 42 | * @brief emulation of PROM a63 in the display schematics page 8 |
| 37 | 43 | * <PRE> |
| r26335 | r26336 | |
| 97 | 103 | */ |
| 98 | 104 | |
| 99 | 105 | //!< test the HBLANK (horizontal blanking) signal in PROM a63 being high |
| 100 | | #define A63_HBLANK_HI(a) ((a & A63_HBLANK) ? true : false) |
| 106 | #define A63_HBLANK(a) ((a & disp_a63_HBLANK) ? true : false) |
| 101 | 107 | |
| 102 | 108 | //!< test the HSYNC (horizontal synchonisation) signal in PROM a63 being high |
| 103 | | #define A63_HSYNC_HI(a) ((a & A63_HSYNC) ? true : false) |
| 109 | #define A63_HSYNC(a) ((a & disp_a63_HSYNC) ? true : false) |
| 104 | 110 | |
| 105 | 111 | //!< test the SCANEND (scanline end) signal in PROM a63 being high |
| 106 | | #define A63_SCANEND_HI(a) ((a & A63_SCANEND) ? true : false) |
| 112 | #define A63_SCANEND(a) ((a & disp_a63_SCANEND) ? true : false) |
| 107 | 113 | |
| 108 | 114 | //!< test the HLCGATE (horz. line counter gate) signal in PROM a63 being high |
| 109 | | #define A63_HLCGATE_HI(a) ((a & A63_HLCGATE) ? true : false) |
| 115 | #define A63_HLCGATE(a) ((a & disp_a63_HLCGATE) ? true : false) |
| 110 | 116 | |
| 111 | 117 | /** |
| 112 | 118 | * @brief PROM a66 is a 256x4 bit (type 3601) |
| r26335 | r26336 | |
| 122 | 128 | */ |
| 123 | 129 | |
| 124 | 130 | //! test the VSYNC (vertical synchronisation) signal in PROM a66 being high |
| 125 | | #define A66_VSYNC(a) (a & (HLC1024 ? A66_VSYNC_ODD : A66_VSYNC_EVEN) ? false : true) |
| 131 | #define A66_VSYNC(a) (a & (HLC1024 ? disp_a66_VSYNC_ODD : disp_a66_VSYNC_EVEN) ? false : true) |
| 126 | 132 | |
| 127 | 133 | //! test the VBLANK (vertical blanking) signal in PROM a66 being high |
| 128 | | #define A66_VBLANK(a) (a & (HLC1024 ? A66_VBLANK_ODD : A66_VBLANK_EVEN) ? false : true) |
| 134 | #define A66_VBLANK(a) (a & (HLC1024 ? disp_a66_VBLANK_ODD : disp_a66_VBLANK_EVEN) ? false : true) |
| 129 | 135 | |
| 130 | 136 | /** |
| 131 | 137 | * @brief double the bits for a byte (left and right of display word) to a word |
| r26335 | r26336 | |
| 215 | 221 | UINT16* scanline = m_dsp.raw_bitmap + y * ALTO2_DISPLAY_SCANLINE_WORDS; |
| 216 | 222 | |
| 217 | 223 | UINT32 word = m_dsp.inverse; |
| 218 | | if (FIFO_MBEMPTY_0() == 0) { |
| 224 | UINT8 a38 = m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr]; |
| 225 | if (FIFO_MBEMPTY(a38)) { |
| 219 | 226 | LOG((LOG_DISPL,1, " DSP FIFO underrun y:%d x:%d\n", y, x)); |
| 220 | 227 | } else { |
| 221 | 228 | word ^= m_dsp.fifo[m_dsp.fifo_rd]; |
| r26335 | r26336 | |
| 288 | 295 | } |
| 289 | 296 | |
| 290 | 297 | UINT8 a63 = m_disp_a63[m_dsp.state]; |
| 291 | | if (A63_HLCGATE_HI(a63)) { |
| 298 | if (A63_HLCGATE(a63)) { |
| 292 | 299 | /* reset or count horizontal line counters */ |
| 293 | 300 | if (m_dsp.hlc == ALTO2_DISPLAY_HLC_END) |
| 294 | 301 | m_dsp.hlc = ALTO2_DISPLAY_HLC_START; |
| r26335 | r26336 | |
| 348 | 355 | */ |
| 349 | 356 | m_dsp.curt_blocks = false; |
| 350 | 357 | } |
| 351 | | if (!A63_HBLANK_HI(a63) && A63_HBLANK_HI(m_dsp.a63)) { |
| 358 | if (!A63_HBLANK(a63) && A63_HBLANK(m_dsp.a63)) { |
| 352 | 359 | // falling edge of a63 HBLANK starts unloading of FIFO words |
| 353 | 360 | LOG((LOG_DISPL,1, " HBLANK↘ UNLOAD")); |
| 354 | 361 | m_unload_time = ALTO2_DISPLAY_BITTIME(m_dsp.halfclock ? 32 : 16); |
| r26335 | r26336 | |
| 367 | 374 | * if DHT is not blocked, and if the buffer is not full, DWT wakeups |
| 368 | 375 | * are generated. |
| 369 | 376 | */ |
| 370 | | if (!m_dsp.dwt_blocks && !m_dsp.dht_blocks && FIFO_STOPWAKE_0() != 0) { |
| 377 | UINT8 a38 = m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr]; |
| 378 | if (!m_dsp.dwt_blocks && !m_dsp.dht_blocks && !FIFO_STOPWAKE(a38)) { |
| 371 | 379 | m_task_wakeup |= 1 << task_dwt; |
| 372 | 380 | LOG((LOG_DISPL,1, " (wake DWT)")); |
| 373 | 381 | } |
| 374 | 382 | |
| 375 | 383 | // Stop waking the display word task at SCANEND time |
| 376 | | if (A63_SCANEND_HI(a63)) { |
| 384 | if (A63_SCANEND(a63)) { |
| 377 | 385 | LOG((LOG_DISPL,1, " SCANEND")); |
| 378 | 386 | m_task_wakeup &= ~(1 << task_dwt); |
| 379 | 387 | } |
| 380 | 388 | |
| 381 | | LOG((LOG_DISPL,1, "%s", A63_HBLANK_HI(a63) ? " HBLANK": "")); |
| 389 | LOG((LOG_DISPL,1, "%s", A63_HBLANK(a63) ? " HBLANK": "")); |
| 382 | 390 | |
| 383 | | if (A63_HSYNC_HI(a63)) { |
| 384 | | if (!A63_HSYNC_HI(m_dsp.a63)) { |
| 391 | if (A63_HSYNC(a63)) { |
| 392 | if (!A63_HSYNC(m_dsp.a63)) { |
| 385 | 393 | LOG((LOG_DISPL,1, " HSYNC↗ (CLRBUF)")); |
| 386 | 394 | /* |
| 387 | 395 | * The hardware sets the buffer empty and clears the DWT block |
| r26335 | r26336 | |
| 401 | 409 | } |
| 402 | 410 | } |
| 403 | 411 | // FIXME: jiggly cursor issue; try to wake up CURT at the end of HSYNC |
| 404 | | if (A63_HSYNC_HI(m_dsp.a63) && !A63_HSYNC_HI(a63)) { |
| 412 | if (A63_HSYNC(m_dsp.a63) && !A63_HSYNC(a63)) { |
| 405 | 413 | /* |
| 406 | 414 | * CLRBUF' also resets the 2nd cursor task block flip flop, |
| 407 | 415 | * which is built from two NAND gates a30c and a30d (74H00). |
branches/alto2/src/emu/cpu/alto2/a2disp.h
| r26335 | r26336 | |
| 226 | 226 | |
| 227 | 227 | //! output bits of PROM A38 |
| 228 | 228 | enum { |
| 229 | | A38_STOPWAKE = (1 << 1), |
| 230 | | A38_MBEMPTY = (1 << 3) |
| 229 | disp_a38_STOPWAKE = (1 << 1), |
| 230 | disp_a38_MBEMPTY = (1 << 3) |
| 231 | 231 | }; |
| 232 | 232 | |
| 233 | | //! PROM a38 bit O1 is STOPWAKE' (stop DWT if bit is zero) |
| 234 | | inline UINT8 FIFO_STOPWAKE_0() { return m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr] & A38_STOPWAKE; } |
| 235 | | |
| 236 | | //! PROM a38 bit O3 is MBEMPTY' (FIFO is empty if bit is zero) |
| 237 | | inline UINT8 FIFO_MBEMPTY_0() { return m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr] & A38_MBEMPTY; } |
| 238 | | |
| 239 | 233 | /** |
| 240 | 234 | * @brief emulation of PROM a63 in the display schematics page 8 |
| 241 | 235 | * <PRE> |
| r26335 | r26336 | |
| 266 | 260 | UINT8* m_disp_a63; |
| 267 | 261 | |
| 268 | 262 | enum { |
| 269 | | A63_HBLANK = (1 << 0), //!< PROM a63 B0 is latched as HBLANK signal |
| 270 | | A63_HSYNC = (1 << 1), //!< PROM a63 B1 is latched as HSYNC signal |
| 271 | | A63_A0 = (1 << 2), //!< PROM a63 B2 is the latched next address bit A0 |
| 272 | | A63_A1 = (1 << 3), //!< PROM a63 B3 is the latched next address bit A1 |
| 273 | | A63_A2 = (1 << 4), //!< PROM a63 B4 is the latched next address bit A2 |
| 274 | | A63_A3 = (1 << 5), //!< PROM a63 B5 is the latched next address bit A3 |
| 275 | | A63_SCANEND = (1 << 6), //!< PROM a63 B6 SCANEND signal, which resets the FIFO counters |
| 276 | | A63_HLCGATE = (1 << 7) //!< PROM a63 B7 HLCGATE signal, which enables counting the HLC |
| 263 | disp_a63_HBLANK = (1 << 0), //!< PROM a63 B0 is latched as HBLANK signal |
| 264 | disp_a63_HSYNC = (1 << 1), //!< PROM a63 B1 is latched as HSYNC signal |
| 265 | disp_a63_A0 = (1 << 2), //!< PROM a63 B2 is the latched next address bit A0 |
| 266 | disp_a63_A1 = (1 << 3), //!< PROM a63 B3 is the latched next address bit A1 |
| 267 | disp_a63_A2 = (1 << 4), //!< PROM a63 B4 is the latched next address bit A2 |
| 268 | disp_a63_A3 = (1 << 5), //!< PROM a63 B5 is the latched next address bit A3 |
| 269 | disp_a63_SCANEND = (1 << 6), //!< PROM a63 B6 SCANEND signal, which resets the FIFO counters |
| 270 | disp_a63_HLCGATE = (1 << 7) //!< PROM a63 B7 HLCGATE signal, which enables counting the HLC |
| 277 | 271 | }; |
| 278 | 272 | |
| 279 | 273 | /** |
| r26335 | r26336 | |
| 282 | 276 | * PROM a66 is a 256x4 bit (type 3601), containing the vertical blank + synch. |
| 283 | 277 | * Address lines are driven by H[1] to H[128] of the the horz. line counters. |
| 284 | 278 | * The PROM is enabled whenever H[256] and H[512] are both 0. |
| 285 | | * |
| 286 | | * Q1 (001) is VSYNC for the odd field (with H1024=1) |
| 287 | | * Q2 (002) is VSYNC for the even field (with H1024=0) |
| 288 | | * Q3 (004) is VBLANK for the odd field (with H1024=1) |
| 289 | | * Q4 (010) is VBLANK for the even field (with H1024=0) |
| 290 | 279 | */ |
| 291 | 280 | UINT8* m_disp_a66; |
| 292 | 281 | |
| 293 | 282 | enum { |
| 294 | | A66_VSYNC_ODD = (1 << 0), |
| 295 | | A66_VSYNC_EVEN = (1 << 1), |
| 296 | | A66_VBLANK_ODD = (1 << 2), |
| 297 | | A66_VBLANK_EVEN = (1 << 3) |
| 283 | disp_a66_VSYNC_ODD = (1 << 0), //!< Q1 (001) is VSYNC for the odd field (with H1024=1) |
| 284 | disp_a66_VSYNC_EVEN = (1 << 1), //!< Q2 (002) is VSYNC for the even field (with H1024=0) |
| 285 | disp_a66_VBLANK_ODD = (1 << 2), //!< Q3 (004) is VBLANK for the odd field (with H1024=1) |
| 286 | disp_a66_VBLANK_EVEN = (1 << 3) //!< Q4 (010) is VBLANK for the even field (with H1024=0) |
| 298 | 287 | }; |
| 299 | 288 | |
| 300 | 289 | void update_bitmap_word(int x, int y, UINT16 word); //!< update a word in the screen bitmap |