;Stscopy - Data Technology Corporation CP/M 2.2 Stscopy.
;
;       +-----------------------+
;       |                       |
;       |     S T S C O P Y     |
;       |                       |
;       +-----------------------+
;
;
;       Version number: 2.1
;       Version date:   April 16, 1981
;
;       Update date:    May 26, 1981
;                       Clear FCB before OPEN for verify.

;       Update date:    June 16, 1981
;                       Initialize DTCBIOS.
;
;       The following code is supplied to customers who
;       purchase a hard/floppy disk system from DTC.
;       Type STSCOPY HELP cr for instructions on usage.
;




VERS:   EQU     21

CR:     EQU     0Dh             ;ASCII carrriage return
LF:     EQU     0Ah             ;ASCII line feed
TAB:    EQU     9               ;ASCII HORIZONTAL TAB
EOS:    EQU     '$'             ;BDOS End of string
ERRCD:  EQU     0FFh            ;BDOS error code



;       BDOS function equates.

PRTSTR: EQU     09      ;Print String    DE = buffer address.
RDCB:   EQU     10      ;Read console buffer   DE = buffer address.
INIT:   EQU     13      ;Initialize BDOS
SELECT: EQU     14      ;Select disk drive,     DE = drive number
OPEN:   EQU     15      ;Open file   DE = FCB address.
CLOSE:  EQU     16      ;Close file,    DE = FCB
SFIRST: EQU     17      ;Search for first occurrence,   DE = FCB
SNEXT:  EQU     18      ;Search for next occurrence,    DE = FCB
DELETE: EQU     19      ;Delete file,   DE = FCB
READS:  EQU     20      ;Read sequential file    DE = FCB.
WRITES: EQU     21      ;Write sequential file, DE = FCB.
CREATE: EQU     22      ;Create file,   DE = FCB.
RENAME: EQU     23      ;Rename file,   DE = FCB.
IDRIVE: EQU     25      ;Interrogate drive
SETDMA: EQU     26      ;Set DMA address    DE = DMA address.

;       Page zero locations.

WBOOT:  EQU     0       ;Warm boot jump address.
BDOSV:  EQU     5       ;BDOS jump address.
CPMFCB: EQU     005Ch   ;Default FCB address.
DBUF:   EQU     0080h   ;Default DMA buffer.








       ORG     100h

STSCOPY:
       PUSH    PSW
       PUSH    B
       PUSH    D
       PUSH    H
       LXI     H,0
       DAD     SP
       SHLD    SYSTK           ;save system stack


       LXI     SP,STACK
       MVI     C,IDRIVE        ;Save original drive number
       CALL    BDOSV
       STA     ODRIVE
       CALL    HELPCK          ;Check for user help request.
       CALL    GFILEN          ;Get file name
       CALL    SKIPF           ;Skip do not care sectors
       CALL    RCPM            ;Read CP/M
       CALL    RBIOS           ;Read BIOS
       CALL    SYSINI          ;Initialize destination system
STSCO1:
       CALL    COMMAND         ;Do keyboard commands
       CALL    COPY            ;Copy files
       JMP     STSCO1

;       Return to system gracefully.

SYSRET:
       LDA     ODRIVE          ;Restore original drive selection
       MOV     E,A
       MVI     D,0
       MVI     C,SELECT
       CALL    BDOSV
       LHLD    SYSTK
       SPHL
       POP     H
       POP     D
       POP     B
       POP     PSW
       RET                     ;return to system





;       GFILEN - Get file name and open the file.
;
;       ENTRY   loaction 5C = filename.

GFILEN:
       LXI     D,FCB           ;Initialize FCB
       CALL    INIFCB
       LXI     H,CPMFCB
       LXI     D,FCB
       LXI     B,12
       CALL    MOVDTA          ;Move file name to FCB

       LXI     D,FCB
       MVI     C,OPEN
       CALL    BDOSV           ;Open the file
       CPI     ERRCD
       RNZ                     ;If no error

       LXI     D,OPNERR
       MVI     C,PRTSTR
       CALL    BDOSV
       JMP     SYSRET

OPNERR: DB      CR,LF,'Error on file open.',CR,LF,EOS



;       SKIPF - Skip meaningless sectors and boot sector on file.


SKIPF:
       LXI     D,DBUF
       MVI     C,SETDMA
       CALL    BDOSV           ;Set DMA address to default buffer

       MVI     A,17            ;Skip 17 sectors
