The Latest Version of Toad Hall's TOADCPM.COM
                    (Version 2.2, 10 Dec 83)


     Using various patches (credit given below), I've patched CPM 
2.2 to add some things I've found very useful:


PRINTER:   In  Version  2.1,  it's  configured for  a  9600  baud 
printer,  using  the Data Ready protocol (donno if it's the  best 
for  my Mannesman Tally,  but it works!).   Version 2.2  now  has 
XON/XOFF,  which  works just fine using exactly the same cabling.  
Seems to cause a bit less delay when simultaneously printing  and 
making  keyboard  entries  during  UNSPOOL  or  WordStar's  PRINT 
utility.   [Note:   As of 10 Dec I went back to Xon/Xoff, just to 
see if there was a difference.  None, really.]


ASSEMBLY SETTINGS:  (Look at the TOADBIOS.ASM listing for details 
-- it's for the XON/XOFF, 19200 baud Version 2.2, but all changes 
are  fully  documented.)  You'll see it's for a 64K  system  with 
DEBUG set to ON to give me various sizes and locations during MAC 
assembly, and NONSTANDARD set to 1 (donno why; I thought Morrow's 
BIOS  was conventional,  but I'm just following the advice of  my 
vendor/-confidant  Jack  Long at Cost Plus Computers -- and  he's 
batting a thousand so far!).   The original CBIOS&.ASM had at one 
point a value set to DECISION I I/O instead of Mult/IO; suspecting 
this  might  be giving me some problems in  using  the  clock,  I 
changed it to Mult/IO, which is exactly what's in my Decision I.


DUPLICATE *.COM  FILES:   I  dislike  having  to  duplicate  .COM 
programs  (utilities and other files) in different User Areas and 
disks when my trusty 5 Meg hard disk is just sitting there as the 
default A disk most of the time.

    I've  used DUPUSR.COM (a program to put a kind of pointer  in 
each User area directory so you get the name of a program or file 
in that directory, but not the actual file.  This means no actual 
disk  storage  space  used.),  but  DUPUSR  has  one  SEVERE  AND 
DANGEROUS problem:   if you erase a DUPUSR-created file name  and 
don't  hit  CTRL  C right after the erasure,  you can  have  some 
SEVERE directory damage!   About the third time I trashed my hard 
disk  directory through carelessness like this,  I decided  there 
had to be a better way!

     I  read an article out in Netland by Neil Maron that gave  a 
patch to make the system look on drive A: if your .COM file isn't 
on the logged in drive.   Additionally,  if it isn't on A: in the 
same  User Area,  it'll look to User Area 0 for that file  before 
giving  up.   This means I can keep all the common utilities  and 
.COM files in User Area 0 on my hard disk,  configure my CP/M  to 
always use the hard disk as A:, and I'm in business.  

     There are only a couple of places where this fails me.

    a.   WordStar:   You can have WS.COM on disk A,  User Area 0, 
all  right,  BUT  you  must have the *.OVR files it uses  in  the 
default disk (A for me) and the User Area you're working in!   WS 
can  be  installed or patched to look to a default disk  for  its 
.OVR files,  but it does NOT know how to look to User Area 0!  No 
problem,  really  -- this  is  where I take the  chance  and  use 
DUPUSR.   I  DUPUSR the .OVR files to all appropriate User  Areas 
where  I might want to run WS.COM.   I naturally use STAT to make 
the  .OVR  files Read/Only and $SYS so they don't clutter  up  my 
directory  and I won't erase them by accident.   I  don't  bother 
copying  WS or the .OVR files to other disks,  but instead depend 
on the default disk (A).

     b.  MBASIC (Microsoft BASIC v.  5.1) doesn't seem to want to 
accept  a  compound command line like MBASIC STARTREK  if  MBASIC 
isn't actually on that disk or in that User Area.   (I think it's 
a function of Neil's patch only looking at the .COM file name and 
not handling the STARTREK extension properly.)  No big problem -- 
I  have  two options:   (1)  RUN MBASIC (which works  just  fine, 
reaching  out to A:  and then if necessary User Area 0 on  A:  to 
find  MBASIC)  and then when in MBASIC,  LOAD or RUN  whatever  I 
want; or (2) DUPUSR MBASIC into necessary User Areas so I'll know 
it's there.  (Again protect it with R/O and $SYS.)

    c.  SUBMIT may give some problems.  So far I've had none, but 
