; MODULE NAME: PASSWORD.ASM ; LAST UPDATE: 15 DEC 84 BY: PEC ; FUNCTION: SECURITY PASSWORD FOR CP/M 2.2 ;====================================================================== ; ASCII CHARACTERS CR EQU 0DH ; CARRIAGE RETURN LF EQU 0AH ; LINE FEED BYPASS EQU 1AH ; CONTROL-Z, FOR INTERRUPT BDOS EQU 5 ; BDOS entry point DRIVE EQU 4 ; current drive number LOCKUP EQU 7eh+15h ; will lock up keyboard of Hazeltine ; Esprit TAB EQU 09h ; horizontal tab ORG 100H ; TRANSIENT PROGRAMME AREA ; savecpm: lxi h,0 ; save the CP/M stack dad sp ; and the stack pointer shld CPMSP lxi sp,stack ; set up local stack lda DRIVE ; save current disk sta DRSAV ; ; CLEAR SCREEN ; mvi b,3 ; use Register B as a counter call clear signon: lxi d,msg1 ; point to first message call sprint ; and print it call crlf ; space down ; ; INPUT SECTION ; getnom: lxi h,text ; point to the text input: mvi e,0ffh ; initialise function 6 for input mvi c,6 push h push b call BDOS ; and ask for character from console pop b pop h ora a ; logical OR of Register A jz input ; if zero then loop until key pressed cpi BYPASS jz DONE ; quit if a CONTROL-Z call clcuc ; convert to upper case mov m,a ; else put character into memory inx h ; get ready for next character cpi CR ; was it Return jz check ; if so compare with PASSWORD jmp input ; else loop ; ; CHECK THE NAME ; check: lxi d,name ; point to the permitted name lxi h,text match: ldax d ; character from NAME cpi '$' ; finished yet? jz pass ; ok then print welcome message cmp m ; else compare with memory jnz fail ; if not matched, then quit inx d inx h jmp match ; else continue ; ; OUTPUT SECTION ; pass: mvi b,3 ; re-set the counter read: lxi h,text ; point to start of message call crlf ; and space down push h push b lxi d,msg3 ; print welcome message mvi c,9 call BDOS pop b pop h it: mov a,m ; get character call print ; and print to screen inx h ; point to next character cpi CR ; are we finished ? jz id ; then get second message ; jmp it ; else read another character ; ; ; ID Number section ; id: lxi d,msg2 ; get second message call sprint call crlf getid: lxi h,text2 ; prepare buffer for ID Number input2: mvi e,0ffh ; initialise function 6 for input push b mvi c,6 push h call BDOS ; and ask for character from console pop h pop b ora a ; logical OR of Register A jz input2 ; if zero then loop until key pressed cpi BYPASS cz DONE ; quit if CONTROL-Z mov m,a ; else put character into memory inx h ; get ready for next character cpi CR ; was it Return jz check2 ; if so compare with ID Number jmp input2 ; else loop ; check2: lxi d,number ; point to the permitted ID number lxi h,text2 match2: ldax d ; character from NAME cpi '$' ; finished yet? jz success ; ok then print welcome message cmp m ; else compare with memory jnz fail2 ; if not matched, then quit inx d inx h jmp match2 ; else continue ; ; SUBROUTINES ; ; CLCUC.ASM ; ; convert lower case to upper case ; ; entry: A - character to convert ; exit: A - converted to upper case ; clcuc: cpi 'a' ; compare to "a" rc ; return if less than "a" cpi 'z'+1 ; see if larger than "z" rnc ; not lower case, so quit sui 'a'-'A' ; change "a...z" into "A...Z" ret ; ; CLEAR SCREEN - for Hazeltine Esprit ; clear: mvi a,7eh ; tilde call print mvi a,1ch call print ret ; sprint: push h push b mvi c,9 ;set up string print function call BDOS ; call BDOS to do it pop b pop h ret ; crlf: push psw ; save Register A mvi a,CR ; return call print mvi a,LF ; line feed call print pop psw ret ; done ; lfadj: mvi m,LF ; add line feed to memory inx h ; increment the pointer ret ; print: mov e,a ; put character into Register E push b mvi c,6 ; initialise print routine push psw push h call BDOS ; and do it pop h pop psw pop b ret ; done ; success: lxi d,startup call sprint call DONE ; fail: dcr b ; count down 1 jnz retry lxi d,signoff call sprint ; quit jmp getnom ; fail2: dcr b ; count down 1 jnz retry2 lxi d,signoff call sprint ; quit jmp getnom ; retry: call clear lxi d,again call sprint jmp getnom ; retry2: call clear lxi d,again2 call sprint jmp getid ; DONE: lda DRSAV ; return to CP/M without re-boot sta DRIVE ; restore current disk lhld CPMSP ; restore CP/M stack sphl ret ; ; MESSAGES ; again db CR,LF,'You missed that time, please try again' db CR,LF,CR,LF msg1 db TAB,TAB,'PASSWORD - a programme to provide a secure' db CR,LF,TAB,TAB,'sign on system for CP/M 2.2',CR,LF,LF db 'This programme does not print to screen.' db CR,LF,'Enter your name please - ',CR,LF db 'Then type to allow check to be made.' db CR,LF,'$' again2 db CR,LF,'You missed that time, please try again' db CR,LF msg2 db CR,LF,CR,LF,'Now enter your ID Number - ',CR,LF,'$' msg3 db CR,LF,'Welcome $' name db 'NAME$' number db '123$' signoff db CR,LF,'You are not authorised to use the computer,' db ' goodbye now',LOCKUP,'$' startup db CR,LF,'You are authorised to start now, go ahead$' ; ; LOCAL STORAGE SPACE ; DRSAV db 0 ; current drive number CPMSP dw 0 ; CP/M stack pointer ; ds 20h ; 32-byte stack stack: ; text equ $ ; begin message here text2 equ $+128 ; begin second message for ID Number ; end