Port over some improvements from jor1k for uart
This commit is contained in:
parent
1120f2b95c
commit
997d4c6c6d
125
src/uart.js
125
src/uart.js
|
@ -10,6 +10,8 @@
|
|||
/** @const */
|
||||
var DLAB = 0x80;
|
||||
|
||||
|
||||
/** @const */ var UART_IER_MSI = 0x08; /* Modem Status Changed int. */
|
||||
/** @const */ var UART_IER_THRI = 0x02; /* Enable Transmitter holding register int. */
|
||||
/** @const */ var UART_IER_RDI = 0x01; /* Enable receiver data interrupt */
|
||||
|
||||
|
@ -20,6 +22,10 @@ var DLAB = 0x80;
|
|||
/** @const */var UART_IIR_RLSI = 0x06; /* Receiver line status interrupt (High p.) */
|
||||
/** @const */var UART_IIR_CTI = 0x0c; /* Character timeout */
|
||||
|
||||
/** @const */ var UART_LSR_DATA_READY = 0x1; // data available
|
||||
/** @const */ var UART_LSR_TX_EMPTY = 0x20; // TX (THR) buffer is empty
|
||||
/** @const */ var UART_LSR_TRANSMITTER_EMPTY = 0x40; // TX empty and line is idle
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
|
@ -40,7 +46,9 @@ function UART(cpu, port, bus)
|
|||
this.baud_rate = 0;
|
||||
|
||||
this.line_control = 0;
|
||||
this.line_status = 0;
|
||||
|
||||
// line status register
|
||||
this.lsr = UART_LSR_TRANSMITTER_EMPTY | UART_LSR_TX_EMPTY;
|
||||
|
||||
this.fifo_control = 0;
|
||||
|
||||
|
@ -48,7 +56,7 @@ function UART(cpu, port, bus)
|
|||
this.ier = 0;
|
||||
|
||||
// interrupt identification register
|
||||
this.iir = 1;
|
||||
this.iir = UART_IIR_NO_INT;
|
||||
|
||||
this.modem_control = 0;
|
||||
this.modem_status = 0;
|
||||
|
@ -92,7 +100,7 @@ function UART(cpu, port, bus)
|
|||
|
||||
dbg_log("data: " + h(out_byte), LOG_SERIAL);
|
||||
|
||||
this.ThrowTHRI();
|
||||
this.ThrowInterrupt(UART_IIR_THRI);
|
||||
|
||||
if(out_byte === 0xFF)
|
||||
{
|
||||
|
@ -107,6 +115,7 @@ function UART(cpu, port, bus)
|
|||
|
||||
if(char === "\n")
|
||||
{
|
||||
dbg_log("SERIAL: " + String.fromCharCode.apply("", this.current_line));
|
||||
this.bus.send("serial0-output-line", String.fromCharCode.apply("", this.current_line));
|
||||
this.current_line = [];
|
||||
}
|
||||
|
@ -130,9 +139,9 @@ function UART(cpu, port, bus)
|
|||
}
|
||||
else
|
||||
{
|
||||
this.ier = out_byte;
|
||||
this.ier = out_byte & 0xF;
|
||||
dbg_log("interrupt enable: " + h(out_byte), LOG_SERIAL);
|
||||
this.NextInterrupt();
|
||||
this.CheckInterrupt();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -155,9 +164,10 @@ function UART(cpu, port, bus)
|
|||
dbg_log("Read input: " + h(data), LOG_SERIAL);
|
||||
}
|
||||
|
||||
if(this.input.length)
|
||||
if(this.input.length === 0)
|
||||
{
|
||||
this.ThrowCTI();
|
||||
this.lsr &= ~UART_LSR_DATA_READY;
|
||||
this.ClearInterrupt(UART_IIR_CTI);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -172,7 +182,7 @@ function UART(cpu, port, bus)
|
|||
}
|
||||
else
|
||||
{
|
||||
return this.ier;
|
||||
return this.ier & 0xF;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -181,14 +191,9 @@ function UART(cpu, port, bus)
|
|||
var ret = this.iir & 0xF | 0xC0;
|
||||
dbg_log("read interrupt identification: " + h(this.iir), LOG_SERIAL);
|
||||
|
||||
if(this.iir === UART_IIR_THRI)
|
||||
{
|
||||
if (this.iir == UART_IIR_THRI) {
|
||||
this.ClearInterrupt(UART_IIR_THRI);
|
||||
}
|
||||
else if(this.iir === UART_IIR_CTI)
|
||||
{
|
||||
this.ClearInterrupt(UART_IIR_CTI);
|
||||
}
|
||||
|
||||
return ret;
|
||||
});
|
||||
|
@ -222,17 +227,8 @@ function UART(cpu, port, bus)
|
|||
|
||||
io.register_read(port | 5, this, function()
|
||||
{
|
||||
var line_status = 0;
|
||||
|
||||
if(this.input.length)
|
||||
{
|
||||
line_status |= 1;
|
||||
}
|
||||
|
||||
line_status |= 0x20 | 0x40;
|
||||
|
||||
dbg_log("read line status: " + h(line_status), LOG_SERIAL);
|
||||
return line_status;
|
||||
dbg_log("read line status: " + h(this.lsr), LOG_SERIAL);
|
||||
return this.lsr;
|
||||
});
|
||||
io.register_write(port | 5, this, function(out_byte)
|
||||
{
|
||||
|
@ -266,7 +262,7 @@ UART.prototype.get_state = function()
|
|||
state[0] = this.ints;
|
||||
state[1] = this.baud_rate;
|
||||
state[2] = this.line_control;
|
||||
state[3] = this.line_status;
|
||||
state[3] = this.lsr;
|
||||
state[4] = this.fifo_control;
|
||||
state[5] = this.ier;
|
||||
state[6] = this.iir;
|
||||
|
@ -283,7 +279,7 @@ UART.prototype.set_state = function(state)
|
|||
this.ints = state[0];
|
||||
this.baud_rate = state[1];
|
||||
this.line_control = state[2];
|
||||
this.line_status = state[3];
|
||||
this.lsr = state[3];
|
||||
this.fifo_control = state[4];
|
||||
this.ier = state[5];
|
||||
this.iir = state[6];
|
||||
|
@ -293,59 +289,33 @@ UART.prototype.set_state = function(state)
|
|||
this.irq = state[10];
|
||||
};
|
||||
|
||||
UART.prototype.push_irq = function()
|
||||
{
|
||||
dbg_log("Push irq", LOG_SERIAL);
|
||||
this.cpu.device_raise_irq(this.irq);
|
||||
};
|
||||
|
||||
UART.prototype.ClearInterrupt = function(line)
|
||||
{
|
||||
this.ints &= ~(1 << line);
|
||||
this.iir = UART_IIR_NO_INT;
|
||||
|
||||
if(line === this.iir)
|
||||
{
|
||||
this.NextInterrupt();
|
||||
}
|
||||
};
|
||||
|
||||
UART.prototype.ThrowCTI = function() {
|
||||
this.ints |= 1 << UART_IIR_CTI;
|
||||
if (!(this.ier & UART_IER_RDI)) {
|
||||
return;
|
||||
}
|
||||
if ((this.iir != UART_IIR_RLSI) && (this.iir != UART_IIR_RDI)) {
|
||||
UART.prototype.CheckInterrupt = function() {
|
||||
if ((this.ints & (1 << UART_IIR_CTI)) && (this.ier & UART_IER_RDI)) {
|
||||
this.iir = UART_IIR_CTI;
|
||||
this.push_irq();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
UART.prototype.ThrowTHRI = function() {
|
||||
this.ints |= 1 << UART_IIR_THRI;
|
||||
if (!(this.ier & UART_IER_THRI)) {
|
||||
return;
|
||||
}
|
||||
if ((this.iir & UART_IIR_NO_INT) || (this.iir == UART_IIR_MSI) || (this.iir == UART_IIR_THRI)) {
|
||||
this.cpu.device_raise_irq(this.irq);
|
||||
} else
|
||||
if ((this.ints & (1 << UART_IIR_THRI)) && (this.ier & UART_IER_THRI)) {
|
||||
this.iir = UART_IIR_THRI;
|
||||
this.push_irq();
|
||||
}
|
||||
};
|
||||
|
||||
UART.prototype.NextInterrupt = function() {
|
||||
if ((this.ints & (1 << UART_IIR_CTI)) && (this.ier & UART_IER_RDI)) {
|
||||
this.ThrowCTI();
|
||||
}
|
||||
else if ((this.ints & (1 << UART_IIR_THRI)) && (this.ier & UART_IER_THRI)) {
|
||||
this.ThrowTHRI();
|
||||
}
|
||||
else {
|
||||
this.cpu.device_raise_irq(this.irq);
|
||||
} else
|
||||
if ((this.ints & (1 << UART_IIR_MSI)) && (this.ier & UART_IER_MSI)) {
|
||||
this.iir = UART_IIR_MSI;
|
||||
this.cpu.device_raise_irq(this.irq);
|
||||
} else {
|
||||
this.iir = UART_IIR_NO_INT;
|
||||
//this.intdev.ClearInterrupt(0x2);
|
||||
this.cpu.device_lower_irq(this.irq);
|
||||
}
|
||||
};
|
||||
|
||||
UART.prototype.ThrowInterrupt = function(line) {
|
||||
this.ints |= (1 << line);
|
||||
this.CheckInterrupt();
|
||||
}
|
||||
|
||||
UART.prototype.ClearInterrupt = function(line) {
|
||||
this.ints &= ~(1 << line);
|
||||
this.CheckInterrupt();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} data
|
||||
|
@ -354,10 +324,7 @@ UART.prototype.data_received = function(data)
|
|||
{
|
||||
dbg_log("input: " + h(data), LOG_SERIAL);
|
||||
this.input.push(data);
|
||||
this.ints |= 1 << UART_IIR_CTI;
|
||||
|
||||
if(this.ier & UART_IER_RDI)
|
||||
{
|
||||
this.ThrowCTI();
|
||||
}
|
||||
this.lsr |= UART_LSR_DATA_READY;
|
||||
this.ThrowInterrupt(UART_IIR_CTI);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue