CPL (Centurion Programming Language) - Nakazoto/CenturionComputer GitHub Wiki

CPL

CPL, or Centurion Programming Language, is the preferred method of programming on the Centurion. Unlike BASIC, CPL gets compiled down to machine code and an executable file is created that will run as fast as it can. CPL works very well for business oriented applications, similar to other languages like COBOL. For more information on CPL, refer to the CPU6 Programmer's Manual.

CPL executable programs are only half of the story though. The executable programs are often called from JCL Script Files, which are written in ASCII files and run directly from within the Operating System.

Hellorld! Example

The following is an example CPL program that prints "Hellorld!" on the screen.

TITLE 'HELLORLD! IN CPL ON A CENTURION'
SYSTEM ZHELLORLD (MAIN,EXP=D)
FILE CRT:SYSIPT,CLASS=0,SEQ
DEFINE M00:'HELLORLD!'
FORMAT F00:C132
ENTRYPOINT CRT
ENTRY
OPEN IO CRT
WRITE (CRT,F00)M00
STOP 0
END

Compiling

To actually compile this program, it must first be typed up in an ASCII file. Follow the steps below to create the ASCII file, edit it, and then compile and execute the program. These steps are written with the Operating System loaded onto the fixed disk (1) and the default disk set to 1.

  1. .NEW ZHELLO ON 1 'A' 1S
    • Can be skipped if using KOMPOZ as it will create the file for you
    • File name must have "Z" at the beginning
  2. .NEW @SCRE0 ON 1 'E' 1T
    • Only needs to be done if file doesn't already exist
  3. S.KOMPOZ
    • KOMPOZ is a single line editor that can be used to write code into ZHELLO
  4. P.CPL HELLO 1 CRT0 X
  5. .RUN XHELLO

Project Euler Question 01

The following is the code for a fancy version of answering Project Euler question #1 with comments explaining the majority of lines. This program was typed into the real hardware on the episode about programming in CPL. You can watch the full episode here.

TITLE 'PROJECT EULER IN CPL ON A CENTURION'
SYSTEM ZPE01 (MAIN,EXP=D,LL=80)    ; Main=Not Subroutine, EXP=CPU5/6 Compatability (no comp), LL=Line Length
FILE CRT:SYSIPT,CLASS=0,SEQ    ; File control block, maps to CRT class and sequential use
FORMAT FLIN:C80    ; Set a format for printing: 80 characters (full line)
FORMAT FANS:N9    ; Set a format for printing: 9 numbers (up to 999,999,999)
SET CNT:0    ; Set and declare a variable
SET OPA:0    ; CNT=Count, OPA=Outer Planets Alliance
SET ANS:0    ; ANS= ANSWER, PRO=Progress
SET PRO:0
STRING WAT(1)    ; Declare a string of 1 character in length
ENTRYPOINT CRT    ; Defines symbols that need to be used by other libs.
ENTRY    ; Indicates the start of actual code
OPEN IO CRT    ; Open CRT file declared up top for I/O
WRITE(CRT,FLIN)EJECT    ; Eject the page (clear the screen)
WRITE(CRT,FLIN)'PROBLEM 1: MULTIPLES OF 3 OR 5'
WRITE(CRT,FLIN)'IF WE LIST ALL THE NATURAL NUMBERS BELOW 10 THAT ARE MULTIPLES OF 3 OR 5,'
WRITE(CRT,FLIN)'WE GET 3, 5, 6 AND 9. THE SUM OF THESE MULTIPLES IS 23.'
WRITE(CRT,FLIN)'FIND THE SUM OF ALL THE MULTIPLES OF 3 OR 5 BELOW 1000.'
WRITE(CRT,FLIN)''
LOOP WHILE (CNT.LE.999)    ; Main program loop. Loops while CNT is less than 1000
  OPA=MOD(CNT,3)    ; OPA is set to the remainder of CNT/3
  IF(OPA.EQ.0)DO    ; If that remainder is 0, then add 3 to running total
    ANS=ANS+CNT
  END DO    ; Must have END DO here, even if we're doing ELSE DO next
  ELSE DO    ; We use an ELSE so we don't double up additions for 3 AND 5
    OPA=MOD(CNT,5)
    IF(OPA.EQ.0)ANS=ANS+CNT
  END DO
  OPA=MOD(CNT,10)    ; Every 10 numbers we want to update the status display
  IF(OPA.EQ.0)DO
    IF(PRO.EQ.0)'WAT'="'|'"    ; String assignments are weird
    IF(PRO.EQ.1)'WAT'="'/'"    ; Variable from variable: 'STR1'='STR2'
    IF(PRO.EQ.2)'WAT'="'-'"    ; Variable from literal: 'STR1'="'literal'"
    IF(PRO.EQ.3)'WAT'="'\'"    ; Variable from mixed: 'STR1'="'literal'+STR2"
    CURS(CRT,1,WAT)    ; Moves the cursor back one position, prints the string
    IF(PRO.LE.2)INCR PRO    ; Increment the progress counter
    ELSE PRO=0    ; Reset the progress counter when too high
  END DO
  INCR CNT    ; Increment main counter
