diff --git a/10.01_base/2_src/arm/unibusadapter.cpp b/10.01_base/2_src/arm/unibusadapter.cpp index f6fc29d..74a493d 100644 --- a/10.01_base/2_src/arm/unibusadapter.cpp +++ b/10.01_base/2_src/arm/unibusadapter.cpp @@ -237,9 +237,8 @@ bool unibusadapter_c::register_device(unibusdevice_c& device) { if (cpu) { assert(the_cpu == NULL); // only one allowed! the_cpu = cpu; - // TODO: PRU code debuggen - //mailbox->cpu_enable = 1 ; - //mailbox_execute(ARM2PRU_CPU_ENABLE) ; + mailbox->cpu_enable = 1 ; + mailbox_execute(ARM2PRU_CPU_ENABLE) ; } return true; } @@ -765,14 +764,21 @@ void unibusadapter_c::cpu_DATA_transfer(dma_request_c& dma_request, uint8_t unib // do the transfer. Wait until concurrent device DMA/INTR complete do { - while (mailbox->arbitrator.device_BBSY) - timeout.wait_us(100); + while (mailbox->arbitrator.device_BBSY) { + timeout.wait_us(10); + // This blocks the CPU thread. + // Device threads continue and are waiting for End of DMA/INTR + // PRU performs DMA/INTR) and master_arbitrator clears device_BBSY. + // PRU cpu logic responds as INTR_slave + } mailbox->arbitrator.cpu_BBSY = true; // mark as "initiated by CPU, not by device" success = mailbox_execute(ARM2PRU_DMA); // a device may have acquired the bus concurrently, - // then ARM2PRU_DMA is answered with an error + // then ARM2PRU_DMA is answered with error PRU2ARM_DMA_CPU_TRANSFER_BLOCKED. // infinite time may have passed after that check above } while (!success); + + // wait for PRU complete event, no clear why that double lock() is working anyhow! pthread_mutex_lock(&cpu_data_transfer_request->complete_mutex); // DMA() is blocking: Wait for request to finish. @@ -1068,7 +1074,6 @@ void unibusadapter_c::worker(unsigned instance) { bool dclo_falling_edge = false; bool aclo_raising_edge = false; bool aclo_falling_edge = false; - // DEBUG("mailbox->events: mask=0x%x", mailbox->events.eventmask); if (!EVENT_IS_ACKED(*mailbox, init)) { any_event = true; // robust: any change in ACLO/DCL=INIT updates state of all 3. diff --git a/10.01_base/2_src/pru1/pru1_main_unibus.c b/10.01_base/2_src/pru1/pru1_main_unibus.c index 8976818..18bd2c2 100644 --- a/10.01_base/2_src/pru1/pru1_main_unibus.c +++ b/10.01_base/2_src/pru1/pru1_main_unibus.c @@ -79,7 +79,7 @@ other GRANTS - monitoring INIT and AC_LO/DC_LO - watching fpr AMR2PRU commands - 2. "BBSYWAIT": UNibone got PRIORITY GRAMT, has set SACK and released BR/NPR + 2. "BBSYWAIT": UniBone got PRIORITY GRAMT, has set SACK and released BR/NPR waits for current BUS master to relaeasy BBSY (ony DATI/DATO cycle max) - SACK active: no GRANT forward necessary, no arbitration necessary - INIT is monitored by DMA statemachine: no DC_LO/INIT monitoring necessary @@ -219,7 +219,7 @@ void main(void) { } else { // Emulated device: raise request for emulated or physical Arbitrator. // request DMA, arbitrator must've been selected with ARM2PRU_ARB_MODE_* - sm_arb.request_mask |= PRIORITY_ARBITRATION_BIT_NP; + sm_arb.device_request_mask |= PRIORITY_ARBITRATION_BIT_NP; // sm_arb_worker() evaluates this,extern Arbitrator raises Grant, excution starts in future loop // end of DMA is signaled to ARM with signal @@ -238,7 +238,7 @@ void main(void) { // request INTR, arbitrator must've been selected with ARM2PRU_ARB_MODE_* // start one INTR cycle. May be raised in midst of slave cycle // by ARM, if access to "active" register triggers INTR. - sm_arb.request_mask |= mailbox.intr.priority_arbitration_bit; + sm_arb.device_request_mask |= mailbox.intr.priority_arbitration_bit; // sm_arb_worker() evaluates this, extern Arbitrator raises Grant, // vector of GRANted level is transfered with statemachine sm_intr_master @@ -254,7 +254,7 @@ void main(void) { case ARM2PRU_INTR_CANCEL: // cancels one or more INTR requests. If already Granted, the GRANT is forwarded, // and canceled by reaching a "SACK turnaround terminator" or "No SACK TIMEOUT" in the arbitrator. - sm_arb.request_mask &= ~mailbox.intr.priority_arbitration_bit; + sm_arb.device_request_mask &= ~mailbox.intr.priority_arbitration_bit; // no completion event, could interfer with other INTRs? mailbox.arm2pru_req = ARM2PRU_NONE; // done break; diff --git a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c index 5ca8091..52fd2fa 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c @@ -99,7 +99,7 @@ statemachine_arbitration_t sm_arb; void sm_arb_reset() { // cleanup: clear all REQUESTS and SACK buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK | BIT(5), 0); - sm_arb.request_mask = 0; + sm_arb.device_request_mask = 0; sm_arb.bbsy_wait_grant_mask = 0; sm_arb.arbitrator_grant_mask = 0; @@ -123,13 +123,56 @@ uint8_t sm_arb_worker_none() { ; // ignore BR* INTR requests, only ack DMA. - if (sm_arb.request_mask & PRIORITY_ARBITRATION_BIT_NP) { - sm_arb.request_mask &= ~PRIORITY_ARBITRATION_BIT_NP; + if (sm_arb.device_request_mask & PRIORITY_ARBITRATION_BIT_NP) { + sm_arb.device_request_mask &= ~PRIORITY_ARBITRATION_BIT_NP; return PRIORITY_ARBITRATION_BIT_NP; } else return 0; } +/* Helper: + Wait for GRANTs requested by emulated devices, + then raise SACK, + then wait for BBSY deasserted. + Calling this is only 2*5 ns extra. + "grant_mask": all GRANT lines received from physical or emulated CPU. + result: 0 if busy, else bitmask with one bit set for GRANTed and SACKEd request. + */ +static uint8_t sm_arb_worker_device_grant_sack_bbsy(uint8_t grant_mask) { + + if (sm_arb.bbsy_wait_grant_mask == 0) { + // State 1: Wait For GRANT: + // process the requested grant for an open requests. + grant_mask &= sm_arb.device_request_mask; + if (grant_mask) { + // one of our requests was granted: + // set SACK + // AND simultaneously clear granted requests BR*/NPR + // BIT(5): SACK mask and level + buslatches_setbits(1, (PRIORITY_ARBITRATION_BIT_MASK & sm_arb.device_request_mask) | BIT(5), + ~grant_mask | BIT(5)) + ; + + // clear granted requests internally + sm_arb.device_request_mask &= ~grant_mask; + // UNIBUS DATA section is indepedent: MSYN, SSYN, BBSY may still be active. + // -> DMA and INTR statemachine must wait for BBSY. + + // Arbitrator should remove GRANT now. Data section on Bus still BBSY + sm_arb.bbsy_wait_grant_mask = grant_mask; // next is State 2: wait for BBSY clear + } + return 0; // no GRANT for us, or wait for BBSY + } else { + // State 2: wait for BBSY to clear + if (buslatches_getbyte(1) & BIT(6)) + return 0; // BBSY still set + grant_mask = sm_arb.bbsy_wait_grant_mask; + sm_arb.bbsy_wait_grant_mask = 0; // Next State is 1 + + return grant_mask; // signal what request we got granted. + } +} + /* worker_client: Issue request to extern Arbitrator (PDP-11 CPU). Watch for GRANTs on the bus signal lines, then raise SACK. @@ -139,52 +182,25 @@ uint8_t sm_arb_worker_none() { But it guarantees caller may now issue an DMA or INTR. */ uint8_t sm_arb_worker_client() { - uint8_t grant_mask; // Always update UNIBUS BR/NPR lines, are ORed with requests from other devices. - buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.request_mask) + buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask) ; - // read GRANT IN lines from CPU (Arbitrator). Only one at a time may be active + // read GRANT IN lines from CPU (Arbitrator). + // Only one at a time may be active, else arbitrator malfucntion. // Arbitrator asserts SACK is inactive // latch[0]: BG signals are inverted, "get" is non-inverting: bit = active signal. // "set" is inverting! - grant_mask = buslatches_getbyte(0) & PRIORITY_ARBITRATION_BIT_MASK; // read GRANT IN + uint8_t grant_mask = buslatches_getbyte(0) & PRIORITY_ARBITRATION_BIT_MASK; // read GRANT IN // forward un-requested GRANT IN to GRANT OUT for other cards on neighbor slots - buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK & ~sm_arb.request_mask, ~grant_mask) + buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK & ~sm_arb.device_request_mask, ~grant_mask) ; - if (sm_arb.bbsy_wait_grant_mask == 0) { - // State 1: Wait For GRANT: - // process the requested grant for an open requests. - grant_mask &= sm_arb.request_mask; - if (grant_mask) { - // one of our requests was granted: - // set SACK - // AND simultaneously Clear granted requests BR*/NPR - // BIT(5): SACK mask and level - buslatches_setbits(1, (PRIORITY_ARBITRATION_BIT_MASK & sm_arb.request_mask) | BIT(5), - ~grant_mask | BIT(5)) - ; - - // clear granted requests internally - sm_arb.request_mask &= ~grant_mask; - // Arbitrator should remove GRANT now. Data section on Bus still BBSY - sm_arb.bbsy_wait_grant_mask = grant_mask; // next is State 2: wait for BBSY clear - } - return 0; // no GRANT for us, or wait for BBSY - } else { - // wait for BBSY to clear - if (buslatches_getbyte(1) & BIT(6)) - return 0; // BBSY still set - grant_mask = sm_arb.bbsy_wait_grant_mask; - sm_arb.bbsy_wait_grant_mask = 0; // Next State is 1 - - return grant_mask; // signal what request we got granted. - } - // UNIBUS DATA section is indepedent: MSYN, SSYN, BBSY may still be active. - // -> DMA and INTR statemachine must wait for BBSY. + // GRANT forwarding complete, + // handle GRANT/SACK/BBSY for emulated devices + return sm_arb_worker_device_grant_sack_bbsy(grant_mask); } /* "worker_master" @@ -198,28 +214,38 @@ uint8_t sm_arb_worker_client() { - GRANT BR* in descending priority, when CPU execution level allows . - Cancel GRANT, if no device responds with SACK within timeout period */ - +#if 0 // decode set of requests lines to highest INTR level // BR4 = 0x01 -> 4, BR5 = 0x02 -> 5, etc. // Index only PRIORITY_ARBITRATION_INTR_MASK, [0] invalid. -static const uint8_t requests_2_highests_intr[16] = { // +static uint8_t requests_2_highests_intr[16] = { // /*0000*/9, /*0001*/4, /*0010*/5, /*0011*/5, /*0100*/6, /*0101*/6, /*0110*/6, /*0111*/6, - /*1000*/7, /*1001*/7, /*1010*/7, /*0011*/7, - /*1100*/7, /*1101*/7, /*1110*/7, /*0111*/7 }; + /*1000*/7, /*1001*/7, /*1010*/7, /*1011*/7, + /*1100*/7, /*1101*/7, /*1110*/7, /*1111*/7 }; +#endif uint8_t sm_arb_worker_master() { /******* arbitrator logic *********/ uint8_t intr_request_mask; uint8_t latch1val = buslatches_getbyte(1); + // monitor BBSY + if (!(latch1val & BIT(5)) && !(latch1val & BIT(6))) { + // neither SACK nor BBSY: bus is not used by device. + // exclude "SACK and NOT BBSY": device has not yet raised BBSY + mailbox.arbitrator.device_BBSY = false ; + } + + if (latch1val & BIT(5)) { // SACK set by a device // priority arbitration disabled, remove GRANT. sm_arb.arbitrator_grant_mask = 0; // CPU looses now access to UNIBUS after current cycle - mailbox.arbitrator.device_BBSY = 1; // DATA section used by device now + mailbox.arbitrator.device_BBSY = true; // DATA section used by device now + //NONO: BBSY ! No SACK for parts of DMA cycle . timeout_cleanup(TIMEOUT_SACK); } else if (latch1val & PRIORITY_ARBITRATION_BIT_NP) { @@ -229,76 +255,52 @@ uint8_t sm_arb_worker_master() { sm_arb.arbitrator_grant_mask = PRIORITY_ARBITRATION_BIT_NP; timeout_set(TIMEOUT_SACK, MILLISECS(ARB_MASTER_SACK_TIMOUT_MS)); } - } else if ((intr_request_mask = latch1val & PRIORITY_ARBITRATION_INTR_MASK)) { + } else if ((intr_request_mask = (latch1val & PRIORITY_ARBITRATION_INTR_MASK))) { // device BR4,BR5,BR6 or BR7 if (sm_arb.arbitrator_grant_mask == 0) { // no 2nd device's request may modify GRANT before 1st device acks with SACK // GRANT request depending on CPU priority level - // find highest request line - uint8_t requested_intr_level = requests_2_highests_intr[intr_request_mask]; - + // find level # of highest request in bitmask + // lmbd() = LeftMostBitDetect(0x01)-> 0 (0x03) -> 1, (0x07) -> 2, 0x0f -> 3 + // BR4 = 0x01 -> 4, BR5 = 0x02 -> 5, etc. + uint8_t requested_intr_level = __lmbd(intr_request_mask,1) + 4 ; // compare against cpu run level 4..7 // but do not GRANT anything if emulated CPU did not fetch new PSW yet, // then cpu_priority_level is invalid - if (requested_intr_level > mailbox.arbitrator.cpu_priority_level - && requested_intr_level != CPU_PRIORITY_LEVEL_FETCHING) { + if (requested_intr_level > mailbox.arbitrator.cpu_priority_level // + && requested_intr_level != CPU_PRIORITY_LEVEL_FETCHING) { // GRANT request, set GRANT line: - // BG4 is signal bit maskl 0x01, etc ... + // BG4 is signal bit mask 0x01, 0x02, etc ... +//requested_intr_level = 4 ; sm_arb.arbitrator_grant_mask = BIT(requested_intr_level - 4); + // 320 ns ??? timeout_set(TIMEOUT_SACK, MILLISECS(ARB_MASTER_SACK_TIMOUT_MS)); } } } else if (sm_arb.arbitrator_grant_mask && timeout_reached(TIMEOUT_SACK)) { // no SACK, no requests, but GRANTs: SACK timeout? sm_arb.arbitrator_grant_mask = 0; - mailbox.arbitrator.device_BBSY = 0; // started by SACK, but UNIBUS DATA section not used by device + mailbox.arbitrator.device_BBSY = false; // started by SACK, but UNIBUS DATA section not used by device timeout_cleanup(TIMEOUT_SACK); } + // put the single BR/NPR GRANT onto BUS lines. BGOUT inverted. + buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK, ~sm_arb.arbitrator_grant_mask ) ; + /***** client device logic *****/ + // Always update UNIBUS BR/NPR lines, are ORed with requests from other devices. - buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.request_mask) + buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask) ; - // read GRANT IN lines from CPU (Arbitrator). Only one at a time may be active - // Arbitrator asserts SACK is inactive - uint8_t grant_mask = sm_arb.arbitrator_grant_mask; - // forward GRANTs not requested by UniBone devices to other cards on neighbor slots - buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK & ~sm_arb.request_mask, ~grant_mask) - ; + // Do not forward GRANT IN to GRANT OUT: we, the arbitrator, do not have GRANT IN. // GRANTs for UniBone internal devices are not visible on UNIBUS // (emualted GRANT OUT - GRANT IN connections) - if (sm_arb.bbsy_wait_grant_mask == 0) { - // State 1: Wait For GRANT: - // process the requested grant for an open requests. - grant_mask &= sm_arb.request_mask; - if (grant_mask) { - // one of our requests was granted: - // set SACK - // AND simultaneously Clear granted requests BR*/NPR - // BIT(5): SACK mask and level - buslatches_setbits(1, (PRIORITY_ARBITRATION_BIT_MASK & sm_arb.request_mask) | BIT(5), - ~grant_mask | BIT(5)) - ; - // clear granted requests internally - sm_arb.request_mask &= ~grant_mask; - // Arbitrator should remove GRANT now. Data section on Bus still BBSY - sm_arb.bbsy_wait_grant_mask = grant_mask; // next is State 2: wait for BBSY clear - } - return 0; // no GRANT for us, or wait for BBSY - } else { - // wait for BBSY to clear - if (buslatches_getbyte(1) & BIT(6)) - return 0; // BBSY still set - grant_mask = sm_arb.bbsy_wait_grant_mask; - sm_arb.bbsy_wait_grant_mask = 0; // Next State is 1 - - return grant_mask; // signal what request we got granted. - } - // UNIBUS DATA section is indepedent: MSYN, SSYN, BBSY may still be active. - // -> DMA and INTR statemachine must wait for BBSY. + // Arbitration master stuff complete, + // handle GRANT/SACK/BBSY for emulated devices + return sm_arb_worker_device_grant_sack_bbsy(sm_arb.arbitrator_grant_mask); } diff --git a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h index 1ce74f5..c12890c 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h +++ b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h @@ -40,7 +40,7 @@ typedef struct { // There are 5 request/grant signals (BR4,5,6,7 and NPR). // These are encoded as bitmask fitting the buslatch[0] or[1] // BR/NPR lines = set of _PRIORITY_ARBITRATION_BIT_* - uint8_t request_mask; + uint8_t device_request_mask; // sm_arb has 2 states: State 1 "Wait for GRANT" and State 2 "wait for BBSY" // When arbitrator GRANts a request, we set SACK, GRAMT is cleared and we wait @@ -53,7 +53,7 @@ typedef struct { // only used wif working as Arbitrator/Interupt Fielding Processor uint8_t ifs_priority_level; // priority level of Interrupt Fielding processor (CPU) - uint8_t arbitrator_grant_mask; // GRANT line set by master + uint8_t arbitrator_grant_mask; // single GRANT line set by master } statemachine_arbitration_t; diff --git a/10.01_base/2_src/pru1/pru1_statemachine_data_slave.c b/10.01_base/2_src/pru1/pru1_statemachine_data_slave.c index c1b3bc7..4973423 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_data_slave.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_data_slave.c @@ -83,6 +83,10 @@ statemachine_state_func sm_data_slave_start() { // addr8..15 = latch[3] // addr 16,17 = latch[4].0,1 addr = latch2val | ((uint32_t) latch3val << 8) | ((uint32_t) (latch4val & 3) << 16); +//if (addr == 0777546) // LTC +// PRU_DEBUG_PIN0(1) ; // trigger to LA. + + // make bool of a17..a13. iopage, if a17..a13 all 1's // iopage = ((latch3val & 0xe0) | (latch4val & 3)) == 0xe3; diff --git a/10.01_base/2_src/pru1/pru1_statemachine_dma.c b/10.01_base/2_src/pru1/pru1_statemachine_dma.c index 62220ea..559b0a5 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_dma.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_dma.c @@ -333,7 +333,7 @@ static statemachine_state_func sm_dma_state_99() { // device or cpu cycle ended: now CPU may become UNIBUS master again mailbox.events.dma.cpu_transfer = mailbox.arbitrator.cpu_BBSY ; - mailbox.arbitrator.device_BBSY = false; + // device_BBSY monitored by sm_arbitration (physical devices). mailbox.arbitrator.cpu_BBSY = false; // SACK already de-asserted at wordcount==1 diff --git a/10.01_base/2_src/pru1/pru1_statemachine_intr_master.c b/10.01_base/2_src/pru1/pru1_statemachine_intr_master.c index 1ca9ec5..308de1a 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_intr_master.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_intr_master.c @@ -98,7 +98,7 @@ static statemachine_state_func sm_intr_master_state_2() { // deassert BBSY buslatches_setbits(1, BIT(6), 0); // device cycle ended: now CPU may become UNIBUS master again - mailbox.arbitrator.device_BBSY = false ; + // device_BBSY monitored by sm_arbitration (physical devices). // SACK already removed diff --git a/10.01_base/2_src/pru1/pru1_statemachine_intr_slave.c b/10.01_base/2_src/pru1/pru1_statemachine_intr_slave.c index cf65a2f..7bae1d7 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_intr_slave.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_intr_slave.c @@ -47,11 +47,11 @@ statemachine_intr_slave_t sm_intr_slave; // forwards static statemachine_state_func sm_intr_slave_state_1(void); -// Wait for BBSY deasserted, then assert, SACK already held asserted +// WAIT for INTR. +// Master holds BBSY and SACK statemachine_state_func sm_intr_slave_start() { - // WAIT for INTR if ((buslatches_getbyte(7) & BIT(0)) == 0) - return NULL ; // still idle + return NULL ; // INTR still deasserted // device has put vector onto DATA lines, fetch after 150ns __delay_cycles(NANOSECS(150)); uint8_t latch5val = buslatches_getbyte(5) ;// DATA[0..7] = latch[5] @@ -65,7 +65,11 @@ statemachine_state_func sm_intr_slave_start() { // signal ARM, wait for event to be processed mailbox.events.intr_slave.vector = (uint16_t) latch6val << 8 | latch5val ; + + EVENT_SIGNAL(mailbox,intr_slave) ; // signal to ARM + PRU2ARM_INTERRUPT ; + PRU_DEBUG_PIN0(1); // wait until ARM acked return (statemachine_state_func) &sm_intr_slave_state_1; } diff --git a/10.01_base/2_src/pru1/pru1_utils.c b/10.01_base/2_src/pru1/pru1_utils.c index 1a51ea2..a32e3b6 100644 --- a/10.01_base/2_src/pru1/pru1_utils.c +++ b/10.01_base/2_src/pru1/pru1_utils.c @@ -44,7 +44,7 @@ void do_event_initializationsignals() { uint8_t bus_cur = buslatches_getbyte(7) & 0x38; // now sampled if (bus_cur & INITIALIZATIONSIGNAL_INIT) { - sm_arb.request_mask = 0 ; // INIT clears all PRIORITY request signals + sm_arb.device_request_mask = 0 ; // INIT clears all PRIORITY request signals // SACK cleared later on end of INTR/DMA transaction } diff --git a/10.01_base/2_src/shared/mailbox.h b/10.01_base/2_src/shared/mailbox.h index f19e7df..c929f95 100644 --- a/10.01_base/2_src/shared/mailbox.h +++ b/10.01_base/2_src/shared/mailbox.h @@ -123,9 +123,9 @@ typedef struct { // data for bus arbitrator typedef struct { - // arbitrator.device_BBSY indicates a device wants or has acquired the UNIBUS - // cpu DATA transfer must be delayed until == 00 - // set by arbitration logic + // arbitrator.device_BBSY indicates a device wants or has acquired the UNIBUS. + // cpu DATA transfer must be delayed until device_BBSY == 0 + // set when arbitration logic detects SACK! uint8_t device_BBSY; // Command by ARM on DMA start: DATA transfer as CPU, else as device diff --git a/10.02_devices/2_src/cpu.cpp b/10.02_devices/2_src/cpu.cpp index d743b74..5d6315e 100644 --- a/10.02_devices/2_src/cpu.cpp +++ b/10.02_devices/2_src/cpu.cpp @@ -106,8 +106,10 @@ void cpu_c::worker(unsigned instance) { if (runmode.value != (ka11.state != 0)) ka11.state = runmode.value; ka11_condstep(&ka11); - if (runmode.value != (ka11.state != 0)) + if (runmode.value != (ka11.state != 0)) { runmode.value = ka11.state != 0; + printf("CPU HALT at %06o.\n", ka11.r[7]) ; + } // serialize asynchronous power events if (runmode.value) {