SKPF1:  PUSH    PSW
       LXI     D,FCB
       MVI     C,READS
       CALL    BDOSV           ;Read a sector
       CPI     ERRCD
       JZ      SKPF2           ;If error on read
       POP     PSW
       DCR     A
       JNZ     SKPF1           ;If 16 sectors not read
       RET

SKPF2:  LXI     D,SKERR
       MVI     C,PRTSTR
       CALL    BDOSV           ;Output error message
       JMP     SYSRET

SKERR:  DB      CR,LF,'File read error sectors 0 thru 15.'
       DB      CR,LF,EOS



;       RCPM - Read CPM sectors.

RCPM:
       MVI     A,22*2
       LXI     D,CCP
RCPM1:  PUSH    PSW
       PUSH    D               ;Save buffer address
       MVI     C,SETDMA
       CALL    BDOSV           ;Set DMA address to default buffer

       LXI     D,FCB
       MVI     C,READS
       CALL    BDOSV           ;Read a sector
       CPI     ERRCD
       JZ      RCPM2           ;If error on read
       POP     D
       LXI     H,128
       DAD     D
       XCHG
       POP     PSW
       DCR     A
       JNZ     RCPM1           ;If 22*2 sectors not read
       RET

RCPM2:  LXI     D,RCERR
       MVI     C,PRTSTR
       CALL    BDOSV           ;Output error message
       JMP     SYSRET

RCERR:  DB      CR,LF,'File read error in CPM sectors (17 thru 60).'
       DB      CR,LF,EOS
       RET




;       RBIOS - Read BIOS sectors.

RBIOS:
       LXI     D,CBIOS
RBIOS1: PUSH    D               ;Save buffer address
       MVI     C,SETDMA
       CALL    BDOSV           ;Set DMA address to default buffer

       LXI     D,FCB
       MVI     C,READS
       CALL    BDOSV           ;Read a sector
       POP     D
       LXI     H,128
       DAD     D
       XCHG
       ORA     A
       JZ      RBIOS1          ;If no errors

       RET


;       COMMAND - keyboard command processor
;
COMMAND:
       LXI     D,PROMPT        ;show prompt
COM1:   CALL    INFCRT
       LXI     H,INBUFX+1      ;Get count
       MOV     C,M
       INX     H               ;Point to first character
       MOV     A,C
       ORA     A
       JZ      SYSRET
       LXI     D,DFCB          ;Parse for destination
       CALL    PARSE
       CPI     ERRCD           ;Valid descriptor?
       JZ      COM2
       MOV     A,B             ;Yes. Save destination drive
       STA     DDRIVE
       MOV     A,C             ;End of command?
       ORA     A
       JZ      COM2
       MVI     A,'='           ;No. Correct format?
       CMP     M
       JNZ     COM2
       INX     H               ;Yes. Skip separator
       DCR     C
       JZ      COM2
       LXI     D,SFCB          ;Parse for source
       CALL    PARSE
       CPI     ERRCD           ;Valid descriptor?
       JZ      COM2
       MOV     A,B             ;Yes. Save source drive
       STA     SDRIVE
       LXI     H,SFCB+1        ;Check for wild cards
       MVI     B,11
       MVI     A,'?'
COM3:
       CMP     M
       JZ      COM4
       INX     H
       DCR     B
       JNZ     COM3
COM4:   MOV     A,B             ;Set wild card flag
       STA     WILD
       RET
COM2:   LXI     D,INVMSG
       JMP     COM1


INVMSG: DB      CR,LF,'Invalid command.'
PROMPT: DB      CR,LF,'*',EOS



;       COPY - Copy selected source system files to destination system
;
COPY:
       LXI     D,COPMSG        ;If wild cards, print header.
       MVI     C,PRTSTR
       LDA     WILD
       ORA     A
       CNZ     BDOSV
       LDA     SDRIVE          ;Select source drive
       CPI     ERRCD           ;  if specified.
       JZ      COPY1
       MOV     E,A
       MVI     D,0
       MVI     C,SELECT
       CALL    BDOSV
       CPI     ERRCD
       JNZ     COPY1

       LXI     D,COPYM1        ;Select error
COPYER: MVI     C,PRTSTR        ;Print error message
       CALL    BDOSV
       MVI     A,ERRCD         ;Return error code
       RET

