--------------------------------------------------------- - - - Steps to make your Pascal procedure/function into a - - .REL file so it may be included into a library of - - commonly used routines. - --------------------------------------------------------- 1. Write your function/procedure and test it in a complete program. When you are happy with your function then write up a dummy Pascal program. It will look something like this: Program dummy; type new : (xxx,yyy); var str8 : STRING 8; (*$I+ [include Pascal prgm stmts] *) FUNCTION DOESITALL; begin ...main body of function end(*---of does it all---*); (*---dummy program---*) begin end. 2. -Notice the compiler option - $I+ This is a must so you can see where the assembly source program starts and ends. -You may include types and variables in the program heading to get your function/procedure to compile but notice that there is NO main program. 3 Compile the program with the Pascal compiler producing DOESITALL.SRC. 4. Edit DOESITALL.SRC to include the following: a. The name of the routine: NAME DOESITALL b. The entry name for the linker: ENTRY DOESITALL c. The entry name as a label for the assembler: DOESITALL: 5. All together it will look somwthing like this: ;FUNCTION DOESITALL; <---all Pascal source statements ; will be included as comments ; in your source program. NAME DOESITALL <---These are the 3 statements ENTRY DOESITALL that you added DOESITALL: ENTR D,2,0 <---this is the first line of the source program ---the rest of the source program continues here--- ;end(*---of does it all---*); <---this is the last line of EXIT D,0 your function and this is the last line of the assembly source. -------------------------------- Anything after the EXIT statement is to be deleted. 6. You are now ready to assemble the source program and make a .REL file. ASMBL MACRO,DOESITALL/REL -This will produce DOESITALL.REL 7. DOESITALL.REL is now ready to be included in your library: LINK /L:B:ALLOFIT B:DOESITALL /E -This will create a library named ALLOFIT.REL 8. We now write a program that calls DOESITALL. It is not until link time that there is any need for the routine at all. LINK /N:B:SUPERWRITER B:SUPERWRITER A:ALLOFIT/S /E -Did you get all of that? a. We opened a .COM file on drive B: named SUPERWRITER.COM b. We opened a .REL file on drive B: named SUPERWRITER.REL c. We will search a library file named ALLOFIT.REL on drive A: d. And then exit to the CP/M operating system, searching a file named LIB.REL to resolve any unresolved symbols. <> 9. Following is a Pascal program called RANDOM.PAS. that has been compiled and converted into a .REL file. Look it over and see if you can do it also. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ (*$I+ [include Pascal prgm stmts] *) PROGRAM RANDOM; VAR SEED1, SEED2 : INTEGER; (* ============================================== PROGRAM TITLE: RANDOM_NUMB_GENERATOR WRITTEN BY: Raymond E. Penley DATE WRITTEN: SEP 1979 WRITTEN FOR: Use with PASCAL/Z SUMMARY: Implement a Fibonacci series Random number generator. RANDOM will return numbers from 0 to 32767 Call RANDOM with the following convention: Range Use 0 - 32 RANDOM DIV 1000 0 - 327 RANDOM DIV 100 0 - 32767 RANDOM ** Add these lines to your PASCAL source program: VAR SEED1, SEED2 : INTEGER; PROCEDURE SEEDRAND; EXTERNAL; FUNCTION RANDOM: INTEGER; EXTERNAL; Also within the body of the main program but BEFORE calling RANDOM: SEEDRAND; ============================================== *) PROCEDURE SEEDRAND; (* INITIAL VALUES FOR SEED1 AND SEED2 ARE HERE *) (* NAME RANDOM <<< these statements were included ENTRY SEEDRAND,RANDOM <<< by me to make it easy to edit <<< the source code. SEEDRAND: <<< the LABEL goes directly in front *) <<< of the first BEGIN stmt Begin SEED1 := 10946; SEED2 := 17711 END; FUNCTION RANDOM : INTEGER; (* GLOBAL SEED1, SEED2 : INTEGER *) CONST HALFINT = 16383; (* 1/2 OF MAXINT *) VAR temp1, temp2, HALF_ADDER : INTEGER; (* RANDOM: <<< the LABEL goes directly in *) <<< front of the first BEGIN stmt Begin (* Take 1/2 of the seeds for the comparison test *) temp1 := SEED1 DIV 2; temp2 := SEED2 DIV 2; IF (temp1+temp2) >= HALFINT THEN (* the number is too big - scale it down *) HALF_ADDER := temp1 + temp2 - HALFINT ELSE HALF_ADDER := temp1 + temp2; SEED1 := SEED2; (* Restore from previous DIVision *) SEED2 := HALF_ADDER * 2; RANDOM := SEED2 END(*---RANDOM---*); (*-----------DUMMY PROGRAM--------------*) (* THIS MUST BE REMOVED VIA YOUR EDITOR *) BEGIN END. +++++++++++++++++++++++++++++++++++++++++++++++++++++++ The assembler source code follows There has been some editing of the code to remove unwanted labels and program statements. +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ============================================== ; PROGRAM TITLE: RANDOM_NUMB_GENERATOR ; ; WRITTEN BY: Raymond E. Penley ; DATE WRITTEN: SEP 1979 ; ; WRITTEN FOR: Use with PASCAL/Z ; ; SUMMARY: ; Implement a Fibonacci series Random number generator. ; RANDOM will return numbers from 0 to 32767 ; Call RANDOM with the following convention: ; Range Use ; 0 - 32 RANDOM DIV 1000 ; 0 - 327 RANDOM DIV 100 ; 0 - 32767 RANDOM ; ; Add these lines to your PASCAL source program: ; ; VAR SEED1, SEED2 : INTEGER; ; ; PROCEDURE SEEDRAND; EXTERNAL; ; FUNCTION RANDOM: INTEGER; EXTERNAL; ; ; ; Also within the body of the main program ; but BEFORE calling RANDOM: ; ; SEEDRAND; ; ;============================================== ; NAME RANDOM ; ENTRY SEEDRAND,RANDOM ; ;PROCEDURE SEEDRAND; ; INITIAL VALUES OF SEED1 AND SEED2 ARE HERE ; SEEDRAND: ENTR D,2,0 ; SEED1 := 10946; MVI 0(IY),42 MVI -1(IY),194 ; SEED2 := 17711 MVI -2(IY),69 MVI -3(IY),47 ; END; EXIT D,0 ; ; ; ; FUNCTION RANDOM : INTEGER; ; GLOBAL ; SEED1, SEED2 : INTEGER ; CONST ; HALFINT = 16383; (* 1/2 OF MAXINT *) ; VAR ; temp1, temp2, HALF_ADDER : INTEGER; ; RANDOM: ENTR D,2,6 ; (* Take 1/2 of the seeds for the comparison test *) ; temp1 := SEED1 DIV 2; MOV L,-1(IY) MOV H,0(IY) LXI D,2 DIVD D,0 MOV -2(IX),H MOV -3(IX),L ; temp2 := SEED2 DIV 2; MOV L,-3(IY) MOV H,-2(IY) LXI D,2 DIVD D,0 MOV -4(IX),H MOV -5(IX),L ; IF (temp1+temp2) >= HALFINT THEN MOV L,-3(IX) MOV H,-2(IX) MOV E,-5(IX) MOV D,-4(IX) DADD D,0 LXI D,16383 GE D,0 ; (* the number is too big - scale it down *) ; HALF_ADDER := temp1 + temp2 - HALFINT JNC L171 MOV L,-3(IX) MOV H,-2(IX) MOV E,-5(IX) MOV D,-4(IX) DADD D,0 ; ELSE LXI D,-16383 DADD D,0 MOV 0(IX),H MOV -1(IX),L ; HALF_ADDER := temp1 + temp2; JMP L191 L171 MOV L,-3(IX) MOV H,-2(IX) MOV E,-5(IX) MOV D,-4(IX) DADD D,0 MOV 0(IX),H MOV -1(IX),L L191 ; SEED1 := SEED2; MOV L,-3(IY) MOV H,-2(IY) MOV 0(IY),H MOV -1(IY),L ; (* Restore from previous DIVision *) ; SEED2 := HALF_ADDER * 2; MOV L,-1(IX) MOV H,0(IX) DADD C MOV -2(IY),H MOV -3(IY),L ; RANDOM := SEED2 MOV L,-3(IY) MOV H,-2(IY) MOV 3(IX),H MOV 2(IX),L ; END(*---RANDOM---*); EXIT D,0 +++++++++++++++++++++++++++++++++++++++++++++++++++++ .