home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG008.ARK / DISKDUP.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  8KB  |  443 lines

  1.     ORG    100H
  2. CTLC    EQU    3
  3. LASTSEC    EQU    26
  4.     LXI    SP,STKTOP
  5. GO:
  6.     LXI    D,MESGA
  7.     CALL    CRPRT
  8.     CALL    CONIN
  9.     CPI    CTLC    ;IS IT CONTROL C?
  10.     JZ    0    ;REBOOT IF YES
  11.     LXI    D,MESGB
  12.     CALL    CRPRT
  13.     CALL    CONIN
  14.     CALL    COPY
  15.     JMP    GO    ;LOOP TILL CTL C
  16. ;
  17. MESGA:    DB    'SOURCE ON A, THEN RETURN $'
  18. MESGB:    DB    'DESTINATION ON B, THEN RETURN $'
  19. MESGC:    DB    'COMPARE ERROR ON TRACK $'
  20. MESGD:    DB    '(HEX) SECTOR $'
  21. MESGE:    DB    'PERMANENT $'
  22. ;
  23. CRPRT:    CALL    CRLF
  24. PRTMSG:    LDAX    D    ;GET CHAR
  25.     INX    D
  26.     CPI    '$'
  27.     RZ
  28.     PUSH    D
  29.     MOV    C,A
  30.     CALL    CONOUT
  31.     POP    D
  32.     JMP    PRTMSG    ;LOOP TILL $
  33. ;
  34. CRLF:    MVI    C,0DH
  35.     CALL    CONOUT
  36.     MVI    C,0AH
  37.     CALL    CONOUT
  38.     RET
  39. ;
  40. PRTHEX:    PUSH    PSW
  41.     RAR
  42.     RAR
  43.     RAR
  44.     RAR
  45.     CALL    PRTNBL
  46.     POP    PSW
  47. PRTNBL:    ANI    0FH
  48.     ADI    30H
  49.     CPI    3AH
  50.     JC    SML
  51.     ADI    7
  52. SML:
  53.     MOV    C,A
  54.     CALL    CONOUT
  55.     RET
  56. ;
  57. ;
  58. CONIN:    PUSH    B
  59.     PUSH    D
  60.     PUSH    H
  61.     MVI    C,01
  62.     CALL    0005H
  63.     POP    H
  64.     POP    D
  65.     POP    B
  66.     RET
  67. ;
  68. ;
  69. CONOUT:    PUSH    B
  70.     PUSH    D
  71.     PUSH    H
  72.     MOV    E,C
  73.     MVI    C,02
  74.     CALL    0005H
  75.     POP    H
  76.     POP    D
  77.     POP    B
  78.     RET
  79. ;
  80. ;
  81. COPY:
  82.     MVI    C,0
  83.     CALL    SELDSK    ;SELECT DISK A
  84.     CALL    HOME    ;AND HOME
  85.     MVI    C,1
  86.     CALL    SELDSK    ;ALSO B
  87.     CALL    HOME
  88.     MVI    A,0
  89.     STA    TRK    ;SET UP TRACK POINTER
  90. RDLOOP:    MVI    C,0
  91.     XRA    A
  92.     STA    CMPERR
  93.     CALL    SELDSK
  94.     LDA    TRK    ;GET TRACK
  95.     MOV    C,A
  96.     CALL    READT    ;READ ENTIRE TRACK
  97. RETRYW:
  98.     MVI    C,1
  99.     CALL    SELDSK
  100.     LDA    TRK
  101.     MOV    C,A
  102.     CALL    WRITET    ;WRITE TRACK
  103.     LDA    TRK
  104.     MOV    C,A
  105.     CALL    COMPT    ;REREAD AND COMPARE
  106.     JNZ    RETRYW    ;RETRY IF ERR
  107.     LDA    TRK
  108.     INR    A
  109.     STA    TRK
  110.     CPI    77    ;ARE WE DONE?
  111.     JNZ    RDLOOP    ;LOOP IF NOT
  112.     RET
  113. ;
  114. ;
  115. COMPT:    LXI    H,BUF1
  116.     CALL    RT2    ;REREAD INTO BUF1
  117.     LXI    H,BUF0
  118.     LXI    D,BUF1
  119.     LXI    B,128*LASTSEC
  120. CMPLP:    LDAX    D
  121.     CMP    M
  122.     JNZ    CERR
  123.     INX    H
  124.     INX    D
  125.     DCR    C
  126.     JNZ    CMPLP
  127.     DCR    B    ;ARE WE AT END OF BUFFER?
  128.     JNZ    CMPLP
  129.     RET
  130. CERR:    PUSH    B
  131.     LXI    D,MESGC
  132.     CALL    CRPRT
  133.     LDA    TRK
  134.     CALL    PRTHEX
  135.     LXI    D,MESGD
  136.     CALL    PRTMSG
  137.     POP    H    ;PUSHED FROM B
  138.     DAD    H    ;COMPUTE SECTOR IN ERROR
  139.     LXI    D,0FF00H
  140.     DAD    D
  141.     MVI    A,27
  142.     SUB    H
  143.     CALL    PRTHEX    ;PRINT SECTOR
  144.     LDA    CMPERR
  145.     INR    A
  146.     STA    CMPERR    ;INCREMENT ERROR COUNT
  147.     CPI    10
  148.     RNZ
  149.     LXI    D,MESGE
  150.     CALL    PRTMSG
  151.     XRA    A
  152.     RET
  153. ;
  154. ;
  155. READT:    LXI    H,BUF0    ;TRACK # IN C
  156. RT2:    SHLD    DMAAD
  157.     CALL    SETTRK
  158.     MVI    C,1
  159. RT3:    PUSH    B
  160.     CALL    SETSEC
  161.     CALL    READ
  162.     LHLD    DMAAD
  163.     LXI    D,128
  164.     DAD    D
  165.     SHLD    DMAAD
  166.     POP    B
  167.     MVI    A,LASTSEC
  168.     CMP    C
  169.     RZ
  170.     INR    C
  171.     JMP    RT3
  172. ;
  173. ;
  174. WRITET:    LXI    H,BUF0    ;TRACK # IN C
  175. WT2:    SHLD    DMAAD
  176.     CALL    SETTRK
  177.     MVI    C,1
  178. WT3:    PUSH    B
  179.     CALL    SETSEC
  180.     CALL    WRITE
  181.     LHLD    DMAAD
  182.     LXI    D,128
  183.     DAD    D
  184.     SHLD    DMAAD
  185.     POP    B
  186.     MVI    A,LASTSEC
  187.     CMP    C
  188.     RZ
  189.     INR    C
  190.     JMP    WT3
  191. CMPERR:    DB    0    ;NUMBER OF COMPARE ERRORS
  192. TRK:    DB    0
  193. STK:    DS    32
  194. STKTOP:    DB    0
  195.     ORG    400H    ;KEEP CONSTANT
  196. ;        TRACK   =  LAST SELECTED TRACK
  197. ;        SECTOR  =  LAST SELECTED SECTOR
  198. ;        DMAAD   =  LAST SELECTED DMA ADDRESS
  199. ;        DISKNO  =  LAST SELECTED DISK NUMBER
  200. ;    (NOTE THAT ALL ARE BYTE VALUES EXCEPT FOR DMAAD)
  201. ;
  202. SCRAT    DB    0,0,0,0,0,0,0,0,0,0,0    ;START OF SCRATCH AREA
  203. TRACK    EQU    SCRAT        ;CURRENT TRACK ON DRIVE 0
  204. TRAK1    EQU    TRACK+1        ;CURRENT TRACK ON DRIVE 1
  205. SECTOR    EQU    SCRAT+2        ;CURRENTLY SELECTED SECTOR
  206. DMAAD    EQU    SCRAT+3        ;CURRENT DMA ADDRESS
  207. DISKNO    EQU    SCRAT+5        ;CURRENT DISK NUMBER
  208. DUMMY    EQU    DISKNO+1    ;MUST BE 0 FOR DOUBLE ADD
  209. ;
  210. ;
  211. ;
  212. ;
  213. ;    I/O DRIVERS FOR THE DISK FOLLOW
  214. ;
  215. HOME:    ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE
  216.     LDA    DISKNO    ;SELECTED DISK
  217.     MOV    C,A    ;FOLLOW PARAMETER CONVENTIONS
  218.     CALL    SELDSK    ;ROUTINE TO SELECT THE DISK
  219. ;SET UP H,L TO POINT TO WORD WITH TRACK FOR SELECTED DISK
  220.     LXI    D,TRACK
  221.     LHLD    DISKNO
  222.     DAD    D
  223. HOMEL:
  224.     MVI    M,00    ;SET CURRENT TRACK PTR BACK TO 0
  225.     IN    127    ;READ FDC STATUS
  226.     ANI    4    ;TEST TRACK 0 BIT
  227.     RNZ        ;RETURN IF AT 0
  228.     STC        ;DIRECTION=OUT
  229.     CALL    STEP    ;STEP ONE TRACK
  230.     JMP    HOMEL    ;LOOP
  231. ;
  232. SELDSK:    ;SELECT DISK GIVEN BY REGISTER C
  233. ;MAKE SURE DUMMY IS 0 (FOR USE IN DOUBLE ADD TO H,L)
  234.     XRA    A
  235.     STA    DUMMY
  236.     MOV    A,C
  237.     STA    DISKNO
  238.     RRC        ;PUT INTO BITS 4,5
  239.     RRC
  240.     RRC
  241.     RRC
  242.     ORI    08    ;ENABLE DISK SELECT
  243.     OUT    127    ;SELECT THE DISK
  244.     RET
  245. ;
  246. SETTRK:    ;SET TRACK GIVEN BY REGISTER C
  247. ;FIRST REFERENCE CORRECT TRACK INDICATOR ACCORDING TO
  248. ;SELECTED DISK
  249.     LXI    D,TRACK    ;ADDRESS OF TRACK FOR DISK 0
  250.     LHLD    DISKNO    ;FIND OUT WHICH DISK IS SELECTED
  251.     DAD    D
  252.     MOV    A,C    ;DESIRED TRACK
  253.     CMP    M
  254.     RZ        ;WE ARE ALREADY ON THE TRACK
  255. SETTKX:
  256.     CALL    STEP    ;STEP TRACK-CARRY HAS DIRECTION
  257.             ;STEP WILL UPDATE TRACK INDICATOR
  258.     MOV    A,C
  259.     CMP    M    ;ARE WE WHERE WE WANT TO BE
  260.     JNZ    SETTKX    ;NOT YET
  261. ;HAVE STEPPED ENOUGH
  262. SEEKRT:
  263. ;DELAY 18 MSEC FOR FINAL STEP TIME AND HEAD SETTLE TIME
  264.     MVI    A,18D
  265.     CALL    DELAY
  266.     RET        ;END OF SETTRK ROUTINE
  267. ;
  268. DELAY:    ;ROUTINE TO DELAY C(A) MILLISECONDS
  269.     MVI    C,82H    ;ADJUST FOR 1 MSEC LOOP DELAY
  270.             ;THIS IS THE VALUE FOR OUR IMSAI
  271. LDXA:
  272.     DCR    C
  273.     JNZ    LDXA    ;LOOP 1 MSEC
  274.     DCR    A
  275.     JNZ    DELAY
  276.     RET        ;END OF DELAY ROUTINE
  277. ;
  278. SETSEC:    ;SET SECTOR GIVEN BY REGISTER C
  279.     MOV    A,C
  280.     STA    SECTOR
  281.     RET
  282. ;
  283. SETDMA:    ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C
  284.     MOV    L,C    ;LOW ORDER ADDRESS
  285.     MOV    H,B    ;HIGH ORDER ADDRESS
  286.     SHLD    DMAAD    ;SAVE THE ADDRESS
  287.     RET
  288. ;
  289. ;
  290. ERRORS:    DB    0    ;KEEP TRACK OF NUMBER OF ERRORS
  291. READ:    ;PERFORM READ OPERATION.
  292.     ;THIS IS SIMILAR TO WRITE, SO SET UP READ COMMAND AND USE
  293.     ;COMMON CODE IN WRITE
  294.     MVI    D,40H    ;SET READ FLAG
  295.     JMP    WAITIO    ;TO PERFORM THE ACTUAL I/O
  296. ;
  297. WRITE:    ;PERFORM A WRITE OPERATION
  298.     MVI    D,80H    ;SET WRITE COMMAND
  299. ;
  300. WAITIO:
  301. ;ENTER HERE FROM READ AND WRITE TO PERFORM THE ACTUAL I/O 
  302. ;OPERATION.  RETURN A 00H IN REGISTER A IF THE OPERATION COMPLETES
  303. ;PROPERLY, AND 01H IF AN ERROR OCCURS DURING THE READ OR WRITE
  304. ;
  305. ;IN THIS CASE, WE HAVE SAVED THE DISK NUMBER IN 'DISKNO' (0,1)
  306. ;            THE TRACK NUMBER IN 'TRACK' (0-76)
  307. ;            THE SECTOR NUMBER IN 'SECTOR' (1-26)
  308. ;            THE DMA ADDRESS IN 'DMAAD' (3-3F80H)
  309.             ;D STILL HAS R/W FLAG
  310.     MVI    A,0    ;SET ERROR COUNT
  311.     STA    ERRORS    ;RETRY SOME FAILURES 10 TIMES
  312.             ;BEFORE GIVING UP
  313. TRYAGN:
  314. ;FIRST WE HAVE TO FIGURE OUT WHICH DRIVE IS SELECTED
  315. ;AND WHICH TRACK IS DESIRED
  316.     LXI    B,TRACK
  317.     LHLD    DISKNO
  318.     DAD    B    ;H,L POINT TO CORRECT TRACK INDICATOR
  319.     MOV    A,M
  320.     PUSH    PSW    ;NEED IT LATER
  321.     LHLD    DMAAD    ;GET BUFFER ADDRESS
  322.     DCX    H    ;SAVE AND REPLACE 3 BYTES BELOW
  323.             ;BUF WITH TRACK,SECTOR,ADDRESS MARK
  324.     MOV    B,M
  325.     MVI    A,0FBH    ;ADDRESS MARK
  326.     MOV    M,A
  327.     DCX    H
  328.     MOV    C,M
  329.     LDA    SECTOR    ;NOTE THAT INVALID SECTOR NUMBER
  330.             ;WILL RESULT IN HEAD UNLOADED
  331.             ;ERROR, SO DONT CHECK
  332.     MOV    M,A
  333.     DCX    H
  334.     MOV    E,M
  335.     POP    PSW
  336.     MOV    M,A
  337.     MOV    A,H    ;SET UP FDC DMA ADDRESS
  338.     OUT    126    ;HIGH BYTE
  339.     MOV    A,L
  340.     OUT    125    ;LOW BYTE
  341.     MOV    A,D    ;GET R/W FLAG
  342.     OUT    127    ;START DISK READ/WRITE
  343. RWWAIT:    IN    127    ;READ FDC STATUS
  344.     ANI    0F8H    ;TEST FOR ANY ERROR OR IOF
  345.     JZ    RWWAIT
  346.     MOV    M,E    ;RESTORE 3 BYTES BELOW BUF
  347.     INX    H
  348.     MOV    M,C
  349.     INX    H
  350.     MOV    M,B
  351.     IN    127    ;TEST FOR ERRORS
  352.     ANI    0F0H
  353.     RZ        ;A WILL BE 0 IF NO ERRORS
  354. ;COME HERE ON ERROR FROM DISK
  355.     PUSH    D    ;SAVE READ/WRITE CODE
  356.     LXI    D,MESGE1
  357.     CALL    CRPRT
  358.     IN    127
  359.     ANI    0F0H
  360.     CALL    PRTHEX
  361.     LXI    D,MESGE2
  362.     CALL    PRTMSG
  363.     LDA    DISKNO
  364.     ADI    'A'
  365.     MOV    C,A
  366.     CALL    CONOUT
  367.     LXI    D,MESGE3
  368.     CALL    PRTMSG
  369.     LXI    D,TRACK
  370.     LHLD    DISKNO
  371.     DAD    D
  372.     MOV    A,M
  373.     CALL    PRTHEX
  374.     LXI    D,MESGE4
  375.     CALL    PRTMSG
  376.     LDA    SECTOR
  377.     CALL    PRTHEX
  378.     LDA    ERRORS
  379.     INR    A
  380.     STA    ERRORS
  381.     CPI    20
  382.     JNZ    REDO    ;RETRY    20 TIMES
  383.     POP    D
  384.     MVI    A,0FFH    ;ERROR RETURN
  385.     RET
  386. ;
  387. MESGE1:    DB    'DISK ERROR, TYPE $'
  388. MESGE2:    DB    ', ON DRIVE $'
  389. MESGE3:    DB    ', AT TRACK $'
  390. MESGE4:    DB    ', SECTOR $'
  391. REDO:
  392.     POP    D    ;GET R/W FLAG
  393.     IN    127    ;GET ERROR BITS
  394.     ANI    0E0H    ;RETRY IF NOT TRACK ERROR
  395.     JNZ    TRYAGN
  396. ;WAS A TRACK ERROR SO NEED TO RESEEK
  397.     PUSH    D    ;SAVE    READ/WRITE INDICATOR
  398. ;FIGURE OUT THE DESIRED TRACK
  399.     LXI    D,TRACK
  400.     LHLD    DISKNO    ;SELECTED DISK
  401.     DAD    D    ;POINT TO CORRECT TRACK INDICATOR
  402.     MOV    A,M    ;DESIRED TRACK
  403.     PUSH    PSW    ;SAVE IT
  404.     CALL    HOME
  405.     POP    PSW
  406.     MOV    C,A
  407.     CALL    SETTRK
  408.     POP    D    ;GET READ/WRITE INDICATOR
  409.     JMP    TRYAGN
  410. ;
  411. ;
  412. ;
  413. STEP:                ;STEP HEAD OUT TOWARDS ZERO
  414.                 ;IF CARRY IS SET; ELSE
  415.                 ;STEP IN
  416. ; H,L POINT TO CORRECT TRACK INDICATOR WORD
  417.     PUSH    PSW    ;SAVE DIRECTION
  418. STWAIT:    IN    127    ;INPUT FDC STATUS
  419.     ANI    2    ;TEST STEP READY BIT
  420.     JZ    STWAIT    ;WAIT FOR STEP READY(MAX 10 MSEC)
  421.     POP    PSW    ;GET DIRECTION TO STEP
  422.     JC    OUTX
  423.     INR    M    ;INCREMENT CURRENT TRACK BYTE
  424.     MVI    A,4    ;SET DIRECTION = IN
  425. DOSTEP:
  426.     OUT    127    ;SET DIRECTION BIT IN FDC
  427.     ORI    2
  428.     OUT    127    ;PULSE STEP BIT
  429.     ANI    0FDH
  430.     OUT    127    ;TURN OFF PULSE
  431.     RET
  432. ;
  433. OUTX:
  434.     DCR    M    ;UPDATE TRACK BYTE
  435.     XRA    A    ;SET DIRECTION = OUT
  436.     JMP    DOSTEP
  437. ;
  438. ;
  439. ;
  440. BUF0:    DS    128*LASTSEC
  441. BUF1:    DS    128*LASTSEC
  442.     END
  443.