home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l320 / 2.img / EXAMPLES / CALLM1.F < prev    next >
Encoding:
Text File  |  1989-12-14  |  4.2 KB  |  131 lines

  1.       PROGRAM CALLM1
  2. C Purpose: calls real mode TSR via interrupt
  3. C Copyright (C) MicroWay, Inc. 1989
  4.  
  5. C The real mode Interrupt Service Routine (ISR) is 
  6. C table-driven. The calling program invokes the
  7. C various routines by passing an index into the
  8. C table via the ax register.
  9.  
  10.       INTEGER INIT_TEST
  11.       PARAMETER (INIT_TEST=0)
  12.       INTEGER FIRST_TEST_MSG,LAST_TEST_MSG
  13.       PARAMETER (FIRST_TEST_MSG=1,LAST_TEST_MSG=3)
  14.       INTEGER SHARE_BUFFER
  15.       PARAMETER (SHARE_BUFFER=LAST_TEST_MSG+1)
  16.  
  17.       INTEGER MSG_LEN
  18.       PARAMETER (MSG_LEN=80)
  19.  
  20.       INCLUDE 'DOS.FH'
  21.  
  22.       INTEGER INTNUM, I
  23.  
  24. C The following holds the address of the real mode data buffer.
  25. C It is declared an integer because FORTRAN has no pointer type
  26.       INTEGER PDB
  27. C The following function returns the address of a data object
  28.       INTEGER GET_ADDR
  29.  
  30. C This program makes extensive use of Phar Lap's 
  31. C DOS Extender Function Z'25', subfunction Z'11',
  32. C Issue Real Mode Interrupt. See the appropriate
  33. C section of the Phar Lap manual. The array defined
  34. C below serves as the parameter block to be passed
  35. C to that subfunction.
  36.       INTEGER*2 PARM_BLOCK (9)
  37.  
  38. C The values below act as indexes into the PARM_BLOCK array
  39.       INTEGER INTNUM_INDEX, DS_INDEX, ES_INDEX
  40.       INTEGER FS_INDEX, GS_INDEX, AX_INDEX, DX_INDEX
  41.  
  42.       PARAMETER (INTNUM_INDEX=1,DS_INDEX=2,ES_INDEX=3)
  43.       PARAMETER (FS_INDEX=4,GS_INDEX=5,AX_INDEX=6)
  44.       PARAMETER (DX_INDEX=8)
  45.  
  46. C Real Mode Interrupt Number
  47.       INTEGER RM_INTNUM
  48.       PARAMETER (RM_INTNUM=Z'48')
  49.  
  50.       CHARACTER*(6) OUT_MSG
  51.       CHARACTER*(MSG_LEN) IN_MSG
  52.  
  53.       DATA (PARM_BLOCK(I),I=1,9) /0/
  54.       DATA OUT_MSG /'Hello '/
  55.  
  56. C This program uses CALL INT386() to issue the Int Z'21',
  57. C function Z'25'. Any calls to real mode code must
  58. C go through Phar Lap's DOS Extender, i.e., we can
  59. C not issue a real mode interrupt directly via INT386.
  60.  
  61.       INTNUM = Z'21'
  62. C Real mode interrupt number => cl
  63.       BINREGS(9) = RM_INTNUM
  64. C Get real mode interrupt vector => ax
  65.       WINREGS(1) = Z'2503'
  66.       CALL INT386 (INTNUM,INREGS(1),OUTREGS(1))
  67.  
  68. C If vector is zero, definitely an error. However, a non-zero
  69. C value does not prove everything okay. We could make a more
  70. C stringent test, but in this example it didn't seem worthwhile
  71.       IF (OUTREGS(2).EQ.0) THEN
  72.         WRITE (*,100) 'Real Mode Interrupt not installed'
  73.         WRITE (*,100) CHAR (7)
  74.   100 FORMAT (1X,A)
  75.         STOP
  76.       ENDIF
  77.  
  78. C Initialize ax with error value
  79.       WOUTREGS(1) = -1
  80.  
  81. C Call the real mode routine for the first time. If all is
  82. C okay, it will pass back the address of a real mode buffer.
  83. C We can access that buffer from protected mode by using
  84. C segment selector Z'34', which maps to the first megabyte
  85. C of memory
  86.  
  87.       PARM_BLOCK (INTNUM_INDEX) = RM_INTNUM
  88.       PARM_BLOCK (AX_INDEX) = INIT_TEST
  89. C Move address of PARM_BLOCK => edx
  90.       INREGS(4) = GET_ADDR (PARM_BLOCK(1))
  91.       WINREGS(1) = Z'2511'
  92.       CALL INT386 (INTNUM,INREGS(1),OUTREGS(1))
  93.       
  94.       IF (WOUTREGS(1).NE.0) THEN
  95.         WRITE (*,100) 'Problem in Real Mode Interrupt'
  96.         WRITE (*,100) CHAR (7)
  97.       ELSE
  98.         PDB = WOUTREGS(5)*16
  99.         PDB = PDB + WOUTREGS(3)
  100.         WRITE (*,105) 'Address of data buffer = ',PDB
  101.         WRITE (*,110)
  102.   105 FORMAT (1X,A,Z5)
  103.   110 FORMAT (1X)
  104.       ENDIF
  105.  
  106. C Call real mode routine to output the test messages
  107.       DO 115 I = FIRST_TEST_MSG, LAST_TEST_MSG
  108.         PARM_BLOCK (AX_INDEX) = I
  109.         CALL INT386 (INTNUM,INREGS(1),OUTREGS(1))
  110.   115 CONTINUE
  111.  
  112. C Move output message defined in the Fortran program
  113. C into data buffer. Real mode routine will output the
  114. C message and move a new message which was defined in
  115. C the real mode program into the shared buffer. Note
  116. C that the real mode routine expects a null-terminated
  117. C string.
  118.       OUT_MSG(6:6) = CHAR(0)
  119.       CALL BLK_BM(OUT_MSG,Z'34',PDB,LEN(OUT_MSG))
  120.       PARM_BLOCK (AX_INDEX) = SHARE_BUFFER
  121.       CALL INT386 (INTNUM,INREGS(1),OUTREGS(1))
  122.  
  123. C Move new message from data buffer into character
  124. C variable and display it, to prove the process.
  125.       CALL BLK_MB(IN_MSG(1:1),Z'34',PDB,MSG_LEN)
  126.       WRITE (*,100) IN_MSG
  127.       WRITE (*,110)
  128.  
  129.       END
  130.  
  131.