@aptre/v86 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/LICENSE.MIT +22 -0
- package/Readme.md +237 -0
- package/dist/v86.browser.js +26666 -0
- package/dist/v86.browser.js.map +7 -0
- package/dist/v86.js +26632 -0
- package/dist/v86.js.map +7 -0
- package/gen/generate_analyzer.ts +512 -0
- package/gen/generate_interpreter.ts +522 -0
- package/gen/generate_jit.ts +624 -0
- package/gen/rust_ast.ts +107 -0
- package/gen/util.ts +35 -0
- package/gen/x86_table.ts +1836 -0
- package/lib/9p.ts +1547 -0
- package/lib/filesystem.ts +1879 -0
- package/lib/marshall.ts +168 -0
- package/lib/softfloat/softfloat.c +32501 -0
- package/lib/zstd/zstddeclib.c +13520 -0
- package/package.json +75 -0
- package/src/acpi.ts +267 -0
- package/src/browser/dummy_screen.ts +106 -0
- package/src/browser/fake_network.ts +1771 -0
- package/src/browser/fetch_network.ts +361 -0
- package/src/browser/filestorage.ts +124 -0
- package/src/browser/inbrowser_network.ts +57 -0
- package/src/browser/keyboard.ts +564 -0
- package/src/browser/main.ts +3415 -0
- package/src/browser/mouse.ts +255 -0
- package/src/browser/network.ts +142 -0
- package/src/browser/print_stats.ts +336 -0
- package/src/browser/screen.ts +978 -0
- package/src/browser/serial.ts +316 -0
- package/src/browser/speaker.ts +1223 -0
- package/src/browser/starter.ts +1688 -0
- package/src/browser/wisp_network.ts +332 -0
- package/src/browser/worker_bus.ts +64 -0
- package/src/buffer.ts +652 -0
- package/src/bus.ts +78 -0
- package/src/const.ts +128 -0
- package/src/cpu.ts +2891 -0
- package/src/dma.ts +474 -0
- package/src/elf.ts +251 -0
- package/src/floppy.ts +1778 -0
- package/src/ide.ts +3455 -0
- package/src/io.ts +504 -0
- package/src/iso9660.ts +317 -0
- package/src/kernel.ts +250 -0
- package/src/lib.ts +645 -0
- package/src/log.ts +149 -0
- package/src/main.ts +199 -0
- package/src/ne2k.ts +1589 -0
- package/src/pci.ts +815 -0
- package/src/pit.ts +406 -0
- package/src/ps2.ts +820 -0
- package/src/rtc.ts +537 -0
- package/src/rust/analysis.rs +101 -0
- package/src/rust/codegen.rs +2660 -0
- package/src/rust/config.rs +3 -0
- package/src/rust/control_flow.rs +425 -0
- package/src/rust/cpu/apic.rs +658 -0
- package/src/rust/cpu/arith.rs +1207 -0
- package/src/rust/cpu/call_indirect.rs +2 -0
- package/src/rust/cpu/cpu.rs +4501 -0
- package/src/rust/cpu/fpu.rs +923 -0
- package/src/rust/cpu/global_pointers.rs +112 -0
- package/src/rust/cpu/instructions.rs +2486 -0
- package/src/rust/cpu/instructions_0f.rs +5261 -0
- package/src/rust/cpu/ioapic.rs +316 -0
- package/src/rust/cpu/memory.rs +351 -0
- package/src/rust/cpu/misc_instr.rs +613 -0
- package/src/rust/cpu/mod.rs +16 -0
- package/src/rust/cpu/modrm.rs +133 -0
- package/src/rust/cpu/pic.rs +402 -0
- package/src/rust/cpu/sse_instr.rs +361 -0
- package/src/rust/cpu/string.rs +701 -0
- package/src/rust/cpu/vga.rs +175 -0
- package/src/rust/cpu_context.rs +69 -0
- package/src/rust/dbg.rs +98 -0
- package/src/rust/gen/analyzer.rs +3807 -0
- package/src/rust/gen/analyzer0f.rs +3992 -0
- package/src/rust/gen/interpreter.rs +4447 -0
- package/src/rust/gen/interpreter0f.rs +5404 -0
- package/src/rust/gen/jit.rs +5080 -0
- package/src/rust/gen/jit0f.rs +5547 -0
- package/src/rust/gen/mod.rs +14 -0
- package/src/rust/jit.rs +2443 -0
- package/src/rust/jit_instructions.rs +7881 -0
- package/src/rust/js_api.rs +6 -0
- package/src/rust/leb.rs +46 -0
- package/src/rust/lib.rs +29 -0
- package/src/rust/modrm.rs +330 -0
- package/src/rust/opstats.rs +249 -0
- package/src/rust/page.rs +15 -0
- package/src/rust/paging.rs +25 -0
- package/src/rust/prefix.rs +15 -0
- package/src/rust/profiler.rs +155 -0
- package/src/rust/regs.rs +38 -0
- package/src/rust/softfloat.rs +286 -0
- package/src/rust/state_flags.rs +27 -0
- package/src/rust/wasmgen/mod.rs +2 -0
- package/src/rust/wasmgen/wasm_builder.rs +1047 -0
- package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
- package/src/rust/zstd.rs +105 -0
- package/src/sb16.ts +1928 -0
- package/src/state.ts +359 -0
- package/src/uart.ts +472 -0
- package/src/vga.ts +2791 -0
- package/src/virtio.ts +1756 -0
- package/src/virtio_balloon.ts +273 -0
- package/src/virtio_console.ts +372 -0
- package/src/virtio_net.ts +326 -0
package/src/uart.ts
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
declare let DEBUG: boolean
|
|
2
|
+
|
|
3
|
+
import { LOG_SERIAL } from './const.js'
|
|
4
|
+
import { h } from './lib.js'
|
|
5
|
+
import { dbg_log } from './log.js'
|
|
6
|
+
import { IO } from './io.js'
|
|
7
|
+
import { BusConnector } from './bus.js'
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Serial ports
|
|
11
|
+
* http://wiki.osdev.org/UART
|
|
12
|
+
* https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js
|
|
13
|
+
* https://www.freebsd.org/doc/en/articles/serial-uart/
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const DLAB = 0x80
|
|
17
|
+
|
|
18
|
+
const UART_IER_MSI = 0x08 /* Modem Status Changed int. */
|
|
19
|
+
const UART_IER_THRI = 0x02 /* Enable Transmitter holding register int. */
|
|
20
|
+
const UART_IER_RDI = 0x01 /* Enable receiver data interrupt */
|
|
21
|
+
|
|
22
|
+
const UART_IIR_MSI = 0x00 /* Modem status interrupt (Low priority) */
|
|
23
|
+
const UART_IIR_NO_INT = 0x01
|
|
24
|
+
const UART_IIR_THRI = 0x02 /* Transmitter holding register empty */
|
|
25
|
+
const UART_IIR_RDI = 0x04 /* Receiver data interrupt */
|
|
26
|
+
const _UART_IIR_RLSI = 0x06 /* Receiver line status interrupt (High p.) */
|
|
27
|
+
const UART_IIR_CTI = 0x0c /* Character timeout */
|
|
28
|
+
|
|
29
|
+
// Modem control register
|
|
30
|
+
const UART_MCR_LOOPBACK = 0x10
|
|
31
|
+
|
|
32
|
+
const UART_LSR_DATA_READY = 0x1 // data available
|
|
33
|
+
const UART_LSR_TX_EMPTY = 0x20 // TX (THR) buffer is empty
|
|
34
|
+
const UART_LSR_TRANSMITTER_EMPTY = 0x40 // TX empty and line is idle
|
|
35
|
+
|
|
36
|
+
// Modem status register
|
|
37
|
+
const UART_MSR_DCD = 0x7 // Data Carrier Detect
|
|
38
|
+
const UART_MSR_RI = 0x6 // Ring Indicator
|
|
39
|
+
const UART_MSR_DSR = 0x5 // Data Set Ready
|
|
40
|
+
const UART_MSR_CTS = 0x4 // Clear To Send
|
|
41
|
+
// Delta bits
|
|
42
|
+
const UART_MSR_DDCD = 0x3 // Delta DCD
|
|
43
|
+
const UART_MSR_TERI = 0x2 // Trailing Edge RI
|
|
44
|
+
const UART_MSR_DDSR = 0x1 // Delta DSR
|
|
45
|
+
const UART_MSR_DCTS = 0x0 // Delta CTS
|
|
46
|
+
|
|
47
|
+
// Minimal interface for CPU fields UART uses
|
|
48
|
+
interface UARTCpu {
|
|
49
|
+
io: IO
|
|
50
|
+
device_raise_irq(irq: number): void
|
|
51
|
+
device_lower_irq(irq: number): void
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type UARTState = [
|
|
55
|
+
number,
|
|
56
|
+
number,
|
|
57
|
+
number,
|
|
58
|
+
number,
|
|
59
|
+
number,
|
|
60
|
+
number,
|
|
61
|
+
number,
|
|
62
|
+
number,
|
|
63
|
+
number,
|
|
64
|
+
number,
|
|
65
|
+
number,
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* UART serial port controller.
|
|
70
|
+
*/
|
|
71
|
+
export class UART {
|
|
72
|
+
name: string
|
|
73
|
+
bus: BusConnector
|
|
74
|
+
cpu: UARTCpu
|
|
75
|
+
ints: number
|
|
76
|
+
baud_rate: number
|
|
77
|
+
line_control: number
|
|
78
|
+
lsr: number
|
|
79
|
+
fifo_control: number
|
|
80
|
+
ier: number
|
|
81
|
+
iir: number
|
|
82
|
+
modem_control: number
|
|
83
|
+
modem_status: number
|
|
84
|
+
scratch_register: number
|
|
85
|
+
irq: number
|
|
86
|
+
input: number[]
|
|
87
|
+
current_line: string
|
|
88
|
+
com: number
|
|
89
|
+
|
|
90
|
+
constructor(cpu: UARTCpu, port: number, bus: BusConnector) {
|
|
91
|
+
this.name = 'uart'
|
|
92
|
+
this.bus = bus
|
|
93
|
+
this.cpu = cpu
|
|
94
|
+
|
|
95
|
+
this.ints = 1 << UART_IIR_THRI
|
|
96
|
+
|
|
97
|
+
this.baud_rate = 0
|
|
98
|
+
|
|
99
|
+
this.line_control = 0
|
|
100
|
+
|
|
101
|
+
// line status register
|
|
102
|
+
this.lsr = UART_LSR_TRANSMITTER_EMPTY | UART_LSR_TX_EMPTY
|
|
103
|
+
|
|
104
|
+
this.fifo_control = 0
|
|
105
|
+
|
|
106
|
+
// interrupts enable
|
|
107
|
+
this.ier = 0
|
|
108
|
+
|
|
109
|
+
// interrupt identification register
|
|
110
|
+
this.iir = UART_IIR_NO_INT
|
|
111
|
+
|
|
112
|
+
this.modem_control = 0
|
|
113
|
+
this.modem_status = 0
|
|
114
|
+
|
|
115
|
+
this.scratch_register = 0
|
|
116
|
+
|
|
117
|
+
this.irq = 0
|
|
118
|
+
|
|
119
|
+
this.input = []
|
|
120
|
+
|
|
121
|
+
this.current_line = ''
|
|
122
|
+
|
|
123
|
+
switch (port) {
|
|
124
|
+
case 0x3f8:
|
|
125
|
+
this.com = 0
|
|
126
|
+
this.irq = 4
|
|
127
|
+
break
|
|
128
|
+
case 0x2f8:
|
|
129
|
+
this.com = 1
|
|
130
|
+
this.irq = 3
|
|
131
|
+
break
|
|
132
|
+
case 0x3e8:
|
|
133
|
+
this.com = 2
|
|
134
|
+
this.irq = 4
|
|
135
|
+
break
|
|
136
|
+
case 0x2e8:
|
|
137
|
+
this.com = 3
|
|
138
|
+
this.irq = 3
|
|
139
|
+
break
|
|
140
|
+
default:
|
|
141
|
+
dbg_log('Invalid serial port: ' + h(port), LOG_SERIAL)
|
|
142
|
+
this.com = 0
|
|
143
|
+
this.irq = 4
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.bus.register(
|
|
147
|
+
'serial' + this.com + '-input',
|
|
148
|
+
(data: number): void => {
|
|
149
|
+
this.data_received(data)
|
|
150
|
+
},
|
|
151
|
+
this,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
this.bus.register(
|
|
155
|
+
'serial' + this.com + '-modem-status-input',
|
|
156
|
+
(data: number): void => {
|
|
157
|
+
this.set_modem_status(data)
|
|
158
|
+
},
|
|
159
|
+
this,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
// Set individual modem status bits
|
|
163
|
+
|
|
164
|
+
this.bus.register(
|
|
165
|
+
'serial' + this.com + '-carrier-detect-input',
|
|
166
|
+
(data: number): void => {
|
|
167
|
+
const status = data
|
|
168
|
+
? this.modem_status |
|
|
169
|
+
(1 << UART_MSR_DCD) |
|
|
170
|
+
(1 << UART_MSR_DDCD)
|
|
171
|
+
: this.modem_status &
|
|
172
|
+
~(1 << UART_MSR_DCD) &
|
|
173
|
+
~(1 << UART_MSR_DDCD)
|
|
174
|
+
this.set_modem_status(status)
|
|
175
|
+
},
|
|
176
|
+
this,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
this.bus.register(
|
|
180
|
+
'serial' + this.com + '-ring-indicator-input',
|
|
181
|
+
(data: number): void => {
|
|
182
|
+
const status = data
|
|
183
|
+
? this.modem_status |
|
|
184
|
+
(1 << UART_MSR_RI) |
|
|
185
|
+
(1 << UART_MSR_TERI)
|
|
186
|
+
: this.modem_status &
|
|
187
|
+
~(1 << UART_MSR_RI) &
|
|
188
|
+
~(1 << UART_MSR_TERI)
|
|
189
|
+
this.set_modem_status(status)
|
|
190
|
+
},
|
|
191
|
+
this,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
this.bus.register(
|
|
195
|
+
'serial' + this.com + '-data-set-ready-input',
|
|
196
|
+
(data: number): void => {
|
|
197
|
+
const status = data
|
|
198
|
+
? this.modem_status |
|
|
199
|
+
(1 << UART_MSR_DSR) |
|
|
200
|
+
(1 << UART_MSR_DDSR)
|
|
201
|
+
: this.modem_status &
|
|
202
|
+
~(1 << UART_MSR_DSR) &
|
|
203
|
+
~(1 << UART_MSR_DDSR)
|
|
204
|
+
this.set_modem_status(status)
|
|
205
|
+
},
|
|
206
|
+
this,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
this.bus.register(
|
|
210
|
+
'serial' + this.com + '-clear-to-send-input',
|
|
211
|
+
(data: number): void => {
|
|
212
|
+
const status = data
|
|
213
|
+
? this.modem_status |
|
|
214
|
+
(1 << UART_MSR_CTS) |
|
|
215
|
+
(1 << UART_MSR_DCTS)
|
|
216
|
+
: this.modem_status &
|
|
217
|
+
~(1 << UART_MSR_CTS) &
|
|
218
|
+
~(1 << UART_MSR_DCTS)
|
|
219
|
+
this.set_modem_status(status)
|
|
220
|
+
},
|
|
221
|
+
this,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
const io = cpu.io
|
|
225
|
+
|
|
226
|
+
io.register_write(
|
|
227
|
+
port,
|
|
228
|
+
this,
|
|
229
|
+
(out_byte: number): void => {
|
|
230
|
+
this.write_data(out_byte)
|
|
231
|
+
},
|
|
232
|
+
(out_word: number): void => {
|
|
233
|
+
this.write_data(out_word & 0xff)
|
|
234
|
+
this.write_data(out_word >> 8)
|
|
235
|
+
},
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
io.register_write(port | 1, this, (out_byte: number): void => {
|
|
239
|
+
if (this.line_control & DLAB) {
|
|
240
|
+
this.baud_rate = (this.baud_rate & 0xff) | (out_byte << 8)
|
|
241
|
+
dbg_log('baud rate: ' + h(this.baud_rate), LOG_SERIAL)
|
|
242
|
+
} else {
|
|
243
|
+
if (
|
|
244
|
+
(this.ier & UART_IIR_THRI) === 0 &&
|
|
245
|
+
out_byte & UART_IIR_THRI
|
|
246
|
+
) {
|
|
247
|
+
// re-throw THRI if it was masked
|
|
248
|
+
this.ThrowInterrupt(UART_IIR_THRI)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
this.ier = out_byte & 0xf
|
|
252
|
+
dbg_log('interrupt enable: ' + h(out_byte), LOG_SERIAL)
|
|
253
|
+
this.CheckInterrupt()
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
io.register_read(port, this, (): number => {
|
|
258
|
+
if (this.line_control & DLAB) {
|
|
259
|
+
return this.baud_rate & 0xff
|
|
260
|
+
} else {
|
|
261
|
+
let data = 0
|
|
262
|
+
|
|
263
|
+
if (this.input.length === 0) {
|
|
264
|
+
dbg_log('Read input empty', LOG_SERIAL)
|
|
265
|
+
} else {
|
|
266
|
+
data = this.input.shift()!
|
|
267
|
+
dbg_log('Read input: ' + h(data), LOG_SERIAL)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (this.input.length === 0) {
|
|
271
|
+
this.lsr &= ~UART_LSR_DATA_READY
|
|
272
|
+
this.ClearInterrupt(UART_IIR_CTI)
|
|
273
|
+
this.ClearInterrupt(UART_IIR_RDI)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return data
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
io.register_read(port | 1, this, (): number => {
|
|
281
|
+
if (this.line_control & DLAB) {
|
|
282
|
+
return this.baud_rate >> 8
|
|
283
|
+
} else {
|
|
284
|
+
return this.ier & 0xf
|
|
285
|
+
}
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
io.register_read(port | 2, this, (): number => {
|
|
289
|
+
let ret = this.iir & 0xf
|
|
290
|
+
dbg_log('read interrupt identification: ' + h(this.iir), LOG_SERIAL)
|
|
291
|
+
|
|
292
|
+
if (this.iir === UART_IIR_THRI) {
|
|
293
|
+
this.ClearInterrupt(UART_IIR_THRI)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (this.fifo_control & 1) ret |= 0xc0
|
|
297
|
+
|
|
298
|
+
return ret
|
|
299
|
+
})
|
|
300
|
+
io.register_write(port | 2, this, (out_byte: number): void => {
|
|
301
|
+
dbg_log('fifo control: ' + h(out_byte), LOG_SERIAL)
|
|
302
|
+
this.fifo_control = out_byte
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
io.register_read(port | 3, this, (): number => {
|
|
306
|
+
dbg_log('read line control: ' + h(this.line_control), LOG_SERIAL)
|
|
307
|
+
return this.line_control
|
|
308
|
+
})
|
|
309
|
+
io.register_write(port | 3, this, (out_byte: number): void => {
|
|
310
|
+
dbg_log('line control: ' + h(out_byte), LOG_SERIAL)
|
|
311
|
+
this.line_control = out_byte
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
io.register_read(port | 4, this, (): number => {
|
|
315
|
+
return this.modem_control
|
|
316
|
+
})
|
|
317
|
+
io.register_write(port | 4, this, (out_byte: number): void => {
|
|
318
|
+
dbg_log('modem control: ' + h(out_byte), LOG_SERIAL)
|
|
319
|
+
this.modem_control = out_byte
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
io.register_read(port | 5, this, (): number => {
|
|
323
|
+
dbg_log('read line status: ' + h(this.lsr), LOG_SERIAL)
|
|
324
|
+
return this.lsr
|
|
325
|
+
})
|
|
326
|
+
io.register_write(port | 5, this, (_out_byte: number): void => {
|
|
327
|
+
dbg_log('Factory test write', LOG_SERIAL)
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
io.register_read(port | 6, this, (): number => {
|
|
331
|
+
dbg_log('read modem status: ' + h(this.modem_status), LOG_SERIAL)
|
|
332
|
+
// Clear delta bits
|
|
333
|
+
this.modem_status &= 0xf0
|
|
334
|
+
return this.modem_status
|
|
335
|
+
})
|
|
336
|
+
io.register_write(port | 6, this, (out_byte: number): void => {
|
|
337
|
+
dbg_log('write modem status: ' + h(out_byte), LOG_SERIAL)
|
|
338
|
+
this.set_modem_status(out_byte)
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
io.register_read(port | 7, this, (): number => {
|
|
342
|
+
return this.scratch_register
|
|
343
|
+
})
|
|
344
|
+
io.register_write(port | 7, this, (out_byte: number): void => {
|
|
345
|
+
this.scratch_register = out_byte
|
|
346
|
+
})
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
get_state(): UARTState {
|
|
350
|
+
const state: UARTState = [
|
|
351
|
+
this.ints,
|
|
352
|
+
this.baud_rate,
|
|
353
|
+
this.line_control,
|
|
354
|
+
this.lsr,
|
|
355
|
+
this.fifo_control,
|
|
356
|
+
this.ier,
|
|
357
|
+
this.iir,
|
|
358
|
+
this.modem_control,
|
|
359
|
+
this.modem_status,
|
|
360
|
+
this.scratch_register,
|
|
361
|
+
this.irq,
|
|
362
|
+
]
|
|
363
|
+
|
|
364
|
+
return state
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
set_state(state: UARTState): void {
|
|
368
|
+
this.ints = state[0]
|
|
369
|
+
this.baud_rate = state[1]
|
|
370
|
+
this.line_control = state[2]
|
|
371
|
+
this.lsr = state[3]
|
|
372
|
+
this.fifo_control = state[4]
|
|
373
|
+
this.ier = state[5]
|
|
374
|
+
this.iir = state[6]
|
|
375
|
+
this.modem_control = state[7]
|
|
376
|
+
this.modem_status = state[8]
|
|
377
|
+
this.scratch_register = state[9]
|
|
378
|
+
this.irq = state[10]
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
CheckInterrupt(): void {
|
|
382
|
+
if (this.ints & (1 << UART_IIR_CTI) && this.ier & UART_IER_RDI) {
|
|
383
|
+
this.iir = UART_IIR_CTI
|
|
384
|
+
this.cpu.device_raise_irq(this.irq)
|
|
385
|
+
} else if (this.ints & (1 << UART_IIR_RDI) && this.ier & UART_IER_RDI) {
|
|
386
|
+
this.iir = UART_IIR_RDI
|
|
387
|
+
this.cpu.device_raise_irq(this.irq)
|
|
388
|
+
} else if (
|
|
389
|
+
this.ints & (1 << UART_IIR_THRI) &&
|
|
390
|
+
this.ier & UART_IER_THRI
|
|
391
|
+
) {
|
|
392
|
+
this.iir = UART_IIR_THRI
|
|
393
|
+
this.cpu.device_raise_irq(this.irq)
|
|
394
|
+
} else if (this.ints & (1 << UART_IIR_MSI) && this.ier & UART_IER_MSI) {
|
|
395
|
+
this.iir = UART_IIR_MSI
|
|
396
|
+
this.cpu.device_raise_irq(this.irq)
|
|
397
|
+
} else {
|
|
398
|
+
this.iir = UART_IIR_NO_INT
|
|
399
|
+
this.cpu.device_lower_irq(this.irq)
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
ThrowInterrupt(line: number): void {
|
|
404
|
+
this.ints |= 1 << line
|
|
405
|
+
this.CheckInterrupt()
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
ClearInterrupt(line: number): void {
|
|
409
|
+
this.ints &= ~(1 << line)
|
|
410
|
+
this.CheckInterrupt()
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
data_received(data: number): void {
|
|
414
|
+
dbg_log('input: ' + h(data), LOG_SERIAL)
|
|
415
|
+
this.input.push(data)
|
|
416
|
+
|
|
417
|
+
this.lsr |= UART_LSR_DATA_READY
|
|
418
|
+
|
|
419
|
+
if (this.fifo_control & 1) {
|
|
420
|
+
this.ThrowInterrupt(UART_IIR_CTI)
|
|
421
|
+
} else {
|
|
422
|
+
this.ThrowInterrupt(UART_IIR_RDI)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
write_data(out_byte: number): void {
|
|
427
|
+
if (this.line_control & DLAB) {
|
|
428
|
+
this.baud_rate = (this.baud_rate & ~0xff) | out_byte
|
|
429
|
+
return
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
dbg_log('data: ' + h(out_byte), LOG_SERIAL)
|
|
433
|
+
|
|
434
|
+
this.ThrowInterrupt(UART_IIR_THRI)
|
|
435
|
+
|
|
436
|
+
if (this.modem_control & UART_MCR_LOOPBACK) {
|
|
437
|
+
this.data_received(out_byte)
|
|
438
|
+
} else {
|
|
439
|
+
this.bus.send('serial' + this.com + '-output-byte', out_byte)
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (DEBUG) {
|
|
443
|
+
const char = String.fromCharCode(out_byte)
|
|
444
|
+
this.current_line += char
|
|
445
|
+
|
|
446
|
+
if (char === '\n') {
|
|
447
|
+
const line = this.current_line
|
|
448
|
+
.trimRight()
|
|
449
|
+
// eslint-disable-next-line no-control-regex
|
|
450
|
+
.replace(/[\x00-\x08\x0b-\x1f\x7f\x80-\xff]/g, '')
|
|
451
|
+
dbg_log('SERIAL: ' + line)
|
|
452
|
+
this.current_line = ''
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
set_modem_status(status: number): void {
|
|
458
|
+
dbg_log('modem status: ' + h(status), LOG_SERIAL)
|
|
459
|
+
const prev_delta_bits = this.modem_status & 0x0f
|
|
460
|
+
// compare the bits that have changed and shift them into the delta bits
|
|
461
|
+
let delta = (this.modem_status ^ status) >> 4
|
|
462
|
+
// The delta should stay set if they were previously set
|
|
463
|
+
delta |= prev_delta_bits
|
|
464
|
+
|
|
465
|
+
// update the current modem status
|
|
466
|
+
this.modem_status = status
|
|
467
|
+
// update the delta bits based on the changes and previous
|
|
468
|
+
// values, but also leave the delta bits set if they were
|
|
469
|
+
// passed in as part of the status
|
|
470
|
+
this.modem_status |= delta
|
|
471
|
+
}
|
|
472
|
+
}
|