COPY1:                          ;Search for source file
       XRA     A               ;Initialize search occurrence
       STA     SRCOCC

COPYS:  MVI     B,0             ;Clear search count
       LDA     SRCOCC
       MOV     C,A
       INR     A               ;Increment occurrence count
       STA     SRCOCC
       PUSH    B               ;Save counts
       LXI     D,SFCB          ;Search for first occurrence
       MVI     C,SFIRST
       CALL    BDOSV
       POP     B               ;Restore counts
       CPI     ERRCD
       JNZ     COPYS1
       LXI     D,COPYM2        ;File not found.
       JMP     COPYER

COPYS1: MOV     A,B             ;This occurrence?
       CMP     C
       JZ      COPYS2
       INR     B               ;No. increment search count
       PUSH    B               ;Save counts
       LXI     D,SFCB          ;Search for next occurrence
       MVI     C,SNEXT
       CALL    BDOSV
       POP     B               ;Restore counts
       CPI     ERRCD
       MVI     A,0
       RZ                      ;Found all occurrences.
       JMP     COPYS1

COPYS2: DAD     H               ;HL=entry number, DE=end of dir. buffer
       DAD     H               ;*32 for entry offset
       DAD     H
       DAD     H
       DAD     H
       DAD     D               ;Add directory pointer
       LXI     D,-128          ;relative to beginning of dir. buffer
       DAD     D
       LXI     D,SFFCB
       LXI     B,32
       CALL    MOVDTA
       XRA     A               ;Clear next record number
       STAX    D
       LDA     WILD            ;If wild cards, print file name.
       ORA     A
       JZ      COPYS3
       LXI     H,SFFCB+1
       LXI     D,FN
       LXI     B,8
       CALL    MOVDTA
       INX     D               ;Skip '.'
       LXI     B,3
       CALL    MOVDTA
       LXI     D,FNMSG
       MVI     C,PRTSTR
       CALL    BDOSV
COPYS3:
       LXI     D,SFFCB         ;Open source file
       MVI     C,OPEN
       CALL    BDOSV
       LXI     D,COPYM3
       CPI     ERRCD
       JZ      COPYER

COPYR:  XRA     A               ;clear continuation flag
       STA     CFLAG
       LXI     D,BUFFER        ;Set buffer pointer
       LXI     B,0             ;Clear file record count.

COPYR1: PUSH    B               ;Read a record
       PUSH    D
       MVI     C,SETDMA
       CALL    BDOSV
       LXI     D,SFFCB
       MVI     C,READS
       CALL    BDOSV
       POP     D               ;Restore buffer pointer
       POP     B               ;Restore record count
       CPI     0               ;Done?
       JNZ     COPYR2
       INX     B               ;No. Increment record count
       LXI     H,128           ;Increment buffer pointer
       DAD     D
       XCHG
       LXI     H,-BUFEND       ;Buffer full?
       DAD     D
       MOV     A,H
       ORA     L
       JNZ     COPYR1
       LXI     H,CFLAG         ;Yes. Set continuation flag.
       INR     M
COPYR2:
       PUSH    B               ;Save file record count
       POP     H
       SHLD    FCNT
       MOV     A,H             ;Empty file?
       ORA     L
       JZ      COPYS

       CALL    SWSD            ;No. Switch to destination system.
       LDA     CFLAG           ;On a continuation?
       CPI     2
       JNC     COPYW
       LDA     DDRIVE          ;No. Select destination drive
       CPI     ERRCD           ;  if specified
       JZ      COPYD
       MOV     E,A
       MVI     D,0
       PUSH    D               ;Save selection
       MVI     C,INIT          ;Initialize CP/M
       CALL    BDOSV
       POP     D
       MVI     C,SELECT
       CALL    BDOSV
       CPI     ERRCD
       LXI     D,COPYM4
       JZ      COPYED
COPYD:                          ;Initialize destination file.
       LXI     D,DFFCB
       CALL    INIFCB
       LXI     D,DFFCB+1       ;Move file name
       LDA     WILD            ;If wild cards, use source name
       ORA     A
       JNZ     COPYD0
       LXI     H,DFCB+1        ;Was file name specified?
       MVI     A,' '
       CMP     M
       JNZ     COPYD1
COPYD0:
       LXI     H,SFFCB+1       ;No. Use source file name.
