*
* TYPE: Display file/memory/disk on console or list device
*
* ?COPY.TXT 1983-2005 Dave Dunfield
* **See COPY.TXT**.
*
PAGSIZ  EQU 22      PAGE SIZE
ESCCHR  EQU $1B     ESCAPE CHARACTER
TAB EQU $09     TAB CHARACTER
CR  EQU $0D     CARRIAGE RETURN
LF  EQU $0A     LINE-FEED
* DIRECTORY ENTRY STRUCTURE
    ORG 0
DPREFIX RMB 8       DIRECTRY PREFIX
DNAME   RMB 8       FILENAME
DTYPE   RMB 3       FILETYPE
DDADR   RMB 2       DISK ADDRESS
DRADR   RMB 2       RUN ADDRESS
DATTR   RMB 1       FILE ATTRIBUTES
*
    ORG OSUTIL      DOS UTILITY RUN AREA
TYPE    CMPA    #'?'        QUERY?
    BNE QUAL        SHOW HOW IT'S DONE
    SSR 25      DISPLAY MESSAGE
    FCC 'Use: TYPE[/DISK/DUMP/MEMORY/PAGE] <file> or'
    FCCZ    ' <address> [<device>]'
    RTS
* PARSE FOR COMMAND QUALIFIERS
QUAL    LDA ,Y      GET CHAR FROM COMMAND LINE
    CMPA    #'/'        IS IT A QUALIFIER?
    BNE MAIN        NO, GET PARAMETERS
    LDX #QTABLE     POINT TO QUALIFIER TABLE
    SSR 18      LOOK IT UP
    CMPB    #QMAX       IS IT IN RANGE
    BHS QERR        IF SO, IT'S INVALID
    LDX #QFLAGS     POINT TO QUALIFIER FLAGS
    CLR B,X     SET THE FLAG
    BRA QUAL        LOOK FOR ANOTHER QUALIFIER
QERR    SSR 24      DISPLAY MESSAGE
    FCCZ    /Invalid qualifier: '/
    LDA ,Y+     GET CHARACTER
DSQU1   SSR 33      DISPLAY
    SSR 5       GET NEXT CHAR
    BEQ GOABO       END, EXIT
    CMPA    #'/'        START OF ANOTHER QUALIFIER?
    BNE DSQU1       NO, KEEP DUMPING
GOABO   SSR 25      DISPLAY MESSAGE
    FCCZ    /'/     CLOSING QUOTE
    LDA #1      INVALID OPERAND RETURN CODE
    RTS
* MAIN PGM
MAIN    STS SAVSTK      SAVE STACK
    SSR 40      GET DEFAULT DEVICE
    STA >DEVICE     SET DEFAULT
    CLRA            ZERO HIGH
    CLRB            ZERO LOW
    STD MEMADR      INIT TO ZERO OFFSET
    LDA MEMORY      ARE WE REFERENCING MEMORY?
    BEQ MEMREF      IF SO, DISPLAY IT
    LDA DISK        ARE WE DISPLAYING DATA FROM DISK
    BNE GETFIL      NO, GET FILENAME
* READ ABSOLUTE DISK ADDRESES
    SSR 8       GET ADDRESS
    LBNE    ABORT       ERROR, QUIT
    BSR GETDEV      GET DEVICE
    TFR X,D     COPY TO D
    BRA DMPF1       DUMP IT
* GET DEVICE IF ANY
GETDEV  PSHS    X
    SSR 4       MORE OPERANDS?
    BEQ GETD1       NO, EXIT
    SSR 6       GET DEVICE ID
    LBNE    ABORT       ERROR
    BITB    #7      INSURE IN RANGE
    STB >DEVICE     SET NEW DEVICE
GETD1   PULS    X,PC
* DISPLAY MEMORY
MEMREF  SSR 7       GET ADDRESS
    LBNE    ABORT       GET UPSET IF INVALID
    STX MEMADR      SAVE MEMORY ADDRESS
    BSR GETDEV      GET DEVICE
