home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
grafik
/
hgdemo
/
hgdemo.asm
next >
Wrap
Assembly Source File
|
1993-07-12
|
26KB
|
1,420 lines
PAGE 60,132
TITLE HGDEMO GRAPHICS PACKAGE FOR HERCULES CARD
DOSSEG
.MODEL SMALL
;***********************************************************************
; HGDEMO Title: HERCULES GRAPHICS PACKAGE DEMO *
; *
; Programmer: Scott A. Armitage (c) 1993 *
; *
; Purpose: Illustrate the use of HIGH resolution graphics *
; routines for HGA display. *
; *
; *
; Special Requirements: Must use a HERCULES CARD *
;***********************************************************************
GLOBAL SCRN_ADR:WORD, PLOT_SUB:WORD
; some equates....
; HGA port address used by _gmode, _tmode & setmd procs.
index equ 03b4h
cntrl equ 03b8h
; control codes
scrn_on equ 8
grph equ 2
text equ 20h
SX_MIN EQU 0 ; MIN/MAX X/Y VALUES FOR HGA HIGH RES...
SX_MAX EQU 719
SY_MIN EQU 0
SY_MAX EQU 347
HGA_ADR EQU 0B000H ; HGA SCREEN ADR
FNT_LEN EQU 8 ; SIZE OF CHARS IN TABLE - FOR DSPLY_MGS PROC...
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX ; GET ADDRESSABILITY TO OUR DATA SEGMENT
CALL SET_MODE ; SET TO GRAPHICS HIGH RESOLUTION MODE
MOV DX,3
MOV BX,9
MOV CX,4
MOV AX,7
CALL G_FR_2
LEA SI,HR_MESS
CALL DSPLY_MSG
LEA SI,SA_MESS
CALL DSPLY_MSG
CALL WOW_WHEE ; display "wow" in 7 sizes.... font scaleing demo
; START OF MAIN LOOP, DRAW SCREENS UNTIL KEYHIT.....
LLLS:
CALL CLR_FR ; CLEAR SCREEN AND FRAME IT....
CALL STEP_ADJ ; ADJUST SOME COORDINATE VALUES....
CALL CHK_KBD ; CHECK KEYBOARD...
JNZ MX_T0
LEA SI,FRAME_DAT ; SET UP FOR CALL TO SWEEP BOX...
MOV X1,359
MOV Y1,170
MOV X2,83
MOV Y2,23
CALL SWEEP_BOX ; DRAW BOX FULL OF SWEEPING LINES...
CALL STEP_ADJ ; ADJUST SOME COORDINATES AGAIN...
CALL DELAY ; WAIT A BIT AND DO MORE OF THE SAME....
CALL CHK_KBD
JNZ MX_T0
LEA SI,FRAME_DAT
MOV X1,359
MOV Y1,170
MOV X2,283
MOV Y2,123
CALL SWEEP_BOX
CALL DELAY
CALL STEP_ADJ
CALL CHK_KBD
MX_T0:
JNZ MX_TARG_0
CALL STEP_ADJ
LEA SI,CIRCLE_DATA ;SET UP FOR DRAWING 3 CIRCLES...
MOV WORD PTR [SI+4],140
MOV WORD PTR [SI+8],1100
REPEAT:
CALL CHK_KBD
JNZ MX_TARG
SUB WORD PTR [SI],150
CALL CIRCLE
ADD WORD PTR [SI],150
CALL CIRCLE
ADD WORD PTR [SI],150
CALL CIRCLE
SUB WORD PTR [SI],150
SUB WORD PTR [SI+4],AX
JG REPEAT
CALL DELAY
CALL CHK_KBD
MX_TARG_0:
JNZ MX_TARG
CALL CLR_FR ; CLEAR WHOLE SCREEN
CALL STEP_ADJ
LEA SI,FRAME_DAT
MOV X1,359
MOV Y1,170
MOV X2,122
MOV Y2,84
CALL SWEEP_BOX
CALL DELAY
CALL STEP_ADJ
LEA SI,CIRCLE_DATA ; DRAW SOME MORE CIRCLES....
MOV WORD PTR [SI+4],155
MOV WORD PTR [SI+8],1000
REPEAT1:
CALL CHK_KBD
MX_TARG:
JNZ MX_TARGIT
SUB WORD PTR [SI],150
CALL CIRCLE
ADD WORD PTR [SI],150
CALL CIRCLE
ADD WORD PTR [SI],150
CALL CIRCLE
SUB WORD PTR [SI],150
SUB WORD PTR [SI+4],AX
JG REPEAT1
CALL DELAY
CALL CLR_FR ; CLEAR WHOLE SCREEN
CALL STEP_ADJ
LEA SI,CIRCLE_DATA
MOV WORD PTR [SI+4],115
MOV WORD PTR [SI+8],600
REPEAT2:
CALL CHK_KBD
JNZ MX_TARGIT
SUB WORD PTR [SI],175
CALL CIRCLE
ADD WORD PTR [SI],175
CALL CIRCLE
ADD WORD PTR [SI],175
CALL CIRCLE
SUB WORD PTR [SI],175
SUB WORD PTR [SI+4],AX
JG REPEAT2
CALL STEP_ADJ
CALL CHK_KBD
MX_TARGIT:
JNZ M_EXIT
CALL SWEEP_FRAME
CALL STEP_ADJ
LEA SI,CIRCLE_DATA
MOV WORD PTR [SI+4],115
MOV WORD PTR [SI+8],1200
REPEAT3:
CALL CHK_KBD
JNZ M_EXIT
SUB WORD PTR [SI],175
CALL CIRCLE
ADD WORD PTR [SI],175
CALL CIRCLE
ADD WORD PTR [SI],175
CALL CIRCLE
SUB WORD PTR [SI],175
SUB WORD PTR [SI+4],AX
JG REPEAT3
CALL CHK_KBD
JNZ M_EXIT
CALL DELAY
JMP LLLS ; GO DO THE WHOLE MESS AGAIN UNTIL KEYPRESS...
M_EXIT:
MOV AH,0
INT 16H
CALL RESTORE_MODE ; RESTORE hga text MODE
MOV AX,4C00H ; SET FOR RETURN TO DOS WITH RETURN CODE 0
INT 21H
MAIN ENDP
SUBTTL VARIOUS graphics ROUTINES
PAGE +
G_FRAME PROC NEAR ; draws a box... set X1,X2,Y1,Y2 to opposite corner
; coordinates.....
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
LEA SI,LINE1
MOV AX,X1
MOV BX,X2
MOV CX,Y1
MOV DX,Y2
MOV Y2,CX
CALL PLOTLINE
MOV X2,AX
MOV Y2,DX
CALL PLOTLINE
MOV X1,BX
MOV Y1,DX
CALL PLOTLINE
MOV X2,BX
MOV Y1,CX
CALL PLOTLINE
MOV X1,AX
MOV X2,BX
MOV Y1,CX
MOV Y2,DX
POP SI
POP DX
POP CX
POP BX
POP AX
RET
G_FRAME ENDP
G_FR_2 PROC NEAR ; SETS UP LINE1 FOR G_FRAME CALLS
; USES FRAME_PARMS STRUC AND FRAME_DAT DATA
; draws box with NUMREPS lines spaced @
; X_STEP/Y_STEP pixels apart...
FRAME_PARMS STRUC
X_MIN DW ?
X_MAX DW ?
Y_MIN DW ?
Y_MAX DW ?
X_STEP DW ?
Y_STEP DW ?
NUM_REPS DW ?
FRAME_PARMS ENDS
PUSH AX
PUSH BX
PUSH CX
PUSH SI
LEA SI,FRAME_DAT
MOV AX,[SI].X_MIN
MOV X1,AX
MOV AX,[SI].X_MAX
MOV X2,AX
MOV AX,[SI].Y_MIN
MOV Y1,AX
MOV AX,[SI].Y_MAX
MOV Y2,AX
MOV CX,[SI].NUM_REPS
MOV AX,[SI].X_STEP
MOV BX,[SI].Y_STEP
GFR_LOOP:
CALL G_FRAME
ADD X1,AX
SUB X2,AX
ADD Y1,BX
SUB Y2,BX
LOOP GFR_LOOP
POP SI
POP CX
POP BX
POP AX
RET
G_FR_2 ENDP
SWEEP_BOX PROC NEAR ; draws box of sweeping lines.....
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
LEA DI,FRAME_DAT
MOV AX,X1
MOV BX,X2
SUB AX,BX
ADD AX,X1
MOV [DI].X_MAX,AX
MOV [DI].X_MIN,BX
MOV AX,Y1
MOV BX,Y2
SUB AX,BX
ADD AX,Y1
MOV [DI].Y_MAX,AX
MOV [DI].Y_MIN,BX
MOV AX,[DI].X_STEP
MOV BX,[DI].Y_STEP
LEA SI,LINE1
MOV CX,[DI].X_MAX
TOP_SIDE:
CALL PLOTLINE
ADD X2,AX
CMP X2,CX
JBE TOP_SIDE
SUB X2,AX
MOV CX,[DI].Y_MAX
RIGHT_SIDE:
CALL PLOTLINE
ADD Y2,BX
CMP Y2,CX
JBE RIGHT_SIDE
SUB Y2,BX
MOV CX,[DI].X_MIN
BOT_SIDE:
CALL PLOTLINE
SUB X2,AX
CMP X2,CX
JGE BOT_SIDE
ADD X2,AX
MOV CX,[DI].Y_MIN
LEFT_SIDE:
CALL PLOTLINE
SUB Y2,BX
CMP Y2,CX
JGE LEFT_SIDE
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
SWEEP_BOX ENDP
SWEEP_FRAME PROC NEAR ; draws frame where each edge is a swept box....?
PUSH AX
PUSH SI
LEA SI,SWFRAME_DAT
MOV AX,[SI].X_MAX
SUB AX,[SI].X_MIN
SHR AX,1
ADD AX,[SI].X_MIN
MOV X1,AX
MOV AX,[SI].Y_MIN
ADD AX,[SI].Y_STEP
MOV Y1,AX
MOV AX,[SI].X_MIN
MOV X2,AX
MOV AX,[SI].Y_MIN
MOV Y2,AX
CALL SWEEP_BOX
MOV AX,[SI].X_MAX
SUB AX,[SI].X_MIN
SHR AX,1
ADD AX,[SI].X_MIN
MOV X1,AX
MOV AX,[SI].Y_MAX
SUB AX,[SI].Y_STEP
MOV Y1,AX
MOV AX,[SI].X_MIN
MOV X2,AX
MOV AX,[SI].Y_MAX
SUB AX,[SI].Y_STEP
SUB AX,[SI].Y_STEP
MOV Y2,AX
CALL SWEEP_BOX
MOV AX,[SI].Y_MAX
SUB AX,[SI].Y_MIN
SHR AX,1
ADD AX,[SI].Y_MIN
MOV Y1,AX
MOV AX,[SI].X_MIN
ADD AX,[SI].X_STEP
MOV X1,AX
MOV AX,[SI].Y_MIN
ADD AX,[SI].Y_STEP
ADD AX,[SI].Y_STEP
MOV Y2,AX
MOV AX,[SI].X_MIN
MOV X2,AX
CALL SWEEP_BOX
MOV AX,[SI].Y_MAX
SUB AX,[SI].Y_MIN
SHR AX,1
ADD AX,[SI].Y_MIN
MOV Y1,AX
MOV AX,[SI].X_MAX
SUB AX,[SI].X_STEP
MOV X1,AX
MOV AX,[SI].X_MAX
SUB AX,[SI].X_STEP
SUB AX,[SI].X_STEP
MOV X2,AX
MOV AX,[SI].Y_MIN
ADD AX,[SI].Y_STEP
ADD AX,[SI].Y_STEP
MOV Y2,AX
CALL SWEEP_BOX
POP SI
POP AX
RET
SWEEP_FRAME ENDP
; Routines to plot straight lines and circles
; Based on routines by Rollins - "8088 Macro Assembler Programming"
INCLUDE HGD.INC ; INCLUDE ROUTINES FOR PLOTLINE AND CIRCLE HERE
; SOURCE CODE NOT PROVIDED....see doc file.
GET_RLET PROC NEAR ; LOOKUP CHAR IN BL STASH VALS IN LETTER DB 8 DUP ?
; GRABS FONT VALUE FROM ROM TABLE...
PUSH AX
PUSH CX
PUSH SI
PUSH DI
MOV CX,8
MOV AL,BL
CBW
SHL AX,1
SHL AX,1
SHL AX,1
ADD AX,0FA6EH+7
MOV SI,AX
MOV DI,DS ; SAVE DS
MOV AX,0F000H
MOV DS,AX
STD
G_RCH1:
LODSB
PUSH AX
LOOP G_RCH1
MOV DS,DI ; RESTORE DS...
LEA SI,LETTER
MOV CX,8
P_RCH1:
POP AX
MOV [SI],AL
INC SI
LOOP P_RCH1
POP DI
POP SI
POP CX
POP AX
RET
GET_RLET ENDP
SUBTTL C_DISPLAY ROUTINE TO DISPLAY A CHARACTER
PAGE +
C_DISPLAY PROC ; CALLED BY DSPLY_MSG PROCEDURE....
; C_DISPLAY shows a character in small format for HIGH resolution graphics
; uses LETTER_TBL for stroke sequences - assumes color 1 - pixel on...
; each letter uses 4 pixels by 8 pixels x X/Y scale values
; assumes DX = line number
; CX = column number
; BL = character to display
; AH = SIZE OF CHARACTER... WIDTH 8xAH COLS...
; BH = SIZE OF CHARACTER... LENGTH 8xBH ROWS...
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
; set SI to point to character definition array
CALL GET_RLET
LEA SI,LETTER
; set length to display 8 lines of 1 byte
MOV BL,8 ; SET NUMBER OF BYTES TO MOVE
PUSH AX
MOV AL,AH
CBW
MOV BP,AX ; BP NOW HAS S_XSIZE VALUE...
POP AX
DISPLAY_LOOP:
MOV AL,[SI] ; GET NEXT BYTE TO SHOW
PUSH CX
SCALE_LOOP:
; now display the lines that make the character
MOV AH,080H
T_PIX_L:
TEST AL,AH ; ANY PIXEL?
JZ D1 ; NO SO SKIP
CALL CD_PLOT2
D1:
ADD CX,BP
SHR AH,1
JNZ T_PIX_L
ADD DL,BH
ADC DH,00H
POP CX
INC SI ; POINT TO NEXT BYTE TO DISPLAY
DEC BL
JNZ DISPLAY_LOOP ; REPEAT FOR WHOLE LETTER
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
C_DISPLAY ENDP
CD_PLOT2 PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH BP
MOV AX,BP ; HOLD X SCALE VALUE IN AX...
CD_PL:
MOV BP,AX ; RESTORE X SCALE FOR EACH PASS
PUSH CX ; HOLD COL VAL ON STACK...
CD_PLX:
CALL PLOT_SUB ; PLOT A DOT
INC CX ; INC COLUMN
DEC BP ; DO THE LOOP THING WITH BP...
JNZ CD_PLX
POP CX ; RESTORE START COLUMN VALUE...
INC DX ; DX = LINE#, BH = Y SCALE...
DEC BH ; DO IT FOR ALL LINES NEEDED
JNZ CD_PL
POP BP
POP DX
POP CX
POP BX
POP AX
RET
CD_PLOT2 ENDP
SUBTTL DSPLY_MSG ROUTINE TO DISPLAY ANY SIZED LETTER MESSAGE
PAGE +
DSPLY_MSG PROC
; Routine will display a message in ASCIIZ string format
; assumes SI = address of scale_mess structure
SCALE_MESS STRUC
S_ROW DW ? ; ROW COORD
S_COL DW ? ; COLUMN COORD
S_XSIZE DB ? ; X SCALE
S_YSIZE DB ? ; Y SCALE
MESSAGE DW ? ; ACTUALLY A ASCIIZ STRING....
SCALE_MESS ENDS
PUSH AX
PUSH BX
PUSH CX
PUSH SI
MOV AL,00H
MOV AH,[SI].S_XSIZE
C_XSL:
ADD AL,8
DEC AH
JNZ C_XSL
MOV BH,[SI].S_YSIZE
MOV AH,[SI].S_XSIZE
MOV DX,[SI].S_ROW
MOV CX,[SI].S_COL
LEA SI,[SI].MESSAGE
DSPLY_LOOP:
MOV BL,[SI] ; FETCH CHARACTER TO DISPLAY
CMP BL,0 ; ARE WE DONE?
JE DSPLY_DONE ; YES, SO LEAVE
CALL C_DISPLAY ; SHOW ONE CHARACTER
INC SI ; POINT TO NEXT CHARACTER TO DISPLAY
ADD CL,AL ; POINT TO NEXT BYTE ON LINE
ADC CH,00H ; + ANY CARRY...
JMP DSPLY_LOOP ; REPEAT FOR ENTIRE MESSAGE
DSPLY_DONE:
POP SI
POP CX
POP BX
POP AX
RET
DSPLY_MSG ENDP
CLR_FR PROC NEAR
PUSH CX
PUSH SI
CALL CLS ; CLEAR THE SCREEN
CALL G_FR_2 ; DRAW A DOUBLE FRAME
MOV SI,PLOT_ADR
MOV PLOT_SUB,SI
LEA SI,HR_MESS ; POINT AT HI-RES MESSAGE DATA
CALL DSPLY_MSG ; DISPLAY IT....
LEA SI,PX_MESS ; POINT AT PRESS ANY KEY MESSAGE DATA
CALL DSPLY_MSG ; DISPLAY IT
POP CX
POP SI
RET
CLR_FR ENDP
WOW_WHEE PROC NEAR
PUSH CX
MOV CX,3 ; CALL ROUTINE WOW 3 TIMES...
WOW_LOOP:
CALL WOW
LOOP WOW_LOOP
POP CX
RET
WOW_WHEE ENDP
WOW PROC NEAR ; DISPLAY 'WOW' MESSAGE AND SCALE IT UP AND DOWN ON THE FLY
PUSH CX
PUSH SI
MOV SI,XPLOT_ADR ; USE XPLOT FOR EASY WIPE OUT OF PREVIOUS MESSAGE...
MOV PLOT_SUB,SI
LEA SI,TST_MESS
MOV CX,7 ; SHOW 7 INCREASEING SIZES....
WL_1:
CALL DSPLY_MSG
; NO CALL DELAY
CALL DSPLY_MSG
SUB WORD PTR [SI],4 ; ADJUST ROW COORDINATE TO KEEP MESSAGE CENTERED
SUB WORD PTR [SI+2],12 ; " " COLUMN " " " "
INC BYTE PTR [SI+4] ; INCREASE SCALE..
INC BYTE PTR [SI+5]
LOOP WL_1
MOV CX,7 ; SHOW 7 DECREASING SIZES....
WL_2:
LEA SI,TST_MESS
CALL DSPLY_MSG
LEA SI,TST_MESS
CALL DSPLY_MSG
ADD WORD PTR [SI],4
ADD WORD PTR [SI+2],12
DEC BYTE PTR [SI+4]
DEC BYTE PTR [SI+5]
LOOP WL_2
; COORDINATES FOR TST_MESS DATA NOW AT ORIGINAL VALUES....
POP SI
POP CX
RET
WOW ENDP
STEP_ADJ PROC NEAR ; ROUTINE MODIFIES COORDINATES, NUMBER
; OF REPETITIONS AND PLOT ROUTINE USED
; IN AN ATTEMPT TO CREATE MANY VARIATIONS
; OF THE GRAPHICS SCREENS....
PUSH SI
DEC AX
DEC BX
INC CX
INC DX
CMP AX,0
JA SA_1
MOV AX,5
SA_1:
CMP BX,0
JA SA_2
MOV BX,12
SA_2:
CMP DX,17
JB SA_3
MOV DX,2
SA_3:
CMP CX,14
JB SA_X
MOV CX,2
SA_X:
TEST CX,1
JNZ NPDT
CALL PD_TOG
NPDT:
LEA SI,SWFRAME_DAT
MOV [SI].NUM_REPS,DX
MOV [SI].X_MIN,0
MOV [SI].X_MAX,719
MOV [SI].Y_MIN,0
MOV [SI].Y_MAX,347
ADD [SI].X_STEP,CX
ADD [SI].Y_STEP,DX
CMP [SI].X_STEP,100
JB NFXS
MOV [SI].X_STEP,CX
SHL [SI].X_STEP,1
NFXS:
CMP [SI].Y_STEP,100
JB NFYS
MOV [SI].Y_STEP,DX
SHL [SI].Y_STEP,1
NFYS:
LEA SI,FRAME_DAT
MOV [SI].NUM_REPS,CX
MOV [SI].X_MIN,0
MOV [SI].X_MAX,719
MOV [SI].Y_MIN,0
MOV [SI].Y_MAX,347
MOV [SI].X_STEP,BX
MOV [SI].Y_STEP,DX
INC [SI].NUM_REPS
SHL [SI].NUM_REPS,1
POP SI
RET
STEP_ADJ ENDP
CHK_KBD PROC NEAR ; CALL BIOS FOR KEYCHECK.....
PUSH AX
MOV AH,1
INT 16H
POP AX
RET
CHK_KBD ENDP
PD_TOG PROC NEAR ; TOGGLE CURRENT PLOT ROUTINE ADDRESS....
PUSH SI
MOV SI,PLOT_ADR
CMP SI,PLOT_SUB
JNE SET_PLD
MOV SI,XPLOT_ADR
MOV PLOT_SUB,SI
JMP HR_CONT
SET_PLD:
MOV SI,PLOT_ADR
MOV PLOT_SUB,SI
HR_CONT:
POP SI
RET
PD_TOG ENDP
PLOT_HGA PROC NEAR
; assumes DX = line offset number 0 to 347
; CX = column offset from 0 to 719
; routine plots the pixel dot
PUSH AX
PUSH BX
PUSH DI
PUSH ES
; determine mask by table look up
MOV DI,CX
AND DI,7
SHL DI,1 ; AND MULTIPLY BY 2
MOV BX,GMASK_TBL [DI] ; BL = OFF MASK, BH = ON MASK
PUSH BX
; get the address of the pixel byte
MOV DI,DX ; GET LINE NUMBER
AND DI,0FFFEH ; ELIMINATE EVEN ODD BIT
SHR DI,1
SHR DI,1
SHL DI,1 ; AND MULTIPLY BY SUCCESSIVE POWERS OF 2
MOV BX,DI ; save val*2...
SHL DI,1
SHL DI,1
ADD BX,DI ; add val*2...
SHL DI,1 ; DI IS NOW MULTIPLIED BY 16
MOV AX,DI ; SAVE PARTIAL PRODUCT
SHL DI,1
SHL DI,1 ; DI IS NOW MULTIPLIED BY 64
ADD DI,AX ; DI IS NOW * 80
ADD DI,BX ; DI IS NOW * 90
POP BX
TEST DX,3 ; IS LINE N3?
JZ N_N1 ; NO BITS SET, GO ON
ADD DI,2000H ; ODD, SO ADD 2000H TO GET TO 2ND SECTION
TEST DX,2
JZ N_N1
ADD DI,2000H
TEST DX,1
JZ N_N1
ADD DI,2000H
N_N1:
MOV AX,CX ; GET COLUMN NUMBER
SHR AX,1
SHR AX,1 ; AND DIVIDE BY 4 FOR OFFSET FROM START OF LINE
SHR AX,1
ADD DI,AX ; AND ADD TO FINAL ADDRESS
MOV AX,0B000H ; POINT TO DMA
MOV ES,AX ; ES = DMA
; now set the pixel
AND ES:[DI],BL ; BLANK OUT PIXEL
OR ES:[DI],BH ; INSERT NEW PIXEL
POP ES
POP DI
POP BX
POP AX
RET
PLOT_HGA ENDP
SUBTTL XPLOTDOT PLOTS ONE PIXEL DOT USING XOR
PAGE +
XPLOT_HGA PROC NEAR
; assumes DX = line offset number 0 to 347
; CX = column offset from 0 to 719
; routine plots the pixel dot by XOR
PUSH AX
PUSH BX
PUSH DI
PUSH ES
; determine mask and color bits by table look up
; table index = ( (pixel number * 4) + color ) * 2
MOV DI,CX
AND DI,7
SHL DI,1 ; AND MULTIPLY BY 2
MOV BX,GMASK_TBL [DI] ; BL = OFF MASK, BH = ON MASK
PUSH BX
; get the address of the pixel byte
MOV DI,DX ; GET LINE NUMBER
AND DI,0FFFEH ; ELIMINATE EVEN ODD BIT
SHR DI,1
SHR DI,1
SHL DI,1 ; AND MULTIPLY BY SUCCESSIVE POWERS OF 2
MOV BX,DI
SHL DI,1
SHL DI,1
ADD BX,DI
SHL DI,1 ; DI IS NOW MULTIPLIED BY 16
MOV AX,DI ; SAVE PARTIAL PRODUCT
SHL DI,1
SHL DI,1 ; DI IS NOW MULTIPLIED BY 64
ADD DI,AX ; DI IS NOW * 80
ADD DI,BX ; " " * 90
POP BX
TEST DX,3 ; IS LINE N3?
JZ XN_N1 ; NO,
ADD DI,2000H ; ODD, SO ADD 2000H TO GET TO 2ND SECTION
TEST DX,2
JZ XN_N1
ADD DI,2000H
TEST DX,1
JZ XN_N1
ADD DI,2000H
XN_N1:
MOV AX,CX ; GET COLUMN NUMBER
SHR AX,1
SHR AX,1
SHR AX,1 ; AND DIVIDE BY 8 FOR OFFSET FROM START OF LINE
ADD DI,AX ; AND ADD TO FINAL ADDRESS
MOV AX,0B000H ; POINT TO DMA
MOV ES,AX ; ES = DMA
; now set the pixel
XOR ES:[DI],BH ; XOR IN NEW COLOR
POP ES
POP DI
POP BX
POP AX
RET
XPLOT_HGA ENDP
DELAY PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH ES
MOV AX,0040H
MOV ES,AX
MOV CX,D_VAL ; OR DELAY VAL # OF CLOCKS....
CMP CX,00H
JE D2_L_EX
D2_L_2:
MOV AX,ES:[006CH]
D2_L_1:
MOV BX,ES:[006CH]
CMP AX,BX
JE D2_L_1
LOOP D2_L_2
D2_L_EX:
POP ES
POP CX
POP BX
POP AX
RET
DELAY ENDP
SUBTTL SET_MODE AND RESTORE GRAPHICS MODE ROUTINES
PAGE +
SET_MODE PROC
; routine to set high resolution mode and plot routine addresses...
PUSH AX
PUSH BX
LEA SI,PLOT_HGA
MOV PLOT_ADR,SI
MOV PLOT_SUB,SI
LEA SI,XPLOT_HGA
MOV XPLOT_ADR,SI
MOV SCRN_ADR,HGA_ADR
CALL _GMODE ; SET HERC TO 720 x 348 GRAPHICS MODE ??
POP BX
POP AX
RET
SET_MODE ENDP
; routine to restore HGA text video mode
RESTORE_MODE PROC
PUSH AX
CALL _TMODE
POP AX
RET
RESTORE_MODE ENDP
;*********************************************************************
;GRAPHICS MODE - Programs the 6845 CRT controller for the 720 x 348 graphics
;mode. The active page for both writing and display is set to the default value
;of page 0.
;ON ENTRY - no parameters.
; source unknown ?? c-serve ?
;*********************************************************************
_gmode proc near
push si
push di
mov al,1
mov dx, 3bfh
out dx, al
mov al,grph
lea si,gtable
mov bx,0
mov cx,4000h
call setmd
pop di
pop si
ret
_gmode endp
;**********************************************************************
;TEXT MODE - Programs the 6845 and control register to produce text mode.
;
;ON ENTRY - no parameters.
;***********************************************************************
_tmode proc near
push si
push di
mov al,text
lea si,ttable
mov bx,720h
mov cx,2000
call setmd
pop di
pop si
ret
_tmode endp
setmd proc near
; sets mode to graphics or text
; depending on al
; si = parameter table
; cx = number of words to be cleared
; bx = blank value
push ds
push es
push ax
push bx
push cx
; change mode but without scrn_on
mov dx,cntrl
out dx,al
; intialize the 6845
mov dx,index
mov cx,12 ;12 parameters to
;be output
xor ah,ah ;starting from
;reg. 0
parms: mov al,ah
out dx,al ;output register
;number
cld
inc dx
lodsb
out dx,al ;output data
inc ah ;next value
dec dx
loop parms
pop cx ;clear the buffer
mov ax,0b000h
mov es,ax
xor di,di
pop ax
rep stosw
; scrn_on, page 0
mov dx,cntrl
pop ax
add al,scrn_on
out dx,al
pop es
pop ds
ret
setmd endp
SUBTTL CLS CLEAR THE GRAPHICS SCREEN
PAGE +
CLS PROC
; clears a graphics screen using color palette choice COLOR_CLS
PUSH AX
PUSH CX
PUSH DI
PUSH ES
MOV AX,0B000H ; POINT TO DMA
MOV ES,AX ; ES = DMA ADDRESS
MOV DI,0 ; POINT TO START OF SCREEN
MOV CX,4000H ; WORD COUNT OF WHOLE SCREEN
MOV AX,COLOR_CLS ; SET PIXEL PATTERN FOR WHOLE SCREEN
CLD ; SET FOR FORWARD DIRECTION
REP STOSW ; CLEAR WHOLE SCREEN
POP ES
POP DI
POP CX
POP AX
RET
CLS ENDP
SUBTTL DATA AREA
PAGE +
.DATA
; used by CLS
COLOR_CLS DW 0000H ; SET CLEAR SCREEN COLOR TO 00
; used by SET_MODE and RESTORE_MODE routines
ST_MODE DB ? ; OLD VIDEO MODE
SCRN_ADR DW ?
PLOT_SUB DW ?
PLOT_ADR DW ?
XPLOT_ADR DW ?
; used by PLOTDOT and XPLOTDOT routines
GMASK_TBL LABEL WORD
DB 01111111B, 10000000B ; LEFT PIXEL
DB 10111111B, 01000000B ;
DB 11011111B, 00100000B ;
DB 11101111B, 00010000B ;
DB 11110111B, 00001000B ; RIGHT PIXEL
DB 11111011B, 00000100B ;
DB 11111101B, 00000010B ;
DB 11111110B, 00000001B ;
; used by PLOTLINE routine
SHORT_STEP DW ?
LONG_STEP DW ?
LINE_START DW ?
LINE_STOP DW ?
LINE1 LABEL WORD
X1 DW 0
Y1 DW 0
X2 DW 719
Y2 DW 347
CO DB 1
LN DW 0
SK DW 0
FRAME_DAT LABEL WORD
DW 0 ; X_MIN
DW 719 ; X_MAX
DW 0 ; Y_MIN
DW 347 ; Y_MAX
DW 8 ; X_STEP
DW 3 ; Y_STEP
DW 2 ; NUM_REPS
SWFRAME_DAT LABEL WORD
DW 0 ; X_MIN
DW 719 ; X_MAX
DW 0 ; Y_MIN
DW 347 ; Y_MAX
DW 8 ; X_STEP
DW 3 ; Y_STEP
DW 2 ; NUM_REPS
; used by CIRCLE routine
CIRCLE_DATA DW 359, 172, 90, 1, 5000/8
gtable db 35h,2dh,2eh,07h
db 5bh,02h,57h,57h
db 02h,03h,00h,00h
ttable db 61h,50h,52h,0fh
db 19h,06h,19h,19h
db 02h,0dh,0bh,0ch
LETTER DB FNT_LEN DUP (?)
HR_MESS LABEL WORD
DW 5 ; LINE #
DW 275 ; COLUMN #
DB 1 ; X SCALE
DB 2 ; Y SCALE
DB 'Hi-Res graphics demo !?!',00H
SA_MESS LABEL WORD
DW 275 ; LINE #
DW 200 ; COLUMN #
DB 2 ; X SCALE
DB 1 ; Y SCALE
DB '(c) 1993 Scott Armitage',00H
PX_MESS LABEL WORD
DW 320 ; LINE #
DW 175 ; COLUMN #
DB 2 ; X SCALE
DB 3 ; Y SCALE
DB 'Press any key to QUIT...',00H
TST_MESS LABEL WORD
DW 162 ; LINE #
DW 336 ; COLUMN #
DB 2 ; X SCALE
DB 2 ; Y SCALE
DB 'WoW',00H
; USE FOR # OF CLOCKS TO DELAY IN DELAY ROUTINE...
D_VAL DW 10H
.STACK
DW 50 DUP (?)
END MAIN