📄 utility.cpp
字号:
}
/* ******************************************************************** *
*
* elapsed_time() -- return elapsed time in ticks
*
* ******************************************************************** */
ULONG elapsed_time(ULONG st) // start time in ticks
{
static
ULONG far *timer = (unsigned long far *) // BIOS timer tick counter
MK_FP(0x40, 0x6c); // ..down in low memory
if (st > *timer) // q. start time greater?
return((TICKS_DAY - st) + *timer); // a. yes .. add in rollover;
else
return(*timer - st); // return elapsed ticks
}
/* ******************************************************************** *
*
* wait() -- wait for a given number of timer ticks
*
* ******************************************************************** */
void wait(long n) // time to wait in ticks
{
long far *timer = (long far *) // BIOS timer tick counter
MK_FP(0x40, 0x6c), // ..down in low memory
start, work; // start tick count
start = *timer; // get current time
while (n > 0) // loop 'til n ticks past
{
if ((work = *timer) != start) // q. time pass?
{ // a. yes .. see how much
if (work < start) // q. clock go past midnite?
n--; // a. yes .. count as 1 tick
else
n -= (UINT)(work - start); // else .. count everything
start = work; // start again w/curr time
}
else
kbhit(); // else .. check keyboard
}
}
/* ******************************************************************** *
*
* wait_ms() -- wait in milliseconds
*
* ******************************************************************** */
void wait_ms(long ms) // milliseconds to wait
{
wait((ms + 54) / 55); // convert then wait in ticks
}
/* ******************************************************************** *
*
* malloc_chk() -- allocate memory with error processing
*
* ******************************************************************** */
void *malloc_chk(int s) // size to allocate
{
void *p; // work pointer
if ((p = malloc(s)) == 0) // q. out of memory?
quit_with(no_memory, s); // a. yes .. give error msg
return(p); // finally rtn with pointer
}
/* ******************************************************************** *
*
* field_edit() -- edit a string field in a window
*
* ******************************************************************** */
int field_edit(Window *win, // window to work in
int c, int r, // initial column and row
char **s, // initial field data
int m) // maximum field length
{
int i, // string index
k, // keyboard input
x, // current column
ins; // insert flag
char *org, // original string pointer
*w, // work string pointer
b[80]; // work buffer
org = *s; // get initial field data
w = (char *) malloc_chk(m + 1); // allocate work string
memset(w, ' ', m); // clear to blanks
w[m] = 0; // ..and make a string
ins = 0; // clear insert flag
if (org) // q. orig data available?
strncpy(w, org, strlen(org)); // a. yes .. copy to work
CURSOR(); // turn cursor on
win->AtSayReverse(c, r, w); // ..display field
win->GotoXY(x = c, r); // locate start of field
for(;;) // loop till user quits
{
while (NOT (k = get_key(NO_ALT))) // wait for a key
; // ..before continuing
switch (k) // handle user's input
{
case LEFT: // left key
if (--x < c) // q. past left margin?
x = c; // a. yes .. reset
break; // ..then get next key
case RIGHT: // right key
if (++x >= (m + c - 1)) // q. past right margin?
x = m + c - 1; // a. yes .. reset
break; // ..then get next key
case BACKSPACE: // backspace
if (x == c) // q. at top of window?
{
printf(BELL); // a. yes .. give warning
break; // ..and wait for another..
}
x--; // move left one character
// ..and fall into delete key
case DELETE: // delete key
i = x - c; // set up string index
strcpy(&w[i], &w[i + 1]); // simulate delete
w[m - 1] = ' '; // ..and put a blank at end
sprintf(b, "%s", &w[i]); // make into string
win->AtSayReverse(x, r, b); // ..display remainder
break; // ..and wait for next key
case HOME: // home key
x = c; // reset pointer to start
break; // ..and wait for next key
case END: // end key
x = c + m - 1; // reset pointer to end
break; // ..and wait for next key
case CR: // carriage return
case UP: // up arrow key
case DOWN: // down arrow key
NOCURSOR(); // turn cursor off
free(org); // release original data
*s = w; // store addr of new data
win->AtSay(c, r, w); // ..display field normally
return(DOWN); // ..then return to caller
case ESC: // escape key
NOCURSOR(); // turn cursor off
win->AtSay(c, r, w); // ..display field normally
free(w); // release work copy
return(0); // ..then return to caller
case INSERT: // insert toggle
if (ins) // q. insert mode active?
{
ins = 0; // a. yes .. turn it off
CURSOR(); // ..and use proper cursor
}
else
{
ins = 1; // else .. set on insert
BIGCURSOR(); // ..and show insert cursor
}
break; // then wait for next key
default: // error case
if (k & 0xff00 || // q. function key..
k < ' ') // ..or less than a blank?
{
printf(BELL); // a. yes .. ring the bell
break; // ..and wait for next key
}
i = x - c; // get string index
if (ins) // q. insert mode active?
{
memmove(&w[i + 1], &w[i], // a. yes .. move everything
m - i); // ..for the remainder over
w[m] = 0; // ..and overlay the overflow
w[i] = (char) k; // put new char its place
sprintf(b, "%s", &w[i]); // make into a displayable
}
else
{
w[i] = (char) k; // save character in string
sprintf(b, "%c", k); // make into a string
}
win->AtSayReverse(x, r, b); // display new char/string
if (i < (m - 1)) // q. up to right margin?
x++; // a. no .. advance one
break; // ..then get next key
}
win->GotoXY(x, r); // ..then go there
}
}
/* ******************************************************************** *
*
* delete_file() -- delete file any way necessary
*
* ******************************************************************** */
int delete_file(char *s) // filename to delete
{
int rc; // return code, 0=ok
if ((rc = unlink(s)) != 0) // q. regular unlink work?
{ // a. no .. change attributes
if (NOT (rc = chmod(s, S_IWRITE))) // q. change work?
rc = unlink(s); // a. yes .. try delete again
}
return(rc); // return with final status
}
/* ******************************************************************** *
*
* pad() -- pad a string to a length
*
* ******************************************************************** */
void pad(char *s, // target string
int len) // final length
{
int i; // calculated pad length
i = strlen(s); // get current length
if (i < len) // q. need padding?
{
len -= i; // a. yes .. get pad length
memset(&s[i], ' ', len); // ..blank out rest
}
s[len] = 0; // ..and terminate string
}
/* ******************************************************************** *
*
* touppers() -- translate all characters to uppercase
*
* ******************************************************************** */
void touppers(char *s) // string to translate
{
while (*s) // for each char in string
{
*s = toupper(*s); // .. translate to uppercase
s++; // .. and go to next char
}
}
/* ******************************************************************** *
*
* control_break() -- control break intercept routine
*
* ******************************************************************** */
#pragma option -O2-b-e // no global reg allocation
// ..or dead code elimination
void interrupt control_break(...)
{
asm mov al, 20 // al = end of interrupt cmd
asm out 20, al // clear kb interrupt on 8259
}
/* ******************************************************************** *
*
* critical_rtn() -- DOS critical error handler
*
* ******************************************************************** */
#pragma option -O2-b-e // no global reg allocation
// ..or dead code elimination
void interrupt critical_routine(...)
{
if (_AX & 0x800) // q. fail allowed?
_AX = (_AX & 0xff00) | 3; // a. yes .. show failed
else
_AX = (_AX & 0xff00) | 2; // else .. abort
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -