diff --git a/10.01_base/2_src/arm/unibusdevice.cpp b/10.01_base/2_src/arm/unibusdevice.cpp index 9a15f22..75564e7 100644 --- a/10.01_base/2_src/arm/unibusdevice.cpp +++ b/10.01_base/2_src/arm/unibusdevice.cpp @@ -162,7 +162,7 @@ void unibusdevice_c::reset_unibus_registers() { // set an UNIBUS interrupt condition with intr_vector and intr_level void unibusdevice_c::interrupt(unsigned vector, unsigned level) { - unibusadapter->request_INTR(vector, level); + unibusadapter->request_INTR(level, vector); } void unibusdevice_c::interrupt(void) { diff --git a/10.02_devices/2_src/dl11w.cpp b/10.02_devices/2_src/dl11w.cpp index c2ba016..bda6036 100644 --- a/10.02_devices/2_src/dl11w.cpp +++ b/10.02_devices/2_src/dl11w.cpp @@ -57,11 +57,12 @@ slu_c::slu_c() : unibusdevice_c() { //ip_port.value = IP_PORT; // not used // static config - name.value = "SLU"; + name.value = "DL11"; type_name.value = "slu_c"; log_label = "slu"; - break_enable.value = 1 ; // SW4-1 per default ON + break_enable.value = 1 ; // SW4-1 default ON + error_bits_enable.value = 1 ; // SE4-7 default ON // SLU has 2 Interrupt vectors: base = RCV, base+= XMT set_default_bus_params(SLU_ADDR, SLU_VECTOR, SLU_LEVEL); // base addr, intr-vector, intr level @@ -166,10 +167,13 @@ void slu_c::eval_rcsr_dato_value(void) { // Update RBUF, readonly void slu_c::set_rbuf_dati_value(void) { - uint16_t val = (rcv_or_err ? RBUF_OR_ERR : 0) | (rcv_fr_err ? RBUF_FR_ERR : 0) + uint16_t val = 0 ; + if (error_bits_enable.value) { + val = (rcv_or_err ? RBUF_OR_ERR : 0) | (rcv_fr_err ? RBUF_FR_ERR : 0) | (rcv_p_err ? RBUF_P_ERR : 0); if (val) // set general error flag val |= RBUF_ERROR; + } val |= rcv_buffer; // received char in bits 7..0 set_register_dati_value(reg_rbuf, val, __func__); } @@ -295,14 +299,17 @@ void slu_c::worker_rcv(void) { int n; char buffer[BUFLEN + 1]; - // 1. poll with frequency > baudrate, to see single bits - unsigned poll_periods_us = 1000000 / baudrate.value; + // poll with frequency > baudrate, to see single bits + //unsigned poll_periods_us = 1000000 / baudrate.value; /* Receiver not time critical? UARTS are buffering So if thread is swapped out and back a burst of characters appear. -> Wait after each character for transfer time before polling RS232 again. */ + unsigned poll_periods_us = (rs232.CharTransmissionTime_us * 9) / 10; + // poll a bit faster to be ahead of char stream. + // don't oversample: PDP-11 must process char in that time // worker_init_realtime_priority(rt_device); @@ -310,7 +317,7 @@ void slu_c::worker_rcv(void) { timeout.wait_us(poll_periods_us); // "query // rcv_active: can only be set by polling the UART input GPIO pin? - // at the moments, it is onyl sen on maintenance loopback xmt + // at the moments, it is only sent on maintenance loopback xmt /* read serial data, if any */ if (rs232.PollComport((unsigned char*) buffer, 1)) { pthread_mutex_lock(&on_after_rcv_register_access_mutex); // signal changes atomic against UNIBUS accesses @@ -378,7 +385,7 @@ void slu_c::worker_xmt(void) { // 3. wait for data byte being shifted out pthread_mutex_unlock(&on_after_xmt_register_access_mutex); - timeout.wait_us(rs232.TransmissionTime_us); + timeout.wait_us(rs232.CharTransmissionTime_us); pthread_mutex_lock(&on_after_xmt_register_access_mutex); if (xmt_maint) // put sent byte into rcv buffer, receiver will poll it @@ -407,7 +414,7 @@ ltc_c::ltc_c() : { // static config - name.value = "LTC"; + name.value = "KW11"; type_name.value = "ltc_c"; log_label = "ltc"; diff --git a/10.02_devices/2_src/dl11w.hpp b/10.02_devices/2_src/dl11w.hpp index c3053f2..3b50efe 100644 --- a/10.02_devices/2_src/dl11w.hpp +++ b/10.02_devices/2_src/dl11w.hpp @@ -153,6 +153,9 @@ public: parameter_string_c mode = parameter_string_c(this, "mode", "m", /*readonly*/false, "Mode: 8N1, 7E1, ... "); + parameter_bool_c error_bits_enable = parameter_bool_c(this, "errorbits", "eb", /*readonly*/false, + "Enable error bits (M7856 SW4-7)"); + parameter_bool_c break_enable = parameter_bool_c(this, "break", "b", /*readonly*/false, "Enable BREAK transmission (M7856 SW4-1)"); diff --git a/10.02_devices/2_src/rs232.cpp b/10.02_devices/2_src/rs232.cpp index 76c13ba..c412c8e 100644 --- a/10.02_devices/2_src/rs232.cpp +++ b/10.02_devices/2_src/rs232.cpp @@ -33,7 +33,7 @@ #include "rs232.hpp" rs232_c::rs232_c() { - TransmissionTime_us = 0; + CharTransmissionTime_us = 0; } // devname without leading "/dev/" @@ -219,7 +219,7 @@ int rs232_c::OpenComport(const char *devname, int baudrate, const char *mode, } // bit count is 10 for 8N1 // Calc time to transmit on character - TransmissionTime_us = (1000000 * bitcount) / baudrate; + CharTransmissionTime_us = (1000000 * bitcount) / baudrate; /* scan for BREAK and frame/parity errors? To read BREAK not as \0: @@ -353,7 +353,7 @@ void rs232_c::SetBreak(int break_state) { void rs232_c::CloseComport(void) { int status; - TransmissionTime_us = 0; + CharTransmissionTime_us = 0; if (ioctl(Cport, TIOCMGET, &status) == -1) { perror("unable to get portstatus"); diff --git a/10.02_devices/2_src/rs232.hpp b/10.02_devices/2_src/rs232.hpp index 14f8e60..36df9ac 100644 --- a/10.02_devices/2_src/rs232.hpp +++ b/10.02_devices/2_src/rs232.hpp @@ -65,7 +65,7 @@ private: public: rs232_c(); - unsigned TransmissionTime_us; + unsigned CharTransmissionTime_us; int OpenComport(const char *devname, int baudrate, const char *mode, bool par_and_break); int PollComport(unsigned char *buf, int size); int SendByte(unsigned char byte); diff --git a/10.02_devices/3_test/dl11w/test.cmd b/10.02_devices/3_test/dl11w/test.cmd new file mode 100644 index 0000000..a5abfac --- /dev/null +++ b/10.02_devices/3_test/dl11w/test.cmd @@ -0,0 +1,73 @@ +# "demo" cmd Testsequence for DL11W +dc # "demo" menu: device without cpu +sd dl11 +.print Test of DL11-W, without CPU. +.print Put UniBone in emtpy backplane. +.print Connect serial terminal emulator to UniBone "UART2", set to 9600 8N1 +.input +en dl11 + +INIT +E +.print expected: +.print EXAM reg #0 RCSR 777560 -> 000000 +.print EXAM reg #1 RBUF 777562 -> 000000 +.print EXAM reg #2 XCSR 777564 -> 000200 +.print EXAM reg #3 XBUF 777566 -> 000000 + + +. print Send chars "Hello". Fast, chars may get lost +d xbuf 110 +d xbuf 145 +d xbuf 154 +d xbuf 154 +d xbuf 157 +d xbuf 15 +d xbuf 12 + +.print Now press an "a" on terminal keyboard +.input +e rcsr +e rbuf +e rcsr +.print Expected: rcsr = 200, rbuf = 141, rcsr = 000 (reading rbuf cleared "RCV_DONE") + +.print Now press a "yz" on terminal keyboard +.input +e rcsr +e rbuf +e rcsr +.print Expected: rcsr = 200, rbuf = 14172 ("z"), rcsr = 000 + +.print switch terminal to 7NO. press "c" +e rbuf +.print Expected: rbuf = 373 (c +parity) + +.print Check BREAK receive: +.print Set terminal to 300 baud, send a space (0x20) -> looots of 00s +e rbuf +.print Expected: a "0" with framing error: 170000 +.print Set terminal back to 9600 baud +.input + +.print Maintenance self receive +d xcsr 4 # MAINT ON +d xbuf 123 # sent "S" +e +.print Expected: rcsr = 200, rbuf = 123 (sent char "S" received back) + + + + + + + + + + + + + + + + diff --git a/10.02_devices/3_test/dl11w/zdld.cmd b/10.02_devices/3_test/dl11w/zdld.cmd new file mode 100644 index 0000000..ca95ee2 --- /dev/null +++ b/10.02_devices/3_test/dl11w/zdld.cmd @@ -0,0 +1,19 @@ +# "demo" cmd Testsequence for DL11W +d # "demo" menu: device with cpu +sd dl11 +.print Test of DL11-W, with PDP-11 CPU. +.print Connect serial terminal emulator to UniBone "UART2", set to 9600 8N1 +.input + +en dl11 + +pwr + +.wait 1000 +.print must see Bootloader prompt on UART2 now! + +m i + + +m lp /root/10.02_devices/3_test/dl11w/ZDLDI0.BIN +.print Now start ZDLD at address 200 \ No newline at end of file diff --git a/10.03_app_demo/2_src/makefile b/10.03_app_demo/2_src/makefile index eec8f2f..f40f4ef 100644 --- a/10.03_app_demo/2_src/makefile +++ b/10.03_app_demo/2_src/makefile @@ -150,7 +150,7 @@ clean: # TODO -# uato dependcies +# auto dependencies of header files # http://scottmcpeak.com/autodepend/autodepend.html # gcc -MM $(CCFLAGS) $< >$(OBJDIR)*.c > ***.d diff --git a/10.03_app_demo/2_src/menu_devices.cpp b/10.03_app_demo/2_src/menu_devices.cpp index 69924bf..801b4d6 100644 --- a/10.03_app_demo/2_src/menu_devices.cpp +++ b/10.03_app_demo/2_src/menu_devices.cpp @@ -59,11 +59,22 @@ static char memory_filename[PATH_MAX + 1]; // entry_label is program start, tpyically "start" -static void load_memory(enum unibus_c::arbitration_mode_enum arbitration_mode, char *fname, - const char *entry_label) { +// 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) { uint32_t firstaddr, lastaddr; - bool load_ok = membuffer->load_macro11_listing(fname, entry_label); + bool load_ok; bool timeout; + switch (format) { + case fileformat_macro11_listing: + load_ok = membuffer->load_macro11_listing(fname, entry_label); + break; + case fileformat_papertape: + load_ok = membuffer->load_papertape(fname); + break; + default: + load_ok = false; + } if (load_ok) { strcpy(memory_filename, fname); membuffer->get_addr_range(&firstaddr, &lastaddr); @@ -76,11 +87,11 @@ static void load_memory(enum unibus_c::arbitration_mode_enum arbitration_mode, c 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->dma_wordcount, &timeout); + if (timeout) + printf(" Error writing UNIBUS memory\n"); } - unibus->mem_write(arbitration_mode, membuffer->data.words, firstaddr, lastaddr, - unibus->dma_wordcount, &timeout); - if (timeout) - printf(" Error writing UNIBUS memory\n"); } // CPU is enabled, act as ARBITRATION_MASTER @@ -129,9 +140,8 @@ void application_c::menu_devices(bool with_CPU) { // Create UDA50 uda_c *UDA50 = new uda_c(); // Create SLU+ LTC - slu_c *DL11 = new slu_c() ; - ltc_c *LTC = new ltc_c() ; - + slu_c *DL11 = new slu_c(); + ltc_c *LTC = new ltc_c(); // //demo_regs.install(); // //demo_regs.worker_start(); @@ -179,6 +189,7 @@ void application_c::menu_devices(bool with_CPU) { if (strlen(memory_filename)) printf("m ll Reload last memory content from file \"%s\"\n", memory_filename); + printf("m lp Load memory content from absolute papertape image\n"); printf("ld List all defined devices\n"); printf("en Enable a device\n"); printf("dis Disable device\n"); @@ -271,11 +282,16 @@ 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, s_param[1], "start"); + load_memory(arbitration_mode, 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, memory_filename, "start"); + load_memory(arbitration_mode, 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); } else if (!strcasecmp(s_opcode, "ld") && n_fields == 1) { unsigned n; list::iterator it; @@ -438,10 +454,10 @@ void application_c::menu_devices(bool with_CPU) { delete cpu; } - LTC->enabled.set(false) ; - delete LTC ; - DL11->enabled.set(false) ; - delete DL11 ; + LTC->enabled.set(false); + delete LTC; + DL11->enabled.set(false); + delete DL11; RL11->enabled.set(false); delete RL11;