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 | /** |