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 |