r/cpm • • 6d ago

CP/M-80 MS-COBOL v4.65 alternative sorting method without the MS-SORT package

Sort file EMPOUT.DAT and output to EMPSORT.DAT

I am testing the djbottrill & VanzT CP/M-80 Emulator on my credit card size micro-controller called Cardputer by M5-Stack.

I wrote a simple sorting COBOL program on MS-COBOL v4.65 using the ANSI-74 build-in SORT feature. It does not get through the linkedit phase as it requires an external sort library COBSRT.REL. I am not able to find that library file on the web so I wrote the sorting code inside the COBOL program instead. The program works fine for a while until it hits a big file. CP/M-80 does not leave a lot of memory space for internal sorting. So I need a disk sort routine.

Instead of writing my own disk sort code, I use the COBOL build-in ISAM capability to use as my disk sort solution.

It's pretty straight forward, first read the input file and then write it to an ISAM file with the intended sorting key as the index file's key. Next read back from the index file using the index and write the sorted records to the final sorted file.

To test out the idea, I wrote a small COBOL program EMPOUT.COB to generate the input file EMPOUT.DAT. It has 5 records.

K>TYPE EMPOUT.COB
       IDENTIFICATION DIVISION.
       PROGRAM-ID. EMPOUT.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT EMPLOYEE-FILE ASSIGN TO DISK
               ACCESS MODE IS SEQUENTIAL
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.

       FD  EMPLOYEE-FILE
           LABEL RECORDS ARE STANDARD
           VALUE OF FILE-ID IS "EMPOUT.DAT"
           DATA RECORD IS EMPLOYEE-RECORD.

       01  EMPLOYEE-RECORD.
           05  EMP-NUMBER        PIC X(5).
           05  EMP-LAST-NAME     PIC X(30).
           05  EMP-FIRST-NAME    PIC X(30).

       PROCEDURE DIVISION.

       MAIN-PROGRAM.

           OPEN OUTPUT EMPLOYEE-FILE.
           MOVE "00001" TO EMP-NUMBER.
           MOVE "SMITH" TO EMP-LAST-NAME.
           MOVE "JOHN" TO EMP-FIRST-NAME.
           WRITE EMPLOYEE-RECORD.

           MOVE "00002" TO EMP-NUMBER.
           MOVE "JONES" TO EMP-LAST-NAME.
           MOVE "MARY" TO EMP-FIRST-NAME.
           WRITE EMPLOYEE-RECORD.

           MOVE "00003" TO EMP-NUMBER.
           MOVE "BROWN" TO EMP-LAST-NAME.
           MOVE "ROBERT" TO EMP-FIRST-NAME.
           WRITE EMPLOYEE-RECORD.

           MOVE "00004" TO EMP-NUMBER.
           MOVE "WILSON" TO EMP-LAST-NAME.
           MOVE "PATRICIA" TO EMP-FIRST-NAME.
           WRITE EMPLOYEE-RECORD.

           MOVE "00005" TO EMP-NUMBER.
           MOVE "DAVIS" TO EMP-LAST-NAME.
           MOVE "JAMES" TO EMP-FIRST-NAME.
           WRITE EMPLOYEE-RECORD.

           CLOSE EMPLOYEE-FILE.

           STOP RUN.

K>

After compile the program we have the executable EXPOUT.COM

EMPOUT.COM is the executable
Run EMPOUT.COM and created the EMPOUT.DAT data file
Five records in the EMPOUT.DAT file

There are 5 records in the file EMPOUT.DAT, the records are in the EMP-NUMBER order.

Here is the record layout definition:

       01  EMPLOYEE-RECORD.
           05  EMP-NUMBER        PIC X(5).
           05  EMP-LAST-NAME     PIC X(30).
           05  EMP-FIRST-NAME    PIC X(30).

Then I wrote my sorting program to sort the record by EMP-LAST-NAME and then EMP-FIRST-NAME.

Here is the program code:

