pcs/zio.asm

850 lines
38 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; =====> ZIO.ASM
;****************************************
;* TIPC Scheme Runtime Support *
;* File IO - MS-DOS Version 2.1 *
;* *
;* (C) Copyright 1985 by Texas *
;* Instruments Incorporated. *
;* All rights reserved. *
;* *
;* Date Written: 21 January 1985 *
;* Last Modification: 26 September 1986 *
;****************************************
page 60,132
include scheme.equ
include pcmake.equ
MSDOS equ 021h
TI_CRT equ 049h
IBM_CRT equ 010h
TI_KEYBD equ 04Ah
IBM_KEYB equ 016h
MAX_COLS equ 80
MAX_ROWS equ 25
CURSMASK equ 10011111b ; The zeros are the bits that disable cursor
NOCURSOR equ 00100000b ; byte mask to disable cursor
DGROUP group data
data segment word public 'DATA'
assume DS:DGROUP
public zapcurs,curs_sav, ega_col, ega_row
zapcurs dw 0 ; for disabling cursor altogether
curs_sav dw 400Ch ; For saving the cursor size when it's
; disabled. Default value just in case...
ega_col db ?
ega_row db ?
c_row dw ?
c_col dw ?
c_len dw ?
banka dw 0a000h
sav_di dw ?
extrn vid_mode:word
extrn cur_off:byte
extrn char_hgt:word
data ends
XGROUP group progx
progx segment word public 'progx'
assume CS:XGROUP
extrn z%border:far ; border drawer
extrn crt_dsr:far ; use machine appropriate VIDEO interrupt
extrn save%scr:far ; save screen
extrn rest%scr:far ; restore screen
extrn ega_curs:far ; display an ega cursor
extrn enable:far ; part of the ega cursor routine
;************************************************************************
;* Generate a Bell Character *
;* *
;* Purpose: To generate a "bell character" (i.e., make a noise) to *
;* simulate the effect of outputting a bell character *
;* (control-G) in the output stream. *
;* *
;* Calling Sequence: zbell(); *
;* *
;* Input Parameters: None. *
;* *
;* Output Parameters: None. *
;* *
;************************************************************************
public zbell
zbell proc far
cmp DGROUP:PC_MAKE,TIPC
jne zbmbell
zbwait: mov AH,1 ; Get speaker status
int 48h
jnz zbwait ; wait for bell to turn off
mov AH,2 ; Set speaker frequency
mov CX,1563 ; Value for 1.25MHz/800Hz (system beep)
int 48h
mov AX,000Ah ; Turn speaker on for AL*25-ms. 0Ah = .25-sec
int 48h
ret ; return to caller
;
zbmbell: mov BX,080h ; ****Copied from IBM-PC/XT BIOS listing****
in AL,61h
push AX ; Save
beep_cycle: and AL,0FCh ; Turn off timer gate and speaker data
out 61h,AL ; output to control
mov CX,48h ; Half cycle time for TONE
here: loop here ; speaker off
or AL,2 ; Turn speaker on
out 61h,AL
mov CX,48h
here2: loop here2
dec BX ; Decrease cycle count
jnz beep_cycle
pop AX
out 61h,AL
ret
zbell endp
public zch_rdy
zch_rdy proc far
; IFDEF extmem ; Kludge to fix hanging keyboard
; mov AL,0AEh ; Ensure keyboard enabled
; out 64h,AL ; Output to 8042 controller
; ENDIF
mov AH,01h ; load "check keyboard status" function code
cmp pc_make,TIPC ; TI or IBM flavored PC?
jne zch_IBM
int TI_KEYBD ; issue TI keyboard DSR service call
jz zch_no ; is character buffered? if not, jump
zch_yes: xor AH,AH ; clear high order byte of AX
cmp AL,0 ; test next character to be read
jne zch_ret ; binary zero? if not, jump
mov AX,256 ; if character is 0, make it non-zero
zch_ret: ret ; return (true)
zch_IBM: int IBM_KEYB ; issue IBM keyboard DSR service call
jnz zch_yes ; is character buffered? if so, jump
zch_no: xor AX,AX ; set result = false
ret ; return (false)
zch_rdy endp
zop_args struc
dd ? ; far CS and IP
dw ? ; caller's BP
dw ? ; return address
zhandle dw ? ; address of handle
zpathnam dw ? ; address of string containing file pathname
zmode dw ? ; mode: 0=read, 1=write, 2=read/write
zhigh dw ? ; address of high word of file size
zlow dw ? ; address of low word of file size
zop_args ends
public z%open
z%open proc far
push BP ; save caller's BP
mov BP,SP
mov AH,03Dh ; load function request id
mov AL,byte ptr [BP].zmode ; load access code (mode)
mov DX,[BP].zpathnam ; load pointer to pathname
int MSDOS ; issue open request
jc zop_ret ; if error, jump
mov BX,[BP].zhandle ; load address of handle
mov [BX],AX ; and store returned handle value
;
push AX ; save file handle
mov BX,AX ; set bx to file handle
xor CX,CX
xor DX,DX
mov AX,4202h ; poisition file pointer at eof
int MSDOS
;
mov BX,[BP].zhigh ; load address of hsize
mov [BX],DX ; and store returned hsize value
mov BX,[BP].zlow ; load address of lsize
mov [BX],AX ; and store returned lsize value
;
pop BX ; retrieve file handle
xor CX,CX
xor DX,DX
mov AX,4200h ; reset file pointer to begining of file
int MSDOS
;
xor AX,AX ; set return code for normal return
zop_ret: pop BP ; restore caller's BP
ret ; return
z%open endp
public z%create
z%create proc far
push BP ; save caller's BP
mov BP,SP
mov AH,03Ch ; load function request id
mov DX,[BP].zpathnam ; load pointer to pathname
mov CX,020h ; create with "archive" attribute
int MSDOS ; issue create request
jc zcr_ret ; if error, jump
mov BX,[BP].zhandle ; load address of handle
mov [BX],AX ; and store returned handle value
xor AX,AX ; set return code for normal return
zcr_ret: pop BP ; restore caller's BP
ret ; return
z%create endp
public z%close
z%close proc far
push BP ; save caller's BP
mov BP,SP
mov AH,03Eh ; load function request id
mov BX,[BP].zhandle ; load handle of file to close
int MSDOS ; issue close request
jc zcl_ret ; if error, jump
xor AX,AX ; set return code for normal return
zcl_ret: pop BP ; restore caller's BP
ret ; return
z%close endp
zrw_args struc
dd ? ; far cs and ip
dw ? ; caller's BP
dw ? ; return address
dw ? ; zhandle (use previous equate)
zbuffer dw ? ; input/output buffer
zlength dw ? ; address of length value
zrw_args ends
public z%read
z%read proc far
push BP ; save caller's BP
mov BP,SP
mov AH,03Fh ; load function request id
mov DX,[BP].zbuffer ; load address of input buffer
mov BX,[BP].zlength ; load address of length value
mov CX,[BX] ; then load length for read
mov BX,[BP].zhandle ; load file's handle
int MSDOS ; issue create request
jc zrd_ret ; if error, jump
mov BX,[BP].zlength ; load address of length parameter
mov [BX],AX ; and store number of characters read
xor AX,AX ; set return code for normal return
zrd_ret: pop BP ; restore caller's BP
ret ; return
z%read endp
public z%write
z%write proc far
push BP ; save caller's BP
mov BP,SP
mov AH,040h ; load function request id
mov DX,[BP].zbuffer ; load address of input buffer
mov BX,[BP].zlength ; load address of length value
mov CX,[BX] ; then load length for write
mov BX,[BP].zhandle ; load file's handle
int MSDOS ; issue write request
jc zwr_ret ; if error, jump
mov BX,[BP].zlength ; load address of length parameter
mov [BX],AX ; and store number of characters written
xor AX,AX ; set return code for normal return
zwr_ret: pop BP ; restore caller's BP
ret ; return
z%write endp
strd struc
dd ? ; far cs and ip
dw ?,? ;Caller's BP, Return address
strdpg dw ? ;Page, displacement of port
strdds dw ?
strdbuf dw ? ;Buffer address
strdlen dw ? ;Length address
strd ends
public string%rd
string%rd proc far
push BP
mov BP,SP
push DS ;Save caller's DS, ES
mov AX,ES ; (and make AX nonzero as well)
mov BX,[BP].strdlen ;Load CX with number of chars to transfer
mov CX,[BX]
mov DI,[BP].strdpg ;Get port page
mov DX,DI ; and save for later
%LoadPage DS,DI ;Get para address
mov DI,[BP].strdds ;DS:DI point to port
mov SI,word ptr[DI+car].pt_ptr ;Point DS:SI to string
mov BL,[DI+car_page].pt_ptr
xor BH,BH
%LoadPage DS,BX
;;; mov DS,ES:pagetabl+[BX]
cmp byte ptr[SI],STRTYPE ;Is this a string?
jne nostr ;Jump if not (error)
mov BX,[SI].str_len ;Else fetch string length
cmp BX,0 ;;; check for small string
jge strn_01
add BX,BLK_OVHD+PTRSIZE
strn_01: %LoadPage ES,DX ;Restore ptr to port
mov DX,ES:[DI].pt_ullin ;Fetch position within string
sub BX,DX ;Set BX to # of chars left
jns notpast ;If not negative, skip
xor BX,BX ;Set # of chars left to 0
notpast: cmp BX,CX ;Set CX to # of chars left or maximum
jae max ; called for, whichever is smaller
mov CX,BX
max: add SI,DX ;Adjust SI into string
add DX,CX ;Reset pointer into string
mov ES:[DI].pt_ullin,DX
mov ES,AX ;Restore C's ES
mov DI,[BP].strdbuf ;Point DI to buffer
xor AX,AX ;Prepare to return 0 (all's well)
jmp short storlen ;Store # of chars
nostr: xor CX,CX ;When not a string, move no chars
storlen: mov BX,[BP].strdlen ;Set LENGTH to # of chars read
mov ES:[BX],CX
rep movsb ;Transfer bytes
pop DS ;Restore caller's DS
pop BP
ret
string%rd endp
;************************************************************************
;* Buffered Keyboard Input *
;* *
;* Calling Sequence: ch = getch(); *
;* where ch - the character read from the keyboard *
;************************************************************************
public get%ch
get%ch proc far
; IFDEF extmem ; Kludge to fix hanging keyboard
; mov AL,0AEh ; Ensure keyboard enabled
; out 64h,AL ; Output to 8042 controller
; ENDIF
mov AH,07h ; function code = Direct Console Input
int MSDOS ; do it
xor AH,AH ; clear the high order byte
ret ; return to caller
get%ch endp
z%ega proc far
mov AX,banka
mov ES,AX ; set ES to the video plane
mov AX,c_row ; set AX to the row
mul char_hgt ; multiply by the character height
mov BX,80 ; multiply by 80 bytes per line
mul BX
add AX,c_col ; add in the starting column
mov sav_di,AX ; save the starting value
xor BX,BX ; use BX as a counter
mov DX,c_len ; number of columns to blank
zc_03: mov CX,DX ; restore counter
mov DI,sav_di ; restore index
mov AH,0fh
call enable ; enable all banks
xor AX,AX ; clear AX
cld
rep stosb
add sav_di,80 ; next line
inc BX ; increment counter
cmp BX,char_hgt ; done with this row?
jne zc_03
xor BX,BX ; clear counter
dec [BP].zc_nrows ; decrement row count
jg zc_03 ; if more rows, loop (jump)
ret
z%ega endp
progx ends
PGROUP group prog
prog segment byte public 'PROG'
assume CS:PGROUP
;************************************************************************
;* Create a File *
;* *
;* Calling sequence: stat = zcreate(handle, pathname) *
;* where: int *handle - location to store handle *
;* returned by open request*
;* char *pathname - zero terminated string *
;* containing the file's *
;* pathname *
;* int stat - the completion code *
;* 0=no errors *
;* 3=path not found *
;* 4=too many open files *
;* 5=access denied *
;************************************************************************
public zcreate
zcreate proc near
call z%create
ret ; return
zcreate endp
;************************************************************************
;* Open a File *
;* *
;* Calling sequence: stat = zopen(handle, pathname, access_code) *
;* where: int *handle - location to store handle *
;* returned by open request*
;* char *pathname - zero terminated string *
;* containing the file's *
;* pathname *
;* int access_code - 0=read, 1=write, *
;* 2=read and write *
;* int stat - the completion code *
;* 0=no errors *
;* 2=file not found *
;* 4=too many open files *
;* 5=access denied *
;* 12=invalid access *
;************************************************************************
public zopen
zopen proc near
call z%open
ret ; return
zopen endp
;************************************************************************
;* Close a File *
;* *
;* Calling sequence: stat = zclose(handle) *
;* where: int handle - handle returned by open *
;* request *
;* int stat - the completion code *
;* 0=no errors *
;* 6=invalid handle *
;************************************************************************
public zclose
zclose proc near
call z%close
ret ; return
zclose endp
;************************************************************************
;* Read From a File *
;* *
;* Calling sequence: stat = zread(handle, buffer, length) *
;* where: int handle - handle returned by open *
;* request *
;* char *buffer - address of character *
;* buffer into which data *
;* is to be read *
;* int *length - on input, the maximum *
;* number of characters *
;* which the buffer will *
;* hold. On output, the *
;* number of characters *
;* actually read. Note: *
;* a return value of zero *
;* characters read *
;* indicates end of file. *
;* int stat - the completion code *
;* 0=no errors *
;* 5=access denied *
;* 6=invalid handle *
;************************************************************************
public zread
zread proc near
call z%read
ret ; return
zread endp
;************************************************************************
;* Write to a File *
;* *
;* Calling sequence: stat = zwrite(handle, buffer, length) *
;* where: int handle - handle returned by open *
;* char *buffer - address of character *
;* buffer from which data *
;* is to be written *
;* int *length - on input, the number of *
;* characters to write. *
;* The actual number of *
;* characters which were *
;* written is returned in *
;* "length" *
;* int stat - the completion code *
;* 0=no errors *
;* 5=access denied *
;* 6=invalid handle *
;************************************************************************
public zwrite
zwrite proc near
call z%write
ret ; return
zwrite endp
;************************************************************************
;* Clear a Window *
;************************************************************************
zc_args struc
dw ? ; caller's BP
dw ? ; return address
zc_row dw ? ; upper left hand corner row number
zc_col dw ? ; upper left hand corner column number
zc_nrows dw ? ; number of rows
zc_len dw ? ; line length (number of characters)
zc_attrib dw ? ; character attributes
zc_args ends
public zclear
zclear proc near
push BP ; save caller's BP
mov BP,SP
push ES
push DI
push AX
push BX
push CX
push DX
; Put cursor at beginning of next row
zc_loop: mov DL,byte ptr [BP].zc_row ; load current row number
mov DH,byte ptr [BP].zc_col ; load starting column number
xor BH,BH ; page number (0 if in graphics mode)
mov AH,02H ; load "put cursor" code
call crt_dsr ; position the cursor
; Write line of blanks at current cursor position
mov AX,0920h ; load write char/attr code + blank (= 20h)
xor BH,BH ; (for IBM-PC BH=display page #)
mov BL,byte ptr [BP].zc_attrib ; load attribute flag
cmp vid_mode,14 ; IBM EGA modes?
jl zc_01
cmp BL,87h ; attribute is rv white?
jne zc_22
mov AX,09dbh ; use the block character not the blank
and BL,7fh ; strip off the xor bit
zc_01: mov CX,[BP].zc_len ; load number of times to write the blank
call crt_dsr ; perform the write
; Increment row number, decrement row count, test, loop
inc [BP].zc_row ; increment row number
dec [BP].zc_nrows ; decrement row count
jg zc_loop ; if more rows, loop (jump)
; Return to caller
zc_end: pop DX
pop CX
pop BX
pop AX
pop DI
pop ES
pop BP ; restore caller's BP
ret ; return
; clear out the line by writing directly to the graphics planes
zc_22: mov AX,[BP].zc_row ; set AX to the row
mov c_row,AX
mov AX,[BP].zc_col ; add in the starting column
mov c_col,AX
mov AX,[BP].zc_len ; number of columns to blank
mov c_len,AX
call z%ega ; restore counter
jmp zc_end ; return
zclear endp
;************************************************************************
;* Draw Border *
;************************************************************************
zb_args struc
dw ? ; caller's BP
dw ? ; return address
zb_line dw ? ; upper left corner line number
zb_col dw ? ; upper left corner column number
zb_nlines dw ? ; number of lines
zb_ncols dw ? ; number of columns
zb_battr dw ? ; border attributes
zb_label dw ? ; pointer to label text
zb_args ends
public zborder
zborder proc near
call z%border
ret
zborder endp
;************************************************************************
;* Link to Save Screen Support *
;************************************************************************
public save_scr
save_scr proc near
call save%scr
ret
save_scr endp
;************************************************************************
;* Link to Restore Screen Support *
;************************************************************************
public rest_scr
rest_scr proc near
call rest%scr
ret
rest_scr endp
;************************************************************************
;* Cursor Off *
;************************************************************************
public zcuroff
zcuroff proc near
call ega_curs
mov AH,03
xor BH,BH ; IBM page number/must be 0 for graphics mode
call crt_dsr ; get the cursor position/mode
cmp zapcurs,0
jne zcoff_01
mov curs_sav,CX ; save it for restoration
zcoff_01:
and CH,CURSMASK ; mask off bits to select cursor type
or CH,NOCURSOR ; disables cursor (turns it off)
mov AH,01h ; load "set cursor type" code
call crt_dsr ; turn the cursor off
ret ; return to caller
zcuroff endp
;************************************************************************
;* Cursor On *
;************************************************************************
public zcuron
zcuron proc near
cmp zapcurs,0 ; if cursor disabled
jne zcon_ret ; then return
mov CX,curs_sav ; attributes for cursor on
mov AH,01h ; load "set cursor type" code
call crt_dsr ; turn the cursor on
zcon_ret:
ret ; return to caller
zcuron endp
;************************************************************************
;* Put Cursor *
;************************************************************************
public zputcur
zputcur proc near
push BP ; save caller's BP
mov BP,SP
; put cursor in desired location
mov DH,byte ptr [BP].zc_col ; load column number
mov ega_col,DH
mov DL,byte ptr [BP].zc_row ; load row number
mov ega_row,DL
xor BH,BH ; IBMism: page number (0 if in graphics mode)
mov AH,02H ; load "put cursor" code
call crt_dsr ; position the cursor (DSR swaps DH/DL)
call ega_curs ; display cursor for ega mode
; Return to caller
pop BP ; restore caller's BP
ret ; return
zputcur endp
;************************************************************************
;* Scroll a Window *
;************************************************************************
zs_args struc
dw ? ; caller's BP
dw ? ; return address
zs_line dw ? ; upper left hand corner line number
zs_col dw ? ; upper left hand corner column number
zs_nline dw ? ; number of lines
zs_ncols dw ? ; number of columns
zs_attr dw ? ; text attributes (used for blanking)
zs_args ends
public zscroll
zscroll proc near
push BP ; save caller's BP
mov BP,SP
push AX
push BX
push CX
push DX
; scroll window's text up one line
mov CL,byte ptr [BP].zs_nline ; load number of lines
dec CL ; decrease number of lines by one
jz blank1 ; Jump if scrolling 1-line and just blank it
mov CH,byte ptr [BP].zs_ncols ; load number of columns
mov DL,byte ptr [BP].zs_line ; load upper left line number
mov DH,byte ptr [BP].zs_col ; load upper left column number
mov AX,0601h ; load "scroll text" code with no blanking
cmp DGROUP:PC_MAKE,TIPC
je ti_scrl
;;;;;;;;; cmp vid_mode,14
;;;;;;;;; jge txt_mod ; treat ega modes as text
cmp vid_mode,4 ; Are we in graphics mode?
jl txt_mod ; If we are then fix blank fill attributes
cmp vid_mode,7 ; so that the bar characters don't show up
je txt_mod
xor BH,BH ; zero attribute for fill blanks
jmp short rite_atr
txt_mod: mov BH,byte ptr [BP].zs_attr ; Blanked lines' attribute txt mode
rite_atr: xchg CX,DX ; CX=Upper left corner
xchg CH,CL ; Row,column instead of TI's column,row
xchg DH,DL ; ditto
add DX,CX ; DX=Lower right corner
dec DL ; adjust column count (0 is first column)
int IBM_CRT
jmp short z_quit ; IFF IBM is in graphics mode weird char's
; are used for blanks when scrolling. Do
; as TIPC does and "manual" blank 'em.
;
ti_scrl: mov BX,DX ; copy destination coordinates
inc DL ; compute source by incrementing line number
int TI_CRT ; perform block move
; paint the last line of the window with blank of proper attributes
blank1: mov DH,byte ptr [BP].zs_col ; load starting column number
mov DL,byte ptr [BP].zs_line ; load upper line number
add DL,byte ptr [BP].zs_nline ; add the number of lines and
dec DL ; subtract offf one
mov AH,02h ; load "put cursor" code
xor BH,BH ; IBMism
call crt_dsr ; position cursor for write
mov AX,0920h ; load "write char/attr" code, write a blank
mov BL,byte ptr [BP].zs_attr ; load attribute bit setting
cmp vid_mode,14 ; ega mode?
jl z_scr01
mov BH,BL
and BH,80h
cmp BH,80h ; reverse video?
jne z_scr01
mov AX,09dbh ; change for block character
and BL,7fh ; strip off xor bit
z_scr01: xor BH,BH ; IBMism
mov CX,[BP].zs_ncols ; load line length
call crt_dsr ; write a line of blanks
; return to caller
z_quit: pop DX ; restore caller's BP
pop CX
pop BX
pop AX
pop BP
ret
zscroll endp
;************************************************************************
;* Output Character To Window *
;************************************************************************
zp_args struc
dw ? ; caller's BP
dw ? ; return address
zp_line dw ? ; cursor position - line number
zp_col dw ? ; cursor position - column number
zp_char dw ? ; character to write
zp_attr dw ? ; character's attributes
zp_args ends
public zputc
zputc proc near
push BP ; save caller's BP
mov BP,SP
push DX
push CX
push BX
push AX
; position cursor for write
mov DL,byte ptr [BP].zp_line ; load line number
mov DH,byte ptr [BP].zp_col ; load column number
xor BH,BH ; IBMism
mov AH,02h ; load "put cursor" code
call crt_dsr ; positio the cursor
mov BL,byte ptr [BP].zp_attr ; load its attributes
cmp vid_mode,14 ; only attribute for EGA modes is a
jl zchar_1 ; simulated reverse video
mov BH,BL ; save the attribute
and BH,80h ; reverse video?
jz zchar_1 ; zero indicates bit 8 not set
zchar_2: and BL,7fh ; strip off high bit
mov CX,1 ; character count
xor BH,BH ; video page number
mov AL,0dbh ; block character
mov AH,09h
call crt_dsr
or BL,80h ; set xor bit
; write the characters with attributes
zchar_1: mov AL,byte ptr [BP].zp_char ; load the character
xor BH,BH ; IBMism
mov CX,1 ; repeat count = 1
mov AH,09h ; load write char/attribute code
call crt_dsr
; return to caller
pop AX
pop BX
pop CX
pop DX
pop BP
ret
zputc endp
;************************************************************************
;* Buffered Keyboard Input *
;* *
;* Calling Sequence: ch = getch(); *
;* where ch - the character read from the keyboard *
;************************************************************************
public getch
getch proc near
call get%ch
ret ; return to caller
getch endp
;************************************************************************
;* Read characters from a string *
;* *
;* Calling Sequence: stringrd(page, disp, buffer, &length) *
;* where page,disp: location of string-fed port *
;* buffer and length are as in ZREAD (see above) *
;* *
;* Note: The passing parameter `page' is page # *
;************************************************************************
public stringrd
stringrd proc near
call string%rd
ret
stringrd endp
;***************************************************************************
;* Link for routines in PROGX *
;***************************************************************************
extrn shft_brk:near
extrn dos_err:near
public shft%brk
public dos%err
shft%brk proc far
call shft_brk ;link to SHF BREAK process
ret
shft%brk endp
dos%err proc far
call dos_err ;link to DOS fatal error process
ret
dos%err endp
;
public char_rdy
char_rdy proc near ;our equivalent of Lattice C's kbhit fn
call zch_rdy
ret
char_rdy endp
prog ends
end