1
0
mirror of https://github.com/livingcomputermuseum/UniBone.git synced 2026-04-13 23:44:17 +00:00

DL11 cleanup&fixes

This commit is contained in:
Joerg Hoppe
2019-06-24 17:25:20 +02:00
parent 28ab69050c
commit 81c3295e31
9 changed files with 148 additions and 30 deletions

View File

@@ -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) {

View File

@@ -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";

View File

@@ -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)");

View File

@@ -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");

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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 <filename> Load memory content from absolute papertape image\n");
printf("ld List all defined devices\n");
printf("en <dev> Enable a device\n");
printf("dis <dev> 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 <filename>
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 <filename>
load_memory(arbitration_mode, fileformat_papertape, s_param[1], NULL);
} else if (!strcasecmp(s_opcode, "ld") && n_fields == 1) {
unsigned n;
list<device_c *>::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;