Previous Up Next The following program accepts a line of input (terminated by Carriage Return) from the terminal and outputs that line with the characters reversed.
TITLE REVERSE
A=1 ;Symbolic AC names are defined
P=17
CHTTYO==1 ;Channel for output
CHTTYI==2 ;Channel for input
PDLLEN==100 ;Length of push down stack
PDL: BLOCK PDLLEN ;Storage for push down stack
BEG: MOVE P,[-PDLLEN,,PDL-1] ;Initialize stack pointer.
;Open TTY channels.
.CALL [SETZ ? SIXBIT/OPEN/
[.UAI,,CHTTYI] ? [SIXBIT/TTY/] ((SETZ))]
.LOSE %LSFIL
.CALL [SETZ ? SIXBIT/OPEN/
[.UAO,,CHTTYO] ? [SIXBIT/TTY/] ((SETZ))]
.LOSE %LSFIL
LOOP: .IOT CHTTYO,["*] ;Prompt for input.
PUSHJ P,REVERS ;do the work, once.
.IOT CHTTYO,[^M] ;Output CRLF to go to new line.
.IOT CHTTYO,[^J]
JRST LOOP ;Jump back to repeat.
REVERS: .IOT CHTTYI,A ;Read a character.
CAIN A,^M ;If it is a Carriage Return, the line is ended,
POPJ P, ;so return.
PUSH P,A ;Else save this character on the stack,
PUSHJ P,REVERS ;call REVERS recursively,
POP P,A ;get our character back
.IOT CHTTYO,A ;and print it.
POPJ P, ;Return.
END BEG
From then on, calling is done with PUSHJ and returning with POPJ. PUSH is used to save data on the stack, and POP to get it back.
It is reasonable to omit the address field of an instruction if it is unused (as it is in a POPJ). An omitted field assembles as zero, but you should never omit a field which is supposed to contain a zero which actually stands for something. For example, instructions which refer to AC zero should always have a zero (or better, a symbolic name) where the AC is referred to.