COPYD1:
       LXI     B,8
       CALL    MOVDTA
       LXI     H,DOLLAR        ;Set file type to $$$.
       LXI     B,3
       CALL    MOVDTA
       LXI     D,DFFCB         ;Delete any temporary file of same name
       MVI     C,DELETE
       CALL    BDOSV
       LXI     D,DFFCB         ;Create temporary file
       MVI     C,CREATE
       CALL    BDOSV
       LXI     D,COPYM5
       CPI     ERRCD
       JZ      COPYED
       LXI     D,DFFCB         ;Open destination file
       MVI     C,OPEN
       CALL    BDOSV
       LXI     D,COPYM6
       CPI     ERRCD
       JZ      COPYED

COPYW:                          ;Write buffer.
       LXI     D,BUFFER
       LHLD    FCNT            ;Initialize record count
       PUSH    H               ;Save record count
COPYW1:
       PUSH    D               ;Save buffer pointer
       MVI     C,SETDMA        ;Set dma address
       CALL    BDOSV
       LXI     D,DFFCB
       MVI     C,WRITES        ;Write a record
       CALL    BDOSV
       POP     D               ;Restore buffer pointer
       POP     H               ;Restore record count
       CPI     0
       JNZ     COPYW2          ;If write error.
       DCX     H               ;Decrement record count
       MOV     A,H
       ORA     L
       JZ      COPYW3
       PUSH    H               ;Save record count
       LXI     H,128           ;Increment buffer pointer
       DAD     D
       XCHG
       JMP     COPYW1

COPYW2:                         ;Write error
       LXI     D,COPYM7
       CPI     1
       JZ      COPYED
       LXI     D,COPYM8
       CPI     2
       JZ      COPYED
       LXI     D,COPYM5

COPYED:                         ;Error on destination system
       PUSH    D               ;Save message pointer
       CALL    SWDS            ;Switch to source system
       POP     D               ;Restore message pointer
       JMP     COPYER          ;Print error and return

COPYW3:                         ;Close destination and verify.
       LXI     D,DFFCB
       MVI     C,CLOSE
       CALL    BDOSV
       LXI     D,COPYM9
       CPI     ERRCD
       JZ      COPYED
       LXI     H,DFFCB+12      ;CLEAR FCB
       MVI     B,33-12
       XRA     A
COPYV0:
       MOV     M,A
       INX     H
       DCR     B
       JNZ     COPYV0
       LXI     D,DFFCB         ;Verify
       MVI     C,OPEN
       CALL    BDOSV
       LXI     D,COPYM6
       CPI     ERRCD
       JZ      COPYED
       LXI     D,VBUFF         ;Set dma address
       MVI     C,SETDMA
       CALL    BDOSV
       LHLD    FCNT            ;Initialize record count
       MOV     B,H
       MOV     C,L
       LXI     H,BUFFER        ;Initialize buffer pointer

COPYV:                          ;Verify record
       PUSH    H               ;Save buffer pointer
       PUSH    B               ;Save record count
       LXI     D,DFFCB
       MVI     C,READS         ;Get record
       CALL    BDOSV
       POP     B               ;Restore record count
       POP     H               ;Restore buffer pointer
       LXI     D,COPYMA
       CPI     0
       JNZ     COPYED
       PUSH    B               ;Save record count
       MVI     B,128           ;Set compare count
       LXI     D,VBUFF         ;Set compare buffer pointer
COPYV1:
       LDAX    D               ;Get destination byte
       CMP     M               ;Are they equal?
       JZ      COPYV2
       POP     B               ;Remove compare count
       LXI     D,COPYMA
       JMP     COPYED
COPYV2:
       INX     H               ;Yes. Increment buffer pointers
       INX     D
       DCR     B               ;Decrement compare count
       JNZ     COPYV1
       POP     B               ;Restore record count
       DCX     B               ;Decrement record count
       MOV     A,B
       ORA     C
       JNZ     COPYV
       LXI     D,DFFCB         ;Close destination file
       MVI     C,CLOSE
       CALL    BDOSV
       LXI     D,COPYM9
       CPI     ERRCD
       JZ      COPYED
       LXI     D,DFFCB+16      ;Setup FCB for rename
       LXI     H,DFFCB
       LXI     B,9
       CALL    MOVDTA
       LXI     H,DFCB+9        ;Was type specified?
       MVI     A,' '
       CMP     M
       JNZ     COPYN1
       LXI     H,SFFCB+9       ;No. Use source type.
