home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PJ8_3.ZIP / HIMEM.ASM < prev    next >
Assembly Source File  |  1990-04-03  |  12KB  |  456 lines

  1. ;HI-MEM.ASM
  2. ;This program contains a BIOS patch in a TSR running in HI-MEMORY.
  3. ;The module contains:
  4. ;********************
  5. ;       GATE_A20:This module is packed into the PSP before termination. It
  6. ;resides in normal memory as a TSR, traps calls to the BIOS extended memory
  7. ;block move function (INT 15H : AH = 87H) and gates address line 20 open after
  8. ;each call.
  9. ;
  10. ;       EUROTRS:Printer interface to the TSR 2100 printer.
  11. ;
  12. ;conditionals************************
  13.  
  14. TRUE    equ 0ffh
  15. FALSE   equ 0
  16.  
  17. _80386  equ TRUE
  18. TESTING equ FALSE
  19.  
  20. ;equates*****************************
  21.  
  22. ON      equ 0ffh                ;Uniform codes for ON/OFF toggles
  23. OFF     equ 00h
  24.  
  25. LF              EQU     0AH             ;ASCII LINEFEED
  26. CR              EQU     0DH             ;ASCII RETURN
  27.  
  28.  
  29. ;-------------
  30. ;equates for the INT 2fH handler
  31. ;-------------
  32. KERNEL_ID       equ 0FFh
  33. EUROTRS_ID      equ KERNEL_ID
  34. INSTALLED       equ 0FFh                ;indicates installed
  35.  
  36. ;-------------
  37. ;function codes supported: ( placed by caller in AL )
  38. ;-------------
  39. GET_INSTALLED_STATE     equ 0
  40. ;-------------
  41. ;This function is supported by EUROTRS
  42. ;-------------
  43. STATUS                  equ 4           ;return ES:[DI] ---> STATUS_FLAG
  44.  
  45. ;--------------
  46. ;8042 KEYBOARD CONTROLLER equates
  47. ;--------------
  48.  
  49. KB_STATUS_PORT  equ 64H
  50. PORT_A          equ 60H
  51.  
  52. ENABLE_A20      equ 0DFH
  53. DISABLE_A20     equ 0DDH
  54. WRITE2_8042     equ 0D1H
  55.  
  56. SUCCESS         equ 0   ;RETURN CODES
  57. FAILURE         equ 2   ;8042 could not perform the command
  58. BUFFER_FULL     equ FAILURE
  59.  
  60. ;macros*************
  61.  
  62. CALLF   macro
  63.         db 09ah         ;code for a far call to the immediate following
  64.                         ;dword pointer
  65.         endm
  66.  
  67.  
  68.  
  69.  
  70. ;program**********************************************************************;
  71. ;
  72. ;ACHTUNG!!! BE VERY CAREFUL WITH ASSUME STATEMENTS THROUGHOUT!!!!
  73. ;EACH PROCEDURE (AND I MEAN EACH!) SHOULD HAVE AN ASSUME STATEMENT AS PART
  74. ;OF ITS HEADER. THINK OF IT AS PART OF THE PROCEDURE DECLARATION.
  75. ;
  76. TSRGROUP        GROUP CODESEG,DATASEG,INITSEG
  77.  
  78.                 TSR     equ TSRGROUP    ;for group overrides
  79.  
  80. ;--------------
  81. ;SPECIFY THE LOAD ORDER FOR THE LINKER
  82. ;--------------
  83. CODESEG SEGMENT BYTE PUBLIC 'PROG'
  84. CODESEG ENDS
  85. ;
  86. DATASEG SEGMENT BYTE PUBLIC 'DATA'
  87. DATASEG ENDS
  88. ;
  89. INITSEG SEGMENT BYTE PUBLIC 'INIT'
  90. INITSEG ENDS
  91. ;
  92.  
  93. ;--------------
  94. ;SOME USEFUL ADDRESSES IN PSP
  95. ;--------------
  96. CODESEG SEGMENT BYTE PUBLIC 'PROG'
  97.         ORG 2CH
  98. ENVIRONMENT     dw ?
  99.  
  100. CODESEG ENDS
  101.  
  102. ;--------------
  103. ;START OF ACTUAL PROGRAM SEGMENTS
  104. ;--------------
  105. ;
  106. ;--------------
  107. DATASEG SEGMENT BYTE PUBLIC 'DATA'
  108.                 ASSUME DS:TSRGROUP
  109.  
  110. ;--------------
  111. ;EUROTRS resident data area
  112. ;--------------
  113. STATUS_FLAG     db ON
  114.  
  115. CONVERSION_TABLE        LABEL BYTE
  116. ;--------------
  117. ;This is a simple look-up table to convert IBM hi ASCII codes into codes 
  118. ;understood by my not so compatible printer.
  119. ;This is a translation table for codes 128 to 255 ONLY.
  120. ;To test this table replace each entry with a known character
  121. ;--------------
  122.         DB 080H,0B8H,0BBH,083H,0B6H,0A1H,086H,0A2H
  123.         DB 088H,089H,0BDH,0A9H,0AFH,0BAH,0B1H,08FH
  124. D144    DB 090H,091H,092H,093H,0B7H,095H,096H,097H
  125.         DB 098H,0B2H,0B3H,0B4H,0A3H,0B0H,09EH,0BFH
  126. D160    DB 0A0H,0A1H,0A2H,0A3H,0A4H,0A5H,0A6H,0A7H
  127.         DB 0A8H,0F0H,0F2H,0AEH,0ACH,0ADH,0AEH,0AFH
  128. D176    DB 0EFH,0EFH,0EFH,0F5H,0F9H,0B5H,0B6H,0B7H
  129.         DB 0B8H,0B9H,0BAH,0BBH,0BCH,0BDH,0BEH,0F2H
  130. D192    DB 0F6H,0F8H,0F3H,0F4H,0F1H,0FAH,0C6H,0C7H
  131.         DB 0C8H,0C9H,0CAH,0CBH,0CCH,0CDH,0CEH,0CFH
  132. D208    DB 0D0H,0D1H,0D2H,0D3H,0D4H,0D5H,0D6H,0D7H
  133.         DB 0D8H,0F7H,0F0H,0EFH,0E8H,0E9H,0EAH,0E7H
  134. D224    DB 0E0H,0B9H,0E2H,0E3H,0E4H,0E5H,0A5H,0E7H
  135.         DB 0E8H,0E9H,0EAH,0EBH,0ECH,0EDH,0EEH,0EFH
  136. D240    DB 0F0H,0F1H,0F2H,0F3H,0F4H,0F5H,0F6H,0A6H
  137.         DB 0A7H,0F9H,0FAH,0FBH,0FCH,0FDH,0FEH,020H
  138.  
  139. DATASEG ENDS
  140.  
  141. ;
  142.  
  143. CODESEG SEGMENT BYTE PUBLIC 'PROG'
  144.                 ASSUME CS:TSRGROUP,DS:TSRGROUP ;ES:TSRGROUP,SS:TSRGROUP
  145.                 ORG 10H ;THE FIRST 16 BYTES OF THE SEGMENT @ 0FFFFH ARE IN ROM
  146.  
  147. INT_17H label dword     ;BIOS Print routine
  148. INT_17H_OFF     dw ?
  149. INT_17H_SEG     dw ?
  150.  
  151. INT_2FH label dword     ;DOS multiplex interrupt
  152. INT_2FH_OFF     dw ?
  153. INT_2FH_SEG     dw ?
  154.  
  155.         ORG 5CH         ;BELOW THIS ADDRESS IS FOR DOS
  156.  
  157. INT_15H label dword     ;storage for the address of INT 15H to chain to
  158. INT_15H_OFF     dw ?
  159. INT_15H_SEG     dw ?
  160.  
  161. TARGET  label byte      ;target for the moved INT 15H handler
  162.  
  163. ZZZ     LABEL BYTE      ;N.B. THIS LABEL MUST BE AT AN OFFSET < 100H - GATE_A20_SIZE
  164.         PUBLIC  ZZZ
  165.  
  166. ;--------------
  167. ;RESIDENT CODE
  168. ;--------------
  169.                 ORG 100H
  170.  
  171. BEGIN:          jmp SETUP
  172.  
  173.                         ;----------------------;
  174.                         ; MULTIPLEX  INTERRUPT ;
  175.                         ;----------------------;
  176.  
  177.  
  178. INT_2FH_HANDLER proc far
  179. ;--------------
  180. ;Look for the ID of KERNEL and the individual modules.
  181. ;--------------
  182.         cmp ah,KERNEL_ID
  183.         je MINE
  184.  
  185.         jmp CS:[INT_2FH]
  186.  
  187. MINE:   or al,al
  188.         jnz INVALID_FUNCTION
  189.  
  190.         mov al,INSTALLED
  191. INVALID_FUNCTION:
  192.         iret
  193.  
  194. EUROTRS:
  195. ;------------
  196. ;       ENTRY:  AH = EUROTRS_ID
  197. ;------------
  198.         cmp al,STATUS           ;only STATUS and RETURN_INSTALLED_STATE
  199.         jne MINE                ;are supported by EUROTRS
  200.  
  201.         push CS
  202.         pop ES                  ;return ES:[DI] ---> STATUS_FLAG
  203.         mov di,offset TSR:[STATUS_FLAG]
  204.         iret
  205.  
  206. INT_2FH_HANDLER endp
  207.  
  208.  
  209.                         ;----------------------;
  210.                         ;       EUROTRS        ;
  211.                         ;----------------------;
  212.  
  213. INT_17H_HANDLER proc far
  214. ;--------------
  215. ;Interface to the TRS 2100 printer.
  216. ;--------------
  217.  
  218.                 ASSUME DS:NOTHING,ES:NOTHING
  219.  
  220.         cmp CS:[STATUS_FLAG],ON
  221.         jne DONE
  222.  
  223.         cmp ah,0                        ;PRINTER OUTPUT?
  224.         jne DONE                        ;NO
  225.  
  226.         test al,80H                     ;HI ASCII CODE?
  227.         jz DONE                         ;NO
  228.  
  229.         and al,7FH                      ;YES, CLOBBER THE HI BIT AND TRANSLATE
  230.         push bx                         ;REG RETTEN
  231.         mov bx,offset TSR:[CONVERSION_TABLE]    ;CS:[BX] ---> CONVERSION TABLE
  232.         xlat byte ptr CS:[bx]           ;CONVERT
  233.         pop bx
  234.                 
  235. DONE:   jmp  CS:[INT_17H]               ;PASS ON THE TRANSLATED CODE
  236.  
  237. INT_17H_HANDLER endp
  238.  
  239.  
  240. CODESEG ENDS
  241. ;
  242. INITSEG SEGMENT BYTE PUBLIC 'INIT'
  243.                 ASSUME CS:TSRGROUP,DS:TSRGROUP
  244. ;--------------
  245. ;Throwaway code and data for the initialization of the resident portion
  246. ;--------------
  247.  
  248. ;--------------
  249. ;INITDATA
  250. ;--------------
  251. PROMPT          db 'KER386 installed. Bye!',CR,LF,'$'
  252.  
  253. LOADED_MSG      db 'KER386 is already loaded. Aborting!',CR,LF,'$'
  254.  
  255. BAD_DOS_MSG     db 'KER386 requires DOS 3.0 or higher. Aborting!',CR,LF,'$'
  256.  
  257. HARDERROR_MSG   db 'Cannot load KER386!',CR,LF,'$'
  258. ;--------------
  259. ;INITCODE
  260. ;--------------
  261. SETUP:  mov ah,30h              ;be sure DOS version is ok
  262.         int 21h
  263.         cmp al,3
  264.         jae VERSION_OK
  265.  
  266.         mov dx,offset TSR:[BAD_DOS_MSG]
  267.         jmp short ABORT_EXIT
  268.  
  269. VERSION_OK:
  270.         mov ax,KERNEL_ID shl 8
  271.         int 2Fh
  272.         or al,al
  273.         jz CONTINUE
  274.  
  275. ABORT:  mov dx,offset TSR:[LOADED_MSG]
  276. ABORT_EXIT:
  277.         mov ah,09h              ;DOS display ASCII string function
  278.         int 21h
  279.  
  280.         int 20h
  281.  
  282. CONTINUE:
  283.         call GATE_A20           ;open up the first 64 KB above 1 MEG
  284.         or al,al
  285.         jz INSTALL
  286.  
  287.         mov dx,offset TSR:[HARDERROR_MSG]
  288.         jmp short ABORT_EXIT
  289.  
  290. INSTALL:
  291. ;-----------------
  292. ;Move the essential functions to HI RAM
  293. ;-----------------
  294.         mov si,10h
  295.         mov di,si
  296.         mov ax,0FFFFh
  297.         mov ES,ax
  298.         mov cx,offset TSR:[THE_END] - 10h
  299.         CLD
  300.         rep movsb
  301.  
  302.         CALLF                   ;call the routine at the address in the next dword
  303.         dw offset TSR:[HI_RAM_ENTRY]
  304.         dw 0FFFFH
  305. ;-------------------
  306. ;The code in HI RAM ends with a RETF, so control returns here after the call.
  307. ;-------------------
  308.         mov ax,CS
  309.         mov DS,ax       ;restore DS to CS
  310. ;-------------------
  311. ;get and save the address of the INT 15H routine
  312. ;-------------------
  313.         mov ax,3515h    ;get the address of INT 15h from DOS
  314.         int 21h
  315.         mov [INT_15H_OFF],bx
  316.         mov [INT_15H_SEG],ES
  317.  
  318.         mov ax,DS       ;restore ES to DS=CS
  319.         mov ES,ax
  320. ;-------------------
  321. ;Move the code for gate_a20 into the PSP and establish residency.
  322. ;-------------------
  323.         mov si,offset TSR:[INT_15H_HANDLER]
  324.         mov di,offset TSR:[TARGET]
  325.         mov cx,GATE_A20_SIZE
  326.         CLD
  327.         rep movsb
  328. ;--------------------
  329. ;now reset the interrupt routine
  330. ;--------------------
  331.         mov ax,2515h
  332.         mov dx,offset TSR:[TARGET]
  333.         int 21h
  334. ;-------------
  335. ;free up the environment segment
  336. ;-------------
  337.         mov ES,TSR:[ENVIRONMENT]
  338.         mov ah,49h
  339.         int 21h
  340. ;-------------
  341. ;establish TSR status
  342. ;-------------
  343.         mov dx,0FFH
  344.         int 27h
  345.  
  346. ;-----------------------------------------------------------------------------;
  347. ;                       INIT ENTRY POINT IN HI MEMORY                         ;
  348. ;-----------------------------------------------------------------------------;
  349.  
  350. HI_RAM_ENTRY:
  351. ;------------------
  352. ;This is the entry point called by the original copy of the code after the move
  353. ;to high memory.
  354. ;------------------
  355.         mov ax,CS
  356.         mov DS,ax
  357.         mov ES,ax
  358. ;-----------
  359. ;chain into INT 2Fh chain
  360. ;----------
  361.         mov ax,352Fh
  362.         int 21h
  363.         mov [INT_2FH_SEG],ES
  364.         mov [INT_2FH_OFF],bx
  365.         mov ax,252Fh
  366.         mov dx,offset TSR:[INT_2FH_HANDLER]
  367.         int 21h
  368. ;-------------
  369. ;now Bios PRINT INTERRUPT
  370. ;-------------
  371.         mov ax,3517h    ;get the address of INT 15h from DOS
  372.         int 21h
  373.         mov [INT_17H_OFF],bx
  374.         mov [INT_17H_SEG],es
  375.         mov ax,2517h
  376.         mov dx,offset TSR:[INT_17H_HANDLER]
  377.         int 21h
  378.  
  379. RETURN2CALLER:
  380.         RETF                            ;RETURN TO CODE IN NORMAL MEMORY
  381.  
  382. ;-----------------
  383. ;The next label marks the end of code transferred to hi memory
  384. ;-----------------
  385. THE_END label byte
  386.  
  387. ;------------------
  388. ;This code is packed into the PSP before termination.
  389. ;------------------
  390.  
  391. INT_15H_HANDLER proc far
  392. ;---------------
  393. ;Patch the BIOS EXTENDED MEMORY BLOCK MOVE function to gate address line 20.
  394. ;---------------
  395.         cmp ah,87H              ;BIOS extended memory block move function
  396.         je REGATE_A20
  397.  
  398.         jmp CS:[INT_15H]        ;N.B. must be "relocatable"
  399.  
  400. REGATE_A20:
  401.         pushf                   ;simulate an interrupt
  402.         call CS:[INT_15H]       ;must be "relocatable"
  403.  
  404.         pushf                   ;save the flags from the BIOS call
  405.         call GATE_A20
  406.         popf
  407.         RETF 2          ;throw away user flags and return flags from BIOS call.
  408.  
  409. INT_15H_HANDLER endp
  410.  
  411.  
  412. GATE_A20        proc near
  413. ;------------------------
  414. ;       ENTRY:  NONE
  415. ;       EXIT:   AL = STATUS CODE
  416. ;-------------------------
  417.         push ax
  418.         CLI
  419.         call EMPTY_8042         ;be sure 8042 input buffer is empty
  420.         jnz GATE_A20_X          ;quit if no go
  421.  
  422.         mov al,WRITE2_8042      ;enable the 8042 for a command
  423.         out KB_STATUS_PORT,al
  424.         call EMPTY_8042
  425.         jnz GATE_A20_X
  426.  
  427.         mov al,ENABLE_A20       ;get the command
  428.         out PORT_A,al           ;send it to the 8042
  429.         call EMPTY_8042
  430. GATE_A20_X:
  431.         pop ax
  432.         RET
  433. GATE_A20        endp
  434.  
  435. EMPTY_8042      proc near
  436. ;---------------
  437. ;This routine waits for the 8042 input buffer to empty
  438. ;       ENTRY:  NONE (AX SAVED BY CALLER)
  439. ;       EXIT:   AL = RETURN CODE (SUCCESS or FAILURE)
  440. ;---------------
  441.         push cx                 ;save scratch register
  442.         xor cx,cx               ;set up a time out counter
  443. EMPTY_LOOP:
  444.         in al,KB_STATUS_PORT
  445.         and al,BUFFER_FULL
  446.         loopnz EMPTY_LOOP
  447.         pop cx
  448.         RET
  449. EMPTY_8042      endp
  450.  
  451.  
  452. GATE_A20_SIZE   equ $ - INT_15H_HANDLER
  453.  
  454. INITSEG ENDS
  455.         END BEGIN
  456.