;*************************** AMUS Program Label ******************************
; Filename: RENUM.M68                                       Date: 3/25/92
; Category: UTIL         Hash Code: 754-305-263-452      Version: 1.0A(103)
; Initials: PSS          Name: DENNIS W. NEDER
; Company: PROFESSIONAL SOFTWARE SYSTEMS           Telephone #: 8189575930
; Related Files: LIB.UNV
; Min. Op. Sys.: 1.3                           Expertise Level: BEG
; Special: Be sure to get LIB.UNV here in the library!
; Description: This program will renumber a sequential source file, (usually
; a BASIC or BASIC+ program), and optionally, compile the resulting file.
;
;*****************************************************************************
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; *     RENUM.M68                                                       *
; *     Program to renumber BASIC source files.                         *
; *                                                                     *
; *     Copyright (c) 1987 by Dennis W. Neder                           *
; *     Professional Software Systems                                   *
; *     Permission is granted to use and copy this program, but may     *
; *     not be sold or included with a package for resale without       *
; *     written permission of the author.                               *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; Edit History:
;[103] 07 December 1989 12:14   Edited by Dennis W. Neder
;       Added support for BASIC+ files, updated HELP screen and edit history.
;[102] 26-March-1987            Edited by Dennis W. Neder
;       "Prettied-up" /Number display
;[101] 10-March-1987            Edited by Dennis W. Neder
;       Added /Force renumber switch
;[100] 21-February-1987         Edited by Dennis W. Neder
;       Created
;
       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  LIB

; Version Information:

       VMAJOR  =       1               ; Completely rewritten
       VMINOR  =       0
       VSUB    =       1               ; 10-Mar-87
       VEDIT   =       103.            ; 26-Mar-87
       VWHO    =       0

; Equates:

       JOB=A0
       IMP=A5
       CR=15
       LF=12
       TAB=11
       SPC=40

; Impure storage:

       .OFINI
       .OFDEF  INBUF,D.DDB             ; Input buffer
       .OFDEF  OUTBUF,D.DDB            ; Output buffer
       .OFDEF  NEWNAM,6                ; Six bytes for rename
       .OFDEF  LINBUF,512.             ; Input line buffer
       .OFDEF  WRTBUF,512.             ; Output line buffer
       .OFDEF  STRT,4                  ; Starting line
       .OFDEF  INC,2                   ; Line increment
       .OFDEF  FLAGS,2                 ; Working flags
               FL.QRY=1                ; Query flag
               FL.DSP=2                ; Display flag
               FL.NUM=4                ; Display numbers flag
               FL.CMP=10               ; Compile switch
               FL.FRC=20               ; Force renumber flag           [101]
               FL.EOF=40               ; End of File flag
       .OFSIZ  IMPSIZ

HDR:    PHDR    -1,0,PH$REE!PH$REU

; Begin program here:
;
START:  CRT     #0
       NAME    HDR                     ; Program name
       CRLF
       CRT     #11.                    ; Set dim video
       CPYRGT                          ; Process copyright
       CRT     #12.                    ; Set regular video
       BYP
       LIN
       JNE     GETLIN

; Process help information here:
;
HELP:   TYPECR  <Program to renumber a sequential file.  Commonly used for BASIC source files.>
       CRLF
       TYPECR  <Calling sequence:>
;       CRLF
       TYPE    <       .RENUM>
       CRT     #11.
       TTYI
       ASCII   "{/switches} "
       BYTE    0
       EVEN
       CRT     #12.
       TYPE    <FILENM>
       CRT     #11.
       TTYI
       ASCII   "{/compile switches}"
       BYTE    0
       EVEN
       CRT     #12.
       CRLF
       CRLF
       TYPESP  <Where:>
       CRT     #11.
       TTYI
       ASCII   "/switches:"
       BYTE    CR,0
       EVEN
       CRT     #12.
       CRLF
       TAB
       CRT     #11.
       TYPE    Q
       CRT     #12.
       TYPECR  < - Query for start line, increment.  Otherwise default to 1000, 10>
       TAB
       CRT     #11.
       TYPE    D
       CRT     #12.
       TYPECR  < - Display lines as renumbered>
       TAB
       CRT     #11.
       TYPE    N
       CRT     #12.
       TYPECR  < - Display line numbers only>
       TAB
       CRT     #11.
       TYPE    C
       CRT     #12.
       TYPECR  < - Don't compile program by default if '.BAS' or '.BP' extension>
       TAB
       CRT     #11.
       TYPE    F
       CRT     #12.
       TYPECR  < - Force line numbers to all lines, even if currently un-numbered>
       TAB
       TYPESP  <NOTE:>
       CRT     #11.
       TYPE    D
       CRT     #12.
       TYPESP  < and>
       CRT     #11.
       TYPE    N
       CRT     #12.
       TYPECR  < switches are mutually exclusive.>
       CRLF
       TAB
       CRT     #11.
       TTYI
       ASCII   "/compile switches:"
       BYTE    CR,0
       EVEN
       CRT     #12.
       CRLF
       TYPECR  <       Standard COMPIL or COMPLP switches to use in program compilation.>
       CRLF
       TYPECR  <Note:  If not specified, the program first checks for a '.BAS' and then a>
       TYPECR  <       '.BP' extension.>
       EXIT

