home *** CD-ROM | disk | FTP | other *** search
- /*
- * MBIBM.C - 4/20/88 - System dependent functions.
- * For standard IBM PC, under MS-DOS 3.1 or later
- *
- * Uses calls thru int 14h to drivers that replace the regular
- * interrupt 14h drivers.
- * Uses brkoff and brkon to disable/enable ctrl-brk by VE3GYQ
- * - VE3GYQ and NK6K
- *
- */
-
- #include "mb.h"
- #include <time.h>
- #include <dos.h>
-
- /*
- * INT14 function codes.
- */
-
- #define SER_OUT 1 /* Character out serial port */
- #define SER_IN 2 /* Character in from serial port */
- #define SER_STAT 3 /* Check status of serial port */
- #define SER_INQ 4 /* Verify driver loaded */
- #define SET_BUSY 8 /* Set port busy flag */
- #define CLR_BUSY 9 /* Clear port busy flag */
- #define PP_FLAG 10 /* Store port flag in bios */
- #define PC_FLAG 11 /* Store command flag in bios */
- #define GP_FLAG 12 /* Retreive port flag */
- #define GC_FLAG 13 /* Retreive command flag */
- #define GCMD 14 /* Get command from bios */
- #define PCMD 15 /* Store command in bios */
-
- /*
- * INT21 Functions codes.
- */
-
- #define SETDATE 0x2b
- #define SETTIME 0x2d
-
- #define SETDTA 0x1a
- #define GETDTA 0x2f
- #define GETFRE 0x36
- #define SRCFST 0x4e
- #define SRCNXT 0x4f
-
- #define DV_PAUSE 0x1000 /* Relinquish control to other */
- #define DV_BEGINC 0x101B /* Begin DV critical region */
- #define DV_ENDC 0x101C /* End critical region */
-
- char l_date[7], l_time[5];
- long time();
- static union REGS inreg, outreg, ingive, outgive;
- char pt_flag = 0;
- char bios_call;
-
- #define CMDPORT 15 /* Port for passing commands */
-
- /*
- * Initialize the serial I/O system.
- * Ports are initialized by loading driver and then running mbmode.
- */
-
- ioinit()
- {
- brkoff(); /* disable DOS ctrl-brk fn */
- }
-
- dosinit()
- {
- if (s_flag & s_dv)
- {
- ingive.x.ax = DV_PAUSE;
- bios_call = 0x15;
- printf ("Set for DESQview.\n");
- }
- }
-
- iooff()
- {
- brkon(); /* restore DOS ctrl-brk fn */
- }
-
- /*
- * Switch out of the current window.
- */
-
- switchw()
- {
- if (s_flag & s_dv)
- int86(bios_call, &ingive, &outgive);
- }
- /*
- * Set the current I/O device.
- */
-
- ioport(pp)
- PORTS *pp;
- {
- port = pp;
- }
-
- breakport()
- {
- inreg.x.dx = port->idn;
- inreg.h.ah = 7;
- int86( 0x14, &inreg, &outreg);
- }
-
- isdcd()
- {
- switch (port->dev)
- {
- case p_tnc:
- case p_serial:
- inreg.x.dx = port->idn;
- inreg.h.ah = SER_STAT;
- int86( 0x14, &inreg, &outreg );
- return (0x80 & outreg.h.al);
- default: return true;
- }
- }
-
- /*
- * Suspend multitasking permitting only calling task to
- * continue execution.
- */
-
- begin_lock()
- {
- inreg.x.ax = DV_BEGINC;
- int86(0x15, &inreg, &outreg);
- }
-
- /*
- * Resume multitasking.
- */
-
- end_lock()
- {
- inreg.x.ax = DV_ENDC;
- int86(0x15, &inreg, &outreg);
- }
-
- /*
- * Mark all the ports in this window as busy.
- */
-
- setbusy()
- {
- inreg.h.ah = SET_BUSY;
- inreg.x.dx = CMDPORT;
- inreg.h.al = p_window;
- int86(0x14, &inreg, &outreg);
- }
-
- /*
- * Mark all the ports in this window as idle.
- */
-
- clrbusy()
- {
- inreg.h.ah = CLR_BUSY;
- inreg.x.dx = CMDPORT;
- inreg.h.al = p_window;
- int86(0x14, &inreg, &outreg);
- }
-
- /*
- * Store the port flag in the bios. Port flag bits set
- * indicate that the corresponding port is initialized
- * in a window.
- */
-
- putp_flag(c)
- byte c;
- {
- inreg.h.ah = PP_FLAG;
- inreg.x.dx = CMDPORT;
- inreg.h.al = c;
- int86(0x14, &inreg, &outreg);
-
- }
- /*
- * Store the command flag in the bios. Command flag bits set
- * indicate that the corresponding port has a command waiting
- * for it to process.
- */
-
- putc_flag(c)
- byte c;
- {
- inreg.h.ah = PC_FLAG;
- inreg.x.dx = CMDPORT;
- inreg.h.bl = c;
- int86(0x14, &inreg, &outreg);
- }
-
- /*
- * Get the port flag from the bios. Port flag bits set
- * indicate that the corresponding port is initialized
- * in a window.
- */
-
- byte getp_flag()
- {
- inreg.h.ah = GP_FLAG;
- inreg.x.dx = CMDPORT;
- int86(0x14, &inreg, &outreg);
- return outreg.h.al;
-
- }
- /*
- * Get the command flag from the bios. Command flag bits set
- * indicate that the corresponding port has a command waiting
- * for it to process.
- */
-
- getc_flag()
- {
- inreg.h.ah = GC_FLAG;
- inreg.x.dx = CMDPORT;
- int86(0x14, &inreg, &outreg);
- c_flag = outreg.h.bl;
- b_flag = outreg.h.bh;
- }
-
- /*
- * Recover two characters from the bios storage area for use
- * as commands. Port->line will contain these on return.
- */
-
- getcomd()
- {
- inreg.h.ah = GCMD;
- inreg.x.dx = CMDPORT;
- int86(0x14, &inreg, &outreg);
- port->opt1 = outreg.h.bl;
- port->opt2 = outreg.h.bh;
- }
-
- /*
- * Pass a two character command to the bios storage area.
- */
-
- putcomd(c1, c2)
- char c1, c2;
- {
- inreg.h.ah = PCMD;
- inreg.x.dx = CMDPORT;
- inreg.h.bl = c1;
- inreg.h.bh = c2;
- int86(0x14, &inreg, &outreg);
- }
-
- /*
- * Return character from the current port.
- */
-
- char inchar()
- {
- register char ch;
-
- if (port->dev is p_console)
- { ch = bdos(7, 0, 0);if (ch is '\020') pt_flag = !pt_flag; }
- else
- {
- inreg.h.ah = SER_IN;
- inreg.x.dx = port->idn;
- int86(0x14, &inreg, &outreg);
- ch = (0x00ff & outreg.h.al);
- }
-
- if (ch is del) ch = '\b';
- if (port->dev is p_console) return ch;
-
- /*
- * Input did not come from the console.
- * Echo the input to the console.
- */
-
- if (!(port->ec)) return ch;
-
- if (ch isnt ctl_g)
- {
- bdos(2, ch, 0);
- if (ch is '\r') bdos(2, '\n', 0);
- }
- return ch;
- }
-
- /*
- * Return non-zero if a character waits at current input.
- */
-
- instat()
- {
- register int st;
-
- if (port->dev is p_console) st = kbstat();
- else
- {
- inreg.x.dx = port->idn;
- inreg.h.ah = SER_STAT;
- int86(0x14, &inreg, &outreg);
- st = 0x01 & outreg.h.ah;
- }
-
- if (!st) if (s_flag & s_dv)
- if (port->flags & p_give)
- int86(bios_call, &ingive, &outgive);
-
- return st;
- }
-
- outi(ch)
- char ch;
- {
- inreg.x.dx = port->idn;
- inreg.h.ah = SER_STAT;
-
- /*
- * Check if cts on and xmtr rgstr empty.
- * Else maybe give some time to other DV windows.
- */
-
- int86(0x14, &inreg, &outreg);
- while((0x2010 & outreg.x.ax) isnt 0x2010)
- {
- /*
- if (s_flag & s_dv)
- if (port->flags & p_give) int86(bios_call, &ingive, &outgive);
- */
- int86(0x14, &inreg, &outreg);
- }
-
- /*
- * Stuff the character out the port.
- */
-
- inreg.h.ah = SER_OUT;
- inreg.h.al = ch;
- int86(0x14, &inreg, &outreg);
- }
-
- /*
- * Put the character out the current port,
- * echo to console if the current port is not the console.
- * Note special handling of end-of-line character.
- */
-
- outchar(ch)
- char ch;
- {
- if (ch is '\r') return;
- if (ch is '\n') ch = '\r';
-
- /*
- * Put it out to the console, if it is going there.
- */
-
- if ((port->dev is p_console) or port->ec)
- {
- bdos(2, ch, 0);
- if (ch is '\r') bdos(2,'\n',0);
- if (pt_flag) { bdos(5,ch,0); if(ch is '\r') bdos(5,'\n',0); }
- }
-
- /*
- * If the port is the console, nothing more to do.
- */
-
- if (port->dev is p_console) return;
-
- /*
- * Stuff this byte out the port.
- */
-
- outi(ch);
- if (ch is '\r') if (port->flags & p_lf) outi('\n');
- }
-
- outstr(cp)
- char *cp;
- {
- while(*cp) outchar(*cp++);
- }
-
- /*
- * Set the clock.
- * fld[1] has the date string.
- * fld[2] has the time string.
- */
-
- setime()
- {
- inreg.h.ah = SETTIME;
- inreg.h.ch = two(port->fld[2]); /* Hour */
- inreg.h.cl = two(port->fld[2]+2); /* Minute */
- inreg.x.dx = 0; /* Seconds and hundredths */
- intdos(&inreg, &outreg);
-
- inreg.h.ah = SETDATE;
- inreg.h.dl = two(port->fld[1]+4); /* Day */
- inreg.h.dh = two(port->fld[1]+2); /* Month */
- inreg.x.cx = 1900 + two(port->fld[1]); /* Year */
- intdos(&inreg, &outreg);
- }
-
- two(cp)
- char *cp;
- {
- return (10 * (*cp - '0') + (*(cp + 1) - '0'));
- }
-
- /*
- * Fill the globals "l_date", "l_time", and "dt" with
- * the current date and time by reading the system clock.
- * l_time is HHMM, l_date is YYMMDD.
- * dt has the format of a directory item date/time.
- */
-
- curtim()
- {
- struct tm *ct;
- long ltime;
-
- time(<ime);
- ct = localtime(<ime);
- sprintf(l_time, "%02d%02d", ct->tm_hour, ct->tm_min);
- sprintf(l_date, "%02d%02d%02d", ct->tm_year, ct->tm_mon + 1, ct->tm_mday);
- /* month returned by localtime is 0-11 */
- }
-
- /*
- * Check a timer.
- */
-
- chktmr(l)
- long l;
- {
- long cur;
-
- time(&cur);
- if (cur > l) return false;
- return true;
- }
-
- /*
- * Set a timer.
- */
-
- settmr(l, i)
- long *l;
- int i;
- {
- long cur;
-
- time(&cur);
- *l = cur + (long)i;
- }
-
- /*
- * Wait a bit.
- */
-
- wait(sec)
- int sec;
- {
- long l;
-
- settmr(&l, sec);
- while (chktmr(l)) if (s_flag & s_dv)
- int86(bios_call, &ingive, &outgive);
- }
-
- /*
- * Directory access routines.
- */
-
- #define d_dir 0x10
-
- /*
- * A directory item.
- */
-
- typedef struct
- {
- char res[21];
- char attr;
- int time;
- int date;
- word sizel;
- word sizeh;
- char name[13];
- } FCB;
-
- static int olddta;
- static FCB fcb;
-
- /*
- * Open directory, return first item.
- */
-
- diropen(cp, p, dirdef)
- char *cp;
- DIRDEF *dirdef;
- DIRENT *p;
- {
- long csize;
-
- /*
- * Save DOS current buffer.
- */
-
- inreg.h.ah = GETDTA;
- intdos(&inreg, &outreg);
- olddta = outreg.x.bx;
-
- /*
- * Point DOS at local buffer.
- */
-
- inreg.h.ah = SETDTA;
- inreg.x.dx = (int)&fcb;
- intdos(&inreg, &outreg);
-
- /*
- * Get disk free space.
- */
-
- inreg.h.ah = GETFRE;
- if (*(cp + 1) is ':') inreg.h.dl = toupper(*cp) - 'A' + 1; else inreg.h.dl = 0;
-
- intdos(&inreg, &outreg);
-
- /*
- * Compute device size.
- * ax = sectors / cluster
- * bx = available clusters
- * cx = bytes / sector
- * dx = total cluster / drive
- */
-
- csize = (long)outreg.x.ax * (long)outreg.x.cx;
- dirdef->size = (int)((csize * (long)outreg.x.dx + 1023l) / 1024l);
- dirdef->free = (int)((csize * (long)outreg.x.bx + 1023l) / 1024l);
-
- /*
- * Get the first directory entry.
- */
-
- if (port->flds is 1) strcat(cp, "*.*");
- if (port->mode & (local | sysop)) inreg.x.cx = d_dir; else inreg.x.cx = 0;
- inreg.x.dx = (int)cp;
-
- inreg.h.ah = SRCFST;
- while (true)
- {
- if (intdos(&inreg, &outreg))
- {
- p->size = -1;
- inreg.h.ah = SETDTA;
- inreg.x.dx = olddta;
- intdos(&inreg, &outreg);
- return false;
- }
- if (dodir(p)) return true;
- inreg.h.ah = SRCNXT;
- }
- }
-
- /*
- * Return second and succeding directory entries.
- */
-
- dirnext(p, dirdef)
- DIRENT *p;
- DIRDEF *dirdef;
- {
- inreg.h.ah = SRCNXT;
- while(true)
- {
- if (intdos(&inreg, &outreg))
- {
- p->size = -1;
- inreg.h.ah = SETDTA;
- inreg.x.dx = olddta;
- intdos(&inreg, &outreg);
- return;
- }
- if (dodir(p)) return;
- }
- }
-
- dodir(p)
- DIRENT *p;
- {
- strcpy(p->name, fcb.name);
-
- if (fcb.attr & d_dir)
- {
- if (match(p->name, ".")) return false;
- if (match(p->name, "..")) return false;
- strcat(p->name, "\\");
- }
- p->size = (int)((65536l * (long)fcb.sizeh + (long)fcb.sizel + 1023l) / 1024l);
- return true;
- }
-
-