home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ENTERPRS
/
CPM
/
UTILS
/
F
/
PASSWORD.ARK
/
PASSWORD.ASM
next >
Wrap
Assembly Source File
|
1989-09-27
|
8KB
|
306 lines
; 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