GETLIN: CMPB    @A2,#'?                 ; Help requested?
       JEQ     HELP
       GETIMP  IMPSIZ,IMP
       MOV     #1000.,STRT(IMP)        ; Load default starting line number
       MOVW    #10.,INC(IMP)           ; Load default increment
       CLRW    FLAGS(IMP)              ; Pre-clear flags

; This logic handles all switch set-up:
;
GETSW:  CMPB    @A2,#'/                 ; Switch specified?
       JNE     GETFIL
       INC     A2                      ; Bump pointer
       MOVB    @A2,D1                  ; Get byte from command line
       UCS                             ; Force upper case
       CMPB    D1,#'Q                  ; Query switch?
       BNE     10$
       BITSW   #FL.QRY,FLAGS(IMP)      ; Set query flag
       INC     A2                      ; Bump to next character
       BR      GETSW

10$:    CMPB    D1,#'D                  ; Display switch?
       BNE     20$
       BITSW   #FL.DSP,FLAGS(IMP)      ; Set display flag
       BITCW   #FL.NUM,FLAGS(IMP)      ; Clear number flag
       INC     A2                      ; Bump to next character
       BR      GETSW

20$:    CMPB    D1,#'N
       BNE     30$
       BITSW   #FL.NUM,FLAGS(IMP)      ; Set number flag
       BITCW   #FL.DSP,FLAGS(IMP)      ; Clear display flag
       INC     A2                      ; Bump to next character
       BR      GETSW

30$:    CMPB    D1,#'C
       BNE     40$
       BITSW   #FL.CMP,FLAGS(IMP)      ; Set compile flag
       INC     A2                      ; Bump to next character
       BR      GETSW

40$:    CMPB    D1,#'F                  ;                               [101]
       BNE     50$                     ;                               [101]
       BITSW   #FL.FRC,FLAGS(IMP)      ; Set force renumber flag       [101]
       INC     A2                      ;                               [101]
       BR      GETSW                   ;                               [101]

50$:    TYPECR  ?Illegal switch specified
       JMP     HELP

; Process filespec here:
;
GETFIL: BYP
       MOV     A2,A3                   ; Save filespec for later
       FSPEC   INBUF(IMP),BAS          ; Get file to renumber
       INIT    INBUF(IMP)              ; Initialize DDB
       LOOKUP  INBUF(IMP)              ; Check to see if it exists
       BEQ     10$                     ; Process this file
       MOV     A3,A2                   ; Restore pointer
       FSPEC   INBUF(IMP),BP           ; Check for BASIC+ file         [103]
       INIT    INBUF(IMP)              ;                               [103]
       LOOKUP  INBUF(IMP)              ;                               [103]
       BEQ     10$                     ;                               [103]
       TYPESP  <?File:>
       PFILE   INBUF(IMP)
       TYPECR  < not found>
       EXIT

10$:    JOBIDX  A0                      ; Get our job index pointer
       MOV     A3,A2                   ; Restore command line pointer
       FSPEC   OUTBUF(IMP)             ; Use same name for output DDB  [103]
       INIT    OUTBUF(IMP)             ; Initialize DDB
       MOVW    JOBDEV(A0),OUTBUF+D.DEV(IMP) ; Load current device
       MOVW    JOBDRV(A0),OUTBUF+D.DRV(IMP) ; Load current drive #
       MOVW    JOBUSR(A0),OUTBUF+D.PPN(IMP) ; Load current PPN
       MOVW    #[IPF],OUTBUF+D.EXT(IMP); Load new extension
       LOOKUP  OUTBUF(IMP)             ; Does this file exist?
       BNE     20$
       DSKDEL  OUTBUF(IMP)             ; Delete it

