;*************************** AMUS Program Label ******************************
; Filename: MFDSRT                                          Date: 5/25/92
; Category: UTIL         Hash Code: 031-506-264-074      Version: 1.0(102)
; Initials: GR/AM        Name: JAMES A. JARBOE IV
; Company: EDUCATIONAL VIDEO NETWORK               Telephone #: 4092955767
; Related Files:
; Min. Op. Sys.: 2.X                           Expertise Level: INT
; Special: Only works on AMOS 2.x
; Description: Sequences PPNs on traditional and extended format devices for
; AMOS 2.x. Sequences PPNs on extended directories so directory listings are
; in PPN order.
;*****************************************************************************
;*; Updated on 25-May-92 at 11:36 AM by James A. Jarboe I V; edit time: 4:51:21
;***************************************************************************
;*                                                                         *
;*                              MFDSRT.M68                                 *
;*                                                                         *
;*                     Written By: James A. Jarboe IV                      *
;*                            1401 19th Street                             *
;*                          Huntsville, TX 77340                           *
;*                              409-295-5767                               *
;*                                                                         *
;*                               21-Apr-92                                 *
;*                                 GR/AM                                   *
;***************************************************************************
;
; Description:   Sequences MFD's for Traditional and Extended devices.
;                Because I was getting tired of seeing directory displays
;                and listings out of order on extended directories.
;
; Edit History:
;
;[102] 25-May-92 by James A. Jarboe IV
;                Added check to see if user did complete filespec.
;                Worked fine if they included it, but they shouldn't.
;
;[101] 23-May-92 by James A. Jarboe IV.
;                Added check for AMOS 2.x (only works on AMOS 2.x)
;                Added check for non-structured devices.
;                Added check for mounted device.
;                Set DDB flag to not abort on errors so we can DSKDRU.
;
;[100] 21-Apr-92 by James A. Jarboe IV.
;                Works.
;
;***************************************************************************
;                                                                          *
;                            S Y M B O L I C S                             *
;                                                                          *
;***************************************************************************
;

       SEARCH  SYS                     ; Get AMOS symbolics.
       SEARCH  SYSSYM                  ; Get AMOS symbolics.

       AMOS2.X1        =       1
       AMOS2.X2        =       2

IF EQ,  AMOS2.X2-AMOS2.X1,  ASMERP "?Must assemble with AMOS 2.x assembler."

       PAGE
;***************************************************************************
;                                                                          *
;                              V E R S I O N                               *
;                                                                          *
;***************************************************************************
;

       VMAJOR  =       1.
       VMINOR  =       0.
       VSUB    =       0.
       VEDIT   =       102.
       VWHO    =       0.


       PAGE
;***************************************************************************
;                                                                          *
;                               M A C R O ' S                              *
;                                                                          *
;***************************************************************************
;
DEFINE  PRTTAB  ROW, COL
       MOVW    #<ROW_8.+COL>, D1       ; Set up row column or TCRT call.
       TCRT
ENDM

DEFINE  DIM
       PRTTAB  -1,11.                  ; Dim.
ENDM

DEFINE  BRIGHT
       PRTTAB  -1,12.                  ; Bright.
ENDM

DEFINE  PRTPPN  ADDB
       DIM                             ; Dim.
       TYPE    [
       BRIGHT                          ; Bright.
       PRPPN   ADDB                    ; Output ppn.
       DIM                             ; Dim.
       TYPE    ]
ENDM


       PAGE
;***************************************************************************
;                                                                          *
;                       C O N S T A N T    V A L U E S                     *
;                                                                          *
;***************************************************************************
;

       MX.MFD  =       3200.           ; MFD block number storage size.
       MX.NUM  =       63.             ; PPNs per traditional block.
       MX.ENM  =       13.             ; PPNs per extended block.
       MX.BPT  =       8.              ; Bytes per traditional PPN.
       MX.BPE  =       38.             ; Bytes per extended PPN.

       PAGE
;***************************************************************************
;                                                                          *
;                           I M P U R E   A R E A                          *
;                                                                          *
;***************************************************************************
;

