home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol042 / mtx2000.asm < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  35.8 KB  |  1,556 lines

  1. ;===================================================================
  2. ;    MICRO RESOURCES CP/M -- MTX FILE TRANSFER PROGRAM
  3. ;        FOR USE WITH PERTEC PCC 2000 DD CP/M 1.4
  4. ;===================================================================
  5. ;
  6. ;
  7. ; THIS PROGRAM IS A UTILITY TO TRANSFER FILES FROM PCC 2000 MTX
  8. ; DOUBLE DENSITY DISKS TO CP/M DISKS OR TO TRANSFER A CP/M
  9. ; FILE TO A PCC 2000 MTX DOUBLE DENSITY DISK. A PROVISION HAS
  10. ; ALSO BEEN INCLUDED TO ALLOW EXAMINATION OF THE DIRECTORY OF
  11. ; THE MTX DISKETTE. THE OPERATION OF THIS PROGRAM ASSUMES
  12. ; THAT A CP/M SYSTEM DISK IS PRESENT IN DRIVE A: AND THAT THE
  13. ; MTX DATA DISK IS IN DRIVE B:. THE BIOS PRIMITIVES OF THE CP/M
  14. ; SYSTEM ARE ACCESSED DIRECTLY TO ALLOW READING AND WRITING
  15. ; OF THE DOUBLE DENSITY MTX DISK WITH IT'S 2 TO 1 LOGICAL
  16. ; TO PHYSICAL SECTOR MAPPING. NOTE THAT THIS SOFTWARE IS
  17. ; SPECIFICALLY TAYLORED TO FUNCTION THROUGH THE BIOS VECTORS
  18. ; OF THE PERTED IMPLEMENTATION OF CP/M 1.4 ON A PCC 2000 WITH
  19. ; DOUBLE DENSITY FLOPPY DISKS.
  20. ;
  21. ; THIS PROGRAM DOES NOT PACK THE FILES OF THE MTX DISK
  22. ; WHEN CREATING NEW FILES UPON TRANSFER FROM A CP/M FILE.
  23. ; SUBSEQUENT PACKING MAY DONE UPON THE DESTINATION MTX/PCC 2000
  24. ; SYSTEM.
  25. ;
  26. ; THE DIRECTORIES OF EITHER DISK WILL BE SCANNED FOR FILES
  27. ; OF SIMILAR NAMES BEFORE A TRANSFER IS ACTUALLY MADE. A PROMPT
  28. ; QUESTION WILL INDICATE WHEN THE FILE ALREADY EXISTS. IN THE
  29. ; CASE OF THE CP/M DISK THE INDICATED FILE MAY BE ERASED IF
  30. ; DESIRED. WITH THE MTX DISK A FILE WILL NOT BE DELETED
  31. ; AND THE NAME OF THE SOURCE FILE ON THE CP/M DISK WILL HAVE
  32. ; TO BE CHANGED TO A NAME NOT CURRENTLY ON THE MTX DISK.
  33. ; FILE NAMES OF MTX FILES ARE A MAXIMUM OF 6 ASCII CHARACTERS
  34. ; IN LENGTH SO THE CP/M FILE TRANSFERRED TO THE MTX DISK
  35. ; WILL HAVE ITS NAME TRUNCATED TO THE FIRST SIX CHARACTERS.
  36. ; THE MTX FILE TYPE WILL ALWAYS BE SET TO 00 AS AN INDEXED
  37. ; FILE TYPE. RECORD SIZE OF A MTX DESTINATION FILE WILL BE
  38. ; SET TO 128 BYTES. FOR MTX DESTINATION FILES THAT ARE AN
  39. ; ODD NUMBER OF 128 BYTE RECORDS THE LAST HALF IS BACK
  40. ; FILLED WITH AN ARBITRARY CHOICE OF ZEROS.
  41. ;
  42. ; FOR FILES TRANSFERRED TO CP/M FROM MTX DISKS THE FILE
  43. ; TYPE WILL BE CHECKED AND IF THE SOURCE TYPE IS NOT AN
  44. ; INDEXED FILE THEN THE TRANSFER TO CP/M WILL NOT BE
  45. ; MADE.
  46. ;
  47. ; THIS PROGRAM BUFFERS CP/M SECTOR READS UP 156 IN 
  48. ; LENGTH TO MAKE THE TRANSFER MORE EFFICIENT.
  49. ;
  50. ;
  51. ;
  52. ;
  53. ;*****************************************************************
  54. ;
  55. ;THIS SOFTWARE IS PROTECTED UNDER THE FOLLOWING COPYRIGHT
  56. ;AND MAY NOT BE REPRODUCED OR COPIED IN ANY FORM WITHOUT 
  57. ;SPECIFIC PERMISSION FROM MICRO RESOURCES.
  58. ;
  59. ;
  60. ;   COPYRIGHT (C) 1980
  61. ;
  62. ;
  63. ;    MICRO RESOURCES
  64. ;    MICHAEL J. KARAS
  65. ;    2468 HANSEN CT.
  66. ;    SIMI VALLEY, CA 93065
  67. ;    (805) 527-7922
  68. ;
  69. ;ANY QUESTIONS ABOUT THIS PROGRAM OR ITS APPLICATION
  70. ;CAN BE DIRECTED TO THE ABOVE ADDRESS OR TELEPHONE NUMBER.
  71. ;
  72. ;*********************************************************************
  73. ;
  74. WBOOT    EQU    00        ;CP/M WARM BOOT ENTRY ADDRESS
  75. ;
  76. ERRLIM    EQU    10        ;MAX ALLOWABLE ERRORS
  77. ;DEFINE ASCII CHARACTERS USED
  78. ;
  79. LF    EQU    10        ;LINEFEED
  80. CR    EQU    13        ;CARRIAGE RETURN
  81. ;
  82. ;START OF EXECUTABLE CODE
  83. ;
  84.     ORG    100H
  85.     CALL    START        ;GO PRINT ID
  86.     DB    'MICRO RESOURCES FILE TRANSFER UTILITY '
  87.     DB    CR,LF,'  PCC 2000 CP/M <----> PCC 2000 MTX'
  88.     DB    CR,LF,'          VER 1.31 11/15/80'
  89.     DB    CR,LF,'$'
  90. ;
  91.     DB    'COPYRIGHT 1980 MICRO RESOURCES'
  92.     DB    '2468 HANSEN CT.'
  93.     DB    'SIMI VALLEY, CA 93065'
  94.     DB    '(805) 527-7922'
  95. START:
  96.     POP    D        ;GET ID MESSAGE
  97.     MVI    C,PRINT
  98.     CALL    BDOS        ;PRINT ID MESSAGE
  99. ;
  100. ;INIT PRIVATE STACK
  101. ;
  102.     LXI    H,0        ;HL=0
  103.     DAD    SP        ;HL=STACK FROM CP/M
  104.     SHLD    STACK        ;..SAVE IT
  105.     LXI    SP,STACK     ;SP=MY STACK
  106. ;
  107. ;INITIALIZE THE CP/M FILE BUFFERING PARAMETERS
  108. ;
  109.     MVI    A,00H
  110.     STA    SECINBF        ;ZERO SEC IN BUFFER COUNTER
  111.     STA    EOFLG        ;RESET CP/M END OF FILE FLAG
  112.     LXI    H,DBUF        ;INITIALIZE BUFFER POINTER
  113.     SHLD    SECPTR
  114. ;
  115. ;INITIALIZE THE JMPS TO CP/M BIOS
  116. ;
  117.     CALL    INITADR
  118. ;
  119. ;SAVE PROGRAM OPTION
  120. ;
  121.     CALL    PROCOPT
  122. ;
  123. ;MOVE THE FILENAME FROM FCB 2 TO FCB 1
  124. ;
  125.     CALL    MOVEFCB
  126. ;
  127. ;JMP TO APPROPRIATE FUNCTION
  128. ;
  129.     LDA    OPTION        ;GET PROGRAM OPTION
  130. ;
  131.     CPI    'R'        ;READ MTX FILE?
  132.     JZ    MTXRD
  133. ;
  134.     CPI    'W'        ;WRITE MTX FILE?
  135.     JZ    MTXWR
  136. ;
  137.     CPI    'D'         ;LOOK AT MTX DIRECTORY
  138.     JZ    MTXDIR
  139. ;
  140.     CPI    'H'        ;GO TO HELP FILE PRINTOUT?
  141.     JZ    HELP
  142. ;
  143. ;INVALID OPTION
  144. ;
  145.     JMP    BADOPT
  146. ;
  147. ;
  148. ;
  149. * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  150. *                                        *
  151. *    MTXDIR: LISTS MTX DIRECTORY TO CONSOLE          *
  152. *                                   *
  153. * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  154. ;
  155. ;
  156. ;THE DIRECTORY OF THE DOUBLE DENSITY MTX
  157. ;DISK IN DRIVE B: IS LISTED TO THE CONSOLE IN
  158. ;A SINGLE COLUMN FORMAT. CONSOLE I/O IS DONE
  159. ;THROUGH CP/M SO THAT THE CTL-S AND CTL-P
  160. ;FUNCTIONS WILL WORK. THE LISTING ALSO STOPS
  161. ;AFTER EACH 16 ENTRIES HAVE BEEN TYPED
  162. ;
  163. MTXDIR:
  164.     CALL    ILPRT        ;PRINT THE DIRECTORY HEADER LABEL
  165.     DB    CR,LF,CR,LF,'            MTX DISK DIRECTORY'
  166.     DB    CR,LF,CR,LF
  167.     DB    'FILENAME  TYPE RECORD RECORD START  END ',CR,LF
  168.     DB    '               COUNT  SIZE   SECTOR SECTOR',CR,LF
  169.     DB    '------------------------------------------',CR,LF,0
  170. ;
  171.     MVI    A,016        ;SET PRINT LOOP COUNT
  172.     STA    LISTCNT
  173.     MVI    A,00        ;SET SCAN FOR FIRST ENTRY
  174.     JMP    MDIR2        ;JUMP INTO LOOP
  175. MDIR1:
  176.     MVI    A,01        ;SET SCAN CODE FOR NEXT ENTRY
  177. MDIR2:
  178.     CALL    MDIRSC        ;SCAN FOR NEXT DIRECTORY ENTRY
  179.     ORA    A        ;SET FLAGES FOR RETURN CODE
  180.     JNZ    MDEREX        ;GO EXIT FOR FULL DISK DIRECTORY
  181.     LDA    MDENT        ;GET FIRST CHAR OF DERECTORY ENTRY
  182.     CPI    0FFH        ;MUST BE AT END OF THE LIST
  183.     JZ    MDIREX
  184.     CPI    000H        ;CHECK IF THIS ENTRY IS EMPTY
  185.     JZ    MDIR1        ;SKIP PRINT IF SO
  186.     CALL    PRTDIR        ;PRINT THIS ENTRY
  187. ;
  188.     LDA    LISTCNT        ;GET LIST LINE COUNT
  189.     DCR    A        ;DECREMENT IT
  190.     STA    LISTCNT        ;STORE NEW COUNT BACK
  191.     JNZ    MDIR1        ;GO TO DO NEXT ENTRY
  192. ;
  193.     CALL    ILPRT        ;GIVE THE GUY A CHANCE TO STOP A LONG DIRECTORY
  194.     DB    1,CR,LF,0
  195. ;
  196.     MVI    A,016        ;RESET PRINT LOOP COUNT
  197.     STA    LISTCNT
  198.     JMP    MDIR1        ;GO START ON 16 MORE ENTRIES
  199. ;
  200. MDIREX:
  201.     CALL    ILPRT        ;PRINT END OF LIST MESSAGE
  202.     DB    CR,LF,CR,LF,'END OF MTX DISK DIRECTORY',CR,LF,0
  203. MDIREX1:
  204.     MVI    C,00H        ;RESTORE SELECT OF DRIVE A:
  205.     CALL    SELDSK        ;DIRECT BIOS ACCESS
  206.     JMP    EXIT        ;DONE WITH DIRECTORY
  207. ;
  208. MDEREX:
  209.     CALL    ILPRT        ;PRINT DISK FULL MESSAGE
  210.     DB    CR,LF,'++MTX DISK DIRECTORY SPACE FULL++',CR,LF,0
  211. ;
  212.     JMP    MDIREX1
  213. ;
  214. ;
  215. ;
  216. ;
  217. ;SCAN MTX DIRECTORY ROUTINE
  218. ;    ROUTINE ENTRY IS CODED TO ALLOW VARIABLE FUNCTIONS
  219. ;    CODE IS PASSED IN THE A REGISTER
  220. ;    CODES AS FOLLOWS:
  221. ;        00=OPEN SCAN FROM BEGINNING WITH LOGICAL SECTOR 1
  222. ;        01=GET NEXT DIRECTORY ENTRY
  223. ;
  224. ;    RETURN VALUE IS THE FIRST OR NEXT ENTRY AS SPECIFIED BY THE
  225. ;    FUNCTION CODE AND IS PASSED IN BUFFER "MDENT" WHICH IS 16
  226. ;    BYTES LONG.
  227. ;
  228. ;    THIS ROUTINE SCANS AND RETURNS ALL POSSIBLE ENTRIES
  229. ;    AND WHEN END OF LOGICAL SECTOR 25 IS ENCOUNTERED AN 
  230. ;    0FFH CODE IS RETURNED IN THE ACCUMULATOR. ELSE A 00H 
  231. ;    CODE IS RETURNED.
  232. ;
  233. ;
  234. ;
  235. MDIRSC:
  236.     ORA    A        ;SET FLAGS FOR FUNCTION CHECK
  237.     JNZ    NEXTENT        ;FOR NON-ZERO CODE JUST GET NEXT ENTRY
  238. ;
  239. ;SETUP FOR BEGINNING OF SCAN
  240.     MVI    A,000H        ;SETUP START SECTOR OF DIRECTORY-1 
  241.     STA    MDIRSEC
  242.     MVI    A,016        ;SET CURRENT SUBSCAN COUNT TO MAX
  243.     STA    DIRSECI
  244. ;
  245. NEXTENT:
  246.     LDA    DIRSECI        ;GET SECTOR INDEX
  247.     CPI    016        ;AT MAXIMUM ENTRY?
  248.     JNZ    SAMSEC        ;NO STAY WITH THIS SECTOR
  249.     LXI    H,MDIRSEC
  250.     INR    M        ;INCREMENT CURRENT SECTOR NUMBER
  251.     MOV    A,M        ;GET THE SECTOR NUMBER
  252.     CPI    026        ;CHECK FOR THE LAST SECTOR
  253.     JNZ    NXTSEC        ;GO AROUND THE END OF TRACK EXIT
  254. ;
  255.     MVI    A,0FFH        ;SETUP EXIT FOR END OF DIRECTORY SPACE
  256.     RET
  257. ;
  258. NXTSEC:
  259.     MOV    L,A
  260.     MVI    H,00H
  261.     CALL    MRDSEC        ;GO READ MTX SECTOR
  262.     LXI    H,MTXBUF    ;MOVE INPUT BUFFER 
  263.     LXI    D,DIRBUF    ;..TO DIRECTORY BUFFER
  264.     MVI    B,00H        ;SET COUNT FOR FULL 256
  265.     CALL    MOVE
  266.     MVI    A,00
  267.     STA    DIRSECI        ;SET SECTOR INDEX TO MINIMUM
  268. ;
  269. SAMSEC:
  270.     LXI    H,DIRSECI
  271.     MOV    B,M        ;GET THE INDEX
  272.     INR    M        ;INCR THE SECTOR INDEX
  273.     LXI    H,DIRBUF    ;POINT TO THE MTX DIRECTORY BUFFER
  274.     LXI    D,016        ;LENGTH OF AN ENTRY
  275.     MOV    A,B
  276.     CPI    00H        ;CHECK FOR ILLEGAL ZERO LOOP COUNT
  277.     JZ    SAMSEC2
  278. SAMSEC1:
  279.     DAD    D        ;LOOP TO MAKE OFFSET INDEX
  280.     DCR    B
  281.     JNZ    SAMSEC1
  282. SAMSEC2:
  283.     LXI    D,MDENT        ;POINT TO ENTRY PASS BUFFER
  284.     MVI    B,016        ;SETUP LENGTH OF DIRECTORY ENTRY
  285.     CALL    MOVE        ;GO MOVE A DIRECTORY ENTRY
  286.     LXI    H,MDENT        ;SETUP TO STRIP MTX MBS'S FROM FILE NAME
  287.     MOV    A,M        ;SEE IF FIRST BYTE IS 0FFH
  288.     CPI    0FFH        ;IF SO WE SKIP MSB STRIP
  289.     JZ    ENDRET
  290.     MVI    B,06H        ;CHARACTER COUNT
  291. SAMSEC3:
  292.     MOV    A,M        ;GET CHARACTER OF NAME
  293.     ANI    07FH        ;STRIP MTX STRING CRAP
  294.     MOV    M,A
  295.     INX    H
  296.     DCR    B        ;DEC NAME BYTE COUNT
  297.     JNZ    SAMSEC3
  298. ;
  299. ENDRET:
  300.     MVI    A,00H        ;SET NORMAL RETURN FLAG
  301.     RET
  302. ;
  303. ;
  304. ;
  305. ;
  306. ;DIRECTORY SCAN POINTER PARAMETERS
  307. ;
  308. ;
  309. MDIRSEC    DB    00        ;CURRENT DIRECTORY SECTOR NUMBER
  310. DIRSECI    DB    00        ;INDEX OF SCAN INTO CURRENT DIRECTORY SECTOR
  311. DIRBUF    DS    256        ;256 BYTE DIRECTORY ENTRY BUFFER
  312. LISTCNT    DB    00        ;DIRECTORY LIST ENTRY COUNT
  313. ;
  314. ;
  315. ;
  316. ;PRINT DIRECTORY ENTRY SUBROUTINE
  317. ;
  318. ;
  319. PRTDIR:
  320.     LXI    H,MDENT        ;POINT TO DIRECTORY ENTRY BUFFER
  321.     MVI    A,'B'
  322.     CALL    CTYPE        ;PRINT OUT DRIVE DESIGNATOR
  323.     MVI    A,':'
  324.     CALL    CTYPE
  325.     MVI    B,06        ;FILE NAME CHARACTER COUNT
  326. NAMLP:
  327.     MOV    A,M        ;GET NAME CHARACTER
  328.     CALL    CTYPE
  329.     INX    H        ;INCREMENT BUFFER POINTER
  330.     DCR    B
  331.     JNZ    NAMLP        ;GO FOR NEXT NAME CHAR
  332. ;
  333.     CALL    SP3        ;THREE SPACES
  334.     MOV    A,M        ;GET TYPE BYTE
  335.     CALL    HEXO        ;SHOW IT
  336.     INX    H        ;INCREMENT THE BUFFER POINTER
  337. ;
  338.     INX    H        ;SKIP THE KEY SIZE FIELD
  339. ;
  340.     CALL    SP2        ;TWO SPACES
  341.     MOV    D,M        ;GET HIGH RECORD COUNT BYTE
  342.     INX    H
  343.     MOV    E,M        ;GET LOW RECORD COUNT BYTE
  344.     INX    H
  345.     PUSH    H        ;SAVE STRING POINTER
  346.     CALL    DECPRT        ;GO PRINT RECORD COUNT
  347.     POP    H
  348. ;
  349.     CALL    SP2        ;TWO SPACES
  350.     MOV    D,M        ;GET HIGH RECORD SIZE BYTE
  351.     INX    H
  352.     MOV    E,M        ;GET LOW RECORD SIZE BYTE
  353.     INX    H
  354.     PUSH    H        ;SAVE STRING POINTER
  355.     CALL    DECPRT        ;GO PRINT RECORD SIZE
  356.     POP    H
  357. ;
  358.     CALL    SP2        ;TWO SPACES
  359.     MOV    D,M        ;GET HIGH START SECTOR BYTE
  360.     INX    H
  361.     MOV    E,M        ;GET LOW START SECTOR BYTE
  362.     INX    H
  363.     PUSH    H        ;SAVE STRING POINTER
  364.     CALL    DECPRT        ;GO PRINT START SECTOR COUNT
  365.     POP    H
  366. ;
  367.     CALL    SP2        ;TWO SPACES
  368.     MOV    D,M        ;GET HIGH END SECTOR BYTE
  369.     INX    H
  370.     MOV    E,M        ;GET LOW END SECTOR BYTE
  371.     DCX    D        ;SET THE ENDING SECTOR TO REAL VALUE
  372.     CALL    DECPRT        ;GO PRINT ENDING SECTOR COUNT
  373. ;
  374.     CALL    CRLF        ;GET READY FOR NEXT LINE
  375.     RET
  376. ;
  377. ;
  378. ;CONVERT AND PRINT A TWO BYTE VALUE AT CONSOLE IN DECIMAL
  379. ;
  380. DECPRT:
  381.     XCHG            ;HL=WORD TO PRINT
  382.     LXI    D,STRBUF    ;POINT TO A CONVERT BUFFER
  383.     CALL    BINASC        ;CONVERT TO DECIMAL ASCII
  384.     MVI    B,05H        ;BYTE COUNT PRINT STRING
  385.     LXI    H,STRBUF    ;POINT TO THE PRINT BUFFER
  386. DECPRT1:
  387.     MOV    A,M        ;GET PARAMETER CHARACTER
  388.     PUSH    H
  389.     CALL    CTYPE        ;PRINT AT CONSOLE
  390.     POP    H
  391.     INX    H        ;INCREMENT STRING POINTER
  392.     DCR    B        ;DEC BYTE COUNT
  393.     JNZ    DECPRT1        ;DONE WITH FIVE CHAR YET
  394.     RET
  395. ;
  396. ;
  397. ;DECIMAL PRINTING ROUTINE TEMPORARY BUFFER STRING SPACE
  398. ;
  399. STRBUF:
  400.     DS    14        ;RESERVE SOME BYTES FOR BUFFER
  401. ;
  402. ;
  403. ;CONSOLE SPACE PRINTING ROUTINE
  404. ;
  405. SP5:
  406.     MVI    A,' '        ;5 SPACES
  407.     CALL    CTYPE
  408. SP4:
  409.     MVI    A,' '        ;4 SPACES
  410.     CALL    CTYPE
  411. SP3:
  412.     MVI    A,' '        ;3 SPACES
  413.     CALL    CTYPE
  414. SP2:
  415.     MVI    A,' '        ;2 SPACES
  416.     CALL    CTYPE
  417. SP1:
  418.     MVI    A,' '        ;1 SPACE
  419.     CALL    CTYPE
  420.     RET
  421. ;
  422. ;
  423. ;
  424. ;
  425. * * * * * * * * * * * * * * * * * * * * *
  426. *                    *
  427. *    MTXWR: COPIES FILE TO MTX       *
  428. *                    *
  429. * * * * * * * * * * * * * * * * * * * * *
  430. ;
  431. ;THE CP/M FILE SPECIFIED IN THE COMMAND
  432. ;IS TRANSFERRED TO THE MTX DISK IN DRIVE B:
  433. ;
  434. MTXWR:
  435.     CALL    OPENFIL        ;OPEN THE FILE
  436.     LXI    H,0000H        ;SET INITIAL RECORD COUNT TO ZERO
  437.     SHLD    RECCNT
  438.     MVI    H,26        ;SET MAX UTILIZED SECTOR TO 26
  439.                 ;..MTX STARTS FILES AT LOGICAL SECTOR 26
  440.     SHLD    MAXSEC        ;STORE AWAY
  441.     MVI    A,00H
  442.     STA    MTXEOF        ;CLEAR MTX EOF FLAG
  443.     MVI    A,00H        ;SETUP FOR DIRECTORY SCAN
  444.     JMP    SCAN2        ;JUMP INTO LOOP
  445. SCAN1:
  446.     MVI    A,01H        ;SET SCAN CODE FOR NEXT ENTRY
  447. SCAN2:
  448.     CALL    MDIRSC        ;SCAN FOR NEXT DIRECTORY ENTRY
  449.     ORA    A        ;SET FLAGS FOR RETURN CODE
  450.     JNZ    MDIRFUL        ;EXIT FOR FULL DIRECTORY
  451. ;
  452.     MVI    B,06        ;SETUP FOR COMPARE OF FILE NAMES
  453.     LXI    D,FCB+1        ;..FOR 6 CHAR FROM CP/M FCB
  454.     LXI    H,MDENT        ;..TO MTX DIRECTORY ENTRY
  455.     CALL    COMPARE        ;GO DO THE COMPARE
  456.     ORA    A        ;CHECK    RETURN FLAG
  457.     JNZ    FEXEX        ;EXIT WITH FILE EXISTS MESSAGE
  458. ;
  459.     LDA    MDENT        ;FIRST BYTE OF NAME "FF" IF END
  460.     CPI    0FFH        ;ARE WE AT END OF LIST?
  461.     JZ    SCAN3        ;IF AT END THEN BALE OUT OF LOOP
  462. ;
  463.     LHLD    MAXSEC        ;SET TO UPDATE MAX USED SECTOR IF NEEDED
  464.     XCHG
  465.     LHLD    MDENT+14
  466.     MOV    A,L        ;COMPARE HIGH BYTE OF THIS ONE AND CURRENT MAX
  467.     CMP    E
  468.     JC    SCAN1        ;NO UPDATE NEEDED
  469.     JNZ    UDTMAX        ;IF HIGH BYTE GREATER THEN UPDATE MAX
  470.     MOV    A,H        ;COMPARE LOW BYTES OF THIS ONE AND CURRENT MAX
  471.     CMP    D
  472.     JC    SCAN1        ;NO UPDATE IF HIGHS EQUAL AND LOW NOT BIGGER
  473. UDTMAX:
  474.     SHLD    MAXSEC        ;STORE NEW BIG SEC NUM AT MAX SEC LOC
  475.     JMP    SCAN1        ;GO DO MORE DIRECTORY ENTRIES
  476. ;
  477. SCAN3:
  478.     MVI    B,06        ;MOVE FILE NAME INTO MTX DIRECTORY ENTRY
  479.     LXI    H,FCB+1
  480.     LXI    D,MDENT
  481. SCANAP:
  482.     MOV    A,M        ;GET CHAR FROM FCB AREA
  483.     ORI    080H        ;PUT ON TOP BIT FOR MTX COMPATIBILITY
  484.     STAX    D        ;PUT IN NEW DIRECTORY ENTRY
  485.     INX    H        ;BUMP POINTERS
  486.     INX    D
  487.     DCR    B        ;DEC NAME BYTE COUNT
  488.     JNZ    SCANAP
  489. ;
  490.     MVI    A,00        ;SET THE NEW FILE TYPE TO ZERO AS INDEXED FILE
  491.     STA    MDENT+6
  492.     STA    MDENT+7        ;SET KEYSIZE FIELD TO ZERO
  493.     STA    MDENT+10    ;SET HIGH BYTE OF RECORD SIZE TO ZERO
  494.     MVI    A,080H
  495.     STA    MDENT+11    ;SET RECORD SIZE TO 128 BYTES AS CP/M
  496.                 ;SECTOR SIZE
  497.     LHLD    MAXSEC        ;GET CURRENT MAX SECTOR AND PUT AS START
  498.     SHLD    MDENT+12
  499. ;
  500.     SHLD    MDENT+14    ;SET INITIAL END SECTOR
  501. MFILWLP:
  502.     CALL    RDSECT        ;READ A SECTOR FROM CP/M
  503.     JC    UPDATE        ;UPDATE MTX DIRECTORY IF DONE
  504.     LHLD    RECCNT        ;INC RECORD COUNT
  505.     CALL    MTXINC
  506.     SHLD    RECCNT
  507.     LXI    H,080H        ;MOVE SECTOR FROM CPM AREA
  508.     LXI    D,MTXBUF
  509.     CALL    MOVE128
  510.     CALL    RDSECT        ;READ ANOTHER SECTOR FROM CP/M
  511.     JC    UPDAFIL        ;UPDATE MTX DIRECTORY IF DONE
  512.     LHLD    RECCNT        ;INC RECORD COUNT
  513.     CALL    MTXINC
  514.     SHLD    RECCNT
  515.     LXI    H,080H        ;MOVE SECTOR FROM CP/M AREA
  516.     LXI    D,MTXBUF+128
  517.     CALL    MOVE128
  518. WRTENT:
  519.     LXI    H,MDENT+14    ;POINT TO SECTOR TO BE WRITTEN
  520.     MOV    D,M
  521.     INX    H
  522.     MOV    E,M
  523. ;
  524.     LXI    H,07B8H        ;CHECK IF DISK FULL
  525.     MOV    A,H
  526.     CMP    D
  527.     JNZ    NOTFUL
  528.     MOV    A,L
  529.     CMP    E
  530.     JZ    DSKFUL        ;EXIT WITH MESSAGE IF DISK IS FULL
  531. ;
  532. NOTFUL:
  533.     XCHG            ;HL=LOGICAL SECTOR TO WRITE
  534.     CALL    MWRSEC        ;GO WRITE CURRENT MTX SECTOR
  535.     LHLD    MDENT+14    ;INCREMENT END SECTOR
  536.     CALL    MTXINC
  537.     SHLD    MDENT+14
  538. ;
  539.     LDA    MTXEOF        ;SEE IF WE GOT TO END BEFORE
  540.     ORA    A
  541.     JNZ    UPDATE        ;GO TO UPDATE DIRECTORY IF END
  542. ;
  543.     JMP    MFILWLP        ;GO TO GET THE NEXT SECTOR FROM CP/M
  544. ;
  545. ;
  546. ;CP/M EOF ENCOUNTERED ON MIDDLE OF SECTOR NEEDS FILLING TO END
  547. ;    WE ARBITRARILY CHOOSE TO FILL WITH ZEROS.
  548. ;
  549. UPDAFIL:
  550.     LXI    H,MTXBUF+128    ;POINT TO SECOND HALF OF BUFFER
  551.     MVI    B,128        ;SET FILL COUNT
  552. SHFILL:
  553.     MVI    M,00H        ;PUT IN A ZERO
  554.     INX    H        ;BUMP POINTER
  555.     DCR    B        ;DEC BYTE COUNT
  556.     JNZ    SHFILL        ;MORE TO DO?
  557. ;
  558.     MVI    A,0FFH        ;SET END OF FILE FLAG
  559.     STA    MTXEOF
  560.     JMP    WRTENT        ;GO WRITE SECTOR
  561. ;
  562. ;FILE WRITTEN, NOW UPDATE THE DIRECTORY
  563. ;
  564. UPDATE:
  565.     XRA    A        ;INITIALIZE TWO SECTOR UPDATE FLAG
  566.     STA    U2SEC
  567. ;
  568.     LHLD    RECCNT        ;PUT RECORD COUNT INTO DIR ENTRY
  569.     MOV    A,H        ;CHECK IF THERE WAS NO CP/M FILE SIZE
  570.     ORA    L
  571.     JZ    NOSIZF        ;EXIT IF FILE FIZE IS ZERO
  572.     SHLD    MDENT+8
  573. ;
  574.     LXI    H,DIRBUF     ;MOVE DIRECTORY SECTOR TO OUTPUT BUFFER
  575.     LXI    D,MTXBUF
  576.     MVI    B,00H        ;SET THE COUNT FOR FULL 256 BYTE MOVE
  577.     CALL    MOVE
  578.     LDA    DIRSECI        ;GET DIRECTORY SECTOR INDEX    
  579.     LXI    H,MTXBUF-16
  580.     LXI    D,16        ;MAKE INSERT POINTER FOR NEW ENTRY
  581. UPDAT:
  582.     DAD    D
  583.     DCR    A
  584.     JNZ    UPDAT
  585. ;
  586.     XCHG            ;PUT INSERT POINTER IN DE
  587.     LXI    H,MDENT        ;POINT TO NEW DIRECTORY ENTRY
  588.     MVI    B,16        ;LENGTH OF DIRECTORY ENTRY
  589.     CALL    MOVE        ;MOVE INTO OUTPUT BUFFER
  590.     LDA    DIRSECI        ;SEE IF NEW ENTRY IS LAST IN SECTOR
  591.     CPI    016
  592.     JNZ    ONESEC        ;JUMP TO PUT END ENTRY IN THIS SECTOR
  593. ;
  594.     MVI    A,0FFH        ;SET U2SEC FLAG
  595.     STA    U2SEC
  596.     JMP    WDIRSEC        ;GO WRITE CURRENT SECTOR
  597. ;
  598. ONESEC:
  599.     MVI    A,0FFH         ;PUT "FF"ed OUT ENTRY INTO THIS SECTOR
  600.     MVI    B,16        ;ENTRY LENGTH-- DE OK FROM PREVIOUS MOVE
  601. ONESEC1:
  602.     STAX    D        ;PUT FF IN ENTRY
  603.     INX    D        ;INC FF'ING POINTER    
  604.     DCR    B        ;DEC BYTE COUNTER
  605.     JNZ    ONESEC1
  606. ;
  607. WDIRSEC:
  608.     LDA    MDIRSEC        ;GET THE DIRECTORY SECTOR NUMBER
  609.     MVI    H,0        ;MAKE TWO BYTE LOGICAL SECTOR NUMBER
  610.     MOV    L,A
  611.     CALL    MWRSEC        ;GO WRITE THE SECTOR OF DIRECTORY
  612.     LDA    U2SEC        ;CHECK IF WE SHOULD UPDATE TWO SECTORS
  613.     ORA    A
  614.     JNZ    GETSEC        ;IF SO GO PREPARE FOR IT
  615. ;
  616.     JMP    DONE        ;ALL DONE
  617. ;
  618. GETSEC:
  619.     XRA    A
  620.     STA    U2SEC        ;RESET UPDATE TWO SECTORS FLAG
  621.     LDA    MDIRSEC        ;GET CURRENT DIRECTORY SECTOR NUMBER
  622.     INR    A
  623.     STA    MDIRSEC        ;STORE THIS NEW ONE AWAY
  624.     CPI    01BH        ;SEE IF DIRECTORY FULL HERE
  625.     JZ    UDFULL        ;GO PRINT EXIT MESSAGE
  626. ;
  627.     MVI    H,0        ;MAKE TWO BYTE SECTOR NUMBER
  628.     MOV    L,A
  629.     CALL    MRDSEC        ;GO READ NEXT SECTOR
  630. ;
  631.     LXI    D,MTXBUF    ;POINT TO START OF DIRECTORY SECTOR
  632.     JMP    ONESEC        ;GO END THE PROCESS OF UPDATE ON SECOND SEC
  633. ;
  634. ;
  635. ;SUBROUTINE TO INCREMENT A REVERSE ORDER TWO BYTE PAIR
  636. ;
  637. MTXINC:
  638.     MOV    A,H        ;SET TO INCREMENT END SECTOR
  639.     MOV    H,L
  640.     MOV    L,A
  641.     INX    H        ;INC THE END SECTOR
  642.     MOV    A,H
  643.     MOV    H,L
  644.     MOV    L,A
  645.     RET
  646. ;
  647. ;
  648. ;EXIT POINT FROM WRITE IF MTX DIRECTORY IS FULL UPON UPDATE
  649. ;
  650. UDFULL:
  651.     CALL    ILPRT        ;PRINT DIRECTORY FULL MESSAGE
  652.     DB    CR,LF,'++MTX DIRECTORY FULL UPON UPDATE++'
  653.     DB    CR,LF,'++TRANSFERRED FILE EXISTS ON DISK++',CR,LF,0
  654.     JMP    EXIT
  655. ;
  656. ;
  657. ;EXIT POINT FROM WRITE IF MTX DIRECTORY IS FULL
  658. ;
  659. MDIRFUL:
  660.     CALL    ILPRT        ;PRINT DIRECTORY FULL MESSAGE
  661.     DB    CR,LF,'++MTX DIRECTORY MUST BE FULL++',CR,LF,0
  662.     JMP    EXIT
  663. ;
  664. ;
  665. ;EXIT POINT FROM WRITE IF NOTHING IN CP/M FILE
  666. ;
  667. NOSIZF:
  668.     CALL    ILPRT        ;PRINT NO SIZE TO CP/M FILE
  669.     DB    CR,LF,'++CP/M FILE EMPTY-NO MTX FILE CREATED++',CR,LF,0
  670.     JMP    EXIT
  671. ;
  672. ;
  673. ;EXIT POINT FROM WRITE IF MTX DISK GETS FULL
  674. ;
  675. DSKFUL:
  676.     CALL    ILPRT        ;PRINT DISK FULL MESSAGE
  677.     DB    CR,LF,'++FILE TOO BIG - MTX DISK FULL++'
  678.     DB    CR,LF,'++DIRECTORY NOT UPDATED WITH NEW FILE++',CR,LF,0
  679.     JMP    EXIT
  680. ;
  681. ;EXIT POINT FROM WRITE IF MTX FILE ALREADY EXISTS
  682. ;
  683. FEXEX:
  684.     CALL    ILPRT
  685.     DB    CR,LF,'++MTX FILE ALREADY EXISTS++'
  686.     DB    CR,LF,'++CHANGE NAME OF SOURCE FILE ON CP/M++',CR,LF,0
  687.     JMP    EXIT
  688. ;
  689. ;
  690. ;
  691. ;
  692. ;PARAMETER STORAGE AREA FOR MTX WRITE ROUTINE
  693. ;
  694. U2SEC    DB    00        ;USED TO SEE IF TWO SECTORS S/B SET IN DIR
  695. MAXSEC    DW    00        ;STORAGE FOR MAXIMUM USED LOGICAL SECTOR
  696. MTXEOF    DB    00        ;FLAG TO INDICATE IF END OF MTX FILE
  697. RECCNT    DW    00        ;CURRENT MTX FILE SIZE IN 128 BYTE RECORDS
  698. ;
  699. ;
  700. ;
  701. * * * * * * * * * * * * * * * * * * * * *
  702. *                    *
  703. *    MTXRD: COPY FILE FROM MTX       *
  704. *                    *
  705. * * * * * * * * * * * * * * * * * * * * *
  706. ;
  707. ;FETCHES AN MTX FILE AND THEN WRITES
  708. ;IT TO A CP/M FILE ON DRIVE A:
  709. ;
  710. MTXRD:
  711.     CALL    ERASFIL        ;ERASE THE CP/M FILE
  712.     CALL    MAKEFIL        ;..THEN MAKE NEW
  713.     MVI    A,00        ;SET SCAN FOR FIRST ENTRY
  714.     JMP    FIND2        ;JUMP INTO LOOP
  715. FIND1:
  716.     MVI    A,01        ;SET SCAN CODE FOR NEXT ENTRY
  717. FIND2:
  718.     CALL    MDIRSC        ;SCAN FOR NEXT DIRECTORY ENTRY
  719.     ORA    A        ;SET FLAGES FOR RETURN CODE
  720.     JNZ    MDNFEX        ;GO EXIT FOR NOT FOUND MTX FILE
  721.     LDA    MDENT        ;FIRST CHAR OF FILE NAME
  722.     CPI    0FFH        ;MUST BE AT END OF THE LIST IF "FF"
  723.     JZ    MDNFEX        ;GO EXIT FOR NOT FOUND MTX FILE
  724.     MVI    B,06H        ;SETUP FOR COMPARE FILE NAMES
  725.     LXI    D,FCB+1        ;..FOR 6 CHAR FROM FCB TO
  726.     LXI    H,MDENT        ;..MTX DIRECTORY ENTRY
  727.     CALL    COMPARE        ;GO COMPARE
  728.     ORA    A        ;CHECK THE RETURN FLAG
  729.     JZ    FIND1        ;NO NAME MATCH IF ZERO    
  730. ;
  731. ;FOUND FILE ON MTX DISK
  732. ;
  733. RMTXLP:
  734.     LDA    MDENT+6
  735.     CPI    000H        ;CKECK IF SOURCE FILE IS OF INDEXED TYPE
  736.     JNZ    NINDX        ;EXIT WITH ERROR IF NOT INDEXED FILE
  737. ;
  738.     LXI    H,MDENT+12    ;GET LOGICAL SECTOR NUMBER
  739.     MOV    D,M        ;..HIGH BYTE
  740.     INX    H
  741.     MOV    E,M        ;..LOW BYTE
  742.     INX    D        ;INCREMENT SECTOR FOR NEXT TIME
  743.     MOV    M,E        ;STORE BACK AWAY
  744.     DCX    H
  745.     MOV    M,D
  746.     DCX    D        ;GET BACK NUMBER OF ONE WE WANT
  747.     XCHG            ;LOGICAL SECTOR COUNT TO HL
  748.     CALL    MRDSEC        ;GO READ IT FROM MTX DISK
  749. ;
  750.     LXI    H,MTXBUF    ;MOVE 1ST HALF TO CP/M AREA
  751.     LXI    D,080H        ;..TO 128 BYTE PASS BUFFER FOR CP/M
  752.     CALL    MOVE128
  753.     CALL    WRSECT        ;MOVE DATA TO CP/M QUEUE
  754. ;
  755.     LXI    H,MTXBUF+128    ;MOVE 2ND HALF TO CP/M AREA
  756.     LXI    D,080H        ;..TO 128 BYTE PASS BUFFER FOR CP/M
  757.     CALL    MOVE128
  758.     CALL    WRSECT        ;MOVE 2ND HALF DATA TO CP/M QUEUE
  759. ;
  760.     LHLD    MDENT+12    ;GET CURRENT INCREMENTED LOGICAL SECTOR
  761.     XCHG            ;TO (DE). NOTE HI/LOW ORDER WRONG
  762.     LHLD    MDENT+14    ;GET DIRECTORY ENTRY 1+ ENDING SECTOR TO (HL)
  763.     MOV    A,H        ;COMPARE LOW BYTES OF SECTOR NUMBERS
  764.     CMP    D
  765.     JNZ    RMTXLP        ;BOTH MUST COMPARE FOR EQUALITY
  766.     MOV    A,L        ;NOW COMPARE HIGH BYTES OF SECTOR NUMBERS
  767.     CMP    E
  768.     JNZ    RMTXLP        ;AGAIN NO COMPARE SO MORE TO READ
  769. ;
  770. ;GOT EOF ON SECTOR - FLUSH BUFFERS, END
  771. ;
  772.     CALL    WRBLOCK        ;WRITE THE LAST BLOCK
  773.     CALL    CLOSFIL        ;CLOSE THE FILE
  774.     JMP    DONE        ;GO PRINT END OF TRANSFER MESSAGE
  775. ;
  776. ;
  777. ;
  778. MDNFEX:
  779.     CALL    ILPRT        ;PRINT MTX FILE NOT FOUND
  780.     DB    CR,LF,'++MTX FILE NOT FOUND++',CR,LF,0
  781.     JMP    EXIT
  782. ;
  783. ;
  784. ;
  785. NINDX:
  786.     CALL    ILPRT        ;PRINT MTX FILE TYPE NOT INDEXED TYPE
  787.     DB    CR,LF,'++MTX FILE NOT AN INDEXED FILE++',CR,LF,0
  788.     JMP    EXIT
  789. ;
  790. ;
  791. ;
  792. * * * * * * * * * * * * * * * * * * * * *
  793. *                    *
  794. *        SUBROUTINES        *
  795. *                    *
  796. * * * * * * * * * * * * * * * * * * * * *
  797. ;
  798. ;
  799. ;
  800. ;---->    ERASFIL: ERASE THE INCOMING FILE.
  801. ;
  802. ;IF IT EXISTS, ASK IF IT MAY BE ERASED.
  803. ;
  804. ERASFIL:
  805.     LXI    D,FCB        ;POINT TO CTL BLOCK
  806.     MVI    C,SRCHF     ;SEE IF IT..
  807.     CALL    BDOS        ;..EXISTS
  808.     INR    A        ;FOUND?
  809.     RZ            ;..NO, RETURN
  810.     CALL    ILPRT        ;PRINT:
  811.     DB    '++CP/M FILE EXISTS, TYPE Y TO ERASE: ',0
  812.     CALL    KEYIN        ;GET A CHARACTER FROM CONSOLE
  813.     ANI    5FH        ;MAKE UPPER CASE
  814.     CPI    'Y'        ;WANT ERASED?
  815.     JNZ    EXIT        ;QUIT IF NOT ERASE
  816.     CALL    CRLF        ;BACK TO START OF LINE
  817. ;
  818. ;ERASE OLD FILE
  819. ;
  820.     LXI    D,FCB        ;POINT TO FCB
  821.     MVI    C,ERASE        ;GET BDOS FNC
  822.     CALL    BDOS        ;DO THE ERASE
  823.     RET            ;FROM "ERASFIL"
  824. ;
  825. ;---->    MAKEFIL: MAKES THE FILE TO BE RECEIVED
  826. ;
  827. MAKEFIL:
  828.     LXI    D,FCB        ;POINT TO FCB
  829.     MVI    C,MAKE        ;GET BDOS FNC
  830.     CALL    BDOS        ;TO THE MAKE
  831.     INR    A        ;FF=BAD?
  832.     RNZ            ;OPEN OK
  833. ;
  834. ;DIRECTORY FULL - CAN'T MAKE FILE
  835. ;
  836.     CALL    ERXIT
  837.     DB    '++ERROR - CANNOT MAKE FILE++',CR,LF
  838.     DB    '++DIRECTORY MUST BE FULL++',CR,LF,'$'
  839. ;
  840. ;---->    OPENFIL: OPENS THE FILE TO BE SENT
  841. ;
  842. OPENFIL:
  843.     LXI    D,FCB        ;POINT TO FILE
  844.     MVI    C,OPEN        ;GET FUNCTION
  845.     CALL    BDOS        ;OPEN IT
  846.     INR    A        ;OPEN OK?
  847.     RNZ            ;FILE OPENED OK
  848.     CALL    ERXIT        ;..NO, ABORT
  849.     DB    '++CANNOT OPEN CP/M FILE++',CR,LF,'$'
  850. ;
  851. ;
  852. ;---->    CLOSFIL: CLOSES THE RECEIVED FILE
  853. ;
  854. CLOSFIL:
  855.     LXI    D,FCB        ;POINT TO FILE
  856.     MVI    C,CLOSE        ;GET FUNCTION
  857.     CALL    BDOS        ;CLOSE IT
  858.     INR    A        ;CLOSE OK?
  859.     RNZ            ;..YES, RETURN
  860.     CALL    ERXIT        ;..NO, ABORT
  861.     DB    '++CANNOT CLOSE CP/M FILE++',CR,LF,'$'
  862. ;
  863. ;---->    RDSECT: READS A SECTOR
  864. ;
  865. ;FOR SPEED, THIS ROUTINE BUFFERS UP 156
  866. ;SECTORS AT A TIME.
  867. ;
  868. RDSECT:
  869.     LDA    SECINBF        ;GET # SECT IN BUFF.
  870.     DCR    A        ;DECREMENT..
  871.     STA    SECINBF        ;..IT
  872.     CPI    0FFH        ;CHECK IF SECTOR COUNT UNDERFLOWS
  873.     JZ    RDBLOCK        ;EXHAUSTED?  NEED MORE.
  874.     LHLD    SECPTR        ;GET POINTER
  875.     LXI    D,80H        ;TO DATA 
  876.     CALL    MOVE128        ;MOVE TO BUFFER
  877.     SHLD    SECPTR        ;SAVE BUFFER POINTER
  878.     STC
  879.     CMC            ;CLEAR CARRY SO EOF NOT INDICATED
  880.                 ;ON NORMAL RETURN
  881.     RET            ;FROM "READSEC"
  882. ;
  883. ;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 156
  884. ;
  885. RDBLOCK:
  886.     LDA    EOFLG        ;GET EOF FLAG
  887.     CPI    1        ;IS IT SET?
  888.     STC            ;TO SHOW EOF
  889.     RZ            ;GOT EOF
  890.     MVI    C,00H        ;SELECT DRIVE A:
  891.     CALL    SELDSK
  892.     MVI    C,0        ;SECTORS IN BLOCK
  893.     LXI    D,DBUF        ;TO DISK BUFFER
  894. RDSECLP:
  895.     PUSH    B
  896.     PUSH    D
  897.     MVI    C,STDMA        ;SET DMA..
  898.     CALL    BDOS        ;..ADDR
  899.     LXI    D,FCB
  900.     MVI    C,READ
  901.     CALL    BDOS
  902.     POP    D
  903.     POP    B
  904.     ORA    A        ;READ OK?
  905.     JZ    RDSECOK        ;YES
  906.     DCR    A        ;EOF?
  907.     JZ    REOF        ;GOT EOF
  908. ;
  909. ;READ ERROR
  910. ;
  911.     CALL    ERXIT
  912.     DB    '++CP/M FILE READ ERROR++',CR,LF,'$'
  913. ;
  914. RDSECOK:
  915.     LXI    H,80H
  916.     DAD    D        ;TO NEXT BUFF
  917.     XCHG            ;BUFF TO DE
  918.     INR    C        ;MORE SECTORS?
  919.     MOV    A,C        ;GET COUNT
  920.     CPI    156        ;DONE?
  921.     JZ    RDBFULL        ;..YES, BUF IS FULL
  922.     JMP    RDSECLP        ;READ MORE
  923. ;
  924. REOF:
  925.     MVI    A,1
  926.     STA    EOFLG        ;SET EOF FLAG
  927.     MOV    A,C
  928. ;
  929. ;BUFFER IS FULL, OR GOT EOF
  930. ;
  931. RDBFULL:
  932.     STA    SECINBF        ;STORE SECTOR COUNT
  933.     LXI    H,DBUF        ;INIT BUFFER..
  934.     SHLD    SECPTR        ;..POINTER
  935.     LXI    D,80H        ;RESET..
  936.     MVI    C,STDMA        ;..DMA..
  937.     CALL    BDOS        ;..ADDR
  938.     JMP    RDSECT        ;PASS SECT TO CALLER
  939. ;
  940. ;---->    WRSECT: WRITE A SECTOR
  941. ;
  942. ;WRITES THE SECTOR INTO A BUFFER. WHEN 156
  943. ;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
  944. ;
  945. ;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
  946. ;
  947. WRSECT:
  948.     LHLD    SECPTR        ;GET BUFF ADDR
  949.     XCHG            ;TO DE FOR MOVE
  950.     LXI    H,80H        ;FROM HERE
  951.     CALL    MOVE128        ;MOVE TO BUFFER
  952.     XCHG            ;SAVE NEXT..
  953.     SHLD    SECPTR        ;..BLOCK POINTER
  954.     LDA    SECINBF        ;BUMP THE..
  955.     INR    A        ;..SECTOR #..
  956.     STA    SECINBF        ;..IN THE BUFF
  957.     CPI    156        ;HAVE WE 156?
  958.     RNZ            ;NO, RETURN
  959. ;
  960. ;---->    WRBLOCK: WRITES A BLOCK TO DISK
  961. ;
  962. WRBLOCK:
  963.     LDA    SECINBF        ;# SECT IN BUFFER
  964.     ORA    A        ;0 MEANS END OF FILE
  965.     RZ            ;NONE TO WRITE
  966.     PUSH    PSW        ;SAVE SECINBUF
  967.     MVI    C,00H        ;SELECT DISK DRIVE A:
  968.     CALL    SELDSK
  969.     POP    PSW        ;GET SECINBUF BACK
  970.     MOV    C,A        ;SAVE COUNT
  971.     LXI    D,DBUF        ;POINT TO DISK BUFF
  972. DKWRLP:
  973.     PUSH    H
  974.     PUSH    D
  975.     PUSH    B
  976.     MVI    C,STDMA        ;SET DMA
  977.     CALL    BDOS        ;TO BUFFER
  978.     LXI    D,FCB        ;THEN WRITE
  979.     MVI    C,WRITE        ;..THE..
  980.     CALL    BDOS        ;..BLOCK
  981.     POP    B
  982.     POP    D
  983.     POP    H
  984.     ORA    A
  985.     JNZ    WRERR        ;OOPS, ERROR
  986.     LXI    H,80H        ;LENGTH OF 1 SECT
  987.     DAD    D        ;HL= NEXT BUFF
  988.     XCHG            ;TO DE FOR SETDMA
  989.     DCR    C        ;MORE SECTORS?
  990.     JNZ    DKWRLP        ;..YES, LOOP
  991.     XRA    A        ;GET A ZERO
  992.     STA    SECINBF        ;RESET # OF SECTORS
  993.     LXI    H,DBUF        ;RESET BUFFER..
  994.     SHLD    SECPTR        ;..POINTER
  995.     RET
  996. ;
  997. WRERR:
  998.     CALL    ERXIT        ;EXIT W/MSG:
  999.  
  1000.     DB    '++ERROR WRITING CP/M FILE++',CR,LF,'$'
  1001. ;
  1002. ;
  1003. ;
  1004. ;---->    PROCOPT: PROCESS COMMAND OPTIONS
  1005. ;SAVES THE PROGRAM OPTION IN 'OPTION';
  1006. ;
  1007. PROCOPT:
  1008.     LXI    D,FCB+1        ;TO PROGRAM OPT.
  1009.     LDAX    D        ;GET OPTION
  1010.     STA    OPTION        ;SAVE IT
  1011.     RET            ;FROM 'PROCOPT'
  1012. ;
  1013. ;DONE - CLOSE UP SHOP
  1014. ;
  1015. DONE:
  1016.     CALL    ILPRT
  1017.     DB    CR,LF,'TRANSFER COMPLETE'
  1018.     DB    CR,LF,0
  1019. ;
  1020.     JMP    EXIT        ;DONE, GO BACK
  1021. ;
  1022. ;
  1023. ;ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
  1024. ;TO THE FIRST
  1025. ;
  1026. MOVEFCB:
  1027.     LXI    H,FCB+16     ;FROM
  1028.     LXI    D,FCB        ;TO
  1029.     MVI    B,16        ;LEN
  1030.     CALL    MOVE        ;DO THE MOVE
  1031.     XRA    A        ;GET 0
  1032.     STA    FCBSNO        ;ZERO SECTOR #
  1033.     STA    FCB        ;..AND DRIVE DESIGNATOR
  1034.     STA    FCBEXT        ;..AND EXTENT
  1035.     RET
  1036. ;
  1037. ;
  1038. ; MTX DOUBLE DENSITY FLOPPY DISK ACCESS ROUTINE FOR DRIVE B:
  1039. ; ON AN ICOM 3812 RUNNING LIFEBOAT CP/M VER 1.4
  1040. ;
  1041. ;
  1042. ;
  1043. ;---->  MRDSEC: READS A GIVEN SECTOR ACCORDING
  1044. ;        TO MTX CONVENTION. REGISTER PAIR (HL)
  1045. ;        CONTAINS THE LOGICAL SECTOR NUMBER.
  1046. ;
  1047. MRDSEC:
  1048.     CALL    MTXSCAL        ;GET OURSELVES A TRACK AND SECTOR
  1049.     PUSH    H        ;SAVE SECTOR NUMBER
  1050.     PUSH    B        ;SAVE TRACK NUMBER
  1051.     MVI    C,01H        ;LETS SELECT B: FOR MTX ACCESS
  1052.     CALL    SELDSK        ;LET BIOS SELECT DISK
  1053.     POP    B        ;GET TRACK NUMBER FOR NEXT CALL
  1054.     MOV    C,B
  1055.     CALL    SETTRK        ;HAVE BIOS HANDLE TRACK SEEK
  1056.     LXI    B,MTXBUF    ;SET DMA ADDRESS FOR BUFFER
  1057.     CALL    SETDMA
  1058.     POP    H        ;GET SECTOR NUMBER
  1059.     MOV    C,L        ;PUT FOR BIOS
  1060.     PUSH    B        ;SAVE FOR 2ND 128 BYTES
  1061.     CALL    SETSEC        ;BIOS POINT TO FIRST HALF
  1062.     CALL    RDSEC        ;READ THE SECTOR INTO BUFFER
  1063.     ORA    A        ;LOOK TO SEE IF READ ERROR
  1064.     JNZ    MRDER        ;TELL OF MTX READ ERROR
  1065.     LXI    B,MTXBUF+128
  1066.     CALL    SETDMA        ;FIX DMA ADDR FOR 2ND HALF
  1067.     POP    B        ;FIX FOR SEC +1 TO GET 2ND HALF
  1068.     INR    C
  1069.     CALL    SETSEC
  1070.     CALL    RDSEC        ;READ 2ND HALF
  1071.     ORA    A        ;LOOK AGAIN TO SEE IF READ ERROR
  1072.     JNZ    MRDER
  1073.     RET            ;GO BACK IF NO ERRORS DETECTED
  1074. ;
  1075. ;MTX DISK READ ERROR
  1076. ;
  1077. MRDER:
  1078.     CALL    ERXIT
  1079.     DB    '++MTX DISK READ ERROR++$'
  1080. ;
  1081. ;
  1082. ;---->  MWRSEC:    WRITES A GIVEN SECTOR ACCORDING 
  1083. ;        TO MTX CONVENTION. REGISTER PAIR (HL)
  1084. ;        CONTAINS THE LOGICAL SECTOR NUMBER.
  1085. ;
  1086. ;
  1087. MWRSEC:
  1088.     CALL    MTXSCAL        ;GET OURSELVES A TRACK AND SECTOR
  1089.     PUSH    H        ;SAVE SECTOR NUMBER
  1090.     PUSH    B        ;SAVE TRACK NUMBER
  1091.     MVI    C,01H        ;LETS SELECT B: FOR MTX ACCESS
  1092.     CALL    SELDSK        ;LET BIOS SELECT DISK
  1093.     POP    B        ;GET TRACK NUMBER FOR NEXT CALL
  1094.     MOV    C,B
  1095.     CALL    SETTRK        ;HAVE BIOS HANDLE TRACK SEEK
  1096.     LXI    B,MTXBUF    ;SET DMA ADDRESS FOR BUFFER
  1097.     CALL    SETDMA
  1098.     POP    H        ;GET SECTOR NUMBER
  1099.     MOV    C,L        ;PUT FOR BIOS
  1100.     PUSH    B        ;SAVE FOR 2ND 128 BYTES
  1101.     CALL    SETSEC        ;BIOS POINT TO FIRST HALF
  1102.     CALL    WRTSEC        ;WRITE THE SECTOR FROM BUFFER
  1103.     ORA    A        ;LOOK TO SEE IF WRITE ERROR
  1104.     JNZ    MWRER        ;TELL OF MTX WRITE ERROR
  1105.     LXI    B,MTXBUF+128
  1106.     CALL    SETDMA        ;FIX DMA ADDR FOR 2ND HALF
  1107.     POP    B        ;FIX FOR SEC +1 TO GET 2ND HALF
  1108.     INR    C
  1109.     CALL    SETSEC
  1110.     CALL    WRTSEC        ;WRITE 2ND HALF
  1111.     ORA    A        ;LOOK AGAIN TO SEE IF WRITE ERROR
  1112.     JNZ    MWRER
  1113.     RET            ;GO BACK IF NO ERRORS DETECTED
  1114. ;
  1115. ;MTX DISK WRITE ERROR
  1116. ;
  1117. MWRER:
  1118.     CALL    ERXIT
  1119.     DB    '++MTX DISK WRITE ERROR++$'
  1120. ;
  1121. ;
  1122. ;---->  MTXSCAL: TRANSLATES MTX LOGICAL SECTOR TO
  1123. ;         TRACK AND PHYSICAL SECTOR NUMBERS
  1124. ;
  1125. ;         ENTRY WITH DOUBLE BYTE LOGICAL SECTOR
  1126. ;             NUMBER IN (HL).
  1127. ;         EXIT WITH TRACK IN (B) AND PHYSICAL SECTOR
  1128. ;            IN (L)
  1129. ;
  1130. ;         NOTE THAT THE SUBSEQUENT ROUTINE WILL HAVE
  1131. ;         READ SECTORS (L) AND (L+1) TO OBTAIN ALL OF
  1132. ;         THE MTX SECTORS DATA.
  1133. ;
  1134. MTXSCAL:
  1135.     LXI    D,-26        ;SET TO CALCULATE TRACK NUMBER
  1136.     MVI    B,00H        ;INITIAL TRACK COUNTER
  1137. TRCLP1:
  1138.     INR    B        ;TRACK LOOP COUNTER INCREMENT
  1139.     DAD    D        ;SUBTRACT SECTOR NUMBERS MOD 26        
  1140.     JC    TRCLP1        ;LOOP IN SUBTRACT TILL WE UNDERFLOW
  1141. ;
  1142.     LXI    D,26        ;SET THE HL PAIR TO REAL LOGICAL SECTOR
  1143.                 ; ON THIS TRACK
  1144.     DAD    D
  1145. ;
  1146.     XCHG            ;PUT LOGICAL SECTOR IN DE FOR NOW
  1147.     LXI    H,TRANTBL    ;GET BASE OF TRANSLATION TABLE
  1148.     DAD    D        ;INDEX INTO TABLE
  1149.     MOV    L,M        ;GET PHYSICAL NUMBER
  1150.     RET
  1151. ;
  1152. ;
  1153. ;MTX LOGICAL TO PHYSICAL SECTOR TRANSLATION TABLE
  1154. ;    TABLE ENTRIES ARE IN LOGICAL ORDER
  1155. ;    TRACK LOGICAL SECTOR ZERO MAPS TO PHYSICAL #1
  1156. ;    ALSO NOTE THAT THIS TABLE ASSUMES THAT DISK
  1157. ;    SOFTWARE THINKS TRACK HAS 52 128 BYTE SECTORS
  1158. ;
  1159. TRANTBL:
  1160.     DB    01H
  1161.     DB    21H
  1162.     DB    0DH
  1163.     DB    2DH
  1164.     DB    19H
  1165.     DB    05H
  1166.     DB    25H
  1167.     DB    11H
  1168.     DB    31H
  1169.     DB    1DH
  1170.     DB    09H
  1171.     DB    29H
  1172.     DB    15H
  1173.     DB    2BH
  1174.     DB    17H
  1175.     DB    03H
  1176.     DB    23H
  1177.     DB    0FH
  1178.     DB    2FH
  1179.     DB    1BH
  1180.     DB    07H
  1181.     DB    27H
  1182.     DB    13H
  1183.     DB    33H
  1184.     DB    1FH
  1185.     DB    0BH
  1186. ;
  1187. ;
  1188. ;---->    INITADR: INIT'S CP/M BDOS ADDRESSES
  1189. ;
  1190. ;THIS ROUTINE FILLS IN THE ADDRESSES OF VARIOUS
  1191. ;JUMP VECTOR ENTRY POINTS SO THAT CP/M BDOS
  1192. ;IS BYPASSED WHILE ACCESSING THE MTX DISK
  1193. ;IN DRIVE B: SO THAT THE MODIFIED LOGICAL
  1194. ;SECTORING MAY BE USED.
  1195. ;
  1196. INITADR:
  1197.     LHLD    1        ;GET WARM BOOT ADDR
  1198.     LXI    D,015H        ;OFFSET TO HOME VECTOR
  1199.     DAD    D        ;TO HOME DISK ROUTINE
  1200.     SHLD    HOME+1      ;SET INTERNAL HOME VECTOR
  1201.     LXI    D,003H        ;OFFSET TO NEXT VECTOR
  1202.     DAD    D        ;TO SELECT DISK ROUTINE
  1203.     SHLD     SELDSK+1    ;SET INTERNAL SELDSK VECTOR
  1204.     DAD    D        ;TO SET TRACK ROUTINE
  1205.     SHLD    SETTRK+1    ;SET INTERNAL SETTRK VECTOR
  1206.     DAD    D        ;TO SET SECTOR ROUTINE
  1207.     SHLD    SETSEC+1    ;SET INTERNAL SETSEC VECTOR
  1208.     DAD    D        ;TO SET DMA ADDRESS ROUTINE
  1209.     SHLD    SETDMA+1    ;SET INTERNAL SETDMA VECTOR
  1210.     DAD    D        ;TO READ SECTOR ROUTINE
  1211.     SHLD    RDSEC+1        ;SET INTERNAL READ VECTOR
  1212.     DAD    D        ;TO WRITE SECTOR ROUTINE
  1213.     SHLD    WRTSEC+1    ;SET INTERNAL WRITE VECTOR
  1214. ;
  1215.     RET
  1216. ;
  1217. ;
  1218. ;----> ENTRY POINTS FOR BIOS DISK ACCESS PRIMATIVES-ADDRESSES SETUP AT INIT
  1219. ;
  1220. HOME:
  1221.     JMP    $-$        ;HOME DISK INTERNAL VECTOR
  1222. SELDSK:
  1223.     JMP    $-$        ;SELECT DISK INTERNAL VECTOR
  1224. SETTRK:
  1225.     JMP    $-$        ;SET TRACK INTERNAL VECTOR
  1226. SETSEC:
  1227.     JMP    $-$        ;SET SECTOR INTERNAL VECTOR
  1228. SETDMA:
  1229.     JMP    $-$        ;SET DMA ADDRESS INTERNAL VECTOR
  1230. RDSEC:
  1231.     JMP    $-$        ;READ SECTOR INTERNAL VECTOR
  1232. WRTSEC:
  1233.     JMP    $-$        ;WRITE SECTOR INTERNAL VECTOR
  1234. ;
  1235. ;
  1236. ;
  1237. ;SETUP A DATA BUFFER FOR MTX SECTOR WHICH IS 256 BYTES LONG
  1238. ;IT TAKES TWO CP/M 1.4 128 BYTE SECTOR READS TO FILL THE
  1239. ;MTX LOGICAL SECTOR BUFFER.
  1240. ;
  1241.     DS    20        ;DUMMY BUFFER PAD
  1242. MTXBUF:
  1243.     DS    256        ;MTX READ DATA BUFFER
  1244.     DS    20        ;BUFFER PAD
  1245. ;
  1246. ;
  1247. ;
  1248. ;
  1249. ;---->  KEYIN: GETS A KEY CODE IN FROM CONSOLE
  1250. ;
  1251. KEYIN:
  1252.     PUSH    B        ;SAVE..
  1253.     PUSH    D        ;..ALL..
  1254.     PUSH    H        ;..REGS
  1255.     MVI    C,RDCON        ;GET CONSOLE CHARACTER FUNCTION CODE
  1256.     CALL    BDOS        ;GET CHARACTER
  1257.     MOV    A,E
  1258.     POP    H        ;RESTORE..
  1259.     POP    D        ;..ALL..
  1260.     POP    B        ;..REGS
  1261.     RET
  1262. ;
  1263. ;
  1264. ;---->    CTYPE: TYPES VIA CP/M SO TABS ARE EXPANDED
  1265. ;
  1266. CTYPE:
  1267.     PUSH    B        ;SAVE..
  1268.     PUSH    D        ;..ALL..
  1269.     PUSH    H        ;..REGS
  1270.     MOV    E,A        ;CHAR TO E
  1271.     MVI    C,WRCON        ;GET BDOS FNC
  1272.     CALL    BDOS        ;PRIN THE CHR
  1273.     POP    H        ;RESTORE..
  1274.     POP    D        ;..ALL..
  1275.     POP    B        ;..REGS
  1276.     RET            ;FROM "CTYPE"
  1277. ;
  1278. CRLF:
  1279.     MVI    A,CR
  1280.     CALL    CTYPE
  1281.     MVI    A,LF
  1282.     CALL    CTYPE
  1283.     RET
  1284. ;
  1285. ;
  1286. ;HEX OUTPUT
  1287. ;
  1288. HEXO:
  1289.     PUSH    PSW        ;SAVE FOR RIGHT DIGIT
  1290.     RAR            ;RIGHT..
  1291.     RAR            ;..JUSTIFY..
  1292.     RAR            ;..LEFT..
  1293.     RAR            ;..DIGIT..
  1294.     CALL    NIBBL        ;PRINT LEFT DIGIT
  1295.     POP    PSW        ;RESTORE RIGHT
  1296.     CALL    NIBBL        ;PRINT RIGHT DIGIT
  1297.     RET
  1298. ;
  1299. ;
  1300. NIBBL:
  1301.     ANI    0FH        ;ISOLATE DIGIT
  1302.     CPI    10        ;IS IS <10?
  1303.     JC    ISNUM        ;YES, NOT ALPHA
  1304.     ADI    7        ;ADD ALPHA BIAS
  1305. ISNUM:
  1306.     ADI    '0'        ;MAKE PRINTABLE
  1307.     CALL    CTYPE        ;..THEN TYPE IT
  1308.     RET
  1309. ;
  1310. ;
  1311. ;---->    ILPRT: INLINE PRINT OF MSG
  1312. ;
  1313. ;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
  1314. ;BINARY 0 AS THE END.  BINARY 1 MAY BE USED TO
  1315. ;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
  1316. ;
  1317. ILPRT:
  1318.     XTHL            ;SAVE HL, GET HL=MSG
  1319. ILPLP:
  1320.     MOV    A,M        ;GET CHAR
  1321.     ORA    A        ;END OF MSG?
  1322.     JZ    ILPRET        ;..YES, RETURN
  1323.     CPI    1        ;PAUSE?
  1324.     JZ    ILPAUSE        ;..YES
  1325.     CALL    CTYPE        ;TYPE THE CHARACTER OF MESSAGE
  1326. ILPNEXT:
  1327.     INX    H        ;TO NEXT CHAR
  1328.     JMP    ILPLP        ;LOOP
  1329. ;
  1330. ;PAUSE WHILE TYPING HELP SO INFO DOESN'T
  1331. ;    SCROLL OFF OF VIDEO SCREENS
  1332. ;
  1333. ILPAUSE:
  1334.     CALL    ILPRT        ;PRINT:
  1335.  
  1336.     DB    CR,LF,'PRESS RETURN TO CONTINUE OR ^C TO EXIT'
  1337.     DB    CR,LF,0
  1338.     CALL    KEYIN        ;GET ANY CHAR
  1339.     CPI    'C'-40H        ;REBOOT?
  1340.     JZ    EXIT        ;YES.
  1341.     JMP    ILPNEXT        ;LOOP
  1342. ;
  1343. ILPRET:
  1344.     XTHL            ;RESTORE HL
  1345.     RET            ; & RETURN ADDR PAST MESSAGE
  1346. ;
  1347. ;---->    PRTMSG: PRINTS MSG POINTED TO BY (DE)
  1348. ;
  1349. ;A '$' IS THE ENDING DELIMITER FOR THE PRINT.
  1350. ;NO REGISTERS SAVED.
  1351. ;
  1352. PRTMSG:
  1353.     MVI    C,PRINT        ;GET BDOS FNC
  1354.     JMP    BDOS        ;PRINT MESSAGE, RETURN
  1355. ;
  1356. ;---->    ERXIT: EXIT PRINTING MSG FOLLOWING CALL
  1357. ;
  1358. ERXIT:
  1359.     POP    D        ;GET MESSAGE
  1360.     CALL    PRTMSG        ;PRINT IT
  1361. ;
  1362. EXIT:
  1363.     MVI    C,00H        ;SET SELECTED UNIT BACK TO A:
  1364.     CALL    SELDSK
  1365.     LXI    D,080H        ;RESET DEFAULT DMA ADDRESS FOR EXIT
  1366.     MVI    C,STDMA
  1367.     CALL    BDOS
  1368.     LHLD    STACK        ;GET ORIGINAL STACK
  1369.     SPHL            ;RESTORE IT
  1370.     JMP    WBOOT        ;GO DO A WARM BOOT OF CP/M SO THIS 
  1371.                 ;THING WILL WORK IN A SUBMIT FILE
  1372. ;
  1373. ;MOVE 128 CHARACTERS
  1374. ;
  1375. MOVE128:
  1376.     MVI    B,128        ;SET MOVE COUNT
  1377. ;
  1378. ;MOVE FROM (HL) TO (DE) LENGTH IN (B)
  1379. ;
  1380. MOVE:
  1381.     MOV    A,M        ;GET A CHAR
  1382.     STAX    D        ;STORE IT
  1383.     INX    H        ;TO NEXT "FROM"
  1384.     INX    D        ;TO NEXT "TO"
  1385.     DCR    B        ;MORE?
  1386.     JNZ    MOVE        ;..YES, LOOP
  1387.     RET            ;..NO, RETURN
  1388. ;
  1389. ;
  1390. ;COMPARE FROM (HL) TO (DE) FOR (B) BYTES
  1391. ;RETURN WITH A REGISTER:
  1392. ;    =00 IF NO COMPARE
  1393. ;    =FF IF VALID COMPARE
  1394. ;
  1395. COMPARE:
  1396.     LDAX    D        ;GET A CHAR
  1397.     CMP    M        ;CHECK AGAINST OTHER
  1398.     JNZ    COMFAL        ;GO EXIT FOR FAIL
  1399.     INX    H        ;INCREMENT COMPARE POINTERS
  1400.     INX    D
  1401.     DCR    B        ;DECREMENT CHAR COUNT
  1402.     JNZ    COMPARE        ;MORE?
  1403.     MVI    A,0FFH        ;EXIT FOR GOOD COMPARE
  1404.     RET
  1405. COMFAL:
  1406.     XRA    A        ;EXIT FOR NON COMPARE
  1407.     RET
  1408. ;
  1409. ;
  1410. ;----> BINASC: CONVERTS A 16 BIT BINARY NUMBER TO ASCII
  1411. ;        INPUT NUMBER ASSUMED TO BE IN HL AND
  1412. ;        OUTPUT ASCII 5 CHARACTER BUFFER IS POINTED
  1413. ;        TO BY DE. MAXIMUM NUMBER FOR CONVERSION IS
  1414. ;        THE EQUIVALENT OF 16 BITS BINARY.
  1415. ;
  1416. BINASC:
  1417.     PUSH    PSW        ;SAVE REGISTERS
  1418.     PUSH    B
  1419.     PUSH    D
  1420.     LXI    B,004H        ;FIX DE TO POINT TO END OF BUFFER
  1421.     XCHG
  1422.     DAD    B
  1423.     XCHG
  1424.     PUSH    D        ;SAVE ASCII POINTER
  1425.     MVI    A,05H        ;GET A DIGIT COUNT
  1426.     STA    DIGCNT
  1427. NDIG:
  1428.     LXI    B,-10        ;RADIX FOR CONVERSION
  1429.     LXI    D,-1        ;THIS BECOMES NO DIVIDED BY RADIX
  1430. DX:
  1431.     DAD    B        ;SUBTRACT 10
  1432.     INX    D
  1433.     JC    DX
  1434.     LXI    B,10
  1435.     DAD    B        ;ADD RADIX BACK IN ONCE
  1436.     XCHG
  1437.     MOV    A,E
  1438.     ADI    '0'        ;CONVERT FROM BCD TO ASCII
  1439.     POP    D        ;GET ASCII BUFFER POINTER
  1440.     STAX    D        ;STORE ASCII CHARACTER
  1441.     DCX    D        ;ADJUST ASCII POINTER
  1442.     LDA    DIGCNT        ;CHECK IF CONVERSION DONE
  1443.     DCR    A
  1444.     JZ    DDIG        ;EXIT IF DONE
  1445.     STA    DIGCNT
  1446.     PUSH    D        ;SAVE ASCII POINTER
  1447.     JMP    NDIG        ;GO DO NEXT DIGIT
  1448. DDIG:
  1449.     POP    D        ;RESTORE REGISTERS
  1450.     POP    B
  1451.     POP    PSW
  1452.     RET
  1453. ;
  1454. ;
  1455. ;BINASC ROUTINE STORAGE ALLOCATIONS
  1456. ;
  1457. DIGCNT    DB    00        ;PLACE TO STORE ASCII DIGIT COUNT
  1458. ;
  1459. ;
  1460. ;
  1461. ;
  1462. ;    ----------------
  1463. ;
  1464. ;PROGRAM DATA AREA SPACE ALLOCATIONS
  1465. ;
  1466. OPTION    DB    0        ;PROGRAM OPTION
  1467. ;
  1468. ;
  1469. ;FOLLOWING 3 USED BY THE CP/M DISK BUFFERING ROUTINES
  1470. ;
  1471. EOFLG    DB    0        ;EOF FLAG (1=TRUE)
  1472. SECPTR    DW    DBUF
  1473. SECINBF    DB    0        ;# OF SECTORS IN BUFFER
  1474. ;
  1475. ;
  1476. ;MTX FILE HANDLER PARAMETER STORAGE LOCATIONS
  1477. ;
  1478.     DS    20
  1479. MDENT    DS    16        ;TEMPORARY STORAGE FOR A DIRECTORY ENTRY
  1480.     DS    20
  1481. ;
  1482. ;
  1483. ;SETUP A STACK AREA
  1484. ;
  1485.     DS    400        ;STACK AREA
  1486. STACK    DS    2        ;STACK POINTER
  1487. ;
  1488. ;+++++++++
  1489. ;+++++++++
  1490. ;++
  1491. ;++ NOTE: THE FOLLOWING DISK DATA BUFFERS ARE ALLOCATED
  1492. ;++       OVER THE HELP FILE AND NON DISK I/O SOFTWARE
  1493. ;++
  1494. ;+++++++++
  1495. ;+++++++++
  1496. ;
  1497. ;
  1498. ;16 SECTOR CP/M DISK BUFFER 
  1499. ;
  1500.     DS    20
  1501. DBUF    EQU    $+1        ;16 SECTOR CP/M DISK BUFFER
  1502. ;
  1503. ;INVALID COMMAND
  1504. ;
  1505. BADOPT:
  1506.     PUSH    PSW        ;SAVE BAD OPTION
  1507.     MVI    A,'['
  1508.     CALL    CTYPE
  1509.     POP    PSW
  1510.     CALL    CTYPE
  1511.     CALL    ILPRT        ;EXIT W/ERROR
  1512.     DB    '] INVALID OPTION FOR PROGRAM SELECTION '
  1513.     DB    'COMMAND - ',CR,LF
  1514.     DB    'PRESS CTL-C TO ABORT',1,0
  1515. ;
  1516. HELP:
  1517.     CALL    ILPRT
  1518.     DB    CR,LF,CR,LF,'FORMAT FOR COMMAND IS:',CR,LF,CR,LF
  1519.     DB    'MTX # FILENAME',CR,LF,CR,LF
  1520.     DB    'WHERE # IS A 1 CHARACTER PROGRAM OPTION,',CR,LF
  1521.     DB    'PROGRAM OPTIONS:',CR,LF
  1522.     DB    '    R TO READ AN MTX FILE FROM B:',CR,LF
  1523.     DB    '    W TO WRITE AN MTX FILE TO B:',CR,LF
  1524.     DB    '    D TO VIEW THE MTX DIRECTORY ON B:',CR,LF
  1525.     DB    '    H TO PRINT THIS HELP FILE',CR,LF,CR,LF,0
  1526.     JMP    EXIT
  1527. ;
  1528. ;
  1529. ; BDOS EQUATES (VERSION 2)
  1530. ;
  1531. RDCON    EQU    1
  1532. WRCON    EQU    2
  1533. PRINT    EQU    9
  1534. CONST    EQU    11        ;CONSOLE STAT
  1535. OPEN    EQU    15        ;0FFH=NOT FOUND
  1536. CLOSE    EQU    16        ;    "    "
  1537. SRCHF    EQU    17        ;    "    "
  1538. SRCHN    EQU    18        ;    "    "
  1539. ERASE    EQU    19        ;NO RET CODE
  1540. READ    EQU    20        ;0=OK, 1=EOF
  1541. WRITE    EQU    21        ;0=OK, 1ERR, 2=?, 0FFH=NO DIR SPC
  1542. MAKE    EQU    22        ;0FFH=BAD
  1543. REN    EQU    23        ;0FFH=BAD
  1544. STDMA    EQU    26        ;SET DMA
  1545. BDOS    EQU    5
  1546. REIPL    EQU    0
  1547. FCB    EQU    5CH        ;SYSTEM FCB
  1548. FCBEXT    EQU    FCB+12        ;FILE EXTENT
  1549. FCBSNO    EQU    FCB+32        ;SECTOR #
  1550. FCB2    EQU    6CH        ;SECOND FCB
  1551.     END
  1552.