MEMGO   BSR DMPRAM      DISPLAY IT
    BRA MEMGO       CONTINUE
* DISPLAY A FILE
GETFIL  SSR 10      GET FILENAME
    LBNE    ABORT       ERROR, QUIT
    BSR GETDEV      GET DEVICE
    SSR 70      LOOKUP FOR READ
    LBNE    ABORT       IF NOT THERE, QUIT
    LDD DDADR,X     GET ADDRESS
DMPF1   STD SECTOR      SAVE SECTOR NUMBER
    LDX #WRKSPC     POINT TO IT
    SSR 92      READ A WORK SECTOR
    BSR DMPRAM      DISPLAY THIS PORTION
    LDD SECTOR      GET SECTOR NUMBER BACK
    SSR 77      GET NEXT SECTOR NUMBER
    BEQ DMPEND      END OF FILE, QUIT
    CMPD    #0      NO MORE?
    BNE DMPF1       GET THIS ONE
DMPEND  CLRA            ZERO RETURN CODE
    RTS
*
* DUMPS RAM POINTED TO BY X, FOR ONE 1 SECTOR SIZE
*
DMPRAM  TST DUMP        ARE WE DUMPING IN HEX FORMAT
    BEQ DUMPH       IF SO, DUMP IN HEX
* DUMP AS ASCII TEXT
    LDY #512        1 SECTOR
    LDB LINPOS      GET LINE POSITION
DSPASC1 LDA ,X+     GET DATA
    LBMI    XQUIT       END OF FILE
    CMPA    #' '        PRINTABLE CHARACTER?
    BHS DSPASC4     YES, ITS OK
* CHECK FOR CARRIAGE RETURN (END OF LINE)
    CMPA    #$0D        CARRIAGE RETURN?
    BNE DSPASC2     NO, TRY NEXT
    LBSR    CHKPAG      CHECK FOR PAGE STOP
    CLRB            ZERO LINE POSITION
    BRA DSPASC5     AND EXIT
* CHECK FOR TAB AND SKIP TO TAB STOP
DSPASC2 CMPA    #TAB        IS IT A TAB?
    BNE DSPASC5     NO, TRY NEXT
    LDA #' '        INDICATE SPACE
DSPASC3 BSR OUTPUT      WRITE THE SPACE
    INCB            ADVANCE COUNT
    BITB    #%00000111  AT NEXT TAB STOP?
    BNE DSPASC3     NO, KEEP GOING
    BRA DSPASC5     TEST AGAIN
* NORMAL CHARACTER TO OUTPUT
DSPASC4 INCB            ADVANCE COUNT
    BSR OUTPUT      DISPLAY
DSPASC5 LEAY    -1,Y        BACKUP
    BNE DSPASC1     CONTINUE LOOKING
    STB LINPOS      RESAVE POSITION
    RTS
*
* DUMP IN HEX
*
DUMPH   LDY #32     32 LINES/SECTOR
DMP0    LDD MEMADR      GET MEMORY ADDRESS
    BSR HEXOUT      DISPLAY IT
    TFR B,A     GET LOW ADDRESS
    BSR HEXOUT      DISPLAY IT
    LDD MEMADR      GET ADDRESS BACK
    ADDD    #16     ADD 16 BYTES
    STD MEMADR      RESAVE
    LDB #16     GET NUMBER BYTES/LINE
    PSHS    B,X     SAVE
DMP1    LDA #' '        GET SPACE
    BITB    #$03        AT A FOUR BYTE BOUNDARY?
    BNE NOT4        NO, SKIP IT
    BSR OUTPUT      EXTRA SPACE
NOT4    BSR OUTPUT      SPACE
    LDA ,X+     GET CHAR FROM RAM
    BSR HEXOUT      DISPLAY IT
    DECB            REDUCE COUNT
    BNE DMP1        CONTINUE
    LDA #' '        SPACE
    BSR OUTPUT      DISPLAY
    BSR OUTPUT      DISPLAY
    BSR OUTPUT      DISPLAY
    BSR OUTPUT      DISPLAY
    PULS    B,X     RESTORE REGS
