home *** CD-ROM | disk | FTP | other *** search
- ; This code supports an article in issue #51 of:
-
- ; Micro Cornucopia Magazine
- ; P.O. Box 223
- ; Bend, OR 97709
-
- ; This macro gets around a bug in 80286 that won't popf correctly
- POPFF MACRO
- JMP $+3
- IRET
- PUSH CS
- DB 0E8H,0FBH,0FFH ;Call far $-2
- ENDM
-
- REFRESH SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:REFRESH, DS:REFRESH, ES:REFRESH, SS:NOTHING
- ORG 100h ; .COM format
-
- REFR PROC FAR
-
- BEGIN:
- JMP OVER ; Jump over resident section of code
-
- OLD_40 DD 0 ; Place to store old INT 40H vector
-
- I_40:
- PUSHF
- PUSH AX ; Save the registers we're changing
-
- MOV AL, 74H
- OUT 43H, AL ; Set up to write LSB-MSB clock rate
- JMP $+2 ; Delay for lousy IBM AT design
- MOV AL, 12H ; Set refresh to every 12h clock ticks
- OUT 41H, AL ; (15.3 u-secs ???)
- JMP $+2 ; More delay
- XOR AL, AL ; MSB of timer value to 0
- OUT 41H, AL
-
- POP AX ; Recover our trashed registers
- POPFF
-
- PUSHF ; (make this call look like an INT)
- CALL CS:[OLD_40] ; and call the original stuff
-
- PUSHF ; INT 40 done, restore fast DMA value
- PUSH AX ; Save the registers we're changing
-
- MOV AL, 74H ; Set up for LSB-MSB rate again
- OUT 43H, AL
- JMP $+2 ; More lousy delay
- MOV AL, 80H ; A reasonable value for timeout
- OUT 41H, AL ; That nets about 5% more CPU speed
- JMP $+2 ; for free
- XOR AL, AL ; Set MSB to 0
- OUT 41H, AL
-
- POP AX ; Restore trashed registers
- POPFF
- RET 2 ; IRET without popping flags
-
- ; This ends resident code section. From here on, we set things up and
- ; parse command line. Since this gets done only once, we don't want to
- ; save this code, so it also contains the means to decide how much
- ; memory to save when going resident.
-
- OVER: PUSH DS
- CLI ; Turn off INTs while revectoring INT
- XOR AX,AX ; INT vectors are at SEGMENT 0
- MOV DS,AX ; Set DS SEGMENT to zero
-
- ;Redirect the floppy
- MOV AX, DS:[100H] ;Get old addr, and store it here
- MOV WORD PTR CS:OLD_40,AX
- MOV AX, DS:[102H]
- MOV WORD PTR CS:OLD_40+2,AX
-
- MOV WORD PTR DS:[100H],OFFSET I_40 ; Then replace it with
- MOV WORD PTR DS:[102H],CS ; vector to floppy interceptor
-
- POP DS ; Put DS back where it belongs
-
- MOV AL, 74H ; Set DMA timer to slower value
- OUT 43H, AL ; (less refresh)
- JMP $+2
- MOV AL, 80H
- OUT 41H, AL
- JMP $+2
- XOR AL, AL
- OUT 41H, AL
-
- MOV AX,OFFSET OVER ; Get the addr of the end of INT code
- SHR AX,1
- SHR AX,1
- SHR AX,1
- SHR AX,1 ; Dvivde by 16 and add 1,
- INC AX ; to get how much memory to save
- MOV DX,AX ; Save the calculated amount of memory
- MOV AH,31H ; DOS func to terminate & stay residnt
- STI ; Allow interrupts again
- INT 21H ; Do DOS call (never returns)
-
- REFR ENDP
- REFRESH ENDS
- END BEGIN
-