Flicker Remover

This is one of the programs I wrote long time back in the year 1994, this helped me a lot as my moniter used to flicker as I scrolled down. Back in those days we used to have CGA monitors and for some reason (I dont know why) my computer's system bios was programmed to turn of the signal to the monitor when moving data in the display area.

It is not much of use now, but at least this helps me look back on my DOS Days.

;------------ FLICKER REMOVER --------------------- EN#1.5SRW01R-----------\
; A Terminate and stay resident program to remove flicker in the display.  :
; Must me converted into a .COM file.                                      :
; Solely - Titas Raha, 17 Uttarpalli, Sodepur, 24 P.G.S (N) WB-743178      :
;--------------------------------------------------------------------------/

GETKBD                   EQU      3509h   ; Get keyboard interrupt No.
SETKBD                   EQU      2509h   ; Set keyboard interrupt No.
GET10                    EQU      3510h   ; Get BIOS Hex. 10 interrupt
SET10                    EQU      2510h   ; Set BIOS Hex. 10 interrupt
BIOSSEG                  EQU      40h     ; BIOS segment address
NOBIOS                   EQU      0FFh    ; Indicates not to use BIOS
CHANGEKEY                EQU      55      ; Print Screen key scan code


code                     SEGMENT          ; Program segment starts here
                         ASSUME cs:code, ds:code

                         ORG 10h          ; Equipment flag offset
EQUIPFLAG                LABEL WORD
                         ORG 17h          ; Keyboard status flag offset
KBFLAG                   LABEL BYTE
                         ORG 49h          ; CRT mode indicator offset
CRTMODE                  LABEL BYTE
                         ORG 4Ah          ; Current no. of columns offset
CRTCOLS                  LABEL WORD
                         ORG 4Eh          ; Current page offset
CRTSTART                 LABEL WORD
                         ORG 100h         ; Leave 256 bytes for PSP

RESIDENT                 EQU ((OFFSET RESEND - OFFSET RESSTART + 100h) SHR 4)+1
                                          ; Calculate the resident length
RESSTART                 LABEL WORD       ; Beginning of the resident portion

start:                   jmp main         ; Jump to the main

option                   db   NOBIOS      ; Declare, set option not to use BIOS
org10                    dw   0, 0        ; Original address BIOS Hex. 10 int.
orgkbd                   dw   0, 0        ; Original Keyboard interrupt address

new10                    PROC   FAR       ; New redirected BIOS Hex. 10 int.

                         cmp   cs:option,NOBIOS ; Use BIOS or this procedure
                         jne   origbios   ; No call BIOS routine
                         sti              ; Allow interrupts
                         cmp   ah,7       ; Is it scroll down ?
                         je    scroll     ; Yes, follow from scroll
                         cmp   ah,6       ; Is it scroll up ?
                         jne   orig       ; If not call BIOS

scroll:                  push  ds         ; Save registers to use
                         push  es
                         push  di
                         push  ax
                         mov   ax,BIOSSEG ; Get the BIOS Data segment
                         mov   ds,ax      ; Put it as program's Data Seg
                         mov   ax,0B800h  ; Default CGA's base address
                         mov   di,EQUIPFLAG ; Get the Equipment flag
                         and   di,30h     ; Get the card status
                         cmp   di,30h     ; Check for mono
                         jne   nomono     ; If not, skip
                         mov   ah,0B0h    ; Get the mono base address
nomono:                  mov   es,ax      ; Save whichever card's address
                         mov   ah,CRTMODE ; Get the current screen mode
                         cmp   ah,4       ; Check for text mode
                         jc    myscroll   ; Yes, procedure can handle it
                         cmp   ah,7       ; Check for mono
                         je    myscroll   ; Can also handle mono
                         pop   ax         ; No, its Graphics
                         pop   di         ;     get back saved registers
                         pop   es
                         pop   ds
orig:                    cli              ; Turn off interrupts
origbios:                jmp   dword ptr cs:[org10] ; Call original BIOS

myscroll:                pop   ax         ; Get back AX
                         push  dx         ; Save other registers
                         push  cx
                         push  bx
                         push  si
                         push  bp
                         mov   bl,al      ; Get No. of lines to BL
                         push  bx         ; Save the attribute
                         cmp   ah,6       ; Is it scroll up ?
                         je    scrollup   ; Yes, perform scroll up
                         std              ; No, set direction flag
                         mov   ax,dx      ; Lower right corner
                         call  scrollpos  ; Adjust before scroll
                         pushf            ; Save flags changed by scrollpos
                         neg   bp         ; Negate for scroll down
                         neg   ax
                         popf             ; Get back original flag condition
                         jmp   genscroll  ; Do common scroll
scrollup:                mov   ax,cx      ; Upper left position
                         cld              ; forward movement for scroll up
                         call  scrollpos  ; Adjust before scroll
genscroll:               jz    clrscr     ; If lines to scroll = 0 then CLS
                         add   si,ax      ; Get actual position
                         mov   ah,dh      ; Rows in the window
                         sub   ah,bl      ; No. of rows to be moved
vmemshift:               mov   cl,dl      ; No. of cells to be filled
                         push  si         ; Save scroll position
                         push  di
                         rep movsw        ; Move one line
                         pop   di         ; Recover previous position
                         pop   si
                         add   si,bp      ; Reposition source
                         add   di,bp      ; Reposition destination
                         dec   ah         ; Decrease rows left
                         jnz   vmemshift  ; Until AH = 0
clsfill:                 pop   ax         ; Get back the attribute saved by BX
                         mov   al,' '     ; Fill with spaces
scrollcls:               mov   cl,dl      ; No. of cells to fill
                         push  di         ; Save destination
                         rep   stosw      ; Clear a row
                         pop   di         ; Get back previous destination
                         add   di,bp      ; Reposition destination
                         dec   bl         ; Decrease rows to blank
                         jnz   scrollcls  ; Until BL = 0
                         pop   bp         ; Get back saved registers
                         pop   si
                         pop   bx
                         pop   cx
                         pop   dx
                         pop   di
                         pop   es
                         pop   ds
                         iret             ; Interrupt return

clrscr:                  mov   bl,dh      ; Get no of rows
                         jmp   clsfill    ; Continue from clsfill

new10                    ENDP

scrollpos                PROC  NEAR

                         push  bx         ; Save BX
                         mov   bx,ax
                         mov   al,ah      ; Rows to AL
                         mul   byte ptr CRTCOLS ; Bytes to rows
                         xor   bh,bh      ; Clear high bits
                         add   ax,bx      ; Add in column value
                         sal   ax,1       ; Multiply by 2 for attribute byte
                         pop   bx         ; Get back BX
                         add   ax,CRTSTART ; Offset of active page
                         mov   di,ax      ; Destination address for scroll
                         mov   si,ax      ; Source address for scroll
                         sub   dx,cx      ; Get width and height
                         inc   dh         ; Add one to row
                         inc   dl         ; Add one to column
                         xor   ch,ch      ; Clear high bits
                         mov   bp,CRTCOLS ; No. of lines in display
                         add   bp,bp      ; X 2 for attribute
                         mov   al,bl      ; Get line count
                         mul   byte ptr CRTCOLS ; Offset to from address
                         add   ax,ax      ; X 2 for attribute
                         push  es
                         pop   ds         ; Let DS also point to V memory
                         cmp   bl,0       ; Is BL = 0 ?
                         ret              ; Return

scrollpos                ENDP

newkbd                   PROC  FAR        ; Rerouted keyboard handler

                         push  ax         ; Save registers to use
                         push  ds
                         mov   ax,BIOSSEG ; Get the BIOS Data segment
                         mov   ds,ax      ; Put it in DS
                         test  byte ptr KBFLAG,8 ; Test for  key
                         pop   ds         ; Get back original DS
                         jz    nospl      ; If no  key pressed
                         in    al,60h     ;  pressed, Get the character
                         cmp   al,CHANGEKEY ; Is the character PrtSc key ?
                         jnz   nospl      ; If not call original handler
                         not   byte ptr cs:[option] ; Change option flag
nospl:                   pop   ax         ; Get back AX
                         jmp   dword ptr cs:[orgkbd] ; Call original handler

newkbd                   ENDP

RESEND                   LABEL WORD       ; End of resident portion

main:                    mov   ax,cs      ; Get the Code segment
                         mov   ds,ax      ; Save it in DS

                         mov   ah,9       ; DOS subfunction for string write
                         lea   dx,heading ; Get the heading
                         int   21h        ; DOS int 21 does it
                         mov   ax,GET10   ; GET the INT 10h vector
                         int   21h
                         mov   ax,es      ; Get the Segment
                         cmp   ax,0D000h  ; Is it greater then D000 ?
                         ja    continue   ; Yes, continue
                         mov   ah,9       ; No, Subfunction for string write
                         lea   dx,alreadyld ; Get message to be displayed
                         int   21h        ; Display the message
                         int   20h        ; Terminate as a normal program

continue:                mov   org10,bx   ; Save offset of Hex 10. INT vector
                         mov   org10+2,es ; Save segment of Hex. 10 INT vector
                         mov   ax,GETKBD  ; Get the keyboard interrupt vector
                         int   21h        ; DOS INT 21h does it
                         mov   orgkbd,bx  ; Save its offset
                         mov   orgkbd+2,es ; Save its segment
                         lea   dx,new10   ; Offset of the new scroll routine
                         mov   ax,SET10   ; Set the new INT 10h
                         int   21h
                         lea   dx,newkbd  ; Get the new keyboard handler
                         mov   ax,SETKBD  ; Set the new keyboard handler
                         int   21h
                         lea   dx,loaded  ; Get the message to be displayed
                         mov   ah,9       ; Subfunction to do it
                         int   21h        ; DOS 21h does it
                         mov   ax,3100h   ; Initiate residency
                         mov   dx,RESIDENT ; Set no. of para to be resident
                         int   21h        ; DOS 21h does it


heading          db    13,10
                 db    9,'FLICKER REMOVER',9,9,9,'EN#1.5SRW01R  12/5/94',13,10
                 db    9,'---------------',9,9,9,'---------------------',13,10,10
                 db    'FLICKOFF.COM Solely by - Titas Raha, 17 Uttarpalli, Sodepur',13,10
                 db    'Dist. 24 Parganas (N), WEST BENGAL - 743178. PH: 5535195.'
                 db    13,10,10,'$'

alreadyld        db    'Problem! Either the program is already loaded',13,10
                 db    'or some program have redirected the BIOS Hex. 10',13,10
                 db    'interrupt vector.  If this program was not loaded',13,10
                 db    'earlier then make sure that this is the first TSR',13,10
                 db    'which is run after booting.'
                 db    13,10,10,'$'

loaded           db    'Resident portion loaded.',13,10,10
                 db    'Pressing + changes between BIOS and',13,10
                 db    "the loaded program's scroll handling routine."
                 db    13,10,10,'$'

code                     ends             ; End of the code segment
                         end start        ; End of program

Navigation

Useful Links