Category : Assembly Language Source Code
Archive   : NORTASM.ZIP
Filename : VIDEO_30.ASM

 
Output of file : VIDEO_30.ASM contained in archive : NORTASM.ZIP
.MODEL SMALL

.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


  3 Responses to “Category : Assembly Language Source Code
Archive   : NORTASM.ZIP
Filename : VIDEO_30.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/