OFINI
OFDEF   MQ.DDB, D.DDB                   ; Device specification.
OFDEF   MQ.BUF, MX.MFD                  ; Mfd Block storage buffer.
OFDEF   MQ.FRE, 4                       ; Address of free memory.
OFDEF   MQ.END, 4                       ; Address of end of memory.
OFDEF   MQ.NUM, 4                       ; Number of ppns processed.
OFDEF   MQ.DEL, 4                       ; Number of deleted ppns.
OFDEF   MQ.DEV, DC.SIZ                  ; Device characteristics.
OFSIZ   MQ.SIZ                          ; Size of impure area.


       PAGE
;***************************************************************************
;                                                                          *
;                        P R O G R A M    S T A R T                        *
;                                                                          *
;***************************************************************************
;
; Sequence MFD's
;
MFDSRT: PHDR    -1,0,PH$REE!PH$REU

       GETIMP MQ.SIZ,A5                ; Get impure area.

       BYP                             ; Bypass junk
       TRM                             ; Anything there?
       JEQ     HELPEM                  ; No..helpem.
       CMPB    @A2, #'/                ; Slash?
       JEQ     HELPEM                  ; Yes..helpem.
       CMPB    @A2, #'?                ; Question?
       JEQ     HELPEM                  ; Yes..helpem.

       MOV     SYSTEM, D7              ; Get system flags.
       AND     #SY$EXD, D7             ; Supports extended directory?
       JEQ     NO.VER                  ; No..report we're not 1.x compatible.

       FSPEC   MQ.DDB(A5)              ; Get device spec.

       TST     D.FIL+MQ.DDB(A5)        ; Filename there?
       JNE     DINGEM
       TSTW    D.EXT+MQ.DDB(A5)        ; Extension there?
       JNE     DINGEM
       TSTW    D.PPN+MQ.DDB(A5)        ; Ppn there?
       JNE     DINGEM

       .NONET  MQ.DDB(A5)              ; Restrict to local system.

       INIT    MQ.DDB(A5)              ; Initialize ddb.

       DEVCHR  MQ.DDB(A5), MQ.DEV(A5)  ; Get device characteristics.

       MOV     MQ.DEV+DC.FLG(A5), D7   ; Get Device flags.
       AND     #DC$FSD, D7             ; Is device file structured?
       JEQ     NO.STRUC                ; No..report not file structured.

       MOV     MQ.DEV+DC.FLG(A5), D7   ; Get device flags.
       AND     #DC$MNT, D7             ; Is device mounted?
       JEQ     NO.MNT                  ; No..report device not mounted.

       PRTTAB  -1,0                    ; Clear screen.

       PRTTAB  1,1                     ; Set row 1.
       DIM                             ;
       TYPE    <Working on >
       CALL    DEV.NAME
       TYPESP
       CALL    SHOW.DEV.TYPE           ; Show device format type.

       ORB     #<D$ERC>,D.FLG+MQ.DDB(A5) ; No abort on error.

; Lock directory structure.

       DSKDRL  MQ.DDB(A5)              ; Lock directory structure.
       MOV     #1,MQ.DDB+D.REC(A5)     ; Set first block.

       USREND  A4                      ; Get end of memory address.
       SUB     #1024., A4              ; Make sure.
       MOV     A4, MQ.END(A5)          ; Save end of useable memory.

       USRFRE  A4                      ; Get free memory.
       MOV     A4, MQ.FRE(A5)          ; Save free memory address.
       LEA     A3, MQ.BUF(A5)          ; Index MFD block buffer.
       CLR     D0                      ; Clear counter.

       PAGE
