branches/alto2/src/emu/cpu/alto2/a2disp.c
r26332 | r26333 | |
313 | 313 | |
314 | 314 | LOG((LOG_DISPL,1, " VBLANK")); |
315 | 315 | |
316 | | /* VSYNC is always within VBLANK */ |
| 316 | // VSYNC is always within VBLANK, thus we handle it only here |
317 | 317 | if (A66_VSYNC(a66)) { |
318 | 318 | if (!A66_VSYNC(m_dsp.a66)) { |
319 | | LOG((LOG_DISPL,1, " VSYNC/ (wake DVT)")); |
| 319 | LOG((LOG_DISPL,1, " VSYNC↗ (wake DVT)")); |
320 | 320 | /* |
321 | 321 | * The display vertical task DVT is awakened once per field, |
322 | 322 | * at the beginning of vertical retrace. |
323 | 323 | */ |
324 | 324 | m_task_wakeup |= 1 << task_dvt; |
325 | | // sdl_update(HLC1024()); // FIXME: upade odd or even field |
| 325 | // TODO: upade odd or even field of the internal bitmap |
326 | 326 | } else { |
327 | 327 | LOG((LOG_DISPL,1, " VSYNC")); |
328 | 328 | } |
329 | 329 | } |
330 | 330 | } else { |
331 | 331 | if (A66_VBLANK(m_dsp.a66)) { |
332 | | /** |
| 332 | /* |
333 | 333 | * VBLANKPULSE: |
334 | 334 | * The display horizontal task DHT is awakened once at the |
335 | 335 | * beginning of each field, and thereafter whenever the |
r26332 | r26333 | |
349 | 349 | m_dsp.curt_blocks = false; |
350 | 350 | } |
351 | 351 | if (!A63_HBLANK_HI(a63) && A63_HBLANK_HI(m_dsp.a63)) { |
352 | | /* falling edge of a63 HBLANK starts unload */ |
353 | | LOG((LOG_DISPL,1, " HBLANK\\ UNLOAD")); |
| 352 | // falling edge of a63 HBLANK starts unloading of FIFO words |
| 353 | LOG((LOG_DISPL,1, " HBLANK↘ UNLOAD")); |
354 | 354 | m_unload_time = ALTO2_DISPLAY_BITTIME(m_dsp.halfclock ? 32 : 16); |
355 | 355 | m_unload_word = 0; |
356 | 356 | #if DEBUG_DISPLAY_TIMING |
r26332 | r26333 | |
363 | 363 | |
364 | 364 | /* |
365 | 365 | * The wakeup request for the display word task (DWT) is controlled by |
366 | | * the state of the 16 word buffer. If DWT has not executed a BLOCK, |
| 366 | * the state of the 16 word FIFO. If DWT has not executed a BLOCK, |
367 | 367 | * if DHT is not blocked, and if the buffer is not full, DWT wakeups |
368 | 368 | * are generated. |
369 | 369 | */ |
r26332 | r26333 | |
372 | 372 | LOG((LOG_DISPL,1, " (wake DWT)")); |
373 | 373 | } |
374 | 374 | |
| 375 | // Stop waking the display word task at SCANEND time |
375 | 376 | if (A63_SCANEND_HI(a63)) { |
376 | 377 | LOG((LOG_DISPL,1, " SCANEND")); |
377 | 378 | m_task_wakeup &= ~(1 << task_dwt); |
r26332 | r26333 | |
381 | 382 | |
382 | 383 | if (A63_HSYNC_HI(a63)) { |
383 | 384 | if (!A63_HSYNC_HI(m_dsp.a63)) { |
384 | | LOG((LOG_DISPL,1, " HSYNC/ (CLRBUF)")); |
| 385 | LOG((LOG_DISPL,1, " HSYNC↗ (CLRBUF)")); |
385 | 386 | /* |
386 | 387 | * The hardware sets the buffer empty and clears the DWT block |
387 | 388 | * flip-flop at the beginning of horizontal retrace for |
r26332 | r26333 | |
390 | 391 | m_dsp.fifo_wr = 0; |
391 | 392 | m_dsp.fifo_rd = 0; |
392 | 393 | m_dsp.dwt_blocks = false; |
393 | | /* now take the new values from the last setmode */ |
| 394 | // now take the new values from the last SETMODE← |
394 | 395 | m_dsp.inverse = GET_SETMODE_INVERSE(m_dsp.setmode) ? 0xffff : 0x0000; |
395 | 396 | m_dsp.halfclock = GET_SETMODE_SPEEDY(m_dsp.setmode); |
396 | | /* stop the CPU from calling unload_word() */ |
| 397 | // stop the CPU from calling unload_word() |
397 | 398 | m_unload_time = -1; |
398 | 399 | } else { |
399 | 400 | LOG((LOG_DISPL,1, " HSYNC")); |
400 | 401 | } |
401 | 402 | } |
402 | | // FIXME: try at the end of HSYNC |
| 403 | // FIXME: jiggly cursor issue; try to wake up CURT at the end of HSYNC |
403 | 404 | if (A63_HSYNC_HI(m_dsp.a63) && !A63_HSYNC_HI(a63)) { |
404 | | /* |
405 | | * CLRBUF' also resets the 2nd cursor task block flip flop, |
406 | | * which is built from two NAND gates a30c and a30d (74H00). |
407 | | * If both flip flops are reset, the NOR gate a20d (74S02) |
408 | | * decodes this as WAKECURT signal. |
409 | | */ |
410 | | m_dsp.curt_wakeup = true; |
| 405 | /* |
| 406 | * CLRBUF' also resets the 2nd cursor task block flip flop, |
| 407 | * which is built from two NAND gates a30c and a30d (74H00). |
| 408 | * If both flip flops are reset, the NOR gate a20d (74S02) |
| 409 | * decodes this as WAKECURT signal. |
| 410 | */ |
| 411 | m_dsp.curt_wakeup = true; |
411 | 412 | } |
412 | 413 | |
413 | 414 | |
branches/alto2/src/emu/cpu/alto2/alto2cpu.c
r26332 | r26333 | |
86 | 86 | alto2_cpu_device::alto2_cpu_device(const machine_config& mconfig, const char* tag, device_t* owner, UINT32 clock) : |
87 | 87 | cpu_device(mconfig, ALTO2, "Xerox Alto-II", tag, owner, clock, "alto2", __FILE__), |
88 | 88 | #if ALTO2_DEBUG |
89 | | m_log_types(LOG_ETH), |
| 89 | m_log_types(LOG_DISK), |
90 | 90 | m_log_level(8), |
91 | 91 | m_log_newline(true), |
92 | 92 | #endif |
r26332 | r26333 | |
2505 | 2505 | m_next = X_RDBITS(m_mir, 32, NEXT0, NEXT9) | m_next2; |
2506 | 2506 | m_next2 = X_RDBITS(RD_CROM(m_next), 32, NEXT0, NEXT9) | (m_next2 & ~ALTO2_UCODE_PAGE_MASK); |
2507 | 2507 | LOG((LOG_CPU,2,"%s-%04o: %011o r:%02o aluf:%02o bs:%02o f1:%02o f2:%02o t:%o l:%o next:%05o next2:%05o\n", |
2508 | | task_name(m_task), m_mpc, m_mir, m_rsel, m_d_aluf, m_d_bs, m_d_f1, m_d_f2, MIR_T(m_mir), MIR_L(m_mir), m_next, m_next2)); |
| 2508 | task_name(m_task), m_mpc, m_mir, m_rsel, m_d_aluf, m_d_bs, m_d_f1, m_d_f2, m_d_loadt, m_d_loadl, m_next, m_next2)); |
2509 | 2509 | debugger_instruction_hook(this, m_mpc); |
2510 | 2510 | |
2511 | 2511 | /* |
r26332 | r26333 | |
2815 | 2815 | if (do_bs) |
2816 | 2816 | ((*this).*m_bs[1][m_task][m_d_bs])(); |
2817 | 2817 | |
2818 | | // update L register and LALUC0, and also M register, if a RAM related task is active |
| 2818 | // update T register, if LOADT is set |
| 2819 | if (m_d_loadt) { |
| 2820 | m_cram_addr = m_alu; // latch CRAM address |
| 2821 | if (flags & TSELECT) { |
| 2822 | m_t = m_alu; // T source is ALU |
| 2823 | LOG((LOG_CPU,2, " T← ALU (%#o)\n", m_alu)); |
| 2824 | } else { |
| 2825 | m_t = m_bus; // T source is BUS |
| 2826 | LOG((LOG_CPU,2, " T← BUS (%#o)\n", m_bus)); |
| 2827 | } |
| 2828 | } |
| 2829 | |
| 2830 | // update L register and LALUC0 |
2819 | 2831 | if (m_d_loadl) { |
2820 | 2832 | m_l = m_alu; // load L from ALU |
2821 | 2833 | if (flags & ALUM) { |
2822 | 2834 | m_laluc0 = 0; // logic operation - latch 0 |
2823 | 2835 | LOG((LOG_CPU,2, " L← ALU (%#o); LALUC0← %o\n", m_alu, 0)); |
2824 | 2836 | } else { |
2825 | | m_laluc0 = m_aluc0; // logic operation - latch carry |
| 2837 | m_laluc0 = m_aluc0; // arithmethic operation - latch carry |
2826 | 2838 | LOG((LOG_CPU,2, " L← ALU (%#o); LALUC0← ALUC0 (%o)\n", m_alu, m_aluc0)); |
2827 | 2839 | } |
| 2840 | // update M (MYL) register, if a RAM related task is active |
2828 | 2841 | if (m_ram_related[m_task]) { |
2829 | 2842 | m_m = m_alu; // load M from ALU, if 'GOODTASK' |
2830 | 2843 | m_s[m_s_reg_bank[m_task]][0] = m_alu; // also writes to S[bank][0], which can't be read |
r26332 | r26333 | |
2832 | 2845 | } |
2833 | 2846 | } |
2834 | 2847 | |
| 2848 | // handle task switching |
2835 | 2849 | if (m_task != m_next2_task) { |
2836 | 2850 | /* switch now? */ |
2837 | 2851 | if (m_task == m_next_task) { |
r26332 | r26333 | |
2851 | 2865 | } |
2852 | 2866 | } |
2853 | 2867 | |
2854 | | // update T register, if LOADT is set |
2855 | | if (m_d_loadt) { |
2856 | | m_cram_addr = m_alu; // latch CRAM address |
2857 | | if (flags & TSELECT) { |
2858 | | m_t = m_alu; // T source is ALU |
2859 | | LOG((LOG_CPU,2, " T← ALU (%#o)\n", m_alu)); |
2860 | | } else { |
2861 | | m_t = m_bus; // T source is BUS |
2862 | | LOG((LOG_CPU,2, " T← BUS (%#o)\n", m_bus)); |
2863 | | } |
2864 | | } |
2865 | | |
2866 | 2868 | /* |
2867 | 2869 | * Subtract the microcycle time from the display time accu. |
2868 | 2870 | * If it underflows, call the display state machine and add |
branches/alto2/src/emu/cpu/alto2/a2curt.c
r26332 | r26333 | |
25 | 25 | void alto2_cpu_device::f2_late_load_xpreg() |
26 | 26 | { |
27 | 27 | m_dsp.xpreg = X_RDBITS(m_bus,16,6,15); |
28 | | LOG((LOG_CURT,2," XPREG← BUS[6-15] (%#o)\n", m_dsp.xpreg)); |
| 28 | LOG((LOG_CURT, 9," XPREG← BUS[6-15] (%#o)\n", m_dsp.xpreg)); |
29 | 29 | } |
30 | 30 | |
31 | 31 | /** |
r26332 | r26333 | |
48 | 48 | void alto2_cpu_device::f2_late_load_csr() |
49 | 49 | { |
50 | 50 | m_dsp.csr = m_bus; |
51 | | LOG((LOG_CURT,2," CSR← BUS (%#o)\n", m_dsp.csr)); |
52 | | int x = 1023 - m_dsp.xpreg; \ |
53 | | m_dsp.curdata = m_dsp.csr << (16 - (x & 15)); \ |
54 | | m_dsp.curword = x / 16; \ |
| 51 | LOG((LOG_CURT, m_dsp.csr ? 2 : 9," CSR← BUS (%#o)\n", m_dsp.csr)); |
55 | 52 | } |
56 | 53 | |
57 | 54 | /** |
r26332 | r26333 | |
61 | 58 | { |
62 | 59 | m_task_wakeup &= ~(1 << m_task); |
63 | 60 | m_dsp.curt_wakeup = false; |
| 61 | int x = 01777 - m_dsp.xpreg; |
| 62 | m_dsp.curdata = m_dsp.csr << (16 - (x & 15)); |
| 63 | m_dsp.curword = x / 16; |
64 | 64 | } |
65 | 65 | |
66 | 66 | /** @brief initialize the cursor task F1 and F2 functions */ |
branches/alto2/src/emu/cpu/alto2/a2ram.c
r26332 | r26333 | |
16 | 16 | |
17 | 17 | //! direct write access to the microcode CRAM |
18 | 18 | #define WR_CRAM(addr,data) do { \ |
19 | | *reinterpret_cast<UINT32 *>(m_ucode_cram + addr * 4) = data; \ |
| 19 | *reinterpret_cast<UINT32 *>(m_ucode_cram + addr * 4) = data; \ |
20 | 20 | } while (0) |
21 | 21 | |
22 | 22 | /** |
r26332 | r26333 | |
158 | 158 | if (m_d_rsel) { |
159 | 159 | UINT8 bank = m_s_reg_bank[m_task]; |
160 | 160 | r = m_s[bank][m_d_rsel]; |
161 | | LOG((LOG_RAM,2," ←S%02o; bus &= S[%o][%02o] (%#o)\n", reg, bank, reg, r)); |
| 161 | LOG((LOG_RAM,2," ←S%02o; bus &= S[%o][%02o] (%#o)\n", m_d_rsel, bank, m_d_rsel, r)); |
162 | 162 | } else { |
163 | 163 | r = m_m; |
164 | | LOG((LOG_RAM,2," ←S%02o; bus &= M (%#o)\n", reg, r)); |
| 164 | LOG((LOG_RAM,2," ←S%02o; bus &= M (%#o)\n", m_d_rsel, r)); |
165 | 165 | } |
166 | 166 | m_bus &= r; |
167 | 167 | } |
r26332 | r26333 | |
172 | 172 | void alto2_cpu_device::bs_early_load_sreg() |
173 | 173 | { |
174 | 174 | int r = 0; /* ??? */ |
175 | | LOG((LOG_RAM,2," S%02o← BUS &= garbage (%#o)\n", MIR_RSEL(m_mir), r)); |
| 175 | LOG((LOG_RAM,2," S%02o← BUS &= garbage (%#o)\n", m_d_rsel, r)); |
176 | 176 | m_bus &= r; |
177 | 177 | } |
178 | 178 | |
r26332 | r26333 | |
183 | 183 | { |
184 | 184 | UINT8 bank = m_s_reg_bank[m_task]; |
185 | 185 | m_s[bank][m_d_rsel] = m_m; |
186 | | LOG((LOG_RAM,2," S%02o← S[%o][%02o] := %#o\n", reg, bank, reg, m_m)); |
| 186 | LOG((LOG_RAM,2," S%02o← S[%o][%02o] := %#o\n", m_d_rsel, bank, m_d_rsel, m_m)); |
187 | 187 | } |
188 | 188 | |
189 | 189 | /** |