;*************************** AMUS Program Label ******************************
; Filename: JMAP.M68                                        Date: 05/21/90
; Category: UTIL         Hash Code: 703-441-041-676      Version: 1.2(111)       
; Initials: AMI/AM       Name: AMI BAR-YADIN
; Company: UNITED FASHIONS OF TEXAS, INC.          Telephone #: 5126312277
; Related Files: NONE
; Min. Op. Sys.:                               Expertise Level: BEG
; Special: 
; Description: Displays memory map (with various options) similar to the
; AMOS MAP command for any job on the system.
; Type JMAP/? for options.
;*****************************************************************************
;* Updated on 01-May-90 at 2:38 PM by Ami Bar-Yadin; edit time: 5:10:40 *;
; JMAP.LIT - Print memory map for any job, default to self.  Can dump memory modules.
; (c) 1988,89,90 by Ami Bar-Yadin (AMI/AM)
;
; command usage syntax:		(type JMAP/? for on line help)
;	.JMAP{/[C|D{:n}|F|H|M]} {jobname}
;	switches must preceed job name
;
;
; Output of program:
;
; o First line is formatted as follows:
;   jobnam(trmnam): prgnam, memsize. bytes @memaddress{, cmdsize in CMD}
;   Note that "bytes" and "in CMD" are literal, all else are values
;
; o  Followed by a dump of the active .CMD file, if one is active (unless /C is used)
;
; o  Followed by a memory partition map (unless /M is used)
;    Very similiar to Alphamicro's MAP.LIT, but shows ALL modules
;    If /H is used hash codes are computed and displayed
;    If /D is used the module is dumped if it is smaller than a set maximum size
;    Module is dumped in ASCII, 64 chars per line with a leading tab
;
;
; History:
;
;[111] 01-May-90 Ami Bar-Yadin
;	Release to AMUS.  Reduce to common system macros.
;	Define all symbols internally.
;[110] 25-Apr-90 Ami Bar-Yadin
; 1.2
;	Added /D{:n} switch to dump memory modules
;	only modules smaller then n bytes (512 default) are dumped
;	Fixed a bug:  I was using the F$xx form of the bitflags instead of F%xx form.
;[109] 18-Oct-89  Ami Bar-Yadin
;	add /M switch to disable partition map display
;	add /C switch to disable active .CMD display
;	add /H switch to enable hash code computation and display
;	add /F switch to force display of FREE memory even if map is not
;	shortend job stats line
;	updated and expanded USAGE output to 
;[108] 25-Aug-89  Ami Bar-Yadin
;	Attempting to fix memory addressing bug in the routine
;	which displays the in-memory .CMD file
;[107] 10-Apr-89  Ami Bar-Yadin
; 1.1
;	modified header output
;	added display of command file size and text, if any
;[106] 26-Feb-89 Ami Bar-Yadin
;	general cleanup and restructuring
;	changed default to sub-command  (EH??)
;
VMAJOR=1
VMINOR=2
VEDIT=111.

L0:
	SYM
	MAYCREF
	SEARCH	SYS
	SEARCH	SYSSYM
	RADIX	16.
	DEFAULT	VEDIT,1
	DEFAULT $$MFLG,PV$RSM!PV$WSM
	DEFAULT	$$SFLG,PH$REE!PH$REU
	DEFAULT	$$SFLG,0
	DEFAULT $$LFLG,-1
	PHDR	$$LFLG,$$MFLG,$$SFLG

;=======
; EQUATES

TAB=9.
LF=10.
CR=13.
SPACE=32.
COMMA=44.
DEL=127.
DEFDSZ=512			; default dump's maximum is 512 bytes or less

;=======
; Impure area

	.OFINI
	.OFDEF	JNAM,4
	.OFDEF	MODNAM,12.	; FILNAM.EXT
	.OFDEF	FLAGS1,1	; see bellow
	.OFDEF	FLAGS2,1	; (not used, here as even address filler)
	.OFDEF	DUMPSZ,4	; maximum memory module size that may be dumped
	.OFSIZ	SIZIMP

;=======
; layout of memory module header

	.OFINI
	.OFDEF	M.SIZ,4
	.OFDEF	M.FLG,2
	.OFDEF	M.NAM,4
	.OFDEF	M.EXT,2
	.OFSIZ	MMHSIZ

