Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 63 / AUGUST 1988 / PAGE 41

Wordlock
by Andy A. Lee

If you have $10 million at home, where do you think is a safer place for it? The heavy-duty safe in your study or the center of your driveway, where everyone can see it?

    The safe, of course, is the better place. The programs on your disks are like money on your driveway. You know most people who come by and see the money would take it if you're not around. This applies to your programs too! If you leave your disks lying around, sooner or later your programs will be copied without your authorization.
    Wordlock is a binary program that will stop all that. Using a password of up to 14 characters, it assures you that no one else will have access to your programs.

The programs on your
disks are like money on
your driveway. You
know most people who
come by and see the
money would take it
if you're not around.



How does it do that?
    First of all, let's take a look at the programs on your disks. Atari programs are made up of sequences of bytes, or numbers between 0 and 255. When you're saving a program, the computer puts the program directly from memory to the disk. So when you're loading it, the computer just copies the sequences of bytes back to memory.

The user will be asked
to enter a password
whenever the computer
is going to save or load
a program. You can
enter up to 14
characters as your
password.

    Let's play a game: Assume we have a number, 2534, and we want to remember this number by writing it down on paper. But we don't want to let others know what this number is. So we add one to every digit of 2534. After we do that, we will have a new number, 3645. We can now write that down on a piece of paper and nobody will guess the number is actually 2534. When we come back tomorrow to read the number, all we have to do is subtract one from every digit of 3645 to get the original number, 2534.
    So much for fun-let's get back to our computer. We know the programs are made up of sequences of bytes, or numbers between 0 and 255, in the memory of our computer. The computer saves the programs to disk exactly as they are in memory. And the computer loads it back to memory exactly as they are on disk. If we add one to every byte as it goes to the disk, we will have a sort of code.
    If we want to restore the program, we should subtract one from every byte, and then put the result of the subtraction in memory. If we don't subtract one (copy the bytes exactly as they are on disk), the program will not be restored, because every byte will be off by one. See how it works?
    Similar techniques are used in Wordlock, though they are much more complicated than just subtraction or addition. Every character of your password or passphrase is used in the coding process. So if you misspell the word by one letter or leave a letter out, you will not be able to load the program.
    Type in Listing 1 using the M/L Editor, and name the resultant file AUTORUN.SYS.
    To use Wordlock, you need to load the binary program as soon as possible after the boot process. This means if you are using a DOS that recognizes AUTORUN.SYS, you should name Wordlock AUTORUN.SYS so it will be loaded right after DOS. Such DOSs include DOS 2, DOS 2.5, DOS 3, SpartaDOS 23C.b, etc. If you are using a DOS that gives you control after the system is booted, please refer to your user's manual. It should tell you how to load a binary file. For example, OS/A + and SPARTADOS 1.1 give you a "Dl:" prompt after the boot process. You'll only need to type in "WORDLOCK" and press RETURN if you name the Wordlock file WORDLOCK.COM.
    Once Wordlock is loaded, it will be present until you turn the computer off. The reset key does nothing to it.

Password entering
    The user will be asked to enter a password whenever the computer is going to save or load a program. You can enter up to 14 characters as your password. Carefully check your password before you press RETURN. If the program you're loading or saving doesn't need a password, all you have to do when it asks for the password is press RETURN. This tells Wordlock to save or load the program as it is in memory or on disk. You need to do this to load old programs. Here's how to assign a password to your old programs:
  1. Load the program.
  2. When Wordlock asks for the password, press RETURN.
  3. Save the program.
  4. Wordlock will ask for a password. Enter your password for this program.
  5. Remember the password!
Last word
    Since it's impossible to restore your programs if you don't have the password, use only one or two passwords on all your programs-or write your passwords down some place. It's also a good idea to use at least four characters in your password.

Since it's impossible to
restore your programs
if you don't have the
password, use only one
or two passwords on all
your programs-or
write your passwords
down someplace.

    Listing 2 is the assembly source code for Wordlock, written using MAC/65. Wordlock locates itself at MEMLO, the first available memory in RAM for users, so it should work with all DOSs and all 8-bit Atari languages.

