;***************************************************************************** ; This program is designed to illustrate the use of BIOS interrupt 10h for ; controlling the video display and BIOS interrupt 16h to read input from the ; keyboard. It will also print directly to the printer attached to your ; parallel port, IF you are running DOS, Win95, or Win98 ....NOT NT, 2000, or ; XP. ; ; Written by Joe Toone 11/19/2003 1:42:12 PM ;***************************************************************************** TITLE hardware.asm CR equ 0dh ;ASCII 13 for carriage return LF equ 0ah ;ASCII 10 for line feed NEWLINE equ CR,LF ;Combine the newline characters FORMFEED equ 0ch ;ASCII 12 for the form feed DISPLAYLOC equ 0b800h ;Start of Video RAM DATAPORT equ 3bch ;Data port for the printer CONTROL equ 3beh ;Control port for the printer STATUS equ 3bdh ;Status port for the printer DOSSEG .MODEL SMALL ;Small memory model .586 ;Needed for pusha and popa .STACK 100h ;100 hex words for stack .DATA Attributes equ this Byte Normal db 07h Reverse db 70h Intense db 0fh Blink db 87h IntenseAndBlink db 8fh ReverseAndBlink db 0f0h RevIntBlink db 0f8h Foreground db 0 Background db 0 Prompt db 'Type a number from 1 to 7 or C for color --> ',0 PrintDemo db 'This is a demonstration of direct printer control' db NEWLINE,FORMFEED,0 ;************************** Main Body of Program ***************************** .CODE Start: mov ax,@data ;Starting address of the data segment mov ds,ax ;Set DS to point to the data segment mov ax,DISPLAYLOC ;Starting address of video ram mov es,ax ;Set ES to point to video ram call clrscr ;Call procedure to clear the screen lea si,Prompt ;Set SI to point to string call PrintString ;Call BIOS to print the string call Display ;Display 7 Black and White modes call Color ;Use 6845 chip regs to display color call FillScreen ;Fill the Screen with the letter X call ClrScr ;Clear the screen and end ;call printer ;Uncomment this line if you have ; DOS, Win95 or Win98, to print ; directly to the printer. mov ax,4c00h ;DOS terminate program function #4C hex AllDone: ;NOTE: 4c00h clears AL to avoid hang-up int 21h ;End of Main Body - Exit to DOS prompt ;-------- Procedure GetChar --------------------------------------------------- ; Given :Nothing ; Process :Call BIOS GetChar function ; Return :Input character in AL ;------------------------------------------------------------------------------ GetChar PROC mov ah,0h ;Set up for BIOS read char function int 16h ;Call BIOS to get a char, but don't ; print it on the screen, store in al ret ;Return to caller GetChar ENDP ;-------- Procedure PutChar --------------------------------------------------- ; Given :The character to print in AL ; Process :Call BIOS PrintChar function ; Return :Nothing ;------------------------------------------------------------------------------ PutChar PROC pusha ;Save the registers mov bh,0 ;Use video page 0 mov ah,0eh ;Set up for BIOS write char function int 10h ;Call BIOS to print a char mov al,8 ;Load a Backspace and print it first mov ah,0eh ;Set up for BIOS write char function int 10h ;Call BIOS to print a char popa ;Restore the registers ret ;Return to caller PutChar ENDP ;-------- Procedure PrintString ----------------------------------------------- ; Given :The address of the string to print in SI register ; Process :Call BIOS PrintChar function until a NULL (0) is reached ; Return :Nothing ;------------------------------------------------------------------------------ PrintString PROC pusha ;Save the registers mov ah,0eh ;Display character and advance cursor mov bh,0 ;Use video page 0 NextLetter:lodsb ;Place character to print in AL cmp al,0h ;Is this the end of string? jz Finish ;If yes, go to Finish int 10h ;Invoke BIOS to display character jmp NextLetter ;Loop to get next letter Finish: popa ;Restore the registers ret ;Return to caller PrintString ENDP ;----------- Procedure to Demonstrate Screen Attribs -------------------------- ; Given : Nothing ; Process : Allow user to display ASCII set in Seven different modes ; Return : Nothing ;------------------------------------------------------------------------------ Display PROC GetMode:call GetChar ;Get a character from the keyboard call PutChar ;Echo it back on the screen InRange:cmp al,31h ;Check for < 1 jc Done ; Quit if not in range cmp al,38h ;Check for > 7 jnc Done ; Quit if not in range sub al,31h ;Convert Char to Int mov bl,al ;Set up BX as the Index register mov bh,0h ; mov ah, Attributes[bx] ;Move correct attribute into AH mov di,(1*160d)+(0*2) ;Pointer to row and column mov al,0h ;Set AL to first ASCII char mov dh,0h ;Set DH to first row NextChar:mov es:[di]+1,ah ;Copy Character to Screen RAM mov es:[di],al ;Copy Attribute to Screen RAM ; This causes the char to be displayed add di,4h ;Skip one space between chars add dh,2h ;Increment row by two cmp dh,79d ;Is this the last column? jb NextCode ; No - print next ASCII code add di,160d ;Else increment row mov dh,0h ; and go back to first column NextCode:inc al ;Increment AL for next ASCII char cmp al,0h ;If we are back to 0? jz GetMode ;then ask for another mode to display jmp NextChar ;Else print the next char Done: ret ;Return to caller Display ENDP ;--------- Procedure to Demonstrate using 6845 regs for color display --------- ; Given : Nothing ; Process : Demonstrate 8 background and 16 foregound colors ; Return : Nothing ;------------------------------------------------------------------------------ Color PROC mov ah,0 ;Set up display for 40 columns mov al,1 ; and 25 rows int 10h ; mov al,1 ;Setting for blue mov dx,3d9h ;Color select register out dx,al ;Set the reg to blue mov di,0 ;First row and column mov al,' ' ;Clear the screen by printing blue mov ah,1*16d+0 ;Number of possible foreground colors mov cx,8000d ;Number of Screen bytes available cld ;Process forward in memory rep stosw ;Blue space on blue background stored ; in all of screen RAM mov di,(80d*2d)+(2*0) ;Starting location for first 'A' mov Foreground,0 ;Black foreground mov Background,0 ;Black background DoNext: mov byte ptr es:[di],'A' ;Copy 'A' to RAM mov al,16d ;Max forground color mul Background ;Sets the next background add al,Foreground ; mov es:[di]+1,al ;Set background for the 'A' mov es:[di]+3,al ;Set background for next 3 bytes mov es:[di]+5,al ; mov es:[di]+7,al ; add di,8 ;Location for next 'A' inc Background ;Next background cmp Background,8d ;Is it the last one? jnz DoNext ; no, do next background add di,16d ;Move to next line mov Background,0 ;Reset background inc Foreground ;Next foreground cmp Foreground,16d ;Is it the last one? jnz DoNext ; no, do next forground pause: call GetChar ;Pause by waiting for a char from kbd mov ah,0 ;Set up display for 80 columns mov al,2 ; and 25 rows Black and White int 10h ret ;Return to caller Color ENDP ;--------------- Procedure to fill the Screen with 'X' ------------------------ ; Given : Nothing ; Process : Fill the entire screen using the letter 'X' ; Return : Nothing ;------------------------------------------------------------------------------ FillScreen PROC cld ;Set the direction flag to forward mov di,0 ;Point to start of screen RAM mov al,'X' ;Blank to print mov ah,Normal ;White on black text mov cx,2000d ;Number of chars in 80x25 display rep stosw ;Fill first 2000 bytes of screen RAM call GetChar ;Pause by waiting for a char from kbd ret ;Return to caller FillScreen ENDP ;-------------- Procedure to Clear the Screen --------------------------------- ; Given : Nothing ; Process : Clear the entire screen. This procedure could easily be modified ; to clear only a certain portion of the screen by requiring that ; CX and DX be loaded pryor to a call to this procedure. ; Return : Nothing ;------------------------------------------------------------------------------ Clrscr PROC pusha ;Save the contents of all registers mov ah,06h ;Set screen scroll code to 6 hex mov al,0h ;Set clear screen code to 0 hex mov bh,07h ;Set blank line to black mov ch,0h ;Set starting row mov cl,0h ;Set starting column mov dh,18h ;Set ending row to 24 decimal mov dl,4fh ;Set ending column to 79 decimal int 10h ;Clear the screen mov dh,0h ;Row to locate cursor in mov dl,0h ;Column to locate cursor in call GotoXY ;Call procedure to set cursor location popa ;Restore the registers ret ;Return to calling procedure Clrscr ENDP ;------------ Procedure to Set Cursor Location -------------------------------- ; Given : Row number in DH and Column number in DL ; Process : Locate the cursor in the requested row and column ; Return : Nothing ;------------------------------------------------------------------------------ GotoXY PROC pusha ;Save the contents of all registers mov ah,02h ;Set cursor address function mov bh,0h ;Set for 0 video page int 10h ;Set cursor to row in DH and column DL popa ;Restore the registers ret ;Return to calling procedure GotoXY ENDP ;-------- Procedure Printer --------------------------------------------------- ; Given :Nothing ; Process :Print a string of characters from the data segment on the printer ; :using IN and OUT in conjunction with DATA, CONTROL, and STATUS ports ; Return :Nothing ;------------------------------------------------------------------------------ Printer PROC pusha ;Protect the Registers mov dx,CONTROL ;Begin initializing the printer by mov al,08h ; setting bit 6 of output control port out dx,al ; to zero (0) mov al,FORMFEED ; mov cx,50d ;wait for 50 milliseconds waitmore:nop ;No operation to perform loop waitmore ; do nothing 50 times lea si,PrintDemo ;Point the the string to print NextPrint:lodsb ;Place character to print in AL cmp al,0h ;Is this the end of string? jz DonePrinting ;If yes, go to Finish call Send2Printer ;Go print the character jmp NextPrint ;Loop to get next letter DonePrinting: popa ;Restore the Registers Printer ENDP ;-------- Procedure Send2Printer ---------------------------------------------- ; Given :A character to be printed in the AL register ; Process :Check to see if the printer is busy and then print the character ; Return :Nothing ;------------------------------------------------------------------------------ Send2Printer PROC pusha ;Protect the Registers mov dx,DATAPORT ;Point DX to the data port out dx,al ;Transfer the character to data port mov dx,STATUS ;Point DX to the status port CheckBusy:in al,dx ;Read the status port test al,80h ;Look for bit a 1 in bit 7 jz CheckBusy ; if busy, check again mov dx,CONTROL ;Point DX to control port mov al,0dh ;Character to signal - begin printing out dx,al ;Start printing mov al,0ch ;Character to signal - stop printing out dx,al ;Stop printing popa ;Restore the Registers Send2Printer ENDP END Start ;End of Code Segment