.MCALL .MODULE .MODULE RESMEM,VERSION=5,COMMENT=,IDENT=NO ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ;++ ; ; Edit Who Date Description of modification ; ---- --- ---- --------------------------- ; 001 WLD 13-NOV-90 Eliminate references to C1.SJFB ; (FBMON$). ;-- ; Edit History: ; 001 George Stevens Overlaid version of RESORC. Created from RESORC ; Version 97 ; 002 George Stevens Added display of CACHE bypass status to SHOW MEM .NLIST .INCLUDE /SRC:RESPFX.MAC/ .LIST .SBTTL MEMORY - Show memory layout ;+ ; This subroutine shows the layout of memory ;- ORIGIN RESMEM .ENABL LSB MEMORY::.PRINT #CRLF ;Start with a carriage return etc. BIT #C1.XM,$CNFG1(R5) ;Is this XM? BEQ 10$ ;No then only do kernel memory. PRINT EXLAYO,<------- Extended Memory --------> CLR ADJLO ;Don't adjust high memory values. CALL MEMEXT ;Show the extended memory layout. .PRINT #CRLF ;Start with a carriage return. PRINT KELAYO,<------ Low Memory -------> 10$: MOV #-1,(PC)+ ;Adjust the low memory. ADJLO: .WORD -1 ; : Flag to indicate adjustment needed CALL MEMLOW ;Show the low memory layout. RETURN ;Return to the caller. .DSABL LSB ;+ ; Subroutine to show the layout of extended memory. ;- MEMEXT::MOV SRTBUF,R1 ;R1 -> Working buffer for sort. ;+ ; Find the extended memory allocation table ;- MOV $MEMPT(R5),R2 ;R2 = offset from RMON to free list. ADD R5,R2 ;Make it an absolute address. MOV 4(R2),R2 ;R2 = offset from RMON to extm list. ADD R5,R2 ;R5 -> ext. memory allocation table. ;+ ; Fill in the free spots. ;- 10$: MOV #<^R...>,(R1)+ ;Yes, enter the name ...... MOV #<^R...>,(R1)+ CLR (R1)+ MOV (R2)+,-(SP) ;Save how big it is! MOV (R2)+,(R1)+ ;Store where it is! MOV (SP),(R1)+ ;Store how big it is! CLR (R1)+ ;Skip over TYPE field TST (SP)+ ;Was there memory in this entry? BNE 20$ ;Branch if so SUB #,R1 ;No, then ignore it. 20$: CMP @R2,#-1 ;Yes, then is it the end of the table? BNE 10$ ;No, then keep filling. ;+ ; Add memory allocated in global regions ;- TST (R2)+ ;Move to the global RCBs. 30$: CMP @R2,#-1 ;End of the global RCB table? BEQ 110$ ;Yes, then go add other items. TST @R2 ;Is this region in use? BNE 40$ ;Yes, then go fill it in. ADD #GR.ESZ,R2 ;Move to the next entry. BR 30$ ;Continue checking. 40$: MOV R1,-(SP) ;Save buffer pointer CMP GR.NAM+2(R2),RAD50$ ;Is second word of name a $? BNE 50$ MOV GR.NAM(R2),R0 ;R0 = first word in name MOV #50,R1 ;R1 = divisor CALL $DIV ;Divide R1 into R0 TST R1 ;Is remainder (last character) blank? BNE 50$ ;Branch if not MOV #50,R1 ;Multiply quotient by 50 CALL $MUL ; to shift it 1 character to left MOV R1,R0 ;R0 = low order result MOV (SP)+,R1 ;Restore buffer pointer MOV R0,(R1)+ ;Store first word of name CLR (R1)+ ;Store second word of name BR 60$ ; continue 50$: MOV (SP)+,R1 ;Restore buffer pointer MOV GR.NAM(R2),(R1)+ ;Store the owner's name. MOV GR.NAM+2(R2),(R1)+ 60$: CLR (R1)+ MOV (R2)+,-(SP) ;Save how big it is! MOV (R2)+,(R1)+ ;Store where it is! MOV (SP)+,(R1)+ ;Store how big it is! CLR @R1 ;Clear TYPE field BIT #GR.AGE,@R2 ;Is AGE on? BEQ 70$ ;Branch if not BIS #AGEBIT,@R1 ;Set AGE in TYPE 70$: BIT #GR.PRM,@R2 ;Is PRM bit on? BEQ 80$ ;Branch if not BIS #PRMBIT,@R1 ;Set PRM in TYPE 80$: BIT #GR.NRF,@R2 ;Is NRF bit set? BEQ 90$ ;Branch if not BIS #HDWBIT,@R1 ;Set HDW in TYPE 90$: BIT #GR.PRV,@R2 ;Is PRIVATE bit on? BEQ 100$ ;Branch if not BIS #PVTBIT,@R1 ;Set PVT in TYPE 100$: TST @R1 ;Is there a TYPE? BNE 101$ ;Branch if so MOV #SHRBIT,@R1 ;Assume SHR TYPE 101$: BIT #GR.CAC,@R2 ;Is CACHE bypass bit on? BEQ 102$ ;Branch if not BIS #BYPBIT,@R1 ;Set BYP in TYPE 102$: TST (R1)+ ;Skip over type ADD #,R2 ;Move to the next entry. BR 30$ ;Continue ;+ ; Add MEMTOP ;- 110$: MOV #<^RMEM>,(R1)+ ;** MEMTOP ** MOV #<^RTOP>,(R1)+ CLR (R1)+ ;No high order address. MOV $MEMSZ(R5),(R1)+ ;Get the memory size. CLR (R1)+ ;Top indicator has no size. CLR (R1)+ ;Skip TYPE field ;+ ; Add regions allocated to foreground and system jobs. ;- MOV #<16+2>,R2 ;R2 = job number of interrest. MOV $SYSGN(R5),R4 ;Put in register because we ; map away user PAR6 later BIT #SY.SJB,R4 ;System jobs supported? BNE 120$ ;Yes, then go scan the jobs. MOV #<2+2>,R2 ;No, then only look at the FG. 120$: SUB #2,R2 ;Move to next lower job. BEQ 190$ ;Don't do the background. .GTJB #AREA,#BUFFER,R2 ;Get the info about the job. BCS 120$ ;No such job, so continue next. ;+ ; Valid job so determine where its region control blocks are. ;- MOV R2,-(SP) ;Save R2 (it contains job number). MOV $MEMPT(R5),R3 ;R3 = offset from RMON to free ptn. ADD R5,R3 ;Make it an absolute address. MOV 6.(R3),-(SP) ;@SP = offset to MCA chunk pointer ADD BUFFER+10,@SP ;@SP -> job's MCA chunk pointer MOVB 8.(R3),R2 ;R2 = number of job RCBs MOV 10.(R3),R3 ;Get offset to RCBs ADD #,R3 ;R3 -> job's RCBs MOV @(SP)+,@#UISAR6 ;Map user PAR6 to job's MCA ;+ ; Determine if there are any RCBs in use. ;- 130$: TST @R3 ;Is this RCB in use? BEQ 180$ ;No, then go check the next. BIT #R.SHAR,RG.STA(R3) ;Is this memory already shown as a BNE 180$ ;global region? Yes, then next entry. ;+ ; Insert the name of the owner of this region. ;- MOV R3,-(SP) ;Save R3 (contains RCB pointer). BIT #SY.SJB,R4 ;Got system job support? BEQ 160$ ;No, so don't get the job name. MOV #BUFFER+22,R3 ;R3 -> Job name in ASCII 140$: MOVB (R3)+,(R1) ;Move a character over. BNE 150$ ;Was it a null? MOVB #BLANK,(R1) ;Yes, then space it out. 150$: INC R1 ;Point to the next position. CMP R3,#BUFFER+22+6 ;All 6 characters transferred? BLO 140$ ;No, go transfer another. BR 170$ ;Yes, then go get address values. 160$: MOV #<^RF >,(R1)+ ;set the name to foreground. CLR (R1)+ ;** F ** CLR (R1)+ ;+ ; Now put the region information into the table. ;- 170$: MOV (SP)+,R3 ;R3 -> RCB again. MOV (R3),(R1)+ ;Put address of region in table. MOV 2(R3),(R1)+ ;Put size of region in table. MOV #LOCBIT,@R1 ;Store TYPE field BIT #R.CACH,RG.STA(R3) ;Is CACHE bypass bit on? BEQ 175$ ;Branch if not BIS #BYPBIT,@R1 ;Set BYP in TYPE 175$: TST (R1)+ ;Skip TYPE field ;+ ; Select the next region. ;- 180$: ADD #RG.SIZ,R3 ;Move to next RCB. DECB R2 ;Have all RCBs been checked? BNE 130$ ;Branch if not MOV #,@#UISAR6 ;Remap user PAR6 to kernel PAR6 MOV (SP)+,R2 ;R2 = job number again. BR 120$ ;Continue until all jobs checked. ;+ ; Now sort the table ;- 190$: CALL TSORT ;Sort into ascending order. ;+ ; Print the table ;- .PRINT #MEMHTX ;Print a header. .PRINT #MEMHTZ .PRINT #MEMHLI ;Underline it. .PRINT #MEMHLZ DEC HIFLAG ;Indicate it is high memory printout. CALL TPRINT ;Print the table. RETURN ;Return to the caller. ;+ ; Subroutine to show the layout of low memory. ;- .ENABL LSB MEMLOW::MOV SRTBUF,R1 ;R1 -> Working buffer for sort. ;+ ; Determine the size of the I/O page. ;- BIT #,$SYSGN(R5) ;Is this RTEM or TSX PLUS? BNE 10$ ;Yes, then there is no I/O page. BIT #C1.XM,$CNFG1(R5) ;Is this XM? BNE 10$ ;Yes, then I/O page is global region. MOV #<^RIOP>,(R1)+ ;** IOPAGE ** MOV #<^RAGE>,(R1)+ CLR (R1)+ ;No high order bits. MOV #160000,(R1)+ ;Assume it is at 160000. MOV #<4096.*2>,(R1)+ ;Assume size is 8KB. CLR (R1)+ ;Skip TYPE field CMP $MEMSZ(R5),#<56.*KB> ;Is the memory < than 56KB? BLOS 10$ ;Yes then unmapped so we're right. MOV #170000,-6(R1) ;Assume it is a 170000 (PDT case). MOV #<2048.*2>,-4(R1) ;with 4KB I/O page size. CMP $MEMSZ(R5),#<60.*KB> ;Is it? BLOS 10$ ;Yes then merge with common code. MOV #160000,-6(R1) ;Must be an 18 bit I/O page. MOV #<4096.*2>,-4(R1) ;Back to 8KB I/O page. ;+ ; Include his top-of-memory if he has less than 28KW. ;- 10$: CMP $MEMSZ(R5),#<56.*KB> ;Does he have full memory? BHIS 20$ ;Yes, then don't conflict with I/O. MOV #<^RMEM>,(R1)+ ;** MEMTOP ** MOV #<^RTOP>,(R1)+ CLR (R1)+ ;No high order address. MOV $MEMSZ(R5),(R1)+ ;Get the memory size. .REPT 3 ASL -(R1) ;Shift left 6 bits for actual ASL (R1)+ ; address .ENDR CLR (R1)+ ;Top indicator has no size. CLR (R1)+ ;Skip TYPE field ;+ ; Include all loaded device handlers except for those within RMON. ;- 20$: MOV S.PNAM(R5),R3 ;Get offset to $PNAME table. ADD R5,R3 ;R3 -> $PNAME. CLR R2 ;Set flag to determine if handler CLR (PC)+ ;PNAME size counter PSIZ: .WORD 0 30$: INC PSIZ ;Keep track of table index. CMP (R3)+,#-1 ;At end of table? BNE 30$ ASR PSIZ ;Yes, calc size of PNAME INC PSIZ MOV S.PNAM(R5),R3 ;Get offset to $PNAME table. ADD R5,R3 ;R3 -> $PNAME. 40$: DEC PSIZ BEQ 80$ ;All done? Go to next section. MOV (R3)+,(R1) ;No, move device name to sort table. BEQ 40$ ;Branch if it's a blank entry INC R2 ;Keep track of table index for SY .DSTAT #AREA+1,R1 ;Find out about this device. ; real devices/not logical names BCS 40$ ;Device not installed so continue. SUB #6,AREA+4 ;Is handler loaded? + calc real addr. BLO 40$ ;No, so ignore it. CMP R2,#2 ;Is this the system device handler? BEQ 50$ ;Branch if yes ;*JMP* CMP #<^RUB>,@R1 ;Is this the UB handler? BEQ 70$ ;Branch if yes to include in table ;*JMP* CMP #<^RPI >,@R1 ;Is this the PI handler? BNE 60$ ;No, so continue MOV AREA+4,(PC)+ ;Yes then save its base for later. PIDVBS: .WORD 0 ; : Base of PI handler BR 70$ ;And include even though in RMON. 50$: MOV AREA+4,(PC)+ ;Save system device's base for later. SYDVBS: .WORD 0 ; : Base of system device. BR 70$ ;And include even though in RMON. 60$: CMP AREA+4,R5 ;Is this handler in RMON? BHIS 40$ ;Yes, then ignore it. 70$: ADD #2,R1 ;Name uses only one word. CLR (R1)+ ;Flag it as a device name. CLR (R1)+ ;It is in RADIX 50. MOV AREA+4,(R1)+ ;Store the address in sort table. MOV AREA+2,(R1)+ ;Store the handler size. CLR (R1)+ ;Skip TYPE field BR 40$ ;Continue scanning $PNAME. ;+ ; Add the resident monitor itself. ;- 80$: MOV #<^RRMO>,(R1)+ ;** RMON ** MOV #<^RN >,(R1)+ CLR (R1)+ ;No high order (its in words). MOV R5,(R1)+ ;Store base of RMON. MOV PIDVBS,@R1 ;Assume PI handler is resident BNE 90$ ;Branch if it is resident MOV SYDVBS,(R1) ;Calc size of RMON, from base of 90$: SUB R5,(R1)+ ;RMON to system or PI = RMON size. CLR (R1)+ ;Skip TYPE field ;+ ; Add the USR if it is set to noswap. ;- BIT #C1.USR,$CNFG1(R5) ;Is the USR loaded? BEQ 100$ ;No, then its not in memory. MOV #<^RUSR>,(R1)+ ;Save name of USR. CLR (R1)+ ;Its only three characters. CLR (R1)+ ;Only a 16-bit address... MOV $USRLC(R5),(R1)+ ;Base address, in bytes... MOV $USRSZ(R5),(R1)+ ;Size in bytes... CLR (R1)+ ;Skip TYPE field ;+ ; Add foreground and/or system jobs. ;- 100$: CLR R2 ;Get # jobs supported under BISB $JOBS(R5),R2 ;this monitor. CMP #1,R2 ;Single background job monitor? BEQ 160$ ;BR if yes: no other jobs to look at. ASL R2 ;multiply by 2 for .GTJB 110$: SUB #2,R2 ;Move to next lower job. BEQ 160$ ;Don't do the background. .GTJB #AREA,#BUFFER,R2 ;Get the info about the job. BCS 110$ ;No such job, so continue next. BIT #SY.SJB,$SYSGN(R5) ;Got system job support? BEQ 140$ ;No, so don't get the job name. MOV #BUFFER+22,R3 ;R3 -> Job name in ASCII 120$: MOVB (R3)+,(R1) ;Move a character over. BNE 130$ ;Was it a null? MOVB #BLANK,(R1) ;Yes, then space it out. 130$: INC R1 ;Point to the next position. CMP R3,#BUFFER+22+6 ;All 6 characters transferred? BLO 120$ ;No, go transfer another. BR 150$ ;Yes, then go get address values. 140$: MOV #<^RF >,(R1)+ ;set the name to foreground. CLR (R1)+ ;** F ** CLR (R1)+ 150$: MOV BUFFER+10,(R1)+ ;Starts at impure area and... MOV BUFFER+02,(R1) ;goes up to the high limit. SUB BUFFER+10,(R1)+ ;So its in size. CLR (R1)+ ;Skip TYPE field BR 110$ ;+ ; Add holes in low memory from low memory allocation list. ;- 160$: MOV $MEMPT(R5),R2 ;R2 = offset from RMON to free list. ADD R5,R2 ;Make it an absolute address. MOV R2,(PC)+ ;Save address of start of list. .CORPT: .WORD 0 ADD #2,R2 ;Point to next block in list. 170$: MOV R2,R3 ;Copy pointer to previous block. MOV @R3,R2 ;R2 -> to next free block. CMP R2,.CORPT ;Back at start of list? BEQ 180$ ;Yes, then all done. CMP (R2)+,#2 ;Enough to be worth mentioning? BLE 170$ ;No, continue through the list. MOV #<^R...>,(R1)+ ;Yes, enter the name *HOLE* MOV #<^R...>,(R1)+ CLR (R1)+ SUB #2,R2 ;Back to start (we auto inced past). MOV R2,(R1)+ ;Where it is. MOV (R2)+,(R1)+ ;How big it is. CLR (R1)+ ;Skip TYPE field BR 170$ ;Continue in the search. ;+ ; Store the background area. ;- 180$: MOV #<^R..B>,(R1)+ ;** BACKGROUND ** MOV #<^RG..>,(R1)+ CLR (R1)+ MOV #1000,(R1)+ ;By default, it starts at 1000. MOV BG.SIZ,(R1)+ ;Size is a much as the .SETTOP got. CLR (R1)+ ;Skip TYPE field ;+ ; Go sort the table. ;- CALL TSORT ;Terminate and sort the table. ;+ ; Print the memory layout ;- .PRINT #MEMHTX ;Output a header. .PRINT #CRLF .PRINT #MEMHLI ;Underline it .PRINT #CRLF CLR (PC)+ ;Indicate low memory printout. HIFLAG: .WORD 0 ; : Flag to indicate high/low printout CALL TPRINT ;Go print the table. RETURN ;Return to the caller. .DSABL LSB ;+ ; Subroutine to print a memory table. ; ; SRTBUF contains a list of entries 6 words in length terminated ; with a zero. ; ; +---------------+ ; | | ; : entry 1 : ; | | ; +---------------+ ; | | ; : entry 2 : ; | | ; +---------------+ ; : : ; : : ; : : ; +---------------+ ; | | ; : entry n : ; | | ; +---------------+ ; | 0 | ; +---------------+ ; ; Each entry in SRTBUF has the following format: ; ; +---------------+ ; | NAME | ; +---------------+ ; | NAME | ; +---------------+ ; | NAME | ; +---------------+ ; | ADDRESS | ; +---------------+ ; | SIZE | ; +---------------+ ; | TYPE | ; +---------------+ ; ; WHERE: NAME can be up to 6 character long and is represented in ; either RADIX-50 or ASCII. When NAME is in RADIX-50, the ; third NAME word is zero (0). ; ; TYPE has the following format: ; ; +-------------------+-+-+-+-+-+-+ ; | | | | | | | | ; +-------------------+-+-+-+-+-+-+ ; ^ ^ ^ ^ ^ ^ ; | | | | | | ; CACHE BYPASS --------+ | | | | | ; SHARE -----------------+ | | | | ; PRIVATE -----------------+ | | | ; HARDWARE ------------------+ | | ; PERMANENT -------------------+ | ; AUTOMATIC GLOBAL ELIMINATION --+ ; ;- .ENABL LSB TPRINT: MOV SRTBUF,R1 ;Reset to point to start of table. 10$: FORMAT #BUFFER,<[B] >,<6(R1)> ;Make memory address printable. TST 4(R1) ;Is the name already in ASCII? BNE 20$ ;Yes, go get the name. FORMAT ,<[R]>, ;Make RADIX 50 name printable. BR 30$ 20$: FORMAT ,<[S]>, ;Make ASCII name printable. 30$: TST HIFLAG ;Is this high or low memory printout? BNE 40$ ;Go do high memory if not zero. MOV 10(R1),R2 ;Get the element size. BEQ 90$ ;Don't print anything if size 0 CLC ;Do low memory printout. ROR R2 ;Convert to words. FORMAT ,< [D5].>, ;Make the size printable. BR 90$ ;Go print the report. 40$: MOVB #ZERO,BUFFER+6 ;Add the low order bits for a high MOVB #ZERO,BUFFER+7 ; memory address. MOV 10(R1),R2 ;Get the element size. BEQ 90$ ;Don't print anything if size 0 CLR (PC)+ ;Assume even number of 32 word blocks. 50$: .WORD 0 ;Don't lose resolution during MUL/DIV. CLC ;Don't shift in the carry. ROR R2 ;Convert to 64 word blocks. BCC 60$ ;It was even, don't add odd guy in. ADD #32.,50$ ;Count the odd numbered 32 words. 60$: MUL #64.,R2 ;Signed conversion to words. DIV #1000.,R2 ;Make into high/low precision. ADD 50$,R3 ;Add in last 32 word block. CMP R3,#1000. ;Did the low order get too big? BLT 70$ ;No then don't adjust. SUB #1000.,R3 ;Subtract off the overflow. INC R2 ;Add it to the high order. 70$: FORMAT ,< [D5][D3].>, ;Make the size printable. TST R2 ;Was R2 zero? BNE 80$ ;No, then don't care. MOVB #40,-5(R0) ;Yes, then make leading 0 a space. BR 90$ ;If high order bits are blank, don't ; add leading 0's to low order. 80$: CMP R3,#100. ;Is R3 less than 100? BGE 90$ ;No, then don't care. MOVB #ZERO,-4(R0) ;Yes,then make leading space a 0. CMP R3,#10. ;Is R3 less than 10? BGE 90$ ;No, then don't care. MOVB #ZERO,-3(R0) ;Yes, then make leading space a 0. 90$: MOV R1,-(SP) ;Save table pointer ADD #12,R1 ;C=0 Point to TYPE MOV @R1,R1 ;C=0 Get TYPE word BEQ 93$ ;C=0 Branch if no TYPE MOV #TYPTBL,R2 ;C=0 Point to TYPE RAD50 table 91$: ROR R1 ;Is low bit set? BCC 92$ ;Branch if not FORMAT ,< [R] >, ;Make the TYPE printable.. 92$: TST (R2)+ ;Point to next TYPE in RAD50 table TST R1 ;C=0 Done? BNE 91$ ;C=0 Branch if not 93$: MOV (SP)+,R1 ;Restore table pointer ;Convert % to . (FORMAT error) 100$: CMPB -(R0),#'% ;Is it a %? BNE 110$ ;No, then go see if we're done. MOVB #'.,(R0) ;Yes, then convert to a . 110$: CMP R0,#BUFFER ;No, then at start of buffer? BHI 100$ ;No, then continue .PRINT #BUFFER ;Print the buffer. ADD #SBESIZ*2,R1 ;Move to the next entry. TST @R1 ;All done? BEQ 120$ ;Yes JMP 10$ ;No, go do some more. 120$: RETURN ;Yes, then continue. .DSABL LSB ;+ ; Subroutine to Terminate and sort the table. ;- ;+ ; Terminate the table with nulls ;- TSORT: .REPT SBESIZ CLR (R1)+ ;Terminate the table with zeros. .ENDR ;+ ; Sort the table into descending order. Using Quicker sort method. ;- 10$: CLR R2 ;R2 is the "done" flag 20$: MOV SRTBUF,R1 ;Move to the start of the table. 30$: CMP 6(R1),(R1) ;Ok, so who is the biggest eh? BHIS 50$ ;First one is so don't swap. DEC R2 ;Record the fact we're gonna swap. MOV #SBESIZ,R3 ;R3 = number of elements per entry. 40$: MOV (R1),-(SP) ;Save top entry on stack. MOV (R1),(R1)+ ;Swap bottom for top. MOV (SP)+,(R1) ;Swap top for bottom. DEC R3 ;All elements swapped? BGT 40$ ;No, continue. BR 20$ ;Yes, restart at the start. 50$: ADD #,R1 ;Move to the next entry. TST (R1) ;Past end of table? BNE 30$ ;No, then continue this pass. TST R2 ;Was the table sorted this time. BNE 10$ ;No, then start at the beginning. ;+ ; Adjust job sizes (GETJOB lies for virtual jobs). ;- TST ADJLO ;Are we sorting low memory? BEQ 70$ ;No, then don't adjust. MOV SRTBUF,R1 ;R1 -> sort buffer again. 60$: TST (R1) ;Is there an entry following? BEQ 70$ ;No, go exit. MOV 6(R1),R2 ;Get this entry's address. SUB (R1),R2 ;Subtract the next entry's. MOV R2,(R1) ;Store the corrected size. ADD #,R1 ;Move to the next entry. BR 60$ ;Continue until all checked. 70$: RETURN ;Return to the caller. .SBTTL PURE DATA .PSECT MEMPUR,D .MACRO MKBTBL NAME NAME'BIT= BITMSK BITMSK= BITMSK * 2 .RAD50 /'NAME'/ .ENDM BITMSK= 1 ; START WITH BIT 0 TYPTBL: MKBTBL AGE ; TABLE FOR TYPE FIELD IN SRTBUF MKBTBL PRM MKBTBL HDW MKBTBL PVT MKBTBL SHR MKBTBL LOC MKBTBL BYP RAD50$: .RAD50 /$ / .END