home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / rcpm / userpw37.asm < prev    next >
Assembly Source File  |  1994-07-13  |  21KB  |  681 lines

  1. ;
  2. ;    USERPW.ASM  version 3.7   10/05/82
  3. ;      By Dave Hardy
  4. ;
  5. ;
  6. ;    USERPW is used to replace the 'USER' command in a remote
  7. ;    CP/M system, which is usually removed to restrict users
  8. ;    to the lower user areas. USERPW will allow password access
  9. ;    to any group of user areas via any number of passwords
  10. ;    that are specified in an external file called PWFILE.
  11. ;    An option is also available that allows only a single
  12. ;    built-in password to be used, as in the original version.
  13. ;    Public access is available to all user areas with values less
  14. ;    than MAXUSER (set below), and USERPW will also allow password
  15. ;    access to the 'restricted' user areas.  If the caller
  16. ;    types only the filename, with no user number on the command
  17. ;    tail, the program will tell the caller what user number he
  18. ;    is in and give instructions.
  19. ;
  20. ;   If the PWFILE option is selected, then the entered password will
  21. ;    be compared with a disk-resident file called PWFILE kept in a
  22. ;    user area specified by the PWUSR equate.  Each line of PWFILE
  23. ;    contains one password, followed by each allowed user area, all
  24. ;    separated by commas.  The last line of the file must contain
  25. ;    a '$' to indicate the end-of-file.  In addition, a semicolon
  26. ;    (';') may be used to indicate that the rest of any line is to
  27. ;    be ignored, and treated as a comment.  This feature may be used with
  28. ;    the CHGPW.ASM program to allow users to change their own passwords,
  29. ;    or just as a convenient way to leave comments in the PW file.
  30. ;
  31. ;PWFILE STRUCTURE IS:    PASSWORD1,X,Y<cr><lf>    <--X and Y are USER #'s
  32. ;            PASSWORD2,Y<cr><lf>
  33. ;            PASSWORD3,X,Y;JOHN SMITH<--this is a comment
  34. ;            etc....
  35. ;            $            <--this must be here
  36. ;
  37. ;  Modification history:
  38. ;10/05/82 Added code to allow PW to be echoed to the local console
  39. ;      as it is printed.  This uses direct console I/O which must
  40. ;      be modified to match your system.  The status of the output
  41. ;      port is not checked, since the console ALWAYS runs faster
  42. ;      than the modem.  See the PWCON equate below.
  43. ;      By Dave Hardy
  44. ;
  45. ;08/23/82 Added comment option to PWFILE to allow comments, and to work
  46. ;      with CHGPW.ASM to allow users to change their passwords.
  47. ;      Repaired bugs in optional drive select routines that caused
  48. ;      PWFILE to be trashed if both DRIVE and PWFILE are TRUE, and
  49. ;      modified LODPWF to prevent PWFILE from overlaying the CCP. 
  50. ;      However, there are still problems in the code that prevent the
  51. ;      program from working when BOTH DRIVE and PWFILE are TRUE.
  52. ;     (Therefore, the DRIVE option only works when the PWFILE option
  53. ;      is false.  In order to modify this program to work with DRIVE
  54. ;      and PWFILE at the same time, I would have to entirely restructure
  55. ;      the PWFILE itself.  Also, the PWFILE would become extremely large.
  56. ;      If enough interest is shown, I will modify this program (and 
  57. ;      CHGPW.ASM) to work with this selection method (USER <drive><user>),
  58. ;      but I prefer to keep the syntax used with this program the same as
  59. ;      that used by DR's CCP (USER <user>), since this program is intended
  60. ;      to be an upward compatible replacement for the CCP's USER function.)
  61. ;      Changed defaults to conform with standard CP/M.
  62. ;      By Dave Hardy
  63. ;
  64. ;06/04/82 Added optional drive select to command line. If DRIVE
  65. ;      is TRUE then the command line should contain both drive
  66. ;      and user area desired. Ex: USER B4 will select drive B,
  67. ;      user area 4.  Added necessary code to allow drive
  68. ;      logging.  MAXDRV should be set to the maximum drive allowed.
  69. ;      Ex: A=1, B=2, etc.  Added offset capability with BASE 
  70. ;      definition.
  71. ;      By Howard Booker 
  72. ;
  73. ;11/03/81 Removed BACKSPACE and DELETE code to prevent nightmare
  74. ;      bug that allowed remote callers to backspace over code 
  75. ;      and cause PWFILE to be printed as part of "INCORRECT"
  76. ;      error messages.
  77. ;      By Dave Hardy
  78. ;
  79. ;08/24/81 Cleaned up file, made compatible with MAC/ASM, made lower
  80. ;      case trap conditional (since some PW's might want them,
  81. ;      or numbers, etc.), changed PW error jump to eliminate
  82. ;      reloading PWFILE, corrected errors in BADPW routine,
  83. ;      and separated GOCCP code to avoid confusion.
  84. ;      By Dave Hardy
  85. ;
  86. ;08/23/81 Added multiple tries at PW, Trap for lower case,
  87. ;         cleaned up code and added many needed C/R's & L/F's.
  88. ;         By Jim C., Larkspur, Ca. RCPM (415) 461-7726
  89. ;
  90. ;08/19/81 Added equates for use with the GOCCP program.
  91. ;         By Larry Shipinski
  92. ;
  93. ;08/18/81 Moved PWFILE loader CALL so that PWFILE will be loaded 
  94. ;      before asking for PW, to eliminate the noticeable delay
  95. ;      before warm-boot, cleaned up code, and added comments.
  96. ;      By Dave Hardy
  97. ;
  98. ;08/11/81 Added RANGE conditional to allow PW access to a range of
  99. ;      user areas.  For example, if the range is from 1 to 4, then
  100. ;      once a user has logged into any user area within the range,
  101. ;      he may log into any other user areas within the range without
  102. ;      having to re-enter the password.  This is similar to the
  103. ;      LOGONCE option, but allows any range of user numbers to be
  104. ;      selected, while the range of LOGONCE includes all non-zero
  105. ;      user areas.  In addition, RANGE can only be used if the
  106. ;      PWFILE conditional is selected, and LOGONCE can only be
  107. ;      used if the PWFILE conditional is NOT selected.
  108. ;      By Dave Hardy
  109. ;
  110. ;08/09/81 Added PWFILE conditional to allow multiple passwords to be
  111. ;      readfrom a file, so that separate PW's can be used for
  112. ;      different user areas.  The number of PW's will be limited
  113. ;      only by the amount of available memory in the TPA.
  114. ;      The file of passwords can be kept in any user area,
  115. ;      and can be created with any editor.  Multiple user areas
  116. ;      are available to each password.  The format of the PWFILE
  117. ;      is defined at the beginning of this file.
  118. ;      By Dave Hardy
  119. ;
  120. ;08/03/81 Changed console input routines to DIRECT I/O so that
  121. ;      password will not be echoed.  This should make the
  122. ;      program's function a bit more secure by making it more
  123. ;      difficult to see what password has been typed.
  124. ;      By Dave Hardy
  125. ;
  126. ;07/12/81 Added TELUSR routines to inform caller of current user
  127. ;      number and how to use program.  Changed version number
  128. ;      to 2.1 instead of 3.0, because I'm still working on a
  129. ;      major revision of USERPW to be released as version 3.0.
  130. ;      By Dave Hardy
  131. ;
  132. ;05/23/81 Added LOGONCE option so that program will not ask for PW
  133. ;      if user is already in password-accessible user area.
  134. ;      By Dave Hardy
  135. ;
  136. ;  Define miscellaneous values:
  137. SETUSR    EQU    32    ;BDOS Set User function
  138. PRNSTR    EQU    9    ;BDOS Print String function
  139. OPEN    EQU    15    ;BDOS Open File function
  140. CURDSK    EQU    25    ;BDOS Return Current Disk function
  141. STDMA    EQU    26    ;BDOS Set DMA Address function
  142. READ    EQU    20    ;BDOS Read Sequential function
  143. CONOUT    EQU    2    ;BDOS Print Character function
  144. DIRIO    EQU    6    ;BDOS Direct Console I/O function
  145. BASE    EQU    0    ;SET TO BASE ADDRESS OF YOUR SYSTEM
  146. USERDR    EQU    BASE+4    ;CP/M's USER/DRIVE select byte
  147. WBOOT    EQU    BASE    ;CP/M's warm-boot address
  148. BDOS    EQU    BASE+5    ;CP/M'S BDOS JUMP vector
  149. DFCB    EQU    BASE+5CH ;Default File Control Block address
  150. SELDSK    EQU    18H    ;SELDSK vector offset from BIOS's warm-boot vector
  151. INPUT    EQU    0FFH    ;Value passed to DIRIO to cause console input
  152. CR    EQU    0DH    ;ASCII carriage-return
  153. LF    EQU    0AH    ;ASCII line-feed
  154. ;
  155. ;  Define TRUE and FALSE:
  156. FALSE    EQU    0
  157. TRUE    EQU    NOT FALSE
  158. ;
  159. ;
  160. ;  Set the following equates as desired:
  161. ;
  162. ; ***NOTE: DRIVE AND PWFILE CANNOT BE TRUE AT SAME TIME***
  163. MAXUSER EQU    0    ;Set to highest PUBLIC user area desired
  164. ABSUSER    EQU    15    ;Set to highest PW ACCESS user area desired
  165. MAXTRYS    EQU    3    ;Max # of PW attempts before exit to CP/M
  166. DRIVE    EQU    FALSE    ;True, if using both drive and user command line
  167. MAXDRV    EQU    2    ;Set to max # drives to avoid sel. err. if DRIVE TRUE
  168. PWFILE    EQU    TRUE    ;True, if PW's from file instead of built-in
  169. PWUSR    EQU    21    ;User area where PWFILE is to be kept
  170. PWDRV    EQU    1    ;Drive where PWFILE is kept (1=A, 2=B, etc.)
  171. PWCON    EQU    TRUE    ;True, if want PW echoed locally as it is typed
  172. LOCCON    EQU    81H    ;Local console output port (if PWCON=TRUE)
  173. TRAPLC    EQU    TRUE    ;True, if want to only use upper-case PW's
  174. RANGE    EQU    TRUE    ;True, if no ask for PW when within ranges
  175. HRANGE    EQU    4    ;High-end value of "no ask" range
  176. LRANGE    EQU    1    ;Low-end value of "no-ask" range
  177. LOGONCE    EQU    FALSE    ;True, if desire log-in only from user 0
  178.             ;LOGONCE SHOULD BE FALSE if PWFILE is used
  179. ;
  180. ;  The following code is for use with the GOCCP program, which
  181. ;  is a CCP substitute.  If you are not using GOCCP, then setting
  182. ;  GOCCP to TRUE will cause unpredictable results.  NOTE that this
  183. ;  option requires that you set the label CCP equal to the address
  184. ;  of the CCP in your system.  This address can be determined most
  185. ;  easily by using the STATUS or BDLOC programs.
  186. ;
  187. GOCCP    EQU    FALSE    ;True, if using the GOCCP program
  188.     IF    GOCCP
  189. CCP    EQU    BASE+3400H    ;Set to start of CCP in your system
  190. REQUSR    EQU    CCP+7FEH    ;Store requested USER number in CCP
  191.     ENDIF
  192. ;
  193. ; Start of USERPW code
  194. ;
  195.     ORG    BASE+100H
  196. ;
  197.     XRA    A        ;Initialize first pass flag
  198.     STA    FLAG
  199. ;
  200.     LXI    H,DFCB+1 ;Point to specified USER # in command line
  201.     MOV    A,M    ;Check that there is something in command line
  202.     CPI    20H
  203.     JZ    TELUSR    ;Nothing?  then tell user number and give help
  204. ;
  205.     IF    DRIVE    ;Select drive option
  206.     LDA    USERDR    ;Get current drive
  207.     STA    CURDRV    ;And save it
  208.     MOV    A,M
  209.     SUI    'A'    ;Remove ASCII bias
  210.     CPI    MAXDRV
  211.     JNC    NOBODY
  212.     STA    USERDR
  213.     MOV    C,A
  214.     PUSH    H
  215.     LHLD    WBOOT+1    ;Get BIOS vector
  216.     LXI    D,SELDSK
  217.     DAD    D    ;Compute SELDSK adr
  218.     SHLD    SAVSEL    ;Save it
  219.     LXI    D,VECRET
  220.     PUSH    D
  221.     MVI    E,1    ;Dont log yet (for speed)
  222.     PCHL
  223. VECRET    POP    H    ;Continue..
  224.     INX    H
  225.     ENDIF        ;DRIVE
  226. ;
  227.     MVI    E,0    ;Initialize user number accumulator
  228. NUMLUP    MOV    A,M    ;Get first character
  229.     INX    H    ;Point to next location in command line
  230.     SUI    '0'    ;Remove ASCII bias
  231.     JC    NUMDONE    ;Exit with specified user number in E
  232.     CPI    10    ;Check for illegal number (>9)
  233.     JNC    NUMDONE    ;Stop if illegal character found
  234.     MOV    D,A    ;Get specified user number
  235.     MOV    A,E    ; into A register
  236.     ADD    A
  237.     ADD    A
  238.     ADD    E
  239.     ADD    A
  240.     ADD    D
  241.     MOV    E,A    ;Save accumulation
  242.     JMP    NUMLUP    ;Loop back for next character
  243. ;
  244. TELUSR    LXI    D,TUMSG    ;Tell the user what user number he's in
  245.     MVI    C,PRNSTR
  246.     CALL    BDOS
  247.     LDA    USERDR    ;Get current USER number
  248.     RRC
  249.     RRC
  250.     RRC
  251.     RRC
  252.     ANI    0FH
  253.     CPI    0AH
  254.     JC    LT10
  255.     PUSH    PSW    ;Save user number
  256.     MVI    E,'1'    ;If user # is 10-16, then print leading '1'
  257.     MVI    C,CONOUT    ;This routine won't work
  258.     CALL    BDOS        ;if your CCP allows more than 19 user areas.
  259.     POP    PSW    ;Restore user number
  260.     SUI    0AH
  261. LT10    ADI    30H    ;Print user number
  262.     MOV    E,A
  263.     MVI    C,CONOUT
  264.     CALL    BDOS
  265.     MVI    E,'.'    ;End the line with a period
  266.     MVI    C,CONOUT
  267.     CALL    BDOS
  268. ;
  269.     CALL    ERRXIT    ;Print rest of message, then exit to CP/M
  270.     DB    CR,LF,'To change user areas, type '
  271. ;
  272.     IF    DRIVE
  273.     DB    'drive letter and '
  274.     ENDIF
  275. ;
  276.     DB    'user number on command line.',CR,LF
  277.     DB    'For example, type: USER '
  278. ;
  279.     IF    DRIVE
  280.     DB    'B'
  281.     ENDIF
  282. ;    
  283.     DB    '3   to enter '
  284. ;
  285.     IF    DRIVE
  286.     DB    'Drive B, '
  287.     ENDIF
  288. ;
  289.     DB    'user area 3.',CR,LF,'$'
  290. ;
  291. NUMDONE    MOV    A,E    ;Get requested user number
  292.     STA    REQUSR    ;Save for later, if needed
  293.     ORA    A
  294.     RM        ;Exit if illegal user number
  295.     CPI    ABSUSER+1
  296.     JNC    NOBODY    ;Illegal user area request
  297.     CPI    MAXUSER+1
  298.     JNC    SOME    ;Password user area request
  299. CHANGE    RLC        ;Move to upper nibble
  300.      RLC
  301.      RLC
  302.      RLC
  303.     MOV    B,A    ;Save requested user number
  304.     LDA    USERDR    ;Get current user/drive number
  305.     ANI    0FH    ;Trim off old user number
  306.     ORA    B    ;Add new user number
  307.     STA    USERDR    ;Set new user number
  308.     LDA    REQUSR
  309.     MOV    E,A
  310.     MVI    C,SETUSR ;Set user number with BDOS call, too.
  311. ;
  312.     IF    DRIVE
  313.     CALL    BDOS
  314.     JMP    WBOOT
  315.     ENDIF
  316. ;
  317.     JMP    BDOS     ;  then exit
  318. ;
  319. ;
  320. ;  REQUEST FOR RESTRICTED USER AREA, SO ASK FOR PASSWORD
  321. ;
  322. SOME    EQU    $
  323. ;
  324.     IF    LOGONCE    ;then see if user has already logged in
  325.     LDA    USERDR    ;Get USER NUMBER/DRIVE
  326.     ANI    0F0H
  327.     RLC
  328.     RLC
  329.     RLC
  330.     RLC
  331.     MVI    B,MAXUSER+1
  332.     CMP    B
  333.     JNC    GOTPW    ;If in non-public user area, PW was already
  334.             ; given so don't ask again
  335.     ENDIF
  336. ;
  337.     IF    PWFILE AND RANGE    ;Then check for already in RANGE
  338.     LDA    USERDR            ;Get USER/DRIVE number
  339.     ANI    0F0H
  340.     RLC
  341.     RLC
  342.     RLC
  343.     RLC
  344.     MVI    B,HRANGE+1        ;See if above RANGE
  345.     CMP    B
  346.     JNC    PRANGE            ;Jump if above RANGE
  347.     MVI    B,LRANGE        ;See if below RANGE
  348.     CMP    B
  349.     JC    PRANGE            ;Jump if below RANGE
  350.     LDA    REQUSR    ;Now see if requested user# is in RANGE
  351.     MVI    B,HRANGE+1        ;See if above RANGE
  352.     CMP    B
  353.     JNC    PRANGE            ;Jump if above RANGE
  354.     MVI    B,LRANGE        ;See if below RANGE
  355.     CMP    B
  356.     JC    PRANGE            ;Jump if below RANGE
  357.     JMP    GOTPW    ;If already in RANGE, and new user # is also in
  358.     ENDIF        ; RANGE, then don't ask for PW
  359. ;
  360. PRANGE    EQU    $
  361. ;
  362.     IF    PWFILE
  363.     CALL    LODPWF    ;Load the file of PW's
  364.     ENDIF
  365. ;
  366. PR2    LDA    FLAG    ;Get # of passes
  367.     ORA    A    ;First pass?
  368.     JZ    NOCRLF    ;If yes, then no CRLF needed
  369.     LXI    D,CRLF    ;Else print a CRLF to put next PW on a new line
  370.     MVI    C,PRNSTR
  371.     CALL    BDOS    ;Print CRLF
  372. NOCRLF    LXI    D,MSG    ;Ask for password
  373.     MVI    C,PRNSTR
  374.     CALL    BDOS
  375. ;
  376.     LXI    H,CONBUF    ;Reset console buffer pointer
  377.     MVI    C,10H        ;Allow 16 characters maximum
  378. TRYAGN    PUSH    B
  379.     PUSH    H
  380.     MVI    C,06H    ;Direct console I/O
  381.     MVI    E,0FFH    ;Console input
  382.     CALL    BDOS    ;Get password, 1 character at a time
  383.     POP    H
  384.     POP    B
  385.     ORA    A    ;Wait for input
  386.     JZ    TRYAGN
  387. ;
  388.     IF    TRAPLC
  389.     CPI    060H    ;Lower Case?
  390.     JC    NOTLC    ;No, Skip.
  391.     ANI    05FH    ;Strip L/C.
  392.     ENDIF
  393. ;
  394. NOTLC    CPI    0DH    ;Carriage return?
  395.     JZ    CHKPW    ;If yes, then check for match
  396. ;
  397.     IF    PWCON    ;Then echo the character to the local console
  398.     OUT    LOCCON    ;(NOTE that NO status checking is necessary)
  399.     ENDIF
  400. ;
  401.     MOV    M,A    ;Put character into buffer
  402.     INX    H    ;Increment pointer
  403.     DCR    C    ;See if 16 characters entered
  404.     MOV    A,C
  405.     ORA    A
  406.     JNZ    TRYAGN        ;If less than 16 characters entered,
  407.                 ;then continue...
  408. ;
  409.     IF    NOT PWFILE    ;Then check built-in PW
  410. CHKPW    LXI    H,CONBUF    ;Check for match with password
  411.     LXI    D,PASSWD    ;Point DE and HL to buffers
  412. NEXT    LDAX    D
  413.     CPI    '$'        ;When '$' found, then passwords match,
  414.     JZ    GOTPW        ;  so jump
  415.     CMP    M        ;Else check for character match
  416.     JNZ    BADPW        ;Jump if wrong password given
  417.     INX    H        ;Check next character for match
  418.     INX    D
  419.     JMP    NEXT
  420.     ENDIF
  421. ;
  422.     IF    PWFILE        ;Then check list of PW's in PWFILE
  423. CHKPW    LHLD    LASTPW
  424.     XCHG            ;Make DE point to first PW in file
  425.     JMP    FRSTPW        ; Then check for match
  426. DONXPW    CALL    GETNXPW        ;Returns with DE==>PW or '$' in PWFILE
  427. FRSTPW    LDAX    D        ;If DE==>'$' then done, no match
  428.     CPI    '$'        
  429.     JZ    BADPW        ;Jump if wrong PW given
  430.     LXI    H,CONBUF    ;Point HL to entered password
  431. NEXT    LDAX    D
  432.     CMP    M        ;Else check for character match
  433.     JNZ    DONXPW        ;If no match, then try next PW
  434.     INX    H        ;Else try next character for match
  435.     INX    D
  436.     LDAX    D
  437.     CPI    ','        ;If ',' found, then passwords may match
  438.     JNZ    NEXT        ; If not found, then continue,
  439.     MOV    A,M        ;Else check that both PW's are all read
  440.     CPI    0
  441.     JZ    CHKUSR        ;If both completely read, then match, so jump
  442.     JMP    DONXPW        ;Else try next PW in PWFILE list
  443. ;
  444. GETNXPW    LHLD    LASTPW        ;Get pointer to last PW checked
  445. NXCH    MOV    A,M
  446.     CPI    0DH        ;Scan for carriage return
  447.     JZ    GOTCR        ;When CR found, then point to next PW
  448.     CPI    '$'        ;Check for '$' here just in case...
  449.     JZ    NOMORE        ;If '$' found, then no more PW's
  450.     INX    H
  451.     JMP    NXCH
  452. ;
  453. GOTCR    INX    H        ;Skip over LF
  454.     INX    H        ;And point to next PW
  455.     SHLD    LASTPW        ;Save pointer to current PW
  456. NOMORE    XCHG            ;MAKE DE==>PW or '$'
  457.     RET            ;Then return to calling routine
  458. ;
  459. CHKUSR    XCHG        ;Make HL==>first user number in PWFILE line
  460.     INX    H
  461. NXNUM    MVI    E,0    ;Initialize USER number accumulator
  462. NUMLUP2    MOV    A,M    ;Get first character
  463.     INX    H    ;Point to next location in command line
  464.     SUI    '0'    ;Remove ASCII bias
  465.     JC    CMPUSR    ;Exit with specified user number in A
  466.     CPI    10    ;Check for illegal number (>9)
  467.     JNC    CMPUSR    ;Stop if illegal character found
  468.     MOV    D,A    ;Get specified user number
  469.     MOV    A,E    ; into A register
  470.     ADD    A
  471.     ADD    A
  472.     ADD    E
  473.     ADD    A
  474.     ADD    D
  475.     MOV    E,A    ;Save accumulation
  476.     JMP    NUMLUP2    ;Loop back for next character
  477. ;
  478. CMPUSR    DCX    H    ;Back up pointer (NUMLUP2 advanced 1 too many)
  479.     LDA    REQUSR    ;Compare allowable user# to the requested one.
  480.     CMP    E
  481.     JZ    GOTPW    ;Jump if they match, change user #, then exit
  482.     MOV    A,M    ;Check for CR, which means no more user areas
  483.     CPI    0DH    ;Jump if no more, and say "denied"
  484.     JZ    NOBODY2
  485.     INX    H    ;Skip over ',' and point to next user number
  486.     MOV    A,M    ;Check for CR, which means no more user areas
  487.     CPI    0DH    ;Jump if no more, and say "denied"
  488.     JZ    NOBODY2
  489.     CPI    ';'    ;If comments found, then treat same as CR found
  490.     JZ    NOBODY2
  491.     JMP    NXNUM    ;Try next user number in PWFILE line
  492.     ENDIF
  493. ;
  494. GOTPW    LDA    REQUSR        ;Get back requested user number
  495.     JMP    CHANGE        ;Change user number and exit
  496. ;
  497. BADPW    MVI    C,PRNSTR    ;Print "BAD PASSWORD" message
  498.     LXI    D,BADMSG
  499.     CALL    BDOS
  500. ;
  501.     IF    PWFILE    ;Then initialize CONBUF and PW pointer
  502.     CALL    INIT        
  503.     ENDIF
  504. ;
  505.     IF    NOT PWFILE    ;Then just initialize CONBUF
  506.     LXI    H,CONBUF
  507.     MVI    C,17
  508. NXIN    MVI    M,0
  509.     INX    H
  510.     DCR    C
  511.     JNZ    NXIN
  512.     ENDIF
  513. ;
  514.     LDA    FLAG        ;Get # of trys flag
  515.     INR    A        ;Increment # of trys.
  516.     STA    FLAG
  517.     CPI    MAXTRYS        ;See if max guesses...
  518.     JC    PR2        ;If more tries allowed, then jump
  519. ;
  520. NOBODY2    LXI    D,CRLF    ;Print 'NO ACCESS' msg on new line, then exit to CP/M
  521.     MVI    C,PRNSTR
  522.     CALL    BDOS
  523. ;
  524. NOBODY    CALL    ERRXIT    ;Print 'NO ACCESS' message, then exit to CP/M
  525.     DB    'Sorry, that '
  526. ;
  527.     IF    DRIVE
  528.     DB    'drive/'
  529.     ENDIF
  530. ;
  531.     DB    'user area is not available.','$'
  532. ;
  533. ;    Routine to load the password file
  534.     IF    PWFILE
  535. LODPWF    MVI    E,PWUSR
  536.     MVI    C,SETUSR
  537.     CALL    BDOS    ;Set to whatever user number that PWFILE is in
  538.     MVI    A,PWDRV    ;Initialize FCB for selected drive
  539.     STA    LOCFCB
  540.     LXI    H,LOCFCB+12
  541.     MVI    B,21
  542. ZLOOP    MVI    M,0
  543.     INX    H
  544.     DCR    B
  545.     JNZ    ZLOOP
  546.     MVI    C,OPEN    ;Open the file
  547.     LXI    D,LOCFCB
  548.     CALL    BDOS
  549.     INR    A
  550.     JZ    ABORT    ;If A has 0 then no file, so abort
  551. ;
  552. ;    Now load the file
  553. ;
  554.     LHLD    6    ;Check for attempt to load past top of TPA
  555.     LXI    D,-880H    ;Calculate BDOS - 800H (=CCP) - 80H
  556.     DAD    D
  557.     PUSH    H    ;Save top of memory for later checks
  558. ;
  559.     LXI    D,PWBUF-80H    ;Point to file load area-80H
  560.     LXI    B,0    ;Initialize record counter
  561.     PUSH    B    ; and save it
  562.     PUSH    D    ;Save load address, too
  563. GLOOP    POP    D    ;Get last load address
  564.     LXI    H,80H    ;Point HL to next address to read to
  565.     DAD    D
  566.     POP    B    ;Increment the record counter
  567. ;
  568. ;    Check for attempt to load past top-of-memory
  569. ;
  570.     POP    D    ;Get -(TOP-OF-MEMORY)
  571.     PUSH    D    ;Save again for next time
  572. ;
  573.     MOV    A,E    ;Subtract: (TOP) - (ADRS)
  574.     SUB    L
  575.     MOV    A,D    ;Look at carry to see if out of memory
  576.     SBB    H
  577. ;
  578.     JNC    SIZEOK    ;Jump if enough room
  579.     CALL    ERRXIT    ; Else print message and abort
  580.     DB    '+++DATA AREA TOO SMALL FOR PWFILE','$'
  581. ;
  582. SIZEOK    INX    B    ;Continue loading...
  583.     PUSH    B
  584.     PUSH    H    ;Save load address
  585.     XCHG
  586.     MVI    C,STDMA ;Set DMA address for next read
  587.     CALL    BDOS
  588.     LXI    D,LOCFCB ;Then read the next sector
  589.     MVI    C,READ
  590.     CALL    BDOS
  591.     ORA    A
  592.     JZ    GLOOP    ;If A=0 then more to read
  593.     POP    B
  594.     POP    B    ;Restore record counter
  595.     POP    H
  596.     MOV    A,B
  597.     ORA    C
  598.     JZ    ABORT    ;If 0 then nothing read, so abort
  599.     LXI    D,80H    ;Else, reset DMA address
  600.     MVI    C,STDMA
  601.     CALL    BDOS
  602. INIT    LXI    H,CONBUF    ;Initialize console input buffer
  603.     MVI    C,17
  604. NXINIT    MVI    M,0
  605.     INX    H
  606.     DCR    C
  607.     JNZ    NXINIT
  608.     LXI    H,PWBUF
  609.     SHLD    LASTPW    ;Save pointer to first PW in file
  610.     RET        ; and return
  611. ;
  612. ABORT    CALL    ERRXIT
  613.     DB    '+++CANNOT FIND PW FILE, ACCESS DENIED','$'
  614.     ENDIF
  615. ;
  616. ERRXIT    POP    D
  617.     MVI    C,PRNSTR
  618.     CALL    BDOS    ;PRINT THE ABORT MSG, THEN EXIT
  619. ;
  620.     IF    DRIVE
  621.     LDA    CURDRV    ;Return to original drive/user
  622.     STA    USERDR
  623.     ANI    0FH
  624.     MOV    C,A
  625.     LHLD    SAVSEL
  626.     LXI    D,WBOOT
  627.     PUSH    D
  628.     MVI    E,1
  629.     PCHL
  630.     ENDIF        ;DRIVE
  631. ;
  632.     JMP    WBOOT
  633. ;
  634. ;
  635. ;  Some miscellaneous messages:
  636. ;
  637. MSG    DB    'PW=','$'    ;Msg to ask user for pw
  638. ;
  639. BADMSG    DB    '+++INCORRECT','$'
  640. ;
  641. TUMSG    DB    'You are in USER area $'    ;First part of help msg.
  642. ;
  643. CRLF    DB    CR,LF,'$'    ;Printed to start a new line
  644. ;
  645. ;
  646.     IF    NOT GOCCP;Then save user number here in TPA
  647. REQUSR    DB    00H    ;Temporary storage area for user area number
  648.     ENDIF
  649. ;
  650. FLAG    DB    0    ;Counter for multiple PW attempts
  651. ;
  652.     IF    DRIVE    ;Then need a place to store these
  653. CURDRV    DB    0    ;Storage area for current drive
  654. SAVSEL    DW    0    ;Storage area for SELDSK address
  655.     ENDIF
  656. ;
  657. ;
  658. ;  CONSOLE INPUT BUFFER, USED FOR PASSWORD INPUT
  659. ;
  660. CONBUF    DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  661.         ;Up to 16 characters for password
  662. ;
  663.     IF    NOT PWFILE
  664. ;  PASSWORD TO ALLOW 'RESTRICTED USER AREA' ACCESS GOES HERE
  665. PASSWD    DB    'PASSWORD','$'    ;Must be followed by '$'
  666.     ENDIF
  667. ;
  668.     IF    PWFILE
  669. LOCFCB    DB    0    ;Drive is filled in here
  670.     DB    'PWFILE     '    ;Name of file that contains PW's
  671.     DS    40H    ;Some more room+ for PWFILE
  672. ;
  673. LASTPW    DW    0000H    ;Pointer to current PW in PWFILE
  674. ;
  675. ;  PWFILE is read in starting here.  It can take up the entire TPA
  676. ;    if desired.  The CCP is not overlayed.
  677. PWBUF    EQU    $    ;Rest of TPA is available for PWFILE
  678.     ENDIF
  679. ;
  680.     END
  681.