20$:    OPENI   INBUF(IMP)              ; Open file for input
       OPENO   OUTBUF(IMP)             ; Open file for output
       LEA     A1,SWITCH               ; Address switch storage
       BYP
       LIN                             ; Check for any switches
       BEQ     40$
       MOV     #10,D2                  ; Load counter, 8 bytes max

30$:    MOVB    (A2)+,(A1)+             ; Pick up next byte
       TRM                             ; Terminator?
       BEQ     40$                     ; Yes - done
       DEC     D2                      ; Check number of bytes
       BNE     30$                     ; And continue

40$:    MOVB    #0,@A1                  ; Force null at end
       BITW    #FL.QRY,FLAGS(IMP)      ; Was query flag set?
       JEQ     RENUM
       CRT     #5,#1                   ; Set cursor position

; This logic handles the entry of starting line:
;
STRTLN: TYPESP  <Enter starting line number:>

10$:    CRT     #5,#29.
       CRT     #9.
       KBD     EXIT$
       TRM                             ; Terminator entered?
       BEQ     30$                     ; Yes, use default line number
       CLR     D1                      ; Pre-clear D1
       NUM                             ; Numeric?
       BEQ     40$

20$:    MOVB    #7,D1                   ; Load up bell
       TTY
       BR      10$                     ; Go try again

30$:    CRT     #5,#29.                 ; Address cursor
       LEA     A1,STRT(IMP)            ; Address start line number
       MOV     @A1,D1                  ; Get
       DCVT    0,OT$TRM                ; Display number
       BR      50$

40$:    GTDEC
       CMP     D1,#0                   ; Check ranges of entered number
       BLOS    20$
       CMP     D1,#65534.
       BHI     20$

50$:    MOV     D1,STRT(IMP)            ; Save value

INCREM: CRT     #6,#1
       TYPESP  <           Enter increment:>

10$:    CRT     #6,#29.
       CRT     #9.
       KBD     EXIT$
       TRM                             ; Terminator entered?
       BEQ     30$                     ; Yes, use default line number
       CLR     D1                      ; Pre-clear D1
       NUM                             ; Numeric?
       BEQ     40$

20$:    MOVB    #7,D1                   ; Load up bell
       TTY
       BR      10$                     ; Go try again

30$:    CRT     #6,#29.                 ; Address cursor
       LEA     A1,INC(IMP)             ; Address start line number
       CLR     D1
       MOVW    @A1,D1                  ; Get line number
       DCVT    0,OT$TRM                ; Display number
       BR      50$

40$:    GTDEC
       CMPW    D1,#0                   ; Check ranges of entered number
       BLOS    20$
       CMPW    D1,#65534.
       BHI     20$

50$:    MOVW    D1,INC(IMP)             ; Save value

; Begin actual program renumber process here:
;
RENUM:  CTRLC   ABORT
       BITW    #FL.NUM,FLAGS(IMP)      ; Check /N(umber) switch        [102]
       BEQ     10$                     ;                               [102]
       CRT     #12.,#1                 ;                               [102]
       CRT     #11.                    ;                               [102]
       TYPE    <Original Line #:>      ;                               [102]
       CRT     #12.,#27.               ;                               [102]
       TYPE    <New Line #:>           ;                               [102]
       CRT     #12.                    ;                               [102]

10$:    CRT     #8.,#1
       CRT     #11.
       TYPESP  <Renumbering file:>
       CRT     #12.
       PFILE   INBUF(IMP)
       TYPESP
       CLR     D5                      ; Pre-clear loop counter
       BITW    #FL.DSP,FLAGS(IMP)
       BEQ     RENUM1
       CRLF

RENUM1: CTRLC   ABORT
       CALL    LODLIN                  ; Load next line from file
       LEA     A2,LINBUF(IMP)          ; Address input line storage
       TST     D2                      ; Check line size
       JEQ     CKEOF
       GTDEC                           ; Check for line number
       CMP     D1,#0                   ; No line number?
       BNE     10$                     ;                               [101]
       BITW    #FL.FRC,FLAGS(IMP)      ; Check force renumber flag     [101]
       BEQ     20$                     ;                               [101]

