648 lines
22 KiB
NASM
648 lines
22 KiB
NASM
; =====> BORDER.ASM
|
||
;***************************************
|
||
;* TIPC Scheme Runtime Support *
|
||
;* Window Support Routines *
|
||
;* *
|
||
;* (C) Copyright 1985 by Texas *
|
||
;* Instruments Incorporated. *
|
||
;* All rights reserved. *
|
||
;* *
|
||
;* Date Written: 16 May 1985 *
|
||
;* Last Modification: *
|
||
;* 14 April 1986 : *
|
||
;* Make references to pagetabl *
|
||
;* call Memory Manager for use *
|
||
;* with extended/expanded mem. *
|
||
;* 26 Sept 1986 : *
|
||
;* added EGA support *
|
||
;* 13 May 1987 : *
|
||
;* Fixed Save/restore problem. *
|
||
;***************************************
|
||
page 60,132
|
||
include scheme.equ
|
||
include pcmake.equ
|
||
|
||
MSDOS equ 021h
|
||
TI_CRT equ 049h
|
||
IBM_CRT equ 010h
|
||
|
||
|
||
DGROUP group data
|
||
data segment word public 'DATA'
|
||
assume DS:DGROUP
|
||
extrn MAX_ROWS:byte,MAX_COLS:byte
|
||
|
||
|
||
; ___ __ __
|
||
; + -| |- _|_ | -- | __| |__ | | (extra)
|
||
map_tab db 0c5h,0b4h,0c3h,0c1h,0c2h,0c4h,0b3h,0d9h,0c0h,0bfh,0dah,0dah
|
||
map_tabx equ $
|
||
|
||
trns_tab db 0dah,0c2h,0c3h,0c5h,0c3h,0c2h,0c2h,0c5h,0c3h,0c5h,0c5h
|
||
db 0c2h,0bfh,0c5h,0b4h,0b4h,0c2h,0c2h,0c5h,0c5h,0b4h,0c5h
|
||
db 0c3h,0c5h,0c0h,0c1h,0c3h,0c1h,0c5h,0c1h,0c3h,0c5h,0c5h
|
||
db 0c5h,0b4h,0c1h,0d9h,0b4h,0c1h,0c5h,0c1h,0c5h,0b4h,0c5h
|
||
db 0c3h,0b4h,0c3h,0b4h,0b3h,0c5h,0c5h,0c5h,0c3h,0b4h,0c5h
|
||
db 0c2h,0c2h,0c1h,0c1h,0c5h,0c4h,0c2h,0c1h,0c5h,0c5h,0c5h
|
||
|
||
m14_attr equ $
|
||
;33-60 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; <
|
||
db 1,0,2,2,1,4,2,0,0,3,3,7,3,5,6,2,6,6,5,3,5,2,1,2,2,1,7,3
|
||
|
||
;61-88 = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X
|
||
db 2,6,1,2,2,0,3,0,0,0,3,1,0,4,0,0,1,1,3,0,3,0,2,0,1,3,1,1
|
||
|
||
;89-116 Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t
|
||
db 0,1,0,0,0,3,7,1,5,0,3,4,3,3,3,0,6,6,0,0,2,2,3,2,3,2,3,2
|
||
|
||
;117-126 u v w x y z { | } ~
|
||
db 2,3,3,2,2,2,3,1,0,1
|
||
|
||
;127-191
|
||
db 64 dup (0)
|
||
|
||
;192-197
|
||
db 5,2,0,0,0,4
|
||
|
||
;198-218
|
||
db 20 dup (0)
|
||
;219-220
|
||
db 2,5
|
||
|
||
m16_attr equ $
|
||
;33-60 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; <
|
||
db 3,1,4,4,4,7,4,2,2,6,6,11,6,9,9,4,10,10,9,6,9,4,2,4,4,3,10,6
|
||
|
||
;61-88 = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X
|
||
db 5,10,3,4,5,2,5,2,2,2,5,2,2,8,2,2,2,2,5,2,5,2,4,2,2,5,2,2
|
||
|
||
;89-116 Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t
|
||
db 2,2,2,2,2,3,12,2,9,2,6,7,6,6,6,2,10,11,2,2,5,5,6,5,6,5,6,4
|
||
|
||
;117-126 u v w x y z { | } ~
|
||
db 5,5,5,5,5,5,6,2,2,3
|
||
db 64 dup (0)
|
||
db 7,2,0,0,0,7
|
||
db 20 dup (0)
|
||
db 2,7
|
||
|
||
public m18_attr
|
||
m18_attr equ $
|
||
;33-60 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; <
|
||
db 2,1,4,4,8,8,4,2,2,6,6,10,9,10,05,4,10,10,10,6,10,4,2,4,4,10,10,6
|
||
|
||
;61-88 = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X
|
||
db 9,06,2,4,4,2,6,2,2,2,6,2,2,8,2,2,2,2,6,2,6,2,4,2,2,6,2,2
|
||
|
||
;89-116 Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t
|
||
db 2,2,2,3,2,3,13,2,10,2,6,8,6,6,6,2,10,12,2,2,5,5,6,5,6,5,6,4
|
||
|
||
;117-126 u v w x y z { | } ~
|
||
db 5,6,6,5,5,5,6,2,2,2
|
||
db 64 dup (0)
|
||
db 10,4,0,0,0,8
|
||
db 20 dup (0)
|
||
db 8,8
|
||
|
||
last_char db 0dbh
|
||
|
||
extrn char_hgt:byte
|
||
extrn vid_mode:word
|
||
data ends
|
||
|
||
XGROUP group PROGX
|
||
PROGX segment byte public 'PROGX'
|
||
assume CS:XGROUP
|
||
|
||
;************************************************************************
|
||
;* Perform appropriate VIDEO I/O interrupt *
|
||
;* Any difference in register definition should be handled by *
|
||
;* the caller except where DH,DL contain row,col information. *
|
||
;************************************************************************
|
||
public crt_dsr
|
||
crt_dsr proc far
|
||
cmp PC_MAKE,TIPC
|
||
jne ibm_dsr
|
||
int TI_CRT
|
||
ret
|
||
ibm_dsr: xchg DH,DL ; Do this now instead of making special checks
|
||
int IBM_CRT ; IBM's row,col is diff'rnt from TI's col,row
|
||
ret
|
||
crt_dsr endp
|
||
|
||
;************************************************************************
|
||
;* Draw Border *
|
||
;************************************************************************
|
||
zb_args struc
|
||
dw ? ; caller's BP
|
||
dd ? ; return address (far linkage)
|
||
dw ? ; return address (original)
|
||
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 z%border
|
||
z%border proc far
|
||
push BP ; save caller's BP
|
||
mov BP,SP
|
||
|
||
; output corners
|
||
mov BL,byte ptr [BP].zb_battr ; load attribute bits
|
||
mov DH,byte ptr [BP].zb_col ; load left column number
|
||
mov DL,byte ptr [BP].zb_line ; load left line number
|
||
dec DL
|
||
dec DH
|
||
mov AL,0DAh ; load upper left corner character
|
||
call zcorner
|
||
inc DH
|
||
add DH,byte ptr [BP].zb_ncols
|
||
mov AL,0BFh ; load upper right corner character
|
||
call zcorner
|
||
inc DL
|
||
add DL,byte ptr [BP].zb_nlines
|
||
mov AL,0D9h ; load lower right corner character
|
||
call zcorner
|
||
dec DH
|
||
sub DH,byte ptr [BP].zb_ncols
|
||
mov AL,0C0h ; load lower left corner character
|
||
call zcorner
|
||
|
||
; output sides
|
||
mov DH,byte ptr [BP].zb_col ; reload upper left column number
|
||
mov DL,byte ptr [BP].zb_line ; and line number
|
||
dec DH ; decrement column number
|
||
mov CX,[BP].zb_nlines
|
||
call zside ; draw the left hand border
|
||
mov DH,byte ptr [BP].zb_col ; reload upper left column number
|
||
mov DL,byte ptr [BP].zb_line ; and line number
|
||
add DH,byte ptr [BP].zb_ncols ; add in line length
|
||
mov CX,[BP].zb_nlines
|
||
call zside ; draw the right hand border
|
||
|
||
; Output the top of the border
|
||
mov DL,byte ptr [BP].zb_line ; load upper left row number
|
||
dec DL
|
||
jl z_no_top ; if row negative, skip write
|
||
mov DH,byte ptr [BP].zb_col ; load upper left column number
|
||
mov CX,[BP].zb_ncols
|
||
call ztop
|
||
; Put the label in the top left corner of the border, if it'll fit
|
||
mov BX,[BP].zb_label ; load pointer to the label's text
|
||
cmp BX,0 ; if pointer NULL, no label
|
||
je z_no_top ; jump, if NULL pointer
|
||
mov DX,[BP].zb_ncols ; load window width
|
||
xor CX,CX ; zero the character counter
|
||
zb_loop: cmp byte ptr [BX],0 ; end of string?
|
||
je zb_eos ; if end of string, jump
|
||
inc CX ; increment the character count
|
||
inc BX ; increment the character string pointer
|
||
cmp CX,DX ; compare to window width
|
||
jl zb_loop ; if label still shorter than window, loop
|
||
zb_eos: jcxz z_no_top ; if no label, jump
|
||
push CX ; save label length
|
||
; Write the label
|
||
mov DL,byte ptr [BP].zb_line ; load upper left row number
|
||
mov DH,byte ptr [BP].zb_col ; load upper left column number
|
||
dec DL ; decrement row number
|
||
xor BH,BH ; IBMism (page 0 for text-mode)
|
||
mov AH,02h ; load "put cursor" code
|
||
call CRT_DSR ; put cursor in upper left corner of border
|
||
pop CX ; restore label's character count
|
||
cmp PC_MAKE,TIPC
|
||
jne ibm_cblk
|
||
mov AH,011h ; load "write block of characters" code
|
||
mov DX,DS ; load segment address
|
||
mov BX,[BP].zb_label ; load label offset
|
||
int TI_CRT ; write the label
|
||
jmp short z_no_top
|
||
;
|
||
ibm_cblk: mov AL,byte ptr [BP].zb_col
|
||
add AL,CL
|
||
cmp AL,MAX_COLS
|
||
jle zb_sml ; jump if label length is OK
|
||
sub AL,MAX_COLS
|
||
sub CL,AL ; force label to remain within 80-col screen
|
||
zb_sml: mov DI,[BP].zb_label ; load label offset
|
||
lbl_loop: mov AH,0Eh ; Write ASCII Teletype
|
||
mov AL,byte ptr [DI]
|
||
mov BL,byte ptr [BP].zb_battr ; load attribute bits just in case
|
||
xor BH,BH ; page # for alpha mode
|
||
push CX
|
||
push DI
|
||
int IBM_CRT
|
||
pop DI
|
||
pop CX
|
||
inc DI
|
||
loop lbl_loop ; DECrement CX and jump if != 0
|
||
; Output the bottom of the border
|
||
z_no_top: mov BL,byte ptr [BP].zb_battr ; load attribute bits
|
||
mov DL,byte ptr [BP].zb_line
|
||
add DL,byte ptr [BP].zb_nlines
|
||
mov DH,byte ptr [BP].zb_col ; load upper left column number
|
||
mov CX,[BP].zb_ncols
|
||
call ztop
|
||
|
||
; return to caller
|
||
pop BP ; restore caller's BP
|
||
ret ; return
|
||
z%border endp
|
||
|
||
;************************************************************************
|
||
;* Local Support: Draw a single character at cursor position *
|
||
;* *
|
||
;* Input Registers: AL - the character to be output *
|
||
;* BL - the character attributes for the write *
|
||
;* DH - column *
|
||
;* DL - row *
|
||
;* *
|
||
;* Registers Modified: AX,CX,SI,DI *
|
||
;************************************************************************
|
||
zcorner proc near ; draw a single corner character
|
||
cmp DH,MAX_COLS
|
||
jae zcornret
|
||
cmp DL,MAX_ROWS
|
||
jae zcornret
|
||
push DX ; save cursor coordinates
|
||
push AX ; save character to be output
|
||
xor BH,BH ; page number (=0 for graphics mode also)
|
||
mov AH,02h ; load "put cursor" code
|
||
call CRT_DSR ; position the cursor
|
||
; read the character in this screen position
|
||
; ** This is tricky 'cause DH/DL are correct but
|
||
; ** will be swapped back (to incorrect) by CRT_DSR proc
|
||
; ** if using an IBM!!!
|
||
cmp PC_MAKE,TIPC
|
||
je no_swap
|
||
xchg DH,DL
|
||
xor BH,BH ; IBM display page
|
||
no_swap: mov AH,08h
|
||
call CRT_DSR
|
||
; see if it's one of the borderline characters
|
||
call map_char
|
||
mov SI,AX
|
||
pop AX ; recover character to be output
|
||
cmp SI,0
|
||
jl zcornput
|
||
; map corner to border character
|
||
call map_char
|
||
mov DL,map_tabx-map_tab-1
|
||
mul DL
|
||
add SI,AX
|
||
mov AL,trns_tab+[SI]
|
||
; output the corner character
|
||
zcornput: mov AH,09h ; load "write character/attribute" code
|
||
mov CX,1 ; number of characters = 1
|
||
xor BH,BH ; Display page for IBM text mode (=0)
|
||
call CRT_DSR ; write it to the screen at cursor position
|
||
pop DX ; restore cursor coordinates
|
||
zcornret: ret ; return
|
||
zcorner endp
|
||
|
||
;************************************************************************
|
||
;* Local Support: Draw a border sides *
|
||
;* *
|
||
;* Input Registers: DH - column *
|
||
;* DL - row *
|
||
;* CX - number of rows *
|
||
;* *
|
||
;* Registers Modified: AX,CX,DL *
|
||
;************************************************************************
|
||
zside proc near
|
||
cmp DH,MAX_COLS ; is column within the CRT's boundaries?
|
||
jae zsideret ; if not, jump
|
||
zside_lp: mov AL,0B3h ; load "|" border character
|
||
push CX ; save line count
|
||
push DX ; save next cursor position
|
||
call zcorner ; output the border character
|
||
pop DX ; restore current cursor position
|
||
pop CX ; restore line counter
|
||
inc DL ; increment the row number
|
||
loop zside_lp ; loop until side is drawn
|
||
zsideret: ret
|
||
zside endp
|
||
|
||
;************************************************************************
|
||
;* Local Support: Draw a border - Top or Bottom *
|
||
;* *
|
||
;* Input Registers: DH - column *
|
||
;* DL - row *
|
||
;* CX - number of columns *
|
||
;* *
|
||
;* Registers Modified: AX,CX *
|
||
;************************************************************************
|
||
ztop proc near
|
||
cmp DL,MAX_ROWS ; is row within the CRT's boundaries?
|
||
jae ztopret ; if not, jump
|
||
ztop_lp: mov AL,0C4h ; load "-" border character
|
||
push CX ; save line count
|
||
push DX ; save next cursor position
|
||
call zcorner ; output the border character
|
||
pop DX ; restore current cursor position
|
||
pop CX ; restore line counter
|
||
inc DH ; increment the column number
|
||
loop ztop_lp ; loop until top/bottom is drawn
|
||
ztopret: ret
|
||
ztop endp
|
||
|
||
map_char proc near
|
||
mov CX,map_tabx-map_tab
|
||
mov DI,offset map_tab
|
||
repne scasb
|
||
mov AX,CX
|
||
dec AX
|
||
ret
|
||
map_char endp
|
||
|
||
;************************************************************************
|
||
;* Save Screen Contents *
|
||
;* *
|
||
;* Purpose: To save a rectangular region of the CRT in a string data *
|
||
;* object. *
|
||
;* *
|
||
;* Calling Sequence: save_scr(str_reg, ul_row, ul_col, n_rows, ncols) *
|
||
;* where str_reg - pointer to string data object *
|
||
;* which is to receive the screen *
|
||
;* contents *
|
||
;* ul_row - row number of the upper left *
|
||
;* corner of the region to be *
|
||
;* saved *
|
||
;* ul_col - column number of the upper left *
|
||
;* corner of the region to be *
|
||
;* saved *
|
||
;* n_rows - number of rows in the region to *
|
||
;* be saved *
|
||
;* n_cols - number of columns in the region *
|
||
;* to be saved *
|
||
;************************************************************************
|
||
sv_args struc
|
||
dw ? ; caller's BP
|
||
dw ? ; caller's ES
|
||
dd ? ; return address (long)
|
||
; dw ? ; original return address (short)
|
||
sv_str dw ? ; address of register pointing to string
|
||
sv_ulrow dw ? ; upper left hand corner's row number
|
||
sv_ulcol dw ? ; upper left hand corner's column number
|
||
sv_nrow dw ? ; number of rows
|
||
sv_ncol dw ? ; number of columns
|
||
sv_args ends
|
||
|
||
public save%scr
|
||
save%scr proc far
|
||
push ES
|
||
push BP ; save the caller's BP register
|
||
mov BP,SP ; and establish local addressability
|
||
; create a pointer to the string object
|
||
mov BX,[BP].sv_str ; load address of register
|
||
mov DI,[BX].C_disp ; load the string
|
||
mov BX,[BX].C_page ; pointer
|
||
%LoadPage ES,BX ; load string page's paragraph address
|
||
;;; mov ES,pagetabl+[BX] ; load string page's paragraph address
|
||
add DI,BLK_OVHD ; advance pointer past string header
|
||
; store number of rows and columns into the first two bytes of the string
|
||
mov AL,byte ptr [BP].sv_nrow
|
||
stosb
|
||
mov AL,byte ptr [BP].sv_ncol
|
||
stosb
|
||
; adjust number of lines/columns for test conditions
|
||
mov AX,[BP].sv_ulrow
|
||
add [BP].sv_nrow,AX
|
||
mov AX,[BP].sv_ulcol
|
||
add [BP].sv_ncol,AX
|
||
; loop until all rows processed
|
||
mov DL,byte ptr [BP].sv_ulrow
|
||
rw_loop: mov DH,byte ptr [BP].sv_ulcol
|
||
; position cursor
|
||
cl_loop: push DX ; save current position
|
||
mov AH,02h ; load "put cursor" function id
|
||
xor BH,BH ; IBMism (page number for cursor)
|
||
call crt_dsr ; position the cursor
|
||
; read character/attributes at current screen position
|
||
mov AH,08h ; load "read char/attribute" function id
|
||
xor BH,BH ; IBMism (display page #)
|
||
call crt_dsr ; read said
|
||
;*******
|
||
cmp vid_mode,14
|
||
jl sav_01 ; not graphics modes
|
||
cmp AL,0 ; don't bother with attributes if nul
|
||
je sav_01
|
||
; cmp AL,07fh ; is it above the first 128 characters ?
|
||
; jno sav_00 ; no
|
||
cmp AL,0dah
|
||
jbe sav_00
|
||
; test AL,010h ; look for D0-DF
|
||
; je sav_00
|
||
xor AL,AL ; set to nul
|
||
jmp sav_01
|
||
sav_00: call graph_attr ; mode 14,16, and 18 attribute function
|
||
;******
|
||
sav_01: stosw ; store char/attr into output string
|
||
; increment column number, test, branch
|
||
pop DX
|
||
inc DH
|
||
cmp DH,byte ptr [BP].sv_ncol
|
||
jl cl_loop
|
||
; increment row number, test, branch
|
||
inc DL
|
||
cmp DL,byte ptr [BP].sv_nrow
|
||
jl rw_loop
|
||
|
||
; return to caller
|
||
pop BP
|
||
pop ES
|
||
ret ; return to caller
|
||
save%scr endp
|
||
|
||
;************************************************************************
|
||
;* Restore Screen Contents *
|
||
;* *
|
||
;* Purpose: To restore a rectangular region of the CRT from a string *
|
||
;* data object. *
|
||
;* *
|
||
;* Calling Sequence: rest_scr(str_reg, ul_row, ul_col) *
|
||
;* where str_reg - pointer to string data object *
|
||
;* which contains the screen *
|
||
;* contents *
|
||
;* ul_row - row number of the upper left *
|
||
;* corner of the region to be *
|
||
;* restored *
|
||
;* ul_col - column number of the upper left *
|
||
;* corner of the region to be *
|
||
;* restored *
|
||
;************************************************************************
|
||
rs_args struc
|
||
rs_nrow dw ? ; number of rows in saved data
|
||
rs_ncol dw ? ; number of columns in saved data
|
||
rs_BP dw ? ; caller's BP
|
||
dw ? ; caller's ES
|
||
dd ? ; return address (long)
|
||
; dw ? ; original return address (short)
|
||
rs_str dw ? ; address of register pointing to string
|
||
rs_ulrow dw ? ; upper left hand corner's row number
|
||
rs_ulcol dw ? ; upper left hand corner's column number
|
||
rs_mrow dw ? ; number of rows in new window
|
||
rs_mcol dw ? ; number of columns in new window
|
||
rs_args ends
|
||
|
||
public rest%scr
|
||
rest%scr proc far
|
||
push ES
|
||
push BP ; save the caller's BP register
|
||
sub SP,offset rs_BP
|
||
mov BP,SP ; and establish local addressability
|
||
; create a pointer to the string object
|
||
mov BX,[BP].rs_str ; load address of register
|
||
mov SI,[BX].C_disp ; load the string
|
||
mov BX,[BX].C_page ; pointer
|
||
%LoadPage ES,BX ; load string page's paragraph address
|
||
;;; mov ES,pagetabl+[BX] ; load string page's paragraph address
|
||
add SI,BLK_OVHD ; advance pointer past string header
|
||
; recover number of rows and columns from screen object
|
||
xor AX,AX
|
||
lods byte ptr ES:[SI]
|
||
add AX,[BP].rs_ulrow
|
||
mov [BP].rs_nrow,AX
|
||
lods byte ptr ES:[SI]
|
||
add AX,[BP].rs_ulcol
|
||
mov [BP].rs_ncol,AX
|
||
; adjust number of lines/columns for test conditions
|
||
mov AX,[BP].rs_ulrow
|
||
add [BP].rs_mrow,AX
|
||
mov AX,[BP].rs_ulcol
|
||
add [BP].rs_mcol,AX
|
||
; loop until all rows processed
|
||
mov DL,byte ptr [BP].rs_ulrow
|
||
xw_loop: mov DH,byte ptr [BP].rs_ulcol
|
||
; position cursor
|
||
xl_loop: cmp DH,byte ptr [BP].rs_mcol ; column too long for new window?
|
||
jge x_long ; if too long, jump
|
||
push DX ; save current position
|
||
mov AH,02h ; load "put cursor" function id
|
||
xor BH,BH ; IBMism (page number/0 in graphic mode)
|
||
call crt_dsr ; position the cursor
|
||
; read character/attributes at current screen position
|
||
lods word ptr ES:[SI] ; fetch the character and attribute
|
||
|
||
;;;;;;;; cmp AL,20h
|
||
;;;;;;;; je x_sp ; if a space skip
|
||
|
||
mov BL,AH ; and copy attribute to BL
|
||
mov AH,09h ; load "write char/attribute" function id
|
||
xor BH,BH ; IBMism (page number)
|
||
mov CX,1 ; character count = 1
|
||
call crt_dsr ; read said
|
||
; increment column number, test, branch
|
||
x_sp: pop DX ; recover the row/column coordinates
|
||
x_more: inc DH ; increment the column number
|
||
cmp DH,byte ptr [BP].rs_ncol ; more characters in this row?
|
||
jl xl_loop ; if so, jump
|
||
; increment row number, test, branch
|
||
inc DL ; increment the row number
|
||
cmp DL,byte ptr [BP].rs_mrow ; check against new window boundary
|
||
jge rs_fin ; if all rows filled, jump
|
||
cmp DL,byte ptr [BP].rs_nrow ; check against saved data
|
||
jl xw_loop ; if more lines, jump
|
||
|
||
; return to caller
|
||
rs_fin: add SP,offset rs_BP ; deallocate local storage
|
||
pop BP ; restore the caller's BP register
|
||
pop ES ; restore the caller's ES register
|
||
ret ; return to caller
|
||
;
|
||
x_long: inc SI ; increment index into saved screen
|
||
inc SI ; buffer
|
||
jmp short x_more ; continue processing row
|
||
rest%scr endp
|
||
|
||
;************************************************************************
|
||
;* Graphics Character Attribute *
|
||
;* *
|
||
;* Purpose: To retrieve the attribute of a character on an IBM screen *
|
||
;* in a graphics mode, either 14 or 16. *
|
||
;* *
|
||
;************************************************************************
|
||
|
||
public graph_attr
|
||
graph_attr proc near
|
||
|
||
cmp AL,20h ; skip if a space
|
||
je grphend
|
||
|
||
cmp AL,00h ; skip if a null
|
||
je grphend
|
||
|
||
cmp AL,0dbh ; block character?
|
||
je grphend
|
||
|
||
push ES
|
||
push SI
|
||
push AX ; save character
|
||
push DX ; save row and column
|
||
xor AH,AH ; clear AH
|
||
mov SI,AX ; use SI as an index
|
||
sub SI,21h
|
||
|
||
mov AL,DL ; row
|
||
mul char_hgt ; pixels per character
|
||
xor BX,BX
|
||
|
||
mov BL,byte ptr m18_attr[SI] ; default mode 18 adjustment
|
||
cmp vid_mode,18 ; are we in mode 18?
|
||
je grph_02 ; yes, jump
|
||
mov BL,byte ptr m16_attr[SI] ; default mode 16 adjustment
|
||
cmp vid_mode,16 ; are we in mode 16?
|
||
je grph_02 ; yes, jump
|
||
mov BL,byte ptr m14_attr[SI] ; must be mode 14
|
||
grph_02:
|
||
add AX,BX
|
||
mov BX,80 ; 80 bytes per line
|
||
mul BX
|
||
|
||
pop DX ; restore the column
|
||
xor DL,DL ; clear the row
|
||
xchg DH,DL ; set AX to the row
|
||
add AX,DX
|
||
mov SI,AX ; put result in SI
|
||
|
||
mov AX,0a000h ; load in graphics plane
|
||
mov ES,AX
|
||
xor CX,CX ; clear CX
|
||
|
||
mov CH,01
|
||
mov AH,0
|
||
grph_03: call get_val
|
||
|
||
shl CH,1 ; shift mask one bit to the left
|
||
inc AH ; next plane
|
||
cmp AH,3
|
||
jbe grph_03
|
||
|
||
pop AX ; retrieve character
|
||
mov AH,CL ; set attribute byte
|
||
pop SI
|
||
pop ES
|
||
grphend: ret
|
||
graph_attr endp
|
||
|
||
get_val proc near
|
||
push AX ; save AH
|
||
mov DX,3ceh ; port addr of sequencer
|
||
mov AL,04h ; index to other map mask register
|
||
out DX,AL ; set index register
|
||
inc DX
|
||
xchg AL,AH
|
||
out DX,AL ; enable bank
|
||
pop AX ; restore AH
|
||
mov AL,ES:[SI]
|
||
or AL,AL
|
||
jz get_end
|
||
or CL,CH ; set attribute bit
|
||
get_end: ret
|
||
get_val endp
|
||
|
||
PROGX ends
|
||
end
|
||
|