Andy Lee is 18 years old and attends Concord High School in Elkhart, Indiana. He moved to the U.S. from Taiwan in the summer of '82. He has been programming Atari computers for over two years, and also runs a BBS called Green Alley Bulletin Board System.

LISTING 1: M/L EDITOR DATA

1000 DATA 255,255,0,64,78,66,32,255,25
5,162,0,160,0,142,231,2,6391
1010 DATA 140,232,2,162,0,160,0,134,12
,132,13,169,87,141,253,3,4847
1020 DATA 96,142,255,3,32,255,255,8,19
2,1,240,2,40,96,136,174,6806
1030 DATA 255,3,152,157,14,4,189,74,3,
201,4,240,4,201,8,208,5659
1040 DATA 85,169,11,141,254,3,172,254,
3,185,254,64,32,235,64,206,9985
1050 DATA 254,3,208,242,32,246,64,160,
14,217,9,65,240,246,136,208,1373
1060 DATA 248,201,126,208,13,172,254,3
,240,234,32,235,64,206,254,3,1065
1070 DATA 16,226,201,155,240,24,168,17
3,254,3,201,14,240,214,13,255,1751
1080 DATA 3,170,152,157,0,4,32,235,64,
238,254,3,16,198,32,235,7641
1090 DATA 64,172,254,3,208,8,152,174,2
55,3,157,0,4,200,174,255,9410
1100 DATA 3,152,157,15,4,160,1,174,255
,3,40,96,142,255,3,32,4207
1110 DATA 255,255,8,140,254,3,174,255,
3,32,193,64,172,254,3,40,6720
1120 DATA 96,32,193,64,76,255,255,72,1
42,255,3,189,14,4,13,255,7028
1130 DATA 3,168,254,14,4,189,14,4,221,
15,4,208,5,169,0,157,3193
1140 DATA 14,4,104,240,8,217,0,4,240,3
,89,0,4,174,255,3,3338
1150 DATA 96,168,173,7,228,72,173,6,22
8,72,152,96,173,37,228,72,7895
1160 DATA 173,36,228,72,96,32,58,32,10
0,114,111,119,115,115,97,80,4240
1170 DATA 27,28,29,30,31,125,127,156,1
57,158,159,253,254,255,166,212,5034
1180 DATA 164,213,142,48,66,140,50,66,
174,42,3,172,43,3,134,212,4522
1190 DATA 132,213,173,253,3,201,87,208
,3,76,47,66,166,12,164,13,3863
1200 DATA 142,1,64,140,2,64,174,231,2,
172,232,2,134,12,132,13,3968
1210 DATA 142,14,64,140,16,64,24,173,2
31,2,105,24,141,4,64,173,3307
1220 DATA 232,2,105,1,141,6,64,160,0,2
4,177,212,105,1,141,31,2965
1230 DATA 64,200,177,212,105,0,141,32,
64,160,4,24,177,212,105,1,4209
1240 DATA 141,170,64,200,177,212,105,0
,141,171,64,200,24,177,212,105,9338
1250 DATA 1,141,191,64,200,177,212,105
,0,141,192,64,160,0,24,169,6182
1260 DATA 26,109,231,2,145,212,200,169
,0,109,232,2,145,212,160,4,7937
1270 DATA 24,169,165,109,231,2,145,212
,200,169,0,109,232,2,145,212,9850
1280 DATA 200,24,169,186,109,231,2,145
,212,200,169,0,109,232,2,145,8666
1290 DATA 212,162,17,189,61,66,133,213
,202,189,61,66,133,212,160,1,8253
1300 DATA 56,177,212,233,0,145,212,200
,177,212,233,64,145,212,136,24,1553
1310 DATA 177,212,109,231,2,145,212,20
0,177,212,109,232,2,145,212,202,3290
1320 DATA 16,209,174,231,2,172,232,2,1
34,212,132,213,160,0,185,0,8071
1330 DATA 64,145,212,200,208,248,230,2
13,160,23,185,0,65,145,212,136,898
1340 DATA 192,255,208,246,24,173,231,2
,105,24,141,231,2,173,232,2,7909
1350 DATA 105,1,141,232,2,162,0,160,0,
134,212,132,213,169,87,141,9022
1360 DATA 253,3,96,70,64,100,64,128,64
,136,64,78,64,67,64,83,2213
1370 DATA 64,179,64,187,64,226,2,227,2
,24,65,0,0,0,0,0,7211

