Convert 16 bit to a similar 32 bit program

Started by Magnum, December 14, 2010, 06:19:41 PM

Previous topic - Next topic

Magnum

I would like to convert this to 32 bit.


; Screen saver (blanks screen)   COM file..
; Only works in 80x25 screen modes (2,3,7) [could easily be adapted/others]
;        Uses F-8 key to activate, un-install by typing name of program again
;
;   **** ADJUSTABLE time interval to pop up
;
;   Program can be uninstalled                                                                                                                                                                                                                                      
;        
;
.SEQ               ; store segment sequentially as they appear
.286               ; use 80286+ code
.MODEL tiny        ; TINY model to make it a .COM program

;* Macros *

StAlloc MACRO sizew    ; macro to allocate stack, size "sizew" words
MOV BX,((sizew*2)+15) SHR 4    ; BX = size in paragraphs
MOV AH,48h        ; allocate memory function
INT 21h           ; call DOS
CLI               ; freeze interrupts
MOV SS,AX         ; set stack segment to allocated segment returned in AX
MOV SP,sizew*2-2  ; set stack pointer to end of segment (goes top down)
STI               ; restore interrupts
ENDM

StDeAlloc MACRO    ; macro to deallocate stack
MOV AX,SS
MOV ES,AX
MOV AH,49h        ; call DOS deallocate block function
INT 21h
ENDM

;* Code Segment *

code SEGMENT PARA PUBLIC 'CODE'    ; code segment
ASSUME CS:code, DS:code, ES:code, SS:code  ; assume CS->"code" etc.
ORG 100h                           ; start assembling at offset 0h (default)

;* Program Start *

start:               ; label for start of program
JMP init

;* Procedures *

; Save screen and display (init) screen saver logo

ScreenSaver PROC NEAR

MOV AX,CS
MOV ES,AX
MOV DI,OFFSET ScrData
MOV DS,CS:ScrAddress
XOR SI,SI
CLD
MOV CX,2000
REP MOVSW           ; save screen
MOV CS:SSOn,1

MOV AH,0Fh
INT 10h             ; get current page in BH
MOV AH,03h
INT 10h             ; get old cursor size
MOV CS:OldCursor,CX
MOV AH,01h
MOV CX,0100h
INT 10h             ; hide cursor
CALL RunSaver       ; clear screen
CALL DrawSaver      ; draw logo
RET

ENDP

; Restore screen and deinitialize screen saver

RemoveSaver PROC NEAR

MOV ES,CS:ScrAddress
XOR DI,DI
MOV AX,CS
MOV DS,AX
MOV SI,OFFSET ScrData
CLD
MOV CX,2000
REP MOVSW
MOV CS:SSOn,0
MOV AH,01h
MOV CX,CS:OldCursor
INT 10h           ; restore cursor
RET
ENDP

; Re-hide screen to cover any writing

RunSaver PROC NEAR

MOV ES,CS:ScrAddress
XOR DI,DI
MOV CX,2000
XOR AX,AX
REP STOSW
RET

ENDP

; Find parts of screen that were changed and save to virtual screen

DeltaSaver PROC NEAR

CLD
MOV DS,CS:ScrAddress
XOR SI,SI            ; DS:SI -> physical screen
MOV AX,CS
MOV ES,AX            
MOV DI,OFFSET ScrData  ; ES:DI -> virtual screen
XOR BH,BH            ; row 0

ds_nextrow:

MOV CX,80
CMP BH,CS:Row        
JZ ds_check          ; if row of copyright string handle separately

ds_loop:

LODSW
CMP AX,0             ; check if still zero (as set by screen saver)
JZ ds_again

MOV ES:[DI],AX       ; set to new value

ds_again:

INC DI
INC DI
LOOP ds_loop

ds_new:

INC BH
CMP BH,25
JNZ ds_nextrow
RET

ds_check:

MOV BP,OFFSET Copyright
MOV BL,CS:Color

ds_loop2:

LODSW
CMP AL,ES:[BP]
JNZ ds_delta
CMP AH,BL
JZ ds_ok
ds_delta:
MOV ES:[DI],AX
ds_ok:
INC DI
INC DI
INC BP
LOOP ds_loop2
JMP SHORT ds_new
ENDP

; Draw copyright string

DrawSaver PROC NEAR
MOV AX,WORD PTR CS:Row2
MOV WORD PTR CS:Row,AX  ; now safe to copy incremented data
MOV AH,CS:Row
MOV AL,160
MUL AH
MOV DI,AX
MOV AX,CS
MOV DS,AX
MOV SI,OFFSET CS:Copyright
MOV AH,CS:Color
ds_write:
LODSB
OR AL,AL
JZ ds_donemsg
STOSW
JMP SHORT ds_write
ds_donemsg:
RET
ENDP

; move message and change color

IncSaver PROC NEAR
MOV AX,WORD PTR CS:Row2  ; AL = row, AH = attribute
ADD AX,101h              ; increment both
CMP AL,25
JNZ is_rowset

