home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_300
/
331_01
/
pcio.asm
< prev
next >
Wrap
Assembly Source File
|
1990-06-12
|
34KB
|
1,229 lines
; pcio
; Most of these routines should not be called directly by the application.
; Routines are being added in term.c which relay the call to here. In that
; way terminal specific functions will be consolidated in term.c. By
; changing just term.c the program can be adapted to a different host,
; resulting in better portability. Many of the routines contained here
; are unused, but may be useful for other applications. Many of these
; functions could also be implemented mostly in C. Some assembly language
; is essential for speed on slow systems, but it becomes less important
; on fast processors, and may eventually have to go away altogether for
; better portability. The standard BIOS video calls are incredibly slow,
; and are mostly unused here. On an 80386 system the screen refresh time
; is less than the keyboard autorepeat time with the interface in this
; file.
;
; May 87 G. Osborn
; Converted from DeSmet to the Microsoft version 3.0 macro
; assembler format. Microsoft does not follow data labels
; by a colon. Code segment labels are followed by a colon, though.
; Changed "byte" to "byte ptr" throughout.
; Changed calling sequence to that of Microsoft C compiler version 3.0.
; Same as DeSmet except SI and DI must be saved in case register
; variables are used, so the new sequence is compatible with both compilers.
; publics are defined two ways for compiler compatibility. Each is
; defined as _LABEL (Microsoft) and LABEL_ (DeSmet).
; Effort required to reconvert to DeSmet is minor
; 2-18-87 G. Osborn
_TEXT SEGMENT BYTE PUBLIC 'CODE'
; instructions
_TEXT ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
; read only constants. not constant strings.
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
; uninitialized static data
_BSS ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
; initialized global and static data
_DATA ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
;------------------------------------------------------------------
; pcio.a -- Screen and keyboard interface routines for the PC
; Specific to DeSmet C
;
; last modified - 08/06/86
;
;
; !!! PLEASE NOTE !!!
; This is not quite the same as pcio.a from DeSmet -
; I've made some changes here and there for use with ged.
; Am slowly changing all Desmet functions that use x,y co-ords
; to work as col,row - but have not finished
; Mel Tearle
;------------------------------------------------------------------
;------------------------------------------------------------------
; data starts here
;------------------------------------------------------------------
_DATA SEGMENT
; In this implementation, all special and function keys are translated
; to the following values.
; control key translations. would be better done in C, because the
; convesion time is not critical.
up_char equ 5 ;equ 196 mapped into cursor-pad
down_char equ 24 ;equ 197
left_char equ 19 ;equ 198
right_char equ 4 ;equ 199
bol_char equ 15 ;equ 200
eol_char equ 16 ;equ 201
pageup_char equ 18 ;equ 202
pagedown_char equ 3 ;equ 203
Del_char equ 7 ;equ 207
Ins_char equ 16h
; bof_char equ 204 not used
; eof_char equ 205 not used
; NextWord_char equ 208 not used
; PrevWord_char equ 209 not used
M1 equ 210
M2 equ 211
M3 equ 212
M4 equ 213
M5 equ 214
M6 equ 215
M7 equ 216
M8 equ 217
M9 equ 218
M10 equ 219
M11 equ 220
M12 equ 221
; the table that is used to make the translation
; note - not all used
convert db 72, up_char
db 80, down_char
db 75, left_char
db 77, right_char
db 71, 220 ; <home> becomes beginning of file
db 79, 221 ; <end> becomes end of file
db 73, pageup_char
db 81, pagedown_char
db 113, 222 ; ^<up arrow> .. cursor to top of window
db 118, 223 ; cursor to bottom of window
db 82, Ins_char ; <ins> becomes ^V
db 83, Del_char
db 115, 15h ; ^<left arrow> becomes ^U = cursor full left
db 116, 1Dh ; ^<right arrow> becomes ^] = cursor full right
db 59, M1
db 60, M2
db 61, M3
db 62, M4
db 63, M5
db 64, M6
db 65, M7
db 66, M8
db 67, M9
db 68, M10
db 69, M11
db 70, M12
db 0, 255 ; illegal character
; equates for bios interface.
; the interrupt and codes for the screen interface interrupt.
video equ 10h ;interrupt for dealing with screen
mode equ 0 ;code for setting new screen mode
curtype equ 1 ;code for setting new cursor type
setcur equ 2 ;code for addressing cursor
readcur equ 3 ;code for reading cursor location
readlp equ 4 ;code for reading light pen position
setpage equ 5 ;code to select active page
scrollup equ 6 ;code to scroll screen up
scrolldn equ 7 ;code to scroll screen nown
readch equ 8 ;code to read a character from screen
writeach equ 9 ;code to write char and attributes
writech equ 10 ;code to write character only
setpal equ 11 ;code to set new setpal or border
wdot equ 12 ;code to write a dot
rdot equ 13 ;code to read a dot
wtty equ 14 ;code to write as if teletype
state equ 15 ;code to find current screen status
; int 10 (video) changes all registers except cs,ss,ds,es,bx,cx,dx
; used in set_video
mono_adr equ 0b000h ;mono adapter
graph_adr equ 0b800h ;graphics adapter*
vadrs dw 0
; the interrupt and codes for the keyboard interface.
keyboard equ 16h ;interrupt 16 to deal with keyboard
cicode equ 0 ;code for reading a character
cstscode equ 1 ;code for keyboard status
; caution: must change column number if 40 column mode
crt_cols equ 80
; variables available to a C88 program
public scr_cols_, scr_rows_, scr_scrollup_, scr_scrolldown_
public scr_mode_, scr_page_, scr_attr_, scr_window_top_
public _scr_cols, _scr_rows, _scr_scrollup, _scr_scrolldown
public _scr_mode, _scr_page, _scr_attr, _scr_window_top
_scr_cols label byte
scr_cols_ db crt_cols ;current number of columns
; note- make 25 for ms-dos and 24 for cp/m as cp/m steals the bottom
; line.
scr_rows equ 25
_scr_rows label byte
scr_rows_ db scr_rows ;current number of rows, for ged, was 25
_scr_mode label byte
scr_mode_ db 0 ;current screen mode
_scr_page label byte
scr_page_ db 0 ;current page
_scr_attr label byte
scr_attr_ db 7 ;current attributes for screen
;7 is white letters on black
_scr_window_top label byte
scr_window_top_ db 1 ;first line to scroll, was 0
; variables needed by SEE. Not used here.
_scr_scrollup label byte
scr_scrollup_ db 0 ;zero if scrollup leaves top line alone
_scr_scrolldown label byte
scr_scrolldown_ db 0 ;zero if scroll down supported
_DATA ENDS
;------------------------------------------------------------------
; code starts here
;------------------------------------------------------------------
_TEXT SEGMENT
PUBLIC _scr_setup
;-------------------------------------------------------------------------
; SCR_SETUP_ scr_setup must be called before any use of any
; other routine unless the starting mode is 80X25
; character mode (3,4 or 7). Must be called for monochrome
; (mode 7) for scr_curson to set a proper cursor.
;
; Usage: mode = scr_setup();
;-------------------------------------------------------------------------
scr_setup_:
_scr_setup:
scrsetup:
push bp
mov bp,sp
push di
push si
mov ah,state ;get current state
int video
mov scr_mode_,al ;current mode
mov cl,ah ;make cols a word
mov ch,0
mov scr_cols_,cl ;40 or 80 columns
mov scr_page_,bh
mov scr_attr_,7 ;set to white chars on black
cmp al,4 ;see if a character mode
jc got_attr
cmp al,7 ;7 is for graphics mode
jz got_attr
mov scr_attr_,0 ;attribute is zero in graphics
got_attr:
mov ah,0 ;return int containing mode
push ax ;slight detour
call set_video_ ;get display address
pop ax
pop si
pop di
pop bp
ret
;-------------------------------------------------------
; SCR_TERM_ do any required termination.
;
; Usage: scr_term();
;-------------------------------------------------------
public scr_term_
public _scr_term
_scr_term:
scr_term_:
ret
;-------------------------------------------------------
; SCR_SETMODE_ set a new screen mode
;
; Usage: scr_setmode(new mode);
;-------------------------------------------------------
public scr_setmode_
public _scr_setmode
_scr_setmode:
scr_setmode_:
push bp
mov bp,sp
push di
push si
mov al,[bp+4] ;new mode value
mov ah,mode
int video ;set new mode
call scrsetup ;remember new values
pop si
pop di
pop bp
ret
;-------------------------------------------------------
; SCR_ROWCOL_ sets cursor at any location.
;
; Usage: scr_rowcol(new row, new column);
; Note!: wil be changed to col,row
;-------------------------------------------------------
public scr_rowcol_
public _scr_rowcol
_scr_rowcol:
scr_rowcol_:
push bp ;save from bios
mov bp,sp
push di
push si
mov dx,[bp+6] ;column
mov ax,[bp+4] ;row
mov dh,al
mov bh,scr_page_ ;force page zero
mov ah,setcur ;set cursor location
int video ;call bios
pop si
pop di
pop bp
ret
;-------------------------------------------------------
; SCR_CLR_ clear entire screen
;
; Usage: scr_clr();
;-------------------------------------------------------
public scr_clr_
public _scr_clr
_scr_clr:
scr_clr_:
push bp ;save from video call
mov bp,sp
push di
push si
mov al,0 ;ask for a clear window
xor cx,cx ;start at 0,0
mov dl,scr_cols_ ;clear entire width
dec dl ;last column is width-1
mov dh,scr_rows_ ;last line
dec dh
mov bh,scr_attr_ ;attributes for new blanks
mov ah,scrollup ;ask for a scrollup to clear
int video ;do the clear
pop si
pop di
pop bp
ret
;-------------------------------------------------------
; SCR_CLRL_ clear rest of line.
;
; Usage: scr_clrl();
;-------------------------------------------------------
public scr_clrl_
public _scr_clrl
_scr_clrl:
scr_clrl_:
push bp
mov bp,sp
push di
push si
mov bh,scr_page_
mov ah,readcur ;see where we are
int video
mov cl,scr_cols_ ;calc how many chars left in line
sub cl,dl ;number left
mov ch,0 ;number of blanks needed
mov al,' ' ;write blanks
mov bl,scr_attr_ ;normal attributes
mov bh,scr_page_ ;page number
mov ah,writeach ;write the blanks
int video
pop si
pop di
pop bp
ret
;-------------------------------------------------------
; SCR_CLS_ clear rest of screen.
;
; Usage: scr_cls();
;-------------------------------------------------------
public scr_cls_
public _scr_cls
_scr_cls:
scr_cls_:
push bp
mov bp,sp
push di
push si
call scr_clrl_ ;clear rest of line
mov ah,readcur ;see where we are
mov bh,scr_page_
int video
mov al,0 ;ask for a clear window
mov ch,dh ;current row
inc ch ;+1
cmp ch,scr_rows_ ;see if in last line
jz cleared ;all done
mov cl,0 ;first column
mov dh,scr_rows_ ;24 is the last line
dec dh
mov dl,scr_cols_ ;clear entire width
dec dl ;last column is width-1
mov bh,scr_attr_ ;attributes for new blanks
mov ah,scrollup ;ask for a scrollup to clear
int video ;do the clear
cleared:
pop si
pop di
pop bp
ret
;--------------------------------------------------------
; SCR_SCUP_ scroll text up leaving top lines alone.
;
; Usage: scr_scup();
;--------------------------------------------------------
public scr_scup_
public _scr_scup
_scr_scup:
scr_scup_:
;scroll last line, screen from line
;scr_windor_top to end
push bp
mov bp,sp
push di
push si
mov al,scr_cols_ ;need last column of screen
dec al
xor ah,ah
push ax
mov al,scr_rows_ ;scroll through last line
dec al
xor ah,ah
push ax
xor ax,ax ;from column 0
push ax
mov al,scr_window_top_ ;leave top line alone
push ax
mov al,1
push ax ;scroll by 1
call scr_scrup_ ;do the scroll
add sp,10 ;clear arge
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_SCRUP_ Scroll the screen up. The window is scrolled
; up nline lines. A zero nline will clear the
; window. Top left of the screen in 0,0.
;
; Usage: scr_scrup(nline,fromrow,fromcol,torow,tocol);
;---------------------------------------------------------------
public scr_scrup_
public _scr_scrup
_scr_scrup:
scr_scrup_:
push bp
mov bp,sp
push di
push si
mov al,[bp+4] ;number of lines
mov ch,[bp+6] ;starting row
mov cl,[bp+8] ;starting column
mov dh,[bp+10] ;ending row
mov dl,[bp+12] ;ending column
mov bh,scr_attr_ ;current attribute
mov ah,scrollup
int video ;do the scroll
pop si
pop di
pop bp
ret
;-------------------------------------------------------------
; SCR_SCDN_ scroll all but the top lines down one.
;
; Usage: scr_scdn();
;-------------------------------------------------------------
public scr_scdn_
public _scr_scdn
_scr_scdn:
scr_scdn_:
push bp
mov bp,sp
push di
push si
mov al,scr_cols_ ;need last column of screen
dec al
xor ah,ah
push ax
mov al,scr_rows_ ;scroll through last line
dec al
xor ah,ah
push ax
xor ax,ax ;from column 0
push ax
mov al,scr_window_top_ ;leave top lines alone
push ax
mov al,1
push ax ;scroll by 1
call scr_scrdn_ ;do the scroll
add sp,10 ;clear arge
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_SCRDN_ scroll the screen down. the window is scrolled
; down nline lines. A zero nline will clear the
; window. Top left of the screen in 0,0.
;
; Usage: scr_scrdn(nline,fromrow,fromcol,torow,tocol);
;---------------------------------------------------------------
public scr_scrdn_
public _scr_scrdn
_scr_scrdn:
scr_scrdn_:
push bp
mov bp,sp
push di
push si
mov al,[bp+4] ;number of lines
mov ch,[bp+6] ;starting row
mov cl,[bp+8] ;starting column
mov dh,[bp+10] ;ending row
mov dl,[bp+12] ;ending column
mov bh,scr_attr_ ;current attribute
mov ah,scrolldn
int video ;do the scroll
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_CO_ write a character to the screen. this
; routine increments the cursor position
; after writing. normal C88 puts and printf
; statements can also be used to write to the
; screen.
;
; Usage: scr_co(character);
;---------------------------------------------------------------
public scr_co_
public _scr_co
_scr_co:
scr_co_:
push bp
mov bp,sp
push di
push si
mov al,[bp+4] ;character to write
mov bh,scr_page_
mov ah,wtty ;use tty write routine
int video
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_CI_ keyboard input. function and soft keys are
; translated. see equates for values.
;
; Usage: character = scr_ci();
;---------------------------------------------------------------
public scr_ci_
public _scr_ci
_scr_ci:
scr_ci_:
push bp
mov bp,sp
push di
push si
mov ah,cicode ;ask for a keyboard character
int keyboard
cmp al,0
jne not_special
mov bx, offset dgroup:convert ;convert special key
ci_loop:
cmp byte ptr[bx],0
jne ci1 ; not end of list
and ah,ah
js ci2 ; pass codes 80h - ffh through (eg. alt-160)
xor ah,ah
ci2:
mov al,ah
jmp not_special
ci1:
cmp ah,[bx]
je got_it ; char matches table
add bx,2
jmp ci_loop
got_it:
inc bx
mov al,[bx]
not_special:
mov ah,0
cix: pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_CSTS_ return character if any available. otherwise
; return zero.
;
; Usage: character = scr_csts();
;---------------------------------------------------------------
public scr_csts_
public _scr_csts
_scr_csts:
scr_csts_:
push bp
mov bp,sp
push di
push si
mov ah,cstscode
int keyboard
mov ax,0
jz csts_over
call scr_ci_ ;get the coded character
csts_over:
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_SET_CURSOR_ does nothing. needed by SEE.
;
;---------------------------------------------------------------
public scr_set_cursor_
public _scr_set_cursor
_scr_set_cursor:
scr_set_cursor_: ;set the visible cursor to the
;current position
ret
;---------------------------------------------------------------
; SCR_SINP_ screen input (read character from the screen).
;
; Usage: character = scr_sinp();
;---------------------------------------------------------------
public scr_sinp_
public _scr_sinp
_scr_sinp:
scr_sinp_:
push bp ;save the registers
mov bp,sp
push di
push si
mov bh,scr_page_
mov ah,readch ;code to read a character
int video ;al is letter, ah=attributes
or al,al ;zero returned instead of blank in
;graphics mode
jnz ret_ch
mov al,' '
ret_ch:
mov ah,0 ;kill the attributes
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_CURSOFF_ turn cursor off.
;
; Usage: scr_cursoff();
;
; This routing must not be called directly. See curson() in term.c.
;---------------------------------------------------------------
public scr_cursoff_
public _scr_cursoff
_scr_cursoff:
scr_cursoff_:
push bp ;save registers
mov bp,sp
push di
push si
cmp scr_mode_,4 ;see if graphics
jc text_coff
cmp scr_mode_,7
jnz no_cur
text_coff:
mov cx,0f00h ;should turn cursor off
new_cur:
mov ah,curtype ;set a new cursor type
int video
no_cur:
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_CURSON_ turn cursor back on.
;
; Usage: scr_curson();
;
; This routine must not be called directly. See curson() in term.c
;---------------------------------------------------------------
public scr_curson_
public _scr_curson
_scr_curson:
scr_curson_:
push bp
mov bp,sp
push di
push si
mov cx,0c0dh ;assume monocrome
cmp scr_mode_,7 ;true is mono
jz new_cur ;set it
mov cx,0607h ;assume color card in text mode
cmp scr_mode_,4 ;color text is 0 to 3
jc new_cur
pop si
pop di
pop bp ;do nothing if in graphics mode
ret
;---------------------------------------------------------------
; SCR_MARK mark the current character on the screen.
; Used to delimit block areas in SEE. Just write
; an X or something if reverse video is not available.
;
; Usage: scr_mark(current character);
;---------------------------------------------------------------
public scr_mark_
public _scr_mark
_scr_mark:
scr_mark_: ;mark the passed char, cursor does not advance
push bp
mov bp,sp
push di
push si
mov al,219 ;just write a block character
mov bl,scr_attr_ ;normal attributes
mov cx,1 ;one character
mov bh,scr_page_ ;page number
mov ah,writeach ;write char and attr
int video ;write character and attributes
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_APUTS_ write a string and attributes to the screen.
; goto col, row first. the cursor is moved normally
;
; Usage: scr_aputs(x,y,"Print This",attribute);
;---------------------------------------------------------------
; the following routine is not used by either SEE or D88.
public scr_aputs_
public _scr_aputs
_scr_aputs:
scr_aputs_:
push bp
mov bp,sp
push di
push si
mov di,sp
mov dx,[bp+4] ;col
mov ax,[bp+6] ;row
mov dh,al
mov bh,scr_page_ ;force page
mov ah,setcur ;set cursor location
push bp
int video ;dx is cursor location, bh is page
pop bp
mov si,[bp+8] ;string pointer
mov cx,1 ;number of characters to write
mov bl,[bp+10] ;attribute
naputs:
cld
lodsb ;next character to write
or al,al ;zero at end
jz eaputs
cmp al,10 ;look for LF
jnz normal_ap
ap_scroll:
mov bp,sp ;reset pointer to next char
mov [bp+4],si
mov al,13 ;use tty output to scroll screen
mov ah,wtty
int video ;write cr,lf
mov ah,wtty
mov al,10
int video
pop bp
jmp scr_aputs_ ;start over
normal_ap:
mov bh,scr_page_ ;page number
mov ah,writeach ;write char and attr
int video ;write character and attributes
inc dl ;next column
cmp dl,crt_cols ;see if wrapping around
jc set_loc
mov dl,0 ;at start of column
inc dh ;at next row
cmp dh,scr_rows_ ;see if need a scroll
jc set_loc
jmp ap_scroll ;do a scroll up
set_loc:
mov ah,setcur ;move the cursor
int video
jmp naputs
eaputs:
mov sp,di
pop si
pop di
pop bp
ret
;-------------------------------------------------------------------
; SCR_PUTCH_ write a character to the screen with attribute set.
; see scr_aputs and scr_co
;
; Usage: scr_putch( character, attribute );
;-------------------------------------------------------------------
public scr_putch_
public _scr_putch
_scr_putch:
scr_putch_:
push bp
mov bp,sp
push di
push si
push bp
mov ah,readcur ;see where we are
mov bh,scr_page_
int video ;dx is cursor location, bh is page
pop bp
mov al,[bp+4] ;character to write
mov bl,[bp+6] ;attribute of char
mov bh,scr_page_ ;set page number
mov cx,1 ;write just one char
mov ah,writeach ;write char and attr
int video
inc dl ;move to next column
mov ah,setcur ;move the cursor
int video
pop si
pop di
pop bp
ret
;--------------------------------------------------------
; SCR_DELETE_ clear rest of line starting at column, row.
;
; Usage: scr_delete(x,y);
;--------------------------------------------------------
public scr_delete_
public _scr_delete
_scr_delete:
scr_delete_:
push bp
mov bp,sp
push di
push si
mov dx,[bp+4] ;col
mov ax,[bp+6] ;row
mov dh,al
mov bh,scr_page_ ;force page zero
mov ah,setcur ;set cursor location
int video ;call bios
mov cl,scr_cols_ ;calc how many chars left in line
sub cl,dl ;number left
mov ch,0 ;number of blanks needed
mov al,' ' ;write blanks
mov bl,scr_attr_ ;normal attributes
mov bh,scr_page_ ;page number
mov ah,writeach ;write the blanks
int video
pop si
pop di
pop bp
ret
;----------------------------------------------------------
; The following routines get_mode_, calc_video_,
; set_video_ and scr_putstr were adapted from
; Computer Language Magazine - January 1986
; "Assembly Video Routines for your P.C.", Thomas Webb
;----------------------------------------------------------
;----------------------------------------------------------
; GET_MODE_ get video mode
;
; Usage: internal subroutine used in scr_putstr
;----------------------------------------------------------
public get_mode_
public _get_mode
_get_mode:
get_mode_:
push bp
mov bp,sp
push di
push si
mov ax,0
mov ah,15
int video
pop si
pop di
pop bp
ret
;----------------------------------------------------------
; CALC_VIDEO_ calculate offset into video buffer
; set begining location and attribute
;
; Usage: internal subroutine used in scr_putstr
;----------------------------------------------------------
public calc_video_
public _calc_video
_calc_video:
calc_video_:
mov ax,crt_cols
mul dx
add ax,cx
shl ax,1
ret
;-------------------------------------------------------
; SET_VIDEO_ set video address
;
; Usage: internal subroutine used in scr_setup
;-------------------------------------------------------
public set_video_
public _set_video
_set_video:
set_video_:
call get_mode_
cmp al,7h
jne adp_graphics
mov ax,mono_adr
jmp return
adp_graphics:
mov ax,graph_adr
return:
mov vadrs,ax
ret
;----------------------------------------------------------
; SCR_PUTSTR_ write a string directly to video buffer
; at col, row location with attribute.
; Doesn't change cursor position.
;
; Usage: scr_putstr( x, y, string, attribute );
;----------------------------------------------------------
public scr_putstr_
public _scr_putstr
_scr_putstr:
scr_putstr_:
push bp
mov bp,sp
push di
push si
push es
mov dx,[bp+6] ;get row
mov cx,[bp+4] ;get col
mov ax,crt_cols ;calc video routine
mul dx ;moved here
add ax,cx ;to save a call
shl ax,1
mov di,ax ;return position
mov si,[bp+8] ;get string pointer
mov dh,[bp+10] ;get attribute
mov ax,vadrs ;get display address from setup
mov es,ax ;move absolute display address to es
mov cl,0 ;used to test for end of string
str_loop:
mov dl,[si] ;get the next byte from the string
cmp dl,cl ;if end of string then exit
je str_exit
mov es:[di],dx ;move a word into screen display
add di,2h ;bump display index
inc si ;bump index to string
jmp str_loop
str_exit:
pop es
pop si
pop di
pop bp
ret
;---------------------------------------------------------------
; SCR_APUTCH_ write a character to the screen with
; attribute set. see scr_aputs and scr_co
;
; Usage: scr_aputch(x,y,char,attribute);
;
; After getting this to work found that it isn't that fast.
; However, it's a good replacement for gotoxy() scr_putch()
; if you're only writing one char to a specific location.
;---------------------------------------------------------------
public scr_aputch_
public _scr_aputch
_scr_aputch:
scr_aputch_:
push bp
mov bp,sp
push di
push si
push es
mov dx,[bp+6] ;get col
mov cx,[bp+4] ;get row
call calc_video_ ;locate position in video buffer
mov di,ax ;return position
mov dl,[bp+8] ;get char
mov dh,[bp+10] ;get attribute
mov ax,vadrs ;get video address
mov es,ax ;move buffer address to es
mov es:[di],dx
pop es
pop si
pop di
pop bp
ret
; write a graphics dot
; plot(color,horz,vert)
; int color,horz,vert;
public plot_
public _plot
_plot:
plot_:
push bp
mov bp,sp
push di
push si
call setdot
mov ah,12
int video
pop si
pop di
pop bp
ret
setdot:
mov bp,sp
mov ax,[bp+4] ;color
mov cx,[bp+6] ;horiz
mov dx,[bp+8] ;vert
ret
; *** *** *** *** *** *** *** *** ***
;
; Mixed memory model string move. Programmed in assembly language for
; speed. The string must not cross a 64 k boundary. Equivalent C code:
;
; movesf(sptr,fptr)
; char far *fptr;
; char near *sptr;
; {
; while (*sptr++ = *fptr++)
; ;
; return;
; }
;
PUBLIC _movesf
_movesf PROC NEAR
push bp
mov bp,sp
push si
mov si,[bp+4] ;sptr
les bx,[bp+6] ;fptr
msp1: mov al,es:[bx]
mov [si],al
inc si
inc bx
or al,al
jne msp1
pop si
mov sp,bp
pop bp
ret
_movesf ENDP
; that's all
_TEXT ENDS
END