- parallel port patch from Volker Ruppert

This commit is contained in:
Bryce Denney 2001-11-11 22:55:02 +00:00
parent 0d632755fe
commit 1a77f3bedd
1 changed files with 299 additions and 0 deletions

299
bochs/patches/patch.parport Normal file
View File

@ -0,0 +1,299 @@
--- ../bochs/bios/rombios.c Sat Oct 6 21:38:48 2001
+++ bios/rombios.c Sun Nov 11 20:07:04 2001
@@ -246,6 +246,7 @@
static void int13_diskette_function();
static void int15_function();
static void int16_function();
+static void int17_function();
static void int1a_function();
static void int70_function();
static void int74_function();
@@ -3174,6 +3175,48 @@
}
void
+int17_function(regs, ds, iret_addr)
+ pusha_regs_t regs; // regs pushed from PUSHA instruction
+ Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
+ iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call
+{
+ Bit16u addr;
+ Bit8u timeout,val8;
+
+ #asm
+ sti
+ #endasm
+
+ if ((regs.u.r8.ah < 3) && (regs.u.r16.dx == 0)) {
+ addr = read_word(0x0040, 0x0008);
+ timeout = read_byte(0x0040, 0x0078);
+ if (regs.u.r8.ah == 0) {
+ outb(addr, regs.u.r8.al);
+ val8 = inb(addr+2);
+ val8 |= 0x01;
+ outb(addr+2, val8); // send strobe
+ // one microsecond pause should be here
+ outb(addr+2, val8 & 0xFE);
+ while ((timeout--) && ((inb(addr+1) & 0x40) == 0x40)) {}
+ }
+ if (regs.u.r8.ah == 1) {
+ val8 = inb(addr+2);
+ val8 &= 0xFB;
+ outb(addr+2, val8); // send init
+ outb(addr+2, val8 | 0x04);
+ }
+ regs.u.r8.ah = inb(addr+1);
+ val8 = (~regs.u.r8.ah & 0x48);
+ regs.u.r8.ah &= 0xB7;
+ regs.u.r8.ah |= val8;
+ if (!timeout) regs.u.r8.ah |= 0x01;
+ ClearCF(iret_addr.flags);
+ } else {
+ SetCF(iret_addr.flags); // Unsupported
+ }
+}
+
+ void
int1a_function(regs, ds, iret_addr)
pusha_regs_t regs; // regs pushed from PUSHA instruction
Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
@@ -4207,13 +4250,17 @@
SET_INT_VECTOR(0x0F, #0xF000, #dummy_iret_handler)
mov ax, #0x0000
mov ds, ax
- mov 0x408, AX ; Parallel I/O address, port 1
+ mov 0x408, #0x378 ; Parallel I/O address, port 1
mov 0x40A, AX ; Parallel I/O address, port 2
mov 0x40C, AX ; Parallel I/O address, port 3
- mov 0x478, AL ; Parallel printer 1 timeout
- mov 0x479, AL ; Parallel printer 2 timerout
- mov 0x47A, AL ; Parallel printer 3 timerout
- mov 0x47B, AL ; Parallel printer 4 timerout
+ mov 0x478, #0x14 ; Parallel printer 1 timeout
+ mov 0x479, AL ; Parallel printer 2 timeout
+ mov 0x47A, AL ; Parallel printer 3 timeout
+ mov 0x47B, AL ; Parallel printer 4 timeout
+ mov AX, 0x410 ; Equipment word bits 14..15 determing # parallel ports
+ and AX, #0x3fff
+ or AX, #0x4000 ; one parallel port
+ mov 0x410, AX
;; Serial setup
SET_INT_VECTOR(0x0C, #0xF000, #dummy_iret_handler)
@@ -4607,7 +4654,14 @@
;----------------------------------------
.org 0xefd2
int17_handler:
- iret ;; for now...
+ push ds
+ pusha
+ mov ax, #0x0000
+ mov ds, ax
+ call _int17_function
+ popa
+ pop ds
+ iret
.org 0xf045 ; INT 10 Functions 0-Fh Entry Point
HALT(__LINE__)
--- ../bochs/iodev/parallel.h Wed Oct 3 17:40:44 2001
+++ iodev/parallel.h Sun Nov 11 20:37:59 2001
@@ -33,6 +33,23 @@
# define BX_PAR_THIS this->
#endif
+typedef struct {
+ Bit8u data;
+ struct {
+ Boolean error;
+ Boolean slct;
+ Boolean pe;
+ Boolean ack;
+ Boolean busy;
+ } STATUS;
+ struct {
+ Boolean strobe;
+ Boolean autofeed;
+ Boolean init;
+ Boolean slct_in;
+ Boolean irq;
+ } CONTROL;
+} bx_par_t;
@@ -44,12 +61,13 @@
BX_PAR_SMF void init(bx_devices_c *);
private:
+ FILE *output;
- struct {
- unsigned unused; // filler for now
- } s;
+ bx_par_t s;
bx_devices_c *devices;
+
+ static void virtual_printer();
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
--- ../bochs/iodev/parallel.cc Wed Oct 3 17:40:44 2001
+++ iodev/parallel.cc Sun Nov 11 20:47:05 2001
@@ -30,6 +30,7 @@
#include "bochs.h"
#define LOG_THIS bx_parallel.
+#define OUTPUT BX_PAR_THIS output
bx_parallel_c bx_parallel;
@@ -47,32 +48,55 @@
bx_parallel_c::~bx_parallel_c(void)
{
- // nothing for now
+ fclose(OUTPUT);
}
void
bx_parallel_c::init(bx_devices_c *d)
{
- BX_DEBUG(("Init $Id: parallel.cc,v 1.8 2001/10/03 13:10:38 bdenney Exp $"));
+ BX_DEBUG(("Init $Id: parallel.cc,v 1.8 2001/10/03 13:10:38 bdenney Exp $"));
BX_PAR_THIS devices = d;
-#if 0
/* PARALLEL PORT 1 */
BX_PAR_THIS devices->register_irq(7, "Parallel Port 1");
- for (unsigned addr=0x03BC; addr<=0x03BE; addr++) {
- BX_PAR_THIS devices->register_io_read_handler(this,
- read_handler,
- addr, "Parallel Port 1");
- BX_PAR_THIS devices->register_io_write_handler(this,
- write_handler,
- addr, "Parallel Port 1");
- }
-#endif
+ BX_PAR_THIS devices->register_io_read_handler(this,
+ read_handler, 0x0379, "Parallel Port 1");
+ BX_PAR_THIS devices->register_io_read_handler(this,
+ read_handler, 0x037A, "Parallel Port 1");
+ BX_PAR_THIS devices->register_io_write_handler(this,
+ write_handler, 0x0378, "Parallel Port 1");
+ BX_PAR_THIS devices->register_io_write_handler(this,
+ write_handler, 0x037A, "Parallel Port 1");
+
+ BX_PAR_THIS s.STATUS.error = 1;
+ BX_PAR_THIS s.STATUS.slct = 1;
+ BX_PAR_THIS s.STATUS.pe = 0;
+ BX_PAR_THIS s.STATUS.ack = 1;
+ BX_PAR_THIS s.STATUS.busy = 1;
+
+ BX_PAR_THIS s.CONTROL.strobe = 0;
+ BX_PAR_THIS s.CONTROL.autofeed = 0;
+ BX_PAR_THIS s.CONTROL.init = 1;
+ BX_PAR_THIS s.CONTROL.slct_in = 1;
+ BX_PAR_THIS s.CONTROL.irq = 0;
+
+ OUTPUT = fopen("parport.out", "w");
}
+ void
+bx_parallel_c::virtual_printer(void)
+{
+ fprintf(OUTPUT, "%c", BX_PAR_THIS s.data);
+ if (BX_PAR_THIS s.CONTROL.irq == 1) {
+ BX_PAR_THIS devices->pic->trigger_irq(7);
+ }
+ BX_PAR_THIS s.STATUS.ack = 0;
+ BX_PAR_THIS s.STATUS.busy = 1;
+}
+
// static IO port read callback handler
// redirects to non-static class handler to avoid virtual functions
@@ -92,9 +116,35 @@
#else
UNUSED(this_ptr);
#endif // !BX_USE_PAR_SMF
- UNUSED(address);
- UNUSED(io_len);
+ if (io_len == 1) {
+ switch (address) {
+ case 0x0379:
+ {
+ Bit32u retval;
+ retval = ((BX_PAR_THIS s.STATUS.busy << 7) |
+ (BX_PAR_THIS s.STATUS.ack << 6) |
+ (BX_PAR_THIS s.STATUS.pe << 5) |
+ (BX_PAR_THIS s.STATUS.slct << 4) |
+ (BX_PAR_THIS s.STATUS.error << 3));
+ BX_PAR_THIS s.STATUS.ack = 1;
+ if (BX_PAR_THIS s.CONTROL.irq == 1) {
+ BX_PAR_THIS devices->pic->untrigger_irq(7);
+ }
+ return retval;
+ }
+ break;
+ case 0x037A:
+ {
+ return ((BX_PAR_THIS s.CONTROL.irq << 4) |
+ (BX_PAR_THIS s.CONTROL.slct_in << 3) |
+ (BX_PAR_THIS s.CONTROL.init << 2) |
+ (BX_PAR_THIS s.CONTROL.autofeed << 1) |
+ (BX_PAR_THIS s.CONTROL.strobe));
+ }
+ break;
+ }
+ }
/* PARALLEL PORT 1 */
return(0);
}
@@ -118,8 +168,38 @@
#else
UNUSED(this_ptr);
#endif // !BX_USE_PAR_SMF
- UNUSED(address);
- UNUSED(value);
- UNUSED(io_len);
+
+ if (io_len == 1) {
+ switch (address) {
+ case 0x0378:
+ {
+ BX_PAR_THIS s.data = (Bit8u)value;
+ }
+ break;
+ case 0x037A:
+ {
+ if ((value & 0x01) == 1) {
+ if (BX_PAR_THIS s.CONTROL.strobe == 0) {
+ BX_PAR_THIS s.CONTROL.strobe = 1;
+ virtual_printer(); // data is valid now
+ }
+ } else {
+ if (BX_PAR_THIS s.CONTROL.strobe == 1) {
+ BX_PAR_THIS s.CONTROL.strobe = 0;
+ }
+ }
+ BX_PAR_THIS s.CONTROL.autofeed = ((value & 0x02) == 1);
+ BX_PAR_THIS s.CONTROL.init = ((value & 0x04) == 1);
+ BX_PAR_THIS s.CONTROL.slct_in = ((value & 0x08) == 1);
+ BX_PAR_THIS s.STATUS.slct = BX_PAR_THIS s.CONTROL.slct_in;
+ if ((value & 0x10) == 0x10) {
+ BX_PAR_THIS s.CONTROL.irq = 1;
+ } else {
+ BX_PAR_THIS s.CONTROL.irq = 0;
+ }
+ }
+ break;
+ }
+ }
/* PARALLEL PORT 1 */
}