there are lots of fancy applications,  modified SUBMITs, etc. out 
there  where  this may hang up.   If there's a problem  with  any 
SUBMIT applications,  just DUPUSR it into the User Area requiring 
SUBMIT applications and forget about it.

    d.   My library is a bit limited,  but if you have any  other 
fancy  programs  that  do lots of overlaying,  calling  in  other 
programs,  etc.,  you'd better not depend on this A:  User Area 0 
patch working correctly.   I suspect Visicalc, DBaseII, and those 
kinds of application programs won't take kindly to it!

     One  thing -- if you DON'T have your hard disk set up as  A, 
then you need to change those JMPs around.   Make CP/M first look 
to User Area 0 on the present disk,  and then to Drive  A.   That 
way,  if  you're working in your hard disk,  it'll check out User 
Area  0  there  first before running off to  look  at  some  poor 
innocent floppy.  


USER AREA WITH > PROMPT:   I HATE not knowing which User Area I'm 
in,  and  I've had some real problems.   Examples:   You get  the 
infamous  BDOS ERR ON d:  error message;  you get kicked back  to 
User  Area  0 automatically;  you don't know or remember  it  and 
erase or do something to a file;  and successfully trash the very 
special,  unique,  and  wonderful file in User Area 0 you had  NO 
intention of messing with!

    In any case,  it's a pain having to go back to the right User 
Area  again.   The  original  code was written by  Bruce  Kendall 
(address unknown)  7-12-80,  and  tightened up  by  Bruce  Ratoff
11-17-80.  I made all the Morrow Decision CP/M-specific stuff.
     Basically, it patches a little CALL into the portion of your 
CCP  that prints the > prompt,  reaches out to a wee little patch 
that was poked into an area of NOPs in the CCP that gets the User 
Area and then displays current disk,  user area (in hex  -- sorry 
abot that -- had to keep it small),  and > prompt, and goes right 
on about its business!   Real simple.  [Note:  I grabbed a little 
routine  from another program (donno where),  and made this patch 
now print the User Area in decimal after the disk.   Couldn't  do 
this  with  a  "hot patch" in the actual BIOS;  had to do  it  in 
assembler in the source code.  If you HAVE source code, great!]

    The  TOADCPM.COM  on this disk (assuming you have  the  disk) 
includes that patch.   The code is at the end of this article  if 
you  want  to  implement  it yourself in  your  own  BIOS.   It's 
definitely nice to have,  and not at all hard to implement.  Note 
that  I  did NOT make this a stand-alone little  program  that'll 
reach out and patch your CP/M in memory.   You'll have to use DDT 
for this,  and if you aren't sure of the procedures,  a  step-by-
step  (hopefully eminently logical and easy to follow)  procedure 
is  outlined right after the source code.

    The  memory locations given are for Morrow Design's CP/M  for 
their Decision I (where the CCP starts at 0B00H in the DDT image, 
and at D400H in real memory).  If your CCP starts somewhere else, 
you'll  have to figure out your own locations for  COUT  (console 
out), GTCMD (Get Command), PATCH (my patch in the NOP area of the 
CCP),  etc.   Not  very hard -- you can use the H tool in DDT  to 
figure  out some offsets.   (If you're doing these hacks in  your 
own CCP and BIOS,  it's time for you to figure out DDT,  offsets, 
DDT images, real images, etc. anyway!)


AUTOSTART:   There  have  been several articles around on how  to 
make   a  "turn-key"  system  with  CP/M  and   its   "Autostart" 
capability.   Basically,  they  involve making a version of  CP/M 
that has a .COM file name already in the CCP where CP/M looks for 
a  program  name  to execute.   When you boot up (cold  or  warm, 
depending),  that program will run.  One article fully explaining 
it is "'Turn-Key' CP/M Systems" by James J.  Frantz, published in 
Creative Computing,  December 1979.   (It's for CP/M Version 1.4, 
but not to worry - that part still is the same in Ver 2.2.)

    One little problem with this,  though!  Morrow's CBIOS& has a 
kind of switch (variable name AUTOST) in the source code that you 
have to turn on for Autostart to work!  You have several options:  
Never, only on cold boot, only on warm boot, and on both cold and 
warm boot.   This version is engaged for warm and cold boot.  The 
default command "AUTO" is plugged in at the front of the CCP, but 
will  have  absolutely  no  effect so long as you  don't  have  a 
AUTO.COM file in User Area 0!  If you do ... it'll run!  (You can 
get  rid of this with DDT by replacing from 0B07H (DDT image)  up 
to the remaining 20's with 20, and then SAVE 48 TOADCPM.COM. 

     If  you're  hacking  up  a special  CP/M  for  an  Autostart 
