home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / mslang / dbhex / dbhex.asm next >
Assembly Source File  |  1993-04-03  |  22KB  |  933 lines

  1. _MODEL    equ    <small>
  2.  
  3.  
  4. include        MODEL.INC
  5. include        CONSOLE.INC
  6. include        FILEIO.INC
  7. include        IMATH.INC
  8.  
  9. .codeseg    lib
  10.  
  11. .extrn        start:auto, exit_ok:auto
  12. .extrn        console_init:auto, set_directvideo:auto
  13. .extrn        open_h:auto,close_h:auto,read_h:auto
  14. .extrn        str_len:auto,str_ncpy:auto,str_stri:auto,str_cat:auto
  15. .extrn        put_str:auto,put_newline:auto,put_chr:auto
  16. .extrn        byte_to_hex:auto,word_to_hex:auto,dword_to_asc:auto
  17. .extrn        arg_next:auto
  18. .extrn        getfsize_h:auto
  19.  
  20. .ends
  21.  
  22.  
  23. .dataseg
  24.  
  25. DBFNAME                DB    128 DUP(0)
  26. DBEXT                DB    ".DBF",0
  27. DBHANDLE            DW    0
  28. HEADERMSG            DB    '.DBF Header:',0
  29. FLDDESCMSG            DB    'Field Descriptor:',0
  30. RECNOMSG            DB    'Record Number ',0
  31. FLDCOUNTER            DB    0
  32. BYTECOUNTER            DD    0
  33. BYTECNTRSTRING        DB    5 DUP(0)
  34. FILESIZE            DW    2 DUP(0)
  35. POS_COUNTER            DB    0    ; Position counter, from 1 to 16 (0 to F)
  36. CURPOINTER            DW    0    ; For saving SI or DI.
  37. BYTEHEXSTRING        DB    3 DUP(0)
  38.  
  39. VERSNO                DB    0
  40. LASTYEAR            db    0
  41. LASTMONTH            DB    0
  42. LASTDAY                DB    0
  43. RECCOUNT            DD    0
  44. HEADERLEN            DW    0
  45. RECLEN                DW    0
  46. DRESERVED1            DW    0
  47. DRESERVED2            DB    0
  48. DRESERVED3            DB    13 DUP(0)
  49. DRESERVED4            DB    0
  50. DRESERVED5            DB    3 DUP(0)
  51.  
  52. DESCLEN                DW    0
  53. NO_OF_FIELDS        DB    0
  54.  
  55. FIELDNAME            DB    11 DUP(0)
  56. FIELDTYPE            DB    0
  57. FIELDOFFSET            DW    2 DUP(0)
  58. FIELDLENGTH            DB    0
  59. DECPLACE            DB    0
  60. FRESERVED            DB    14 DUP(0)
  61.  
  62. RECNO                DD    0            ; Current Record Number
  63. RECNOSTRING            DB    10 DUP(0)    ; This will contain either the hex or
  64.                                     ; decimal ascii string version of RECNO.
  65.  
  66. LINES_PER_RECORD    DW    0    ; Number of lines needed to display a record,
  67.                             ;  not counting the bytes on the last line
  68.                             ;  of each record block.
  69.  
  70. REMAINING_BYTES        DB    0    ; Number of bytes on last line of each record
  71.                             ;  block; when all records are displayed, this
  72.                             ;  becomes the number of bytes on the last line
  73.                             ;  of the file.
  74.  
  75. REMAINING_SPACES    DB    0    ; Number of spaces to pad with on last line of
  76.                             ;  block; when all records are displayed, this
  77.                             ;  becomes the number of spaces to pad on the last
  78.                             ;  line of the file.
  79.  
  80. RECBLKCOUNTER        DW    0    ; Counter to store which line of block is currently
  81.                             ;  being read or displayed.
  82.  
  83. RECORDDATA            DB    16    DUP(0)    ; This holds the actual data, which is then
  84.                                     ;  displayed in hex and ascii formats.
  85.  
  86. TERMINATOR            DB    0Dh    ; This holds the terminator byte, which should
  87.                             ;  always be 0D hex.
  88.  
  89. NUM_BYTES_TO_READ    DB    0    ; This is the number of bytes to be read.  It is
  90.                             ;  usually 16, unless the number of fields and/or
  91.                             ;  the field widths in the database is small.  It
  92.                             ;  may become less than 16, though, e.g. for the
  93.                             ;  last line of each record block.
  94.  
  95.  
  96. .ends
  97.  
  98.  
  99. .stackseg
  100.         db    1024 dup(?)    ;define a 1024 byte stack
  101. .ends
  102.  
  103.  
  104. .codeseg
  105.  
  106. assume        cs:@codeseg, ds:@dataseg, es:@dataseg, ss:@stackseg
  107.  
  108. .public        main
  109. .proc        main        auto
  110.  
  111. MOV            AX,    @DATASEG
  112. MOV            DS,    AX 
  113.  
  114. BEGINNING:     
  115.  
  116. CALL    CONSOLE_INIT
  117. CALL    SET_DIRECTVIDEO
  118.  
  119. MOV    SI,OFFSET @DATASEG:DBFNAME
  120.  
  121. CALL    ARG_NEXT            ; Get 1st argument - database name.
  122. CALL    OPENDBF                ; Try to open the file.
  123.  
  124. CALL    DISP_HDRSTRING        ; Display '.DBF Header:' or similar heading.
  125. CALL    GET_AND_DISP_HEADER    ; Display hex and ascii forms of header.
  126. CALL    CALCFROMHDR            ; Calculate some relevant parameters from
  127.                             ;  header.
  128.  
  129. CALL    DISP_DESCSTRING        ; Display 'Field Descriptor:' or similar heading.
  130. CALL    GET_AND_DISP_DESC    ; Display hex and ascii forms of field descriptor
  131.                             ;  array.
  132.  
  133. CALL    GET_AND_DISP_TERMINATOR    ; Display terminator of field descriptor.
  134.  
  135. CALL    GET_AND_DISP_RECS    ; Read records from disk and display.
  136.  
  137. CALL    LAST_BYTES            ; Read and display the final byte(s).
  138.  
  139. CALL    CLOSE_AND_EXIT        ; Close the database file and exit to DOS.
  140.  
  141. ;=============================================================================
  142. ;Procedure: CLOSE_AND_EXIT
  143. ;
  144. ;DESC:    Closes the .DBF file and exits.
  145. ;
  146. ;IN:    DBHANDLE should contain the name of the open .DBF file.
  147. ;
  148. ;OUT:    None
  149. ;=============================================================================
  150.  
  151. .PROC    CLOSE_AND_EXIT
  152.  
  153. MOV     BX,DBHANDLE            ; Make sure the proper file handle is back in BX.
  154. CALL    CLOSE_H
  155. CALL    EXIT_OK
  156.  
  157. .ENDP    CLOSE_AND_EXIT
  158.  
  159. ret            ;exit to DOS with ERRORLEVEL=0
  160. .endp        main
  161.  
  162.  
  163. ;=============================================================================
  164. ;Procedure: DISP_HDRSTRING
  165. ;
  166. ;DESC:    Displays a short description to appear above the .DBF header lines
  167. ;         e.g., '.DBF Header:'
  168. ;
  169. ;IN:    HEADERMSG should point to the desired description.
  170. ;
  171. ;OUT:    None
  172. ;=============================================================================
  173.  
  174. .PROC    DISP_HDRSTRING
  175.  
  176. PUSH     SI
  177.  
  178. MOV        SI,OFFSET @DATASEG:HEADERMSG
  179. CALL    PUT_STR
  180. CALL    PUT_NEWLINE
  181.  
  182. POP     SI
  183.  
  184. RET
  185. .ENDP    DISP_HDRSTRING
  186.  
  187. ;=============================================================================
  188. ;Procedure: DISP_DESCSTRING
  189. ;
  190. ;DESC:    Displays a short description to appear above the .DBF descriptor
  191. ;         lines.  e.g., '.Field Descriptor:'
  192. ;
  193. ;IN:    FLDDESCMSG should point to the desired description.
  194. ;
  195. ;OUT:    None
  196. ;=============================================================================
  197.  
  198. .PROC    DISP_DESCSTRING
  199.  
  200. PUSH    SI
  201.  
  202. MOV     SI,OFFSET @DATASEG:FLDDESCMSG
  203. CALL    PUT_STR
  204. CALL    PUT_NEWLINE
  205.  
  206. POP        SI
  207.  
  208. RET
  209. .ENDP    DISP_DESCSTRING
  210.  
  211. ;=============================================================================
  212. ;Procedure: DISP_HEXCHR
  213. ;
  214. ;DESC:    Converts next number to ASCII hex, and displays.
  215. ;
  216. ;IN:    AL contains byte to be displayed.
  217. ;
  218. ;OUT:    BYTECOUNTER is incremented; POS_COUNTER is incremented; BYTEHEXSTRING
  219. ;         contains ascii hex form of byte.
  220. ;=============================================================================
  221.  
  222. .PROC    DISP_HEXCHR
  223.  
  224. .PUSH    AX,DX,SI
  225.  
  226. LODSB
  227. MOV        SI,OFFSET @DATASEG:BYTEHEXSTRING
  228. CALL    BYTE_TO_HEX
  229. CALL    PUT_STR
  230. INC        POS_COUNTER                ; Keep track of where the cursor is in hex area.
  231. MOV        DX,WORD PTR BYTECOUNTER[2]
  232. MOV        AX,WORD PTR BYTECOUNTER[0]
  233. .INC_D    DX,AX                    ; Increment doubleword at BYTECOUNTER
  234. MOV        WORD PTR BYTECOUNTER[2],DX
  235. MOV        WORD PTR BYTECOUNTER[0],AX
  236.  
  237. .POP    AX,DX,SI
  238.  
  239. RET
  240. .ENDP    DISP_HEXCHR
  241.  
  242. ;=============================================================================
  243. ;Procedure: GET_AND_DISP_HEADER
  244. ;
  245. ;DESC:    Reads header information, and displays offset, hex and ascii.
  246. ;
  247. ;IN:    None
  248. ;
  249. ;OUT:    BYTECOUNTER is incremented.
  250. ;=============================================================================
  251. .PROC    GET_AND_DISP_HEADER
  252.  
  253. .PUSH    CX,SI
  254.  
  255. MOV        SI,OFFSET @DATASEG:VERSNO
  256.  
  257. ; Read 32 bytes
  258. CALL    GET_AND_DISP_16BYTES    ; Read and display 16 bytes in hexadecimal
  259.                                 ;  format and ascii format.
  260. CALL    GET_AND_DISP_16BYTES    ;  Same with the next 16 bytes.
  261.  
  262. CALL    PUT_NEWLINE
  263.  
  264. .POP    CX,SI
  265.  
  266. RET
  267. .ENDP    GET_AND_DISP_HEADER
  268.  
  269.  
  270. ;=============================================================================
  271. ;Procedure: GET_AND_DISP_DESC
  272. ;
  273. ;DESC:    Reads and displays the field descriptor array.
  274. ;
  275. ;IN:    None.
  276. ;
  277. ;OUT:    BYTECOUNTER is incremented.
  278. ;=============================================================================
  279.  
  280. .PROC    GET_AND_DISP_DESC        ; Get and Display field descriptor array
  281.  
  282. .PUSH    AX,CX,SI
  283.  
  284. GET_AND_DISP_DESC1:
  285. MOV        SI,OFFSET @DATASEG:FIELDNAME
  286.  
  287. ; Each field descriptor is 32 bytes long.
  288. CALL    GET_AND_DISP_16BYTES
  289. CALL    GET_AND_DISP_16BYTES
  290.  
  291. CALL    PUT_NEWLINE
  292. INC        FLDCOUNTER
  293. MOV        AL,FLDCOUNTER            ; Move the number of fields displayed so far
  294.                                 ;  into AL.
  295. CMP        AL,NO_OF_FIELDS            ; If the number of fields displayed is less
  296.                                 ;  the total number [ NO_OF_FIELDS ], then
  297. JB        GET_AND_DISP_DESC1        ;  display another field.
  298.  
  299. .POP    AX,CX,SI
  300.  
  301. RET                                ; Return when all fields specs have been 
  302.                                 ;  displayed.
  303. .ENDP    GET_AND_DISP_DESC
  304.  
  305.  
  306. ;=============================================================================
  307. ;Procedure: GET_AND_DISP_TERMINATOR
  308. ;
  309. ;DESC:    Reads and displays the terminator byte, which should be 0D, and
  310. ;         which follows the field descriptor.
  311. ;
  312. ;IN:
  313. ;
  314. ;OUT:    BYTECOUNTER is incremented.
  315. ;=============================================================================
  316.  
  317. .PROC    GET_AND_DISP_TERMINATOR
  318.  
  319. .PUSH    CX,SI
  320.  
  321. MOV     CL,1
  322. MOV     SI,OFFSET @DATASEG:TERMINATOR
  323. CALL    GET_BYTES
  324. CALL    DISP_OFFSET
  325. CALL    DISP_BYTES
  326. MOV        CL,45            ; There will always be 45 spaces to display on
  327.                         ;  a terminator line, right after the terminator (0D)
  328. CALL    PUT_SPACES        ;  so display them.
  329. MOV        CL,1
  330.  
  331. CALL    DISP_ASCII        ; Now display the corresponding ascii form of
  332.                         ;  TERMINATOR, which in our interpretation is a period.
  333. CALL    PUT_NEWLINE
  334. CALL    PUT_NEWLINE
  335.  
  336. .POP    CX,SI
  337.  
  338. RET
  339. .ENDP    GET_AND_DISP_TERMINATOR
  340.  
  341.  
  342. ;=============================================================================
  343. ;Procedure: CALCFROMHDR
  344. ;
  345. ;DESC:    Using information from the header, calculates the length of the 
  346. ;         field descriptor array (DESCLEN), the number of fields (NO_OF_FIELDS),
  347. ;         the number of hex/ascii lines to be displayed for each record 
  348. ;         (LINES_PER_RECORD), the number of bytes on the last line of each ;
  349. ;         record block (REMAINING_BYTES) and the number of spaces to pad after
  350. ;         the hex portion (REMAINING_SPACES). 
  351. ;
  352. ;IN:    None
  353. ;
  354. ;OUT:    DESCLEN, NO_OF_FIELDS, LINES_PER_RECORD, REMAINING_BYTES,
  355. ;         REMAINING_SPACES
  356. ;=============================================================================
  357.  
  358. .PROC    CALCFROMHDR
  359.  
  360. .PUSH    AX,BX,DX
  361.  
  362. XOR        DX,DX
  363. MOV        AX,HEADERLEN
  364. SUB        AX,33
  365. MOV        DESCLEN,AX                ; Field descriptor length
  366.  
  367. MOV        BX,32
  368. DIV        BX
  369. MOV        NO_OF_FIELDS,AL
  370.  
  371. XOR        DX,DX
  372. MOV        AX,RECLEN
  373. MOV        BX,16
  374. DIV        BX
  375. MOV        LINES_PER_RECORD,AX
  376. MOV        REMAINING_BYTES,DL
  377. MOV        AL,DL
  378. CALL    CALC_REM_SPACES
  379.  
  380. .POP    AX,BX,DX
  381.  
  382. RET
  383. .ENDP    CALCFROMHDR
  384.  
  385. ;=============================================================================
  386. ;Procedure: CALC_REM_SPACES
  387. ;
  388. ;DESC:    Calculates the necessary number of spaces to pad a line with, after
  389. ;         the hex area and before the ascii area.
  390. ;
  391. ;IN:    AL contains the number of hex bytes on the line.
  392. ;
  393. ;OUT:    REMAINING_SPACES contains the number of spaces to pad with.
  394. ;=============================================================================
  395.  
  396. .PROC    CALC_REM_SPACES
  397.  
  398. .PUSH    AX,BX
  399.  
  400. MOV        BL,16
  401. SUB        BL,AL
  402. MOV        AL,3
  403. MUL        BL
  404. MOV        REMAINING_SPACES,AL
  405.  
  406. .POP    AX,BX
  407.  
  408. RET
  409. .ENDP    CALC_REM_SPACES
  410.  
  411. ;=============================================================================
  412. ;Procedure: DISP_OFFSET
  413. ;
  414. ;DESC:    Displays the offset from the current 64k block that is being processed,
  415. ;         as well as a couple of spaces after the offset and before the rest of
  416. ;         the hex/ascii output.
  417. ;IN:    BYTECOUNTER contains the hex form of the offset
  418. ;
  419. ;OUT:    BYTECNTRSTRING contains the string form of the offset
  420. ;=============================================================================
  421.  
  422. .PROC    DISP_OFFSET
  423.  
  424. .PUSH    AX,SI
  425.  
  426. MOV        SI,OFFSET @DATASEG:BYTECNTRSTRING
  427. MOV        AX, WORD PTR BYTECOUNTER[0]
  428. CALL    WORD_TO_HEX
  429. CALL    PUT_STR
  430. CALL    PUT_SPACE
  431. CALL    PUT_SPACE
  432.  
  433. .POP    AX,SI
  434.  
  435. RET
  436.  
  437. .ENDP    DISP_OFFSET
  438.  
  439.  
  440. ;=============================================================================
  441. ;Procedure: PUT_SPACES
  442. ;
  443. ;DESC:    Displays cl number of spaces at the current cursor location.
  444. ;
  445. ;IN:    CL contains number of spaces to display.
  446. ;
  447. ;OUT:    None
  448. ;=============================================================================
  449.  
  450. .PROC    PUT_SPACES
  451.  
  452. PUSH    CX
  453.  
  454. PUT_SPACES1:
  455. CALL    PUT_SPACE
  456. LOOP    PUT_SPACES1
  457.  
  458. POP        CX
  459.  
  460. RET
  461. .ENDP    PUT_SPACES
  462.  
  463.  
  464.  
  465. ;=============================================================================
  466. ;Procedure: PUT_SPACE
  467. ;
  468. ;DESC:    Displays a space at the current cursor location.
  469. ;
  470. ;IN:    None
  471. ;
  472. ;OUT:    None
  473. ;=============================================================================
  474.  
  475. .PROC    PUT_SPACE
  476.  
  477. PUSH    AX
  478.  
  479. MOV        AL," "
  480. CALL    PUT_CHR
  481.  
  482. POP        AX
  483.  
  484. RET
  485. .ENDP    PUT_SPACE
  486.  
  487.  
  488. ;=============================================================================
  489. ;Procedure: GET_AND_DISP_RECS
  490. ;
  491. ;DESC:    Reads and displays all records from file.
  492. ;
  493. ;IN:    None
  494. ;
  495. ;OUT:    BYTECOUNTER is updated.
  496. ;=============================================================================
  497.  
  498. .PROC    GET_AND_DISP_RECS
  499. GET_AND_DISP_RECS1:
  500.  
  501. .PUSH    AX,BX,CX,DX
  502.  
  503. MOV        DX, WORD PTR RECNO[2]    ; Bring high word of RECNO into DX
  504. MOV        AX,    WORD PTR RECNO[0]    ;  and low word into AX. 
  505. MOV        CX,    WORD PTR RECCOUNT[2]    ; High word of RECCOUNT into CX
  506. MOV        BX,    WORD PTR RECCOUNT[0]    ;  and low word into BX.
  507. .CMP_DD    DX,AX,CX,BX            ; Compare double words RECNO and RECCOUNT.
  508.  
  509. .POP    AX,BX,CX,DX
  510.  
  511. JE        GET_AND_DISP_RECSEND    ; If RECNO is now the same as RECCOUNT,
  512.                                 ;  stop displaying records.
  513.  
  514. CALL    DISP_RECNO            ; Display hex/decimal string form of record number.
  515. CALL    GET_AND_DISP_REC    ; Read record from file, and display it in
  516.                             ;  hex and ascii formats.
  517. CALL    PUT_NEWLINE
  518. JMP        GET_AND_DISP_RECS1    ; Loop back to get and display another record.
  519.  
  520. GET_AND_DISP_RECSEND:
  521. RET
  522. .ENDP    GET_AND_DISP_RECS
  523.  
  524. ;=============================================================================
  525. ;Procedure: DISP_RECNO
  526. ;
  527. ;DESC:    Displays the current record number, in hex and decimal ascii formats.
  528. ;
  529. ;IN:    None
  530. ;
  531. ;OUT:    Increments RECNO.
  532. ;=============================================================================
  533.  
  534. .PROC    DISP_RECNO
  535.  
  536. .PUSH    AX,BX,CX,DX,SI
  537.  
  538. XOR        CH,CH
  539. MOV        CL,11
  540. CALL    PUT_SPACES
  541. MOV        SI,OFFSET @DATASEG:RECNOMSG
  542. CALL    PUT_STR
  543. MOV        DX,WORD PTR RECNO[2]
  544. MOV        AX,WORD PTR RECNO[0]
  545. .INC_D    DX,AX            ; Increment double word at RECNO.
  546. MOV        WORD PTR RECNO[2],DX
  547. MOV        WORD PTR RECNO[0],AX
  548. MOV        BL,16
  549. MOV        SI,OFFSET @DATASEG:RECNOSTRING
  550. CALL    DWORD_TO_ASC
  551. CALL    PUT_STR
  552. MOV        AL,'h'
  553. CALL    PUT_CHR
  554. MOV        AL,'/'
  555. CALL    PUT_CHR
  556. MOV        DX,WORD PTR RECNO[2]
  557. MOV        AX,WORD PTR RECNO[0]
  558. MOV        BL,10
  559. MOV        SI,OFFSET @DATASEG:RECNOSTRING
  560. CALL    DWORD_TO_ASC
  561. CALL    PUT_STR
  562. MOV        AL,'d'
  563. CALL    PUT_CHR
  564. MOV        AL,':'
  565. CALL    PUT_CHR
  566. CALL    PUT_NEWLINE
  567.  
  568. .POP    AX,BX,CX,DX,SI
  569.  
  570. RET
  571. .ENDP    DISP_RECNO
  572.  
  573.  
  574. ;=============================================================================
  575. ;Procedure: GET_AND_DISP_REC
  576. ;
  577. ;DESC:    Reads 16 bytes from file, and displays in hex and ascii format.
  578. ;
  579. ;IN:    None
  580. ;
  581. ;OUT:    BYTECOUNTER is updated.
  582. ;=============================================================================
  583.  
  584. .PROC    GET_AND_DISP_REC
  585.  
  586. .PUSH    AX,CX,SI
  587. GET_AND_DISP_REC1:
  588. MOV     SI,OFFSET @DATASEG:RECORDDATA
  589. CALL    GET_AND_DISP_16BYTES    ;Display 16 bytes of a record.
  590. INC        RECBLKCOUNTER
  591. MOV        AX,RECBLKCOUNTER
  592. CMP        AX,LINES_PER_RECORD
  593. JB        GET_AND_DISP_REC1
  594. MOV        RECBLKCOUNTER,0
  595. MOV     SI,OFFSET @DATASEG:RECORDDATA
  596. XOR        CH,CH
  597. MOV        CL,REMAINING_BYTES
  598. CMP        CL,0
  599. JE        GET_AND_DISP_RECEND        ;If no remaining bytes in block, then display
  600.                                 ; blank line and return.
  601. CALL    GET_BYTES
  602. CALL    DISP_OFFSET
  603. CALL    DISP_REMBYTES
  604.  
  605. GET_AND_DISP_RECEND:
  606. CALL    PUT_NEWLINE
  607.  
  608. .POP    AX,CX,SI
  609.  
  610. RET
  611. .ENDP    GET_AND_DISP_REC
  612.  
  613.  
  614. ;=============================================================================
  615. ;Procedure: GET_AND_DISP_16BYTES
  616. ;
  617. ;DESC:    Reads 16 bytes from file, and displays in hex and ascii format.
  618. ;
  619. ;IN:    SI points to sequence of bytes.
  620. ;
  621. ;OUT:    BYTECOUNTER is updated.
  622. ;=============================================================================
  623.  
  624. .PROC    GET_AND_DISP_16BYTES
  625.  
  626. PUSH    CX
  627.  
  628. MOV        CX,16
  629. CALL    GET_BYTES        
  630. CALL    DISP_OFFSET
  631. CALL    DISP_BYTES
  632. CALL    DISP_ASCII_CHARS
  633. CALL    PUT_NEWLINE
  634.  
  635. POP        CX
  636.  
  637. RET
  638. .ENDP    GET_AND_DISP_16BYTES
  639.  
  640.  
  641. ;=============================================================================
  642. ;Procedure: GET_BYTES
  643. ;
  644. ;DESC:    Reads CL number of bytes from file.
  645. ;
  646. ;IN:    CL contains number of bytes to read.  SI points to sequence of bytes.
  647. ;         BL contains the file handle.
  648. ;
  649. ;OUT:    
  650. ;=============================================================================
  651.  
  652. .PROC    GET_BYTES
  653.  
  654. .PUSH    CX,SI
  655.  
  656. MOV        NUM_BYTES_TO_READ,CL
  657. CALL    READ_H
  658. JA        GET_BYTES1
  659. JMP        GET_BYTES2
  660.  
  661. GET_BYTES1:
  662. CALL    CLOSE_AND_EXIT
  663.  
  664. GET_BYTES2:
  665. CMP        CL,NUM_BYTES_TO_READ    ;If number of bytes read is less than
  666.                                 ; expected, pointer must be at end of file.
  667. JE        GET_BYTESEND
  668. GET_BYTESEND:
  669.  
  670. .POP    CX,SI
  671.  
  672. RET
  673. .ENDP    GET_BYTES
  674.  
  675.  
  676.  
  677. ;=============================================================================
  678. ;Procedure: LAST_BYTES
  679. ;
  680. ;DESC:    Reads and displays the last line of file.
  681. ;
  682. ;IN:    BL contains the file handle.
  683. ;
  684. ;OUT:    None
  685. ;=============================================================================
  686.  
  687. .PROC    LAST_BYTES
  688.  
  689. .PUSH    AX,BX,CX,SI
  690.  
  691. MOV        SI,OFFSET @DATASEG:RECORDDATA
  692. MOV        CX,16            ; There should only be 1 byte left to read, but it
  693.                         ;  doesn't hurt to attempt it at 16.  The true number
  694.                         ;  of bytes left will be returned in CL after a call
  695.                         ;  to READ_H.
  696. CALL    READ_H
  697. CALL    DISP_OFFSET
  698. CALL    DISP_BYTES
  699. MOV        REMAINING_BYTES,CL
  700. MOV        AL,CL
  701. CALL    CALC_REM_SPACES
  702. MOV        CL,REMAINING_SPACES
  703. CALL    PUT_SPACES
  704. MOV        CL,REMAINING_BYTES
  705. CALL    DISP_ASCII_CHARS
  706. CALL    PUT_NEWLINE
  707.  
  708. .POP    AX,BX,CX,SI
  709.  
  710. RET
  711. .ENDP    LAST_BYTES
  712.  
  713.  
  714.  
  715. ;=============================================================================
  716. ;Procedure: DISP_BYTES
  717. ;
  718. ;DESC:    Displays CL number of bytes from file, in hex format.
  719. ;
  720. ;IN:    CL contains number of bytes to display.    SI points to sequence of bytes.
  721. ;
  722. ;OUT:    None
  723. ;=============================================================================
  724.  
  725. .PROC    DISP_BYTES
  726.  
  727. PUSH    AX
  728.  
  729. MOV        CURPOINTER,SI
  730. MOV        POS_COUNTER,0
  731. DISP_BYTES1:
  732.     CALL    DISP_HEXCHR
  733.     CALL    PUT_SPACE
  734.     INC     SI
  735.     CMP        POS_COUNTER,CL        ;If position counter is still less than the
  736.                                 ; number of bytes to be displayed, then
  737. JNE        DISP_BYTES1                ; continue displaying.
  738.  
  739. POP        AX
  740.  
  741. RET
  742. .ENDP    DISP_BYTES
  743.  
  744.  
  745. ;=============================================================================
  746. ;Procedure: DISP_ASCII_CHARS
  747. ;
  748. ;DESC:    Displays CL number of bytes from file, in ascii format.
  749. ;
  750. ;IN:    CL contains number of bytes to display. SI points to sequence of bytes.
  751. ;
  752. ;OUT:    None
  753. ;=============================================================================
  754.  
  755. .PROC    DISP_ASCII_CHARS
  756.  
  757. PUSH    AX
  758.  
  759. MOV        SI,CURPOINTER
  760. MOV        POS_COUNTER,0
  761. DISP_BYTES2:
  762.     CALL    DISP_ASCII
  763.     INC        SI
  764.     CMP        POS_COUNTER,CL
  765. JNE DISP_BYTES2
  766.  
  767. POP        AX
  768.  
  769. RET
  770. .ENDP    DISP_ASCII_CHARS
  771.  
  772.  
  773. ;=============================================================================
  774. ;Procedure: DISP_ASCII
  775. ;
  776. ;DESC:    Displays byte in ascii format.  If ascii code of byte is less than 32,
  777. ;         (20h), then display a period (.).
  778. ;
  779. ;IN:    AL contains byte to display.
  780. ;
  781. ;OUT:    POS_COUNTER is incremented.
  782. ;=============================================================================
  783.  
  784. .PROC    DISP_ASCII
  785.  
  786. .PUSH    AX,BX,SI
  787.  
  788. LODSB
  789. CMP        AL,20h
  790. JB        PUT_PERIOD
  791. CALL    PUT_CHR
  792. JMP        DISP_ASCII1
  793.  
  794. PUT_PERIOD:
  795. MOV        AL,'.'
  796. CALL    PUT_CHR
  797.  
  798. DISP_ASCII1:
  799. INC        POS_COUNTER
  800.  
  801. .POP    AX,BX,SI
  802.  
  803. RET
  804. .ENDP    DISP_ASCII
  805.  
  806.  
  807. ;=============================================================================
  808. ;Procedure: DISP_REMBYTES
  809. ;
  810. ;DESC:    Displays last line of record, if less than 16 bytes and more than 0.
  811. ;         If the last line contains exactly 16 bytes, then it has already
  812. ;         been displayed during a call to DISP_BYTES.
  813. ;
  814. ;IN:    AL contains byte to display.  SI points to sequence of bytes.
  815. ;
  816. ;OUT:    POS_COUNTER is incremented.
  817. ;=============================================================================
  818.  
  819. .PROC    DISP_REMBYTES            ; Display remainder of record.
  820.  
  821. .PUSH    AX,SI,CX
  822.  
  823. MOV        CURPOINTER,SI
  824. MOV        POS_COUNTER,0
  825. DISP_REMBYTES1:
  826.     CALL    DISP_HEXCHR
  827.     CALL    PUT_SPACE
  828.     INC        SI
  829.     MOV        AL,REMAINING_BYTES
  830.     CMP        POS_COUNTER,AL
  831. JNE        DISP_REMBYTES1
  832.  
  833. MOV        CL,REMAINING_SPACES
  834. CALL    PUT_SPACES
  835.  
  836. MOV        SI,CURPOINTER
  837. MOV        POS_COUNTER,0
  838. DISP_REMBYTES2:
  839. CALL    DISP_ASCII
  840. INC        SI
  841. MOV        AL,REMAINING_BYTES
  842. CMP        POS_COUNTER,AL
  843. JNE        DISP_REMBYTES2
  844.  
  845. .POP    AX,SI,CX
  846.  
  847. RET
  848. .ENDP    DISP_REMBYTES
  849.  
  850.  
  851. ;=============================================================================
  852. ;Procedure: OPENDBF
  853. ;
  854. ;DESC:    Opens a .DBF file.
  855. ;
  856. ;IN:    DS:SI should point to the .DBF PATHNAME.
  857. ;
  858. ;OUT:    BX and DBHANDLE contain the file handle.
  859. ;=============================================================================
  860.  
  861. .PROC    OPENDBF
  862.  
  863. .PUSH    AX,CX,DX,SI,DI
  864.  
  865. MOV        DI,OFFSET @DATASEG:DBFNAME
  866. CALL    STR_LEN
  867. CALL    STR_NCPY            ; Now DI should point to the full path name,
  868.                             ;  with or without the extension.
  869.  
  870. MOV        SI,DI                ; But now SI should have the path name.
  871.  
  872. MOV        DI,OFFSET @DATASEG:DBEXT
  873. PUSH    SI
  874. CALL    STR_STRI            ; Look for ".DBF" extension in path name;
  875.                             ;  that is, look for the extension pointed
  876.                             ;  to by DI in the string pointed to by SI.
  877. POP        SI
  878. JNC        OPEN_IT                ; If the extension is in the filename,
  879.                             ;  open the file.
  880.  
  881.                             ; Otherwise,...
  882.  
  883.                             ; Right now, SI points to the filename
  884.                             ;  string, and DI points to the extension.
  885.  
  886. XCHG    SI,DI                ; Make DI point to the filename and SI to
  887.                             ;  the extension, for a call to STR_CAT.
  888.  
  889. CALL    STR_CAT                ; Append the extension to the filename;
  890.                             ;  that is, append the string pointed to
  891.                             ;  by SI to the string pointed to by DI.
  892.  
  893. MOV    SI,DI                    ; Okay.  Now move the offset of the path
  894.                             ;  name back into SI.
  895.  
  896. OPEN_IT:
  897. MOV        AX,O_RDONLY
  898. CALL    OPEN_H
  899. JC        OPENDBFOUT
  900. JMP        OPENDBFEND
  901.  
  902. OPENDBFOUT:
  903. CALL    CLOSE_AND_EXIT
  904.  
  905. OPENDBFEND:
  906. MOV        DBHANDLE,BX            ; The file handle will generally remain in BX
  907.                             ;  throughout the program, but store it in DBHANDLE
  908.                             ;  just in case BX is temporarily used for
  909.                             ;  something else.
  910.  
  911. CALL    GETFSIZE_H            ; Get size of file at handle BX.
  912. MOV        FILESIZE[0],AX        ; Store it in FILESIZE.
  913. MOV        FILESIZE[2],DX
  914.  
  915. .POP    AX,CX,DX,SI,DI
  916.  
  917. RET
  918. .ENDP    OPENDBF
  919.  
  920.  
  921. .ends
  922.  
  923.  
  924. .public        nheap_default, fheap_default
  925. .stackseg
  926. .public        stack_end        ;used by START to normalize stack
  927. .label        stack_end    word    ;must be defined past entire stack
  928. .label        nheap_default    word    ;used by the near heap
  929. .label        fheap_default    word    ;used by the far heap
  930. .ends
  931.  
  932. end    start        ;specify START as starting address
  933.