home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
sigm
/
sigmv017.ark
/
SCRAMBLE.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
6KB
|
320 lines
;
;Scramble.asm - program to scramble CP/M files
;using an 8 byte password
;
month equ 3 ;last..
day equ 14 ;..modification..
year equ 79 ;..date
;
;Scrambling is done in place, i.e. the file is
;modified on top of itself. The same password
;used to scramble the file is used to unscramble
;it, using the exact same command. This is because
;the scrambling code is exclusive-or'ed with the
;data file, and two same exclusive ors result
;in the original value being returned.
;
;Command format:
;
; scramble filename.type password
;
;where password is any 8 character string which
;is allowable as a file name (i.e. no '.', etc).
;
MF SET 0 ;SHOW MOVE NOT REQUESTED
CF SET 0 ;SHOW COMP NOT REQUESTED
;
;(FROM EQU8.LIB...)
;DEFINE SOME MACROS TO MAKE THINGS EASIER
;
;DEFINE DATA MOVE MACRO: MOVE from,to,length
; from may be addr, or quoted string
;
MOVE MACRO ?F,?T,?L
IF NOT NUL ?F
IRPC ?C,?F
?Q SET '&?C&?C' ;;TEST FOR QUOTE
EXITM
ENDM
IF ?Q EQ ''''
LOCAL ?B,?Z
CALL ?Z
?B DB ?F
?Z POP H ;GET FROM
LXI B,?Z-?B ;GET LEN
ELSE
LXI H,?F
ENDIF
ENDIF
IF NOT NUL ?T
LXI D,?T
ENDIF
IF NOT NUL ?L
LXI B,?L
ENDIF
CALL MOVER
MF SET -1 ;;SHOW EXPANSION
ENDM
;
;DEFINE CP/M MACRO - CPM FNC,PARM
;
CPM MACRO ?F,?P
PUSH B
PUSH D
PUSH H
IF NOT NUL ?F
MVI C,?F
ENDIF
IF NOT NUL ?P
LXI D,?P
ENDIF
CALL BDOS
POP H
POP D
POP B
ENDM
;
ORG 100H
CALL START
DB 'SCRAMBLE.COM AS OF '
DB '0'+MONTH/10
DB '0'+MONTH MOD 10,'/'
DB '0'+DAY/10
DB '0'+DAY MOD 10,'/'
DB '0'+YEAR/10
DB '0'+YEAR MOD 10
DB 0DH,0AH,'$'
START POP D ;GET ID
MVI C,PRINT
CALL BDOS ;PRINT ID
;
;INIT LOCAL STACK
;
LXI H,0
DAD SP
SHLD STACK
LXI SP,STACK
;
;START OF PROGRAM EXECUTION
;
;SCRAMBLE A WHILE TO MIX UP THE SEED
;
MVI H,0 ;GET 256 #'S
MIXUP CALL PSEURAN ;GET A #
DCR H ;MORE?
JNZ MIXUP ;LOOP IF SO
;
;SEE THAT THE PASSWORD IS 8 CHARACTERS
;
LDA FCB2+8
CPI ' '
JNZ PWIS8
CALL ERXIT
DB '++ PASSWORD NOT 8 BYTES ++$'
;
;SAVE THE PASSWORD
;
PWIS8 MOVE FCB2+1,PASSWD,8
;
;PASSWORD IS 8 BYTES, NOW MAKE SURE NO CHARACTER
;IS REPEATED MORE THAN 2 TIMES
;
LXI H,PASSWD
MVI B,8 ;8 CHARS TO TEST
DUPTEST CALL CKDUP ;ABORTS IF 3 = CHARS
INX H ;TO NEXT CHAR
DCR B
JNZ DUPTEST
;
;SEE THAT THE INPUT FILE EXISTS
;
CPM OPEN,FCB
INR A ;OK?
JNZ SCRAMLP ;YES, SCRAMBLE IT
CALL ERXIT
DB '++NO SUCH FILE++$'
;
;READ THE FILE, SCRAMBLE A SECTOR, RE-WRITE IT.
;
SCRAMLP CALL RDSECT ;READ A SECTOR
JC FINISH ;EXIT LOOP IF EOF
CALL SCRAMBL ;SCRAMBLE IT
CALL BACKUP ;RE-POSITION FOR WRITE
CALL WRSECT ;RE-WRITE THE SECTOR
JMP SCRAMLP ;LOOP UNTIL EOF
;
;ALL DONE - ON A "NORMAL" CP/M SYSTEM, WE WOULDN'T
;HAVE TO DO ANYTHING, BECAUSE WE RE-WROTE IN PLACE.
;
;HOWEVER, FOR SUCH SYSTEMS AS THE NORTHSTAR CP/M,
;WE MUST EXPLICITLY CLOSE THE FILE, BECAUSE THE WRITE
;TO THE DIRECTORY WILL CAUSE THE CLEVER LIFEBOAT-
;DESIGNED BIOS TO FLUSH IT'S MEMORY-RESIDENT DISK
;BUFFERS
;
FINISH CPM CLOSE,FCB
INR A ;THIS BETTER WORK..
JNZ EXIT
DB '++ CLOSE ERROR - FILE LEFT IN '
DB 'UNKNOWN CONDITION ++$'
;
;SECTOR READ ROUTINE
;
RDSECT CPM READ,FCB
ORA A
RZ ;ALL OK
;
;READ ERROR OR EOF
;
CPI 1 ;EOF?
STC ;CARRY SHOWS EOF
RZ ;RET, CARRY SET
CALL ERXIT
DB '++ READ ERROR - FILE MAY BE '
DB 'DESTROYED ++$'
;
;SCRAMBLE THE SECTOR
;
SCRAMBL LXI H,80H ;POINT TO SECTOR
SCRLP CALL PSEURAN ;GET PSEUDO RANDOM #
XRA M ;SCRAMBLE
MOV M,A
INR L ;MORE IN SECTOR?
JNZ SCRLP
RET
;
;BACKUP THE FILE POINTER FOR THE RE-WRITE
;
BACKUP LDA FCBRNO ;GET SECTOR #
DCR A ;BACK UP
STA FCBRNO
RP ;RETURN IF OK
;
;WE BACKED UP INTO PREVIOUS EXTENT, WILL HAVE
;TO RE-OPEN IT
;
LDA FCBEXT ;GET EXTENT
DCR A ;BACK UP 1
STA FCBEXT
CPM OPEN,FCB ;RE-OPEN
INR A
JNZ OPEN2OK
CALL ERXIT
DB '++ RE-OPENING EXTENT FAILED',0DH,0AH
DB '++ FILE IS CLOBBERED $'
OPEN2OK MVI A,7FH ;GET HI SECTOR
STA FCBRNO
RET
;
;WRITE BACK THE SECTOR
;
WRSECT CPM WRITE,FCB
ORA A
RZ
CALL ERXIT
DB '++ WRITE ERROR - FILE CLOBBERED ++$'
;
;GET A PSEUDO-RANDOM 8 BIT NUMBER USING THE PASSWORD
;AS A SEED
;
; FOR SPEED, THIS ROUTINE DOES NO REGISTER
; PUSHES AND POPS, HOWEVER HL AREN'T USED.
;
PSEURAN MVI C,4 ;GRAB EVERY 4TH PSEU. #
PSEULP0 MVI B,8 ;SHIFT THRU 8 BYTES
LXI D,PASSWD
ORA A ;CLEAR INITIAL CARRY
PSEULP1 LDAX D ;GET A CHAR
RAR ;SHIFT
STAX D
INX D
DCR B
JNZ PSEULP1
;EXCLUSIVE-OR THE LAST FEW BITS INTO THE FIRST ONE
DCX D ;BACK UP TO LAST
RAR
RAR ;SHIFT A FEW MORE
XCHG
XRA M
RRC ;SHIFT LO BIT INTO HI
ANI 80H ;ISOLATE SINGLE BIT
LXI H,PASSWD ;GET FIRST BYTE
ORA M ;'OR' IN THE BIT
MOV M,A ;MOVE IT BACK
XCHG ;RESTORE HL
DCR C
JNZ PSEULP0 ;LOOP IF MORE PASSES
RET
;
;ROUTINE TO CHECK FOR DUPLICATE CHARS IN PASSWORD
;
CKDUP MVI C,3 ;DUP CHAR COUNTER
LXI D,PASSWD
MVI A,8 ;CHAR COUNT
CKDLP PUSH PSW ;SAVE COUNT
LDAX D ;GET CHAR
CMP M ;DUP?
JNZ CKNDUP
DCR C ;COUNT DUPS
JNZ CKNDUP
STA DUPCHAR ;SAVE FOR PRINT
CALL ERXIT
DB '++ NO CHARACTER MAY APPEAR MORE '
DB 'THAN TWICE IN THE PASSWORD. ',0DH,0AH
DB ''''
DUPCHAR DB $-$,''' DOES IN YOURS ++$'
CKNDUP INX D
POP PSW ;GET COUNT
DCR A
JNZ CKDLP
RET ;OK, NOT 3 DUP
;
;FOLLOWING FROM 'EQU7.LIB'---->
;
;MOVE SUBROUTINES
;
IF MF ;MACRO EXPANSION FLAG SET?
MOVER MOV A,M
STAX D
INX H
INX D
DCX B
MOV A,B
ORA C
JNZ MOVER
RET
ENDIF
;
;EXIT WITH ERROR MESSAGE
MSGEXIT EQU $ ;EXIT W/"INFORMATIONAL" MSG
ERXIT POP D ;GET MSG
MVI C,PRINT
CALL BDOS
;EXIT, RESTORING STACK AND RETURN
EXIT LHLD STACK
SPHL
RET ;TO CCP
PASSWD DS 8 ;PASSWORD KEPT HERE
DS 40H ;STACK AREA
STACK DS 2
;BDOS/CBIOS EQUATES (VERSION 7)
RDCON EQU 1
WRCON EQU 2
PRINT EQU 9
CONST EQU 11
OPEN EQU 15
CLOSE EQU 16
SRCHF EQU 17
SRCHN EQU 18
ERASE EQU 19
READ EQU 20
WRITE EQU 21
MAKE EQU 22
REN EQU 23
STDMA EQU 26
BDOS EQU 5
FCB EQU 5CH
FCB2 EQU 6CH
FCBEXT EQU FCB+12
FCBRNO EQU FCB+32