Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

2649 lines
60 KiB
Plaintext
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.

;************************************************************************
;* DEVICE DRIVER *
;* FOR NCR DM V WITH NEC 7220 *
;************************************************************************
;
;01/SEPTEMBER/1983 10:00 WF bar error corrected
;13/oktober /1983 10:30 wf input locator sample mode error corrected
;14/dezember /1983 15:30 wf erweiterung fuer language translation
;
;LINK86 DDDMVc,DDNECLIc,NECASCIc,ddtrans
;
DGROUP GROUP DATA
DDRIVER CSEG
;
;
;
;
EXTRN GRRESET:NEAR,GRSLV:NEAR,GRSYNC:NEAR,GRPITCH:NEAR
EXTRN GRZOOM:NEAR,GRSTART:NEAR,GRCSRO:NEAR
EXTRN GRCSRFORM:NEAR,GRCLEAR:NEAR
EXTRN GRTEXTW:NEAR,GRWRITE:NEAR,GRVECTW:NEAR
EXTRN GRVECTE:NEAR,GRMASK:NEAR
EXTRN GRTEXTE:NEAR,GRGDCC1:NEAR,GRGDCC:NEAR
EXTRN GRCSRO:NEAR
EXTRN DDINIT:NEAR
EXTRN GRFXON:NEAR,GRFXOFF:NEAR
;
BDOS EQU 0E0H
SBDOS EQU 222 ;SPEZIAL OUTPUT TO CPM OPERATING SYSTEM
;
;
GRCMD EQU 0A1H
GRWRTW EQU 020H
;
;
;The following equates are for BP addressing the arguments
;passed into the GIOS device driver
;
OLD_BP EQU 0
CONTRL_O EQU 2 ;offset control array
CONTRL_S EQU 4 ;segment control array
CONTRL EQU dword ptr CONTRL_O
INTIN_O EQU 6 ;offset integer in array
INTIN_S EQU 8 ;integer in array
INTIN EQU dword ptr INTIN_O
PTSIN_O EQU 10 ;offset points in array
PTSIN_S EQU 12 ;segment points in array
PTSIN EQU dword ptr PTSIN_O
INTOUT_O EQU 14 ;offset of integer out array
INTOUT_S EQU 16 ;segment of integer out array
INTOUT EQU dword ptr INTOUT_O
PTSOUT_O EQU 18 ;offset pts out array
PTSOUT_S EQU 20 ;segment pts out array
PTSOUT EQU dword ptr PTSOUT_O
;
;The following equates are for integer array indexing
W_1 EQU word ptr 0
W_2 EQU word ptr 2
W_3 EQU word ptr 4
W_4 EQU word ptr 6
W_5 EQU word ptr 8
W_6 EQU word ptr 10
W_7 EQU word ptr 12
W_8 EQU word ptr 14
W_9 EQU word ptr 16
W_10 EQU word ptr 18
Eject
; Upon entry to the driver from GSX, Ds:Dx points to the parameter block.
; All other registers are undefined.
; The driver should use its own stack, to avoid overflowing the Gdos caller's.
DDDMV:
Mov Ax,Sp ; Save caller's stack
Mov Bx,Ss
Pushf
Pop SI
Cli ; watch out for old chips
Mov Cx,Seg DriverStack ; Point stack at our area
Mov Ss,Cx
Mov Sp,Offset DriverStackTop
Push SI
Popf
; Now in driver's stack
Push Bx ; Preserve caller' stack base
Push Ax ; and offset
Push DS ; and his DS
; Put the parameter block on the stack for Bp addressing.
Mov Si,Dx ; Point Ds:Si at parameter block
Add Si,18 ; Point at last word
Mov Cx,10 ; 10 words of pointers
Std ; Work down in address
ParamPushLoop:
LODSW ;Get a parameter pointer word
Push Ax ; Push onto my stack
Loop ParamPushLoop ; Loop until all 5 Dword Ptrs pushed
Push Bp ; Point Bp at Contrl offset, preserving
Mov Bp,Sp ; the caller's for politeness
; Point Ds to our data segment
Mov Ax,Seg Function_Table ; Segment base of our data
Mov Ds,Ax ; No further need for caller's Ds
;The following routine does a computed call based on the function op code
;passed in CONTRL(1)
Cld ;make the direction flag 'normal'
Les DI,CONTRL[BP] ;ES:DI -> control array
Mov ES:W_3[DI],0 ;clear contrl(3)
Mov BX,ES:[DI] ;get the function number into BX
Cmp BX,MAX_FUNCTION ;asking for nonexistant function
Ja NO_FUNCTION
Shl BX,1 ;make it a word pointer
Call FUNCTION_TABLE[BX] ;call the proper routine
NO_FUNCTION:
Pop BP ;restore the old BP
Add Sp,20 ; Remove parameter block from stack
Pop DS ; recover the DS
Pop Ax ; Ax <- caller's Sp
Pop Bx ; Bx <- caller's Ss
Pushf ; watch out for old chips
Pop SI
Cli
Mov Ss,Bx ; Return to caller's stack
Mov Sp,Ax ; Pair not interruptable on 8086/88
Push SI
Popf
Retf ; Return to driver caller
Eject
;The following routine sets up all of the default information for a driver
;and returns all of the device characteristics
;ENTRY:
; SS:BP -> stacked long pointers
; ES:DI -> CONTRL(1)
;
;EXIT:
; CONTRL(3) = 6
; CONTRL(5) = 45
; INTOUT(1) - INTOUT(45) set up
F_OPEN_WORKSTATION:
Mov ES:W_3[DI],6 ;set up CONTRL(3)
Mov ES:W_5[DI],45 ;set up CONTRL(5)
CALL GETCOL_FROM_HARDW ;GET COLOR INDICATOR FROM HARDWARE
push es
push ds
push si
push di
call get_lang_trans ;language translation table
pop di
pop si
pop ds
pop es
Les DI,INTOUT[BP] ;point at the output array
Mov SI,offset X_MAX ;point to top of structure
Mov CX,45 ;number of words to move
Rep MOVSW
Les DI,PTSOUT[BP] ;point at the output array
Mov SI,offset OPEN_WORKSTATION_PTSOUT
Mov CX,12
Rep MOVSW
;
Push DS ;save our data segment
Mov AX,DS ;get our data segment
Mov ES,AX ;into the extra segment
Mov DI,offset WORKSTATION_ID ;point at the variables
Lds SI,INTIN[BP] ;point at the default values
Mov CX,10 ;words to move
Rep MOVSW
Mov AL,1
Mov CX,5
Mov DI,offset INPUT_MODE
Rep STOSB ;initilize all input modes to request
Pop DS ;recover our DS
Mov CX,28 ;get the number of words to move
Mov SI,offset DEFAULT_COLOR_DATA
Mov DI,offset COLOR_REQUEST_ARRAY
MOV AX,NUMBER_COLORS
CMP AX,8
JE F_OPEN_1 ;JUMP IF COLOR
MOV SI,OFFSET DEFAULT_MONO_DATA
F_OPEN_1:
Rep MOVSW ;move them in
Mov NEC_MODE,MODE_REP ;set up the defaults
Mov POLYMARKER_NEC_SIZE,0
Mov TEXT_NEC_DIRECTION,2
Mov TEXT_NEC_SIZE,0
Mov INCREMENT_BIAS,0 ;make graphic cursor move slowly
MOV CL,0
MOV AL,0FFH
CALL CPM_SPEZIAL_OUT ;SET GRAPHIC FLAG
Call DDINIT ;wake up the 7220
RET
;
;The following routine returns the color capability flag and sets
; the number of predefined color and color pallette
;
;
GETCOL_FROM_HARDW:
PUSH ES ;SAVE EXTRA SEGMENT
PUSH BX
MOV BX,0FF9H
MOV AX,0
MOV ES,AX ;SET EXTRA SEGMENT --> 0
OUT 011H,AL ;ROMSELECT
MOV AX,ES:[BX] ;GET COLOR INDICATOR
OUT 10H,AL ;RAMSELECT
POP BX
POP ES ;GET ORIGINAL EXTRA SEGMENT
CMP AL,'C'
JNE GETCOL_MONO ;JUMP IF MONOCHROME HARDWARE
MOV NUMBER_COLORS,8 ;PREDEFINED COLOR = 8
MOV PALLETTE_COLORS,8 ;PALLETTE COLOR = 8
MOV COLOR_CAP_FLAG,1 ;
JMP GETCOL_END
GETCOL_MONO:
MOV NUMBER_COLORS,2 ;PREDEFINED COLORS = 2
MOV PALLETTE_COLORS,2 ;PALLETTE COLOR = 2
MOV COLOR_CAP_FLAG,0
GETCOL_END:
RET
get_lang_trans:
push es
mov cl,0fh
mov dx,offset fcb_trans
call fbdos
inc al
jnz get_ready
mov text_conversion_table,0
pop es
ret
get_ready:
mov ax,ds
mov dx,ax
mov cl,33h
call fbdos ;set dma base address
mov dx,offset text_conversion_table
get_loop:
push dx
mov cl,1ah ;set dma address to conversion table
call fbdos
mov cl,14h
mov dx,offset fcb_trans
call fbdos
pop dx
cmp al,1
jz get_end
add dx,128
jmp get_loop
get_end:
mov cl,16 ;close file
mov dx,offset fcb_trans
call fbdos
mov fcb_trans+15,0
mov fcb_trans+32,0
mov ax,offset text_conversion_table
mov si,ax
push ds
pop es
get_end_1:
push si
lodsw ;get 1. vli
cmp al,1ah
jz end_reached
cmp al,0dh
jnz end_reached ;no vli found
mov bx,0
get_end_2:
lodsb
cmp al,0dh
jz end_string_reached
cmp al,1ah
jz end_string_reached
inc bx ;counter + 1
jmp get_end_2
end_string_reached:
pop di
mov ax,bx ;get string length
stosw
add di,bx ;pointer to next string
push di
pop si
jmp get_end_1
end_reached:
pop di
mov ax,0
stosw ;last vli = 0
mov cx,bx
cmp cx,0
jz end_reached_2
end_reached_1:
stosb
loop end_reached_1 ;clear one more string
stosw
end_reached_2:
pop es
ret
;
;
;The following closes a workstation
F_CLOSE_WORKSTATION:
MOV CL,0
MOV AL,0
CALL CPM_SPEZIAL_OUT ;RESET GRAPHIC FLAG
CALL GRFXOFF ;RESET TO NORMAL MODE
MOV CURCOL,1
MOV CURROW,1
RET
;
;The following routine clears the graphics screen
F_CLEAR_WORKSTATION:
Call GRCLEAR
Ret
;
;The following routine updates any pending graphics
F_UPDATE_WORKSTATION:
Ret
;
;The following routine is the escape code processor
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTROL(1) escape op-code
;
;EXIT:
; from selected routine
;
F_ESCAPE:
Mov BX,ES:W_6[DI] ;get the opcode
Cmp BX,LAST_ESCAPE_CODE ;too big ?
Jbe DO_ESCAPE ;no then leap
SUB BX,31
CMP BX,23
JBE DO_ESCAPE
Ret ;else just return
DO_ESCAPE:
Shl BX,1 ;make it a word pointer
Jmp ESCAPE_TABLE[BX] ;leap to it
;
F_ESCAPE_0:
Mov SI,offset ID_STRING
Lodsw ;get the count
Mov ES:W_5[DI],AX ;set size
Les DI,INTOUT[BP]
Mov CX,AX
Rep MOVSW ;copy the ID
Ret
;
F_ESCAPE_1: ;inquire addressable character cels
Les DI,INTOUT[BP] ;point at the output array
Mov ES:W_1[DI],24 ;24 rows
Mov ES:W_2[DI],80 ;80 columns
Ret
;
F_ESCAPE_2:
MOV CL,0
MOV AL,0FFH
CALL CPM_SPEZIAL_OUT ;SET GRAPHIC FLAG
Call GRFXON ;turn on the grafix screen
RET
;
F_ESCAPE_3:
MOV CL,0
MOV AL,0
CALL CPM_SPEZIAL_OUT ;RESET GRAPHIC FLAG
Call GRFXOFF ;turn off the grafix
MOV CURCOL,1
MOV CURROW,1
RET
;
F_ESCAPE_4: ;cursor up
MOV AL,CURROW
CMP AL,1
JE ESCAPE_DONE ;CURSOR JUST ON TOP
DEC AL
MOV CURROW,AL
Mov AL,0BH ;VT
Jmps ESCAPE_CHAR_OUT
;
F_ESCAPE_5: ;cursor down
MOV AL,CURROW
CMP AL,24
JNC ESCAPE_DONE ;CURSOR JUST ON BOTTOM LINE
INC AL
MOV CURROW,AL
Mov AL,0AH ;LF
Jmps ESCAPE_CHAR_OUT
;
F_ESCAPE_6: ;cursor forward
MOV AL,CURCOL
CMP AL,80
JNC ESCAPE_DONE ;CURSOR JUST ON RIGHT SIDE
INC AL
MOV CURCOL,AL
Mov AL,0CH ;FF
Jmps ESCAPE_CHAR_OUT
;
F_ESCAPE_7:
MOV AL,CURCOL
CMP AL,1
JE ESCAPE_DONE ;CURSOR JUST ON LEFT SIDE
DEC AL
MOV CURCOL,AL
Mov AL,08H ;cursor backward
Jmps ESCAPE_CHAR_OUT
;
F_ESCAPE_8:
MOV CURCOL,1
MOV CURROW,1
Mov AL,01EH ;cursor home
ESCAPE_CHAR_OUT:
Call PUT_CHAR
ESCAPE_DONE:
Ret
;
F_ESCAPE_9: ;erase to end of page
MOV AL,1AH
JMPS ESCAPE_CHAR_OUT
; Mov SI,offset ERASE_END_SCREEN
; Jmps ESCAPE_STRING_OUT
;
F_ESCAPE_10: ;erase to end of line
Mov AL,017H
Jmps ESCAPE_CHAR_OUT
;
F_ESCAPE_11: ;direct cursor address
Mov SI,offset ADM3A_CURSOR_POSITION ;point at the string
Les DI,INTIN[BP] ;point at input string
Mov AX,ES:W_1[DI] ;get the row
CMP AL,0
JZ F_ESCAPE_11_1 ;JUMP IF OUT OF RANGE
CMP AL,25
JNC F_ESCAPE_11_1 ;JUMP IF OUT OF RANGE
MOV CURROW,AL ;UPDATE CURRENT ROW
Add AL,01FH ;20HEX is row 0
Mov ADM3A_ROW,AX ;stash it
F_ESCAPE_11_1:
Mov AX,ES:W_2[DI] ;get the column
CMP AL,0
JZ F_ESCAPE_11_2 ;JUMP IF OUT OF RANGE
CMP AL,81
JNC F_ESCAPE_11_2 ;JUMP IF OUT OF RANGE
MOV CURCOL,AL
Add AL,01FH ;20Hex is col 0
Mov ADM3A_COL,AX ;stash it
F_ESCAPE_11_2:
Jmps ESCAPE_STRING_OUT ;do it
;
F_ESCAPE_12: ;output cursor addressable text
Mov CX,ES:W_4[DI] ;get the string count
Push DS ;save our data segment
Lds SI,INTIN[BP] ;point at the string
pop es
push es
mov ax,offset text_buffer
mov di,ax
push cx
F_ESCAPE_12_LOOP:
LODSW ;GET NEXT CHARACTER
stosb
loop F_ESCAPE_12_LOOP
pop cx
pop ds
mov ax,offset text_buffer
mov di,ax
mov ax,offset text_conversion_table
mov si,ax
mov ax,0
text_comp:
lodsw
cmp al,0
jz text_equal_1 ;jump if end of table reached
cmp ax,cx
jz text_compare ;jump if length of string equal
text_comp_1:
add si,ax ;
lodsw
add si,ax ;pointer to next entry
jmp text_comp
text_compare:
push cx ;length
push si ;start of string
PUSH DI
rep cmpsb
POP DI
pop si
pop cx
jz text_equal
mov ax,cx ;pointer to next entry
jmp text_comp_1
text_equal:
add si,cx
lodsw ;get vli of translated text
mov cx,ax
jmp text_equal_2
text_equal_1:
push di
pop si
text_equal_2:
lodsb ;
CALL PUT_CHAR ;DRAW CHARACTER
MOV AL,CURCOL
CMP AL,80
JZ F_ESCAPE_12_END ;END OF LINE REACHED
INC AL
MOV CURCOL,AL
LOOP text_equal_2
F_ESCAPE_12_END:
Ret
;
F_ESCAPE_13:
Mov SI,offset ANSI_REVERSE_ON
Jmps ESCAPE_STRING_OUT
;
F_ESCAPE_14:
Mov SI,offset ANSI_REVERSE_OFF
ESCAPE_STRING_OUT:
Lodsw ;first word is count
Mov CX,AX ;get it into CX
ESCAPE_STRING_OUT_LOOP:
Lodsw ;get next character
Call ESCAPE_CHAR_OUT ;send it
Loop ESCAPE_STRING_OUT_LOOP
Ret
;
F_ESCAPE_15: ;inquire current cursor address
LES DI,INTOUT[BP]
MOV AL,CURROW
MOV AH,0
MOV ES:W_1[DI],AX
MOV AL,CURCOL
MOV ES:W_2[DI],AX
Ret
;
F_ESCAPE_16: ;inquire tablet status
Les DI,INTOUT[BP]
Mov ES:W_1[DI],0 ;not available
Ret
;
F_ESCAPE_17:
Ret
;
F_ESCAPE_18: ;place cursor
Les DI,PTSIN[BP]
Mov AX,ES:W_1[DI] ;get X
Mov XAD,AX
Mov LAST_CURSOR_X,AX
Mov AX,ES:W_2[DI] ;get y
Mov YAD,AX
Mov LAST_CURSOR_Y,AX
TOGGLE_INPUT_CURSOR:
Push TEXT_FONT
Push XAD
Push YAD
Push word ptr NEC_MODE
Mov NEC_MODE,MODE_COM ;set mode to XOR
Mov NEC_COLOR,7 ;select white for cursor
Mov TEXT_FONT,1 ;select normal font
Mov CURRENT_CHARACTER,012H ;select cursor character
Mov GRZOOMP,2 ;select size
Call GRZOOM
Sub XAD,13
Sub YAD,13
Call DISPLAY_CHARACTER
Pop word ptr NEC_MODE
Pop YAD
Pop XAD
Pop TEXT_FONT
Ret
;
F_ESCAPE_19: ;remove cursor
Mov AX,LAST_CURSOR_X
Mov XAD,AX
Mov AX,LAST_CURSOR_Y
Mov YAD,AX
Jmps TOGGLE_INPUT_CURSOR
F_ESCAPE_51:
MOV SI,OFFSET ANSI_HALF_INT_ON
JMP ESCAPE_STRING_OUT
F_ESCAPE_52:
MOV SI,OFFSET ANSI_HALF_INT_OFF
JMP ESCAPE_STRING_OUT
F_ESCAPE_53:
MOV SI,OFFSET ANSI_BLINKING_ON
JMP ESCAPE_STRING_OUT
F_ESCAPE_54:
MOV SI,OFFSET ANSI_STANDARD_VIDEO
JMP ESCAPE_STRING_OUT
;
;
;The following routine does the poly line function based on the endpoint data
;passed in PTSIN
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
;
;
F_POLYLINE:
Mov BX,POLYLINE_COLOR
Mov AL,COLOR_MAP_TABLE[BX] ;look up the color
Mov NEC_COLOR,AL ;save the mapped color
Mov BX,POLYLINE_TYPE ;get the type index
Shl BX,1 ;make it a word pointer
Mov AX,POLYLINE_TABLE[BX] ;look up the line type
F_POLY_1:
Mov GRTEXTP_W,AX ;drop into the structure
Call GRTEXTW ;only needs the first 2 bytes
Mov AX,0FFFFH ;get a mask
Mov GRMASK_W,AX ;drop the mask into the structure
Call GRMASK ;set up the mask values
Mov GRWRT,GRWRTW ;set base mode to write
Les DI,CONTRL[BP]
Mov CX,ES:W_2[DI] ;get the number of vertices
Dec CX ;make it zero relative
Jnz DO_POLYLINE
Ret ;if the bozo sent us only one vertex
DO_POLYLINE:
Les DI,PTSIN[BP] ;ES:DI -> input vertices
Mov AX,ES:W_1[DI] ;get initial X
Mov XAD,AX
Mov AX,ES:W_2[DI] ;get initial Y
Mov YAD,AX
PLYLP: ADD DI,4 ; POINT AT NEXT PAIR
PLYLP_1:
Push CX ;save the loop count
MOV CX,ES:W_1[DI] ;next X
MOV AX,CX
SUB CX,XAD ; DELTA X
MOV NXTX,AX
JZ XZER
JNC XPOS
NEG CX ; ABS(DEL X)
MOV XSGN,0 ; WAS NEGATIVE
JMP DELY
XZER: MOV XSGN,2
JMP DELY
XPOS: MOV XSGN,1
DELY: MOV DX,ES:W_2[DI] ;next Y
MOV AX,DX
SUB DX,YAD
MOV NXTY,AX
JZ YZER
JNC YPOS
NEG DX ; GET ABS(DEL Y)
MOV YSGN,0 ; WAS NEGATIVE
CMP XSGN,2
JNE DELDEL
MOV XSGN,1
JMPS DELDEL
YZER: MOV AL,XSGN
MOV YSGN,AL
JMPS DELDEL
YPOS: MOV YSGN,1
CMP XSGN,2
JNE DELDEL
MOV XSGN,0
DELDEL: CMP CX,DX ; ABS(DELX) - ABS(DEL Y)
JC DELNEG
MOV AL,0
JMPS GETDIR
DELNEG: MOV AL,2
XCHG CX,DX ; DELX MUST BE GREATER THAN DELY
GETDIR: ADD AL,XSGN
ADD AL,AL
ADD AL,YSGN
MOV BX,offset DIRTBL
XLAT DIRTBL
OR AL,8 ; SET UP LINE DRAW COMMAND
MOV GRVECTP1,AL
MOV GRVECTDC,CX ; DRAW PARM DC
AND GRVECTDC,3FFFH
ADD DX,DX ; 2 * ABS (DEL Y)
MOV GRVECTD1,DX
MOV AX,DX
SUB AX,CX ; 2 * ABS(DEL Y) - ABS(DEL X)
MOV GRVECTD,AX
AND GRVECTD,3FFFH
SUB AX,CX ; 2* ABS(DELY) - 2 * ABS(DEL X)
MOV GRVECTD2,AX
AND GRVECTD2,3FFFH
CALL CVECTE ;COLOR VECTOR EXECUTE
MOV AX,NXTX
MOV XAD,AX
MOV AX,NXTY
MOV YAD,AX
Pop CX ;recover the loop counter
Dec CX ;can,t use loop instruction, too far
Jz POLYLINE_DONE
Jmp PLYLP
POLYLINE_DONE:
Ret
;
;The following rotuine does the poly marker function
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
F_POLYMARKER:
Mov CX,ES:W_2[DI] ;get the number of markers
Jcxz POLYMARKER_DONE ;if bozo sent us no coordinates
Push CX ;save the count
Mov NEC_DIRECTION,2 ;set the direction to normal
Mov AX,0FFFFH ;get a mask of all ones
Mov GRMASK_W,AX
Call GRMASK ;set the mask values
Mov GRWRT,GRWRTW ;set base mode to write
Mov BX,POLYMARKER_COLOR ;get the color index
Mov AL,COLOR_MAP_TABLE[BX] ;get the color
Mov NEC_COLOR,AL ;set up the color for the 7220
Mov AX,POLYMARKER_TYPE ;get the type of marker
Add AL,010H ;markers start at 10H
Mov CURRENT_CHARACTER,AL ;drop it into the character
Mov AL,POLYMARKER_NEC_SIZE ;get the size of the marker
Mov GRZOOMP,AL ;drop it into the structure
Call GRZOOM ;set the size
Les DI,PTSIN[BP] ;point at the points in array
Pop CX ;recover the counter
Push TEXT_FONT ;save the current font
Mov TEXT_FONT,1 ;set it to normal
POLYMARKER_LOOP:
Mov BL,GRZOOMP ;get the scale factor
Inc BL ;make it one relative
Xor BH,BH ;clear the top
Shl BX,1 ;X 2
Shl BX,1 ;X 4
Mov AX,ES:W_1[DI] ;get the next X
Sub AX,BX ;bias character into the center
Mov XAD,AX ;save the new XAD
Mov AX,ES:W_2[DI] ;get next Y
Sub AX,BX
Mov YAD,AX ;stash it
Add DI,4 ;point DI at next pair
Push CX
Push ES
Push DI
Call DISPLAY_CHARACTER
Pop DI
Pop ES
Pop CX
Loop POLYMARKER_LOOP
POLYMARKER_DONE:
Pop TEXT_FONT ;recover the font
Ret
;
;
;The following routine displays the text at INTIN(1) with a length in CONTRL(4)
;at the position in PTSIN(1),PTSIN(2) with the current text color,scale,direction
;
;ENTRY:
; SS:BP -> stacked long pointers
; ES:DI -> CONTRL(1)
;EXIT:
;
F_TEXT:
Push ES
Push DI
Mov AL,TEXT_NEC_SIZE ;get the size value
Mov GRZOOMP,AL ;set up the parameter
Call GRZOOM ;set the zoom factor
Pop DI
Pop ES
Mov GRWRT,GRWRTW ;set the mode to write
Mov BX,TEXT_COLOR ;get the color for the text
Mov AL,COLOR_MAP_TABLE[BX] ;look it up
Mov NEC_COLOR,AL
Mov CX,ES:W_4[DI] ;get the length into CX
Jcxz F_TEXT_DONE ;if zero length then leap
Les DI,PTSIN[BP] ;ES:DI -> points in array
Mov AX,ES:W_1[DI] ;get X address
Mov XAD,AX
Mov AX,ES:W_2[DI] ;and Y address
Mov YAD,AX
Mov BL,GRZOOMP ;get the zoom factor
Inc BL ;make it one relative
Mov AL,TEXT_NEC_DIRECTION ;get the text direction code
Mov NEC_DIRECTION,AL ;drop into the 7220 direction
Xor AH,AH ;zero the high byte
Shl AL,1
Shl AL,1 ;make a dword pointer
Add AX,offset BASELINE_TABLE
Mov SI,AX ;point at word pair
Lodsw ;get X bias
Imul BL ;scale the base line bias
Add XAD,AX ;zap it
Lodsw
Imul BL
Add YAD,AX
Les DI,INTIN[BP] ;ES:DI -> string data
DO_DISPLAY_STRING:
Mov AL,ES:[DI] ;get the next character
Inc DI ;bump the pointer
Inc DI ;by a word value
DO_DISPLAY_ONE_CHARACTER:
PUSH ES
Push DI
Push CX ;save the count and the index
Mov CURRENT_CHARACTER,AL ;save the character
;
Call DISPLAY_CHARACTER
;
SCALE_CURSOR:
Mov BL,GRZOOMP ;get our current zoom factor
Inc BL ;make it 1 relative
Mov AL,TEXT_NEC_DIRECTION ;get the 7220 direction code
Xor AH,AH
Shl AL,1
Shl AL,1 ;make it a dword offset
Add AX,offset INCREMENT_TABLE ;point at the proper pair
Mov SI,AX ;put it in an index register
Lodsw ;get the value
Imul BL ;scale it
Add XAD,AX ;adjust the X address
Lodsw
Imul BL
Add YAD,AX ;adjust the Y address
Pop CX
Pop DI
Pop ES
Loop DO_DISPLAY_STRING ;till done
F_TEXT_DONE:
Ret
;
;
;the following routine displays the character at CURRENT_CHARACTER
;in the color specified in NEC_COLOR, at the CURRENT XAD,YAD
;
DISPLAY_CHARACTER:
Mov AL,CURRENT_CHARACTER ;get the character
Xor AH,AH ;parinoia strikes deep
Mov BX,8 ;calculate the bias
Mul BL ;find the start of the character bits
Add AX,offset CHARACTER_BIT_TABLE
Mov SI,AX ;index into SI
Mov DI,offset GRTEXTP1 ;point DI to output structure
Push ES ;save both the segments
Mov AX,DS ;get the data segment
Mov ES,AX ;into the extra segment
Mov CX,4 ;8 byte transfer but words go faster
Rep Movsw ;do the move
Pop ES
;
Mov GRVECTP2,7 ;always a 7 for text word ptr
Mov AH,NEC_NORMAL_CHAR ;get bit for normal character
Cmp TEXT_FONT,1 ;is it normal set
Jle SET_CHARACTER_FONT
Mov AH,NEC_SLANT_CHAR ;else set 2 is slanted
SET_CHARACTER_FONT:
Mov AL,NEC_DIRECTION ;get the 7220 dirction code
Or AL,AH ;mark as character write
Mov GRVECTP1,AL ;drop into the data structure
Mov GRVECTP4,8
;
DISPLAY_PATTERN:
Mov GRCOLR,GPLANE ;set the plane
Mov AL,NEC_MODE
Test NEC_COLOR,BIT_GREEN
Jnz CHAR_GRN ;if color then leap
Cmp AL,MODE_REP
Jnz TRY_CHAR_BLU
Mov AL,MODE_RES
CHAR_GRN:
Call DO_DISPLAY_PATTERN
TRY_CHAR_BLU:
MOV AX,NUMBER_COLORS
CMP AX,2
JE DO_DISPLAY_PATTERN_DONE ;JUMP IF MONOCHROME
Mov GRCOLR,BPLANE
Mov AL,NEC_MODE
Test NEC_COLOR,BIT_BLUE
Jnz CHAR_BLU
Cmp AL,MODE_REP
Jnz TRY_CHAR_RED
Mov AL,MODE_RES
CHAR_BLU:
Call DO_DISPLAY_PATTERN
TRY_CHAR_RED:
Mov GRCOLR,RPLANE
Mov AL,NEC_MODE
Test NEC_COLOR,BIT_RED
Jnz DO_DISPLAY_PATTERN
Cmp AL,MODE_REP
Jnz DO_DISPLAY_PATTERN_DONE
Mov AL,MODE_RES
DO_DISPLAY_PATTERN:
Cmp AL,MODE_REP
Jnz DDP_SAVE_MODE
Mov AL,MODE_SET
DDP_SAVE_MODE:
Mov GRATTRIB,AL ;save the write mode
Mov CX,0 ;command only
Call GRWRITE ;set the writing mode
Call GRCSRO ;put the cursor in the proper page
Call GRTEXTW ;set up the pattern registers
Mov CX,5 ;5 byte write
Call GRVECTW ;send out this stuff
Call GRTEXTE ;do a write
DO_DISPLAY_PATTERN_DONE:
Ret
;
;The following routine fills the area described by the input data in PTSIN
;ENTRY:
; SS:BP -> stacked long word pointers
;
F_FILLED_AREA:
Mov BX,FILL_COLOR
Mov AL,COLOR_MAP_TABLE[BX]
Mov NEC_COLOR,AL
Mov GRWRT,GRWRTW ;mode to write
Mov GRMASK_W,0FFFFH
Call GRMASK
Mov GRWRTP,0FFFFH
les si,contrl[bp]
mov ax,es:word ptr 2[si]
mov num,ax
sub ax,1
mov numsav,ax ; save number of vertices
Mov AX,FILL_INTERIOR ;get interior style
Cmp AX,0
Jnz DO_FILL ;if solid then leap
Jmp FILL_OUTLINE
DO_FILL_PATTERN:
MOV BX,FILL_STYLE
ADD BX,8
JMPS DO_FILL_1
DO_FILL:
Mov BX,0 ;index if solid
CMP AX,2
JE DO_FILL_PATTERN
Cmp AX,1 ;test for solid
Jz DO_FILL_1 ;yes then leap
Mov BX,FILL_STYLE
DO_FILL_1:
Mov CL,3
Shl BX,CL
Add BX,offset CHARACTER_BIT_TABLE
Mov FILL_MASK_BASE,BX ;save it for later
mov minY,1000 ! mov maxY,0 ; impossible min's and max's
; search for biggest and smallest X and Y's
les si,PTSIN[BP] ; reference PTSIN
mov cx,num ; total number of points
linelp:
add si,2 ; skip X coord
lods es:word ptr [si] ! cmp ax,miny ; see if Y is smallest
jnl domaxy
mov miny,ax
domaxy:
cmp ax,maxy
jng minmax_iterate
mov maxy,ax
minmax_iterate:
loop linelp ; iterate til done
mov ax,miny ! mov f1,ax ; F1 is raster counter
mov bx,maxy ! sub bx,ax ; maxy-miny gives...
mov count,bx ; is number of lines
Jnz RASTER_LOOP ; if any lines
Jmp FILL_OUTLINE ;else just outline
; For each raster line......
raster_loop:
mov jint,0 ; intersection index
mov cx,numsav ; for J = num-1 to 1 by -1
Les SI,PTSIN[BP]
; For each vertice....
vertice_loop:
push cx
lea di,4[si] ; addr(PTSIN((J+1)*2)
push si
call compute_intercept
pop si
add si,4
pop cx
loop vertice_loop
; Now, connect last and first
les di,ptsin[BP]
call compute_intercept
; Now, fill between each pair of X intercepts of this raster line
mov ax,jint ; get number of X intercepts
shr ax,1 ; jint/2 # of pairs
jz nxtpt ; no pairs, nothing to fill
mov I,ax ; is the loop index
; F1 is the raster line (Y)
; SCRATCH(0:i) has X coord pairs
mov SI,f1
mov yad,SI
And SI,7
Neg SI
Add SI,7 ;point to wrong end of character
Add SI,FILL_MASK_BASE
Mov AL,[SI]
Mov AH,AL
mov bx,offset scratch
drwlp:
Push AX
Push BX
Mov CX,[BX]
Mov XAD,CX
And CX,0FH
Ror AX,CL
Mov GRTEXTP_W,AX ;set up pattern
Mov AX,2[BX]
Sub AX,XAD ;get delta
Mov GRVECTDC,AX
Neg AX
Mov GRVECTD,AX
Shl AX,1
Mov GRVECTD2,AX
Mov GRVECTD1,0
Mov GRVECTP1,0AH ;vector dir 2
Call GRTEXTW
Call CVECTE
Pop BX
Pop AX
NXT_PAIR:
Add BX,4
Dec I ;count down loop
Jz NXTPT
Jmp DRWLP
;
nxtpt: inc f1
dec count
jz FILL_OUTLINE
jmp RASTER_LOOP
;
;
FILL_OUTLINE:
Mov AX,0FFFFH ;line style of solid
Call F_POLY_1
Les DI,PTSIN[BP]
Mov AX,ES:W_1[DI] ;get first X
Mov XAD,AX
MOv AX,ES:W_2[DI]
Mov YAD,AX
Mov BX,NUMSAV
Shl BX,1
Shl BX,1 ;BX -> at last pair
Add DI,BX
Mov CX,1
Call PLYLP_1
f_fill_exit:
no_int: ; here for short jumps...
ret
compute_intercept: ; ES:SI -> x1, y1 ; ES:DI -> x2,y2, F1 = Y
mov bx,es:2[di] ! sub bx,es:2[si] ; compute Y2-Y1
jz no_int ; no horizontals allowed
mov ax,f1 ; get Y
mov cx,ax ! sub cx,es:2[si] ; Y - Y1
sub ax,es:2[di] ; Y - Y2
xor ax,cx ! jns no_int ; if signs equal, not on line
; here if Y is within line segment
; compute hi and lo intercepts
; and insert them into the list
mov ax,es:0[di] ! sub ax,es:0[si] ; X2 - X1
shl cx,1 ; (Y-Y1)*2 so we can half round
imul cx ; (x2-x1) * (y-y1+1/2)*2
idiv bx ; / (y2-y1)
inc ax ! sar ax,1 ; +1/2 and half round
add ax,es:0[si] ; + X1 is X intercept
; insert AX into SCRATCH before first greater element
; (this maintains the list in sorted order)
insert_list:
Push ES
mov bx,es:0[si] ! mov cx,es:0[di] ; get X1 and X2
cmp bx,cx ! jng no_swap_1 ; insure BX is smaller of two
xchg bx,cx ; no, swap 'em
no_swap_1:
cmp ax,bx ! jnl il_1 ; see if AX is left of endpoint
mov ax,bx ; yes, limit it to edge
il_1:
cmp ax,cx ! jng il_2 ; see if AX is right of other end
mov ax,cx ; yes, limit to other edge
il_2:
mov bx,ds ! mov es,bx ; insure destination in our data segment
mov di,offset scratch ; point to start of list
mov cx,JINT ; get length of list
jcxz insert_store ; if list empty, skip scan
scanloop:
scasw ! jl scanmatch ; see if less than this one
loop scanloop ; no, try next
jmps insert_store ; greater than all, just add to end
scanmatch: ; have match, move rest of list out one
mov di,jint ; get current length
shl di,1 ; *2 is length of word array
add di,offset scratch ; destination is end of scratch
lea si,(-2)[di] ; source is last element
std ! rep movsw ! cld ; move rest of list (backwards)
insert_store:
stosw ; store intercept
inc JINT ; bump length
Pop ES
ret
;
;
;The following routine fills a cell array with the data and attributes passed
;in CONTRL & PTSIN
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL array
F_CELL_ARRAY:
Push word ptr NEC_MODE ;save the current writing mode
Mov BX,ES:W_9[DI] ;get the selected writing mode
And BX,3 ;mask into reality
Mov AL,MODE_MAP_TABLE[BX] ;get the nec mode
Mov NEC_MODE,AL ;save it
Mov BX,ES:W_8[DI] ;get the row count
Mov SI,ES:W_7[DI] ;get the element count
Mov CA_ELEMENT_COUNT,SI ;save it
Mov AX,ES:W_6[DI] ;get the row length
Mov CA_ROW_LENGTH,AX ;save it for later
Les DI,PTSIN[BP] ;point at input vertices
Mov AX,ES:W_4[DI] ;get the upper Y
Mov YAD,AX ;save it
Mov CX,ES:W_2[DI] ;get lower Y
Sub AX,CX ;calculate delta Y
Xor DX,DX
Div BX ;divide for repeat count
Mov CA_REP_COUNT_Y,AX ;save the Y rep count
Mov CX,ES:W_1[DI] ;get left X
Mov CA_XAD,CX ;save it
Mov AX,ES:W_3[DI] ;get right X
Sub AX,CX ;compute DELTA X
Xor DX,DX ;clear AX
Div SI ;calculate X repeat count
Inc AX
Mov GRVECTDC,AX ;set up draw count
Neg AX
Mov GRVECTD,AX
Shl AX,1
Mov GRVECTD2,AX
Mov GRVECTD1,0
Mov GRVECTP1,0AH ;vector direction 2
Mov GRTEXTP_W,0FFFFH ;line style to solid
Call GRTEXTW
Les DI,CONTRL[BP]
Mov CX,ES:W_8[DI] ;get the row count
Les DI,INTIN[BP] ;point at the cell array
F_CELL_ARRAY_Y_LOOP:
Push CX ;stack the row count
Mov CX,CA_REP_COUNT_Y ;get the Y repeat count
DO_NEXT_CA_Y:
Push CX
Mov BX,0 ;zero the element counter
Mov CX,CA_ELEMENT_COUNT ;get the X element count
Mov AX,CA_XAD
Mov XAD,AX
DO_NEXT_CA_X:
Mov SI,ES:[DI+BX] ;get the next element
Mov AX,NUMBER_COLORS ;get max color
DEC AX
Cmp SI,AX ;above the max
Jbe DO_CA_COLOR ;no then leap
Mov SI,AX ;else stick at max
DO_CA_COLOR:
Mov AL,COLOR_MAP_TABLE[SI] ;get the nec color
Mov NEC_COLOR,AL ;save it for line draw
Push ES
Push DI
Push BX
Push CX
Call CVECTE
Pop CX
Pop BX
Pop DI
Pop ES
Inc BX ;bump the element pointer
Inc BX ;by a word
Mov AX,GRVECTDC ;get the vector length
Add XAD,AX ;move the XAD
Loop DO_NEXT_CA_X ;if not the last element
Dec YAD ;move down on Y axis
Pop CX ;get the Y repeat count
Loop DO_NEXT_CA_Y ;if not last then loop
Pop CX
Add DI,CA_ROW_LENGTH ;move to the next row
Add DI,CA_ROW_LENGTH ;its a word array
Loop F_CELL_ARRAY_Y_LOOP
F_CELL_ARRAY_DONE:
Pop word ptr NEC_MODE ;restore the writing mode
Ret
;
;The following routine dispacthes to the selected generlized drawing primitive
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
F_GENERALIZED_DRAWING_PRIMITIVE:
Mov BX,ES:W_6[DI] ;get the GDP op code
Cmp BX,LAST_GDP ;too big ?
Jbe DO_GDP ;no the lets do it
Ret
DO_GDP:
Push BX ;save the pointer
Mov GRWRT,GRWRTW ;set mode to write
Mov GRMASK_W,0FFFFH
Call GRMASK
Pop BX
Shl BX,1
Jmp GDP_TABLE[BX] ;leap to the routine
;
F_GDP_BAR:
Push word ptr GRZOOMP
Mov GRZOOMP,0
Call GRZOOM
Pop word ptr GRZOOMP
MOV BX,FILL_COLOR ;get the color
Mov AL,COLOR_MAP_TABLE[BX]
Mov NEC_COLOR,AL
Mov AX,FILL_INTERIOR ;get the interior type
Cmp AX,0 ;is it hollow ?
Jnz FILLED_BAR
Jmp HOLLOW_BAR ;yes then leap
FILL_PATTERN:
MOV BX,FILL_STYLE
ADD BX,8
JMPS DO_BAR
FILLED_BAR:
Mov BX,0 ;first style is BLOT
CMP AX,2 ;IS IT PATTERN
JE FILL_PATTERN
Cmp AX,1 ;is it solid ?
Jz DO_BAR
Mov BX,FILL_STYLE ;get the style index
;
DO_BAR:
Mov CX,3
Shl BX,CL ;mul by 8
Mov SI,offset CHARACTER_BIT_TABLE ;point at the character table
Add SI,BX
MOV DI,OFFSET GRTEXTP1
MOV AX,DS
MOV ES,AX
MOV CX,4
Rep MOVSW
;
Les DI,PTSIN[BP] ;ES:DI -> input data
Mov AX,ES:W_1[DI]
Mov XAD,AX ;set up start X
Mov CX,ES:W_3[DI]
Sub CX,AX ;delta X
MOV AX,ES:W_2[DI]
Mov YAD,AX
Mov DX,ES:W_4[DI]
SUB DX,AX ; DELTA Y
CMP DX,0
JE DO_BAR_3D
CMP DX,1
JE DO_BAR_3
Dec DX ;-1
DO_BAR_3:
MOV GRVECTDC,DX
MOV GRVECTD,CX
Mov GRVECTP1,012H ;area fill dir 2
Call DISPLAY_PATTERN ;go do it
;
HOLLOW_BAR:
Mov GRTEXTP_W,0FFFFH ;set up the outline style
Call GRTEXTW
Les DI,PTSIN[BP] ;ES:DI -> input data
Mov AX,ES:W_1[DI]
Mov XAD,AX ;set up start X
Mov CX,ES:W_3[DI]
Sub CX,AX ;delta X
MOV AX,ES:W_2[DI]
Mov YAD,AX
Mov DX,ES:W_4[DI]
SUB DX,AX ; DELTA Y
CMP DX,0
JE DO_BAR_1D
CMP DX,1
JE DO_BAR_1
Dec DX ;-1
DO_BAR_1:
CMP CX,0
JE DO_BAR_1C
CMP CX,1
JE DO_BAR_2 ;DPAR,D2PAR,DMPAR SHOULD NOT TO BE 0
Dec CX ;-1
DO_BAR_2:
MOV GRVECTD2,DX
MOV GRVECTD,CX
Mov GRVECTDM,CX
Mov GRVECTP1,042H ;rectangle dir 2
Mov GRVECTDC,3
Mov GRVECTD1,-1
Call CVECTE
Ret
DO_BAR_1D:
INC DX
JMPS DO_BAR_1
DO_BAR_1C:
INC CX
JMPS DO_BAR_2
DO_BAR_3D:
INC DX
JMPS DO_BAR_3
;
F_GDP_ARC:
Ret
;
F_GDP_PIESLICE:
Ret
;
F_GDP_CIRCLE:
Mov GRTEXTP_W,0FFFFH ;set up the line style
Call GRTEXTW
Mov BX,FILL_COLOR ;get the color index
Mov AL,COLOR_MAP_TABLE[BX]
Mov NEC_COLOR,AL ;save the selected color
Call DO_GDP_CIRCLE ;do the selected size
Cmp FILL_INTERIOR,0 ;is it hollow ?
Jz GDP_CIRCLE_DONE ;yes then leap
FILL_CIRCLE_LOOP:
Les DI,PTSIN[BP] ;point at the points in
Cmp ES:W_5[DI],0 ;is radius zero ?
Jz GDP_CIRCLE_DONE ;yes then leap
Dec ES:W_5[DI] ;else lets do the next one
Call DO_GDP_CIRCLE
Jmps FILL_CIRCLE_LOOP
GDP_CIRCLE_DONE:
Ret
;
DO_GDP_CIRCLE:
Les DI,PTSIN[BP] ;point to the points in array
Mov BX,ES:W_5[DI] ;get the radius
Mov AX,0B505H ;pick up 1/1.41 (0B505H)
Inc BX
Mul BX
Mov GRVECTDC,DX ;stash it in the structure
Dec BX ;R-1
Mov GRVECTD,BX ;stash it in the structure
Shl BX,1 ;2(R-1)
Mov GRVECTD2,BX ;stash it in the structure
Mov GRVECTD1,-1 ;set up the constants
Mov GRVECTDM,0
GDP_CIRCLE_LOOP:
Mov AX,ES:W_1[DI] ;get the center X
Add AX,ES:W_5[DI] ;add in the radius
Mov XAD,AX ;save it
Mov AX,ES:W_2[DI] ;get center Y
Mov YAD,AX
Mov GRVECTP1,27H ;arc 7
Call CVECTE
Mov GRVECTP1,24H ;arc 4
Call CVECTE
Les DI,PTSIN[BP]
Mov AX,ES:W_1[DI]
Mov XAD,AX
Mov AX,ES:W_2[DI]
Add AX,ES:W_5[DI]
Mov YAD,AX
Mov GRVECTP1,21H ;arc 1
Call CVECTE
Mov GRVECTP1,26H ;arc 6
Call CVECTE
Les DI,PTSIN[BP]
Mov AX,ES:W_1[DI]
Sub AX,ES:W_5[DI]
Mov XAD,AX
Mov AX,ES:W_2[DI]
Mov YAD,AX
Mov GRVECTP1,23H ;arc 3
Call CVECTE
Mov GRVECTP1,20H ;arc 0
Call CVECTE
Les DI,PTSIN[BP]
Mov AX,ES:W_1[DI]
Mov XAD,AX
Mov AX,ES:W_2[DI]
Sub AX,ES:W_5[DI]
Mov YAD,AX
Mov GRVECTP1,25H ;arc 5
Call CVECTE
Mov GRVECTP1,22H ;arc 2
Call CVECTE
Ret
;
F_GDP_PGC:
Ret
;
;The following routine sets the character height in device units
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
;EXIT:
; CONTRL(3) = 2
; PTSOUT(1) - PTSOUT(4) filled with arguments
F_SET_CHARACTER_HEIGHT:
Mov ES:W_3[DI],2 ;set up contrl(3)
Les DI,PTSIN[BP] ;ES:DI -> PTSIN(1)
Mov AX,ES:W_2[DI] ;get the requested character height
Inc AX ;make it one relative
Mov BL,7 ;height of character in pixels
Div BL ;compute nearest size
Xor AH,AH ;zero the remainder
Cmp AX,0 ;min height ?
Jz SET_CHARACTER_HEIGHT ;yes then leap
Dec AX ;round down
Mov BX,AX ;get size into BX
Mov AX,15 ;get the max size
Cmp BX,AX ;too big
Ja SET_CHARACTER_HEIGHT
Mov AX,BX ;else get the size
SET_CHARACTER_HEIGHT:
Mov TEXT_NEC_SIZE,AL ;and save it
Inc AX ;make it one relative to scale
Mov BX,AX ;put in BX to multiply
Les DI,PTSOUT[BP] ;get the output array pointer
Mov AX,5 ;characters are 5 pixels wide
Mul BL ;scale by size
Mov ES:W_1[DI],AX ;report the scaled character width
Mov AX,7
Mul BL
Mov ES:W_2[DI],AX ;report scaled character height
Mov AX,8
Mul BL
Mov ES:W_3[DI],AX ;report scaled cell width
Mov ES:W_4[DI],AX ;report scaled cell height
Ret
;
;The following routine sets the character up vector
;based on the angle of rotation passed in INTIN(1) in 1/10 of degrees
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
; INTIN(1) = Theta in 1/10 degrees
;EXIT:
; INTOUT(1) = Theta selected
F_SET_CHARACTER_UP_VECTOR:
Les DI,INTIN[BP] ;ES:DI -> integer input array
Mov AX,ES:[DI] ;get the requested direction
Add AX,225 ;bias by 1/2 octent
Xor DX,DX ;clear DH
Mov BX,450 ;pick up 45 degrees
Div BX ;chug chug chug
Add AX,2 ;bias into nec land
And AX,07H ;mask into reality
Mov TEXT_NEC_DIRECTION,AL ;save the computed nec direction code
Shl AX,1 ;make it a word pointer
Add AX,offset ROTATION_MAP_TABLE
Mov SI,AX
Lodsw ;get the direction in 1/10 degrees
Les DI,INTOUT[BP] ;ES:DI -> integer output array
Mov ES:[DI],AX ;drop in the result
Ret
;
;The following routine set the color map value for the index requested in INTIN(1)
;based on the values requested in INTIN(2) - INTIN(4)
;ENTRY:
; SS:BP -> stacked arguments
; ES:DI -> CONTRL(1)
;EXIT:
;
F_SET_COLOR_REPRESENTATION:
Les DI,INTIN[BP] ;get the long pointer
Mov BX,ES:[DI] ;get the color index
MOV AX,NUMBER_COLORS
DEC AX
CMP AX,1
JE F_S_C_R_DONE ;JUMP IF MONOCHROME
Cmp BX,AX ;is it too big ?
Ja F_S_C_R_DONE ;yes then do nothing
Mov AX,6 ;get bytes per index for request array
Mul BL ;scale the index
Mov SI,AX ;put it in SI
Add SI,offset COLOR_REQUEST_ARRAY
Mov DX,BIT_RED ;DH will accumulate DL is first mask
Mov CX,3 ;how many colors
F_S_C_R_LOOP:
Inc DI
Inc DI ;point at the next value
Mov AX,ES:[DI] ;get it
Mov [SI],AX ;drop it into the request array
Inc SI ;and bump the pointer
Inc SI
Cmp AX,500 ;is it over 50%
Jb F_S_C_R_NEXT ;no then leap
Or DH,DL ;else set the bit
F_S_C_R_NEXT:
Shl DL,1 ;move the bit
Loop F_S_C_R_LOOP
Mov COLOR_MAP_TABLE[BX],DH ;move the color into the map
F_S_C_R_DONE:
Ret
;
;The following routine sets the poly line type
;ENTRY:
; SS:BP -> stacked long word pointers
F_SET_POLYLINE_TYPE:
Les DI,INTIN[BP] ;point at the input array
Mov AX,ES:W_1[DI] ;get the requested line style
Cmp AX,7 ;OK ?
Jbe SET_POLYLINE_TYPE
Mov AX,7
SET_POLYLINE_TYPE:
Les DI,INTOUT[BP] ;point at the output array
Mov POLYLINE_TYPE,AX ;save the selected line type
Mov ES:[DI],AX ;and return it
Ret
;
;The following routine sets the polyline width
;ENTRY:
; SS:BP -> stacked long word pointers
F_SET_POLYLINE_WIDTH:
Mov ES:W_3[DI],1 ;say one end point
Les DI,PTSOUT[BP] ;point at the output array
Mov ES:W_1[DI],1 ;we support only one size
Mov ES:W_2[DI],0 ;clear the Y value
Ret
;
;The following routine sets the poly line color index
;ENTRY:
; SS:SP -> stacked long word pointers
F_SET_POLYLINE_COLOR_INDEX:
Les DI,INTIN[BP] ;ES:DI -> integer input array
Mov AX,ES:[DI] ;get the requested color index
CALL CHECK_COLOR_INDEX
Les DI,INTOUT[BP] ;ES:DI -> integer output array
Mov POLYLINE_COLOR,AX ;save the index
Mov ES:[DI],AX ;drop it into the output array
Ret
;
;The following routine sets the poly marker type
;ENTRY:
; SS:SP -> stacked long word pointers
F_SET_POLYMARKER_TYPE:
Les DI,INTIN[BP] ;ES:DI -> integer input array
Mov AX,ES:[DI] ;get the requested marker
CMP AX,0
JE SET_MARKER_TYPE_1 ;OUT OF RANGE
Cmp AX,5 ;max marker
Jbe SET_MARKER_TYPE
SET_MARKER_TYPE_1:
Mov AX,3
SET_MARKER_TYPE:
Les DI,INTOUT[BP] ;point at the output array
Mov POLYMARKER_TYPE,AX ;save the selected type
Mov ES:[DI],AX ;and return the selected value
Ret
;
;The following routine sets the poly marker scale
;ENTRY:
; SS:SP -> stacked long word pointers
F_SET_POLYMARKER_SCALE:
Mov ES:W_3[DI],1 ;set up contrl(3)
Les DI,PTSIN[BP] ;ES:DI -> PTSIN(1)
Mov AX,ES:W_2[DI] ;get the requested marker height
Inc AX ;make it one relative
Mov BL,7 ;height of marker in pixels
Div BL ;compute nearest size
Xor AH,AH ;zero the remainder
Cmp AX,0 ;too small ?
Jz SET_MARKER_HEIGHT ;yes
Dec AX ;make 0 relative
Mov BX,AX ;get size into BX
Mov AX,15 ;get the max size
Cmp BX,AX ;too big
Ja SET_MARKER_HEIGHT
Mov AX,BX ;else get the size
SET_MARKER_HEIGHT:
Mov POLYMARKER_NEC_SIZE,AL ;and save it
Inc AX ;make it one relative to scale
Mov BX,AX ;put in BX to multiply
Mov AX,7 ;heigth of character in pixels
Mul BL ;scale
Les DI,PTSOUT[BP] ;get the output array pointer
Mov ES:W_1[DI],0 ;clear it
Mov ES:W_2[DI],AX ;report the scaled marker heigth
Ret
;
;The following routine sets the polymarker color index
;ENTRY:
; SS:BP -> stacked long word pointers
F_SET_POLYMARKER_COLOR_INDEX:
Les DI,INTIN[BP] ;ES:DI -> integer input array
Mov AX,ES:[DI] ;get the requested color index
CALL CHECK_COLOR_INDEX
Les DI,INTOUT[BP] ;ES:DI -> integer output array
Mov POLYMARKER_COLOR,AX ;save the index
Mov ES:[DI],AX ;drop it into the output array
Ret
;
;The followung routine sets the text font selected
;based on the font passed in INTIN(1)
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
; INTIN(1) = requested font
;EXIT:
; INTOUT(1) = selected font number
F_SET_TEXT_FONT:
Les DI,INTIN[BP] ;ES:DI -> integer input array
Mov AX,ES:[DI] ;get the requested font
Les DI,INTOUT[BP] ;point at the output array
Cmp AX,2 ;2 ?
Jz SELECT_TEXT_FONT ;yes then leap
Mov AX,1
SELECT_TEXT_FONT:
Mov TEXT_FONT,AX ;save the selected font
Mov ES:[DI],AX ;and return it
Ret
;
;The following routine sets the text color
;based on the color passed in INTIN(1)
;ENTRY:
; SS:BP -> stacked long word pointers
; ES:DI -> CONTRL(1)
; INTIN(1) = requested color
;EXIT:
; INTOUT(1) = selected color
F_SET_TEXT_COLOR_INDEX:
Les DI,INTIN[BP] ;ES:DI -> integer input array
Mov AX,ES:[DI] ;get the requested color index
CALL CHECK_COLOR_INDEX
Les DI,INTOUT[BP] ;ES:DI -> integer output array
Mov TEXT_COLOR,AX ;save the index
Mov ES:[DI],AX ;drop it into the output array
Ret
;
;The following routine sets the fill interior variable
;ENTRY:
; SS:SP -> stacked long word pointers
; ES:DI -> CONTROL(1)
;EXIT:
; INTOUT(1) set to interior selected
F_SET_FILL_INTERIOR_STYLE:
Les DI,INTIN[BP] ;ES:DI -> integer input
Mov AX,ES:[DI] ;get requested interior
Cmp AX,3 ;OK
Jbe SET_FILL_INTERIOR
Mov AX,0 ;force hollow
SET_FILL_INTERIOR:
Mov FILL_INTERIOR,AX ;save it
Les DI,INTOUT[BP] ;ES:DI -> integer output
Mov ES:[DI],AX
Ret
;
;The following routine sets the fill style variable
;ENTRY:
; SS:SP -> stacked long pointers
;EXIT:
; INTOUT(1) set to style selected
F_SET_FILL_STYLE_INDEX:
Les DI,INTIN[BP] ;ES:DI -> integer input
Mov AX,ES:[DI] ;get the requested style
CMP AX,0
JE SET_FILL_STYLE_IND1 ;OUT OF RANGE
Cmp AX,8 ;OK ?
Jbe SET_FILL_STYLE_INDEX
SET_FILL_STYLE_IND1:
Mov AX,1 ;force solid style
SET_FILL_STYLE_INDEX:
Mov FILL_STYLE,AX
Les DI,INTOUT[BP]
Mov ES:[DI],AX
Ret
;
;The following routine sets the fill color variable
;ENTRY:
; SS:SP -> stackes long word pointers
;EXIT:
; INTOUT(1) set to color
F_SET_FILL_COLOR_INDEX:
Les DI,INTIN[BP] ;ES:DI -> integer input
Mov AX,ES:[DI] ;get the requested color
CALL CHECK_COLOR_INDEX
Les DI,INTOUT[BP] ;ES:DI -> integer output array
Mov FILL_COLOR,AX ;save the index
Mov ES:[DI],AX ;drop it into the output array
Ret
;
;The following reports the current color representation
;ENTRY:
; SS:BP -> stackes long word pointers
F_INQUIRE_COLOR_REPRESENTATION:
Les DI,INTIN[BP] ;point at the input array
Mov CX,3 ;3 colors R,G,B
Mov AX,ES:W_1[DI] ;get the color index
Mov BX,ES:W_2[DI] ;get the mode
Les DI,INTOUT[BP] ;point at the output array
Stosw ;set the output color index
Xchg AX,BX
Cmp AX,0 ;requested ?
Jz I_C_R_REQUESTED ;yes then leap
Mov DL,COLOR_MAP_TABLE[BX] ;get the current map value
Mov DH,BIT_RED
I_C_R_REALIZED:
Xor AX,AX ;get a 0
Test DL,DH ;bit set ?
Jz I_C_R_REAL ;no then leap
Mov AH,10H
I_C_R_REAL:
Stosw
Shl DH,1 ;move the mask
Loop I_C_R_REALIZED
Ret
I_C_R_REQUESTED:
Mov AL,6
Mul BL
Mov SI,offset COLOR_REQUEST_ARRAY
Add SI,AX ;SI -> requested values
Rep Movsw ;move the words
Ret
;
;
CHECK_COLOR_INDEX:
MOV BX,NUMBER_COLORS ;GET NUMBER OF COLORS
DEC BX
CMP AX,BX
JBE COLOR_INDEX_OK
MOV AX,BX ;SET MAX NUMBER OF COLORS
COLOR_INDEX_OK:
RET
;
;
;
;
;The following routine reports the pixel data at the selected cell array
;ENTRY:
; SS:BP -> stacked long word pointers
F_INQUIRE_CELL_ARRAY:
Ret
;
;The following routine gets input from the locator device
;ENTRY:
; SS:BP -> stacked long word pointers
;
;For sample mode
;EXIT:
; CONTRL(3) CONTRL(5)
;VALID KEY 1 1
;INVALID KEY 0 1
;NO KEY 0 0
;NEVER RETURN 1 0
;
F_INPUT_LOCATOR:
Cmp LOCATOR_MODE,1 ;request mode input
Jnz INPUT_LOCATOR_SAMPLE ;no then leap
Les DI,PTSIN[BP] ;point at starting X,Y
Mov AX,ES:W_1[DI] ;get X
Mov XAD,AX
Mov AX,ES:W_2[DI] ;get Y
Mov YAD,AX
F_INPUT_LOCATOR_REQUEST_LOOP:
Call TOGGLE_INPUT_CURSOR ;make a cursor
Call GET_CHAR_NO_ECHO
Push AX ;save the character
Call TOGGLE_INPUT_CURSOR ;cursor off
Pop AX
Push AX
Call CHECK_LOCATOR_KEY ;move the stuff
Pop AX
Jz F_INPUT_LOCATOR_REQUEST_LOOP ;valid then loop
Mov BX,1 ;return code of success
Mov CX,1 ;on pair of coordinates
F_INPUT_LOCATOR_DONE:
Les DI,INTOUT[BP] ;point at integer out array
Xor AH,AH ;zero the high byte
Mov ES:W_1[DI],AX ;send the terminator back
Les DI,PTSOUT[BP] ;point at points out array
Mov AX,XAD ;get X
Mov ES:W_1[DI],AX ;send X back
Mov AX,YAD ;get Y
Mov ES:W_2[DI],AX ;send Y back
Les DI,CONTRL[BP] ;point at CONTROL array
Mov ES:W_3[DI],CX ;number of pairs 0 or 1
Mov ES:W_5[DI],BX ;mark as successful or not
Ret
;
INPUT_LOCATOR_SAMPLE:
Call CON_STAT ;get status
Mov BX,0 ;un successfull code
Mov CX,0 ;no pairs
Or AX,AX
Jz F_INPUT_LOCATOR_DONE ;no key then leap
Call GET_CHAR ;get the key
Push AX
CAll CHECK_LOCATOR_KEY
Pop AX
Mov BX,1 ;success at getting a key
Mov CX,1 ;valid key
Jz F_INPUT_LOCATOR_DONE ;if valid then leap
Mov CX,0 ;invalid key
Jmps F_INPUT_LOCATOR_DONE ;leave
;
;The following routine checks the key code in AX for a valid key cursor key
;and moves the XAD,YAD with wrap around check
;It returns AX,0 if the key was valid
;
CHECK_LOCATOR_KEY:
Mov SI,0 ;bias for UP
Cmp AL,05H ;up ?
Jz CHECK_GRAPHIC_CURSOR
Mov SI,8
Cmp AL,018H
Jz CHECK_GRAPHIC_CURSOR
Mov SI,16
Cmp AL,04H
Jz CHECK_GRAPHIC_CURSOR
Mov SI,24
Cmp AL,013H
Jz CHECK_GRAPHIC_CURSOR
Cmp AL,017H ;toggle speed ?
Jnz CHECK_GRAPHIC_CURSOR_DONE ;no then return invalid
Xor INCREMENT_BIAS,100B ;toggle bias
Jmps CHECK_GRAPHIC_CURSOR_OK ;send back a zero
CHECK_GRAPHIC_CURSOR:
Add SI,INCREMENT_BIAS
Mov AX,CURSOR_INCREMENT_TABLE[SI]
Add XAD,AX
Inc SI
Inc SI
Mov AX,CURSOR_INCREMENT_TABLE[SI]
Add YAD,AX
Mov AX,X_MAX
Cmp XAD,AX
Jle I_L_X_0
Mov XAD,AX
I_L_X_0:
CMP XAD,0
Jge I_L_Y
Mov XAD,0
I_L_Y:
Mov AX,Y_MAX
Cmp YAD,AX
Jle I_L_Y_0
Mov YAD,AX
I_L_Y_0:
Cmp YAD,0
Jge CHECK_GRAPHIC_CURSOR_OK
Mov YAD,0
CHECK_GRAPHIC_CURSOR_OK:
Xor AX,AX
CHECK_GRAPHIC_CURSOR_DONE:
Or AX,AX ;set flags
Ret
;
;The following routine gets input from the valuator device
;ENTRY:
; SS:BP -> stacked long word pointers
F_INPUT_VALUATOR:
Les DI,INTIN[BP] ;point at input data
Mov CX,ES:W_2[DI] ;get the initial value
Cmp VALUATOR_MODE,1 ;request mode
Jnz INPUT_VALUATOR_SAMPLE ;no then leap
INPUT_VALUATOR_REQUEST_LOOP:
Push CX
Call GET_CHAR_NO_ECHO ;get a character
Pop CX
Call CHECK_VALUATOR_KEY ;see it ok
Jz INPUT_VALUATOR_REQUEST_LOOP ;yes then loop
Mov BX,1 ;always OK
INPUT_VALUATOR_DONE:
Les DI,INTOUT[BP] ;point at the output array
Mov ES:W_1[DI],CX ;save the current value
Les DI,CONTRL[BP]
Mov ES:W_5[DI],BX ;set or clear success flag
Ret
;
INPUT_VALUATOR_SAMPLE:
Push CX
Call CON_STAT ;any one home ?
Pop CX
Mov BX,0 ;un successful
Or AL,AL
Jz INPUT_VALUATOR_DONE ;no then leap
Push CX
Call GET_CHAR
Pop CX
Call CHECK_VALUATOR_KEY
Mov BX,1
Jz INPUT_VALUATOR_DONE
Mov BX,0 ;no successful
Jmps INPUT_VALUATOR_DONE
;
CHECK_VALUATOR_KEY:
Cmp AL,'+'
Jnz C_V_K_1
Inc CX ;bump count
Jmps C_V_K_OK
C_V_K_1:
Cmp AL,'-'
Jnz C_V_K_DONE
Dec CX
Xor AX,AX
C_V_K_DONE:
Or AX,AX
C_V_K_OK:
Ret
;
;The following routine gets input from the choice device
;ENTRY:
; SS:BP -> stacked long word pointers
;
F_INPUT_CHOICE:
MOV CL,1
MOV AL,0FFH
CALL CPM_SPEZIAL_OUT ;SET CONFIG FLAG
Mov ES:W_5[DI],0 ;mark as unsuccessful
Cmp CHOICE_MODE,1 ;request mode ?
Jz INPUT_CHOICE_REQUEST ;yes then leap
INPUT_CHOICE_SAMPLE:
Call CON_STAT ;any body home ?
Jz INPUT_CHOICE_DONE ;no key then leap
Call GET_CHAR ;get the character
Mov BX,1 ;say we got a chatacter
Mov CX,AX
SUB CX,0DFH
Cmp AX,0E0H
Jb I_C_S_BAD ;if invalid then leap
Cmp AX,0F3H
Jbe INPUT_CHOICE_SAVE ;if valid then leap
I_C_S_BAD:
Mov CX,0
INPUT_CHOICE_SAVE:
Les DI,CONTRL[BP] ;point at the contrl array
Mov ES:W_5[DI],BX ;report success or failure
Les DI,INTOUT[BP]
Mov ES:W_1[DI],CX ;return the code 1 relative
INPUT_CHOICE_DONE:
MOV CL,1
MOV AL,0
CALL CPM_SPEZIAL_OUT ;RESET CONFIG FLAG
Ret
INPUT_CHOICE_REQUEST:
Call GET_CHAR_NO_ECHO
Mov BX,1
Mov CX,AX
SUB CX,0DFH
Cmp AX,0E0H ;valid ?
Jb I_C_R_BAD ;no then leap
Cmp AX,0F3H
Jbe INPUT_CHOICE_SAVE ;valid then leap
I_C_R_BAD:
Mov CX,0
Mov BX,0
Jmps INPUT_CHOICE_SAVE
;
;The following routing gets input from the string device
;ENTRY:
; SS:BP -> stacked long word pointers
F_INPUT_STRING:
Les DI,INTIN[BP] ;point to integer in array
Mov CX,ES:W_2[DI] ;get max length
Mov AX,ES:W_3[DI] ;get echo mode
Les DI,INTOUT[BP] ;point at the output string
Xor BX,BX ;clear the character count
Or AX,AX ;set flags
Jz INPUT_STRING_NO_ECHO
INPUT_STRING_ECHO:
Cmp STRING_MODE,1 ;request ?
Jz I_S_E ;yes then leap
Call CON_STAT ;any characters
Or AL,AL
Jz INPUT_STRING_DONE ;no the leap
I_S_E:
Call GET_CHAR_ECHO
Cmp AL,0DH ;done ?
Jz INPUT_STRING_DONE
Xor AH,AH
Stosw ;save char as an integer
Inc BX
Loop INPUT_STRING_ECHO
Jmps INPUT_STRING_DONE
;
INPUT_STRING_NO_ECHO:
Cmp STRING_MODE,1 ;request ?
Jz I_S_N_E ;yes then leap
Call CON_STAT ;any characters
Or AL,AL
Jz INPUT_STRING_DONE ;no then leap
I_S_N_E:
Call GET_CHAR_NO_ECHO
Cmp AL,0DH ;done ?
Jz INPUT_STRING_DONE
Xor AH,AH
Stosw ;save char as an integer
Inc BX
Loop INPUT_STRING_NO_ECHO
INPUT_STRING_DONE:
Les DI,CONTRL[BP]
Mov ES:W_5[DI],BX ;save the length
Ret
;
;The following routine sets the writing mode
;ENTRY:
; SS:BP -> stacked long word pointers
F_SET_WRITING_MODE:
Les DI,INTIN[BP] ;point at the input parameter
Mov BX,ES:[DI] ;get the requested writing mode
Mov AX,1 ;get the default mode
Cmp BX,0
Jz SET_WRITING_MODE ;if to low then set the mode
Cmp BX,4
Ja SET_WRITING_MODE ;if to high then set the mode
Mov AX,BX ;else get the selected mode
SET_WRITING_MODE:
Les DI,INTOUT[BP] ;point at the output array
Mov ES:[DI],AX ;and return the selected mode
Mov BX,AX
Mov AL,MODE_MAP_TABLE[BX] ;get the magic byte
Mov NEC_MODE,AL ;save it for later
Ret
;
;The following routine sets the input mode
;ENTRY:
; SS:BP -> stacked long word pointers
F_SET_INPUT_MODE:
Les DI,INTIN[BP]
Mov BX,ES:W_1[DI] ;get device pointer
Mov AX,ES:W_2[DI] ;get the mode
Cmp AX,2 ;sample ?
Jz SET_INPUT_MODE ;yes then leap
Mov AX,1 ;else force request
SET_INPUT_MODE:
Mov SI,offset INPUT_MODE ;point at the table
Cmp BX,4 ;device out of range
Jbe SAVE_INPUT_MODE ;no then leap
Mov BX,0 ;point to dummy
SAVE_INPUT_MODE:
Add SI,BX ;point SI
Mov [SI],AL ;save the selected mode
Les DI,INTOUT[BP] ;point at integer output array
Mov ES:W_3[DI],AX ;send back the mode
Ret
;
;The following routine writes an item to the meta file
;ENTRY:
; SS:BP -> stacked long word pointers
F_WRITE_ITEM_TO_METAFILE:
Ret
;
;The following routine draws a vector in the selected color with the arguments
;placed at VECDAT
;
CVECTE: Mov GRCOLR,GPLANE
Mov AL,NEC_MODE
Test NEC_COLOR,BIT_GREEN ;any green ?
Jnz DO_GRN_VEC ;yes then do it
Cmp AL,MODE_REP ;replace mode ?
Jnz TRY_BLU_VEC ;no then leap
Mov AL,MODE_RES ;else get clear mode
DO_GRN_VEC:
Call DO_VECTOR_WRITE
TRY_BLU_VEC:
MOV AX,NUMBER_COLORS
CMP AX,2
JE VECTOR_WRITE_DONE ;JUMP IF MONOCHROME
MOV GRCOLR,BPLANE
Mov AL,NEC_MODE
Test NEC_COLOR,BIT_BLUE
Jnz DO_BLU_VEC
Cmp AL,MODE_REP
Jnz TRY_RED_VEC
Mov AL,MODE_RES
DO_BLU_VEC:
Call DO_VECTOR_WRITE
TRY_RED_VEC:
MOV GRCOLR,RPLANE
Mov AL,NEC_MODE
Test NEC_COLOR,BIT_RED
Jnz DO_VECTOR_WRITE
Cmp AL,MODE_REP
Jnz VECTOR_WRITE_DONE
Mov AL,MODE_RES
DO_VECTOR_WRITE:
Cmp AL,MODE_REP
Jnz DVW_SAVE_MODE
Mov AL,MODE_SET
DVW_SAVE_MODE:
Mov GRATTRIB,AL ;stash the writing mode
Mov CX,0 ;command only
Call GRWRITE ;set the writing mode
Call GRCSRO ;set us in the right page
Mov CX,11 ;# of fig parms
Call GRVECTW ;load 'em up
Call GRVECTE ;draw it
VECTOR_WRITE_DONE:
Ret
;
F_RETURN:
Ret
;
CON_STAT:
Push ES
Push DI
Push SI
Push DX
Push CX
Push BX
Mov CL,6
Mov DX,0FEH
Int BDOS
Pop BX
Pop CX
Pop DX
Pop SI
Pop DI
Pop ES
Ret
fbdos:
Push ES
Push DI
Push SI
Push DX
Push CX
Push BX
Int BDOS
Pop BX
Pop CX
Pop DX
Pop SI
Pop DI
Pop ES
Ret
;
;The following routine gets a character using function 6 DIO
GET_CHAR_NO_ECHO:
Call CON_STAT
Or AL,AL ;set flag
Jz GET_CHAR_NO_ECHO
GET_CHAR:
Push ES
Push DI
Push SI
Push DX
Push CX
Push BX
Mov CL,6 ;BDOS direct I/O
Mov DX,0FFH ;input character
Int BDOS ;ring CP/M-86 bell
Pop BX
Pop CX
Pop DX
Pop SI
Pop DI
Pop ES
Ret
;
GET_CHAR_ECHO:
Call GET_CHAR_NO_ECHO
PUSH CX
PUSH AX
PUSH SI
PUSH DX
PUSH BX
MOV CX,1 ;CHARACTER LENGTH
CALL DO_DISPLAY_ONE_CHARACTER
POP BX
POP DX
POP SI
POP AX
POP CX
RET
;
;
;
PUT_CHAR:
Push AX ;save the character
Push ES
Push DI
Push SI
Push DX
Push CX
Push BX
XOR DH,DH
Mov DL,AL
Mov CL,6
Int BDOS
Pop BX
Pop CX
Pop DX
Pop SI
Pop DI
Pop ES
Pop AX ;restore the character
Ret
;
CPM_SPEZIAL_OUT:
Push AX ;save the character
Push ES
Push DI
Push SI
Push DX
Push CX
Push BX
Int SBDOS
Pop BX
Pop CX
Pop DX
Pop SI
Pop DI
Pop ES
Pop AX ;restore the character
Ret
;*********************************************************************
;* GRAPHIC DISPLAY DATA AREA *
;*********************************************************************
;
DSEG
MAX_X EQU 639
MAX_Y EQU 399
;
PUBLIC X_MAX,Y_MAX
;
EXTRN GRTEXTP1:BYTE,GRTEXTP2:BYTE,GRATTRIB:BYTE
EXTRN GRTEXTP_W:WORD
EXTRN GRVECTP1:BYTE,GRVECTDC:WORD,GRVECTD:WORD
EXTRN GRVECTD2:WORD
EXTRN GRVECTD1:WORD,GRVECTDM:WORD
EXTRN GRATTRIB:BYTE
EXTRN XAD:WORD,YAD:WORD
EXTRN GRCOLR:WORD
EXTRN GRWRT:BYTE,GRWRTP:WORD
EXTRN GRMASK_L:BYTE
EXTRN GRMASK_W:WORD
EXTRN GRVECTP2:WORD,GRVECTP4:WORD
EXTRN GRZOOMP:BYTE
extrn text_conversion_table:byte
;
EXTRN CHARACTER_BIT_TABLE:BYTE
;
;
;
FUNCTION_TABLE DW offset F_RETURN ;no function 0
DW offset F_OPEN_WORKSTATION ;function 1
DW offset F_CLOSE_WORKSTATION ;function 2
DW offset F_CLEAR_WORKSTATION ;function 3
DW offset F_UPDATE_WORKSTATION ;function 4
DW offset F_ESCAPE ;function 5
DW offset F_POLYLINE ;function 6
DW offset F_POLYMARKER ;function 7
DW offset F_TEXT ;function 8
DW offset F_FILLED_AREA ;function 9
DW offset F_CELL_ARRAY ;function 10
DW offset F_GENERALIZED_DRAWING_PRIMITIVE ;function 11
DW offset F_SET_CHARACTER_HEIGHT ;function 12
DW offset F_SET_CHARACTER_UP_VECTOR ;function 13
DW offset F_SET_COLOR_REPRESENTATION ;function 14
DW offset F_SET_POLYLINE_TYPE ;function 15
DW offset F_SET_POLYLINE_WIDTH ;function 16
DW offset F_SET_POLYLINE_COLOR_INDEX ;function 17
DW offset F_SET_POLYMARKER_TYPE ;function 18
DW offset F_SET_POLYMARKER_SCALE ;function 19
DW offset F_SET_POLYMARKER_COLOR_INDEX ;function 20
DW offset F_SET_TEXT_FONT ;function 21
DW offset F_SET_TEXT_COLOR_INDEX ;function 22
DW offset F_SET_FILL_INTERIOR_STYLE ;function 23
DW offset F_SET_FILL_STYLE_INDEX ;function 24
DW offset F_SET_FILL_COLOR_INDEX ;function 25
DW offset F_INQUIRE_COLOR_REPRESENTATION ;function 26
DW offset F_INQUIRE_CELL_ARRAY ;function 27
DW offset F_INPUT_LOCATOR ;function 28
DW offset F_INPUT_VALUATOR ;function 29
DW offset F_INPUT_CHOICE ;function 30
DW offset F_INPUT_STRING ;function 31
DW offset F_SET_WRITING_MODE ;function 32
DW offset F_SET_INPUT_MODE ;function 33
DW offset F_WRITE_ITEM_TO_METAFILE ;function 34
MAX_FUNCTION EQU 34 ;last valid function code
;
LAST_ESCAPE_CODE EQU 19 ;0 relative code number
ESCAPE_TABLE DW offset F_ESCAPE_0
DW offset F_ESCAPE_1
DW offset F_ESCAPE_2
DW offset F_ESCAPE_3
DW offset F_ESCAPE_4
DW offset F_ESCAPE_5
DW offset F_ESCAPE_6
DW offset F_ESCAPE_7
DW offset F_ESCAPE_8
DW offset F_ESCAPE_9
DW offset F_ESCAPE_10
DW offset F_ESCAPE_11
DW offset F_ESCAPE_12
DW offset F_ESCAPE_13
DW offset F_ESCAPE_14
DW offset F_ESCAPE_15
DW offset F_ESCAPE_16
DW offset F_ESCAPE_17
DW offset F_ESCAPE_18
DW offset F_ESCAPE_19
DW offset F_ESCAPE-51
DW offset F_ESCAPE_52
DW offset F_ESCAPE_53
DW offset F_ESCAPE_54
;
LAST_GDP EQU 7 ;0 relative number of last
GDP_TABLE DW offset F_RETURN ;no GDP 0
DW offset F_GDP_BAR
DW offset F_GDP_ARC
DW offset F_GDP_PIESLICE
DW offset F_GDP_CIRCLE
DW offset F_GDP_PGC
DW offset F_RETURN
DW offset F_RETURN
;
ID_STRING DW length ID_TEXT
ID_TEXT DW '0','.','2',' ','N','C','R',' ','D','M','V',' ','4','/','1','8','/','8','3'
;
ERASE_END_SCREEN DW 2,01BH,059H
ANSI_REVERSE_ON DW 3,01BH,'G','4'
ANSI_REVERSE_OFF DW 3,01BH,'G','0'
ANSI_HALF_INT_ON DW 2,01BH,029H
ANSI_HALF_INT_OFF DW 2,01BH,028H
ANSI_BLINKING_ON DW 3,01BH,'G','2'
ANSI_STANDARD_VIDEO DW 3,01BH,'G','0'
ADM3A_CURSOR_POSITION DW 4,01BH,'='
ADM3A_ROW DW 0
ADM3A_COL DW 0
;
;The following 10 word variables should not be disturbed
;because a Rep MOVSW is used to initilize them during F_OPEN_WORKSTATION
WORKSTATION_ID DW 0
POLYLINE_TYPE DW 0
POLYLINE_COLOR DW 0
POLYMARKER_TYPE DW 0
POLYMARKER_COLOR DW 0
TEXT_FONT DW 0
TEXT_COLOR DW 0
FILL_INTERIOR DW 0
FILL_STYLE DW 0
FILL_COLOR DW 0
;
;
DIRTBL DB 6,5,1,2,7,4,0,3
NXTX DW 0
NXTY DW 0
XSGN DB 0
YSGN DB 0
;
CURRENT_CHARACTER DB 0
POLYMARKER_NEC_SIZE DB 0
;
TEXT_NEC_DIRECTION DB 2
TEXT_NEC_SIZE DB 0 ;0 - 15
;
NEC_DIRECTION DB 2 ;0-7 NEC 7220 driection
NEC_MODE DB 0 ;
NEC_COLOR DB 0 ;RBG from look up table
;
CA_REP_COUNT_Y DW 0
CA_ELEMENT_COUNT DW 0
CA_ROW_LENGTH DW 0
CA_XAD DW 0
;
LAST_CURSOR_X DW 0
LAST_CURSOR_Y DW 0
;
CURROW DB 1 ;CURRENT ROW
CURCOL DB 1 ; COLUMN
;
CURSOR_X DW 0 ;for locator input
CURSOR_Y DW 0
;
INCREMENT_BIAS DW 0
;
CURSOR_INCREMENT_TABLE DW 0
DW 1
DW 0
DW 10
DW 0
DW -1
DW 0
DW -10
DW 1
DW 0
DW 10
DW 0
DW -1
DW 0
DW -10
DW 0
;
INPUT_MODE DB 0 ;no device 0 dummy entry
LOCATOR_MODE DB 0
VALUATOR_MODE DB 0
CHOICE_MODE DB 0
STRING_MODE DB 0
;
NEC_NORMAL_CHAR EQU 010H ;for normal graphics character
NEC_SLANT_CHAR EQU 090H ;for italics
;
GPLANE EQU 0 ;high address for plane
RPLANE EQU 4000H
BPLANE EQU 8000H
;
BIT_RED EQU 0001B
BIT_GREEN EQU 0010B
BIT_BLUE EQU 0100B
;
MODE_REP EQU 020H ;replace all bits with the pattern
MODE_COM EQU 021H ;xor all bits with pattern
MODE_RES EQU 022H ;reset 1 bits to 0
MODE_SET EQU 023H ;set 1 bits to 1
;
;
POLYLINE_TABLE DW 1111111111111111B ;NO STYLE 0
DW 1111111111111111B ;SOLID
DW 0000000011111111B ;STYLE 2 DASHED
DW 1000100010001000B ;STYLE 3 DOTTED
DW 0001100011111111B ;STYLE 4 DASHDOT
DW 0010010011111111B
DW 1100110011001100B
DW 1010101010101010B
DW 1100000011000000B
;
;
DEFAULT_COLOR_DATA DW 0,0,0 ;black R,G,B
DW 1000,0,0 ;red
DW 0,1000,0 ;green
DW 0,0,1000 ;blue
DW 0,1000,1000 ;cyan
DW 1000,1000,0 ;yellow
DW 1000,0,1000 ;magenta
DW 1000,1000,1000 ;white
;
DB 0 ;black
DB BIT_RED ;red
DB BIT_GREEN ;green
DB BIT_BLUE ;blue
DB BIT_GREEN+BIT_BLUE ;cyan
DB BIT_GREEN+BIT_RED ;yellow
DB BIT_BLUE+BIT_RED ;magenta
DB BIT_BLUE+BIT_RED+BIT_GREEN ;white
;
DEFAULT_MONO_DATA DW 0,0,0 ;black R,G,B
DW 1000,0,0 ;red
DW 0,1000,0 ;green
DW 0,0,1000 ;blue
DW 0,1000,1000 ;cyan
DW 1000,1000,0 ;yellow
DW 1000,0,1000 ;magenta
DW 1000,1000,1000 ;white
;
DB 0
DB 0FFH
DB 0FFH
DB 0FFH
DB 0FFH
DB 0FFH
DB 0FFH
DB 0FFH
;
COLOR_REQUEST_ARRAY DW 0,0,0 ;black R,G,B
DW 1000,0,0 ;red
DW 0,1000,0 ;green
DW 0,0,1000 ;blue
DW 0,1000,1000 ;cyan
DW 1000,1000,0 ;yellow
DW 1000,0,1000 ;magenta
DW 1000,1000,1000 ;white
;
COLOR_MAP_TABLE DB 0 ;black
DB BIT_RED ;red
DB BIT_GREEN ;green
DB BIT_BLUE ;blue
DB BIT_GREEN+BIT_BLUE ;cyan
DB BIT_GREEN+BIT_RED ;yellow
DB BIT_BLUE+BIT_RED ;magenta
DB BIT_BLUE+BIT_RED+BIT_GREEN ;white
;
MODE_MAP_TABLE DB MODE_REP ;replace (no mode 0)
DB MODE_REP ;replace
DB MODE_SET ;overstrike (set)
DB MODE_COM ;complement (xor)
DB MODE_RES ;erase (reset)
;
ROTATION_MAP_TABLE DW 2700 ;nec 0
DW 3150 ;nec 1
DW 0 ;nec 2
DW 450 ;nec 3
DW 900 ;nec 4
DW 1350 ;nec 5
DW 1800 ;nec 6
DW 2250 ;nec 7
;
;The following table of words are base scale values for the 8 different
;possible drawing directions of graphic text. They are ordered X,Y
;
INCREMENT_TABLE DW 0,-8 ;0
DW 8,-8 ;1
DW 8,0 ;2
DW 8,8 ;3
DW 0,8 ;4
DW -8,8 ;5
DW -8,0 ;6
DW -8,-8 ;7
;
BASELINE_TABLE DW -1,0 ;0
DW -1,-1 ;1
DW 0,-1 ;2
DW 1,-1 ;3
DW 1,0 ;4
DW 1,1 ;5
DW 0,1 ;6
DW -1,1 ;7
;
FILL_MASK_BASE DW 0
;
ix rw 1
jx rw 1
maxy rw 1
miny rw 1
count rw 1
jint rw 1
i rw 1
j rw 1
num rw 1
numsav rw 1
f1 rw 1
scratch rw 100 ;max intersections
;
;OPEN_WORKSTATION_INTOUT
X_MAX DW MAX_X ;max width 0 relative
Y_MAX DW MAX_Y ;max height 0 relative
DW 1 ;not precisely scaled
DW 320 ;width of pixel in micrometers
DW 320 ;height of pixel in micrometers
DW 16 ;number of character heights
DW 8 ;number of line types
DW 1 ;number of line widths
DW 5 ;number of marker types
DW 16 ;number of marker sizes
DW 2 ;number of fonts
DW 8 ;number of patterns
DW 8 ;number of hatch styles
NUMBER_COLORS DW 0 ;number of predefined colors
DW 2 ;number of GDP's
DW 1 ;GDP 1
DW 4 ;GDP 2
DW -1 ;GDP 3
DW -1 ;GDP 4
DW -1 ;GDP 5
DW -1 ;GDP 6
DW -1 ;GDP 7
DW -1 ;GDP 8
DW -1 ;GDP 9
DW -1 ;GDP 10
DW 3 ;GDP attributes 1
DW 3 ;GDP attributes 2
DW -1 ;GDP attributes 3
DW -1 ;GDP attributes 4
DW -1 ;GDP attributes 5
DW -1 ;GDP attributes 6
DW -1 ;GDP attributes 7
DW -1 ;GDP attributes 8
DW -1 ;GDP attributes 9
DW -1 ;GDP attributes 10
COLOR_CAP_FLAG DW 0 ;color capability
DW 1 ;text rotation
DW 1 ;fill capability
DW 0 ;pixel operation
PALLETTE_COLORS DW 2 ;number of colors in pallette
DW 1 ;number of locator devices
DW 1 ;number of valuator devices
DW 1 ;number of choice devices
DW 1 ;number of string devices
DW 2 ;type input/output
;
OPEN_WORKSTATION_PTSOUT DW 0
DW 7 ;min character height
DW 0
DW 112 ;max character height
DW 1 ;min line width
DW 0
DW 1 ;max line width
DW 0
DW 0
DW 7 ;min marker height
DW 0
DW 112 ;max marker height
;
text_buffer rs 80 ;text buffer for language
; translation Eject
fcb_trans db 0
db 'TRANSLAT'
db 'DAT'
db 0
db 0
db 0
db 0
rs 16
db 0
db 0,0,0
;
;
Sseg ; Driver stack
DriverStack Rs 512 ; Adjust before shipping
DriverStackTop Rs 0
End