1
0
mirror of https://github.com/livingcomputermuseum/UniBone.git synced 2026-02-27 01:00:00 +00:00

CPU20 UNIBUS Interrupt, Experiments to probe UNIBUS arbitrator

This commit is contained in:
Joerg Hoppe
2019-10-08 12:36:36 +02:00
parent 53e22d558c
commit 3f71d6f093
17 changed files with 499 additions and 255 deletions

View File

@@ -97,43 +97,112 @@ char *unibus_c::control2text(uint8_t control) {
/* pulse INIT cycle for some milliseconds
*/
void unibus_c::init(unsigned pulsewidth_ms) {
timeout_c timeout;
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_INIT;
mailbox->initializationsignal.val = 1;
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
timeout.wait_ms(pulsewidth_ms);
timeout_c::wait_ms(pulsewidth_ms);
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_INIT;
mailbox->initializationsignal.val = 0;
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
}
// return: bitmask with shortcount BG*/NPG IN_OUT signals
// Values see PRIORITY_ARBITRATION_BIT_*
// Fiddling with the BG*/NPG signal may crash running CPU, also
// the M9302 will generate a SACK.
// So CPU is stopped with a surrounding a power cycle
uint8_t unibus_c::probe_grant_continuity(bool error_if_closed) {
uint8_t grant_mask = 0;
// simulate POWER OFF
powercycle(1);
#if 0
// CPU should be stopped now, holding BG*/NPG lines active LOW = logic 0.
// If the power vector 24 does something weird, we may have
// BG*/NPG set and have malfunctions now.
// Test algorithm is difficult to implement.
// First, pull INIT low to disable fucntion of other cards
// 3 cases:
// 1) Running CPU on BUS: set a BR, wait for BGIN
// (not tested here)
//
// 2) If HALTed CPU on bus: BG*/NPG held LOW
// Need M9302 with SACK turnaround.
// - set each BGOUT/NPGOUT (assume IN 0 by CPU)
// - if M9302 responds with SACK:
// it sees a BG 1 => no jumper IN-OUT
// if no SACK: M9302 sees a "0" => jumper set
// 3) If no CPU on bus: BG*/NPG pulled up
// set BG OUT = 0, if IN 0 -> jumper!
// Set BG*_OUT/NPG_OUT bits at latch 0
// and read back
mailbox->buslatch.addr = 0;
mailbox->buslatch.bitmask = PRIORITY_ARBITRATION_BIT_MASK;
mailbox->buslatch.val = 0x00; // output 0 = against pullups
mailbox_execute(ARM2PRU_BUSLATCH_SET);
// Read back BG*_IN/NPG_IN bits from latch 0
// mailbox->buslatch.addr = 0;
// mailbox_execute(ARM2PRU_BUSLATCH_GET);
uint8_t grant_mask = ~ (mailbox->buslatch.val & PRIORITY_ARBITRATION_BIT_MASK);
#endif
// simulate POWER ON
powercycle(2);
if (grant_mask && error_if_closed) {
printf("Error: GRANT IN-OUT closed on UNIBUS backplane:");
if (grant_mask & PRIORITY_ARBITRATION_BIT_B4)
printf(" BG4");
if (grant_mask & PRIORITY_ARBITRATION_BIT_B5)
printf(" BG5");
if (grant_mask & PRIORITY_ARBITRATION_BIT_B6)
printf(" BG6");
if (grant_mask & PRIORITY_ARBITRATION_BIT_B7)
printf(" BG7");
if (grant_mask & PRIORITY_ARBITRATION_BIT_NP)
printf(" NPG");
printf(".\n");
exit(1);
}
return grant_mask;
}
/* 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
* phase: 0x01 = only OFF, 0x02 = only ON, 0x03 = ON and OFF
*/
void unibus_c::powercycle(void) {
timeout_c timeout;
void unibus_c::powercycle(int phase) {
const unsigned delay_ms = 200; // 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);
// wait for CPU to come up
timeout.wait_ms(delay_ms);
if (phase & 0x01) {
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_ACLO;
mailbox->initializationsignal.val = 1;
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
timeout_c::wait_ms(delay_ms);
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_DCLO;
mailbox->initializationsignal.val = 1;
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
timeout_c::wait_ms(delay_ms);
}
if (phase & 0x02) {
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_ACLO;
mailbox->initializationsignal.val = 0;
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
timeout_c::wait_ms(delay_ms);
mailbox->initializationsignal.id = INITIALIZATIONSIGNAL_DCLO;
mailbox->initializationsignal.val = 0;
mailbox_execute(ARM2PRU_INITALIZATIONSIGNAL_SET);
// wait for CPU to come up
timeout_c::wait_ms(delay_ms);
}
}
void unibus_c::set_arbitrator_active(bool active) {
@@ -155,8 +224,8 @@ bool unibus_c::get_arbitrator_active(void) {
// 0 = bus time, error address = mailbox->dma.cur_addr
// 1 = all transfered
// A limit for time used by DMA can be compiled-in
bool unibus_c::dma(bool blocking,
uint8_t control, uint32_t startaddr, uint16_t *buffer, unsigned wordcount) {
bool unibus_c::dma(bool blocking, uint8_t control, uint32_t startaddr, uint16_t *buffer,
unsigned wordcount) {
int dma_bandwidth_percent = 50; // use 50% of time for DMA, rest for running PDP-11 CPU
uint64_t dmatime_ns, totaltime_ns;
// can access bus with DMA when there's a Bus Arbitrator
@@ -203,13 +272,12 @@ uint32_t unibus_c::test_sizer(void) {
// all words from start_addr to including end_addr
//
// DMA blocksize can be choosen arbitrarily
void unibus_c::mem_write(uint16_t *words,
unsigned unibus_start_addr, unsigned unibus_end_addr, bool *timeout) {
void unibus_c::mem_write(uint16_t *words, unsigned unibus_start_addr, unsigned unibus_end_addr,
bool *timeout) {
unsigned wordcount = (unibus_end_addr - unibus_start_addr) / 2 + 1;
uint16_t *buffer_start_addr = words + unibus_start_addr / 2;
assert(pru->prucode_id == pru_c::PRUCODE_UNIBUS);
*timeout = !dma(true, UNIBUS_CONTROL_DATO, unibus_start_addr,
buffer_start_addr, wordcount);
*timeout = !dma(true, UNIBUS_CONTROL_DATO, unibus_start_addr, buffer_start_addr, wordcount);
if (*timeout) {
printf("\nWrite timeout @ 0%6o\n", mailbox->dma.cur_addr);
return;
@@ -220,14 +288,13 @@ void unibus_c::mem_write(uint16_t *words,
// all words from start_addr to including end_addr
// DMA blocksize can be choosen arbitrarily
// arbitration_active: if 1, perform NPR/NPG/SACK arbitration before mem accesses
void unibus_c::mem_read(uint16_t *words,
uint32_t unibus_start_addr, uint32_t unibus_end_addr, bool *timeout) {
void unibus_c::mem_read(uint16_t *words, uint32_t unibus_start_addr, uint32_t unibus_end_addr,
bool *timeout) {
unsigned wordcount = (unibus_end_addr - unibus_start_addr) / 2 + 1;
uint16_t *buffer_start_addr = words + unibus_start_addr / 2;
assert(pru->prucode_id == pru_c::PRUCODE_UNIBUS);
*timeout = !dma(true, UNIBUS_CONTROL_DATI, unibus_start_addr,
buffer_start_addr, wordcount);
*timeout = !dma(true, UNIBUS_CONTROL_DATI, unibus_start_addr, buffer_start_addr, wordcount);
if (*timeout) {
printf("\nRead timeout @ 0%6o\n", mailbox->dma.cur_addr);
return;
@@ -235,9 +302,9 @@ void unibus_c::mem_read(uint16_t *words,
}
// read or write
void unibus_c::mem_access_random(
uint8_t unibus_control, uint16_t *words, uint32_t unibus_start_addr,
uint32_t unibus_end_addr, bool *timeout, uint32_t *block_counter) {
void unibus_c::mem_access_random(uint8_t unibus_control, uint16_t *words,
uint32_t unibus_start_addr, uint32_t unibus_end_addr, bool *timeout,
uint32_t *block_counter) {
uint32_t block_unibus_start_addr, block_unibus_end_addr;
// in average, make 16 sub transactions
assert(pru->prucode_id == pru_c::PRUCODE_UNIBUS);
@@ -260,8 +327,8 @@ void unibus_c::mem_access_random(
assert(block_unibus_end_addr <= unibus_end_addr);
(*block_counter) += 1;
// printf("%06d: %5u words %06o-0%06o\n", *block_counter, block_wordcount, block_unibus_start_addr, block_unibus_end_addr) ;
*timeout = !dma(true, unibus_control, block_unibus_start_addr,
block_buffer_start, block_wordcount);
*timeout = !dma(true, unibus_control, block_unibus_start_addr, block_buffer_start,
block_wordcount);
if (*timeout) {
printf("\n%s timeout @ 0%6o\n", control2text(unibus_control),
mailbox->dma.cur_addr);
@@ -272,8 +339,7 @@ void unibus_c::mem_access_random(
}
// arbitration_active: if 1, perform NPR/NPG/SACK arbitration before mem accesses
void unibus_c::test_mem(
uint32_t start_addr, uint32_t end_addr, unsigned mode) {
void unibus_c::test_mem(uint32_t start_addr, uint32_t end_addr, unsigned mode) {
#define MAX_ERROR_COUNT 8
progress_c progress = progress_c(80);
bool timeout = 0, mismatch = 0;
@@ -332,8 +398,8 @@ void unibus_c::test_mem(
// testwords[cur_test_addr / 2] = (cur_test_addr >> 1) & 0xffff; // linear
progress.put("W"); //info : full memory write
mem_access_random(UNIBUS_CONTROL_DATO, testwords, start_addr,
end_addr, &timeout, &total_write_block_count);
mem_access_random(UNIBUS_CONTROL_DATO, testwords, start_addr, end_addr, &timeout,
&total_write_block_count);
if (SIGINTreceived || timeout)
break; // leave loop
@@ -341,8 +407,8 @@ void unibus_c::test_mem(
// first full read
progress.put("R"); //info : full memory write
// read back into unibus_membuffer[]
mem_access_random(UNIBUS_CONTROL_DATI, membuffer->data.words,
start_addr, end_addr, &timeout, &total_read_block_count);
mem_access_random(UNIBUS_CONTROL_DATI, membuffer->data.words, start_addr, end_addr,
&timeout, &total_read_block_count);
// compare
for (mismatch_count = 0, cur_test_addr = start_addr; cur_test_addr <= end_addr;
cur_test_addr += 2) {

View File

@@ -612,7 +612,7 @@ void unibusadapter_c::DMA(dma_request_c& dma_request, bool blocking, uint8_t uni
} while (!completed);
} else if (blocking) {
pthread_mutex_lock(&dma_request.complete_mutex);
pthread_mutex_lock(&dma_request.complete_mutex) ;
// DMA() is blocking: Wait for request to finish.
// pthread_mutex_lock(&dma_request.mutex);
while (!dma_request.complete) {
@@ -1111,15 +1111,17 @@ void unibusadapter_c::worker(unsigned instance) {
// ARM2PRU opcodes raised by device logic are processed in midst of bus cycle
EVENT_ACK(*mailbox, deviceregister); // PRU continues bus cycle with SSYN now
}
if (!EVENT_IS_ACKED(*mailbox, dma) && !mailbox->dma.cpu_access) {
// not called for CPU DATI/DATO
any_event = true;
pthread_mutex_lock(&requests_mutex);
worker_device_dma_chunk_complete_event();
pthread_mutex_unlock(&requests_mutex);
// rpu may have set again event_dma again, if this is called before EVENT signal??
// call this only on singal, not on timeout!
// PRU may have set again event_dma again, if this is called before EVENT signal??
// call this only on signal, not on timeout!
// this may clear reraised PRU event flag!
EVENT_ACK(*mailbox, dma); // PRU may re-raise and change mailbox now

View File

@@ -128,7 +128,6 @@ void main(void) {
break;
case ARM2PRU_BUSLATCH_SET: { // set a mux register
// don't feed "volatile" vars into buslatch_macros !!!
uint8_t reg_sel = mailbox.buslatch.addr & 7;
uint8_t bitmask = mailbox.buslatch.bitmask;

View File

@@ -230,11 +230,11 @@ void main(void) {
// request DMA, arbitrator must've been selected with ARM2PRU_ARB_MODE_*
if (mailbox.dma.cpu_access) {
// Emulated CPU: no NPR/NPG/SACK protocol
sm_arb.cpu_request = 1 ;
sm_arb.cpu_request = 1;
} else {
// Emulated device: raise request for emulated or physical Arbitrator.
sm_arb.device_request_mask |= PRIORITY_ARBITRATION_BIT_NP;
}
}
// request not put on bus for CPU memory access
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
break;
@@ -291,6 +291,24 @@ void main(void) {
emulate_cpu = mailbox.cpu_enable;
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
break;
case ARM2PRU_BUSLATCH_SET: { // set a mux register
// and read back
// don't feed "volatile" vars into buslatch_macros !!!
uint8_t reg_sel = mailbox.buslatch.addr & 7;
uint8_t bitmask = mailbox.buslatch.bitmask;
uint8_t val = mailbox.buslatch.val;
buslatches_setbits(reg_sel, bitmask, val);
mailbox.buslatch.val = buslatches_getbyte(reg_sel);
}
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
break;
case ARM2PRU_BUSLATCH_GET: {
// don't feed "volatile" vars into buslatch_macros !!!
uint8_t reg_sel = mailbox.buslatch.addr & 7;
mailbox.buslatch.val = buslatches_getbyte(reg_sel);
}
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
break;
case ARM2PRU_HALT:
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
__halt(); // LA: trigger on timeout of REG_WRITE

View File

@@ -83,7 +83,7 @@ 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 == 0777560) // DL11
//if (addr == 01046) // trigger address
// PRU_DEBUG_PIN0(1) ; // trigger to LA.

View File

@@ -130,6 +130,8 @@ static statemachine_state_func sm_dma_state_1() {
}
sm_dma.state_timeout = 0;
//if (addr == 01046) // trigger address
// PRU_DEBUG_PIN0(1) ; // trigger to LA.
// addr0..7 = latch[2]
buslatches_setbyte(2, addr & 0xff);

View File

@@ -30,7 +30,7 @@
#include <stdint.h>
#include "unibus.h"
// arm to pru
// ARM to PRU
#define ARM2PRU_NONE 0 // Operation complete: must be 0!
#define ARM2PRU_NOP 1 // to check wether PRU is running
#define ARM2PRU_HALT 2 // run PRU1 into halt
@@ -43,14 +43,14 @@
#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_DMA 14 // DMA with selected arbitration
//#define PRU2ARM_DMA_CPU_TRANSFER_BLOCKED 15 // possible result of ARM2PRU_DMA
#define ARM2PRU_INTR 16 // INTR with arbitration by external Arbitrator
#define ARM2PRU_INTR_CANCEL 17 // clear INTR which has been requested
#define ARM2PRU_CPU_ENABLE 18 // siwtch CPU master side functions ON/OFF
#define ARM2PRU_DDR_FILL_PATTERN 19 // fill DDR with test pattern
#define ARM2PRU_DDR_SLAVE_MEMORY 20 // use DDR as UNIBUS slave memory
#define ARM2PRU_ARB_GRANT_INTR_REQUESTS 21 // emulated CPU answers device requests
#define ARM2PRU_DMA 13 // DMA with selected arbitration
#define ARM2PRU_INTR 14 // INTR with arbitration by external Arbitrator
#define ARM2PRU_INTR_CANCEL 15 // clear INTR which has been requested
#define ARM2PRU_CPU_ENABLE 16 // siwtch CPU master side functions ON/OFF
#define ARM2PRU_DDR_FILL_PATTERN 17 // fill DDR with test pattern
#define ARM2PRU_DDR_SLAVE_MEMORY 18 // use DDR as UNIBUS slave memory
#define ARM2PRU_ARB_GRANT_INTR_REQUESTS 19 // emulated CPU answers device requests
// signal IDs for ARM2PRU_INITALIZATIONSIGNAL_*
@@ -66,7 +66,7 @@
#define DMA_STATE_TIMEOUTSTOP 3 // stop because of UNIBUS timeout
#define DMA_STATE_INITSTOP 4 // stop because INIT signal sensed
// bits BR*/NPR interrupts in buslatch 0 and 1
// Bit masks BR*/NPR and BG*/NPG in buslatch 0 and 1
// bit # is index into arbitration_request[] array.
#define PRIORITY_ARBITRATION_BIT_B4 0x01
#define PRIORITY_ARBITRATION_BIT_B5 0x02

View File

@@ -91,7 +91,10 @@ public:
bool get_arbitrator_active(void);
void powercycle(void);
uint8_t probe_grant_continuity(bool error_if_closed) ;
void powercycle(int phase = 3);
// functions of unibusadapter to do simple DMA
dma_request_c *dma_request;

View File

@@ -69,7 +69,6 @@ void unibone_logdump(void) {
void unibone_on_before_instruction(void) {
// after that the CPU should check for received INTR vectors
// in its microcode service() step.c
// allow PRU do to produce GRANT for device requests
mailbox_execute (ARM2PRU_ARB_GRANT_INTR_REQUESTS);
// Block CPU thread
@@ -267,7 +266,7 @@ void cpu_c::on_after_register_access(unibusdevice_register_t *device_reg,
}
// CPU received interrupt vector from UNIBUS
// PRU triggers this via unibusadapter,
// PRU triggers this via unibusadapter worker thread,
// mailbox->arbitrator.cpu_priority_level is CPU_PRIORITY_LEVEL_FETCHING
// CPU fetches PSW and calls unibone_prioritylevelchange(), which
// sets mailbox->arbitrator.cpu_priority_level and

View File

@@ -15,7 +15,7 @@ int
dati_bus(Bus *bus)
{
unsigned int data;
if(!unibone_dati(bus->addr, &data))
if(!unibone_dati(bus->addr, &data))
return 1;
bus->data = data;
return 0;
@@ -58,7 +58,6 @@ enum {
TRAP_BR6 = 010,
TRAP_BR5 = 040,
TRAP_BR4 = 0100,
TRAP_BRX = 0200, // for unibone
TRAP_CSTOP = 01000 // can't happen?
};
@@ -66,8 +65,8 @@ enum {
enum {
STATE_HALTED = 0,
STATE_RUNNING,
STATE_WAITING
STATE_RUNNING = 1,
STATE_WAITING = 2
};
word
@@ -118,12 +117,15 @@ printstate(KA11 *cpu)
cpu->ba, cpu->ir, cpu->psw);
}
// only to be called from ka11_condstep() thread
void
ka11_reset(KA11 *cpu)
{
Busdev *bd;
cpu->traps = 0;
cpu->external_intr = 0;
cpu->mutex = PTHREAD_MUTEX_INITIALIZER ;
for(bd = cpu->bus->devs; bd; bd = bd->next)
bd->reset(bd->dev);
@@ -133,7 +135,7 @@ int
dati(KA11 *cpu, int b)
{
trace("dati %06o:\n", cpu->ba);
if(!b && cpu->ba&1)
if(!b && cpu->ba&1)
goto be;
/* internal registers */
@@ -551,7 +553,9 @@ step(KA11 *cpu)
/* Operate */
switch(cpu->ir & 7){
case 0: TR(HALT); cpu->state = STATE_HALTED; return;
case 1: TR(WAIT); cpu->state = STATE_WAITING; return;
case 1: TR(WAIT);
printf("WAIT\n") ;
cpu->state = STATE_WAITING; return;
case 2: TR(RTI);
BA = SP; POP; IN(PC);
BA = SP; POP; IN(PSW);
@@ -571,7 +575,7 @@ be: if(cpu->be > 1){
cpu->state = STATE_HALTED;
return;
}
printf("bus error ar %06o\n", cpu->ba);
trace("bus error at %06o\n", cpu->ba);
TRAP(4);
trap:
@@ -589,6 +593,19 @@ trap:
// SVC;
service:
{
// external interrupt from parallel threads?
pthread_mutex_lock(&cpu->mutex) ;
bool external_intr = cpu->external_intr ;
word external_intrvec = cpu->external_intrvec ;
cpu->external_intr = 0 ;
pthread_mutex_unlock(&cpu->mutex) ;
if (external_intr){
TRAP(external_intrvec);
}
}
c = PSW >> 5;
if(oldpsw & PSW_T){
oldpsw &= ~PSW_T;
@@ -600,9 +617,6 @@ service:
}else if(cpu->traps & TRAP_PWR){
cpu->traps &= ~TRAP_PWR;
TRAP(024);
}else if(cpu->traps & TRAP_BRX){
cpu->traps &= ~TRAP_BRX;
TRAP(cpu->trapvec);
}else if(c < 7 && cpu->traps & TRAP_BR7){
cpu->traps &= ~TRAP_BR7;
TRAP(cpu->br[3].bg(cpu->br[3].dev));
@@ -621,19 +635,28 @@ service:
return;
}
// to be called from parallel threads to signal asnyc intr
// (unibusadapter worker thread)
void
ka11_setintr(KA11 *cpu, unsigned vec)
{
cpu->traps |= TRAP_BRX;
cpu->trapvec = vec;
pthread_mutex_lock(&cpu->mutex) ;
cpu->external_intr = true;
cpu->external_intrvec = vec;
trace("INTR vec=%03o\n", vec) ;
pthread_mutex_unlock(&cpu->mutex) ;
}
// only to be called from ka11_condstep() thread
void
ka11_pwrdown(KA11 *cpu)
{
cpu->traps |= TRAP_PWR;
}
// only to be called from ka11_condstep() thread
// if locked, will lock DATI and unibus adapter()!
void
ka11_pwrup(KA11 *cpu)
{

View File

@@ -16,11 +16,16 @@ struct KA11
int (*bg)(void *dev);
void *dev;
} br[4];
word trapvec; // for unibone
// UniBone
pthread_mutex_t mutex ;
volatile bool external_intr ; // INTR by parallel thread pending
volatile word external_intrvec; // associated vector
word sw;
};
void ka11_reset(KA11 *cpu);
void ka11_setintr(KA11 *cpu, unsigned vec);
void ka11_pwrdown(KA11 *cpu);

View File

@@ -11,30 +11,33 @@
11 177560 serial = 177560 ; base addr of DL11
12
13
14 002000 .=2000
15
16 start:
17 002000 012702 177564 mov #serial+4,r2 ; r2 points to DL11 transmitter section
18 002004 012701 002032 mov #string,r1 ; r1 points to the current character
19 nxtchr:
20 002010 012100 mov (r1)+,r0 ; load xmt char into r0
21 002012 001405 beq done ; string ends with 0
22
23 002014 110062 000002 movb r0,2(r2) ; xmt char
24 002020 105712 wait: tstb (r2) ; character transmitted?
25 002022 100376 bpl wait ; no, loop
26 002024 000771 br nxtchr ; transmit nxt char of string
27
28 002026 000000 done: halt
29 002030 000763 br start
14 000000 .=0 ; incomplete
15 000000 000137 002000 jmp @#start
16
17 002000 .=2000
18
19 start:
20 002000 012702 177564 mov #serial+4,r2 ; r2 points to DL11 transmitter section
21 002004 012701 002032 mov #string,r1 ; r1 points to the current character
22 nxtchr:
23 002010 012100 mov (r1)+,r0 ; load xmt char into r0
24 002012 001405 beq done ; string ends with 0
25
26 002014 110062 000002 movb r0,2(r2) ; xmt char
27 002020 105712 wait: tstb (r2) ; character transmitted?
28 002022 100376 bpl wait ; no, loop
29 002024 000771 br nxtchr ; transmit nxt char of string
30
31 string:
32 002032 000110 000145 000154 .word 110,145,154,154,157,054,040 ; "Hello, "
31 002026 000000 done: halt
32 002030 000763 br start
33
34 string:
35 002032 000110 000145 000154 .word 110,145,154,154,157,054,040 ; "Hello, "
002040 000154 000157 000054
002046 000040
33 002050 000167 000157 000162 .word 167,157,162,154,144,041 ; "world!"
36 002050 000167 000157 000162 .word 167,157,162,154,144,041 ; "world!"
002056 000154 000144 000041
34 002064 000015 000012 000000 .word 15,12,0 ; CR, LF, NUL=end marker
35
36 .end
36
37 002064 000015 000012 000000 .word 15,12,0 ; CR, LF, NUL=end marker
38
39 .end
39

View File

@@ -23,9 +23,9 @@
23 ; DU - MSCP disk drive on UDA controller
24
25 ; enable tests
26 000000 kwenab = 0
27 000000 rkenab = 0
28 000000 rlenab = 0
26 000001 kwenab = 1
27 000001 rkenab = 1
28 000001 rlenab = 1
29 000000 ryenab = 0 ; not yet tested
30 000000 duenab = 0 ; not yet implemeneted
31
@@ -44,28 +44,28 @@
44 000026 000340 .word 340 ; PSW priority level 7
45
46 000060 . = corvec
47 000060 001132 .word corisr ; RCV interrupt
47 000060 001264 .word corisr ; RCV interrupt
48 000062 000340 .word 340
49 000064 . = coxvec
50 000064 001146 .word coxisr ; XMT interrupt
50 000064 001300 .word coxisr ; XMT interrupt
51 000066 000340 .word 340
52
53 000000 .if ne kwenab
54 . = kwvect
55 .word kwisr ; periodic interrupt
56 .word 340
53 000001 .if ne kwenab
54 000100 . = kwvect
55 000100 001524 .word kwisr ; periodic interrupt
56 000102 000340 .word 340
57 .endc
58
59 000000 .if ne rlenab
60 . = rlvect ; RL11
61 .word rlisr
62 .word 340
59 000001 .if ne rlenab
60 000160 . = rlvect ; RL11
61 000160 004640 .word rlisr
62 000162 000340 .word 340
63 .endc
64
65 000000 .if ne rkenab
66 . = rkvect ; RK11
67 .word rkisr
68 .word 340
65 000001 .if ne rkenab
66 000220 . = rkvect ; RK11
67 000220 002562 .word rkisr
68 000222 000340 .word 340
69 .endc
70
71 000000 .if ne ryenab
@@ -92,16 +92,16 @@
92 001004 005037 177776 clr @#psw ; priorty level 0, allow INTR
93 ; Initialize devices
94 001010 000005 reset
95 001012 004737 001154 call corini
96 001016 004737 001170 call coxini
97 000000 .if ne kwenab
98 call kwinit
95 001012 004737 001306 call corini
96 001016 004737 001322 call coxini
97 000001 .if ne kwenab
98 001022 004737 001536 call kwinit
99 .endc
100 000000 .if ne rkenab
101 call rkinit
100 000001 .if ne rkenab
101 001026 004737 002570 call rkinit
102 .endc
103 000000 .if ne rlenab
104 call rlinit
103 000001 .if ne rlenab
104 001032 004737 004646 call rlinit
105 .endc
106 000000 .if ne ryenab
107 call ryinit
@@ -110,67 +110,67 @@
110 call duinit
111 .endc
112
113 001022 012701 001366 mov #shello,r1 ; Print "Hello" message
114 001026 004737 001204 call puts
113 001036 012701 004766 mov #shello,r1 ; Print "Hello" message
114 001042 004737 001336 call puts
115
116 ; main loop: check interrupt flags, restart DMA
117 ; process serial input
118 loop:
119 001032 004737 001044 call dokbd ; check keyboard input
120 001036 004737 001104 call dodev ; check device activities
121 001042 000773 br loop
119 001046 004737 001060 call dokbd ; check keyboard input
120 001052 004737 001120 call dodev ; check device activities
121 001056 000773 br loop
122
123
124
125 ; --- check keyboard input
126 dokbd:
127 001044 004737 001336 call getc
128 001050 103014 bcc 9$ ; nothing received
127 001060 004737 001470 call getc
128 001064 103014 bcc 9$ ; nothing received
129 ; process char in r0
130 001052 120027 000003 cmpb r0,#3
131 001056 001007 bne 1$
132 001060 012701 001457 mov #sbye,r1 ; ^C: print "Bye", back to monitor
133 001064 004737 001204 call puts
134 001070 000005 reset ; stop devices
135 001072 000137 165020 jmp monitr
130 001066 120027 000003 cmpb r0,#3
131 001072 001007 bne 1$
132 001074 012701 005057 mov #sbye,r1 ; ^C: print "Bye", back to monitor
133 001100 004737 001336 call puts
134 001104 000005 reset ; stop devices
135 001106 000137 165020 jmp monitr
136 1$:
137 ; echo chars without special meaning
138 001076 004737 001316 call putc
138 001112 004737 001450 call putc
139 9$:
140 001102 000207 return
140 001116 000207 return
141
142 ; -- check device activities
143 dodev:
144 ; For all devices: restart device DMA if Interrupt received
145 000000 .if ne kwenab
146 tst kwiflg
147 beq 1$
148 clr kwiflg
149 call kwgo
150 mov #kwlabl,r0 ; progress printout
151 mov #kwecnt,r1
152 call progrs
145 000001 .if ne kwenab
146 001120 005737 001520 tst kwiflg
147 001124 001412 beq 1$
148 001126 005037 001520 clr kwiflg
149 001132 004737 001552 call kwgo
150 001136 012700 000127 mov #kwlabl,r0 ; progress printout
151 001142 012701 001522 mov #kwecnt,r1
152 001146 004737 001240 call progrs
153 1$:
154 .endc
155
156 000000 .if ne rkenab
157 tst rkiflg
158 beq 2$
159 clr rkiflg
160 call rkgo
161 mov #rklabl,r0 ; progress printout
162 mov #rkecnt,r1
163 call progrs
156 000001 .if ne rkenab
157 001152 005737 001554 tst rkiflg
158 001156 001412 beq 2$
159 001160 005037 001554 clr rkiflg
160 001164 004737 002576 call rkgo
161 001170 012700 000113 mov #rklabl,r0 ; progress printout
162 001174 012701 002560 mov #rkecnt,r1
163 001200 004737 001240 call progrs
164 2$:
165 .endc
166 000000 .if ne rlenab
167 tst rliflg
168 beq 3$
169 clr rliflg
170 call rlgo
171 mov #rllabl,r0 ; progress printout
172 mov #rlecnt,r1
173 call progrs
166 000001 .if ne rlenab
167 001204 005737 002632 tst rliflg
168 001210 001412 beq 3$
169 001212 005037 002632 clr rliflg
170 001216 004737 004654 call rlgo
171 001222 012700 000114 mov #rllabl,r0 ; progress printout
172 001226 012701 004636 mov #rlecnt,r1
173 001232 004737 001240 call progrs
174 3$:
175 .endc
176 000000 .if ne ryenab
@@ -194,7 +194,7 @@
194 5$:
195 .endc
196
197 001104 000207 return
197 001236 000207 return
198
199
200 ; progress
@@ -202,12 +202,12 @@
202 ; 1024. if yes, print the char in r0
203 progrs:
204 ; bic #777700,(r1) ; mask counter to 0..63
205 001106 042711 177400 bic #777400,(r1) ; mask counter to 0..255
205 001240 042711 177400 bic #777400,(r1) ; mask counter to 0..255
206 ; bic #776000,(r1) ; mask counter to 0..1023
207 001112 001002 bne 9$
208 001114 004737 001316 call putc ; is at 0: print label character
207 001244 001002 bne 9$
208 001246 004737 001450 call putc ; is at 0: print label character
209 9$:
210 001120 000207 return
210 001252 000207 return
211
212
213
@@ -224,30 +224,30 @@
10
11 ; -- ISRs, increment Interrupt FLags
12
13 001122 000001 corifl: .word 1 ; Interrupt flags
14 001124 000001 coxifl: .word 1
13 001254 000001 corifl: .word 1 ; Interrupt flags
14 001256 000001 coxifl: .word 1
15
16 001126 corbuf: .blkw 1 ; data buffer
17 001130 coxbuf: .blkw 1
16 001260 corbuf: .blkw 1 ; data buffer
17 001262 coxbuf: .blkw 1
18
19 corisr:
20 001132 013737 177562 001126 mov @#corbas+2,corbuf ; read char, clear INTR
21 001140 005237 001122 inc corifl
22 001144 000002 rti
20 001264 013737 177562 001260 mov @#corbas+2,corbuf ; read char, clear INTR
21 001272 005237 001254 inc corifl
22 001276 000002 rti
23
24 coxisr:
25 001146 005237 001124 inc coxifl
26 001152 000002 rti
25 001300 005237 001256 inc coxifl
26 001304 000002 rti
27
28 ; -- Initialize device after RESET
29 corini:
30 001154 012737 000100 177560 mov #100,@#corbas ; Bit 6 = Receiver Interrupt Enable
31 001162 005037 001122 clr corifl
32 001166 000207 return
30 001306 012737 000100 177560 mov #100,@#corbas ; Bit 6 = Receiver Interrupt Enable
31 001314 005037 001254 clr corifl
32 001320 000207 return
33 coxini:
34 001170 012737 000100 177564 mov #100,@#coxbas ; Bit 6 = Transmitter Interrupt Enable
35 001176 005037 001124 clr coxifl
36 001202 000207 return
34 001322 012737 000100 177564 mov #100,@#coxbas ; Bit 6 = Transmitter Interrupt Enable
35 001330 005037 001256 clr coxifl
36 001334 000207 return
37
38
39
@@ -256,75 +256,199 @@
42 ; puts - print a string
43 ; r1 = pointer, r0,r1 changed
44 puts:
45 001204 112100 movb (r1)+,r0 ; load xmt char
46 001206 001403 beq 1$ ; string ends with 0
47 001210 004737 001316 call @#putc
48 001214 000773 br puts ; transmit nxt char of string
49 001216 000207 1$: return
45 001336 112100 movb (r1)+,r0 ; load xmt char
46 001340 001403 beq 1$ ; string ends with 0
47 001342 004737 001450 call @#putc
48 001346 000773 br puts ; transmit nxt char of string
49 001350 000207 1$: return
50
51
52 ; putnum - print the octal number in r0
53 001220 numbf0: .blkw 10 ; space to mount number string
54 001240 numbf1 =.
53 001352 numbf0: .blkw 10 ; space to mount number string
54 001372 numbf1 =.
55 putnum:
56 001240 010346 mov r3,-(sp)
57 001242 010002 mov r0,r2 ; r2 = shifter
58 001244 012701 001240 mov #numbf1,r1 ; r1 = buffer pointer, backwards
59 001250 112741 000000 movb #0,-(r1) ; set terminating 0
56 001372 010346 mov r3,-(sp)
57 001374 010002 mov r0,r2 ; r2 = shifter
58 001376 012701 001372 mov #numbf1,r1 ; r1 = buffer pointer, backwards
59 001402 112741 000000 movb #0,-(r1) ; set terminating 0
60 ; repeat 6 times
61 001254 012703 000006 mov #6,r3
61 001406 012703 000006 mov #6,r3
62 1$:
63 001260 010200 mov r2,r0
63 001412 010200 mov r2,r0
64 ; extract lower 3 bits = octal digit
65 001262 042700 177770 bic #177770,r0 ; r0 &= 0x07
66 001266 062700 000060 add #60,r0 ; r0 += '0'
67 001272 110041 movb r0,-(r1) ; write in buffer
68 001274 000241 clc
69 001276 006202 asr r2 ; shift to next digit
70 001300 006202 asr r2
71 001302 006202 asr r2
72 001304 077313 sob r3,1$ ; loop for all 6 digits
65 001414 042700 177770 bic #177770,r0 ; r0 &= 0x07
66 001420 062700 000060 add #60,r0 ; r0 += '0'
67 001424 110041 movb r0,-(r1) ; write in buffer
68 001426 000241 clc
69 001430 006202 asr r2 ; shift to next digit
70 001432 006202 asr r2
71 001434 006202 asr r2
72 001436 077313 sob r3,1$ ; loop for all 6 digits
73
74 001306 004737 001204 call @#puts
75 001312 012603 mov (sp)+,r3
76 001314 000207 return
74 001440 004737 001336 call @#puts
75 001444 012603 mov (sp)+,r3
76 001446 000207 return
77
78
79 ; putc - output a single char
80 ; r0 = char
81 putc:
82 001316 005037 001124 clr coxifl ; reset interrupt flag
83 001322 010037 177566 mov r0,@#coxbas+2 ; char into transmit buffer
84 001326 005737 001124 1$: tst coxifl ; XMT RDY?
85 001332 001775 beq 1$ ; no, loop
82 001450 005037 001256 clr coxifl ; reset interrupt flag
83 001454 010037 177566 mov r0,@#coxbas+2 ; char into transmit buffer
84 001460 005737 001256 1$: tst coxifl ; XMT RDY?
85 001464 001775 beq 1$ ; no, loop
86 ; UART is buffering: char only started to sent now
87 ; interrupt active until next putc
88 001334 000207 return
88 001466 000207 return
89
90 ; getc - poll and input a single char
91 ; result in r0
92 ; carry clear : nothing received
93 ; carry set: char received
94 getc:
95 001336 005000 clr r0
96 001340 005737 001122 tst corifl
97 001344 001002 bne 1$
98 001346 000241 clc ; Carry clear, no Interrupt, nothing received
99 001350 000207 return
95 001470 005000 clr r0
96 001472 005737 001254 tst corifl
97 001476 001002 bne 1$
98 001500 000241 clc ; Carry clear, no Interrupt, nothing received
99 001502 000207 return
100 1$:
101 001352 013700 001126 mov corbuf,r0 ; Interrupt, return char
102 001356 005037 001122 clr corifl ; reset interrupt flag
103 001362 000261 sec ; Carry Set
104 001364 000207 return
101 001504 013700 001260 mov corbuf,r0 ; Interrupt, return char
102 001510 005037 001254 clr corifl ; reset interrupt flag
103 001514 000261 sec ; Carry Set
104 001516 000207 return
104
215 000000 .if ne kwenab
215 000001 .if ne kwenab
216 .include ma_kw.mac
1 .title ma_kw - KW11 test driver
2
3 ; KW11 raises INTR at 50 Hz
4
5 000100 kwvect = 100 ; vector of KW11 line clock
6 177546 kwbase = 777546 ; base addr of KW11 register
7 000127 kwlabl = 'W ; label char
8
9
10 ; --- ISRs, increment Interrupt FLags
11 001520 000001 kwiflg: .word 1 ; Interrupt flags
12
13 001522 000001 kwecnt: .word 1 ; event counter
14
15 kwisr:
16 001524 005237 001522 inc kwecnt ; register as event
17 001530 005237 001520 inc kwiflg ; set ISR flag
18 001534 000002 rti
19
20 ; --- Initialize device after RESET
21 kwinit:
22 001536 012737 000100 177546 mov #100,@#kwbase ; set interrupt enable
23 001544 005037 001522 clr kwecnt
24 001550 000207 return
25
26 ; --- Restart new INTR
27 kwgo:
28 ; nothing todo, INTR repeated automatically
29 ; bic #200,@#kwbase ; clear INTERRUPT MONITOR bit
30 001552 000207 return
31
31
217 .endc
218 000000 .if ne rkenab
218 000001 .if ne rkenab
219 .include ma_rk.mac
1
2 .title ma_rk - RK11/RK05 test driver
3 ; RK11 DMA is generated by reading cylinder 0, head 0, sector 0
4
5 000220 rkvect = 220 ; vector of RK11 controller
6 177400 rkbase = 777400 ; base addr of RK11 controller
7 000113 rklabl = 'K ; label char
8
9 ; --- ISRs, increment Interrupt FLags
10 001554 000001 rkiflg: .word 1 ; Interrupt flags
11
12 001556 rkbuff: .blkw 400+1 ; data buffer: 1 sector = 256 words
13
14 002560 000001 rkecnt: .word 1 ; event counter
15
16 rkisr:
17 002562 005237 001554 inc rkiflg ; set ISR flag
18 002566 000002 rti
19
20 ; --- Initialize device after RESET
21 rkinit:
22 002570 005037 002560 clr rkecnt
23 002574 000207 return
24
25 ; --- Restart new DMA transmission
26 rkgo:
27 ; read first sector into rkbuff
28 002576 005037 177412 clr @#rkbase+12 ; DA disk address = 0: unit 0, cyl/hd/sec=0
29 002602 012737 001556 177410 mov #rkbuff,@#rkbase+10 ; BA bus address of DMA
30 002610 012737 177400 177406 mov #-400,@#rkbase+6 ; WC word count = 256 words
31 002616 012737 000105 177404 mov #100+4+1,@#rkbase+4 ; Command INT ENABLE + "READ" + GO
32 002624 005237 002560 inc rkecnt ; register as event
33 002630 000207 return
34
34
220 .endc
221 000000 .if ne rlenab
221 000001 .if ne rlenab
222 .include ma_rl.mac
1 .title ma_rl - RL11/RL01/2 test driver
2
3 ; RL11 DMA is generated by reading cylinder 0, head0, sector 0
4
5 000160 rlvect = 160 ; vector of RL11 controller
6 174400 rlbase = 774400 ; base addr of RL11 controller
7 000114 rllabl = 'L ; label char
8
9
10 ; --- ISRs, increment Interrupt FLags
11 002632 000001 rliflg: .word 1 ; Interrupt flags
12
13 002634 rlbuff: .blkw 2*400+1 ; data buffer: 2 sector = 256 words
14
15 004636 000001 rlecnt: .word 1 ; event counter
16
17 rlisr:
18 004640 005237 002632 inc rliflg ; set ISR flag
19 004644 000002 rti
20
21 ; --- Initialize device after RESET
22 rlinit:
23 004646 005037 004636 clr rlecnt
24 004652 000207 return
25
26 ; --- Restart new DMA transmission
27 rlgo:
28 004654 012701 174400 mov #rlbase,r1 ; r1 = controller base address
29
30 ; sequence from boot loader 23-751A9, lot of testing
31 ; 1. get status
32 004660 012761 000013 000004 mov #013,4(r1) ; DA subcmd reset+getstatus
33 004666 012711 000004 mov #4,(r1) ; CSR do "GET STATUS"
34 004672 105711 1$: tstb (r1) ; test for ready
35 004674 100376 bpl 1$ ; wait
36 ; 2. read current track
37 004676 012711 000010 mov #10,(r1) ; CSR read header cmd
38 004702 105711 2$: tstb (r1) ; test for ready
39 004704 100376 bpl 2$ ; wait
40 ; 3. seek
41 004706 016102 000006 mov 6(r1),r2 ; MP retrieve cyl/head/sector
42 004712 042702 000077 bic #77,r2 ; set sector to zero
43 004716 005202 inc r2 ; set seek flag, head 0, seek to cyl 0
44 004720 010261 000004 mov r2,4(r1) ; DA for seek
45 004724 012711 000006 mov #6,(r1) ; CSR seek cmd
46 004730 105711 3$: tstb (r1) ; test for ready
47 004732 100376 bpl 3$ ; wait
48 ; 4. read sector 0+1 and interrupt
49 004734 012761 002634 000002 mov #rlbuff,2(r1) ; BA bus address of DMA
50 004742 005061 000004 clr 4(r1) ; DA select cyl0/head0/sector0
51 004746 012761 177000 000006 mov #-512.,6(r1) ; MP set word count
52 004754 012711 000114 mov #100+14,(r1) ; CSR read data cmd with Interrupt Enable
53
54 004760 005237 004636 inc rlecnt ; register as event
55 004764 000207 return
56
56
223 .endc
224 000000 .if ne ryenab
225 .include ma_ry.mac
@@ -336,36 +460,36 @@
1
2 .title ma_strings - String constants
3 shello:
4 001366 015 012 .byte 15,12 ; space, CR, LF,
5 001370 052 052 052 .ascii /*** Multi Device Interrupt&DMA test ***/
001373 040 115 165
001376 154 164 151
001401 040 104 145
001404 166 151 143
001407 145 040 111
001412 156 164 145
001415 162 162 165
001420 160 164 046
001423 104 115 101
001426 040 164 145
001431 163 164 040
001434 052 052 052
6 001437 015 012 .byte 15,12 ; CR, LF
7 001441 136 103 040 .ascii /^C to stop./
001444 164 157 040
001447 163 164 157
001452 160 056
8 001454 015 012 .byte 15,12 ; CR, LF
9 001456 000 .byte 0
4 004766 015 012 .byte 15,12 ; space, CR, LF,
5 004770 052 052 052 .ascii /*** Multi Device Interrupt&DMA test ***/
004773 040 115 165
004776 154 164 151
005001 040 104 145
005004 166 151 143
005007 145 040 111
005012 156 164 145
005015 162 162 165
005020 160 164 046
005023 104 115 101
005026 040 164 145
005031 163 164 040
005034 052 052 052
6 005037 015 012 .byte 15,12 ; CR, LF
7 005041 136 103 040 .ascii /^C to stop./
005044 164 157 040
005047 163 164 157
005052 160 056
8 005054 015 012 .byte 15,12 ; CR, LF
9 005056 000 .byte 0
10
11
12 sbye:
13 001457 015 012 .byte 15,12
14 001461 107 157 157 .ascii /Good Bye!/
001464 144 040 102
001467 171 145 041
15 001472 015 012 .byte 15,12 ; CR, LF
16 001474 000 .byte 0
13 005057 015 012 .byte 15,12
14 005061 107 157 157 .ascii /Good Bye!/
005064 144 040 102
005067 171 145 041
15 005072 015 012 .byte 15,12 ; CR, LF
16 005074 000 .byte 0
17
17
231

View File

@@ -123,7 +123,7 @@ void application_c::menu_device_exercisers(void) {
} else if (!strcasecmp(s_opcode, "init")) {
unibus->init(50);
} else if (!strcasecmp(s_opcode, "pwr")) {
unibus->powercycle();
unibus->probe_grant_continuity(true);
} else if (!strcasecmp(s_opcode, "dbg") && n_fields == 2) {
if (!strcasecmp(s_param[0], "c")) {
logger->clear();

View File

@@ -182,7 +182,7 @@ void application_c::menu_devices(bool with_emulated_CPU) {
}
// now devices are "Plugged in". Reset PDP-11.
unibus->powercycle();
unibus->probe_grant_continuity(true);
while (!ready) {
@@ -261,7 +261,7 @@ void application_c::menu_devices(bool with_emulated_CPU) {
} else if (!strcasecmp(s_opcode, "init")) {
unibus->init(50);
} else if (!strcasecmp(s_opcode, "pwr")) {
unibus->powercycle();
unibus->probe_grant_continuity(true) ;
} else if (!strcasecmp(s_opcode, "dbg") && n_fields == 2) {
if (!strcasecmp(s_param[0], "c")) {
logger->clear();

View File

@@ -121,7 +121,7 @@ void application_c::menu_interrupts(void) {
if (!strcasecmp(s_opcode, "q")) {
ready = true;
} else if (!strcasecmp(s_opcode, "pwr")) {
unibus->powercycle();
unibus->probe_grant_continuity(true);
} else if (!strcasecmp(s_opcode, "m") && n_fields == 1) {
emulate_memory();
} else if (!strcasecmp(s_opcode, "e") && n_fields == 2) {

View File

@@ -158,7 +158,7 @@ void application_c::menu_masterslave(bool with_CPU) {
} else if (!strcasecmp(s_opcode, "i")) {
iopageregisters_print_tables();
} else if (!strcasecmp(s_opcode, "pwr")) {
unibus->powercycle();
unibus->probe_grant_continuity(true);
} else if (!strcasecmp(s_opcode, "m") && n_fields == 3) {
uint32_t start_addr, end_addr;
parse_addr18(s_param[0], &start_addr);