COPYN1:
       LXI     B,3
       CALL    MOVDTA
       LXI     D,DFFCB+16      ;Delete any file of same name & type
       MVI     C,DELETE
       CALL    BDOSV
       LXI     D,DFFCB         ;Rename the destination file
       MVI     C,RENAME
       CALL    BDOSV
       LXI     D,COPYMB
       CPI     ERRCD
       JZ      COPYED

COPYL:  CALL    SWDS            ;Switch to source system
       LDA     CFLAG           ;Continuation?
       ORA     A
       JNZ     COPYR           ;Yes
       JMP     COPYS           ;No.  Get next occurrence.


DOLLAR: DB      '$$$'

COPMSG: DB      CR,LF,LF,'COPYING -',EOS
COPYM1: DB      CR,LF,'Source drive not ready.',EOS
COPYM2: DB      CR,LF,'File not found.',EOS
COPYM3: DB      CR,LF,'Open error on source file.',EOS
COPYM4: DB      CR,LF,'Destination drive not ready.',EOS
COPYM5: DB      CR,LF,'Destination drive directory is full.',EOS
COPYM6: DB      CR,LF,'Open error on destination file.',EOS
COPYM7: DB      CR,LF,'Error in extending destination file.',EOS
COPYM8: DB      CR,LF,'Destination disk is full.',EOS
COPYM9: DB      CR,LF,'Close error on destination file.',EOS
COPYMA: DB      CR,LF,'Verify error.',EOS
COPYMB: DB      CR,LF,'Rename error.',EOS






;       INFCRT - Output message and input from console.
;
;       ENTRY   DE = message address.
;
;       EXIT    A = First character entered (upper case).

INFCRT:
       MVI     C,PRTSTR
       CALL    BDOSV           ;Output message
       LXI     D,INBUFX
       MVI     C,RDCB
       CALL    BDOSV
       LDA     INBUFX+1
       ANA     A
       MVI     A,CR
       RZ
       LDA     INBUF
       CPI     'A'+20h
       RC                      ;If upper case
       CPI     'Z'+20h+1
       RNC                     ;If upper case
       SUI     20h             ;Fold to uppercase
       RET

INBUFX: DB      40,0
INBUF:  DS      40


;       PARSE - Parse file descriptor
;
;       Entry:  HL = address of string buffer
;               DE = address of FCB
;                C = string length
;       Exit:   A = 0ffh if illegal file descriptor or drive
;               B = drive code or 0ffh
;
PARSE:
       CALL    INIFCB          ;Initialize FCB
       INX     D               ;skip entry type
       MVI     B,0FFH          ;initialize drive code
       MOV     A,C             ;empty string?
       ORA     A
       JNZ     PARSE2
PARSE1: MVI     A,0FFh          ;yes. return error code
       RET

PARSE2: MVI     A,1             ;drive specified?
       CMP     C
       JNC     PARSE3
       INX     H               ;maybe
       MOV     A,M             ;Is second character ':'?
       DCX     H
       CPI     ':'
       JNZ     PARSE3
       CALL    GETFDC          ;Yes. Get drive character
       SUI     'A'             ;Legal drive #?
       JM      PARSE1
       CPI     16
       JNC     PARSE1
       MOV     B,A             ;Yes.  Save drive code.
       INX     H               ;Skip to file name
       DCR     C
       INX     H
       DCR     C
       JNZ     PARSE3
       XRA     A               ;done
       RET
PARSE3:
       PUSH    B               ;Save drive code
       MVI     B,8             ;Set maximum length of file name
       CALL    PARSNT          ;parse file name
       XRA     A               ;done?
       CMP     C
       JZ      PARSE4
       MVI     A,'.'           ;No. file type?
       CMP     M
       JNZ     PARSE4
       INX     H               ;Yes. parse file type
       DCR     C

       JZ      PARSE5
       MVI     B,3
       CALL    PARSNT
PARSE4: MOV     A,C             ;Save count
       POP     B               ;Restore drive code
       MOV     C,A
       XRA     A
       RET
PARSE5:
       MOV     A,C
       POP     B
       MOV     C,A
       MVI     A,0FFh
       RET


;       PARSNT - Parse file name or type
;
PARSNT: MVI     A,'*'           ;Wild card?
       CMP     M
       JNZ     PARSN3
PARSN1: INX     H               ;Yes. Skip to terminator.
       DCR     C
       JZ      PARSN2
       CALL    GETFDC
       JNZ     PARSN1