;****************
; MFD.LOOP      *
;****************
;
; Read a traditional MFD format or an extended MFD format.
;
;  Description:
;       Read MFD's storing the complete PPN structure for each PPN
;       starting at the USRFRE area. The MFD block link structure for
;       each MFD block is stored starting at MQ.BUF for traditional MFD's.
;
;
;  Incoming:
;
;         A3 -> Indexes MFD block number storage area.
;         A4 -> Indexes free memory area for PPN data storage.
;
;  During:
;         A0 -> MFD block structure.
;         D3 := size of PPN structure per MFD block.
;  Outgoing:
;
;         D0 =: Number of PPN's processed.
;         A3 -> Indexes end of Stored MFD block numbers.
;         A4 -> Indexes end of PPN data list.
;
MFD.LOOP:
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     8$                      ; No..do traditional.
       MOV     MQ.DDB+D.REC(A5), (A3)+ ; Store extended next block.
       MOV     #<MX.ENM - 1>, D5       ; Dbf adjusted count of PPN's
       MOV     #MX.BPE, D3             ; Set bytes per extended MFD.
       BR      9$                      ; Read block.

8$:     MOVW    MQ.DDB+D.REC+2(A5),(A3)+; Save MFD block.
       MOV     #<MX.NUM - 1>,D5        ; Set num of ppns per block. (dbf adj)
       MOV     #MX.BPT, D3             ; Set bytes per traditional MFD.

9$:     READ    MQ.DDB(A5)              ; Read block.
       JNE     DSK.REL                 ; Release lock on error.
       MOV     MQ.DDB+D.BUF(A5),A0     ; Set DDB buffer address.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     10$                     ; No..do traditional.
       ADD     #4, A0                  ; Offset traditional format.

10$:    TSTW    @A0                     ; End of PPNs?
       BEQ     40$                     ; Yes..
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended format.
       BEQ     15$                     ; No..do traditional.

; Test for extended format deleted PPN.
;
       MOVW    @A0, D7                 ; Get extended flag.
       ANDW    #100000, D7             ; PPN deleted?
       BEQ     20$                     ; No..show it and store it.
       BR      18$                     ; Yes..delete it.

;Test for traditional format deleted PPN.
;
15$:    CMPW    @A0,#-1                 ; Is ppn deleted?
       BNE     20$                     ; No..process ppn.

; Delete a deleted PPN from structure.
;
18$:    ADD     D3, A0                  ; Yes.. offset to to next ppn.
       ADD     #1, MQ.DEL(A5)          ; Bump delete count.
       BR      30$                     ; Do next ppn.

; Set ppn into DDB for output to terminal.
;
20$:
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended format?
       BEQ     22$                     ; No..do traditional.
       MOVW    32.(A0), MQ.DDB+D.PPN(A5) ; Set up PPN for output.
       BR      25$                     ; Show it.

22$:    MOVW    @A0,MQ.DDB+D.PPN(A5)    ; Set ppn to DDB.

; Store PPn data for sequencing.
;
25$:
       INC     D0                      ; Bump count.
       CMP     D0, #MX.MFD             ; Maxed out MFD blocks?
       JHI     NO.MEM
       MOVW    (A0)+,(A4)+             ; Save PPN data.
       MOVW    (A0)+,(A4)+             ;
       MOV     (A0)+,(A4)+             ;
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     30$                     ; No..do traditional.
       MOV     (A0)+,(A4)+             ; Save extended PPN data.
       MOV     (A0)+,(A4)+             ;
       MOV     (A0)+,(A4)+             ;
       MOV     (A0)+,(A4)+             ;
       MOV     (A0)+,(A4)+             ;
       MOV     (A0)+,(A4)+             ;
       MOVW    (A0)+,(A4)+             ;
       MOVW    (A0)+,(A4)+             ;
       MOVW    (A0)+,(A4)+             ;
       CMM     A4, MQ.END(A5)          ; End of usable memory yet?
       JHIS    NO.MEM
30$:    DBF     D5,10$                  ; Do for full block of PPNs.

; Reached end of block. Now check for possible next block of PPns.
;
40$:
       MOV     MQ.DDB+D.BUF(A5),A0     ; Reset DDB buffer.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     60$                     ; No..do traditional.

; Find next MFD block of extended format.
;
       MOV     @A0, D1                 ; Another MFD block?
       BEQ     PPN.SEQ                 ; No..time to sequence what we have.
       MOV     D1, MQ.DDB+D.REC(A5)    ; Set next block.
       BR      99$                     ; Do next block.