;=======
; Flag bits for options

; macro which defines symbols for bit numbers and bit masks 
; for use as flags
;	F%name is the bit number (ie 0..31 for longword)
;	F$name is the bit mask   (ie 1 for lsb, 2, 4, 8...2^32 for msb)
 DEFINE	FLGBIT	NAME,BIT
	IF NB,BIT,	XCFBIT=BIT
	IF NDF,XCFBIT,	XCFBIT=0
	F%'NAME = XCFBIT
	F$'NAME = 1_XCFBIT
	XCFBIT=XCFBIT+1
 ENDM
	FLGBIT	CMD
	FLGBIT	FREE
	FLGBIT	HASH
	FLGBIT	MAP
	FLGBIT	DUMP

;=======
; Macros

		; TCRT -1,x
 DEFINE	XTABF	X
	IF	DF,SAVD1,	PUSH	D1
	MOVW	#<-1_8>+X,D1
	TCRT
	IF	DF,SAVD1,	POP	D1
 ENDM

		; output character
 DEFINE	OUTCHR	CHR
	IF NB,CHR,	MOVB	CHR,D1
	TTY
 ENDM

;
;=======
;
JMAP:
	CALL	SETUP
	CALL	CHKJOB	
	CALL	PRTHDR
	BTST	#F%FREE,FLAGS1(A5)	; force display of free space
	BNE	10$
	BTST	#F%MAP,FLAGS1(A5)
	BNE	20$		; if flag is set skip memory map
10$:	CALL	PRTMAP
	CALL	PRTSUM
20$:	EXIT


SETUP:
	GETIMP	SIZIMP,A5
	MOVW	#[JMA],M.NAM-ZID(A5)
	MOVW	#[P  ],M.NAM+2-ZID(A5)   
	MOVW	#[IMP],M.EXT-ZID(A5)

	MOV	#DEFDSZ,DUMPSZ(A5)		; initialize default Dump maximum size

	XTABF	3	; up			\
	XTABF	2	; column 1		 } erase command line text from screen
	XTABF	9	; clear to end of line	/

; process command switches

5$:
	BYP
	CMPB	@A2,#'/
	JNE	99$
6$:
	INC	A2
7$:
10$:
	CMPB	@A2,#'C
	BNE	20$
	BSET	#F%CMD,FLAGS1(A5)
	BR	6$
20$:
	CMPB	@A2,#'D
	BNE	30$
	BSET	#F%DUMP,FLAGS1(A5)
	CMPB	1(A2),#':		; is optional max size present:
	BNE	6$
	ADD	#2,A2			; point A2 to number after ":"
	GTDEC				; get number
	MOV	D1,DUMPSZ(A5)		; set new maximum size for dump
	BR	7$
30$:
	CMPB	@A2,#'F
	BNE	40$
	BSET	#F%FREE,FLAGS1(A5)
	BR	6$
40$:
	CMPB	@A2,#'H
	BNE	50$
	BSET	#F%HASH,FLAGS1(A5)
	BR	6$
50$:
	CMPB	@A2,#'M
	BNE	60$
	BSET	#F%MAP,FLAGS1(A5)
	BR	6$
60$:
	CMPB	@A2,#'?
	BNE	70$
	BEQ	USAGE		; and exit to AMOS
70$:
	BR	5$
99$:	BYP
	RTN

; print usage instructions
USAGE:
	CRLF

	XTABF	34.		; reverse blink on
	CALL	CREDIT	
;			; reverse blink off done by CREDIT

	TTYI
	BYTE	CR
	ASCII	/Usage:/
	BYTE	CR
	ASCII	!	.JMAP {/[C|F|H|M]..} {jobname}!
	BYTE	CR
	ASCII	/Defaults: 	Current (your) job/
	BYTE	CR
	ASCII	/		Display active .CMD, memory map without hash codes/
	BYTE	CR
	ASCII	/Switches:  (before job name, in any order, any combination)/
	BYTE	CR
	ASCII	!	/C DON'T display the job's active command (.CMD) file!
	BYTE	CR
	ASCII	!	/D Dump each memory partition that is 512 bytes or less!
	BYTE	CR
	ASCII	!	   Use /D:n to change the maximum size!
	BYTE	CR
	ASCII	!	/F Force display of free space even if not displaying map!
	BYTE	CR
	ASCII	!	/H display hash code in memory map!
	BYTE	CR
	ASCII	!	/M DON'T display the job's memory partition map!
	BYTE	CR
	BYTE	CR
	ASCII	/First line display:/
	BYTE	CR
	ASCII	/jobnam(trmnam): prgnam, memsize. @membase{, cmdsize IN CMD}/
	BYTE	CR
	ASCII	/Portion in {} is only displayed if job is executing a command (.CMD) file/
	BYTE	CR
	ASCII	/memsiz and cmdsize are always in decimal/
	BYTE	CR
	ASCII	/membase is either octal (leading "0") or hex (leading "x")/
	BYTE	CR,0
	EVEN
	EXIT