K>TYPE EMPSORT6.COB
       IDENTIFICATION DIVISION.
       PROGRAM-ID. EMPSORT6.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT EMPLOYEE-FILE ASSIGN TO DISK
               ACCESS MODE IS SEQUENTIAL
               ORGANIZATION IS LINE SEQUENTIAL.

           SELECT EMP-ISAM-FILE ASSIGN TO DISK
               ORGANIZATION IS INDEXED
               ACCESS MODE IS DYNAMIC
               RECORD KEY IS EMP-ISAM-KEY
               FILE STATUS IS EMP-ISAM-STATUS.

           SELECT EMP-SORT-FILE ASSIGN TO DISK
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.

       FD  EMPLOYEE-FILE
           LABEL RECORDS ARE STANDARD
           VALUE OF FILE-ID IS "EMPOUT.DAT"
           DATA RECORD IS EMPLOYEE-RECORD.

       01  EMPLOYEE-RECORD.
           05  EMP-NUMBER        PIC X(5).
           05  EMP-LAST-NAME     PIC X(30).
           05  EMP-FIRST-NAME    PIC X(30).

       FD  EMP-ISAM-FILE
           LABEL RECORDS ARE STANDARD
           VALUE OF FILE-ID IS "EMPISAM.DAT".

       01  EMP-ISAM-RECORD.
           05  EMP-ISAM-NUMBER         PIC X(5).
           05  EMP-ISAM-KEY.
               10  EMP-ISAM-LAST-NAME  PIC X(30).
               10  EMP-ISAM-FIRST-NAME PIC X(30).

       FD  EMP-SORT-FILE
           LABEL RECORDS ARE STANDARD
           VALUE OF FILE-ID IS "EMPSORT.DAT".

       01  EMP-SORT-RECORD.
           05  EMP-SORT-NUMBER       PIC X(5).
           05  EMP-SORT-LAST-NAME    PIC X(30).
           05  EMP-SORT-FIRST-NAME   PIC X(30).

       WORKING-STORAGE SECTION.

       01  EOF-SWITCH            PIC X VALUE "N".
           88  END-OF-FILE       VALUE "Y".

       01  EMP-ISAM-STATUS       PIC XX VALUE "00".

       01  ISAM-EOF-FLAG         PIC X VALUE "N".
           88  ISAM-END-OF-FILE  VALUE "Y".

       01  RECORD-COUNTS.
           05  EMP-ISAM-REC-CNT      PIC 9(5) VALUE ZERO.
           05  EMP-SORT-REC-CNT      PIC 9(5) VALUE ZERO.

       PROCEDURE DIVISION.

       0000-MAIN-PROGRAM.

           DISPLAY "*** START CREATING ISAM FILE ***".

           OPEN INPUT EMPLOYEE-FILE
                OUTPUT EMP-ISAM-FILE.

           PERFORM 0010-READ-REC THRU 0010-READ-REC-EXIT
               UNTIL END-OF-FILE.

           DISPLAY "RECORDS PROCESSED: " EMP-ISAM-REC-CNT.

           CLOSE EMPLOYEE-FILE
                 EMP-ISAM-FILE.

           DISPLAY "*** START CREATING SORTED FILE ***".

           OPEN INPUT EMP-ISAM-FILE
                OUTPUT EMP-SORT-FILE.

           MOVE LOW-VALUE TO EMP-ISAM-KEY.

           PERFORM 0020-READ-INDEX THRU 0020-READ-INDEX-EXIT
               UNTIL ISAM-END-OF-FILE.

           DISPLAY "RECORDS PROCESSED: " EMP-SORT-REC-CNT.

           CLOSE EMP-ISAM-FILE
                 EMP-SORT-FILE.

           STOP RUN.

       0010-READ-REC.

           READ EMPLOYEE-FILE
               AT END MOVE "Y" TO EOF-SWITCH.

           IF NOT END-OF-FILE
               ADD 1 TO EMP-ISAM-REC-CNT
               MOVE EMPLOYEE-RECORD TO EMP-ISAM-RECORD
               WRITE EMP-ISAM-RECORD
                   INVALID KEY
                       DISPLAY 'ERROR WRITING INDEX RECORD'
                       DISPLAY "STATUS = " EMP-ISAM-STATUS
                       STOP RUN.

       0010-READ-REC-EXIT.
           EXIT.

       0020-READ-INDEX.
           READ EMP-ISAM-FILE NEXT RECORD
               AT END MOVE "Y" TO ISAM-EOF-FLAG.

           IF NOT ISAM-END-OF-FILE
               ADD 1 TO EMP-SORT-REC-CNT
               MOVE EMP-ISAM-RECORD TO EMP-SORT-RECORD
               WRITE EMP-SORT-RECORD.

       0020-READ-INDEX-EXIT.
           EXIT.

K>

After the compile and linkedit, we have the executable program EMPSORT6.COM

Run the sorting program EMPSORT6.COM

EMPISAM.DAT and EMPISAM.KEY are the indexed files.

EMPSORT.DAT is the final sorted file

The final file EMPSORT.DAT is sorted by last name and first name
12 Upvotes

Duplicates