; Find next MFD block of traditional format.
;
60$:    MOVW    772(A0),D1              ; Set end.
       BEQ     PPN.SEQ                 ; End of PPNs.
       MOVW    D1,MQ.DDB+D.REC+2(A5)   ; Set next block of ppns.
99$:    JMP     MFD.LOOP                ; Process next block.


       PAGE
;****************
; PPN.SEQ       *
;****************
;
; Description:
;       Check to see if we processed any PPN's. If so then we
;       do a simple memory sort of the PPN data structure.
; This simple sort checks the current PPN word to see if it is higher
; than the previous PPN word in the ppn data list. If it is, it bypasses
; the current ppn in the data list. We essentially are looking for the
; possibility of a lower value PPn throughout the entire list of ppn data
; entries. Once the entire list is processed looking for the lowest PPN,
; it is written out to the new sorted ppn data list in memory and the
; PPN data in the original list is cleared to nulls.
; Then the entire process is started over again bypassing the nulled ppns
; in the data list and searching for the lowest possible PPn left in the
; original data list.
;
;  Incoming:
;
;       D0 := Number of PPNs to process.
;       D3 := size of PPN structure per MFD block.
;
;       A3 -> Indexes end of MFD block storage of MQ.BUF.
;       A4 -> End of PPN data list.
;
;  During:
;
;       D5 := Number of PPns to sort at each step.
;
;       A1 -> Indexes current original PPn data list to process.
;       A3 -> Indexes new area of sorted PPn data list.
;       A4 -> Indexes original PPn data list.
;
;
PPN.SEQ:
       MOV     D0,MQ.NUM(A5)           ; Save number of ppns processed.
       JEQ     NO.PPNS                 ; No..ppns done.

       CLR     @A3                     ; Clear end of MFD block storage.
       MOV     A4,A3                   ; Set end of PPN data list.

       MOV     MQ.FRE(A5),A4           ; Set start of PPN data list.
       MOV     A3,MQ.FRE(A5)           ; Save end of PPN data list.

10$:    MOV     #-1,D1                  ; Set high number mark.
       MOV     MQ.NUM(A5),D5           ; Set number of PPN's to process.
       MOV     A4,A1                   ; Set start of ppn list.
20$:
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended format?
       BEQ     25$                     ; No..do traditional.

       MOVW    32.(A1), D6             ; PPN already out of data list?
       BEQ     30$                     ; Yes..bump to next entry.
       BR      28$                     ; No..test PPN sequence.

25$:    MOVW    @A1,D6                  ; PPN already out of data list?
       BEQ     30$                     ; Yes..bump to next entry.

28$:    CMPW    D6,D1                   ; Is new PPN > than previous PPN?
       BHI     30$                     ; Yes..bypass this one, try next one.
       MOV     D6,D1                   ; No..save current as lowest.
       MOV     A1,A2                   ; Save address of lowest ppn value.
30$:
       ADD     D3, A1                  ; Bump to next PPN in MFD.
       DEC     D5                      ; Decrease ppns to process count.
       BNE     20$                     ; Try out full list of PPNs.

; Finished processing list for lowest PPN. Write out to memory the PPN
; data list, clear PPN data from original list, decrease ppn count and
; try for next PPN.
;
       MOV     A2,A1                   ; Reset last lowest PPN address.
       MOVW    @A1,(A3)+               ; Save PPN to free memory area.
       CLRW    (A1)+                   ; Clear old ppn from ppn list.
       MOVW    @A1,(A3)+               ; Save PPN to free memory area.
       CLRW    (A1)+                   ; Clear ppn from ppn list.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     40$                     ; Yes..can't do yet.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       MOV     @A1,(A3)+               ; Save PPN to free memory area.
       CLR     (A1)+                   ; Clear ppn from ppn list.
       MOVW    @A1,(A3)+               ; Save PPN to free memory area.
       CLRW    (A1)+                   ; Clear ppn from ppn list.
       MOVW    @A1,(A3)+               ; Save PPN to free memory area.
       CLRW    (A1)+                   ; Clear ppn from ppn list.
       MOVW    @A1,(A3)+               ; Save PPN to free memory area.
       CLRW    (A1)+                   ; Clear ppn from ppn list.