CHKJOB:
;	PUSH	A5
	LIN
	BEQ	20$
	CALL	JSRCH
	BCS	30$
	TYPECR	<? No such job.>
	EXIT
20$:
;	KBD	30$
;	AMOS
;	JOBIDX	A0
30$:
;	POP	A5
	RTN


PRTHDR:
;
; RETURN: D4=JOB PARTITION SIZE
;
	OUTCHR	#SPACE		; reserve 1st col for underline on/off

	LEA	A1,JOBNAM(A0)
	CALL	TYPR50

	OUTCHR	#'(				;[107]
	MOV	JOBTRM(A0),A1
	LEA	A1,-4(A1)
	CALL	TYPR50

	TYPESP	<):>
	LEA	A1,JOBPRG(A0)
	CALL	TYPR50

	OUTCHR	#COMMA
	MOV	JOBSIZ(A0),D4		; return partition size
	MOV	D4,D1
	DCVT	0,OT$TRM+OT$ZER+OT$LSP
	TYPE	<. bytes @>			;[107]
	JOBIDX
	MOVW	JOBTYP(A6),D6
	AND	#J.HEX,D6		; hex output?
	BEQ	5$			; no
	MOVB	#'x,D1			; leading character for hexdecimal
	BR	7$
5$:	MOVB	#'0,D1			; leading characger for octal
7$:	TTY				; output leading character
	MOV	JOBBAS(A0),D1
	OCVT	0,OT$TRM+OT$ZER

	MOV	D1,A3

	CLR	D1
	MOVW	JOBCMZ(A0),D1
	JEQ	10$

	TYPE	<,>
	DCVT	0,OT$TRM+OT$ZER+OT$LSP+OT$TSP
	TYPECR	<in CMD>			;[107]

	ADD	D4,A3
	DEC	A3		;[108]

	BTST	#F%CMD,FLAGS1(A5)
	JNE	15$		; if flag is set skip .CMD display

	MOVB	@A3,D6		; so go thru D6
	PUSHW	D6		;[108] was PUSHB D6

	PUSH	A3
	CLRB	@A3		; make sure string is terminated
	SUB	D1,A3

	XTABF	31.
	XTABF	3.
	XTABF	2.
	XTABF	30.
	XTABF	4.
	XTABF	2.
	XTABF	31.
	CALL	TYPCMD		; output the active .CMD
	XTABF	31.
	XTABF	3.
	XTABF	2.
	XTABF	30.
	XTABF	4.
	XTABF	2.
	XTABF	31.
	POP	A3
	POPW	D6
	MOVB	D6,@A3
	BR	20$
10$:
	CRLF
15$:
	OUTCHR	#SPACE
20$:
	RTN

TYPCMD:
	MOVB	(A3)+,D1
	BEQ	99$
	CMPB	D1,#CR		; CR is line-term
	BEQ	3$
	CMPB	D1,#LF		; ignore LF
	BEQ	TYPCMD
	CALL	LINBYT
	BR	TYPCMD
3$:	CRLF
	OUTCHR	#SPACE
	BR	TYPCMD
99$:	RTN


LINBYT:
	ANDB	#^H0FF,D1
	TSTB	D1
	BEQ	2$		; output "." for NULLS
	BPL	3$
	PUSHB	D1
	XTABF	11.
	POPB	D1
	AND	#^H07F,D1
	BSET	#15.,D1		; set high word bit as flag
	BR	4$
3$:	CMPB	D1,#TAB
	BEQ	0$		; output as is