DMP2    LDA ,X+     GET CHAR
    CMPA    #' '        < SPACE
    BLO UPRT        NOT PRINTABLE
    CMPA    #$7F        DELETE?
    BLO PRTOK       OK TO DISPLAY
UPRT    LDA #'.'        CONVERT TO DOT
PRTOK   BSR OUTPUT      DISPLAY
    DECB            REDUCE COUNT
    BNE DMP2        CONTINUE
    BSR CHKPAG      NEWLINE & CHECK PAGE
    LEAY    -1,Y        BACKUP A LINE
    BNE DMP0        CONTINUE
EPAGE   RTS
* OUTPUT CONTENTS OF ACCA IN HEX
HEXOUT  PSHS    A       SAVE IT
    RORA
    RORA
    RORA
    RORA            SHIFT UPPER NIBBLE INTO LOWER
    BSR HOUT        DISPLAY NIBBLE
    PULS    A       RESTORE A
HOUT    ANDA    #$0F        MASK OFF CRAP
    ADDA    #'0'        CONVERT TO ASCII
    CMPA    #'9'        OVER NUMERIC?
    BLS OUTPUT      OK TO DISPLAY
    ADDA    #$7     CONVERT TO ALPHA
* OUTPUT ROUTINE
OUTPUT  PSHS    B       SAVE REGS
    LDB >DEVICE
    SSR 36      OUTPUT TO DEVICE
    PULS    B,PC        RESTORE REGS
* CHECK FOR PAGE END OR <ESCAPE> ABORT COMMAND
CHKPAG  LDA #$0A        LINE-FEED
    BSR OUTPUT      WRITE IT OUT
    LDA #$0D        CARRIAGE RETURN
    BSR OUTPUT      WRITE IT OUT
    LDA PAGE        ARE WE PAGEING
    BNE CHKP1       DON'T PAGE IT
    DEC PAGPOS      TEST FOR PAGE UNDERFLOW
    BNE CHKP1       NO PAGE YET
    LDA #PAGSIZ     RESTORE PAGE SIZE
    STA PAGPOS      SAVE PAGE POSITION
    SSR 34      WAIT FOR A KEY
    BRA CHKP2       AND CONTINUE
CHKP1   SSR 35      IS THERE A CHARACTER
CHKP2   CMPA    #ESCCHR     IS IT AN ESCAPE?
    BNE EPAGE       NO, SKIP IT
    SSR 25      DISPLAY MESSAGE
    FCCZ    '<Aborted>'
* EXIT WITH ZERO RETURN CODE
XQUIT   CLRA            ZERO RC
ABORT   LDS SAVSTK      GET STACK POINTER BACK
    TSTA            SET FLAGS FOR RETURN CODE
    RTS
* QUALIFIER TABLE
QTABLE  FCB $82
    FCC '/PAGE'
    FCB $82
    FCC '/DUMP'
    FCB $82
    FCC '/DISK'
    FCB $82
    FCC '/MEMORY'
    FCB $80     END OF TABLE
QMAX    EQU 4       LARGEST QUALIFIER VALUE
* QUALIFIER FLAGS
QFLAGS  EQU *
PAGE    FCB $FF     PAGE OUTPUT
DUMP    FCB $FF     DUMP IN HEX FORMAT
DISK    FCB $FF     DISPLAY FROM DISK
MEMORY  FCB $FF     DISPLAY MEMORY
*
LINPOS  FCB 0       POSITION IN LINE
PAGPOS  FCB PAGSIZ      POSITION IN PAGE
DEVICE  RMB 1       OUTPUT DEVICE NUMBER
MEMADR  RMB 2       MEMORY ADDRESS
SECTOR  RMB 2       CURRENT SECTOR
SAVSTK  RMB 2       SAVED STACK POINTER
*
WRKSPC  EQU *       WORK AREA