40$:    DEC     D0                      ; Any more PPN's to process.
       BNE     10$                     ; Yes..start again.

       PAGE
;****************
; PPN.OUT       *
;****************
; Finished sorting entire list of ppn's.
; Now we output the new sorted PPN data list back to the original
; MFD blocks.
;
; Incoming:
;
;       Sorted PPN data structure.
;
; During:
;
;       D0 := Number of ppns to process.
;       D5 := Number of PPNs per MFD block.
;
;       A0 -> Indexes DDB I/O buffer.
;       A3 -> Indexes MFD block list.
;       A4 -> Indexes sorted PPN data list.
;
; Outgoing:
;
;       Exit program.
;
PPN.OUT:
       MOV     #3, D2                  ; Set start row.
       MOV     #1, D4                  ; Set start column.
       LEA     A3,MQ.BUF(A5)           ; Index MFD Block list.
       MOV     MQ.FRE(A5),A4           ; Reset start of PPN data list.
       MOV     MQ.NUM(A5),D0           ; Reset number of ppns to process.
10$:
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     15$                     ; No..do traditional.
       MOV     #<MX.ENM - 1>, D5       ; Set PPN's per MFD block. (dbf adj).
       MOV     (A3)+, MQ.DDB+D.REC(A5) ; Reset block.
       BR      16$                     ; Process.

15$:    MOV     #<MX.NUM - 1>,D5        ; Set num of ppns per block. (dbf adj)
       MOVW    (A3)+,MQ.DDB+D.REC+2(A5) ; Set MFD block number.

16$:
       MOV     MQ.DDB+D.BUF(A5),A0     ; Set ddb buffer address.

       READ    MQ.DDB(A5)              ; Read block.
       JNE     DSK.REL                 ; Release lock on error.
       LEA     A6,@A0                  ; Index Block buffer.
       MOV     #176,D7                 ; Set Lwords per block.
20$:    CLR     (A6)
+                       ; Clear buffer.
       DEC     D7                      ; Decrease count.
       BNE     20$                     ; Try again.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended format?
       BEQ     30$                     ; No..do traditional.
       ADD     #4, A0                  ; Offset extended.

30$:    TSTW    MQ.DDB+D.FMT(A5)        ; Extended format?
       BEQ     32$                     ; No..do traditional.
       MOVW    32.(A4), MQ.DDB+D.PPN(A5) ; Yes..set up PPN.
       BR      33$                     ; Show it.
32$:    MOVW    @A4,MQ.DDB+D.PPN(A5)    ; Set ppn.
33$:
       CALL    SET.COL                 ; Set row/col.
       PRTPPN  MQ.DDB+D.PPN(A5)        ; Output PPN.
       MOVW    (A4)+,(A0)+             ; Set ppn to block buffer.
       MOVW    (A4)+,(A0)+             ; Set ppn to block buffer.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     35$                     ; No..do traditional.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       MOV     (A4)+,(A0)+             ; Set ppn to block buffer.
       MOVW    (A4)+,(A0)+             ; Set ppn to block buffer.
       MOVW    (A4)+,(A0)+             ; Set ppn to block buffer.
       MOVW    (A4)+,(A0)+             ; Set ppn to block buffer.

35$:    DEC     D0                      ; Finished with all ppns?
       BEQ     40$                     ; Yes..clean up.
       DBF     D5,30$                  ; Do again for entire block.

; DDB Buffer is full of PPN data.
;
; A3 -> Indexes next MFD block number
;       Which is set into last word of MFD block and then is used to
;       set up next block to read.
;
       MOV     MQ.DDB+D.BUF(A5),A0     ; Set ddb buffer.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     38$                     ; No..do traditional.
       MOV     @A3, @A0                ; Set up next MFD block.
       BR      39$                     ; Write out updated MFD block.
38$:    MOVW    @A3,772(A0)             ; Set next block to end of ppn data.
39$:    WRITE   MQ.DDB(A5)              ; Output block of sorted ppns.
       JNE     DSK.REL                 ; Release lock on error.
       JMP     10$                     ; Try for more.