PARSN2: PUSH    B               ;Save count
       MOV     C,B             ;Fill with '?'
       MVI     B,0
       CALL    PARSEQ
       POP     B               ;Restore count
       RET
PARSN3:
       CALL    GETFDC          ;Get character
       JZ      PARSN5
       STAX    D               ;Store char
       INX     D               ;Incr. FCB pointer
       INX     H               ;Incr. string pointer
       DCR     B               ;Out of space?
       JZ      PARSN4
       DCR     C               ;Decr. string count.
       JNZ     PARSN3
       RET
PARSN4:
       CALL    GETFDC          ;Skip to terminator.
       RZ
       DCR     C
       JNZ     PARSN4
       RET
PARSN5:
       MOV     A,E             ;Adjust FCB pointer to end of field.
       ADD     B
       MOV     E,A
       RNC
       INR     D
       RET

;       PARSEQ - Fill field with '?'
;
PARSEQ: PUSH    H               ;Save string pointer
       MOV     H,D
       MOV     L,E
       MVI     A,'?'
       STAX    D
       INX     D
       DCX     B
       CALL    MOVDTA
       POP     H
       RET





;       GETFDC - Get file descriptor character
;
;       Entry:  HL = Address of FD string
;       Exit:   A = character (upper case)
;               Z = 1 iff terminator
;
GETFDC: MOV     A,M             ;Get character
       CPI     'A'+20h         ;Convert to upper case
       JC      GETFC1
       CPI     'Z'+20h
       JNC     GETFC1
       SUI     20h
GETFC1: CPI     '.'             ;Check for terminator
       RZ
       CPI     ' '
       RZ
       CPI     '='
       RZ
       CPI     '*'
       RET




;       INIFCB - Initialize FCB
;
;       Entry:  DE = Address of FCB
;
INIFCB: PUSH    H               ;Save registers
       PUSH    D
       POP     H               ;HL = FCB
       PUSH    H
       PUSH    B
       XRA     A               ;clear entry type
       MOV     M,A
       INX     H
       INX     D               ;set file name & type to spaces
       INX     D
       MVI     A,' '
       MOV     M,A
       LXI     B,10
       CALL    MOVDTA
       INX     H
       XRA     A               ;clear rest of FCB
       MOV     M,A
       INX     D
       LXI     B,20            ; and next record number
       CALL    MOVDTA
       POP     B
       POP     D               ;restore registers
       POP     H
       RET






;       MOVDTA - Move data utility program.
;
;       ENTRY   HL = Source field.
;               DE = Destination field.
;               BC = number of bytes.

MOVDTA:
       MOV     A,M
       STAX    D
       INX     H
       INX     D
       DCX     B
       MOV     A,B
       ORA     C
       JNZ     MOVDTA
       RET



;       SYSINI - Initialize destination system
;
SYSINI: CALL    SWSD            ;Switch page 0
       LXI     H,SYSIN1        ;Set BIOS initialization return
       PUSH    H
       LHLD    WBOOT+1         ;Get warm boot vector address
       DCX     H               ;Get cold boot address
       MOV     D,M
       DCX     H
       MOV     E,M
       LXI     H,-3            ;Point to STSINI entry
       DAD     D
       PCHL                    ;Initialize BIOS
SYSIN1:
       CPI     0FFh            ;Initialization error?
       JNZ     SYSIN2
       CALL    SWDS            ;Yes.  Restore source system
       LXI     D,INIMSG
       MVI     C,PRTSTR
       CALL    BDOSV
       JMP     SYSRET
SYSIN2:
       MVI     C,INIT          ;Initialize BDOS and select A
       CALL    BDOSV
       CALL    SWDS            ;Switch page 0
       RET
INIMSG: DB      CR,LF,'BIOS initialization error.', EOS



;       SWSD - Switch from source to destination system
;
SWSD:   LXI     H,0             ;Save source page 0 pointers
       LXI     D,SPZERO
       LXI     B,8
       CALL    MOVDTA
       LXI     H,DPZERO        ;Set destination page 0 pointers
SWDS1:  LXI     D,0
       LXI     B,8
       CALL    MOVDTA
       RET

;       SWDS - Switch from destination to source system
;
SWDS:   LXI     H,0             ;Save destination page 0 pointers.
       LXI     D,DPZERO
       LXI     B,8
       CALL    MOVDTA
       LXI     H,SPZERO        ;Set source page 0 pointers.
       JMP     SWDS1


