home *** CD-ROM | disk | FTP | other *** search
- ; title 'PASSWORD.ASM'
- ; page 60
- ;
- ;
- ; PASSWORD.ASM Version 1.0
- ; By Bo McCormick 8/6/81
- ;
- ; This is a program that adds password protection
- ; to programs. Format:
- ;
- ; PASSWORD name_of_file
- ;
- ; Then answer the prompt with the password to be
- ; applied to the program:
- ;
- ; Password : enter password here
- ;
- ; If everything goes well, the program will be saved to disk.
- ; If not, a message is printed and control is passed
- ; to the CCP.
- ;
- ; The good part of this is, when you type in the program
- ; program name next time, instead of running the program
- ; right away, the program asks you for the password. If you
- ; reply with something other than the original password, the
- ; program doesn't run, and it returns to the ccp.
- ;
- ;
- ;EQUATES
- mesout: equ 9 ;BDOS functions
- incon: equ 10
- open: equ 15
- close: equ 16
- delete: equ 19
- read: equ 20
- write: equ 21
- setdma: equ 26
- ;
- cr equ 0dh ;ascii values
- lf equ 0ah
- eos equ '$'
- ;
- boot equ 0 ;0 for standard CP/M
- ;4200H for ALT. CP/M;
- bdos equ boot+5
- fcb equ boot+5ch
- defbuf equ boot+80h
- tpa equ boot+100h
- stack equ tpa
- ;
- org tpa
-
- ;
- ;
- start: lxi h,0 ;save stack pointer
- dad sp ;put stack in hl
- shld old$stack-offset ;save it
- lxi sp,stack ;get new stack
- ;
- ; stack saved so program can return to CCP without
- ; intervening warm start.
- ;
- lda fcb+9 ;get first char of extension
- cpi ' ' ;if ' ' then change to .COM
- jz no$type
- cpi 'C' ;If there is an extension,
- jnz not$right ;make sure it's .COM
- lda fcb+10 ;check second letter
- cpi 'O'
- jnz not$right
- lda fcb+11
- cpi 'M' ;last letter
- jz is$com ;if it is a COM, then cont.
- not$right:
- call end$mes ;it's not a com file, so tell
- ;
- db cr,lf,'Must be a command (.COM) file'
- db cr,lf,eos
- ;
- end$mes:
- pop d ;get address of message
- mvi c,mesout ;PRINT STRING command
- call bdos ;print error message
- ;
- finish: lhld old$stack-offset ;get old stack
- sphl ;put it in HL
- ret ;return to CP/M
- ;
- no$type mvi a,'C' ;if there was space, change
- sta fcb+9 ;to COM
- mvi a,'O'
- sta fcb+10
- mvi a,'M'
- sta fcb+11
- ;
- is$com mvi a,0 ;zero record count
- sta fcb+32
- mvi c,open ;OPEN file command
- lxi d,fcb ;load address of FCB in DE
- call bdos ;Open file
- inr a ;successful?
- jnz open$ok ;if so, then continue
- call end$mes ;if not, then tell
- ;
- db cr,lf,'Cannot open file',cr,lf,eos
- ;
- open$ok lxi d,buffer-offset ;point to where program goes
- r$loop: mvi c,setdma ;SET DMA command
- push d ;save it
- call bdos ;and tell CP/M
- lxi d,fcb ;point to FCB
- mvi c,read ;READ sector command
- call bdos ;do it
- pop d ;get DMA address back
- ana a ;EOF?
- jnz done$read ;if so, then ask for password
- lxi h,80h ;length of sector
- dad d ;bump DMA
- xchg ;put new address in DE
- jmp r$loop ;and read some more
- ;
- done$read:
- xchg ;dma ==> hl
- shld end$prog-offset ;save last address
- gpasag call get$pas ;print password message
- ;
- pas$mes db 'Password: ',eos
- ;
- get$pas pop d ;get address of message
- mvi c,mesout ;PRINT STRING function
- call bdos ;print it
- lxi d,defbuf ;point to default buffer
- mvi a,8 ;tell CP/M max chars
- stax d ;put it there
- mvi c,incon ;READ LINE command
- call bdos ;do it
- lxi h,defbuf+1 ;point to length
- lxi d,password-offset ;point to storage
- lda defbuf+1 ;get length
- ana a ;set flags
- jz gpasag ;if 0 then ask again
- inr a ;plus 1 for length byte
- mov b,a ;put length in B
- mploop mov a,m ;get char
- stax d ;save it
- inx h ;increment pointer
- inx d ; " "
- dcr b ;decrement length
- jnz mploop ;if not zero, then next char
- xra a ;zero a
- sta fcb+12 ;zero bytes in FCB
- sta fcb+14
- sta fcb+32
- mvi c,open ;OPEN file command
- lxi d,fcb ;point to FCB
- call bdos ;open the file
- lxi d,n$start ;point to new program start
- ;
- push d
- w$loop1 pop d ;get DMA
- push d ;put it back on stack
- mvi c,setdma ;SET DMA command
- call bdos ;tell CP/M
- lxi d,fcb ;point to FCB
- mvi c,write ;WRITE SECTOR command
- call bdos ;do it
- pop h ;get DMA address from stack
- lxi d,80h ;length of sector
- dad d ;HL has new DMA
- push h ;put it on stack
- mov a,h ;this is to get 2's complement
- cma ;of address. We are subtracting
- mov d,a ;the current address from the
- mov a,l ;high address. If the high byte
- cma ;<1 , we are done
- mov e,a ;
- inx d ;Now 2's comp. of address in DE
- lhld end$prog-offset ;get ending address
- dad d ;Subtract (add 2's comp)
- mov a,h ;get high byte
- inr a ;is it FF (-1)?
- ana a ;set flags
- jnz w$loop1 ;if not, write another sector
- ;
- mvi c,close ;That's it. Close the file
- lxi d,fcb ;point to FCB
- call bdos ;do it
- jmp finish ;goto finish
- ;
- ;
- n$start:
- offset equ 100h-n$start
- ;
- ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- ; %% WARNING - %%
- ; %% From now on, all labels are in %%
- ; %% the form: %%
- ; %% LABEL EQU $+OFFSET %%
- ; %% This is to allow the program to run at100H %%
- ; %% when it is saved by the earlier portion. %%
- ; %% ALL new labels added MUST be in the form %%
- ; %% LABEL EQU $+OFFSET for this program to work %%
- ; %% properly. %%
- ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- ;
- ;This is portion of the program is placed at the beginning
- ;of the program to be PASSWORDed. When it is executed, it will
- ;ask for a password. If the password is incorrect, the program
- ;warm starts. If the password is correct, the program is moved
- ;to the TPA and executed.
- ;
- lxi h,0 ;save stack pointer
- dad sp ;stack is in HL
- shld old$stack ;save it
- lxi sp,stack ;get new stack
- call ot$pw ;print password message
- ;
- db cr,lf,'Password :'
- db eos
- ;
- ot$pw equ $+offset
- pop d ;get address of message
- mvi c,mesout ;PRINT STRING command
- call bdos ;print it
- lxi d,newbuf ;point to input buffer
- mvi c,incon ;READ LINE command
- call bdos ;read it
- ;
- lxi h,password ;point to actual password
- lxi d,newbuf+1 ;point to user's input
- mov b,m ;get length
- ;
- c$lp equ $+offset
- ldax d ;get char
- cmp m ;are they the same?
- jnz boot ;if not, restart
- inx h ;point to next characters
- inx d ; " " " "
- dcr b ;decrement length
- jnz c$lp ;if not done, then loop
- ;
- ; Now we move a segment of code to a part of the default
- ; buffer. This segment moves the actual program down to the
- ; TPA
- ;
- lxi h,n$mv ;point to code
- lxi d,defbuf+20h ;point to new postion
- mvi b,n$m$len ;length
- ;
- move equ $+offset
- mov a,m ;get byte
- stax d ;save it
- inx d ;point to next addresses
- inx h ; " " " "
- dcr b ;decrement length
- jnz move ;if not done, loop
- jmp defbuf+20h ;go to segment
- ;
- n$mv equ $+offset ;segment that gets moved
- lhld old$stack ;get stack pointer
- push h ;save it on stack
- lxi h,buffer ;get start of actual program
- mov a,h ;We have to compute the length
- cma ;and because X-Y equals
- mov d,a ;X + Two's complent(Y), we have
- mov a,l ;to find the 2's comp. of the
- cma ;first address
- mov e,a ;
- inx d ;Y is in DE
- lhld end$prog ;get last address
- dad d ;subtract (add 2's comp)
- mov b,h ;put length in BC
- mov c,l ; " " " "
- lxi d,tpa ;point to TPA
- lxi h,buffer ;point to first address
- n$m$lp equ defbuf+20h+$+offset-n$mv
- mov a,m ;get byte
- stax d ;save byte
- inx h ;increment address
- inx d ; " "
- dcx b ;decrement length
- mov a,b ;check for zero left
- ora c ;Are we done?
- jnz n$m$lp ;if not, loop some more
- pop h ;get stack from stack
- sphl ;put stack in SP
- jmp tpa ;run program
- ;
- n$m$len equ $+offset-n$mv ;length of segment
- ;
- ;
- password equ $+offset ;password storage
- db 0,' '
- ;
- newbuf equ $+offset ;Users input buffer
- db 10H,0,' '
- ;
- old$stack equ $+offset ;place for stack
- ds 2
- ;
- end$prog equ $+offset ;place for address
- ds 2
- ;
- buffer equ $+offset ;where actual program goes
- end