Others have already pointed out what CIS stands for and what the
instructions are. SIMH is a good source for describing the
instructions, but also the later PDP-11 Processor Handbooks have
complete chapters devoted to explaining the instructions. For
example, my 1979-80 04/34a/44/60/70 handbook (a spare that I keep at
work) has Chapter 12 devoted entirely to CIS.
A couple of other ideas:
Seems to me that the VAX string and decimal instructions are direct
descendents of the CIS set. I never asked anyone at the time as it
seemed obvious. But maybe I should ask the former DEC-types. Is
this true?
One of the most used string instructions on VAX was MOVC3/MOVC5. [At
least in my opinion, in my own code, and in most of the OS code.]
Later versions of RSTS (starting around 9.0) used CIS in the OS, if
it was available. Perhaps Paul Koning could comment on what it was
used for. [Do we have any other former RSTS developers on list?]
While COBOL was the primary user of CIS, it wasn't limited to COBOL
programmers, of course. I don't remember if there are options in
F-77 or BP2+ to use CIS if available, but it wouldn't surprise me if
there were. Of course a Macro programmer could access the
instructions.
One of the things I actually did on the VAX but never got around to
back-porting to CIS on an -11 was to use the string and decimal
instructions to implement sprintf() internals. There were some neat
tricks one could do converting decimal to ASCII. For example, here
is my ltoa() routine:
.title ltoa - integer to ascii conversions
.ident /31-Oct-1984/
.enable debug
.dsabl global
;
; *** Edit History ***
;
; 27-Jun-1984 Original creation and testing. Only `d'
; implemented.
;
; 28-Jun-1984 Octal, hex and unsigned added. Decimal re-written.
;
; 20-Jul-1984 Re-write of the dispatch mechanism.
; Common exit path which copies out the string and
; makes it asciz.
;
; 30-Jul-1984 Add binary.
; Use mulp instead of movp and addp in unsigned.
;
; 31-Jul-1984 Grab more stack space. Binary conversion needs it.
; Reduce code for non-decimal conversions.
;
; 01-Aug-1984 Minor change to binary code.
;
; 10-Aug-1984 Enable debugging in the source module.
; Use the `packed' directive instead of compiling
; packed values by hand.
;
; 10-Sep-1984 Use the same dispatch method as jd_format().
; Use movc3 instead of movc5 in all_common.
;
; 19-Oct-1984 Reverse change of 30-Jul-1984. According to the internal
; VAX Performance Summary, the movp/addp4 combination will
; be faster (on all machines) than the mulp instruction.
; Make sure that the `forms' and `action' tables have the
; same number of entries in them.
;
; 31-Oct-1984 Change movc5 to use a better source mode.
;
.psect jd_ro_data, noexe, pic, shr, rd, nowrt
packed_one:
.packed 1
;packed_two:
; .packed 2
dec_pattern:
eo$float 9
eo$end_float
eo$move 1
eo$end
upper_hex:
.ascii /0123456789ABCDEF/
lower_hex:
.ascii /0123456789abcdef/
forms:
.ascii /duoxXb/ ; format types that we handle
form_len = . - forms
action:
.address signed ; %d - regular decimal
.address unsigned ; %u - unsigned decimal
.address octal ; %o - octal
.address hex_low ; %x - hexadecimal lower case
.address hex_comm ; %X - hexadecimal upper case
.address binary ; %b - binary
act_len = . - action
assume <act_len / 4> eq form_len ; tables must have same
number of entries
;
; function void jd_ltoa (buffer, radix, value)
; char *buffer, radix;
; int value;
;
.psect jd_ro_code, pic, shr, rd, nowrt
.entry jd_ltoa, ^m<r2, r3, r4, r5, r6, r7>
movab -40(sp), sp ; get some local space
movc5 #0, (sp), #0, #40, (sp) ; pre-zero it
locc 8(ap), #form_len, forms ; find the radix character
beql 10$ ; not found, exit
movab upper_hex, r4 ; set this up if needed
subl3 r0, #form_len, r0 ; create offset
movl action[r0], r0 ; get action routine address
jmp (r0) ; dispatch
10$:
clrb @4(ap) ; asciz string
ret ; ...
signed:
cvtlp 12(ap), #10, -20(fp) ; convert long to packed
dec_common:
editpc #10, -20(fp), dec_pattern, (sp) ; edit the string
skpc #^a/ /, #10, (sp) ; skip leading blanks
all_common:
incl r0 ; plus the one we're on
movc3 r0, (r1), @4(ap) ; move out the string
clrb (r3) ; make it asciz
ret ; ...
unsigned:
extzv #1, #31, 12(ap), r0 ; get all but the lowest bit
cvtlp r0, #10, (sp) ; convert long to packed
movp #10, (sp), -20(fp) ; replicate the result
addp4 #10, (sp), #10, -20(fp) ; * 2
; mulp #1, packed_two, #10, (sp), #10, -20(fp) ; *2
blbc 12(ap), dec_common ; was the low bit set originally?
addp4 #1, packed_one, #10, -20(fp) ; add a one into it
brb dec_common ; to common code
octal:
movzbl #30, r2 ; initial position
movzbl #3, r3 ; field width
movzbl #10, r7 ; number of significant digits
brb oct_comm
hex_low:
movab lower_hex, r4 ; table to use
hex_comm:
movzbl #28, r2 ; initial position
movzbl #4, r3 ; field width
movzbl #7, r7 ; number of significant digits
oct_comm:
mnegl r3, r5 ; increment
movl 12(ap), r6 ; get the value
movab (sp), r0 ; get the addr of temp buffer
10$:
extzv r2, r3, r6, r1 ; extract a digit of right size
movb (r4)[r1], (r0)+ ; move a byte
acbl #0, r5, r2, 10$ ; continue 'till done
skpc #^a/0/, r7, (sp) ; skip leading 0's
brb all_common ; use common code
binary:
movzbl #31, r2 ; initial position
movzbl #1, r3 ; field width
movl r2, r7 ; number of significant digits
brb oct_comm ; use common code
.end
Might be a fun exercise to try converting this to Macro-11 with CIS.
John