JRT Pascal User's Guide version 3.0 NOT FOR SALE -120- 10. Assembler The JRT Pascal system provides two methods of preparing external procedures and functions written in assembly language. A special purpose assembler is provided which generates modules in the correct format. The second method may be used if a Microsoft format assembler is available, such as RMAC or MACRO-80. The CONVERTM utility converts the '.REL' files produced by these two assemblers into '.INT' format files which may be accessed as external procedures (see section 10.7 of this manual). The JRT assembler translates 8080 assembly language into JRT relocatable format modules. These modules can be called from a Pascal program as if they were Pascal external procedures. Parameters may be passed to them and function return values may be received. The JRT assembler is compatible with the standard ASM.COM program distributed with CP/M. Input files must have a file type of '.ASM'. The assembler output is a file of type '.INT', which may be linked with the main program or automatically loaded at run-time. 10.1 Entry codes After an external procedure is loaded into main storage, EXEC transfers control to it. A five byte code (95,6,0,92,0) is placed at the start of the procedure to inform EXEC that this is an assembler procedure rather than Pascal. The procedure must end with a return (RET) instruction. Any registers EXCEPT the 8080 stack pointer may be modified. Example of entry codes: ;procedure entry db 95,6,0,92,0 ;required entry codes ; ;send a message to console mvi c,9 ;print buffer code lxi d,msg ;address of message call 5 ;bdos entry point ; ret ;end of procedure ; msg db 'JRTASM sample procedure' db 0dh,0ah,'$' ;carriage return/line feed ; end Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -121- If this procedure were named SAMPLE.ASM then the declaration in the Pascal program referencing it would be: PROCEDURE SAMPLE; EXTERN; 10.2 Operating JRTASM To assemble an external procedure, enter: EXEC JRTASM You will be prompted at the console for the input filename and options. The options are: 1 - produce a listing on the console during pass 1 of the assembly process, useful for debugging. C - produce an output file of type '.COM' rather than '.INT'. This is not an external procedure but a directly executable command file in standard CP/M format. An ORG 100H directive should be included since the default origin is 0. 10.3 Directives These assembler directives are supported: directive purpose --------- --------- ORG set location counter, not used in external procedures SET assign a value to a variable EQU assign a value to a fixed symbol IF/ELSE/ENDIF conditional assembly of code, may be nested to 16 levels DB define byte, multiple operands DW define word DS define storage READ used to assign a new value to a variable, like SET except that value is obtained from console WRITE display strings or expressions on console Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -122- Examples of directives: 1. a set 9 if a = 9 write 'a is equal to nine' else write 'a is not equal to nine' endif 2. x read ;msg at console will ask for x write 'x squared is ',(x * x) 3. a set a + 1 ;increment a db 'string',a,255 Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -123- 10.4 Expressions Integer expressions can be used in assembler instructions. Expressions are either fixed or relocatable. A symbol is relocatable if it refers to an address, otherwise it is fixed. If any symbol in an expression is relocatable then the entire expression is relocatable. Parenthesis may be nested to any level. These operators are supported: * / + - NOT AND OR XOR MOD HIGH LOW EQ NE LT LE GT GE Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -124- 10.5 Parameters and function return values Parameters of any data type may be passed to assembler external procedures and functions. The EXEC maintains a data stack which contains all static variables, parameters, function return values and procedure linkage blocks. Three address pointers are used to access the data stack. These are available to external procedures in the 8080 register pairs on entry to the procedure. BASE (HL) - address of the data stack CUR (DE) - address of the linkage block for currently active procedure TOS (BC) - top of stack, points past last allocated byte I I I I TOS-->I I I-----------------I I I I 6 bytes I linkage block for I I current procedure CUR-->I I I-----------------I I 2 bytes I parameter length fld I-----------------I I I I x bytes I parameters of I I current procedure I I I-----------------I I I I I I I I I global variables I I of main program I-----------------I I I I 6 bytes I linkage block for I I main program I I BASE-->I-----------------I Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -125- With the three data stack pointers, the parameters passed to the procedure can be accessed. If it is a function, the return value can be stored. Also, the global variables of the main program can be accessed. For example, if the first global variable declared in the main Pascal program which calls the external procedure is an integer named INT1, then just add 6 to the BASE pointer to get the address of INT1. The BASE pointer is in register pair HL on entry to the procedure. Data stack after procedure call DEMO( 'A',7 ); 'A' 7 length linkage block 41 0700 0300 xx xx xx xx xx xx yy I I CUR TOS The two byte integer fields are in 8080 byte-reverse format. The parameter length field is equal to three. The linkage block is six bytes of unspecified data Parameters are accessed by decrementing the CUR pointer. Pascal value parameters are actually present in the data stack. For reference parameters, the address of the variable is present in the data stack. If the procedure has no parameters, the parameter length field is zero. Function return values must be stored just before the function's first parameter in the data stack. Data stack after function call X := TEST( 3,8 ); (The return value is of the type integer) 3 8 length linkage block rrrr 0300 0800 0400 xx xx xx xx xx xx yy I I I return value CUR TOS If the return value is of type CHAR, a string, or a structured variable (entire array, entire record) then there is a two byte length field between the return value and the first parameter. This field is set by EXEC and MUST NOT be modified. If the return value is a dynamic string, the current length field is a two byte field at the beginning of the string. This must be set to the desired length of the field. Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -126- Data stack after function call NAME := LOOKUP( 'X',1); (The return value is of type ARRAY [1..4] OF CHAR;) return value rv len 'X' 1 length linkage block rr rr rr rr 0400 58 0100 0300 xx xx xx xx xx xx yy I I CUR TOS 10.6 Debugging assembler procedures One effective way to debug external procedures written in assembler uses the CP/M Dynamic Debugging Tool (DDT). If a user is running a Pascal program under DDT, then a RST 7 instruction will be seen as a breakpoint and allow the user to access all the DDT facilities. To run under DDT, enter: DDT EXEC.COM Iprogram_name G100 When the RST 7 instruction is encountered, DDT will gain control. The display, modify, disassemble facilities then can be used to examine the procedure data areas. To resume execution, use the XP command to set the instruction address ahead by 1, to get past the RST 7 instruction. Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -127- 10.7 Convertm program The Convertm program translates Microsoft format '.REL' files into JRT format '.INT' files. Only '.REL' files may be input - '.HEX' files do not contain information about relocation addresses. To run the Convertm program, enter: EXEC CONVERTM The program will inquire at the console for the name of the module to be translated. A file type of '.REL' is assumed. The output module '.INT' file is placed on the same disk. 10.8 Sample assembly programs Three sample assembly programs are included here. Two external procedures (setbit, resetbit) and one external function (testbit) can be called from any Pascal program or external function. These small modules provide fast and simple bit manipulation facilities. They also illustrate the passing and returning of parameters for assembly language external procedures. Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -128- Listing of setbit.asm: ;setbit.asm ;external procedure which sets a bit on in a byte ; ; procedure setbit ( var x : char; bit : integer ); ; extern; ; bit# in range 0..7 ; ;entry code db 95,6,0 ;int vmcode db 92 ;lpn vmcode db 0 ;mode vmcode ;on entry bc=wtos de=wb hl=wbase ; ;get bit# in b_reg, addr(x) in hl, x into c_reg setbit xchg ;hl=wb dcx h! dcx h! dcx h! dcx h mov b,m ;bit# dcx h! mov d,m! dcx h! mov e,m ;addr(x) xchg ;hl=addr(x) mov c,m ;c=x ;create mask inr b ;incr loop count mvi a,1 loop rrc dcr b jnz loop ;a=mask c=byte ora c mov m,a ;store byte ret ; end Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -129- Listing of resetbit.asm ;resetbit.asm ;external procedure which reset bit in a byte ; ; procedure resetbit ( var x : char; bit : integer ); ; extern; ; bit# in range 0..7 ; ;entry code db 95,6,0 ;int vmcode db 92 ;lpn vmcode db 0 ;mode vmcode ;on entry bc=wtos de=wb hl=wbase ; ;get bit# in b_reg, addr(x) in hl, x into c_reg resetbit xchg ;hl=wb dcx h! dcx h! dcx h! dcx h mov b,m ;bit# dcx h! mov d,m! dcx h! mov e,m ;addr(x) xchg ;hl=addr(x) mov c,m ;c=x ;create mask inr b ;incr loop count mvi a,0feh loop rrc dcr b jnz loop ;a=mask c=byte ana c mov m,a ;store byte ret ; end Copy compliments of Merle Schnick SECTION 10: Assembler JRT Pascal User's Guide version 3.0 NOT FOR SALE -130- Listing of testbit.asm ;testbit.asm ;external function which returns bit value of a byte ; ; function testbit ( x : char; bit : integer ): ; boolean; extern; ; ; bit number is in range 0..7 ; ;entry code db 95,6,0 ;int vmcode db 92 ;lpn vmcode db 0 ;mode vmcode ;on entry bc=wtos de=wb hl=wbase ; ;get bit# into b_reg and x into a_reg testbit xchg ;hl=wb dcx h! dcx h! dcx h! dcx h ;point to bit lownib mov b,m ;low byte of bit dcx h! mov a,m ;x inr b ;shift loop loop rlc dcr b jnz loop jc true ;bit is set ;false : bit is zero dcx h! mvi m,0! dcx h! mvi m,0 ret ;true : bit is one true dcx h! mvi m,0! dcx h! mvi m,1 ret ; end Copy compliments of Merle Schnick SECTION 10: Assembler  ret ;true : bit is one true dcx h! mvi m,0! dcx h! mvi m,1 ret ; end