;*************************** AMUS Program Label ******************************
; Filename: ADDMAP.M68                                      Date: 04/18/89
; Category: UTIL         Hash Code: 453-747-537-401      Version: 1.0
; Initials: ULTR/AM      Name: LEE PALLMANN
; Company: ULTRASOFT                               Telephone #: 5163484848
; Related Files: NONE
; Min. Op. Sys.: NA                            Expertise Level: BEG
; Special: na
; Description: Computes the size of a maped record in a basic program.
; Usage .ADDMAP {basic filename}
; where {basic filename} is a filename containing AlphaBASIC MAP statements.
; ADDMAP will tell you the record size of each record found.
;*****************************************************************************
; By Lee Pallmann, UltraSoft Corporation.  No rights reserved.
;
;  Edit history:
;       [1.0]   Written by Lee Pallmann, UltraSoft
;

       SEARCH  SYS
       SEARCH  SYSSYM

       FLOAT.FLAG=D3
       ARRAY.FLAG=D4

       VMAJOR= 1
       VMINOR= 0

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

       .OFINI
       .OFDEF  MAP.FILE,D.DDB          ; MAP file
       .OFDEF  REC.SIZE,4              ; record size
       .OFDEF  ARRAY.SIZE,4            ; array size
       .OFDEF  TEXT,512.               ; text line from MAP file
       .OFSIZ  MEMSIZ

; Define BLANK macro

DEFINE  BLANK   LABEL
       LIN
       JEQ     LABEL
       ENDM

; Define END-OF-FILE macro

DEFINE  EOF     LABEL
       TST     MAP.FILE+D.SIZ(A5)
       JEQ     LABEL
       ENDM

; Define CALL-EQUAL macro

DEFINE  CEQ     LABEL
       BNE     1$$
       CALL    LABEL
1$$:
       ENDM

;************************
;*  ALLOCATE.WORK.AREA  *
;************************
;
ALLOCATE.WORK.AREA:
       GETIMP  MEMSIZ,A5               ; allocate memory module

;**********************
;*  GET.MAP.FILENAME  *
;**********************
;
GET.MAP.FILENAME:
       BYP                             ; bypass spaces and tabs
       BLANK   HELP                    ; no argument?  go to HELP
       FSPEC   MAP.FILE(A5),MAP        ; get MAP filespec from comand line
       INIT    MAP.FILE(A5)            ; init DDB

;*******************
;*  OPEN.MAP.FILE  *
;*******************
;
OPEN.MAP.FILE:
       OPENI   MAP.FILE(A5)            ; open file

;************
;*   LOOP   *
;************
;
; Main Loop
;
LOOP:   CALL    NEXT.LINE               ; get next line of file into TEXT
       BNE     FINISHED                ; eof?
       CALL    REMOVE.LABEL            ; remove line numbers and labels
       CALL    PROCESS                 ; process line
       CTRLC   FINISHED                ; Control-C?
       BR      LOOP                    ; keep going

;**************
;*  FINISHED  *
;**************
;
FINISHED:
       CLOSE   MAP.FILE(A5)            ; close file
       CALL    OUTPUT.REC.SIZE         ; output record size
       CRLF
       EXIT