4$:	CMPB	D1,#SPACE
	BLO	1$		; output ^x
	CMPB	D1,#DEL
	BHIS	2$		; output "." for DEL and above
0$:	TTY			; output as is
99$:	TSTW	D1
	BPL	98$
	XTABF	12.
98$:	RTN
1$:	PUSHW	D1		; must save hi byte too
	OUTCHR	#'^
	POPW	D1
	ADDB	#'@,D1
	BR	0$
2$:	MOVB	#'.,D1
	BR	99$


PRTMAP:
	MOV	JOBBAS(A0),A0
10$:	TST	@A0
	BNE	30$
20$:	RTN
30$:	CTRLC	20$
	BTST	#F%MAP,FLAGS1(A5)
	BNE	35$		; if flag is set, don't display module
	CALL	PRTMOD
	BTST	#F%DUMP,FLAGS1(A5)
	BEQ	35$		; if flag is not set, don't dump module
	CALL	DUMP
35$:	ADD	@A0,A0
	BR	10$

;
; output module stats
; ENTRY: D4=MEMORY PARTITION SIZE (FREE MEMORY SO FAR)
;	 A0=>MODULE HEADER
; RETURN: D4=FREE MEM LEFT
;
PRTMOD:
	CALL	PRTNAM		; print module's name or "<NO NAME>"

	MOV	M.SIZ(A0),D1		; Module size
	SUB	D1,D4			; compute mem left free
	SUB	#ZID,D1			; (NOT INCLUDING OVERHEAD)
	DCVT	8.,OT$LSP+OT$TRM+OT$ZER

	TYPESP	<>
	MOV	A0,D1			; Module base address
	ADD	#ZID,D1			; (NOT INCLUDING OVERHEAD)
	OCVT	8.,OT$LSP+OT$TRM+OT$ZER

	BTST	#F%HASH,FLAGS1(A5)
	BEQ	10$			; if flag is clear, don't print hash

	TYPESP	< >
	CALL	PRTHSH			; Hash total

10$:
	MOVW	M.FLG(A0),D7		; Module status
	BEQ	20$			; flags all off
	TYPE	<  [>
	MOVW	M.FLG(A0),D7
	ANDW	#LOK,D7
	BEQ	11$
	TYPE	<L>
11$:	MOVW	M.FLG(A0),D7
	ANDW	#FIL,D7
	BEQ	12$
	TYPE	<D>
12$:	MOVW	M.FLG(A0),D7
	ANDW	#FGD,D7
	BEQ	13$
	TYPE	<F>
13$:	TYPE	<]>
20$:	CRLF
	OUTCHR	#SPACE		; underline on/off reserve
	RTN

PRTNAM:
	TST	M.NAM(A0)		; if name is blank
	BNE	10$
	TSTW	M.NAM+4(A0)		; and ext is blank
	TTYL	NONAME
	RTN
10$:	LEA	A2,MODNAM(A5)	; Module Name
	LEA	A1,M.NAM(A0)
	UNPACK
	UNPACK
	MOVB	#SPACE,(A2)+	; Extension
	UNPACK
	CLRB	@A2
	TTYL	MODNAM(A5)
	RTN

; dump module stats in ASCII
; 64 characters per line with a leading TAB
;
; ENTRY:  A0=>MODULE HEADER
;
; Register usage:	D0-MODULE SIZE
;			D1-CHAR TO OUTPUT
;			D2-CHARS PER LINE COUNTER
;			A1->next byte
DUMP:
	SAVE	D0,D1,D2,A1
	MOV	M.SIZ(A0),D0		; get module's size
	SUB	#ZID,D0			; remove module's header from byte count
	CMP	D0,DUMPSZ(A5)		; is module small enough to allow dumping?
	BHI	99$			; no.  don't dump this module.
	LEA	A1,M.EXT+2(A0)		; A1->1st data byte of module
	; next line of characters
10$:	MOV	#64.-1,D2		; init characters per line counter (-1 for DBF)
	TAB				; output leading TAB
20$:	MOVB	(A1)+,D1		; get next byte
	CALL	DMPBYT			; dump it
	DEC	D0			; count bytes
	BEQ	98$			; until all are done
	DBF	D2,20$			; count bytes left per line
	CRLF
	BR	10$	
98$:	CRLF
99$:	REST	D0,D1,D2,A1
	RTN

