home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols100 / vol140 / xtcpm141.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  39.0 KB  |  1,512 lines

  1. ;**********************************************************
  2. ;                              *
  3. ;              EXTENDED CPM-- 12/06/81          *
  4. ;      DESIGNED TO BE PORTABLE TO ANY CP/M 2.2      *
  5. ;       SYSTEM THAT IS IN ORIGINAL 8080 CODE FOR CCP.      *
  6. ;    (will work with others also, but you will      *
  7. ;    have to find all of the CCP equates.)          *
  8. ;             RLP                  *
  9. ;                              *
  10. ;        will assemble w/ASM.COM              *
  11. ;                              *
  12. ;    Donated 11/22/81 for the benefit of hobby      *
  13. ;    computing, but may not be sold or copied      *
  14. ;    for a profit.                      *
  15. ;                              *
  16. MSIZE    EQU    61        ;MEMORY SIZE THIS VERS      *
  17.                 ;CHANGE TO YOUR SIZE HERE *
  18. OVERLAY    EQU    OVERLAY        ;COMPUTED SYSGEN OVERLAY  *
  19. ;                              *
  20. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  21. ;                        >>
  22. ;    *** I M P O R T A N T ***        >>
  23. ;                        >>
  24. ; You must obtain the address for CBOOT from    >>
  25. ; the argument of the first jump at the        >>
  26. ; beginning of YOUR BIOS and place it in the     >>
  27. ; conditional equate assembled for your system.    >>
  28. ; Make it relative to the beginning of the    >>
  29. ; BIOS as shown.                >>
  30. ;                        >>
  31. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  32. ;
  33. ;**********************************************************
  34. ;
  35. ;           XTCPM.ASM  VERS 1.41
  36. ;
  37. ;    THIS PROGRAM PROVIDES FOR AN EXPANSION OF YOUR
  38. ;    SYSTEM BY EITHER ONE OR 2 KBYTES WITHOUT THE NEED
  39. ;    FOR A SPECIAL SYSGEN.  JUST ADD THIS CODE TO YOUR
  40. ;    SYSTEM BY OVERLAYING YOUR CPMxx.COM FILE USING DDT.
  41. ;    AFTER YOU HAVE OVERLAYED THE CODE INTO CPMxx.COM
  42. ;    WITH DDT, DO TWO SAVES. ONE, SAVE YOUR CPMxx.COM
  43. ;    FILE AS USUAL. TWO, DO A SAVE OF THE CODE WHICH
  44. ;    WILL BE IN THE IMAGE AT 100H. THIS WILL BE A TRAN-
  45. ;    SIENT THAT YOU MUST KEEP ON YOUR 'A' DRIVE AND CON-
  46. ;    TAINS THE ADDITIONAL CODE - SO SAVE IT WITH ENOUGH
  47. ;    SECTORS TO WRITE 1 OR 2 KB DEPENDING ON THE SIZE.
  48. ;    NAME THE TRANSIENT 'XTCPM.COM'. BE SURE THAT YOUR
  49. ;    BIOS IS SET TO DO A TURNKEY START BY HAVING IT
  50. ;    JMP TO THE FIRST ENTRY POINT (CCP+0H) AFTER BIOS
  51. ;    INITIALIZATION.  SOME PROPRIETARY BIOS'S DO THIS
  52. ;    THROUGH A MODE BYTE. FINALLY USE YOUR NORMAL 
  53. ;    'SYSGEN' TO WRITE THE CPMxx.COM TO YOUR SYSTEM
  54. ;    TRACKS. IT IS PREFERABLE THAT YOUR BIOS DO A JUMP
  55. ;    TO THE SECOND ENTRY POINT IN THE CCP (CCP+3H) ON
  56. ;    A WARM BOOT, HOWEVER THIS CODE WILL PROPERLY HANDLE
  57. ;    THE SITUATION EVEN IF YOUR BIOS IS NOT IMPLEMENTED
  58. ;    THAT WAY.
  59. ;
  60. ;    THE EXPANDED CODE SHOWN HERE PROVIDES FOR AN
  61. ;    EXTENDED CCP THAT CAN CONTAIN ADDITIONAL USER
  62. ;    DEFINED CCP COMMANDS AS WELL AS TO MAKE TRANSIENTS
  63. ;    APPEAR AS CCP-LIKE IN THAT THEY CAN BE INVOKED
  64. ;    REGARDLESS OF LOGGED DRIVE/USER AREA. THUS IT IS
  65. ;    COMPLETELY UN-NECESSARY TO PLACE THESE TRANSIENTS
  66. ;    IN MULTIPLE USER AREAS.  IT ALSO PROVIDES FOR
  67. ;    TWO LEVELS OF PASSWORD PROTECTION.  ADD A TURNKEY
  68. ;    START OF WARD'S 'BYE' W/O PASSWORD TO MAKE A VERS-
  69. ;    ATILE ON-LINE SYSTEM. JUST PUT 'BYE' AT 'FILNAM'
  70. ;    PRECEEDED BY A '3' AND ADD A TEMINATING NULL.
  71. ;    THEN PLACE 'BYE.COM' IN USER 13 ON YOUR 'A' DRIVE
  72. ;    AND SET TNKY2 EQUAL TO TRUE.
  73. ;
  74. ;    AS DISTRIBUTED HERE, ALL OF THE FEATURES ARE
  75. ;    AVAILABLE WITH LESS THAN ONE KILOBYTE OF SPACE ABOVE
  76. ;    CP/M. THE CODE REQUIRES A Z80 CPU BUT MAY BE
  77. ;    CONVERTED TO 8080 OR 8085. STUFF THE HOLES W/CARE.
  78. ;
  79. ;    TESTED OK WITH LIFEBOAT CP/M FOR NORTH STAR AND
  80. ;    NORTH STAR'S CP/M PRODUCT. IF YOU ARE USING THE
  81. ;    NORTH STAR CP/M WITH HARD DISK OR NON-STANDARD
  82. ;    PROM, BE CAREFUL NOT TO OVERWRITE THE LAST 80H
  83. ;    OF THE USER AREA CODE STARTING AT 3380H IN IMAGE.
  84. ;    ALSO BE SURE TO SAVE 54 FOR A CPMXX.COM FILE SINCE
  85. ;    THE IMAGE STARTS HIGHER THAN THE USUAL STANDARD.
  86. ;
  87. ;    ALSO TESTED WITH A STANDARD CP/M USING 8 IN DISKS
  88. ;    AND A MICROMATION DOUBLER.
  89. ;
  90. ;    YOU CAN APPEND YOUR OWN CUSTOMIZED VERSION OF 'BYE'
  91. ;    WITHOUT A MOVER INTO THE USER2 AREA IF YOU ARE CARE-
  92. ;    FUL TO AVOID LABEL CONFLICTS. IF YOU DO SO, THEN ADD
  93. ;    A COMMAND STRING AT THE 0 PASSWORD LEVEL AND POINT
  94. ;    TO THE ADDRESS OF YOUR 'BYE' ENTRY POINT. ALSO,
  95. ;    REDIRECT THE STACK IN 'BYE' TO BE THE SAME AS THE
  96. ;    STACK IN THIS CODE AND ELIMINATE THE SEPARATE STACK.
  97. ;    ALSO SEE THE NOTE AT LABEL CCPINIT.
  98. ;
  99. ;    NOTE....THIS PROGRAM DOES NOT CLOBBER ANYTHING IN THE
  100. ;    TPA EXCEPT WHEN LOADING 'BYE' AS A TRANSIENT WHICH
  101. ;    CAN BE AVOIDED AS ABOVE.
  102. ;
  103. ;    YOU CAN ELIMINATE THE USER1 CODE AREA IN ITS ENTIRETY
  104. ;    IF YOU ARE ALREADY HAPPY WITH YOUR I/O DRIVERS. THERE
  105. ;    IS A CONDITIONAL ASSEMBLY EQUATE TO ACCOMPLISH THIS.
  106. ;
  107. ;    12/6/81 Fixed warm boot branch address in CCPINIT.
  108. ;    Added second DIR string and address so that CCP code
  109. ;    for DIR will run at 0 password level and a DIR.COM
  110. ;    transient will run above that level if it is on the
  111. ;    system disk.  See NOTE just above label DIR1.
  112. ;    Changed location of PASBYTE vector to the buffer at
  113. ;    the end of the BDOS (spare location) so that if the
  114. ;    CCP is crashed by DDT or anything else, BYE will still
  115. ;    be able to find the PASBYTE to reset it. Former loc-
  116. ;    ation of this vector was at a spare location in the CCP.
  117. ;    Clarified USER2 equate for IF STDCPM.   RLP
  118. ;
  119. ;    12/4/81 Major revision, see the DOC file. Also
  120. ;    cleaned up the code.            RLP
  121. ;
  122. ;    11/30/81 Added code to make USERs 13, 14, & 15 on 'A'
  123. ;    universal depending on password level achieved at
  124. ;    log-on time. Removed nested IF's. Cleaned up code so
  125. ;    that a warm boot will properly initialize the CCP.
  126. ;    Also removed bug that would have prevented a file
  127. ;    from being executed by a transient that loads the
  128. ;    command line, sets the buffer pointer, and jumps to
  129. ;    the beginning of the CCP.        RLP
  130. ;
  131. ;    11/25/81 Added conditional assembly equate to
  132. ;    allow removal of i/o drivers and added routines
  133. ;    to link the code in USER2 to your own customized
  134. ;    BIOS.                    RLP
  135. ;    
  136. ***********************************************************
  137. ;
  138. ;        SYSTEM EQUATES
  139. ;    IMPORTANT   You must check these system equates to
  140. ;be sure that they are valid for your system and change them
  141. ;if they are not.  You may choose to integrate the USER1 code
  142. ;with your open BIOS if you have one and thus eliminate the
  143. ;USER1 equate.  USER2 will usually be just above CP/M including
  144. ;any buffer and will usually be MSIZE*1024+32. 32 is to allow
  145. ;room for stack. Change the value of ADJUST until the values
  146. ;for CCP, BDOS and BIOS are correct for your system. The value
  147. ;0D00H for Lifeboat on North Star and for North Star CP/M is
  148. ;correct, and the value 600H is correct for standard CP/M.
  149. ;
  150. FALSE    EQU    0
  151. TRUE    EQU    NOT FALSE    ;SEE OPTIONS BLOCK
  152.                 ;TO SELECT ALL OPTIONS
  153. ;
  154. IOBYTE    EQU    0003H        ;I/O BYTE ADDRESS
  155. DRIVE    EQU    0004H        ;LOC OF CURR DRV BYTE
  156. STAKSIZ    EQU    32        ;15 LEVEL STACK + BOOT FLAG
  157.                 ;AND PASBYTE
  158. ;
  159. ;        - - - - - - - - - - - - -
  160. ;
  161. ;select only one of these true except that if Lifeboat BIOS
  162. ;then make decision on S22X
  163. ;
  164. STDCPM    EQU    FALSE    ;true if standard CP/M on IBM
  165.             ;compatible floppy disk.
  166. NSTRCPM    EQU    FALSE    ;true if North Star CP/M
  167. LIFBOAT    EQU    TRUE    ;true if Lifeboat CP/M for North
  168.             ;Star DQ.
  169. S22X    EQU    TRUE    ;TRUE FOR 2.21A & 2.22. THIS IS A
  170.             ;SPECIAL EQUATE FOR LIFEBOAT BIOS'S
  171.             ;AND ANY OTHERS THAT HAVE ADDED AN
  172.             ;ADDITIONAL JMP FOR WINIT IN THE 
  173.             ;USER1 JUMP TABLE. SET TO FALSE
  174.             ;FOR ALL OTHERS. BE SURE THAT YOUR
  175.             ;BIOS JMP TABLE IS PROPERLY LINKED
  176.             ;TO USER1 OR JUST FORGET IT IF YOU
  177.             ;INTEGRATE THIS CODE INTO YOUR 
  178.             ;OPEN BIOS.
  179. M2BIOS    EQU    FALSE    ;true if micromation bios
  180.             ;
  181. ;        - - - - - - - - - - - -
  182.             ;
  183. ;
  184. SKIP    EQU    0    ;EQUATE THIS TO SIZE OF ROM TO SKIP
  185.     ;NOTE:  This will add an additional offset to the
  186.     ;    USER2 equate if you wish to place the USER2
  187.     ;    code above any PROM or ROM areas. Thus, it
  188.     ;    will be unecessary to reserve space between
  189.     ;    the top of CP/M and ROM
  190.     ;
  191.     IF    LIFBOAT
  192.     ;
  193. ADJUST    EQU    0D00H
  194. BIOS    EQU    (MSIZE*1024)-ADJUST    ;BASE OF BIOS
  195. USER1    EQU    BIOS+0700H        ;BASE 1RST USER AREA
  196. USER2    EQU    MSIZE*1024+STAKSIZ+SKIP    ;BASE 2ND USER AREA
  197. RAMEND    EQU    0FC00H            ;CHANGE TO YOUR VALUE
  198. CBOOT    EQU    BIOS+80H        ;COLDBOOT VECTOR FOR 2.22
  199. CCPIMAGE EQU    0A00H            ;CHANGE THIS TO EQUAL THE
  200.                     ;ADDRESS OF YOUR CCP IN
  201.                     ;THE DDT/SYSGEN IMAGE.
  202. OVERLAY    EQU    2000H-BIOS        ;COMPUTED OVERLAY
  203.     ;
  204.     ENDIF
  205.     ;
  206.     IF    NSTRCPM
  207.     ;
  208. ADJUST    EQU    0D00H
  209. BIOS    EQU    (MSIZE*1024)-ADJUST    ;BASE OF BIOS
  210. USER1    EQU    BIOS+0700H        ;BASE 1RST USER AREA
  211. USER2    EQU    MSIZE*1024+STAKSIZ+SKIP    ;BASE 2ND USER AREA
  212. RAMEND    EQU    0FC00H            ;CHANGE TO YOUR VALUE
  213. CBOOT    EQU    BIOS+0xxH
  214. CCPIMAGE EQU    1500H
  215. OVERLAY    EQU    2B00H-BIOS        ;COMPUTED OVERLAY
  216.     ;
  217.     ENDIF
  218.     ;
  219.     IF    STDCPM
  220.     ;
  221. ADJUST    EQU    600H
  222. BIOS    EQU    (MSIZE*1024)-ADJUST    ;BASE OF BIOS
  223. ;USER1    EQU    BIOS + (YOUR OFFSET TO USER1 PATCH AREA) 
  224. USER2    EQU    MSIZE*1024+STAKSIZ+SKIP    ;*NOTE* IF YOUR BIOS CODE
  225.                     ;INCLUDING ITS BUFFER SPACE
  226.                     ;HAS SPACE LEFT BELOW
  227.                     ;MSIZE*1024, YOU CAN SUBTRACT
  228.                     ;THE AMOUNT OF SPACE YOU HAVE
  229.                     ;LEFT FROM THIS USER2 EQUATE.
  230.                     ;SEE THE CODE AT 'IF M2BIOS'
  231.                     ;BELOW FOR AN EXAMPLE OF THIS. 
  232. ;RAMEND    EQU    (PUT YOUR VALUE HERE)
  233. CBOOT    EQU    BIOS+0xxH
  234. CCPIMAGE EQU    980H            ;ADDR OF CCP IN DDT IMAGE
  235. OVERLAY    EQU    1F80H-BIOS        ;COMPUTED OVERLAY
  236.     ;
  237.     ENDIF
  238.     ;
  239.     IF    M2BIOS
  240.     ;This is for a particular user's CBIOS that uses a
  241.     ;Micromation Doubler and has a user code area begin-
  242.     ;ning at BIOS+23DH.  Make your own conditional ass-
  243.     ;embly equates for your values.
  244. ADJUST    EQU    600H
  245. BIOS    EQU    (MSIZE*1024)-ADJUST
  246. USER1    EQU    BIOS+23DH        ;BASE 1RST USER AREA
  247. USER2    EQU    MSIZE*1024+STAKSIZ-256+SKIP ;BASE 2ND USER AREA
  248. RAMEND    EQU    0F400H            ;CHANGE TO YOUR VALUE
  249.                     ;USED ONLY IN PARITY
  250.                     ;SETTING CODE IN 'INITIAL'
  251. CBOOT    EQU    BIOS+0ABH
  252. CCPIMAGE EQU    980H            ;ADDR OF CCP IN DDT IMAGE
  253. OVERLAY    EQU    1F80H-BIOS        ;COMPUTED OVERLAY
  254.     ;
  255.     ENDIF
  256.     ;
  257. BOOTFLG    EQU    USER2-1            ;LOC OF BOOT FLAG
  258.                     ;IF NOT 0, then a
  259.                     ;cold boot is in progress.
  260. PASBYTE    EQU    USER2-2            ;LOC OF PASBYTE
  261. STACK    EQU    USER2-2            ;TOP OF STACK
  262. CCP    EQU    BIOS-1600H        ;BASE OF CCP
  263. BDOS    EQU    CCP+800H        ;BASE OF BDOS
  264. ;
  265. ;
  266. IOBYT    EQU    00000001B    ;VALUE OF IOBYTE
  267.         ; ; ; ;---------;CONSOLE IS TTY:    00
  268.         ; ; ;        ;        CRT:    01
  269.         ; ; ;        ;        BAT:    10
  270.         ; ; ;        ;        UC1:    11
  271.         ; ; ;-----------;READER IS  TTY:    00
  272.          ; ;        ;        RDR:    01 
  273.         ; ;        ;        UR1:    10 
  274.         ; ;        ;        UR2:    11 
  275.         ; ;-------------;PUNCH IS   TTY:    00 
  276.         ;        ;        PUN:    01 
  277.         ;        ;        UP1:    10 
  278.         ;        ;        UP2:    11  
  279.         ;---------------;LIST IS    TTY:    00 
  280.                 ;        CRT:    01 
  281.                 ;        LPT:    10 
  282.                 ;-----------UL1:    11 
  283. ;
  284. DRIVERS    EQU    TRUE    ;WANT THE I/O DRIVERS? (CONTAINED
  285.             ;IN USER1 CODE AREA)
  286. BGTST    EQU    TRUE    ;WANT BACKGROUND MEMORY TEST?
  287. ;                               
  288. PARITY    EQU    TRUE    ;WANT TO SET PARITY MEMORY       
  289. ;                               
  290. TNKY2    EQU    TRUE    ;WANT 2ND TURNKEY START
  291. ;
  292. MAXUSER    EQU    2    ;FOR EXAMPLE..MAX PUBLIC USER AREA 
  293. ;                               
  294. SGNON    EQU    FALSE    ;NEED SIGN ON MESSAGE?
  295. ;
  296. PASBYT    EQU    00100100B    ;PASSWORD BYTE       
  297.           ;  ;----------;PASSWORD 2 REQUIRED       
  298.           ;-------------;PASSWORD 1 REQUIRED       
  299. ;                               
  300. ;END OF OPTIONS BLOCK                       
  301. ;***********************************************************
  302. ;***********************************************************
  303. ;
  304. ;        PORT ASSIGNMENTS
  305. ;
  306. ;Be sure to check port assignments for your system.
  307. ;
  308. PARAL    EQU    0    ;PARALLEL I/O PORT
  309. SER1D    EQU    2    ;LEFT SERIAL PORT DATA
  310. SER1ST    EQU    3    ;LEFT SERIAL PORT STATUS
  311. SER2D    EQU    4    ;RIGHT SERIAL PORT DATA
  312. SER2ST    EQU    5    ;RIGHT SERIAL PORT STATUS
  313. MOTHER    EQU    6    ;MOTHERBOARD COMMAND/STATUS
  314. MEMORY    EQU    0C0H    ;PARITY MEMORY PORT unique to
  315.             ;North Star
  316. ;
  317. ;**********************************************************
  318. ;START OF USER1 CODE
  319. ;
  320. ;        JUMP TABLE LINKS BIOS TO XTCPM
  321. ;        The rest of the jumps are at base
  322. ;        of the BIOS.
  323. ;
  324. ;NOTICE.  The IOBYTE processor in this code saves and re-
  325. ;stores BC, DE, and HL registers.
  326. ;
  327. ;**********************************************************
  328. ;
  329.     IF    DRIVERS
  330.     ;
  331.     ORG    USER1
  332.     JMP    INITIAL        ;USER INIT ROUTINE
  333.     ;
  334.     ENDIF
  335.     ;
  336.     IF    S22X
  337.     ;
  338.     DS    3        ;SPACE FOR JMP TO WINIT
  339.                 ;USED BY 221A & HIGHER ONLY
  340.     ENDIF
  341.     ;
  342.     IF    DRIVERS AND NOT (STDCPM OR M2BIOS)
  343.     ;
  344.     JMP    CONST        ;CONSOLE STATUS ROUTINE
  345.     JMP    CONIN        ;CONSOLE INPUT
  346.     JMP    CONOUT        ;CONSOLE OUTPUT
  347.     ;
  348.     ENDIF
  349.     ;
  350.     IF    DRIVERS
  351. ;
  352. ;***********************************************************
  353. ;
  354. ;        IOBYTE PROCESSOR
  355. ;
  356. ;***********************************************************
  357. ;
  358. CONSOL:
  359.     MVI    A,CONCNT    ;SHIFT COUNTER
  360. ;
  361. DISPAT:    ;I/O DISPATCHER - TO MAP LOGICAL TO PHYSICAL
  362.     XTHL             ;GET RETURN ADDR & SAVE HL
  363.     PUSH    B        ;SAVE BC
  364.     PUSH    D        ;SAVE DE
  365.      MOV    B,A        ;PUT COUNTER VALUE IN B
  366.     LDA    IOBYTE        ;GET THE IO BYTE
  367.     ;
  368. DISPAT1:
  369.     DCR    B        ;SHIFT IOBYTE UNTIL
  370. DB    JRZ,    DISPAT2-$-1    ;COUNT IN B=0
  371.     RRC
  372.     RRC
  373. DB    JR,    DISPAT1-$-1 AND 0FFH ;SHIFT NEXT TWO BYTES
  374.     ;
  375. DISPAT2:
  376.     ANI    03H        ;MASK OUT BITS 0,1
  377.     RLC            ;DOUBLE
  378.     MVI    D,0        ;CLEAR D
  379.     MOV    E,A        ;
  380.     DAD    D        ;H,L POINTS TO ENTRY
  381.     MOV    A,M        ;GET LOW BYTE
  382.     INX    H        ;POINT TO HIGH BYTE
  383.     MOV    H,M        ;GET HIGH BYTE
  384.     MOV    L,A        ;H,L POINTS TO SUBR.
  385.     POP    D        ;RESTORE DE
  386.     POP    B        ;RESTORE BC
  387.     XTHL            ;RSTR HL & PUT RET ON STACK
  388.     RET
  389. ;
  390. CONST:    ;CONSOLE STATUS, RETURN 0FFH IF READY ,0 IF NOT
  391.     CALL    CONSOL        ;COMMON ROUTINE
  392.     DW    TTYST        ;TTY STATUS
  393.     DW    CRTST        ;CRT STATUS
  394.     DW    RDRST        ;READER STATUS 
  395.     DW    UC1ST        ;USER CONSOLE STATUS
  396. ;
  397. CONIN:
  398.     ENDIF
  399.     ;
  400.     IF    BGTST
  401.     ;
  402.     CALL    TEST        ;BACKGROUND MEMORY TEST
  403.     ;
  404.     ENDIF
  405.     ;
  406.     IF    DRIVERS
  407.     ;
  408.     CALL    CONST
  409.     ORA    A        ;SET CC
  410. DB    JRZ,    CONIN-$-1 AND 0FFH
  411.     ;CONSOLE INPUT ROUTINE
  412.     CALL    CONSOL        ;COMMON CONSOLE ROUTINE
  413.     DW    TTYIN        ;TTY INPUT
  414.     DW    CRTIN        ;CRT INPUT
  415.     DW    READER        ;READER INPUT 
  416.     DW    UC1IN        ;USER CONSOLE INPUT
  417.     ;
  418. CONOUT: ;CONSOLE OUTPUT ROUTINE
  419.     CALL    CONSOL        ;COMMON ROUTINE
  420.     DW    TTYOUT        ;TTY OUTPUT
  421.     DW    CRTOUT        ;CRT OUTPUT
  422.     DW    LIST        ;LIST OUTPUT 
  423.     DW    UC1OUT        ;USER CONSOLE OUTPUT
  424. ;
  425. READER0:
  426.     ENDIF
  427.     ;
  428.     IF    BGTST
  429.     ;
  430.     CALL TEST        ;BACKGROUND MEM TEST
  431.     ;
  432.     ENDIF
  433.     ;
  434.     IF    DRIVERS
  435.     ;
  436. READER:    ;READER INPUT ROUTINE
  437.     MVI    A,RDRCNT    ;SHIFT COUNTER
  438.     CALL    DISPAT        ;GO TO LOOKUP ROUTINE
  439.     DW    TTYRDR        ;READER IS TTY KBD.
  440.     DW    HSRIN        ;IS HIGH SPEED READER
  441.     DW    UR1IN        ;USER READER ONE
  442.     DW    UR2IN        ;USER READER TWO
  443. ;
  444. PUNCH:    ;PUNCH OUTPUT ROUTINE
  445.     MVI    A,PCHCNT    ;SHIFT COUNTER
  446.     CALL    DISPAT        ;LOOK UP ROUTINE
  447.     DW    TTYOUT        ;PUNCH IS TTY
  448.     DW    PUNOUT        ;HIGH SPEED PUNCH
  449.     DW    UP1OUT        ;USER PUNCH ONE
  450.     DW    UP2OUT        ;USER PUNCH TWO
  451. ;
  452. LIST:    ;LIST OUTPUT ROUTINE
  453.     MVI    A,LSTCNT    ;SHIFT COUNTER
  454.     CALL    DISPAT        ;GO TO DISPATCHER
  455.     DW    TTYOUT        ;LIST DEVICE IS TTY
  456.     DW    CRTOUT        ;LIST DEVICE IS CRT
  457.     DW    LPTOUT        ;LINE PRINTER
  458.     DW    UL1OUT        ;USER LIST DEVICE
  459. ;
  460. LISTST:    ;LIST DEVICE STATUS ROUTINE
  461.     MVI    A,LSTCNT    ;SHIFT COUNTER
  462.     CALL    DISPAT        ;LOOK UP ROUTINE
  463.     DW    TTYST        ;RETURN TTY STATUS
  464.     DW    CRTST        ;RETURN CRT STATUS
  465.     DW    LPTST        ;LINE PRINTER STATUS
  466.     DW    UL1ST        ;USER LIST DEVICE STATUS
  467. ;
  468. ;**********************************************************
  469. ;
  470. ;           INPUT/OUTPUT DRIVERS
  471. ;
  472. ;**********************************************************
  473. ;
  474. ;        CRT DRIVERS 
  475. ;
  476. CRTST:    ;CRT STATUS
  477.     IN     SER1ST    ;GET SERIAL ONE STATUS
  478. DB    JR,    TSTSTAT-$-1
  479. ;
  480. CRTIN:    IN    SER1D    ;GET DATA
  481. STRPRET: ANI    7FH    ;STRIP PARITY
  482.     RET
  483. ;
  484. CRTOUT:    ;CRT OUTPUT
  485.     IN    SER1ST    ;GET STATUS FOR 1RST SERIAL
  486.     ANI    OUTRDY    ;READY TO RECEIVE DATA?
  487. DB    JRZ,    CRTOUT-$-1 AND 0FFH    ;NO, LOOP TIL READY
  488.     MOV    A,C    ;GET DATA
  489.           OUT    SER1D    ;SEND TO DATA PORT
  490.     RET
  491. ;
  492. ;        TTY DRIVERS 
  493. ;
  494. TTYST:        ;TTY INPUT STATUS
  495.     IN    SER2ST    ;GET SERIAL TWO STATUS
  496. DB    JR,    TSTSTAT-$-1
  497. ;
  498. TTYRDR:    ;TTY KEYBOARD AS READER
  499.     IN    SER2ST
  500.     ANI    INRDY
  501.     JZ    READER0
  502. TTYIN:    IN    SER2D    ;GET DATA
  503. DB    JR,    STRPRET-$-1 AND 0FFH    
  504. ;
  505. TTYOUT:    ;TTY OUTPUT
  506.     IN    SER2ST    ;GET STATUS FOR SERIAL PORT 1
  507.     ANI    OUTRDY    ;READY FOR DATA?
  508. DB    JRZ,    TTYOUT-$-1 AND 0FFH    ;NO, WAIT TIL READY
  509.     MOV    A,C    ;GET DATA
  510.     OUT    SER2D    ;SEND TO SERIAL 2 DATA PORT
  511.     RET
  512. ;
  513. ;        READER DRIVER (PARALLEL INPUT PORT)
  514. ;
  515. RDRST:                ;READER STATUS
  516.     IN    MOTHER        ;GET STATUS
  517. TSTSTAT:
  518.     ANI    INRDY        ;MASK FOR READY
  519.     RRC            ;SHIFT TO LSB
  520. DCRCMA:
  521.     DCR    A        ;IF ZERO, MAKE FF
  522.     CMA            ;COMPLEMENT THE ACC.
  523.     RET
  524.  
  525. HSRIN:                ;HIGH-SPEED READER INPUT 
  526.     IN    MOTHER        ;GET STATUS
  527.     ANI    INRDY        ;READY WITH DATA?
  528.     JZ    READER0        ;LOOP UNTIL PI FLAG
  529.     IN    PARAL        ;GET PARALLEL INPUT DATA
  530.     ANI    07FH        ;STRIP PARITY
  531.     MOV    B,A        ;SAVE
  532.     MVI    A,30H        ;LOAD COMMAND BYTE TO A
  533.     OUT    MOTHER        ;RESET PI FLAG
  534.     MOV    A,B        ;RECOVER DATA
  535.     RET
  536. ;
  537. ;        PUNCH DRIVER (PARALLEL OUTPUT PORT)
  538. ;
  539. PUNOUT:                ;HIGH-SPEED PUNCH OUTPUT 
  540. LPTOUT:                ;LINE PRINTER OUT
  541.     ;PUNOUT AND LPTOUT ARE SAME ROUTINE
  542.     IN    MOTHER        ;GET STATUS
  543.     ANI    OUTRDY        ;READY FOR DATA
  544. DB    JRZ,     LPTOUT-$-1 AND 0FFH    ;NO, WAIT TIL READY
  545.     MOV    A,C        ;GET DATA
  546.     OUT    PARAL        ;SEND TO PARALLEL PORT
  547.     MVI    A,20H        ;COMMAND BYTE
  548.     OUT    MOTHER        ;RESET PO FLAG
  549.     MOV    A,C        ;GET DATA AGAIN
  550.     RET
  551. ;
  552. LPTST:                ;LINE PRINTER STATUS 
  553.     IN    MOTHER        ;GET STATUS
  554.     ANI    OUTRDY        ;READY TO RECEIVE CHAR
  555. DB    JR,    DCRCMA-$-1 AND 0FFH
  556. ;
  557. ;**********************************************************
  558. ;
  559. ;        USER DEFINED I/O DEVICE DRIVERS
  560. ;
  561. ;**********************************************************
  562. ;
  563. UC1ST:    ;USER CONSOLE 1 STATUS
  564. UL1ST:    ;USER LIST DEVICE STATUS
  565.     MVI    A,0FFH        ;ALWAYS READY
  566.     RET
  567. ;
  568. UC1OUT:    ;USER CONSOLE 1 IN (NULL)    
  569. UP1OUT:    ;USER PUNCH ONE OUT (NULL)
  570. UP2OUT:    ;USER PUNCH TWO OUTPUT "
  571. UL1OUT:    ;USER LIST OUTPUT (NULL)
  572.     MOV    A,C        ;CHARACTER INTO A
  573.     RET
  574. ;
  575. UC1IN:    ;USER CONSOLE 1 IN (NULL)
  576. UR1IN:    ;USER READER ONE INPUT
  577. UR2IN:    ;USER READER TWO INPUT
  578.     MVI    A,EOF        ;END OF FILE FOR NOW
  579.     RET
  580. ;
  581. ;**********************************************************
  582. ;THIS IS THE INIT ROUTINE....You should change this for
  583. ;your hardware.  Usually you should make it the same as
  584. ;the init routine that came with the version of CP/M that
  585. ;is customized for your system. The init routine below is
  586. ;for a North Star Horizon.
  587. ;
  588. INITIAL:
  589.     MVI    A,IOBYT        ;THE VALUE
  590.     STA    IOBYTE        ;THE LOCATION
  591. ;
  592.     XRA    A        ;SET TO CLEAR MOTHERBOARD
  593.     OUT    MOTHER
  594.     OUT    MOTHER        ;EXTRAS FOR TIMING, 
  595.     OUT    MOTHER
  596.     OUT    MOTHER        ;DON'T ASK
  597.     ;
  598. ;
  599.     MVI    A,40H        ;DISABLE PARITY LOGIC
  600.     OUT    MEMORY        ;BEFORE READING RAM
  601.     ;
  602.     ENDIF
  603.     ;
  604.     IF    PARITY    
  605.     ;
  606.     LXI    H,RAMEND    ;PARITY SETTING CODE
  607.     MOV    D,H
  608.     MOV    E,L
  609.     LXI    B,RAMEND+1    ;NUMBER OF BYTES TO CLEAR
  610. DW    LDDR            ;SET PARITY ON ALL RAM
  611.     MVI    A,41H        ;PARITY ENABLE CODE
  612.     OUT    MEMORY        ;REARM PARITY LOGIC
  613.     ;
  614.     ENDIF
  615.     ;
  616.     IF    DRIVERS
  617.     ;
  618.     MVI    A,0CEH        ;INITIALIZE UARTS
  619.                 ;2 STOPS, 16X CLOCK
  620.                 ;8 BITS, NO PARITY
  621.     OUT    SER1ST
  622.     OUT    SER2ST
  623. ;
  624.     MVI    A,37H        ;COMMAND: RTS, ER,
  625.                 ;RXF, DTR, TXEN
  626.     OUT    SER1ST
  627.     OUT    SER2ST
  628. ;
  629.     IN    PARAL
  630.     IN    SER1D
  631.     IN    SER2D
  632. ;
  633. ;
  634.     MVI    A,30H        ;RESET PI FLAG
  635.     OUT    MOTHER
  636.     ;
  637.     RET
  638.     ;
  639.     ENDIF
  640. ;
  641. USR1END: EQU    $        ;END OF USER1 CODE FOR NOW
  642. USR1SIZE EQU    USR1END-USER1    ;MUST NOT EXCEED SPACE 
  643.                 ;ALLOCATED IN USER1
  644. ;
  645. ;**********************************************************
  646. ; USER2 code starts here. Will be loaded to just above
  647. ; CP/M by the CCP.
  648. ;The following ORG statement will provide for loading of
  649. ;USER2 code just above CP/M by the specially initialized
  650. ;CCP(which this program does); AND, will provide for the
  651. ;memory image to appear at 100H when the OVERLAY offset
  652. ;is used with DDT to patch in your code to a CPMxx.COM
  653. ;file. Save your USER2 code as a transient called XTCPM.COM
  654. ;and keep it on your A drive since it will be needed for all
  655. ;cold boots.  Also save your CPMxx.COM file after patching
  656. ;with DDT and use your normal SYSGEN program to write it
  657. ;to the system tracks. Save both files to appropriate size.
  658. ;
  659. ;Any code placed in this area should have the EQU  $+OFFSET
  660. ;at each label and Z80 jump relatives should use the FR and
  661. ;BR post-fixes as shown.
  662. ;
  663. ;THIS ORG STATEMENT SHOULD CAUSE THE FOLLOWING CODE TO APPEAR
  664. ;AT 100H IN THE DDT IMAGE AFTER OFFSETTING WITH THE OVERLAY
  665. ;BIAS THAT YOU USE IN PATCHING YOUR BIOS INTO CPMxx.COM.
  666. ;
  667.     ORG    CCP-(CCPIMAGE-100H)
  668. SOURCE:    EQU    $        ;SOURCE OF USER2 CODE
  669. OFFSET:    EQU    USER2-SOURCE    ;OFFSET FOR USER2 CODE
  670. FR:    EQU    -1-OFFSET    ;FORWARD RELATIVE
  671. BR:    EQU    FR+0FFH+1    ;BACKWARD RELATIVE
  672. ;
  673.     
  674. ;**********************************************************
  675. ;This routine is the first to be called when going to the
  676. ;TPA on a coldboot turnkey start.  It simply changes the
  677. ;CCP parameters to restore the dma and address for the TPA
  678. ;back to 100H and resets the address tested for CCP overwrite.
  679. ;The turnkey start in the mean time has loaded the rest of
  680. ;the code in the USER2 area to a location just above CP/M
  681. ;and all properly linked to the code in the USER1 area.
  682. ;
  683.     RET            ;TO RET IF EXECUTED FROM
  684.                 ;THE COMMAND LINE.
  685. ;This is the entry point when called by the CCP.
  686. XTCPM:    EQU    $+OFFSET    ;ROUTINE TO RESTORE CCP DMA
  687.                 ;AND TPA ADDRESSES TO 100H
  688.     LXI    H,TPA
  689.     SHLD    CCPDMA
  690.     SHLD    TPASUB
  691.     LXI    H,CCP
  692.     SHLD    TSTOVWR
  693.     ;
  694.     MVI    A,PASBYT ;GET THE PASSWORD BYTE
  695.              ;If you use Ward's 'BYE' ,then
  696.              ;you should restore the PASBYT
  697.              ;to its initial value in the
  698.              ;HANGUP routine of 'BYE'.
  699.              ;Use the following code:
  700.              ;LHLD    0001H    ;get bios vector
  701.              ;LXI    D,-28H     ;set to subtract (SEARA+2)
  702.              ;DAD    D    ;hl pnts to PASBYTE address
  703.              ;MOV    A,M    ;load hl with address
  704.              ;INX    H
  705.              ;MOV    H,M
  706.              ;MOV    L,A
  707.              ;MVI    M,24H    ;reset PASBYTE
  708.              ;
  709.     STA    PASBYTE     ;STORE IT
  710.     ;
  711.     CALL    RSTPRMS
  712.     ;
  713.     IF    SGNON
  714.     ;
  715.     MVI    C,WRBUF        ;GIVE SYSTEM SIGNON MESSAGE
  716.     LXI    D,SIGNON
  717.     CALL    BDOSFNC
  718.     ;
  719.     ENDIF
  720.     ;
  721.     IF    NOT TNKY2
  722.     ;
  723.     RET
  724.     ;
  725.     ENDIF
  726.     ;
  727.     IF    TNKY2
  728.     ;
  729.     LXI    H,COMBUF+1
  730.     SHLD    BUFPTR
  731.     DCX    H
  732.     XCHG
  733.     LXI    H,FILNAM
  734.     LXI    B,5
  735. DW    LDIR
  736.     MVI    C,0
  737.     JMP    CCP
  738.     ;
  739. FILNAM:    EQU    $+OFFSET
  740.     DB    3,'BYE',0
  741.     ;
  742.     ENDIF
  743.     ;
  744.     IF    SGNON
  745.     ;
  746. SIGNON: EQU    $+OFFSET
  747.     DB    CR,LF
  748.     DB    MSIZE/10+30H
  749.     DB    MSIZE MOD 10 + 30H
  750.     DB    'K CP/M 2.2 - XTCPM$'
  751.     ;
  752.     ENDIF
  753. ;
  754. ;**********************************************************
  755. ;The password checking routine- uses string comparator
  756. ;that is contained in the CCP.
  757. ;
  758. CKPASS0: EQU    $+OFFSET
  759.     LXI    H,PASBYTE
  760. DW    BIT2M
  761. DB    JRZ,    OK-$+FR
  762.     LXI    H,PAS2
  763.     SHLD    STRPTR
  764.     LXI    H,PASTBL2
  765.     SHLD    CMDPTR
  766. DB    JR,    CKPASS-$+FR
  767.     ;
  768. PASSINT: EQU    $+OFFSET
  769.     CALL    LOGTST
  770. DB    JRZ,    OK-$+FR
  771.     LXI    H,PAS1
  772.     SHLD    STRPTR
  773.     LXI    H,PASTBL1
  774.     SHLD    CMDPTR
  775.     ;
  776. CKPASS:    EQU    $+OFFSET
  777.     MVI    A,1
  778.     STA    CMDCNT
  779.     MVI    A,10
  780.     STA    CMDLEN
  781.     MVI    C,4    ;GIVES 4 TRIES
  782.     PUSH    B
  783.     ;
  784. CKAGIN:    EQU    $+OFFSET
  785.     CALL    ILPRT
  786.     DB    'Password:',0
  787.     POP    B
  788.     MVI    B,14    ;TO KEEP HIM FROM CLOBBERING
  789.             ;THE CODE
  790.     LXI    H,NAME
  791. DRCON:    EQU    $+OFFSET
  792.     CALL    VCONIN
  793.     CPI    CR
  794. DB    JRNZ,    DRCN2-$+FR
  795.     MVI    A,20H
  796.     MVI    B,1
  797. DRCN2:    EQU    $+OFFSET
  798.     MOV    M,A
  799.     INX    H
  800.     DCR    B
  801. DB    JRNZ,    DRCON-$+BR    
  802.     ;
  803.     DCR    C
  804.     JZ    RELOG0
  805.     PUSH    B
  806.     JMP    SRCHCMD
  807.     ;
  808. OK:    EQU    $+OFFSET
  809.     CALL    ILPRT
  810.     DB    'Ok.',0
  811.     JMP    RETCCP
  812. ;
  813. PASTBL1: EQU    $+OFFSET
  814.     DW    OK1
  815.     DW    CKAGIN
  816. PASTBL2: EQU    $+OFFSET
  817.     DW    OK2
  818.     DW    CKAGIN
  819. ;
  820. ;**********************************************************
  821. ;This is the in-line print subroutine.
  822. ;
  823. ILPRT:    EQU    $+OFFSET
  824. DB    EXX    
  825.     CALL    CRLF
  826. DB    EXX
  827.     ;
  828. ILPRT2:    EQU    $+OFFSET
  829.     XTHL        ;SAVE HL, GET MSG
  830. ILPLP:    EQU    $+OFFSET
  831.     MOV    C,M    ;GET CHAR
  832.     CALL    VCONOUT    ;OUTPUT IT
  833.     INX    H    ;POINT TO NEXT
  834.     MOV    A,M    ;TEST
  835.     ORA    A    ;..FOR END
  836. DB    JRNZ,    ILPLP-$+BR
  837.     XTHL        ;RESTORE HL, RET ADDR
  838.     RET        ;RET PAST MSG
  839. ;
  840. ;***********************************************************
  841. ;ROUTINE TO TEST LOG IN
  842. ;
  843. LOGTST:    EQU    $+OFFSET
  844.     LXI    H,PASBYTE
  845. DW    BIT5M
  846.     RET
  847. ;
  848. ;**********************************************************
  849. ;
  850. RELOG0:    EQU    $+OFFSET
  851.     CALL    CRLF
  852. RELOG:    EQU    $+OFFSET
  853.     CALL    LOGTST
  854. DB    JRZ,    EXIT-$+FR
  855.     CALL    LGMSG
  856. EXIT:    EQU    $+OFFSET
  857.     JMP    RETCCP
  858.     ;
  859. LGMSG:    EQU    $+OFFSET
  860.     CALL    ILPRT2
  861. DB    'Login please. ',CR,LF,0
  862.     RET
  863. ;
  864. ;**********************************************************
  865. ;Routines to trap transient files if they are resident
  866. ;on drive A.  If DIR.COM not present, then the CCP code for
  867. ;the DIR command will be executed. If TYPE.COM not present,
  868. ;then the CCP code for the TYPE command will be executed.
  869. ;This trapping is useful for SD.COM and MLIST.COM re-named
  870. ;to DIR.COM and TYPE.COM respectively.
  871. ;**NOTE**  Do not use a Directory transient that scans user
  872. ;areas such as SD-21 or SD-22. KDIR is ok.  You can use SD-42
  873. ;if you set AOPT to FALSE and add an IF AOPT and ENDIF around
  874. ;the [lda,newusr; cmp m; jnz mordir] sequence at the label,
  875. ;SYSFOK. Otherwise you will defeat the universal user area
  876. ;features in this program so far as directories are concerned,
  877. ;although the universallity will still apply to execution and
  878. ;finding of files in users 13, 14, and 15.
  879. ;
  880. DIR1:    EQU    $+OFFSET
  881.     LXI    H,TRAPBYT
  882. DW    SET0M            ;SET DIR TRAP
  883.     JMP    GETRANS
  884.     ;
  885. TYPE1:    EQU    $+OFFSET
  886.     LXI    H,TRAPBYT
  887. DW    SET1M
  888.     JMP    GETRANS
  889.     ;
  890. HUH0:    EQU    $+OFFSET
  891.     LXI    H,TRAPBYT
  892. DW    BIT0M            ;SEE IF DIR TRAP SET
  893.     JNZ    DIR        ;CCP DIR CODE IF NOT
  894. DW    BIT1M            ;SEE IF TYPE TRAP SET
  895. DW    RES1M
  896.     JNZ    TYPE        ;CCP TYPE CODE IF NOT
  897.     CALL    ILPRT
  898.     DB    'No!, ',BELL,0
  899.     CALL    LOGTST
  900. DB    JRNZ,    RELOG-$+BR
  901.     JMP    HUH+3        
  902.     ;
  903. ;**********************************************************
  904. ;This is the command string which is divided into private
  905. ;and public sections. Do not use more than five letters for
  906. ;the name of any command/transient and fill out each string
  907. ;to exactly five characters by using spaces below. Strings
  908. ;must occur at 5 character intervals.  If you use some
  909. ;other string length such as 4 as in the original CCP, just
  910. ;change string lengths below and change the LENCMD equate
  911. ;from 5 to 4.  I use 5 below so that LOGIN & LOGON can fit.
  912. ;
  913. CMDSTR2: EQU    $+OFFSET
  914.     DB    'ERA  REN  SAVE '
  915. CMDSTR1: EQU    $+OFFSET
  916.     DB    'TYPE USER PASS DIR  '
  917. CMDSTR0: EQU    $+OFFSET
  918.     DB    'DIR  LOGINLOGON'
  919. ;
  920. ;**********************************************************
  921. ;This is the command address table which is divided into
  922. ;private and public areas. The address of the routine to be
  923. ;jumped to must be here for CCP-included code as well as
  924. ;any that you put in your customized BIOS.
  925. ;You can expand the table to any extent that you have space
  926. ;and the command string above must be expanded in synchronism.
  927. ;
  928. CMDTBL2: EQU    $+OFFSET
  929.     DW    ERA    ;ERA....PRIVATE COMMANDS
  930.     DW    REN    ;REN
  931.     DW    SAVE    ;SAVE
  932. CMDTBL1: EQU    $+OFFSET
  933.     DW    TYPE1    ;TYPE..In case MLIST.COM renamed
  934.             ;to 'TYPE.COM'. Put the transient
  935.             ;in USER 14 on drive A.
  936.     DW    USER    ;USER
  937.     DW    CKPASS0    ;PASS(word) to gain access to
  938.             ;private user areas. Can also
  939.             ;be set at LOGIN by entering the
  940.             ;second password.
  941.     DW    DIR1    ;DIR....If you wish to use SD or
  942.             ;KDIR as a CCP transient instead of
  943.             ;the CCP DIR code, just change the
  944.             ;name of your transient to DIR.COM
  945.             ;and put it in USER 14 on drive A.
  946.             ;The transient will run only if 1rst
  947.             ;password level has been achieved.
  948.             ;If transient not present then CCP
  949.             ;'DIR' code will run.
  950. ;These commands will be the only ones allowed until the user
  951. ;logs in to the system with LOGIN.
  952. CMDTBL0: EQU    $+OFFSET
  953.     DW    DIR    ;WILL RUN THE CCP 'DIR' CODE
  954.     DW    PASSINT    ;LOGIN
  955.     DW    PASSINT    ;LOGON
  956. GETRAN0: EQU    $+OFFSET ;This must be last entry in table.
  957.     DW    GETRANS    ;GET THE TRANSIENT AND EXECUTE OR
  958.             ;RETURN TO CCP W/HUH MESSAGE IF NOT
  959.             ;ON DISK.
  960. ;
  961. ;**********************************************************
  962. ;This patch which is called from the CCP provides for a
  963. ;report of USER number at the prompt....i.e. A2> for USER 2,
  964. ;'A' drive.
  965. ;
  966. UPATCH:    EQU    $+OFFSET
  967.     CALL    GETUSR        ;GET USER NUMBER
  968.     ANI    0FH        ;KILL UNWANTED BITS
  969. DB    JRZ,    UPA2-$+FR    ;IF USER 0, DON'T REPORT
  970.     CPI    10
  971. DB    JRC,    UPA1-$+FR    ;JIF USER NUM = 0 THRU 9
  972.     SUI    10        ;USER NUM = 10 THRU 15
  973.     PUSH    PSW
  974.     MVI    C,'1'
  975.     CALL    VCONOUT        ;PRINT A '1'
  976.     POP    PSW
  977.     ;
  978. UPA1:    EQU    $+OFFSET
  979.     ADI    '0'
  980.     MOV    C,A
  981.     CALL    VCONOUT        ;PRINT DIGIT
  982.     ;
  983. UPA2:    EQU    $+OFFSET
  984.     MVI    C,'>'
  985.     CALL    VCONOUT        ;PRINT '>', EXIT
  986.     XRA    A
  987.     STA    TRAPBYT        ;CLEAR THE TRAPS
  988.     ;FALL THROUGH TO RESET PARAMETERS & RETURN
  989. ;
  990. ;**********************************************************
  991. ;Routines to reset parameters for string matching and other
  992. ;purposes.
  993. ;
  994. RSTPRMS: EQU    $+OFFSET
  995.     MVI    A,0C3H        ;SET BDOS TO TREAT USERS 
  996.     STA    BDOS+75EH    ;..13, 14 AND/ OR 15 AS
  997.     LXI    H,UNIV        ;..UNIVERSAL DEPENDING ON
  998.     SHLD    BDOS+75FH    ;..PASSWORD LEVEL.
  999.     ;
  1000.     MVI    A,LENCMD
  1001.     STA    CMDLEN
  1002.     LXI    H,PASBYTE
  1003. DW    BIT2M
  1004. DB    JRNZ,    RST1-$+FR
  1005.     ;
  1006. RST2:    EQU    $+OFFSET
  1007.     LXI    H,CMDSTR2
  1008.     SHLD    STRPTR
  1009.     MVI    A,(GETRAN0-CMDTBL2)/2
  1010.     STA    CMDCNT
  1011.     LXI    H,CMDTBL2
  1012.     SHLD    CMDPTR
  1013.     MVI    A,16
  1014.     STA    TSTUSR
  1015.     RET
  1016.     ;
  1017. RST1:    EQU    $+OFFSET
  1018.     LXI    H,CMDSTR1
  1019.     SHLD    STRPTR
  1020.     MVI    A,(GETRAN0-CMDTBL1)/2
  1021.     STA    CMDCNT
  1022.     LXI    H,CMDTBL1
  1023.     SHLD    CMDPTR
  1024.     MVI    A,MAXUSER+1
  1025.     STA    TSTUSR
  1026.     LDA    PASBYTE
  1027. DW    BIT5A
  1028.     RZ
  1029. RST0:    EQU    $+OFFSET
  1030.     MVI    A,(GETRAN0-CMDTBL0)/2
  1031.     STA    CMDCNT
  1032.     LXI    H,CMDSTR0
  1033.     SHLD    STRPTR
  1034.     LXI    H,CMDTBL0
  1035.     SHLD    CMDPTR
  1036.     RET
  1037. ;
  1038. ;**********************************************************
  1039. ;BIOS routines called herein.
  1040. ;
  1041. VCONIN:    EQU    $+OFFSET
  1042. DB    EXX
  1043.     CALL    BIOS+9H
  1044. DB    EXX
  1045.     RET
  1046.     ;
  1047. VCONOUT: EQU    $+OFFSET
  1048.     PUSH    H
  1049.     PUSH    D
  1050.     PUSH    B
  1051.     CALL    BIOS+0CH
  1052.     POP    B
  1053.     POP    D
  1054.     POP    H    
  1055.     RET
  1056. ;
  1057. ;**********************************************************
  1058. ;This routine will make USER 13, 14, and/or 15 universal on
  1059. ;drive A only depending on password level. Files placed in
  1060. ;user 13 will be universal without any password. Files placed
  1061. ;in user 14 will additionally be universal on drive A at the
  1062. ;first password level, and files placed in user 15 will be
  1063. ;universal at the second password level in addition to those
  1064. ;in users 13 and 14.
  1065. ;    ***** WARNING! *****
  1066. ;NEVER have two files by the same name & extension on the
  1067. ;same disk (one in USER 15 and the other in some other
  1068. ;USER) because CP/M will take which ever one comes first
  1069. ;in the directory.
  1070. ;
  1071. UNIV:    EQU    $+OFFSET
  1072.     MOV    A,B        ;duplicate instruction overlayed
  1073.     ORA    A        ;check pointer for zero byte
  1074. DB    JRNZ,    UNIV1-$+FR    ;skip if not zero byte of fcb
  1075.     ;
  1076.     LDA    CURDSK    ;get current disk
  1077.     ANI    0FH        ;mask out high nibble
  1078.     CPI    0        ;is it drive A? (may be changed
  1079.                 ;to any drive. 0,1,2.. = A,B,C..)
  1080. DB    JRNZ,    UNIV1-$+FR    ;skip if not
  1081.     ;
  1082.     LDAX    D        ;get fcb first byte
  1083.     CPI    0E5H        ;check for erased
  1084. DB    JRZ,    UNIV1-$+FR    ;skip if erased
  1085.     ;
  1086.     LDA    PASBYTE
  1087. DW    BIT5A
  1088. DB    JRNZ,    DFU13-$+FR
  1089. DW    BIT2A
  1090. DB    JRNZ,    DFU14-$+FR
  1091.     ;
  1092.     MOV    A,M
  1093.     CPI    15        ;and check for user 15
  1094. DB    JRZ,    MATCH0-$+FR    ;jump if zero
  1095.     ;
  1096. DFU14:    EQU    $+OFFSET
  1097.     MOV    A,M
  1098.     CPI    14        ;check for user 14
  1099. DB    JRZ,    MATCH0-$+FR
  1100.     ;
  1101. DFU13:    EQU    $+OFFSET
  1102.     MOV    A,M
  1103.     CPI    13        ;check for user 13
  1104. MATCH0:    EQU    $+OFFSET
  1105.     JZ    MATCH
  1106.     ;
  1107. UNIV1:    EQU    $+OFFSET
  1108.     MOV    A,B        ;duplicate instuction overlayed
  1109.     CPI    0DH        ;    "    "    "
  1110.     JMP    TINUSRCH    ;and return where routine left off
  1111.     ;
  1112. ;**********************************************************
  1113. ;This is a background memory test that runs whenever the
  1114. ;current console (including remote) is waiting for an input
  1115. ;character to be typed.
  1116. ;
  1117. ;TEST ROUTINE TO CONSTANTLY TEST MEMORY
  1118. ;
  1119.     IF    BGTST AND DRIVERS
  1120. ;
  1121. TSTPT:    EQU    $+OFFSET
  1122.     DW    0
  1123. TEST:    EQU    $+OFFSET
  1124.     DI
  1125.     PUSH    H
  1126.     LHLD    TSTPT
  1127.     INX    H
  1128.     MOV    A,H
  1129.     CPI    ($+OFFSET)/100H-SKIP/100H
  1130. DB    JRNZ,    TEST1-$+FR
  1131.     LXI    H,0
  1132. ;
  1133. TEST1:    EQU    $+OFFSET
  1134.     SHLD    TSTPT
  1135.     MOV    A,M
  1136.     CMA
  1137.     MOV    M,A
  1138.     CMP    M
  1139. DB    JRZ,    TEST2-$+FR
  1140.     XRA    M
  1141.     PUSH    PSW
  1142.     PUSH    H
  1143.     CALL    CRLF
  1144.     POP    H
  1145.     POP    PSW
  1146.     PUSH    PSW
  1147.     CALL    PRTHX
  1148.     CALL    ILPRT2
  1149.     DB    'H Bits bad at: ',0
  1150.     MOV    A,H
  1151.     CALL    PRTHX
  1152.     MOV    A,L
  1153.     CALL    PRTHX
  1154.     POP    PSW
  1155. ;
  1156. TEST2:    EQU    $+OFFSET
  1157.     CMA
  1158.     MOV    M,A
  1159.     POP    H
  1160.     EI
  1161.     RET
  1162. ;
  1163. PRTHX:    EQU    $+OFFSET
  1164.     PUSH    PSW
  1165.     RRC
  1166.     RRC
  1167.     RRC
  1168.     RRC
  1169.     CALL    PRTHX1
  1170.     POP    PSW
  1171. ;
  1172. PRTHX1:    EQU    $+OFFSET
  1173.     ANI    0FH
  1174.     CPI    10
  1175. DB    JRC,    PRTHX2-$+FR
  1176.     ADI    7
  1177. ;
  1178. PRTHX2:    EQU    $+OFFSET
  1179.     ADI    '0'
  1180.     MOV    C,A
  1181. DB    JR,    VCONOUT-$+BR
  1182.     ;
  1183. ;END OF CONSTANT MEMORY TEST
  1184. ;
  1185.     ENDIF
  1186. ;
  1187. USR2END: EQU    $+OFFSET    ;END OF USER2 CODE FOR NOW
  1188. INITSIZE EQU    INITSIZE    ;
  1189. USR2SIZE EQU    USR2END-USER2    ;DO NOT EXCEED SPACE ALLOCAT-
  1190.                 ;ED ABOVE YOUR RUNNING CP/M. 
  1191. ;
  1192. ;**********************************************************
  1193. ;    EQUATES FOR CCP PATCHES
  1194. LENCMD    EQU    5        ;LENGTH OF CCP CMD STRINGS
  1195. GETUSR    EQU    CCP+113H    ;GET USER #
  1196. SETUSR    EQU    CCP+115H    ;SET USER #
  1197. TSTUSR    EQU    CCP+692H    ;TEST USER #
  1198. USRSAV    EQU    CCP+118H
  1199. UPATCH0    EQU    CCP+390H
  1200. UPATCH1    EQU    CCP+393H
  1201. HUH    EQU    CCP+209H    ;CCP HUH RESPONSE
  1202. CRLF    EQU    CCP+98H        ;CCP CR/LF FUNCTION
  1203. RETCCP  EQU    CCP+382H    ;RE-ENTRY TO CCP
  1204. GETCMD    EQU    CCP+398H    ;GET THE ENTERED COMMAND
  1205. SRCHCMD    EQU    CCP+3B1H    ;ENTRY TO SEARCH OF COMMANDS
  1206. COMBUF    EQU    CCP+7H        ;LOC OF CMD BUFFER
  1207. BUFPTR    EQU    CCP+88H        ;LOC OF CMD BUFFER POINTER
  1208. CMDPTR    EQU    CCP+3B5H    ;LOC OF CMD ADDR TBL PTR
  1209. GETRPTR    EQU    CCP+3AFH    ;LOC OF GET TRANS PTR
  1210. STRPTR    EQU    CCP+32FH    ;POINTER TO CCP CMD STRINGS
  1211. CMDCNT    EQU    CCP+335H    ;BYTE VALUE = # OF COMMANDS
  1212. CMDLEN    EQU    CCP+33BH    ;BYTE VALUE = LENGTH OF EACH
  1213.                 ;COMMAND STRING.
  1214. TSTOPN    EQU    CCP+6DCH    ;TEST FILE OPEN FUNCTION
  1215. CMDDRV    EQU    CCP+7F0H    ;BYTE INDICATES DRV IN CMD
  1216. CMDERR    EQU    CCP+76BH    ;HUH RESPONSE IF DR #
  1217. NAME    EQU    CCP+7CEH    ;LOC FOR FN IN FCB
  1218. XTNSN    EQU    CCP+7D6H    ;STORAGE LOC FOR FILE TYPE,
  1219.                 ;EXT #, AND RECORD COUNT
  1220. RELOOK    EQU    CCP+6CDH    ;RELOOK W/INDICATED DRIVE
  1221. TSTOVWR    EQU    CCP+6F5H    ;TEST OVERWRITE OF CCP
  1222. CCPDMA    EQU    CCP+6DFH    ;LOC TO SUBSTITUTE FOR
  1223.                 ;DMA ADDRESS
  1224. TPASUB    EQU    CCP+75DH    ;LOC TO SUSTITUTE BEFORE
  1225.                   ;CALLING THE TPA
  1226. CLDBOOT    EQU    CCP+35CH    ;COLDBOOT ENTRY POINT
  1227. CONTINUE EQU    CCP+75FH    ;CONTINUE AFTER CALL TO TPA
  1228. GETRANS    EQU    CCP+6A8H    ;GET TRANS OR CCP COMMAND
  1229. ERA    EQU    CCP+51FH    ;ADDR OF ERA ROUTINE
  1230. REN    EQU    CCP+610H    ;ADDR OF REN ROUTINE
  1231. SAVE    EQU    CCP+5ADH    ;ADDR OF SAVE ROUTINE
  1232. DIR    EQU    CCP+477H    ;ADDR OF DIR ROUTINE
  1233. TYPE    EQU    CCP+55DH    ;ADDR OF TYPE ROUTINE
  1234. USER    EQU    CCP+68EH    ;ADDR OF USER ROUTINE
  1235. TPA    EQU    100H        ;OR YOUR TPA ADDRESS
  1236. STKPTR1    EQU    CCP+35DH
  1237. STKPTR2    EQU    CCP+760H
  1238. STKPTR3    EQU    CCP+383H
  1239. PRNSTR1    EQU    CCP+0A7H    ;PRINT STRING WITH LEADING
  1240.                 ;CR/LF..POINT TO IT WITH BC
  1241. PRNSTR2    EQU    CCP+0ACH    ;PRINT STRING..POINT WITH HL
  1242. CCPSPARE EQU    CCP+7F2H    ;14 SPARE BYTES AT END CCP
  1243.     ;Addresses of holes left in CCP that are filled in
  1244.     ;with patches.
  1245. HOLE1    EQU    CCP+79BH    ;16 BYTES
  1246. HOLE2    EQU    CCP+310H    ;30 BYTES    
  1247. HOLE3    EQU    CCP+3C1H    ;24 BYTES
  1248. HOLE4    EQU    CCP+1F5H    ;20 BYTES
  1249. HOLE5    EQU    CCP+6A5H    ;3 BYTES
  1250. ;
  1251. ;**********************************************************
  1252. ;    CCP patches
  1253. ;**********************************************************
  1254.     ORG    GETRPTR
  1255.     DW    GETRANS
  1256.     ;
  1257.     ORG    CMDCNT
  1258.     DB    0
  1259.     ;
  1260.     ORG    CMDPTR
  1261.     DW    GETR0
  1262.     ;
  1263.     ORG    HOLE5
  1264. GETR0:    DW    GETRANS
  1265.     DB    0    ;3 BYTES AT HOLE5
  1266. ;
  1267. ;Patch the turnkey start string into the CCP command buffer.
  1268.     ORG    COMBUF
  1269. TNKY:    DB    05,'XTCPM',0       
  1270. ;
  1271. ;**********************************************************
  1272. ;To trap the HUH message.
  1273. ;
  1274.     ORG    HUH
  1275.     JMP    HUH0
  1276. ;
  1277. ;**********************************************************
  1278. ;To redirect the CCP stack so a larger stack is available.
  1279. ;
  1280.     ORG    STKPTR1
  1281.     DW    STACK
  1282.     ORG    STKPTR2
  1283.     DW    STACK
  1284.     ORG    STKPTR3
  1285.     DW    STACK
  1286. ;
  1287. ;**********************************************************
  1288. ; This patch is used to restrict access to the higher user
  1289. ; areas while leaving the lower user areas public. The high-
  1290. ; est available public user area is defined by MAXUSER.
  1291. ;
  1292.     ORG    HOLE1
  1293. OK2:    LXI    H,PASBYTE
  1294. DW    RES2M
  1295.     ;
  1296. OK1:    LXI    H,PASBYTE
  1297. DW    RES5M
  1298.     JMP    OK
  1299. ;
  1300. TRAPBYT:
  1301.     DB    0
  1302.     DB    0,0    ;SPARES
  1303.             ;DO NOT EXPAND
  1304.             ;16 BYTES AT HOLE1
  1305. ;***********************************************************
  1306. ;The following sequence of statements are to patch the CCP
  1307. ;so that the transient 'XTCPM.COM' will be loaded above CP/M
  1308. ;by the CCP without the need for a special 'sysgen' routine.
  1309. ;Use the normal SYSGEN program with your system.
  1310.     ORG    CCP+1
  1311.     DW    CCPINIT
  1312.     ;
  1313.     ORG    HOLE2
  1314. CCPINIT:
  1315.     LXI    H,CCP+35CH
  1316.     SHLD    CCP+1
  1317.     ;
  1318.     LXI    H,BOOTFLG
  1319. DW    BIT1M            ;SEE IF COLD BOOT
  1320. DW    RES1M
  1321.     JZ    CCP+358H    ;ELSE GOTO WARM BOOT ENTRY 
  1322.     ;
  1323.     LXI    H,USER2+800H    ;TO MOVE OVERWRITE TEST LOC
  1324.                 ;TO TOP OF SYS MEMORY
  1325.     SHLD    TSTOVWR
  1326.     LXI    H,USER2        ;TO SUBSTITUTE DMA AND TPA
  1327.                 ;TO USER2 ADDRESS TEMPORARILY
  1328.     JMP    BRIDGE
  1329. ;
  1330.     DB    0,0        ;SPARES
  1331. ;Do not expand, 30 bytes available here.
  1332. ;
  1333. ;**********************************************************
  1334.     ORG    USRSAV
  1335.     DW    SAVUSR
  1336.     ;
  1337.     ORG    HOLE3
  1338. SAVUSR:    MOV    A,E
  1339.     CPI    0FFH
  1340.     JZ    BDOSFNC
  1341.     RLC
  1342.     RLC
  1343.     RLC
  1344.     RLC
  1345.     MOV    B,A
  1346.     LDA    DRIVE
  1347.     ANI    0FH
  1348.     ORA    B
  1349.     STA    DRIVE
  1350.     JMP    BDOSFNC
  1351.     DB    0    ;DO NOT EXPAND, 24 BYTES HERE
  1352. ;
  1353. ;**********************************************************
  1354. ;These are the passwords for entry to CP/M from BYE       
  1355. ;and to USER area and command privileges above MAXUSER       
  1356. ;repectively. Passwords may be up to 10 characters, and   
  1357. ;must be filled out to this value with spaces.           
  1358.     ORG    HOLE4
  1359. PAS1:    DB    'PASSWORD1 '
  1360. PAS2:    DB    'PASSWORD2 '           
  1361.             ;DO NOT EXPAND, EXACTLY 20 BYTES
  1362.             ;ARE AVAILABLE HERE.
  1363. ;                               
  1364. ;**********************************************************
  1365. ; This patch causes user number to be reported at the cp/m
  1366. ; prompt.....i.e. - A2>.  User 0 report is suppressed.
  1367. ;
  1368.     ORG    UPATCH0
  1369.     MVI    C,USRFNC
  1370.     ;
  1371.     ORG    UPATCH1
  1372.     DW    UPATCH
  1373.     ;the routine UPATCH is located in the USER2 area
  1374. ;**********************************************************
  1375. ; This patch causes the CCP of a cp/m 2.x system to look on
  1376. ; drive A when you are logged into a drive other than A and
  1377. ; call for a .COM file that does not exist on that drive.
  1378. ; Giving an explicit drive reference overrides this feature,
  1379. ; so that you can always force the file to be loaded from a
  1380. ; specific drive.
  1381. ;
  1382.     ORG    TSTOPN
  1383.     DW    APATCH        ;REPLACES 'CMDERR'
  1384. ;
  1385.     ORG    CCPSPARE
  1386. APATCH:    LXI    H,CMDDRV    ;GET DRIVE FROM CURRENT CMD.
  1387.     ORA    M        ;FETCHES DRIVE
  1388.     JNZ    CMDERR        ;GIVE ERR IF CMD HAS DRIVE #
  1389.     INR    M        ;FORCE TO DRIVE A
  1390.     LXI    D,XTNSN        ;UNDO WHEN...
  1391.     JMP    RELOOK        ;REENTERING
  1392.     ;DON'T EXPAND. 14 BYTES HERE.
  1393. ;
  1394. ;**********************************************************
  1395. ;    BDOS patches
  1396. ;**********************************************************
  1397. ;
  1398. BDOSPARE EQU    BDOS+0DEEH    ;18 SPARE BYTES AT END BDOS
  1399. MATCH    EQU    BDOS+077CH
  1400. CURDSK    EQU    BDOS+342H
  1401. TINUSRCH EQU    BDOS+761H
  1402. ;
  1403.     ORG    BDOS+0DDBH    ;SEARA+2
  1404.     DW    PASBYTE        ;ADDRESS OF PASS WORD BYTE
  1405. ;
  1406.     ORG    BDOSPARE
  1407. BRIDGE:    SHLD    CCPDMA
  1408.     INX    H
  1409.     SHLD    TPASUB
  1410.     JMP    CLDBOOT      ;COLDBOOT ENTRY POINT
  1411. ;end of CCP initialization
  1412. ;
  1413. CBOOT0:    LXI    H,BOOTFLG
  1414. DW    SET1M    
  1415.     JMP    CBOOT
  1416.         ;DO NOT EXPAND, EXACTLY 18 BYTES HERE
  1417. ;
  1418. ;**********************************************************
  1419. ;    BIOS patches
  1420. ;**********************************************************
  1421. ;This jump table overlays the table at the base of the BIOS
  1422. ;thus making it unecessary to have all of the jumps in the 
  1423. ;jump table at the base of the USER1 area.
  1424. ;
  1425.     ORG    BIOS
  1426.     JMP    CBOOT0
  1427.     ;
  1428.     IF    DRIVERS    AND NOT (STDCPM OR M2BIOS)
  1429.     ;
  1430.     ORG    BIOS+0FH
  1431.     JMP    LIST
  1432.     JMP    PUNCH
  1433.     JMP    READER
  1434.     ;
  1435.     ORG    BIOS+2DH
  1436.     JMP    LISTST
  1437.     ;
  1438.     ENDIF
  1439.     ;
  1440.     IF    DRIVERS AND (STDCPM OR M2BIOS)
  1441.     ;
  1442.     ORG    BIOS+6H
  1443.     JMP    CONST
  1444.     JMP    CONIN
  1445.     JMP    CONOUT
  1446.     JMP    LIST
  1447.     JMP    PUNCH
  1448.     JMP    READER
  1449.     ;
  1450.     ORG    BIOS+2DH
  1451.     JMP    LISTST
  1452.     ;
  1453.     ENDIF
  1454.     ;
  1455. ;************************************************************
  1456. ;
  1457. ;        SPECIAL ASCII CODES
  1458. ;
  1459. LF    EQU    0AH    ; LINE FEED
  1460. CR    EQU    0DH    ; CARRIAGE RETURN
  1461. EOF    EQU    1AH    ; END OF FILE
  1462. BELL    EQU    07H    ; DING
  1463. NULL    EQU    00H    ; NOTHING
  1464. ESC    EQU    1BH    ; ESCAPE - USED IN TWO CHAR COMMANDS
  1465. LIN    EQU    6CH    ; CHAR AFTER ESCAPE TO CLEAR LINE
  1466. SCRN    EQU    45H    ; CHAR AFTER ESCAPE TO CLEAR SCREEN
  1467. ;
  1468. ;        STATUS MASKS
  1469. ;
  1470. INRDY    EQU    02H    ;INPUT READY MASK
  1471. OUTRDY    EQU    01H    ;OUTPUT READY MASK
  1472. ;
  1473. ;    POSITION OF BIT PAIR IN IOBYTE
  1474. ;
  1475. CONCNT    EQU    1    ;CONSOLE BITS 0,1
  1476. RDRCNT    EQU    2    ;READER  BITS 2,3
  1477. PCHCNT    EQU    3    ;PUNCH   BITS 4,5
  1478. LSTCNT    EQU    4    ;LIST    BITS 6,7
  1479. ;
  1480. ;**********************************************************
  1481. ;
  1482. ;        Z80 EQUATES
  1483. ;
  1484. JR    EQU    18H    ;JUMP RELATIVE
  1485. JRZ    EQU    28H    ;JUMP RELATIVE ON ZERO
  1486. JRNZ    EQU    20H    ;JUMP RELATIVE ON NOT ZERO
  1487. JRC    EQU    38H    ;JUMP RELATIVE ON CARRY
  1488. JRNC    EQU    30H    ;JUMP RELATIVE IF CARRY RESET
  1489. LDIR    EQU    0B0EDH    ;MEMORY BLOCK MOVE
  1490. LDDR    EQU    0B8EDH    ;MOVE BLOCK UNTIL COUNTER=0
  1491. MOVIVA    EQU    47EDH    ;MOVE ACC TO INTERRUPT REGISTER
  1492. IM2    EQU    5EEDH    ;SET INTERRUPT MODE 2
  1493. BIT2A    EQU    57CBH    ;TEST BIT 2 IN ACC.
  1494. BIT5A    EQU    6FCBH    ;TEST BIT 5 IN ACC.
  1495. BIT0M    EQU    46CBH    ;TEST BIT 0 IN MEM
  1496. BIT1M    EQU    4ECBH    ;TEST BIT 1 IN MEM
  1497. BIT2M    EQU    56CBH    ;TEST BIT 2 IN MEM
  1498. BIT5M    EQU    6ECBH    ;TEST BIT 5 IN MEM
  1499. SET0M    EQU    0C6CBH    ;SET BIT 0 IN MEM
  1500. SET1M    EQU    0CECBH    ;SET BIT 1 IN MEM
  1501. RES1M    EQU    8ECBH    ;RESET BIT 1 IN MEM
  1502. RES2M    EQU    96CBH    ;RESET BIT 2 IN MEM
  1503. RES5M    EQU    0AECBH    ;RESET BIT 5 IN MEM
  1504. EXX    EQU    0D9H    ;EXCH REG PAIRS B, D, & H
  1505. ;
  1506. ;
  1507. ;BDOS EQUATES
  1508. ;
  1509. BDOSFNC    EQU    BDOS+6H
  1510. USRFNC    EQU    32
  1511. WRBUF    EQU    9
  1512.