1ba3 .MODEL TINY .386 .CODE ORG 100h start: jmp main ;**************************** Resident data org_int5 dd ? vidseg dw 0A000h handle dw 0 rgb db 3 dup (0) DACreg dw 0 fname db 'MCGA' tendig db '0' onedig db '0' db '.RAW',0 HSIHeader db 'mhwanh' dw 0400h,04001h,0c800h,0001h,0,0,0 db 12 dup (0) pal_buf db 768 dup(?) ;**************************** NewInt5 -- PrintScreen ********************* ScrDump PROC FAR push ax push bx push cx push dx push ds push es push cs pop ds mov ah, 0fh ;Check current video mode int 10h cmp al, 13h ;MCGA?? jz ok_mcga mov bx, 0A97h ;No, beep with 440 Hz and abort call beep jmp abort ok_mcga: mov ah, 3ch ;Create file mov cx, 00h mov dx, offset fname int 21h jc abort mov ax, 03d01h ;Open for writing mov dx, offset fname int 21h jc abort mov handle, ax inc onedig ;Update filename cmp onedig, '9' jle cont mov onedig, '0' inc tendig cmp tendig, '9' jle cont mov tendig, '0' cont: mov ah, 40h ;Write HSI Raw header to file mov bx, handle mov cx, 32 mov dx, offset HSIHeader int 21h mov ah, 10h ;Read all 256 DAC registers mov al, 17h mov bx, 0 mov cx, 256 push cs pop es mov dx, offset pal_buf int 10h mov cx, 256 * 3 ;256 DAC registers * rgb mov bx, offset pal_buf conv_pal: shl byte ptr[bx], 2 ;Multiply DAC values by 4 sinc inc bx ;Trident only has 64 discrete values loop conv_pal ;and HSI uses 256 mov ah, 40h ;Write palette to HSI file mov bx, handle mov cx, 256 * 3 ;256 * rgb mov dx, offset pal_buf int 21h push ds mov ah, 40h ;Write screen to HSI file mov cx, 64000 ;64000 bytes mov ds, vidseg ;MCGA video segment mov dx, 0 ;offset 0 int 21h pop ds mov ah, 3eh ;Close the file mov bx, handle int 21h ; mov bx, 054Bh ;Beep with 880 Hz to signal ready ; call beep abort: pop es pop ds pop dx pop cx pop bx pop ax iret ScrDump ENDP Beep PROC NEAR mov al, 0B6h out 43h, al mov al, bl ;Load divisor out 42h, al mov al, bh out 42h, al in al, 61h or al, 03h out 61h, al ;Turn on speaker mov ah, 86h ;Delay mov cx, 00003h ;250000 microseconds = 0.25 sec mov dx, 0D090h int 15h in al, 61h xor al, 03h out 61h, al ;Turn off speaker ret Beep ENDP ;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ Transient Section ;**************************** Transient data header db 'HSIDUMP Saves MCGA screens in HSI Raw format. Press to save.',13,10,'$' uninstalled db 'Un' installed db 'Installed Successfully',13,10,'$' syntax db 'Syntax: SCRSAV [/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 'HsiDump ' resseg dw 0 ;**************************** Main -- Main procedure main PROC mov ah,9 ;Print "Key128 v1.13..." string 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 ax, 3505h ;Get and store old INT5 address int 21h mov word ptr[org_int5], bx mov word ptr[org_int5+2], es mov ax, 2505h ;Set new PrintScreen handler mov dx, offset ScrDump int 21h 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 ;Print 'Installed' string mov dx, offset installed int 21h mov dx, offset header-1 ;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, 3505h ;Check to make sure that the int 21h ;interrupts still point to cmp bx, offset ScrDump ;the resident copy... jne error mov es, resseg ;ES = resident segment mov ax, 2505h ;Reset PrintScreen vector mov dx, word ptr es:[org_int5] mov ds, word ptr es:[org_int5+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 = MCB segment cmp word ptr es:[9], 6973h ;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