;****************************************************************************
;*****                           ASMTST                                 *****
;*****                                                                  *****
;*****	Program written by: Ryan-McFarland              Date: 84.03.28  *****
;*****	Description: Sample program to illustrate machine language     *****
;*****               linkage  to RM/COBOL.                             *****
;*****               The Runtime would be configured to automatically   *****
;*****               load this module at startup.  The Runtime would    *****
;*****               also be configured to call the program INITIAL     *****
;*****               before the RM/COBOL program begins execution.      *****
;*****                    INITIAL will copy the passed command          *****
;*****               line arguments to a local data space, and its work *****
;*****               is finished.  The RM/COBOL program, LNKTST, will   *****
;*****               later call ASMTST and have the saved               *****
;*****               command line arguments returned to the program     *****
;*****	             LNKTST.                                            *****
;*****      Parameters passed to ASMTST:                                *****
;*****            Register BX points to an argument list                *****
;*****            that has the structure:                               *****
;*****         ES:BX ->     DW  Byte count of argments following = 4    *****
;*****                      DW  OFFSET STRING-VALUE                     *****
;*****                      DW  OFFSET STRING-LENGTH                     *****
;*****            These two variables are in the calling RM/COBOL       *****
;*****            program.  These offsets are relative to the           *****
;*****            segment register ES.                                  *****
;*****                                                                  *****
;*****      ASMTST  will move the string from its local space here to   *****
;*****              the RM/COBOL variable STRING-VALUE, and the length  *****
;*****              of this string to STRING-LENGTH.                     *****
;*****              A return value is returned in register AL           *****
;*****              Zero if all OK, non-zero in case of error.          *****
;****************************************************************************
    NAME     ASMTST
CODE  SEGMENT  BYTE
     ASSUME CS:CODE, DS:CODE, ES:CODE
SPACE      EQU     020H        ;Value of blank
     ORG    100H               ;This program is using an 8080 memory model
                               ;It has only one segment
    DW      ENDCODE            ;Length of module.
    DB      7                  ;Length of 'INITIAL'
    DB      'INITIAL'          ;Program name
    DW      INITIAL            ;Entry point
    DB      6                  ;Length of 'ASMTST'
    DB      'ASMTST'           ;Program name
    DW      ASMTST             ;Entry point
    DB      0                  ;End of table
;      Local data area
;
STRING      RB       20        ;20 bytes to save command line arguments.
LNGTH       RB        2        ;A word for length of above string.
ASMTST  PROC  FAR              ;Must be a far procedure for RET to be correct
                               ;Register BX points to a byte count
    MOV     CL,ES:[BX]         ;We are interested in only the low order byte
    CMP     CL,4               ;Byte count is 4 for 2 arguments
    JNZ     FAILURE            ;Argument count is not 2
                               ;Following the byte count is an argument list
    MOV     DI,ES:[BX+2]        ;DI points to COBOL variable 'STRING-VALUE'
    MOV     SI,OFFSET STRING   ;String here is the source.
    MOV     CX,WORD PTR LNGTH          ;And the length thereof.
HERE
    MOV     AL,[SI]            ;Source
    MOV     ES:[DI],AL         ;Destination
    INC     SI
    INC     DI
    LOOP    HERE               ;Move string from here to COBOL
                               ;address of 'STRING-LENGTH'.
    MOV     DI,ES:[BX+4]       ;DX points to COBOL variable
                               ;  'STRING-LENGTH' 
    MOV     AX,WORD PTR LNGTH          ;Transfer through AX
    XCHG    AH,AL              ;COMP-1 variables are in straight 
                               ;byte order
    MOV     ES:[DI],AX         ;Transfer string length to COBOL.
    XOR     AX,AX              ;Clear AX for return code.
    RET                        ;Return far.
FAILURE
    OR      AX,2               ;Return non-zero error code.
    RET                        ;And return far.
ASMTST  ENDP
;
;                INITIAL is executed once at startup time.
;                        it simply moves a string to local space.
;
;                Enters with SI pointing to a character string
;                        and AL the length of that string.
;
;

INITIAL   PROC   FAR           ;Must be a far procedure to make RET be right
    MOV     BYTE PTR LNGTH,AL          ;Length of the string
    MOV     BYTE PTR LNGTH+1,00        ;High order byte is zero
    MOV     DI,OFFSET STRING   ;String should be set to
    MOV     AL,SPACE           ; blanks.
    MOV     CX,20              ;Length of string
BLANKS
    MOV     [DI],AL            ;Blank fill
    INC     DI
    LOOP    BLANKS
    MOV     CX,WORD PTR LNGTH  ;Make sure that the string length
    CMP     CX,20              ;is <= 20.
    JNC     LNGTHOK
    MOV     CX,20              ;Force to 20 bytes
LNGTHOK
    MOV     WORD PTR LNGTH,CX  ;Update if length was forced
    MOV     DI,OFFSET STRING   ;Reset DI to start of string
LOOP1
    MOV     AL,ES:[SI]         ;SI points to command line characters
    MOV     [DI],AL            ;DI points to local string
    INC     SI
    INC     DI                 ;Move the string to our local variable space
    LOOP    LOOP1
    XOR     AL,AL              ;AL=0 for all ok signal, no abnormal
                               ;exit
    RET                        ;Return far
INITIAL  ENDP
ENDCODE
CODE   ENDS
    END