XOR AL,AL
is_rowset:
CMP AH,16
JNZ is_colset
MOV AH,1
is_colset:
MOV WORD PTR CS:Row2,AX
RET
ENDP

; INT 09h interrupt handler
; checks for hotkey combinations and deinstalls or activates program if found

Int09Handler PROC FAR
PUSHF
CALL CS:OldInt09      ; call old handler
PUSHA
PUSH DS
PUSH ES
MOV AX,40h
MOV ES,AX
MOV DI,ES:[1Ah]
CMP DI,ES:[1Ch]       ; quit if no keys in keyboard buffer
JZ i9_exit
MOV CS:SSTimer,0      ; zero timer for screen saver
CMP CS:SSOn,0
JZ i9_skip
CALL RemoveSaver      ; if screen saver active, restore screen
i9_skip:
MOV DI,ES:[DI]        ; get key in keyboard buffer
CMP DI,4200h          ; check for F8 , zeroes needed after scan code
JNZ i9_exit
PUSH DI
PUSH ES
CALL ScreenSaver      ; startup screen saver
POP ES
POP DI
i9_remove:
INC WORD PTR ES:[1Ah]
INC WORD PTR ES:[1Ah] ; remove key from buffer
CMP WORD PTR ES:[1Ah],3Eh
JNZ i9_exit
MOV WORD PTR ES:[1Ah],1Eh      ; wrap around if required
i9_exit:
POP ES
POP DS
POPA
IRET
ENDP

; INT 1Ch interrupt handler
; activates screen saver when timeout occurs

Int1CHandler PROC FAR
PUSHF
CALL CS:OldInt1C
PUSHA
PUSH DS

PUSH ES
CMP CS:SSOn,0
JZ i1c_off
CALL DeltaSaver      ; store changes to virtual screen
CALL RunSaver        ; blank screen
CALL DrawSaver       ; draw message or graphic
i1c_off:
MOV AL,CS:Timer1
DEC AL
MOV CS:Timer1,AL
JNZ i1c_exit
MOV AH,18
MOV AL,CS:Timer2
DEC AL
JNZ i1c_not19
INC AH
MOV AL,5
i1c_not19:
MOV CS:Timer2,AL
MOV CS:Timer1,AH
CMP CS:SSOn,0
JZ i1c_count
CALL IncSaver
JMP SHORT i1c_exit
i1c_count:
MOV AX,CS:SSTimer
INC AX
MOV CS:SSTimer,AX
CMP AX,180           ; 3 minutes (min x 60 secs)
JNZ i1c_exit
XOR AX,AX
MOV CS:SSTimer,AX    ; set to zero
CALL ScreenSaver     ; startup screen saver
i1c_exit:
POP ES
POP DS
POPA
IRET
ENDP

; TSR data

ScrAddress DW 0
OldCursor  DW 0
OldInt09   DD 0
OldInt1C   DD 0
SSTimer    DW 0
SSOn       DB 0
Timer1     DB 18
Timer2     DB 5
ScrData    DW 2000 DUP (?)
Row        DB 0
Color      DB 1
Row2       DB 0
Color2     DB 1
Copyright  DB 'è The Kennedy Family',0
Sig        DB 'VXSS'

TSR_end LABEL BYTE

; * Main Program *

init:
MOV AX,CS
MOV DS,AX
MOV ES,AX
MOV BX,OFFSET code_end
ADD BX,15
SHR BX,4
MOV AH,4AH
INT 21H                         ; free unneeded memory given to program
StAlloc 50h                     ; allocate stack (saves memory on disk)
XOR AX,AX
MOV ES,AX
PUSH DS
MOV DS,ES:[26h]
CMP WORD PTR DS:Sig,'XV'
JNZ i_skip
CMP WORD PTR DS:Sig+2,'SS'
JNZ i_skip
MOV AX,WORD PTR DS:OldInt09
MOV BX,WORD PTR DS:OldInt09+2
CLI
MOV ES:[24h],AX
MOV ES:[26h],BX
MOV AX,WORD PTR DS:OldInt1C
MOV BX,WORD PTR DS:OldInt1C+2
MOV ES:[70h],AX
MOV ES:[72h],BX
STI
MOV AX,DS
MOV ES,AX
MOV AH,49h
INT 21h
POP DS
MOV AH,09h
MOV DX,OFFSET Deinstall
INT 21h
StDeAlloc
MOV AX,4C00h
INT 21h

i_skip:

POP DS
MOV AX,0B800h
CMP BYTE PTR ES:[0449h],7       ; check if current mode @ 0:449 is 7 (mono)
JNZ i_gotmode
MOV AX,0B000h

i_gotmode:
MOV ScrAddress,AX               ; store screen address
MOV AX,ES:[24h]
MOV BX,ES:[26h]
MOV WORD PTR OldInt09,AX
MOV WORD PTR OldInt09+2,BX      ; save old interrupt 09h
MOV AX,OFFSET Int09Handler
MOV BX,CS
CLI
MOV ES:[24h],AX
MOV ES:[26h],BX
STI
MOV AX,ES:[70h]
MOV BX,ES:[72h]
MOV WORD PTR OldInt1C,AX

