/*
* This file is part of the uHex project.
* Copyright (C) 2013 Mateusz Viste
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dos.h> /* provides int86() along with the union REGS type */
#include <stdio.h> /* this one contains the NULL definition */
#include "io.h" /* include self headers for control */
/* gets cursor's position and size */
void cursor_getprops(int *x, int *y, int *start, int *end) {
union REGS regs;
regs.h.ah = 3; /* get cursor position and shape */
regs.h.bh = 0; /* page number (pretty much always 0) */
int86(0x10, ®s, ®s);
if (x != NULL) *x = regs.h.dl; /* column */
if (y != NULL) *y = regs.h.dh; /* row */
if (start != NULL) *start = regs.h.ch; /* start scan line */
if (end != NULL) *end = regs.h.cl; /* end scan line */
}
void cursor_set(int startscanline, int endscanline) {
union REGS regs;
regs.h.ah = 0x01;
regs.h.ch = startscanline;
regs.h.cl = endscanline;
int86(0x10, ®s, ®s);
}
/* gets file's attributes, and return them. returns -1 on error */
/* int getattrib(char *file) {
union REGS regs;
union SREGS sregs;
regs.h.ah = 0x43; */ /* get file's attribs */
/*regs.h.al = 0x00; *//* must be zero before the call */
/* sregs.ds = (unsigned int) (file >> 16); */ /* segment of the pointer to ASCIZ filename */
/* regs.x.dx = (unsigned int) (file & 0xFFFF); */ /* offset of the pointer to ASCIZ filename */
/* int86x(0x21, ®s, ®s, &sregs); */
/* CF clear if successful, set on error (AX = error code: 01h, 02h, 03h, 05h) */
/* if (regs.x.cflag != 0) return(-1); */
/* return the result */
/* return(regs.h.al);
} */
void locate(int row, int column) {
union REGS regs;
regs.h.ah = 0x02;
regs.h.bh = 0;
regs.h.dh = row;
regs.h.dl = column;
int86(0x10, ®s, ®s);
}
void printchar(char c, int attr) {
union REGS regs;
regs.h.ah = 0x09; /* Write char and attribute */
regs.h.al = c;
regs.h.bh = 0; /* display page */
regs.h.bl = attr;
regs.x.cx = 1; /* write it 1 time */
int86(0x10, ®s, ®s);
}
void readchar(char *c, int *attr) {
union REGS regs;
regs.h.ah = 0x08; /* Read character and attribute at cursor position */
regs.h.bh = 0; /* display page */
int86(0x10, ®s, ®s);
if (c != NULL) *c = regs.h.al;
if (attr != NULL) *attr = regs.h.ah;
}
/* waits for a keypress and return it. Returns 0 for extended keystroke, then
function must be called again to return scan code. */
int getkey() {
union REGS regs;
regs.h.ah = 0x08;
int86(0x21, ®s, ®s);
return(regs.h.al);
}
void cls(int termwidth, int termheight, int colattr) {
union REGS regs;
regs.x.ax = 0x0600; /* Scroll window up - entire window */
regs.x.bx = (colattr << 8); /* Attribute to write */
regs.x.cx = 0x0000; /* Upper left */
regs.x.dx = ((termheight - 1) << 8) | (termwidth - 1); /* Lower right */
int86(0x10, ®s, ®s);
locate(0,0);
}
void getcurvideomode(int *termwidth, int *termheight, int *colorflag) {
union REGS regs;
*termheight = peekb(0x40, 0x84) + 1;
*termwidth = peek(0x40, 0x4A);
if (*termwidth < 20) *termwidth = 25; /* some pre-EGA adapters don't return the height. Assume 25 then. */
regs.h.ah = 0x0F; /* get current video mode */
int86(0x10, ®s, ®s);
if ((regs.h.al == 0) || (regs.h.al == 2) || (regs.h.al == 7)) { /* detect mono modes */
*colorflag = 0;
} else { /* else we are in color */
*colorflag = 1;
}
}