program,  the warm boot and cold boot commands can be entered  as 
DB's  right  around  page  12 of Morrow's CBIOS  Revision  E  for 
Version  2.2  (Mar 4 1982) as provided with my  Decision  I.   In 
memory,  if you want to poke it into your CCP,  it's right at the 
very  start  of your CCP (0B00H in the DDT image  on  my  system) 
where you can see the Digital Research copyright.

     I'm not going to give that full procedure here -- plenty  of 
other references out there already published.  But you can put it 
right in your CBIOS while editing it a lot easier than looking up 
hex and poking into memory.   Remember,  though -- just poking in 
the  Autostart command (with its accompanying requirements,  like 
length of command in CCP+7, and a NOP or 00 after the command) is 
NOT sufficient with Morrow's CBIOS!   You HAVE to turn that Auto-
start switch on!  (Drove me crazy for a while until I figured out 
that was the problem!)


COLDBOOT  TO  YOUR HARD DISK:   My system originally used  an  8" 
floppy  to cold-boot,  and then I had to run "BOOTMW" to make  my 
hard disk A:.  This was a bit of bother, and I accidentally found 
the  answer:   Load the Hard Disk version of CP/M on the  floppy!  

     Morrow  supplied me with MOVCPM-5 to create a CP/M for my  5 
Meg hard disk,  and that's what I used (SYSGENing it to the  hard 
disk,  etc.).   Fine  and  dandy -- saved a nice CPM-HD on  file.  
Then  I accidentally used DDT to do some patches on THAT  version 
of CP/M,  saved it,  and SYSGENed it onto an 8"  floppy!   (Never 
would  have  done  it on purpose -- obviously a  hard  disk  CP/M 
shouldn't  be on a floppy!)  Damned if it didn't work just  fine!  
I put in the floppy, do a reset, she boots, and bingo -- the cold 
boot message comes on, showing the HDCMA hard disk as A:, and the 
8"  as  B:.   And in fact,  that's what's happened -- not just  a 
bogus message.  Works fine, and I've had no problems whatsoever.

    One  little  thing:   You  need the new  improved  CP/M  with 
improved  TDBIOS on your hard disk too,  else the warm boot  just 
boots up the old normal CP/M.  So SYSGEN TOADCPM (or your version 
of your hard disk CP/M with TOADBIOS.ASM) onto both your floppies 
and  your  hard disk.   Works - guaranteed.   (Keep a  couple  of 
floppies around with a normal (i.e., A: is a floppy) just in case 
your hard disk goes down some day!)


TERMINAL/SERIAL BAUD UPGRADE:   Version 2.2 relies on a different 
approach.   Jack  Long  at  Cost-Plus said he tried  to  set  the 
switches  on the CPU board to have the Decision I do a cold  boot 
from the hard disk.   Worked,  OK,  but then refused to recognize 
any  other  disks!   This put me off for a while,  but  found  my 
technique of booting from a floppy and switching over to the hard 
disk  was giving me problems when I tried to upgrade my I/O board 
and terminal to 19,200 baud.

     The Mult/IO board has no baud rate switches at all, and will 
initialize at 9600 baud.  On a cold boot, the Morrow Designs CP/M 
bots from the floppy, loads the monitor (the FFFF: business), and 
then  expects some sort of monitor command.   ("B" is all  that's 
necessary  to tell it to boot off the PROM.)   Unfortunately,  if 
the  Mult/IO board is running at a default 9600  baud,  and  your 
terminal  is set to 19200,  the doggoned monitor can't read  that 
"B",  and you never WILL get booted!  Real hassle, that -- and if 
you  cold boot with everything set at 9600,  then you have to use 
Morrow Design's BAUD.COM to kick up the CPU board and Mult/IO  to 
19200,  physically  kick  up the terminal to 19200 (can't send  a 
command to it,  you know -- not if the serial port's putting  out 
twice as fast as the terminal can read!) ... a real pain!

     Finally  got it working by setting the console default  baud 