; Finished all PPNs. Flush buffer.
;
40$:    WRITE   MQ.DDB(A5)              ; Output block of sorted ppns
       JNE     DSK.REL                 ; Release lock on error.
       CALL    REL.DISK                ; Release disk lock.
       CRLF                            ; Bump line.
       CRLF

       DIM
       TYPE    <Total of >
       BRIGHT
       MOV     MQ.NUM(A5), D1          ; Set number of PPN's sequenced.
       DCVT    0,OT$TRM                ; Output number.
       TYPE    < PPN>
       CMP     D1, #1                  ; Only one?
       BEQ     50$                     ; Yes..no plural.
       TYPE    <s>
50$:    DIM
       TYPE    < sequenced on >
       BRIGHT
       OFILE   MQ.DDB(A5),OT$OFD!OT$TRM ; output device name.
       DIM
       CRLF
       TST     MQ.DEL(A5)              ; Any deleted ppn's?
       BEQ     99$                     ; No..never mind.
       DIM
       TYPE    <Total of >
       BRIGHT
       MOV     MQ.DEL(A5), D1          ; Set number of ppn's deleted.
       DCVT    0,OT$TRM
       TYPE    < deleted PPN>
       CMP     D1, #1                  ; Only one?
       BEQ     80$                     ; Yes..no plural.
       TYPE    <s>
80$:    DIM
       TYPECR  < cleared.>

99$:    EXIT                            ; Exit.

       PAGE
;****************
; REL.DISK      *
;****************
;
; Clears out additional MFD blocks if they are not used after
; sorting has bumped out deleted PPN's. Then releases Directory
; disk lock.
;
; Incoming:
;            A3 => Current MFD buffer.    (most likely end)
;
; During:
;            A0 => Indexes Device buffer.
REL.DISK:
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     5$                      ; No..do traditional.
       TST     @A3                     ; Any more blocks?
       BNE     10$                     ; Yes..clear them out.
       BR      8$                      ; No..release disk lock.

5$:     TSTW    @A3                     ; Any more blocks due to deletes?
       BNE     10$                     ; Yes..clear them out.
8$:     DSKDRU  MQ.DDB(A5)              ; No..release disk lock.
       RTN                             ; Return to caller.

10$:
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended device?
       BEQ     15$                     ; No..do traditional.
       MOV     (A3)+, MQ.DDB+D.REC(A5) ; Set MFD block.
       BR      16$                     ; Read it.
15$:    MOVW    (A3)+,MQ.DDB+D.REC+2(A5) ; Set next block.
16$:    READ    MQ.DDB(A5)              ; Read mfd block.
       JNE     DSK.REL                 ; Release lock on error.
       MOV     MQ.DDB+D.BUF(A5),A0     ; Set buffer
       LEA     A6,@A0                  ; Index buffer
       MOV     #176,D7                 ; Set number of Lwords.

20$:    CLR     (A6)+                   ; Clear out block.
       DEC     D7                      ; Decrease lword count.
       BNE     20$                     ; Do until finished.
       WRITE   MQ.DDB(A5)              ; Output cleared block.
       JNE     DSK.REL                 ; Release lock on error.
       BR      REL.DISK                ; Try to release disk again.

       PAGE
;****************
; MARK.ERR      *
;****************
;
; Mark start of error.
;
MARK.ERR:
       CRLF                            ; Bump line.
       DIM                             ; Set dim output.
       TYPE    <?>
       RTN                             ; Return to caller.

       PAGE
;****************
; DEV.NAME      *
;****************
;
; Displays device name.
;
DEV.NAME:
       BRIGHT                          ; Set bright output.
       OFILE   MQ.DDB(A5), OT$TRM!OT$OFD  ; Output device name only.
       RTN                             ; Return to caller.


       PAGE
;****************
; NO.VER        *
;****************
;
; Report wrong version of AMOS.
;
NO.VER:
       CALL    MARK.ERR
       CALL    PGM.NAM
       DIM
       TYPE    < works only on >
       BRIGHT
       TYPE    <AMOS 2.x >
       DIM
       TYPECR  <operating system.>
       DIM
       EXIT

       PAGE
