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.1 < prev    next >
Text File  |  1984-04-29  |  12KB  |  412 lines

  1. $This is program BATCH.
  2.  
  3. $Operation of this program is described in the BATCH Reference Manual.
  4.  
  5. $This program is entered into the public domain by its author, Daniel
  6. $Ross.  Please do not remove this notice.
  7.  
  8. $The mixed-upper-lower-case version of this file constitutes the 1st
  9. $module of program BATCH.  The upper-case-only version of this file
  10. $constitutes the 2nd module of program BATCH.
  11.  
  12. $Coded by Daniel Ross, in the computer language SIL80Z80, starting
  13. $Jan. 20, 1981.
  14.  
  15. $Revised Feb. 12, 1981
  16.  
  17. $For more information contact:
  18. $Daniel Ross
  19. $Succinct Systems
  20. $1346 River St.
  21. $Santa Cruz, Calif. 95060
  22. $Phone (408) 426-4197
  23.  
  24. DEF  FALSE            = 0;
  25. DEF  TRUE            = 1;
  26. IGNORE1STSPACE  1;
  27. DEF  OPTIMIZED_COMPILATION    = TRUE;
  28.  
  29. DEF  NoInitialValue        = 0;
  30. XREF OF  NoInitialValue : 0;
  31. DEF  PatchMe            = 0;
  32.  
  33. $ASCII characters
  34. DEF  EndOfText            = #03;    $Ctrl-C
  35. DEF  Bell            = #07;
  36. DEF  LineFeed            = #0A;
  37. DEF  CarriageReturn        = #0D;
  38. DEF  NegativeAck        = #15;    $Ctrl-U
  39. DEF  Substitute            = #1A;    $Ctrl-Z
  40. DEF  RecordSeparator        = #1E;
  41. DEF  NonexistentChar        = #80;
  42. DEF  TextTerminator        = NonexistentChar + RecordSeparator;
  43.  
  44. DEF  AdrOf_JMP_WBOOT        = #0001;$Addr. of the JMP WBOOT
  45.                     $instruction in the table at
  46.                     $the beginning of BIOS
  47. DEF  WarmBoot            = #0000;$Entry addr. of procedure WBOOT
  48. DEF  CPMProgramStart        = #0100;$Starting addr. of all CP/M
  49.                     $user programs
  50.  
  51. ASM IF  ^ = 0;    $Assemble if this is the model which will be copied
  52.         $into safe memory
  53.  
  54. DEF  ^ = CPMProgramStart;
  55. :Start    GO.  Main;
  56.  
  57. :SafeMemory            WORD  PatchMe;
  58.                     $Addr. of the start of safe
  59.                     $memory
  60. :SizeOfSafeMemory        WORD  PatchMe;
  61.                     $Size in bytes of safe memory
  62. :SizeOfCodeInSafeMemory        WORD  SizeOfModel;
  63.                     $Do not alter the contents of
  64.                     $this word; just examine it.
  65.                     $This is the size of safe
  66.                     $memory needed just to hold the
  67.                     $code, not including any batch
  68.                     $text.  If you have insufficient
  69.                     $safe memory, this program will
  70.                     $not execute correctly.
  71. :AdrOfModels            WORD  Model, MODEL;
  72.                     $Do not alter the contents of
  73.                     $these words; just examine them.
  74.                     $They contain the starting
  75.                     $addresses for corresponding
  76.                     $patches in each of the models.
  77. :AdrOfYourPatchProc        WORD  YourPatchProc;
  78.                     $Do not alter the contents of
  79.                     $this word; just examine it to
  80.                     $determine where your patch
  81.                     $procedure should be located
  82. :DiagnosticInfo            WORD  0,0,0,0;
  83.                     $This space may be used as
  84.                     $desired, to hold diagnostic
  85.                     $info. in case of error
  86.  
  87. :JUST_BEFORE_MODEL 
  88. END ASMIF;
  89.  
  90. $If this is the model which is used to discover relocatable addresses,
  91. $make sure that both bytes of the addresses will differ from those of
  92. $the model which will be copied into safe memory.
  93. ASM IF  
  94.    (<>(^ - JUST_BEFORE_MODEL) ~= 0) & (><(^ - JUST_BEFORE_MODEL) = 0);
  95. SKIP OVER  1;                $Force the LSB of the addresses
  96.                     $to differ
  97. END ASMIF;
  98.  
  99. $**********************************************************************
  100.  
  101. :Model 
  102.  
  103. SHOW  ^;  $'Start of a model module
  104.  
  105. $The following variables and/or constants may be patched to change their
  106. $initial/permanent values
  107. :BatchCONSTReport        BYTE  0;
  108.                     $This byte contains the value of
  109.                     $the output param from CONST,
  110.                     $when batched chars. are being
  111.                     $read
  112. :RingForAttn            BYTE  FALSE;
  113.                     $0 means quiet, any nonzero
  114.                     $value means ring for attention
  115.                     $when the user must start typing
  116.                     $in chars.
  117. :Escape                BYTE  #01;    $StartOfHeading, Ctrl-A
  118.                     $This must be the 1st char. of
  119.                     $any 2-char. command to BATCH
  120.  
  121. $Table of valid 2nd chars., for 2-char. commands to BATCH, and the
  122. $addresses of their interpretation procedures
  123. :TableOf2ndChars 
  124.    BYTE  "I";  WORD  RequestTypedInput;
  125.    BYTE  "B";  WORD  RequestBatchInput;
  126.    BYTE  "R";  WORD  RequestRingForAttn;
  127.    BYTE  "Q";  WORD  RequestQuiet;
  128.    BYTE  "Y";  WORD  RequestYesFromCONST;
  129.    BYTE  "N";  WORD  RequestNoFromCONST;
  130.    BYTE  "X";  WORD  NoOp;
  131. :TerminationCommandChar 
  132.    BYTE  "Z";  WORD  TerminateBatchProcessing;
  133. :AfterTableOf2ndChars 
  134.  
  135. :AdrOf_JMP_CONST        WORD  NoInitialValue;
  136. :GO_OriginalCONST        GO.   NoInitialValue;
  137. :GO_OriginalCONIN        GO.   NoInitialValue;
  138. :GO_OriginalCONOUT        GO.   NoInitialValue;
  139. :AfterGO_Original 
  140.  
  141. :MiddleOfInputLine        BYTE  FALSE;
  142.                     $0 means input is at the start
  143.                     $of a line, any nonzero value
  144.                     $means input is in the middle of
  145.                     $a line
  146. :UnsolicitedCharWasTypedIn    BYTE  FALSE;
  147.                     $0 means there has not been an
  148.                     $unsolicited char. typed in, any
  149.                     $nonzero value means an
  150.                     $unsolicited char. was typed in
  151. :UnsolicitedChar        BYTE  NonexistentChar;
  152.                     $If an unsolicited char. ~= the
  153.                     $escape char. was typed in, and
  154.                     $detected during a call of
  155.                     $CONST, this byte will contain
  156.                     $the char.; otherwise this byte
  157.                     $will contain NonexistentChar
  158. :NormalSourceForCurrentLine    BYTE  0;$0 means batch input, any
  159.                     $nonzero value means typed
  160.                     $input
  161. :NormalSourceForNextLine    BYTE  0;$0 means batch input, any
  162.                     $nonzero value means typed
  163.                     $input
  164. :BatchInputCursor        WORD  AfterModel;
  165.                     $Addr. of the next batch input
  166.                     $char.
  167.  
  168. :BatchCONST 
  169.    PROCEDURE;
  170.       CALL  DiscoverNormalSourceForCurrentLine;
  171.       IF 0 THEN;
  172.      CALL  GO_OriginalCONST;  A >> ?;
  173.      IF 0 THEN;
  174.         A <- .  BatchCONSTReport;
  175.      ELSE;
  176.         CALL  Input1Char;
  177.         HL <-  Escape;  A - .HL >> ?;
  178.         IF = THEN;
  179.            CALL  InputAndInterpretCommandChar;
  180.            A <- .  BatchCONSTReport;
  181.         ELSE;
  182.            A -> .  UnsolicitedChar;
  183.            A <-  #FF;
  184.         END IF;
  185.      END IF;
  186.       ELSE;
  187.      CALL  GO_OriginalCONST;
  188.       END IF;
  189.       A >> ?;
  190.    END PROCEDURE;
  191.  
  192. :BatchCONIN 
  193.    PROCEDURE;
  194.       ? << A <- .  MiddleOfInputLine;
  195.       IF 0 THEN;
  196.      $Starting a new input line
  197.      IF;
  198.         CALL  DiscoverNormalSourceForCurrentLine;
  199.      IS 0 AND;
  200.         CALL  DiscoverNormalSourceForNextLine;
  201.      IS ~0 AND;
  202.         CALL  GO_OriginalCONST;  A >> ?;
  203.      IS 0 THEN;
  204.         CALL  RingBellIfEnabled;
  205.      END IF;
  206.      A <- .  NormalSourceForNextLine;
  207.         A -> .  NormalSourceForCurrentLine;
  208.       END IF;
  209.       CALL  Input1Char;
  210.       HL <-  Escape;  A - .HL >> ?;
  211.       IF = THEN;
  212.      CALL  InputAndInterpretCommandChar;
  213.      REPEAT;
  214.       END IF;
  215.       A -> B;                $Copy the char. that was input
  216.       CALL  TestWhetherUnsolicitedCharForcesSourceToBeConsole;
  217.       IF ~0 THEN;
  218.      A -> .  NormalSourceForCurrentLine;
  219.      A -> .  NormalSourceForNextLine;
  220.      0 -> A;  A -> .  UnsolicitedCharWasTypedIn;
  221.       END IF;
  222.       CALL  DiscoverNormalSourceForCurrentLine;
  223.       IF ~0 THEN;
  224.      B -> A;            $Copy the char. that was typed
  225.                     $in
  226.      ? << A -  CarriageReturn;
  227.      IF = THEN;
  228.         0 -> A;  A -> .  NormalSourceForNextLine;
  229.      END IF;
  230.      ? << A -  LineFeed;
  231.      IF = THEN;
  232.         B <-  CarriageReturn;    $Change the input char.
  233.      END IF;
  234.       END IF;
  235.       B -> A;                $Copy the char. that was input
  236.       IF;
  237.      ? << A -  CarriageReturn;
  238.       IS = OR;
  239.      ? << A -  NegativeAck;
  240.       IS = OR;
  241.      ? << A -  EndOfText;
  242.       IS = THEN;
  243.      $The next char. will start an input line
  244.      0 -> A;
  245.       ELSE;
  246.      $The next char. will be in the middle of an input line
  247.      A <-  TRUE;            $Just in case the char. was Null
  248.       END IF;
  249.       A -> .  MiddleOfInputLine;
  250.       B -> A;                $Copy the char. that was input
  251.    END PROCEDURE;
  252.  
  253. :TestWhetherUnsolicitedCharForcesSourceToBeConsole 
  254.    PROCEDURE;
  255.       ? << A <- .  UnsolicitedCharWasTypedIn;
  256.    PROCEDURE;
  257.  
  258. :DiscoverNormalSourceForNextLine 
  259.    PROCEDURE;
  260.       ? << A <- .  NormalSourceForNextLine;
  261.    END PROCEDURE;
  262.  
  263. :DiscoverNormalSourceForCurrentLine 
  264.    PROCEDURE;
  265.       ? << A <- .  NormalSourceForCurrentLine;
  266.    END PROCEDURE;
  267.  
  268. :Input1Char 
  269.    PROCEDURE;
  270.       HL <-  UnsolicitedChar;  .HL -> A;  ? << A -  NonexistentChar;
  271.       IF ~= THEN;
  272.      .HL <-  NonexistentChar;
  273.      EXIT;
  274.       END IF;
  275.       IF;
  276.      CALL  DiscoverNormalSourceForCurrentLine;
  277.       IS 0 AND;
  278.      CALL  GO_OriginalCONST;  A >> ?;
  279.      IF ~0 THEN;
  280.         A -> .  UnsolicitedCharWasTypedIn;
  281.      END IF;
  282.       IS 0 THEN;
  283.      HL <- .  BatchInputCursor;  .HL -> A;  HL + 1 -> HL;
  284.         HL -> .  BatchInputCursor;
  285.       ELSE;
  286.      CALL  GO_OriginalCONIN;
  287.      ? << A -  EndOfText;
  288.      IF = THEN;
  289.         CALL  TestWhetherUnsolicitedCharForcesSourceToBeConsole;
  290.            IF ~0 CALL  TerminateBatchProcessing;
  291.         A <-  EndOfText;
  292.      END IF;
  293.       END IF;
  294.    END PROCEDURE;
  295.  
  296. :InputAndInterpretCommandChar 
  297.    PROCEDURE;
  298.       $The char. must be input from the same source as the escape char.,
  299.       $regardless of any new unsolicited typed input
  300.       IF;
  301.      CALL  DiscoverNormalSourceForCurrentLine;
  302.       IS 0 AND;
  303.      CALL  TestWhetherUnsolicitedCharForcesSourceToBeConsole;
  304.       IS 0 THEN;
  305.      HL <- .  BatchInputCursor;  .HL -> A;  HL + 1 -> HL;
  306.         HL -> .  BatchInputCursor;
  307.       ELSE;
  308.      CALL  GO_OriginalCONIN;
  309.       END IF;
  310.       $Look up the char. in the table
  311.       HL <-  TableOf2ndChars;
  312.       B <-  (AfterTableOf2ndChars - TableOf2ndChars) / 3;
  313.       DO;
  314.      A - .HL >> ?;
  315.      IF = THEN;
  316.         $Interpret the char.
  317.         HL + 1 -> HL;  .HL -> E;  HL + 1 -> HL;  .HL -> D;
  318.            HL <-> DE;        $Addr. of interpretation
  319.                     $procedure -> HL
  320.         CALL  GO_rHL;
  321.         CALL  TestWhetherUnsolicitedCharForcesSourceToBeConsole;
  322.         IF ~0 THEN;
  323.            0 -> A;  A -> .  UnsolicitedCharWasTypedIn;
  324.         END IF;
  325.         EXIT  InputAndInterpretCommandChar;
  326.      END IF;
  327.      HL + 1 -> HL;  HL + 1 -> HL;  HL + 1 -> HL;
  328.      B - 1 -> B;  IF ~0 REPEAT;
  329.       END DO;
  330.       $If execution passes through here, no match was found
  331.       C <-  Bell;  CALL  GO_OriginalCONOUT;
  332.       C <-  "E";  CALL  GO_OriginalCONOUT;
  333.       C <-  "R";  CALL  GO_OriginalCONOUT;
  334.       C <-  "R";  CALL  GO_OriginalCONOUT;
  335.       $Test whether the erroneous command char. was input from batch
  336.       $text
  337.       IF;
  338.      CALL  DiscoverNormalSourceForCurrentLine;
  339.       IS 0 AND;
  340.      CALL  TestWhetherUnsolicitedCharForcesSourceToBeConsole;
  341.       IS 0 THEN;
  342.      CALL  TerminateBatchProcessing;
  343.       END IF;
  344.       REPEAT;
  345.    END PROCEDURE;
  346.  
  347. :GO_rHL   GO .HL;
  348.  
  349. :RingBellIfEnabled 
  350.    PROCEDURE;
  351.       ? << A <- .  RingForAttn;  IF 0 EXIT;
  352.       C <-  Bell;  CALL  GO_OriginalCONOUT;
  353.    END PROCEDURE;
  354.  
  355. :RequestTypedInput 
  356.    PROCEDURE;
  357.       A <-  1;  A -> .  NormalSourceForNextLine;
  358.       CALL  TestWhetherUnsolicitedCharForcesSourceToBeConsole;
  359.       IF 0 THEN;
  360.      CALL  DiscoverNormalSourceForCurrentLine;
  361.         IF 0 CALL  RingBellIfEnabled;
  362.      A <-  1;  A -> .  NormalSourceForCurrentLine;
  363.       END IF;
  364.    END PROCEDURE;
  365.  
  366. :RequestBatchInput 
  367.    PROCEDURE;
  368.       0 -> A;  A -> .  NormalSourceForCurrentLine;
  369.      A -> .  NormalSourceForNextLine;
  370.    END PROCEDURE;
  371.  
  372. :TerminateBatchProcessing 
  373.    PROCEDURE;
  374.       CALL  RingBellIfEnabled;
  375.       HL <- .  AdrOf_JMP_CONST;  DE <-  GO_OriginalCONST;  HL <-> DE;
  376.       B <-  AFTER_GO_BATCH - GO_BATCH_CONST;
  377.       DO;
  378.      .HL -> A;  A -> .DE;
  379.      HL + 1 -> HL;  DE + 1 -> DE;
  380.      B - 1 -> B;  IF ~0 REPEAT;
  381.       END DO;
  382.       A <-  1;  A -> .  NormalSourceForCurrentLine;
  383.      A -> .  NormalSourceForNextLine;
  384.    END PROCEDURE;
  385.  
  386. :NoOp 
  387.    PROCEDURE;
  388.    END PROCEDURE;
  389.  
  390. :RequestYesFromCONST 
  391.    PROCEDURE;
  392.       A <-  #FF;  A -> .  BatchCONSTReport;
  393.    END PROCEDURE;
  394.  
  395. :RequestNoFromCONST 
  396.    PROCEDURE;
  397.       0 -> A;  A -> .  BatchCONSTReport;
  398.    END PROCEDURE;
  399.  
  400. :RequestRingForAttn 
  401.    PROCEDURE;
  402.       A <-  TRUE;  A -> .  RingForAttn;
  403.    END PROCEDURE;
  404.  
  405. :RequestQuiet 
  406.    PROCEDURE;
  407.       0 -> A;  A -> .  RingForAttn;
  408.    END PROCEDURE;
  409.  
  410. :AfterModel 
  411. $**********************************************************************
  412.