diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d24f18..cc61315 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,65 +1,117 @@ -################################# -# Project -############## +# DOS utilities for mars-nwe. +# +# Default mode: install a prebuilt net.exe from this source tree. This keeps the +# normal mars-nwe build independent from Open Watcom. +# +# Maintainer mode: configure with -DMARS_NWE_BUILD_DOSUTILS=ON to rebuild +# net.exe with Open Watcom v2 on Linux. -################################# -# Dependencies -############## - -################################# -# Compiler Switches -############## - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_BINARY_DIR}/include +set(MARS_DOSUTILS_NET_EXE + "${CMAKE_CURRENT_SOURCE_DIR}/net.exe" + CACHE FILEPATH "Prebuilt DOS net.exe used for installation when MARS_NWE_BUILD_DOSUTILS is OFF" ) -if (CMAKE_SYSTEM_NAME MATCHES Linux) - add_definitions( - -DLINUX -D_GNU_SOURCE -Dsignal=__sysv_signal - ) -endif (CMAKE_SYSTEM_NAME MATCHES Linux) +set(MARS_DOSUTILS_PUBLIC_TOOLS + net + login + profile + spawn + passwd + path + pathins + pathdel + map + mapdel + logout + capture + endcap +) -add_definitions( - -D_VERS_H_=\"${VERSION_MAJOR}\" - -D_VERS_L_=\"${VERSION_MINOR}\" - -D_VERS_P_=\"${VERSION_PATCH}\" +# Do not install slist.exe yet: func_slist() is empty and SLIST is disabled in net.c. +# Do not install tests/debug by default either; they are developer-only helpers. + +if(MARS_NWE_BUILD_DOSUTILS) + find_package(OpenWatcom REQUIRED) + + set(DOSUTILS_C_SOURCES + net.c + tools.c + netcall.c + ncpcall.c + login.c + map.c + nwcrypt.c + nwdebug.c + nwtests.c + capture.c ) -################################# -# Source Files -############## + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/kern.obj" + COMMAND "${CMAKE_COMMAND}" -E env ${OPENWATCOM_ENV} + "${OPENWATCOM_WASM}" + -q + -zq + -fo="${CMAKE_CURRENT_BINARY_DIR}/kern.obj" + "${CMAKE_CURRENT_SOURCE_DIR}/kern_wasm.asm" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/kern_wasm.asm" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM + ) -#add_executable( net logon.c ... ) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/net.exe" + COMMAND "${CMAKE_COMMAND}" -E env ${OPENWATCOM_ENV} + "${OPENWATCOM_WCL}" + -q + -zq + -bt=dos + -ml + -0 + -k32768 + -fe="${CMAKE_CURRENT_BINARY_DIR}/net.exe" + ${DOSUTILS_C_SOURCES} + "${CMAKE_CURRENT_BINARY_DIR}/kern.obj" + DEPENDS + ${DOSUTILS_C_SOURCES} + "${CMAKE_CURRENT_BINARY_DIR}/kern.obj" + net.h + kern.h + nwcrypt.h + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM + ) -################################# -# Linking -############## + add_custom_target(dosutils_net ALL + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/net.exe" + ) -################################# -# Install Files -############## + set(MARS_DOSUTILS_NET_EXE "${CMAKE_CURRENT_BINARY_DIR}/net.exe") +else() + if(NOT EXISTS "${MARS_DOSUTILS_NET_EXE}") + message(FATAL_ERROR + "Prebuilt DOS utility missing: ${MARS_DOSUTILS_NET_EXE}. " + "Either commit net.exe into dosutils or configure with " + "-DMARS_NWE_BUILD_DOSUTILS=ON and Open Watcom installed." + ) + endif() +endif() -# install the system utils -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME login.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME profile.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME spawn.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME passwd.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME path.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME pathins.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME pathdel.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME map.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME mapdel.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME logout.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME slist.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME capture.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public RENAME endcap.exe) - -# and the minimal login utils -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login RENAME login.exe) -install(FILES net.exe DESTINATION ${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login RENAME map.exe) +foreach(tool IN LISTS MARS_DOSUTILS_PUBLIC_TOOLS) + if(tool STREQUAL "net") + install(FILES "${MARS_DOSUTILS_NET_EXE}" + DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public") + else() + install(FILES "${MARS_DOSUTILS_NET_EXE}" + DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public" + RENAME "${tool}.exe") + endif() +endforeach() +install(FILES "${MARS_DOSUTILS_NET_EXE}" + DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login" + RENAME login.exe) +install(FILES "${MARS_DOSUTILS_NET_EXE}" + DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login" + RENAME map.exe) diff --git a/kern.asm b/kern.asm old mode 100755 new mode 100644 diff --git a/kern.h b/kern.h old mode 100755 new mode 100644 index 6344225..978a784 --- a/kern.h +++ b/kern.h @@ -1,12 +1,12 @@ -/* kern.h Assembler Routinen 20-Nov-93 */ -extern int IPXinit(void); -extern int IPXopen_socket(UI sock, int live); -extern void IPXclose_socket(UI sock); -extern int IPXlisten(ECB *ecb); -extern void asm_esr_routine(void); -extern void esr_routine(ECB *ecb); -extern void xmemmove(void *ziel, void *quelle, UI anz); -extern int Net_Call(UI func, void *req, void *repl); - - - +/* kern.h Assembler Routinen 20-Nov-93 */ +extern int IPXinit(void); +extern int IPXopen_socket(UI sock, int live); +extern void IPXclose_socket(UI sock); +extern int IPXlisten(ECB *ecb); +extern void asm_esr_routine(void); +extern void esr_routine(ECB *ecb); +extern void xmemmove(void *ziel, void *quelle, UI anz); +extern int Net_Call(UI func, void *req, void *repl); + + + diff --git a/kern_wasm.asm b/kern_wasm.asm new file mode 100644 index 0000000..c405462 --- /dev/null +++ b/kern_wasm.asm @@ -0,0 +1,216 @@ +; kern_wasm.asm +; +; Open Watcom WASM/MASM-syntax port of the old TASM IDEAL kern.asm. +; Intended for 16-bit DOS large memory model builds on Linux with Open Watcom v2. +; +; Keep kern.asm as the historical TASM source and use this file for the +; reproducible Open Watcom build. + +.286 +.model large + +.data +enterIPX dd 0 + +.code + +public IPXinit_ +public IPXopen_socket_ +public IPXclose_socket_ +public IPXlisten_ +public xmemmove_ +public Net_Call_ + +IPXinit_ proc far + push bp + mov bp, sp + push ds + push si + push di + + mov ax, 7A00h + int 2Fh + cmp al, 0FFh + jne ipxinit_done + + mov cx, @data + mov ds, cx + mov word ptr enterIPX, di + mov ax, es + mov word ptr enterIPX+2, ax + mov al, 1 + +ipxinit_done: + mov ah, 0 + + pop di + pop si + pop ds + pop bp + ret +IPXinit_ endp + +xmemmove_ proc far + push bp + mov bp, sp + + ; far procedure stack layout, large model: + ; [bp+0] old bp + ; [bp+2] return offset + ; [bp+4] return segment + ; [bp+6] z offset + ; [bp+8] z segment + ; [bp+10] q offset + ; [bp+12] q segment + ; [bp+14] nmbr + + cli + mov cx, [bp+14] + or cx, cx + jz xmem_done + + push ds + push si + push di + pushf + + lds si, dword ptr [bp+10] + les di, dword ptr [bp+6] + cmp di, si + jl xmem_forward + + std + dec cx + add di, cx + add si, cx + inc cx + jmp xmem_copy + +xmem_forward: + cld + +xmem_copy: + rep movsb + + popf + pop di + pop si + pop ds + +xmem_done: + pop bp + sti + ret +xmemmove_ endp + +IPXopen_socket_ proc far + push bp + mov bp, sp + push ds + push si + push di + + ; int IPXopen_socket(UI sock, int live) + mov ax, [bp+8] ; live + mov dx, [bp+6] ; sock + mov bx, @data + mov ds, bx + mov bx, 0 + call dword ptr enterIPX + + cmp al, 0FFh + jne ipxopen_not_already + mov ax, -1 ; socket already open + jmp ipxopen_done + +ipxopen_not_already: + cmp al, 0FEh + jne ipxopen_ok + mov ax, -2 ; socket table full + jmp ipxopen_done + +ipxopen_ok: + mov ax, dx + +ipxopen_done: + pop di + pop si + pop ds + pop bp + ret +IPXopen_socket_ endp + +IPXclose_socket_ proc far + push bp + mov bp, sp + push ds + push si + push di + + ; void IPXclose_socket(UI sock) + mov dx, [bp+6] + mov bx, @data + mov ds, bx + mov bx, 1 + call dword ptr enterIPX + + pop di + pop si + pop ds + pop bp + ret +IPXclose_socket_ endp + +IPXlisten_ proc far + push bp + mov bp, sp + push ds + push si + push di + + ; int IPXlisten(ECB *ecb) + les si, dword ptr [bp+6] + mov bx, @data + mov ds, bx + mov bx, 4 + call dword ptr enterIPX + + pop di + pop si + pop ds + pop bp + mov ah, 0 + ret +IPXlisten_ endp + +Net_Call_ proc far + push bp + mov bp, sp + + ; int Net_Call(UI func, void *req, void *repl) + ; [bp+6] func + ; [bp+8] req offset + ; [bp+10] req segment + ; [bp+12] repl offset + ; [bp+14] repl segment + mov ax, [bp+6] + + push ds + push si + push di + pushf + + lds si, dword ptr [bp+8] + les di, dword ptr [bp+12] + int 21h + + popf + pop di + pop si + pop ds + pop bp + mov ah, 0 + ret +Net_Call_ endp + +end diff --git a/login.c b/login.c old mode 100755 new mode 100644 index c479f2b..dbc4974 --- a/login.c +++ b/login.c @@ -391,9 +391,17 @@ int func_exec(int argc, char *argv[], int mode) xfree(buff); if (nargv != NULL) { if (!mode) +#ifdef __WATCOMC__ + spawnvp(P_WAIT, buf, (const char * const *)nargv); +#else spawnvp(P_WAIT, buf, nargv); +#endif else +#ifdef __WATCOMC__ + execvp(buf, (const char * const *)nargv); +#else execvp(buf, nargv); +#endif } xfree(buf); } diff --git a/makefile.bcc b/makefile.bcc old mode 100755 new mode 100644 diff --git a/map.c b/map.c old mode 100755 new mode 100644 diff --git a/ncpcall.c b/ncpcall.c old mode 100755 new mode 100644 diff --git a/net.c b/net.c old mode 100755 new mode 100644 diff --git a/net.h b/net.h old mode 100755 new mode 100644 index ad1afce..eb7bfe1 --- a/net.h +++ b/net.h @@ -15,6 +15,9 @@ #include #include #include +#ifdef __WATCOMC__ +#include +#endif typedef unsigned int UI; typedef unsigned int uint; @@ -135,6 +138,12 @@ extern void leb(uint8 *s); extern char *getglobenv(char *option); extern int putglobenv(char *option); +#ifdef __WATCOMC__ +/* Borland C compatibility wrappers implemented in tools.c. */ +extern int getcurdir(int drive, char *directory); +extern void setdisk(int drive); +#endif + /* NETCALLS */ #define DRIVE_ADD 1 #define DRIVE_INSERT 2 @@ -159,6 +168,12 @@ extern int neterrno; alloc_dir_handle(0x13, (dhandle), (path), (drive), (rights)) extern int ipx_init(void); +extern int logout(void); +extern int redir_device_drive(int devicetyp, uint8 *devname, uint8 *remotename); +extern int list_redir(int index, int *devicetyp, uint8 *devname, uint8 *remotename); +extern int get_drive_info(uint8 drivenumber, uint8 *connid, + uint8 *dhandle, uint8 *statusflags); +extern int get_fs_name(int connid, char *name); extern int alloc_dir_handle(int func, int dhandle, char *path, int driveletter, uint8 *effrights); @@ -179,11 +194,13 @@ extern int ncp_16_02(int dirhandle, uint32 *creattime, uint32 *owner_id); +extern int ncp_14_46(uint32 *obj_id); extern int ncp_17_02(int module, int debuglevel); extern int ncp_17_14(uint8 *objname, uint16 objtyp, uint8 *password); extern int ncp_17_17(uint8 *key); extern int ncp_17_18(uint8 *cryptkey, uint8 *objname, uint16 objtyp); extern uint32 ncp_17_35(uint8 *objname, uint16 objtyp); +extern int ncp_17_36(uint32 obj_id, uint8 *objname, uint16 *objtyp); extern int ncp_17_40(uint8 *objname, uint16 objtyp, uint8 *password, uint8 *newpassword); @@ -193,6 +210,7 @@ extern int ncp_17_4b(uint8 *cryptkey, uint8 *objname, uint16 objtyp, /* map.c */ extern int func_map (int argc, char *argv[], int mode); extern int func_path (int argc, char *argv[], int mode); +extern void remove_nwpathes(void); /* login.c */ extern int func_login (int argc, char *argv[], int mode); diff --git a/netcall.c b/netcall.c old mode 100755 new mode 100644 diff --git a/nwcrypt.c b/nwcrypt.c old mode 100755 new mode 100644 diff --git a/nwcrypt.h b/nwcrypt.h old mode 100755 new mode 100644 diff --git a/nwdebug.c b/nwdebug.c old mode 100755 new mode 100644 diff --git a/nwtests.c b/nwtests.c old mode 100755 new mode 100644 diff --git a/slist.c b/slist.c old mode 100755 new mode 100644 diff --git a/teste.c b/teste.c old mode 100755 new mode 100644 index 7d6711e..c6fcc99 --- a/teste.c +++ b/teste.c @@ -1,95 +1,95 @@ -int main() -{ - char *fn="F.$LN"; - char *string="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"; - int result; - struct stat stbuff; - long offset; - char buff[1024]; - char readbuff[500]; - int j; - int fd=creatnew(fn, S_IREAD |S_IWRITE); - if (fd > -1) { - printf("Konnte Date erzeugen\n"); - close(fd); - } else { - printf("Konnte Datei nicht erzeugen\n"); - } - fd = open(fn, O_RDWR|O_CREAT|O_TRUNC|O_DENYNONE, 0666); - memset(buff, 0, sizeof(buff) ); - strcpy(buff, string); - write(fd, buff, strlen(buff)); - close(fd); - _chmod(fn, 1, _chmod(fn, 0) | 0x80 ); - stat(fn, &stbuff); - printf("Filesize ber stat =%ld\n", stbuff.st_size); - fd = open(fn, O_RDWR | O_BINARY |O_DENYNONE); - - offset = lseek(fd, 0L, SEEK_END); - printf("Filesize ber lseek =%ld\n", offset); - write(fd, buff, strlen(buff)); - - lseek(fd, 0L, SEEK_SET); - for (j=0; j < strlen(buff)*2; j++){ - read(fd, readbuff, 1); - printf("BUFF = %c\n", readbuff[0]); - } - lseek(fd, 1L, SEEK_SET); - for (j = 0; j < 20; j++){ - write(fd, buff+j, 1); - } - - for (j=0; j <60; j++){ - lseek(fd, (long) j, SEEK_SET); - read(fd, readbuff, 2); - printf("BUFF = %c, %c \n", readbuff[0], readbuff[1]); - } - - lseek(fd, 10L, SEEK_SET); - read(fd, buff, 1); - printf("BUFF[10] = %c\n", buff[0]); - result=lock(fd, 100L, 1L); - printf("lock result = %d\n", result); - result=unlock(fd, 100L, 1L); - printf("unlock result = %d\n", result); - close(fd); - - fd = open(fn, O_BINARY|O_RDWR|O_CREAT|O_TRUNC|O_DENYNONE, 0666); - if (fd > -1) { - int bufflen; - strcpy(buff, "d:..\\marlib\\c0l.obj+"); - strcat(buff, "\r\n"); - strcat(buff, "x"); - strcat(buff, "\r\n"); - strcat(buff, "x"); - strcat(buff, "\r\n"); - strcat(buff, "/c/x"); - strcat(buff, "\r\n"); - strcat(buff, "d:..\\marlib\\EMU.LIB+"); - strcat(buff, "\r\n"); - strcat(buff, "d:..\\marlib\\mathl.lib+"); - strcat(buff, "\r\n"); - strcat(buff, "d:..\\marlib\\cl.lib"); - bufflen=strlen(buff); - printf("bufflen = %d, buff=%s\n", bufflen, buff); - write(fd, buff, bufflen); - close(fd); - fd = open(fn, O_TEXT|O_RDONLY); - if (fd > -1) { - char *p=readbuff; - int anz = 0; - memset(readbuff, 0, sizeof(readbuff) ); - while (read(fd, p, 1) == 1){ - anz++; - p++; - } - printf("read = %d, buff=%s\n", anz, readbuff); - close(fd); - } - } - /* - result = detach(1); - printf("Detach result=0x%x", result); - */ - return(0); -} +int main() +{ + char *fn="F.$LN"; + char *string="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"; + int result; + struct stat stbuff; + long offset; + char buff[1024]; + char readbuff[500]; + int j; + int fd=creatnew(fn, S_IREAD |S_IWRITE); + if (fd > -1) { + printf("Konnte Date erzeugen\n"); + close(fd); + } else { + printf("Konnte Datei nicht erzeugen\n"); + } + fd = open(fn, O_RDWR|O_CREAT|O_TRUNC|O_DENYNONE, 0666); + memset(buff, 0, sizeof(buff) ); + strcpy(buff, string); + write(fd, buff, strlen(buff)); + close(fd); + _chmod(fn, 1, _chmod(fn, 0) | 0x80 ); + stat(fn, &stbuff); + printf("Filesize ber stat =%ld\n", stbuff.st_size); + fd = open(fn, O_RDWR | O_BINARY |O_DENYNONE); + + offset = lseek(fd, 0L, SEEK_END); + printf("Filesize ber lseek =%ld\n", offset); + write(fd, buff, strlen(buff)); + + lseek(fd, 0L, SEEK_SET); + for (j=0; j < strlen(buff)*2; j++){ + read(fd, readbuff, 1); + printf("BUFF = %c\n", readbuff[0]); + } + lseek(fd, 1L, SEEK_SET); + for (j = 0; j < 20; j++){ + write(fd, buff+j, 1); + } + + for (j=0; j <60; j++){ + lseek(fd, (long) j, SEEK_SET); + read(fd, readbuff, 2); + printf("BUFF = %c, %c \n", readbuff[0], readbuff[1]); + } + + lseek(fd, 10L, SEEK_SET); + read(fd, buff, 1); + printf("BUFF[10] = %c\n", buff[0]); + result=lock(fd, 100L, 1L); + printf("lock result = %d\n", result); + result=unlock(fd, 100L, 1L); + printf("unlock result = %d\n", result); + close(fd); + + fd = open(fn, O_BINARY|O_RDWR|O_CREAT|O_TRUNC|O_DENYNONE, 0666); + if (fd > -1) { + int bufflen; + strcpy(buff, "d:..\\marlib\\c0l.obj+"); + strcat(buff, "\r\n"); + strcat(buff, "x"); + strcat(buff, "\r\n"); + strcat(buff, "x"); + strcat(buff, "\r\n"); + strcat(buff, "/c/x"); + strcat(buff, "\r\n"); + strcat(buff, "d:..\\marlib\\EMU.LIB+"); + strcat(buff, "\r\n"); + strcat(buff, "d:..\\marlib\\mathl.lib+"); + strcat(buff, "\r\n"); + strcat(buff, "d:..\\marlib\\cl.lib"); + bufflen=strlen(buff); + printf("bufflen = %d, buff=%s\n", bufflen, buff); + write(fd, buff, bufflen); + close(fd); + fd = open(fn, O_TEXT|O_RDONLY); + if (fd > -1) { + char *p=readbuff; + int anz = 0; + memset(readbuff, 0, sizeof(readbuff) ); + while (read(fd, p, 1) == 1){ + anz++; + p++; + } + printf("read = %d, buff=%s\n", anz, readbuff); + close(fd); + } + } + /* + result = detach(1); + printf("Detach result=0x%x", result); + */ + return(0); +} diff --git a/tools.c b/tools.c old mode 100755 new mode 100644 index 35a86ed..ff30402 --- a/tools.c +++ b/tools.c @@ -5,21 +5,66 @@ * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * ****************************************************************/ + +#ifdef __WATCOMC__ +/* + * Borland C compatibility wrappers used by the historical mars-nwe DOS tools. + * Open Watcom does not provide getcurdir()/setdisk() under these Borland names. + */ +int getcurdir(int drive, char *directory) +{ + REGS regs; + SREGS sregs; + + regs.h.ah = 0x47; /* DOS: get current directory */ + regs.h.dl = (unsigned char)drive; /* 0=current, 1=A:, 2=B:, ... */ + sregs.ds = FP_SEG(directory); + regs.x.si = FP_OFF(directory); + intdosx(®s, ®s, &sregs); + return(regs.x.cflag ? -1 : 0); +} + +void setdisk(int drive) +{ + REGS regs; + + regs.h.ah = 0x0e; /* DOS: select default drive */ + regs.h.dl = (unsigned char)drive; /* 0=A:, 1=B:, ... */ + intdos(®s, ®s); +} +#endif + int key_pressed(void) { +#ifdef __WATCOMC__ + /* + * Open Watcom's WORDREGS does not expose x.flags. The old Borland + * code checked the BIOS INT 16h ZF bit after AH=01h. Open Watcom's + * bios.h provides _bios_keybrd(), which wraps the same BIOS keyboard + * service and returns 0 when no key is waiting. + */ + return(_bios_keybrd(_KEYBRD_READY) != 0); +#else REGS regsin, regsout; regsin.h.ah = 0x01; /* read key-press */ int86(0x16, ®sin, ®sout); return((regsout.x.flags & 0x40) ? 0 : 1); /* zeroflag != 0 */ +#endif } void clear_kb(void) { +#ifdef __WATCOMC__ + while (key_pressed()) { + (void)_bios_keybrd(_KEYBRD_READ); + } +#else REGS regsin, regsout; while (key_pressed()) { /* zeroflag != 0 */ regsin.h.ah = 0x00; /* read key-press */ int86(0x16, ®sin, ®sout); } +#endif } int ask_user(char *p, ...)