home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / sigmv013.ark / MITSCNVT.ASM < prev    next >
Assembly Source File  |  1985-02-09  |  28KB  |  1,349 lines

  1.     TITLE    'MITS 88DCDD DISK TO CP/M FILE TRANSFER'
  2.     PAGE    58
  3.  ; MITS TO CP/M FILE CONVERSION ROUTINE
  4. ; CODED 11/80 THRU 1/81 (MY FIRST CP/M PROGRAM)
  5. ; FOLLOWS CONVPATB FAIRLY CLOSELY ( SEE THIS WELL DOCUMENTED PROGRAM )
  6. ; USES DIFFERENT USER INTERFACE ETC...
  7. ;
  8. ;
  9. ;
  10. ;
  11. TRUE    EQU    0FFFFH
  12. FALSE    EQU    NOT TRUE
  13. DEBUGGING EQU    TRUE    ; SAY BUGS NOT OUT YET ***** CHANGE LATER *****
  14. CHECKOUT EQU    FALSE    ; USED TO INTERFERE WITH CARD BUFFER
  15. LOCATION    EQU    100H    ; LOCATION OF THE START OF THIS STUFF
  16. NFILES    EQU    255    ; NUMBER OF FILES IN MITS DIRECTORY
  17. NSECTS    EQU    32    ; 32 SECTORS PER TRACK
  18. DBIAS    EQU    7    ; BIAS IN MITS DIRECTORY
  19.             ; WHY ISN'T ANY PROGRAM IN HARMONY WITH ITS DOC?
  20. DSIZE    EQU    16    ; LENGTH OF MITS DIRECTORY ENTRY
  21. BSIZE    EQU    137    ; SECTOR LENGTH ON 88-DCDD PERTEC FD-400'S
  22. NFPS    EQU    BSIZE/DSIZE ; NUMBER FILES/SECTOR (TRUNCATED)
  23. VERS    EQU    10    ; VERSION 1.0
  24. MODL    EQU    1    ; MODIFICATION LEVEL 0
  25. DTRACK    EQU    70    ; DIRECTORY TRACK
  26. ENDSLOT EQU    0377Q    ; FLAG FOR LAST FILE
  27. CTLC    EQU    'C'-64    ; CONTROL C
  28. CTLU    EQU    'U'-64    ; CONTROL U
  29. BACKSP    EQU    'H'-64    ; BACKSPACE (CTL H)
  30. CTLD    EQU    'D'-64    ; CONTROL D
  31. CTLP    EQU    'P'-64    ; CONTROL P
  32. CTLZ    EQU    'Z'-64    ; CONTROL Z
  33. CTLS    EQU    'S'-64
  34. CTLQ    EQU    'Q'-64
  35. CR    EQU    0DH    ; CARRIAGE RETURN
  36. LF    EQU    0AH    ; LINE FEED
  37. ;
  38. ; MACROS
  39. ;
  40. CPM    MACRO    ?F,?P
  41.     PUSH    B
  42.     PUSH    D
  43.     PUSH    H
  44.     IF    NOT NUL ?F
  45.     MVI    C,?F
  46.     ENDIF
  47.     IF    NOT NUL ?P
  48.     LXI    D,?P
  49.     ENDIF
  50.     CALL    BDOS
  51.     POP    H
  52.     POP    D
  53.     POP    B
  54.     ENDM
  55. MSG    MACRO    ?M,?J
  56.     IF    NOT NUL ?M
  57.     LXI    H,?M
  58.     ENDIF
  59.     CALL    PRMSG
  60.     IF    NOT NUL ?J
  61.     JMP    ?J
  62.     ENDIF
  63.     ENDM
  64. ;
  65. ;
  66.     ORG    LOCATION ; START OF SOMETHING
  67. ;
  68. ; THIS≡PROGRAM WILL READ A MITS FILE THRU THE 88-DCDD CONTROLLER AND
  69. ; BY MEANS OF RESIDENT CP/M WRITE THE FILE TO A CP/M DISK.
  70. ; .........................................................................
  71. ;
  72. ;    PROGRAMMED BY A. L. BENDER, M.D.
  73. ;
  74. ; .........................................................................
  75. ;
  76. ; MCNVT WILL USE ANY REPRESENTATION OF THE CP/M FILENAME ALLOWED
  77. ;
  78.     JMP    MCNVT
  79.     IF    DEBUGGING
  80. PATCH    DS    50
  81.     ENDIF
  82. OND    DS    NFILES*DSIZE
  83. OP    DS    1    ; CURRENTr.
  84.  
  85. ****
  86. Where is further documentation available: MITSCNVT.DOC as
  87. well as program listing.
  88.  
  89. **********
  90. Hardware dependRENT MITS DISK
  91. ADDR    DW    0    ; I/O ADDRESS IN MITS PACKAGE (LIKE DMA ADDR)
  92. NWDS    DB    0    ; NUMBER OF WORDS TO BE READ BY MITS PACKAGE
  93. FCOUNT    DS    1    ; NUMBER OF FILES ACTUALLY IN MITS DIRECTORY
  94. BUFFER    DS    BSIZE    ; READ MITS BUFFER
  95. FCB    DS    33    ; FILE CONTROL BLOCK
  96. FN    DB    0    ; CURRENT FILE NUMBER BEING PROCESSED
  97. RWFLAG    DB    0    ; READ/WRITE FLAG FOR MAKEFCB
  98. RANDFLAG: DB    0    ; 0=SEQUENTIAL 2=RANDOM 1=ISFMS (SPECIAL NSI FILE)
  99. WRCOUNT:DB    0    ; BYTES WRITTEN
  100. MITSNAME: DS    8    ; MITS FILE NAME
  101. CRCEL    DW    0    ; I-RECORD ADDR
  102. CRCL1    DW    0    ; L RECORD ADDR
  103. FRSTCH:    DB    0    ; FIRST CHARACTER IN MITS FILE
  104. NREC:    DW    0    ; NUMBER RECORDS WRITTEN
  105. ;
  106. ; --- CP/M INTERFACE EQUATES ---
  107. ;
  108. BDOS    EQU    5    ; ENTRY TO CP/M I/O ROUTINE
  109. DOSBUF    EQU    0080H    ; DEFAULT BUFFER
  110. CLOSEF    EQU    16    ; CLOSE FILE
  111. CONS    EQU    1    ; READ CONSOLE INPUT BYTE TO A
  112. CONSTAT    EQU    11
  113. EXIT    EQU    0    ; EXIT ADDRESS
  114. CREATEF    EQU    22    ; CREATE FILE
  115. DELETEF    EQU    19    ; DELETE FILE COMMAND
  116. OPENF    EQU    15    ; OPEN FILE
  117. READF    EQU    20    ; READ FILE
  118. WRITEF    EQU    21    ; WRITE FILE
  119. TBUFF    EQU    0080H    ; DEFAULT BUFFER
  120. TFCB    EQU    005CH    ; DEFAULT FCB
  121. SETDMA: EQU    26    ; SET ADDRESS OF DMA
  122. RDBUF:    EQU    10    ; READ BUFFERED CONSOLE
  123. TYPEF    EQU    2    ; CONSOLE OUTPUT
  124. SRCHF    EQU    17    ; SEARCH FOR FILE IN DIRECTORY
  125. ;
  126. ;----- CONVASCI - CONVERT BINARY NUMBER IN BC TO ASCII
  127. ;          IF RADIX=8 CONVERSION WILL BE OCTAL
  128. ;          IF RADIX=10 CONVERSION WILL BE DECIMAL
  129. ;
  130. ; ENTER WITH NUMBER IN BC (B=LSB, C=MSB)
  131. ; RETURNS WITH NUMBER IN M1-M5 (LSB->MSB) AND
  132. ; ADDRESS OF M1 IN BC
  133. ;
  134. ; REGISTERS DE AND HL PRESERVED
  135. ;
  136. ; RADIX IS IN A ON ENTRY (A=10 OR A=8) (THIS WORKS FOR ANY BASE <=10)
  137. ;
  138. ; IF ENTRY IS AT SETRADIX THEN A MUST BE SET IF CONVASCI IS USED THEN
  139. ; RADIX IS ASSUMED 10 OR SET.
  140. ;
  141. SETRADIX STA    RADIX
  142.         RET
  143. ;
  144. CONVASCI PUSH    H
  145.     PUSH    B
  146.     LXI    H,M1
  147.     XRA    A
  148.     MVI    B,5
  149. CV1:
  150.     MOV    M,A
  151.     INX    H
  152.     DCR    B
  153.     JNZ    CV1
  154.     POP    B
  155.     MOV    H,B
  156.     MOV    L,C
  157.     PUSH    D
  158.     MVI    D,5
  159.     LXI    B,M1
  160. CV2    CALL    CONVONE
  161.     STAX    B
  162.     INX    B
  163.     DCR    D
  164.     JNZ    CV2
  165.     POP    D
  166.     POP    H
  167.     LXI    B,M1
  168.     RET
  169. CONVONE    PUSH    B
  170.     MVI    C,10
  171. RADIX    EQU    $-1
  172.     CALL    DIVIDE
  173.     POP    B
  174.     ADI    '0'
  175.     RET
  176. M1    DB    0,0,0,0,0
  177. ;
  178. ;
  179. ; DIVIDE 16 BITS BY 8 BITS
  180. ; HL=>DIVIDEND
  181. ; C=>DIVISOR
  182. ;
  183. ; RETURNS WITH HL=>QUOTIENT
  184. ; C=>DIVISOR
  185. ; A=>REMAINDER
  186. ;
  187. DIVIDE    XRA    A
  188.     CMP    C
  189.     STC
  190.     RZ
  191.     MVI    B,16    ; NUMBER OF TIMES TO LOOP
  192. D1    DAD    H
  193.     RAL
  194.     CMP    C
  195.     JC    D2
  196.     SUB    C
  197.     INX    H
  198. D2    DCR    B
  199.     JNZ    D1
  200.     RET
  201. ; DIRECTORY LOOKUP ROUTINE
  202. ; USED TO SEARCH MFD BEGINNING AT OND
  203. ;
  204. LOOKUP:    LXI    H,OND    ; GET BASE OF DIRECTORY
  205.     LDA    FCOUNT    ; NUMBER OF FILES IN DIRECTORY
  206.     MOV    B,A    ; NUMBR OF FILES IN DIRECTORY
  207. LOOK1    MVI    C,8    ; NUMBER OF BYTES IN FILENAME
  208.     PUSH    D
  209. LOOK2    LDAX    D    ; INPUT FILE TO LOOKUP ADDR IN DE
  210.     CMP    M
  211.     JNZ    LOOK3    ; NOT THIS ENTRY
  212.     INX    D
  213.     INX    H
  214.     DCR    C
  215.     JNZ    LOOK2
  216.     MOV    A,M
  217.     STA    TRACK    ; SET TRACK ADDRESS
  218.     INX    H
  219.     MOV    A,M
  220.     STA    SECTOR
  221.     INX    H
  222.     MOV    A,M    ; FILE TYPE
  223.     SUI    2    ; ZERO FOR SEQUENTIAL
  224.     STA    RANDFLAG ; RANDOM/SEQUENTIAL FLAG
  225.     INX    H
  226.     MOV    A,M    ; FILE NUMBER
  227.     STA    FN    ; SAVE FILE NUMBER (PREVENT FILE LINK ERROR LATER)
  228.     POP    D
  229.     ORA    A    ; CLEAR CARRY
  230.     RET        ;HL=>ENTRY
  231. LOOK3    DCR    B    ; DECREMENT NUMBER OF FILES
  232.     JNZ    LOOK4    ; JUMP IF MORE TO DO
  233.     POP    D
  234.     STC        ; FAILED, FILE NOT IN DIRECTORY
  235.     RET
  236. LOOK4    MVI    A,DSIZE-8
  237.     ADD    C    ; NUMBER OF BYTES TO SKIP PAST
  238.     CALL    ADDAHL    ; ADD A TO HL
  239.     POP    D
  240.     JMP    LOOK1
  241. ;
  242. PRMPT    PUSH    H
  243.     PUSH    D
  244.     CALL    CRLF
  245.     MVI    A,'*'
  246.     CALL    OUTEEE
  247.     POP    D
  248.     POP    H
  249.     RET
  250. NAMEMOV:
  251.     LXI    B,8
  252.     MVI    A,' '
  253.     LXI    D,MITSNAME
  254.     PUSH    D
  255.     CALL    FILLB
  256.     POP    D
  257.     MVI    C,9    ; MITS FILE NAME SIZE+1
  258. MOVE1:
  259.     MOV    A,M    ; PICK UP MITS FILE NAME OR DISK
  260.     CALL    TERMT    ; CHECK TERMINATION
  261.     RZ        ; PROPER
  262.     STAX    D    ; SAVE IT AWAY
  263.     INX    H
  264.     INX    D
  265.     DCR    C    ; COUNT
  266.     JNZ    MOVE1
  267.     MSG    BMFN    ; IMPROPER MITS FILE NAME
  268.     XRA    A
  269.     STA    TBUFF
  270.     JMP    INPUTX    ; GET CARD IMAGE
  271. BADTERM: MSG    BADPUNK,INPUTX    ; IMPROPER PUNCTUATION
  272. BADDISK: MSG    DSKERR,INPUTX    ; BAD DISK NUMBER (MITS DISK)
  273. ;
  274. INPUTCDI:
  275.     LXI    H,TBUFF
  276.     MOV    A,M    ; GET CHARACTER COUNT OF TBUFFER
  277.     CPI    2    ; IF 0 OR 1 CHARACTER, NO INPUT ON TBUFF
  278.     JC    INPUT1    ; NO LINE IMAGE
  279.     PUSH    H
  280.     INR    A    ; POSITION BEYOND INPUT
  281.     CALL    ADDAHL    ; UPDATE POINTER
  282.     MVI    M,CR    ; PUT CR AT END OF LINE BUFFER
  283.     POP    H
  284.     LXI    D,FCB    ; SET FCB ADDRESS
  285.     INX    H    ; SET H TO FW OF TBUFF
  286.     CALL    SKIPS    ; SKIP BLANKS LEADING MSG
  287.     MOV    A,M    ; GET F.C OF IMAGE
  288.     CPI    '='    ; IF FC IS = THEN WANT DIRECTORY ONLY
  289.     JZ    PUTDIR    ; PUT OUT DIRECTORY THEN RESTORE STACK REINITIALIZE
  290.     CALL    MAKEFCB    ; BUILD FCB
  291.     JNC    SCAN2    ; GO TO SCAN MITS FILE NAME
  292.     LXI    H,CPFMSG ; INDICATE CP/M FILE NAME IS IN ERROR
  293. INPERR:    CALL    PRMSG
  294. INPUTX:    XRA    A
  295.     LXI    H,TBUFF
  296.     MOV    M,A
  297.     INX    H
  298.     LXI    B,080H    ; C=128 BYTE BUFFER, B=NR WDS READ
  299. INPUT1    CALL    PRMPT    ; PROMPT INPUT FROM CONSOLE
  300.     MVI    A,125    ; SO IT WILL FIT TBUFF...
  301.     STA    BUFFER    ; CONSTRUCT READ BUFFER
  302.     CPM    RDBUF,BUFFER
  303.     LXI    D,BUFFER+1 ; TRANSFER IMAGE TO TBUFF
  304.     LXI    H,TBUFF    ; [PRETEND IT WAS THERE ALWAYS]
  305.     LDA    BUFFER+1 ; GET COUNT OF BUFFER BYTES
  306.     INR    A    ; COUNT BYTE
  307.     MOV    B,A    ; STUFF INTO COUNTER
  308. INPUT2    LDAX    D    ; MOVE STRING FROM BUFFER TO TBUFF
  309.     MOV    M,A ;
  310.     INX    H ;
  311.     INX    D ;
  312.     DCR    B ;
  313.     JNZ    INPUT2    ; LOOP
  314.     MVI    A,CR    ; TACK ON FINAL C/R CHARACTER
  315.     MOV    M,A    ; TO BUFFER (10 FUNCTION DOESN'T PUT IT THERE)
  316.     CALL    CRLF
  317.     JMP    INPUTCDI
  318. SCAN2:    CPI    CR    ; SEE IF IMAGE IS NOT COMPLETE
  319.     JNZ    SCAN3    ; SO FAR SO GOOD
  320.     LXI    H,NOMITS
  321.     JMP    INPERR    ; ERROR IN INPUT
  322. SCAN3:    LXI    D,MITSNAME
  323.     CALL    NAMEMOV    ; MOVE MITS FILE NAME
  324.     JC    BADTERM
  325.     CPI    ','    ; LOOK FOR COMMA TERM
  326.     JNZ    BADTERM
  327.     INX    H    ; GET TO THE NUMBER NOT THE COMMA
  328.     CALL    DN    ; CONVERT DISK NUMBER TO BINARY
  329.     STA    DISK
  330.     CPI    16    ; HIGHEST DISK + 1
  331.     JNC    BADDISK
  332.     MOV    A,M
  333.     CALL    TERMT
  334.     JNZ    BADDISK
  335.     XRA    A
  336.     STA    TBUFF
  337.     RET
  338. ;
  339. ; DN / CONVERTS STRING AT HL TO BINARY IN A
  340. ; HL ADVANCED TO END OF INTEGER
  341. DN:    XRA    A
  342.     PUSH    D
  343. DN1:    MOV    D,A    ; SAVE A
  344.     MOV    A,M
  345.     SUI    '0'    ; TAKE BIAS AWAY
  346.     JC    DNX    ; DONE, GET OUT
  347.     CPI    10    ; DONE, IF >
  348.     JNC    DNX
  349.     MOV    E,A
  350.     MOV    A,D
  351.     RLC    ;
  352.     RLC    ;        *4
  353.     ADD    D    ; *5
  354.     RLC    ;        *10
  355.     ADD    E    ; ADD DIGIT
  356.     INX    H
  357.     JMP    DN1
  358. DNX:
  359.     MOV    A,D
  360.     POP    D
  361.     RET
  362. ; MAKEFCB.LIB 9/4/78
  363. ; ORIGINAL VERSION IN CP/M LIBRARY VOL 8
  364. ; CORRECTED 9/78 BY P. HOLLIDAY
  365. ;
  366. ; LOCAL SYMBOLS
  367. ;
  368. FCBSIZ:    EQU    33    ; SIZE OF FCB
  369. FNMLEN:    EQU    11    ; LENGTH OF FILE NAME
  370. MAKEFCB:DS    0    ; ENTRY POINT LABEL
  371. MTFCB:    PUSH    H    ; COMMAND STRING POINTER
  372.     PUSH    D    ; FCB ADDRESS
  373.     STA    RWFLAG    ; SAVE READ/WRITE FLAG
  374.     LXI    B,FCBSIZ ; FILL FCB WITH ZERO
  375.     CALL    CLRB    ; CLEAR FCB
  376.     LXI    D,FCB+1
  377.     LXI    B,FNMLEN    ; FILL FILE NAME AREA
  378.     MVI    A,' '    ; WITH BLANKS
  379.     CALL    FILLB
  380.     POP    D
  381.     POP    H    ; RESTORE POINTERS
  382.     CALL    SKIPS    ; PASS LEADING BLANKS
  383.     INX    H    ; CHECK FOR DISK CODE
  384.     MOV    A,M
  385.     DCX    H
  386.     CPI    ':'    ; EXPLICIT DISK
  387.     JNZ    MTFCB1    ; NOT EXPLICIT DISK
  388.     MOV    A,M    ; VALID DISK CODE?
  389.     INX    H
  390.     INX    H
  391.     SBI    '@'    ; SENSE A-Z
  392.     RC        ; IN CASE ZERO TEST FAILS
  393.     CPI    'Z'-'A'+1
  394.     CMC
  395.     RC        ; SET IF IN ERROR
  396.     STAX    D    ; SAVE DISK CODE AT FCB+0
  397. ;PROCESS FILE NAME FIELD
  398. MTFCB1:    INX    D
  399.     MVI    C,8
  400.     CALL    GETNAM
  401.     MOV    A,M    ; TEST FOR FILE TYPE SEPARATOR
  402.     INX    H
  403.     CPI    '.'
  404.     JNZ    MTFCB2
  405.     MVI    C,3
  406.     CALL    GETNAM
  407.     MOV    A,M
  408.     INX    H
  409. ;CHECK TERMINATION OF FIELD
  410. MTFCB2:    CALL    TERMT
  411.     RET        ; RETURN TO USER
  412. ;
  413. ;PROCESS NAME FIELD
  414. ;
  415. GETNAM:    MOV    A,M    ; GET CHARACTER FROM COMMAND STRING
  416.     INX    H
  417.     CPI    '?'    ; ALLOW AMBIGUITY TO EXIST IN NAME
  418.     JNZ    GETN20    ; NOT AMBIGUOUS CHARACTER
  419.     LDA    RWFLAG    ; GET R/W FLAG
  420.     ORA    A    ; SET FLAGS
  421.     MVI    A,'?'    ; RESET ? CHAR
  422.     JZ    GETNA1    ; STORE AMBIG CHAR
  423.     JMP    GETNA3    ; NG,WRITING FILE ? DISALLOWED
  424. GETN20:    CPI    '*'    ; CHECK FOR FULL FIELD OF ???
  425.     JZ    GETNA2
  426.     CALL    VALCHR    ; TEST FOR VALID CHARACTERS IN NAME
  427.     JC    GETNA3    ; INVALID, SKIP OVER REMAINDER OF FIELD
  428. GETNA1:    STAX    D    ; SAVE FILE NAME OR TYPE
  429.     INX    D
  430.     DCR    C    ; ACCUMULATE EVERYTHING
  431.     JNZ    GETNAM    ; LOOP TO FINISH FIELD
  432.     RET        ; DONE WITH SCAN
  433. GETNA2:    LDA    RWFLAG
  434.     ORA    A    ; TEST FOR WRITE OPERATION ON FILE
  435.     JZ    GETNA3    ; NG,WRITE ON AMBIGUOUS FILE NAME
  436.     MVI    A,'?'
  437.     MVI    B,0    ; FILL WITH ?
  438.     JMP    FILLB    ; FILLB WILL RETURN TO USER
  439. GETNA3:    INX    D    ; SKIP TO END OF FIELD IN FCB
  440.     DCR    C
  441.     JNZ    GETNA3
  442.     DCX    H    ; POINT TO NEXT CHARACTER IN INPUT STRING
  443.     RET
  444. ; TEST FOR VALID CHARACTER IN NAME FIELD
  445. ; RETURN IF INVALID WITH CARRY SET
  446. ; ADDED TEST FOR = SIGN ALSO 12/19/80
  447. ;
  448. VALCHR:    CPI    CR    ; TEST FOR C/R
  449.     CMC    ;     COMPL CARRY
  450.     RZ
  451.     CPI    '*'
  452.     CMC
  453.     RZ
  454.     CPI    ','
  455.     CMC
  456.     RZ
  457.     CPI    '='
  458.     CMC
  459.     RZ
  460.     CPI    '.'
  461.     CMC
  462.     RZ
  463.     CPI    ' '
  464.     RC
  465.     CPI    '^'+1
  466.     CMC
  467.     RC
  468.     CPI    ':'
  469.     CMC
  470.     RNC
  471.     CPI    'A'-1    
  472.     RET
  473. ;
  474. ;TEST FOR VALID FILE NAME TERMINATOR
  475. ;
  476. TERMT:    CPI    ' '
  477.     RZ
  478.     CPI    ','
  479.     RZ
  480.     CPI    CR
  481.     RZ
  482.     CPI    ';'
  483.     RZ
  484.     CPI    '='
  485.     RZ
  486.     STC
  487.     RET
  488. ;
  489. ;SKIP SPACES IN COMMAND STRING
  490. ;
  491. SKIPS:    MVI    A,' '
  492. SKIPS1:    CMP    M
  493.     RNZ
  494.     INX    H
  495.     JMP    SKIPS1
  496. ; FILL BLOCK WITH VALUE
  497. ; ENTER WITH VALUE IN A
  498. ; DE=START OF BLOCK
  499. ; BC=LENGTH OF BLOCK
  500. ;
  501. CLRB:    XRA    A    ; ENTRY TO ZERO BLOCK
  502. FILLB:    INR    B    ; DOUBLE TALK TO AVOID MESSING WITH A
  503.     DCR    B
  504.     JNZ    FILLB1
  505.     INR    C
  506.     DCR    C
  507.     RZ
  508. FILLB1:    STAX    D
  509.     INX    D
  510.     DCX    B
  511.     JMP    FILLB
  512. ;
  513. ; END OF MAKEFCB.LIB
  514. ;
  515. ;
  516. ;
  517. ;
  518. ; FNCALC - CALCULATES THE FILE NUMBER RELATIVE TO  THE OLD DIRECTORY
  519. ;
  520. ; ENTER WITH B=SLOT-K
  521. ;
  522. ; THE TERM NEW DIRECTORY REFERS TO THE MITS DIRECTORY WITH ALL DELETED FILES
  523. ; REMOVED.  OND=>IS THE  "ORIGIN OF THE NEW DIRECTORY" FCOUNT=>THE NUMBER OF
  524. ; FILES REALLY PRESENT IN THE NEW DIRECTORY
  525. ;
  526. FNCALC    LDA    BUFFER+1
  527.     PUSH    B
  528.     RLC    ; *2
  529.     RLC    ; *4
  530.     RLC    ; *8 (THE BOOK IS WRONG, ITS 8*SSECTOR+)
  531.     MOV    C,A    ; SECTOR
  532.     MVI    A,9
  533.     SUB    B
  534.     ADD    C    ; 8*SECTOR+(SLOT+1)
  535.     POP    B
  536.     RET
  537. ;
  538. ;
  539. ; MESSAGES
  540. ;
  541. SIGNON    DB    0DH,0AH,'MITS FILE COPY VERS '
  542.     DB    VERS/10+'0','.',VERS MOD 10+'0'
  543.     DB    ' (,',MODL+'0',')'
  544.     DB    0
  545. FMTERR    DB    0DH,0AH,'DIRECTRY FMT ERR'
  546.     DB    0
  547. NFMSG    DB    0DH,0AH,'NMBR OF FILES IN CURRENT '
  548.     DB    'DIRECTORY:',0
  549. FLERRM    DB    0DH,0AH,'FILE LINK ERROR ON MITS DISK',0
  550. CKSUM    DB    0DH,0AH,'CHECKSUM ERROR ON MITS FILE',0
  551. DIRRD    DB    0DH,0AH,'ERROR TRYING TO RECOVER MITS DIRECTORY FROM DISK',0
  552. CPFMSG    DB    0DH,0AH,'CP/M FILE NAME IN ERROR',0
  553. TRKERR    DB    0DH,0AH,'BAD TRACK ADDRESS',0
  554. SECERR    DB    0DH,0AH,'BAD SECTOR ADDRESS',0
  555. FMTNG    DB    0DH,0AH,'DATA SECTOR FORMAT IMPROPER',0
  556. RDMSG    DB    0DH,0AH,'READING MITS FILE',0
  557. ENDMSG    DB    CR,0AH,'END OF CP/M DISK MEDIUM',0
  558. EXTMSG    DB    CR,0AH,'ERROR ENCOUNTERED EXTENDING CP/M DISK',0
  559. FULMSG:    DB    CR,0AH,'CP/M DIRECTORY FULL',0
  560. NOMITS:    DB    CR,0AH,'NO MITS DISK FILE SPECIFIED',0
  561. NAMERR    DB    CR,0AH,'ERROR SPECIFYING MITS DISK',0
  562. DSKERR    DB    CR,0AH,'ERROR IN CONVERTING DISK NUMBER',0
  563. NFMDMS    DB    ' FILES IN MITS DIRECTORY',CR,LF,0
  564.     DB    CR,0AH,'TOO MANY OR TOO LONG ARGUMENTS',0
  565. BMFN    DB    CR,LF,'BAD MITS FILE NAME (TOO LONG)',0
  566. BADPUNK    DB    CR,LF,'IMPROPER FILE SYNTAX',0
  567. FSRCHF    DB    CR,LF,'MITS FILE SEARCH FAILED',0
  568. ;
  569. ; CHARACTER OUTPUT TO CONSOLE
  570. ;
  571. OUTEEE:    MOV    E,A
  572.     CPM    TYPEF    ; TYPE A CHARACTER
  573.     RET
  574. CRLF    MVI    A,0DH
  575.     CALL    OUTEEE
  576.     MVI    A,0AH
  577.     JMP    OUTEEE
  578. ;
  579. PRMSG:
  580. ;
  581. ;PRINT MESSAGE TO ZERO BYTE
  582. ;FOR DETAILS SEE INTEL ISIS MANUAL OR CP/M SAMPLE BIOS
  583.     MOV    A,M
  584.     ORA    A
  585.     RZ
  586.     MOV    E,A
  587.     CPM    TYPEF
  588.     INX    H
  589.     JMP    PRMSG
  590. ;
  591. ;
  592. ;
  593. ; START OF MAIN PROGRAM
  594. ;
  595. MCNVT    LXI    H,0
  596.     DAD    SP    ; SAVE CP/M STATUS AS THIS PROGRAM DOESN'T CLOBBER IT
  597.     SHLD    CPMSTK    ; STACK POINTER FOR CP/M
  598. MCNVT1    LXI    SP,STACK ; GET NEW STACK ADDRESS
  599.     MSG    SIGNON    ; PUT OUT SIGNON MESSAGE
  600. MCNVT1A:    CALL    INITIAL    ; INITIALIZE
  601.     CALL    SETFILES
  602.     CALL    MDRD    ; RECOVER MITS FILE DIRECTRY
  603.     CALL    SORT    ; SORT DIRECTORY
  604.     CALL    PRINTDIRECTRY
  605.     LXI    D,MITSNAME
  606.     CALL    LOOKUP    ; LOOKUP NAME IN DIRECTORY
  607.     JNC    MCNVT2    ; SEARCH SUCCESSFUL
  608.     MSG    FSRCHF,MCNVT1A    ; SEARCH FAILED
  609. MCNVT2:    CALL    COPYFILE
  610.     CALL    CRLF
  611.     LHLD    NREC    ; GET WRITE COUNTER
  612.     MOV    B,H
  613.     MOV    C,L
  614.     CALL    CONVASCI    ; CONVERT TO ASCII
  615.     LXI    H,M1+4    ; START OF DIGIT STRING
  616.     MVI    B,5    ; NO OF ASCII DIGITS
  617.     MVI    E,0    ; FLAG TO SUPRESS ZERO
  618. MCNVT3:    MOV    A,M    ; GET A DIGIT
  619.     CPI    '0'
  620.     JZ    MCNVT6
  621.     MOV    E,A    ; SET FLAG SIGNIFICANT DIGIT
  622. MCNVT4:    CALL    OUTEEE
  623. MCNVT5:    DCX    H
  624.     DCR    B
  625.     JNZ    MCNVT3
  626.     CALL    MCNVT8
  627.     MSG    BLOCKMSG,MCNVT7
  628. MCNVT6:    MOV    D,A
  629.     MOV    A,E
  630.     ORA    A
  631.     JZ    MCNVT5    ; LEADING ZEROS
  632.     MOV    A,D    ; IN SIGNIFICANT PART OF INTEGER
  633.     JMP    MCNVT4
  634. BLOCKMSG: DB    ' SECTORS COPIED TO CP/M FILE.',CR,LF,0
  635. MCNVT7:    CALL    CLWRF    ; CLOSE WRITE FILE
  636.     JMP    MCNVT1A
  637. MCNVT8:    LXI    H,BINARY
  638.     LDA    FRSTCH
  639.     INR    A
  640.     JZ    MCNVT9    ; JUMP IF BINARY DATA
  641.     LXI    H,ASCII
  642. MCNVT9:    CALL    PRMSG
  643.     RET
  644. BINARY:    DB    ' BINARY DATA',0
  645. ASCII:    DB    ' ASCII BYTE DATA',0
  646. ; PRINT DIRECTORY ON MITS DISK - INVOKED BY =N
  647. ;
  648. PUTDIR:    INX    H
  649.     CALL    DN
  650.     STA    DISK
  651.     CALL    PMITS    ; PRINT SORTED DIRECTORY
  652.     XRA    A
  653.     STA    TBUFF    ; ZEROIZE TO PREVENT COMING BACK IN A LOOP
  654.     LXI    SP,STACK
  655.     JMP    MCNVT1A
  656. ; PRINT MITS FILE DIRECTORY
  657. ; THE DIRECTORY IS STORED AT OND
  658. ; IT MAY BE PRESORTED BY SORT OR IT MAY BE PRINTED
  659. ; WITHOUT SORTING.
  660. ;
  661. PRINTDIRECTRY:
  662.     CALL    CRLF
  663.     LDA    FCOUNT
  664.     CALL    DECOUT
  665.     MSG    NFMDMS    ; PUT OUT NUMBER OF FILES
  666.     LDA    FCOUNT    ; GET PRESET
  667.     MOV    B,A    ; NUMBER OF FILES IN DIRECTORY
  668.     LXI    D,OND    ; ORIGIN OF THE NEW MITS DIRECTORY
  669. PRDIR1:    CALL    DLIST    ; PRINT ONE DIRECTORY ENTRY
  670.     LXI    H,DSIZE    ; LENGTH OF A DIRECTORY ENTRY
  671.     DAD    D    ; PLUS ADDRESS
  672.     XCHG        ; TO D
  673.     DCR    B
  674.     JNZ    PRDIR1    ; LOOP UNTIL ENTIRE DIRECTORY PRINTED
  675.     RET
  676. DLIST:    PUSH    H
  677.     PUSH    D
  678.     PUSH    B    ; SAVE EVERYTHING
  679.     XCHG        ; HL=ADDRESS OF THIS ENTRY
  680.     LXI    B,0803H    ; MVI C,3; MVI B,8
  681. DLIST1    MOV    A,M    ; FILE NAME TO A
  682.     CALL    OUTEEE
  683.     INX    H
  684.     DCR    B
  685.     JNZ    DLIST1
  686.     MVI    A,' '    ; BLANK
  687. DLIST2:    CALL    OUTEEE    ; (THREE OF THEM)
  688.     DCR    C
  689.     JNZ    DLIST2    ; TO PRINTER
  690.     MOV    A,M    ; GET TRACK NUMBER
  691.     CALL    DECOUT    ; PRINT IT
  692.     MVI    A,','    ; PRINT BLANK
  693.     INX    H
  694.     CALL    OUTEEE
  695.     MOV    A,M    ; GET SECTOR NUMBER
  696.     CALL    DECOUT    ; PRINT SECTOR NUMBER
  697.     MVI    A,','
  698.     CALL    OUTEEE
  699.     INX    H
  700.     MOV    A,M
  701.     MVI    B,'R'
  702.     CPI    4    ; 4=RANDOM
  703.     JZ    DLIST3
  704.     MVI    B,'S'
  705. DLIST3:    MOV    A,B
  706.     CALL    OUTEEE    ; PRINT FILE TYPE
  707.     MVI    A,','
  708.     CALL    OUTEEE
  709.     INX    H    ; GET TO FILE NUMBER
  710.     MOV    A,M
  711.     CALL    DECOUT    ; PRINT FILE NUMBER
  712.     CALL    CRLF
  713.     POP    B
  714.     POP    D
  715.     POP    H
  716.     RET
  717. ;
  718. ; DECOUT => DECIMAL OUTPUT
  719. ;
  720. ; SUPPRESS LEADING ZERO
  721. ; OUTPUT A BLANK INSTEAD
  722. ;
  723. DECOUT:    PUSH    D
  724.     PUSH    B
  725.     MVI    E,0    ; CLEAR ZERO FLAG
  726.     MVI    C,100    ; DIVIDE BY 100
  727.     CALL    DECOU1
  728.     MVI    C,10    ; DIVIDE BY 10
  729.     CALL    DECOU1
  730.     ADI    '0'    ; DIVIDE BY '1'
  731.     CALL    OUTEEE    ; UNITS
  732.     POP    B
  733.     POP    D
  734.     RET
  735. DECOU1:    MVI    B,'0'-1
  736.     INR    B
  737.     SUB    C
  738.     JNC    DECOU1+2    ; LOOP UNTIL DIVIDE RESULTS IN REMAINDER
  739.     ADD    C
  740.     MOV    D,A
  741.     MOV    A,B
  742.     CPI    '0'    ; SENSE ZERO
  743.     JNZ    DECOU2    ; NOT ZERO, SET FLAG NZ, OUTPUT ASCII
  744.     MOV    A,E    ; GET ZERO FLAG
  745.     ORA    A    ; SET
  746.     MOV    A,D
  747.     RZ
  748. DECOU2:    INR    E    ; SET FLAG
  749.     MOV    A,B
  750.     CALL    OUTEEE
  751.     MOV    A,D
  752.     RET
  753. ;
  754. ; COPYFILE => READS MITS FILE / WRITES CPM FILE
  755. ;
  756. ; AT THE START OF THE COPY, TRACK=TRACK ADDRESS OF FILE
  757. ; SECTOR = SECTOR ADDRESS OF FILE.  DISK IS SELECTED FROM READ OF DIRECTORY
  758. ; TRACK AND SECTOR WERE SET BY DIRECTORY SEARCH SUBROUTINE.
  759. ;
  760. ; COPY PROCEEDS ONE SECTOR AT A TIME.
  761. ; READ MITS SECTOR, UPDATE TRACK AND SECTOR, WRITE CP/M SECTOR LOOP ETC.
  762. ; TERMINATES ON ZERO TRACK/SECTOR OR EOF CHARACTER.
  763. ;
  764. COPYFILE:
  765.     LDA    RANDFLAG    ; IS FILE RANDOM
  766.     ORA    A    ; SET
  767.     JNZ    APOLOGY    ; DONT DO AT THIS TIME
  768. CPYFL1:    CALL    RDMITS    ; READ MITS DISK
  769.     CALL    WRCPM    ; WRITE CP/M FILE
  770.     LHLD    BUFFER+5
  771.     MOV    A,L
  772.     ORA    H
  773.     JNZ    CPYFL1
  774.     RET
  775. APOLOGY: MSG    APMSG,MCNVT
  776. APMSG    DB    CR,LF,'CANT DO RANDOM FILES YET',0
  777.     ;
  778. ;INITIALIZE
  779. ;
  780. INITIAL: LXI    H,BUFFER    ; SET BUFFER ADDRESS
  781.     SHLD    ADDR
  782.     MVI    A,BSIZE
  783.     STA    RWFLAG    ; SAY READING
  784.     STA    NWDS
  785.     XRA    A
  786.     STA    OP    ; READING=0
  787.     STA    RWFLAG
  788.     IF    CHECKOUT
  789.     STA    TBUFF
  790.     ENDIF
  791.     OUT    8    ; SELECT DRIVE 0
  792.     LXI    H,0
  793.     SHLD    NREC    ; INITIALIZE WRITE COUNTER
  794.     CALL    INPUTCDI
  795.     RET
  796. ;
  797. ; PMITS => RECOVERS AND PRINTS MITS DIRECTORY
  798. ;
  799. PMITS    CALL    MDRD
  800.     CALL    SORT
  801.     CALL    PRINTDIRECTRY
  802.     RET
  803. ;
  804. ; SETFILES
  805. ; THIS ROUTINE SETS UP THE OUTPUT FILE
  806. ; IT CALLS ON CP/M TO SEARCH FOR THE FILE AND THEN IT
  807. ; DESTROYS IT IF FOUND.
  808. ;
  809. SETFILES: LXI    D,FCB    ; SET UP FCB ADDRESS AS INPUT
  810.     PUSH    D
  811.     CPM    SRCHF
  812.     INR    A    ; NOT FOUND?
  813.     JZ    SET1    ; YES
  814.     POP    D
  815.     PUSH    D
  816.     CPM    DELETEF
  817. SET1    POP    D
  818.     PUSH    D
  819.     CPM    CREATEF
  820.     POP    D
  821.     CALL    SETUPO    ; OPEN FILE
  822.     CPM    SETDMA,BUFFER+7 ; DMA ADDRESS TO WRITE MITS FILE
  823.     RET        ; RETURN TO USER
  824. ;
  825. ; END OF PROGRAM
  826. ;
  827. ;
  828. ; SECTOR TRACK ROUTINE FOR 88-DCDD
  829. ;
  830. SECGET    DI    ; SECTOR ACQUIRE DON'T ALLOW TRAPPING
  831. SG1    IN    9 ; GET CURRENT DATA STUFF
  832.     RAR
  833.     JC    SG1
  834.     ANI    31    ; MASK OFF SECTOR NUMBER
  835.     CMP    E ; E=>DESIRED SECTOR
  836.     JNZ    SG1 ; NXT ONE MAYBE
  837.     RET
  838. ;
  839. ; TRACK ROUTINE
  840. ;
  841. TRACKGET IN    8 ; GET STATUS OF DISK
  842.     ANI    4 ; IS HEAD LOADED?
  843.     CNZ    LOADHEAD ; NOPE, LOAD IT
  844.     CALL    FINDTRACK ; FIND TRACK IN RAT
  845.     LDA    TRK ; FOR DEBUGGING TRK IS PUT HERE WHEN FOUND IN RAT
  846.     CMP    D ; IS THIS THE DESIRED TRACK ON THIS DISK?
  847.     RZ    ; YES
  848.     PUSH    PSW ; SAVE RESULTS OF COMPARE
  849.     CALL    LOADHEAD
  850.     POP    PSW
  851.     
  852.     JM    STEPIN ; NEGATIVE MEANS HEAD IS TOO FAR TOWARDS EDGE
  853. STEPOUT
  854.     CALL    POUT ; POSITIVE, MEANS TOO FAR TOWARDS CENTER
  855.     LDA    TRK
  856.     DCR    A
  857.     STA    TRK ; COUNT DOWN TRACK AS WE STEP HEAD
  858.     CMP    D ; IS THIS THE DESIRED TRACK?
  859.     JNZ    STEPOUT ; NO, KEEP COUNTING
  860.     CALL    STORETRACK ; PUT TRACK BACK IN RAT
  861.     JMP    MOVE
  862. STEPIN    CALL    PIN
  863.     LDA    TRK
  864.     INR    A
  865.     STA    TRK ; INCREMENT AS  WE GO IN TOWARDS THE HUB
  866.     CMP    D
  867.     JNZ    STEPIN
  868.     CALL    STORETRACK
  869.     JMP    MOVE
  870. PIN    CALL    MOVE
  871.     MVI    A,1
  872.     OUT    9
  873.     RET    ; STEPS HEAD INWARDS 1 TRACK
  874. LOADHEAD MVI    A,4 ; 4 SAYS MOVE HEAD ONTO THE SURFACE
  875.     OUT    9
  876. LH1    IN    8 ; GET DISK STATUS
  877.     ANI    4 ; MOVEMENT ALLOWED?
  878.     RZ
  879.     JMP    LH1
  880. TRACK0    XRA    A
  881.     STA    TRK ; SET IT TO ZERO
  882.     CALL    STORETRACK ; FIX RAT
  883. TR01    CALL    MOVE
  884.     IN    8
  885.     ANI    0100Q ; CHECK IF ON TRACK ZERO
  886.     RZ    ; YES, DONE
  887.     CALL    POUT ; STEP HEAD TOWARDS TRACK 0
  888.     JMP    TR01
  889. POUT    CALL    MOVE
  890.     MVI    A,2 ; COMMAND TO STEP OUT
  891.     OUT    9
  892.     RET
  893. MOVE    IN    8
  894.     ANI    2 ; IS HEAD MOVEMENT ALLOWED (VALID SECTOR INDEX PULSE)
  895.     RZ ; YES
  896.     JMP    MOVE
  897. HEADUNLOAD MVI    A,8 ; UNLOAD COMMAND
  898.     OUT    9
  899.     RET
  900. FINDTRACK PUSH  H ; FINDS TRACK IN RAPID ACCESS TABLE
  901.     LDA    DISK
  902.     LXI    H,RAT
  903.     CALL    ADDAHL ; ADD  A TO HL (GET WHICH DISK IT IS)
  904.     MOV    A,M ; GET THE ENTRY FOR THAT DISK
  905.     STA    TRK ; SET THAT TOO
  906.     POP    H
  907.     RET
  908. ADDAHL:
  909.     ADD    L
  910.     MOV    L,A
  911.     RNC
  912.     INR    H
  913.     RET    ; THATS ALL THERE IS TO IT
  914. STORETRACK PUSH H
  915.     LXI    H,RAT
  916.     LDA    DISK
  917.     CALL    ADDAHL ; ADD A TO HL GET THE RIGHT SLOT IN RAT
  918.     LDA    TRK
  919.     MOV    M,A
  920.     POP    H
  921.     RET
  922.     ; RAPID ACCESS TABLE
  923. RAT    DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  924. TRK    EQU    RAT+16
  925. ;
  926. ; READ A SECTOR FROM MITS DISK.  SECTOR AND TRACK ARE ASSUMED SET
  927. ; PRIOR TO ENTRY.  IF SECTOR AND TRACK ARE WRONG FOR FILE
  928. ; GROUP INDICATES "FILE LINK ERROR"
  929. ;
  930. ; IF CHECKSUM IS IN ERROR, "CHECKSUM ERROR" WILL BE INDICATED
  931. ;
  932. RDMITS    LDA    TRACK
  933.     CPI    77    ; SENSE OFF DISK
  934.     JP    BADTRK
  935.     ADI    0
  936.     JM    BADTRK
  937.     LDA    SECTOR
  938.     ADI    0
  939.     JM    BADSEC
  940.     CPI    32
  941.     JP    BADSEC
  942.     LXI    H,BUFFER
  943.     SHLD    ADDR
  944.     MVI    A,BSIZE
  945.     STA    NWDS
  946.     CALL    DISKIN    ; INPUT THE SECTOR
  947.     LDA    FN    ; GET CURRENT FILE NUMBER
  948.     LXI    H,BUFFER+2 ; FILENUMBER ON DISK
  949.     CMP    M    ; SHOULD ALWAYS BE =
  950.     JNZ    BADLNK    ; FILE LINK ERROR
  951.     INX    H
  952.     MOV    A,M    ; NUMBER DATA BYTES IN SECTOR
  953.     STA    WRCOUNT ; SAVE NUMBER OF BYTES TO WRITE
  954.     INX    H
  955.     MOV    C,M    ; GET CHECKSUM
  956.     LHLD    BUFFER+5
  957.     MOV    A,H
  958.     ANI    1
  959.     MOV    A,H
  960.     JZ    RDMIT1
  961.     ADI    16
  962.     ANI    1FH
  963. RDMIT1:    STA    SECTOR
  964.     MOV    A,L
  965.     STA    TRACK
  966.     ADD    H
  967.     MOV    B,A
  968.     LDA    FN
  969.     ADD    B
  970.     MOV    B,A
  971.     LDA    WRCOUNT
  972.     ADD    B
  973.     MVI    B,128
  974.     LXI    H,BUFFER+7
  975. CSCALC    ADD    M
  976.     INX    H
  977.     DCR    B
  978.     JNZ    CSCALC
  979.     XRA    C    ; CHECKSUM
  980.     JNZ    BADCKS
  981.     PUSH    H
  982.     LHLD    NREC
  983.     MOV    A,H
  984.     ORA    L
  985.     JNZ    SKIPIT
  986.     LDA    BUFFER+7
  987.     STA    FRSTCH    ; SAVE FIRST CHARACTER OF FILE
  988. SKIPIT:    POP    H
  989.     IF    DEBUGGING
  990.     MOV    A,M    ; LOOK FOR CHECK BYTE
  991.     INR    A    ; 255+1=0
  992.     RZ
  993.     LXI    H,CKBYTE ; CHECK BYTE ERROR
  994.     JMP    CPMERR
  995. CKBYTE    DB    CR,LF,'CHECK BYTE NOT FOUND IN MITS FILE'
  996.     ENDIF
  997.     IF    NOT DEBUGGING
  998.     RET
  999.     ENDIF
  1000. ; WRITE CP/M DISK FILE
  1001. ;
  1002. WRCPM:    LDA    WRCOUNT    ; GET WORD COUNT
  1003.     CPI    128    ; CHECK FOR FULL BUFFER
  1004.     JZ    WRCPM1    ; YES,WRITE IT
  1005.     MOV    B,A    ; SAVE COUNT
  1006.     LXI    H,BUFFER+7 ; START OF DATA REGION
  1007.     CALL    ADDAHL    ; ADD WORDS WRITTEN
  1008.     LDA    FRSTCH
  1009.     INR    A    ; =255=>BINARY FILE
  1010.     JZ    ZSR    ; ZERO OUT REMAINDER OF BUFFER
  1011.     MVI    A,1AH    ; EOF MARK FOR ASCII FILES
  1012. ZSR    MOV    M,A    ; STORE ZERO OR 1A IN BUFFER
  1013.     MVI    A,128
  1014.     SUB    B
  1015.     INX    H
  1016.     DCR    A
  1017.     JZ    WRCPM1    ; JUMP IF ONLY ONE CHARACTER REMAINING (DONE)
  1018.     MOV    B,A
  1019.     XRA    A
  1020. ZRLOOP:    MOV    M,A    ; ZEROIZE THE REST OF THE BUFFER
  1021.     INX    H
  1022.     DCR    B
  1023.     JNZ    ZRLOOP
  1024. WRCPM1:    CPM    WRITEF,FCB
  1025.     LHLD    NREC    ; INCREMENT RECORD COUNT
  1026.     INX    H
  1027.     SHLD    NREC
  1028.     ORA    A
  1029.     RZ        ; WRITE OPERATION COMPLETED OK
  1030.     CPI    2    ; < MEANS ERROR EXTENDING > MEANS DIRECTRY ERR
  1031.     JZ    ENDDSK
  1032.     JC    EXTERR
  1033.     JMP    DIRFUL
  1034. ;
  1035. ; SET UP CPM FILE
  1036. ;
  1037. SETUPO:    CPM    OPENF    ; OPEN CP/M FILE
  1038.     CPI    255
  1039.     JZ    DIRFUL
  1040.     RET
  1041. ;
  1042. ; SET UP FCB FOR OUTPUT
  1043. ;
  1044. ; DATA IS IN TFCB AND TFCB+16
  1045. ;
  1046. KATHY:    PUSH    B
  1047.     LDAX    D
  1048.     MOV    M,A
  1049.     INX    D
  1050.     INX    H
  1051.     DCX    B
  1052.     MOV    A,B
  1053.     ORA    C
  1054.     JNZ    KATHY+1
  1055.     POP    B
  1056.     RET
  1057. ;
  1058. ; CLOSE WRITE FILE
  1059. ;
  1060. CLWRF:    CPM    CLOSEF,FCB ; CLOSE WRITE FILE
  1061.     RET
  1062. ;
  1063. ;
  1064. ;
  1065. ; ERROR CONDITIONS
  1066. ;
  1067. BADLNK    LXI    H,FLERRM
  1068.     CALL    PRMSG
  1069.     JMP    EXIT    ; WE ARE ROGH ON ERRORS - YOU MIGHT WANT TO GO ON
  1070. BADSEC    LXI    H,SECERR    ; SECTOR NOT 0-31
  1071.     CALL    PRMSG
  1072.     JMP    EXIT
  1073. BADTRK    LXI    H,TRKERR    ; TRACK NOT 0-76
  1074.     CALL    PRMSG
  1075.     JMP    EXIT
  1076. BADCKS    LXI    H,CKSUM
  1077.     CALL    PRMSG
  1078.     JMP    EXIT
  1079. BADFMT    LXI    H,FMTNG
  1080.     CALL    PRMSG
  1081.     JMP    EXIT
  1082. ENDDSK:    LXI    H,FULMSG    ; DISK FULL
  1083.     JMP    CPMERR    ; ERROR ENCOUNTERED IN CP/M SEGMENT OF PROGRAM
  1084. EXTERR:    LXI    H,EXTMSG
  1085.     JMP    CPMERR
  1086. DIRFUL    LXI    H,FULMSG
  1087. CPMERR    CALL    PRMSG
  1088.     JMP    EXIT
  1089. ;
  1090. ;
  1091. ;; READ MITS FILE DIRECTORY
  1092. ;
  1093. ; DESTROYS EVERYTHING - USES EVERYTHING
  1094. ; DISK IS LEFT WITH HEAD UNLOADED ON TRACK 70
  1095. ;
  1096. ; DOESN'T SORT DIRECTORY
  1097. ;
  1098. ;
  1099. MDRD    LDA    DISK    ; SELECT DISK
  1100.     CALL    DISKSET
  1101.     XRA    A
  1102.     STA    SECTOR
  1103.     STA    FCOUNT    ; ZER OFILE COUNTER
  1104.     STA    OP    ; READ=>0
  1105.     MVI    A,DTRACK    ; DIRECTORY TRACK
  1106.     STA    TRACK    ; DIRECTORY TRACK
  1107.     LXI    D,OND    ; SET ORIGIN OF THE NEW DIRECTORY
  1108. MDRD1    LXI    H,BUFFER ; SET ORIGIN OF INPUT BUFFER
  1109.     SHLD    ADDR    ; SET ADDRESS OF INPUT BUFFER TO READ RTN
  1110.     MVI    A,BSIZE ; BUFFER SIZE
  1111.     STA    NWDS    ; SET
  1112.     CALL    DISKIN    ; READ A SECTOR
  1113.     LXI    H,BUFFER+DBIAS ; START OF MEANINGFUL DATA IN DIRECTORY
  1114.     MVI    B,NFPS
  1115. MDRD2    MOV    A,M
  1116.     ORA    A
  1117.     JZ    MDRD5    ; DELETED OR EMPTY FILE
  1118.     CPI    ENDSLOT    ; LAST ENTRY IN MITS DIRECTORY
  1119.     RZ
  1120.     PUSH    H
  1121.     MVI    A,11
  1122.     CALL    ADDAHL    ; POINT TO FIRST UNUSED LOC IN THIS ENTRY
  1123.     CALL    FNCALC
  1124.     MOV    M,A    ; PUT FILE NUMBER IN OLD DIRECTORY
  1125.     IF    DEBUGGING
  1126.     LDA    SECTOR
  1127.     INX    H
  1128.     MOV    M,A
  1129.     INX    H
  1130.     MVI    A,9
  1131.     SUB    B
  1132.     MOV    M,A
  1133.     ENDIF
  1134.     POP    H
  1135.     MVI    C,DSIZE ; SIZE OF ENTRY
  1136. MDRD3    MOV    A,M
  1137.     STAX    D
  1138.     INX    D
  1139.     INX    H
  1140.     DCR    C
  1141.     JNZ    MDRD3    ; LOOP TILL DIRECTORY IS OBTAINED
  1142.     LDA    FCOUNT    ; INCREMENT FILE COUNT
  1143.     INR    A
  1144.     STA    FCOUNT
  1145. MDRD4    DCR    B    ; NUMBER OF DIRECTORY ENTRIES/SECTOR
  1146.     JNZ    MDRD2
  1147.     JMP    MDRD6    ; READ NEXT DIRECTORY SECTOR
  1148. MDRD5    PUSH    D
  1149.     LXI    D,DSIZE    ; PASS VACANT DIRECTORY ENTRY
  1150.     DAD    D
  1151.     POP    D
  1152.     JMP    MDRD4
  1153. MDRD6    LDA    SECTOR
  1154.     ADI    17    ; LATENCY CALCULATION SCHTICK
  1155.     CPI    32
  1156.     JC    MDRD7
  1157.     SUI    32    ; REDUCE MODULO 32
  1158. MDRD7    STA    SECTOR
  1159.     JMP    MDRD1
  1160. ;SHELL-METZNER SORT
  1161. ; THIS IS AN 8080 ADAPTATION OF THE SHELL SORT AS MODIFIED BY MARLENE METZNER
  1162. ; IT WILL SORT ANY FIXED LENGTH RECORD OF UP TO 255 BYTES INTO ASCENDING ORDER.
  1163. ; BY MODIFICATION OF THE PROGRAM AT "COMP" IT CAN SORT INTO DESCENDING ORDER OR
  1164. ; CAN BE MADE TO EXIT EACH TIME THAT AN EQUAL RECORD IS FOUND.
  1165. ;
  1166. ;
  1167. ; REGISTER USE:
  1168. ;
  1169. ; B=VAR I , C= VAR J , D= VAR K , E= VAR L , H= VAR M
  1170. ; FOR MORE DETAILS SEE KNUTH, DONALD E.: THE ART OF COMPUTER PROGRAMMING,
  1171. ;    VOL. 3: SORTING AND SEARCHING. ADDISON-WESLEY, 1973
  1172. ;    THERE IS NO DIRECT REFERENCE TO METZNER'S MODIFICATION
  1173. SORT:    LDA    FCOUNT    ; NUMBER OF RECORDS TO SORT
  1174.     MOV    H,A    ; PUT IT IN H (FIRST TIME ONLY)
  1175. SORT1:    MOV    A,H    ; START NEW PASS
  1176.     ORA    A    ; CLEAR CARRY FLAG
  1177.     RAR        ;M=M/2 (VARM)
  1178.     ORA    A    ; CLEAR CARRY
  1179.     MOV    H,A    ; M=INT(M/2)
  1180.     RZ        ; SORT FINISHED
  1181.     LDA    FCOUNT    ; GET N (NUMBER OF RECORDS)
  1182.     SUB    H    ; MINUS M
  1183.     MOV    D,A    ; SAVE IN D (K)
  1184.     MVI    C,1    ; SET VAR J=1
  1185. SORT2:    MOV    B,C    ; SET I=J INNER LOOP
  1186. SORT3:    MOV    A,B
  1187.     ADD    H    ; L=I+M (VAR L)
  1188.     MOV    E,A
  1189. SORT4:    PUSH    H
  1190.     PUSH    D
  1191.     PUSH    B
  1192.     MOV    A,B    ; GET I
  1193.     CALL    SETAD    ; CALCULATE ADDRESS (DISPLACEMENTS INTO RECORD)
  1194.     SHLD    CRCEL    ; SAVE I ADDRESS DISPLACED
  1195.     POP    B
  1196.     POP    D
  1197.     POP    H
  1198. SORT5:    PUSH    H
  1199.     PUSH    D
  1200.     PUSH    B
  1201.     MOV    A,E    ; GET L
  1202.     CALL    SETAD    ; CALCULATE ADDRESS (DISPLACEMENT INTO RECORD)
  1203.     SHLD    CRCL1    ; SAVE L ADDRESS DISPLACED
  1204.     POP    B
  1205.     POP    D
  1206.     POP    H
  1207. SORT6:    PUSH    H
  1208.     PUSH    D
  1209.     PUSH    B
  1210.     MVI    B,8    ; LENGTH OF SORT FIELD
  1211.     LHLD    CRCL1    ; L RECORD ADDRESS
  1212.     XCHG        ; MOVE L RECORD COMPARE ADDRESS TO DE
  1213.     LHLD    CRCEL    ; I-RECORD
  1214.     XCHG        ; I-RECORD ADDRESS TO DE, L RECORD TO HL
  1215.     CALL    COMP    ; COMPARE STRINGS
  1216.     POP    B
  1217.     POP    D
  1218.     POP    H
  1219. TEST:    ORA    A
  1220.     JZ    SORT7
  1221.     JM    SORT7    ; SORT7=>NO SWAP
  1222.     CALL    XFER    ; SWAP SUBROUTINE
  1223.     MOV    A,B
  1224.     SUB    H
  1225.     MOV    B,A    ; I=I-M
  1226.     JC    SORT7
  1227.     JNZ    SORT3    ; SET NEW L
  1228. SORT7:    INR    C    ; INCREMENT J COUNT
  1229.     MOV    A,D
  1230.     CMP    C    ; J>K?
  1231.     JC    SORT1    ; YES, START NEW (NEXT) PASS
  1232.     JMP    SORT2    ; ELSE CONTINUE THIS PASS
  1233. ; SUBROUTINES
  1234. ;SETAD - SET ADDRESS
  1235. ;
  1236. SETAD:    MVI    D,0
  1237.     MOV    E,A
  1238.     MVI    A,DSIZE    ; LENGTH OF RECORD TO SORT
  1239.     MOV    H,D
  1240.     MOV    L,D
  1241.     MVI    B,8
  1242. SETAD1:    DAD    H
  1243.     RLC
  1244.     JNC    SETAD2
  1245.     DAD    D
  1246. SETAD2:    DCR    B
  1247.     JNZ    SETAD1
  1248.     XCHG
  1249.     LXI    H,OND-DSIZE
  1250.     DAD    D
  1251.     RET
  1252. ;
  1253. ; XFER - SWAPS STRINGS I AND J
  1254. ;
  1255. XFER:    PUSH    H
  1256.     PUSH    D
  1257.     PUSH    B
  1258.     MVI    B,DSIZE
  1259.     LHLD    CRCEL
  1260.     XCHG
  1261.     LHLD    CRCL1
  1262. XFER1:    LDAX    D
  1263.     MOV    C,A
  1264.     MOV    A,M
  1265.     STAX    D
  1266.     MOV    M,C
  1267.     INX    D
  1268.     INX    H
  1269.     DCR    B
  1270.     JNZ    XFER1
  1271.     POP    B
  1272.     POP    D
  1273.     POP    H
  1274.     RET
  1275. COMP:    DCR    B
  1276.     RM
  1277.     LDAX    D
  1278.     SUB    M
  1279.     INX    D
  1280.     INX    H
  1281.     JZ    COMP
  1282.     RET
  1283. ;
  1284. ; HARD SECTOR DISK INPUT
  1285. ;
  1286. HSDI    CALL    SECGET
  1287.     MVI    C,BSIZE
  1288. HSDI1    IN    8
  1289.     ORA    A
  1290.     JM    HSDI1
  1291.     IN    10
  1292.     MOV    M,A
  1293.     INX    H
  1294.     DCR    C
  1295.     JZ    HSDI2
  1296.     DCR    C
  1297.     NOP
  1298.     IN    10
  1299.     MOV    M,A
  1300.     INX    H
  1301.     JNZ    HSDI1
  1302. HSDI2    EI
  1303.     RET
  1304. ;
  1305. ;DISK INPUT DRIVER COUPLER
  1306. ;
  1307. DISKIN    PUSH    H
  1308.     PUSH    D
  1309.     PUSH    B
  1310.     LDA    DISK
  1311.     OUT    8    ; SELECT DISK
  1312.     LDA    TRACK
  1313.     MOV    D,A
  1314.     CALL    TRACKGET
  1315.     LDA    SECTOR
  1316.     MOV    E,A
  1317.     LHLD    ADDR
  1318.     CALL    HSDI
  1319.     CALL    HEADUNLOAD
  1320.     POP    B
  1321.     POP    D
  1322.     POP    H
  1323.     RET
  1324. DISKSET:
  1325.     PUSH    PSW
  1326.     OUT    8    ; SELECT DISK
  1327.     NOP        ; IN CASE HARDWARE DOESN'T WORK
  1328.     IN    8    ; SENSE READY
  1329.     ANI    020H    ; SENSE INTERRUPTS ENABLED (READY)
  1330.     JNZ    WAITUP    ;
  1331.     POP    PSW
  1332.     CALL    TRACK0
  1333.     RET
  1334. WAITUP:    MVI    A,200
  1335. WAIT1:    DCR    A
  1336.     JNZ    WAIT1
  1337.     POP    A
  1338.     OUT    8
  1339.     NOP
  1340.     NOP
  1341.     JMP    DISKSET
  1342.     DS    50    ; STACK REGION
  1343. STACK    EQU    $
  1344. CPMSTK    DW    0    ; CP/M STACK POINTER
  1345.     END    0100H    ; START OF TPA
  1346.