From 1a77f3bedd5d9608d077a9bce1d002e17e4e37a8 Mon Sep 17 00:00:00 2001 From: Bryce Denney Date: Sun, 11 Nov 2001 22:55:02 +0000 Subject: [PATCH] - parallel port patch from Volker Ruppert --- bochs/patches/patch.parport | 299 ++++++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 bochs/patches/patch.parport diff --git a/bochs/patches/patch.parport b/bochs/patches/patch.parport new file mode 100644 index 000000000..fef49c940 --- /dev/null +++ b/bochs/patches/patch.parport @@ -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 */ + }