10$:    BITW    #FL.NUM,FLAGS(IMP)      ; Was numeric display requested?
       BEQ     20$
       PUSH    D1                      ; Save for later
       CRT     #12.,#18.               ; Position cursor               [102]
       POP     D1                      ; Restore old line number
       DCVT    0,OT$TRM                ; Display current line number
       CRT     #12.,#39.               ; Position cursor               [102]
       LEA     A1,STRT(IMP)            ; Get line number
       MOV     @A1,D1
       DCVT    0,OT$TRM                ; And display new number

; Handle new line number here:
;
20$:    CMP     D1,#0                   ; Line number exists?
       BNE     30$                     ; Yes, process line number
       BITW    #FL.FRC,FLAGS(IMP)      ; Check force renumber flag     [101]
       BNE     30$                     ; Go process new line number    [101]
       PUSH    A2                      ; Save for later
       LEA     A2,WRTBUF(IMP)          ; Address output buffer
       BR      REMNDR                  ; Process remainder of line

; Check range of new line number:
;
30$:    LEA     A1,STRT(IMP)            ; Address line number
       MOV     @A1,D1                  ; Get current line number
       AND     #^H0FFFF,D1             ; Mask off overflow
       CMP     D1,#^H0FFFF             ; Check size of D1
       BLOS    40$
       CRLF
       TYPECR  <?Line number overflow>
       MOV     #7,D1
       TTY
       JMP     ABORT

; Output new line number to buffer:
;
40$:    PUSH    A2                      ; Save input line pointer
       LEA     A2,WRTBUF(IMP)          ; Address output buffer
       DCVT    0,OT$MEM                ; Write new line number to buffer
       LEA     A1,INC(IMP)             ; Address increment value
       MOVW    @A1,D0                  ; Pick up increment
       ADD     D0,D1                   ; Add to current line number
       LEA     A1,STRT(IMP)            ; Re-address line number
       MOV     D1,@A1                  ; Replace old line number

; Process remainder of line here:
;
REMNDR: MOV     A2,A1                   ; Load pointer to output buffer
       POP     A2                      ; Restore original line pointer
       CTRLC   ABORT
       BITW    #FL.FRC,FLAGS(IMP)      ; Check force renumber flag     [101]
       BEQ     10$                     ;                               [101]
       CMPB    @A2,#SPC                ; Space following number?       [101]
       BEQ     10$                     ;                               [101]
       CMPB    @A2,#TAB                ; Tab following number?         [101]
       BEQ     10$                     ;                               [101]
       MOVB    #SPC,(A1)+              ; Then Load space character     [101]

10$:    MOVB    (A2)+,(A1)+             ; Copy up next byte
       BNE     10$                     ; Continue until end of line
       BITW    #FL.DSP,FLAGS(IMP)      ; Was display requested?
       BEQ     20$                     ; No, continue normally
       LEA     A2,WRTBUF(IMP)          ; Index output buffer
       TTYL    @A2                     ;  and display line

; Now write line to file:
;
20$:    CALL    WRTLIN                  ; Go dump line to file
       BITW    #FL.DSP,FLAGS(IMP)      ; Display flag set?
       BNE     CKEOF
       BITW    #FL.NUM,FLAGS(IMP)      ; Number flag set?
       BNE     CKEOF
       INC     D5                      ; Bump loop counter
       CMP     D5,#50.                 ; 50 lines written?
       BLO     CKEOF
       TYPE    <.>
       CLR     D5                      ; Clear counter again

; Check to see if we are at the end of file:
;
CKEOF:  BITW    #FL.EOF,FLAGS(IMP)      ; End of file flag set?
       JEQ     RENUM1
       BR      COMPIL

ABORT:  CRLF
       CALL    CLS                     ; Close working files
       DSKDEL  OUTBUF(IMP)             ; Kill renumber file
       CRLF
       TYPECR  <Renumber aborted.>
       EXIT

COMPIL: CRLF
       CALL    CLS                     ; Close working files

