I have this program written in asm that generates random characters and displays them on the screen until you press a key on the keyboard.  The program currently works but my problem is that it's basically a regurgitation of what was written on the board in my classroom so I don't understand why the keyboard interrupt works as it does.  Also if anyone could explain how a mouse interrupt works that would be welcome as well.

Here is the code...



.model small
.stack 100h
.data
seed DW 1234h
.code

main proc
mov ax,@data
mov ds,ax

push ds
mov ax,@code
mov ds,ax
mov ah,25h
mov al,9h                          ;I believe this is what makes the interrupt work?
mov dx,offset keyboard_int
int 21h
pop ds

mov al,'0'
mov ah,02h
mov dl,0d      ;across
mov dh,0d      ;down
mov bx,offset chars
mov si,0
mov cx,2

L1: call drawChar
call offsetPOS
call randomCH
inc cx
push ax
mov ah,9h
pop ax
loop L1

mov ax,4c00h
int 21h
main endp

keyboard_int proc
mov ax,4c00h
int 21h
iret
keyboard_int endp

offsetPOS proc
inc dh            ;across
cmp dh, 50d
jl notEdge
mov dh, 0
inc dl            ;down
cmp dl, 80d
jl notEdge
mov dl, 0
notEdge:
ret
offsetPOS endp

drawChar proc
push ax          ; symbol, color
push dx
mov al, 80
mul dh            ; ax = 80*ROW
xor dh, dh        ; dx = COL
add ax, dx        ; ax = 80*ROW+COL
shl ax, 1        ; ax = (80*ROW+COL)*2
mov di, ax        ; di = offset for char

mov ax, 0B800h
mov es, ax

pop dx            ; restore width, height
pop ax            ; Restore symbol, color
mov es:, ax  ; Symbol should appear after this
ret
drawChar endp

randomCH proc
push ax
push dx
mov ax, 32fdh
mul seed
xor dx, dx
add ax, 26c4h
mov seed, ax
xor ax, 8h
mov bx, ax
pop dx
pop ax
mov al, bl
ret
randomCH endp

end main
Posted on 2008-12-15 18:16:20 by Unclejunebug
The first int21 is setting up the pointer to your interrupt function, in this case a keyboard interrupt.
This will be called whenever a key is pressed.

Basically, an interrupt function is some code that is executed in response to an interrupt event (usually hardware-generated).

The interrupt function itself doesn't care what key was pressed, it just calls int 21 with ah=4Ch, which terminates a DOS program.

Check out Ralf Brown's Interrupt List (RBIL) for specific information on all DOS interrupts.
Posted on 2008-12-15 21:57:17 by Homer
You are on the right track regarding your comment in the posted code.

Under DOS, INT 0x21, Function 0x25, allows you to hook a specified Interrupt Vector so that it will call a custom routine. The code you posted sets Interrupt Vector 0x09 to point to code that calls a DOS exit, thus terminating the program.

RBIL is probably your best friend for PC interrupt information.

-INT 0x21, Function 0x25.
-INT 0x33, General Mouse Functions.
Posted on 2008-12-15 22:07:03 by SpooK
Hey!

Thanks for the clarification and the link to RBIL.  I think the mov ah,25h line was what was giving me the most trouble.  I didn't realize that is what is used to set an interrupt vector to a different interrupt.  I've been trying now to get a mouse interrupt to work but with no success yet.  The program I wrote just draws the letter 'H' all over the screen and should stop when you either click a mouse button or move the mouse.  If I take the mouseInt procedure out the letters draw on the screen without any problem, but with it in it doesn't draw anything and just hangs.  Can anyone tell me what I'm doing wrong here?

.model small
.stack 100h
.data

mouseX DW ?
mouseY DW ?
mButton DW ?

.code
main proc

mov ax,@data
mov ds,ax
push ds

mov ax,@code
mov ds,ax
mov ah,25h
mov al,33h
mov dx,offset mouseInt
int 21h
pop ds

mov ax,3
int 33h
mov mButton,bx
mov mouseX,cx
mov mouseY,dx

mov bx,80
mov di,bx
mov cx,0
L1: call drawChar
mov ah,33h
jmp L1

mov ax,4C00h
int 21h

main endp

mouseInt proc
mov ax,3
int 33h
cmp bx,mButton
jne endProgram
cmp cx,mouseX
jne endProgram
cmp dx,mouseY
jne endProgram
jmp continue
endProgram: mov ax,4C00h
int 21h
continue: iret
mouseInt endp

keyboardInt proc
mov ax,4C00h
int 21h
;iret
keyboardInt endp

drawChar proc
mov ax,0B800h
mov es,ax
mov ah,25h
mov al,'H'
mov es:,ax
add di,10
ret
drawChar endp

end main
Posted on 2008-12-16 12:47:05 by Unclejunebug
The INT 0x21, Function 0x25, method of hooking of INT 0x09 works in the above code because the interrupt vector is triggered (either directly or indirectly) by a hardware interrupt; an event with origins external to the processor.

Interrupts 0x20 and above are considered "programmer/user/OS defined", in which are mainly used in an API-like fashion via a specialized trapped software exception commonly known as the "INT" instruction. There are exceptions (no pun intended) to these higher interrupt vectors, such as mapping IRQs, as well as the availability of other INT-like instructions, but that summary should suffice as a general guideline.

The use of INT 0x33 would necessitate polling, periodically checking for a specific event. Figure out which INT 0x33 function would serve you best in this situation and work it in.
Posted on 2008-12-16 20:43:56 by SpooK