DMPBYT:
	ANDB	#07F,D1			; ignore high bit
	CMPB	D1,#SPACE		; catch control characters
	BHIS	10$
	MOVB	#'.,D1			; output "." for control characters
10$:	TTY
	RTN


PRTSUM:
; ENTRY: D4=FREE MEMORY
;	 A0=>FREE MEMORY (JUST PAST LAST MODULE)
;
	TYPESP	<Free     >
	MOV	D4,D1			; FREE SIZE
	DCVT	8.,OT$LSP+OT$TRM+OT$ZER
	TYPESP	<>			; FREE BASE
	MOV	A0,D1
	OCVT	8.,OT$LSP+OT$TRM+OT$ZER

	TYPE	<  >

CREDIT:
	XTABF	11.		; low intensity
	LEA	A1,L0-ZID+M.NAM
	CALL	TYPR50
	TYPE	< v>
	VCVT	L0+2,OT$TRM
	TYPE	< (c) 1988,89 By Ami Bar-Yadin>
	XTABF	12.
	XTABF	35.		; for when called by USAGE

	CRLF

	RTN


JSRCH:
; ENTRY: A2=>job name in ASCII
; RETURN: A0=>JCB
	LEA	A1,JNAM(A5)
	PACK			; CONVERT JOBNAM TO RAD50
	PACK
	MOV	JNAM(A5),D6	; D1=JOBNAM
	MOV	JOBTBL,A1
1$:	MOV	(A1)+,D7	; GET NEXT JCB ADDRESS
	BEQ	1$		; NO JOB ALLOCATED HERE, GET ANOTHER
	CMP	D7,#-1
	BEQ	2$		; END OF TABLE
	MOV	D7,A0
	CMP	D6,JOBNAM(A0)
	BNE	1$
	LCC	#PS.C
2$:
	RTN
;
;					HASH TOTALS
PRTHSH:
	SAVE	D1-D4
	PUSH	A0
	ADD	#0C,A0
	MOV	#2,D0
	CLR	D3
	CLR	D4
L0134:	MOV	-0C(A0),D2
	SUB	#0C,D2
	ASR	D2,#1
	BEQ	L0168
L0142:	MOVW	(A0)+,D1
	CLR	D7
	ADDW	D1,D3
	ADDXW	D7,D4
	SUBW	D2,D4
	ADDXW	D7,D3
	ADDW	D3,D4
	ADDXW	D7,D3
	LSLW	D3,#1
	ROXLW	D4,#1
	ADDXW	D7,D3
	DEC	D2
	BNE	L0142
	MOV	@SP,A0
	ADD	#0C,A0
	DEC	D0
	BNE	L0134
L0168:	JOBIDX	A0
	PUSHW	JOBTYP(A0)
	ANDW	#^CJ.HEX,JOBTYP(A0)
	CLR	D1
	MOVW	D4,D1
	OCVT	3,OT$TRM
	TYPE	<->
	MOVW	D1,D7
	ASLW	D1,#8
	ANDW	#-0100,D1
	ASRW	D7,#8
	ANDW	#0FF,D7
	ORW	D7,D1
	OCVT	3,OT$TRM
	TYPE	<->
	MOVW	D3,D1
	OCVT	3,OT$TRM
	TYPE	<->
	MOVW	D1,D7
	ASLW	D1,#8
	ANDW	#-0100,D1
	ASRW	D7,#8
	ANDW	#0FF,D7
	ORW	D7,D1
	OCVT	3,OT$TRM
	POPW	JOBTYP(A0)
	POP	A0
	REST	D1-D4
	RTN
;
;				PRINT RAD50 LONG WORD AT A1
PRTR50:
	LEA	A2,JNAM(A5)
	UNPACK
	UNPACK
	CLRB	@A2
	TTYL	JNAM(A5)
	RTN
;				PRINT RAD50 LONG WORD AT A1
;				WITHOUT TRAILING SPACES
TYPR50:
	LEA	A2,JNAM(A5)
	UNPACK
	UNPACK
10$:	CLRB	@A2
	CMPB	-(A2),#SPACE
	BEQ	10$
	TTYL	JNAM(A5)
	RTN
;
;
NONAME:	ASCIZ	/<NO NAME> /
	EVEN
;
;
	END