From f314317e2a82603a692c1bbdfb37e48a64c4ea22 Mon Sep 17 00:00:00 2001 From: Joerg Hoppe Date: Fri, 4 Oct 2019 12:45:26 +0200 Subject: [PATCH] DMA/INTR arbitration rework, emulated CPU20 with DMA&INTR, runs XXDP --- 10.01_base/2_src/arm/gpios.hpp | 10 +- 10.01_base/2_src/arm/priorityrequest.cpp | 7 +- 10.01_base/2_src/arm/priorityrequest.hpp | 8 +- 10.01_base/2_src/arm/unibus.cpp | 67 +- 10.01_base/2_src/arm/unibusadapter.cpp | 309 ++++---- 10.01_base/2_src/arm/unibusadapter.hpp | 4 +- 10.01_base/2_src/arm/utils.cpp | 8 +- 10.01_base/2_src/arm/utils.hpp | 6 +- 10.01_base/2_src/pru1/pru1_main_unibus.c | 97 +-- .../pru1/pru1_statemachine_arbitration.c | 154 ++-- .../pru1/pru1_statemachine_arbitration.h | 18 +- .../2_src/pru1/pru1_statemachine_data_slave.c | 2 +- 10.01_base/2_src/pru1/pru1_statemachine_dma.c | 56 +- .../pru1/pru1_statemachine_intr_master.c | 2 - .../2_src/pru1/pru1_statemachine_intr_slave.c | 2 +- 10.01_base/2_src/shared/mailbox.h | 26 +- 10.01_base/2_src/shared/unibus.h | 34 +- 10.01_base/3_test/multiarb/macro11.sh | 26 + 10.01_base/3_test/multiarb/multiarb.lst | 666 ++++++++++-------- 10.01_base/3_test/multiarb/multiarb.mac | 14 +- 10.02_devices/2_src/cpu.cpp | 132 ++-- 10.02_devices/2_src/cpu.hpp | 4 + 10.02_devices/2_src/cpu20/ka11.c | 14 +- 10.02_devices/2_src/dl11w.cpp | 107 +-- 10.02_devices/3_test/cpu20/cpu20multiarb.cmd | 90 +++ 10.02_devices/3_test/cpu20/multiarb.lst | 376 ++++++++++ 10.02_devices/5_boot/dk.lst | 139 ++-- 10.02_devices/5_boot/dk.mac | 13 +- 10.02_devices/5_boot/dl.lst | 145 ++-- 10.02_devices/5_boot/dl.mac | 13 +- 10.02_devices/5_boot/du.lst | 189 ++--- 10.02_devices/5_boot/du.mac | 13 +- 10.03_app_demo/2_src/application.cpp | 20 - 10.03_app_demo/2_src/application.hpp | 11 +- .../2_src/menu_ddrmem_slave_only.cpp | 3 +- .../2_src/menu_device_exercisers.cpp | 18 +- 10.03_app_demo/2_src/menu_devices.cpp | 55 +- 10.03_app_demo/2_src/menu_interrupts.cpp | 27 +- 10.03_app_demo/2_src/menu_masterslave.cpp | 46 +- 10.03_app_demo/2_src/menus.cpp | 64 +- .../211bsd.mscp/211BSD_du0_44.sh | 2 +- .../5_applications/211bsd.mscp/du.lst | 189 ++--- .../5_applications/mini-unix.rk05/dk.lst | 139 ++-- .../mini-unix.rk05/mini-unix_dk0_05.sh | 2 +- .../5_applications/rsx11.mscp/du.lst | 189 ++--- .../5_applications/rsx11.rl02/dl.lst | 145 ++-- .../rsx11.rl02/rsx11m4.1_dl0_34.sh | 2 +- .../5_applications/rt11.mscp/du.lst | 189 ++--- .../rt11.mscp/rt11v5.5fb_du0_34.sh | 2 +- .../5_applications/rt11.rl02/dl.lst | 145 ++-- .../rt11.rl02/rt11v5.5fb_dl0_34.sh | 2 +- .../rt11.rl02/rt11v5.5sj_dl1_34.sh | 2 +- .../5_applications/unixv6.rk05/dk.lst | 139 ++-- .../unixv6.rk05/unixv6_dk0_34.sh | 2 +- .../5_applications/xxdp.rl02/dl.lst | 145 ++-- .../5_applications/xxdp.rl02/xxdp2.2_dl0.sh | 2 +- .../5_applications/xxdp.rl02/xxdp2.5_dl1.sh | 2 +- 57 files changed, 2498 insertions(+), 1795 deletions(-) create mode 100644 10.01_base/3_test/multiarb/macro11.sh create mode 100644 10.02_devices/3_test/cpu20/cpu20multiarb.cmd create mode 100644 10.02_devices/3_test/cpu20/multiarb.lst diff --git a/10.01_base/2_src/arm/gpios.hpp b/10.01_base/2_src/arm/gpios.hpp index 65d2840..8fa580c 100644 --- a/10.01_base/2_src/arm/gpios.hpp +++ b/10.01_base/2_src/arm/gpios.hpp @@ -87,10 +87,12 @@ typedef struct { // test pins // SET(1) -> pin auf H, LED OFF -#define ARM_DEBUG_PIN0(n) GPIO_SETVAL(gpios->led[0], !!(n)) -#define ARM_DEBUG_PIN1(n) GPIO_SETVAL(gpios->led[1], !!(n)) -#define ARM_DEBUG_PIN2(n) GPIO_SETVAL(gpios->led[2], !!(n)) -#define ARM_DEBUG_PIN3(n) GPIO_SETVAL(gpios->led[3], !!(n)) +#define ARM_DEBUG_PIN0(val) GPIO_SETVAL(gpios->led[0], !!(val)) +#define ARM_DEBUG_PIN1(val) GPIO_SETVAL(gpios->led[1], !!(val)) +#define ARM_DEBUG_PIN2(val) GPIO_SETVAL(gpios->led[2], !!(val)) +#define ARM_DEBUG_PIN3(val) GPIO_SETVAL(gpios->led[3], !!(val)) +#define ARM_DEBUG_PIN(n,val) GPIO_SETVAL(gpios->led[n], !!(val)) + class gpios_c: public logsource_c { diff --git a/10.01_base/2_src/arm/priorityrequest.cpp b/10.01_base/2_src/arm/priorityrequest.cpp index d81d4aa..fa85ac9 100644 --- a/10.01_base/2_src/arm/priorityrequest.cpp +++ b/10.01_base/2_src/arm/priorityrequest.cpp @@ -35,7 +35,7 @@ priority_request_c::priority_request_c(unibusdevice_c *device) { this->device = device; this->complete = false; this->executing_on_PRU = false; - this->slot = 0xff; // uninitialized, asserts() if used + this->priority_slot = 0xff; // uninitialized, asserts() if used complete_mutex = PTHREAD_MUTEX_INITIALIZER; complete_cond = PTHREAD_COND_INITIALIZER; // PRU signal notifies request on completeness } @@ -47,13 +47,13 @@ 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) + if (this->priority_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()); } - this->slot = priority_slot; + this->priority_slot = priority_slot; // todo: check for collision with all other devices, all other requests } @@ -62,6 +62,7 @@ dma_request_c::dma_request_c(unibusdevice_c *device) : priority_request_c(device) { this->level_index = PRIORITY_LEVEL_INDEX_NPR; this->success = false; + this->is_cpu_access = false ;// over written for emulated CPU // register request for device if (device) { device->dma_requests.push_back(this); diff --git a/10.01_base/2_src/arm/priorityrequest.hpp b/10.01_base/2_src/arm/priorityrequest.hpp index c6c61e5..d41d3ed 100644 --- a/10.01_base/2_src/arm/priorityrequest.hpp +++ b/10.01_base/2_src/arm/priorityrequest.hpp @@ -74,7 +74,7 @@ private: // internal priority index of a request level, see REQUEST_INDEX_* uint8_t level_index; // is BR4567,NPR level - 4 - uint8_t slot; // backplane slot which triggered request + uint8_t priority_slot; // backplane priority_slot which triggered request public: // better make state variables volatile, accessed by unibusadapter::worker volatile bool executing_on_PRU; // true between schedule to PRU and compelte signal @@ -89,7 +89,7 @@ public: void set_priority_slot(uint8_t slot); uint8_t get_priority_slot(void) { - return slot; + return priority_slot; } }; @@ -106,6 +106,8 @@ public: uint16_t* buffer; uint32_t wordcount; + bool is_cpu_access; // true if DMA is CPU memory access + // DMA transaction are divided in to smaller DAT transfer "chunks" uint32_t chunk_max_words; // max is PRU capacity PRU_MAX_DMA_WORDCOUNT (512) uint32_t chunk_unibus_start_addr; // current chunk @@ -166,7 +168,7 @@ public: // detect raising edge of interrupt level enum interrupt_edge_enum edge_detect(bool new_signal_level) { - if (signal_level == new_signal_level) + if (signal_level == new_signal_level) return INTERRUPT_EDGE_NONE; else { // change: which edge? diff --git a/10.01_base/2_src/arm/unibus.cpp b/10.01_base/2_src/arm/unibus.cpp index cf27eee..eaa12e2 100644 --- a/10.01_base/2_src/arm/unibus.cpp +++ b/10.01_base/2_src/arm/unibus.cpp @@ -136,40 +136,32 @@ void unibus_c::powercycle(void) { timeout.wait_ms(delay_ms); } -void unibus_c::set_arbitration_mode(arbitration_mode_enum arbitration_mode) { - // switch pru to desired mode - switch (arbitration_mode) { - case unibus_c::ARBITRATION_MODE_NONE: - mailbox_execute(ARM2PRU_ARB_MODE_NONE); - break; - case unibus_c::ARBITRATION_MODE_CLIENT: +void unibus_c::set_arbitrator_active(bool active) { + if (active) { mailbox_execute(ARM2PRU_ARB_MODE_CLIENT); - break; - case unibus_c::ARBITRATION_MODE_MASTER: - mailbox_execute(ARM2PRU_ARB_MODE_MASTER); - break; - default: - printf("Illegal arbitration_mode %d\n", (int) arbitration_mode); - exit(1); + } else { + mailbox_execute(ARM2PRU_ARB_MODE_NONE); } + arbitrator_active = active; } -// do a DMA transaction with or without abritration (arbitration_client) +bool unibus_c::get_arbitrator_active(void) { + return arbitrator_active; +} + +// do a DMA transaction with or without arbitration (arbitration_client) // mailbox.dma.words already filled // if result = timeout: = // 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(enum unibus_c::arbitration_mode_enum arbitration_mode, bool blocking, +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 assert(pru->prucode_id == pru_c::PRUCODE_UNIBUS); - set_arbitration_mode(arbitration_mode); // changes PRU behaviour - timeout.start_ns(0); // no timeout, just running timer unibusadapter->DMA(*dma_request, blocking, control, startaddr, buffer, wordcount); @@ -192,11 +184,10 @@ bool unibus_c::dma(enum unibus_c::arbitration_mode_enum arbitration_mode, bool b * arbitration_active: if 1, perform NPR/NPG/SACK arbitration before mem accesses * words[]: buffer for whole UNIBUS address range, is filled with data */ -uint32_t unibus_c::test_sizer(enum unibus_c::arbitration_mode_enum arbitration_mode) { +uint32_t unibus_c::test_sizer(void) { // tests chunks of 128 word unsigned addr = 0; - set_arbitration_mode(arbitration_mode); // changes PRU behaviour // one big transaction, automatically split in chunks unibusadapter->DMA(*dma_request, true, UNIBUS_CONTROL_DATI, addr, testwords, UNIBUS_WORDCOUNT); @@ -212,12 +203,12 @@ uint32_t unibus_c::test_sizer(enum unibus_c::arbitration_mode_enum arbitration_m // all words from start_addr to including end_addr // // DMA blocksize can be choosen arbitrarily -void unibus_c::mem_write(enum unibus_c::arbitration_mode_enum arbitration_mode, uint16_t *words, +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(arbitration_mode, true, UNIBUS_CONTROL_DATO, unibus_start_addr, + *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); @@ -229,13 +220,13 @@ void unibus_c::mem_write(enum unibus_c::arbitration_mode_enum arbitration_mode, // 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(enum unibus_c::arbitration_mode_enum arbitration_mode, uint16_t *words, +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(arbitration_mode, true, UNIBUS_CONTROL_DATI, unibus_start_addr, + *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); @@ -244,7 +235,7 @@ void unibus_c::mem_read(enum unibus_c::arbitration_mode_enum arbitration_mode, u } // read or write -void unibus_c::mem_access_random(enum unibus_c::arbitration_mode_enum arbitration_mode, +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; @@ -269,7 +260,7 @@ void unibus_c::mem_access_random(enum unibus_c::arbitration_mode_enum arbitratio 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(arbitration_mode, true, unibus_control, block_unibus_start_addr, + *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), @@ -281,7 +272,7 @@ void unibus_c::mem_access_random(enum unibus_c::arbitration_mode_enum arbitratio } // arbitration_active: if 1, perform NPR/NPG/SACK arbitration before mem accesses -void unibus_c::test_mem(enum unibus_c::arbitration_mode_enum arbitration_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); @@ -301,7 +292,7 @@ void unibus_c::test_mem(enum unibus_c::arbitration_mode_enum arbitration_mode, testwords[cur_test_addr / 2] = (cur_test_addr >> 1) & 0xffff; /**** 2. Write memory ****/ progress.put("W"); //info : full memory write - mem_write(arbitration_mode, testwords, start_addr, end_addr, &timeout); + mem_write(testwords, start_addr, end_addr, &timeout); /**** 3. read until ^C ****/ while (!SIGINTreceived && !timeout && !mismatch_count) { @@ -312,18 +303,12 @@ void unibus_c::test_mem(enum unibus_c::arbitration_mode_enum arbitration_mode, total_read_block_count++; progress.put("R"); // read back into unibus_membuffer[] - mem_read(arbitration_mode, membuffer->data.words, start_addr, end_addr, &timeout); + mem_read(membuffer->data.words, start_addr, end_addr, &timeout); // compare for (mismatch_count = 0, cur_test_addr = start_addr; cur_test_addr <= end_addr; cur_test_addr += 2) { uint16_t cur_mem_val = membuffer->data.words[cur_test_addr / 2]; mismatch = (testwords[cur_test_addr / 2] != cur_mem_val); - if (mismatch) { - ARM_DEBUG_PIN0(1) - ; // trigger - ARM_DEBUG_PIN0(0) - ; - } if (mismatch && ++mismatch_count <= MAX_ERROR_COUNT) // print only first errors printf( "\nMemory mismatch #%d at %06o: expected %06o, found %06o, diff mask = %06o. ", @@ -347,7 +332,7 @@ void unibus_c::test_mem(enum unibus_c::arbitration_mode_enum arbitration_mode, // testwords[cur_test_addr / 2] = (cur_test_addr >> 1) & 0xffff; // linear progress.put("W"); //info : full memory write - mem_access_random(arbitration_mode, UNIBUS_CONTROL_DATO, testwords, start_addr, + mem_access_random(UNIBUS_CONTROL_DATO, testwords, start_addr, end_addr, &timeout, &total_write_block_count); if (SIGINTreceived || timeout) @@ -356,19 +341,13 @@ void unibus_c::test_mem(enum unibus_c::arbitration_mode_enum arbitration_mode, // first full read progress.put("R"); //info : full memory write // read back into unibus_membuffer[] - mem_access_random(arbitration_mode, UNIBUS_CONTROL_DATI, membuffer->data.words, + 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) { uint16_t cur_mem_val = membuffer->data.words[cur_test_addr / 2]; mismatch = (testwords[cur_test_addr / 2] != cur_mem_val); - if (mismatch) { - ARM_DEBUG_PIN0(1) - ; // trigger - ARM_DEBUG_PIN0(0) - ; - } if (mismatch && ++mismatch_count <= MAX_ERROR_COUNT) // print only first errors printf( "\nMemory mismatch at %06o: expected %06o, found %06o, diff mask = %06o. ", diff --git a/10.01_base/2_src/arm/unibusadapter.cpp b/10.01_base/2_src/arm/unibusadapter.cpp index b44ad2c..036746f 100644 --- a/10.01_base/2_src/arm/unibusadapter.cpp +++ b/10.01_base/2_src/arm/unibusadapter.cpp @@ -231,14 +231,14 @@ bool unibusadapter_c::register_device(unibusdevice_c& device) { // printf("!!! register @0%06o = reg 0x%x\n", addr, reghandle) ; register_handle++; } - // if its a CPU, switch PRU to "with_CPU" unibuscpu_c *cpu = dynamic_cast(&device); if (cpu) { assert(registered_cpu == NULL); // only one allowed! registered_cpu = cpu; - mailbox->cpu_enable = 1 ; - mailbox_execute(ARM2PRU_CPU_ENABLE) ; + // enable/disable will start/stop CPU arbitrator on PRU +// mailbox->cpu_enable = 1; +// mailbox_execute(ARM2PRU_CPU_ENABLE); } return true; } @@ -286,7 +286,7 @@ void unibusadapter_c::requests_init(void) { } // put a request into the level/slot table -// do not yet active! +// do not yet activate! void unibusadapter_c::request_schedule(priority_request_c& request) { // Must run under pthread_mutex_lock(&requests_mutex); priority_request_level_c *prl = &request_levels[request.level_index]; @@ -294,16 +294,16 @@ void unibusadapter_c::request_schedule(priority_request_c& request) { // a device may reraise on of its own interrupts, but not an DMA on same slot if (dynamic_cast(&request)) { - if (prl->slot_request[request.slot] != NULL) - FATAL("Concurrent DMA requested for slot %d.", (unsigned )request.slot); + if (prl->slot_request[request.priority_slot] != NULL) + FATAL("Concurrent DMA requested for slot %d.", (unsigned )request.priority_slot); } else if (dynamic_cast(&request)) { - if (prl->slot_request[request.slot] != NULL) { - unibusdevice_c *slotdevice = prl->slot_request[request.slot]->device; + if (prl->slot_request[request.priority_slot] != NULL) { + unibusdevice_c *slotdevice = prl->slot_request[request.priority_slot]->device; if (slotdevice != request.device) FATAL( "Devices %s and %s share both slot %u for INTR request with priority index %u", slotdevice ? slotdevice->name.value.c_str() : "NULL", - request.device->name.value.c_str(), (unsigned )request.slot, + request.device->name.value.c_str(), (unsigned )request.priority_slot, (unsigned )request.level_index); // DEBUG("request_schedule(): update request %p into level %u, slot %u",&request, request.level_index, request.slot); } else { @@ -311,8 +311,8 @@ void unibusadapter_c::request_schedule(priority_request_c& request) { } } - prl->slot_request[request.slot] = &request; // mark slot with request - prl->slot_request_mask |= (1 << request.slot); // set slot bit + prl->slot_request[request.priority_slot] = &request; // mark slot with request + prl->slot_request_mask |= (1 << request.priority_slot); // set slot bit } // Cancel all pending device_DMA and IRQ requests of every level. @@ -422,9 +422,10 @@ void unibusadapter_c::request_execute_active_on_PRU(unsigned level_index) { mailbox->dma.startaddr = dmareq->chunk_unibus_start_addr; mailbox->dma.control = dmareq->unibus_control; mailbox->dma.wordcount = dmareq->chunk_words; + mailbox->dma.cpu_access = dmareq->is_cpu_access; // Copy outgoing data into mailbox device_DMA buffer - if (dmareq->unibus_control == UNIBUS_CONTROL_DATO) { + if (UNIBUS_CONTROL_IS_DATO(dmareq->unibus_control)) { memcpy((void*) mailbox->dma.words, dmareq->chunk_buffer_start(), 2 * dmareq->chunk_words); } @@ -482,7 +483,7 @@ void unibusadapter_c::request_execute_active_on_PRU(unsigned level_index) { } /* when PRU is finished, the worker() gets a signal, - then worker_dma_chunk_complete_event() or worker_intr_complete_event() is called. + then worker_device_dma_chunk_complete_event() or worker_intr_complete_event() is called. On INTR or last DMA chunk, the request is completed. It is removed from the slot schedule table and request->compelte_conmd is signaled to DMA() or INTR() @@ -491,7 +492,7 @@ void unibusadapter_c::request_execute_active_on_PRU(unsigned level_index) { // remove request pointer currently handled by PRU from tables // also called on INTR_CANCEL -void unibusadapter_c::request_active_complete(unsigned level_index) { +void unibusadapter_c::request_active_complete(unsigned level_index, bool signal_complete) { // Must run under pthread_mutex_lock(&requests_mutex); priority_request_level_c *prl = &request_levels[level_index]; @@ -499,7 +500,7 @@ void unibusadapter_c::request_active_complete(unsigned level_index) { return; // DEBUG("request_active_complete") ; - unsigned slot = prl->active->slot; + unsigned slot = prl->active->priority_slot; //if (prl->slot_request[slot] != prl->active) // mailbox_execute(ARM2PRU_HALT) ; // LA: trigger on timeout REG_WRITE // active not in table, if table cleared by INIT requests_cancel_scheduled() @@ -515,11 +516,13 @@ void unibusadapter_c::request_active_complete(unsigned level_index) { priority_request_c *tmprq = prl->active; prl->active = NULL; - // signal to DMA() or INTR() - pthread_mutex_lock(&tmprq->complete_mutex); - tmprq->complete = true; - pthread_cond_signal(&tmprq->complete_cond); - pthread_mutex_unlock(&tmprq->complete_mutex); + if (signal_complete) { + // signal to DMA() or INTR() + pthread_mutex_lock(&tmprq->complete_mutex); + tmprq->complete = true; + pthread_cond_signal(&tmprq->complete_cond); + pthread_mutex_unlock(&tmprq->complete_mutex); + } } @@ -533,25 +536,27 @@ void unibusadapter_c::request_active_complete(unsigned level_index) { void unibusadapter_c::DMA(dma_request_c& dma_request, bool blocking, uint8_t unibus_control, uint32_t unibus_addr, uint16_t *buffer, uint32_t wordcount) { - assert(dma_request.slot < PRIORITY_SLOT_COUNT); + assert(dma_request.priority_slot < PRIORITY_SLOT_COUNT); assert(dma_request.level_index == PRIORITY_LEVEL_INDEX_NPR); // setup device request assert(wordcount > 0); assert((unibus_addr + 2*wordcount) <= 2*UNIBUS_WORDCOUNT); + // lowest priority reserved for CPU + assert(!dma_request.is_cpu_access || dma_request.priority_slot == 31); + // ignore calls if INIT cndition if (line_INIT) { dma_request.complete = true; return; } - pthread_mutex_lock(&requests_mutex); // lock schedule table operations // In contrast to re-raised INTR, overlapping DMA requests from same board // must not be ignored (different DATA situation) and are an device implementation error. // If a device indeed has multiple DMA channels, it must use different pseudo-slots. priority_request_level_c *prl = &request_levels[PRIORITY_LEVEL_INDEX_NPR]; - assert(prl->slot_request[dma_request.slot] == NULL); // not scheduled or prev completed + assert(prl->slot_request[dma_request.priority_slot] == NULL); // not scheduled or prev completed // dma_request.level-index, priority_slot in constructor dma_request.complete = false; @@ -581,7 +586,32 @@ void unibusadapter_c::DMA(dma_request_c& dma_request, bool blocking, uint8_t uni pthread_mutex_unlock(&requests_mutex); // DEBUG("device DMA start: %s @ %06o, len=%d", unibus->control2text(unibus_control), unibus_addr, wordcount); - if (blocking) { + + if (dma_request.is_cpu_access) { + // NO wait for PRU signal, instead busy waiting. CPU thread blocked. + // Reason: SPEED. CPU does high frequency single word accesses. + bool completed = false; + do { + // CPU thread is now spinning + // wait until CPU access scheduled and processed on PRU + // in parallel, other device threads call DMA() + pthread_mutex_lock(&requests_mutex);//&dma_request.complete_mutex); + dma_request_c *activereq = dynamic_cast(prl->active); +//if (activereq == &dma_request) +// printf("a\n") ; +//if (DMA_STATE_IS_COMPLETE(mailbox->dma.cur_status)) +// printf("b\n") ; + if ((activereq == &dma_request) && !EVENT_IS_ACKED(*mailbox, dma)) { + assert(activereq->is_cpu_access); + // transfer DATI data to buffer, set success flag, schedule next request + worker_device_dma_chunk_complete_event(); // do not signal, uses complete_mutex + EVENT_ACK(*mailbox, dma) ; + completed = true; + } + pthread_mutex_unlock(&requests_mutex);//&dma_request.complete_mutex); + } while (!completed); + + } else if (blocking) { pthread_mutex_lock(&dma_request.complete_mutex); // DMA() is blocking: Wait for request to finish. // pthread_mutex_lock(&dma_request.mutex); @@ -594,9 +624,25 @@ void unibusadapter_c::DMA(dma_request_c& dma_request, bool blocking, uint8_t uni } } +// do DATO/DATI as master CPU. +// result: success, else BUS TIMEOUT +void unibusadapter_c::cpu_DATA_transfer(dma_request_c& cpu_data_transfer_request, + uint8_t unibus_control, uint32_t unibus_addr, uint16_t *buffer) { + // no NPR/NPG/SACK arbitration + // no PRU->ARM signal on complete + cpu_data_transfer_request.is_cpu_access = true; + // CPU memory access is serialized with DMA, + // but less then all other device DMA requests + // so set "priority_slot to max=31, despite a CPU plugs into left most slot 0 + // Also less then INTR, thats implementend in PRU statemachine_arbitration_master() + cpu_data_transfer_request.priority_slot = 31; + // "blocking" flag not used + DMA(cpu_data_transfer_request, true, unibus_control, unibus_addr, buffer, 1); +} + // A device raises an interrupt and simultaneously changes a value in // one of its registers, the "interrupt register". -// ''interrupt_register' may be NULL if none. +// interrupt_register' may be NULL if none. // INTR() is NOT BLOCKING: it returns immediately. // the actual interrupt vector is transfered when CPU interrupt level is lowered enough and // other arbitration rules apply, which may never be the case. @@ -604,7 +650,7 @@ void unibusadapter_c::DMA(dma_request_c& dma_request, bool blocking, uint8_t uni void unibusadapter_c::INTR(intr_request_c& intr_request, unibusdevice_register_t *interrupt_register, uint16_t interrupt_register_value) { - assert(intr_request.slot < PRIORITY_SLOT_COUNT); + assert(intr_request.priority_slot < PRIORITY_SLOT_COUNT); assert(intr_request.level_index <= 3); assert((intr_request.vector & 3) == 0); // multiple of 2 words @@ -616,17 +662,16 @@ void unibusadapter_c::INTR(intr_request_c& intr_request, priority_request_level_c *prl = &request_levels[intr_request.level_index]; pthread_mutex_lock(&requests_mutex); // lock schedule table operations - //if (intr_request.device->log_level == LL_DEBUG) DEBUG("INTR() req: dev %s, slot/level/vector= %d/%d/%03o", - intr_request.device->name.value.c_str(), (unsigned) intr_request.slot, + intr_request.device->name.value.c_str(), (unsigned ) intr_request.priority_slot, intr_request.level_index + 4, intr_request.vector); // Is an INTR with same slot and level already executed on PRU // or waiting in the schedule table? // If yes: do not re-raise, will be completed at some time later. - if (prl->slot_request[intr_request.slot] != NULL) { + if (prl->slot_request[intr_request.priority_slot] != NULL) { intr_request_c *scheduled_intr_req = - dynamic_cast(prl->slot_request[intr_request.slot]); + dynamic_cast(prl->slot_request[intr_request.priority_slot]); assert(scheduled_intr_req); // A device may re-raised a pending INTR again // (quite normal situation when other ISRs block, CPU overload) @@ -708,7 +753,7 @@ void unibusadapter_c::INTR(intr_request_c& intr_request, void unibusadapter_c::cancel_INTR(intr_request_c& intr_request) { uint8_t level_index = intr_request.level_index; // alias priority_request_level_c *prl = &request_levels[level_index]; - if (prl->slot_request[intr_request.slot] == NULL) + if (prl->slot_request[intr_request.priority_slot] == NULL) return; // not scheduled or active pthread_mutex_lock(&requests_mutex); // lock schedule table operations @@ -718,7 +763,7 @@ void unibusadapter_c::cancel_INTR(intr_request_c& intr_request) { mailbox->intr.priority_arbitration_bit = priority_level_idx_to_arbitration_bit[level_index]; mailbox_execute(ARM2PRU_INTR_CANCEL); - request_active_complete(level_index); + request_active_complete(level_index, true); // restart next request request_activate_lowest_slot(level_index); @@ -726,8 +771,8 @@ void unibusadapter_c::cancel_INTR(intr_request_c& intr_request) { request_execute_active_on_PRU(level_index); } else { // not active on PRU: just remove from schedule table - prl->slot_request[intr_request.slot] = NULL; // clear slot from request - prl->slot_request_mask &= ~(1 << intr_request.slot); // mask out slot bit + prl->slot_request[intr_request.priority_slot] = NULL; // clear slot from request + prl->slot_request_mask &= ~(1 << intr_request.priority_slot); // mask out slot bit } // both empty, or both filled assert((prl->slot_request_mask == 0) == (prl->active == NULL)); @@ -740,61 +785,6 @@ void unibusadapter_c::cancel_INTR(intr_request_c& intr_request) { } -// do DATO/DATI as master CPU. -// no NPR/NPG/SACK request, but waiting for BUS idle -// result: success, else BUS TIMEOUT -void unibusadapter_c::cpu_DATA_transfer(dma_request_c& dma_request, uint8_t unibus_control, - uint32_t unibus_addr, uint16_t *buffer) { - timeout_c timeout; - bool success; - cpu_data_transfer_request = &dma_request; - - // request is not queued, so only request.mutex used - - pthread_mutex_lock(&cpu_data_transfer_request->complete_mutex); - cpu_data_transfer_request->complete = false; - - mailbox->dma.startaddr = unibus_addr; - mailbox->dma.control = unibus_control; - mailbox->dma.wordcount = 1; - - // Copy outgoing data into mailbox device_DMA buffer - if (UNIBUS_CONTROL_ISDATO(unibus_control)) - memcpy((void*) mailbox->dma.words, buffer, 2); - - // do the transfer. Wait until concurrent device DMA/INTR complete - do { - 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 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. - while (!cpu_data_transfer_request->complete) { - int res = pthread_cond_wait(&cpu_data_transfer_request->complete_cond, - &cpu_data_transfer_request->complete_mutex); - assert(!res); - } - pthread_mutex_unlock(&cpu_data_transfer_request->complete_mutex); - - // Copy incoming data from mailbox DMA buffer - if (unibus_control == UNIBUS_CONTROL_DATI) - memcpy(buffer, (void *) mailbox->dma.words, 2); - -} - // set state of INIT void unibusadapter_c::worker_init_event() { unsigned device_handle; @@ -858,7 +848,7 @@ void unibusadapter_c::worker_deviceregister_event() { DATO: save written value into .active_write_val restore changed shared PRU register with .active_read_val for next read */ - if (device_reg->active_on_dati && !UNIBUS_CONTROL_ISDATO(unibus_control)) { + if (device_reg->active_on_dati && !UNIBUS_CONTROL_IS_DATO(unibus_control)) { // register is read with DATI, this changes the logic state evt_addr &= ~1; // make even assert(evt_addr == device->base_addr.value + 2 * evt_idx); @@ -869,7 +859,7 @@ void unibusadapter_c::worker_deviceregister_event() { device->log_register_event("DATI", device_reg); device->on_after_register_access(device_reg, unibus_control); - } else if (device_reg->active_on_dato && UNIBUS_CONTROL_ISDATO(unibus_control)) { + } else if (device_reg->active_on_dato && UNIBUS_CONTROL_IS_DATO(unibus_control)) { // uint16_t reg_value_written = device_reg->shared_register->value; // restore value accessible by DATI device_reg->shared_register->value = device_reg->active_dati_flipflops; @@ -914,81 +904,70 @@ void unibusadapter_c::worker_deviceregister_event() { // called by PRU signal when DMA transmission complete // Called for device DMA() chunk, // or cpu_DATA_transfer() -void unibusadapter_c::worker_dma_chunk_complete_event(bool cpu_DATA_transfer) { - if (cpu_DATA_transfer) { - // cpu_DATA_transfer() started independent of request_levels table, - // prl->active == NULL - cpu_data_transfer_request->success = (mailbox->dma.cur_status == DMA_STATE_READY); +void unibusadapter_c::worker_device_dma_chunk_complete_event() { + priority_request_level_c *prl = &request_levels[PRIORITY_LEVEL_INDEX_NPR]; + bool more_chunks; + // Must run under pthread_mutex_lock(&requests_mutex) ; - // signal to DMA() or INTR() - cpu_data_transfer_request->complete = true; // close to signal - pthread_mutex_unlock(&cpu_data_transfer_request->complete_mutex); + dma_request_c *dmareq = dynamic_cast(prl->active); - // concurrent to this DATA transfer a device may have requested DMA. + assert(dmareq != NULL); + dmareq->unibus_end_addr = mailbox->dma.cur_addr; // track emnd of trasnmission, eror position + unsigned wordcount_transferred = dmareq->wordcount_completed_chunks() + + mailbox->dma.wordcount; + assert(wordcount_transferred <= dmareq->wordcount); + assert(!dmareq->is_cpu_access || dmareq->wordcount == 1); // CPU accesses only single words + if (UNIBUS_CONTROL_IS_DATI(mailbox->dma.control)) { + // guard against buffer overrun + // PRU read chunk data from UNIBUS into mailbox + // copy result cur_DMA_wordcount from mailbox->DMA buffer to cur_DMA_buffer + memcpy(dmareq->chunk_buffer_start(), (void *) mailbox->dma.words, + 2 * mailbox->dma.wordcount); + } + if (mailbox->dma.cur_status != DMA_STATE_READY) { + // failure: abort remaining chunks + dmareq->success = false; + more_chunks = false; + } else if (wordcount_transferred == dmareq->wordcount) { + // last chunk completed + dmareq->success = true; + more_chunks = false; + } else { + // more data to transfer: next chunk. + assert(!dmareq->is_cpu_access); // CPU accesses only single words + dmareq->chunk_unibus_start_addr = mailbox->dma.cur_addr + 2; + // dmarequest remains prl->active and ->busy + + _DEBUG( + "DMA chunk complete: dev %s, %s @ %06o..%06o, wordcount %d, data=%06o, %06o, ... %s", + prl->active->device ? prl->active->device->name.value.c_str() : "none", + unibus->control2text(mailbox->dma.control), mailbox->dma.startaddr, + mailbox->dma.cur_addr, mailbox->dma.wordcount, mailbox->dma.words[0], + mailbox->dma.words[1], dmareq->success ? "OK" : "TIMEOUT"); + + // re-activate this request, or choose another with higher slot priority, + // inserted in parallel (interrupt this DMA) + prl->active = NULL; + request_activate_lowest_slot(PRIORITY_LEVEL_INDEX_NPR); + + request_execute_active_on_PRU(PRIORITY_LEVEL_INDEX_NPR); + more_chunks = true; + + } + if (!more_chunks) { + _DEBUG("DMA ready: %s @ %06o..%06o, wordcount %d, data=%06o, %06o, ... %s", + unibus->control2text(dmareq->unibus_control), dmareq->unibus_start_addr, + dmareq->unibus_end_addr, dmareq->wordcount, dmareq->buffer[0], + dmareq->buffer[1], dmareq->success ? "OK" : "TIMEOUT"); + + // clear from schedule table of this level + // CPu memory accesses are not signaled, but polled in DMA() + request_active_complete(PRIORITY_LEVEL_INDEX_NPR, /*signal*/!dmareq->is_cpu_access); + + // check and execute DMA on other priority_slot if (request_activate_lowest_slot(PRIORITY_LEVEL_INDEX_NPR)) request_execute_active_on_PRU(PRIORITY_LEVEL_INDEX_NPR); - } else { - priority_request_level_c *prl = &request_levels[PRIORITY_LEVEL_INDEX_NPR]; - bool more_chunks; - // Must run under pthread_mutex_lock(&requests_mutex) ; - dma_request_c *dmareq = dynamic_cast(prl->active); - - assert(dmareq != NULL); - dmareq->unibus_end_addr = mailbox->dma.cur_addr; // track emnd of trasnmission, eror position - unsigned wordcount_transferred = dmareq->wordcount_completed_chunks() - + mailbox->dma.wordcount; - assert(wordcount_transferred <= dmareq->wordcount); - if (mailbox->dma.control == UNIBUS_CONTROL_DATI) { - // guard against buffer overrun - // PRU read chunk data from UNIBUS into mailbox - // copy result cur_DMA_wordcount from mailbox->DMA buffer to cur_DMA_buffer - memcpy(dmareq->chunk_buffer_start(), (void *) mailbox->dma.words, - 2 * mailbox->dma.wordcount); - } - if (mailbox->dma.cur_status != DMA_STATE_READY) { - // failure: abort remaining chunks - dmareq->success = false; - more_chunks = false; - } else if (wordcount_transferred == dmareq->wordcount) { - // last chunk completed - dmareq->success = true; - more_chunks = false; - } else { - // more data to transfer: next chunk. - dmareq->chunk_unibus_start_addr = mailbox->dma.cur_addr + 2; - // dmarequest remains prl->active and ->busy - - _DEBUG( - "DMA chunk complete: dev %s, %s @ %06o..%06o, wordcount %d, data=%06o, %06o, ... %s", - prl->active->device ? prl->active->device->name.value.c_str() : "none", - unibus->control2text(mailbox->dma.control), mailbox->dma.startaddr, - mailbox->dma.cur_addr, mailbox->dma.wordcount, mailbox->dma.words[0], - mailbox->dma.words[1], dmareq->success ? "OK" : "TIMEOUT"); - - // re-activate this request, or choose another with higher slot priority, - // inserted in parallel (interrupt this DMA) - prl->active = NULL; - request_activate_lowest_slot(PRIORITY_LEVEL_INDEX_NPR); - - request_execute_active_on_PRU(PRIORITY_LEVEL_INDEX_NPR); - more_chunks = true; - - } - if (!more_chunks) { - _DEBUG("DMA ready: %s @ %06o..%06o, wordcount %d, data=%06o, %06o, ... %s", - unibus->control2text(dmareq->unibus_control), dmareq->unibus_start_addr, - dmareq->unibus_end_addr, dmareq->wordcount, dmareq->buffer[0], - dmareq->buffer[1], dmareq->success ? "OK" : "TIMEOUT"); - - // clear from schedule table of this level - request_active_complete(PRIORITY_LEVEL_INDEX_NPR); - - // check and execute DMA on other priority_slot - if (request_activate_lowest_slot(PRIORITY_LEVEL_INDEX_NPR)) - request_execute_active_on_PRU(PRIORITY_LEVEL_INDEX_NPR); - - } } } @@ -1005,7 +984,7 @@ void unibusadapter_c::worker_intr_complete_event(uint8_t level_index) { //assert(prl->active); // clear from schedule table of this level - request_active_complete(level_index); + request_active_complete(level_index, true); // activate next request of this level on PRU for priority arbitration request_activate_lowest_slot(level_index); @@ -1132,10 +1111,12 @@ 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)) { + 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_dma_chunk_complete_event(mailbox->events.dma.cpu_transfer); + 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! diff --git a/10.01_base/2_src/arm/unibusadapter.hpp b/10.01_base/2_src/arm/unibusadapter.hpp index 42caaff..13f188f 100644 --- a/10.01_base/2_src/arm/unibusadapter.hpp +++ b/10.01_base/2_src/arm/unibusadapter.hpp @@ -69,7 +69,7 @@ private: void worker_init_event(void); void worker_power_event(bool power_down); void worker_deviceregister_event(void); - void worker_dma_chunk_complete_event(bool cpu_DATA_transfer); + void worker_device_dma_chunk_complete_event(void); void worker_intr_complete_event(uint8_t level_index); void worker(unsigned instance) override; // background worker function @@ -101,7 +101,7 @@ public: priority_request_c *request_activate_lowest_slot(unsigned level_index); // bool request_is_active( unsigned level_index); bool request_is_blocking_active(uint8_t level_index); - void request_active_complete(unsigned level_index); + void request_active_complete(unsigned level_index, bool signal_complete); void request_execute_active_on_PRU(unsigned level_index); void DMA(dma_request_c& dma_request, bool blocking, uint8_t unibus_control, diff --git a/10.01_base/2_src/arm/utils.cpp b/10.01_base/2_src/arm/utils.cpp index a3a0c10..ff41be1 100644 --- a/10.01_base/2_src/arm/utils.cpp +++ b/10.01_base/2_src/arm/utils.cpp @@ -122,12 +122,16 @@ bool timeout_c::reached() { return (elapsed_ns() > duration_ns); } +/*** + Tests indicate that any nano_sleep() often causes delays of 60-80 µs +***/ + // wait a number of nanoseconds, resolution in 0.1 millisecs void timeout_c::wait_ns(uint64_t duration_ns) { struct timespec ts = { (long) (duration_ns / BILLION), (long) (duration_ns % BILLION) }; int res = nanosleep(&ts, NULL); - if (res) - DEBUG("nanosleep() return a %d", res); + assert(res == 0); +// DEBUG("nanosleep() return a %d", res); } // wait a number of milliseconds diff --git a/10.01_base/2_src/arm/utils.hpp b/10.01_base/2_src/arm/utils.hpp index 8d480a6..e39d6fa 100644 --- a/10.01_base/2_src/arm/utils.hpp +++ b/10.01_base/2_src/arm/utils.hpp @@ -73,9 +73,9 @@ public: uint64_t elapsed_us(void); uint64_t elapsed_ms(void); bool reached(void); - void wait_ns(uint64_t duration_ns); - void wait_us(unsigned duration_us); - void wait_ms(unsigned duration_ms); + static void wait_ns(uint64_t duration_ns); + static void wait_us(unsigned duration_us); + static void wait_ms(unsigned duration_ms); }; 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 8092839..bb38af7 100644 --- a/10.01_base/2_src/pru1/pru1_main_unibus.c +++ b/10.01_base/2_src/pru1/pru1_main_unibus.c @@ -91,7 +91,7 @@ void main(void) { // state function pointer for different state machines - statemachine_arb_worker_func sm_arb_worker = &sm_arb_worker_client; + statemachine_arb_worker_func sm_device_arb_worker = &sm_arb_worker_device; statemachine_state_func sm_data_slave_state = NULL; statemachine_state_func sm_data_master_state = NULL; statemachine_state_func sm_intr_slave_state = NULL; @@ -144,17 +144,36 @@ void main(void) { // ARM may start DMA within deviceregister event! if (EVENT_IS_ACKED(mailbox, deviceregister)) { // execute one of the arbitration workers - uint8_t grant_mask = sm_arb_worker(); - // sm_arb_worker()s include State 2 "BBSYWAIT". + + uint8_t cpu_grant_mask; + if (emulate_cpu) { + cpu_grant_mask = sm_arb_worker_cpu(); // GRANT device requests + // do not read GRANT signals from UNIBUS, BG/NPGOUT not visible for + // emulated devices + } else { + // device requests GRANTed by physical CPU + + // 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! + cpu_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.device_request_mask, ~cpu_grant_mask) + ; + } + // handle GRANT/SACK/BBSY for emulated devices + uint8_t granted_request = sm_device_arb_worker(cpu_grant_mask); // devices process GRANT + // sm_device_arb_worker()s include State 2 "BBSYWAIT". // So now SACK maybe set, even if grant_mask is still 0 - if (grant_mask & PRIORITY_ARBITRATION_BIT_NP) { + if (granted_request & PRIORITY_ARBITRATION_BIT_NP) { sm_data_master_state = (statemachine_state_func) &sm_dma_start; // can data_master_state be overwritten in the midst of a running data_master_state ? // no: when running, SACK is set, no new GRANTs - } else if (grant_mask & PRIORITY_ARBITRATION_INTR_MASK) { + } else if (granted_request & PRIORITY_ARBITRATION_INTR_MASK) { // convert bit in grant_mask to INTR index - uint8_t idx = PRIORITY_ARBITRATION_INTR_BIT2IDX(grant_mask); + uint8_t idx = PRIORITY_ARBITRATION_INTR_BIT2IDX(granted_request); // now transfer INTR vector for interupt of GRANted level. // vector and ARM context have been setup by ARM before ARM2PRU_INTR already sm_intr_master.vector = mailbox.intr.vector[idx]; @@ -179,12 +198,12 @@ void main(void) { // Receive INTR from physical or emulated devices, and signal ARM. if (!sm_intr_slave_state) sm_intr_slave_state = (statemachine_state_func) &sm_intr_slave_start; - sm_intr_slave_state = sm_intr_slave_state() ; -/* - while ((sm_intr_slave_state = sm_intr_slave_state()) - && EVENT_IS_ACKED(mailbox, intr_slave)) - ; -*/ + sm_intr_slave_state = sm_intr_slave_state(); + /* + while ((sm_intr_slave_state = sm_intr_slave_state()) + && EVENT_IS_ACKED(mailbox, intr_slave)) + ; + */ } // process ARM commands in master and slave mode @@ -197,45 +216,26 @@ void main(void) { break; case ARM2PRU_ARB_MODE_NONE: // ignore SACK condition // from now on, ignore INTR requests and allow DMA request immediately - sm_arb_worker = &sm_arb_worker_none; + sm_device_arb_worker = &sm_arb_worker_none; mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done break; case ARM2PRU_ARB_MODE_CLIENT: // request DMA from external Arbitrator - sm_arb_worker = &sm_arb_worker_client; - mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done - break; - case ARM2PRU_ARB_MODE_MASTER: - sm_arb_worker = &sm_arb_worker_master; + sm_device_arb_worker = &sm_arb_worker_device; mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done break; case ARM2PRU_DMA: - if (mailbox.arbitrator.cpu_BBSY) { - // ARM CPU emulation did a single word DATA transfer with cpu_DATA_transfer() - if (mailbox.arbitrator.device_BBSY) { - // ARM started cpu DATA transfer, but arbitration logic - // GRANTed a device request in the mean time. Tell ARM. - mailbox.arm2pru_req = PRU2ARM_DMA_CPU_TRANSFER_BLOCKED; // error - mailbox.arbitrator.cpu_BBSY = false; - } - // start bus cycle - sm_data_master_state = (statemachine_state_func) &sm_dma_start; + // different arbitration for device and CPU memory access. + + // 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 ; } else { // Emulated device: raise request for emulated or physical Arbitrator. - // request DMA, arbitrator must've been selected with ARM2PRU_ARB_MODE_* 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 - - /* TODO: speed up DMA - While DMA is active: - - SACK active: no GRANT forward necessary - no arbitration necessary - - INIT is monitored: no DC_LO/INIT monitoring necessary - - no scan for new ARM2PRU commands: ARM2PRU_DMA is blocking - - smaller chunks ? - */ - } + } + // request not put on bus for CPU memory access mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done break; case ARM2PRU_INTR: @@ -243,7 +243,7 @@ void main(void) { // start one INTR cycle. May be raised in midst of slave cycle // by ARM, if access to "active" register triggers INTR. sm_arb.device_request_mask |= mailbox.intr.priority_arbitration_bit; - // sm_arb_worker() evaluates this, extern Arbitrator raises Grant, + // sm_device_arb_worker() evaluates this, extern Arbitrator raises Grant, // vector of GRANted level is transfered with statemachine sm_intr_master // Atomically change state in a device's associates interrupt register. @@ -262,6 +262,13 @@ void main(void) { // no completion event, could interfer with other INTRs? mailbox.arm2pru_req = ARM2PRU_NONE; // done break; + case ARM2PRU_ARB_GRANT_INTR_REQUESTS: + if (emulate_cpu) { + mailbox.arbitrator.ifs_intr_arbitration_pending = true; + // also blocks ARM thread + } + mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done + break; case ARM2PRU_INITALIZATIONSIGNAL_SET: switch (mailbox.initializationsignal.id) { case INITIALIZATIONSIGNAL_ACLO: @@ -280,12 +287,8 @@ void main(void) { mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done break; case ARM2PRU_CPU_ENABLE: - // bool flag much faster to access then shared mailbox member. + // bool flag much faster to access than shared mailbox member. emulate_cpu = mailbox.cpu_enable; - if (emulate_cpu) - sm_arb_worker = &sm_arb_worker_master; - else - sm_arb_worker = &sm_arb_worker_client; mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done break; case ARM2PRU_HALT: 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 ee5a49c..3b4b98f 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c @@ -116,12 +116,10 @@ void sm_arb_reset() { * Ignores active SACK and/or BBSY from other bus masters. * For diagnostics on hung CPU, active device or console processor holding SACK. */ -uint8_t sm_arb_worker_none() { +uint8_t sm_arb_worker_none(uint8_t grant_mask) { // Unconditionally forward GRANT IN to GRANT OUT - uint8_t grant_mask = buslatches_getbyte(0) & PRIORITY_ARBITRATION_BIT_MASK; // read GRANT IN buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK, ~grant_mask) ; - // ignore BR* INTR requests, only ack DMA. if (sm_arb.device_request_mask & PRIORITY_ARBITRATION_BIT_NP) { sm_arb.device_request_mask &= ~PRIORITY_ARBITRATION_BIT_NP; @@ -130,15 +128,66 @@ uint8_t sm_arb_worker_none() { 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. +/* worker_client: + Issue request to extern or emulated Arbitrator (PDP-11 CPU). + Watch for GRANTs on the bus signal lines, then raise SACK. + Wait for current bus master to release bus => Wait for BBSY clear. + Then return GRANTed request. + "Wait for BBSY clear" may not be part of the arbitration protocol. + But it guarantees caller may now issue an DMA or INTR. + + grant_mask: state of all BGIN/NPGIN lines */ -static uint8_t sm_arb_worker_device_grant_sack_bbsy(uint8_t grant_mask) { +uint8_t sm_arb_worker_device(uint8_t grant_mask) { + if (sm_arb.cpu_request) { + // Emulated CPU memory access: no NPR/NPG/SACK protocol. + // No arbitration, start transaction when bus idle. + // device_request_mask is ignored for CPU + uint8_t latch1val = buslatches_getbyte(1); + + /* Do not GRANT cpu memory ACCESS if - + - SACK + - NPR pending + - BR4-7 request and ifs_arbitration_pending + (Deadlock ahead: CPu needs to execute program to reach point before fecth", + where INTRs are granted.) + */ + bool granted = true; + if ((latch1val & 0x70) != 0) + // NPR, BBSY or SACK set + granted = false; + else if ((latch1val & 0xf) && mailbox.arbitrator.ifs_intr_arbitration_pending) + // BR* set, and next is opcode fetch: INTR first + granted = false; + if (granted) { + // neither REQUESTs nor SACK nor BBSY asserted + sm_arb.cpu_request = 0; + return PRIORITY_ARBITRATION_BIT_NP; + // DMA will be started, BBSY will be set + } else { + // CPU memory access delayed until device requests processed/completed + } + } +#if 0 + if ((sm_arb.device_request_mask & PRIORITY_ARBITRATION_BIT_NP) && mailbox.dma.cpu_access) { + uint8_t latch1val = buslatches_getbyte(1); + if ((latch1val & 0x1f) == 0) { + // neither REQUESTs nor SACK nor BBSY asserted + sm_arb.device_request_mask &= ~PRIORITY_ARBITRATION_BIT_NP; + return PRIORITY_ARBITRATION_BIT_NP; + // DMA will be started, BBSY will be set + } else { + // CPU memory access delayed until device requests processed/completed + } + } +#endif + // Always update UNIBUS BR/NPR lines, are ORed with requests from other devices. + buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask) + ; + + // read GRANT IN lines from CPU (Arbitrator). + // Only one nit ion cpu_grant_mask at a time may be active, else arbitrator malfunction. + // Arbitrator asserts SACK is inactive if (sm_arb.bbsy_wait_grant_mask == 0) { // State 1: Wait For GRANT: @@ -173,36 +222,6 @@ static uint8_t sm_arb_worker_device_grant_sack_bbsy(uint8_t grant_mask) { } } -/* worker_client: - Issue request to extern Arbitrator (PDP-11 CPU). - Watch for GRANTs on the bus signal lines, then raise SACK. - Wait for current bus master to release bus => Wait for BBSY clear. - Then return GRANTed request. - "Wait for BBSY clear" may not be part of the arbitration protocol. - But it guarantees caller may now issue an DMA or INTR. - */ -uint8_t sm_arb_worker_client() { - - // Always update UNIBUS BR/NPR lines, are ORed with requests from other devices. - 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, else arbitrator malfucntion. - // Arbitrator asserts SACK is inactive - // latch[0]: BG signals are inverted, "get" is non-inverting: bit = active signal. - // "set" is inverting! - 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.device_request_mask, ~grant_mask) - ; - - // GRANT forwarding complete, - // handle GRANT/SACK/BBSY for emulated devices - return sm_arb_worker_device_grant_sack_bbsy(grant_mask); -} - /* "worker_master" Act as Arbitrator, Interrupt Fielding Processor and Client Is assumed to be on first slot, so BG*IN/NPGIN lines are ignored @@ -219,33 +238,26 @@ uint8_t sm_arb_worker_client() { // BR4 = 0x01 -> 4, BR5 = 0x02 -> 5, etc. // Index only PRIORITY_ARBITRATION_INTR_MASK, [0] invalid. 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, /*1011*/7, - /*1100*/7, /*1101*/7, /*1110*/7, /*1111*/7 }; + /*0000*/9, /*0001*/4, /*0010*/5, /*0011*/5, + /*0100*/6, /*0101*/6, /*0110*/6, /*0111*/6, + /*1000*/7, /*1001*/7, /*1010*/7, /*1011*/7, + /*1100*/7, /*1101*/7, /*1110*/7, /*1111*/7}; #endif -uint8_t sm_arb_worker_master() { +uint8_t sm_arb_worker_cpu() { /******* arbitrator logic *********/ uint8_t intr_request_mask; uint8_t latch1val = buslatches_getbyte(1); + bool do_intr_arbitration = mailbox.arbitrator.ifs_intr_arbitration_pending; // ARM allowed INTR arbitration // 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 = true; - // DATA section to be used by device now, for DMA or INTR + // DATA section to be used by device now, for DMA or INTR timeout_cleanup(TIMEOUT_SACK); } else if (latch1val & PRIORITY_ARBITRATION_BIT_NP) { @@ -255,7 +267,8 @@ 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 (do_intr_arbitration + && (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 @@ -263,15 +276,14 @@ uint8_t sm_arb_worker_master() { // 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 ; + 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.ifs_priority_level // + && requested_intr_level != CPU_PRIORITY_LEVEL_FETCHING) { // GRANT request, set GRANT line: // 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)); @@ -280,27 +292,17 @@ uint8_t sm_arb_worker_master() { } 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 = 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.device_request_mask) + // put the single BR/NPR GRANT onto GRANT OUT BUS line, latches inverted. + // visible for physical devices, not for emulated devcies on this UniBone + buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK, ~sm_arb.arbitrator_grant_mask ) ; - // Do not forward GRANT IN to GRANT OUT: we, the arbitrator, do not have GRANT IN. + // do not produce GRANTs until next ARM call of ARM2PRU_ARB_GRANT_INTR_REQUESTS + mailbox.arbitrator.ifs_intr_arbitration_pending = false; - // GRANTs for UniBone internal devices are not visible on UNIBUS - // (emualted GRANT OUT - GRANT IN connections) - - // Arbitration master stuff complete, - // handle GRANT/SACK/BBSY for emulated devices - return sm_arb_worker_device_grant_sack_bbsy(sm_arb.arbitrator_grant_mask); + return 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 c12890c..5f0c927 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h +++ b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h @@ -28,13 +28,13 @@ #include -// Arbitration master restes GRANT if devcie does not respond with +// Arbitration master restes GRANT if device does not respond with // SACK within this period. #define ARB_MASTER_SACK_TIMOUT_MS 10 // a priority-arbitration-worker returns a bit mask with the GRANT signal he recognized -typedef uint8_t (*statemachine_arb_worker_func)(); +typedef uint8_t (*statemachine_arb_worker_func)(uint8_t grant_mask); typedef struct { // There are 5 request/grant signals (BR4,5,6,7 and NPR). @@ -50,11 +50,13 @@ typedef struct { uint8_t bbsy_wait_grant_mask; /*** master ****/ - // only used wif working as Arbitrator/Interupt Fielding Processor - uint8_t ifs_priority_level; // priority level of Interrupt Fielding processor (CPU) - + // CPU is requesting memory access via PRU2ARM_DMA/mailbox.dma + uint8_t cpu_request ; + uint8_t arbitrator_grant_mask; // single GRANT line set by master + // uint8_t dummy[3] ; + } statemachine_arbitration_t; /* receives a grant_mask with 1 bit set and returns the index of that bit @@ -70,8 +72,8 @@ typedef struct { extern statemachine_arbitration_t sm_arb; void sm_arb_reset(void); -uint8_t sm_arb_worker_none(void); -uint8_t sm_arb_worker_client(void); -uint8_t sm_arb_worker_master(void); +uint8_t sm_arb_worker_none(uint8_t grant_mask); +uint8_t sm_arb_worker_device(uint8_t grant_mask); +uint8_t sm_arb_worker_cpu(void); #endif 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 4973423..70fda3f 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,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 == 0777546) // LTC +//if (addr == 0777560) // DL11 // PRU_DEBUG_PIN0(1) ; // trigger to LA. 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 559b0a5..129e256 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_dma.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_dma.c @@ -82,8 +82,7 @@ static statemachine_state_func sm_dma_state_99(void); // startaddr, wordcount, cycle, words[] ? // "cycle" must be UNIBUS_CONTROL_DATI or UNIBUS_CONTROL_DATO // Wait for BBSY, SACK already held asserted -// Sorting between device and CPU transfers: -// IF a device DMA is busy mailbox.device_BBSY is set. +// Sorting between device and CPU transfers: unibusadapter request scheduler statemachine_state_func sm_dma_start() { // assert BBSY: latch[1], bit 6 // buslatches_setbits(1, BIT(6), BIT(6)); @@ -118,8 +117,6 @@ static statemachine_state_func sm_dma_state_1() { uint16_t data; uint8_t control = mailbox.dma.control; // uint8_t page_table_entry; - uint8_t b; - bool internal; // BBSY released if (mailbox.dma.cur_status != DMA_STATE_RUNNING || mailbox.dma.wordcount == 0) @@ -143,10 +140,15 @@ static statemachine_state_func sm_dma_state_1() { // C1 = latch[4], bit 3 // MSYN = latch[4], bit 4 // SSYN = latch[4], bit 5 - if (UNIBUS_CONTROL_ISDATO(control)) { + if (UNIBUS_CONTROL_IS_DATO(control)) { + bool internal; + bool is_datob = (control == UNIBUS_CONTROL_DATOB); tmpval = (addr >> 16) & 3; - tmpval |= BIT(3); // DATO: c1=1, c0=0 - // bit 2,4,5 == 0 -> C0,MSYN,SSYN not asserted + if (is_datob) + tmpval |= (BIT(3) | BIT(2)); // DATOB: c1=1, c0=1 + else + tmpval |= BIT(3); // DATO: c1=1, c0=0 + // bit 4,5 == 0 -> MSYN,SSYN not asserted buslatches_setbits(4, 0x3f, tmpval); // write data. SSYN may still be active and cleared now? by sm_slave_10 etc? // data = mailbox.dma.words[sm_dma.cur_wordidx]; @@ -171,18 +173,13 @@ static statemachine_state_func sm_dma_state_1() { // DATO to internal slave (fast test). // write data into slave ( - switch (control) { - case UNIBUS_CONTROL_DATO: - internal = iopageregisters_write_w(addr, data); - break; - case UNIBUS_CONTROL_DATOB: + if (is_datob) { // A00=1: upper byte, A00=0: lower byte - b = (addr & 1) ? (data >> 8) : (data & 0xff); + uint8_t b = (addr & 1) ? (data >> 8) : (data & 0xff); internal = iopageregisters_write_b(addr, b); // always sucessful, addr already tested - break; - default: - internal = false; // not reached - } + } else + // DATO + internal = iopageregisters_write_w(addr, data); if (internal) { buslatches_setbits(4, BIT(5), BIT(5)); // slave assert SSYN buslatches_setbits(4, BIT(4), 0); // master deassert MSYN @@ -329,23 +326,26 @@ static statemachine_state_func sm_dma_state_99() { // remove BBSY: latch[1], bit 6 buslatches_setbits(1, BIT(6), 0); - timeout_cleanup(TIMEOUT_DMA); - - // device or cpu cycle ended: now CPU may become UNIBUS master again - mailbox.events.dma.cpu_transfer = mailbox.arbitrator.cpu_BBSY ; - // device_BBSY monitored by sm_arbitration (physical devices). - mailbox.arbitrator.cpu_BBSY = false; + timeout_cleanup(TIMEOUT_DMA); // SACK already de-asserted at wordcount==1 mailbox.dma.cur_status = final_dma_state; // signal to ARM - // signal to ARM - EVENT_SIGNAL(mailbox,dma) ; - // ARM is clearing this, before requesting new DMA. + // device or cpu cycle ended // no concurrent ARM+PRU access - PRU2ARM_INTERRUPT - ; + // for cpu access: ARM CPU thread ends looping now + // test for DMA_STATE_IS_COMPLETE(cur_status) + EVENT_SIGNAL(mailbox, dma); + + // for device DMA: unibusadapter worker() waits for signal + if (!mailbox.dma.cpu_access) { + // signal to ARM + // ARM is clearing this, before requesting new DMA. + // no concurrent ARM+PRU access + PRU2ARM_INTERRUPT + ; + } return NULL; // now stopped } } 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 d1e6743..7720d28 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,8 +98,6 @@ 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 - // device_BBSY monitored by sm_arbitration (physical devices). - // SACK already removed // signal to ARM which INTR was completed 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 4a0a2d0..fa90d29 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 @@ -61,7 +61,7 @@ statemachine_state_func sm_intr_slave_start() { buslatches_setbits(4, BIT(5), BIT(5)); // mark priority level as invalid, block more BG GRANTS until PSW fetched - mailbox.arbitrator.cpu_priority_level = CPU_PRIORITY_LEVEL_FETCHING ; + mailbox.arbitrator.ifs_priority_level = CPU_PRIORITY_LEVEL_FETCHING ; // signal ARM, wait for event to be processed mailbox.events.intr_slave.vector = (uint16_t) latch6val << 8 | latch5val ; diff --git a/10.01_base/2_src/shared/mailbox.h b/10.01_base/2_src/shared/mailbox.h index d88c989..fc01f26 100644 --- a/10.01_base/2_src/shared/mailbox.h +++ b/10.01_base/2_src/shared/mailbox.h @@ -43,14 +43,15 @@ #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 #define ARM2PRU_DMA 14 // DMA with selected arbitration -#define PRU2ARM_DMA_CPU_TRANSFER_BLOCKED 15 // possible result of ARM2PRU_DMA +//#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 + // signal IDs for ARM2PRU_INITALIZATIONSIGNAL_* // states of initialization section lines. Bitmask = latch[7] @@ -123,17 +124,12 @@ 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 device_BBSY == 0 - // set when arbitration logic detects SACK! - uint8_t device_BBSY; + // ifs = Interrupt Fielding Processor + uint8_t ifs_priority_level; // Priority level of CPU, visible in PSW. 7,6,5,4 <4. - // Command by ARM on DMA start: DATA transfer as CPU, else as device - uint8_t cpu_BBSY; + uint8_t ifs_intr_arbitration_pending ; // produce GRANTS from requests - uint8_t cpu_priority_level; // Priority level of CPU, visible in PSW. 7,6,5,4 <4. - - uint8_t _dummy1; // keep 32 bit borders + uint8_t _dummy[2]; // keep 32 bit borders } mailbox_arbitrator_t; @@ -141,11 +137,13 @@ typedef struct { typedef struct { // take care of 32 bit word borders for struct members uint8_t cur_status; // 0 = idle, 1 = DMA running, 2 = timeout error - // 0x80: set on start to indicate CPU access uint8_t control; // cycle to perform: only DATO, DATI allowed uint16_t wordcount; // # of remaining words transmit/receive, static // ---dword--- + uint8_t cpu_access ; // 0 for device DMA, 1 for emulated CPU + uint8_t dummy[3] ; + // ---dword--- uint32_t cur_addr; // current address in transfer, if timeout: offending address. // if complete: last address accessed. uint32_t startaddr; // address of 1st word to transfer @@ -213,8 +211,8 @@ typedef struct { */ uint8_t signaled; // PRU->ARM uint8_t acked; // ARM->PRU - uint8_t cpu_transfer; // 1: ARM must process DMA as completed cpu DATA transfer - uint8_t _dummy2; +//int8_t cpu_transfer; // 1: ARM must process DMA as completed cpu DATA transfer + uint8_t _dummy2[2]; } mailbox_event_dma_t; // INTR raised by device diff --git a/10.01_base/2_src/shared/unibus.h b/10.01_base/2_src/shared/unibus.h index 2b238e5..eb05e09 100644 --- a/10.01_base/2_src/shared/unibus.h +++ b/10.01_base/2_src/shared/unibus.h @@ -39,7 +39,8 @@ #define UNIBUS_CONTROL_DATO 0x02 // 16 bit word from master to slave #define UNIBUS_CONTROL_DATOB 0x03 // 8 bit byte from master to slave // data<15:8> for a00 = 1, data<7:0> for a00 = 0 -#define UNIBUS_CONTROL_ISDATO(c) (!!((c) & 0x02)) // check for DATO/B +#define UNIBUS_CONTROL_IS_DATI(c) (!((c) & 0x02)) // check for DATI/P +#define UNIBUS_CONTROL_IS_DATO(c) (!!((c) & 0x02)) // check for DATO/B #define UNIBUS_TIMEOUTVAL 0xffffffff // EXAM result for bus timeout @@ -66,17 +67,16 @@ class intr_request_c; class unibus_c: public logsource_c { public: - enum arbitration_mode_enum { - ARBITRATION_MODE_NONE = 0, // no BR*/BG*, NR/NPG SACK protocoll - ARBITRATION_MODE_CLIENT = 1, // external Arbitrator (running PDP-11 CPU) required - ARBITRATION_MODE_MASTER = 2 // implmenet Arbitrator - // with or without physical CPU for arbitration - }; private: timeout_c timeout; + // false: no running CPU on UNIBUS (physical or emulated) + // devices do DMA without NPR/NPG protocol + // true: active CPU. devcies pus perform Request/Grant/SACK protocoll + bool arbitrator_active; + public: unibus_c(); @@ -86,7 +86,10 @@ public: static char *data2text(unsigned val); void init(unsigned pulsewidth_ms); - static void set_arbitration_mode(enum arbitration_mode_enum arbitration_mode); + + void set_arbitrator_active(bool active); + + bool get_arbitrator_active(void); void powercycle(void); @@ -94,24 +97,23 @@ public: dma_request_c *dma_request; //intr_request_c *intr_request; - bool dma(enum unibus_c::arbitration_mode_enum arbitration_mode, bool blocking, uint8_t control, - uint32_t startaddr, uint16_t *buffer, unsigned wordcount); + bool dma(bool blocking, + uint8_t control, uint32_t startaddr, uint16_t *buffer, unsigned wordcount); - void mem_read(enum unibus_c::arbitration_mode_enum arbitration_mode, uint16_t *words, + void mem_read(uint16_t *words, uint32_t unibus_start_addr, uint32_t unibus_end_addr, bool *timeout); - void mem_write(enum unibus_c::arbitration_mode_enum arbitration_mode, uint16_t *words, + void mem_write(uint16_t *words, unsigned unibus_start_addr, unsigned unibus_end_addr, bool *timeout); - void mem_access_random(enum unibus_c::arbitration_mode_enum arbitration_mode, + void 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 test_sizer(enum unibus_c::arbitration_mode_enum arbitration_mode); + uint32_t test_sizer(void); uint16_t testwords[UNIBUS_WORDCOUNT]; - void test_mem(enum unibus_c::arbitration_mode_enum arbitration_mode, uint32_t start_addr, - uint32_t end_addr, unsigned mode); + void test_mem(uint32_t start_addr, uint32_t end_addr, unsigned mode); }; diff --git a/10.01_base/3_test/multiarb/macro11.sh b/10.01_base/3_test/multiarb/macro11.sh new file mode 100644 index 0000000..2eb7e4b --- /dev/null +++ b/10.01_base/3_test/multiarb/macro11.sh @@ -0,0 +1,26 @@ +# Wrapper for macro11.exe or any other MACRO-11 assembler +# +# Parameters: +SRC=multiarb.mac +LST=multiarb.lst + +MACRO11=$HOME/91_3rd_party/MACRO11/macro11 + +# The output of MACRO-11 is an object module that must be linked before it can be loaded. +# Macro11.exe has no linking step, so ONLY ABSOLUTE SYMBOLS are allowed in the code! +# A relocatable symbol (= relative to module start) is marked with an single quote ' +# See pages 3-15, 4-1 and 6-14 of "PDP-11 MACRO-11 Langugage Reference Manual (Version 5.5, Oct 1987, AA-KX10A-TC).pdf" + + +# I use modified http://www.dbit.com/pub/pdp11/macro11/ +# "-e AMA" = ".ENABL AMA" = assemble relocatable addrs as absolute, since we have no linker +# "-e LISTHEX = list binary code in hex notation (instead of octal) + +# $MACRO11 -e AMA $SRC -l $LST +$MACRO11 $SRC -l $LST + +# generate a listing with binary code in hex notation +# (support for logic analyzer evaluation) +$MACRO11 -e listhex $SRC -l $LST.hex + + diff --git a/10.01_base/3_test/multiarb/multiarb.lst b/10.01_base/3_test/multiarb/multiarb.lst index d998f10..fdb4e29 100644 --- a/10.01_base/3_test/multiarb/multiarb.lst +++ b/10.01_base/3_test/multiarb/multiarb.lst @@ -24,8 +24,8 @@ 24 25 ; enable tests 26 000001 kwenab = 1 - 27 000000 rkenab = 0 - 28 000000 rlenab = 0 + 27 000001 rkenab = 1 + 28 000001 rlenab = 1 29 000000 ryenab = 0 ; not yet tested 30 000000 duenab = 0 ; not yet implemeneted 31 @@ -33,177 +33,185 @@ 33 .asect 34 35 ; ************************************************* - 36 ; Vectors - 37 - 38 000060 . = corvec - 39 000060 001170 .word corisr ; RCV interrupt - 40 000062 000340 .word 340 - 41 000064 . = coxvec - 42 000064 001204 .word coxisr ; XMT interrupt - 43 000066 000340 .word 340 - 44 - 45 000001 .if ne kwenab - 46 000100 . = kwvect - 47 000100 001430 .word kwisr ; periodic interrupt - 48 000102 000340 .word 340 - 49 .endc - 50 - 51 000000 .if ne rlenab - 52 . = rlvect ; RL11 - 53 .word rlisr - 54 .word 340 - 55 .endc - 56 - 57 000000 .if ne rkenab - 58 . = rkvect ; RK11 - 59 .word rkisr - 60 .word 340 - 61 .endc - 62 - 63 000000 .if ne ryenab - 64 . = ryvect ; RX211 - 65 .word ryisr - 66 .word 340 - 67 .endc - 68 - 69 000000 .if ne duenab - 70 . = duvect ; UDA MSCP controller - 71 .word duisr - 72 .word 340 - 73 .endc - 74 - 75 177776 psw = 177776 - 76 165020 monitr = 165020 ; Monitor addr for back jump - 77 - 78 ; ************************************************* - 79 ; Main - 80 001000 . = 1000 - 81 000776 stack = .-2 - 82 start: - 83 001000 012706 000776 mov #stack,sp - 84 001004 005037 177776 clr @#psw ; priorty level 0, allow INTR - 85 ; Initialize devices - 86 001010 000005 reset - 87 001012 004737 001212 call corini - 88 001016 004737 001226 call coxini - 89 000001 .if ne kwenab - 90 001022 004737 001442 call kwinit - 91 .endc - 92 000000 .if ne rkenab - 93 call rkinit - 94 .endc - 95 000000 .if ne rlenab - 96 call rlinit - 97 .endc - 98 000000 .if ne ryenab - 99 call ryinit - 100 .endc - 101 000000 .if ne duenab - 102 call duinit - 103 .endc - 104 - 105 001026 012701 001460 mov #shello,r1 ; Print "Hello" message - 106 001032 004737 001242 call puts - 107 - 108 ; main loop: check interrupt flags, restart DMA - 109 ; process serial input - 110 loop: - 111 001036 004737 001050 call dokbd ; check keyboard input - 112 001042 004737 001110 call dodev ; check device activities - 113 001046 000773 br loop - 114 + 36 ; Vectors ; UniBone emulated CPU start + 37 000000 . = 0 + 38 000000 000137 001000 jmp @#start + 39 + 40 + 41 ; Emulated CPU: restart on pwoer event + 42 000024 . = 24 ; Power ON/OFF + 43 000024 001000 .word start ; PC + 44 000026 000340 .word 340 ; PSW priority level 7 + 45 + 46 000060 . = corvec + 47 000060 001264 .word corisr ; RCV interrupt + 48 000062 000340 .word 340 + 49 000064 . = coxvec + 50 000064 001300 .word coxisr ; XMT interrupt + 51 000066 000340 .word 340 + 52 + 53 000001 .if ne kwenab + 54 000100 . = kwvect + 55 000100 001524 .word kwisr ; periodic interrupt + 56 000102 000340 .word 340 + 57 .endc + 58 + 59 000001 .if ne rlenab + 60 000160 . = rlvect ; RL11 + 61 000160 004640 .word rlisr + 62 000162 000340 .word 340 + 63 .endc + 64 + 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 + 72 . = ryvect ; RX211 + 73 .word ryisr + 74 .word 340 + 75 .endc + 76 + 77 000000 .if ne duenab + 78 . = duvect ; UDA MSCP controller + 79 .word duisr + 80 .word 340 + 81 .endc + 82 + 83 177776 psw = 177776 + 84 165020 monitr = 165020 ; Monitor addr for back jump + 85 + 86 ; ************************************************* + 87 ; Main + 88 001000 . = 1000 + 89 000776 stack = .-2 + 90 start: + 91 001000 012706 000776 mov #stack,sp + 92 001004 005037 177776 clr @#psw ; priorty level 0, allow INTR + 93 ; Initialize devices + 94 001010 000005 reset + 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 000001 .if ne rkenab + 101 001026 004737 002570 call rkinit + 102 .endc + 103 000001 .if ne rlenab + 104 001032 004737 004646 call rlinit + 105 .endc + 106 000000 .if ne ryenab + 107 call ryinit + 108 .endc + 109 000000 .if ne duenab + 110 call duinit + 111 .endc + 112 + 113 001036 012701 004766 mov #shello,r1 ; Print "Hello" message + 114 001042 004737 001336 call puts 115 - 116 - 117 ; --- check keyboard input - 118 dokbd: - 119 001050 004737 001374 call getc - 120 001054 103014 bcc 9$ ; nothing received - 121 ; process char in r0 - 122 001056 120027 000003 cmpb r0,#3 - 123 001062 001007 bne 1$ - 124 001064 012701 001551 mov #sbye,r1 ; ^C: print "Bye", back to monitor - 125 001070 004737 001242 call puts - 126 001074 000005 reset ; stop devices - 127 001076 000137 165020 jmp monitr - 128 1$: - 129 ; echo chars without special meaning - 130 001102 004737 001354 call putc - 131 9$: - 132 001106 000207 return - 133 - 134 ; -- check device activities - 135 dodev: - 136 ; For all devices: restart device DMA if Interrupt received - 137 000001 .if ne kwenab - 138 001110 005737 001424 tst kwiflg - 139 001114 001412 beq 1$ - 140 001116 005037 001424 clr kwiflg - 141 001122 004737 001456 call kwgo - 142 001126 012700 000127 mov #kwlabl,r0 ; progress printout - 143 001132 012701 001426 mov #kwecnt,r1 - 144 001136 004737 001144 call progrs - 145 1$: - 146 .endc - 147 - 148 000000 .if ne rkenab - 149 tst rkiflg - 150 beq 2$ - 151 clr rkiflg - 152 call rkgo - 153 mov #rklabl,r0 ; progress printout - 154 mov #rkecnt,r1 - 155 call progrs - 156 2$: - 157 .endc - 158 000000 .if ne rlenab - 159 tst rliflg - 160 beq 3$ - 161 clr rliflg - 162 call rlgo - 163 mov #rllabl,r0 ; progress printout - 164 mov #rlecnt,r1 - 165 call progrs - 166 3$: - 167 .endc - 168 000000 .if ne ryenab - 169 tst ryiflg - 170 beq 4$ - 171 clr ryiflg - 172 call rygo - 173 mov #rylabl,r0 ; progress printout - 174 mov #ryecnt,r1 - 175 call progrs - 176 4$: - 177 .endc - 178 000000 .if ne duenab - 179 tst duiflg - 180 beq 5$ - 181 clr duiflg - 182 call dugo - 183 mov #dulabl,r0 ; progress printout - 184 mov #duecnt,r1 - 185 call progrs - 186 5$: - 187 .endc - 188 - 189 001142 000207 return - 190 - 191 - 192 ; progress - 193 ; check if the counter with address in r1 is at - 194 ; 1024. if yes, print the char in r0 - 195 progrs: - 196 ; bic #777700,(r1) ; mask counter to 0..63 - 197 001144 042711 177400 bic #777400,(r1) ; mask counter to 0..255 - 198 ; bic #776000,(r1) ; mask counter to 0..1023 - 199 001150 001002 bne 9$ - 200 001152 004737 001354 call putc ; is at 0: print label character - 201 9$: - 202 001156 000207 return - 203 - 204 - 205 - 206 .include ma_cons.mac + 116 ; main loop: check interrupt flags, restart DMA + 117 ; process serial input + 118 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 001060 004737 001470 call getc + 128 001064 103014 bcc 9$ ; nothing received + 129 ; process char in r0 + 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 001112 004737 001450 call putc + 139 9$: + 140 001116 000207 return + 141 + 142 ; -- check device activities + 143 dodev: + 144 ; For all devices: restart device DMA if Interrupt received + 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 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 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 + 177 tst ryiflg + 178 beq 4$ + 179 clr ryiflg + 180 call rygo + 181 mov #rylabl,r0 ; progress printout + 182 mov #ryecnt,r1 + 183 call progrs + 184 4$: + 185 .endc + 186 000000 .if ne duenab + 187 tst duiflg + 188 beq 5$ + 189 clr duiflg + 190 call dugo + 191 mov #dulabl,r0 ; progress printout + 192 mov #duecnt,r1 + 193 call progrs + 194 5$: + 195 .endc + 196 + 197 001236 000207 return + 198 + 199 + 200 ; progress + 201 ; check if the counter with address in r1 is at + 202 ; 1024. if yes, print the char in r0 + 203 progrs: + 204 ; bic #777700,(r1) ; mask counter to 0..63 + 205 001240 042711 177400 bic #777400,(r1) ; mask counter to 0..255 + 206 ; bic #776000,(r1) ; mask counter to 0..1023 + 207 001244 001002 bne 9$ + 208 001246 004737 001450 call putc ; is at 0: print label character + 209 9$: + 210 001252 000207 return + 211 + 212 + 213 + 214 .include ma_cons.mac 1 2 .title ma_cons - Serial Console I/O 3 000060 corvec= 060 ; vector for Receiver @@ -216,30 +224,30 @@ 10 11 ; -- ISRs, increment Interrupt FLags 12 - 13 001160 000001 corifl: .word 1 ; Interrupt flags - 14 001162 000001 coxifl: .word 1 + 13 001254 000001 corifl: .word 1 ; Interrupt flags + 14 001256 000001 coxifl: .word 1 15 - 16 001164 corbuf: .blkw 1 ; data buffer - 17 001166 coxbuf: .blkw 1 + 16 001260 corbuf: .blkw 1 ; data buffer + 17 001262 coxbuf: .blkw 1 18 19 corisr: - 20 001170 013737 177562 001164 mov @#corbas+2,corbuf ; read char, clear INTR - 21 001176 005237 001160 inc corifl - 22 001202 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 001204 005237 001162 inc coxifl - 26 001210 000002 rti + 25 001300 005237 001256 inc coxifl + 26 001304 000002 rti 27 28 ; -- Initialize device after RESET 29 corini: - 30 001212 012737 000100 177560 mov #100,@#corbas ; Bit 6 = Receiver Interrupt Enable - 31 001220 005037 001160 clr corifl - 32 001224 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 001226 012737 000100 177564 mov #100,@#coxbas ; Bit 6 = Transmitter Interrupt Enable - 35 001234 005037 001162 clr coxifl - 36 001240 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 @@ -248,69 +256,69 @@ 42 ; puts - print a string 43 ; r1 = pointer, r0,r1 changed 44 puts: - 45 001242 112100 movb (r1)+,r0 ; load xmt char - 46 001244 001403 beq 1$ ; string ends with 0 - 47 001246 004737 001354 call @#putc - 48 001252 000773 br puts ; transmit nxt char of string - 49 001254 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 001256 numbf0: .blkw 10 ; space to mount number string - 54 001276 numbf1 =. + 53 001352 numbf0: .blkw 10 ; space to mount number string + 54 001372 numbf1 =. 55 putnum: - 56 001276 010346 mov r3,-(sp) - 57 001300 010002 mov r0,r2 ; r2 = shifter - 58 001302 012701 001276 mov #numbf1,r1 ; r1 = buffer pointer, backwards - 59 001306 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 001312 012703 000006 mov #6,r3 + 61 001406 012703 000006 mov #6,r3 62 1$: - 63 001316 010200 mov r2,r0 + 63 001412 010200 mov r2,r0 64 ; extract lower 3 bits = octal digit - 65 001320 042700 177770 bic #177770,r0 ; r0 &= 0x07 - 66 001324 062700 000060 add #60,r0 ; r0 += '0' - 67 001330 110041 movb r0,-(r1) ; write in buffer - 68 001332 000241 clc - 69 001334 006202 asr r2 ; shift to next digit - 70 001336 006202 asr r2 - 71 001340 006202 asr r2 - 72 001342 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 001344 004737 001242 call @#puts - 75 001350 012603 mov (sp)+,r3 - 76 001352 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 001354 005037 001162 clr coxifl ; reset interrupt flag - 83 001360 010037 177566 mov r0,@#coxbas+2 ; char into transmit buffer - 84 001364 005737 001162 1$: tst coxifl ; XMT RDY? - 85 001370 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 001372 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 001374 005000 clr r0 - 96 001376 005737 001160 tst corifl - 97 001402 001002 bne 1$ - 98 001404 000241 clc ; Carry clear, no Interrupt, nothing received - 99 001406 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 001410 013700 001164 mov corbuf,r0 ; Interrupt, return char - 102 001414 005037 001160 clr corifl ; reset interrupt flag - 103 001420 000261 sec ; Carry Set - 104 001422 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 - 207 000001 .if ne kwenab - 208 .include ma_kw.mac + 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 @@ -321,80 +329,172 @@ 8 9 10 ; --- ISRs, increment Interrupt FLags - 11 001424 000001 kwiflg: .word 1 ; Interrupt flags + 11 001520 000001 kwiflg: .word 1 ; Interrupt flags 12 - 13 001426 000001 kwecnt: .word 1 ; event counter + 13 001522 000001 kwecnt: .word 1 ; event counter 14 15 kwisr: - 16 001430 005237 001426 inc kwecnt ; register as event - 17 001434 005237 001424 inc kwiflg ; set ISR flag - 18 001440 000002 rti + 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 001442 012737 000100 177546 mov #100,@#kwbase ; set interrupt enable - 23 001450 005037 001426 clr kwecnt - 24 001454 000207 return + 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 001456 000207 return + 30 001552 000207 return 31 31 - 209 .endc - 210 000000 .if ne rkenab - 211 .include ma_rk.mac - 212 .endc - 213 000000 .if ne rlenab - 214 .include ma_rl.mac - 215 .endc - 216 000000 .if ne ryenab - 217 .include ma_ry.mac - 218 .endc - 219 000000 .if ne duenab - 220 .include ma_du.mac - 221 .endc - 222 .include ma_strings.mac + 217 .endc + 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 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 + 226 .endc + 227 000000 .if ne duenab + 228 .include ma_du.mac + 229 .endc + 230 .include ma_strings.mac 1 2 .title ma_strings - String constants 3 shello: - 4 001460 015 012 .byte 15,12 ; space, CR, LF, - 5 001462 052 052 052 .ascii /*** Multi Device Interrupt&DMA test ***/ - 001465 040 115 165 - 001470 154 164 151 - 001473 040 104 145 - 001476 166 151 143 - 001501 145 040 111 - 001504 156 164 145 - 001507 162 162 165 - 001512 160 164 046 - 001515 104 115 101 - 001520 040 164 145 - 001523 163 164 040 - 001526 052 052 052 - 6 001531 015 012 .byte 15,12 ; CR, LF - 7 001533 136 103 040 .ascii /^C to stop./ - 001536 164 157 040 - 001541 163 164 157 - 001544 160 056 - 8 001546 015 012 .byte 15,12 ; CR, LF - 9 001550 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 001551 015 012 .byte 15,12 - 14 001553 107 157 157 .ascii /Good Bye!/ - 001556 144 040 102 - 001561 171 145 041 - 15 001564 015 012 .byte 15,12 ; CR, LF - 16 001566 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 - 223 - 224 .end - 225 - 226 - 227 - 227 + 231 + 232 .end + 233 + 234 + 235 + 235 diff --git a/10.01_base/3_test/multiarb/multiarb.mac b/10.01_base/3_test/multiarb/multiarb.mac index 12bd962..beb14c2 100644 --- a/10.01_base/3_test/multiarb/multiarb.mac +++ b/10.01_base/3_test/multiarb/multiarb.mac @@ -24,8 +24,8 @@ ; enable tests kwenab = 1 -rkenab = 0 -rlenab = 0 +rkenab = 1 +rlenab = 1 ryenab = 0 ; not yet tested duenab = 0 ; not yet implemeneted @@ -33,7 +33,15 @@ duenab = 0 ; not yet implemeneted .asect ; ************************************************* - ; Vectors + ; Vectors ; UniBone emulated CPU start + . = 0 + jmp @#start + + + ; Emulated CPU: restart on pwoer event + . = 24 ; Power ON/OFF + .word start ; PC + .word 340 ; PSW priority level 7 . = corvec .word corisr ; RCV interrupt diff --git a/10.02_devices/2_src/cpu.cpp b/10.02_devices/2_src/cpu.cpp index d681a91..afe42f8 100644 --- a/10.02_devices/2_src/cpu.cpp +++ b/10.02_devices/2_src/cpu.cpp @@ -58,12 +58,27 @@ void unibone_log(unsigned msglevel, const char *srcfilename, unsigned srcline, c va_end(arg_ptr); } - void unibone_logdump(void) { // logger->dump(logger->default_filepath); logger->dump(); // stdout } +// called before opcode fetch of next instruction +// This is the point in time were INTR requests are checked and GRANTed +// (PRU implementation may limit NPR GRANTs also to this time) +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 + while (mailbox->arbitrator.ifs_intr_arbitration_pending) { +// often 60-80 us, So just idle loop the CPU thread +// timeout_c::wait_us(1); + } +} + // Result: 1 = OK, 0 = bus timeout int unibone_dato(unsigned addr, unsigned data) { uint16_t wordbuffer = (uint16_t) data; @@ -93,8 +108,6 @@ int unibone_dati(unsigned addr, unsigned *data) { *data = wordbuffer; dbg = 0; // printf("DATI; ba=%o, data=%o\n", addr, *data) ; -//if (!unibone_cpu->data_transfer_request.success) -// ARM_DEBUG_PIN0(1) ; return unibone_cpu->data_transfer_request.success; } @@ -104,7 +117,7 @@ int unibone_dati(unsigned addr, unsigned *data) { // mailbox->arbitrator.cpu_priority_level was CPU_PRIORITY_LEVEL_FETCHING // In that case, PRU is allowed now to grant BGs again. void unibone_prioritylevelchange(uint8_t level) { - mailbox->arbitrator.cpu_priority_level = level; + mailbox->arbitrator.ifs_priority_level = level; } // CPU executes RESET opcode -> pulses INIT line @@ -148,15 +161,43 @@ cpu_c::~cpu_c() { bool cpu_c::on_param_changed(parameter_c *param) { if (param == &enabled) { if (!enabled.new_value) { - // HALT disabled CPU - runmode.value = false; init.value = false; + // HALT disabled CPU + stop(); + } else { + // enable active: assert CPU starts stopped + stop(); + } + } else if (param == &runmode) { + if (runmode.new_value) { + start(); + } else { + stop(); } } + return unibusdevice_c::on_param_changed(param); // more actions (for enable) } +// start CPU logic on PRU and switch arbitration mode +void cpu_c::start() { + runmode.value = true; + mailbox->cpu_enable = 1; + mailbox_execute(ARM2PRU_CPU_ENABLE); + unibus->set_arbitrator_active(true); +} + +// stop CPU logic on PRU and switch arbitration mode +void cpu_c::stop() { + ka11.state = 0; + runmode.value = false; + mailbox->cpu_enable = 0; + mailbox_execute(ARM2PRU_CPU_ENABLE); + unibus->set_arbitrator_active(false); +} + // background worker. +// Started/stopped on param "enable" void cpu_c::worker(unsigned instance) { UNUSED(instance); // only one timeout_c timeout; @@ -169,58 +210,45 @@ void cpu_c::worker(unsigned instance) { power_event = power_event_none; // run with lowest priority, but without wait() - // => get all remainingn CPU power -// worker_init_realtime_priority(none_rt); -//worker_init_realtime_priority(device_rt); + // => get all remaining CPU power + worker_init_realtime_priority(none_rt); + //worker_init_realtime_priority(device_rt); + + timeout.wait_us(1); + while (!workers_terminate) { - // speed control is diffiuclt, force to use more ARM cycles - timeout.wait_us(1); - for (int i = 0; i < 10; i++) { - - if (runmode.value != (ka11.state != 0)) - ka11.state = runmode.value; - ka11_condstep(&ka11); - 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) { - // don't call power traps if HALTed. Also not on CONT. - if (power_event == power_event_down) - ka11_pwrdown(&unibone_cpu->ka11); - // stop stop some time after power down - else if (power_event == power_event_up) - ka11_pwrup(&unibone_cpu->ka11); - power_event = power_event_none; // processed - } - - if (init.value) { - // user wants CPU reset - ka11_reset(&ka11); - init.value = 0; - } + // speed control is difficult, force to use more ARM cycles +// if (runmode.value != (ka11.state != 0)) +// ka11.state = runmode.value; + if (runmode.value && (ka11.state == 0)) + ka11.state = 1; // HALTED -> RUNNING + else if (!runmode.value) + // HALT position inside instructions !!! + ka11.state = 0; // WAITING|RUNNING =- HALTED + int prev_ka11_state = ka11.state; + ka11_condstep(&ka11); + if (prev_ka11_state > 0 && ka11.state == 0) { + // CPU run on HALT, sync runmode + runmode.value = false; + printf("CPU HALT at %06o.\n", ka11.r[7]); } -#if 0 + // serialize asynchronous power events if (runmode.value) { - // simulate a fetch - nxm = !unibone_dati(pc, &opcode); - if (nxm) { - printf("Bus timeout at PC = %06o. HALT.\n", pc); - runmode.value = false; - } - pc = (pc + 2) % 0100; // loop around - // set LEDS - nxm = !unibone_dato(dr, pc & 0xf); - if (nxm) { - printf("Bus timeout at DR = %06o. HALT.\n", dr); - runmode.value = false; - } + // don't call power traps if HALTed. Also not on CONT. + if (power_event == power_event_down) + ka11_pwrdown(&unibone_cpu->ka11); + // stop stop some time after power down + else if (power_event == power_event_up) + ka11_pwrup(&unibone_cpu->ka11); + power_event = power_event_none; // processed } -#endif + if (init.value) { + // user wants CPU reset + ka11_reset(&ka11); + init.value = 0; + } } } diff --git a/10.02_devices/2_src/cpu.hpp b/10.02_devices/2_src/cpu.hpp index 520279d..fc16730 100644 --- a/10.02_devices/2_src/cpu.hpp +++ b/10.02_devices/2_src/cpu.hpp @@ -59,6 +59,10 @@ public: struct Bus bus; // UNIBUS interface of CPU struct KA11 ka11; // Angelos CPU state + void start(void) ; + void stop(void) ; + + // background worker function void worker(unsigned instance) override; diff --git a/10.02_devices/2_src/cpu20/ka11.c b/10.02_devices/2_src/cpu20/ka11.c index 2fb308f..a329129 100644 --- a/10.02_devices/2_src/cpu20/ka11.c +++ b/10.02_devices/2_src/cpu20/ka11.c @@ -3,6 +3,7 @@ #include "gpios.hpp" // ARM_DEBUG_PIN* +void unibone_on_before_instruction(void) ; int unibone_dato(unsigned addr, unsigned data); int unibone_datob(unsigned addr, unsigned data); int unibone_dati(unsigned addr, unsigned *data); @@ -132,11 +133,8 @@ int dati(KA11 *cpu, int b) { trace("dati %06o:\n", cpu->ba); - if(!b && cpu->ba&1) { -//ARM_DEBUG_PIN0(1) ; -//unibone_logdump() ; // write trace() output to file + if(!b && cpu->ba&1) goto be; -} /* internal registers */ if((cpu->ba&0177400) == 0177400){ @@ -367,7 +365,6 @@ step(KA11 *cpu) #define TRB(m) trace("%06o "#m"%s\n", PC-2, by ? "B" : "") oldpsw = PSW; - INA(PC, cpu->ir); PC += 2; /* don't increment on bus error! */ by = !!(cpu->ir&B15); @@ -574,7 +571,7 @@ be: if(cpu->be > 1){ cpu->state = STATE_HALTED; return; } -printf("bus error\n"); +printf("bus error ar %06o\n", cpu->ba); TRAP(4); trap: @@ -654,6 +651,9 @@ ka11_condstep(KA11 *cpu) if((cpu->state == STATE_RUNNING) || (cpu->state == STATE_WAITING && cpu->traps)){ cpu->state = STATE_RUNNING; + + unibone_on_before_instruction() ; + svc(cpu, cpu->bus); step(cpu); } } @@ -663,8 +663,6 @@ run(KA11 *cpu) { cpu->state = STATE_RUNNING; while(cpu->state != STATE_HALTED){ - svc(cpu, cpu->bus); - ka11_condstep(cpu); } diff --git a/10.02_devices/2_src/dl11w.cpp b/10.02_devices/2_src/dl11w.cpp index 0da70f6..b86480f 100644 --- a/10.02_devices/2_src/dl11w.cpp +++ b/10.02_devices/2_src/dl11w.cpp @@ -132,7 +132,7 @@ bool slu_c::on_param_changed(parameter_c *param) { INFO("Serial port %s opened", serialport.value.c_str()); char buff[256]; - sprintf(buff, "Serial port %s opened\n\r", serialport.value.c_str()); + sprintf(buff, "\n\rSerial port %s opened\n\r", serialport.value.c_str()); rs232.cputs(buff); } else { // disable SLU @@ -552,9 +552,9 @@ void ltc_c::on_init_changed(void) { intr_enable = 0; line_clock_monitor = 1; intr_request.edge_detect_reset(); // but edge_detect() not used - // initial condition is "not signaled" - // INFO("ltc_c::on_init()"); -} + // initial condition is "not signaled" + // INFO("ltc_c::on_init()"); + } } /* background worker. @@ -563,60 +563,61 @@ void ltc_c::on_init_changed(void) { lost edges are compensated */ void ltc_c::worker(unsigned instance) { -UNUSED(instance); // only one -timeout_c global_time; -timeout_c timeout; -int64_t global_next_edge_ns; + UNUSED(instance); // only one + timeout_c global_time; + timeout_c timeout; + int64_t global_next_edge_ns; // set prio to RT, but less than unibus_adapter -worker_init_realtime_priority(rt_device); + worker_init_realtime_priority(rt_device); -INFO("KW11 time resolution is < %u us", (unsigned )(global_time.get_resolution_ns() / 1000)); -global_time.start_ns(0); -global_next_edge_ns = global_time.elapsed_ns(); -uint64_t global_edge_count = 0; -while (!workers_terminate) { - // signal egde period may change if 50/60 Hz is changed - uint64_t edge_period_ns = BILLION / (2 * frequency.value); - uint64_t wait_ns; - // overdue_ns: time which signal edge is too late - int64_t overdue_ns = (int64_t) global_time.elapsed_ns() - global_next_edge_ns; - // INFO does not work on 64 ints - // printf("elapsed [ms] =%u, overdue [us] =%u\n", (unsigned) global_time.elapsed_ms(), (unsigned) overdue_ns/1000) ; - // if overdue_ns positive, next signal edge should have occured - if (overdue_ns < 0) { - wait_ns = -overdue_ns; // wait until next edge time reached - } else { - // time for next signal edge reached - if (ltc_enable.value) { - global_edge_count++; - clock_signal = !clock_signal; // square wave - if (clock_signal) { - line_clock_monitor = 1; - pthread_mutex_lock(&on_after_register_access_mutex); - set_lks_dati_value_and_INTR(intr_enable); - pthread_mutex_unlock(&on_after_register_access_mutex); - } - } else - // clock disconnected - clock_signal = 0; + INFO("KW11 time resolution is < %u us", + (unsigned )(global_time.get_resolution_ns() / 1000)); + global_time.start_ns(0); + global_next_edge_ns = global_time.elapsed_ns(); + uint64_t global_edge_count = 0; + while (!workers_terminate) { + // signal egde period may change if 50/60 Hz is changed + uint64_t edge_period_ns = BILLION / (2 * frequency.value); + uint64_t wait_ns; + // overdue_ns: time which signal edge is too late + int64_t overdue_ns = (int64_t) global_time.elapsed_ns() - global_next_edge_ns; + // INFO does not work on 64 ints + // printf("elapsed [ms] =%u, overdue [us] =%u\n", (unsigned) global_time.elapsed_ms(), (unsigned) overdue_ns/1000) ; + // if overdue_ns positive, next signal edge should have occured + if (overdue_ns < 0) { + wait_ns = -overdue_ns; // wait until next edge time reached + } else { + // time for next signal edge reached + if (ltc_enable.value) { + global_edge_count++; + clock_signal = !clock_signal; // square wave + if (clock_signal) { + line_clock_monitor = 1; + pthread_mutex_lock(&on_after_register_access_mutex); + set_lks_dati_value_and_INTR(intr_enable); + pthread_mutex_unlock(&on_after_register_access_mutex); + } + } else + // clock disconnected + clock_signal = 0; - // time of next signal edge - global_next_edge_ns += edge_period_ns; - // overdue_ns now time which next signal edge is too late - overdue_ns -= edge_period_ns; + // time of next signal edge + global_next_edge_ns += edge_period_ns; + // overdue_ns now time which next signal edge is too late + overdue_ns -= edge_period_ns; - if (overdue_ns < 0) - // next edge now in future: wait exact - wait_ns = -overdue_ns; - else - // next edge still in past: - // wait shorter than signal edge period to keep up slowly - wait_ns = edge_period_ns / 2; - //if ((global_edge_count % 100) == 0) - // INFO("LTC: %u secs by edges", (unsigned)(global_edge_count/100) ) ; + if (overdue_ns < 0) + // next edge now in future: wait exact + wait_ns = -overdue_ns; + else + // next edge still in past: + // wait shorter than signal edge period to keep up slowly + wait_ns = edge_period_ns / 2; + //if ((global_edge_count % 100) == 0) + // INFO("LTC: %u secs by edges", (unsigned)(global_edge_count/100) ) ; + } + timeout.wait_ns(wait_ns); } - timeout.wait_ns(wait_ns); -} } diff --git a/10.02_devices/3_test/cpu20/cpu20multiarb.cmd b/10.02_devices/3_test/cpu20/cpu20multiarb.cmd new file mode 100644 index 0000000..7ba7396 --- /dev/null +++ b/10.02_devices/3_test/cpu20/cpu20multiarb.cmd @@ -0,0 +1,90 @@ +# Inputfile for demo to execute "Hello world" +# Uses emulated CPU and (physical or emulated) DL11 +# Read in with command line option "demo --cmdfile ..." + +dc # "device with cpu" menu + +m i # emulate missing memory + +sd dl11 +# p b 300 # reduced baudrate +en dl11 # switch on emulated DL11 +p + +### Enable KW11 clock +en kw11 +sd kw11 + + +### Enable 2 RL drives +en rl # enable RL11 controller +sd rl +p il 4 # use BR4 + +en rl0 # enable drive #0 +sd rl0 # select +p emulation_speed 10 # 10x speed. Load disk in 5 seconds +# set type to "rl02" +p runstopbutton 0 # released: "LOAD" +p powerswitch 1 # power on, now in "load" state +p image scratch0.rl02 # mount image file with test pattern +p runstopbutton 1 # press RUN/STOP, will start +#.end + +en rl1 # enable drive #1 +sd rl1 # select +p emulation_speed 10 # 10x speed. Load disk in 5 seconds +# set type to "rl02" +p runstopbutton 0 # released: "LOAD" +p powerswitch 1 # power on, now in "load" state +p image scratch1.rl02 # mount image file with test pattern +p runstopbutton 1 # press RUN/STOP, will start + + +### Enable 2 RK05 drives +en rk # enable RK11 controller + +en rk0 # enable drive #0 +sd rk0 # select +p image scratch0.rk + +en rk1 # enable drive #1 +sd rk1 # select +p image scratch1.rk + +### Enable 2 MSCP drives +en uda0 # enable drive #0 +sd uda0 # select +# set type to "RA80" +p type RA80 +p image scratch0.ra80 # mount image file with test pattern + +en uda1 # enable drive #1 +sd uda1 # select +p type RA80 +p image scratch1.ra80 + +.wait 5000 # wait to spin up + +m ll multiarb.lst # load test program + + +en cpu20 # switch on emulated 11/20 CPU +sd cpu20 # select +p + +init + +.print Emulated PDP-11/20 CPU will now output "Hello world" +.print and enter a serial echo loop on DL11 at 177650. +.print Make sure physical CPU is disabled. + +.input + +p run 1 + +# .print CPU20 started... wait for auto-typed input. +# dl11 rcv 5000 + + + diff --git a/10.02_devices/3_test/cpu20/multiarb.lst b/10.02_devices/3_test/cpu20/multiarb.lst new file mode 100644 index 0000000..8eb9663 --- /dev/null +++ b/10.02_devices/3_test/cpu20/multiarb.lst @@ -0,0 +1,376 @@ + 1 .title Multi Arbitration DMA/INTR test + 2 + 3 ; ************************************************* + 4 ; Exercises several devices in parallel, + 5 ; each with INTR and DMA + 6 ; For a device XX we have + 7 ; XXENAB - flag to enable device + 8 ; XXBASE - base address of device + 9 ; XXVEC - the INTR vector + 10 ; XXISR - Interrupt Service + 11 ; XXIFLG - flag which is incremented in ISR + 12 ; XXBUF - data buffer for DMA transfer + 13 ; XXINIT - Initialize device after RESET + 14 ; XXGO - subroutine to initiate DMA and INTR + 15 ; XXECNT - event counter, indicates activity + 16 ; XXLABL - single char label to print activity + 17 ; + 18 ; Devices are + 19 ; CO - serial console + 20 ; RK - RK11/RK05 disk + 21 ; RL - RL11/RL02 disk + 22 ; RY - Serial RX211 Floppy, + 23 ; DU - MSCP disk drive on UDA controller + 24 + 25 ; enable tests + 26 000000 kwenab = 0 + 27 000000 rkenab = 0 + 28 000000 rlenab = 0 + 29 000000 ryenab = 0 ; not yet tested + 30 000000 duenab = 0 ; not yet implemeneted + 31 + 32 .enable AMA + 33 .asect + 34 + 35 ; ************************************************* + 36 ; Vectors ; UniBone emulated CPU start + 37 000000 . = 0 + 38 000000 000137 001000 jmp @#start + 39 + 40 + 41 ; Emulated CPU: restart on pwoer event + 42 000024 . = 24 ; Power ON/OFF + 43 000024 001000 .word start ; PC + 44 000026 000340 .word 340 ; PSW priority level 7 + 45 + 46 000060 . = corvec + 47 000060 001132 .word corisr ; RCV interrupt + 48 000062 000340 .word 340 + 49 000064 . = coxvec + 50 000064 001146 .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 + 57 .endc + 58 + 59 000000 .if ne rlenab + 60 . = rlvect ; RL11 + 61 .word rlisr + 62 .word 340 + 63 .endc + 64 + 65 000000 .if ne rkenab + 66 . = rkvect ; RK11 + 67 .word rkisr + 68 .word 340 + 69 .endc + 70 + 71 000000 .if ne ryenab + 72 . = ryvect ; RX211 + 73 .word ryisr + 74 .word 340 + 75 .endc + 76 + 77 000000 .if ne duenab + 78 . = duvect ; UDA MSCP controller + 79 .word duisr + 80 .word 340 + 81 .endc + 82 + 83 177776 psw = 177776 + 84 165020 monitr = 165020 ; Monitor addr for back jump + 85 + 86 ; ************************************************* + 87 ; Main + 88 001000 . = 1000 + 89 000776 stack = .-2 + 90 start: + 91 001000 012706 000776 mov #stack,sp + 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 + 99 .endc + 100 000000 .if ne rkenab + 101 call rkinit + 102 .endc + 103 000000 .if ne rlenab + 104 call rlinit + 105 .endc + 106 000000 .if ne ryenab + 107 call ryinit + 108 .endc + 109 000000 .if ne duenab + 110 call duinit + 111 .endc + 112 + 113 001022 012701 001366 mov #shello,r1 ; Print "Hello" message + 114 001026 004737 001204 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 + 122 + 123 + 124 + 125 ; --- check keyboard input + 126 dokbd: + 127 001044 004737 001336 call getc + 128 001050 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 + 136 1$: + 137 ; echo chars without special meaning + 138 001076 004737 001316 call putc + 139 9$: + 140 001102 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 + 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 + 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 + 174 3$: + 175 .endc + 176 000000 .if ne ryenab + 177 tst ryiflg + 178 beq 4$ + 179 clr ryiflg + 180 call rygo + 181 mov #rylabl,r0 ; progress printout + 182 mov #ryecnt,r1 + 183 call progrs + 184 4$: + 185 .endc + 186 000000 .if ne duenab + 187 tst duiflg + 188 beq 5$ + 189 clr duiflg + 190 call dugo + 191 mov #dulabl,r0 ; progress printout + 192 mov #duecnt,r1 + 193 call progrs + 194 5$: + 195 .endc + 196 + 197 001104 000207 return + 198 + 199 + 200 ; progress + 201 ; check if the counter with address in r1 is at + 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 + 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 + 209 9$: + 210 001120 000207 return + 211 + 212 + 213 + 214 .include ma_cons.mac + 1 + 2 .title ma_cons - Serial Console I/O + 3 000060 corvec= 060 ; vector for Receiver + 4 000064 coxvec= 064 ; vector for Xmitter + 5 + 6 177560 corbas= 777560 ; base addr of Receiver + 7 177564 coxbas= 777564 ; base addr of Xmitter + 8 + 9 + 10 + 11 ; -- ISRs, increment Interrupt FLags + 12 + 13 001122 000001 corifl: .word 1 ; Interrupt flags + 14 001124 000001 coxifl: .word 1 + 15 + 16 001126 corbuf: .blkw 1 ; data buffer + 17 001130 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 + 23 + 24 coxisr: + 25 001146 005237 001124 inc coxifl + 26 001152 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 + 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 + 37 + 38 + 39 + 40 ; -------- Console I/O -------- + 41 + 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 + 50 + 51 + 52 ; putnum - print the octal number in r0 + 53 001220 numbf0: .blkw 10 ; space to mount number string + 54 001240 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 + 60 ; repeat 6 times + 61 001254 012703 000006 mov #6,r3 + 62 1$: + 63 001260 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 + 73 + 74 001306 004737 001204 call @#puts + 75 001312 012603 mov (sp)+,r3 + 76 001314 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 + 86 ; UART is buffering: char only started to sent now + 87 ; interrupt active until next putc + 88 001334 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 + 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 + 104 + 215 000000 .if ne kwenab + 216 .include ma_kw.mac + 217 .endc + 218 000000 .if ne rkenab + 219 .include ma_rk.mac + 220 .endc + 221 000000 .if ne rlenab + 222 .include ma_rl.mac + 223 .endc + 224 000000 .if ne ryenab + 225 .include ma_ry.mac + 226 .endc + 227 000000 .if ne duenab + 228 .include ma_du.mac + 229 .endc + 230 .include ma_strings.mac + 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 + 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 + 17 + 17 + 231 + 232 .end + 233 + 234 + 235 + 235 diff --git a/10.02_devices/5_boot/dk.lst b/10.02_devices/5_boot/dk.lst index 1eaab3c..c51cbe4 100644 --- a/10.02_devices/5_boot/dk.lst +++ b/10.02_devices/5_boot/dk.lst @@ -14,71 +14,80 @@ 14 000002 xxwc =rkwc ; common word count offset 15 16 .asect - 17 010000 .=10000 - 18 - 19 ; -------------------------------------------------- + 17 ; ---- Simple boot drive 0 from 0 + 18 000000 . = 0 + 19 000000 000137 010000 jmp @#start0 20 - 21 start: - 22 ; 8 unit numbers => 8 entry addresses - 23 start0: - 24 010000 012700 000000 mov #0,r0 - 25 010004 000435 br dknr - 26 010006 000240 nop - 27 start1: - 28 010010 012700 000001 mov #1,r0 - 29 010014 000431 br dknr - 30 010016 000240 nop - 31 start2: - 32 010020 012700 000002 mov #2,r0 - 33 010024 000425 br dknr - 34 010026 000240 nop - 35 start3: - 36 010030 012700 000003 mov #3,r0 - 37 010034 000421 br dknr - 38 010036 000240 nop - 39 start4: - 40 010040 012700 000004 mov #4,r0 - 41 010044 000415 br dknr - 42 010046 000240 nop - 43 start5: - 44 010050 012700 000005 mov #5,r0 - 45 010054 000411 br dknr - 46 010056 000240 nop - 47 start6: - 48 010060 012700 000006 mov #6,r0 - 49 010064 000405 br dknr - 50 010066 000240 nop - 51 start7: - 52 010070 012700 000007 mov #7,r0 - 53 010074 000401 br dknr - 54 010076 000240 nop - 55 - 56 - 57 dknr: - 58 010100 012701 177404 mov #rkcsr+4,r1 ; boot std csr, unit - 59 - 60 010104 010003 mov r0,r3 ; get unit number - 61 010106 000241 clc ; C=0 for ror - 62 010110 006003 ror r3 ; shift into 15:12 - 63 010112 006003 ror r3 ; - 64 010114 006003 ror r3 ; - 65 010116 006003 ror r3 ; - 66 010120 010361 000006 mov r3,rkda(r1) ; unit number, sector 0 to disk addr - 67 - 68 010124 012761 177000 000002 mov #-512.,xxwc(r1) ; set word count - 69 010132 052703 000005 bis #5,r3 ; command READ+GO - 70 010136 010311 mov r3,(r1) ; execute - 71 010140 105711 2$: tstb (r1) ; test ready - 72 010142 100376 bpl 2$ ; loop - 73 - 74 010144 005711 tst (r1) ; check error - 75 010146 100002 bpl 3$ ; br if no error + 21 ; ---- Reboot drive 0 on power event + 22 000024 . = 24 ; Power ON/OFF + 23 000024 010000 .word start0 ; PC + 24 000026 000340 .word 340 ; PSW priority level 7 + 25 + 26 + 27 ; ----- Main boot addresses + 28 010000 .=10000 ; arbitrary position > 3000 + 29 + 30 start: + 31 ; 8 unit numbers => 8 entry addresses + 32 start0: + 33 010000 012700 000000 mov #0,r0 + 34 010004 000435 br dknr + 35 010006 000240 nop + 36 start1: + 37 010010 012700 000001 mov #1,r0 + 38 010014 000431 br dknr + 39 010016 000240 nop + 40 start2: + 41 010020 012700 000002 mov #2,r0 + 42 010024 000425 br dknr + 43 010026 000240 nop + 44 start3: + 45 010030 012700 000003 mov #3,r0 + 46 010034 000421 br dknr + 47 010036 000240 nop + 48 start4: + 49 010040 012700 000004 mov #4,r0 + 50 010044 000415 br dknr + 51 010046 000240 nop + 52 start5: + 53 010050 012700 000005 mov #5,r0 + 54 010054 000411 br dknr + 55 010056 000240 nop + 56 start6: + 57 010060 012700 000006 mov #6,r0 + 58 010064 000405 br dknr + 59 010066 000240 nop + 60 start7: + 61 010070 012700 000007 mov #7,r0 + 62 010074 000401 br dknr + 63 010076 000240 nop + 64 + 65 + 66 dknr: + 67 010100 012701 177404 mov #rkcsr+4,r1 ; boot std csr, unit + 68 + 69 010104 010003 mov r0,r3 ; get unit number + 70 010106 000241 clc ; C=0 for ror + 71 010110 006003 ror r3 ; shift into 15:12 + 72 010112 006003 ror r3 ; + 73 010114 006003 ror r3 ; + 74 010116 006003 ror r3 ; + 75 010120 010361 000006 mov r3,rkda(r1) ; unit number, sector 0 to disk addr 76 - 77 010150 000005 reset ; reset the world - 78 010152 000752 br dknr ; and retry - 79 - 80 010154 042711 000377 3$: bic #377,(r1) ; nop command - 81 010160 005007 clr pc ; jump to loaded boot sector + 77 010124 012761 177000 000002 mov #-512.,xxwc(r1) ; set word count + 78 010132 052703 000005 bis #5,r3 ; command READ+GO + 79 010136 010311 mov r3,(r1) ; execute + 80 010140 105711 2$: tstb (r1) ; test ready + 81 010142 100376 bpl 2$ ; loop 82 - 83 .end - 83 + 83 010144 005711 tst (r1) ; check error + 84 010146 100002 bpl 3$ ; br if no error + 85 + 86 010150 000005 reset ; reset the world + 87 010152 000752 br dknr ; and retry + 88 + 89 010154 042711 000377 3$: bic #377,(r1) ; nop command + 90 010160 005007 clr pc ; jump to loaded boot sector + 91 + 92 .end + 92 diff --git a/10.02_devices/5_boot/dk.mac b/10.02_devices/5_boot/dk.mac index b8d265b..8620ebf 100644 --- a/10.02_devices/5_boot/dk.mac +++ b/10.02_devices/5_boot/dk.mac @@ -14,9 +14,18 @@ rkda =+12-4 ; disk address xxwc =rkwc ; common word count offset .asect - .=10000 + ; ---- Simple boot drive 0 from 0 + . = 0 + jmp @#start0 - ; -------------------------------------------------- + ; ---- Reboot drive 0 on power event + . = 24 ; Power ON/OFF + .word start0 ; PC + .word 340 ; PSW priority level 7 + + + ; ----- Main boot addresses + .=10000 ; arbitrary position > 3000 start: ; 8 unit numbers => 8 entry addresses diff --git a/10.02_devices/5_boot/dl.lst b/10.02_devices/5_boot/dl.lst index 4bcbdf6..f3a7d96 100644 --- a/10.02_devices/5_boot/dl.lst +++ b/10.02_devices/5_boot/dl.lst @@ -1,6 +1,6 @@ 1 .title M9312 'DL' BOOT prom for RL11 controller 2 - 3 ; This source code is a modified copyof the DEC M9312 23-751A9 boot PROM. + 3 ; This source code is a modified copy of the DEC M9312 23-751A9 boot PROM. 4 ; 5 ; This boot PROM is for the RL11 controller with RL01/RL02 drives. 6 ; @@ -20,73 +20,82 @@ 20 000014 cmrdda =6*2 ; read data 21 22 .asect - 23 010000 .=10000 ; arbitrary position > 3000 - 24 - 25 ; -------------------------------------------------- + 23 ; ---- Simple boot drive 0 from 0 + 24 000000 . = 0 + 25 000000 000137 010000 jmp @#start0 26 - 27 start: - 28 ; 4 unit numbers => 4 entry addresses - 29 start0: - 30 010000 012700 000000 mov #0,r0 - 31 010004 000413 br dlnr - 32 010006 000240 nop - 33 start1: - 34 010010 012700 000001 mov #1,r0 - 35 010014 000407 br dlnr - 36 010016 000240 nop - 37 start2: - 38 010020 012700 000002 mov #2,r0 - 39 010024 000403 br dlnr - 40 010026 000240 nop - 41 start3: - 42 010030 012700 000003 mov #3,r0 - 43 - 44 dlnr: - 45 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit - 46 - 47 ; -------------------------------------------------- - 48 - 49 010040 010003 mov r0,r3 ; save unit number - 50 010042 000303 swab r3 ; unit number in upper byte - 51 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 27 ; ---- Reboot drive 0 on power event + 28 000024 . = 24 ; Power ON/OFF + 29 000024 010000 .word start0 ; PC + 30 000026 000340 .word 340 ; PSW priority level 7 + 31 + 32 + 33 ; ----- Main boot addresses + 34 010000 .=10000 ; arbitrary position > 3000 + 35 + 36 start: + 37 ; 4 unit numbers => 4 entry addresses + 38 start0: + 39 010000 012700 000000 mov #0,r0 + 40 010004 000413 br dlnr + 41 010006 000240 nop + 42 start1: + 43 010010 012700 000001 mov #1,r0 + 44 010014 000407 br dlnr + 45 010016 000240 nop + 46 start2: + 47 010020 012700 000002 mov #2,r0 + 48 010024 000403 br dlnr + 49 010026 000240 nop + 50 start3: + 51 010030 012700 000003 mov #3,r0 52 - 53 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus - 54 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) - 55 010060 010311 mov r3,(r1) ; execute - 56 010062 105711 1$: tstb (r1) ; test for ready - 57 010064 100376 bpl 1$ ; wait - 58 - 59 010066 105003 clrb r3 ; unit number in upper byte - 60 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd - 61 010074 010311 mov r3,(r1) ; execute - 62 010076 105711 2$: tstb (r1) ; test for ready - 63 010100 100376 bpl 2$ ; wait - 64 - 65 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector - 66 010106 042702 000077 bic #77,r2 ; set sector to zero - 67 010112 005202 inc r2 ; set head 0, seek to cyl 0 - 68 010114 010261 000004 mov r2,rlda(r1) ; into da for seek - 69 010120 105003 clrb r3 ; unit number in upper byte - 70 010122 052703 000006 bis #cmseek,r3 ; seek cmd - 71 010126 010311 mov r3,(r1) ; execute - 72 010130 105711 3$: tstb (r1) ; test for ready - 73 010132 100376 bpl 3$ ; wait - 74 - 75 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 - 76 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count - 77 010146 105003 clrb r3 ; unit number in upper byte - 78 010150 052703 000014 bis #cmrdda,r3 ; read data cmd - 79 010154 010311 mov r3,(r1) ; execute - 80 010156 105711 4$: tstb (r1) ; test for ready - 81 010160 100376 bpl 4$ ; wait - 82 - 83 010162 005711 tst (r1) ; test for error - 84 010164 100002 bpl 5$ ; br if ok - 85 010166 000005 reset ; ERROR - reset the world - 86 010170 000721 br dlnr ; retry. r0 unchanged - 87 - 88 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd - 89 010176 005007 clr pc ; jump to bootstrap at zero - 90 - 91 .end + 53 dlnr: + 54 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit + 55 + 56 ; -------------------------------------------------- + 57 + 58 010040 010003 mov r0,r3 ; save unit number + 59 010042 000303 swab r3 ; unit number in upper byte + 60 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 61 + 62 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus + 63 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) + 64 010060 010311 mov r3,(r1) ; execute + 65 010062 105711 1$: tstb (r1) ; test for ready + 66 010064 100376 bpl 1$ ; wait + 67 + 68 010066 105003 clrb r3 ; unit number in upper byte + 69 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd + 70 010074 010311 mov r3,(r1) ; execute + 71 010076 105711 2$: tstb (r1) ; test for ready + 72 010100 100376 bpl 2$ ; wait + 73 + 74 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector + 75 010106 042702 000077 bic #77,r2 ; set sector to zero + 76 010112 005202 inc r2 ; set head 0, seek to cyl 0 + 77 010114 010261 000004 mov r2,rlda(r1) ; into da for seek + 78 010120 105003 clrb r3 ; unit number in upper byte + 79 010122 052703 000006 bis #cmseek,r3 ; seek cmd + 80 010126 010311 mov r3,(r1) ; execute + 81 010130 105711 3$: tstb (r1) ; test for ready + 82 010132 100376 bpl 3$ ; wait + 83 + 84 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 + 85 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count + 86 010146 105003 clrb r3 ; unit number in upper byte + 87 010150 052703 000014 bis #cmrdda,r3 ; read data cmd + 88 010154 010311 mov r3,(r1) ; execute + 89 010156 105711 4$: tstb (r1) ; test for ready + 90 010160 100376 bpl 4$ ; wait 91 + 92 010162 005711 tst (r1) ; test for error + 93 010164 100002 bpl 5$ ; br if ok + 94 010166 000005 reset ; ERROR - reset the world + 95 010170 000721 br dlnr ; retry. r0 unchanged + 96 + 97 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd + 98 010176 005007 clr pc ; jump to bootstrap at zero + 99 + 100 .end + 100 diff --git a/10.02_devices/5_boot/dl.mac b/10.02_devices/5_boot/dl.mac index 44bf284..223185d 100644 --- a/10.02_devices/5_boot/dl.mac +++ b/10.02_devices/5_boot/dl.mac @@ -20,9 +20,18 @@ cmrdhd =4*2 ; read header cmrdda =6*2 ; read data .asect - .=10000 ; arbitrary position > 3000 + ; ---- Simple boot drive 0 from 0 + . = 0 + jmp @#start0 - ; -------------------------------------------------- + ; ---- Reboot drive 0 on power event + . = 24 ; Power ON/OFF + .word start0 ; PC + .word 340 ; PSW priority level 7 + + + ; ----- Main boot addresses + .=10000 ; arbitrary position > 3000 start: ; 4 unit numbers => 4 entry addresses diff --git a/10.02_devices/5_boot/du.lst b/10.02_devices/5_boot/du.lst index 615cee3..99a2256 100644 --- a/10.02_devices/5_boot/du.lst +++ b/10.02_devices/5_boot/du.lst @@ -22,92 +22,103 @@ 22 000002 mssa =+2 ; SA register 23 24 .asect - 25 010000 .=10000 ; arbitrary position > 3000 - 26 - 27 ; -------------------------------------------------- - 28 001004 rpkt =1004 ; rpkt structure - 29 001070 cpkt =1070 ; cpkt structure - 30 001200 comm =1200 ; comm structure - 31 ;comm =2404 ; comm structure (at 'blt .+12') - 32 - 33 ; register usage: - 34 ; r0: unit number 0..3 - 35 ; r1: MSCP csrbase - 36 ; r2: moving buffer pointer - 37 ; r3: moving buffer pointer - 38 ; r5: init mask - 39 - 40 ; 4 unit numbers => 4 entry addresses - 41 start0: - 42 010000 012700 000000 mov #0,r0 - 43 010004 000413 br duNr - 44 010006 000240 nop - 45 start1: - 46 010010 012700 000001 mov #1,r0 - 47 010014 000407 br duNr - 48 010016 000240 nop - 49 start2: - 50 010020 012700 000002 mov #2,r0 - 51 010024 000403 br duNr - 52 010026 000240 nop - 53 start3: - 54 010030 012700 000003 mov #3,r0 - 55 - 56 ; retry entry - 57 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit - 58 - 59 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr - 60 010042 012705 004000 mov #4000,r5 ; S1 state bitmask - 61 010046 012703 010166 mov #mscpdt,r3 ; point to data - 62 - 63 ; write 4 init words, with r5 mask from 4000 to 40000 - 64 010052 005711 3$: tst (r1) ; error bit set ? - 65 010054 100767 bmi duNr ; yes, fail back to begin to retry - 66 010056 031105 bit (r1),r5 ; step bit set ? - 67 010060 001774 beq 3$ ; not yet, wait loop - 68 010062 012311 mov (r3)+,(r1) ; yes, send next init data - 69 010064 006305 asl r5 ; next mask - 70 010066 100371 bpl 3$ ; s4 done? br if not yet - 71 - 72 010070 005002 4$: clr r2 ; set bufptr to 0 - 73 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] - 74 010074 020227 001200 cmp r2,#comm ; check for end of buffer - 75 010100 001374 bne 5$ ; loop if not done - 76 - 77 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 - 78 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command - 79 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) - 80 010116 010037 001074 mov r0,@#cpkt+4 ; set unit - 81 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr - 82 010126 010522 mov r5,(r2)+ ; rq own bit15 - 83 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr - 84 010134 010522 mov r5,(r2)+ ; cq own bit15 - 85 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) - 86 - 87 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? - 88 010146 100775 bmi 6$ ; loop if not done - 89 - 90 010150 105737 001016 tstb @#rpkt+12 ; check for error ? - 91 010154 001327 bne duNr ; yup, fail back to begin to retry - 92 - 93 010156 105723 tstb (r3)+ ; check end of table ? - 94 010160 001743 beq 4$ ; br if not yet - 95 - 96 010162 005041 clr -(r1) ; init controller (write IP) - 97 010164 005007 clr pc ; jmp to bootstrap at zero - 98 - 99 ; MSCP init and command data - 100 ; pointed to by r3 - 101 mscpdt: - 102 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector - 103 010170 001200 .word comm ; S2: 002404 = ringbase lo addr - 104 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr - 105 010174 000001 .word 000001 ; S4: 000001 = go bit - 106 ; - 107 ; MSCP command data - 108 ; - 109 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) - 110 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) - 111 - 112 .end - 112 + 25 ; ---- Simple boot drive 0 from 0 + 26 000000 . = 0 + 27 000000 000137 010000 jmp @#start0 + 28 + 29 ; ---- Reboot drive 0 on power event + 30 000024 . = 24 ; Power ON/OFF + 31 000024 010000 .word start0 ; PC + 32 000026 000340 .word 340 ; PSW priority level 7 + 33 + 34 + 35 ; ----- Main boot addresses + 36 010000 .=10000 ; arbitrary position > 3000 + 37 + 38 + 39 001004 rpkt =1004 ; rpkt structure + 40 001070 cpkt =1070 ; cpkt structure + 41 001200 comm =1200 ; comm structure + 42 ;comm =2404 ; comm structure (at 'blt .+12') + 43 + 44 ; register usage: + 45 ; r0: unit number 0..3 + 46 ; r1: MSCP csrbase + 47 ; r2: moving buffer pointer + 48 ; r3: moving buffer pointer + 49 ; r5: init mask + 50 + 51 ; 4 unit numbers => 4 entry addresses + 52 start0: + 53 010000 012700 000000 mov #0,r0 + 54 010004 000413 br duNr + 55 010006 000240 nop + 56 start1: + 57 010010 012700 000001 mov #1,r0 + 58 010014 000407 br duNr + 59 010016 000240 nop + 60 start2: + 61 010020 012700 000002 mov #2,r0 + 62 010024 000403 br duNr + 63 010026 000240 nop + 64 start3: + 65 010030 012700 000003 mov #3,r0 + 66 + 67 ; retry entry + 68 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit + 69 + 70 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr + 71 010042 012705 004000 mov #4000,r5 ; S1 state bitmask + 72 010046 012703 010166 mov #mscpdt,r3 ; point to data + 73 + 74 ; write 4 init words, with r5 mask from 4000 to 40000 + 75 010052 005711 3$: tst (r1) ; error bit set ? + 76 010054 100767 bmi duNr ; yes, fail back to begin to retry + 77 010056 031105 bit (r1),r5 ; step bit set ? + 78 010060 001774 beq 3$ ; not yet, wait loop + 79 010062 012311 mov (r3)+,(r1) ; yes, send next init data + 80 010064 006305 asl r5 ; next mask + 81 010066 100371 bpl 3$ ; s4 done? br if not yet + 82 + 83 010070 005002 4$: clr r2 ; set bufptr to 0 + 84 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] + 85 010074 020227 001200 cmp r2,#comm ; check for end of buffer + 86 010100 001374 bne 5$ ; loop if not done + 87 + 88 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 + 89 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command + 90 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) + 91 010116 010037 001074 mov r0,@#cpkt+4 ; set unit + 92 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr + 93 010126 010522 mov r5,(r2)+ ; rq own bit15 + 94 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr + 95 010134 010522 mov r5,(r2)+ ; cq own bit15 + 96 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) + 97 + 98 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? + 99 010146 100775 bmi 6$ ; loop if not done + 100 + 101 010150 105737 001016 tstb @#rpkt+12 ; check for error ? + 102 010154 001327 bne duNr ; yup, fail back to begin to retry + 103 + 104 010156 105723 tstb (r3)+ ; check end of table ? + 105 010160 001743 beq 4$ ; br if not yet + 106 + 107 010162 005041 clr -(r1) ; init controller (write IP) + 108 010164 005007 clr pc ; jmp to bootstrap at zero + 109 + 110 ; MSCP init and command data + 111 ; pointed to by r3 + 112 mscpdt: + 113 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector + 114 010170 001200 .word comm ; S2: 002404 = ringbase lo addr + 115 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr + 116 010174 000001 .word 000001 ; S4: 000001 = go bit + 117 ; + 118 ; MSCP command data + 119 ; + 120 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) + 121 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) + 122 + 123 .end + 123 diff --git a/10.02_devices/5_boot/du.mac b/10.02_devices/5_boot/du.mac index e9756b6..bb5bb25 100644 --- a/10.02_devices/5_boot/du.mac +++ b/10.02_devices/5_boot/du.mac @@ -22,9 +22,20 @@ msip =+0 ; IP register mssa =+2 ; SA register .asect + ; ---- Simple boot drive 0 from 0 + . = 0 + jmp @#start0 + + ; ---- Reboot drive 0 on power event + . = 24 ; Power ON/OFF + .word start0 ; PC + .word 340 ; PSW priority level 7 + + + ; ----- Main boot addresses .=10000 ; arbitrary position > 3000 - ; -------------------------------------------------- + rpkt =1004 ; rpkt structure cpkt =1070 ; cpkt structure comm =1200 ; comm structure diff --git a/10.03_app_demo/2_src/application.cpp b/10.03_app_demo/2_src/application.cpp index b757045..2d3e93e 100644 --- a/10.03_app_demo/2_src/application.cpp +++ b/10.03_app_demo/2_src/application.cpp @@ -170,15 +170,6 @@ void application_c::parse_commandline(int argc, char **argv) { "Lines are processed as if typed in.", "testseq", "read commands from file \"testseq\" and execute line by line", "", ""); - getopt_parser.define("arb", "arbitration_mode", "mode", "", "", - "Setup configuration of UNIBUS test system.\n" - "arb 0: no Bus Arbitrator. No PDP-11 CPU is doing NPR/INTR/SACK arbitration\n" - " (HALTed, Not plugged in, or console processor active SACK)\n" - " Bus master memory access without handshake to CPU.\n" - "arb 1: UniBone is client to PDP-11 CPU Bus Arbitrator.\n" - " Bus master memory access with NPR/G/SACK handshake to CPU.\n", "", "", - "", ""); - // test options getopt_parser.define("t", "test", "iarg1,iarg2", "soptarg", "8 15", @@ -200,11 +191,6 @@ void application_c::parse_commandline(int argc, char **argv) { } else if (getopt_parser.isoption("cmdfile")) { if (getopt_parser.arg_s("cmdfilename", opt_cmdfilename) < 0) commandline_option_error(NULL); - } else if (getopt_parser.isoption("arbitration_mode")) { - unsigned mode; - WARNING("Option \"arbitration_mode\" was removed"); - if (getopt_parser.arg_u("mode", &mode) < 0) - commandline_option_error(NULL); } else if (getopt_parser.isoption("test")) { int i1, i2; string s; @@ -251,12 +237,6 @@ void application_c::hardware_startup(enum pru_c::prucode_enum prucode_id) { iopageregisters_init(); } -// if prucode_id is UNIBUS, define also wether Abritration ignored, doen by remote CPU or emulated -void application_c::hardware_startup(enum pru_c::prucode_enum prucode_id, - enum unibus_c::arbitration_mode_enum arbitration_mode) { - hardware_startup(prucode_id); - unibus_c::set_arbitration_mode(arbitration_mode); -} // disable all hardware related subsystems: void application_c::hardware_shutdown() { diff --git a/10.03_app_demo/2_src/application.hpp b/10.03_app_demo/2_src/application.hpp index d4ea383..5b19889 100644 --- a/10.03_app_demo/2_src/application.hpp +++ b/10.03_app_demo/2_src/application.hpp @@ -70,8 +70,6 @@ public: void parse_commandline(int argc, char **argv); void hardware_startup(enum pru_c::prucode_enum prucode_id); - void hardware_startup(enum pru_c::prucode_enum prucode_id, - enum unibus_c::arbitration_mode_enum arbitration_mode); void hardware_shutdown(void); @@ -79,10 +77,9 @@ public: uint32_t emulated_memory_start_addr; uint32_t emulated_memory_end_addr; - void print_arbitration_info(enum unibus_c::arbitration_mode_enum arbitration_mode, - const char *indent); - char *getchoice(void);bool emulate_memory( - enum unibus_c::arbitration_mode_enum arbitration_mode); + void print_arbitration_info( const char *indent); + char *getchoice(void); + bool emulate_memory(void); void print_params(parameterized_c *parameterized, parameter_c *p); unibusdevice_register_t * device_register_by_id(unibusdevice_c *device, char *specifier); @@ -98,7 +95,7 @@ public: void menu_buslatches(void); void menu_unibus_signals(void); void menu_ddrmem_slave_only(void); - void menu_masterslave(enum unibus_c::arbitration_mode_enum arbitration_mode); + void menu_masterslave(bool with_CPU); void menu_interrupts(void); void menu_devices(bool with_CPU); void menu_device_exercisers(void); diff --git a/10.03_app_demo/2_src/menu_ddrmem_slave_only.cpp b/10.03_app_demo/2_src/menu_ddrmem_slave_only.cpp index 9d66c84..395ac39 100644 --- a/10.03_app_demo/2_src/menu_ddrmem_slave_only.cpp +++ b/10.03_app_demo/2_src/menu_ddrmem_slave_only.cpp @@ -47,7 +47,8 @@ void application_c::menu_ddrmem_slave_only() { bool ready; int n_fields; - hardware_startup(pru_c::PRUCODE_UNIBUS, unibus_c::ARBITRATION_MODE_NONE); + hardware_startup(pru_c::PRUCODE_UNIBUS); + unibus->set_arbitrator_active(false) ; ready = false; while (!ready) { diff --git a/10.03_app_demo/2_src/menu_device_exercisers.cpp b/10.03_app_demo/2_src/menu_device_exercisers.cpp index a609794..92b99a6 100644 --- a/10.03_app_demo/2_src/menu_device_exercisers.cpp +++ b/10.03_app_demo/2_src/menu_device_exercisers.cpp @@ -48,7 +48,6 @@ #include "devexer_rl.hpp" void application_c::menu_device_exercisers(void) { - enum unibus_c::arbitration_mode_enum arbitration_mode = unibus_c::ARBITRATION_MODE_MASTER; bool ready = false; bool show_help = true; bool memory_installed = false; @@ -59,8 +58,9 @@ void application_c::menu_device_exercisers(void) { // iopageregisters_init(); // UNIBUS activity - hardware_startup(pru_c::PRUCODE_UNIBUS, unibus_c::ARBITRATION_MODE_CLIENT); + hardware_startup(pru_c::PRUCODE_UNIBUS); buslatches_output_enable(true); + unibus->set_arbitrator_active(false) ; // instantiate different device exercisers @@ -76,7 +76,7 @@ void application_c::menu_device_exercisers(void) { show_help = false; // only once printf("\n"); printf("*** Exercise (= work with) installed UNIBUS decives.\n"); - print_arbitration_info(arbitration_mode, " "); + print_arbitration_info(" "); if (cur_exerciser) { printf(" Current device is \"%s\" @ %06o\n", cur_exerciser->name.value.c_str(), cur_exerciser->base_addr.value); @@ -135,7 +135,7 @@ void application_c::menu_device_exercisers(void) { } else if (!strcasecmp(s_opcode, "m") && n_fields == 2 && !strcasecmp(s_param[0], "i")) { // install (emulate) max UNIBUS memory - memory_installed = emulate_memory(arbitration_mode); + memory_installed = emulate_memory(); show_help = true; // menu struct changed } else if (memory_installed && !strcasecmp(s_opcode, "m") && n_fields >= 2 && !strcasecmp(s_param[0], "f")) { @@ -149,7 +149,7 @@ void application_c::menu_device_exercisers(void) { // write buffer-> UNIBUS printf("Fill memory with %06o, writing UNIBUS memory[%06o:%06o]\n", fillword, emulated_memory_start_addr, emulated_memory_end_addr); - unibus->mem_write(arbitration_mode, membuffer->data.words, + unibus->mem_write(membuffer->data.words, emulated_memory_start_addr, emulated_memory_end_addr, &timeout); if (timeout) printf("Error writing UNIBUS memory!\n"); @@ -159,13 +159,13 @@ void application_c::menu_device_exercisers(void) { const char * filename = "memory.dump"; bool timeout; // 1. read UNIBUS memory - uint32_t end_addr = unibus->test_sizer(arbitration_mode) - 2; + uint32_t end_addr = unibus->test_sizer() - 2; printf("Reading UNIBUS memory[0:%06o] with DMA\n", end_addr); // clear memory buffer, to be sure content changed membuffer->set_addr_range(0, end_addr); membuffer->fill(0); - unibus->mem_read(arbitration_mode, membuffer->data.words, 0, end_addr, + unibus->mem_read(membuffer->data.words, 0, end_addr, &timeout); if (timeout) printf("Error reading UNIBUS memory!\n"); @@ -226,7 +226,7 @@ void application_c::menu_device_exercisers(void) { // interpret as 18 bit address parse_addr18(s_param[0], &addr); parse_word(s_param[1], &wordbuffer); - bool timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATO, addr, + bool timeout = !unibus->dma(true, UNIBUS_CONTROL_DATO, addr, &wordbuffer, 1); printf("DEPOSIT %06o <- %06o\n", addr, wordbuffer); if (timeout) @@ -237,7 +237,7 @@ void application_c::menu_device_exercisers(void) { uint32_t addr; if (n_fields == 2) { // single reg number given parse_addr18(s_param[0], &addr); // interpret as 18 bit address - timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATI, addr, + timeout = !unibus->dma(true, UNIBUS_CONTROL_DATI, addr, &wordbuffer, 1); printf("EXAM %06o -> %06o\n", addr, wordbuffer); } diff --git a/10.03_app_demo/2_src/menu_devices.cpp b/10.03_app_demo/2_src/menu_devices.cpp index 898619c..13b8ed1 100644 --- a/10.03_app_demo/2_src/menu_devices.cpp +++ b/10.03_app_demo/2_src/menu_devices.cpp @@ -60,8 +60,7 @@ static char memory_filename[PATH_MAX + 1]; // entry_label is program start, tpyically "start" // format: 0 = macrop11, 1 = papertape -static void load_memory(enum unibus_c::arbitration_mode_enum arbitration_mode, - memory_fileformat_t format, char *fname, const char *entry_label) { +static void load_memory(memory_fileformat_t format, char *fname, const char *entry_label) { uint32_t firstaddr, lastaddr; bool load_ok; bool timeout; @@ -89,7 +88,7 @@ static void load_memory(enum unibus_c::arbitration_mode_enum arbitration_mode, else printf(" No entry address at \"%s\" label is %06o.\n", entry_label, membuffer->entry_address); - unibus->mem_write(arbitration_mode, membuffer->data.words, firstaddr, lastaddr, + unibus->mem_write(membuffer->data.words, firstaddr, lastaddr, &timeout); if (timeout) printf(" Error writing UNIBUS memory\n"); @@ -106,13 +105,10 @@ static void print_device(device_c *device) { device->type_name.value.c_str()); } -// CPU is enabled, act as ARBITRATION_MASTER -void application_c::menu_devices(bool with_CPU) { +void application_c::menu_devices(bool with_emulated_CPU) { /** list of usable devices ***/ bool with_storage_file_test = false; - enum unibus_c::arbitration_mode_enum arbitration_mode; - bool ready = false; bool show_help = true; bool memory_emulated = false; @@ -122,21 +118,22 @@ void application_c::menu_devices(bool with_CPU) { char *s_choice; char s_opcode[256], s_param[3][256]; - // with_CPU: PRU Arbitrator is answering BR and NPR requests. - if (with_CPU) - arbitration_mode = unibus_c::ARBITRATION_MODE_MASTER; -// arbitration_mode = unibus_c::ARBITRATION_MODE_NONE; - else - arbitration_mode = unibus_c::ARBITRATION_MODE_CLIENT; - strcpy(memory_filename, ""); // iopageregisters_init(); // UNIBUS activity // assert(unibus->arbitrator_client) ; // External Bus Arbitrator required - hardware_startup(pru_c::PRUCODE_UNIBUS, arbitration_mode); + hardware_startup(pru_c::PRUCODE_UNIBUS); // now PRU executing UNIBUS master/slave code, physical PDP-11 CPU as arbitrator required. buslatches_output_enable(true); + + // devices need physical or emulated CPU Arbitrator + // to answer BR and NPR requests. + if (with_emulated_CPU) + // not yet active, switches to CLIENT when emulated CPU started + unibus->set_arbitrator_active(false) ; + else + unibus->set_arbitrator_active(true) ; // without PDP-11 CPU no INIT after power ON was generated. // Devices may trash the bus lines. @@ -172,7 +169,7 @@ void application_c::menu_devices(bool with_CPU) { // //demo_regs.install(); // //demo_regs.worker_start(); - if (with_CPU) { + if (with_emulated_CPU) { cpu = new cpu_c(); cpu->enabled.set(true); } @@ -193,7 +190,7 @@ void application_c::menu_devices(bool with_CPU) { show_help = false; // only once printf("\n"); printf("*** Test of device parameter interface and states.\n"); - print_arbitration_info(arbitration_mode, " "); + print_arbitration_info(" "); if (cur_device) { printf(" Current device is \"%s\"\n", cur_device->name.value.c_str()); if (unibuscontroller) @@ -279,7 +276,7 @@ void application_c::menu_devices(bool with_CPU) { } else if (!strcasecmp(s_opcode, "m") && n_fields == 2 && !strcasecmp(s_param[0], "i")) { // install (emulate) max UNIBUS memory - memory_emulated = emulate_memory(arbitration_mode); + memory_emulated = emulate_memory(); show_help = true; // menu struct changed } else if (!strcasecmp(s_opcode, "m") && n_fields >= 2 && !strcasecmp(s_param[0], "f")) { @@ -293,7 +290,7 @@ void application_c::menu_devices(bool with_CPU) { // write buffer-> UNIBUS printf("Fill memory with %06o, writing UNIBUS memory[%06o:%06o]\n", fillword, emulated_memory_start_addr, emulated_memory_end_addr); - unibus->mem_write(arbitration_mode, membuffer->data.words, + unibus->mem_write(membuffer->data.words, emulated_memory_start_addr, emulated_memory_end_addr, &timeout); if (timeout) printf("Error writing UNIBUS memory!\n"); @@ -303,13 +300,13 @@ void application_c::menu_devices(bool with_CPU) { const char * filename = "memory.dump"; bool timeout; // 1. read UNIBUS memory - uint32_t end_addr = unibus->test_sizer(arbitration_mode) - 2; + uint32_t end_addr = unibus->test_sizer() - 2; printf("Reading UNIBUS memory[0:%06o] with DMA\n", end_addr); // clear memory buffer, to be sure content changed membuffer->set_addr_range(0, end_addr); membuffer->fill(0); - unibus->mem_read(arbitration_mode, membuffer->data.words, 0, end_addr, + unibus->mem_read(membuffer->data.words, 0, end_addr, &timeout); if (timeout) printf("Error reading UNIBUS memory!\n"); @@ -321,20 +318,20 @@ void application_c::menu_devices(bool with_CPU) { } else if (!strcasecmp(s_opcode, "m") && n_fields == 3 && !strcasecmp(s_param[0], "ll")) { // m ll - load_memory(arbitration_mode, fileformat_macro11_listing, s_param[1], "start"); + load_memory(fileformat_macro11_listing, s_param[1], "start"); } else if (!strcasecmp(s_opcode, "m") && n_fields == 2 && !strcasecmp(s_param[0], "ll") && strlen(memory_filename)) { // m ll - load_memory(arbitration_mode, fileformat_macro11_listing, memory_filename, + load_memory(fileformat_macro11_listing, memory_filename, "start"); } else if (!strcasecmp(s_opcode, "m") && n_fields == 3 && !strcasecmp(s_param[0], "lp")) { // m lp - load_memory(arbitration_mode, fileformat_papertape, s_param[1], NULL); + load_memory(fileformat_papertape, s_param[1], NULL); } else if (!strcasecmp(s_opcode, "m") && n_fields == 2 && !strcasecmp(s_param[0], "lp") && strlen(memory_filename)) { // m lp - load_memory(arbitration_mode, fileformat_papertape, memory_filename, NULL); + load_memory(fileformat_papertape, memory_filename, NULL); } else if (!strcasecmp(s_opcode, "ld") && n_fields == 1) { unsigned n; list::iterator it; @@ -433,7 +430,7 @@ void application_c::menu_devices(bool with_CPU) { parse_addr18(s_param[0], &addr); parse_word(s_param[1], &wordbuffer); - bool timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATO, addr, + bool timeout = !unibus->dma(true, UNIBUS_CONTROL_DATO, addr, &wordbuffer, 1); if (reg) { assert( @@ -458,7 +455,7 @@ void application_c::menu_devices(bool with_CPU) { addr = reg->addr; else parse_addr18(s_param[0], &addr); // interpret as 18 bit address - timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATI, addr, + timeout = !unibus->dma(true, UNIBUS_CONTROL_DATI, addr, &wordbuffer, 1); printf("EXAM %06o -> %06o\n", addr, wordbuffer); } else if (n_fields == 1 && unibuscontroller) { // list all regs @@ -468,7 +465,7 @@ void application_c::menu_devices(bool with_CPU) { wordcount = unibuscontroller->register_count; if (wordcount) { unsigned i; - timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATI, + timeout = !unibus->dma(true, UNIBUS_CONTROL_DATI, addr, wordbuffer, wordcount); for (i = 0; addr <= mailbox->dma.cur_addr; i++, addr += 2) { reg = unibuscontroller->register_by_unibus_address(addr); @@ -551,7 +548,7 @@ void application_c::menu_devices(bool with_CPU) { } } // ready - if (with_CPU) { + if (with_emulated_CPU) { cpu->enabled.set(false); delete cpu; } diff --git a/10.03_app_demo/2_src/menu_interrupts.cpp b/10.03_app_demo/2_src/menu_interrupts.cpp index 5bae7cd..8450adc 100644 --- a/10.03_app_demo/2_src/menu_interrupts.cpp +++ b/10.03_app_demo/2_src/menu_interrupts.cpp @@ -42,9 +42,6 @@ #include "testcontroller.hpp" void application_c::menu_interrupts(void) { - // needs physical CPU - enum unibus_c::arbitration_mode_enum arbitration_mode = unibus_c::ARBITRATION_MODE_CLIENT; - bool show_help = true; // show cmds on first screen, then only on error or request bool active = false; // 1 if PRU executes slave&master logic bool ready; @@ -58,8 +55,10 @@ void application_c::menu_interrupts(void) { // These test need active PRUs // and an PDP-11 CPU as Arbitrator - hardware_startup(pru_c::PRUCODE_UNIBUS, arbitration_mode); + hardware_startup(pru_c::PRUCODE_UNIBUS); buslatches_output_enable(true); + // CPU required + unibus->set_arbitrator_active(true) ; ready = false; test_loaded = false; @@ -82,13 +81,13 @@ void application_c::menu_interrupts(void) { unibusadapter->enabled.set(true); active = true; } - printf("m emulate all missing memory\n"); - printf("e EXAMINE the word at . [octal]\n"); + printf("m emulate all missing memory\n"); + printf("e EXAMINE the word at . [octal]\n"); printf("d DEPOSIT into [octal]\n"); printf("ll Load test program from MACRO-11 listing\n"); if (test_loaded) { printf( - "i Issue interrupt at priority to < [octal]\n"); + "i Issue interrupt at priority to < [octal]\n"); printf(" = 0..7, = 0,4,10,...,374\n"); printf( " Then interrupts cause print-out, and processor priority\n"); @@ -110,9 +109,9 @@ void application_c::menu_interrupts(void) { printf(" 0..%u possible.\n", (unsigned) test_controller->dma_channel_count); } - printf("dbg c|s|f Debug log: Clear, Show on console, dump to File.\n"); - printf("pwr Simulate UNIBUS power cycle (ACLO/DCLO)\n"); - printf("q Quit\n"); + printf("dbg c|s|f Debug log: Clear, Show on console, dump to File.\n"); + printf("pwr Simulate UNIBUS power cycle (ACLO/DCLO)\n"); + printf("q Quit\n"); } s_choice = getchoice(); @@ -124,12 +123,12 @@ void application_c::menu_interrupts(void) { } else if (!strcasecmp(s_opcode, "pwr")) { unibus->powercycle(); } else if (!strcasecmp(s_opcode, "m") && n_fields == 1) { - emulate_memory(arbitration_mode); + emulate_memory(); } else if (!strcasecmp(s_opcode, "e") && n_fields == 2) { uint32_t cur_addr; uint16_t wordbuffer; parse_addr18(s_param[0], &cur_addr); - bool timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATI, cur_addr, + bool timeout = !unibus->dma(true, UNIBUS_CONTROL_DATI, cur_addr, &wordbuffer, 1); if (timeout) printf("Bus timeout at %06o.\n", cur_addr); @@ -140,7 +139,7 @@ void application_c::menu_interrupts(void) { uint16_t wordbuffer; parse_addr18(s_param[0], &cur_addr); parse_word(s_param[1], &wordbuffer); - bool timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATO, cur_addr, + bool timeout = !unibus->dma(true, UNIBUS_CONTROL_DATO, cur_addr, &wordbuffer, 1); if (timeout) printf("Bus timeout at %06o.\n", cur_addr); @@ -160,7 +159,7 @@ void application_c::menu_interrupts(void) { membuffer->get_addr_range(&start_addr, &end_addr); printf("Loaded %u words, writing UNIBUS memory[%06o:%06o].\n", membuffer->get_word_count(), start_addr, end_addr); - unibus->mem_write(arbitration_mode, membuffer->data.words, start_addr, end_addr, + unibus->mem_write(membuffer->data.words, start_addr, end_addr, &timeout); if (timeout) printf("Memory write failed with UNIBUS timeout, aborting.\n"); diff --git a/10.03_app_demo/2_src/menu_masterslave.cpp b/10.03_app_demo/2_src/menu_masterslave.cpp index 0bc3942..2d95d54 100644 --- a/10.03_app_demo/2_src/menu_masterslave.cpp +++ b/10.03_app_demo/2_src/menu_masterslave.cpp @@ -48,9 +48,9 @@ #define WORDBUFFER_LEN 256 -// "arbitration_active": operate in an environment without +// "with_CPU": false if operating in an environment without // arbitration and interrupt fielding? -void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitration_mode) { +void application_c::menu_masterslave(bool with_CPU) { // UniBone uses this test controller: // memory cells at start of IO page, can be tested with ZKMA testcontroller_c testcontroller; @@ -68,10 +68,10 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr // iopageregisters_init(); // erase all devices from PRU // These test need active PRUs - //TODO: rewrite. - hardware_startup(pru_c::PRUCODE_UNIBUS, arbitration_mode); + hardware_startup(pru_c::PRUCODE_UNIBUS); buslatches_output_enable(true); - + unibus->set_arbitrator_active(with_CPU) ; + // PRUCODE_UNIBUS can raise events (INIT,ACLO,DCLO) // handle & clear these unibusadapter->enabled.set(true); @@ -86,13 +86,13 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr if (show_help) { show_help = false; // only once printf("\n"); - print_arbitration_info(arbitration_mode, " "); + print_arbitration_info(" "); if (emulated_memory_start_addr > emulated_memory_end_addr) printf(" UniBone does not emulate memory.\n"); else printf(" UniBone emulates memory from %06o to %06o.\n", emulated_memory_start_addr, emulated_memory_end_addr); - if (arbitration_mode == unibus_c::ARBITRATION_MODE_CLIENT && !active) { + if (with_CPU && !active) { // Old: physical PDP_11 CPU -> test of testcontroller? printf("***\n"); printf("*** Starting full UNIBUS master/slave logic on PRU\n"); @@ -170,44 +170,44 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr emulated_memory_start_addr, emulated_memory_end_addr); } } else if (!strcasecmp(s_opcode, "m") && n_fields == 1) { - emulate_memory(arbitration_mode); + emulate_memory(); } else if (!strcasecmp(s_opcode, "sz")) { - uint32_t first_invalid_addr = unibus->test_sizer(arbitration_mode); + uint32_t first_invalid_addr = unibus->test_sizer(); if (first_invalid_addr == 0) printf("Address [0] invalid\n"); else printf("Found valid addresses in range %06o..%06o.\n", 0, first_invalid_addr - 2); } else if (!strcasecmp(s_opcode, "ta") && n_fields == 1) { - uint32_t end_addr = unibus->test_sizer(arbitration_mode) - 2; // well, may be invalid + uint32_t end_addr = unibus->test_sizer() - 2; // well, may be invalid printf( "Testing %06o..%06o linear with \"address\" data pattern (stop with ^C) ...\n", 0, end_addr); - unibus->test_mem(arbitration_mode, 0, end_addr, 1); + unibus->test_mem(0, end_addr, 1); } else if (!strcasecmp(s_opcode, "ta") && n_fields == 3) { uint32_t start_addr, end_addr; parse_addr18(s_param[0], &start_addr); parse_addr18(s_param[1], &end_addr); - uint32_t last_addr = unibus->test_sizer(arbitration_mode) - 2; + uint32_t last_addr = unibus->test_sizer() - 2; if (end_addr > last_addr) end_addr = last_addr; // trunc to memory size printf( "Testing %06o..%06o linear with \"address\" data pattern (stop with ^C) ...\n", start_addr, end_addr); - unibus->test_mem(arbitration_mode, start_addr, end_addr, 1); + unibus->test_mem(start_addr, end_addr, 1); } else if (!strcasecmp(s_opcode, "tr") && n_fields == 1) { - uint32_t end_addr = unibus->test_sizer(arbitration_mode) - 2; // well, may be invalid + uint32_t end_addr = unibus->test_sizer() - 2; // well, may be invalid printf("Testing %06o..%06o randomly (stop with ^C) ...\n", 0, end_addr); - unibus->test_mem(arbitration_mode, 0, end_addr, 2); + unibus->test_mem(0, end_addr, 2); } else if (!strcasecmp(s_opcode, "tr") && n_fields == 3) { uint32_t start_addr, end_addr; parse_addr18(s_param[0], &start_addr); parse_addr18(s_param[1], &end_addr); - uint32_t last_addr = unibus->test_sizer(arbitration_mode) - 2; + uint32_t last_addr = unibus->test_sizer() - 2; if (end_addr > last_addr) end_addr = last_addr; // trunc to memory size printf("Testing %06o..%06o randomly (stop with ^C) ...\n", start_addr, end_addr); - unibus->test_mem(arbitration_mode, start_addr, end_addr, 2); + unibus->test_mem(start_addr, end_addr, 2); } else if (!strcasecmp(s_opcode, "e")) { unsigned wordcount = 1; unsigned i; @@ -224,7 +224,7 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr if (wordcount > WORDBUFFER_LEN) wordcount = WORDBUFFER_LEN; } - timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATI, cur_addr, + timeout = !unibus->dma(true, UNIBUS_CONTROL_DATI, cur_addr, wordbuffer, wordcount); for (i = 0; cur_addr <= unibus->dma_request->unibus_end_addr; i++, cur_addr += 2) printf("EXAM %06o -> %06o\n", cur_addr, wordbuffer[i]); @@ -271,7 +271,7 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr parse_word(s_param[0], &wordbuffer[0]); wordcount = 1; } - timeout = !unibus->dma(arbitration_mode, true, UNIBUS_CONTROL_DATO, cur_addr, + timeout = !unibus->dma(true, UNIBUS_CONTROL_DATO, cur_addr, wordbuffer, wordcount); for (i = 0; cur_addr <= unibus->dma_request->unibus_end_addr; i++, cur_addr += 2) printf("DEPOSIT %06o <- %06o\n", cur_addr, wordbuffer[i]); @@ -340,14 +340,14 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr membuffer->get_addr_range(&startaddr, &endaddr); printf("Loaded %u words, writing UNIBUS memory[%06o:%06o].\n", wordcount, startaddr, endaddr); - unibus->mem_write(arbitration_mode, membuffer->data.words, startaddr, endaddr, + unibus->mem_write(membuffer->data.words, startaddr, endaddr, &timeout); } } else if (!strcasecmp(s_opcode, "s") && (n_fields == 2)) { bool timeout; - uint32_t end_addr = unibus->test_sizer(arbitration_mode) - 2; + uint32_t end_addr = unibus->test_sizer() - 2; printf("Reading UNIBUS memory[0:%06o] with DMA.\n", end_addr); - unibus->mem_read(arbitration_mode, membuffer->data.words, 0, end_addr, &timeout); + unibus->mem_read(membuffer->data.words, 0, end_addr, &timeout); printf("Saving to file %s\n", s_param[0]); membuffer->save_binary(s_param[0], end_addr + 2); } else if (!strcasecmp(s_opcode, "dbg") && n_fields == 2) { @@ -364,7 +364,7 @@ void application_c::menu_masterslave(enum unibus_c::arbitration_mode_enum arbitr } } - if (arbitration_mode == unibus_c::ARBITRATION_MODE_CLIENT && active) { + if (with_CPU && active) { printf("***\n"); printf("*** Stopping UNIBUS logic on PRU\n"); printf("***\n"); diff --git a/10.03_app_demo/2_src/menus.cpp b/10.03_app_demo/2_src/menus.cpp index 68c8802..62dc3fd 100644 --- a/10.03_app_demo/2_src/menus.cpp +++ b/10.03_app_demo/2_src/menus.cpp @@ -46,38 +46,36 @@ using namespace std; // octal, or '' bool application_c::parse_word(char *txt, uint16_t *word) { - *word = 0 ; + *word = 0; if (!txt || *txt == 0) - return false ; - + return false; + if (*txt == '\'') { - txt++ ; + txt++; if (*txt) - *word = *txt ; // ASCII code of first char after '' + *word = *txt; // ASCII code of first char after '' } else *word = strtol(txt, NULL, 8); // octal literal - return true ; + return true; } // octal, trunc to 18 bit bool application_c::parse_addr18(char *txt, uint32_t *addr) { - *addr = strtol(txt, NULL, 8) ; + *addr = strtol(txt, NULL, 8); if (*addr > 0777777) { - *addr = 0777777 ; - return false ; + *addr = 0777777; + return false; } - return true ; + return true; } - - bool application_c::parse_level(char *txt, uint8_t *level) { *level = strtol(txt, NULL, 8); if (*level < 4 || *level > 7) { printf("Illegal interrupt level %u, must be 4..7.\n", *level); return false; } - return true; + return true; } bool application_c::parse_vector(char *txt, uint16_t max_vector, uint16_t *vector) { @@ -90,23 +88,26 @@ bool application_c::parse_vector(char *txt, uint16_t max_vector, uint16_t *vecto printf("Illegal interrupt vector %06o, must be multiple of 4.\n", *vector); return false; } - return true; + return true; } bool application_c::parse_slot(char *txt, uint8_t *priority_slot) { *priority_slot = strtol(txt, NULL, 10); - if (*priority_slot <= 0 || *priority_slot > 31) { + if (*priority_slot <= 0 || *priority_slot > 31) { printf("Illegal priority slot %u, must be 1..31.\n", *priority_slot); return false; } - return true; + return true; } - -void application_c::print_arbitration_info( - enum unibus_c::arbitration_mode_enum arbitration_mode, const char *indent) { - switch (arbitration_mode) { - case unibus_c::ARBITRATION_MODE_NONE: +void application_c::print_arbitration_info(const char *indent) { + if (unibus->get_arbitrator_active()) { + printf("%s\"UniBone devcies are clients to PDP-11 CPU doing NPR/INTR Arbitrator\n", + indent); + printf("%s(CPU active, console processor inactive).\n", indent); + printf("%sCPU is physical or emulated.\n", indent); + printf("%sMemory access as Bus Master with NPR/NPG/SACK handshake.\n", indent); + } else { printf( "%s\"BR/BG and NPR/NPG Arbitration INACTIVE\": Expects no PDP-11 CPU doing NPR/INTR arbitration\n", indent); @@ -114,19 +115,6 @@ void application_c::print_arbitration_info( printf("%sOnly UNIBUS data transfers can be tested.\n", indent); printf("%sUnconditional memory access as Bus Master without NPR/NPG/SACK handshake.\n", indent); - break; - case unibus_c::ARBITRATION_MODE_CLIENT: - printf("%s\"UniBone is client to PDP-11 CPU doing NPR/INTR Arbitrator\n", indent); - printf("%s(CPU active, console processor inactive).\n", indent); - printf("%sMemory access as Bus Master with NPR/NPG/SACK handshake.\n", indent); - break; - case unibus_c::ARBITRATION_MODE_MASTER: - printf("%s\"UniBone is active Arbitrator for NPR/INTR Arbitrator\n", indent); - printf("%s\"Expects no physical PDP-11 CPU doing NPR/INTR arbitration\n", indent); - printf("%s(CPU not plugged in, NO console processor active).\n", indent); - break; - default: - FATAL("Illegal arbitration mode"); } } @@ -154,14 +142,14 @@ char *application_c::getchoice(void) { // scan UNIBUS address range and emulate missing memory // result: false, if nothing emulated -bool application_c::emulate_memory(enum unibus_c::arbitration_mode_enum arbitration_mode) { +bool application_c::emulate_memory() { bool result = false; unsigned first_invalid_addr; printf("Disable memory emulation, size physical memory ...\n"); emulated_memory_start_addr = 0xffffffff; emulated_memory_end_addr = 0; // start > end: disable ddrmem->set_range(emulated_memory_start_addr, emulated_memory_end_addr); - first_invalid_addr = unibus->test_sizer(arbitration_mode); + first_invalid_addr = unibus->test_sizer(); if (first_invalid_addr >= 0760000) printf("Found physical memory in full range 0..0757776, no emulation necessary!\n"); else { @@ -325,7 +313,7 @@ void application_c::menu_main(void) { } else if (!strcasecmp(opcode, "us")) { menu_unibus_signals(); } else if (!strcasecmp(opcode, "tm")) { - menu_masterslave(unibus_c::ARBITRATION_MODE_NONE); + menu_masterslave(/*with_CPU*/false); } else if (!strcasecmp(opcode, "ts")) { menu_ddrmem_slave_only(); } else if (!strcasecmp(opcode, "ti")) { @@ -337,7 +325,7 @@ void application_c::menu_main(void) { } else if (!strcasecmp(opcode, "de")) { menu_device_exercisers(); } else if (!strcasecmp(opcode, "m")) { - menu_masterslave(unibus_c::ARBITRATION_MODE_CLIENT); + menu_masterslave(/*with_CPU*/true); } else if (!strcasecmp(opcode, "i")) { menu_info(); } diff --git a/10.03_app_demo/5_applications/211bsd.mscp/211BSD_du0_44.sh b/10.03_app_demo/5_applications/211bsd.mscp/211BSD_du0_44.sh index 3560217..3cb644a 100644 --- a/10.03_app_demo/5_applications/211bsd.mscp/211BSD_du0_44.sh +++ b/10.03_app_demo/5_applications/211bsd.mscp/211BSD_du0_44.sh @@ -1,4 +1,4 @@ # start RT11 5.5 with "demo" application cd ~/10.03_app_demo/5_applications/211bsd.mscp -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile 2.11BSD_du_44.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile 2.11BSD_du_44.cmd diff --git a/10.03_app_demo/5_applications/211bsd.mscp/du.lst b/10.03_app_demo/5_applications/211bsd.mscp/du.lst index 615cee3..99a2256 100644 --- a/10.03_app_demo/5_applications/211bsd.mscp/du.lst +++ b/10.03_app_demo/5_applications/211bsd.mscp/du.lst @@ -22,92 +22,103 @@ 22 000002 mssa =+2 ; SA register 23 24 .asect - 25 010000 .=10000 ; arbitrary position > 3000 - 26 - 27 ; -------------------------------------------------- - 28 001004 rpkt =1004 ; rpkt structure - 29 001070 cpkt =1070 ; cpkt structure - 30 001200 comm =1200 ; comm structure - 31 ;comm =2404 ; comm structure (at 'blt .+12') - 32 - 33 ; register usage: - 34 ; r0: unit number 0..3 - 35 ; r1: MSCP csrbase - 36 ; r2: moving buffer pointer - 37 ; r3: moving buffer pointer - 38 ; r5: init mask - 39 - 40 ; 4 unit numbers => 4 entry addresses - 41 start0: - 42 010000 012700 000000 mov #0,r0 - 43 010004 000413 br duNr - 44 010006 000240 nop - 45 start1: - 46 010010 012700 000001 mov #1,r0 - 47 010014 000407 br duNr - 48 010016 000240 nop - 49 start2: - 50 010020 012700 000002 mov #2,r0 - 51 010024 000403 br duNr - 52 010026 000240 nop - 53 start3: - 54 010030 012700 000003 mov #3,r0 - 55 - 56 ; retry entry - 57 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit - 58 - 59 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr - 60 010042 012705 004000 mov #4000,r5 ; S1 state bitmask - 61 010046 012703 010166 mov #mscpdt,r3 ; point to data - 62 - 63 ; write 4 init words, with r5 mask from 4000 to 40000 - 64 010052 005711 3$: tst (r1) ; error bit set ? - 65 010054 100767 bmi duNr ; yes, fail back to begin to retry - 66 010056 031105 bit (r1),r5 ; step bit set ? - 67 010060 001774 beq 3$ ; not yet, wait loop - 68 010062 012311 mov (r3)+,(r1) ; yes, send next init data - 69 010064 006305 asl r5 ; next mask - 70 010066 100371 bpl 3$ ; s4 done? br if not yet - 71 - 72 010070 005002 4$: clr r2 ; set bufptr to 0 - 73 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] - 74 010074 020227 001200 cmp r2,#comm ; check for end of buffer - 75 010100 001374 bne 5$ ; loop if not done - 76 - 77 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 - 78 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command - 79 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) - 80 010116 010037 001074 mov r0,@#cpkt+4 ; set unit - 81 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr - 82 010126 010522 mov r5,(r2)+ ; rq own bit15 - 83 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr - 84 010134 010522 mov r5,(r2)+ ; cq own bit15 - 85 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) - 86 - 87 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? - 88 010146 100775 bmi 6$ ; loop if not done - 89 - 90 010150 105737 001016 tstb @#rpkt+12 ; check for error ? - 91 010154 001327 bne duNr ; yup, fail back to begin to retry - 92 - 93 010156 105723 tstb (r3)+ ; check end of table ? - 94 010160 001743 beq 4$ ; br if not yet - 95 - 96 010162 005041 clr -(r1) ; init controller (write IP) - 97 010164 005007 clr pc ; jmp to bootstrap at zero - 98 - 99 ; MSCP init and command data - 100 ; pointed to by r3 - 101 mscpdt: - 102 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector - 103 010170 001200 .word comm ; S2: 002404 = ringbase lo addr - 104 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr - 105 010174 000001 .word 000001 ; S4: 000001 = go bit - 106 ; - 107 ; MSCP command data - 108 ; - 109 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) - 110 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) - 111 - 112 .end - 112 + 25 ; ---- Simple boot drive 0 from 0 + 26 000000 . = 0 + 27 000000 000137 010000 jmp @#start0 + 28 + 29 ; ---- Reboot drive 0 on power event + 30 000024 . = 24 ; Power ON/OFF + 31 000024 010000 .word start0 ; PC + 32 000026 000340 .word 340 ; PSW priority level 7 + 33 + 34 + 35 ; ----- Main boot addresses + 36 010000 .=10000 ; arbitrary position > 3000 + 37 + 38 + 39 001004 rpkt =1004 ; rpkt structure + 40 001070 cpkt =1070 ; cpkt structure + 41 001200 comm =1200 ; comm structure + 42 ;comm =2404 ; comm structure (at 'blt .+12') + 43 + 44 ; register usage: + 45 ; r0: unit number 0..3 + 46 ; r1: MSCP csrbase + 47 ; r2: moving buffer pointer + 48 ; r3: moving buffer pointer + 49 ; r5: init mask + 50 + 51 ; 4 unit numbers => 4 entry addresses + 52 start0: + 53 010000 012700 000000 mov #0,r0 + 54 010004 000413 br duNr + 55 010006 000240 nop + 56 start1: + 57 010010 012700 000001 mov #1,r0 + 58 010014 000407 br duNr + 59 010016 000240 nop + 60 start2: + 61 010020 012700 000002 mov #2,r0 + 62 010024 000403 br duNr + 63 010026 000240 nop + 64 start3: + 65 010030 012700 000003 mov #3,r0 + 66 + 67 ; retry entry + 68 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit + 69 + 70 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr + 71 010042 012705 004000 mov #4000,r5 ; S1 state bitmask + 72 010046 012703 010166 mov #mscpdt,r3 ; point to data + 73 + 74 ; write 4 init words, with r5 mask from 4000 to 40000 + 75 010052 005711 3$: tst (r1) ; error bit set ? + 76 010054 100767 bmi duNr ; yes, fail back to begin to retry + 77 010056 031105 bit (r1),r5 ; step bit set ? + 78 010060 001774 beq 3$ ; not yet, wait loop + 79 010062 012311 mov (r3)+,(r1) ; yes, send next init data + 80 010064 006305 asl r5 ; next mask + 81 010066 100371 bpl 3$ ; s4 done? br if not yet + 82 + 83 010070 005002 4$: clr r2 ; set bufptr to 0 + 84 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] + 85 010074 020227 001200 cmp r2,#comm ; check for end of buffer + 86 010100 001374 bne 5$ ; loop if not done + 87 + 88 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 + 89 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command + 90 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) + 91 010116 010037 001074 mov r0,@#cpkt+4 ; set unit + 92 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr + 93 010126 010522 mov r5,(r2)+ ; rq own bit15 + 94 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr + 95 010134 010522 mov r5,(r2)+ ; cq own bit15 + 96 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) + 97 + 98 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? + 99 010146 100775 bmi 6$ ; loop if not done + 100 + 101 010150 105737 001016 tstb @#rpkt+12 ; check for error ? + 102 010154 001327 bne duNr ; yup, fail back to begin to retry + 103 + 104 010156 105723 tstb (r3)+ ; check end of table ? + 105 010160 001743 beq 4$ ; br if not yet + 106 + 107 010162 005041 clr -(r1) ; init controller (write IP) + 108 010164 005007 clr pc ; jmp to bootstrap at zero + 109 + 110 ; MSCP init and command data + 111 ; pointed to by r3 + 112 mscpdt: + 113 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector + 114 010170 001200 .word comm ; S2: 002404 = ringbase lo addr + 115 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr + 116 010174 000001 .word 000001 ; S4: 000001 = go bit + 117 ; + 118 ; MSCP command data + 119 ; + 120 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) + 121 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) + 122 + 123 .end + 123 diff --git a/10.03_app_demo/5_applications/mini-unix.rk05/dk.lst b/10.03_app_demo/5_applications/mini-unix.rk05/dk.lst index 1eaab3c..c51cbe4 100644 --- a/10.03_app_demo/5_applications/mini-unix.rk05/dk.lst +++ b/10.03_app_demo/5_applications/mini-unix.rk05/dk.lst @@ -14,71 +14,80 @@ 14 000002 xxwc =rkwc ; common word count offset 15 16 .asect - 17 010000 .=10000 - 18 - 19 ; -------------------------------------------------- + 17 ; ---- Simple boot drive 0 from 0 + 18 000000 . = 0 + 19 000000 000137 010000 jmp @#start0 20 - 21 start: - 22 ; 8 unit numbers => 8 entry addresses - 23 start0: - 24 010000 012700 000000 mov #0,r0 - 25 010004 000435 br dknr - 26 010006 000240 nop - 27 start1: - 28 010010 012700 000001 mov #1,r0 - 29 010014 000431 br dknr - 30 010016 000240 nop - 31 start2: - 32 010020 012700 000002 mov #2,r0 - 33 010024 000425 br dknr - 34 010026 000240 nop - 35 start3: - 36 010030 012700 000003 mov #3,r0 - 37 010034 000421 br dknr - 38 010036 000240 nop - 39 start4: - 40 010040 012700 000004 mov #4,r0 - 41 010044 000415 br dknr - 42 010046 000240 nop - 43 start5: - 44 010050 012700 000005 mov #5,r0 - 45 010054 000411 br dknr - 46 010056 000240 nop - 47 start6: - 48 010060 012700 000006 mov #6,r0 - 49 010064 000405 br dknr - 50 010066 000240 nop - 51 start7: - 52 010070 012700 000007 mov #7,r0 - 53 010074 000401 br dknr - 54 010076 000240 nop - 55 - 56 - 57 dknr: - 58 010100 012701 177404 mov #rkcsr+4,r1 ; boot std csr, unit - 59 - 60 010104 010003 mov r0,r3 ; get unit number - 61 010106 000241 clc ; C=0 for ror - 62 010110 006003 ror r3 ; shift into 15:12 - 63 010112 006003 ror r3 ; - 64 010114 006003 ror r3 ; - 65 010116 006003 ror r3 ; - 66 010120 010361 000006 mov r3,rkda(r1) ; unit number, sector 0 to disk addr - 67 - 68 010124 012761 177000 000002 mov #-512.,xxwc(r1) ; set word count - 69 010132 052703 000005 bis #5,r3 ; command READ+GO - 70 010136 010311 mov r3,(r1) ; execute - 71 010140 105711 2$: tstb (r1) ; test ready - 72 010142 100376 bpl 2$ ; loop - 73 - 74 010144 005711 tst (r1) ; check error - 75 010146 100002 bpl 3$ ; br if no error + 21 ; ---- Reboot drive 0 on power event + 22 000024 . = 24 ; Power ON/OFF + 23 000024 010000 .word start0 ; PC + 24 000026 000340 .word 340 ; PSW priority level 7 + 25 + 26 + 27 ; ----- Main boot addresses + 28 010000 .=10000 ; arbitrary position > 3000 + 29 + 30 start: + 31 ; 8 unit numbers => 8 entry addresses + 32 start0: + 33 010000 012700 000000 mov #0,r0 + 34 010004 000435 br dknr + 35 010006 000240 nop + 36 start1: + 37 010010 012700 000001 mov #1,r0 + 38 010014 000431 br dknr + 39 010016 000240 nop + 40 start2: + 41 010020 012700 000002 mov #2,r0 + 42 010024 000425 br dknr + 43 010026 000240 nop + 44 start3: + 45 010030 012700 000003 mov #3,r0 + 46 010034 000421 br dknr + 47 010036 000240 nop + 48 start4: + 49 010040 012700 000004 mov #4,r0 + 50 010044 000415 br dknr + 51 010046 000240 nop + 52 start5: + 53 010050 012700 000005 mov #5,r0 + 54 010054 000411 br dknr + 55 010056 000240 nop + 56 start6: + 57 010060 012700 000006 mov #6,r0 + 58 010064 000405 br dknr + 59 010066 000240 nop + 60 start7: + 61 010070 012700 000007 mov #7,r0 + 62 010074 000401 br dknr + 63 010076 000240 nop + 64 + 65 + 66 dknr: + 67 010100 012701 177404 mov #rkcsr+4,r1 ; boot std csr, unit + 68 + 69 010104 010003 mov r0,r3 ; get unit number + 70 010106 000241 clc ; C=0 for ror + 71 010110 006003 ror r3 ; shift into 15:12 + 72 010112 006003 ror r3 ; + 73 010114 006003 ror r3 ; + 74 010116 006003 ror r3 ; + 75 010120 010361 000006 mov r3,rkda(r1) ; unit number, sector 0 to disk addr 76 - 77 010150 000005 reset ; reset the world - 78 010152 000752 br dknr ; and retry - 79 - 80 010154 042711 000377 3$: bic #377,(r1) ; nop command - 81 010160 005007 clr pc ; jump to loaded boot sector + 77 010124 012761 177000 000002 mov #-512.,xxwc(r1) ; set word count + 78 010132 052703 000005 bis #5,r3 ; command READ+GO + 79 010136 010311 mov r3,(r1) ; execute + 80 010140 105711 2$: tstb (r1) ; test ready + 81 010142 100376 bpl 2$ ; loop 82 - 83 .end - 83 + 83 010144 005711 tst (r1) ; check error + 84 010146 100002 bpl 3$ ; br if no error + 85 + 86 010150 000005 reset ; reset the world + 87 010152 000752 br dknr ; and retry + 88 + 89 010154 042711 000377 3$: bic #377,(r1) ; nop command + 90 010160 005007 clr pc ; jump to loaded boot sector + 91 + 92 .end + 92 diff --git a/10.03_app_demo/5_applications/mini-unix.rk05/mini-unix_dk0_05.sh b/10.03_app_demo/5_applications/mini-unix.rk05/mini-unix_dk0_05.sh index f87abe0..9cb1ef7 100644 --- a/10.03_app_demo/5_applications/mini-unix.rk05/mini-unix_dk0_05.sh +++ b/10.03_app_demo/5_applications/mini-unix.rk05/mini-unix_dk0_05.sh @@ -1,4 +1,4 @@ # start Mini-Unix rom RK05 with "demo" application cd ~/10.03_app_demo/5_applications/mini-unix.rk05 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile mini-unix_dk_05.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile mini-unix_dk_05.cmd diff --git a/10.03_app_demo/5_applications/rsx11.mscp/du.lst b/10.03_app_demo/5_applications/rsx11.mscp/du.lst index 615cee3..99a2256 100644 --- a/10.03_app_demo/5_applications/rsx11.mscp/du.lst +++ b/10.03_app_demo/5_applications/rsx11.mscp/du.lst @@ -22,92 +22,103 @@ 22 000002 mssa =+2 ; SA register 23 24 .asect - 25 010000 .=10000 ; arbitrary position > 3000 - 26 - 27 ; -------------------------------------------------- - 28 001004 rpkt =1004 ; rpkt structure - 29 001070 cpkt =1070 ; cpkt structure - 30 001200 comm =1200 ; comm structure - 31 ;comm =2404 ; comm structure (at 'blt .+12') - 32 - 33 ; register usage: - 34 ; r0: unit number 0..3 - 35 ; r1: MSCP csrbase - 36 ; r2: moving buffer pointer - 37 ; r3: moving buffer pointer - 38 ; r5: init mask - 39 - 40 ; 4 unit numbers => 4 entry addresses - 41 start0: - 42 010000 012700 000000 mov #0,r0 - 43 010004 000413 br duNr - 44 010006 000240 nop - 45 start1: - 46 010010 012700 000001 mov #1,r0 - 47 010014 000407 br duNr - 48 010016 000240 nop - 49 start2: - 50 010020 012700 000002 mov #2,r0 - 51 010024 000403 br duNr - 52 010026 000240 nop - 53 start3: - 54 010030 012700 000003 mov #3,r0 - 55 - 56 ; retry entry - 57 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit - 58 - 59 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr - 60 010042 012705 004000 mov #4000,r5 ; S1 state bitmask - 61 010046 012703 010166 mov #mscpdt,r3 ; point to data - 62 - 63 ; write 4 init words, with r5 mask from 4000 to 40000 - 64 010052 005711 3$: tst (r1) ; error bit set ? - 65 010054 100767 bmi duNr ; yes, fail back to begin to retry - 66 010056 031105 bit (r1),r5 ; step bit set ? - 67 010060 001774 beq 3$ ; not yet, wait loop - 68 010062 012311 mov (r3)+,(r1) ; yes, send next init data - 69 010064 006305 asl r5 ; next mask - 70 010066 100371 bpl 3$ ; s4 done? br if not yet - 71 - 72 010070 005002 4$: clr r2 ; set bufptr to 0 - 73 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] - 74 010074 020227 001200 cmp r2,#comm ; check for end of buffer - 75 010100 001374 bne 5$ ; loop if not done - 76 - 77 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 - 78 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command - 79 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) - 80 010116 010037 001074 mov r0,@#cpkt+4 ; set unit - 81 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr - 82 010126 010522 mov r5,(r2)+ ; rq own bit15 - 83 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr - 84 010134 010522 mov r5,(r2)+ ; cq own bit15 - 85 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) - 86 - 87 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? - 88 010146 100775 bmi 6$ ; loop if not done - 89 - 90 010150 105737 001016 tstb @#rpkt+12 ; check for error ? - 91 010154 001327 bne duNr ; yup, fail back to begin to retry - 92 - 93 010156 105723 tstb (r3)+ ; check end of table ? - 94 010160 001743 beq 4$ ; br if not yet - 95 - 96 010162 005041 clr -(r1) ; init controller (write IP) - 97 010164 005007 clr pc ; jmp to bootstrap at zero - 98 - 99 ; MSCP init and command data - 100 ; pointed to by r3 - 101 mscpdt: - 102 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector - 103 010170 001200 .word comm ; S2: 002404 = ringbase lo addr - 104 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr - 105 010174 000001 .word 000001 ; S4: 000001 = go bit - 106 ; - 107 ; MSCP command data - 108 ; - 109 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) - 110 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) - 111 - 112 .end - 112 + 25 ; ---- Simple boot drive 0 from 0 + 26 000000 . = 0 + 27 000000 000137 010000 jmp @#start0 + 28 + 29 ; ---- Reboot drive 0 on power event + 30 000024 . = 24 ; Power ON/OFF + 31 000024 010000 .word start0 ; PC + 32 000026 000340 .word 340 ; PSW priority level 7 + 33 + 34 + 35 ; ----- Main boot addresses + 36 010000 .=10000 ; arbitrary position > 3000 + 37 + 38 + 39 001004 rpkt =1004 ; rpkt structure + 40 001070 cpkt =1070 ; cpkt structure + 41 001200 comm =1200 ; comm structure + 42 ;comm =2404 ; comm structure (at 'blt .+12') + 43 + 44 ; register usage: + 45 ; r0: unit number 0..3 + 46 ; r1: MSCP csrbase + 47 ; r2: moving buffer pointer + 48 ; r3: moving buffer pointer + 49 ; r5: init mask + 50 + 51 ; 4 unit numbers => 4 entry addresses + 52 start0: + 53 010000 012700 000000 mov #0,r0 + 54 010004 000413 br duNr + 55 010006 000240 nop + 56 start1: + 57 010010 012700 000001 mov #1,r0 + 58 010014 000407 br duNr + 59 010016 000240 nop + 60 start2: + 61 010020 012700 000002 mov #2,r0 + 62 010024 000403 br duNr + 63 010026 000240 nop + 64 start3: + 65 010030 012700 000003 mov #3,r0 + 66 + 67 ; retry entry + 68 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit + 69 + 70 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr + 71 010042 012705 004000 mov #4000,r5 ; S1 state bitmask + 72 010046 012703 010166 mov #mscpdt,r3 ; point to data + 73 + 74 ; write 4 init words, with r5 mask from 4000 to 40000 + 75 010052 005711 3$: tst (r1) ; error bit set ? + 76 010054 100767 bmi duNr ; yes, fail back to begin to retry + 77 010056 031105 bit (r1),r5 ; step bit set ? + 78 010060 001774 beq 3$ ; not yet, wait loop + 79 010062 012311 mov (r3)+,(r1) ; yes, send next init data + 80 010064 006305 asl r5 ; next mask + 81 010066 100371 bpl 3$ ; s4 done? br if not yet + 82 + 83 010070 005002 4$: clr r2 ; set bufptr to 0 + 84 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] + 85 010074 020227 001200 cmp r2,#comm ; check for end of buffer + 86 010100 001374 bne 5$ ; loop if not done + 87 + 88 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 + 89 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command + 90 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) + 91 010116 010037 001074 mov r0,@#cpkt+4 ; set unit + 92 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr + 93 010126 010522 mov r5,(r2)+ ; rq own bit15 + 94 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr + 95 010134 010522 mov r5,(r2)+ ; cq own bit15 + 96 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) + 97 + 98 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? + 99 010146 100775 bmi 6$ ; loop if not done + 100 + 101 010150 105737 001016 tstb @#rpkt+12 ; check for error ? + 102 010154 001327 bne duNr ; yup, fail back to begin to retry + 103 + 104 010156 105723 tstb (r3)+ ; check end of table ? + 105 010160 001743 beq 4$ ; br if not yet + 106 + 107 010162 005041 clr -(r1) ; init controller (write IP) + 108 010164 005007 clr pc ; jmp to bootstrap at zero + 109 + 110 ; MSCP init and command data + 111 ; pointed to by r3 + 112 mscpdt: + 113 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector + 114 010170 001200 .word comm ; S2: 002404 = ringbase lo addr + 115 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr + 116 010174 000001 .word 000001 ; S4: 000001 = go bit + 117 ; + 118 ; MSCP command data + 119 ; + 120 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) + 121 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) + 122 + 123 .end + 123 diff --git a/10.03_app_demo/5_applications/rsx11.rl02/dl.lst b/10.03_app_demo/5_applications/rsx11.rl02/dl.lst index 4bcbdf6..f3a7d96 100644 --- a/10.03_app_demo/5_applications/rsx11.rl02/dl.lst +++ b/10.03_app_demo/5_applications/rsx11.rl02/dl.lst @@ -1,6 +1,6 @@ 1 .title M9312 'DL' BOOT prom for RL11 controller 2 - 3 ; This source code is a modified copyof the DEC M9312 23-751A9 boot PROM. + 3 ; This source code is a modified copy of the DEC M9312 23-751A9 boot PROM. 4 ; 5 ; This boot PROM is for the RL11 controller with RL01/RL02 drives. 6 ; @@ -20,73 +20,82 @@ 20 000014 cmrdda =6*2 ; read data 21 22 .asect - 23 010000 .=10000 ; arbitrary position > 3000 - 24 - 25 ; -------------------------------------------------- + 23 ; ---- Simple boot drive 0 from 0 + 24 000000 . = 0 + 25 000000 000137 010000 jmp @#start0 26 - 27 start: - 28 ; 4 unit numbers => 4 entry addresses - 29 start0: - 30 010000 012700 000000 mov #0,r0 - 31 010004 000413 br dlnr - 32 010006 000240 nop - 33 start1: - 34 010010 012700 000001 mov #1,r0 - 35 010014 000407 br dlnr - 36 010016 000240 nop - 37 start2: - 38 010020 012700 000002 mov #2,r0 - 39 010024 000403 br dlnr - 40 010026 000240 nop - 41 start3: - 42 010030 012700 000003 mov #3,r0 - 43 - 44 dlnr: - 45 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit - 46 - 47 ; -------------------------------------------------- - 48 - 49 010040 010003 mov r0,r3 ; save unit number - 50 010042 000303 swab r3 ; unit number in upper byte - 51 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 27 ; ---- Reboot drive 0 on power event + 28 000024 . = 24 ; Power ON/OFF + 29 000024 010000 .word start0 ; PC + 30 000026 000340 .word 340 ; PSW priority level 7 + 31 + 32 + 33 ; ----- Main boot addresses + 34 010000 .=10000 ; arbitrary position > 3000 + 35 + 36 start: + 37 ; 4 unit numbers => 4 entry addresses + 38 start0: + 39 010000 012700 000000 mov #0,r0 + 40 010004 000413 br dlnr + 41 010006 000240 nop + 42 start1: + 43 010010 012700 000001 mov #1,r0 + 44 010014 000407 br dlnr + 45 010016 000240 nop + 46 start2: + 47 010020 012700 000002 mov #2,r0 + 48 010024 000403 br dlnr + 49 010026 000240 nop + 50 start3: + 51 010030 012700 000003 mov #3,r0 52 - 53 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus - 54 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) - 55 010060 010311 mov r3,(r1) ; execute - 56 010062 105711 1$: tstb (r1) ; test for ready - 57 010064 100376 bpl 1$ ; wait - 58 - 59 010066 105003 clrb r3 ; unit number in upper byte - 60 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd - 61 010074 010311 mov r3,(r1) ; execute - 62 010076 105711 2$: tstb (r1) ; test for ready - 63 010100 100376 bpl 2$ ; wait - 64 - 65 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector - 66 010106 042702 000077 bic #77,r2 ; set sector to zero - 67 010112 005202 inc r2 ; set head 0, seek to cyl 0 - 68 010114 010261 000004 mov r2,rlda(r1) ; into da for seek - 69 010120 105003 clrb r3 ; unit number in upper byte - 70 010122 052703 000006 bis #cmseek,r3 ; seek cmd - 71 010126 010311 mov r3,(r1) ; execute - 72 010130 105711 3$: tstb (r1) ; test for ready - 73 010132 100376 bpl 3$ ; wait - 74 - 75 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 - 76 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count - 77 010146 105003 clrb r3 ; unit number in upper byte - 78 010150 052703 000014 bis #cmrdda,r3 ; read data cmd - 79 010154 010311 mov r3,(r1) ; execute - 80 010156 105711 4$: tstb (r1) ; test for ready - 81 010160 100376 bpl 4$ ; wait - 82 - 83 010162 005711 tst (r1) ; test for error - 84 010164 100002 bpl 5$ ; br if ok - 85 010166 000005 reset ; ERROR - reset the world - 86 010170 000721 br dlnr ; retry. r0 unchanged - 87 - 88 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd - 89 010176 005007 clr pc ; jump to bootstrap at zero - 90 - 91 .end + 53 dlnr: + 54 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit + 55 + 56 ; -------------------------------------------------- + 57 + 58 010040 010003 mov r0,r3 ; save unit number + 59 010042 000303 swab r3 ; unit number in upper byte + 60 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 61 + 62 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus + 63 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) + 64 010060 010311 mov r3,(r1) ; execute + 65 010062 105711 1$: tstb (r1) ; test for ready + 66 010064 100376 bpl 1$ ; wait + 67 + 68 010066 105003 clrb r3 ; unit number in upper byte + 69 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd + 70 010074 010311 mov r3,(r1) ; execute + 71 010076 105711 2$: tstb (r1) ; test for ready + 72 010100 100376 bpl 2$ ; wait + 73 + 74 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector + 75 010106 042702 000077 bic #77,r2 ; set sector to zero + 76 010112 005202 inc r2 ; set head 0, seek to cyl 0 + 77 010114 010261 000004 mov r2,rlda(r1) ; into da for seek + 78 010120 105003 clrb r3 ; unit number in upper byte + 79 010122 052703 000006 bis #cmseek,r3 ; seek cmd + 80 010126 010311 mov r3,(r1) ; execute + 81 010130 105711 3$: tstb (r1) ; test for ready + 82 010132 100376 bpl 3$ ; wait + 83 + 84 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 + 85 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count + 86 010146 105003 clrb r3 ; unit number in upper byte + 87 010150 052703 000014 bis #cmrdda,r3 ; read data cmd + 88 010154 010311 mov r3,(r1) ; execute + 89 010156 105711 4$: tstb (r1) ; test for ready + 90 010160 100376 bpl 4$ ; wait 91 + 92 010162 005711 tst (r1) ; test for error + 93 010164 100002 bpl 5$ ; br if ok + 94 010166 000005 reset ; ERROR - reset the world + 95 010170 000721 br dlnr ; retry. r0 unchanged + 96 + 97 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd + 98 010176 005007 clr pc ; jump to bootstrap at zero + 99 + 100 .end + 100 diff --git a/10.03_app_demo/5_applications/rsx11.rl02/rsx11m4.1_dl0_34.sh b/10.03_app_demo/5_applications/rsx11.rl02/rsx11m4.1_dl0_34.sh index b388485..60359d2 100644 --- a/10.03_app_demo/5_applications/rsx11.rl02/rsx11m4.1_dl0_34.sh +++ b/10.03_app_demo/5_applications/rsx11.rl02/rsx11m4.1_dl0_34.sh @@ -1,4 +1,4 @@ # start RSX4.1 with "demo" application cd ~/10.03_app_demo/5_applications/rsx11.rl02 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile rsx11m4.1_dl_34.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile rsx11m4.1_dl_34.cmd diff --git a/10.03_app_demo/5_applications/rt11.mscp/du.lst b/10.03_app_demo/5_applications/rt11.mscp/du.lst index 615cee3..99a2256 100644 --- a/10.03_app_demo/5_applications/rt11.mscp/du.lst +++ b/10.03_app_demo/5_applications/rt11.mscp/du.lst @@ -22,92 +22,103 @@ 22 000002 mssa =+2 ; SA register 23 24 .asect - 25 010000 .=10000 ; arbitrary position > 3000 - 26 - 27 ; -------------------------------------------------- - 28 001004 rpkt =1004 ; rpkt structure - 29 001070 cpkt =1070 ; cpkt structure - 30 001200 comm =1200 ; comm structure - 31 ;comm =2404 ; comm structure (at 'blt .+12') - 32 - 33 ; register usage: - 34 ; r0: unit number 0..3 - 35 ; r1: MSCP csrbase - 36 ; r2: moving buffer pointer - 37 ; r3: moving buffer pointer - 38 ; r5: init mask - 39 - 40 ; 4 unit numbers => 4 entry addresses - 41 start0: - 42 010000 012700 000000 mov #0,r0 - 43 010004 000413 br duNr - 44 010006 000240 nop - 45 start1: - 46 010010 012700 000001 mov #1,r0 - 47 010014 000407 br duNr - 48 010016 000240 nop - 49 start2: - 50 010020 012700 000002 mov #2,r0 - 51 010024 000403 br duNr - 52 010026 000240 nop - 53 start3: - 54 010030 012700 000003 mov #3,r0 - 55 - 56 ; retry entry - 57 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit - 58 - 59 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr - 60 010042 012705 004000 mov #4000,r5 ; S1 state bitmask - 61 010046 012703 010166 mov #mscpdt,r3 ; point to data - 62 - 63 ; write 4 init words, with r5 mask from 4000 to 40000 - 64 010052 005711 3$: tst (r1) ; error bit set ? - 65 010054 100767 bmi duNr ; yes, fail back to begin to retry - 66 010056 031105 bit (r1),r5 ; step bit set ? - 67 010060 001774 beq 3$ ; not yet, wait loop - 68 010062 012311 mov (r3)+,(r1) ; yes, send next init data - 69 010064 006305 asl r5 ; next mask - 70 010066 100371 bpl 3$ ; s4 done? br if not yet - 71 - 72 010070 005002 4$: clr r2 ; set bufptr to 0 - 73 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] - 74 010074 020227 001200 cmp r2,#comm ; check for end of buffer - 75 010100 001374 bne 5$ ; loop if not done - 76 - 77 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 - 78 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command - 79 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) - 80 010116 010037 001074 mov r0,@#cpkt+4 ; set unit - 81 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr - 82 010126 010522 mov r5,(r2)+ ; rq own bit15 - 83 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr - 84 010134 010522 mov r5,(r2)+ ; cq own bit15 - 85 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) - 86 - 87 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? - 88 010146 100775 bmi 6$ ; loop if not done - 89 - 90 010150 105737 001016 tstb @#rpkt+12 ; check for error ? - 91 010154 001327 bne duNr ; yup, fail back to begin to retry - 92 - 93 010156 105723 tstb (r3)+ ; check end of table ? - 94 010160 001743 beq 4$ ; br if not yet - 95 - 96 010162 005041 clr -(r1) ; init controller (write IP) - 97 010164 005007 clr pc ; jmp to bootstrap at zero - 98 - 99 ; MSCP init and command data - 100 ; pointed to by r3 - 101 mscpdt: - 102 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector - 103 010170 001200 .word comm ; S2: 002404 = ringbase lo addr - 104 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr - 105 010174 000001 .word 000001 ; S4: 000001 = go bit - 106 ; - 107 ; MSCP command data - 108 ; - 109 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) - 110 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) - 111 - 112 .end - 112 + 25 ; ---- Simple boot drive 0 from 0 + 26 000000 . = 0 + 27 000000 000137 010000 jmp @#start0 + 28 + 29 ; ---- Reboot drive 0 on power event + 30 000024 . = 24 ; Power ON/OFF + 31 000024 010000 .word start0 ; PC + 32 000026 000340 .word 340 ; PSW priority level 7 + 33 + 34 + 35 ; ----- Main boot addresses + 36 010000 .=10000 ; arbitrary position > 3000 + 37 + 38 + 39 001004 rpkt =1004 ; rpkt structure + 40 001070 cpkt =1070 ; cpkt structure + 41 001200 comm =1200 ; comm structure + 42 ;comm =2404 ; comm structure (at 'blt .+12') + 43 + 44 ; register usage: + 45 ; r0: unit number 0..3 + 46 ; r1: MSCP csrbase + 47 ; r2: moving buffer pointer + 48 ; r3: moving buffer pointer + 49 ; r5: init mask + 50 + 51 ; 4 unit numbers => 4 entry addresses + 52 start0: + 53 010000 012700 000000 mov #0,r0 + 54 010004 000413 br duNr + 55 010006 000240 nop + 56 start1: + 57 010010 012700 000001 mov #1,r0 + 58 010014 000407 br duNr + 59 010016 000240 nop + 60 start2: + 61 010020 012700 000002 mov #2,r0 + 62 010024 000403 br duNr + 63 010026 000240 nop + 64 start3: + 65 010030 012700 000003 mov #3,r0 + 66 + 67 ; retry entry + 68 010034 012701 172150 duNr: mov #mscsr,r1 ; boot std csr, unit + 69 + 70 010040 010021 go: mov r0,(r1)+ ; init controller (write IP), bump ptr + 71 010042 012705 004000 mov #4000,r5 ; S1 state bitmask + 72 010046 012703 010166 mov #mscpdt,r3 ; point to data + 73 + 74 ; write 4 init words, with r5 mask from 4000 to 40000 + 75 010052 005711 3$: tst (r1) ; error bit set ? + 76 010054 100767 bmi duNr ; yes, fail back to begin to retry + 77 010056 031105 bit (r1),r5 ; step bit set ? + 78 010060 001774 beq 3$ ; not yet, wait loop + 79 010062 012311 mov (r3)+,(r1) ; yes, send next init data + 80 010064 006305 asl r5 ; next mask + 81 010066 100371 bpl 3$ ; s4 done? br if not yet + 82 + 83 010070 005002 4$: clr r2 ; set bufptr to 0 + 84 010072 005022 5$: clr (r2)+ ; clear buffer [0..2403] + 85 010074 020227 001200 cmp r2,#comm ; check for end of buffer + 86 010100 001374 bne 5$ ; loop if not done + 87 + 88 010102 010237 001064 mov r2,@#cpkt-4 ; set lnt -- R2=2404 + 89 010106 112337 001100 movb (r3)+,@#cpkt+10 ; set command + 90 010112 111337 001105 movb (r3),@#cpkt+15 ; set bytecnt(hi) + 91 010116 010037 001074 mov r0,@#cpkt+4 ; set unit + 92 010122 012722 001004 mov #rpkt,(r2)+ ; rq desc addr + 93 010126 010522 mov r5,(r2)+ ; rq own bit15 + 94 010130 012722 001070 mov #cpkt,(r2)+ ; cp desc addr + 95 010134 010522 mov r5,(r2)+ ; cq own bit15 + 96 010136 016102 177776 mov -2(r1),r2 ; wake controller (read IP) + 97 + 98 010142 005737 001202 6$: tst @#comm+2 ; rq own controller ? + 99 010146 100775 bmi 6$ ; loop if not done + 100 + 101 010150 105737 001016 tstb @#rpkt+12 ; check for error ? + 102 010154 001327 bne duNr ; yup, fail back to begin to retry + 103 + 104 010156 105723 tstb (r3)+ ; check end of table ? + 105 010160 001743 beq 4$ ; br if not yet + 106 + 107 010162 005041 clr -(r1) ; init controller (write IP) + 108 010164 005007 clr pc ; jmp to bootstrap at zero + 109 + 110 ; MSCP init and command data + 111 ; pointed to by r3 + 112 mscpdt: + 113 010166 100000 .word 100000 ; S1: 100000 = no int, ring size 1, no vector + 114 010170 001200 .word comm ; S2: 002404 = ringbase lo addr + 115 010172 000000 .word 000000 ; S3: 000000 = no purge/poll, ringbase hi addr + 116 010174 000001 .word 000001 ; S4: 000001 = go bit + 117 ; + 118 ; MSCP command data + 119 ; + 120 010176 011 000 .byte 011,000 ; cmd=011(online), bytecnt_hi=000(0) + 121 010200 041 002 .byte 041,002 ; cmd=041(read), bytecnt_hi=002(512) + 122 + 123 .end + 123 diff --git a/10.03_app_demo/5_applications/rt11.mscp/rt11v5.5fb_du0_34.sh b/10.03_app_demo/5_applications/rt11.mscp/rt11v5.5fb_du0_34.sh index 5fa77c0..56da3dd 100644 --- a/10.03_app_demo/5_applications/rt11.mscp/rt11v5.5fb_du0_34.sh +++ b/10.03_app_demo/5_applications/rt11.mscp/rt11v5.5fb_du0_34.sh @@ -1,4 +1,4 @@ # start RT11 5.5 with "demo" application cd ~/10.03_app_demo/5_applications/rt11.mscp -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile rt11v5.5_du_34.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile rt11v5.5_du_34.cmd diff --git a/10.03_app_demo/5_applications/rt11.rl02/dl.lst b/10.03_app_demo/5_applications/rt11.rl02/dl.lst index 4bcbdf6..f3a7d96 100644 --- a/10.03_app_demo/5_applications/rt11.rl02/dl.lst +++ b/10.03_app_demo/5_applications/rt11.rl02/dl.lst @@ -1,6 +1,6 @@ 1 .title M9312 'DL' BOOT prom for RL11 controller 2 - 3 ; This source code is a modified copyof the DEC M9312 23-751A9 boot PROM. + 3 ; This source code is a modified copy of the DEC M9312 23-751A9 boot PROM. 4 ; 5 ; This boot PROM is for the RL11 controller with RL01/RL02 drives. 6 ; @@ -20,73 +20,82 @@ 20 000014 cmrdda =6*2 ; read data 21 22 .asect - 23 010000 .=10000 ; arbitrary position > 3000 - 24 - 25 ; -------------------------------------------------- + 23 ; ---- Simple boot drive 0 from 0 + 24 000000 . = 0 + 25 000000 000137 010000 jmp @#start0 26 - 27 start: - 28 ; 4 unit numbers => 4 entry addresses - 29 start0: - 30 010000 012700 000000 mov #0,r0 - 31 010004 000413 br dlnr - 32 010006 000240 nop - 33 start1: - 34 010010 012700 000001 mov #1,r0 - 35 010014 000407 br dlnr - 36 010016 000240 nop - 37 start2: - 38 010020 012700 000002 mov #2,r0 - 39 010024 000403 br dlnr - 40 010026 000240 nop - 41 start3: - 42 010030 012700 000003 mov #3,r0 - 43 - 44 dlnr: - 45 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit - 46 - 47 ; -------------------------------------------------- - 48 - 49 010040 010003 mov r0,r3 ; save unit number - 50 010042 000303 swab r3 ; unit number in upper byte - 51 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 27 ; ---- Reboot drive 0 on power event + 28 000024 . = 24 ; Power ON/OFF + 29 000024 010000 .word start0 ; PC + 30 000026 000340 .word 340 ; PSW priority level 7 + 31 + 32 + 33 ; ----- Main boot addresses + 34 010000 .=10000 ; arbitrary position > 3000 + 35 + 36 start: + 37 ; 4 unit numbers => 4 entry addresses + 38 start0: + 39 010000 012700 000000 mov #0,r0 + 40 010004 000413 br dlnr + 41 010006 000240 nop + 42 start1: + 43 010010 012700 000001 mov #1,r0 + 44 010014 000407 br dlnr + 45 010016 000240 nop + 46 start2: + 47 010020 012700 000002 mov #2,r0 + 48 010024 000403 br dlnr + 49 010026 000240 nop + 50 start3: + 51 010030 012700 000003 mov #3,r0 52 - 53 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus - 54 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) - 55 010060 010311 mov r3,(r1) ; execute - 56 010062 105711 1$: tstb (r1) ; test for ready - 57 010064 100376 bpl 1$ ; wait - 58 - 59 010066 105003 clrb r3 ; unit number in upper byte - 60 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd - 61 010074 010311 mov r3,(r1) ; execute - 62 010076 105711 2$: tstb (r1) ; test for ready - 63 010100 100376 bpl 2$ ; wait - 64 - 65 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector - 66 010106 042702 000077 bic #77,r2 ; set sector to zero - 67 010112 005202 inc r2 ; set head 0, seek to cyl 0 - 68 010114 010261 000004 mov r2,rlda(r1) ; into da for seek - 69 010120 105003 clrb r3 ; unit number in upper byte - 70 010122 052703 000006 bis #cmseek,r3 ; seek cmd - 71 010126 010311 mov r3,(r1) ; execute - 72 010130 105711 3$: tstb (r1) ; test for ready - 73 010132 100376 bpl 3$ ; wait - 74 - 75 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 - 76 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count - 77 010146 105003 clrb r3 ; unit number in upper byte - 78 010150 052703 000014 bis #cmrdda,r3 ; read data cmd - 79 010154 010311 mov r3,(r1) ; execute - 80 010156 105711 4$: tstb (r1) ; test for ready - 81 010160 100376 bpl 4$ ; wait - 82 - 83 010162 005711 tst (r1) ; test for error - 84 010164 100002 bpl 5$ ; br if ok - 85 010166 000005 reset ; ERROR - reset the world - 86 010170 000721 br dlnr ; retry. r0 unchanged - 87 - 88 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd - 89 010176 005007 clr pc ; jump to bootstrap at zero - 90 - 91 .end + 53 dlnr: + 54 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit + 55 + 56 ; -------------------------------------------------- + 57 + 58 010040 010003 mov r0,r3 ; save unit number + 59 010042 000303 swab r3 ; unit number in upper byte + 60 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 61 + 62 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus + 63 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) + 64 010060 010311 mov r3,(r1) ; execute + 65 010062 105711 1$: tstb (r1) ; test for ready + 66 010064 100376 bpl 1$ ; wait + 67 + 68 010066 105003 clrb r3 ; unit number in upper byte + 69 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd + 70 010074 010311 mov r3,(r1) ; execute + 71 010076 105711 2$: tstb (r1) ; test for ready + 72 010100 100376 bpl 2$ ; wait + 73 + 74 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector + 75 010106 042702 000077 bic #77,r2 ; set sector to zero + 76 010112 005202 inc r2 ; set head 0, seek to cyl 0 + 77 010114 010261 000004 mov r2,rlda(r1) ; into da for seek + 78 010120 105003 clrb r3 ; unit number in upper byte + 79 010122 052703 000006 bis #cmseek,r3 ; seek cmd + 80 010126 010311 mov r3,(r1) ; execute + 81 010130 105711 3$: tstb (r1) ; test for ready + 82 010132 100376 bpl 3$ ; wait + 83 + 84 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 + 85 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count + 86 010146 105003 clrb r3 ; unit number in upper byte + 87 010150 052703 000014 bis #cmrdda,r3 ; read data cmd + 88 010154 010311 mov r3,(r1) ; execute + 89 010156 105711 4$: tstb (r1) ; test for ready + 90 010160 100376 bpl 4$ ; wait 91 + 92 010162 005711 tst (r1) ; test for error + 93 010164 100002 bpl 5$ ; br if ok + 94 010166 000005 reset ; ERROR - reset the world + 95 010170 000721 br dlnr ; retry. r0 unchanged + 96 + 97 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd + 98 010176 005007 clr pc ; jump to bootstrap at zero + 99 + 100 .end + 100 diff --git a/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5fb_dl0_34.sh b/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5fb_dl0_34.sh index f644b25..d31eac3 100644 --- a/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5fb_dl0_34.sh +++ b/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5fb_dl0_34.sh @@ -1,4 +1,4 @@ # start RT11 5.5 with "demo" application cd ~/10.03_app_demo/5_applications/rt11.rl02 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile rt11v5.5_dl_34.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile rt11v5.5_dl_34.cmd diff --git a/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5sj_dl1_34.sh b/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5sj_dl1_34.sh index f644b25..d31eac3 100644 --- a/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5sj_dl1_34.sh +++ b/10.03_app_demo/5_applications/rt11.rl02/rt11v5.5sj_dl1_34.sh @@ -1,4 +1,4 @@ # start RT11 5.5 with "demo" application cd ~/10.03_app_demo/5_applications/rt11.rl02 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile rt11v5.5_dl_34.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile rt11v5.5_dl_34.cmd diff --git a/10.03_app_demo/5_applications/unixv6.rk05/dk.lst b/10.03_app_demo/5_applications/unixv6.rk05/dk.lst index 1eaab3c..c51cbe4 100644 --- a/10.03_app_demo/5_applications/unixv6.rk05/dk.lst +++ b/10.03_app_demo/5_applications/unixv6.rk05/dk.lst @@ -14,71 +14,80 @@ 14 000002 xxwc =rkwc ; common word count offset 15 16 .asect - 17 010000 .=10000 - 18 - 19 ; -------------------------------------------------- + 17 ; ---- Simple boot drive 0 from 0 + 18 000000 . = 0 + 19 000000 000137 010000 jmp @#start0 20 - 21 start: - 22 ; 8 unit numbers => 8 entry addresses - 23 start0: - 24 010000 012700 000000 mov #0,r0 - 25 010004 000435 br dknr - 26 010006 000240 nop - 27 start1: - 28 010010 012700 000001 mov #1,r0 - 29 010014 000431 br dknr - 30 010016 000240 nop - 31 start2: - 32 010020 012700 000002 mov #2,r0 - 33 010024 000425 br dknr - 34 010026 000240 nop - 35 start3: - 36 010030 012700 000003 mov #3,r0 - 37 010034 000421 br dknr - 38 010036 000240 nop - 39 start4: - 40 010040 012700 000004 mov #4,r0 - 41 010044 000415 br dknr - 42 010046 000240 nop - 43 start5: - 44 010050 012700 000005 mov #5,r0 - 45 010054 000411 br dknr - 46 010056 000240 nop - 47 start6: - 48 010060 012700 000006 mov #6,r0 - 49 010064 000405 br dknr - 50 010066 000240 nop - 51 start7: - 52 010070 012700 000007 mov #7,r0 - 53 010074 000401 br dknr - 54 010076 000240 nop - 55 - 56 - 57 dknr: - 58 010100 012701 177404 mov #rkcsr+4,r1 ; boot std csr, unit - 59 - 60 010104 010003 mov r0,r3 ; get unit number - 61 010106 000241 clc ; C=0 for ror - 62 010110 006003 ror r3 ; shift into 15:12 - 63 010112 006003 ror r3 ; - 64 010114 006003 ror r3 ; - 65 010116 006003 ror r3 ; - 66 010120 010361 000006 mov r3,rkda(r1) ; unit number, sector 0 to disk addr - 67 - 68 010124 012761 177000 000002 mov #-512.,xxwc(r1) ; set word count - 69 010132 052703 000005 bis #5,r3 ; command READ+GO - 70 010136 010311 mov r3,(r1) ; execute - 71 010140 105711 2$: tstb (r1) ; test ready - 72 010142 100376 bpl 2$ ; loop - 73 - 74 010144 005711 tst (r1) ; check error - 75 010146 100002 bpl 3$ ; br if no error + 21 ; ---- Reboot drive 0 on power event + 22 000024 . = 24 ; Power ON/OFF + 23 000024 010000 .word start0 ; PC + 24 000026 000340 .word 340 ; PSW priority level 7 + 25 + 26 + 27 ; ----- Main boot addresses + 28 010000 .=10000 ; arbitrary position > 3000 + 29 + 30 start: + 31 ; 8 unit numbers => 8 entry addresses + 32 start0: + 33 010000 012700 000000 mov #0,r0 + 34 010004 000435 br dknr + 35 010006 000240 nop + 36 start1: + 37 010010 012700 000001 mov #1,r0 + 38 010014 000431 br dknr + 39 010016 000240 nop + 40 start2: + 41 010020 012700 000002 mov #2,r0 + 42 010024 000425 br dknr + 43 010026 000240 nop + 44 start3: + 45 010030 012700 000003 mov #3,r0 + 46 010034 000421 br dknr + 47 010036 000240 nop + 48 start4: + 49 010040 012700 000004 mov #4,r0 + 50 010044 000415 br dknr + 51 010046 000240 nop + 52 start5: + 53 010050 012700 000005 mov #5,r0 + 54 010054 000411 br dknr + 55 010056 000240 nop + 56 start6: + 57 010060 012700 000006 mov #6,r0 + 58 010064 000405 br dknr + 59 010066 000240 nop + 60 start7: + 61 010070 012700 000007 mov #7,r0 + 62 010074 000401 br dknr + 63 010076 000240 nop + 64 + 65 + 66 dknr: + 67 010100 012701 177404 mov #rkcsr+4,r1 ; boot std csr, unit + 68 + 69 010104 010003 mov r0,r3 ; get unit number + 70 010106 000241 clc ; C=0 for ror + 71 010110 006003 ror r3 ; shift into 15:12 + 72 010112 006003 ror r3 ; + 73 010114 006003 ror r3 ; + 74 010116 006003 ror r3 ; + 75 010120 010361 000006 mov r3,rkda(r1) ; unit number, sector 0 to disk addr 76 - 77 010150 000005 reset ; reset the world - 78 010152 000752 br dknr ; and retry - 79 - 80 010154 042711 000377 3$: bic #377,(r1) ; nop command - 81 010160 005007 clr pc ; jump to loaded boot sector + 77 010124 012761 177000 000002 mov #-512.,xxwc(r1) ; set word count + 78 010132 052703 000005 bis #5,r3 ; command READ+GO + 79 010136 010311 mov r3,(r1) ; execute + 80 010140 105711 2$: tstb (r1) ; test ready + 81 010142 100376 bpl 2$ ; loop 82 - 83 .end - 83 + 83 010144 005711 tst (r1) ; check error + 84 010146 100002 bpl 3$ ; br if no error + 85 + 86 010150 000005 reset ; reset the world + 87 010152 000752 br dknr ; and retry + 88 + 89 010154 042711 000377 3$: bic #377,(r1) ; nop command + 90 010160 005007 clr pc ; jump to loaded boot sector + 91 + 92 .end + 92 diff --git a/10.03_app_demo/5_applications/unixv6.rk05/unixv6_dk0_34.sh b/10.03_app_demo/5_applications/unixv6.rk05/unixv6_dk0_34.sh index 0c9f62b..ae22f42 100644 --- a/10.03_app_demo/5_applications/unixv6.rk05/unixv6_dk0_34.sh +++ b/10.03_app_demo/5_applications/unixv6.rk05/unixv6_dk0_34.sh @@ -1,4 +1,4 @@ # start Mini-UNix rom RK05 with "demo" application cd ~/10.03_app_demo/5_applications/unixv6.rk05 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile unixv6_dk_34.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile unixv6_dk_34.cmd diff --git a/10.03_app_demo/5_applications/xxdp.rl02/dl.lst b/10.03_app_demo/5_applications/xxdp.rl02/dl.lst index 4bcbdf6..f3a7d96 100644 --- a/10.03_app_demo/5_applications/xxdp.rl02/dl.lst +++ b/10.03_app_demo/5_applications/xxdp.rl02/dl.lst @@ -1,6 +1,6 @@ 1 .title M9312 'DL' BOOT prom for RL11 controller 2 - 3 ; This source code is a modified copyof the DEC M9312 23-751A9 boot PROM. + 3 ; This source code is a modified copy of the DEC M9312 23-751A9 boot PROM. 4 ; 5 ; This boot PROM is for the RL11 controller with RL01/RL02 drives. 6 ; @@ -20,73 +20,82 @@ 20 000014 cmrdda =6*2 ; read data 21 22 .asect - 23 010000 .=10000 ; arbitrary position > 3000 - 24 - 25 ; -------------------------------------------------- + 23 ; ---- Simple boot drive 0 from 0 + 24 000000 . = 0 + 25 000000 000137 010000 jmp @#start0 26 - 27 start: - 28 ; 4 unit numbers => 4 entry addresses - 29 start0: - 30 010000 012700 000000 mov #0,r0 - 31 010004 000413 br dlnr - 32 010006 000240 nop - 33 start1: - 34 010010 012700 000001 mov #1,r0 - 35 010014 000407 br dlnr - 36 010016 000240 nop - 37 start2: - 38 010020 012700 000002 mov #2,r0 - 39 010024 000403 br dlnr - 40 010026 000240 nop - 41 start3: - 42 010030 012700 000003 mov #3,r0 - 43 - 44 dlnr: - 45 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit - 46 - 47 ; -------------------------------------------------- - 48 - 49 010040 010003 mov r0,r3 ; save unit number - 50 010042 000303 swab r3 ; unit number in upper byte - 51 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 27 ; ---- Reboot drive 0 on power event + 28 000024 . = 24 ; Power ON/OFF + 29 000024 010000 .word start0 ; PC + 30 000026 000340 .word 340 ; PSW priority level 7 + 31 + 32 + 33 ; ----- Main boot addresses + 34 010000 .=10000 ; arbitrary position > 3000 + 35 + 36 start: + 37 ; 4 unit numbers => 4 entry addresses + 38 start0: + 39 010000 012700 000000 mov #0,r0 + 40 010004 000413 br dlnr + 41 010006 000240 nop + 42 start1: + 43 010010 012700 000001 mov #1,r0 + 44 010014 000407 br dlnr + 45 010016 000240 nop + 46 start2: + 47 010020 012700 000002 mov #2,r0 + 48 010024 000403 br dlnr + 49 010026 000240 nop + 50 start3: + 51 010030 012700 000003 mov #3,r0 52 - 53 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus - 54 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) - 55 010060 010311 mov r3,(r1) ; execute - 56 010062 105711 1$: tstb (r1) ; test for ready - 57 010064 100376 bpl 1$ ; wait - 58 - 59 010066 105003 clrb r3 ; unit number in upper byte - 60 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd - 61 010074 010311 mov r3,(r1) ; execute - 62 010076 105711 2$: tstb (r1) ; test for ready - 63 010100 100376 bpl 2$ ; wait - 64 - 65 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector - 66 010106 042702 000077 bic #77,r2 ; set sector to zero - 67 010112 005202 inc r2 ; set head 0, seek to cyl 0 - 68 010114 010261 000004 mov r2,rlda(r1) ; into da for seek - 69 010120 105003 clrb r3 ; unit number in upper byte - 70 010122 052703 000006 bis #cmseek,r3 ; seek cmd - 71 010126 010311 mov r3,(r1) ; execute - 72 010130 105711 3$: tstb (r1) ; test for ready - 73 010132 100376 bpl 3$ ; wait - 74 - 75 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 - 76 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count - 77 010146 105003 clrb r3 ; unit number in upper byte - 78 010150 052703 000014 bis #cmrdda,r3 ; read data cmd - 79 010154 010311 mov r3,(r1) ; execute - 80 010156 105711 4$: tstb (r1) ; test for ready - 81 010160 100376 bpl 4$ ; wait - 82 - 83 010162 005711 tst (r1) ; test for error - 84 010164 100002 bpl 5$ ; br if ok - 85 010166 000005 reset ; ERROR - reset the world - 86 010170 000721 br dlnr ; retry. r0 unchanged - 87 - 88 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd - 89 010176 005007 clr pc ; jump to bootstrap at zero - 90 - 91 .end + 53 dlnr: + 54 010034 012701 174400 mov #rlcsr,r1 ; boot std csr, unit + 55 + 56 ; -------------------------------------------------- + 57 + 58 010040 010003 mov r0,r3 ; save unit number + 59 010042 000303 swab r3 ; unit number in upper byte + 60 010044 010311 mov r3,(r1) ; set unit, NOP cmd + 61 + 62 010046 012761 000013 000004 mov #013,rlda(r1) ; subcmd reset+getstatus + 63 010054 052703 000004 bis #cmstat,r3 ; get status cmd (r3lo is 0) + 64 010060 010311 mov r3,(r1) ; execute + 65 010062 105711 1$: tstb (r1) ; test for ready + 66 010064 100376 bpl 1$ ; wait + 67 + 68 010066 105003 clrb r3 ; unit number in upper byte + 69 010070 052703 000010 bis #cmrdhd,r3 ; read header cmd + 70 010074 010311 mov r3,(r1) ; execute + 71 010076 105711 2$: tstb (r1) ; test for ready + 72 010100 100376 bpl 2$ ; wait + 73 + 74 010102 016102 000006 mov rlmp(r1),r2 ; retrieve cyl/head/sector + 75 010106 042702 000077 bic #77,r2 ; set sector to zero + 76 010112 005202 inc r2 ; set head 0, seek to cyl 0 + 77 010114 010261 000004 mov r2,rlda(r1) ; into da for seek + 78 010120 105003 clrb r3 ; unit number in upper byte + 79 010122 052703 000006 bis #cmseek,r3 ; seek cmd + 80 010126 010311 mov r3,(r1) ; execute + 81 010130 105711 3$: tstb (r1) ; test for ready + 82 010132 100376 bpl 3$ ; wait + 83 + 84 010134 005061 000004 clr rlda(r1) ; select cyl0/head0/sector0 + 85 010140 012761 177000 000006 mov #-512.,rlmp(r1) ; set word count + 86 010146 105003 clrb r3 ; unit number in upper byte + 87 010150 052703 000014 bis #cmrdda,r3 ; read data cmd + 88 010154 010311 mov r3,(r1) ; execute + 89 010156 105711 4$: tstb (r1) ; test for ready + 90 010160 100376 bpl 4$ ; wait 91 + 92 010162 005711 tst (r1) ; test for error + 93 010164 100002 bpl 5$ ; br if ok + 94 010166 000005 reset ; ERROR - reset the world + 95 010170 000721 br dlnr ; retry. r0 unchanged + 96 + 97 010172 042711 000377 5$: bic #377,(r1) ; execute nop cmd + 98 010176 005007 clr pc ; jump to bootstrap at zero + 99 + 100 .end + 100 diff --git a/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.2_dl0.sh b/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.2_dl0.sh index 16b031d..fe5ce25 100644 --- a/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.2_dl0.sh +++ b/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.2_dl0.sh @@ -1,3 +1,3 @@ # start xxdp with "demo" application cd ~/10.03_app_demo/5_applications/xxdp.rl02 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile xxdp.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile xxdp.cmd diff --git a/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.5_dl1.sh b/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.5_dl1.sh index 16b031d..fe5ce25 100644 --- a/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.5_dl1.sh +++ b/10.03_app_demo/5_applications/xxdp.rl02/xxdp2.5_dl1.sh @@ -1,3 +1,3 @@ # start xxdp with "demo" application cd ~/10.03_app_demo/5_applications/xxdp.rl02 -~/10.03_app_demo/4_deploy/demo --arb 1 --verbose --cmdfile xxdp.cmd +~/10.03_app_demo/4_deploy/demo --verbose --cmdfile xxdp.cmd