home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG052.ARK / BATCH.3 < prev    next >
Text File  |  1984-04-29  |  9KB  |  341 lines

  1. $This file constitutes the 3rd module of program BATCH.
  2.  
  3. SHOW  ^;  $'Start of the installation module
  4.  
  5. DEF  SizeOfModel        = AfterModel - Model;
  6. SHOW  SizeOfModel;
  7.  
  8. DEF  CPMPerformFunction        = #0005;
  9. DEF  CPMDefaultFCB        = #005C;
  10. DEF  CPMDefaultTextBuf        = #0080;
  11. DEF  SectorSize            = #80;
  12. DEF  AfterCPMDefaultTextBuf    = CPMDefaultTextBuf + SectorSize;
  13.  
  14. $CP/M system functions
  15. DEF  CPMTypeOut            = 2;
  16. DEF  CPMOpen            = 15;
  17. DEF  CPMClose            = 16;
  18. DEF  CPMRead            = 20;
  19.  
  20. MACRO  CPMSystemCall;
  21. C <-  `P(1);
  22. ASM IF  `CHARS =|=`P(2)=|= ~= 0;
  23. DE <-  `P(2);
  24. END ASMIF;
  25. CALL  CPMPerformFunction;
  26. END MACRO;
  27.  
  28. MACRO  TypeOutMessage;
  29. HL <-  ^ + 9;
  30. CALL  TypeOutLine;
  31. GO.  ^ + `CHARS =|=`P(1)=|= + 2;
  32. BYTE  `P(1), TextTerminator;
  33. END MACRO;
  34.  
  35. MACRO  Error,Message<-;
  36. Type Out Message  `P(1);
  37. GO.  WarmBoot;
  38. END MACRO;
  39.  
  40. :CRLF                BYTE  CarriageReturn, LineFeed;
  41.                 BYTE  TextTerminator;
  42.  
  43. :EndOfFileWasFound        BYTE  FALSE;
  44.  
  45. :FileInputCursor        WORD  AfterCPMDefaultTextBuf;
  46.                     $Addr. of next char. to input
  47.                     $from the batch text file,
  48.                     $initialized to force reading of
  49.                     $the 1st sector of the file
  50.  
  51. :RelocationValue        WORD  NoInitialValue;
  52. :AfterSafeMemory        WORD  NoInitialValue;
  53.  
  54. :GO_BATCH_CONST            GO.  BatchCONST;
  55. :GO_BATCH_CONIN            GO.  BatchCONIN;
  56. :AFTER_GO_BATCH 
  57.  
  58. :TypeOutString 
  59.    PROCEDURE;
  60.       .HL -> A;  ? << A -  TextTerminator;  IF = EXIT;
  61.       HL\/;
  62.       A -> E;
  63.       CPM System Call  CPMTypeOut;
  64.       /\HL;  HL + 1 -> HL;
  65.       REPEAT;
  66.    END PROCEDURE;
  67.  
  68. :TypeOutCRLF 
  69.    PROCEDURE;
  70.       HL <-  CRLF;  CALL  TypeOutString;
  71.    END PROCEDURE;
  72.  
  73. :TypeOutLine 
  74.    PROCEDURE;
  75.       HL\/;
  76.       CALL  TypeOutCRLF;
  77.       /\HL;  CALL  TypeOutString;
  78.    END PROCEDURE;
  79.  
  80. :OpenBatchTextFile 
  81.    PROCEDURE;
  82.       $Verify the file name
  83.       A <- .  CPMDefaultFCB + 1;  ? << A -  " ";
  84.       IF = THEN;
  85.      Error, Message <-  "WHAT FILE?";
  86.       END IF;
  87.       A <- .  CPMDefaultFCB + 9;  ? << A -  " ";
  88.       IF = THEN;
  89.      $Use the default file name extension
  90.      HL <-  "AB";  HL -> .  CPMDefaultFCB + 9;
  91.      A <-  "T";  A -> .  CPMDefaultFCB + 11;
  92.       END IF;
  93.       CPM System Call  CPMOpen, CPMDefaultFCB;
  94.       A + 1 -> A;            $Test the return code
  95.       IF 0 THEN;
  96.      Error, Message <-  "NO FILE";
  97.       END IF;
  98.    END PROCEDURE;
  99.  
  100. :CloseBatchTextFile 
  101.    PROCEDURE;
  102.       CPM System Call  CPMClose, CPMDefaultFCB;
  103.       A + 1 -> A;            $Test the return code
  104.       IF 0 THEN;
  105.      Error, Message <-  "ERR CLOSING FILE";
  106.       END IF;
  107.    END PROCEDURE;
  108.  
  109. :Read1SectorOfBatchTextFile 
  110.    PROCEDURE;
  111.       CPM System Call  CPMRead, CPMDefaultFCB;
  112.       A -> .  EndOfFileWasFound;
  113.    END PROCEDURE;
  114.  
  115. :Input1CharFromBatchTextFile 
  116.    PROCEDURE;
  117.       HL <- .  FileInputCursor;
  118.       $Test if past the end of the buffer by comparing addresses
  119.       IF;
  120.      L -> A;  ? << A -  >< AfterCPMDefaultTextBuf;
  121.       IS = AND;
  122.      H -> A;  ? << A -  <> AfterCPMDefaultTextBuf;
  123.       IS = THEN;
  124.      CALL  Read1SectorOfBatchTextFile;
  125.      HL <-  CPMDefaultTextBuf;
  126.      ? << A <- .  EndOfFileWasFound;
  127.      IF ~0 THEN;
  128.         .HL <-  Substitute;
  129.      END IF;
  130.       END IF;
  131.       .HL -> A;
  132.       HL + 1 -> HL;  HL -> .  FileInputCursor;
  133.    END PROCEDURE;
  134.  
  135. :RelocateAddressesInTheModel 
  136.    PROCEDURE;
  137.       HL <-  Model;  DE <-  MODEL;
  138.       DO;
  139.      .DE -> A;  A - .HL -> A;
  140.      IF ~= THEN;
  141.         $Verify that this is the 1st byte of a word that must be
  142.         $relocated
  143.         A?\/;
  144.         ? << A -  >< (MODEL - Model);
  145.         IF ~= THEN;
  146.            Error, Message <-  "CODE MODELS DO NOT CORRESPOND";
  147.         END IF;
  148.         HL + 1 -> HL;  DE + 1 -> DE;
  149.         /\A?;
  150.         .DE -> A;  A - .HL - CY -> A;  ? << A -  <> (MODEL - Model);
  151.         IF ~= THEN;
  152.            HL -> .  DiagnosticInfo;  HL <-> DE;
  153.           HL -> .  DiagnosticInfo + 2;
  154.            Error, Message <-  "1-BYTE RELOC ADDR PROHIBITED";
  155.         END IF;
  156.         $Perform relocation
  157.         DE\/;  HL\/;
  158.         .HL -> D;  HL - 1 -> HL;  .HL -> E;
  159.                     $Original addr. from Model ->
  160.                     $DE
  161.         HL <- .  RelocationValue;  HL + DE -> HL;  HL <-> DE;
  162.                     $Relocated addr. -> DE
  163.         /\HL;
  164.         D -> .HL;  HL - 1 -> HL;  E -> .HL;  HL + 1 -> HL;
  165.         /\DE;
  166.      END IF;
  167.      HL + 1 -> HL;  DE + 1 -> DE;
  168.      $Test if done by comparing addresses
  169.      L -> A;  ? << A -  >< AfterModel;  IF ~= REPEAT;
  170.      H -> A;  ? << A -  <> AfterModel;  IF ~= REPEAT;
  171.       END DO;
  172.    END PROCEDURE;
  173.  
  174. :CopyModelToSafeMemory 
  175.    PROCEDURE;
  176.       HL <- .  SafeMemory;
  177.       DE <-  Model;
  178.       DO;
  179.      .DE -> A;  A -> .HL;
  180.      HL + 1 -> HL;  DE + 1 -> DE;
  181.      $Test if done by comparing addresses
  182.      E -> A;  ? << A -  >< AfterModel;  IF ~= REPEAT;
  183.      D -> A;  ? << A -  <> AfterModel;  IF ~= REPEAT;
  184.       END DO;
  185.    END PROCEDURE;
  186.  
  187. :CopyCharToSafeMemory 
  188.    PROCEDURE;
  189.       A -> D;                $Copy the char.
  190.       $Verify that there is at least 1 available byte remaining in safe
  191.       $memory
  192.       IF;
  193.      L -> A;  A - C >> ?;
  194.       IS = AND;
  195.      H -> A;  A - B >> ?;
  196.       IS = THEN;
  197.      Error, Message <-  "BATCH TEXT TOO LONG";
  198.       END IF;
  199.       D -> .HL;                $Copy the char. into safe
  200.                     $memory
  201.       HL + 1 -> HL;
  202.    END PROCEDURE;
  203.  
  204. :CopyTextToSafeMemory 
  205.    PROCEDURE;
  206.       HL <- .  AfterSafeMemory;  H -> B;  L -> C;
  207.                     $1st addr. after end of safe
  208.                     $memory -> BC
  209.       HL <- .  SafeMemory;  DE <-  SizeOfModel;  HL + DE -> HL;
  210.                     $Destination addr. of text ->
  211.                     $HL
  212.       DO;
  213.      HL\/;  BC\/;
  214.      CALL  Input1CharFromBatchTextFile;
  215.      HL <-  Escape;  A - .HL >> ?;
  216.      IF = THEN;
  217.         CALL  Input1CharFromBatchTextFile;
  218.         ? << A -  "C";
  219.         IF = THEN;
  220.            $This is the start of a comment to the batch processor
  221.            DO;
  222.           CALL  Input1CharFromBatchTextFile;
  223.           HL <-  Escape;  A - .HL >> ?;  IF = EXIT;
  224.           ? << A -  Substitute;  IF = EXIT;
  225.           A -> E;  CPM System Call  CPMTypeOut;
  226.           REPEAT;
  227.            END DO;
  228.         ELSE;
  229.            $Regenerate and copy the escape char.
  230.            A -> H;            $Char. following escape
  231.            /\BC;  HL <-> .SP;
  232.            A <- .  Escape;  CALL  CopyCharToSafeMemory;
  233.            HL <-> .SP;  BC\/;
  234.            H -> A;            $Char. following escape
  235.         END IF;
  236.      END IF;
  237.      /\BC;  /\HL;
  238.      ? << A -  CarriageReturn;
  239.      IF = THEN;
  240.         CALL  CopyCharToSafeMemory;
  241.         $Delete any possible following LineFeed
  242.         HL\/;  BC\/;
  243.         CALL  Input1CharFromBatchTextFile;
  244.         /\BC;  /\HL;
  245.         ? << A -  LineFeed;  IF = REPEAT;
  246.      END IF;
  247.      ? << A -  Substitute;
  248.      IF = THEN;
  249.         A <- .  Escape;  CALL  CopyCharToSafeMemory;
  250.         A <- .  TerminationCommandChar;
  251.            CALL  CopyCharToSafeMemory;
  252.         EXIT;
  253.      END IF;
  254.      CALL  CopyCharToSafeMemory;
  255.      REPEAT;
  256.       END DO;
  257.    END PROCEDURE;
  258.  
  259. :CopyOriginalJMPVectorToModel 
  260.    PROCEDURE;
  261.       HL <- .  AdrOf_JMP_WBOOT;  HL + 1 -> HL;  HL + 1 -> HL;
  262.      HL + 1 -> HL;  HL -> .  AdrOf_JMP_CONST;
  263.       DE <-  GO_OriginalCONST;
  264.       B <-  AfterGO_Original - GO_OriginalCONST;
  265.       DO;
  266.      .HL -> A;  A -> . DE;
  267.      HL + 1 -> HL;  DE + 1 -> DE;
  268.      B - 1 -> B;  IF ~0 REPEAT;
  269.       END DO;
  270.    END PROCEDURE;
  271.  
  272. $Verify that the batch program is not calling itself recursively.  The
  273. $detection method is to test whether the original CONST address is the
  274. $same as the address of the batch version of CONST.
  275. :VerifyLackOfRecursion 
  276.    PROCEDURE;
  277.       DE <-  BatchCONST;  HL <- .  RelocationValue;  HL + DE -> HL;
  278.      HL <-> DE;            $Relocated addr. of BatchCONST
  279.                     $ -> DE
  280.       HL <- .  GO_OriginalCONST + 1;
  281.       IF;
  282.      D -> A;  A - H >> ?;
  283.       IS = AND;
  284.      E -> A;  A - L >> ?;
  285.       IS = THEN;
  286.      Error, Message <-  "BATCH MUST NOT CALL ITSELF";
  287.       END IF;
  288.    END PROCEDURE;
  289.  
  290. :InstateBatchProcessing 
  291.    PROCEDURE;
  292.       HL <- .  AdrOf_JMP_CONST;  DE <-  GO_BATCH_CONST;
  293.       B <-  AFTER_GO_BATCH - GO_BATCH_CONST;
  294.       DO;
  295.      .DE -> A;  A -> .HL;
  296.      HL + 1 -> HL;  DE + 1 -> DE;
  297.      B - 1 -> B;  IF ~0 REPEAT;
  298.       END DO;
  299.    END PROCEDURE;
  300.  
  301. :Main                    $*** Not a procedure ***
  302.    CALL  OpenBatchTextFile;
  303.    CALL  YourPatchProc;
  304.    HL <- .  SizeOfSafeMemory;  HL <-> DE;  HL <- .  SafeMemory;
  305.       HL + DE -> HL;  HL -> .  AfterSafeMemory;
  306.    HL <- .  SafeMemory;  DE <-  - Model;  HL + DE -> HL;
  307.       HL -> .  RelocationValue;  HL <-> DE;
  308.    HL <- .  GO_BATCH_CONST + 1;  HL + DE -> HL;
  309.       HL -> .  GO_BATCH_CONST + 1;
  310.    HL <- .  GO_BATCH_CONIN + 1;  HL + DE -> HL;
  311.       HL -> .  GO_BATCH_CONIN + 1;
  312.    CALL  RelocateAddressesInTheModel;
  313.    CALL  CopyOriginalJMPVectorToModel;
  314.    CALL  VerifyLackOfRecursion;
  315.    CALL  CopyModelToSafeMemory;
  316.    CALL  CopyTextToSafeMemory;
  317.    CALL  CloseBatchTextFile;
  318.    CALL  InstateBatchProcessing;
  319.    GO.  WarmBoot;
  320.  
  321. $You may assemble or patch in the code here, to store the correct values
  322. $into variables SafeMemory and SizeOfSafeMemory.
  323. :YourPatchProc 
  324.    PROCEDURE;
  325.       $This procedure may expand as necessary, to accommodate your code.
  326.       $The existing code in this procedure may be discarded.  It is
  327.       $peculiar to the version of CP/M and the BIOS used by the author
  328.       $of this program.
  329.       $*************************
  330.       $SafeMemory starts after the end of BIOS.
  331.       HL <- .  CPMPerformFunction + 1;  DE <-  #10C0;  HL + DE -> HL;
  332.      HL -> .  SafeMemory;
  333.       $SafeMemory extends up to the next 1K boundary of address space.
  334.       L -> A;  ~A -> A;  A -> L;
  335.       H -> A;  ~A -> A;  A <- A &  #03;  A -> H;
  336.       HL + 1 -> HL;
  337.       HL -> .  SizeOfSafeMemory;
  338.    END PROCEDURE;
  339.  
  340. :ZZZ    END  Start;
  341.