home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol073 / icopy.asm < prev    next >
Assembly Source File  |  1984-04-29  |  9KB  |  456 lines

  1. ;************************************************************************
  2. ;                                    *
  3. ;               ISIS II TO CPM                        *
  4. ;             FILE COPY UTILITY                        *
  5. ;                                    *
  6. ;                VERSION 2.2                        *
  7. ;    Modified by Rod Whitworth to allow nomination of the        *
  8. ;    drive & file of origin and destination. An input file        *
  9. ;    cannot reside on drive A: and a name must be given.        *
  10. ;    The output file defaults to A:nnnnnnnn.typ (named as         *
  11. ;    in the input). The output drive name is also optional        *
  12. ;    The original program also transferred only whole sectors    *
  13. ;    causing garbage to be placed on end of files: fixed now.    *
  14. ;************************************************************************
  15. cdisk    equ    4        ;logged disk stored here
  16.  
  17. FALSE    EQU    0
  18. TRUE    EQU    NOT FALSE
  19. LOGICAL    EQU    TRUE        ;SET TRUE IF SECTORS INCREMENTED IN BIOS
  20.  
  21.     ORG    100H
  22. ICOPY:    LXI    SP,STACK    ;SET STACK
  23.     LDA    CDISK        ;WHERE LOGGED
  24.     STA    ODISK        ;SAVED FOR LATER
  25.     LDA    TFCB
  26.     ORA    A
  27.     JZ    EXIT        ; NO FILE SPECIFIED
  28.     SUI    1
  29.     STA    DRNUM        ;INPUT DRIVE
  30.     MOV    C,A        ;SELECT DISK
  31.     LXI    D,0        ;IN CASE NOT LOGGED IN
  32.     CALL    SDSK
  33.     CALL    VALID        ;SEE IF IT'S OK FOR INPUT
  34.     CALL    HOME        ;HOME INPUT DISK
  35.     LDA    OFCB+1        ;IS THERE A NAME
  36.     CPI    20H        ;IF NOT IT'S A SPACE & WE CAN
  37.     LXI    D,TFCB        ;USE THE OLD NAME
  38.     JZ    OTRAN        ;BY JUMPING AROUND
  39.     LXI    D,OFCB        ;POINT TO OUTPUT DISK & NAME
  40. OTRAN:    LXI    H,VFCB        ;POINT TO OUR FCB
  41.     MVI    B,16
  42.     CALL    MOVE        ;PUT IT SAFELY AWAY
  43.     LDA    OFCB        ;FIND THE REAL DESTINATION DISK
  44.     STA    VFCB        ;MAYBE REDUNDANT BUT SO WHAT ??
  45.     ORA    A        ;IS IT DEFAULT ?
  46.     JZ    STDSK
  47.     SUI    1        ;OR DOES IT NEED ADJUSTMENT ?
  48. STDSK:    STA    DESTN        ;READY FOR SET-UP
  49.     XRA    A
  50.     STA    VFCB+32        ;SET CURRENT RECORD TO ZERO
  51.     LXI    D,DIRLNK    ;POINT TO DIR LINK BLOCK LINK
  52.     LXI    H,DBCA        ;DIR BCA
  53.     CALL    GLB        ;GET LINK BLOCK
  54. ICL0:    LXI    H,DBCA        ;DIR BCA
  55.     CALL    GDB        ;GET DIR BLOCK
  56.     JC    NOTF        ;NO MORE DIR BLOCKS, ERR
  57.     LXI    H,DBUF        ;DIR BUFFER
  58.     SHLD    DENT        ;SAVE IN POINTER
  59.     MVI    A,8        ;NUMBER OF  ENTRIES/BLOCK
  60.     STA    DCNT        ;SAVE
  61. ICL1:    LHLD    DENT        ;GET DIR ENTRY PTR
  62.     MOV    A,M        ;GET STATUS BYTE
  63.     CPI    00        ;ACTIVE?
  64.     JNZ    ILN1        ;NO, GET NEXT ENTRY
  65.     INX    H        ;POINT TO FN
  66.     LXI    D,TFCB+1    ;POINT TO ENTERED FN
  67.     MVI    B,6        ;FN SIZE
  68.     CALL    FCHK        ;TEST FN
  69.     JNZ    ILN1        ;NO, GET NEXT ENTRY
  70.     LHLD    DENT        ;GET DIR ENTRY ADDR
  71.     LXI    D,7        ;OFFSET TO EXT.
  72.     DAD    D        ;ADDR OF EXT.
  73.     LXI    D,TFCB+1+8    ;EXT
  74.     MVI    B,3        ;SIZE OF EXT.
  75.     CALL    FCHK        ;TEST EXT
  76.     JZ    ICL2        ;OK, FOUND FILE
  77. ILN1:    LHLD    DENT        ;POINTER TO ENTRY
  78.     LXI    D,16        ;SIZE OF ENTRY
  79.     DAD    D        ;POINT TO NEXT ENTRY
  80.     SHLD    DENT
  81.     LDA    DCNT        ;ENTRY COUNTER
  82.     DCR    A        ;DECREMENT
  83.     STA    DCNT
  84.     JNZ    ICL1        ;LOOP
  85.     JMP    ICL0
  86.  
  87. NOTF:    LXI    D,MSG1
  88.     MVI    C,09
  89.     CALL    CPM
  90.     JMP    EXIT
  91.  
  92. IOERR:    LXI    D,MSG2
  93.     MVI    C,09
  94.     CALL    CPM
  95.     JMP    EXIT
  96.  
  97.  
  98. ICL2:    LHLD    DENT        ;GET DIR ENTRY ADDRESS
  99.     LXI    D,11        ;OFFSET TO BYTE COUNT OF LAST BLOCK
  100.     DAD    D
  101.     MOV    A,M
  102.     STA    LASTX        ;# OF BYTES IN LAST TRANSFER
  103.     INX    H        ;POINT TO BLOCK COUNT
  104.     MOV    E,M
  105.     INX    H
  106.     MOV    D,M        ;BLOCK COUNT IN DE
  107.     XCHG
  108.     SHLD    BCNT        ;SAVE BLOCK COUNT
  109.     INX    D        ;POINT TO LINK BLOCK LINK
  110.     LXI    H,FBCA        ;FILE BCA
  111.     CALL    GLB        ;GET LINK BLOCK
  112.     LDA    DESTN
  113.     MOV    C,A        ;OUTPUT DISK #
  114.     CALL    SDSK        ;SET DISK
  115.     LXI    D,VFCB        ;POINT TO FCB
  116.     MVI    C,DELETE    ;BYE TO ANY OLD ONE
  117.     CALL    CPM
  118.     LXI    D,VFCB
  119.     MVI    C,CREATE
  120.     CALL    CPM        ;CREATE FILE
  121.     CPI    0FFH        ;ERROR?
  122.     JZ    IOERR
  123. ICL3:    LXI    H,FBCA        ;POINT TO BCA
  124.     CALL    GDB        ;GET DATA BLOCK
  125.     JC    DONE        ;FINS
  126.     LXI    D,FBUF        ;COPY FBUF TO TBUF
  127.     LXI    H,TBUF
  128.     LDA    XFERC        ;TRANSFER SIZE
  129.     MOV    B,A
  130.     CPI    128
  131.     CNZ    FLAST        ;FILL BUFF WITH EOF IF SHORT
  132.     CALL    MOVE
  133.     LDA    DESTN
  134.     MOV    C,A
  135.     CALL    SDSK        ;SET DISK FOR OUTPUT
  136.     LXI    D,VFCB
  137.     MVI    C,WRITE
  138.     CALL    CPM        ;WRITE THE BLOCK ON CPM
  139.     ORA    A
  140.     JNZ    IOERR
  141.     LHLD    BCNT        ;GET BLOCK COUNT
  142.     DCX    H        ;DECREMENT
  143.     SHLD    BCNT
  144.     MOV    A,H
  145.     CPI    0        ;TEST FOR DONE
  146.     JNZ    ICL3        ;NO, LOOP
  147.     MOV    A,L
  148.     CPI    1
  149.     JZ    CSWAP
  150.     CPI    0
  151.     JNZ    ICL3
  152. DONE:    LDA    DESTN
  153.     MOV    C,A
  154.     CALL    SDSK        ;SET DISK FOR OUTPUT
  155.     LXI    D,VFCB        ;FCB
  156.     MVI    C,CLOSE
  157.     CALL    CPM
  158. EXIT:    LDA    ODISK
  159.     MOV    C,A        
  160.     CALL    SDSK        ;FORCE LOGIN TO ORIGINAL DISK
  161.     JMP    BOOT        ;FINISHED
  162.  
  163. ;***************************************;
  164. ;
  165. ;           GLB - GET LINK BLOCK
  166. ;
  167. ;         DE= A(LINK TO LINK BLOCK)
  168. ;         HL= A(BLOCK CONTROL AREA)
  169. ;
  170. ;***************************************;
  171. GLB:    SHLD    BCAP        ;SAVE BCA ADDR
  172.     CALL    SEEKR        ;READ LINK BLOCK
  173.     LHLD    BCAP        ;GET BCA ADDR
  174.     LXI    D,BCBL        ;OFFSET TO LINK BUFFER
  175.     DAD    D
  176.     LXI    D,TBUF
  177.     MVI    B,128
  178.     CALL    MOVE        ;COPY TO LINK BUFFER
  179.     LHLD    BCAP        ;GET BCA ADDR
  180.     LXI    D,BCBL+4    ;OFFSET TO FIRST DATA LINK
  181.     XCHG
  182.     DAD    D        ;DE=A(FIRST DATA LINK)
  183.     XCHG
  184.     LXI    B,BCAL        ;OFFSET TO LINK PTR
  185.     DAD    B
  186.     MOV    M,E
  187.     INX    H
  188.     MOV    M,D        ;SET LINK PTR
  189.     LHLD    BCAP        ;BCA ADDR
  190.     LXI    D,BCALC        ;LINK COUNT
  191.     DAD    D
  192.     MVI    M,62        ;NO OF LINKS
  193.     RET
  194.  
  195. ;****************************************:
  196. ;
  197. ;            GDB:   GET DATA BLOCK
  198. ;
  199. ;            HL= A(BLOCK CONTROL AREA)
  200. ;
  201. ;****************************************;
  202.  
  203. GDB:    SHLD    BCAP        ;SAVE BCA ADDR
  204.     LXI    D,BCAL        ;OFFSET TO LINK BUF
  205.     DAD    D
  206.     MOV    E,M
  207.     INX    H
  208.     MOV    D,M        ;GET LINK ADDR
  209.     PUSH    D        ;SAVE LINK ADDR
  210.     LDAX    D        ;GET LINK BYTE
  211.     INX    D
  212.     MOV    C,A
  213.     LDAX    D        ;GET ANOTHER LINK BYTE
  214.     ORA    C        ;TEST FOR ZERO LINK
  215.     POP    D
  216.     JZ    GDBE        ;END, EXIT
  217.     PUSH    D        ;SAVE D AGAIN
  218.     PUSH    H
  219.     CALL    SEEKR        ;GET DATA BLOCK
  220.     POP    H
  221.     POP    D
  222.     INX    D
  223.     INX    D
  224.     MOV    M,D
  225.     DCX    H
  226.     MOV    M,E        ;UPDATE LINK PRT
  227.     LHLD    BCAP        ;GET BCA ADDR
  228.     LXI    D,BCBD        ;OFFSET TO DATA BUF
  229.     DAD    D
  230.     LXI    D,TBUF
  231.     MVI    B,128
  232.     CALL    MOVE        ;COPY DATA TO BUF
  233.     LHLD    BCAP        ;GET BCA ADDR
  234.     LXI    D,BCALC        ;LINK COUNT
  235.     DAD    D
  236.     DCR    M        ;DECREMENT
  237.     RNZ            ;OK, CONTINUE
  238.     LHLD    BCAP        ;GET BCA ADDR
  239.     LXI    D,BCBL+2    ;POINT TO LINK BUF
  240.     DAD    D
  241.     MOV    E,M        ;GET LINK
  242.     INX    H
  243.     MOV    D,M
  244.     DCX    H
  245.     MOV    E,A
  246.     ORA    D        ;TEST FOR ZERO LINK
  247.     JZ    GDBE        ;END, EXIT
  248.     XCHG            ;DE = A(NEXT LINK)
  249.     LHLD    BCAP        ;BCA ADDR
  250.     CALL    GLB        ;GET LINK BLOCK
  251.     RET
  252.  
  253. GDBE:    STC            ;INDICATE EOF
  254.     RET
  255.  
  256. ;************************************;
  257. ;
  258. ;       FCHK:   FILE ID CHECK
  259. ;
  260. ;       DE = A(ISIS FILE ID)
  261. ;    HL = A(CPM FILE ID)
  262. ;    B = SIZE OF FIELD
  263. ;
  264. ;*************************************;
  265.  
  266. FCHK:    XCHG
  267. FCK1:    LDAX    D        ;GET BYTE
  268.     CPI    00        ;SEE IF END OF ID
  269.     JNZ    FCK2        ;YES, SEE IF END OK
  270.     MOV    A,M        ;GET BYTE
  271.     CPI    ' '        ;END BOTH
  272.     RZ            ;DONE
  273.     ORA    1
  274.     RET            ;DONE
  275. FCK2:    CMP    M        ;COMPARE
  276.     RNZ            ;N,G.
  277.     INX    D
  278.     INX    H
  279.     DCR    B        ;DECREMENT COUNT
  280.     JNZ    FCK1
  281.     RET
  282.  
  283. ;***************************************;
  284. ;
  285. ;         SEEKR:   SEEK DISK BLOCK
  286. ;
  287. ;         DE = A(LINK)
  288. ;
  289. ;***************************************;
  290.  
  291. SEEKR:    PUSH    D        ;SAVE DE
  292.     LDA    DRNUM
  293.     MOV    C,A
  294.     LXI    D,1        ;WE'VE BEEN HERE BEFORE
  295.     CALL    SDSK
  296.     POP    D
  297.     PUSH    D
  298.     LDAX    D        ;GET SECTOR
  299.     MOV    C,A
  300.     CALL    SSEC        ;SET SECTOR
  301.     POP    D
  302.     PUSH    D
  303.     INX    D
  304.     LDAX    D        ;GET TRACK
  305.     MOV    C,A
  306.     CALL    STRK
  307.     CALL    READ        ;READ BLOCK
  308.     POP    D
  309.     RET
  310. ;************************************************
  311. ;                        *
  312. ;    FLAST: SET UP BUFFER FOR LAST BLOCK    *
  313. ;    INITIALISE TO 1AH (CP/M EOF)        *
  314. ;    PRIOR TO TRANSFER OF REAL DATA        *
  315. ;                        *
  316. ;************************************************
  317.  
  318. FLAST:
  319.     PUSH    H
  320.     LXI    H,TBUF
  321.     MVI    A,128
  322. EOFL:    MVI    M,01AH
  323.     INX    H
  324.     DCR    A
  325.     JNZ    EOFL
  326.     POP    H
  327.     RET
  328. CSWAP:            ;DOES THE COUNT CORRECTION FOR 
  329.             ;THE LAST BLOCK
  330.     LDA    LASTX
  331.     STA    XFERC
  332.     JMP    ICL3
  333.  
  334. ;*****************************************;
  335. ;
  336. ;       MOVE:   MOVE DATA
  337. ;
  338. ;    DE = A (SOURCE)
  339. ;    HL = A(DEST)
  340. ;    B = COUNT
  341. ;
  342. ;******************************************;
  343.  
  344. MOVE:    LDAX    D        ;GET BYTE
  345.     MOV    M,A        ;STORE BYTE
  346.     INX    H
  347.     INX    D        ;BUMP PTRS
  348.     DCR    B        ;DECREMENT COUNT
  349.     JNZ    MOVE
  350.     RET
  351.  
  352. ;*******************************************;
  353. ;
  354. ;    CPM INTERFACE ROUTINES
  355. ;
  356. ;*******************************************;
  357. VALID:    ;CHECKS DPB TO SEE IF SS/SD FLOPPY AND EXIT IF NOT
  358.     ;HL = 0 IF NOT SELECTABLE ELSE -> DPH ADDR
  359.     MOV    A,H
  360.     ORA    L
  361.     JZ    DONE        ;GO TO CPM
  362.     LXI    D,10
  363.     DAD    D
  364.     MOV    A,M
  365.     INX    H
  366.     MOV    H,M
  367.     MOV    L,A        ;HL -> DPB
  368.     MOV    A,M
  369.     CPI    26
  370.     JNZ    DONE        ;IF NOT 26 SPT
  371.     INX    H
  372.     MOV    A,M
  373.     ORA    A
  374.     JNZ    DONE        ;HIGH BYTE OF SPT
  375.     LXI    D,4
  376.     DAD    D
  377.     MOV    A,M
  378.     CPI    242        ;SINGLE DENSITY DSM
  379.     JNZ    DONE
  380.     RET            ;PRETTY GOOD CHANCE IT'S OK NOW
  381.  
  382.  
  383. SDSK:    LHLD    0001H        ;GET BIOS ADDR
  384.     MVI    L,1BH
  385.     PCHL
  386. SSEC:    LHLD    0001H
  387.     MVI    L,21H
  388.     IF    LOGICAL        ;USED TO REDUCE THE SECTOR #
  389.     DCR    C        ;IF THE BIOS INCREMENTS IT
  390.     ENDIF            ;TO 'CORRECT' LOGICAL TO PHYSICAL
  391.     PCHL
  392. STRK:    LHLD    0001H
  393.     MVI    L,1EH
  394.     PCHL
  395. READ:    LHLD    0001H
  396.     MVI    L,27H
  397.     PCHL
  398. HOME:    LHLD    0001H
  399.     MVI    L,18H
  400.     PCHL
  401.  
  402. ;******************************************;
  403. ;
  404. ;    BLOCK CONTROL AREA DEFINITIONS
  405. ;
  406. ;******************************************;
  407.  
  408. BCA    EQU    0
  409. BCAL    EQU    0
  410. BCALC    EQU    BCAL+2
  411. BCBL    EQU    BCALC+1
  412. BCBD    EQU    BCBL+128
  413.  
  414. ;******************************************;
  415. ;
  416. ;            DATA
  417. ;
  418. ;******************************************;
  419. MSG1:    DB    'FILE NOT FOUND',0DH,0AH,'$'
  420. MSG2:    DB    'I/O ERROR',0DH,0AH,'$'
  421.  
  422. XFERC:    DB    128        ;INITIAL BLOCK SIZE MODIFIED FOR LAST
  423. LASTX:    DS    1        ;BYTE COUNT OF LAST RECORD
  424. DRNUM    DS    1        ;INPUT DRIVE
  425. DESTN    DS    1        ;OUTPUT DRIVE
  426. ODISK    DB    0        ;PROBLY A:
  427. DIRLNK:    DB    01,01
  428. DENT:    DS    2
  429. DCNT:    DS    1
  430. BCNT:    DS    2
  431. BCAP:    DS    2
  432.     DS    64
  433. STACK    EQU    $
  434.  
  435. DBCA:    DS    2
  436.     DS    1
  437.     DS    128
  438. DBUF:    DS    128
  439.  
  440. FBCA:    DS    2
  441.     DS    1
  442.     DS    128
  443. FBUF:    DS    128
  444. VFCB    DS    36
  445.  
  446. TBUF    EQU    0080H
  447. TFCB    EQU    005CH
  448. OFCB    EQU    006CH    ;OUTPUT FILE DRIVE AND [NAME]
  449. CPM    EQU    0005H
  450. BOOT    EQU    0000H
  451. CREATE    EQU    22
  452. WRITE    EQU    21
  453. CLOSE    EQU    16
  454. DELETE    EQU    19
  455.     END
  456.