Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 3.X/CPM 3.0/3.0 PLM SOURCE/UTL1HST.ASM
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

364 lines
7.2 KiB
NASM

ORG 000H
TITLE 'SID HISTOGRAM UTILITY 12/26/77'
;
; COPYRIGHT (C) 1976,1977
; DIGITAL RESEARCH
; BOX 579 PACIFIC GROVE
; CALIFORNIA 93950
;
; HISTOGRAM OF PROGRAM EXECUTION FREQUENCY
; DDT ENTRY POINT
BDOSE EQU 5 ;PRIMARY BDOS ENTRY POINT
DDTBASE EQU 7*8+1 ;RESTART ENTRY POINT HAS BASE
HISTO: JMP SETUP ;INITIAL ENTRY FROM RELOCATOR
;
; SYMBOL TABLE INITIALIZED TO INITIAL, COLLECT, DISPLAY
SYBASE:
DB 'YALPSID',7,LOW DISE,HIGH DISE ;DISPLAY
DB 'TCELLOC',7,LOW COLE,HIGH COLE ;COLLECT
DB 'LAITINI',7,LOW INIE,HIGH INIE ;INITIAL
SYLEN EQU $-SYBASE ;LENGTH OF ADDITIONAL SYMBOLS
;
INIE: JMP INITIAL
COLE: JMP COLLECT
DISE: JMP DISPLAY
DB 'COPYRIGHT (C) 1977 DIGITAL RESEARCH '
; DDT SUBROUTINES
GETBUFF:
; READ NEXT COMMAND BUFFER
LXI B,3
JMP GODDT
;
GNC: ;READ NEXT CHARACTER TO REGISTER A
LXI B,6
JMP GODDT
;
PCHAR: ;PRINT CHARACTER FROM REGISTER A
LXI B,9
JMP GODDT
;
PBYTE: ;PRINT DECODED BYTE FROM REGISTER A
LXI B,12
JMP GODDT
;
;
PADDR: ;PRINT THE ADDRESS GIVEN BY D,E
PUSH D ;SAVE THE ADDRESS FOR THE PRINT
MOV A,D ;PRINT HIGH ADDRESS
CALL PBYTE
POP D ;RECALL
MOV A,E ;LOW ADDRESS
JMP PBYTE ;RETURN THROUGH PBYTE
;
SCANEXP:
; SCAN COMMAND LINE FOR 1,2, OR 3 EXPRESSIONS
LXI B,18
JMP GODDT
;
GETVAL:
; READ NEXT VALUE FROM SCANEXP CALL TO H,L
LXI B,21
;
GODDT: ;PERFORM THE DDT CALL
LHLD DDTBASE
DAD B
PCHL
;
; CONSTANTS
CR EQU 0DH
LF EQU 0AH
HSIZE EQU 64 ;SIZE OF HISTOGRAM (MUST CORRESPOND TO SHR6)
;
; USEFUL SUBROUTINES
DIFF: ;COMPUTE THE DIFFERENCE: DE = DE - HL
MOV A,E
SUB L
MOV E,A
MOV A,D
SBB H
MOV D,A
RET
;
SHR6: ;DIVIDE H,L BY 64 (MUST CORRESPOND TO HSIZE)
MOV A,L
MOV L,H
MVI H,0
DAD H ;HIGH ORDER * 2
DAD H ;HIGH ORDER * 4
RLC ;MOVE HIGH TWO BITS OF LOW BYTE
RLC ;TO POSITION IN A
ANI 11B ;MASK TO REPLACE LOW BITS OF H,L
ORA L
MOV L,A
RET
;
CRLF: ;SEND CRLF CHARACTERS
MVI A,CR
CALL PCHAR
MVI A,LF
CALL PCHAR
RET
;
PRINT: ;PRINT MESSAGE IN D,E 'TIL FIRST ZERO
LDAX D
ORA A
RZ
; MORE TO PRINT
INX D
PUSH D
CALL PCHAR
POP D
JMP PRINT
;
; PRINCIPAL PROCESSORS
SETUP: ;ARRIVE HERE FROM THE RELOCATOR, SET UP JUMPS
LHLD BDOSE+1 ;PRIMARY ENTRY TO BDOS
SHLD HISTO+1 ;CHANGE JUMP AT BASE OF THIS MODULE
LXI H,HISTO ;CHANGE BDOS ENTRY ADDRESS
SHLD BDOSE+1 ;INITIAL JUMP ADDRESS CHANGED
;
; THE PRIMARY BDOS ENTRY ADDRESS NOW REFLECTS THE ADDITION
; OF THE TRACE MODULE, THE SYMBOL TABLE HAS BEEN INCLUDED
; AT THE BEGINNING OF THE MODULE, AND ITS LENGTH WILL BE
; RETURNED WITH THE "INITIAL" CALL IN REGS DE
JMP INITIAL
;
INERR: LXI D,ERMSG
CALL PRINT
;
INITIAL:
LXI D,BOUNDS ;SEND STARTING MESSAGE
CALL PRINT
CALL GETBUFF ;GET BUFFER FULL FOR BOUNDS SCAN
CALL SCANEXP ;SHOULD BE 2 PARAMETERS
JC INERR ;CANNOT BE ,X,X
CPI 2
JNZ INERR ;1,3?
CALL GETVAL ;FIRST PARAMTER TO H,L
SHLD LB ;LOWER BOUND SAVED
PUSH H ;COMPARED WITH UPPER BOUND LATER
CALL GETVAL ;UPPER BOUND
INX H
SHLD UB
POP D ;LOWER IN D,E UPPER IN H,L
XCHG
CALL DIFF ;UB>=LB?
JC INERR
; DIFFERENCE IN D,E - COMPUTE INCREMENT
XCHG
CALL SHR6 ;DIVIDE BY 64
SHLD INC
LXI H,HVEC ;CLEAR THE HISTGRAM VECTOR
MVI C,HSIZE*2
FILL0: MVI M,0
INX H
DCR C
JNZ FILL0
; VECTOR FILLED, GO BACK TO THE DEBUGGER
LXI D,INIMSG
CALL PRINT
LXI D,INIE
CALL PADDR ;INITIAL = XXXX
LXI D,COLMSG
CALL PRINT
LXI D,COLE
CALL PADDR ;COLLECT = XXXX
LXI D,DISMSG
CALL PRINT
LXI D,DISE
CALL PADDR ;DISPLAY = XXXX
LXI D,SYLEN ;NUMBER OF SYMBOLS
RET
;
;
;
COLLECT:
; CALLED FROM DEBUGGER WITH REGISTER C HOLDING THE OPERATOR
; CATEGORY (NOT USED HERE), AND D,E HOLDING THE PC
PUSH D ;SAVE THE PC
LHLD UB ;WITHIN THE RANGE LB - UB?
XCHG
CALL DIFF ;X = UB - PC
POP D
JC RET0 ;SKIP IF BELOW LB
LHLD LB
CALL DIFF ;X = PC - LB
JC RET0
;
; D,E HAS INDEX TO HIST VECTOR
MVI C,0 ;READY TO COUND INDEX TO PROPER ELEMENT IN HVEC
LHLD INC ;AMOUNT IN EACH CATEGORY
FINDCELL:
CALL DIFF ;X = X - INC
JC FOUND
INR C ;TO NEXT HVEC ELEMENT
JMP FINDCELL
;
; REG C HAS INDEX TO HVECT
FOUND:
MVI B,0 ;BECOMES DOUBLE PRECISION
LXI H,HVEC
DAD B
DAD B ;HVECT(X)
MOV E,M ;OLD VALUE OF HVEC(X)
INX H
MOV D,M ;TO D,E, READY FOR INCREMENT
INX D ;COUNT UP BY ONE, CHECK FOR 0FFFFH
MOV M,D
DCX H
MOV M,E ;REPLACED IN MEMORY
INX D ;0FFFFH GOES TO 0000H
MOV A,D
ORA E
JNZ RET0 ;NORMAL RETURN IF NOT 0FFFFH
;
; ONE CATEGORY FILLED, STOP EXECUTION
MVI A,1
RET
;
RET0: ;RETURN 0 TO CONTINUE COLLECTION
MVI A,0
RET
;
;
;
DISPLAY:
; DISPLAY THE HISTOGRAM COLLECTED SO FAR
; FIND LARGEST VALUE TO SCAL DIAGRAM
LXI H,HVEC
MVI C,HSIZE
LXI D,0 ;MAX SO FAR
LARG0: PUSH D ;SAVE LARGEST
MOV E,M
INX H
MOV D,M ;D,E HOLDS TEST ELEMENT
INX H ;READY FOR NEXT ELEMENT
XTHL ;LARGEST TO H,L ADDRESS TO STACK
PUSH D ;SAVE TEST
CALL DIFF ;X = TEST - LARGEST
POP D ;RESTORE TEST VALUE
XCHG ;LARGEST IN D,E - TEST IN H,L
JC LARG1 ;CARRY IF LARGEST > TEST
XCHG ;TEST GOES TO D,E
LARG1: DCR C ;COUNT LENGTH DOWN
POP H ;RECALL HVEC ADDRESS
JNZ LARG0 ;FOR ANOTHER TEST
;
; MAX IS IN D,E
XCHG ;TO H,L
PUSH H ;SAVE LARGEST FOR PRINTING BELOW
CALL SHR6 ;DIVIDE BY 64 FOR SCALING
INX H ;IN CASE OF REMAINDER
SHLD SCALE
LXI D,LARMSG
CALL PRINT
POP D ;RECALL LARGEST VALUE
CALL PADDR
XRA A ;CLEAR ZERCNT
STA ZERCNT
;
; NOW STEP THROUGH THE HIST VECTOR AND PRINT '*' FOR EACH LINE
LHLD LB
XCHG ;LOWER BOUND TO D,E
LXI B,HVEC ;BASE OF HIST VECTOR
DISP0: PUSH D ;SAVE CURRENT LINE ADDRESS
LHLD UB ;TEST FOR OVER THE TOP
CALL DIFF
POP D
JNC DISP1 ;NO CARRY IF CURRENT >= UB
; CHECK FOR MULTIPLE BLANK LINES AND PRINT .... INSTEAD
MOV H,B ;HIGH ORDER HVEC INDEX
MOV L,C ;LOW ORDER HVEC INDEX
MOV A,M ;LOW ORDER HVEC VALUE
INX H
ORA M ;VALUE = 0?
LXI H,ZERCNT
JNZ ZCHK1 ;VALUE IS NOT ZERO, PRINT LINE
; VALUE IS ZERO, ALREADY PRINTED?
MOV A,M ;GET ZERCNT
ORA A
JNZ ZCHK0 ;JUMP IF ALREADY PRINTED LINE
; NOT PRINTED YET, SET ZERCNT TO TRUE AND PRINT MSG
MVI M,0FFH
PUSH B
PUSH D
LXI D,PERMSG
CALL PRINT
POP D
POP B
ZCHK0: ;INCREMENT LINE ADDRESS
LHLD INC
DAD D
XCHG
; INCREMENT HVEC ADDRESS
INX B
INX B
JMP DISP0
;
ZCHK1: ;LINE IS NOT ZERO, FLAG IT AND CONTINUE
MVI M,0 ;ZERCNT SET FALSE
PUSH B ;INDEX TO HVEC SAVED
PUSH D ;CURRENT LINE SAVED
PUSH D ;ANOTHER COPY
CALL CRLF
POP D ;LINE ADDRESS TO DE
CALL PADDR ;PRINTED
POP D ;RECALL LINE ADDRESS
LHLD INC ;INCREMENT BETWEEN LINES
DAD D
XTHL ;LINE ADDRESS STACKED, INDEX TO HVEC IN HL
MOV E,M
INX H
MOV D,M
INX H
PUSH H ;SAVE UPDATED HVEC ADDRESS
CALL STARS ;PRINTS STARS FOR THIS LINE
POP B ;RECALL HVEC BASE
POP D ;RECALL CURRENT LINE
JMP DISP0
;
DISP1: ;END OF DISPLAY
CALL CRLF
RET ;RETURN TO DDT
;
STARS: ;PRINT STARS ACROSS LINE BASED ON SCALE VALUE
MOV A,E
ORA D
RZ ;RETURN IF ZERO STARS
PUSH D
MVI A,' '
CALL PCHAR
;
POP D
STAR0: ;LOOP PRINTING STARS
LHLD SCALE ;SCALING FACTOR
CALL DIFF ;X = SIZE - SCALE
RC
PUSH D ;SAVE REMAINING LENGTH
MVI A,'*'
CALL PCHAR
POP D
JMP STAR0
;
;
; DATA AREAS
ERMSG: DB CR,LF,'ERROR - FORM IS X,Y',0
BOUNDS: DB CR,LF,'TYPE HISTOGRAM BOUNDS ',0
LARMSG: DB CR,LF,'HISTOGRAM:'
DB CR,LF,'ADDR RELATIVE FREQUENCY, LARGEST VALUE = ',0
INIMSG: DB CR,LF,'.INITIAL = ',0
COLMSG: DB CR,LF,'.COLLECT = ',0
DISMSG: DB CR,LF,'.DISPLAY = ',0
PERMSG: DB CR,LF,'....',0
ZERCNT: DS 1
LB: DS 2 ;LOWER BOUND
UB: DS 2 ;UPPER BOUND
HVEC: DS HSIZE*2 ;HISTOGRAM VECTOR
SCALE: DS 2 ;SCALE FACTOR
INC: DS 2 ;INCREMENT BETWEEN LINES
NOP
END HISTO