; This logic checks to see if we will remove the original file before
; renameing the new:
;
       JOBIDX  A0                      ; Pick up job table pointer
       MOVW    JOBDEV(A0),INBUF+D.DEV(IMP) ; Load current device
       MOVW    JOBDRV(A0),INBUF+D.DRV(IMP) ; Load current drive
       MOVW    JOBUSR(A0),INBUF+D.PPN(IMP) ; Load current PPN
       LOOKUP  INBUF(IMP)              ; Does file exist in current account?
       BNE     10$
       DSKDEL  INBUF(IMP)              ; Kill old file

10$:    MOV     OUTBUF+D.FIL(IMP),NEWNAM(IMP)  ; Load filename
       MOVW    INBUF+D.EXT(IMP),NEWNAM+4(IMP) ; Load extension
       DSKREN  OUTBUF(IMP)             ; Rename the file
       BITW    #FL.CMP,FLAGS(IMP)      ; Check compile flag
       BNE     EXIT$
       CMPW    NEWNAM+4(IMP),#[BAS]    ; Extension BAS?
       BEQ     15$                     ;                               [103]
       CMPW    NEWNAM+4(IMP),#[BP ]    ; Extension BP?                 [103]
       BNE     EXIT$
       LEA     A2,COMMND               ; Address program name          [103]
       ADD     #3,A2                   ; Address last part             [103]
       MOVB    #'P,(A2)+               ; Move in the correct           [103]
       MOVB    #'L,(A2)+               ;  compiler name                [103]
       MOVB    #'P,(A2)+               ;  (COMPLP)

15$:    LEA     A2,PRGNAM               ; Address program name          [103]
       MOVB    #40,(A2)+               ; Load a space
       LEA     A1,OUTBUF+D.FIL(IMP)
       UNPACK
       UNPACK

20$:    MOVB    -(A2),D1                ; Backup one character
       CMPB    D1,#40                  ; Space?
       BEQ     20$                     ; Continue 'till done
       INC     A2
       LEA     A1,SWITCH               ; Address storage of switches

30$:    MOVB    (A1)+,D1                ; Pick up next byte of switch
       BEQ     40$
       MOVB    D1,(A2)+                ; Load into place
       BR      30$                     ;  and continue

40$:    MOVB    #CR,(A2)+               ; Load carriage return
       MOVB    #0,@A2                  ; Load null
       CRLF
       LEA     A2,COMMND               ; Address command line
       TTYL    @A2                     ; Display,
       AMOS                            ;  and execute it!

EXIT$:  EXIT

; Subroutines:
;
; This subroutine reads in a line from the source file:
;
LODLIN: CLR     D2                      ; Pre-clear character counter
       LEA     A2,LINBUF(IMP)          ; Index line-input buffer
       MOVB    #0,@A2                  ; Begin with null line

10$:    FILIN   INBUF(A5)               ; Get next byte from file
       TST     INBUF+D.SIZ(A5)         ; End of file?
       JEQ     30$
       CMPB    D1,#CR                  ; Line feed?
       BEQ     10$                     ; Yes - get next byte
       CMPB    D1,#LF                  ; Carriage return?
       BEQ     20$                     ; Yes - finish off line
       MOVB    D1,(A2)+                ; Load character into buffer
       ADD     #1,D2                   ; Bump character counter
       BR      10$                     ; Continue

20$:    MOVB    #CR,(A2)+               ; Load carriage return
       CLRB    @A2                     ; Null at end
       ADD     #2,D2                   ; Bump line-length counter
       BR      40$

30$:    BITSW   #FL.EOF,FLAGS(IMP)      ; Signal end of file flag
       CMP     D2,#0                   ; Zero bytes loaded?
       BNE     20$                     ; No - clean up line

40$:    RTN                             ; Back to caller

; This subroutine outputs the line to a file:
;
WRTLIN: LEA     A2,WRTBUF(IMP)

10$:    MOVB    (A2)+,D1                ; Pick up next byte
       BEQ     20$
       FILOTB  OUTBUF(IMP)             ; Write the character
       BR      10$

20$:    MOVB    #LF,D1                  ; Load a line feed character
       FILOTB  OUTBUF(IMP)             ;  and write it
       RTN

; This subroutine is used to close working files:
;
CLS:    CLOSE   INBUF(IMP)              ; Source
       CLOSE   OUTBUF(IMP)             ; Destination
       RTN

; Local memory definitions:
;
COMMND: ASCII   "COMPIL"
PRGNAM: BLKB    36                      ; Storage for full filename
SWITCH: BLKB    12                      ; Storage for compile switches
       BYTE    0,0
       END