home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / dos_ency / app_l / bin2hex.bas
Encoding:
BASIC Source File  |  1988-08-11  |  4.7 KB  |  96 lines

  1. 'Binary-to-Hex file conversion utility.
  2. 'Requires Microsoft QuickBASIC version 3.0 or later.
  3.  
  4. DEFINT A-Z                                    ' All variables are integers
  5.                                               ' unless otherwise declared.
  6. CONST FALSE = 0                               ' Value of logical FALSE.
  7. CONST TRUE = NOT FALSE                        ' Value of logical TRUE.
  8.  
  9. DEF FNHXB$(X) = RIGHT$(HEX$(&H100 + X), 2)    ' Return 2-digit hex value for X.
  10. DEF FNHXW$(X!) = RIGHT$("000" + HEX$(X!), 4)  ' Return 4-digit hex value for X!.
  11. DEF FNMOD(X, Y) = X! - INT(X!/Y) * Y          ' X! MOD Y (the MOD operation is
  12.                                               ' only for integers).
  13. CONST SRCCNL = 1                              ' Source (.BIN) file channel.
  14. CONST TGTCNL = 2                              ' Target (.HEX) file channel.
  15.  
  16. LINE INPUT "Enter full name of source .BIN file        :  ";SRCFIL$
  17. OPEN SCRCFIL$ FOR INPUT AS SRCCNL             ' Test for source (.BIN) file.
  18. SRCSIZ! = LOF(SRCCNL)                         ' Save file's size.
  19. CLOSE SRCCNL
  20. IF (SRCSIZ! > 65536) THEN                     ' Reject if file exceeds 64 KB.
  21.     PRINT "Cannot convert file larger than 64 KB."
  22.     END
  23. END IF
  24.  
  25. LINE INPUT "Enter full name of target .HEX file        :  ";TGTFIL$
  26. OPEN TGTFIL$ FOR OUTPUT AS TGTCNL             ' Test target (.HEX) filename.
  27. CLOSE TGTCNL
  28.  
  29. DO
  30.     LINE INPUT "Enter starting address of .BIN file in HEX :  ";L$
  31.     ADRBGN! = VAL("&H" + L$)                  ' Convert ASCII HEX address value
  32.                                               ' to binary value.
  33.     IF (ADRBGN! < 0) THEN                     ' HEX values 8000-FFFFH convert
  34.      ADRBGN! = 65536 + ADRBGN!                ' to negative values.
  35.     END IF
  36.     ADREND! = ADRBGN! + SRCSIZ! - 1           ' Calculate resulting end address.
  37.     IF (ADREND! > 65535) THEN                 ' Reject if address exceeds FFFFH.
  38.      PRINT "Entered start address causes end address to exceed FFFFH."
  39.     END IF
  40. LOOP UNTIL (ADRFLD! >= 0) AND (ADRFLD! <= 65535) AND (ADREND! <= 65535)
  41.  
  42. DO
  43.     LINE INPUT "Enter byte count for each record in HEX    :  ";L$
  44.     SRCRLN = VAL("&H" + L$)                   ' Convert ASCII HEX max record
  45.                                               ' length value to binary value.
  46.     IF (SRCRLN < 0) THEN                      ' HEX values 8000H-FFFFH convert
  47.      SRCRLN = 65536 + SRCRLN                  ' to negative values.
  48.     END IF
  49. LOOP UNTIL (SRCRLN > 0) AND (SRCRLN < 256)    ' Ask again if not 1-255.
  50.  
  51. OPEN SRCFIL$ AS SRCCNL LEN = SRCRLN           ' Reopen source for block I/O.
  52. FIELD#SRCCNL,SRCRLN AS SRCBLK$
  53. OPEN TGTFIL$ FOR OUTPUT AS TGTCNL             ' Reopen target for text output.
  54. SRCREC = 0                                    ' Starting source block # minus 1.
  55.  
  56. FOR ADRFLD! = ADRBGN! TO ADREND! STEP SRCRLN  ' Convert one block per loop.
  57.     SRCREC = SRCREC + 1                       ' Next source block.
  58.     GET SRCCNL,SRCREC                         ' Read the source block.
  59.     IF (ADRFLD! + SRCRLN > ADREND!) THEN      ' If last block less than full
  60.      BLK$=LEFT$(SRCBLK$,ADREND!-ADRFLD!+1)    ' size:  trim it.
  61.     ELSE                                      ' Else:
  62.         BLK$ = SRCBLK$                        ' Use full block.
  63.     END IF
  64.  
  65.     PRINT#TGTCNL, ":";                        ' Write record mark.
  66.  
  67.     PRINT#TGTCNL, FNHXB$(LEN(BLK$));          ' Write data field size.
  68.     CHKSUM = LEN(BLK$)                        ' Initialize checksum accumulate
  69.                                               ' with first value.
  70.     PRINT#TGTCNL,FNHXW$(ADRFLD!);             ' Write record's load address.
  71.  
  72. ' The following "AND &HFF" operations limit CHKSUM to a byte value.
  73.     CHKSUM = CHKSUM + INT(ADRFLD!/256) AND &HFF   ' Add hi byte of adrs to csum.
  74.     CHKSUM = CHKSUM + FNMOD(ADRFLD!,256) AND &HFF ' Add lo byte of adrs to csum.
  75.  
  76.     PRINT#TGTCNL,FNHXB$(0);                   ' Write record type.
  77.  
  78. ' Don't bother to add record type byte to checksum since it's 0.
  79.     FOR IDX = 1 TO LEN(BLK$)                  ' Write all bytes.
  80.      PRINT#TGTCNL,FNHXB$(ASC(MID$(BLK$,IDX,1)));      ' Write next byte.
  81.      CHKSUM = CHKSUM + ASC(MID$(BLK$,IDX,1)) AND &HFF ' Incl byte in csum.
  82.     NEXT IDX
  83.  
  84.     CHKSUM = 0 - CHKSUM AND &HFF              ' Negate checksum then limit
  85.                                               ' to byte value.
  86.     PRINT #TGTCNL,FNHXB$(CHKSUM)              ' End record with checksum.
  87.  
  88. NEXT ADRFLD!
  89.  
  90. PRINT#TGTCNL, ":00000001FF"                   ' Write end-of-file record.
  91.  
  92. CLOSE TGTCNL                                  ' Close target file.
  93. CLOSE SRCCNL                                  ' Close source file.
  94.  
  95. END
  96.