mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-04-03 20:32:28 +00:00
ACLO/DCLO/INIT moved from PRU to ARM
INTR/DMA request params linked to device params on change
This commit is contained in:
@@ -149,7 +149,7 @@ bool device_c::on_param_changed(parameter_c *param) {
|
||||
}
|
||||
// all devices forward their "on_param_changed" to parent classes,
|
||||
// until a class rejects a value.
|
||||
// device_c is the grand pratnes and produces "OK" for unknown or passive parameters
|
||||
// device_c is the grand parent and produces "OK" for unknown or passive parameters
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ priority_request_c::~priority_request_c() {
|
||||
void priority_request_c::set_priority_slot(uint8_t priority_slot) {
|
||||
assert(priority_slot > 0); // 0 reserved
|
||||
assert(priority_slot < PRIORITY_SLOT_COUNT);
|
||||
if (this->slot == priority_slot)
|
||||
return ; // called on every on_param_change()
|
||||
unibusdevice_c *ubdevice = unibusdevice_c::find_by_request_slot(priority_slot);
|
||||
if (ubdevice && ubdevice != this->device) {
|
||||
WARNING("Slot %u already used by device %s", (unsigned) priority_slot, ubdevice->name.value.c_str());
|
||||
@@ -105,3 +107,4 @@ void intr_request_c::set_vector(uint16_t vector) {
|
||||
this->vector = vector;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -94,23 +94,44 @@ char *unibus_c::control2text(uint8_t control) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* pulse INIT cycle for a number of milliseconds
|
||||
* Duration see INITPULSE_DELAY_MS
|
||||
/* pulse INIT cycle for 50 milliseconds ... source?
|
||||
*/
|
||||
void unibus_c::init(void) {
|
||||
/*
|
||||
// INIT: latch[7], bit 3
|
||||
buslatches_setval(7, BIT(3), BIT(3));
|
||||
timeout.wait_ms(duration_ms);
|
||||
buslatches_setval(7, BIT(3), 0);
|
||||
*/
|
||||
mailbox_execute(ARM2PRU_INITPULSE);
|
||||
timeout_c timeout;
|
||||
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_INIT;
|
||||
mailbox->initializationsignal.val = 1;
|
||||
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
|
||||
timeout.wait_ms(50);
|
||||
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_INIT;
|
||||
mailbox->initializationsignal.val = 0;
|
||||
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
|
||||
}
|
||||
|
||||
/* Simulate a power cycle
|
||||
* Sequence:
|
||||
* 1. Line power fail -> ACLO active
|
||||
* 2. Power supply capacitors empty -> DCLO active
|
||||
* 3. Line power back -> ACLO inactive
|
||||
* 4. Logic power OK -> DCLO inactive
|
||||
*/
|
||||
void unibus_c::powercycle(void) {
|
||||
mailbox_execute(ARM2PRU_POWERCYCLE);
|
||||
timeout_c timeout;
|
||||
const unsigned delay_ms = 100; // time between phases
|
||||
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_ACLO;
|
||||
mailbox->initializationsignal.val = 1;
|
||||
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
|
||||
timeout.wait_ms(delay_ms);
|
||||
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_DCLO;
|
||||
mailbox->initializationsignal.val = 1;
|
||||
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
|
||||
timeout.wait_ms(delay_ms);
|
||||
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_ACLO;
|
||||
mailbox->initializationsignal.val = 0;
|
||||
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
|
||||
timeout.wait_ms(delay_ms);
|
||||
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_DCLO;
|
||||
mailbox->initializationsignal.val = 0;
|
||||
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
|
||||
}
|
||||
|
||||
void unibus_c::set_arbitration_mode(arbitration_mode_enum arbitration_mode) {
|
||||
|
||||
@@ -1008,7 +1008,7 @@ void unibusadapter_c::worker(unsigned instance) {
|
||||
if (mailbox->events.event_init) {
|
||||
any_event = true;
|
||||
// robust: any change in ACLO/DCL=INIT updates state of all 3.
|
||||
// Initial DCLO-cycle to PDP_11 intialize these states
|
||||
// Initial DCLO-cycle to PDP_11 initialize these states
|
||||
if (mailbox->events.initialization_signals_cur & INITIALIZATIONSIGNAL_INIT) {
|
||||
if (!line_INIT)
|
||||
init_raising_edge = true;
|
||||
|
||||
@@ -43,6 +43,7 @@ unibusdevice_c::unibusdevice_c() :
|
||||
register_count = 0;
|
||||
// device is not yet enabled, UNIBUS properties can be set
|
||||
base_addr.readonly = false;
|
||||
priority_slot.readonly = false;
|
||||
intr_vector.readonly = false;
|
||||
intr_level.readonly = false;
|
||||
default_base_addr = 0;
|
||||
@@ -80,13 +81,17 @@ bool unibusdevice_c::on_param_changed(parameter_c *param) {
|
||||
}
|
||||
|
||||
// define default values for device BASE address and INTR
|
||||
void unibusdevice_c::set_default_bus_params(uint32_t default_base_addr, unsigned priority_slot,
|
||||
void unibusdevice_c::set_default_bus_params(uint32_t default_base_addr, unsigned default_priority_slot,
|
||||
unsigned default_intr_vector, unsigned default_intr_level) {
|
||||
assert(priority_slot <= PRIORITY_SLOT_COUNT); // bitmask!
|
||||
this->default_base_addr = this->base_addr.value = default_base_addr;
|
||||
this->default_priority_slot = this->intr_vector.value = priority_slot;
|
||||
this->default_intr_vector = this->intr_vector.value = default_intr_vector;
|
||||
this->default_intr_level = this->intr_level.value = default_intr_level;
|
||||
assert(default_priority_slot <= PRIORITY_SLOT_COUNT); // bitmask!
|
||||
this->default_base_addr = default_base_addr;
|
||||
this->default_priority_slot = default_priority_slot;
|
||||
this->default_intr_vector = this->intr_vector.new_value = default_intr_vector;
|
||||
this->default_intr_level = this->intr_level.new_value = default_intr_level;
|
||||
base_addr.set(default_base_addr) ;
|
||||
priority_slot.set(default_priority_slot) ;
|
||||
this->on_param_changed(&this->intr_vector) ;
|
||||
this->on_param_changed(&this->intr_level) ;
|
||||
}
|
||||
|
||||
void unibusdevice_c::install(void) {
|
||||
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
public:
|
||||
uint8_t handle; // assigned by "unibus.adapter.register
|
||||
|
||||
// !!! slot, vector, level READONLY. If user shoudl change,
|
||||
// !!! slot, vector, level READONLY. If user should change,
|
||||
// !! add logic to update dma_request_c and intr_request_c
|
||||
|
||||
// 0 = not "Plugged" in to UNIBUS
|
||||
|
||||
@@ -71,9 +71,7 @@ OBJECTS_COMMON= \
|
||||
$(OBJ_DIR)/pru1_pru_mailbox.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_arbitration.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_dma.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_init.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_intr.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_powercycle.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_slave.object \
|
||||
$(OBJ_DIR)/pru1_timeouts.object \
|
||||
$(OBJ_DIR)/pru1_utils.object
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
#include "pru1_statemachine_dma.h"
|
||||
#include "pru1_statemachine_intr.h"
|
||||
#include "pru1_statemachine_slave.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
// Supress warnings about using void * as function pointers
|
||||
// sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
@@ -162,16 +160,21 @@ void main(void) {
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
}
|
||||
case ARM2PRU_INITPULSE: // generate a pulse on UNIBUS INIT
|
||||
// INIT: latch[7], bit 3
|
||||
buslatches_setbits(7, BIT(3), BIT(3)); // assert INIT
|
||||
__delay_cycles(MILLISECS(250)); // INIT is 250ms
|
||||
buslatches_setbits(7, BIT(3), 0); // deassert INIT
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
|
||||
case ARM2PRU_POWERCYCLE: // do ACLO/DCLO power cycle
|
||||
buslatches_powercycle();
|
||||
case ARM2PRU_INITALIZATIONSIGNAL_SET:
|
||||
switch (mailbox.initializationsignal.id) {
|
||||
case INITIALIZATIONSIGNAL_ACLO:
|
||||
// assert/deassert ACLO
|
||||
buslatches_setbits(7, BIT(4), mailbox.initializationsignal.val? BIT(4):0);
|
||||
break;
|
||||
case INITIALIZATIONSIGNAL_DCLO:
|
||||
// assert/deassert DCLO
|
||||
buslatches_setbits(7, BIT(5), mailbox.initializationsignal.val? BIT(5):0);
|
||||
break;
|
||||
case INITIALIZATIONSIGNAL_INIT:
|
||||
// assert/deassert INIT
|
||||
buslatches_setbits(7, BIT(3), mailbox.initializationsignal.val? BIT(3):0);
|
||||
break;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DMA: {
|
||||
|
||||
@@ -60,8 +60,6 @@
|
||||
#include "pru1_statemachine_dma.h"
|
||||
#include "pru1_statemachine_intr.h"
|
||||
#include "pru1_statemachine_slave.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
// supress warnigns about using void * as function pointers
|
||||
// sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
@@ -78,7 +76,7 @@
|
||||
High speed not necessary: Bus master will wait with MSYN if UniBone not responding.
|
||||
wathcin BG/BPG signals, catching requested GRANts and forwardinf
|
||||
other GRANTS
|
||||
- monitorinf INIT and AC_LO/DC_LO
|
||||
- monitoring INIT and AC_LO/DC_LO
|
||||
- watching fpr AMR2PRU commands
|
||||
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)
|
||||
@@ -95,8 +93,6 @@ void main(void) {
|
||||
statemachine_arb_worker_func sm_arb_worker = &sm_arb_worker_client;
|
||||
statemachine_state_func sm_data_slave_state = NULL;
|
||||
statemachine_state_func sm_data_master_state = NULL;
|
||||
statemachine_state_func sm_init_state = NULL;
|
||||
statemachine_state_func sm_powercycle_state = NULL;
|
||||
// these are function pointers: could be 16bit on PRU?
|
||||
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
@@ -132,13 +128,6 @@ void main(void) {
|
||||
// Acess to interna lregsitres may may issue AMR2PRU opcode, so exit loop then
|
||||
;// execute complete slave cycle, then check NPR/INTR
|
||||
|
||||
// one phase of INIT or power cycle
|
||||
if (sm_powercycle_state)
|
||||
sm_powercycle_state = sm_powercycle_state();
|
||||
else if (sm_init_state)
|
||||
// init only if no power cycle, power cycle overrides INIT
|
||||
sm_init_state = sm_init_state();
|
||||
|
||||
// signal INT or PWR FAIL to ARM
|
||||
do_event_initializationsignals();
|
||||
|
||||
@@ -249,14 +238,21 @@ void main(void) {
|
||||
// no completion event, could interfer with othe INTRs?
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // done
|
||||
break;
|
||||
case ARM2PRU_INITPULSE:
|
||||
if (!sm_init_state)
|
||||
sm_init_state = (statemachine_state_func) &sm_init_start;
|
||||
// INIT aborts DMA
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_POWERCYCLE:
|
||||
sm_powercycle_state = (statemachine_state_func) &sm_powercycle_start;
|
||||
case ARM2PRU_INITALIZATIONSIGNAL_SET:
|
||||
switch (mailbox.initializationsignal.id) {
|
||||
case INITIALIZATIONSIGNAL_ACLO:
|
||||
// assert/deassert ACLO
|
||||
buslatches_setbits(7, BIT(4), mailbox.initializationsignal.val? BIT(4):0);
|
||||
break;
|
||||
case INITIALIZATIONSIGNAL_DCLO:
|
||||
// assert/deassert DCLO
|
||||
buslatches_setbits(7, BIT(5), mailbox.initializationsignal.val? BIT(5):0);
|
||||
break;
|
||||
case INITIALIZATIONSIGNAL_INIT:
|
||||
// assert/deassert INIT
|
||||
buslatches_setbits(7, BIT(3), mailbox.initializationsignal.val? BIT(3):0);
|
||||
break;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_HALT:
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/* pru1_statemachine_init.c: state machine for pulse on INIT
|
||||
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Statemachine for a pulse on UNIBUS INIT
|
||||
! Uses single global timeout, don't run in parallel with other statemachines using timeout !
|
||||
*/
|
||||
|
||||
#define _PRU1_STATEMACHINE_INIT_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mailbox.h"
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_arbitration.h"
|
||||
|
||||
/*** detection of changes in INIT,DCLO,ACLO ***/
|
||||
|
||||
// detect signal change of INIT,DCLO,ACLO and sent event
|
||||
// history initialized (among others) by powercycle
|
||||
// Assume this events come so slow, no one gets raised until
|
||||
// prev event processed.
|
||||
void do_event_initializationsignals() {
|
||||
uint8_t mb_cur = mailbox.events.initialization_signals_cur; // as saved
|
||||
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
|
||||
// SACK cleared later on end of INTR/DMA transaction
|
||||
|
||||
if (bus_cur != mb_cur) {
|
||||
// save old state, so ARM can detect what changed
|
||||
mailbox.events.initialization_signals_prev = mb_cur;
|
||||
mailbox.events.initialization_signals_cur = bus_cur;
|
||||
// trigger the correct event: power and/or INIT
|
||||
if ((mb_cur ^ bus_cur) & (INITIALIZATIONSIGNAL_DCLO | INITIALIZATIONSIGNAL_ACLO))
|
||||
// AC_LO or DC_LO changed
|
||||
mailbox.events.event_power = 1;
|
||||
if ((mb_cur ^ bus_cur) & INITIALIZATIONSIGNAL_INIT)
|
||||
// INIT changed
|
||||
mailbox.events.event_init = 1;
|
||||
PRU2ARM_INTERRUPT
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// forwards
|
||||
static statemachine_state_func sm_init_state_1(void);
|
||||
|
||||
// setup
|
||||
statemachine_state_func sm_init_start() {
|
||||
timeout_set(TIMEOUT_INIT, MILLISECS(INITPULSE_DELAY_MS));
|
||||
// INIT: latch[7], bit 3
|
||||
buslatches_setbits(7, BIT(3), BIT(3)); // assert INIT
|
||||
mailbox.events.initialization_signals_prev &= ~INITIALIZATIONSIGNAL_INIT; // force INIT event
|
||||
return (statemachine_state_func) &sm_init_state_1;
|
||||
}
|
||||
|
||||
static statemachine_state_func sm_init_state_1() {
|
||||
if (!timeout_reached(TIMEOUT_INIT))
|
||||
return (statemachine_state_func) &sm_init_state_1; // wait
|
||||
buslatches_setbits(7, BIT(3), 0); // deassert INIT
|
||||
timeout_cleanup(TIMEOUT_INIT);
|
||||
return NULL; // ready
|
||||
}
|
||||
|
||||
// terminate INIT
|
||||
// To be called from Powercycle?
|
||||
void sm_init_reset() {
|
||||
buslatches_setbits(7, BIT(3), 0); // deassert INIT
|
||||
do_event_initializationsignals();
|
||||
timeout_cleanup(TIMEOUT_INIT);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/* pru1_statemachine_init.h: state machine for pulse on INIT
|
||||
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_INIT_H_
|
||||
#define _PRU1_STATEMACHINE_INIT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
#define INITPULSE_DELAY_MS 250 // length of INIT pulse
|
||||
|
||||
#ifndef _PRU1_STATEMACHINE_INIT_C_
|
||||
extern uint8_t prev_initialization_signals;
|
||||
#endif
|
||||
|
||||
void do_event_initializationsignals(void);
|
||||
|
||||
void sm_init_reset(void);
|
||||
statemachine_state_func sm_init_start();
|
||||
|
||||
#endif
|
||||
@@ -1,109 +0,0 @@
|
||||
/* pru1_statemachine_powercycle.c: state machine to generate an ACLO/DCLO pseudo power cycle
|
||||
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
|
||||
Statemachine for execution of an ACLO/DCLO pseudo power cycle.
|
||||
// ACLO: latch[7], bit 4
|
||||
// DCLO: latch[7], bit 5
|
||||
buslatches_setbits(7, BIT(4), BIT(4)); // ACLO asserted
|
||||
__delay_cycles(MILLISECS(250)) ; // "power supply shuts down"
|
||||
buslatches_setbits(7, BIT(5), BIT(5)); // DCLO asserted
|
||||
__delay_cycles(MILLISECS(250)) ; // "power is OFF now"
|
||||
buslatches_setbits(7, BIT(4), 0); // ACLO deasserted
|
||||
__delay_cycles(MILLISECS(250)) ; // "power supply stabilizing"
|
||||
buslatches_setbits(7, BIT(5), 0); // DCLO deasserted
|
||||
// CPU has to generate INIT and BBSY
|
||||
|
||||
! Uses single global timeout, don't run in parallel with other statemachines using timeout !
|
||||
*/
|
||||
|
||||
#define _PRU1_STATEMACHINE_POWERCYCLE_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mailbox.h"
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
// forwards ; /
|
||||
static statemachine_state_func sm_powercycle_state_1(void);
|
||||
static statemachine_state_func sm_powercycle_state_2(void);
|
||||
static statemachine_state_func sm_powercycle_state_3(void);
|
||||
static statemachine_state_func sm_powercycle_state_4(void);
|
||||
|
||||
// setup with
|
||||
statemachine_state_func sm_powercycle_start() {
|
||||
return (statemachine_state_func) &sm_powercycle_state_1;
|
||||
// next call to sm_slave.state() starts state machine
|
||||
}
|
||||
|
||||
// "Line power shutdown": assert ACLO, then wait
|
||||
static statemachine_state_func sm_powercycle_state_1() {
|
||||
buslatches_setbits(7, BIT(4), BIT(4)); // ACLO asserted
|
||||
timeout_set(TIMEOUT_POWERCYCLE, MILLISECS(POWERCYCLE_DELAY_MS)); // wait for DC power shutdown
|
||||
// DEBUG_OUT(0x01) ;
|
||||
// DEBUG_OUT(0x02) ;
|
||||
return (statemachine_state_func) &sm_powercycle_state_2;
|
||||
}
|
||||
|
||||
// "Power supply switched off": assert DCLO, then wait
|
||||
static statemachine_state_func sm_powercycle_state_2() {
|
||||
if (!timeout_reached(TIMEOUT_POWERCYCLE))
|
||||
return (statemachine_state_func) &sm_powercycle_state_2; // wait
|
||||
buslatches_setbits(7, BIT(5), BIT(5)); // DCLO asserted
|
||||
timeout_set(TIMEOUT_POWERCYCLE, MILLISECS(POWERCYCLE_DELAY_MS)); // system powered off
|
||||
// DEBUG_OUT(0x03) ;
|
||||
// DEBUG_OUT(0x04) ;
|
||||
// make sure we don't "come up from power" with INIT already set.
|
||||
sm_init_reset();
|
||||
|
||||
return (statemachine_state_func) &sm_powercycle_state_3;
|
||||
}
|
||||
|
||||
// "Line power back again": deassert ACLO, then wait
|
||||
static statemachine_state_func sm_powercycle_state_3() {
|
||||
if (!timeout_reached(TIMEOUT_POWERCYCLE))
|
||||
return (statemachine_state_func) &sm_powercycle_state_3; // wait
|
||||
buslatches_setbits(7, BIT(4), 0); // ACLO deasserted
|
||||
timeout_set(TIMEOUT_POWERCYCLE, MILLISECS(POWERCYCLE_DELAY_MS)); // "power supply stabilizing"
|
||||
return (statemachine_state_func) &sm_powercycle_state_4;
|
||||
}
|
||||
|
||||
// "Logic power stabilized": deassert DCLO, ready
|
||||
static statemachine_state_func sm_powercycle_state_4() {
|
||||
if (!timeout_reached(TIMEOUT_POWERCYCLE))
|
||||
return (statemachine_state_func) &sm_powercycle_state_4;
|
||||
buslatches_setbits(7, BIT(5), 0); // DCLO deasserted
|
||||
timeout_cleanup(TIMEOUT_POWERCYCLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* pru1_statemachine_powercycle.h: state machine to generate an ACLO/DCLO pseudo power cycle
|
||||
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_POWERCYCLE_H_
|
||||
#define _PRU1_STATEMACHINE_POWERCYCLE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
#define POWERCYCLE_DELAY_MS 100 // wait period in millsecs between ACLO/DCLO transitions
|
||||
|
||||
statemachine_state_func sm_powercycle_start();
|
||||
|
||||
#endif
|
||||
@@ -29,13 +29,11 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
// predefined timeouts
|
||||
#define TIMEOUT_COUNT 4
|
||||
#define TIMEOUT_COUNT 2
|
||||
|
||||
// fixed pointers
|
||||
#define TIMEOUT_DMA (&timeout_target_cycles[0])
|
||||
#define TIMEOUT_INIT (&timeout_target_cycles[1])
|
||||
#define TIMEOUT_POWERCYCLE (&timeout_target_cycles[2])
|
||||
#define TIMEOUT_SACK (&timeout_target_cycles[3])
|
||||
#define TIMEOUT_SACK (&timeout_target_cycles[1])
|
||||
|
||||
// cycle end count for each active timeoput.
|
||||
extern uint32_t timeout_target_cycles[TIMEOUT_COUNT];
|
||||
|
||||
@@ -28,5 +28,38 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mailbox.h"
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_arbitration.h"
|
||||
#include "pru1_utils.h"
|
||||
|
||||
|
||||
// detect signal change of INIT,DCLO,ACLO and sent event
|
||||
// history initialized (among others) by powercycle
|
||||
// Assume this events come so slow, no one gets raised until
|
||||
// prev event processed.
|
||||
void do_event_initializationsignals() {
|
||||
uint8_t mb_cur = mailbox.events.initialization_signals_cur; // as saved
|
||||
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
|
||||
// SACK cleared later on end of INTR/DMA transaction
|
||||
|
||||
if (bus_cur != mb_cur) {
|
||||
// save old state, so ARM can detect what changed
|
||||
mailbox.events.initialization_signals_prev = mb_cur;
|
||||
mailbox.events.initialization_signals_cur = bus_cur;
|
||||
// trigger the correct event: power and/or INIT
|
||||
if ((mb_cur ^ bus_cur) & (INITIALIZATIONSIGNAL_DCLO | INITIALIZATIONSIGNAL_ACLO))
|
||||
// AC_LO or DC_LO changed
|
||||
mailbox.events.event_power = 1;
|
||||
if ((mb_cur ^ bus_cur) & INITIALIZATIONSIGNAL_INIT)
|
||||
// INIT changed
|
||||
mailbox.events.event_init = 1;
|
||||
PRU2ARM_INTERRUPT
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -125,4 +125,7 @@ typedef void * (*statemachine_state_func)(void);
|
||||
__R31 = PRU2ARM_INTERRUPT_PRU0_R31_VEC_VALID |PRU2ARM_INTERRUPT_SIGNUM ; /* 35 */ \
|
||||
} while(0)
|
||||
|
||||
void do_event_initializationsignals(void) ;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,8 +40,7 @@
|
||||
#define ARM2PRU_BUSLATCH_GET 6 // read a mux register
|
||||
#define ARM2PRU_BUSLATCH_EXERCISER 7 // exercise 8 accesses to mux registers
|
||||
#define ARM2PRU_BUSLATCH_TEST 8 // read a mux register
|
||||
#define ARM2PRU_INITPULSE 9 // pulse UNIBUS INIT
|
||||
#define ARM2PRU_POWERCYCLE 10 // ACLO/DCLO power cycle simulation
|
||||
#define ARM2PRU_INITALIZATIONSIGNAL_SET 9 // set an ACL=/DCLO/INIT signal
|
||||
#define ARM2PRU_ARB_MODE_NONE 11 // DMA without NPR/NPG/SACK arbitration
|
||||
#define ARM2PRU_ARB_MODE_CLIENT 12 // DMA with arbitration by external Arbitrator
|
||||
#define ARM2PRU_ARB_MODE_MASTER 13 // DMA as Arbitrator
|
||||
@@ -52,6 +51,14 @@
|
||||
#define ARM2PRU_DDR_FILL_PATTERN 18 // fill DDR with test pattern
|
||||
#define ARM2PRU_DDR_SLAVE_MEMORY 19 // use DDR as UNIBUS slave memory
|
||||
|
||||
|
||||
// signal IDs for ARM2PRU_INITALIZATIONSIGNAL_*
|
||||
// states of initialization section lines. Bitmask = latch[7]
|
||||
#define INITIALIZATIONSIGNAL_INIT (1 << 3)
|
||||
#define INITIALIZATIONSIGNAL_ACLO (1 << 4)
|
||||
#define INITIALIZATIONSIGNAL_DCLO (1 << 5)
|
||||
|
||||
|
||||
// possible states of DMA machine
|
||||
#define DMA_STATE_READY 0 // idle
|
||||
#define DMA_STATE_ARBITRATING 1 // in NPR/NPG/SACK arbitration
|
||||
@@ -107,6 +114,11 @@ typedef struct {
|
||||
uint8_t data_8_15;
|
||||
} mailbox_buslatch_test_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t id; // which signal to set or get? one of INITIALIZATIONSIGNAL_*
|
||||
uint16_t val; // value set/get.
|
||||
} mailbox_initializationsignal_t;
|
||||
|
||||
|
||||
// data for bus arbitrator
|
||||
typedef struct {
|
||||
@@ -158,11 +170,6 @@ typedef struct {
|
||||
// multiple of 32 bit now
|
||||
} mailbox_intr_t;
|
||||
|
||||
// states of initialization section lines. Bitmask = latch[7]
|
||||
#define INITIALIZATIONSIGNAL_INIT (1 << 3)
|
||||
#define INITIALIZATIONSIGNAL_ACLO (1 << 4)
|
||||
#define INITIALIZATIONSIGNAL_DCLO (1 << 5)
|
||||
|
||||
typedef struct {
|
||||
// trigger flags raised by PRU, reset by ARM
|
||||
// differemt events can be raised asynchronically and concurrent,
|
||||
@@ -234,6 +241,7 @@ typedef struct {
|
||||
mailbox_buslatch_t buslatch;
|
||||
mailbox_buslatch_test_t buslatch_test;
|
||||
mailbox_buslatch_exerciser_t buslatch_exerciser;
|
||||
mailbox_initializationsignal_t initializationsignal ;
|
||||
};
|
||||
} mailbox_t;
|
||||
|
||||
|
||||
@@ -70,15 +70,6 @@ slu_c::slu_c() :
|
||||
// SLU has 2 Interrupt vectors: base = RCV, base+= XMT
|
||||
// put in slot 1, closest to CPU
|
||||
set_default_bus_params(SLU_ADDR, SLU_SLOT, SLU_VECTOR, SLU_LEVEL); // base addr, intr-vector, intr level
|
||||
rcvintr_request.set_priority_slot(default_priority_slot);
|
||||
rcvintr_request.set_level(default_intr_level);
|
||||
rcvintr_request.set_vector(default_intr_vector);
|
||||
// XMT INTR: lower priority->netx slot, and next vector
|
||||
xmtintr_request.set_priority_slot(default_priority_slot + 1);
|
||||
xmtintr_request.set_level(default_intr_level);
|
||||
xmtintr_request.set_vector(default_intr_vector + 4);
|
||||
|
||||
// init parameters
|
||||
|
||||
// controller has some register
|
||||
register_count = slu_idx_count;
|
||||
@@ -152,6 +143,16 @@ bool slu_c::on_param_changed(parameter_c *param) {
|
||||
mode.readonly = false;
|
||||
INFO("Serial port %s closed", serialport.value.c_str());
|
||||
}
|
||||
} else if (param == &priority_slot) {
|
||||
rcvintr_request.set_priority_slot(priority_slot.new_value);
|
||||
// XMT INTR: lower priority => nxt slot, and next vector
|
||||
xmtintr_request.set_priority_slot(priority_slot.new_value + 1);
|
||||
} else if (param == &intr_vector) {
|
||||
rcvintr_request.set_vector(intr_vector.new_value);
|
||||
xmtintr_request.set_vector(intr_vector.new_value + 4);
|
||||
} else if (param == &intr_level) {
|
||||
rcvintr_request.set_level(intr_level.new_value);
|
||||
xmtintr_request.set_level(intr_level.new_value);
|
||||
}
|
||||
return unibusdevice_c::on_param_changed(param); // more actions (for enable)
|
||||
}
|
||||
@@ -471,9 +472,6 @@ ltc_c::ltc_c() :
|
||||
log_label = "ltc";
|
||||
// slot = 3:
|
||||
set_default_bus_params(LTC_ADDR, LTC_SLOT, LTC_VECTOR, LTC_LEVEL); // base addr, intr-vector, intr level
|
||||
intr_request.set_priority_slot(default_priority_slot);
|
||||
intr_request.set_level(default_intr_level);
|
||||
intr_request.set_vector(default_intr_vector);
|
||||
|
||||
// controller has only one register
|
||||
register_count = 1;
|
||||
@@ -501,8 +499,15 @@ bool ltc_c::on_param_changed(parameter_c *param) {
|
||||
if (param == &frequency) {
|
||||
// accept only these
|
||||
return (frequency.new_value == 50 || frequency.new_value == 60);
|
||||
} else
|
||||
return unibusdevice_c::on_param_changed(param); // more actions (for enable)
|
||||
} else if (param == &priority_slot) {
|
||||
intr_request.set_priority_slot(priority_slot.new_value);
|
||||
} else if (param == &intr_level) {
|
||||
intr_request.set_level(intr_level.new_value);
|
||||
} else if (param == &intr_vector) {
|
||||
intr_request.set_vector(intr_vector.new_value);
|
||||
}
|
||||
|
||||
return unibusdevice_c::on_param_changed(param); // more actions (for enable)
|
||||
}
|
||||
|
||||
// calc static INTR condition level.
|
||||
|
||||
@@ -167,27 +167,6 @@ public:
|
||||
parameter_bool_c break_enable = parameter_bool_c(this, "break", "b", /*readonly*/false,
|
||||
"Enable BREAK transmission (M7856 SW4-1)");
|
||||
|
||||
#ifdef USED
|
||||
// @David: duplicating device registers as parameters is not necessary ...
|
||||
// they can be seen with "exam" anyhow.
|
||||
parameter_unsigned_c rcsr = parameter_unsigned_c(this, "Receiver Status Register", "rcsr", /*readonly*/
|
||||
false, "", "%o", "Internal state", 32, 8);
|
||||
parameter_unsigned_c rbuf = parameter_unsigned_c(this, "Receiver Buffer Register", "rbuf", /*readonly*/
|
||||
false, "", "%o", "Internal state", 32, 8);
|
||||
parameter_unsigned_c xcsr = parameter_unsigned_c(this, "Transmitter Status Register",
|
||||
"xcsr", /*readonly*/false, "", "%o", "Internal state", 32, 8);
|
||||
parameter_unsigned_c xbuf = parameter_unsigned_c(this, "Transmitter Buffer Register",
|
||||
"xbuf", /*readonly*/false, "", "%o", "Internal state", 32, 8);
|
||||
|
||||
parameter_bool_c xmit_interrupt_enable = parameter_bool_c(this, "XMIT interrupt enable",
|
||||
"xie",/*readonly*/false, "1 = enable interrupt");
|
||||
parameter_bool_c rcvr_interrupt_enable = parameter_bool_c(this, "RCVR interrupt enable",
|
||||
"rie",/*readonly*/false, "1 = enable interrupt");
|
||||
parameter_bool_c slu_maint = parameter_bool_c(this, "XCSR Maintenance", "maint",/*readonly*/
|
||||
false, "1 = enable Maintenance mode enabled");
|
||||
parameter_bool_c rdr_enable = parameter_bool_c(this, "RDR enable", "rdre",/*readonly*/false,
|
||||
"1 = enable reader enable");
|
||||
#endif
|
||||
// background worker function
|
||||
void worker(unsigned instance) override;
|
||||
void worker_rcv(void);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Copyright Vulcan Inc. 2019 via Living Computers: Museum + Labs, Seattle, WA.
|
||||
Contributed under the BSD 2-clause license.
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -28,10 +28,6 @@ rk11_c::rk11_c() :
|
||||
|
||||
// base addr, intr-vector, intr level
|
||||
set_default_bus_params(0777400, 10, 0220, 5) ;
|
||||
dma_request.set_priority_slot(default_priority_slot) ;
|
||||
intr_request.set_priority_slot(default_priority_slot) ;
|
||||
intr_request.set_level(default_intr_level) ;
|
||||
intr_request.set_vector(default_intr_vector) ;
|
||||
|
||||
// The RK11 controller has seven registers,
|
||||
// We allocate 8 because one address in the address space is unused.
|
||||
@@ -124,6 +120,14 @@ rk11_c::~rk11_c()
|
||||
// verify "new_value", must output error messages
|
||||
bool rk11_c::on_param_changed(parameter_c *param) {
|
||||
// no own parameter or "enable" logic
|
||||
if (param == &priority_slot) {
|
||||
dma_request.set_priority_slot(priority_slot.new_value);
|
||||
intr_request.set_priority_slot(priority_slot.new_value);
|
||||
} else if (param == &intr_level) {
|
||||
intr_request.set_level(intr_level.new_value);
|
||||
} else if (param == &intr_vector) {
|
||||
intr_request.set_vector(intr_vector.new_value);
|
||||
}
|
||||
return storagecontroller_c::on_param_changed(param) ; // more actions (for enable)
|
||||
}
|
||||
|
||||
@@ -189,6 +193,7 @@ void rk11_c::dma_transfer(DMARequest &request)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If an IBA DMA read from memory, we need to fill the request buffer
|
||||
// with the single word returned from memory by the DMA operation.
|
||||
if (request.iba && !request.write)
|
||||
|
||||
@@ -138,10 +138,6 @@ RL11_c::RL11_c(void) :
|
||||
|
||||
// base addr, intr-vector, intr level
|
||||
set_default_bus_params(0774400, 15, 0160, 5);
|
||||
dma_request.set_priority_slot(default_priority_slot);
|
||||
intr_request.set_priority_slot(default_priority_slot);
|
||||
intr_request.set_level(default_intr_level);
|
||||
intr_request.set_vector(default_intr_vector);
|
||||
|
||||
// add 4 RL disk drives
|
||||
drivecount = 4;
|
||||
@@ -206,7 +202,15 @@ bool RL11_c::on_param_changed(parameter_c *param) {
|
||||
// disabled
|
||||
disconnect_from_panel();
|
||||
}
|
||||
} else if (param == &priority_slot) {
|
||||
dma_request.set_priority_slot(priority_slot.new_value);
|
||||
intr_request.set_priority_slot(priority_slot.new_value);
|
||||
} else if (param == &intr_level) {
|
||||
intr_request.set_level(intr_level.new_value);
|
||||
} else if (param == &intr_vector) {
|
||||
intr_request.set_vector(intr_vector.new_value);
|
||||
}
|
||||
|
||||
return storagecontroller_c::on_param_changed(param); // more actions (for enable)
|
||||
}
|
||||
|
||||
@@ -847,11 +851,11 @@ void RL11_c::worker(unsigned instance) {
|
||||
// may still be inactive, when PRU updatesit with iNTR delayed.
|
||||
// enable operation of pending on_after_register_access()
|
||||
/*
|
||||
if (!(busreg_CS->active_dati_flipflops & 0x80)) { // CRDY must be set
|
||||
ERROR("CRDY not set, CS=%06o", busreg_CS->active_dati_flipflops);
|
||||
logger->dump(logger->default_filepath);
|
||||
}
|
||||
*/
|
||||
if (!(busreg_CS->active_dati_flipflops & 0x80)) { // CRDY must be set
|
||||
ERROR("CRDY not set, CS=%06o", busreg_CS->active_dati_flipflops);
|
||||
logger->dump(logger->default_filepath);
|
||||
}
|
||||
*/
|
||||
res = pthread_cond_wait(&on_after_register_access_cond,
|
||||
&on_after_register_access_mutex);
|
||||
if (res != 0) {
|
||||
|
||||
@@ -48,10 +48,6 @@ uda_c::uda_c() :
|
||||
|
||||
// base addr, intr-vector, intr level
|
||||
set_default_bus_params(0772150, 20, 0154, 5) ;
|
||||
dma_request.set_priority_slot(default_priority_slot) ;
|
||||
intr_request.set_priority_slot(default_priority_slot) ;
|
||||
intr_request.set_level(default_intr_level) ;
|
||||
intr_request.set_vector(default_intr_vector) ;
|
||||
|
||||
// The UDA50 controller has two registers.
|
||||
register_count = 2;
|
||||
@@ -99,6 +95,14 @@ uda_c::~uda_c()
|
||||
|
||||
bool uda_c::on_param_changed(parameter_c *param) {
|
||||
// no own parameter or "enable" logic
|
||||
if (param == &priority_slot) {
|
||||
dma_request.set_priority_slot(priority_slot.new_value);
|
||||
intr_request.set_priority_slot(priority_slot.new_value);
|
||||
} else if (param == &intr_level) {
|
||||
intr_request.set_level(intr_level.new_value);
|
||||
} else if (param == &intr_vector) {
|
||||
intr_request.set_vector(intr_vector.new_value);
|
||||
}
|
||||
return storagecontroller_c::on_param_changed(param) ; // more actions (for enable)
|
||||
}
|
||||
|
||||
|
||||
@@ -444,7 +444,7 @@ void application_c::menu_devices(bool with_CPU) {
|
||||
if (timeout)
|
||||
printf("Bus timeout at %06o.\n", mailbox->dma.cur_addr);
|
||||
} else if (!strcasecmp(s_opcode, "e") && n_fields <= 2) {
|
||||
bool timeout;
|
||||
bool timeout = false;
|
||||
uint32_t addr;
|
||||
unibusdevice_register_t *reg = NULL ;
|
||||
if (n_fields == 2) { // single reg number or address given
|
||||
|
||||
Reference in New Issue
Block a user