;       Destination system page 0 pointers
;
DPZERO: JMP     CBIOS+3         ;BIOS entry
       DB      0               ;I/O byte
       DB      0               ;Current disk
       JMP     BDOS            ;BDOS entry


;       Source system page 0 pointers
;
SPZERO: DS      8



WILD:   DS      1               ;Wild card flag
FNMSG:  DB      CR,LF
FN:     DS      8
       DB      '.'
FT:     DS      3
       DB      EOS


SYSTK:  DS      2               ;Hold stack

ODRIVE: DS      1               ;Original drive
DDRIVE: DS      1               ;Destination drive
SDRIVE: DS      1               ;Source drive

SRCOCC: DS      1               ;Source file occurrence count
CFLAG:  DS      1               ;Continuation flag
FCNT:   DS      2               ;File record count



DFCB:   DS      33              ;destination command file name
DFFCB:  DS      33              ;destination FCB
SFCB:   DS      33              ;source command file name
SFFCB:  DS      33              ;source file FCB
FCB:    DS      33              ;STSCPM.COM FCB



       DS      50
STACK:  DS      1




;
VBUFF:  DS      128
BUFFER: DS      (CCP-$) AND 0FF00H
BUFSEC: EQU     ($-BUFFER)/128
BUFEND: EQU     BUFFER+BUFSEC*128
;
       ORG     VBUFF
;
;       Check for HELP request
;
HELPCK: LXI     H,HELPNM
       LXI     D,CPMFCB+1
       MVI     B,8
       LDAX    D               ;Was file specified?
       CPI     ' '
       JZ      HELPC2          ;No
HELPC1: CMP     M               ;Yes
       RNZ
       INX     D
       INX     H
       LDAX    D
       DCR     B
       JNZ     HELPC1
HELPC2: LXI     D,HELP          ;Print HELP message
       MVI     C,PRTSTR
       CALL    BDOSV
       JMP     SYSRET


HELPNM: DB      'HELP    '

HELP:   DB      CR,LF,LF
       DB      'STSCOPY - System-to-System file copy',CR,LF,LF
       DB      'This program provides a means of loading files onto',CR,LF
       DB      'a hard disk from floppy diskette for Data Technology',CR,LF
       DB      'Corporation customers receiving controllers that do',CR,LF
       DB      'not include floppy diskette control.  It is assumed',CR,LF
       DB      'that the customer has an operational CP/M system',CR,LF
       DB      'running with a non-DTC disk controller.',CR,LF,LF
       DB      'After FORMATting the hard disk and INSTALLing CP/M',CR,LF
       DB      'on it, edit the file CONFIG and set MSIZE to a value',CR,LF
       DB      'just below the CCP of your floppy based CP/M.  Then',CR,LF
       DB      'execute the SUBMIT file STSCOPY.SUB which will',CR,LF
       DB      'generate customized copies of STSCOPY.COM and',CR,LF
       DB      'STSCPM.COM.  (See STSCOPY.SUB for details.)',CR,LF
       DB      'To execute STSCOPY.COM, type',CR,LF
       DB      '       STSCOPY STSCPM.COM',CR,LF
       DB      'The file STSCPM.COM is read into memory and the',CR,LF
       DB      'keyboard prompt "*" is output to the console.',CR,LF
       DB      'The form of each command line is',CR,LF,LF
       DB      '       destination=source cr',CR,LF,LF
       DB      'where "destination" is the file in the STSCPM',CR,LF
       DB      'system to receive the data and "source" is the',CR,LF
       DB      'file in the floppy based CP/M system.  Disk drive',CR,LF
       DB      'names may be optionally included in the source',CR,LF
       DB      'and destination.  The destination may be null or',CR,LF
       DB      'an "unambiguous" (ufn) file reference as defined',CR,LF
       DB      'in CP/M.  The source may be a ufn or an "ambiguous"',CR,LF
       DB      '(afn) file reference.  For example',CR,LF,LF
       DB      '       x:=*.COM',CR,LF,LF
       DB      'transfers all COM files from the currently selected',CR,LF
       DB      'drive of the floppy based CP/M system to drive x',CR,LF
       DB      'of the hard disk system.  All transfers are verified',CR,LF
       DB      'by reading them back and comparing.',CR,LF,EOS

       END