rate  to  19200,  setting  the terminal switches  to  19200,  and 
setting  Switch 6 on the Morrow CPU board to ON (engages  a  cold 
boot from the floppy,  skips the monitor, and boots right up with 
no  terminal  input required.   The CBIOS initializes the  serial 
port to 19200,  using that default baud rate, before the terminal 
ever comes into play.

     One little side effect I STILL haven't figured out:   every-
thing  boots  up  fine (provided you gave the  hard  disk  a  few 
seconds  to  come up to speed before hitting that reset  button), 
but  after  the cold boot message and A0> prompt,  I  get  a  ^Q!  
Donno  why  - think I'm overflowing the buffer with my cold  boot 
message.  No big thing; hope to fix it soon.

     I  have  not yet tried to cold boot from the hard  disk  (by 
setting switches 1 through 5 to ON ON ON ON ON.   I don't  really 
like  the  idea since it demands a lot of a barely  running  hard 
disk that MIGHT not be up to speed yet!  

[Note:   I've now added modem port (serial port 3) initialization 
to 1200 baud on cold boot and port  initializations.   Sorry,  no 
code  here  since it's quite Morrow-specific;  will add  to  this 
document later.]

COMPANY  CREDIT LINE ON COLD BOOT:   You can see the little "Toad 
Hall" logo come on,  plus some patch comments,  on the cold  boot 
message.   Easy  - just added it into the CBIOS when editing  it.  
That's on page 76 of Morrow's CBIOS& listing, way toward the end.  
Just add in whatever you want (well,  keep it reasonable -- don't 
want  to make this CBIOS TOO big,  you know!)  Don't forget  ACRs 
and ALFs (carriage returns and line feeds) where appropriate.   I 
mentioned above that ^Q problem after a cold boot.   I suspect it 
comes  from an excessive cold boot message,  so be  warned!   [It 
didn't!   Still don't know the answer.  Suspect just some garbage 
left  around  the  Multi I/O board that wasn't  purged  correctly 
after  initialization  that shows when running  the  terminal  at 
19200 baud!]


MISCELLANEOUS LOCATIONS:  If you MAC TOADBIOS.ASM, you'll get most 
of these as a DEBUG message.  However, just for your information:

     OFFSETC        3700           Offset in CP/M when R'ing
                                   TOADBIOS.HEX on top of your
                                   CPM64.COM in DDT.
     CCP            D400           Start of CCP in real memory
     CCP            0B00           Start of CCP in DDT image
     BDOS           DC00           Start of BDOS in real memory
     BIOS           EA00           Start of TOADBIOS in real memory
     BIOSLN         16             Length of TOADBIOS in pages.
     BIOSHEXLN      0F00           Length of TOADBIOS in hex.
     CCPLEN         800            Length of CCP in hex.

     USRPTCH1       0E8D           Actual location in DDT image
                                   of first User Area Patch.
     USRPTCH2       20F0           Beginning of second User Area
                                   patch in NOP area of DDT image
                                   of CCP.
                    CAD3           First patch in CCP to 
                                   jump to second patch in CCP
                                   for A: User Area 0 default.
                    1DB3           Location in DDT image of
                                   first patch.
     PATCH          12F2           DDT image location of larger
                                   patch in CCP for default A:.
     PATCH1         EC50           Real memory location in 
                                   TOADBIOS of default code.

                    - - - - - - - -

USER AREA DISPLAY CODE:

DDT IMAGE      INSTRS & REAL MEMORY LOCATIONS

0E82      LXI  SP,DBAB        ;original code
0E85      CALL D498           ;    "    ", flush
0E88      CALL D5D0           ;    "    ", get drive
0E8B      ADI  41             ;    "    ", 'A'
- - - - - and here's the patch - - - - -
0E8D      CALL E9F0           ;patch - was CALL D48C, console out
- - - - - end of patch - - - - -
          MVI  A,3E           ;original code - '>'
          CALL D48C           ;    "    ", console out
          CALL D539           ;    "    ", get cmd


ext patch is in an area of NOPs in the CCP - check to be sure!
(And  don't  get  too  low in  that  area:   I  think  it's  disk 
parameters  or something!   Go too low with your patch and  it'll 
get  overlaid  and eaten up!)  If something's  there,  just  find 
about  1 1/2 lines of NOPs somewhere in your CCP where this  will 
fit  (maybe  just  before the BDOS where there's  sometimes  some 
room).   Use DDT's A (for Assembly) instruction to stick in  this 
stuff just like you see it.   If your CCP does NOT start at D400, 
then you'll have to figure out an offset.  Best place to do this, 
of  course,  is  in your CBIOS in assembly -- makes it  all  much 
easier to squeeze.

DDT LOC   REAL MEMORY LOCATIONS

20F0      CALL D48C           ;console out routine
          CALL D513           ;get user routine
          ADI  90H            ;routine to convert to number
          DAA
          ACI  40H
          DAA
          JMP  D48C           ;console out again, which returns
                              ;us automatically to right after
                              ;the first patch at 0E8D where
                              ;things continue like normal.
[Note:   above  was per the original patch.   My patch NOW  reads 
like this to produce the decimal user area:

USRPTCH:
          CALL 0D48CH         ; Console Out routine.
          CALL 0D513H         ; Get User routine.
          CPI  10             ; If User # >9, print leading 1.
          JC   DUX
          PUSH PSW            ; Save A w/User #.
          MVI  A,'1'          ; Load the 10 digit for Conout
          CALL 0D48CH         ; Conout.
          POP  PSW            ; Get A w/User # back.
          SUI  10
DUX:      ADI  '0'
          ORA  A              ; Clear flags.
          JMP  0D48CH         ; Print second digit.
; End of patch
                              
I include the original code below,  just for reference.   It has 
the original locations, plus my patched Morrow locations.

;  --- PATCH TO CP/M 2.X TO LIST USER # IN DRIVE PROMPT ---
;	    ( VALID FOR CP/M 2.0, 2.1, AND 2.2)
;		BY BRUCE KENDALL (TKI)
;		      7/12/80
;		TIGHTENED UP BY BRUCE RATOFF
;		     11/17/80
;
;	IF YOU HAVE TRIED PLAYING WITH THE  'USER' COMMAND
;	IN CP/M 2.X, YOU MAY HAVE BECOME ANNOYED THAT THERE
;	WAS NO WAY OF TELLING WHAT USER AREA YOU WERE IN.  THIS
;	PATCH SOLVES THIS PROBLEM BY DISPLAYING THE USER NUMBER
;	IN HEX ( A SINGLE CHARACTER SINCE USER # : 0-15 ARE VALID)
;	BETWEEN THE DRIVE NAME LETTER AND THE '>'. THAT IS, A USER
;	LOGGED INTO USER AREA #4 WOULD SEE THE STANDARD CP/M 
;	PROMPT (MODIFIED BY THIS PATCH) AS:
;		A4>       ( INSTEAD OF JUST A>)
;
MSIZE	EQU	64	; CP/M SYSTEM SIZE IN KB
;
DELTA	EQU	1000H	; OFFSET FROM STD CP/M SIZE
			; THIS WOULD BE SET TO 400H IF
			; THE 20K CP/M WAS ACTUALLY A 19K
			; CP/M (WHEN COMPARED TO THE STD
			; 20K CP/M DESCRIBED IN THE CP/M
			; MANUALS FROM DIGITAL RESEARCH).
;
BIAS	EQU	(MSIZE-20)*1024-DELTA ; OFFSET FROM 20K CP/M
CCP	EQU	3400H+BIAS
;
OFFSET	EQU	980H-CCP ; OFFSET USED WITH  DDT IN 
			; SYSTEM CONFIGURATION (ASSUMES
			; THAT 'CCP' OCCURES AT 980H IN THE
			; SYSGEN MEMORY IMAGE).
;
COUT	EQU	CCP+8CH ; CCP CONSOLE OUTPUT ROUTINE
GTUSR	EQU	CCP+113H ; CCP GET USER # ROUTINE
;
	ORG	CCP+38DH
;
	CALL	PATCH	; THIS WAS A   CALL  COUT
;
; -----------------------------------------------
; NOTE THE CODE IN THE NEIGHBORHOOD OF THIS PATCH WAS
; USED TO PRINT OUT THE 'A>' PROMPT:
;
; CCP+382H:
;	LXI SP,----
;	CALL	FLUSH	; RESET BUFFERS
;	CALL	GTDRV	; GET DRIVE #
;	ADI	'A'	; ADD IN ASCII BIAS
;	CALL	COUT	; <--- MAKE PATCH HERE
;	MVI	A,'>'	; GET '>'
;	CALL	COUT	; PRINT IT OUT
;	CALL	GTCOMD	; GET CONSOLE COMMAND
;	  .
;	  .
; -------------------------------------------------
;
	ORG	CCP+15F0H	; PATCH AREA AT END OF BDOS
;
PATCH:	CALL	COUT	; OUTPUT CHAR. IN ACC TO CONSOLE
	CALL	GTUSR	; GET USER #
	ADI	90H	; USE INTEL HEX/ASCII TRICK
	DAA
	ACI	40H
	DAA
	JMP	COUT	; PRINT OUT AND RETURN
;
; ------------------------------------------------------
; NOTE: THE 'GTUSR' COMMAND IS JUST A SHORT ROUTINE:
;
;GTUSR:	MVI	E,0FFH
;	MVI	C,32
;	JMP	05
; ------------------------------------------------------
;
	END
                         - - - - - -


DEFAULT TO A: 0 CODE

I  gave you CCP+n locations this time so you can offset from  your 
DDT  image  of  the start of your CCP.   You still  have  my  own 
values, given my real memory CCP at D400 and BIOS at EA00.

                              REAL MEMORY LOCATIONS
                              IN MY SYSTEM

CCP       EQU  0D400          D400      ;start of CCP
GTUSR     EQU  CCP+113H       D513      ;Get user number routine
STUSR     EQU  CCP+115H       D515      ;Set user number
CCPMFCB   EQU  CCP+0D0H       D4D0      ;Open file at CPMFCB$
CPMTYPE$  EQU  CCP+7D6H       DBD6      ;type field in CPMFCB$
CMDSK$    EQU  CCP+7F0H       DBF0      ;loc of disk given in cmd
CMDERR    EQU  CCP+76BH       DB6B      ;loc to type error in cmd
WIN       EQU  CCP+6DEH       DADE      ;go here if we get file open

DDT IMAGE      INSTRS & REAL MEMORY LOCATIONS

11DB      JZ   CCP+6DBH       DADB      ;replaces JZ DB6B in my
                                        ;system.  Loc of cmd err
12F2      PATCH:              DDF2      ;replaces an unused area
                                        ;of NOPs - check!!
          LXI  H,CMDSK$       DBF0      ;get drive from curr cmd
          ORA  M                        ;A=0 on entry, so fetches
                                        ;drive
;in next line, if explicit drive given go try User 0
;(this will be escape even if we force A: in our cmd line
          JNZ  PATCH1         EC50      ;Wherever you put that
                                        ;new code in your CBIOS.
                                        ;I put it here -- you can
                                        ;find it by looking up
                                        ;PATCH1 in the SYM table
                                        ;generated by MAC
          INR  M                        ;force explicit reference
                                        ;to drive A
          LXI  D,CPMTYPE$     DBD6      ;need DE set up to this
                                        ;on entry to CCP
          JMP  CCP+6CDH       DACD      ;Now to reenter CCP

The  following  code must be patched into a blank  area  of  your 
CBIOS  or entered into CBIOS&.ASM prior to assembly.   Be sure to 
call it PATCH1 or something distinctive (and NOT like anything in 
CBIOS&  or you'll have problems!) so you can find it in  the  SYM 
table.

Arrive here because explicit drive set or can't find file on A:

     PATCH1:                  EC50      ;in my TOADBIOS version
          CALL GTUSR          D513      ;get user code
          ORA  A                        ;set flags
          JZ   CMDERR         DB6B      ;already user 0 so we
                                        ;fail - .COM file isn't
                                        ;anywhere!
          MOV  E,A                      ;get old value into E
                                        ;for later
          PUSH D                        ;save it
          MVI  E,0                      ;set USER=0
          CALL STUSR          D515
          CALL OCPMFCB        D4D0      ;try Open again
          POP  D                        ;get old user code back
                                        ;before we save flags
          PUSH PSW                      ;now save flags from call
          CALL STUSR          D515      ;now go set back to old
                                        ;user number
          POP  PSW                      ;get flags back from
                                        ;OPEN call
          JNZ  WIN            DADE      ;we found it!
          JMP  CMDERR         DB6B      ;nope, nowhere!
                         - - - - - - - -

That's  the code.   Hopefully you can make it work.   I'm only  a 
novice Assembler programmer, and managed just fine!  Kind of fun, 
too!  (Kind of nice at parties -- "What, you don't read hex?  And 
don't work in Assembler either?")

                       David P Kirschbaum
                          SGM, US Army
                            Toad Hall
                       7573 Jennings Lane
                     Fayetteville NC  28303