;************************************›;* Atari Phone book *›;* by *›;* Tom Johnson *›;* for the Action!/PRO tutorial *›;* *›;* Originally translated to *›;* the Atari in BASIC XL *›;* *›;* based on TI Mailing List *›;* by *›;* Doug Hapeman *›;* in *›;* July 1983 Compute! *›;* *›;* Thanks to Ray Hill for *›;* the ReadItem and WriteItem *›;* routines *›;* *›;*This program is too big to compile*›;*like normal. You must compile it *›;*from disk. Like this: *›;* *›;*Go to the monitor and type: *›;* *›;* C "D:APROG12.002" *›;* *›;*Don't forget the second " at the *›;*end. *›;* *›;************************************› ›MODULE››DEFINE Cls = "Put(125)" ;clear the screen› ››;************************************›;* The following are the starting *›;* places for each field *›;************************************››DEFINE Lastname = "0"›DEFINE Firstname = "13"›DEFINE Address = "23"›DEFINE City_state= "63"›DEFINE Zipcode = "103"›DEFINE Phone = "114"›;------------------------------------››DEFINE Max = "100" ;max number of people›DEFINE Datasize = "128" ;byte per person›DEFINE Totalsize = "12800" ;room for 100 people› ;gotton by › ;Datasize*Max››BYTE› Choice, ;catch all variable› ;for user input›› NumPeople ;number of people currently› ;in the database› ›BYTE ARRAY› Data_area(Totalsize),› search_person(13)››PROC ReadItem(BYTE num)››;************************************›;* This procedure prints item #num *›;* to the screen *›;************************************›› BYTE POINTER ptr›› ptr = Data_area + (num * Datasize)› PrintF("Name: %S",ptr+Firstname)› PrintF(" %S%E",ptr+Lastname)› PrintF("Address: %S%E",ptr+Address)› PrintF("City, State: %S%E",ptr+City_state)› PrintF("Zipcode: %S%E",ptr+Zipcode)› PrintF("(P) %S%E",ptr+Phone)››RETURN›››PROC WriteItem(BYTE num)››;************************************›;* This procedure writes data into *›;* item #num from the keyboard *›;************************************›› BYTE POINTER ptr› › ptr = Data_area + (num * Datasize)› Print(" Last name: ")› InputS(ptr+Lastname)› Print(" First name: ")› InputS(ptr+Firstname)› Print(" Address: ")› InputS(ptr+Address)› Print(" City, State: ")› InputS(ptr+City_state)› Print(" Zipcode: ")› InputS(ptr+Zipcode)› Print(" Phone: ")› InputS(ptr+Phone)› ›RETURN››BYTE FUNC Getkey()››;************************************›;* This function returns the ATASCII*›;* value of the key pressed *›;************************************›› BYTE key› › Close(1)› Open(1,"K:",4,0)› key=GetD(1)› Close(1)››RETURN(key)›››PROC Skip(BYTE lines)›;************************************›;* This procedure places "lines" *›;* EOLNs on the display for better *›;* better screen formatting *›;************************************››› BYTE counter›› FOR counter=1 TO lines› DO› PutE()› OD›RETURN›››BYTE FUNC look()››;************************************›;*Here we get a last name and if *›;*the person is in the list, we *›;*return their number. Return a 0 *›;*otherwise. *›;************************************›› BYTE num,› found,› key,› rval› BYTE POINTER ptr ›› Cls› num=0› found=0› Skip(5)› Print("Last name? ")› InputS(search_person)› DO› num==+1› ptr = Data_area + (num * Datasize)› IF Scompare(ptr+Lastname,search_person)=0 THEN› PrintE("Is the person:")› Skip(2)› Print(" ")› PrintE(ptr+Firstname)› Print(" ")› PrintE(ptr+Lastname)› Skip(2)› Print("(Y/N) ")› key=Getkey()› IF (key='Y) OR (key='y) THEN› found=1› EXIT› ELSE› PrintE("No")› PutE()› FI› FI› UNTIL num=NumPeople› OD› IF found=1 THEN› rval=num› ELSE› rval=0› FI›RETURN(rval)›››PROC Change()››;************************************›;* Procedure to change any of the *›;* data for any person in the list. *›;* Requires the catch-all global *›;* variable called Choice *›;************************************››› BYTE num,› key› BYTE POINTER ptr ››› DO› num=look()› IF num THEN › DO› DO› Cls › ReadItem(num)› PutE() › PrintE("Press to change")› Skip(2)› PrintE(" 1 = Last name")› PrintE(" 2 = First name(s)")› PrintE(" 3 = Street address")› PrintE(" 4 = City / State")› PrintE(" 5 = Zipcode")› PrintE(" 6 = Phone number")› PrintE(" 7 = No change")› Skip(5)› Print("Your choice: ")› Choice=InputB()› UNTIL (Choice>0) AND (Choice<8)› OD› ptr = Data_area + (num * Datasize)› IF Choice=1 THEN› Print("Last name was: ")› PrintE(ptr+Lastname)› Skip(2)› PrintE("What is the new last name?")› InputS(ptr+Lastname)› ELSEIF Choice=2 THEN› Print("First name was: ")› PrintE(ptr+Firstname)› Skip(2)› PrintE("What is the new first name?")› InputS(ptr+Firstname)› ELSEIF Choice=3 THEN› Print("Address was: ")› PrintE(ptr+Address)› Skip(2)› PrintE("What is the new address?")› InputS(ptr+Address)› ELSEIF Choice=4 THEN› Print("City / State was: ")› PrintE(ptr+City_state)› Skip(2)› PrintE("What is the new city / state?")› InputS(ptr+City_state)› ELSEIF Choice=5 THEN› Print("Zipcode was: ")› PrintE(ptr+Zipcode)› Skip(2)› PrintE("What is the new zipcode?")› InputS(ptr+Zipcode)› ELSEIF Choice=6 THEN› Print("Phone number was: ")› PrintE(ptr+Phone)› Skip(2)› PrintE("What is the new phone number?")› InputS(ptr+Phone)› FI› Skip(2)› PrintE("Are there more changes for")› PrintF("%S %S ?",ptr+Firstname,ptr+Lastname)› PutE()› Print("(Y/N) ")› key=Getkey()› UNTIL (key='n) OR (key='N)› OD› PrintE("No")› FI› PutE()› PrintE("Change data for other names?")› PrintE("(Y/N) ")› key=Getkey()› UNTIL (key='n) OR (key='N)› OD› ›RETURN››PROC View()››;************************************›;* This procedure allows the user to*›;* see the whole list 2 people at a *›;* time. The user can also exit to *›;* the main menu at any time. *›;************************************››› BYTE counter=[0],› two_counter=[0],› tempkey, › flag››› Cls› flag=0› FOR counter=1 TO NumPeople STEP 2› DO›› two_counter=0› DO› ReadItem(counter+two_counter)› Skip(3)› two_counter==+1› UNTIL (two_counter=2) OR (counter+two_counter > NumPeople)› OD› PrintE(" *Press ÒÅÔÕÒÎ to continue*")› PrintE(" *Ò for Main Index*")› Skip(3)› tempkey=Getkey()›› IF (tempkey='R) OR (tempkey='r) THEN› flag=1› EXIT› FI›› OD›› IF flag=0 THEN › PrintE(" *End of File*")› PrintE(" * Press ÒÅÔÕÒÎ to continue*")› tempkey=Getkey()› FI››RETURN› ››;Here is the first time we reassign›;the default device. What does that›;mean? Everytime you compile your›;Action! programs, Action! declares›;a few variable for you. You saw that›;the EOF array was one of them.››;Here's another one. BYTE device ›;When you do a Print or any other›;print type command (PrintBE, PrintF›; etc.), the output goes to your›;screen. If you Open() a file and›;assign device to that channel, all›;the output will go there instead of›;the screen. Example:›;›; Open(3,"D:FILE",8,0)›; device=3›; ›;All Print routines will print to›;that file. You should save the›;value of device before you reassign›;it. That way, you can put it back›;to normal. That is what happens in›;the Search() routine below and in›;PrintL() later on.›››PROC Search()››;************************************›;* This procedure searches the list *›;* for a matching last name. If the *›;* correct person is not found, the *›;* search continues until found or *›;* out of data. *›;************************************›› BYTE num,› key,› holddev› BYTE POINTER ptr › CARD temperr›› Cls›› DO› num=look()› IF num THEN› Cls › ReadItem(num)› Skip(4)›› PrintE("Do you want to print this")› PrintE("out on your printer?")› PutE()› Print("(y/n) ")› key=Getkey()› IF (key='Y) OR (key='y) THEN› PrintE("Yes")› holddev=device ;save the normal› Close(1)› Open(1,"P:",8,0)› device=1 ;reassign output to the printer› ReadItem(num)› Skip(2)› Close(1)› device=holddev ;put everything back to normal› ELSE› PrintE("No")› FI›› ELSE› Skip(3)› Print(" The ")› Print(search_person)› PrintE(" you are looking for")› PrintE(" is not in this file.")› FI›› Skip(3)› PrintE("Search more names?")› Print("(Y/N) ")› key=Getkey()› IF (key='y) OR (key='Y) THEN› PrintE("Yes")› FI› UNTIL (key='n) OR (key='N)› OD››RETURN›››PROC Add()››;************************************›;* This procedure adds people to the*›;* end of the list. *›;************************************››› BYTE key› BYTE POINTER ptr›› DO› Cls› Skip(2)› Print("Enter data: ")› NumPeople==+1› PrintBE(NumPeople)› WriteItem(NumPeople)››;************************************›;* Verify the entry *›;************************************›› Cls› Print("Entry #")› PrintBE(NumPeople)› Skip(3)› ReadItem(NumPeople)› Skip(5)› PrintE("Add more names?")› Print("(Y/N) ")› key=Getkey()› UNTIL (key='n) OR (key='N) OR (NumPeople=Max)› OD››RETURN››PROC Delete()››;************************************›;* This procedure finds a person in *›;* the list and deletes him. It then*›;* move all persons after the *›;* deleted one physically forward in*›;* the list. The speed of Action! *›;* really shines in this PROC. *›;************************************›› BYTE num,› key,› counter› BYTE POINTER ptr,› ptr2›› Cls› DO› num=look()› IF num THEN› FOR counter=num TO NumPeople› DO› ptr = Data_area + (counter * Datasize)› ptr2 = Data_area + ((counter+1) * Datasize)› Scopy(ptr+Lastname,ptr2+Lastname)› Scopy(ptr+Firstname,ptr2+Firstname)› Scopy(ptr+Address,ptr2+Address)› Scopy(ptr+City_state,ptr2+City_state)› Scopy(ptr+Zipcode,ptr2+Zipcode)› Scopy(ptr+Phone,ptr2+Phone)› OD› NumPeople==-1› ELSE› Skip(3)› Print(" The ")› Print(search_person)› PrintE(" you are looking for")› PrintE(" is not in this file.")› FI› Skip(3)› PrintE("More deletions?")› Print("(Y/N) ")› key=Getkey()› IF (key='y) OR (key='Y) THEN› PrintE("Yes")› FI› UNTIL (key='n) OR (key='N)› OD››RETURN››PROC Switch(BYTE x,i)››;************************************›;* Procedure to switch all the *›;* elements of person x with person *›;* i. *›;************************************››› BYTE ARRAY n(40)› BYTE POINTER ptr,› ptr2››› ptr = Data_area + (x * Datasize)› ptr2 = Data_area + (i * Datasize)› SCopy(n,ptr+Lastname)› SCopy(ptr+Lastname,ptr2+Lastname)› SCopy(ptr2+Lastname,n)› SCopy(n,ptr+Firstname)› SCopy(ptr+Firstname,ptr2+Firstname)› SCopy(ptr2+Firstname,n)› SCopy(n,ptr+Address)› SCopy(ptr+Address,ptr2+Address)› SCopy(ptr2+Address,n)› SCopy(n,ptr+City_state)› SCopy(ptr+City_state,ptr2+City_state)› SCopy(ptr2+City_state,n)› SCopy(n,ptr+Zipcode)› SCopy(ptr+Zipcode,ptr2+Zipcode)› SCopy(ptr2+Zipcode,n)› SCopy(n,ptr+Phone)› SCopy(ptr+Phone,ptr2+Phone)› SCopy(ptr2+Phone,n)››RETURN››PROC Alphabetize()››;************************************›;* It was too hard to figure out *›;* what was going on in the alpha- *›;* betize routine in the original. *›;* When I originally translated *›;* the TI version into BASIC XL, *›;* I used the same algorithm. *›;* But to translate it into struc- *›;* tured code was hopeless! *›;* So, I used a Selection Sort *›;* instead. I realize that a *›;* selection sort isn't exactly the *›;* fastest sort method available but*›;* it gets the job done. *›;* Don't worry if you don't *›;* understand this PROC, I got it *›;* out of a book. After you get a *›;* better handle on Action! you will*›;* be able to figure it out. *›;************************************›› BYTE first,› current,› least›› BYTE POINTER ptr,› ptr2›› Cls› Skip(5)› PrintE(" Please wait...")› PrintE(" The list is begin arranged")›› FOR first=1 TO (NumPeople-1)› DO› least=first› FOR current=(first+1) TO NumPeople› DO› ptr = Data_area + (current * Datasize)› ptr2 = Data_area + (least * Datasize)› IF (SCompare(ptr+Lastname,ptr2+Lastname)<0) OR › ((SCompare(ptr+Firstname,ptr2+Lastname)=0) AND› (SCompare(ptr+Firstname,ptr2+Firstname)<0)) THEN› least=current› Switch(least,first)› FI› OD› OD››RETURN››PROC Save()››;************************************›;* This procedure saves the data to *›;* the filename entered. For disk *›;* users the D: or D2: must be *›;* entered. *›;* *›;* The first thing in the data file *›;* is the number of people in the *›;* list. This is just a BYTE. *›;* The comes the actual data about *›;* each person. *›;************************************››› BYTE ARRAY filename(15)› BYTE POINTER ptr› BYTE num››› Cls› PrintE("What is the name of your")› PrintE("storage device?")› Skip(2)› PrintE("Example:")› PrintE(" C:")› PrintE(" or")› PrintE(" D:FILE.DAT ")› PutE() › PrintE("Disk user, be sure to")› PrintE("include the D: or D2: ")› Skip(2)› Print("Filename: ")› InputS(filename)› IF filename(0)>0 THEN ;* check to see if filename is empty› Close(1)› Open(1,filename,8,0)› PrintBDE(1,NumPeople)› FOR num=1 to NumPeople› DO› ptr = Data_area + (num * Datasize)› PrintDE(1,ptr+Lastname)› PrintDE(1,ptr+Firstname)› PrintDE(1,ptr+Address)› PrintDE(1,ptr+City_state)› PrintDE(1,ptr+Zipcode)› PrintDE(1,ptr+Phone)› OD› Close(1)› FI› ›RETURN›››PROC Load()››;************************************›;* This procedure loads the data *›;* from the filename entered. For *›;* disk users the D: or D2: must be *›;* entered. *›;************************************›› BYTE ARRAY filename(15)› BYTE POINTER ptr› BYTE num,› key›› › Cls› PrintE("What is the name of your")› PrintE("storage device?")› Skip(2)› PrintE("Example:")› PrintE(" C:")› PrintE(" or")› PrintE(" D:FILE.DAT ")› PutE() › PrintE("Disk user, be sure to")› PrintE("include the D: or D2: ")› Skip(2)› Print("Filename: ")› InputS(filename)› IF filename(0)>0 THEN ;* check to see if filename is empty› Close(1)› Open(1,filename,4,0)› NumPeople=InputBD(1)› FOR num=1 TO NumPeople› DO› ptr = Data_area + (num * Datasize)› InputSD(1,ptr+Lastname)› InputSD(1,ptr+Firstname)› InputSD(1,ptr+Address)› InputSD(1,ptr+City_state)› InputSD(1,ptr+Zipcode)› InputSD(1,ptr+Phone)› OD› Close(1)› Cls› PrintF(" %S%E",filename)› Skip(2)› Print("This file has ")› PrintB(NumPeople)› PrintE(" entries.")› Skip(2)› Print(" * ")› PrintB(Max)› PrintE(" entries maximum * ")› Skip(12)› Print(" Press ÒÅÔÕÒÎ to continue")› key=Getkey()› FI› ›RETURN›››PROC PrintL()› ›;************************************›;* This procedure dumps the all the *›;* data to the printer. *›;************************************››› BYTE num,› holddev,› key› CARD temperr››› holddev=device ;save the normal output device› Close(1)› Open(1,"P:",8,0)› Cls› Skip(11)› PrintE(" Please wait...")› PrintE(" while printer is working")› device=1› FOR num=1 TO NumPeople› DO› ReadItem(num)› Skip(2)› OD› Close(1)› device=holddev ;put the output back the way it was› Skip(3)› Print(" Press ÒÅÔÕÒÎ to continue")› key=Getkey()››RETURN››››PROC Main()›› BYTE POINTER fgnd,› bgnd›› fgnd=709› bgnd=710› NumPeople=0› Graphics(0)› bgnd^=0 ;Turn background to black› fgnd^=12 ;And characters to white› Zero(Data_area,Totalsize) ;Clear out the data area›› PrintE(" * ATARI Phone book *")› PutE()› PrintE(" by")› PutE()› PrintE(" Thomas M. Johnson")› PutE()› PrintE(" Available from")› PutE()› PrintE("Villa Video's Bargain Cellar")› PrintE(" (414) 265-5149")› PrintE(" ExpressNet Node X11")› Skip(11)› Print(" Press ÒÅÔÕÒÎ to begin")› Choice=Getkey()› DO› DO› Cls› PrintE(" Main Index")› Skip(4)› PrintE("Press To")› Skip(3)› PrintE(" 1 = View names list")› PrintE(" 2 = Search for a name")› PrintE(" 3 = Add a name")› PrintE(" 4 = Change a name")› PrintE(" 5 = Delete a name")› PrintE(" 6 = Alphabetize the list")› PrintE(" 7 = Save the data file")› PrintE(" 8 = Load the data file")› PrintE(" 9 = Print the list")› PrintE(" 10 = Finish the session")› Skip(4)› Print("Your choice: ")› Choice=InputB()› UNTIL (Choice>0) AND (Choice<11)› OD› IF Choice=1 THEN› View()› ELSEIF Choice=2 THEN› Search()› ELSEIF Choice=3 THEN› Add()› ELSEIF Choice=4 THEN› Change()› ELSEIF Choice=5 THEN› Delete()› ELSEIF Choice=6 THEN› Alphabetize()› ELSEIF Choice=7 THEN› Save()› ELSEIF Choice=8 THEN› Load()› ELSEIF Choice=9 THEN› PrintL()› ELSEIF Choice=10 THEN› Cls› Skip(3)› PrintE("Are you sure you want to")› PrintE("end this session?")› Print("(Y/N) ")› Choice=Getkey()› IF (Choice='Y) OR (Choice='y) THEN› PrintE("Yes")› Skip(5)› PrintE("Have a nice day!")› FI› FI› UNTIL (Choice='Y) OR (Choice='y)› OD›RETURN››