MOV WORD PTR OldInt1C+2,BX      ; save old interrupt 1Ch
MOV AX,OFFSET Int1CHandler
MOV BX,CS
CLI
MOV ES:[70h],AX
MOV ES:[72h],BX
STI
MOV AH,49h
MOV ES,CS:[2Ch]
INT 21h                         ; deallocate environment block
MOV AH,09h
MOV DX,OFFSET Install
INT 21h                         ; display message
StDeAlloc                       ; deallocate stack
MOV DX,OFFSET TSR_end
ADD DX,15
SHR DX,4
MOV AX,3100h
INT 21h                         ; go TSR, exit with errorlevel 0

;* Data Area *

; main program data

Install     DB 13,10,'Screen Saver now installed - press F8 to activate.'
           DB 13,10,'Type Saver again to un-install.',13,10,10,'$'

Deinstall   DB 13,10,'Screen Saver un-installed Ok.',13,10,10,'$'

;* End Program *

code_end LABEL BYTE         ; mark end of code segment (end of program)
code ENDS                   ; end code segment "code"

Have a great day,
                         Andy

redskull

No can do.  You can't hook interrupts, install TSRs, or write to video memory in protected mode.  Windows has it's own screensaver model for a reason (google for ScrnSave.Lib)
Strange women, lying in ponds, distributing swords, is no basis for a system of government

Magnum

Have a great day,
                         Andy

oex

What do you mean by the 'hotkey' part? "Press F8 to activate"? or keypress to deactivate? or....?

A screensaver needs to be registered in various places including the registry, it needs to be aware of obvious things such as keypresses, mouse movements etc and also windows messages such as SC_SCREENSAVE and SC_MONITORPOWER....

As red says this is all in ScrnSave.Lib however this can also be done manually without the library
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

redskull

Quote from: Magnum on December 14, 2010, 06:54:52 PM
I am mainly interested in the hotkey part.

I say again, you cannot hook interrupts.  This program works by intercepting all the keyboard input *before* it gets to the operating system, which under Windows is generally referred to as 'malware'.

If you are intent on finding a hotkey solution without too much trouble, it's already built into Windows.  Write a program that does what you need doing, create a shortcut to it, and then set the 'shortcut key' in it's properties to whatever key you want to run it.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

Magnum

Hotkey code to output text.

Screensaver is not needed.

Have a great day,
                         Andy

oex

We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

GregL

Magnum,

You could also use the C Run-Time function _getch().  This is a blocking function, it will stop and wait for a key to be pressed.  GetAsyncKeyState would be better if you don't want to block.


INVOKE crt__getch
.IF (eax == 0) || (eax == 0E0h)
    INVOKE crt__getch
    .IF eax == 77h    ; F8 key code
        ; F8 was pressed
    .ENDIF
.ENDIF


Disclaimer: Code is just from memory and not tested.

Magnum

That would not work.

My wish list

Ideal Scenario

Pressing [Windows Key + I] would send "My tooth is infected." to the clipboard.

Then I could do a Shift Insert to put it in a document etc.

Pressing [Ctrl G] would send "Proper Planning Prevents Poor Performance" to the clipboard also.

I posted on MSFN to find out all the key combinations that Windows uses, so I don't tromp on them.

This program would be useful for a number of reasons, but in particular because I have turned off those functions like history and "remembering what you have typed."






.data

bHidden db 0

.code

invoke GetAsyncKeyState,VK_W          ;// VK_SHIFT and VK_W    is what I'd like to use for instance
.IF eax!=0
.if bHidden == 0
invoke ShowWindow, hWin, SW_HIDE
inc bHidden

.elseif bHidden == 1
invoke ShowWindow, hWin, SW_SHOW
dec bHidden
.endif
        .ENDIF

.elseif uMsg == WM_KEYDOWN
invoke GetKeyState, VK_SHIFT
mov    esi, eax
shr    esi, 15
invoke GetKeyState, VK_CONTROL
mov    edi, eax
shr    edi, 15
.if esi && wParam == VK_A
; shift+A
.elseif esi && edi && wParam == VK_B
; shift+ctrl+B
.endif
Have a great day,
                         Andy

GregL

Quote from: MagnumI posted on MSFN to find out all the key combinations that Windows uses, so I don't tromp on them.

Virtual Key Codes

Magnum

Sorry, I made a mistake.

Since Shift Insert is reserved by Windows, I can use that as a hotkey.

Have a great day,
                         Andy

Magnum

Have a great day,
                         Andy

GregL


Magnum

I have a program that creates a keyboard shortcut and sends text to the clipboard.

I then do a Shift Insert to put the text into a document.

What I am looking for is info or help with sending the text to some other place other
than the clipboard in order to use more than one keyboard shortcut.

Ex.

Ctrl Alt A -> inserts "user1"

Ctrl Alt B -> inserts "password"
Have a great day,
                         Andy

oex

We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv