2000 ; Gamma correction TSR ; Uses Delta DSR input signal on COM port to install/remove kbd handler :-) .MODEL TINY .386 .CODE ORG 100h start: jmp main ;**************************** Resident data scan db ? org_int08 dd ? org_int09 dd ? org_int0B dd ? kbd_installed db 0 old_code db 0 ; Delvis taget fr†n TVGA-BIOS:et. Programmerar registren direkt. ; Skiter i att v„nta p† vsync till skillnad fr†n BIOS. Funkar fint „nd†. set_colors PROC pusha mov bl, 0 adjust_lp2: cli mov dx, 3C7h ;Get color register mov al, bl out dx, al ;Write register index jmp j1 j1: add dx, 2 in al, dx ;Read Red value jmp j2 j2: mov ah, al in al, dx ;Read Green value jmp j3 j3: mov ch, al in al, dx ;Read Blue value jmp j4 j4: mov cl, al sti cmp ah, 40 ;Check and adjust values jae nd1 add ah, 13 nd1: cmp ch, 40 jae nd2 add ch, 13 nd2: cmp cl, 40 jae nd3 add cl, 13 nd3: cli mov dx, 3C8h ; Set color register mov al, bl out dx, al jmp j5 j5: inc dx mov al, ah out dx, al jmp j6 j6: mov al, ch out dx, al jmp j7 j7: mov al, cl out dx, al sti inc bl jnz adjust_lp2 popa ret set_colors ENDP newint09 PROC FAR sti push ax in al,60h ; Get scancode from keyboard processor cmp al, cs:old_code jz no_hotkey mov cs:old_code, al cmp al, 058h ; Check if F12 jz skip_shifttst jmp no_hotkey test_shift: mov cs:scan, al ; Save scan code push es ; look into BIOS data area sub ax, ax ; (segment 0) to check shift state mov es, ax mov ax, es:[417h] ; Get SHIFT-key flags test ax, 0000000000001000b ; Check if Alt-key pressed pop es jz no_hotkey skip_shifttst: cli ; Disable interrupts while resetting in al, 61h ; Get current port 61h state or al, 10000000b ; Turn on bit 7 to signal clear keybrd out 61h, al ; Send to port and al, 01111111b ; Turn off bit 7 to signal break out 61h, al ; Send to port call set_colors mov al, 20h ; Reset interrupt controller out 20h, al sti pop ax iret no_hotkey: pop ax ; Recover AX and fall through cli ; Interrupts cleared for service jmp cs:org_int09 ; jump to old Int 09 routine newint09 ENDP newint0B PROC FAR push ax push dx chk_pending: mov dx, 2FAh ;Check if pending int in al, dx test al, 1 jnz exit_int mov dx, 2FEh ;Read MSR in al, dx test al, 2 ;Check if Delta DSR jz no_DDSR push es push di mov ax, 0 mov es, ax mov di, 24h test byte ptr cs:kbd_installed, 1 jnz uninstall mov ax, word ptr es:[di] ;Save old INT09 mov word ptr cs:[org_int09], ax mov ax, word ptr es:[di + 2] mov word ptr cs:[org_int09 + 2], ax cli mov ax, offset newint09 ;Install new INT09 mov word ptr es:[di], ax mov ax, cs mov word ptr es:[di + 2], ax sti mov byte ptr cs:kbd_installed, 1 jmp over_uninstall uninstall: cli mov ax, word ptr cs:[org_int09] ;Restore old INT09 mov word ptr es:[di], ax mov ax, word ptr cs:[org_int09 + 2] mov word ptr es:[di + 2], ax sti mov byte ptr cs:kbd_installed, 0 over_uninstall: pop di pop es no_DDSR: jmp chk_pending exit_int: sti mov al, 20h out 20h, al pop dx pop ax iret newint0B ENDP ;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ Transient Section ;**************************** Transient data header db 'GAMMA Gamma correction TSR v1.0',13, 10, '$' hotkeys db 'Press F12 to adjust gamma', 13, 10, 13, 10, '$' uninstalled db 13, 10, 'Un' installed db 'Installed Successfully',13,10,'$' syntax db 'Syntax: GAMMA [/U]',13,10,'$' nomemory db 'Out of memory',13,10,'$' alreadyin db 'Already installed',13,10,'$' notfound db 'Resident copy not found',13,10,'$' cantunload db 'Can''t uninstall',13,10,'$' resname db 'GammaTsr' resseg dw 0 ;**************************** Main -- Main procedure main PROC mov ah,9 ;Print install message mov dx, offset header int 21h call findres ;Find resident copy mov al,'/' ;Search for slash xor cx, cx ;in command line mov cl, byte ptr cs:[80h] mov di, 81h repne scasb jne nounload ;No slash, don't unload mov dx, offset syntax ;DX = 'Syntax:' string cmp byte ptr[di], 'U' ;/U or /u, unload je unload cmp byte ptr[di], 'u' je unload cmp byte ptr[di], '?' ;/?, print syntax je error nounload: mov dx, offset alreadyin ;Point DX to error string cmp resseg, 0 ;Already installed? jne error cld ;Clear direction flag mov ax, offset lastbyte ;AX = last byte + 256 inc ah cmp ax, sp ;Check for too little memory jbe memOK mov dx, offset nomemory ;Print 'Out of memory' string error: mov ah, 9 int 21h mov ax, 4C01h ;Exit with error int 21h memOK: mov sp, ax ;Shrink stack jmp load ;Jump to Load procedure main ENDP ;**************************** Load -- TSR loader procedure load PROC mov ah,49h ;Free environment segment mov es, cs:[2Ch] int 21h mov dx, 02FBh in al, dx and al, 07fh ; Clear divisor latch access bit out dx, al mov dx, 2F9h ; IER mov al, 08h ; Enable Modem Status interrupt out dx, al mov dx, 2FCh ; Activate tri-state gate between mov al, 0fh ; UART and PIC (OUT2) out dx, al mov ax, 350Bh ; Get old INT0B vector int 21h mov word ptr[org_int0B], bx mov word ptr[org_int0B + 2], es mov ax, 250Bh ; Install new INT0B vector mov dx, offset newint0B int 21h mov dx, 21h in al, dx and al, 0F7h ; Enable IRQ 3 out dx, al mov ah, 7fh clean_lp: mov dx, 2F8h in al, dx ;Reset RBR add dx, 2 in al, dx ;Reset IIR add dx, 3 in al, dx ;Reset LSR inc dx in al, dx ;Reset MSR sub dx, 4 in al, dx test al, 1 ;Check if pending interrupt jnz all_clean dec ah jnz clean_lp all_clean: mov ax, cs ;ES = MCB segment (CS - 1) dec ax mov es, ax mov si, offset resname ;Change resident name mov di, 8 mov cx, di rep movsb mov ah, 9 mov dx, offset hotkeys ;Print hot-key text int 21h mov ah, 9 ;Print 'Installed' string mov dx, offset installed int 21h mov dx, offset header ;Last byte of program lastbyte: int 27h ;DOS TSR service load ENDP ;**************************** Unload -- Uninstall procedure unload PROC mov cx, resseg ;CX = resident segment mov dx, offset notfound ;Point DX to error string test cx, cx ;Make sure it's in memory je error mov dx, offset cantunload ;Point DX to error string mov ax, 350Bh ;Check to make sure that the int 21h ;interrupts still point to cmp bx, offset newint0B ;the resident copy... jne error mov es, resseg ;ES = resident segment mov dx, 21h in al, dx or al, 08h ;disable IRQ 3 out dx, al mov dx, 2FBh in al, dx and al, 07fh ;Clear divisor latch access bit in xxB... out dx, al mov dx, 2F9h mov al, 00h ;Clear interrupt bits in IER out dx, al mov dx, 2FCh ;DeActivate tri-state gate between mov al, 00h ;UART and PIC (OUT2) out dx, al mov ax, 250Bh ;Reset INT0B vector mov dx, word ptr es:[org_int0B] mov ds, word ptr es:[org_int0B + 2] int 21h mov ah, 49h ;Release memory segment int 21h push cs ;DS = CS pop ds mov byte ptr[installed], 'i';Fix 'Uninstalled' string mov ah,9 ;Print 'Uninstalled' string mov dx, offset uninstalled int 21h mov ax, 4C00h ;Quit program int 21h unload ENDP ;**************************** FindRes -- Find resident copy findres PROC pusha ;Save registers push es mov ax,5802h ;Save UMB link status int 21h push ax mov ax, 5803h ;Link UMBs mov bx, 1 int 21h mov ah, 52h ;Get Internal Config Table int 21h sub bx, 2 ;BX = first MCB mov bx, es:[bx] fr_lp: mov es, bx ;ES = 1af MCB segment cmp dword ptr es:[8], 6d6d6147h ;Check for signature je fr_found add bx, es:[3] ;Step to next one inc bx cmp byte ptr es:[0],'Z' ;Last one in chain? jne fr_lp ;Loop back mov bx,-1 ;Return 0 (-1 + 1 = 0) fr_found: inc bx mov resseg, bx ;Return resident segment mov ax, 5803h ;Restore UMB link status pop bx int 21h pop es popa ret findres ENDP END start . 0