home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / microcrn / issue_51.arc / REFRESH.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-11-13  |  3.7 KB  |  106 lines

  1. ; This code supports an article in issue #51 of:
  2.  
  3. ; Micro Cornucopia Magazine
  4. ; P.O. Box 223
  5. ; Bend, OR 97709
  6.  
  7. ; This macro gets around a bug in 80286 that won't popf correctly
  8. POPFF   MACRO
  9.         JMP     $+3
  10.         IRET
  11.         PUSH    CS
  12.         DB      0E8H,0FBH,0FFH  ;Call far $-2
  13.         ENDM
  14.  
  15. REFRESH SEGMENT PARA PUBLIC 'CODE'
  16.         ASSUME  CS:REFRESH, DS:REFRESH, ES:REFRESH, SS:NOTHING
  17.         ORG     100h            ; .COM format
  18.  
  19. REFR    PROC    FAR
  20.  
  21. BEGIN:
  22.         JMP     OVER            ; Jump over resident section of code
  23.  
  24. OLD_40  DD      0               ; Place to store old INT 40H vector
  25.  
  26. I_40:
  27.         PUSHF
  28.         PUSH    AX              ; Save the registers we're changing
  29.  
  30.         MOV     AL, 74H
  31.         OUT     43H, AL         ; Set up to write LSB-MSB clock rate
  32.         JMP     $+2             ; Delay for lousy IBM AT design
  33.         MOV     AL, 12H         ; Set refresh to every 12h clock ticks
  34.         OUT     41H, AL         ; (15.3 u-secs ???)
  35.         JMP     $+2             ; More delay
  36.         XOR     AL, AL          ; MSB of timer value to 0
  37.         OUT     41H, AL
  38.  
  39.         POP     AX              ; Recover our trashed registers
  40.         POPFF
  41.  
  42.         PUSHF                   ; (make this call look like an INT)
  43.         CALL    CS:[OLD_40]     ; and call the original stuff
  44.  
  45.         PUSHF                   ; INT 40 done, restore fast DMA value
  46.         PUSH    AX              ; Save the registers we're changing
  47.  
  48.         MOV     AL, 74H         ; Set up for LSB-MSB rate again
  49.         OUT     43H, AL
  50.         JMP     $+2             ; More lousy delay
  51.         MOV     AL, 80H         ; A reasonable value for timeout
  52.         OUT     41H, AL         ; That nets about 5% more CPU speed
  53.         JMP     $+2             ; for free
  54.         XOR     AL, AL          ; Set MSB to 0
  55.         OUT     41H, AL
  56.  
  57.         POP     AX              ; Restore trashed registers
  58.         POPFF
  59.         RET     2               ; IRET without popping flags
  60.  
  61. ; This ends resident code section. From here on, we set things up and
  62. ; parse command line. Since this gets done only once, we don't want to
  63. ; save this code, so it also contains the means to decide how much
  64. ; memory to save when going resident.
  65.  
  66. OVER:   PUSH    DS
  67.         CLI                     ; Turn off INTs while revectoring INT
  68.         XOR     AX,AX           ; INT vectors are at SEGMENT 0
  69.         MOV     DS,AX           ; Set DS SEGMENT to zero
  70.  
  71. ;Redirect the floppy
  72.         MOV     AX, DS:[100H]   ;Get old addr, and store it here
  73.         MOV     WORD PTR CS:OLD_40,AX
  74.         MOV     AX, DS:[102H]
  75.         MOV     WORD PTR CS:OLD_40+2,AX
  76.  
  77.         MOV     WORD PTR DS:[100H],OFFSET I_40  ; Then replace it with
  78.         MOV     WORD PTR DS:[102H],CS   ; vector to floppy interceptor
  79.  
  80.         POP     DS              ; Put DS back where it belongs
  81.  
  82.         MOV     AL, 74H         ; Set DMA timer to slower value
  83.         OUT     43H, AL         ;    (less refresh)
  84.         JMP     $+2
  85.         MOV     AL, 80H
  86.         OUT     41H, AL
  87.         JMP     $+2
  88.         XOR     AL, AL
  89.         OUT     41H, AL
  90.  
  91.         MOV     AX,OFFSET OVER  ; Get the addr of the end of INT code
  92.         SHR     AX,1
  93.         SHR     AX,1
  94.         SHR     AX,1
  95.         SHR     AX,1            ; Dvivde by 16 and add 1,
  96.         INC     AX              ; to get how much memory to save
  97.         MOV     DX,AX           ; Save the calculated amount of memory
  98.         MOV     AH,31H          ; DOS func to terminate & stay residnt
  99.         STI                     ; Allow interrupts again
  100.         INT     21H             ; Do DOS call (never returns)
  101.  
  102. REFR    ENDP
  103. REFRESH ENDS
  104.         END     BEGIN
  105.  
  106.