;************
;*   HELP   *
;************
;
; Describe syntax
;
HELP:   CRLF
       TYPECR  ADDMAP (C) 1988 by UltraSoft Corporation.
       TYPECR  (adds up a record and reports it's size)
       CRLF
       TYPECR  Usage:  .ADDMAP {map file}
       CRLF
       EXIT

;%%%%%%%%%%%%%%%
;%  NEXT.LINE  %
;%%%%%%%%%%%%%%%
;
; Get next line from file into TEXT.
; Sets Z-bit at eof.
;
NEXT.LINE:
       LEA     A2,TEXT(A5)             ; point A2 to TEXT
NL.INB: FILINB  MAP.FILE(A5)            ; get next byte
       EOF     NL.EOF                  ; end of file?
       MOVB    D1,(A2)+                ; store byte @A2
       CMPB    D1,#10.                 ; line feed?
       BNE     NL.INB                  ;    no - get next byte
       CLRB    @A2                     ; place null at end of string
NL.RTN: LCC     #PS.Z                   ; set Z-bit
       RTN
NL.EOF: LCC     #0                      ; clear Z-bit
       RTN

;%%%%%%%%%%%%
;%   MAP1   %
;%%%%%%%%%%%%
;
; Determine whether MAP1 line is the beginning of a new record or
; a mere stand-alone variable.  Outputs previous record's size.
;
MAP1:   CALL    OUTPUT.REC.SIZE         ; output size of record
       BYP                             ; bypass spaces and tabs
       MOV     A2,A3                   ; save A2
M1.NXT: TSTB    @A2                     ; end of string?
       BEQ     M1.OUT                  ;    yes
       CMPB    @A2,#13.                ; carriage return?
       BEQ     M1.NUL                  ;    yes
       CMPB    @A2,#'!                 ; exclamation point?
       BEQ     M1.NUL                  ;    yes
       CMPB    (A2)+,#<',>             ; comma?
       BEQ     M1.RTN                  ;    yes
       BR      M1.NXT                  ; get next char
M1.NUL: CLRB    @A2                     ; place null at end of record name
M1.OUT: MOV     A3,A2                   ; restore A2
       TTYL    @A2                     ; output record name
       TYPE    < - >
M1.RTN: CLR     REC.SIZE(A5)
       RTN

;%%%%%%%%%%%%%%%%%%%%%
;%  OUTPUT.REC.SIZE  %
;%%%%%%%%%%%%%%%%%%%%%
;
OUTPUT.REC.SIZE:
       TST     REC.SIZE(A5)            ; is record size zero?
       BEQ     OT.RTN                  ;    yes - do not output
       MOV     REC.SIZE(A5),D1         ; move record size into D1
       DCVT    0,OT$TRM                ; output record size to screen
       CRLF                            ; CR/LF
OT.RTN: RTN

;%%%%%%%%%%%%%%%
;%   PROCESS   %
;%%%%%%%%%%%%%%%
;
; Processes lines in file which begin with a MAP#.  Parses this line (TEXT)
; into variable-name, type, and size.  Adds size to REC.SIZE.
;
PROCESS:
       BYP                             ; bypass spaces and tabs
PR.MAP: CMPB    (A2)+,#'M               ; is first letter 'M'?
       JNE     PR.RTN                  ;    no - forget this line
       CMPB    (A2)+,#'A               ; is second letter 'A'?
       JNE     PR.RTN                  ;    no - forget this line
       CMPB    (A2)+,#'P               ; is third letter 'P'?
       JNE     PR.RTN                  ;    no - forget this line
       GTDEC                           ; get MAP level into D1
       TST     D1                      ; is there a map level?
       BEQ     PR.RTN                  ;    nope - this is'nt a MAP statement
       CMP     D1,#1                   ; is it a MAP1?
       JEQ     MAP1                    ;    yes
       BYP                             ;    no - bypass spaces and tabs
       CLR     ARRAY.FLAG              ; clear array flag
       CLR     ARRAY.SIZE(A5)          ; clear array size
PR.VAR: MOVB    (A2)+,D2                ; move char @A2 to D2
       BEQ     PR.RTN                  ; was it a null?
       CMPB    D2,#<'(>                ; is char a left-paren?
       CEQ     PR.ARY                  ;   yes - we have an array
       CMPB    D2,#<',>                ; is char a comma?
       BNE     PR.VAR                  ;    no - keep searching
       CLR     FLOAT.FLAG              ; clear float flag
PR.TYP: MOVB    (A2)+,D2                ; move char @A2 to D2
       BEQ     PR.CHK                  ; was it a null?
       CMPB    D2,#'F                  ; is char an 'F'?
       CEQ     PR.FLT                  ;   yes - set FLOAT.FLAG
       CMPB    D2,#'f                  ; is char an 'f'?
       CEQ     PR.FLT                  ;   yes - set FLOAT.FLAG
       CMPB    D2,#<',>                ; is it a comma?
       BNE     PR.TYP                  ;    no - keep searching
       BYP                             ; bypass tabs and spaces
PR.CHK: TST     FLOAT.FLAG              ; has float flag been set?
       BEQ     PR.SIZ                  ;    no - get size
       MOV     #6,D1                   ;    yes - assume size of 6
       BR      PR.SZ2
PR.SIZ: GTDEC                           ; get size of variable
PR.SZ2: TST     ARRAY.FLAG              ; do we have an array here?
       BEQ     PR.ADD                  ;     no -
       MOV     ARRAY.SIZE(A5),D0
       MUL     D1,D0                   ; get full array size into D1
PR.ADD: ADD     D1,REC.SIZE(A5)         ; add size to REC.SIZE
PR.RTN: RTN
PR.FLT: MOV     #-1,FLOAT.FLAG          ; variable is a floating point
       RTN                             ;   (set float flag)
PR.ARY: BYP
       GTDEC                           ; get array size
       MOV     D1,ARRAY.SIZE(A5)       ;       into ARRAY.SIZE
       MOV     #-1,ARRAY.FLAG          ; set array flag
PR.MLT: BYP
       CMPB    (A2)+,#<',>             ; is this a multidimensional array?
       BNE     PR.ART                  ;    yes - get next element
       BYP                             ; bypass spaces and tabs
       GTDEC                           ; get next dimenson's array size
       MOV     ARRAY.SIZE(A5),D0
       MUL     D1,D0                   ; multiply array.size * new array.size
       MOV     D1,ARRAY.SIZE(A5)       ; put product in ARRAY.SIZE
       BR      PR.MLT
PR.ART: RTN

;%%%%%%%%%%%%%%%%%%
;%  REMOVE.LABEL  %
;%%%%%%%%%%%%%%%%%%
;
; Remove all line numbers and labels at beginning of line (if any)
;
REMOVE.LABEL:
       LEA     A2,TEXT(A5)             ; point A2 to TEXT
RL.LIN: BYP                             ; bypass spaces and tabs
       GTDEC                           ; remove line number (if there)
       MOV     A2,A3                   ; save A2
RL.LBL: MOVB    (A2)+,D1                ;
       ALF                             ; is char alphabetic?
       BEQ     RL.LBL                  ;    yes - continue
       NUM                             ; is char numeric?
       BEQ     RL.LBL                  ;    yes - continue
       CMPB    D1,#''                  ; is char an apostrophy?
       BEQ     RL.LBL                  ;    yes - keep going
       CMPB    D1,#':                  ; is char a colon?
       BEQ     RL.RTN                  ;    yes - we have a label
       MOV     A3,A2
RL.RTN: RTN

       END