home *** CD-ROM | disk | FTP | other *** search
- .MODEL SMALL
-
- ;-----------------------------------------------------------------------;
- ; This file contains various procedures that write to the screen: ;
- ; ;
- ; INIT_WRITE_CHAR Initializes this module ;
- ; WRITE_CHAR Writes a character on the screen ;
- ; WRITE_STRING Writes a string to the screen ;
- ; WRITE_HEX Writes a two-digit hex number ;
- ; WRITE_HEX_DIGIT Writes a single hexadecimal digit ;
- ; WRITE_DECIMAL Writes a decimal number on the screen ;
- ; WRITE_PATTERN Writes a pattern on the screen ;
- ; WRITE_CHAR_N_TIMES Writes N copies of one character ;
- ; WRITE_ATTRIBUTE_N_TIMES Writes just the attribute to the screen ;
- ;-----------------------------------------------------------------------;
-
- .DATA
- PUBLIC SCREEN_PTR
- PUBLIC SCREEN_X, SCREEN_Y
- SCREEN_SEG DW 0B800h ;Segment of the screen buffer
- SCREEN_PTR DW 0 ;Offset into screen memory of cursor
- SCREEN_X DB 0 ;Position of the screen cursor
- SCREEN_Y DB 0
-
-
- .CODE
-
- PUBLIC WRITE_STRING
- ;-----------------------------------------------------------------------;
- ; This procedure writes a string of characters to the screen. The ;
- ; string must end with DB 0 ;
- ; ;
- ; On entry: DS:DX Address of the string ;
- ; ;
- ; Uses: WRITE_CHAR ;
- ;-----------------------------------------------------------------------;
- WRITE_STRING PROC
- PUSH AX
- PUSH DX
- PUSH SI
- PUSHF ;Save direction flag
- CLD ;Set direction for increment (forward)
- MOV SI,DX ;Place address into SI for LODSB
- STRING_LOOP:
- LODSB ;Get a character into the AL register
- OR AL,AL ;Have we found the 0 yet?
- JZ END_OF_STRING ;Yes, we are done with the string
- MOV DL,AL ;No, write character
- CALL WRITE_CHAR
- JMP STRING_LOOP
- END_OF_STRING:
- POPF ;Restore direction flag
- POP SI
- POP DX
- POP AX
- RET
- WRITE_STRING ENDP
-
-
- PUBLIC WRITE_HEX
- ;-----------------------------------------------------------------------;
- ; This procedure converts the byte in the DL register to hex and writes ;
- ; the two hex digits at the current cursor position. ;
- ; ;
- ; On entry: DL Byte to convert to hex. ;
- ; ;
- ; Uses: WRITE_HEX_DIGIT ;
- ;-----------------------------------------------------------------------;
- WRITE_HEX PROC ;Entry point
- PUSH CX ;Save registers used in this procedure
- PUSH DX
- MOV DH,DL ;Make a copy of byte
- MOV CX,4 ;Get the upper nibble in DL
- SHR DL,CL
- CALL WRITE_HEX_DIGIT ;Display first hex digit
- MOV DL,DH ;Get lower nibble into DL
- AND DL,0Fh ;Remove the upper nibble
- CALL WRITE_HEX_DIGIT ;Display second hex digit
- POP DX
- POP CX
- RET
- WRITE_HEX ENDP
-
- PUBLIC WRITE_HEX_DIGIT
- ;-----------------------------------------------------------------------;
- ; This procedure converts the lower 4 bits of DL to a hex digit and ;
- ; writes it to the screen. ;
- ; ;
- ; On entry: DL Lower 4 bits contain number to be printed ;
- ; in hex. ;
- ; ;
- ; Uses: WRITE_CHAR ;
- ;-----------------------------------------------------------------------;
- WRITE_HEX_DIGIT PROC
- PUSH DX ;Save registers used
- CMP DL,10 ;Is this nibble <10?
- JAE HEX_LETTER ;No, convert to a letter
- ADD DL,"0" ;Yes, convert to a digit
- JMP Short WRITE_DIGIT ;Now write this character
- HEX_LETTER:
- ADD DL,"A"-10 ;Convert to hex letter
- WRITE_DIGIT:
- CALL WRITE_CHAR ;Display the letter on the screen
- POP DX ;Restore old value of DX
- RET
- WRITE_HEX_DIGIT ENDP
-
- PUBLIC INIT_WRITE_CHAR
- ;-----------------------------------------------------------------------;
- ; You need to call this procedure before you call WRITE_CHAR since ;
- ; WRITE_CHAR uses information set by this procedure. ;
- ; ;
- ; Writes: SCREEN_SEG ;
- ;-----------------------------------------------------------------------;
- INIT_WRITE_CHAR PROC
- PUSH AX
- PUSH BX
- MOV BX,0B800h ;Set for color graphics display
- INT 11h ;Get equipment information
- AND AL,30h ;Keep just the video display type
- CMP AL,30h ;Is this a monochrome display adapter?
- JNE SET_BASE ;No, it's color, so use B800
- MOV BX,0B800h ;Yes, it's monochrome, so use B000
- SET_BASE:
- MOV SCREEN_SEG,BX ;Save the screen segment
- POP BX
- POP AX
- RET
- INIT_WRITE_CHAR ENDP
-
- PUBLIC WRITE_CHAR
- EXTRN CURSOR_RIGHT:PROC
- ;-----------------------------------------------------------------------;
- ; This procedure outputs a character to the screen by writing directly ;
- ; into screen memory, so that characters such as the backspace are ;
- ; treated as any other characters and are displayed. ;
- ; ;
- ; This procedure must do a bit of work to update the cursor position. ;
- ; ;
- ; On entry: DL Byte to print on screen. ;
- ; ;
- ; Uses: CURSOR_RIGHT ;
- ; Reads: SCREEN_SEG, SCREEN_PTR ;
- ;-----------------------------------------------------------------------;
- WRITE_CHAR PROC
- PUSH AX
- PUSH BX
- PUSH DX
- PUSH ES
-
- MOV AX,SCREEN_SEG ;Get segment for screen memory
- MOV ES,AX ;Point ES to screen memory
- MOV BX,SCREEN_PTR ;Pointer to character in screen memory
-
- MOV DH,7 ;Use the normal attribute
- MOV ES:[BX],DX ;Write character/attribute to screen
- CALL CURSOR_RIGHT ;Now move to next cursor position
-
- POP ES
- POP DX
- POP BX
- POP AX
- RET
- WRITE_CHAR ENDP
-
- PUBLIC WRITE_DECIMAL
- ;-----------------------------------------------------------------------;
- ; This procedure writes a 16-bit, unsigned number in decimal notation. ;
- ; ;
- ; On entry: DX N : 16-bit, unsigned number. ;
- ; ;
- ; Uses: WRITE_HEX_DIGIT ;
- ;-----------------------------------------------------------------------;
- WRITE_DECIMAL PROC
- PUSH AX ;Save registers used here
- PUSH CX
- PUSH DX
- PUSH SI
- MOV AX,DX
- MOV SI,10 ;Will divide by 10 using SI
- XOR CX,CX ;Count of digits placed on stack
- NON_ZERO:
- XOR DX,DX ;Set upper word of N to 0
- DIV SI ;Calculate N/10 and (N mod 10)
- PUSH DX ;Push one digit onto the stack
- INC CX ;One more digit added
- OR AX,AX ;N = 0 yet?
- JNE NON_ZERO ;Nope, continue
- WRITE_DIGIT_LOOP:
- POP DX ;Get the digits in reverse order
- CALL WRITE_HEX_DIGIT
- LOOP WRITE_DIGIT_LOOP
- END_DECIMAL:
- POP SI
- POP DX
- POP CX
- POP AX
- RET
- WRITE_DECIMAL ENDP
-
- PUBLIC WRITE_CHAR_N_TIMES
- ;-----------------------------------------------------------------------;
- ; This procedure writes more than one copy of a character ;
- ; ;
- ; On entry: DL Character code ;
- ; CX Number of times to write the character ;
- ; ;
- ; Uses: WRITE_CHAR ;
- ;-----------------------------------------------------------------------;
- WRITE_CHAR_N_TIMES PROC
- PUSH CX
- N_TIMES:
- CALL WRITE_CHAR
- LOOP N_TIMES
- POP CX
- RET
- WRITE_CHAR_N_TIMES ENDP
-
-
- PUBLIC WRITE_ATTRIBUTE_N_TIMES
- EXTRN CURSOR_RIGHT:PROC
- ;-----------------------------------------------------------------------;
- ; This procedure sets the attribute for N characters, starting at the ;
- ; current cursor position. ;
- ; ;
- ; CX Number of characters to set attribute for ;
- ; DL New attribute for characters ;
- ; ;
- ; Uses: CURSOR_RIGHT ;
- ; Reads: SCREEN_SEG, SCREEN_PTR ;
- ;-----------------------------------------------------------------------;
- WRITE_ATTRIBUTE_N_TIMES PROC
- PUSH AX
- PUSH CX
- PUSH DI
- PUSH ES
-
- MOV AX,SCREEN_SEG ;Set ES to point to screen segment
- MOV ES,AX
- MOV DI,SCREEN_PTR ;Character under cursor
- INC DI ;Point to the attribute under cursor
- MOV AL,DL ;Put attribute into AL
- ATTR_LOOP:
- STOSB ;Save one attribute
- INC DI ;Move to next attribute
- INC SCREEN_X ;Move to next column
- LOOP ATTR_LOOP ;Write N attributes
-
- DEC DI ;Point to start of next character
- MOV SCREEN_PTR,DI ;Remember where we are
-
- POP ES
- POP DI
- POP CX
- POP AX
- RET
- WRITE_ATTRIBUTE_N_TIMES ENDP
-
-
- PUBLIC WRITE_PATTERN
- ;-----------------------------------------------------------------------;
- ; This procedure writes a line to the screen, based on data in the ;
- ; form ;
- ; ;
- ; DB {character, number of times to write character}, 0 ;
- ; Where {x} means that x can be repeated any number of times ;
- ; ;
- ; On entry: DS:DX Address of the pattern to draw ;
- ; ;
- ; Uses: WRITE_CHAR_N_TIMES ;
- ;-----------------------------------------------------------------------;
- WRITE_PATTERN PROC
- PUSH AX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSHF ;Save the direction flag
- CLD ;Set direction flag for increment
- MOV SI,DX ;Move offset into SI register for LODSB
- PATTERN_LOOP:
- LODSB ;Get character data into AL
- OR AL,AL ;Is it the end of data (0h)?
- JZ END_PATTERN ;Yes, return
- MOV DL,AL ;No, set up to write character N times
- LODSB ;Get the repeat count into AL
- MOV CL,AL ;And put in CX for WRITE_CHAR_N_TIMES
- XOR CH,CH ;Zero upper byte of CX
- CALL WRITE_CHAR_N_TIMES
- JMP PATTERN_LOOP
- END_PATTERN:
- POPF ;Restore direction flag
- POP SI
- POP DX
- POP CX
- POP AX
- RET
- WRITE_PATTERN ENDP
-
- END