Chapter 15 examples BIOS-level programming Variation on keybd.asm Keybd2.asm code… .data;;;I added these messages charis byte "char is=",0 scan byte "scan code=",0 ascii byte "ascii code=",0 .code main PROC mov ax,@data mov ds,ax call ClrScr ; clear screen L1: mov ah,10h ; keyboard input int 16h ; using BIOS push ax push ax mov edx, offset charis call writestring mov dl,al push ax mov ah,2 int 21h exe in p drive call ClrScr ; clear screen pop ax call crlf and eax,0ff00h mov edx, offset scan call writestring shl ax,8 call writeInt call crlf mov edx, offset ascii call writestring pop ax and ax,0ffh call writeInt call crlf pop ax cmp al,1Bh ; ESC key pressed? jne L1 ; no: repeat the loop Clearing the type-ahead buffer • If the user is typing keys in some loop (in a game situation, for example) and the program is waiting for a particular key press, you may need to clear the typeahead buffer INCLUDE Irvine16.inc ClearKeyboard PROTO, scanCode:BYTE ESC_key = 1 ; scan code .code main PROC L1: ;------------------------- LOOP BODY ; Display a dot, to show program's progress mov ah,2 mov dl,'.' int 21h mov eax,300 ; delay for 300 ms call Delay ;------------------------INVOKE ClearKeyboard,ESC_key jnz L1 ; continue loop if ZF=0 quit: call Clrscr exit main ENDP ; check for Esc key clearkbd ;--------------------------------------------------ClearKeyboard PROC, scanCode:BYTE ; ; Clears the keyboard, while checking for a ; particular scan code. ; Receives: keyboard scan code ; Returns: Zero flag set if the ASCII code is ; found; otherwise, Zero flag is clear. ;--------------------------------------------------push ax L1: mov ah,11h ; check keyboard buffer int 16h ; any key pressed? jz noKey ; no: exit now (ZF=0) mov ah,10h ; yes: remove from buffer int 16h cmp ah,scanCode ; was it the exit key? je quit ; yes: exit now (ZF=1) jmp L1 ; no: check buffer again noKey: ; no key pressed or al,1 ; clear zero flag quit: pop ax ret ClearKeyboard ENDP END main Not too impressive getting keyboard flags directly kbdseg dw 0040h kbdofs dw 17h string byte 'the keyboard settings',0ah,0dh,0 flags word ? .code main PROC mov ax,@data mov ds,ax mov ax,kbdseg mov es,ax mov di,kbdofs xor eax,eax mov al, byte ptr ES:[di] inc di mov ah,byte ptr ES:[di] mov flags,ax call writebin getting keyboard flags indirectly xor eax,eax mov ah,12h int 16h mov flags,ax call writebin Keyboard flags: note 1s for caps and numlock toggle keys (table pg 496) C:\Masm615\Examples\ch15>FLAGS 0000 0000 0110 0000 C:\Masm615\Examples\ch15>FLAGS2 0000 0000 0110 0000 C:\Masm615\Examples\ch15> Video display: 3 levels 1. Use DOS int 21h to put stuff on the screen 2. Use BIOS int 10h to put stuff on screen (no output redirect allowed) 3. Direct video access…write chars directly onto screen (see keyboard flags version for example of how to set seg and ofset) Video using int 10h • Each color pixel is generated by an electron beam with r-g-b components A fourth channel control intensity, in the format: • I-R-G-B • Text table pg 500 shows bit setting for various colors. • In color text mode, each character has an attribute byte consisting of 2 4-bit color settings for background and foreground. (bottom pg 500) Int 10h • Text pg 501 has a list of int 10h function codes • These include reading characters from the screen, writing chars or pixels onto the screen Txt pg 502 lists video modes Mode Resolution colors 0 40X25 1 1 40X25 16 2 80X25 2 3 80X25 16 7 80X25 2 14h 132X25 16 Int 10h functions • Get current video mode and save it before setting a new video mode: Int10h, function ah=0 sets mode in al. • Function 1 sets the cursor size • Function 2 sets cursor position (dh,dl=row,col; bh=videopage) Int 10h functions • Function 3=get curpos & size • Text has sample routines pg 545 to show/hide the cursor.. Here’s an example: Showcur proc Mov ah,1 Mov cx,0607h;default size int 10h Ret Showcur endp Writing (color) text to a window… text example TextWin.asm (left out a few lines) ; Scroll a window. mov ax,0600h ; scroll window mov bh,00011110b ; yellow on blue mov cx,050Ah ; upper-left corner mov dx,0A30h ; lower-right corner int 10h ; Position the cursor inside the window. mov ah,2 ; set cursor position mov dx,0714h ; row 7, col 20 mov bh,0 ; video page 0 int 10h ; Write some text in the window. mov dx,OFFSET message call WriteString ; Wait for a keypress. mov ah,10h int 16h exit Text example… colorstring main proc call ClrScr call EnableBlinking mov cx,SIZEOF string mov si,OFFSET string L1: push cx ; save loop counter mov ah,9 ; write character/attribute mov al,[si] ; character to display mov bh,0 ; video page 0 mov bl,color ; attribute or bl,ATTRIB_HI ; set blink/intensity bit mov cx,1 ; display it one time int 10h mov cx,1 ; advance cursor to call AdvanceCursor ; next screen column inc color ; next color inc si ; next character pop cx ; restore loop counter Loop L1 call Crlf exit EnableBlinking PROC EnableBlinking PROC ; ; Enable blinking (using the high bit of color ; attributes). In MS-Windows, this only works if ; the program is running in full-screen mode. ; Receives: nothing. ; Returns: nothing ;-------------------------------------------------push ax push bx mov ax,1003h mov bl,1 ; blinking is enabled int 10h pop bx pop ax ret EnableBlinking ENDP AdvanceCursor PROC AdvanceCursor PROC ; ; Advances the cursor n columns to the right. ; Receives: CX = number of columns ; Returns: nothing ;-------------------------------------------------pusha L1: push cx ; save loop counter mov ah,3 ; get cursor position mov bh,0 ; into DH, DL int 10h ; changes CX register! inc dl ; increment column mov ah,2 ; set cursor position int 10h pop cx ; restore loop counter loop L1 ; next column popa ret Run of colorstr Graphics in int 10h: table of video graphics modes on pg 512 Mode 6 0dh 0eh 0fh 10h 11h 12h 13h 6ah Resolution 640X200 320X200 640X200 640X350 640X350 640X480 640X480 320X200 800X600 # colors 2 16 16 2 16 2 16 256 16 functions • 0Ch write a pixel • 0dh read a pixel • See sample calls and parameters in text Drawline example: Changes mode to full screen and draws a tiny line segment: INCLUDE Irvine16.inc ;------------ Video Mode Constants ------------------Mode_06 = 6 ; 640 X 200, 2 colors Mode_0D = 0Dh ; 320 X 200, 16 colors Mode_0E = 0Eh ; 640 X 200, 16 colors Mode_0F = 0Fh ; 640 X 350, 2 colors Mode_10 = 10h ; 640 X 350, 16 colors Mode_11 = 11h ; 640 X 480, 2 colors Mode_12 = 12h ; 640 X 480, 16 colors Mode_13 = 13h ; 320 X 200, 256 colors Mode_6A = 6Ah ; 800 X 600, 16 colors More… .data saveMode BYTE ? ; save the current video mode currentX WORD 100 ; column number (X-coordinate) currentY WORD 100 ; row number (Y-coordinate) color BYTE 1 ; default color ; In 2-color modes, white = 1 ; In 16-color modes, blue = 1 .code main PROC mov ax,@data mov ds,ax ; Save the current video mode mov ah,0Fh int 10h mov saveMode,al ; Switch to a graphics mode mov ah,0 ; set video mode mov al,Mode_11 int 10h And the rest ; Draw a straight line LineLength = 100 mov dx,currentY mov cx,LineLength ; loop counter L1: push cx mov ah,0Ch ; write pixel mov al,color ; pixel color mov bh,0 ; video page 0 mov cx,currentX int 10h inc currentX ;inc color ; try this for multi-color modes pop cx Loop L1 ; Wait for a keystroke mov ah,0 int 16h ; Restore the starting video mode mov ah,0 ; set video mode… this part doesn’t seem to work mov al,saveMode ; saved video mode int 10h exit main ENDP Cartesian coordinates • Need to switch command prompt to full screen • Even so, it worked ok when I used mode11 but not mode6 • Can’t get screen shot in full screen mode Cartesian example …in slide notes .data saveMode BYTE ? currentX WORD 100 currentY WORD 100 color BYTE 1 ; save the current video mode ; column number (X-coordinate) ; row number (Y-coordinate) ; default color ; In 2-color modes, white = 1 ; In 16-color modes, blue = 1 .code main PROC mov ax,@data mov ds,ax ; Save the current video mode mov ah,0Fh int 10h mov saveMode,al ; Switch to a graphics mode mov ah,0 ; set video mode mov al,Mode_11;;;;;note mode6 did not work for me int 10h Cartesian example ; mov cx,X_axisX mov dx,x_axisY mov ax,x_axislen mov bl,white call horizontal mov cx,y_axisX mov dx,y_axisY mov ax,y_axislen mov bl,white call vertical ; Wait for a keystroke mov ah,0 int 16h ; Restore the starting video mode mov ah,0 ; set video mode mov al,saveMode ; saved video mode int 10h exit main ENDP Cartesian example: horizontal line horizontal proc .data currx word ? .code pusha mov currx,cx mov cx,ax H1: push cx mov al,bl mov ah,0ch mov bh,0 ;;page mov cx,currx int 10h inc currx pop cx loop h1 popa ret horizontal endp Cartesian example: vertical line vertical proc .data curry word ? .code pusha mov curry,dx mov currx,cx mov cx,ax V1: push cx mov al,bl mov ah,0ch mov bh,0 mov cx,currx mov dx,curry int 10h inc curry pop cx loop V1 popa ret vertical endp END main Section 15.5 memory mapped graphics • • • • Mode 13h 320X200, 256 color Text example Mode13.asm Draws a few blue dots on the screen… Need to run this in full screen boatgame • Code in slide and posted • Draws a boat and sub • Uses old medium resolution graphics mode. Medium resolution examples • These examples are based on an older graphics card but they still work: • Moveball---in slide notes • Medres plays cellular automata in medium resolution • Boatgame ---ask for source moveball • Draws a cyan ball on a blue screen. • Hit or hold key to move ball rightwards (it wraps) • Type ‘x’ to exit Hr examples from another text: draws a series of lines in hr –very pretty but can’t get screenshot .model small .stack 100h .386 .code main proc near mov ax,@data mov ds,ax mov es,ax mov ah,0fh int 10h push ax call b10mode call c10display mov ah,10h int 16h pop ax mov ah,0 int 10h mov ax,4c00h int 21h main endp b10mode proc near mov ax,12h int 10h mov ah,0bh mov bx,7 int 10h ret b10mode endp Hr2 continued c10display proc near pusha xor bx,bx mov cx,64 mov dx,70 @@20: mov ah,0ch mov al,bl int 10h inc cx cmp cx, 576;;;row/col delimiters in cx,dc jne @@20 mov cx,64 inc bl inc dx cmp dx,280 jne @@20 popa ret c10display endp end main Hr4…similar…writes letters .model small .stack 100h .386 video segment at 0b900h;;;page 1 vid db 1000H dup (?) video ends .code main proc near mov ax,video mov es,ax assume es:video mov ah,0fh int 10h push ax;;;save current mode push bx mov ax,3 int 10h mov ax,501h;;page 1 int 10h call b10display mov ah,10h;;wait for key int 16h hr4 mov ah,5 pop bx mov al,bh int 10h pop ax xor ah,ah int 10h mov ax,4c00h int 21h main endp b10display proc pusha mov al,41h mov ah,1 mov di,820 @@10: mov cx,60 @@20: mov es:word ptr[di],ax add di,2 loop @@20 inc ah inc al add di,40 cmp al,51h jne @@10 popa ret b10display endp end main hr4 Hr5 draws a block in fullscreen dos window – no screen shot.. Code in slide notes .model small .stack 100h .386 .data color db ? back dw 50 front dw 250 cstart dw 50 cstop dw 250 rstart dw 50 rstop dw 250 red equ 12 grey equ 7 .code main proc near mov ax,@data mov ds,ax mov es,ax mov ah,0fh int 10h push ax call b10mode Hr5 continued (next slide also) mov color,red call putblock;;;code on next slide down: mov ah,10h int 16h pop ax mov ah,0 int 10h mov ax,4c00h int 21h main endp putblock proc near pusha mov bx,0 mov cx,cstart mov dx,rstart @@20: ;check if point cx,dx is in circle push cx push dx sub dx,100 sub cx,100 mov ax,cx imul cx push ax ov ax,dx imul dx pop dx add ax,dx pop dx pop cx cmp ax,10000 jg @@next mov al,color mov ah,0ch;;;write dot int 10h @@next: inc cx cmp cx, cstop jg @@30 jmp @@20 @@30: mov cx,cstart inc dx cmp dx,rstop jg @@40 jmp @@20 @@40: popa ret putblock endp end main More of it b10mode proc near mov ax,12h int 10h mov ah,0bh mov bx,7 int 10h ret b10mode endp Other examples • Game of life (life.exe/.asm) implements a not too interesting one-dimensional cellular automata in hr graphics • Plotdot3 seems to be the same as hr2