home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
t
/
tel2305s.zip
/
ENGINE
/
NCSAIO.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-03-28
|
59KB
|
2,496 lines
;
; ncsaio.asm
; Support for BIOS calls in NCSA Telnet
;****************************************************************************
;* *
;* *
;* part of NCSA Telnet *
;* by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer *
;* *
;* National Center for Supercomputing Applications *
;* 152 Computing Applications Building *
;* 605 E. Springfield Ave. *
;* Champaign, IL 61820 *
;* *
;* *
;****************************************************************************
TITLE NCSAIO -- LOW-LEVEL I/O FOR SANE HARDWARE HANDLING
;Microsoft EQU 1
;Lattice EQU 1
ifndef Microsoft
ifndef Lattice
if2
%out
%out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
%out MASM command line to determine the type of assembly.
%out
endif
end
endif
endif
;
; From original code by Tim Krauskopf 1984-1985
;
; Modified and ported to Lattice C, Sept. 1986
; ifdefs for Microsoft C, June 1987
; Tim Krauskopf
;
; Modified for version 2.3 release May 1990 by Heeren Pathak
;
; National Center for Supercomputing Applications
;
NAME NIO
;
; Macros for reading and writing I/O ports
;
MOUT MACRO REG,STUFF ; one byte to the given I/O register
MOV DX,REG
MOV AL,STUFF
OUT DX,AL
ENDM
;
MIN MACRO REG ; get one byte to al
MOV DX,REG
IN AL,DX
ENDM
;
; Internal data
;
X EQU 6 ; for the large model programs
MONO_SEG EQU 0b000h ; Standard display segments
COLOR_SEG EQU 0b800h
ifdef Microsoft
;DGROUP group _DATA
;_DATA segment public 'DATA'
; assume DS:DGROUP
.MODEL LARGE
.DATA
ifndef NET14
PUBLIC _DTAPTR ; pointer to dta location
PUBLIC _KEYBOARD_TYPE ; Keyboard type installed
_DTAPTR DW 0000H ; DTA address for me
_DTADS DW 0000H ; DS for DTA
endif
_KEYBOARD_TYPE DB ? ; KEYBOARD TYPE (0) - is standard
; (0x10) is enhanced
else
INCLUDE DOS.MAC
DSEG
ifndef NET14
PUBLIC DTAPTR ; pointer to dta location
PUBLIC KEYBOARD_TYPE ; Keyboard type installed
DTAPTR DW 0000H ; dta ADDRESS FOR ME
DTADS DW 0000H ; ds FOR dta
endif
KEYBOARD_TYPE DB ? ; KEYBOARD TYPE (0) - is standard
; (0x10) is enhanced
endif
ATT DB 7 ; CURRENT DEFAULT ATTRIBUTE
TOPL DB 00 ; TOP LINE OF CURRENT WINDOW
BOTL DB 24 ; BOTTOM LINE OF CURRENT WINDOW
LEFTC DB 00 ; LEFT SIDE OF CURRENT WINDOW
RIGHTC DB 79 ; RIGHT SIDE OF CURRENT WINDOW
ROW DB 00 ; CURSOR POSITION ROW
COL DB 00 ; CURSOR POSITION COL
WRAP DB 00 ; WRAP AT END OR NOT
CURSOR DW 0607H ; DEFAULT CURSOR SHAPE
CURSOR_SAVE DW ? ; PLACE TO SAVE THE USER'S CURSOR IN
BREAK_STATE DB ? ; WHETHER THE BREAK IS SET TO ON OR OFF
EGAMODE DB ? ; DEFAULT EGA MODE
video_segment DW COLOR_SEG ; Display memory segment address
video_type DB 0ffh ; Display combination code
video_iscolor DB 01h ; 1=color, 0=monochrome
video_mode DB 03h ; Video display mode
video_page DB 00h ; Video Display Page
video_rows DB 25 ; Number of Text rows
video_cols DB 80 ; Number of Text columns
video_cursor DW ? ; Cursor shape
video_font DW ? ; Current font function
ifdef Microsoft
;_DATA ends
else
ENDDS
endif
;
; The subroutines to call from C
;
ifdef Microsoft
;_TEXT segment public 'CODE'
; assume CS:_TEXT
.CODE
ifndef NET14
PUBLIC _n_color
endif
ifdef FTPBIN
PUBLIC _n_wrap
endif
; PUBLIC _n_erase
ifndef NET14
PUBLIC _n_getchar,_n_cur,_n_row,_n_col,_n_clear,_n_window
endif
PUBLIC _n_putchar
ifndef NET14
PUBLIC _n_chkchar
endif
; PUBLIC _n_savewin,_n_restwin
PUBLIC _n_puts,_n_sound
ifndef NET14
PUBLIC _n_findfirst,_n_findnext,_n_draw,_n_scrup,_n_scrdn,_n_cheat
endif
PUBLIC _n_clicks
ifndef NET14
PUBLIC _n_biosattr
endif
; PUBLIC _getdsk, _chgdsk
ifndef NET14
PUBLIC _ega43,_n_flags,_set_cur,_ega24,_vga50
PUBLIC _n_scrlck,_save_break,_restore_break,_n_gmode,_save_cursor
PUBLIC _restore_cursor,_install_cursor,_n_attr
PUBLIC _install_keyboard,_fix_vid,_get_mode,_set_mode,_get_size
PUBLIC _set_page,_initvideo,_getvconfig,_getvstate,_setvstate
endif
else ; Lattice C
PSEG
ifndef NET14
PUBLIC n_color
endif
ifdef FTPBIN
PUBLIC n_wrap
endif
; PUBLIC n_erase
ifndef NET14
PUBLIC n_getchar,n_cur,n_row,n_col,n_clear,n_window
endif
PUBLIC n_putchar
ifndef NET14
PUBLIC n_chkchar
endif
; PUBLIC n_savewin,n_restwin
PUBLIC n_puts,n_sound
ifndef NET14
PUBLIC n_findfirst,n_findnext,n_draw,n_scrup,n_scrdn,n_cheat
endif
PUBLIC n_clicks
ifndef NET14
PUBLIC n_biosattr
endif
PUBLIC n_srclck
ifndef NET14
PUBLIC ega43,n_flags,set_cur,ega24,vga50
PUBLIC n_scrlck,save_break,restore_break,n_gmode,save_cursor
PUBLIC restore_cursor,install_cursor,n_attr
PUBLIC install_keyboard,fix_vid,get_mode,set_mode,get_size
PUBLIC set_page,initvideo,getvconfig,getvstate,setvstate
endif
endif
ifndef NET14
;****************************************************************
; install_keyboard
;
; check for enhanced keyboard, and set keyboard type variable
;
;
ifdef Microsoft
_install_keyboard proc far
else
install_keyboard proc far
endif
PUSH DS
PUSH SI
MOV AX,040H ; load the address of the keyboard flag
MOV DS,AX
MOV SI,096H
LODSB ; get the keyboard flag
POP SI
POP DS
AND AL,10H ; mask off all bits except the enhanced flag
ifdef Microsoft
MOV _KEYBOARD_TYPE,AL ; store the keyboard type
else
MOV KEYBOARD_TYPE,AL ; store the keyboard type
endif
RET
ifdef Microsoft
_install_keyboard endp
else
install_keyboard endp
endif
;****************************************************************
; install cursor
;
; put in user defined cursor settings
;
;
ifdef Microsoft
_install_cursor proc far
else
install_cursor proc far
endif
push bp ; save the base pointer
mov bp,sp ; point to the stack
mov AX,[bp+x] ; read our first parameter
mov CURSOR,AX ; save into the cursor variable
pop bp ; get the old base
ret
ifdef Microsoft
_install_cursor endp
else
install_cursor endp
endif
;/***************************************************************/
; scrlck
; returns whether scroll lock is on or not
;
ifdef Microsoft
_n_scrlck proc far
else
n_scrlck proc far
endif
mov ax,0200h ; get shift states
int 16h ; keyboard int
and al,010h ; scroll lock state bit
xor ah,ah
ret
ifdef Microsoft
_n_scrlck endp
else
n_scrlck endp
endif
;*********************************************************************
;* save_break
;* record the state of the DOS BREAK status, and turn BREAK ON
;*
ifdef Microsoft
_save_break proc far
else
save_break proc far
endif
MOV AX,3300H ; request current break state
INT 21H ;
MOV BREAK_STATE,DL ; preserve the break state
MOV AX,3301H ; set break state
MOV DL,1 ; turn break on
INT 21H ;
RET
ifdef Microsoft
_save_break endp
else
save_break endp
endif
;*********************************************************************
;* restore_break
;* restore the previous state of the DOS BREAK state
;*
ifdef Microsoft
_restore_break proc far
else
restore_break proc far
endif
MOV AX,3301H ; set break state
MOV DL,BREAK_STATE ; return break state to previous value
INT 21H ;
RET
ifdef Microsoft
_restore_break endp
else
restore_break endp
endif
;*********************************************************************
;* save_cursor
;* record the state of the DOS keyboard cursor for page 0
;*
ifdef Microsoft
_save_cursor proc far
else
save_cursor proc far
endif
MOV AX,0300h ; GET THE CURRENT CURSOR TYPE
MOV BX,0000h ; INFO FOR PAGE 0
INT 10h
MOV CURSOR_SAVE,CX
RET
ifdef Microsoft
_save_cursor endp
else
save_cursor endp
endif
;*********************************************************************
;* restore_cursor
;* restore the previous state of the DOS keyboard cursor
;*
ifdef Microsoft
_restore_cursor proc far
else
restore_cursor proc far
endif
MOV AH,01H ; set the keyboard cursor
MOV CX,CURSOR_SAVE ; get the user's keyboard cursor
INT 10H ; set the cursor
RET
ifdef Microsoft
_restore_cursor endp
else
restore_cursor endp
endif
;*********************************************************************
;* n_gmode
;* change the type of video display being used
;*
ifdef Microsoft
_n_gmode PROC FAR
else
n_gmode PROC FAR
endif
PUSH BP
MOV BP,SP
MOV AX,[BP+X] ;GET SCREEN MODE TO SWITCH TO
XOR AH,AH ;ENTER VIDEO_IO ROUTINE (SET MODE=0)
INT 10H ;VIDEO INTERUPT
POP BP
RET
ifdef Microsoft
_n_gmode ENDP
else
n_gmode ENDP
endif
;*********************************************************************
;* ega24
;* set char set for 24 line mode
;*
ifdef Microsoft
_ega24 proc far
else
ega24 proc far
endif
MOV BL,30H ;Select scan lines for alphanumeric modes.
MOV AX,1202H ;Set 400 scan lines.
INT 10H
MOV AX,3 ; reset egamode
INT 10H
MOV AX,0100H ; SET CURSOR
MOV CX,CURSOR ; TURN ON
INT 10H
RET
ifdef Microsoft
_ega24 endp
else
ega24 endp
endif
;****************************************************************
;* set_cur
;* sets cursor on or off
;*
ifdef Microsoft
_set_cur proc far
else
set_cur proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ;get var
OR AL,AL
JNZ CUR ; MAKE CURSOR
MOV AX,0100H ; TURN OFF
MOV CX,2000H ; BEGIN END OF CURSOR
INT 10h
JMP SHORT EXIT ; we are done
CUR:
MOV CX,CURSOR ; get cursor type
MOV AX,0100h ; reset cursor
INT 10h
EXIT:
POP BP
RET
ifdef Microsoft
_set_cur endp
else
set_cur endp
endif
;****************************************************************
;* n_flags
;* returns the keyboard status flags
;*
ifdef Microsoft
_n_flags proc far
else
n_flags proc far
endif
MOV AX,0200h ; get shift states
INT 16h ; keyboard INT
XOR AH,AH
RET
ifdef Microsoft
_n_flags endp
else
n_flags endp
endif
;****************************************************************
;* ega43
;* code for 43 line ega mode
;*
ifdef Microsoft
_ega43 proc far
else
ega43 proc far
endif
ifdef OLD_WAY
MOV AH,00H ; SET TO 80X25 CHAR MODE
MOV AL,03H
INT 10H
MOV AX,1112H ; CHAR. GENERATOR BIOS ROUTINUE
MOV BL,00H ; LOAD 8 BY 8 DOUBLE DOT CHARACTER FONT
INT 10H ; VIDEO CALL
MOV AX,1200H ; ALTERNATE SCREEN ROUTINE
MOV BL,20H ; SELECT ALTERNATE PRINT SCREEN ROUTINE
INT 10H ; VIDEO CALL
else
MOV BL,30H ; Select scan lines for alphanumeric modes
MOV AX,1201H ; Set 350 scan lines
INT 10H
MOV AX,3 ; 80x25 color text
INT 10H
MOV AX,1112H ; Char. generator BIOS routine
MOV BL,00H ; Load 8x8 double dot character font
INT 10H ;
endif
MOV AX,0007H
MOV CURSOR,AX ; full cursor
RET
ifdef Microsoft
_ega43 endp
else
ega43 endp
endif
;****************************************************************
;* vga50
;* code for 50 line vga mode
;*
ifdef Microsoft
_vga50 proc far
else
vga50 proc far
endif
MOV BL,30H ; Select scan lines for alphanumeric modes
MOV AX,1202H ; Set 400 scan lines
INT 10H
MOV AX,3 ; 80x25 color text
INT 10H
MOV AX,1112H ; Char. generator BIOS routine
MOV BL,00H ; Load 8x8 double dot character font
INT 10H ;
MOV AX,0007H
MOV CURSOR,AX ; full cursor
RET
ifdef Microsoft
_vga50 endp
else
vga50 endp
endif
endif ; NET14
ifdef NOT_USED
;*****************************************************************
;* getDSk
;* gets the active drive
;*
ifdef Microsoft
_getdsk proc far
MOV AH,19H
INT 21h
RET
_getdsk endp
endif
;*****************************************************************
;* chgdsk
;* changes current drive
;*
ifdef Microsoft
_chgdsk proc far
PUSH BP
MOV BP,SP
MOV AH,0Eh
MOV DL,[BP+X]
INT 21H
POP BP
RET
_chgdsk endp
endif
endif
ifndef NET14
;*****************************************************************
;* n_attr
;* replaces char. attribute
;*
ifdef Microsoft
_n_attr proc far
else
n_attr proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DI
;
; for now, assume that the cursor location has ALready been set
; (cursor is there)
;
MOV AX,video_segment
MOV ES,AX ; set up for segment where screen is
MOV AL,ROW ; row where chars go
XOR AH,AH
MOV BL,160
MUL BL ; AX now equALs start of row
XOR BH,BH
MOV BL,COL
SHL BL,1 ; COL*2
ADD AX,BX ; add in column offset
INC AX
MOV DI,AX
MOV AL,[BP+X] ; ATTRIBUTE For CHARS
STOSB ; STorE aTTR
POP DI
POP ES
POP BP
RET
ifdef Microsoft
_n_attr endp
else
n_attr endp
endif
;*****************************************************************
;* n_biosattr
;* replaces char. attribute
;* uses bios instead of directly screen write
;*
ifdef Microsoft
_n_biosattr proc far
else
n_biosattr proc far
endif
PUSH BP
MOV BP,SP
MOV AH,8h ; we want to read
MOV BH,0H ; GET FROM PAGE ZERO
INT 10H
MOV BL,[BP+X] ; GET CHANGED ATTRIBUTE
MOV AH,9H ; WE WANT TO WRITE
MOV CX,1H ; ONLY ONCE
INT 10H
POP BP
RET
ifdef Microsoft
_n_biosattr endp
else
n_biosattr endp
endif
;/***************************************************************/
;
; Change the vALue of my current color
;
ifdef Microsoft
_n_color proc far
else
n_color proc far
endif
PUSH BP
MOV BP,SP
XOR AX,AX
MOV DL,[BP+X] ; PARAMETER, ONE BYTE
MOV AL,ATT ; RETURN OLD COLor
MOV ATT,DL
POP BP
RET
ifdef Microsoft
_n_color endp
else
n_color endp
endif
endif ; NET14
;/*****************************************************************/
; Determine the current type of DISPlay
;
; ask the BIOS which screen is currently active
;
ifdef Microsoft
_n_which proc far
else
n_which proc far
endif
MOV AX,0300h ; GET THE CURRENT CURSOR
MOV BX,0000h ; INFO FOR PAGE 0
INT 10h
MOV CURSOR,CX
RET
ifdef Microsoft
_n_which endp
else
n_which endp
endif
ifdef FTPBIN
;
;/***************************************************************/
;
; Set whether word wrap will be on or not
; usage: n_wrap(flag);
;
ifdef Microsoft
_n_wrap proc far
else
n_wrap proc far
endif
PUSH BP
MOV BP,SP
MOV DL,[BP+X] ; PARAMETER, ONE BYTE FLAG
MOV AL,WRAP ; RETURN OLD COLor
MOV WRAP,DL
POP BP
RET
ifdef Microsoft
_n_wrap endp
else
n_wrap endp
endif
endif
ifndef NET14
;/***************************************************************/
;
; Move the cursor somewhere
;
ifdef Microsoft
_n_cur proc far
else
n_cur proc far
endif
PUSH BP
MOV BP,SP
MOV DH,[BP+X] ; row poSItion
MOV DL,[BP+X+2] ; column poSItion
MOV ROW,DH ; save a copy for me
MOV COL,DL ; save column too
MOV AX,0200h ; ah=2 FUNCTION CalL
XOR BX,BX ; video page 0
INT 10H ; set cursor poSItion
POP BP
RET
ifdef Microsoft
_n_cur endp
else
n_cur endp
endif
;/***************************************************************/
;
; set the window boundaries
;
; usage: n_window(ulrow,ulcol,lrrow,lrcol);
; sets window SIze for future operations.
;
;
ifdef Microsoft
_n_window proc far
else
n_window proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; UPPER LEFT Y
MOV TOPL,AL
MOV AL,[BP+X+2] ; COLUMN POsiTION
MOV LEFTC,AL ; save a copy for me
MOV AL,[BP+X+4]
MOV BOTL,AL ; bottom row
MOV AL,[BP+X+6]
MOV RIGHTC,AL ; keep this one too
ifdef Microsoft
CALL _N_WHICH ; what kind of screen?
else
CALL N_WHICH ; WHAT KIND OF SCREEN?
endif
POP BP
RET
ifdef Microsoft
_n_window endp
else
n_window endp
endif
endif ; NET14
ifdef NOT_USED
;/***************************************************************/
;
; erase portion of the screen
;
; usage: n_erase(ulrow,ulcol,lrrow,lrcol);
;
;
ifdef Microsoft
_n_erase proc far
else
n_erase proc far
endif
PUSH BP
MOV BP,SP
MOV CH,[BP+X] ; UPPER LEFT X
MOV CL,[BP+X+2] ; COLUMN POsiTION
MOV DH,[BP+X+4]
MOV DL,[BP+X+6]
XOR AX,AX ; clear area
MOV AH,6 ; scroll up function
MOV BH,ATT ; ATTRIBUTE For ERAsiNG IS SAME AS PRint
INT 10H ; CalL bios
POP BP
RET
ifdef Microsoft
_n_erase endp
else
n_erase endp
endif
endif
ifndef NET14
;/***************************************************************/
; scroll up and down
; given the number of lines to scroll and the DImenSIons of the
; box to scroll.
;
ifdef Microsoft
_n_scrup proc far
else
n_scrup proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; NUMBER OF LINES TO SCROLL
MOV CH,[BP+X+2] ; UPPER LEFT X
MOV CL,[BP+X+4] ; COLUMN POsiTION
MOV DH,[BP+X+6]
MOV DL,[BP+X+8]
MOV AH,6 ; scroll up function
MOV BH,ATT ; ATTRIBUTE For BLANK LINE IS SAME AS PRint
INT 10H ; CalL bios
POP BP
RET
ifdef Microsoft
_n_scrup endp
else
n_scrup endp
endif
ifdef Microsoft
_n_scrdn proc far
else
n_scrdn proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; number of lines to scroll
MOV CH,[BP+X+2] ; upper left x
MOV CL,[BP+X+4] ; column poSItion
MOV DH,[BP+X+6]
MOV DL,[BP+X+8]
MOV AH,7 ; scroll down function
MOV BH,ATT ; attribute for blank line is same as prINT
INT 10H ; CalL bios
POP BP
RET
ifdef Microsoft
_n_scrdn endp
else
n_scrdn endp
endif
;/***************************************************************/
;
; Find the cursor poSItion, return the row vALue
;
ifdef Microsoft
_n_row proc far
else
n_row proc far
endif
MOV AX,0300H ;video find cursor function
XOR BX,BX
INT 10H ; find cursor
MOV ROW,DH
MOV COL,DL ; save col for next routine
XOR AX,AX
MOV AL,DH ; return row location
RET
ifdef Microsoft
_n_row endp
else
n_row endp
endif
endif ; NET14
;/****************************************************************************/
;-----------------------------------------------------------
; This routine was submitted by David T. Burhans, Jr.
; It was obtained from an RBBS-PC electronic bulleton board
; deDIcated to the "C" language [(703) 321-7003].
;-----------------------------------------------------------
;
; SOUND - This routine produces a tone of a SPecified frequency
; and duration on the SPeaker.
; The frequency in Hertz is moved INTo DI (21 to 65535 Hertz)
; and the duration in hundredths of a second, is moved INTo BX
; (0 to 65535).
; The routine is cALled with the following sequence:
;
; UnSIgned frequency, duration;
;
; n_sound(frequency, duration);
;
ifdef Microsoft
_n_sound proc far
else
n_sound proc far
endif
PUSH BP
MOV BP,SP
PUSH DI
MOV DI,[BP+X] ; Frequency
MOV BX,[BP+X+2] ; Duration
CMP DI, 21H ; See if freq. is below minimum
JB DONE ; iF LESS THAN LIMIT, THEN
; clean up and return
MOV AL,0B6H ; Write timer mode register
OUT 43H, AL
MOV DX, 14H ; Timer DIvisor =
MOV AX, 4F38H ; 1331000/Frequency
DIV DI
OUT 42H,AL ; Write timer 2 count low byte
MOV AL,AH
OUT 42H,AL ; Write timer 2 count high byte
IN AL,61H ; Get current Port B setting
MOV AH,AL ; and save it in AH
OR AL,3 ; Turn SPeaker on
OUT 61H,AL
HOLD:
MOV CX, 2801
SPKR_ON:
LOOP SPKR_ON
DEC BX ; Speaker-on count expired?
JNZ HOLD ; iF NOT, KEEP spEAKER ON
MOV AL,AH ; Otherwise, recover vALue of port
OUT 61H,AL
DONE:
POP DI
POP BP ; Restore cALler's BP
RET ; rETURN TO CalLER
ifdef Microsoft
_n_sound endp
else
n_sound endp
endif
ifndef NET14
;/***************************************************************/
;
; Find the column poSItion of the cursor.
; Must be preceded by a n_row cALl!!!!
; Will work when these routines ALready know the cursor poSItion
;
ifdef Microsoft
_n_col proc far
else
n_col proc far
endif
XOR AH,AH
MOV AL,COL ; RETURN COL LOCATION
RET
ifdef Microsoft
_n_col endp
else
n_col endp
endif
;/***************************************************************/
; n_clear
; Clear what we think is the current window
;
ifdef Microsoft
_n_clear proc far
else
n_clear proc far
endif
MOV AL,0 ; clear window
MOV AH,6 ; scroll up function
MOV CH,TOPL ; TOP ROW TO CLEAR
MOV CL,LEFTC ; LEFT COLUMN
MOV DH,BOTL ; BOTTOM ROW TO CLEAR
MOV DL,RIGHTC ; RIGHT siDE TO CLEAR
MOV BH,ATT ; ATTRIBUTE TO USE For BLANKS
INT 10H ; CalL bios
RET
ifdef Microsoft
_n_clear endp
else
n_clear endp
endif
endif ; NET14
;/***************************************************************/
; n_upscroll
; Scroll up what we think is the current window, n lines
;
ifdef Microsoft
_n_upscroll proc far
else
n_upscroll proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; number of lines to scroll
MOV AH,6 ; scroll up function
MOV CH,TOPL ; top row to clear
MOV CL,LEFTC ; left column
MOV DH,BOTL ; bottom row to clear
MOV DL,RIGHTC ; RIGHT siDE TO CLEAR
MOV BH,ATT ; attribute to use
INT 10H ; cALl BIOS
POP BP
RET
ifdef Microsoft
_n_upscroll endp
else
n_upscroll endp
endif
;/***************************************************************/
; n_dnscroll
; Scroll up what we think is the current window, n lines
;
ifdef Microsoft
_n_dnscroll proc far
else
n_dnscroll proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; number of lines to scroll
MOV AH,7 ; scroll down function
MOV CH,TOPL ; top row to clear
MOV CL,LEFTC ; left column
MOV DH,BOTL ; bottom row to clear
MOV DL,RIGHTC ; right SIde to clear
MOV BH,ATT ; attribute to use for blank lines
INT 10h ; CalL bios
POP BP
RET
ifdef Microsoft
_n_dnscroll endp
else
n_dnscroll endp
endif
;/***************************************************************/
; n_putchar(letter)
; puts onto screen at current cursor location
;
ifdef Microsoft
_n_putchar proc far
else
n_putchar proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; char to write
XOR BX,BX ; set page number for ALl cursor addresses
CMP AL,10 ; line feed
JNZ NXT
MOV AL,ROW ; get current cursor row poSItion
CMP AL,BOTL
JL NOSCR ; within window area
MOV AX,1 ; scroll up one line
PUSH AX
ifdef Microsoft
CALL _N_UPSCROLL ; scrolls it up one
else
CALL N_UPSCROLL ; scrolls it up one
endif
POP AX ; take parameter off of stack
; MOV AL,LEFTC ; get left SIde vALue
; MOV COL,AL ; set cursor to left
JMP PUTCUR
NOSCR:
; MOV AL,LEFTC ; return cursor to left SIde
; MOV COL,AL
INC ROW
JMP PUTCUR ; set new cursor poSItion, return
NXT:
CMP AL,7 ; ctrl-G, bell
JNZ NXT2
;
; handle bell with a cALl to a SPeciAL routine
;
MOV AX,12 ; duration of tone
PUSH AX
MOV AX,1000 ; frequency of tone
PUSH AX
ifdef Microsoft
CALL _N_SOUND
else
CALL N_SOUND
endif
ADD SP,4 ; remove params from stack
HERE2:
POP BP
RET
NXT2:
CMP AL,13 ; cr, home the cursor
JNZ TRYTAB
MOV AL,LEFTC ; new cursor poSItion
MOV COL,AL
JMP PUTCUR
TRYTAB:
CMP AL,9 ; tab character
JNZ NOTCRLF ; ready for regular character
; expand tabs
MOV DL,COL ; get cursor poSItion
MOV CL,3
SHR DL,CL ; DIvide cursor poSItion by 8
INC DL ; increment cursor poSItion
SHL DL,CL ; multiply back by 8
MOV COL,DL
; check to see if past right SIde
MOV DL,COL ; get where the cursor has moved to
CMP DL,RIGHTC ; over the SIde yet?
JA TABOVER ; set the new poSItion
JMP PUTCUR
TABOVER:
MOV DL,LEFTC
MOV COL,DL
INC ROW ; TO NEXT ROW
MOV DL,ROW ; WHAT ROW?
CMP DL,BOTL
JG TABNOS ; we are okay
JMP SHORT PUTCUR
TABNOS:
DEC ROW ; need to scroll
MOV AX,1
PUSH AX
ifdef Microsoft
CALL _N_UPSCROLL ; scroll window up one line
else
CALL N_UPSCROLL ; scroll window up one line
endif
POP AX
MOV AL,LEFTC ; reset cursor poSItion to left
MOV COL,AL
JMP SHORT PUTCUR
NOTCRLF:
CMP AL,8 ; backSPace
JNZ REGCHAR
MOV AL,COL ; where is cursor?
CMP AL,LEFTC ; is at left of screen?
JZ HERE2
DEC COL ; decrement cursor poSItion
JMP SHORT PUTCUR ; okay, move cursor where it belongs
REGCHAR:
MOV CX,1H ; number of repetitions = 1
MOV BL,ATT ; attribute of char
MOV BH,0 ; write to page zero
MOV AH,9 ; write char
INT 10H
INC COL ; move cursor over one.
MOV DL,COL ; get current poSItion
CMP DL,RIGHTC ; is at right SIde of screen?
JLE PUTCUR ; no, char can just be put out, cursor moved.
;
; check wORd-wrap because we are at edge of window
;
MOV DL,WRAP
OR DL,DL ; 0 = NO WRAP, 1 = WRAP
JZ NOWRAP
MOV DL,LEFTC ; cursor will wrap around
MOV COL,DL ; save the new column poSItion
INC ROW ; to next row
MOV DL,BOTL
CMP ROW,DL ; do we need to scroll?
JNG PUTCUR ; no, okay for next row, normAL wrap
; scroll screen up one
MOV AX,1
PUSH AX
ifdef Microsoft
CALL _N_UPSCROLL ; scroll window up one line
else
CALL N_UPSCROLL ; scroll window up one line
endif
POP AX
DEC ROW ; scrolled up one
JMP SHORT PUTCUR ; don't wrap
NOWRAP:
DEC COL
PUTCUR:
MOV DH,ROW
MOV DL,COL
MOV AH,2h
XOR BX,BX
INT 10H ; set cursor poSItion
ESCAPEHERE:
POP BP
RET
ifdef not_used
TELE:
MOV BL,3 ; SEND WHATEVER CHAR
MOV AH,14
INT 10H
POP BP
RET
endif
ifdef Microsoft
_n_putchar endp
else
n_putchar endp
endif
ifndef NET14
;/**********************************************************************/
; draw
; place characters on the screen-- checking for bounDS, etc. ALl done
; at a higher level.
;
; n_draw(s,len)
; char*s ; INT len;
;
ifdef Microsoft
_n_draw proc far
else
n_draw proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH SI
PUSH DI
;
; for now, assume that the cursor location has ALready been set
; (cursor is there)
;
LES SI,[BP+X] ; get the segment and offset of the string
MOV DI,[BP+X+4] ; # OF CHARACTERS
; OR DI,DI ; check for no characters to draw
; JZ ENDDRAW ; exit if no characters to draw
MOV DH,ROW ; row where cursor is
LOOPDRAW:
MOV AL,ES:[SI] ; get character to write from es:SI
INC SI
MOV CX,1H ; number of repetitions = 1
XOR BH,BH ; dispLAY PAGE 0
MOV BL,ATT ; attribute of char
MOV AH,9 ; write char
INT 10h
INC COL ; MOVE THE CURSor OVER
MOV DL,COL
MOV AH,2H
XOR BX,BX
INT 10H ; SET CURSor POsiTION
DEC DI ; check counter
JNZ LOOPDRAW ; GO THROUGH TO REQUIRED COUNT
ENDDRAW:
POP DI
POP SI
POP ES
POP BP
RET
ifdef Microsoft
_n_draw endp
else
n_draw endp
endif
;/**********************************************************************/
; cheat
; put characters on the screen as per n_draw, but write directly
; to display memory. Don't even check for retrace
;
ifdef Microsoft
_n_cheat proc far
else
n_cheat proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DS
PUSH SI
PUSH DI
;
; for now, assume that the cursor location has already been set
; (cursor is there)
;
MOV AX,video_segment
MOV ES,AX ; set up for segment where screen is
MOV AL,ROW ; row where chars go
XOR AH,AH
MOV BL,160
MUL BL ; ax now equals start of row
XOR BH,BH
MOV BL,COL
SHL BL,1 ; COL*2
ADD AX,BX ; add in column offset
MOV DI,AX ; store in di (es:di)
MOV CX,[BP+X+4] ; # of characters
; OR CX,CX ; check whether we really have ANY characters
; JZ ENDCHEAT ; exit if we have no characters
ADD COL,CL ; COLUMN POSITION OF CURSOR
MOV AH,ATT ; ATTRIBUTE FOR CHARS
LDS SI,[BP+X] ; get the segment and offset of the string
;
; do the move
;
CLD
LPCHEAT:
LODSB ; GET NEXT BYTE
STOSW ; STorE BYTE AND ATTRIBUTE
LOOP LPCHEAT
ENDCHEAT:
POP DI
POP SI
POP DS
POP ES
POP BP
RET
ifdef Microsoft
_n_cheat endp
else
n_cheat endp
endif
endif ; NET14
;/**********************************************************************/
;
; New keyboard handling
; the interrupt and codes for the keyboard interface.
KEYBOARD EQU 16H ; interrupt 16 to deal with keyboard
GETC EQU 0 ; code for reading a character
CHECKC EQU 1 ; code for keyboard status
SHIFTSTAT EQU 2 ; code for shift key status
SCAN EQU 00100H ; scan code
SHIFT EQU 00200H ; left or right shift key pressed
CONTROL EQU 00400H ; control key pressed
ALT EQU 00800H ; alt key pressed
ENHANCE EQU 01000H ; enhanced keyboard special key
ifndef NET14
;**********************************************************************
;
; Get a translated character from the keyboard.
;
; Return the next character pressed with the new translation method for
; kermit compatibility.
; Quincey Koziol
;
; Usage:
; unsigned int n_getchar(void);
;
ifdef Microsoft
_n_getchar proc far
else
n_getchar proc far
endif
PUSH BP
ifdef Microsoft
MOV AH,_KEYBOARD_TYPE ; ask for a keyboard character
else
MOV AH,KEYBOARD_TYPE ; ask for a keyboard character
endif
INT KEYBOARD
MOV BX,AX ; store the scan code character
MOV AH,SHIFTSTAT ; get the shift keys' status
INT KEYBOARD ; shift status returned in AX
XOR AH,AH ; clear the top part of the shift status
XOR DX,DX ; set local variables to zero
XOR CX,CX ;
CMP BH,0 ; check for enhanced key
JE NOT_ENHANCED1 ; jump around first enchanced key checks
CMP BH,0E0H ; check for other part of enhanced key
JNE NOT_ENHANCED2
XCHG BH,BL ; shift key from bios left 8 bits
XOR BL,BL ;
OR DX,ENHANCE ; set the enhanced bit
NOT_ENHANCED2:
CMP BL,0E0H ; check for second part of enhanced key
JNE NOT_ENHANCED1
XOR BL,BL ; clear the character code from the bios key
OR DX,ENHANCE ; set the enhanced bit
NOT_ENHANCED1:
CMP BL,0 ; check for not scan code only being zero
JE NOT_ALIAS ; not one of the alias'ed keys from BIOS
CMP BX,(14*SCAN)+8 ; check for Backspace
JE ALIAS_KEY
CMP BX,(55*SCAN)+'*' ; check for '*'
JE ALIAS_KEY
CMP BX,(74*SCAN)+'-' ; check for '-'
JE ALIAS_KEY
CMP BX,(78*SCAN)+'+' ; check for '+'
JE ALIAS_KEY
CMP BX,(71*SCAN)+'7' ; check for '7'
JE ALIAS_KEY
CMP BX,(72*SCAN)+'8' ; check for '8'
JE ALIAS_KEY
CMP BX,(73*SCAN)+'9' ; check for '9'
JE ALIAS_KEY
CMP BX,(75*SCAN)+'4' ; check for '4'
JE ALIAS_KEY
CMP BX,(76*SCAN)+'5' ; check for '5'
JE ALIAS_KEY
CMP BX,(77*SCAN)+'6' ; check for '6'
JE ALIAS_KEY
CMP BX,(79*SCAN)+'1' ; check for '1'
JE ALIAS_KEY
CMP BX,(80*SCAN)+'2' ; check for '2'
JE ALIAS_KEY
CMP BX,(81*SCAN)+'3' ; check for '3'
JE ALIAS_KEY
CMP BX,(82*SCAN)+'0' ; check for '0'
JE ALIAS_KEY
CMP BX,(83*SCAN)+'.' ; check for '.'
JE ALIAS_KEY
CMP BX,(83*SCAN)+',' ; check for ','
JE ALIAS_KEY
CMP BX,(15*SCAN)+9 ; check for Tab
JE ALIAS_KEY
JMP SHORT NOT_ALIAS ; key didn't match one of the alias'ed keys
ALIAS_KEY:
XOR BL,BL ; clear ascii code for alias'ed keys
NOT_ALIAS:
CMP BL,0 ; no ascii value, get a kermit scan code
JNE REGULAR_KEY
MOV DL,BH ; get the scancode
OR DX,SCAN ; set the SCAN flag
TEST AX,3 ; check for shift key down
JE NOT_SHIFT ; shift key not down
OR CX,SHIFT ; set the SHIFT help flag
NOT_SHIFT:
TEST AL,20h ; check for NumLock set
JE NOT_NUMLOCK ; NumLock not down
CMP DX,71+SCAN ; on numeric keypad?
JB NOT_NUMLOCK
CMP DX,83+SCAN
JA NOT_NUMLOCK
CMP DX,74+SCAN ; not the grey - key
JE NOT_NUMLOCK
CMP DX,78+SCAN ; not the grey + key
JE NOT_NUMLOCK
XOR CX,SHIFT ; all true, xor the shift help
NOT_NUMLOCK:
OR DX,CX ; set the correct shift status
TEST AL,4 ; check for the CONTROL key down
JE NOT_CONTROL
OR DX,CONTROL ; set the control flag
NOT_CONTROL:
TEST AX,8 ; check for the ALT key down
JE NOT_ALT
OR DX,ALT ; set the alt flag
NOT_ALT:
MOV AX,DX ; set the return value
JMP SHORT END_NEWGETCHAR
REGULAR_KEY: ; we have an ascii value, return that
XOR BH,BH ;
MOV AX,BX ; return the key id
END_NEWGETCHAR:
POP BP
RET
ifdef Microsoft
_n_getchar endp
else
n_getchar endp
endif
;**********************************************************************
; Check for character present at the keyboard
; If there is one available, return it, if not, return -1
;
; translate any extended characters
;
ifdef Microsoft
_n_chkchar proc far
else
n_chkchar proc far
endif
ifdef Microsoft
MOV AH,_KEYBOARD_TYPE ; get the correct BIOS setting for the keyboard
else
MOV AH,KEYBOARD_TYPE ; get the correct BIOS setting for the keyboard
endif
INC AH ; increment for the setting to check the keyboard
INT KEYBOARD
MOV AX,-1
JZ NEW_NOKEY
ifdef Microsoft
CALL _N_GETCHAR ;get the coded character
else
CALL N_GETCHAR ;get the coded character
endif
NEW_NOKEY:
RET
ifdef Microsoft
_n_chkchar endp
else
n_chkchar endp
endif
endif ; NET14
ifdef NOT_USED
;/***************************************************************/
; savewin
; copy the current window INTo a buffer
;
; usage: n_savewindow(buffer);
;
ifdef Microsoft
_n_savewin proc far
else
n_savewin proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DS
PUSH SI
PUSH DI
LES DI,[BP+X] ; pointer to buffer
CLD
;
; store parameters in first, for recall later
;
MOV AL,ROW ; cursor position: row,col
STOSB
MOV AL,COL
STOSB
MOV AL,TOPL ; window boundaries
STOSB
MOV AL,LEFTC
STOSB
MOV AL,BOTL
STOSB
MOV AL,RIGHTC
STOSB ; STORE IN BUFFER TOO
;
; calculate amount to move
;
;
; calculate number of lines to move
;
MOV AL,TOPL ; X1
MOV BL,BOTL ; X2
SUB BL,AL ; x2 = x2-x1
INC BL ; ADD 1 LINE
MOV [BP+X],BL ; KEEP IT SOMEWHERE SAFE
;
; calculate screen offset = 160*x1+2*y1;
;
; al has topl in it
XOR AH,AH
MOV BL,160
MUL BL ; how many chars in x1 lines, in AX
XOR CH,CH
MOV CL,LEFTC ; chars to left SIde
SHL CL,1 ; *2 counts attributes
ADD AX,CX ; add them
MOV SI,AX ; place into source index
;
; find number of characters to move each time
;
MOV CL,RIGHTC
SUB CL,LEFTC ; Y2 = Y2-Y1
INC CL ; ADD 1
MOV [BP+X+1],CL ; SAFE PLACE AGAIN
;
; find number to add to wrap around for each line
;
MOV BL,CL ; # OF CHARS MOVED EACH TIME
SHL BL,1 ; CHARS*2
MOV AL,160
SUB AL,BL ; 160-chars*2
MOV [BP+X+2],AL ; safe place to keep it
;
;
MOV AX,video_segment ; where source segment is (screen)
MOV DS,AX
MOV DX,03dAH ; color card status port
XOR BH,BH
MOV BL,[BP+X] ; howmany lines to move
CMP AX,0B000H ; CHECK For MONO CARD
JNZ GETLINE
MOV DX,03BAH ; change status port vALue
GETLINE:
MOV CL,[BP+X+1] ; # OF CHARS TO MOVE
GETCHAR:
; IN AL,DX ; GET STATUS BYTE
TEST AL,1 ; horizontal retrace
; JNZ GETCHAR ; not there yet
;ISON:
IN AL,DX
; TEST AL,1
; JZ ISON ; STILL ON, TRY AGAIN
MOVSW ; NOW IS TIME, MOVE THE WORD
LOOP GETCHAR ; DO ANOTHER UNTIL THIS LINE IS DONE
;
DEC BX
JZ ENDKEEP ; DONE, WE ARE OUT OF HERE
MOV AL,[BP+X+2]
XOR AH,AH
ADD SI,AX
; go to next line, skip 160-n*2 bytes
JMP GETLINE
ENDKEEP:
POP DI
POP SI
POP DS
POP ES
POP BP
RET
ifdef Microsoft
_n_savewin endp
else
n_savewin endp
endif
;/***************************************************************/
; restwindow
; restore the contents of the window to the screen
;
ifdef Microsoft
_n_restwin proc far
else
n_restwin proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DS
PUSH SI
PUSH DI
LES SI,[BP+X] ; POINTER TO BUFFER
PUSH ES ; Will pop to ds later
CLD
;
; get back stored variables
;
MOV AL,ES:[SI] ; get cursor row
MOV ROW,AL
INC SI
MOV AL,ES:[SI]
MOV COL,AL
INC SI
MOV AL,ES:[SI] ; window boundaries
MOV TOPL,AL
INC SI
MOV AL,ES:[SI]
MOV LEFTC,AL
INC SI
MOV AL,ES:[SI]
MOV BOTL,AL
INC SI
MOV AL,ES:[SI]
MOV RIGHTC,AL
INC SI ; now we are ready for data
;
; calculate amount to move
;
;
; calculate number of lines to move
;
MOV AL,TOPL ; X1
MOV BL,BOTL ; X2
SUB BL,AL ; x2 = x2-x1
INC BL ; ADD 1 LINE
MOV [BP+X],BL ; KEEP IT SOMEWHERE SAFE
;
; calculate screen offset = 160*x1+2*y1;
;
; AL has topl in it
XOR AH,AH
MOV BL,160
MUL BL ; HOW MANY CHARS IN X1 LINES, IN AX
XOR CH,CH
MOV CL,LEFTC ; CHARS TO LEFT SIDE
SHL CL,1 ; *2 COUNTS ATTRIBUTES
ADD AX,CX ; add them
MOV DI,AX ; place into source index
;
; find number of characters to move each time
;
MOV CL,RIGHTC
SUB CL,LEFTC ; Y2 = Y2-Y1
INC CL ; add 1
MOV [BP+X+1],CL ; safe place again
;
; find number to add to wrap around for each line
;
MOV BL,CL ; # of chars moved each time
SHL BL,1 ; chars*2
MOV AL,160
SUB AL,BL ; 160-chars*2
MOV [BP+X+2],AL ; safe place to keep it
;
;
ifdef CHECK_FOR_REFRESH
MOV AX,video_segment; screen will receive this data
MOV ES,AX
POP DS ; set ds to where data is coming from
MOV DX,03DAH ; COLOR CARD STATUS PorT
XOR BH,BH
MOV BL,[BP+X] ; howmany lines to move
CMP AX,0B000H ; check for mono card
JNZ RGETLINE
MOV DX,03BAH ; change status port vALue
RGETLINE:
MOV CL,[BP+X+1] ; # of chars to move
RGETCHAR:
IN AL,DX ; GET STATUS BYTE
TEST AL,1 ; horizontal retrace
JNZ RGETCHAR ; NOT THERE YET
RISON:
IN AL,DX
TEST AL,1
JZ RISON ; STILL ON, TRY AGAIN
MOVSW ; NOW IS TIME, MOVE THE WORD
LOOP RGETCHAR ; DO ANOTHER UNTIL THIS LINE IS DONE
else
MOV AX,video_segment; screen will receive this data
MOV ES,AX
POP DS ; set ds to where data is coming from
; MOV DX,03DAH ; COLOR CARD STATUS PORT
XOR BH,BH
MOV BL,[BP+X] ; howmany lines to move
; CMP AX,0B000H ; check for mono card
; JNZ RGETLINE
; MOV DX,03BAH ; change status port vALue
RGETLINE:
XOR CH,CH
MOV CL,[BP+X+1] ; # of chars to move
RGETCHAR:
; IN AL,DX ; GET STATUS BYTE
; TEST AL,1 ; horizontal retrace
; JNZ RGETCHAR ; NOT THERE YET
;RISON:
; IN AL,DX
; TEST AL,1
; JZ RISON ; STILL ON, TRY AGAIN
; MOVSW ; NOW IS TIME, MOVE THE WORD
; LOOP RGETCHAR ; DO ANOTHER UNTIL THIS LINE IS DONE
REP MOVSW ; move all the words
endif
;
DEC BX
JZ RENDKEEP ; DONE, WE ARE OUT OF HERE
MOV AL,[BP+X+2]
XOR AH,AH
ADD DI,AX ; go to next line, skip 160-n*2 bytes
JMP RGETLINE
RENDKEEP:
POP DI
POP SI
POP DS
MOV DH,ROW ; LOAD STORED CURSOR POSITION
MOV DL,COL
MOV AH,2H
XOR BX,BX
INT 10H ; SET CURSOR POSITION TO SAVED VALUE
POP ES
POP BP
RET
ifdef Microsoft
_n_restwin endp
else
n_restwin endp
endif
endif ; NOT_USED
;************************************************************************
; n_puts
; Window-compatible puts, uses n_putchar and ALso translates
; \n to CRLF
;
; usage: identical to puts()
;
ifdef Microsoft
_n_puts proc far
else
n_puts proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DI
; MOV DX,[BP+X+2] ; ds OF STRING
; MOV ES,DX
; MOV BX,[BP+X] ; PTR TO STRING
LES DI,[BP+X] ; PTR TO STRING
NEXTC:
; MOV AL,[BX] ; GET CHARACTER
MOV AL,ES:[DI] ; GET CHARACTER
XOR AH,AH ; clear ah
OR AL,AL ; is it end of string?
JZ DONEST
; INC WORD PTR [BP+X] ; INCREMENT POINTER FOR NEXT ONE
INC DI ; INCREMENT POINTER FOR NEXT ONE
CMP AL,10 ; newline?
JNZ DOCHAR
MOV AL,13
PUSH AX
ifdef Microsoft
CALL _N_PUTCHAR
else
CALL N_PUTCHAR
endif
POP AX
MOV AX,10
DOCHAR:
PUSH AX
ifdef Microsoft
CALL _N_PUTCHAR
else
CALL N_PUTCHAR
endif
POP AX ; take off of the stack
JMP NEXTC
DONEST:
MOV AX,13 ; CR
PUSH AX
ifdef Microsoft
CALL _N_PUTCHAR
else
CALL N_PUTCHAR
endif
POP AX
MOV AX,10 ; LF
PUSH AX
ifdef Microsoft
CALL _N_PUTCHAR
else
CALL N_PUTCHAR
endif
POP AX
POP DI
POP ES
POP BP
RET
ifdef Microsoft
_n_puts endp
else
n_puts endp
endif
ifndef NET14
;**********************************************************************
;
; find first
; make dos find file names accorDIng to wildcards
; n_findfirst(filename,attr)
; char *filename; INT attr;
;
ifdef Microsoft
_n_findfirst proc far
else
n_findfirst proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DS
MOV AH,02FH ; DOS FUNCTION GET dta
INT 21H
ifdef Microsoft
MOV _DTAPTR,BX ; SQUIRREL A COPY FOR ME
MOV AX,ES
MOV _DTADS,AX
else
MOV DTAPTR,BX ; SQUIRREL A COPY FOR ME
MOV AX,ES
MOV DTADS,AX
endif
MOV AX,[BP+X+2] ; DS OF FILENAME PTR
MOV DS,AX
MOV DX,[BP+X] ; PTR PART OF FILENAME
MOV CX,[BP+X+4] ; ATTRIBUTE TO SEARCH FOR
MOV AH,04EH ; FIND MATCHING FILE DOS CALL
INT 21H
JC BADRET ; AX ALREADY CONTAINS ERROR CODE
XOR AX,AX
BADRET:
POP DS
POP ES
POP BP
RET
ifdef Microsoft
_n_findfirst endp
else
n_findfirst endp
endif
;
; n_findnext()
; will find entries that follow findfirst
; no need to respecify file name
;
ifdef Microsoft
_n_findnext proc far
else
n_findnext proc far
endif
MOV AH,04FH ; FIND NEXT DOS CALL
INT 21H
JC NBADRET
XOR AX,AX
NBADRET:
RET
ifdef Microsoft
_n_findnext endp
else
n_findnext endp
endif
endif ; NET14
;
; get the number of timer clicks from BIOS
;
ifdef Microsoft
_n_clicks proc far ; must be declared long n_clicks()
else
n_clicks proc far ; must be declared long n_clicks()
endif
MOV AH,0
INT 1AH
ifdef Microsoft
MOV AX,DX ; msc USES AX-LO, DX-HI
MOV DX,CX ; return values from INTerrupt 1A
else
MOV AX,CX ; Lattice uses AX-HI, BX-LO
MOV BX,DX ; Lattice returns in BX, MSC in DX and switched
endif
RET
ifdef Microsoft
_n_clicks endp
else
n_clicks endp
endif
ifndef NET14
;
; void fix_vid(void)
;
ifdef Microsoft
_fix_vid proc far
else
fix_vid proc far
endif
push es
mov ax,40h
mov es,ax
mov bx,10h
mov al,es:[bx] ; get equipment flags
and al,0ch
cmp al,0ch
je done_vid_fix ; if mono, we don't do anything
mov bx,89h
mov al,es:[bx] ; get VDD flag byte
and al,0fdh ; Make sure bit 1 (gray scale summing enable)
; is UNSET
mov es:[bx],al ; put new flag byte in VDD
mov ah,0fh
int 10h ; get current mode
xor ah,ah
int 10h ; reset current mode (new flags take affect)
done_vid_fix:
pop es
ret
ifdef Microsoft
_fix_vid endp
else
fix_vid endp
endif
ifdef Microsoft
_get_mode proc far
else
get_mode proc far
endif
push bp
mov bp,sp
push es
les bx,dword ptr [bp+6]
mov cx,7
mov ax,1c01h
int 10h
mov ax,1c02h ; immediately restore the state
int 10h
pop es
pop bp
ret
ifdef Microsoft
_get_mode endp
else
get_mode endp
endif
ifdef Microsoft
_set_mode proc far
else
set_mode proc far
endif
push bp
mov bp,sp
push es
les bx,dword ptr [bp+6]
mov cx,7
mov ax,1c02h
int 10h
pop es
pop bp
ret
ifdef Microsoft
_set_mode endp
else
set_mode endp
endif
ifdef Microsoft
_get_size proc far
else
get_size proc far
endif
mov ax,1c00h
mov cx,7
int 10h
mov ax,bx
ret
ifdef Microsoft
_get_size endp
else
get_size endp
endif
;************************************************************************
; set_page
;
; Sets the video page
;
ifdef Microsoft
_set_page proc far
else
set_page proc far
endif
PUSH BP
MOV BP,SP
MOV AL,[BP+X] ; Get the page to switch to
MOV AH,05h
INT 10h
POP BP
RET
ifdef Microsoft
_set_page endp
else
set_page endp
endif
;************************************************************************
; initvideo
;
; Determines the active display adapter and various display parameters
;
ifdef Microsoft
_initvideo proc far
else
initvideo proc far
endif
PUSH BP
MOV BP, SP
PUSH DS
PUSH ES
PUSH SI
PUSH DI
MOV AH,0FH ; Read Video information
INT 10H
MOV video_mode,AL ; Video Display Mode
MOV video_page,BH ; Video Display Page
MOV video_cols,AH ; Number of Text Columns
MOV video_segment,MONO_SEG ; Assume monochrome for now
MOV video_iscolor,0 ;
INT 11H ; Read Equipment list
AND AL,00110000b ; Isolate Video bits
CMP AL,00110000b ; Was it mono?
JE find_adapter ; Yes
MOV video_segment,COLOR_SEG ; Else, set color display
MOV video_iscolor,1 ;
find_adapter:
CALL ps2_state ; Read PS/2 video state
JNZ adapter_set ; Done, if supported
CALL ega_state ; Read EGA video state
JNZ adapter_set ; Done, is supported
CALL cga_state ; Determine CGA or mono
adapter_set:
SUB AX,AX ; Adjust dsplay segment for current vide page
MOV ES,AX ;
MOV AX,ES:[044EH] ;
MOV CL,4
SHR AX,CL
ADD video_segment,AX
MOV AH,03H ; get cursor pos'n & shape
INT 10H ; ..
MOV video_cursor,CX ; save shape for later restore
MOV AX,1130H ; get font information
XOR BH,BH ; for current font
INT 10H ; ..
MOV AX,1112H ; assume we're using small font
CMP CX,8 ; using 8 * 8 font?
JE setfont ; if yes, good
MOV AX,1114H ; no. try for the 8 * 16 font
CMP CX,16 ; ..
JE setfont ; ..
MOV AX,1111H ; no. must be the 8 * 14 font
setfont:
MOV video_font,AX ; save function code to restore this font
POP DI
POP SI
POP ES
POP DS
POP BP
ret
ifdef Microsoft
_initvideo endp
else
initvideo endp
endif
;************************************************************************
; ps2_state
;
; This procedure attempts to access ps/2 compatible ROM BIOS video
; services. The zero flag is set if they aren't supported
;
ps2_state proc near
MOV AX,1A00H ; Read PS/2 video state
INT 10H
CMP AL,1AH ; Was function supported?
LAHF ; Toggle zero flag (zf=1 if al is not equal to 1ah)
XOR AH,01000000b ;
SAHF
JZ no_ps2 ; PS/2 BIOS not present
MOV video_type,BL ; Save active display code
MOV AX,1130h ; Read Font Code
SUB BH,BH ; Font Code (not used)
INT 10h ;
INC DL ; Adjust row count (clear zf)
MOV video_rows,DL ; and save
no_ps2:
RET
ps2_state endp
;************************************************************************
; ega_state
;
; If PS/2 compatible ROM BIOS is not present, this procedure attempts
; to access the EGA ROM BIOS video services
;
ega_state proc near
MOV AH,12H ; Read EGA video state
MOV BL,10H
INT 10H
CMP BL,10H ; Was Function supported?
JE no_ega ; No, EGA BIOS not present
CMP video_iscolor,BH ; Is EGA the active display?
JE no_ega ; No, find active display
ADD BH,4 ; Else, calculate display code
MOV video_type,BH ; and save
MOV AX,1130H ; Read Font code
SUB BH,BH ; Font Code (not used)
INT 10H
INC DL ; Adjust row count (clear zf)
MOV video_rows,DL ; and save
no_ega:
RET
ega_state endp
;************************************************************************
; cga_state
;
; If neither PS/2 compatible ROM BIOS nor EGA ROM BIOS is present,
; this procedure is called. It simply assumes 25 text rows and sets
; video_type to MDA or CGA depending on the value of video_iscolor
;
cga_state proc near
MOV video_rows,25 ; If we get here, must be 25 rows
MOV video_type,01H ; Assume MDA adapter for now
CMP video_iscolor,0 ; Is it mono?
JE no_cga ; Yes
MOV video_type,02H ; Else set CGA display adapter
no_cga:
RET
cga_state endp
;************************************************************************
; getvconfig
;
; This routine fills a buffer with the current video parameter values.
; Note: initvideo() must be called first in order for this procedure
; to return meaningful values.
;
; Usage: void getvconfig(struct vidinfo *)
;
; Where: struct vidinfo {
; unsigned int segment;
; int type;
; int iscolor;
; int mode;
; unsigned int page;
; unsigned int rows;
; unsigned int columns;
; unsigned int cursor;
; unsigned int font_func;
; };
;
ifdef Microsoft
_getvconfig proc far
else
getvconfig proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DI
PUSH SI
CLD ; All moves forward
IF @DataSize
LES DI,[BP+X] ; Get the Pointer to the buffer
ELSE
MOV DI,[BP+X] ; Get the Pointer to the buffer
PUSH DS
POP ES
ENDIF
MOV SI,OFFSET video_segment ; Get the offset of the start of the videio information
MOVSW ; Copy the video segment
MOV CX,6 ; Copy six more word values
XOR AH,AH ; Clear the top part of the transfer register
Copy_Loop:
LODSB ; Move each byte from the video parameters
STOSW ; Into a word in the structure
LOOP Copy_Loop
MOVSW ; Copy the cursor
MOVSW ; Copy the font function
POP SI
POP DI
POP ES
POP BP
RET
ifdef Microsoft
_getvconfig endp
else
getvconfig endp
endif
;************************************************************************
; getvstate
;
; This routine fills a buffer with the current video parameter values.
; This routine does not depend on initvideo() for anything.
;
; Usage: void getvstate(struct vidstate *)
;
; Where: struct vidstate {
; char mode;
; unsigned char page;
; unsigned int cursor;
; unsigned int curpos;
; unsigned int font_func;
; };
;
ifdef Microsoft
_getvstate proc far
else
getvstate proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DI
PUSH SI
CLD ; All moves forward
IF @DataSize
LES DI,[BP+X] ; Get the Pointer to the buffer
ELSE
MOV DI,[BP+X] ; Get the Pointer to the buffer
PUSH DS
POP ES
ENDIF
MOV AH,0FH ; get video mode
INT 10H ; ..
MOV BYTE PTR ES:[DI],AL ; save original mode
MOV BYTE PTR ES:[DI+1],BH ; save original display page
MOV AH,03H ; get cursor pos'n & shape
INT 10H ; ..
MOV WORD PTR ES:[DI+2],CX ; save shape for later restore
MOV WORD PTR ES:[DI+4],DX ; save position for later restore
MOV AX,1130h ; get font information
XOR BH,BH ; for current font
PUSH ES ; Preserve the ES from being blown away
INT 10h ; ..
POP ES ; Get the ES back
MOV AX,1112h ; assume we're using small font
CMP CX,8 ; using 8 * 8 font?
JE setvfont ; if yes, good
MOV AX,1114h ; no. try for the 8 * 16 font
CMP CX,16 ; ..
JE setvfont ; ..
MOV AX,1111h ; no. must be the 8 * 14 font
setvfont:
MOV WORD PTR ES:[DI+6],AX ; save function code to restore this font
POP SI
POP DI
POP ES
POP BP
RET
ifdef Microsoft
_getvstate endp
else
getvstate endp
endif
;************************************************************************
; setvstate
;
; This routine takes variables from a video state structure and
; sets that video state
; This routine does not depend on initvideo() for anything.
;
; Usage: void setvstate(struct vidstate *)
;
; Where: struct vidstate {
; char mode;
; unsigned char page;
; unsigned int cursor;
; unsigned int font_func;
; };
;
ifdef Microsoft
_setvstate proc far
else
setvstate proc far
endif
PUSH BP
MOV BP,SP
PUSH ES
PUSH DI
CLD ; All moves forward
IF @DataSize
LES DI,[BP+X] ; Get the Pointer to the buffer
ELSE
MOV DI,[BP+X] ; Get the Pointer to the buffer
PUSH DS
POP ES
ENDIF
MOV AL,BYTE PTR ES:[DI] ; set video mode
XOR AH,AH
INT 10H ; ..
MOV AX,0500h ; Force display page 0
INT 10h
MOV AX,WORD PTR ES:[DI+6] ; Restore original font
XOR BL,BL ; character block 0
INT 10h
MOV AL,BYTE PTR ES:[DI+1] ; Restore original display page
MOV AH,5
INT 10h
MOV CX,WORD PTR ES:[DI+2] ; Restore cursor shape
MOV AH,01h
INT 10h
MOV AH,02 ; Restore cursor position for the page
MOV BH,BYTE PTR ES:[DI+1]
MOV DX,WORD PTR ES:[DI+4]
INT 10h
POP DI
POP ES
POP BP
RET
ifdef Microsoft
_setvstate endp
else
setvstate endp
endif
endif ; NET14
;-----------------------------------------------------------------
ifdef Microsoft
;_TEXT ENDS
else
endps
endif
end