Trailing-Edge
-
PDP-10 Archives
-
decuslib20-06
-
decus/20-153/pd.mac
There are 9 other files named pd.mac in the archive. Click here to see a list.
TITLE PD FOR LIBOL V10 AND RPGLIB V1
SUBTTL CONVERT BINARY TO DISPLAY 15-DEC-74 /ACK
;COPYRIGHT 1974, 1975, DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL MODIFICATIONS FOR RPGII COPYRIGHT 1976, BOB CURRIER AND CERRITOS COLLEGE
;REVISION HISTORY:
;V10 *****
; 15-DEC-74 /ACK CREATION.
; 5/15/75 /DBT BIS
;*****
SEARCH RPGPRM ;DEFINE PARAMETERS.
%%LBLP==:%%LBLP
EBCMP.==:EBCMP.
BIS==:BIS
EXTERN EASTB. ;FORCE EASTBL TO BE LOADED.
HISEG
COMMENT \
THIS ROUTINE CONVERTS A ONE OR TWO WORD BINARY NUMBER TO A
DISPLAY ITEM.
CALL:
MOVE 16,[Z AC,PARAMETER ADDRESS]
PUSHJ 17,PD6./PD7./PD9.
PARAMETERS:
THE ACCUMULATOR FIELD OF AC 16 CONTAINS THE AC WHICH CONTAINS THE
FIRST WORD OF THE NUMBER TO BE CONVERTED. THE SECOND WORD, IF IT EXISTS,
IS IN THE FOLLOWING AC.
THE RIGHT HALF OF AC 16 POINTS TO A WORD IN THE FOLLOWING
FORMAT:
BITS 0-5 BYTE RESIDUE FOR OUTPUT FIELD.
BIT 6 1 IF THE FIELD IS SIGNED.
BITS 7-17 SIZE OF THE OUTPUT FIELD.
BITS 18-35 ADDRESS OF THE FIRST CHARACTER OF THE OUTPUT FIELD.
RETURNS:
CALL+1 ALWAYS.
REGISTERS USED:
T1, CPTR, IPTR (CALLED OPTR), SW, CNT, T2, MASK, JAC, SAV10
\
EXTERN SET1. ;ROUTINE TO PICK UP THE PARAMETERS.
EXTERN PACFL. ;POINTER TO THE NUMBER OF THE AC INTO
; WHICH WE ARE TO PLACE THE RESULT.
ENTRY PD6. ;IF THE INPUT IS SIXBIT.
ENTRY PD7. ;IF THE INPUT IS ASCII.
ENTRY PD9. ;IF THE INPUT IS EBCDIC.
IFE BIS,<
;LOCAL AC DEFINITIONS:
OPTR==IPTR
CPTR==PARM
SAV10==TAC5
MASK==TAC4
T1==TAC2
T2==TAC3
PD6.: JSP T2, PD ;ENTER HERE IF THE OUTPUT IS SIXBIT,
PD7.: JSP T2, PD ; HERE IF IT IN ASCII AND
IFN EBCMP.,<
PD9.: JSP T2, PD ; HERE IF IT IS IN EBCDIC.
>
PD: MOVEM CH, .SVCH## ;save CH
MOVE CH, T2 ;GET INTO PROPER AC FOR SET1.
SUBI CH, PD6.-5 ;FIND OUT WHAT THE INPUT LOOKS LIKE.
JSP JAC, SET1. ;GO SET UP THE PARAMETERS.
MOVE CH, .SVCH ;restore AC5
LDB T2, PACFL. ;FIND OUT WHERE THE INPUT
; OPERAND IS.
HRRZ MASK, NCVTMS-6(SW) ;SELECT THE APPROPRIATE MASK.
MOVE CPTR, SDDPTR-6(SW) ;SELECT THE APPROPRIATE POINTER
; FOR THE SIGN CHAR.
MOVE T1, (T2) ;PICK UP THE FIRST WORD OF THE OPERAND.
CAILE CNT, ^D10 ;ONE OR TWO WORDS?
JRST PD4 ;TWO WORD OPERAND.
;HERE WE CONVERT A SINGLE PRECISION BINARY NUMBER TO DISPLAY.
JUMPGE T1, PD1 ;IS IT NEGATIVE?
ADDI CPTR, ^D10 ;YES, USE NEGATIVE SIGNS.
MOVMS T1 ;MAKE IT POSITIVE.
PD1: JRST PD6 ;IF WE HAVE TO WORRY ABOUT SIGNS,
; GO DO SO.
;CONVERSION ROUTINE:
PD2: IDIV T1, DECTAB(CNT) ;LEFT TRUNCATE IF THE OPERAND
; IS TOO BIG.
PD3: MOVE T1, T1+1 ;GET THE REMAINING DIGITS.
PD3A: IDIV T1, DECTAB-1(CNT) ;GET THE NEXT DIGIT.
IORI T1, (MASK) ;CONVERT IT.
IDPB T1, OPTR ;STASH IT.
SOJG CNT, PD3 ;LOOP IF THERE ARE MORE DIGITS.
POPJ PP, ;OTHERWISE RETURN.
;COME HERE TO CONVERT A DOUBLE PRECISION BINARY NUMBER TO DISPLAY.
PD4: MOVE T2, 1(T2) ;PICK UP THE SECOND WORD OF THE
; OPERAND.
JUMPGE T1, PD5 ;IS IT NEGATIVE?
ADDI CPTR, ^D10 ;YES, USE NEGATIVE SIGNS.
SETCA T1, T1 ;NEGATE THE HIGH ORDER WORD.
MOVNS T2 ;NEGATE THE LOW ORDER WORD.
TLZ T2, (1B0) ;CLEAR THE SIGN BIT OF THE LOW ORDER WORD.
SKIPN T2 ;IF THE LOW ORDER WORD IS ZERO.
ADDI T1, 1 ;BUMP THE HIGH ORDER WORD.
PD5: DIV T1, DEC10 ;BREAK OFF THE LAST TEN DIGITS.
MOVE SAV10, T2 ;SAVE THEM.
MOVEI CNT, -^D10(CNT) ;REDUCE THE COUNT BY 10.
PUSHJ PP, PD2 ;CONVERT THE FIRST N DIGITS.
MOVE T1, SAV10 ;GET BACK THE LAST TEN DIGITS.
MOVEI CNT, ^D10 ;SET UP CNT.
;COME HERE IF WE HAVE TO WORRY ABOUT SIGNS.
PD6: PUSHJ PP, PD2 ;CONVERT THE REMAINING N DIGITS.
ANDI T1, 17 ;RESTORE THE NUMBER.
LDB T1, CPTR ;PICK UP THE APPROPRIATE SIGNED DIGIT.
DPB T1, IPTR ;STASH IT.
POPJ PP, ;AND RETURN.
SUBTTL TABLES.
;MASKS TO MAKE A BINARY DIGIT INTO A DISPLAY DIGIT.
NCVTMS: EXP 20 ;SIXBIT.
EXP 60 ;ASCII.
IFN EBCMP.,<
EXP 360 ;EBCDIC.
>
> ;END OF NON-BIS
DC.TB1::
DECTAB::
DEC 1
DEC 10
DEC 100
DEC 1000
DEC 10000
DEC 100000
DEC 1000000
DEC 10000000
DEC 100000000
DEC 1000000000
DEC10: DEC 10000000000
DC.TB2::
OCT 2 ;11
OCT 351035564000
OCT 35 ;12
OCT 032451210000
OCT 443 ;13
OCT 011634520000
OCT 5536 ;14
OCT 142036440000
OCT 70657 ;15
OCT 324461500000
OCT 1070336 ;16
OCT 115760200000
OCT 13064257 ;17
OCT 013542400000
OCT 157013326 ;18
OCT 164731000000
;TABLE OF SIGNED DISPLAY DIGITS:
IFE BIS,<
DEFINE SDD(A, B, C, D)< BYTE (6)B(7)C(8)D>
>
IFN BIS,<
; PRODUCE TRANSLATION TABLES FOR BIS WITH NEGATIVE OVERPUNCH IN LEFT
; AND POSITIVE IN RIGHT
DEFINE IMAGE(A,B)<A'B>
%IDXX==0
DEFINE SDD(A,B,C,D)
< .XCREF
IFL %IDXX-^D10,< IMAGE(SP,\%IDXX)==B ;;SIXBIT POS
IMAGE(AP,\%IDXX)==C ;;ASCII POS
IMAGE(EP,\%IDXX)==D+60 ;;EBCDIC POS
>
IFGE %IDXX-^D10,< %IDXXX==%IDXX-^D10
IMAGE(SM,\%IDXXX)==B ;;NEG SIXBIT
IMAGE(AM,\%IDXXX)==C ;;NEG ASCII
IMAGE(EM,\%IDXXX)==D ;;NEG EBCDIC
>
IFGE %IDXX-^D20,<%IDXX==-1> ;;REINITIALIZE
%IDXX==%IDXX+1 ;;INCREMENT
.CREF
>
; TABLE BUILDING MACRO
DEFINE CVBDTB(SRC)
< .XCREF
%IDX==0
REPEAT ^D10,<
XWD IMAGE(SRC'M,\%IDX), IMAGE(SRC'P,\%IDX)
%IDX==%IDX+1
>
.CREF
>
> ;END BIS TABLES
SDDTBL: SDD +0,20,60,300
SDD +1,21,61,301
SDD +2,22,62,302
SDD +3,23,63,303
SDD +4,24,64,304
SDD +5,25,65,305
SDD +6,26,66,306
SDD +7,27,67,307
SDD +8,30,70,310
SDD +9,31,71,311
SDD -0,75,135,320
SDD -1,52,112,321
SDD -2,53,113,322
SDD -3,54,114,323
SDD -4,55,115,324
SDD -5,56,116,325
SDD -6,57,117,326
SDD -7,60,120,327
SDD -8,61,121,330
SDD -9,62,122,331
IFN BIS,<
;NOW DEFINE THE TABLES
CVBD.6: CVBDTB(S) ;SIXBIT
CVBD.7: CVBDTB(A) ;ASCII
CVBD.9: CVBDTB(E) ;EBCDIC
>
IFE BIS,<
;POINTERS TO THE SIGNED DISPLAY DIGITS:
SDDPTR: POINT 6,SDDTBL(T1),5
POINT 7,SDDTBL(T1),12
IFN EBCMP.,<
POINT 8,SDDTBL(T1),20
>
>
IFN BIS,<
PD6.: JSP BISCH, PD ;SIXBIT
PD7.: JSP BISCH, PD ;ASCII
BLOCK 1
PD9.: JSP BISCH, PD ;EBCDIC
PD: SUBI BISCH, PD6.-5 ;CONVERT TO BYTE SIZE
LDB BIST0, PACFL.## ;GET SOURCE AC FOR LATER
MOVE DSTPT, (PARM) ;GET DESTINATION POINTER
LDB DSTCNT, BSLPT2## ;GET COUNT
TLZN DSTPT,3777 ;CLEAR BYTE POINTER
POPJ PP, ;RETURN IF ZERO
;ONE OR TWO WORDS??
CAILE DSTCNT, ^D10
JRST PD2WD ;TWO
;ONE WORD
TLZE DSTPT,4000 ;SIGNED??
SKIPA SRCHI,(BIST0) ;YES - TAKE IT AS IS
MOVM SRCHI,(BIST0) ;NO - GET MAGNITUDE
ASHC SRCHI,-^D35 ;EXTEND SIGN
JRST PDGO ;GO
PD2WD: ;TWO WORDS
TLZN DSTPT,4000 ;SIGNED FIELD??
JRST PD2NS ;NO
DMOVE SRCHI,(BIST0) ;YES
JRST PDGO ;GO
PD2NS: ;UNSIGNED FIELD - TAKE MAGNITUDE
SKIPL SRCHI,(BIST0) ;NEGATIVE
SKIPA SRCLO,1(BIST0) ;NO
DMOVN SRCHI,(BIST0) ;YES - NEGATE AGAIN
PDGO: ;NOW WE ARE READY
; TEMPORARY CHANGE TO AVOID BAD DPB
; DPB BISCH,BPTOBS## ;STORE BYTE SIZE IN OUTPUT POINTER
LSH BISCH,6
TLO DSTPT,(BISCH)
LSH BISCH,-6
LSH BISCH,1 ;MULTIPLY INDEX BY 2
PDGOO: HRLI BD.FLG,BFLG.S ;TURN ON FOR RIGHT JUSTIFY.
EXTEND B.FLAG, CVBD.T-14(BISCH) ;CONVERT
JRST OVFLO ;OVERFLOW
TLNE BISCH,-1
CAIE BISCH,22 ;IF IT ISN'T EBCDIC,
POPJ PP, ; RETURN.
MOVE BISCH,(PARM) ;GET THE PARAMETER.
TLNN BISCH,4000 ;IF THE RESULT IS UNSIGNED,
POPJ PP, ; RETURN.
LDB BISCH,DSTPT ;REGET THE LAST CHAR.
TRNE BISCH,40 ;IF THE NUMBER IS POSITVE,
TRZ BISCH,60 ; OVERPUNCH A "+".
DPB BISCH,DSTPT ;STASH THE CHAR.
POPJ PP, ;RETURN.
CVBD.T: XWD CVTBDT, CVBD.6 ;SIXBIT
XWD Z, SP0
XWD CVTBDT, CVBD.7 ;ASCII
XWD Z, AP0
XWD 0, 0
XWD 0, 0
XWD CVTBDT, CVBD.9 ;EBCDIC
XWD Z, EP0
;THERE WAS AN OVERFLO SO WE MUST GO THROUGH A VARIETY
; OF MASCENATIONS TO GET COBOLS VERSION OF OVERFLOW WHICH
; THROWS AWAY THE EXCESS HIGH ORDER DIGITS AND KEEPS THE REST
T1==SRCCNT-2
T2==SRCCNT-1
OVFLO:
SKIPN PARM ;HAVE WE BEEN HERE BEFORE
JRST ERROR ;YES
SETZI PARM,
PUSH PP,T1 ;SAVE REGS
PUSH PP,T2
LSH DSTCNT,1 ;MULTIPLY COUNT BY 2
;SO IT WILL INDEX INTO THE
;DOUBLE WORD CONSTANT TABLE
SKIPL SRCHI ;NEGATIVE??
TDZA T1,T1 ;NO ZERO SIGN EXTEND
SETOI T1, ;YES
MOVE T2,T1
DDIV T1,DTAB(DSTCNT) ;DIVIDE BY LARGEST NUMBER THAT
;WILL FIT AND KEEP THE REMAINDER
LSH DSTCNT,-1 ;RESTORE COUNTER
POP PP,T2
POP PP,T1
JRST PDGOO ;TRY AGAIN
SUBTTL double macro to generate double-word integers
define shift(a,b)<
;macro to simulate ashc a,1. treats b as low part.
%s==a_-43 ;;%s contains sign of number
a==a_1 ;;shift high part
b==b_1 ;;shift low part
ifl b,<a==a!1 ;;high order bit of low part goes into
>
;;low order bit of high part
ifn %s-<a_-43>,< printx shift overflowed !! ;;sign change means overflow
>
b==b&<1b0-1> ;;clear low order sign bit
>
define dmul10(a,b)<
;;macro to multiply double word integer in a and b by ten.
%a==a
%b==b ;;make copy of number
shift(%a,%b) ;;multiply number by 2
%%a==%a
%%b==%b ;;make copy of 2*n
shift(%a,%b)
shift(%a,%b) ;;produce 8*n in %a and %b
b==%b+%%b ;;add low order parts
a==%a+%%a ;;add high order parts
ifl b,<a==a+1 ;;carry... we just added 2n + 8n to get 10n.
b==b&<1b0-1> ;;turn off high order bit
>
>
define .dbl(number) ;;generates double word decimal number
<
%high==<%low==0>
irpc number<
dmul10 (%high,%low) ;;multiply by ten
%low==%low+number ;;add in next digit
ifl %low,<%high==%high+1 ;;maybe carry
>
ifl %high,< printx decimal quantity too large. !!
stopi
>
%low==%low&<1b0-1> ;;clear carry bit
> ;;end of irpc
%high
%low ;;store number in core
> ;;end of definition
DTAB: .dbl 1
.dbl 10
.dbl 100
.dbl 1000
.dbl 10000
.dbl 100000
.dbl 1000000
.dbl 10000000
.dbl 100000000
.dbl 1000000000
.dbl 10000000000
.dbl 100000000000
.dbl 1000000000000
.dbl 10000000000000
.dbl 100000000000000
.dbl 1000000000000000
.dbl 10000000000000000
.dbl 100000000000000000
.dbl 1000000000000000000
.dbl 10000000000000000000
.dbl 100000000000000000000
.dbl 1000000000000000000000
ERROR: OUTSTR [ASCIZ '?LIBOL PD.N ERROR
']
POPJ PP,
> ;END OF BIS
END