END LOOP
WRITE(CRT,FLIN)''
WRITEN(CRT,FLIN)'THE ANSWER IS:'    ; Write to the screen without hitting a newline
WRITE(CRT,FANS)ANS
CLOSE CRT    ; Closes that CRT file
STOP 0    ; Return control to OS with completion code 0
END

After compiling and running the above program, this is the result:

CPL Command Quick Reference List

Program Control

COMMAND arguments Notes
SYSTEM [name] [(parameters)] Marks beginning of a CPL program or subprogram.
ENTRY Indicates master program starting point.
STOP [code] Terminates CPL program and indicates a return to JCL.
END Marks the end of a CPL program.

Compiler Directives

COMMAND arguments Notes
TITLE 'title' Prints a title at the top of each page of program listing during compiling.
DIRECT Tells compiler that subsequent commands will be in assembly language.
CPL Tells compiler that subsequent commands will be in CPL language.
PRINT OFF Tells compiler to print nothing during compilation.
PRINT OFF [,COM] Tells compiler to allow printing of CPL statements only.
PRINT ON Tells compiler to display generated assembler statement.
EJECT Tells compiler to issue a top-of-form command to the device that is being output to.
PAGE EJECT Tells compiler to issue a top-of-form command to the device that is being output to.
SPACE n Tells the compiler to insert blank lines in program listing.
COPY label [SYSn] Allows specific portions of code to be joined into an external source program.
; Semicolon functions as the comment character.
- Hyphen functions as the line continuation character.
\ Reverse slash allows multiple statements on the same source code line.

Program Linkage

COMMAND arguments Notes
EXTERNAL label [,label, label, ...] Notifies compiler that labels are defined outside the program.
ENTRYPOINT label [,label, label, ...] Notifies compiler that labels are defined inside the program.

Reserving Memory

COMMAND arguments Notes
INTEGER label [,label, label, ...] Declares 4- or 6-byte integer variable.
SET label : n [,label:n, label:n, ...] Declares and assigns initial value for a 4- or 6-byte integer variable.
STRING label (n) (,label (n), label (n), ...) of a specified length.
DEFINE label:'string'[,label:'string', ...] Declares and assigns initial value for a character string.
BUFFER label (n) [, label (n), label (n), ...] Declares a temp. holding area during I/O.
TABLE name (n) [,name (n), name (n), ...] Declares an integer table.
TABLE name (n) [,name (len,n), name (len,n), ...] Declares a string table.

Assignment Statements

COMMAND arguments Notes
DECR integer [,n] Decreases the value of a specified integer.
DECREMENT integer [,n] Decreases the value of a specified integer.
INCR integer [,n] Increases the value of a specified integer.
INCREMENT integer [,n] Increases the value of a specified integer.
= Inserts the value of an expression into a variable.
Math Performed left to right, can handle parenthesis.
@REM CPU6 only - where remainder of last division is saved.

Functions

COMMAND arguments Notes
ABS (arg) Evaluates the expression and returns the absolute value.
LEN (arg) Returns the true length of the data contained in a string.
MAX (arg1, arg2, ...) Returns the highest value in a set.
MIN (arg1, arg2, ...) Returns the lowest value in a set.
MOD (arg1, arg2) Returns the remainder after a division in integer math.
ROUND (arg1, arg2) Eliminates the designated number of decimal places.
SGN (arg) Used to determine the sign of the expression/literal.

Transfer of Control

COMMAND arguments Notes
GO TO (label, label, ...) ON expression Specifies a label to which control will be conditionally transferred.
GO TO label Specifies a label to which control will be transferred.
LOOP j (a, b, c) Permits multiple executions of a group of statements.
LOOP WHILE (value operator value) Conditionally permits multiple executions of a group of statements.
END LOOP Terminates the body of the LOOP or LOOP WHILE command.
CALL subroutine [(name, name, ...)]
SUBROUTINE label Sets the beginning of a subroutine.
RETURN Returns control to the statement following the CALL statement.
RETURN TO label Returns control to the statement following the CALL statement.
RETRIEVE (type, location [,location, ...]) Retrieve parameters out of the CALL argument list.
IF (value operator value) action Will perform a function if a specified comparison is true.
IF (value operator value) DO / actions / END DO Optional form of IF.
IF (value operator value) DO / actions / END DO / ELSE action Optional form of IF.
IF (value operator value) DO / actions / END DO / ELSE DO / actions / END DO Optional form of IF.
IF (value operator value) DO / actions / END DO / ELSE Optional form of IF.
IF (value operator value) action / ELSE action Optional form of IF.
IF (value operator value) action / ELSE DO / actions / END DO Optional form of IF.
IF (value operator value) action / ELSE Optional form of IF.
IF (value) action Optional form of IF. Equivalent to IF(x.NE.0)
IFSTRING (string operator string) action Will perform a function if a specified comparison is true.
IFSTRING (string operator string) DO / actions / END DO Optional form of IFSTRING.
IFSTRING (string operator string) DO / actions / END DO / ELSE action Optional form of IFSTRING.
IFSTRING (string operator string) DO / actions / END DO / actions / END DO Optional form of IFSTRING.
IFSTRING (string operator string) DO / actions / END DO / ELSE Optional form of IFSTRING.
IFSTRING (string operator string) action / ELSE action Optional form of IFSTRING.
IFSTRING (string operator string) action / ELSE DO / actions / END DO Optional form of IFSTRING.
IFSTRING (string operator string) action / ELSE Optional form of IFSTRING.
END DO Terminates any of the above IF or IFSTRING statements.
Label: Program labels allow control to be transferred between various portions of the program.