LISTING 2: ASSEMBLY

10       .OPT NO LIST
20 ; *************************
30 ; *                       *
40 ; *        WORD-LOCK      *
50 ; *                       *
51 ; *       April, 1986     *
52 ; *                       *
60 ; *      by Andy A. Lee   *
70 ; *                       *
88 ; *************************
90 ;
0100 INDEX = $03FE
0110 CHN16 = $03FF
0120 BADS =  $0E
0130 MAXIM = $0E
0140 DELETE = $7E
0150 RETURN = $90
0160 DOSINI = $0C
0170 ICAX1 = $034A
0180 MEMLO = $82E7
0190 READ =  $04
0200 WRITE = $08
0210 OK  =   $01
0220 PASS =  $0400
0230 CNTR =  PASS+14
0240 LENS =  PASS+15
0250     *=  $4000
0260 ;
0270 ; Rest Init...
0280 ; ------------
0290 ;
0300 TODOS JSR $FFFF
0310 MLLSB LDX #$00
0320 MLMSB LDY #$00
0330     STX MEMLO
0340     STY MEMLO+1
0350 TDLSB LDX #$00
0360 TDMSB LDY #$00
0370     STX DOSINI
0380     STY DOSINI+1
0390     LDA #'W
0400     STA $03FD
0410     RTS
0420 ;
0430 ; Open vector
0440 ; -----------
0450 ;
0460 OPEN STX CHN16
0470 DOPM JSR $FFFF  ; Open the file
0480     PHP         ; Save status
0490     CPY #OK     ; Process okay?
0500     BEQ OURJOB  ; OK! Our turn!
0510     PLP         ; Error code
0520     RTS         ; Return
0530 ;
0540 ; Our works
0550 ; ---------
0560 ;
0570 OURJOB DEY
0580     LDX CHN16
0590     TYA         ; reset counter
0600     STA CHTR,X  ; to zero
0610     LDA ICAXI,X ; Is this...
0620     CMP #READ   ; read a file?
0630     BEQ CONT    ; Continue if so
0640     CMP #WRITE  ; write a file?
0650     BNE NOPASSWORD ; nopassword
0660 ; if it isn't read or write...
0670 ;
0680 ; PRINT "Password : "
0690 ; ------------------------
0700 ;
0710 CONT LDA #11    ; 11 characters
0720     STA INDEX
0730 PRLOOP
0740     LDY INDEX   ; Load index
0750 M1  LDA MSG-1,Y ; A charater
0760 S1  JSR SCREEN  ; Print it
0770     DEC INDEX   ; Next character
0780     BNE PRLOOP  ; Done?
0790 ;
0800 ; Input the password.
0810 ; -------------------
0820 ;
0830 INLOOP
0840 I1  JSR INPUT   ; A keystroke
8850     LDY UBADS
0860 CHLOOP
0870 B1  CMP BADIN-1,Y ; Compare with
0880     BEQ INLOOP  ; unusable
0890     DEY         ; input table.
0900     BNE CHLOOP
0910     CMP #DELETE ; Delete backs?
0920     BNE CH2     ; If not...
0930     LDY INDEX   ; Check index
8940     BEQ INLOOP  ; No input yet!
0950 S2  JSR SCREEN  ; Delete letter
0960     DEC INDEX   ; = INDEX - 1
0970     BPL INLOOP  ; Next key
0980 CH2 CMP #RETURN ; RETURN key?
0990     BEQ STOPIN  ; If so, stop
1000     TAY         ; Y reg. = A
1010     LDA INDEX   ; Too many?
1020     CMP #MAXIN
1030     BEQ INLOOP  ; Yes!!!
1040     ORA CHN16   ; Store
1050     TAX
1060     TYA
1070     STA PASS,X
1080 S3  JSR SCREEN  ; Print it too.
1090     INC INDEX   ; = INDEX + 1
1100     BPL INLOOP  ; Next key
1110 STOPIN
1120 S4  JSR SCREEN  ; Print the <CR)
1130     LDY INDEX   ; PASSWORD?
1140     BNE SVLEN   ; Yes, go on ...
1150 NOPASSWORD
1160     TYA         ; Y reg. = 0
1170     LDX CHN16   ; Clean password
1180     STA PASS,X
1190     INY         ; Length = 1
1200 SVLEN LDX CHN16 ; Save length
1210     TYA
1220     STA LEMS,X
1230     LDY #OK     ; No error flag
1240     LDX CHN16
1250     PLP
1260     RTS         ; All done.
1270 ;
1280 ; Get vector
1290 ; ----------
1300 ;
1310 GET STX CHN16
1320 DGET JSR $FFFF  ; Get a byte
1330     PHP         ; Save status
1340     STY INDEX   ; Save Y reg.
1350     LDX CHN16
1360 C1  JSR CODE    ; Decode byte
1370     LDY INDEX   ; Restore Y reg.
1380     PLP         ; Reload status
1390     RTS         ; Done!
1400 ;
1410 ; Put vector
1420 ; ----------
1430 ;
1440 PUT
1450 C2  JSR CODE    ; Code the byte
1460 DPUT JMP $FFFF  ; Output to disk
1470 CODE PHA
1480     STX CHN16   ; Save channel #
1490     LDA CHTR,X  ; calculate the
1500     ORA CHN16   ; byte to FOR
1510     TAY         ; with...
1520     INC CHTR,X  ; Reset counter
1530     LDA CNTR,X  ; Set back to
1540     CMP LENS,X  ;   zero?
1550     BNE NOTNOW
1560     LDA #$00    ; set to zero
1570     STA CHTR,X
1580 NOTNOW PLA      ; Load the byte.
1590     BEQ EXIT    ; ZERO? bypass!
1600     CMP PASS,Y  ; = CODE BYTE?
1610     BEQ EXIT    ; Bypass
1620     EOR PASS,Y  ; Coding...
1630 EXIT LDX CHN16  ; All done
1640     RTS         ; Bye-bye!
1650 ;
1660 ; Screen - print a character
1670 ;          on screen.
1680 ;
1690 SCREEN
1700     TAY         ; A = character
1710     LDA $E407   ; location of
1720     PHA         ; PRINT routine
1730     LDA $E406   ; in OS
1740     PHA
1750     TYA         ; restore A
1760     RTS         ; goto routine
1770 ;
1780 ; Input - input a keystroke
1790 ;
1800 INPUT
1810     LDA $E425   ; location of
1820     PHA         ; INPUT routine
1830     LDA $E424   ; in OS
1840     PHA
1850     RTS         ; goto routine
1860 MSG
1870     .BYTE " : drowssaP"
1880 ;
1890 ; Following characters are not
1900 ; usable for password.
1910 ;
1920 BADIN
1930     .BYTE 27,28,29,38,31,125,127
1940     .BYTE 156,157,158,159,253
1950     .BYTE 254,255
1960 ;
1970 ; Install WORDLOCK
1980 ; ----------------
1990 ;
2000 INIT LDX $D4
2010     LDY $D5
2020     STX X+1
2030     STY Y+1
2040     LDX $032A   ; Get address
2050     LDY $032B   ; of "D" vectors
2060     STR $D4     ; table
2070     STY $D5
2080 ;
2090 ; We will see if WORDLOCK is
2100 ; already installed
2110 ;
2120 CHECK
2130     LDA $03FD
2140     CMP #'W
2150     BNE COPY
2160     JMP ERITINIT
2170 ;
2180 ; We now install WORDLOCK
2190 ;
2200 COPY
2210     LDX DOSINI
2220     LDY DOSINI+1
2230     STX TODOS+1
2240     STY TODOS+2
2250     LDX MENLO
2260     LDY MEMLO+1
2270     STX DOSINI
2280     STY DOSINI+1
2290     STX TDLSB+1
2300     STY TDMSB+1
2310     CLC         ; calculate new
2320     LDA MENLO   ; MENLO
2330     ADC # <INIT-$4000
2340     STA MLLSB+1
2350     LDA MEMLO+1
2360     ADC # >INIT-$4000
2370     STA MLMSB+1
2380     LDY #0      ; First, copy
2390     CLC         ; OPEN vector
2400     LDA ($D4),Y ; so we can use
2410     ADC #$01    ;    it ...
2420     STA DOPN+1
2430     INY
2440     LDA ($D4),Y
2450     ADC #$00
2460     STA DOPN+2
2470     LDY #4      ; Now the GET
2480     CLC         ; vetor too...
2490     LDA ($D4),Y
2500     ADC #$01
2510     STA DGET+1
2520     INY
2530     LDA ($D4),Y
2540     ADC #$00
2550     STA DGET+2
2560     INY         ; Last, PUT
2570     CLC         ; vector...
2580     LDA (SD4),Y
2590     ADC #$01
2600     STA DPUT+1
2610     INY
2620     LDA ($D4),Y
2630     ADC #$00
2640     STA DPUT+2
2650     LDY #0
2660     CLC        ; Insert My OPEN
2670     LDA # <OPEN-$4001 ; vector
2680     ADC MENLO
2690     STA ($D4),Y
2700     INY
2710     LDA # >OPEN-$4001
2720     ADC MEMLO+1
2730     STA ($D4),Y
2740     LDY #4      ; Insert My GET
2750     CLC         ; vector
2760     LDA # <GET-$4001
2770     ADC MENLO
2780     STA ($D4),Y
2790     INY
2800     LDA # >GET-$4001
2810     ADC MEMLO+1
2820     STA ($D4),Y
2830     INY         ; Insert My PUT
2940     CLC         ; vector
2850     LDA # <PUT-$4001
2860     ADC MENLO
2870     STA ($D4),Y
2880     INY
2890     LDA # >PUT-$4001
2900     ADC MEMLO+1
2910     STA ($D4),Y
2920     LDX #17
2930 CAL LDA MOVETHESE,X
2940     STA $D5
2950     DEX
2960     LDA MOVETHESE,X
2970     STA $D4
2980     LDY #1
2990     SEC
3000     LDA ($D4),Y
3010     SBC # <4000
3020     STA ($D4),Y
3030     INY
3040     LDA ($D4),Y
3050     SBC # >$4000
3060     STA ($D4),Y
3070     DEY
3080     CLC
3090     LDA ($D4),Y
3100     ADC MENLO
3110     STA ($D4),Y
3120     INY
3130     LDA ($D4),Y
3140     ADC MEMLO+1
3150     STA ($D4),Y
3160     DEX
3170     BPL CAL
3180     LDX MENLO
3190     LDY MEMLO+1
3200     STX SD4
3210     STY $D5
3220     LDY #0
3230 MOVE LDA TODOS,Y
3240     STA ($D4),Y
3250     INY
3270     BNE MOVE
3271     INC $D5
3272     LDY # <INIT-$4001
3273 MOVE2 LDA TODOS+$0100,Y
3274     STA ($D4),Y
3275     DEY
3276     CPY #$FF
3277     BNE MOVE2
3280     CLC         ; calculate new
3290     LDA MENLO   ; MENLO
3300     ADC # <INIT-4000
3310     STA MENLO
3320     LDA MEMLO+1
3330     ADC # >INIT-$4000
3340     STA MEMLO+1
3350 ERITINIT
3360 R   LDX #$00
3370 Y   LDY #$00
3380     STR $D4
3390     STY $D5
3400     LDA #'W
3410     STA $03FD
3420     RTS
3430 MOVETHESE .WORD S1,S2,S3,S4
3440     .WORD I1,M1,B1,C1,C2
3450     *=  $02E2
3460     .WORD INIT