home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / asm_programming / UASM.ZIP / UASM.DOC < prev   
Text File  |  1980-01-01  |  26KB  |  547 lines

  1.                                                                           1
  2.                                 UASM.DOC
  3.  
  4.         UASM  (for  Unassembler) consists of five files at this time:
  5.     UASM.DOC,  UASM-JMP.BAS,  UASM-INT.BAS,  UASM-STR.BAS  and  UASM-
  6.     DOS.MAC,  with  the purpose of converting the unassembled listing
  7.     of a .COM file from DEBUG into a .ASM file which can be  modified
  8.     and re-assembled with the Macro assembler.  
  9.  
  10.  
  11.  
  12.     **************************** NOTICE *****************************
  13.  
  14.        USER SUPPORTED SOFTWARE  (With thanks to Andrew Flugelman)
  15.      
  16.     A limited license is granted to  all  users  of  these  programs,
  17.     to  make  and  distribute  copies  for other users subject to the
  18.     following conditions:                                 
  19.  
  20.        1.  None of  the  notices  or  credits  are  to  be  bypassed,
  21.            altered, or removed.
  22.        2.  The programs are not to be distributed in  modified  form.
  23.            (Users are encouraged to distribute MERGE files.)
  24.        3.  No fee is  to  be  charged  (or  any  other  consideration
  25.            received) for copying or distributing the programs without 
  26.        an express written agreement with White Crane Systems.
  27.  
  28.     ***************************************************************
  29.  
  30.  
  31.  
  32.                UASM - The White Crane Systems Unassembler 
  33.  
  34.         If you are using these program  and  finding  them  of  value
  35.     please  send  a  cash  contribution  to  support their upkeep and
  36.     distribution.  Use the UASM  system  of  programs  to  unassemble
  37.     one average length .COM file, look over the results and calculate
  38.     how many hours this would have taken you  to  produce.   Multiply
  39.     this  by  the  minimum  wage,  contribute that amount and use the
  40.     program free thereafter.  If  that's  too  much  just  send  $20.
  41.     Supporters  will receive free notice of enhancements and updates.
  42.  
  43.         In any case you are encouraged to copy  and  distribute  UASM
  44.     to  your friends provided you do so free of charge and in unmodi-
  45.     fied form. 
  46.      
  47.                              Guy C. Gordon 
  48.                           White Crane Systems 
  49.                           3194 Friar Tuck Way 
  50.                           Doraville, GA 30340 
  51.  
  52.  
  53.                                                                          2
  54.  
  55.                               INTRODUCTION
  56.  
  57.         The strategy used in this system is  to  capture  the  output
  58.     of  DEBUG  and  run  it  through a series of BASIC programs, each
  59.     of which modifies one type of statement in  the  listing,  making
  60.     it  more like an .ASM source file.  This keeps each program short
  61.     and fast, and allows you to look over the  output  at  each  step
  62.     to  make  sure  no mistakes have been entered.  It also makes the
  63.     programs easy to understand and  improve  as  new  steps  can  be
  64.     added  without  interfering  with  the  first steps. Later in its
  65.     development UASM will combine these steps.   I  hope  that  users
  66.     of  these  programs  will  send  me  their improvements so that I
  67.     may add them to future releases.  
  68.  
  69.         UASM-JMP takes captured unassembled code  from  DEBUG  (which
  70.     we  will  name  FILE.DB)  and  finds  all addresses referenced by
  71.     the various Jump, Call, and Loop instructions.  These  referenced
  72.     addresses  are  made  into  labels  of the form Lhhhh (where hhhh
  73.     is the hex address).  A  new  file  (FILE.JMP)  is  then  written
  74.     in  the  form  of  assembler  source  code.  All of the addresses
  75.     and hex opcodes in the left two  columns  of  the  DEBUG  listing
  76.     are  left  out.   Referenced  lines  are appropriately labeled as
  77.     Lhhhh:.  In addition, unconditional  program  transfers  such  as
  78.     JMP,  JMPS,  RET  and  IRET have blank lines inserted after them.
  79.     If the next line is not referenced  it  will  be  force  labeled,
  80.     and  a  warning  comment  will be appended.  The line after a RET
  81.     or IRET is most likely the  beginning  of  a  Procedure,  and  is
  82.     preceeded by three blank lines.
  83.  
  84.         UASM-INT  reads  FILE.JMP  and  writes  FILE.INT  in which it
  85.     has added Macro calls and comments explaining the various  Inter-
  86.     rupts.   The  macros,  symbols,  and  comments  are read from the
  87.     file UASM-DOS.MAC.  This file contains a table of  EQUates  which
  88.     define  the  symbols  for  the various DOS function calls and the
  89.     DOSCALL macro.  It is included in FILE.INT by means of an INCLUDE
  90.     directive.
  91.  
  92.         UASM-STR  reads  FILE.INT  and  writes FILE.STR.  Whenever it
  93.     encounters a DOSCALL PRINT$ hhhh it reads  the  string  beginning
  94.     at  hhhh  from  the original .COM file and prints it as a comment
  95.     beside the macro call.  It also generates a  Dhhhh:  DB  'string'
  96.     instruction  at  the  end  of  the  file.  Carriage Returns, Line
  97.     Feeds, TABs and ESCapes are  expressed  as  symbols.   All  other
  98.     non-printing characters are expressed as hex data bytes.  Because
  99.     this will not catch all text strings in the file,  you  are  also
  100.     allowed  to  specify ranges of DEBUG addresses in which  UASM-STR
  101.     is to find all the strings  it  can.   Whenever  the  code  loads
  102.     the  DX  register  with the address of one of these strings, that
  103.     address is converted to a label and the string is  added  to  the
  104.     line as a comment.
  105.  
  106.                                                                          3
  107.         From that point on, you must take over and supply the remain-
  108.     ing text strings and variables that are  addressed.   You  should
  109.     heavily  comment  the  code  as  you go through it and change the
  110.     labels that UASM has assigned into more meaningful  names.   This
  111.     is  best done with the global change command in your text editor.
  112.     I also recommend using the Macro CREF program to obtain  a  cross
  113.     reference map of the symbols.
  114.  
  115.         These  programs  are  by  no  means  infallible, and they can
  116.     no more read the programmers' mind than you or  I,  so  you  will
  117.     have  to  check  the output closely.  If you expect to simply run
  118.     UASM and be handed a usable source file you're going to be disap-
  119.     pointed.   On  the other hand, if you've ever tried to understand
  120.     a program from just a DEBUG listing you will be  pleasantly  sur-
  121.     prised.   UASM  will  aid you in studying other programs by doing
  122.     a lot of the dirty work for you,  but  if  you  don't  study  the
  123.     code  you  won't  get  usable  output.   For example an interrupt
  124.     handling subroutine will not  necessarily  be  assigned  a  label
  125.     by  UASM-JMP  since it is not accessed by a Jump but by an inter-
  126.     rupt.  Therefore if you find a DOSCALL SET$INT hhhh in the  UASM-
  127.     INT  output  you  must check to see if the label Lhhhh was gener-
  128.     ated.  If not will have to go back to the DEBUG  output  to  find
  129.     the routine at address hhhh and assign it a label of your own.
  130.       
  131.         At  present,  UASM-INT  only  keeps  track of the AX, AH, AL,
  132.     DX, and DL registers.  Future improvements will  involve  a  more
  133.     complete  (and  much more complicated) DOSCALL macro in the UASM-
  134.     DOS.MAC file and the proper  calling  of  it  by  UASM-INT.   For
  135.     now, keep a close eye on the interrupts.
  136.  
  137.         I  have  been  using  these  programs to unassemble DEBUG.COM
  138.     and COMMAND.COM.  When  I  have  them  sufficiently  commented  I
  139.     will  post them on the BBS's.  At present I use mainly the Multi-
  140.     Link BBS at (404) 252-9438.  It is my hope that  UASM  will  lead
  141.     to a whole library of well commented, "reverse engineered" source
  142.     code for the MS-DOS operating  system  and  utilities.   I  would
  143.     appreciate anyone else working on the same to upload your results
  144.     to the BBS.  Suggestions and improvements  are  welcome.   Please
  145.     post them on the MultiLink BBS or send them directly to: 
  146.  
  147.                       Guy C. Gordon
  148.                 White Crane Systems
  149.                 3194 Friar Tuck Way
  150.                 Doraville, GA 30340
  151.                          OPERATING INSTRUCTIONS
  152.                                  -DEBUG-
  153.  
  154.         As an example, we will unassemble a fictitious file, FILE.COM
  155.     A>debug file.com
  156.     -r
  157.     .....CX=1780 ...            ;file length in hex bytes
  158.     -d 100 l 1780                       ;display entire file
  159.  
  160.  
  161.                                                                          4
  162.  
  163.         In  the listing that follows you should be able to spot ASCII
  164.     text and any regular binary tables.   Write  down  the  beginning
  165.     and  ending  addresses  of these, as we do not want to unassemble
  166.     them, but we will want a printed copy.  Our aim is to put togeth-
  167.     er  a  list  of  all  blocks of code to be unassembled and string
  168.     addresses for UASM-STR.  Look  at  the  code  before  each  block
  169.     of  text.   Usually  it  will  be preceded by a hex C3 which is a
  170.     RET instruction, but there may be a  JMP,  JMPS,  IRET,  or  RETF
  171.     instead.   This  is  the  last  instruction we want to unassemble
  172.     in the block of code preceding the  text.   Take  your  time  and
  173.     go  through  the  entire  file, unassembling code and making sure
  174.     that the output looks reasonable.  
  175.  
  176.         Reasonable code contains such things as CALL or Jump instruc-
  177.     tions  to  nearby  addresses,  INT  21  instructions and multiple
  178.     operations on single registers.  It does not contain DB  instruc-
  179.     tions or very many 00 bytes.  Also the ASCII display of a section
  180.     of code will look totally random, with  about  50%  of  it  being
  181.     displayable  characters.   (The  rest  will  be  periods.)  Peter
  182.     Norton has given a good demonstration of this  in  chapter  6  of
  183.     "Inside  the  IBM-PC".   One warning--the DEBUG unassembler tends
  184.     to lock into phase with the correct code,  which  is  very  nice,
  185.     but  be  certain  that  the  beginning  few instructions are also
  186.     in phase.  Sections of code that are in phase will contain  Jumps
  187.     and  CALLs  to  other  sections,  thus telling you where to start
  188.     unassembling.
  189.  
  190.         At the end of this investigation of the .COM file you  should
  191.     have  a  list  of  the  starting  and ending addresses of all the
  192.     code blocks and all the string blocks.   The  next  step  depends
  193.     upon  whether  you  have  DOS  2.0  or not.  It is much easier if
  194.     you have 2.0, or can to this  part  on  a  friend's  machine  who
  195.     has  it.   This  is  because under DOS 2.0 we can pipe the output
  196.     of DEBUG into a file thus  capturing  the  unassembled  code  for
  197.     input  to  UASM-JMP.   Under  DOS version 1. we must modify DEBUG
  198.     (using DEBUG of course) to get it to write the file we need.
  199.  
  200.  
  201.                                                                          5
  202.                         DEBUG - 2.0 Instructions
  203.  
  204.         Create a file, FILE.IN, with  the  following  DEBUG  instruc-
  205.     tions:
  206.  
  207.     u addr 1 addr 2                     ;addresses of blocks of
  208.     u addr 3 addr 4                     ; code to unassemble
  209.     u addr 5 addr 6                     ; from our initial investiga-
  210.     tion
  211.     q                           ;Quit instruction at end
  212.  
  213.         Now we can run DEBUG and pipe the output to a disk file
  214.  
  215.     DEBUG FILE.COM <FILE.IN >FILE.DB
  216.  
  217.         FILE.DB is the input for UASM-JMP.
  218.  
  219.  
  220.                         DEBUG - 1.1 Instructions
  221.  
  222.         While it is quite easy to capture the output of  DEBUG  under
  223.     DOS  2.0  since  we  can pip it to a file, under earlier versions
  224.     of DOS we have no such option.  However, DEBUG is an exceptional-
  225.     ly  powerful  program,  and  already  contains the code necessary
  226.     to write a disk file with the Write command.  We  will  use  this
  227.     to capture the Unassembled code.  
  228.  
  229.         If we unassemble and examine DEBUG, we can find the following
  230.     subroutine:
  231.  
  232.     02C8:02C0   PUSH    AX              ;save registers
  233.                 PUSH    DX
  234.                 AND     AL,7F           ;insure character is ASCII
  235.                 XCHG    DX,AX           ;put character in DL
  236.                 MOV     AH,02           ;DOS Function  2  to  display
  237.     DL
  238.                 INT     21
  239.                 POP     DX              ;restore registers
  240.                 POP     AX
  241.                 RET                     ;return
  242.  
  243.         As  it turns out, DEBUG does all of its screen output through
  244.     this subroutine.  Thus we can modify  just  this  subroutine  and
  245.     capture  each  character  as  it  is  displayed.  What we will do
  246.     with it is write it out to an unused  portion  of  memory.   From
  247.     there  we  can  write  all  the  output to a file using the Write
  248.     command.
  249.  
  250.                                                                          6
  251.         Our subroutine to store character AL  in  consecutive  memory
  252.     locations  will  be very small--about 20 bytes.  We'll need some-
  253.     place to put it.  For DEBUG 1.07 I  chose  to  put  it  inside  a
  254.     string  which  is  only  printed once--the message "DEBUG version
  255.     1.07" located at 0102.  Here is the subroutine:
  256.  
  257.     02C8:0102   DW      3300            ;pointer to memory
  258.                 PUSH    DI              ;save index register
  259.                 SEG     CS              ;offset form code, not ES
  260.                 MOV     DI,[0102]       ;get pointer
  261.                 SEG     CS              ;
  262.                 STOSB                   ;store char in AL into memory
  263.                 SEG     CS              ;
  264.                 MOV     [0102],DI       ;store incremented pointer
  265.                 POP     DI              ;restore register
  266.                 XCHG    DX,AX           ;complete  the   instructions
  267.     that
  268.                 MOV     AH,02           ;  CALL  to  this routine re-
  269.     placed
  270.                 RET                     ;Return to Display routine
  271.  
  272.         We can store this subroutine over the string with  the  Enter
  273.     command.  (here  02C8 is the base address where DEBUG is loaded):
  274.  
  275.     E 2C8:102 00 33 57 2E 8B 3E 02 01 2E AA 2E 89  3E  02  01  5F  92
  276.               B4 02 C3
  277.  
  278.     We  can  check  that  this  was entered correctly by Unassembling
  279.     it:
  280.  
  281.     U 2C8:104           ;you should see the subroutine listed above.
  282.  
  283.         The choice of memory location is up  to  you.   3300  Is  the
  284.     value  I  used  while  unassembling  DEBUG.   It should be larger
  285.     than the sum of the sizes (in bytes) of  DEBUG  and  the  program
  286.     you  are  unassembling.  To have this subroutine called each time
  287.     DEBUG writes a character, we insert a subroutine Call:
  288.  
  289.     E 2C8:2C4 E8 3D FE          ;Call 0104
  290.  
  291.     This puts a CALL 0104 in place  of  XCHG  DX,AX  and  MOV  AH,02.
  292.     That  is  why  we  perform those instructions before returning to
  293.     the display routine.  The very  next  charter  printed  by  DEBUG
  294.     after  you  Enter  the  above  command will be stored in location
  295.     2C8:3300 as well as displayed on the screen. 
  296.  
  297.  
  298.                                                                          7
  299.         Immediately after entering the  CALL  instruction  above  you
  300.     should  begin  the  Unassemble  commands that you determined will
  301.     give you all the code for the program.  
  302.  
  303.     U 100 4D5
  304.     U 6b0 799
  305.     etc.
  306.     D 2C8:102 103               ;This displays  the  pointer  to  the
  307.     end of text
  308.         B3 D9           ;This means we filled memory to D9B3
  309.                         ;(remember the 8088 stores words backwards)
  310.     H D9B3 3300         ;Hex arithmetic
  311.         0CB3 A6B3       ;  D9B3 - 3300 = A6B3
  312.     R CX
  313.         CX=1748
  314.         :A6B3           ;load  CX  register  with  number of bytes to
  315.     write
  316.     N FILE.DB           ;name the output file
  317.     W 2C8:3300          ;start writing at 3300 off. from DEBUG base
  318.        Writing A6B3 bytes
  319.     E 2C8:102 00 33             ;reset pointer if out of space
  320.  
  321.         Remember, you can only write text to memory up  to  2C8:FFFF.
  322.     If  you  exceed  that  you  will write over DEBUG at 2C8:0000 and
  323.     will probably have to re-boot.  If FILE.COM is too big  to  Unas-
  324.     semble  in  one  pass  you'll  have to do it in pieces and append
  325.     them together with your text  editor.   For  this  reason  it  is
  326.     a  good  idea  to  modify  and save a copy of DEBUG under another
  327.     name such as UDEBUG.  If you need to perform any other operations
  328.     with  a  modified  DEBUG  that  you do not want written to memory
  329.     you can restore DEBUG to normal operation with:
  330.  
  331.     E 2C8:2C4 92 B4 02  ;restores XCHG DX,AX and MOV AH,02
  332.  
  333.         Now text edit FILE.DB and remove any  extraneous  lines  such
  334.     as  debug  prompts  that might have been displayed.  If there are
  335.     any TABs in FILE.DB they will confuse UASM-JMP  and  the  others.
  336.     DEBUG  1.1  appears  to  put  a  TAB after each instruction while
  337.     version 2.0 does not.  I always use the  text  editor  to  change
  338.     all  TABs  to the appropriate number of spaces.  (Users of PMATE,
  339.     use the YF command.)
  340.  
  341.         Any of the memory addresses above may vary with your  operat-
  342.     ing  system  and  DEBUG  version.   The  values given are for the
  343.     Victor 9000, MS-DOS 1.25a, and  DEBUG  1.07.   The  Base  Segment
  344.     where  DEBUG  is loaded (2C8 above) will depend upon your machine
  345.     and operating system, and is  found  by  using  DEBUG  to  Search
  346.     for itself in memory.  The display subroutine (2C0 above) depends
  347.     upon your DEBUG  version  number.   The  same  subroutine  occurs
  348.     at  2B5 in the DEBUG that comes with PC-DOS 1.10, and will appear
  349.     near these locations in any  other  version  1  DEBUGs.   If  you
  350.     store  the  capture  subroutine at some other place in memory you
  351.     need to change the two [0102] references and the  CALL  0104  in-
  352.     struction.  
  353.  
  354.                                                                          8
  355.                          UASM-JMP  Instructions
  356.  
  357.          Run UASM-JMP as you would any basic program.  It will prompt
  358.     you for the name of  input  and  output  files.     Respond  with
  359.     FILE.DB  ,which  we  created  above,  and  B:FILE.JMP for output.
  360.     If file extensions are not provided, .DB and .JMP will be assumed
  361.     for  input  and  output  respectively.  Also the output file name
  362.     will default to the input file name. I highly  recommend  putting
  363.     these  files  on  separate drives if you don't have a fixed disk.
  364.     This will speed up the program and save wear on your floppies.
  365.  
  366.         UASM-JMP will make two passes through  the  input  file.   On
  367.     the  first  pass  it  will  build a list of all referenced lines.
  368.     It then sorts this list (shell sort), eliminates  duplicate  ref-
  369.     erences,  and  on  the second pass, labels all of the references.
  370.     The output will be displayed on your screen as  well  as  written
  371.     out on the second pass.  
  372.  
  373.         If  the  program  finds a Jump or CALL to an address not con-
  374.     tained in the file you will get the  message  "WARNING!  No  code
  375.     for  this  label".   This  most likely means you missed the block
  376.     of code starting at address hhhh and  will  have  to  add  it  to
  377.     the  input  file for DEBUG.  The statement after an unconditional
  378.     program transfer (JMP or RET) is  always  labeled.   The  message
  379.     "WARNING!  This  label  not  referenced"  means  that there is no
  380.     Jump or CALL to this label.  It might be  an  interrupt  handler,
  381.     or  it  might  just  be  left over code in a modified program.  A
  382.     large number of these errors might indicate  that  they  are  ac-
  383.     cessed  by  an  address  table.   Both  of the above errors might
  384.     occur if you miss a block of code, unassemble  a  data  area,  or
  385.     the code modifies itself.
  386.  
  387.  
  388.                          UASM-INT  Instructions
  389.  
  390.         To run UASM-INT you must also have the data file UASM-DOS.MAC
  391.     on the default drive.  UASM-INT will  prompt  you  for  an  input
  392.     and  output  file  names.   If  extensions are not provided, .JMP
  393.     and .INT will be  assumed  for  input  and  output  respectively.
  394.     The  program  then  loads  the  symbol  table  contained in UASM-
  395.     DOS.MAC.   While  reading  through  FILE.JMP,  whenever  UASM-INT
  396.     encounters  an  INT  instruction  it  adds  a Macro call, Symbols
  397.     for the DOS function calls, and Comments  from  the  UASM-DOS.MAC
  398.     file.   These  lines  will also be displayed on the screen as the
  399.     program progresses.  Note that  the  DOSCALL  Macro  is  inserted
  400.     in  the  text,  but  the  INT  instruction is not deleted.  After
  401.     you have checked the code you must delete the  INT  and  any  MOV
  402.     instructions that will be duplicated by the Macro.
  403.  
  404.                                                                          9
  405.                           UASM-STR Instructions
  406.  
  407.         To  run UASM-STR you must have the original FILE.COM or other
  408.     binary file on disk.  The program will prompt you for the  input,
  409.     output,  and  binary  file  names.   These  will default to .INT,
  410.     .STR and .COM if no other extension  is  given.   As  usual,  the
  411.     input  file  name will be used as a default if you do not specify
  412.     the others, and you should put the output  file  on  a  different
  413.     floppy drive than the input file.  
  414.  
  415.         You  will  then  be  prompted  for  any string area addresses
  416.     that you may have found  while  examining  FILE.COM  with  DEBUG.
  417.     You  may  enter  an  address  range (hhhh kkkk) or the address of
  418.     a single string (hhhh) on each line.  (Up  to  ten  lines)   Each
  419.     address  must  be  a  four  digit hex offset (taken directly from
  420.     DEBUG).  Upon receiving a blank line as input, the  program  will
  421.     find  all  strings  terminated  with  a  $  starting at the first
  422.     address in a range  and  continue  finding  multiple  strings  to
  423.     the  second  address  if  present.   If a single address is given
  424.     on a line a single string will be  read.   Each  string  is  dis-
  425.     played as it is found.  
  426.  
  427.         Following  this  the  program  reads  through  FILE.INT.  For
  428.     each "DOSCALL PRINT$   hhhh"  encountered  it  reads  the  string
  429.     from  FILE.COM  at  the  specified  location (taking into account
  430.     the 100H byte program prefix) and prints that string as a comment
  431.     next  to  the  Macro.   Also, each time the DX register is loaded
  432.     with the address of a string, that string is shown  next  to  the
  433.     code.   At  the  end  of  the file, UASM-INT will append a number
  434.     of EQUates and Data statements and define  the  string  variables
  435.     with  names  Dhhhh.   Non-printing  characters are converted into
  436.     hex bytes.  CR, LF, TAB, ESC, and $ are defined as symbols.
  437.  
  438.                                                                         10
  439.                  SAMPLE OUTPUT - Excerpts from DEBUG.STR
  440.  
  441. INCLUDE UASM-DOS.MAC
  442. .RADIX  16 
  443.  
  444. START:  JMPS    L011D            
  445.  
  446. L011D:  MOV     SP,1822 
  447.         MOV     [1897],AL 
  448.         MOV     DX,0102 
  449.         MOV     AH,09 
  450.         INT     21 
  451.  
  452. DOSCALL PRINT$,D0102       ;CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  453.         MOV     AX,2522 
  454.         MOV     DX,01E6 
  455.         INT     21 
  456.  
  457. DOSCALL SET$INT     01E6   ; Set interrupt vector (AL=INT, DS:DX=VECTOR)
  458.  
  459.         MOV     AL,23 
  460.         MOV     DX,01EB 
  461.         INT     21 
  462.  
  463. DOSCALL SET$INT     01EB   ; Set interrupt vector (AL=INT, DS:DX=VECTOR)
  464.  
  465.         MOV     DX,CS 
  466.         ADD     DX,01AB 
  467.         MOV     AH,26 
  468.         INT     21 
  469.  
  470. DOSCALL BUILD$PS    01AB      ; Create new program  segment  (DX=SEGMENT)
  471.  
  472.  
  473.         MOV     AX,DX 
  474.         MOV     DI,1832 
  475.         STOSW 
  476.         MOV     DX,0080 
  477.         MOV     AH,1A 
  478.         INT     21 
  479.  
  480. DOSCALL SET$DTA     0080      ; Set Disk Transfer Address to DX 
  481.  
  482.         MOV     AX,[0006] 
  483.         MOV     BX,AX 
  484.         CMP     AX,FFF0 
  485.         PUSH    CS 
  486.         POP     DS 
  487.         ADD     [0008],BX 
  488.         MOV     DI,005C 
  489.         MOV     SI,0081 
  490.         MOV     AX,2901 
  491.  
  492.                                                                         11
  493.         INT     21 
  494.  
  495. DOSCALL PARSE$         ; Parse Filespec (SI -> LINE, DI -> FCB, AL=CODE)
  496.  
  497.         CALL    L0917 
  498.         PUSH    CS 
  499.         POP     ES 
  500.         CMP     B,[005D],20 
  501.         JZ      L01B5 
  502.         JMPS    L01B5 
  503.  
  504. L01E3:  JMP     L04CB 
  505.  
  506. L01E6:   MOV      DX,167A             ;WARNING! This label not referenced
  507.         MOV     DS,AX 
  508.         MOV     SS,AX 
  509.         MOV     SP,1822 
  510.         MOV     AH,09 
  511.         INT     21 
  512.  
  513. DOSCALL PRINT$            ; Display string @DX till terminator 
  514.  
  515.         JMPS    L01B5 
  516.  
  517. L01FD:  MOV     AH,0A 
  518.         MOV     DX,1844 
  519.         INT     21 
  520.  
  521. DOSCALL INSTR$      1844  ; Input keyboard string (DX -> size,cnt,buffer)
  522.  
  523.         MOV     SI,1846 
  524. ;END CODE 
  525. .RADIX  16 
  526. CR      EQU     0D 
  527. LF      EQU     0A 
  528. TAB     EQU     09 
  529. ESC     EQU     1B 
  530. $       EQU     24 
  531. D167A   DB      CR,LF,'Program terminated normally',CR,LF,$ 
  532. D169A   DB      'Invalid drive or file name',CR,LF,$ 
  533. D16B7   DB      'File not found',CR,LF,$ 
  534. D16C8   DB      'No room in disk directory',CR,LF,$ 
  535. D16E4   DB      'Insufficient space on disk',CR,LF,$ 
  536. D1701   DB      'Disk$' 
  537. D1706   DB      'Write protect$' 
  538. D1714   DB      ' error reading drive A',CR,LF,$ 
  539. D172D   DB      'readwritInsufficient memory',CR,LF,$ 
  540. D174B   DB      '^ Error',CR,8A,' ',88,'Error in EXE/HEX file',CR,LF,$
  541. D176E   DB      'EXE/HEX file cannot be written',CR,LF,$ 
  542. D178F   DB      'Writing $' 
  543. D1798   DB      ' bytes',CR,LF,$ 
  544. D0102   DB      CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  545.   ' bytes',CR,LF,$ 
  546. D0102   DB      CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  547.