File Destination and Control

COMMAND arguments Notes
FILE file: SYSccc, [access], [CLASS=n], [BUFFER=n, buffer], [RECSIZ=n], [KEY=integer], [FILTYP=c], [LST=routine] Refer to CPU6 Programmer's Manual for detail.
OPEN access file / or / OPEN access (file, ...) [,access (file, ...) ,...] Allows a CPL program to access a file.
CLOSE file [,file, file, ...] Prohibits further access to a file within a CPL program.
ENDFILE file [,file, file, ...] Writes end-of-file marker for a specified sequential file.
REWIND file [,file, file, ...] Allows first record of a sequential file to be accessed.
SETFORM (file [,n] [,HOLD] [,FREE]) CPU6 only - Allows form number, HOLD/FREE status of job going to spooler to be modified.
SKIP (file,n) Advances the tape by the number of records specified.
RESET file [,file,file,...] Rewind tape to beginning of current file.

Formatted Input/Output

COMMAND arguments Notes
FORMAT format: specification, specification, ... Determines format data will take when converted by READ, WRITE, WRITEN, REWRITE, ENCODE, DECODE.
READ (file, format) variable, variable, ... Transfers ASCII Data from dev./file to one/multiple integers or strings.
WRITE (file, format) variable, variable, ... Transfers ASCII data to console dev./file.
WRITEN (file, format) variable, variable, ... Transfers ASCII data to console dev. without including carriage return.
WRITN (file, format) variable, variable, ... Transfers ASCII data to console dev. without including carriage return.
DECODE (string, format) variable, variable, ... Transfers string data to one/multiple strings/integers to translate ASCII numerics into binary.
ENCODE (string, format) variable, variable, ... Transfers data in one/multiple strings/integers or arithmetic function to single character string.
NOTE (file, integer) Allows a location of a specified record to be stored in an integer. Use with POINT.
POINT (file, integer) Used to locate a specified record within a sequential file. Use with NOTE.
REWRITE Allows a record in a type A file to be updated in place.

Binary Input/Output

COMMAND arguments Notes
RECORD record (n) Used to reserve a binary record. RECORD indicates beginning address.
ENDREC Used to reserve a binary record. RECORD indicates ending address.
READB (file, record) Byte-for-byte transfer from a dev./file to a record area in memory.
WRITEB (file, record) Byte-for-byte transfer from a record area in memory to a dev./file.
HOLD (file) Sets a flag in a shared, discrete-sector type C file.
FREE (file) Turns off the flag set by HOLD.

Spanned Sector Input/Output

COMMAND arguments Notes
GETK Sets key integer of file to the relative key for the specified argument.
NEWK Creates a new index record for a specified argument by reserving space in the data area of the file.
DELK Sets prime data pointer in index record to zero.
NEXK CPU6 only - Searches forward in key area for next valid key.
CALL GETR (file, record) Subroutine used to transfer type C spanned record file to record area in memory.
CALL PUTR (file, record) Subroutine used to transfer record from record area in memory to type C spanned record file.
CALL HLDR (file) Subroutine used to notify program attempting to hold a record that record is already held.
CALL FRER (file) Subroutine that cancels the hold.

Miscellaneous Commands

COMMAND arguments Notes
CURB (file, number) Cursor Blank. Blanks a specified number of characters beginning with current location.
CURP (file, column, line) Cursor Position. Determines point of at which next I/O character will be displayed.
CURS (file, number, string) Cursor Substitute. Allows a program to display a character other than blank.
CURSOR (file, line, column) Specifies where a CRT cursor is to be placed.
DUMP (address1, address2) Displays the hexadecimal value of a register, the stack or a location of memory.
LOAD (mask, label, option) [(name, name, ...)] Allows one program to load another during execution.
ORIGIN address Used to change the location counter during compilation.
EQUATE label, expression Used to assign a label to a specific location.
GTIME (INTEGER, integer) Allows CPL to access the system time and store it in an integer.
GTIME (STRING, string) Allows CPL to access the system time and store it in a string.
LDATE (form) [,label] Used to load a date into the A register.
SDATE (form, label) Date loaded into A register by LDATE can then be stored as integer or string.
TBLGET table (integer) Transfers an entry from a string table to the work area assigned to that table.
TBLPUT table (integer) [:'string'] or [:value] Transfers contents of work area to specified position in table.
ADRLST (address, address, ...) Allows a list of addresses to be coded.