home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / pibterm / pibt41s3.arc / PIBMDOS.MOD < prev    next >
Text File  |  1988-02-02  |  23KB  |  477 lines

  1. (*--------------------------------------------------------------------------*)
  2. (*             PIBMDOS.PAS --- Multitasker interface routines               *)
  3. (*--------------------------------------------------------------------------*)
  4. (*                                                                          *)
  5. (*  Author:  Philip R. Burns                                                *)
  6. (*                                                                          *)
  7. (*  Date:    Version 1.0: January, 1986.   DoubleDos support.               *)
  8. (*           Version 2.0: April, 1986.     Add DesqView support.            *)
  9. (*           Version 3.0: July, 1986.      Add TopView/Windows support.     *)
  10. (*           Version 3.1: September, 1986. Update for TaskView support.     *)
  11. (*           Version 3.2: December, 1986.  Distinguish TaskView/DesqView.   *)
  12. (*           Version 4.0: January, 1988.   Fix bogus TopView update, add    *)
  13. (*                                         check for Novell to stop lockup. *)
  14. (*                                                                          *)
  15. (*  Systems: MS DOS or PC DOS with DoubleDos/DesqView/TopView/Windows       *)
  16. (*           installed.                                                     *)
  17. (*                                                                          *)
  18. (*  History: These routines provide a simple interface for PibTerm          *)
  19. (*           with SoftLogic's DoubleDos multitasking executive,             *)
  20. (*           Quarterdeck's DesqView multitasker, IBM's TopView,             *)
  21. (*           MicroSoft's Windows, and Sunny Hill's TaskView.                *)
  22. (*           (Windows is handled as a Topview-emulating product.  This is   *)
  23. (*           also true for TaskView and DesqView, but those programs do     *)
  24. (*           not require the explicit screen updates TopView requires.      *)
  25. (*                                                                          *)
  26. (*           If you have another multitasker, you should be able to         *)
  27. (*           replace these routines fairly easily with similar-acting       *)
  28. (*           ones for your multitasker.  Use the global types defined       *)
  29. (*           for MultiTasker and MultiTaskerType.                           *)
  30. (*                                                                          *)
  31. (*           Note also that the routine Get_Screen_Address in Pibscren.pas  *)
  32. (*           needs to know about multitaskers.                              *)
  33. (*                                                                          *)
  34. (*           With DoubleDos, it is necessary to reobtain the display buffer *)
  35. (*           address every time the screen memory is written to.  With      *)
  36. (*           DesqView, this is unnecessary.  With TopView and Windows,      *)
  37. (*           it is necessary to inform them that the screen has changed.    *)
  38. (*           TaskView works like DesqView.                                  *)
  39. (*                                                                          *)
  40. (*--------------------------------------------------------------------------*)
  41. (*                                                                          *)
  42. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145      *)
  43. (*           or Ron Fox's BBS (312) 940 6496.                               *)
  44. (*                                                                          *)
  45. (*--------------------------------------------------------------------------*)
  46.  
  47. (*--------------------------------------------------------------------------*)
  48. (*           IsNovellActive  --- Checks if Novell network is active         *)
  49. (*--------------------------------------------------------------------------*)
  50.  
  51. FUNCTION IsNovellActive : BOOLEAN;
  52.  
  53. (*--------------------------------------------------------------------------*)
  54. (*                                                                          *)
  55. (*    Function: IsNovellActive                                              *)
  56. (*                                                                          *)
  57. (*    Purpose:  Checks if Novell network active                             *)
  58. (*                                                                          *)
  59. (*    Calling Sequence:                                                     *)
  60. (*                                                                          *)
  61. (*       Novell_On := IsNovellActive : BOOLEAN;                             *)
  62. (*                                                                          *)
  63. (*          Novell_On --- TRUE if Novell network is active.                 *)
  64. (*                                                                          *)
  65. (*    Calls:  MsDos                                                         *)
  66. (*                                                                          *)
  67. (*--------------------------------------------------------------------------*)
  68.  
  69. VAR
  70.    Regs : Registers;
  71.  
  72. BEGIN (* IsNovellActive *)
  73.  
  74.    Regs.CX := 0;
  75.    Regs.AL := 0;
  76.                                    (* Request workstation ID.          *)
  77.                                    (* This should be ignored if Novell *)
  78.                                    (* network software isn't active.   *)
  79.    Regs.AH := $DC;
  80.  
  81.    MsDos( Regs );
  82.                                    (* If we got back a non-zero station *)
  83.                                    (* ID, then Novell must be loaded.   *)
  84.  
  85.    IsNovellActive := ( Regs.AL <> 0 );
  86.  
  87. END   (* IsNovellActive *);
  88.  
  89. (*--------------------------------------------------------------------------*)
  90. (*           IsTimeSharingActive --- Checks if multitasker is active        *)
  91. (*--------------------------------------------------------------------------*)
  92.  
  93. FUNCTION IsTimeSharingActive : BOOLEAN;
  94.  
  95. (*--------------------------------------------------------------------------*)
  96. (*                                                                          *)
  97. (*    Function: IsTimeSharingActive                                         *)
  98. (*                                                                          *)
  99. (*    Purpose:  Checks if multitasker is active                             *)
  100. (*                                                                          *)
  101. (*    Calling Sequence:                                                     *)
  102. (*                                                                          *)
  103. (*       Ts_On := IsTimeSharingActive : BOOLEAN;                            *)
  104. (*                                                                          *)
  105. (*          Ts_On --- TRUE if multitasker is active.                        *)
  106. (*                                                                          *)
  107. (*    Calls:  MsDos                                                         *)
  108. (*                                                                          *)
  109. (*--------------------------------------------------------------------------*)
  110.  
  111. VAR
  112.    Regs : Registers;
  113.  
  114. (*--------------------------------------------------------------------------*)
  115.  
  116. FUNCTION Get_TopView_Screen_Address : BOOLEAN;
  117.  
  118. VAR
  119.    SegS : INTEGER;
  120.    SegO : INTEGER;
  121.  
  122. BEGIN (* Get_TopView_Screen_Address *)
  123.  
  124.    Regs.Di := 0;
  125.    Regs.Ax := $FE00;
  126.    Regs.Es := SEG( DesqView_Screen^ );
  127.  
  128.    SegO    := 0;
  129.    SegS    := Regs.Es;
  130.  
  131.    INTR( $10 , Regs );
  132.  
  133.    DesqView_Screen := PTR( Regs.Es , Regs.Di );
  134.  
  135.    Get_TopView_Screen_Address := ( ( Regs.Es <> SegS ) OR ( Regs.Di <> SegO ) );
  136.  
  137. END   (* Get_TopView_Screen_Address *);
  138.  
  139. (*--------------------------------------------------------------------------*)
  140.  
  141. BEGIN (* IsTimeSharingActive *)
  142.                                    (* Assume timesharing not active *)
  143.    IsTimeSharingActive := FALSE;
  144.    MultiTasker         := MultiTasker_None;
  145.  
  146.                                    (* Determine if color or mono screen *)
  147.    Regs.Ax := 15 SHL 8;
  148.    INTR( $10 , Regs );
  149.                                    (* Get initial screen address    *)
  150.    IF ( Regs.AL <> 7 ) THEN
  151.       DesqView_Screen := PTR( Color_Screen_Address , 0 )
  152.    ELSE
  153.       DesqView_Screen := PTR( Mono_Screen_Address  , 0 );
  154.  
  155.                                    (* If Novell network not active, *)
  156.                                    (* check if DoubleDos is active. *)
  157.    IF ( NOT IsNovellActive ) THEN
  158.       BEGIN
  159.                                    (* If DDos is active, $E4 should *)
  160.                                    (* return a non-zero value in Al *)
  161.          Regs.Ax := $E400;
  162.  
  163.          MsDos( Regs );
  164.  
  165.          IF ( Regs.Al <> 0 ) THEN
  166.             BEGIN
  167.                IsTimeSharingActive := TRUE;
  168.                MultiTasker         := DoubleDos;
  169.                EXIT;
  170.             END;
  171.  
  172.       END;
  173.                                    (* See if DesqView is active.        *)
  174.                                    (* We do a time/date call with       *)
  175.                                    (* DESQ as date.  If DesqView is     *)
  176.                                    (* active, this will be accepted.    *)
  177.                                    (* If not, it returns as invalid.    *)
  178.                                    (* While we're at it, get the        *)
  179.                                    (* display buffer address, which     *)
  180.                                    (* never changes.                    *)
  181.                                    (*                                   *)
  182.                                    (* NOTE:  Newer versions of TaskView *)
  183.                                    (*        also accept this DesqView  *)
  184.                                    (*        call, so we must check the *)
  185.                                    (*        TopView number to differ-  *)
  186.                                    (*        entiate them.              *)
  187.    Regs.Ax := $2B01;
  188.    Regs.Cx := $4445;  (*'DE'*)
  189.    Regs.Dx := $5351;  (*'SQ'*)
  190.    MsDos( Regs );
  191.  
  192.    IF ( Regs.Al <> $FF ) THEN
  193.       IF Get_TopView_Screen_Address THEN
  194.          BEGIN
  195.  
  196.             IsTimeSharingActive := TRUE;
  197.  
  198.                                    (* Distinguish TaskView from TopView *)
  199.             Regs.Ax := $1022;
  200.             Regs.Bx := 0;
  201.             INTR( $15 , Regs );
  202.  
  203.             IF ( Regs.Bx = 1 ) THEN
  204.                MultiTasker         := TaskView
  205.             ELSE
  206.                MultiTasker         := DesqView;
  207.  
  208.             EXIT;
  209.  
  210.          END;
  211.                                    (* Check for TaskView or TopView.  We do   *)
  212.                                    (* a request for a TopView version number. *)
  213.                                    (* If BX comes back $0001, this must be    *)
  214.                                    (* TaskView.  Anything non-zero indicates  *)
  215.                                    (* TopView or a compatible program.        *)
  216.                                    (* Note:  This catches older TaskView      *)
  217.                                    (*        versions which don't understand  *)
  218.                                    (*        the DesqView call.               *)
  219.    Regs.Ax := $1022;
  220.    Regs.Bx := 0;
  221.    INTR( $15 , Regs );
  222.  
  223.    IF ( Regs.Bx <> 0 ) THEN
  224.       BEGIN
  225.  
  226.          IF ( Regs.Bx = 1 ) THEN
  227.             MultiTasker         := TaskView
  228.          ELSE
  229.             MultiTasker         := TopView;
  230.  
  231.          IF ( NOT Get_TopView_Screen_Address ) THEN
  232.             MultiTasker := Multitasker_None
  233.          ELSE
  234.             IsTimeSharingActive := TRUE;
  235.  
  236.       END;
  237.  
  238. END   (* IsTimeSharingActive *);
  239.  
  240. (*--------------------------------------------------------------------------*)
  241. (*    TurnOnTimeSharing --- allow timesharing to proceed                    *)
  242. (*--------------------------------------------------------------------------*)
  243.  
  244. PROCEDURE TurnOnTimeSharing;
  245.  
  246. (*--------------------------------------------------------------------------*)
  247. (*                                                                          *)
  248. (*    Procedure:  TurnOnTimeSharing;                                        *)
  249. (*                                                                          *)
  250. (*    Purpose:    Activates timesharing                                     *)
  251. (*                                                                          *)
  252. (*    Calling Sequence:                                                     *)
  253. (*                                                                          *)
  254. (*       TurnOnTimeSharing;                                                 *)
  255. (*                                                                          *)
  256. (*    Calls:  MsDos                                                         *)
  257. (*                                                                          *)
  258. (*--------------------------------------------------------------------------*)
  259.  
  260. VAR
  261.    Regs : Registers;
  262.  
  263. BEGIN (* TurnOnTimeSharing *)
  264.  
  265.    CASE MultiTasker OF
  266.                                    (* If DDos is active, $EB turns  *)
  267.                                    (* on timesharing                *)
  268.       DoubleDos:   BEGIN
  269.                       Regs.Ax := $EB00;
  270.                       MsDos( Regs );
  271.                    END;
  272.  
  273.                                    (* Int 15H for TopView family products *)
  274.       DesqView,
  275.       TopView,
  276.       MSWindows,
  277.       TaskView:    BEGIN
  278.                       Regs.Ax := $101C;
  279.                       INTR( $15 , Regs );
  280.                    END;
  281.  
  282.       ELSE;
  283.  
  284.    END (* CASE *);
  285.  
  286. END   (* TurnOnTimeSharing *);
  287.  
  288. (*--------------------------------------------------------------------------*)
  289. (*        TurnOffTimeSharing --- suspend timesharing under DoubleDos        *)
  290. (*--------------------------------------------------------------------------*)
  291.  
  292. PROCEDURE TurnOffTimeSharing;
  293.  
  294. (*--------------------------------------------------------------------------*)
  295. (*                                                                          *)
  296. (*    Procedure:  TurnOffTimeSharing;                                       *)
  297. (*                                                                          *)
  298. (*    Purpose:    Suspends timesharing                                      *)
  299. (*                                                                          *)
  300. (*    Calling Sequence:                                                     *)
  301. (*                                                                          *)
  302. (*       TurnOffTimeSharing;                                                *)
  303. (*                                                                          *)
  304. (*    Calls:  MsDos                                                         *)
  305. (*                                                                          *)
  306. (*--------------------------------------------------------------------------*)
  307.  
  308. VAR
  309.    Regs : Registers;
  310.  
  311. BEGIN (* TurnOffTimeSharing *)
  312.  
  313.    CASE MultiTasker OF
  314.                                    (* If DDos is active, $EA suspends *)
  315.                                    (* timesharing                     *)
  316.       DoubleDos:   BEGIN
  317.                       Regs.Ax := $EA00;
  318.                       MsDos( Regs );
  319.                    END;
  320.                                    (* Int 15H for TopView family products *)
  321.       DesqView,
  322.       TopView,
  323.       MSWindows,
  324.       TaskView:    BEGIN
  325.                       Regs.Ax := $101B;
  326.                       INTR( $15 , Regs );
  327.                    END;
  328.  
  329.      ELSE;
  330.  
  331.    END (* CASE *);
  332.  
  333. END   (* TurnOffTimeSharing *);
  334.  
  335. (*--------------------------------------------------------------------------*)
  336. (*            GiveUpTime --- gives away time slices to other task           *)
  337. (*--------------------------------------------------------------------------*)
  338.  
  339. PROCEDURE GiveUpTime( NSlices : INTEGER );
  340.  
  341. (*--------------------------------------------------------------------------*)
  342. (*                                                                          *)
  343. (*    Procedure:  GiveUpTime;                                               *)
  344. (*                                                                          *)
  345. (*    Purpose:    Gives away time slices to other tasks                     *)
  346. (*                                                                          *)
  347. (*    Calling Sequence:                                                     *)
  348. (*                                                                          *)
  349. (*       GiveUpTime( NSlices :  INTEGER );                                  *)
  350. (*                                                                          *)
  351. (*          NSlices --- # of slices (55 ms) to give away, if DoubleDos.     *)
  352. (*                                                                          *)
  353. (*    Calls:  MsDos                                                         *)
  354. (*                                                                          *)
  355. (*--------------------------------------------------------------------------*)
  356.  
  357. VAR
  358.    Regs : Registers;
  359.  
  360. BEGIN (* GiveUpTime *)
  361.  
  362.    IF ( TimeSharingActive AND ( NSlices > 0 ) ) THEN
  363.       CASE MultiTasker OF
  364.                                    (* Function EE gives time to other part. *)
  365.          DoubleDos:   BEGIN
  366.                          Regs.Ah := $EE;
  367.                          Regs.Al := NSlices;
  368.                          MsDos( Regs );
  369.                       END;
  370.  
  371.          DesqView,
  372.          TopView,
  373.          MSWindows,
  374.          TaskView:    BEGIN
  375.                          INLINE(
  376.                                  $B8/$00/$10 { MOV     AX,$1000 ;Give up time}
  377.                                  /$CD/$15    { INT     $15}
  378.                                );
  379.                       END;
  380.  
  381.          ELSE;
  382.  
  383.       END;
  384.  
  385. END   (* GiveUpTime *);
  386.  
  387. (*--------------------------------------------------------------------------*)
  388. (*    Sync_Screen --- Synchronizes multitasker screen with hardware screen  *)
  389. (*--------------------------------------------------------------------------*)
  390.  
  391. PROCEDURE Sync_Screen( S_Pos: INTEGER; NChars : INTEGER );
  392.  
  393. (*--------------------------------------------------------------------------*)
  394. (*                                                                          *)
  395. (*    Procedure:  Sync_Screen;                                              *)
  396. (*                                                                          *)
  397. (*    Purpose:    Synchronizes multitasker and hardware screens             *)
  398. (*                                                                          *)
  399. (*    Calling Sequence:                                                     *)
  400. (*                                                                          *)
  401. (*       Sync_Screen( S_Pos : INTEGER; NChars: INTEGER );                   *)
  402. (*                                                                          *)
  403. (*    Calls:  INTR                                                          *)
  404. (*                                                                          *)
  405. (*    Remarks:                                                              *)
  406. (*                                                                          *)
  407. (*       This facility is required by the TopView-family products.          *)
  408. (*                                                                          *)
  409. (*--------------------------------------------------------------------------*)
  410.  
  411. BEGIN (* Sync_Screen *)
  412.  
  413.    IF ( NChars > 0 ) THEN
  414.       IF Write_Screen_Memory THEN
  415.          IF ( MultiTasker = TopView ) THEN
  416.             BEGIN
  417.  
  418. INLINE(
  419.   $55/                      {         PUSH    BP                      ;Save BP in case of clobber}
  420.   $C4/$3E/>DESQVIEW_SCREEN/ {         LES     DI,[>DesqView_Screen]   ;Pick up screen address}
  421.   $8B/$8E/>NCHARS/          {         MOV     CX,[BP+>NChars]         ;Get update length in bytes}
  422.   $8B/$86/>S_POS/           {         MOV     AX,[BP+>S_Pos]          ;Get offset of area to update}
  423.   $01/$F8/                  {         ADD     AX,DI                   ;Add to offset of screen memory}
  424.   $89/$C7/                  {         MOV     DI,AX                   ;Starting address of update}
  425.   $B4/$FF/                  {         MOV     AH,$FF                  ;TopView synchronize screen}
  426.   $CD/$10/                  {         INT     $10                     ;Video interrupt}
  427.   $5D);                     {         POP     BP                      ;Restore BP}
  428.  
  429.             END;
  430.  
  431. END   (* Sync_Screen *);
  432.  
  433. (*--------------------------------------------------------------------------*)
  434. (* Sync_Entire_Screen --- Synchronizes multitasker screen with hardware     *)
  435. (*--------------------------------------------------------------------------*)
  436.  
  437. PROCEDURE Sync_Entire_Screen;
  438.  
  439. (*--------------------------------------------------------------------------*)
  440. (*                                                                          *)
  441. (*    Procedure:  Sync_Entire_Screen;                                       *)
  442. (*                                                                          *)
  443. (*    Purpose:    Synchronizes multitasker and hardware screens             *)
  444. (*                                                                          *)
  445. (*    Calling Sequence:                                                     *)
  446. (*                                                                          *)
  447. (*       Sync_Entire_Screen;                                                *)
  448. (*                                                                          *)
  449. (*    Calls:  INTR                                                          *)
  450. (*                                                                          *)
  451. (*    Remarks:                                                              *)
  452. (*                                                                          *)
  453. (*       This facility is used by the TopView-family products when the      *)
  454. (*       entire screen has been updated.                                    *)
  455. (*                                                                          *)
  456. (*--------------------------------------------------------------------------*)
  457.  
  458. BEGIN (* Sync_Entire_Screen *)
  459.  
  460.    IF Write_Screen_Memory THEN
  461.       IF ( MultiTasker  = TopView ) THEN
  462.          BEGIN
  463.  
  464.             INLINE(
  465.   $55                       { PUSH    BP                    ;Save BP in case of clobber}
  466.   /$C4/$3E/>DESQVIEW_SCREEN { LES     DI,[>DesqView_Screen] ;Pick up screen address}
  467.   /$8B/$0E/>SCREEN_LENGTH   { MOV     CX,[>Screen_Length]   ;Get update length in bytes}
  468.   /$D1/$E9                  { SHR     CX,1                  ;Update length in words}
  469.   /$B4/$FF                  { MOV     AH,$FF                ;TopView synchronize screen}
  470.   /$CD/$10                  { INT     $10                   ;Video interrupt}
  471.   /$5D                      { POP     BP                    ;Restore BP}
  472.                   );
  473.  
  474.          END;
  475.  
  476. END   (* Sync_Entire_Screen *);
  477.