;****************
; NO.LOG        *
;****************
;
NO.LOG:
       CALL    MARK.ERR
       CALL    DEV.NAME
       TYPECR  < is not a logical device.>
       EXIT

       PAGE
;****************
; NO.STRUC      *
;****************
;
; Reports device not file structured.
;
NO.STRUC:
       CALL    MARK.ERR
       CALL    DEV.NAME
       TYPECR  < is not a file structured device.>
       EXIT

       PAGE
;****************
; NO.MNT        *
;****************
;
; Reports device not file structured.
;
NO.MNT:
       CALL    MARK.ERR
       CALL    DEV.NAME
       TYPECR  < is not mounted.>
       EXIT

       PAGE
;****************
; NO.MEM        *
;****************
;
; Reports not enough memory.
;
NO.MEM:
       CALL    MARK.ERR
       TYPECR  <Not enough memory to sort PPN's - Process Halted.>
       BR      DSK.REL                 ; Release lock on error.

       PAGE
;****************
; NO.PPNS       *
;****************
;
; Reports no PPN's to sort.
;
NO.PPNS:
       CALL    MARK.ERR
       CALL    DEV.NAME
       TYPECR  < currently has no PPNs to sort.>

       PAGE
;****************
; DSK.REL       *
;****************
;
; Release Disk Directory lock on error.
;
DSK.REL:
       DSKDRU  MQ.DDB(A5)              ; Release Directory lock.
       EXIT


       PAGE
;****************
; SHOW.DEB.TYPE *
;****************
;
; Display Extended or Traditional Text.
;
SHOW.DEV.TYPE:
       DIM                             ; Dim.
       TYPE    < (>
       BRIGHT
       LEA     A6, DTRA                ; Index traditional.
       TSTW    MQ.DDB+D.FMT(A5)        ; Extended format?
       BEQ     10$                     ; No..show traditional.
       LEA     A6, DEXT                ; Index Extended.
10$:    TTYL    @A6                     ; Show device type.
       DIM
       TYPECR  < Format)>
       BRIGHT
       RTN                             ; Return to caller.

DTRA:   ASCIZ   /Traditional/
DEXT:   ASCIZ   /Extended/
       EVEN

       PAGE
;****************
; SET.COL       *
;****************
;
; Set up columns for ppn display.
;
; Incoming:
;               D2 = current row.
;               D4 = current column.
; Outgoing:
;               D2 = next row or row 24.
;               D4 = next offset column or 1.
;
SET.COL:
       MOV     D2, D1                  ; Set current row.
       ROLW    D1, #8.                 ; Setup row.
       ADDB    D4, D1                  ; Set current col.
       TCRT                            ; Position cursor.
       ADD     #10., D4                ; Add offset.
       CMP     D4, #79.                ; Larger than needed?
       BLO     10$                     ; No..
       MOV     #1, D4                  ; Yes..set first column.
       CMP     D2, #24.                ; Rows exceeded?
       BHIS    10$                     ; Yes..always use last row.
       INC     D2                      ; Bump row count.
10$:
       RTN                             ; Return to caller.

       PAGE
;****************
; PGM.NAM       *
;****************
;
; Displays program name.
;
PGM.NAM:
       BRIGHT
       LEA     A1, MFDSRT-6.           ; Index program start.
       PUSH
       PUSH
       MOV     SP, A2
       UNPACK
       UNPACK
       TTYL    @SP
       POP
       POP
       RTN

       PAGE
;****************
; DINGEM        *
;****************
;
; Ring bell first.
;
DINGEM:
       MOV     #7, D1
       TTY
       CRLF
       TYPECR  <?Only Device specifications are allowed.>

       PAGE
;****************
; HELPEM        *
;****************
;
; Display Help.
;
HELPEM: CRLF                            ; Bump line.
       DIM
       TYPESP  <%Usage:>
       BRIGHT
       CALL    PGM.NAM
       TYPE    < Device:> ;
       CRLF                            ; Bump line.
       EXIT

END