Debugging with Sound
As we start working with interrupt code, you may find it difficult to debug. While there are tricks to help you trace through regions of memory, you might like to have a less invasive approach. Typically when you write code in a high-level language, you will put in debug print statements. But this is interrupt code! You don't know if it is safe to write to the console! So, a suggestion is to try sound. You can always write to the PC speaker. I have found that sound is extremely useful for debugging this type of code. To assist you in your organization, am providing this file as an example of how I would strongly suggest you write almost all of your code.
TITLE Sound.asm ;special thanks to Chris Friedersdorf, email@example.com for the SOUND PROC ;======================================================================= ; Sound will play a tone through the PC speaker. ;======================================================================= ; PreCond -- Frequency - di register (from 21 to 65535 h) ; Duration - bx register (in hundredths of second) ; PostCond -- The tone will be generated (freq, dur) ; Remarks -- All registers are returned to their original states. ;======================================================================= PUBLIC sound _TEXT SEGMENT USE16 WORD PUBLIC 'CODE' ASSUME cs:_TEXT SOUND PROC FAR push ax push cx push dx mov al,0B6h ; write timer mode out 43h,al ; write to control register mov dx,14h ; high part of divisor mov ax,4F38h ; DX:AX = 1331000 div di ; 1331000/frequency out 42h,al ; write low part mov al,ah ; out 42h,al ; write high part in al,61h ; read port B mov ah,al ; remember state of port B or al,3 ; resolution of timer and sound out 61h,al ; ; Generation of delay in hundredth of second (value in BX) Waitr: mov cx,2801 ; duration 0.01 s loop $ ; delay 0.01 s dec bx ; has time gone ? jnz Waitr ; no mov al,ah ; out 61h,al ; restore state of port B pop dx pop cx pop ax ret SOUND ENDP _TEXT ENDS END
TITLE io.mac ;======================================================================= ; beep (Frequency, Duration) -- plays the request tone though the PC spkr ; PreCond -- None. ; PostCond -- Nothing (no registers modified) ; Notes -- This macro assumes nothing about segments ;======================================================================= beep MACRO Freq, Duration push di push bx mov bx, Duration mov di, Freq call sound pop bx pop di ENDM
TITLE Snd_test.asm include io.mac _TEXT SEGMENT USE16 BYTE PUBLIC 'CODE' assume cs:_TEXT EXTRN SOUND:FAR Start: beep 300, 50 mov ax, 4c00h int 21h _TEXT ENDS END Start
To use these...
Download the files
Notice the test module... this is very small but fully tests this module. I strongly encourage these simple test procedures to ensure that every possible type of call to a function will be handled correctly. For example, if you wrote a stringLength function, you would want to have a test module that tried a short string (5 chars?) a long string (200 chars?) and then some extreme cases like an empty string (0 chars) and a huge string (65535 chars). But these are tiny procedures that do not take a very long time to create (but save HOURS of headaches... trust me :-) Whatever you choose, to do, good luck!
Last Modified: January 26, 1999 - Barry E. Mapen