marks@elec.uq.oz (Mark Schulz) (09/22/88)
Please reply to hannam.uq.oz . I'm using someone elses account to post this. echo x - read_me sed 's/^X//' >read_me <<'*-*-END-of-read_me-*-*' XPlease reply to hannam.uq.oz . I'm using someone elses account to post Xthis. X XThis is a brand new tty driver. It is vastly superier to the original V1.3 Xin performance (throughput speed). It takes a significant amount of Xrecompiling to install the new driver but the results are worthwhile. The Xrest of the kernel has hardly been touched at all except to improve Xinterrupt latency by removing non-essential locks. XThe tty driver is split into 3 files ... Xtty1.c - contains all the device independent code. (this is truly device X independent and it should be very easy to add a new X low level driver for some other strange device you may have X connected to your PC). Two examples of low level drivers X are given, tty2.c (console) and tty3.c (rs232 using an 8250). Xtty2.c - contains the console driver. This supports a very large subset of X ANSI (it's missing scrolling regions, printer port etc). X Note that insert line and delete line + insert chars, delete X chars + insert mode are fully supported etc. X The cludgy EGA patches that have been floating around the X network are NOT in this version. This version has been X written properly from the start to handle such cards as EGA. X All scrolling is via hardware scrolling, there is no X software scrolling available. For those that have EGA cards X and find this excessivly fast there is a function key that X enables you to toggle between CGA type video access and the X faster EGA access's. X The function keys have been given their proper ANSI codes X and so the special keys have been moved to <Cntrl> <alt> Fx X keys. The <Alt> Fx keys, <Shift> <Alt> Fx , <Cntrl> Fx & X <Shift> Fx keys have been given pre-defined key macros. X At present they can only be reprogrammed at compile time. X The special Fx keys are: X <Cntrl> <Alt> F1 - process map X <Cntrl> <Alt> F2 - memory map X <Cntrl> <Alt> F3 - EGA/ ??? toggle X <Cntrl> <Alt> F4 - amoeba init (if defined) X <Cntrl> <Alt> F9 - kill -9 -1 X As a general point, the scancode to ascii translation routine, X whilst defined in the tty file, is a general translation routine X and could be used on any terminal. The interface has been produced X such that it is possible to add any translation routine very simply. X This translation routine interface has facilities for generating macros X (such as is used for the arrow, Fn, and general macros for the console) X . For Example, an EBDIC to ascii converter may be worth while. X At some lator date some one may add an ioctl call to allow the X translation routine to be changed from amongst a small set provided X by the kernel. Xtty3.c - The rs232 driver routines for the standard PC. This is significantly X superior in performance to the original V1.3 . It also includes both X xonxoff handshaking and hardware handshaking. X X Two # variables are used to control the compilation ... X #ifdef ... X SLOW - default baud = 1200 (normally 4800) X NXONXOFF - default handshaking is hardware (normally xonxoff). X X For the TX, hardware handshaking will not work over a 3 wire cable X so xonxoff is generally best. (Blame the PC hardware.) X For the RX, xonxoff is handled by the high level driver (in COOKED X or CBREAK only). Hardware handshaking works irrespective of the X cable connected so generally hardware is the best. (xonxoff is X still handled by the high level driver in hardware handshaking modes). X X These routines have been used upto 38400 to non IBM-PC machines X and upto 57600 between PC's. (I haven't tried at 115200 although X it is defined). Note - these are NOT throughput figures just speeds X at which it will still operate reliably. X XThe total compiled code is approximately 1K larger than the old V1.3 but Xit includes many many new features in that 1K. For Example, LCASE, CTLECH XDECCTQ, CRTBS, CRTERA, CRTKIL, PRTERA etc etc are included (as well as the Xrs232 flow control and the extra console ANSI codes.) The source code is Xalmost exactly the same size (for the tty files). X XThe misfeatures in the V1.3 tty driver that prompted the rewrite are ... X1/ Only one process is allowed to write to the tty at once X (and read but it really doesn't make sence for more than one to read) X2/ Grossly inefficient and messy code (in my opinion) X3/ No flow control on the rs232 lines X4/ If a reader requests more chars than we can hold in our input buffer, X and the user doesn't type a nl before the tty buffer overflows X then the terminal hangs permanently. X5/ A similiar problem to the above except on output. X6/ If a serial line is overrun (starts to lose characters) then every X terminal on the system will start to lose characters X7/ Insufficient range of ioctl calls to implement any decent screen driving X package (or even kermit without patching the kernel). X XA new ioctl.c has been provided for the libraries ... X This means any program that uses ioctl will need to be recompiled. X MINED relies on no EOL wrap when compiled without termcap. The X new tty driver has EOL wrap so change the init string in mined X to include the escape codes to turn off EOL wrap ("ESC [ 7 l" I X think from memory - see tty2.c) and possibly change the exit X string to turn it back on again. This is simple enough for X most people to patch by hand (my mined is not standard any more X or I would patch a diff) X A new version of STTY has also been provided to show some of the X new features. X LOGIN has been fixed severly (little to do with the change in tty) X and TERM has been fixed for the new TTY. X XONXOFF is a short program that enables you to change between X hardware and xonxoff handshaking. X Full files have been provided for all the above (rather than diffs) X as the diff files are almost as long or longer. Xmpx88.asd is a diff file relative to my assembler (not MINIX). It should X be obvious how to patch your own mpx88.??? Xklib88.as is the full listing using my assembler ... to convert to X whatever you use (I would appreciate it if someone did this for the X standard MINIX assembler and posted it.) X Note carefully when interrupts etc are turned off. X Some notes on my C - compiler ... X it expects cs,ds,ss,sp,bp,si,di to be unaltered upon return, X es, ax, bx, cx, dx can be altered without harm. X ax is the return register for ints etc and ax,dx for longs. X XFILES: Xread_me - this file (documentation) Xsgtty.h - replacement for h/sgtty.h, <sgtty.h>, <minix/sgtty.h> Xioctl.c - replacement for lib/ioctl.c Xstty.c - replacement for commands/stty.c Xlogin.c - replacement for commands/login.c Xterm.c - replacement for commands/term.c Xxonxoff.c - new in commands Xtty.h - new in kernel Xbuffer.h - new in kernel Xtty1.c - new in kernel Xtty2.c - new in kernel Xtty3.c - new in kernel Xtty.c - deleted from kernel Xklib88.as - replacement for kernel/klib88.as Xmpx88.asd - diff file on kernel/mpx88.as Xtable.cd - diff file on kernel/table.c X /* Thanks to hedrick@athos.rutgers.edu (Charles Hedrick) X * for these interrupt latency reducing sections X * (and bug fix for printer.c). X */ Xprinter.cd - diff file on kernel/printer.c Xat_wini.cd - diff file on kernel/at_wini.c Xxt_wini.cd - diff file on kernel/xt_wini.c *-*-END-of-read_me-*-* echo x - buffer.h sed 's/^X//' >buffer.h <<'*-*-END-of-buffer.h-*-*' X/* buffer.h - buffer routines X * X * Written by: A.Hannam (Jul 1987) X * X * Modifications: X */ X X/* X * This header file provides some definitions and macro's for buffer X * handling. They compile to very few instructions and should be very X * fast. The macro's are not protected from interrupt type access and X * should be used inside exclusion locks for this type of work. X * No error checking is done to see if there are any valid objects X * or if the buffer is full on reads or writes etc. X */ X X/****************************************************************************/ X X/* Macros to define the types. X * Also defines 'bool' type and the 'between' function macro. X */ X Xtypedef unsigned char bool; X#ifndef TRUE X# define TRUE 1 /* Really any non zero is true */ X#endif X#ifndef FALSE X# define FALSE 0 X#endif X X#define between(a,b,c) ((b < a) ? a : ((b > c) ? c : b)) X X /* Object FIFO - size <= 128 && power of 2 */ X#define GEN_S_BUF_TYPE(obj,size) \ Xtypedef struct { \ X obj b[size]; \ X unsigned char in, out, count; \ X } obj/**/size; X X /* Object FIFO - size >= 256 && power of 2 */ X#define GEN_L_BUF_TYPE(obj,size) \ Xtypedef struct { \ X obj b[size]; \ X unsigned in, out, count; \ X } obj/**/size; X X/***************************************************************************/ X X/* Fast Buffers - The macros provide fast access "getting" or "putting" X * for objects. (Not Both !!). Use the Macro's defined where the X * speed is desired. To access on the slow side, copy to another fbuf X * variable, re-initialize the original and then use loops to access X * the objects from the copy. These routines are ideal where one side is X * an interrupt handler. X * Note: the fast "getting" macros assume the objects are stored in X * reverse order. X */ X X X /* Fast Buffer - size <= 128 && power of 2 */ X#define GEN_S_FBUF_TYPE(obj,size) \ Xtypedef struct { \ X obj b[size]; \ X unsigned char count; \ X } f/**/obj/**/size; X X /* Fast Buffer - size >= 256 && power of 2 */ X#define GEN_L_FBUF_TYPE(obj,size) \ Xtypedef struct { \ X obj b[size]; \ X unsigned count; \ X } f/**/obj/**/size; X X/***************** Routines to act on all the types defined above ************/ X X#define bufsize(buf) (sizeof((buf).b)/sizeof((buf).b[0]))/* max obj's in buf */ X#define bufcount(buf) ((buf).count) /* objects in buf */ X#define bufempty(buf) (!((buf).count)) /* buf is empty */ X#define bufnempty(buf) ((buf).count) /* buf is not empty */ X#define buffull(buf) ((buf).count >= bufsize(buf)) /* buf is full */ X#define bufnfull(buf) ((buf).count < bufsize(buf)) /* buf is not full. */ X X/*********************** These work on the FIFO buffers **********************/ X X /* bufinit - initialize the buffer */ X#define bufinit(buf) (buf).count= (buf).out= (buf).in= 0 /* initialize buf */ X X /* getobj - Non Destructive Read */ X#define getobj(buf) (buf).b[(buf).out] X X /* advgetobj - advances the FIFO pointers after getobj */ X#define advgetobj(buf) (buf).count--;(buf).out++;(buf).out &= (bufsize(buf) -1) X X /* putobj - Write to FIFO */ X#define putobj(buf,obj) \ X (buf).b[(buf).in++]= (obj); (buf).count++; (buf).in &= (bufsize(buf) -1) X X/*********************** These work on the Fast Buffers **********************/ X X /* fbufinit - initialize the fbuf */ X#define fbufinit(fbuf) (fbuf).count= 0 X X /* putfobj - Fast Write to fbuf */ X#define putfobj(fbuf,obj) (fbuf).b[(fbuf).count++]= (obj) X X /* copyfobj - Transfer the data to safety */ X#define copyfobj(fbuf1,fbuf2) (fbuf1)=(fbuf2) X X /* getfobj - Fast (Destructive) Read from fbuf */ X#define getfobj(fbuf) (fbuf).b[--(fbuf).count] X X/*****************************************************************************/ *-*-END-of-buffer.h-*-* echo x - sgtty.h sed 's/^X//' >sgtty.h <<'*-*-END-of-sgtty.h-*-*' X/* sgtty.h - ioctl information X * X * Written by: A.Hannam (Feb 1988) X * X * Modifications: X * 21/8/88 - Modified for MINIX V1.3 on IBM-PC X * support new tty driver X */ X X/* Data structures for IOCTL. */ X Xstruct sgttyb { X char sg_ispeed; /* input speed */ X char sg_ospeed; /* output speed */ X char sg_erase; /* erase character */ X char sg_kill; /* kill character */ X int sg_flags; /* mode flags */ X}; X Xstruct tchars { X char t_intrc; /* SIGINT char */ X char t_quitc; /* SIGQUIT char */ X char t_startc; /* start output (initially CTRL-Q) */ X char t_stopc; /* stop output (initially CTRL-S) */ X char t_eofc; /* EOF (initially CTRL-D) */ X char t_brkc; /* input delimiter (like nl) */ X}; X X#define IOC_IN 0x0080 X#define IOC_OUT 0x8000 X#define IOC_VOID 0x0000 X#define _IOWR(x,y,t) (IOC_OUT | IOC_IN | ('x'<<8) | y) X#define _IOR(x,y,t) (IOC_OUT | ('x'<<8) | y) X#define _IOW(x,y,t) (IOC_IN | ('x'<<8) | y) X#define _IO(x,y) (IOC_VOID | ('x'<<8) | y) X X#define TIOCMODG _IOR(t, 3, int) /* Get/Set modem control state */ X#define TIOCMODS _IOW(t, 4, int) X#define TIOCM_LE 0001 /* line enable (ignored) */ X#define TIOCM_DTR 0002 /* data terminal ready */ X#define TIOCM_RTS 0004 /* request to send */ X#define TIOCM_ST 0010 /* secondary transmit (ignored) */ X#define TIOCM_SR 0020 /* secondary recieve (ignored) */ X#define TIOCM_CTS 0040 /* clear to send */ X#define TIOCM_CAR 0100 /* carrier detect */ X#define TIOCM_CD TIOCM_CAR X#define TIOCM_RNG 0200 /* ring indicater */ X#define TIOCM_RI TIOCM_RNG X#define TIOCM_DSR 0400 /* data set ready */ X#define TIOCGETP _IOR(t, 8, struct sgttyb) /* Get/Set parameters */ X#define TIOCSETP _IOW(t, 9, struct sgttyb) X#define TIOCSETN _IOW(t, 10, struct sgttyb) /* as above but don't flush */ X /* sg_ispeed/sg_ospeed - Baud Rates */ X#define NO_BAUDS 19 /* there are 19 different speeds */ X#define B00 0 /* no such baud rate */ X#define B45 1 /* really 45.5 */ X#define B50 2 X#define B75 3 X#define B110 4 X#define B134 5 /* really 134.5 */ X#define B150 6 X#define B200 7 /* Not all of these will necessarily be */ X#define B300 8 /* implemented. */ X#define B600 9 /* E.g. The console ignores these bauds. */ X#define B1200 10 X#define B1800 11 X#define B2000 12 X#define B2400 13 X#define B4800 14 X#define B9600 15 X#define B19200 16 X#define B38400 17 X#define B57600 18 X#define B115200 19 X /* sg_flags - Terminal Mode Flags */ X#define TOSTOP 0x8000 /* SIGSTOP (SIGBUS in MINIX) on backgnd outpt*/ X#define DECCTQ 0x4000 /* only ^Q starts after ^S */ X#define CTLECH 0x2000 /* echo control chars as ^X */ X#define CRTKIL 0x1000 /* kill line with "\b \b" */ X#define XTABS 0x0800 /* do tab expansion */ X#define CRTERA 0x0400 /* "\b \b" to wipe out char */ X#define PRTERA 0x0200 /* \ .. / to wipe out chars */ X#define CRTBS 0x0100 /* "\b" to wipe out chars */ X#define ANYP 0x00C0 /* rec any, send no parity */ X#define EVENP 0x0080 /* rec/send even parity */ X#define ODDP 0x0040 /* rec/send odd parity */ X#define RAW 0x0020 /* enable raw mode */ X#define CRMOD 0x0010 /* map lf to cr + lf */ X#define ECHO 0x0008 /* echo input */ X#define LCASE 0x0004 /* simulate lower case */ X#define CBREAK 0x0002 /* enable cbreak mode */ X#define NOHANG 0x0001 /* no SIGHUP on carrier drop */ X#define COOKED 0x0000 /* neither CBREAK nor RAW */ X#define NONEP 0x0000 /* neither EVENP or ODDP or ANYP (no parity) */ X#define TIOCSETC _IOW(t, 17, struct tchars) /* Get/Set chars */ X#define TIOCGETC _IOR(t, 18, struct tchars) X X/* Locals from 127 down */ X#define TIOCGETM _IOR(t, 127, int) /* Get/Set Device Modes */ X#define TIOCSETM _IOW(t, 126, int) X /* Flags for TIOCGETM/TIOCSETM */ X#define D_CONSOLE 0x0100 /* This is the console terminal */ X#define CON_COOK8 0x0001 /* Generate 8 bits in cooked modes */ X#define CON_LOCK 0x0002 /* Console keyboard is locked */ X#define CON_WRAP 0x0004 /* Console does EOL wrap & BS wrap */ X#define CON_INSERT 0x0008 /* Console is in insert mode */ X#define D_SERIAL 0x0200 /* This is a async serial terminal */ X#define SER_DATABITS 0x0003 /* Mask for the no. of data bits */ X#define SER_5DATA 0x0000 /* Generate 5 data bits */ X#define SER_6DATA 0x0001 /* Generate 6 data bits */ X#define SER_7DATA 0x0002 /* Generate 7 data bits */ X#define SER_8DATA 0x0003 /* Generate 8 data bits */ X#define SER_1STOP 0x0000 /* Generate 1 stop bit */ X#define SER_2STOP 0x0004 /* Generate 2 stop bits */ X#define RX_XONXOFF 0x0008 /* Use xon-xoff RX flow cntrl */ X#define TX_XONXOFF 0x0010 /* Use only xon-xoff TX flow cntrl */ X X#define TIOCSBRK _IO(t, 123) /* set break bit */ X#define TIOCCBRK _IO(t, 122) /* clear break bit */ X#define TIOCSDTR _IO(t, 121) /* set data terminal ready */ X#define TIOCCDTR _IO(t, 120) /* clear data terminal ready */ X#define TIOCSTI _IOW(t, 114, char) /* simulate terminal input */ X#define TIOCSTOP _IO(t, 111) /* simulate ^S */ X#define TIOCSTART _IO(t, 110) /* simulate ^Q */ X#define TIOCSMLB _IO(t, 104) /* turn on loopback mode */ X#define TIOCCMLB _IO(t, 103) /* turn off loopback mode */ X X#define FIONREAD _IOR(f, 102, unsigned)/* # of chars in input queue */ *-*-END-of-sgtty.h-*-* echo x - tty.h sed 's/^X//' >tty.h <<'*-*-END-of-tty.h-*-*' X/* tty.h - include file for tty driver X * X * Written by: A.Hannam (Feb 1988) X * X * Modifications: X * 21/8/88 - Modified for MINIX V1.3 on IBM-PC X * Added flush-flag etc to allow flushing by clock X */ X X#include "buffer.h" X X#ifndef SIGSTOP /* not implemented yet */ X#define SIGSTOP SIGBUS /* use SIGBUS for SIGSTOP in MINIX */ X#endif X X /* The types of terminal known about so far */ X#define NR_CONS 1 /* No of console terminals */ X#define NR_8250S 1 /* No of 8250 serial terms */ X#define NR_TTYS NR_CONS + NR_8250S /* Total No of terminals */ X X/* Description of the above terminals - tty_struct[] Numbers */ X#define CON1 0 /* Console - 1 of NR_CONS */ X#define COM1 NR_CONS+0 /* Serial - 1 of NR_8250S */ X#define COM2 NR_CONS+1 /* Serial - 2 of NR_8250S */ X#define COM3 NR_CONS+2 /* Serial - 3 of NR_8250S */ X#define COM4 NR_CONS+3 /* Serial - 4 of NR_8250S */ X/* Next type of device will be "NR_CONS + NR_8250S + 0" etc */ X X#ifdef HIGH_LEVEL X /* Their initialization routines */ Xextern void init_con(), init_8250(); Xstatic void (*dev_init[NR_TTYS])()= { X init_con, init_8250 X }; X Xint flush_flag; /* Chars are ready for input or needed for output */ X X#else X extern flush_flag; X#endif X X /* Info that must be stored to enable backspacing in cooked modes */ Xtypedef struct charpos { X unsigned char ch,col; X } charpos; X X /* These lines set the size of tty_entry */ XGEN_S_BUF_TYPE(charpos,128) XGEN_S_FBUF_TYPE(char,32) X#define MAX_WRITERS 3 X X /* Provide a name for the fbuf that gives no indication of size */ Xtypedef fchar32 charfbuf; X#define CHAR_BUF_THRESHOLD 28 /* Flush if more than this many chars*/ X X /* The definition of a tty_entry */ Xtypedef struct { X /* Input queue. Typed characters are stored here until read by a program. */ X charpos128 tty_inbuf; /* buffer used to store the processed chars */ X int tty_lfct; /* # line feeds in tty_inbuf */ X X /* Information about incomplete read requests is stored here. */ X char tty_incaller; /* process that made the call (usually FS) */ X char tty_inproc; /* process that wants to read from tty */ X int tty_inseg; /* segment of address where data is to go */ X int tty_inoffset; /* offset of address where data is to go */ X int tty_inleft; /* how many chars are still needed */ X int tty_incum; /* the number of chars transfered so far */ X X /* Information about incomplete write requests is stored here. */ X struct writers { X char otcaller; /* process that made the call (usually FS) */ X char outproc; /* process that wants to write to tty */ X int seg; /* seg of address where data comes from */ X int offset; /* offset of address where data comes from */ X int outleft; /* # chars yet to be copied to tty_outqueue */ X } w[MAX_WRITERS]; X int tty_writers; /* no of process's currently trying to write */ X int tty_cum; /* # chars sent to output device so far */ X X /* Information specific to this terminal */ X bool (*tty_devraw)(); /* routine to do raw device output (tp,c,p) */ X#define WRITE_OUT 0 /* use the write stream */ X#define ECHO_OUT 1 /* use the echo stream */ X void (*tty_devclr)(); /* routine to clear raw output buffers (tp) */ X void (*tty_devflush)(); /* routine to flush raw output buffers (tp) */ X void (*tty_devempty)(); /* routine to say raw input bufs clear (tp) */ X void (*tty_devioctl)(); /* routine to do raw device ioctl's (tp,&m) */ X unsigned (*tty_devtrans)(); /* routine to do character translation (uint)*/ X#define MARKER 0x8000 /* The mark bit for translation */ X charfbuf *tty_fbuf; /* the fbuf from which to get raw input */ X X /* Terminal parameters and status. */ X int tty_ddmod; /* device dependant terminal mode */ X int tty_mode; /* terminal mode set by IOCTL flags */ X int tty_pgrp; /* the tty process group */ X char tty_ispeed; /* terminal input baud rate */ X char tty_ospeed; /* terminal output baud rate */ X int tty_column; /* current column number (0-origin) */ X X unsigned tty_state; X#define ESCAPED 1 /* 1 when '\' just seen, else 0 */ X#define INHIBITED 2 /* 1 when CTRL-S just seen (stops output) */ X#define TRANSLATE 4 /* 1 when special char translation required */ X#define WAITING 8 /* 1 when output proc wants a reply */ X#define COK8BIT 0x10 /* 1 when 8 bits even in cooked modes */ X#define BS_WRAP 0x20 /* 1 when column is zero and a \b occurs X - this is not reset by the HL driver */ X#define IN_FLUSH 0x40 /* 1 when the device dependant drivers have X input ready for processing */ X#define OUT_FLUSH 0x80 /* 1 when the device dependant drivers need X to have more chars feed to them to X keep them busy on output */ X#define DD_FLAG1 0x100 /* Device dependant state flags */ X#define DD_FLAG2 0x200 X#define DD_FLAG3 0x400 X#define DD_FLAG4 0x800 X#define DD_FLAG5 0x1000 X#define DD_FLAG6 0x2000 X#define DD_FLAG7 0x4000 X#define DD_FLAG8 0x8000 X X /* User settable characters: erase, kill, interrupt, quit, x-on; x-off. */ X char tty_erase; /* char used to erase 1 char (init ^H) */ X char tty_kill; /* char used to erase a line (init @) */ X char tty_intr; /* char used to send SIGINT (init DEL) */ X char tty_quit; /* char used for core dump (init CTRL-\) */ X char tty_xon; /* char used to start output (init CTRL-Q) */ X char tty_xoff; /* char used to stop output (init CTRL-S) */ X char tty_eof; /* char used to stop output (init CTRL-D) */ X char tty_brk; /* char used as input delimiter (not used) */ X X} tty_entry; X Xextern tty_entry tty_struct[]; *-*-END-of-tty.h-*-* echo x - at_wini.cd sed 's/^X//' >at_wini.cd <<'*-*-END-of-at_wini.cd-*-*' X194c194 X< register int i, old_state; X--- X> register int i/*, old_state*/; X217,219c217,219 X< old_state = lock(); X< dma_read((unsigned)(usr_buf >> 4), (unsigned)(usr_buf & 0x0F)); X< restore(old_state); X--- X> /*old_state = lock();*/ X> dma_read((unsigned)(usr_buf >> 4), (unsigned)(usr_buf & 0x0F)); X> /*restore(old_state);*/ X235,237c235,237 X< old_state = lock(); X< dma_write((unsigned)(usr_buf >> 4), (unsigned)(usr_buf&0x0F)); X< restore(old_state); X--- X> /*old_state = lock();*/ X> dma_write((unsigned)(usr_buf >> 4), (unsigned)(usr_buf&0x0F)); X> /*restore(old_state);*/ *-*-END-of-at_wini.cd-*-* echo x - printer.cd sed 's/^X//' >printer.cd <<'*-*-END-of-printer.cd-*-*' X139,140c139,141 X< } X< } X--- X> } X> } X> restore(old_state); *-*-END-of-printer.cd-*-* echo x - table.cd sed 's/^X//' >table.cd <<'*-*-END-of-table.cd-*-*' X48,49c48,50 X< X< #define TTY_STACK SMALL_STACK X--- X> #define LARGER_STACK 384 X> X> #define TTY_STACK LARGER_STACK *-*-END-of-table.cd-*-* echo x - xt_wini.cd sed 's/^X//' >xt_wini.cd <<'*-*-END-of-xt_wini.cd-*-*' X*** xt_wini.c.ORIG Thu Jan 1 00:12:15 1970 X--- xt_wini.c Thu Sep 1 06:02:15 1988 X*************** X*** 615,621 **** X } X X X! old_state = lock(); X X for (i=0; i<6; i++) { X if(hd_wait(WST_REQ) != OK) X--- 615,621 ---- X } X X X! /* old_state = lock(); */ X X for (i=0; i<6; i++) { X if(hd_wait(WST_REQ) != OK) X*************** X*** 630,636 **** X port_out(WIN_DATA, command[i]); X } X X! restore(old_state); X X if(i != 6) { X return(ERR); X--- 630,636 ---- X port_out(WIN_DATA, command[i]); X } X X! /* restore(old_state); */ X X if(i != 6) { X return(ERR); *-*-END-of-xt_wini.cd-*-* echo x - mpx88.asd sed 's/^X//' >mpx88.asd <<'*-*-END-of-mpx88.asd-*-*' X46,47c46,47 X< .globl _main, _sys_call, _interrupt, _keyboard, _panic, _unexpected_int, _trap X< .globl _pr_char, _rs232, _dp8390_int X--- X> .globl _main, _sys_call, _interrupt, _int_con, _panic, _unexpected_int, _trap X> .globl _pr_char, _int_8250, _dp8390_int X104c104 X< call _keyboard ; process a keyboard interrupt X--- X> call _int_con ; process a keyboard interrupt X111,115c111,115 X< _rs232_int: ; Interrupt routine for rs232 I/O. X< call save ; save the machine state X< mov ax,#1 ; which unit caused the interrupt X< push ax ; pass it as a parameter X< call _rs232 ; process a rs232 interrupt X--- X> _rs232_int: ; Interrupt routine for rs232 port 1. X> call save ; save the machine state X> mov ax,#0 ; which unit caused the interrupt X> push ax ; pass it as a parameter X> call _int_8250 ; process a rs232 interrupt X123,125c123,125 X< mov ax,#2 ; which unit caused the interrupt X< push ax ; pass it as a parameter X< call _rs232 ; process a rs232 interrupt X--- X> mov ax,#1 ; which unit caused the interrupt X> push ax ; pass it as a parameter X> call _int_8250 ; process a rs232 interrupt X304,305c304,306 X< mov ax,ret_save ; ax = address to return to X< jmp ax ; return to caller; Note: sp points to saved ax X--- X> cld ; all kernel copy loops are forward. X> mov ax,ret_save ; ax = address to return to X> jmp ax ; return to caller; Note: sp points to saved ax *-*-END-of-mpx88.asd-*-* echo x - klib88.as sed 's/^X//' >klib88.as <<'*-*-END-of-klib88.as-*-*' X; This file is significantly different in code to klib88.s. It does however X; perform the same functions in the same way as the original klib88. X; i.e. It is largly a translation with a few optimizations. Throughout the X; file the word 'INT' in the comment means to comment out the entire line to X; improve interrupt latency. The 'INT' will be followed by a class letter. X; E.g. INTV indicates all video routine interrupts. X X; This file contains a number of assembly code utility routines needed by the X; kernel. They are: X; X; phys_copy: copies data from anywhere to anywhere in memory X; cp_mess: copies messages from source to destination X; port_out: outputs data on an I/O port X; port_in: inputs data from an I/O port X; dma_read: transfer data between HD controller and memory X; dma_write: transfer data between memory and HD controller X; lock: disable interrupts X; restore: restore interrupts (enable/disabled) as they were before lock() X; build_sig: build 4 word structure pushed onto stack for signals X; get_chrome: returns 0 if display is monochrome, 1 if it is color X; scr_up: scroll screen a line up (in software, by copying) X; scr_down: scroll screen a line down (in software, by copying) X; vid_write: write data to video ram (on color display during retrace only) X; vid_fill: fill a section of video ram with a char (and attribute) X; vid_fmove: move a section of video ram around (using forward copies) X; vid_bmove: move a section of video ram around (using backward copies) X; get_byte: reads a byte from a user program and returns it as value X; put_byte: writes a byte to a user program X; reboot: reboot for CTRL-ALT-DEL X; wreboot: wait for character then reboot X; em_xfer: read or write AT extended memory using the BIOS X X; The following procedures are defined in this file and called from outside it. X.globl _phys_copy, _cp_mess, _port_out, _port_in, _lock, _restore, _em_xfer X.globl _build_sig, _get_chrome, _vid_write, _vid_fill, _vid_fmove, _vid_bmove X.globl _get_byte, _put_byte, _reboot, _wreboot, _dma_read, _dma_write X X; The following external procedure is called in this file. X.globl _panic, _eth_stp X X; Variables and data structures X.globl _cur_proc, _proc_ptr, _vec_table X.globl _color, _vid_mask, _vid_retrace, _vid_base X X.psect _TEXT X X;*===========================================================================* X;* phys_copy * X;*===========================================================================* X; This routine copies a block of physical memory. It is called by: X; phys_copy( (long) source, (long) destination, (long) bytecount) X; interrupts are unchanged. X X_phys_copy: X push bp X mov bp,sp ; set bp to point to parameters X push si ; save si X push di ; save di X push ds ; save ds X X; pushf ; INTC save flags X; cli ; INTC no interrupts X; cld ; INTC ensure this is the correct copy dir X X L0: mov ax,10[bp] ; ax = high-order word of 32-bit destination X mov di,8[bp] ; di = low-order word of 32-bit destination X mov cx,#4 ; start extracting click number from dest X L1: rcr ax,#1 ; click number is destination address / 16 X rcr di,#1 ; it is used in segment register for copy X loop L1 ; 4 bits of high-order word are used X mov es,di ; es = destination click X X mov ax,6[bp] ; ax = high-order word of 32-bit source X mov si,4[bp] ; si = low-order word of 32-bit source X mov cx,#4 ; start extracting click number from source X L2: rcr ax,#1 ; click number is source address / 16 X rcr si,#1 ; it is used in segment register for copy X loop L2 ; 4 bits of high-order word are used X mov ds,si ; ds = source click X X mov di,8[bp] ; di = low-order word of dest address X and di,#000Fh ; di = offset from paragraph # in es X mov si,4[bp] ; si = low-order word of source address X and si,#000Fh ; si = offset from paragraph # in ds X X mov dx,14[bp] ; dx = high-order word of byte count X mov cx,12[bp] ; cx = low-order word of byte count X X test cx,#8000h ; if bytes >= 32768, only do 32768 X jnz L3 ; per iteration X test dx,#0FFFFh ; check high-order 17 bits to see if bytes X jz L4 ; if bytes < 32768 then go to L4 X L3: mov cx,#8000h ; 0x8000 is unsigned 32768 X L4: mov ax,cx ; save actual count used in ax; needed later X X test cx,#1 ; should we copy a byte or a word at a time? X jz L5 ; jump if even X rep movs byte ; copy 1 byte at a time X jmp L6 ; check for more bytes X X L5: shr cx,#1 ; word copy X rep movs word ; copy 1 word at a time X X L6: mov dx,14[bp] ; decr count, incr src & dst, iterate if needed X mov cx,12[bp] ; dx || cx is 32-bit byte count X xor bx,bx ; bx || ax is 32-bit actual count used X sub cx,ax ; compute bytes - actual count X sbb dx,bx ; dx || cx is # bytes not yet processed X or cx,cx ; see if it is 0 X jnz L7 ; if more bytes then go to L7 X or dx,dx ; keep testing X jnz L7 ; if loop done, fall through X X; popf ; INTC restore flags X pop ds ; restore ds X pop di ; restore di X pop si ; restore si X pop bp ; restore bp X ret ; return to caller X XL7: mov 14[bp],dx ; store decremented byte count back in mem X mov 12[bp],cx ; as a long X add 8[bp],ax ; increment destination X adc 10[bp],bx ; carry from low-order word X add 4[bp],ax ; increment source X adc 6[bp],bx ; carry from low-order word X jmp L0 ; start next iteration X X X;*===========================================================================* X;* cp_mess * X;*===========================================================================* X; This routine is makes a fast copy of a message from anywhere in the address X; This routine makes a fast copy of a message from anywhere in the address X; space to anywhere else. It also copies the source address provided as a X; parameter to the call into the first word of the destination message. X; It is called by: X; cp_mess(src, src_clicks, src_offset, dst_clicks, dst_offset) X; where all 5 parameters are shorts (16-bits). X; X; Note that the message size, 'Msize' is in WORDS (not bytes) and must be set X; correctly. Changing the definition of message in type file and not changing X; it here will lead to total disaster. X XMsize equ 12 ; size of a message in 16-bit words X_cp_mess: X mov bx,sp ; index off bp because machine can't use sp X push ds ; save ds X push si ; save si X push di ; save di X X mov ax,2[bx] ; ax = process number of sender X mov di,10[bx] ; di = offset of destination buffer X mov es,8[bx] ; es = clicks of destination X mov si,6[bx] ; si = offset of source message X mov ds,4[bx] ; ds = clicks of source message X mov cx,#Msize-1 ; remember, first word doesn't count X X; pushf ; INTM so we know what to restore later X; cli ; INTM disable interrupts X; cld ; INTM clear direction flag X X stos word ; copy sender's process number to dest message X add si,#2 ; don't copy first word X rep movs word ; iterate cx times to copy 11 words X X; popf ; INTM restore the interupt condition X pop di ; restore di X pop si ; restore si X pop ds ; restore ds X ret ; that's all folks! X X X;*===========================================================================* X;* port_out * X;*===========================================================================* X; port_out(port, value) writes 'value' on the I/O port 'port'. X X_port_out: X mov bx,sp ; index off bx X mov dx,2[bx] ; dx = port X mov ax,4[bx] ; ax = value X out [dx],al ; output 1 byte X ret ; return to caller X X X;*===========================================================================* X;* port_in * X;*===========================================================================* X; port_in(port, &value) reads from port 'port' and puts the result in 'value'. X_port_in: X mov bx,sp ; index off bx X mov dx,2[bx] ; dx = port X in al,[dx] ; input 1 byte X xor ah,ah ; clear ah X mov bx,4[bx] ; fetch address where byte is to go X mov [bx],ax ; return byte to caller in param X ret ; return to caller X X X;*===========================================================================* X;* dma_read * X;*===========================================================================* X_dma_read: X mov bx,sp X push di X mov cx,#256 ; transfer 256 words X mov dx,#1F0H ; from/to port 1f0 X mov es,2[bx] ; segment in es X mov di,4[bx] ; offset in di X .byte 0F3H, 6DH ; opcode for 'rep ins word' X pop di X ret X X;*===========================================================================* X;* dma_write * X;*===========================================================================* X_dma_write: X mov bx,sp X push si X push ds X mov cx,#256 ; transfer 256 words X mov dx,#1F0H ; from/to port 1f0 X mov si,4[bx] ; offset in si X mov ds,2[bx] ; segment in ds X .byte 0F3H, 6FH ; opcode for 'rep outs word' X pop ds X pop si X ret X X;*===========================================================================* X;* lock * X;*===========================================================================* X; Disable CPU interrupts. Return old psw as function value. X_lock: X pushf ; save flags on stack X cli ; disable interrupts X pop ax ; return flags for restoration later X ret ; return to caller X X;*===========================================================================* X;* restore * X;*===========================================================================* X; restore enable/disable bit to the value it had before last lock. X_restore: X mov bx,sp ; set up base for indexing X push 2[bx] ; bp is the psw to be restored X popf ; restore flags X ret ; return to caller X X X;*===========================================================================* X;* build_sig * X;*===========================================================================* X;* Build a structure that is pushed onto the stack for signals. It contains X;* pc, psw, etc., and is machine dependent. The format is the same as generated X;* by hardware interrupts, except that after the "interrupt", the signal number X;* is also pushed. The signal processing routine within the user space first X;* pops the signal number, to see which function to call. Then it calls the X;* function. Finally, when the function returns to the low-level signal X;* handling routine, control is passed back to where it was prior to the signal X;* by executing a return-from-interrupt instruction, hence the need for using X;* the hardware generated interrupt format on the stack. The call is: X;* build_sig(sig_stuff, rp, sig) X X; Offsets within proc table XPC equ 24 Xcsreg equ 18 XPSW equ 28 X X_build_sig: X mov bx,sp ; set bp to sp for accessing params X push si ; save si X mov ax,6[bx] ; ax = signal number X mov si,4[bx] ; si points to proc table entry X mov bx,2[bx] ; bx points to sig_stuff X mov [bx],ax ; put signal number in sig_stuff X mov ax,PC[si] ; ax = signalled process' PC X mov 2[bx],ax ; put pc in sig_stuff X mov ax,csreg[si] ; ax = signalled process' cs X mov 4[bx],ax ; put cs in sig_stuff X mov ax,PSW[si] ; ax = signalled process' PSW X mov 6[bx],ax ; put psw in sig_stuff X pop si ; restore si X ret ; return to caller X X;*===========================================================================* X;* get_chrome * X;*===========================================================================* X; This routine calls the BIOS to find out if the display is monochrome or X; color. The drivers are different, as are the video ram addresses, so we X; need to know. An EGA card is a 'color' for printer ports but may display X; in mono or color. A test on the result returns ... X; if (get_chrome()) ... - true if color or ega card (e.g. for printer X; port) X; if (get_chrome()&1) ... - true if color mode, false if mono mode X; if (get_chrome()&2) ... - true iff ega card X_get_chrome: X mov tmp,#0,byte ; clear previous (if any) modes X mov bl,#10H ; test if EGA X mov ah,#12H X int #10H X cmp bl,#10H X jz 1f ; if EGA then X mov tmp,#2,byte ; mark as EGA X1: int #11h ; test for color/mono X and al,#30h ; isolate color/mono field X cmp al,#30h X mov al,tmp ; if monochrome then X je 2f ; return X or al,#1 ; mark as color X2: xor ah,ah ; return as word X ret X X X;*===========================================================================* X;* video routines (PUBLIC) * X;*===========================================================================* X; This routines handle writes to the screen. For a color display, the writing X; only takes places during the vertical retrace interval, to avoid displaying X; garbage on the screen. It will only display a maximum of vid_retrace words X; in a single refresh cycle for the same reason. The display ram overflow is X; handled carefully so that EGA cards work properly. These routines rely on X; the stack segment being equal to the data segment. X; X; The calls are: X; vid_write(buffer, dest, words) X; vid_fill(fillw, dest, words) X; vid_fmove(src, dest, words) X; vid_bmove(src, dest, words) X; where X; 'buffer' is a pointer to the (character, attribute) pairs X; 'fillw' is the word (character, attribute) for filling X; 'src' tells where within video ram to copy data from X; 'dest' tells where within video ram to copy the data X; 'words' tells how many words to copy X X_vid_write: ; let vidtransfer handle dest overflow X push bp ; set up stack frame X mov bp,sp X push si ; save the registers X push di X mov es,_vid_base ; screen seg register X call vidtransfer ; do the transfer X pop di ; finished - clear stack frame X pop si X pop bp X ret X X_vid_fill: ; handle dest overflow explicitly X push bp ; set up stack frame X mov bp,sp X push di ; save the registers X mov es,_vid_base ; screen seg register X mov ax,4[bp] ; get the fill char X mov di,6[bp] ; get the dest X call lvidfill ; do the initial fill X call vidcheck ; check if overflow has occurred X jz 1f X call lvidfill ; fix overflow X1: pop di ; finished - clear stack frame X pop bp X ret X X_vid_fmove: ; handle src overflow explicitly X ; let vidtransfer handle dest overflow X push bp ; set up stack frame X mov bp,sp X push si ; save the registers X push di X push ds X mov ax,4[bp] ; src &= vid_mask X and ax,_vid_mask X mov 4[bp],ax X add ax,8[bp] ; if (src + words*2 > vid_mask) X add ax,8[bp] ; we have src overflow. X cmp ax,_vid_mask X mov es,_vid_base ; set up segment registers X mov ds,_vid_base X jle 2f ; if src overflow then X push 8[bp] ; save the words count X mov bx,ss:_vid_mask ; count = MIN(count, ((vid_mask+1)-src)/2) X inc bx X sub bx,4[bp] X shr bx,#1 X cmp bx,8[bp] X jle 1f X mov bx,8[bp] X1: mov 8[bp],bx ; bx and count now has count to do X call vidtransfer ; do this first transfer X mov 4[bp],#0,word ; set up for remaining transfer X mov 6[bp],di X pop 8[bp] ; restore our original count X sub 8[bp],bx ; subtract the count done so far X jz 3f ; only continue if more to do X2: call vidtransfer ; do the transfer for no src overflow X3: pop ds ; finished - clear stack frame X pop di X pop si X pop bp X ret X X_vid_bmove: ; handle src overflow explicitly X ; let rvidtransfer handle dest overflow X push bp ; set up stack frame X mov bp,sp X push si ; save the registers X push di X push ds X pushf X std ; transfer in reverse direction X mov bx,4[bp] ; src &= vid_mask X and bx,_vid_mask X mov 4[bp],bx X mov es,_vid_base ; set up segment registers X mov ds,_vid_base X push 8[bp] ; save the total count X shr bx,#1 ; count = MIN(count, src/2 + 1) X inc bx X cmp bx,8[bp] X jle 1f X mov bx,8[bp] ; also save count in bx X1: mov 8[bp],bx X call vidrtransfer ; do the transfer of non overflowing section X mov ax,ss:_vid_mask ; set up to do overflow of src X dec ax ; convert to word address X mov 4[bp],ax ; new src addr X pop 8[bp] ; calculate count left X sub 8[bp],bx X jz 2f ; if none to do don't continue X call vidrtransfer ; transfer overflow X2: popf ; finished - clear stack frame X pop ds X pop di X pop si X pop bp X ret X X;*===========================================================================* X;* video routines (private) * X;*===========================================================================* X; The following video support routines may be changed in thier interrupt X; handling methods. If a glitch due to an interrupt during screen writes X; is acceptable then comment out all lines with 'INTV' in thier comment. X; Doing this improves interrupt latency (e.g. for RS232 throughput). In X; practice I have never seen any glitches with the interrupts on. X Xvidtransfer: ; transfer a block to the screen (forward dir) X ; handle dest overflow X ; final results returned in si, di X mov si,4[bp] ; si = pointer to data to be copied X mov di,6[bp] ; di = offset within video ram X call lvidcopy ; write the block to the screen X call vidcheck ; check for video ram (window) overflow X jz 1f X sub si,8[bp] ; overflow - find buffer position X sub si,8[bp] X call lvidcopy ; fix up overflow X1: ret X Xvidrtransfer: ; transfer a block to the screen (reverse dir) X ; handle dest overflow X ; final results in stack frame X mov si,4[bp] ; si = pointer to data to be copied X mov di,6[bp] ; di = offset within video ram X call lvidcopy ; write the block to the screen X call vidrcheck ; check for video ram (window) overflow X xchg si,4[bp] ; get orig src & dest , save final src dest X xchg di,6[bp] X jz 1f X and di,ss:_vid_mask ; address the overflow block X call lvidcopy ; write the overflow block X1: ret X Xlvidcopy: ; Transfer a block to the screen in sub-blocks X ; with a maximum of vid_retrace words per sub-block. X mov cx,ss:_vid_retrace ; cx = MIN(count, vid_retrace) X cmp cx,8[bp] X jle 1f X mov cx,8[bp] X1: jcxz 2f ; only do transfer if cx != 0 X sub 8[bp],cx ; count -= cx X call vidcopy X jmp lvidcopy ; get the next sub-block X2: ret X Xlvidfill: ; Fill a block on the screen in sub-blocks X ; with a maximum of vid_retrace words per sub-block. X mov cx,ss:_vid_retrace ; cx = MIN(count, vid_retrace) X cmp cx,8[bp] X jle 1f X mov cx,8[bp] X1: jcxz 2f ; only do transfer if cx != 0 X sub 8[bp],cx ; count -= cx X call vidfill X jmp lvidfill ; get the next sub-block X2: ret X Xvidcopy: ; Transfer a sub-block to the screen waiting for X ; retrace if necessary. X call vidwait ; wait for retrace if necessary X rep movs word ; transfer the block X; push ax ; INTV restore the flags X; popf ; INTV X ret X Xvidfill: ; Fill a sub-block on the screen waiting for X ; retrace if necessary. X push ax ; save the fill char X call vidwait ; wait for retrace if necessary X; mov dx,ax ; INTV save the flags X pop ax ; restore the fill char X rep stos word ; do the fill X; push dx ; INTV restore the flags X; popf ; INTV X ret X Xvidwait: ; Wait for retrace only if necessary X test ss:_color,#1,byte ; mono's don't need retrace checking X jz 2f X test ss:_color,#2,byte ; ega's don't need retrace checking X jnz 2f X mov dx,#3DAH ; port for retrace status X; pushf ; INTV X1: X; sti ; INTV ensure interrupts can have a go X; nop ; INTV X; nop ; INTV X; cli ; INTV X in al,[dx] ; wait for retrace on X test al,#8 X jz 1b X; pop ax ; INTV return the flags in ax (ints off) X2: ret X Xvidcheck: ; Check if the forward transfer just completed X ; requires overflow fixing on dest. If so set up X ; di and count. count = 0 on entry X mov dx,di ; dx = final dest X sub dx,ss:_vid_mask ; see if overflowed X sub dx,#1 ; must do sub as dec doesn't set flag X jle 2f ; if so dx = overflow count X sub di,6[bp] ; count = MIN(dx, final dest - init dest) X cmp di,dx X jle 1f X mov di,dx X1: mov 8[bp],di ; save the new count X sub dx,di ; new dest = overflow count - new count X mov di,dx X2: shr 8[bp],#1,word ; turn byte count to word count & test X ret ; if any work done. X Xvidrcheck: ; Check if the backward transfer just completed X ; requires overflow fixing on dest. If so set up X ; count. count = 0 on entry X mov dx,6[bp] ; dx = final dest X sub dx,ss:_vid_mask ; see if overflowed X sub dx,#1 ; must do sub as dec doesn't set flag X jle 2f ; if so dx = overflow count X mov ax,6[bp] ; count = MIN(dx, final dest - init dest) X sub ax,di X cmp ax,dx X jle 1f X mov ax,dx X1: mov 8[bp],ax ; save the new count X2: shr 8[bp],#1,word ; turn byte count to word count & test X ret ; if any work done. X X;*===========================================================================* X;* get_byte * X;*===========================================================================* X; This routine is used to fetch a byte from anywhere in memory. X; The call is: X; c = get_byte(seg, off) X; where X; 'seg' is the value to put in es X; 'off' is the offset from the es value X_get_byte: X mov bx,sp ; we need to access parameters X mov es,2[bx] ; load es with segment value X mov bx,4[bx] ; load bx with offset from segment X ; go get the byte X mov al,es:[bx] ; al = byte X xor ah,ah ; ax = byte X ret ; return to caller X X X;*===========================================================================* X;* put_byte * X;*===========================================================================* X; This routine is used to put a byte anywhere in memory. X; The call is: X; retval = put_byte(seg, off, val) X; where X; 'seg' is the value to put in es X; 'off' is the offset from the es value X; 'val' is value to put in memory X; 'retval' = val & 0xFF X_put_byte: X mov bx,sp ; we need to access parameters X mov al,6[bx] ; load al with value X mov es,2[bx] ; load es with segment value X mov bx,4[bx] ; load bx with offset from segment X mov es:[bx],al ; put the byte X xor ah,ah ; ax = byte X ret ; return to caller X X;*===========================================================================* X;* reboot & wreboot * X;*===========================================================================* X; This code reboots the PC X X_reboot: X cli ; disable interrupts X mov ax,#20h ; re-enable interrupt controller X out 20h,al X call _eth_stp ; stop the ethernet chip X call resvec ; restore the vectors in low core X jmp doboot ; reboot the PC X X_wreboot: X cli ; disable interrupts X mov ax,#20h ; re-enable interrupt controller X out 20h,al X call _eth_stp ; stop the ethernet chip X call resvec ; restore the vectors in low core X xor ax,ax ; wait for character before continuing X int #16h ; get char X jmp doboot ; reboot the PC X X; Restore the interrupt vectors in low core. Xresvec: cld X mov cx,#2*71 X mov si,#_vec_table X xor di,di X mov es,di X rep movs word X ret X X; Replaces int #19h Xdoboot: X mov ax,#40h X mov ds,ax X mov ax,#1234h X mov 72h,ax X mov ax,#0FFFFh X mov ds,ax X mov ax,3 X push ax X mov ax,1 X push ax X iret X X; Some library routines use exit, so this label is needed. X; Actual calls to exit cannot occur in the kernel. X.globl _exit X_exit: sti X jmp _exit X X;=========================================================================== X; em_xfer X;=========================================================================== X; X; This file contains one routine which transfers words between user memory X; and extended memory on an AT or clone. A BIOS call (INT 15h, Func 87h) X; is used to accomplish the transfer. X; X; This particular BIOS routine runs with interrupts off since the 80286 X; must be placed in protected mode to access the memory above 1 Mbyte. X; So there should be no problems using the BIOS call. X; X .psect _TEXT Xgdt: ; Begin global descriptor table X ; Dummy descriptor X .word 0 ; segment length (limit) X .word 0 ; bits 15-0 of physical address X .byte 0 ; bits 23-16 of physical address X .byte 0 ; access rights byte X .word 0 ; reserved X ; descriptor for GDT itself X .word 0 ; segment length (limit) X .word 0 ; bits 15-0 of physical address X .byte 0 ; bits 23-16 of physical address X .byte 0 ; access rights byte X .word 0 ; reserved Xsrc: ; source descriptor Xsrcsz: .word 0 ; segment length (limit) Xsrcl: .word 0 ; bits 15-0 of physical address Xsrch: .byte 0 ; bits 23-16 of physical address X .byte 93H ; access rights byte X .word 0 ; reserved Xtgt: ; target descriptor Xtgtsz: .word 0 ; segment length (limit) Xtgtl: .word 0 ; bits 15-0 of physical address Xtgth: .byte 0 ; bits 23-16 of physical address X .byte 93H ; access rights byte X .word 0 ; reserved X ; BIOS CS descriptor X .word 0 ; segment length (limit) X .word 0 ; bits 15-0 of physical address X .byte 0 ; bits 23-16 of physical address X .byte 0 ; access rights byte X .word 0 ; reserved X ; stack segment descriptor X .word 0 ; segment length (limit) X .word 0 ; bits 15-0 of physical address X .byte 0 ; bits 23-16 of physical address X .byte 0 ; access rights byte X .word 0 ; reserved X; X; X; Execute a transfer between user memory and extended memory. X; X; status = em_xfer(source, dest, count); X; X; Where: X; status => return code (0 => OK) X; source => Physical source address (32-bit) X; dest => Physical destination address (32-bit) X; count => Number of words to transfer X; X; X; X_em_xfer: X push bp ; Save registers X mov bp,sp X push si X push es X; X; Pick up source and destination addresses and update descriptor tables X; X mov ax,4[bp] X mov cs:srcl,ax X mov ax,6[bp] X mov cs:srch,al X mov ax,8[bp] X mov cs:tgtl,ax X mov ax,10[bp] X mov cs:tgth,al X; X; Update descriptor table segment limits X; X mov cx,12[bp] X mov ax,cx X add ax,ax X mov cs:tgtsz,ax X mov cs:srcsz,ax X; X; Now do actual DOS call X; X push cs X pop es X mov si,#gdt X mov ah,#87H X ; Hopefully this will work instead of ... X int #15H ; Do a far call to BIOS routine X; X; All done, return to caller. X; X pop es ; restore registers X pop si X mov sp,bp X pop bp X ret X X .psect data Xvidlock: .word 0 ; dummy variable for use with lock prefix Xtmp: .word 0 ; count of bytes already copied X_vec_table: .blkb 284 ; storage for interrupt vectors X X .psect _TEXT *-*-END-of-klib88.as-*-* exit
pa1293@sdcc15.ucsd.edu (pa1293) (11/10/88)
I have tried to install Andrew Hannam's tty handler routines but I am confronted with the problem that the assembly routines are written in some other unix assembler code and I don't know what the differences are between MINIX asld and the ??UNIX?? as used by Andrew Hannam. Also, I am not sure if the assembly files would be portable with the MINIX cc even if I were to do a simple conversion of the mnemonics. Could anybody who has converted the tty driver to MINIX-compileable code please post the diffs or the files. Is this tty driver relative to v1.3a v1.3b or v1.3c? Thanks. Mail to / flame: pa1293@iugrad2.ucsd.edu ~!nosc!ucsd!iugrad2!pa1293 or try: ~!nosc!ucsd!sdcc15!pa1293