;uses Vector 1CH....Timer Strobe Interrupt to place "Pendulum" ; in the Top-Right Corner of screen.... ; ; ( Note: This Strobe 'ticks' 18.2 times/second ! ) ; ;Screen Positions: Line 1. Col.80 Reserved for TSR_Kybd Smiley Face ; ; Line 1, Col.77-78 will alternately flash a Smiley ; face 18.2 times per second. ; ; Line 2, Col.76-79 /\ "Pendulum" will swing ; Line 3, Col.76-79 @ @ once per second... Data Segment OldVect DD ? ;Old Vector address IntNo Equ 1CH ;Interupt Number we are modifying (clock) Smiley DB 01H, 20H ;Alternate Smiley Face between 02 Smiley/20 Space ; and 20 Space /02 Smiley RPendL1 DB " \ " RPendL2 DB " \ " RPendL3 DB " ->@" LPendL1 DB " / " LPendL2 DB " / " LPendL3 DB "@<- " PendLR DB "L" ;Pendulum position indicator Ctr18 DB 00H ;When this gets to 18 Ticks, swing pendulum Ctr5 DB 00H ;Every 18 ticks, add 1 to this...and when this ;gets to 5, subtract 1 from Ctr18...that should ;make for akuraczy 18.2 Ticks/Sec... Data EndS Code Segment Assume CS:Code,DS:Data Prog_Start: Mov AX, Data Mov DS, AX Jmp ChgVector ;****************************************************************************** My_Int_TSR: Push DS Push DX ; Save DX Mov DX, Data ; TSR code needs DS set Mov DS, DX ; for accessing OldVect... Pop DX ; Now restore it.... PushF ; Call the Call OldVect ; Old Interrupt Routine Push SI Push ES Push AX ;Save the Registers Push DI ;that may be needed PushF ;by the caller (DOS) some times.. Mov AX, 0B800H ;Top-Left Corner of Screen Mov ES, AX Mov AX, 004CH ;go to column 40 (out of 80) in top row Mov DI, AX Mov AL, Smiley STOSB ;Place AL Char. in top-right corner screen Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, Smiley+1 STOSB ; now second char... Cmp Smiley, 01 JE Set_Two Mov Smiley, 01H Mov Smiley+1, 20H ;Smiley Hex Space Hex Jmp Over_Two Set_Two: Mov Smiley, 20H Mov Smiley+1, 01H ;Space Hex Smiley Hex Over_Two: Add Ctr18, 1 ;Remember, 18.2 Interrupts/sec. Cmp Ctr18, 18D JE SwingP ;Yes, time to swing Pendulum Jmp Done SwingP: Mov Ctr18, 0 ;Reset Counter Add Ctr5, 1 Cmp Ctr5, 5 ;Every 5th Pend Swing, remove tick... JNE SWPend Mov Ctr18, 17 ;Set it back a Tick Mov Ctr5, -1 ;Reset the 5 pend swing counter ; -1 because we are comming back in 1 tick Jmp Done ;Done SWPend: Mov AX, 000E8H ;Point DI Mov DI, AX ; to Line 2, Col. 40 Cmp PendLR, "L" JE SwingR SwingL: Mov PendLR, "L" ;Remember you are swinging Left Mov AL, LPendL1 STOSB ;Place AL Char. in top-right corner screen Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL1+1 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL1+2 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL1+3 STOSB ; now second char... Add DI, 1 Mov AL, LPendL1+4 STOSB Add DI, 1 Mov AL, LpendL1+5 STOSB Mov AX, 0188H ;Line 2, Col.40 Mov DI, AX Mov AL, LPendL2 STOSB ;Place AL Char. in top-left corner of screen Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL2+1 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL2+2 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL2+3 STOSB ; now second char... Add DI, 1 Mov AL, LpendL2+4 STOSB Add DI, 1 Mov AL, LpendL2+5 STOSB Mov AX, 0228H ;Line 3, Col. 40 Mov DI, AX Mov AL, LPendL3 STOSB ;Place AL Char. in top-left corner of screen Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL3+1 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL3+2 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, LPendL3+3 STOSB ; now second char... Add DI, 1 Mov AL, LpendL3+4 STOSB Add DI, 1 Mov AL, LpendL3+5 STOSB Jmp Done SwingR: Mov PendLR, "R" ;Remember the Swing Right... Mov AL, RPendL1 STOSB ;Place AL Char. in top-left corner of screen Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, RPendL1+1 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, RPendL1+2 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, RPendL1+3 STOSB ; now second char... Add DI, 1 Mov AL, RPendL1+4 STOSB Add DI, 1 Mov AL, RPendL1+5 STOSB Mov AX, 0188H ;Line 2, Col.64 Mov DI, AX Mov AL, RPendL2 STOSB ;Place AL Char. in top-left corner of screen Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, RPendL2+1 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, RPendL2+2 STOSB ; now second char... Add DI, 1 ; Step to nxt char over Attribute Character Mov AL, RPendL2+3 STOSB ; now second char... Add DI, 1 Mov AL, RPendL2+4 STOSB Add DI, 1 Mov AL, RPendL2+5 STOSB Mov AX, 0228H ;line 3 column 40 Mov DI, AX Mov AL, RPendL3 STOSB ;place AL character in top left corner of screen Add DI, 1 ;step to next character over attribute char Mov AL, RPendL3+1 STOSB ;place AL character in top left corner of screen Add DI, 1 ;step to next character over attribute char Mov AL, RPendL3+2 STOSB ;place AL character in top left corner of screen Add DI, 1 ;step to next character over attribute char Mov AL, RPendL3+3 STOSB ;place AL character in top left corner of screen Add DI, 1 ;step to next character over attribute char Mov AL, RPendL3+4 STOSB ;place AL character in top left corner of screen Add DI, 1 ;step to next character over attribute char Mov AL, RPendL3+5 STOSB Done: PopF Pop DI Pop AX Pop ES Pop SI Pop DS ; Restore DS IRET ;*Return to the program you were running ; when the Interrupt occured..... ;****************************************************************************** ; Set the Clock Interrupt Vector Segment & Offset Addresses to ; our own routine... ChgVector: Mov AL, IntNo ; Interrupt Mov AH, 35H ; DOS Int21H function to get Vector Int 21H Mov Word PTR OldVect, BX ; and Save Mov Word PTR OldVect+2, ES ; it.... Mov AX, 0 ;Set ES to Memory Segment 0 Mov ES, AX ; 0000H Mov DS, AX CLD ;Go forward Mov DI, IntNo*4 ;Set DI offset to the 0Hth Interrupt CLI ;Disable Interrupts Mov AX, OffSet My_Int_TSR STOSW ; Place our Clock_Int offset Mov AX, CS ; and CS Segment Address STOSW ; in the INT 0 Vector Table STI ;Enable Interrupts ; Now EXIT from this program, leaving 20H Paragraphs of it in memory.... Mov DX, 30H ;*Tell TSR to keep 30H Paragraphs of ; 16 bytes each in memory Mov AH, 31H ;*Terminate process, Stay Resident in ; memory TSR Int 21H ;*DOS Int .... Exit Prog, Prog.stays ; in memory ;****************************************************************************** Code EndS End Prog_Start