QB / QB64 Discussion Forum     RULES     Other Subforums, Links and Downloads    Index of Threads

 

 Return to Index  

HEXViewer

April 23 2003 at 9:48 AM
lkt153  (no login)


Response to ProgramList LKT153

 
Notes:
1.This will not work on QB1.1.
2.It uses the INTERRUPT and INTERRUPTX functions, so QB MUST be loaded with the /L switch for it to work (i.e: QB.EXE HEXV.BAS /L or something)
3.This allocates memory from the system so will probably not work on QB's IDE, you'll have to compile it as 'stand-alone'

Heh, this is harder to run than I thought... hehe

Anyway, I just finished writting this, it's still pretty buggy, but I didn't feel like delaying it anymore and who knows... perhaps someone could help me correct it. It seems to fail whenever you go back by pressing either PageUp or the UpArrow, I'm not really sure what's going on.

The code is clean and easy to read IMO, I used most of the C conventions for writting clean code (i.e: declaring all the variables prior to their use) although I still use some pretty old stuff like using LET and REM, but that's my style, and I don't tihng it'll change so soon 'cause you know: old habits die hard.

Given all that, here's the code. Enjoy, it should be updated soon.

--

REM $INCLUDE: 'QB.BI'
REM $STATIC

DECLARE FUNCTION GETFILENAME$ ()
DECLARE FUNCTION GETFILESIZE& (FileHandle%, Res%)
DECLARE FUNCTION GETMEM% (Paras%)
DECLARE FUNCTION FILEREAD% (FileHandle%, MemSeg%, Start%, Size%)
DECLARE FUNCTION OPENFILE% (FileName$)

DECLARE SUB CENTER (Ln%, Message$)
DECLARE SUB CLOSEFILE (FileHandle%)
DECLARE SUB DISPLAYHELP ()
DECLARE SUB DRAWSCREEN ()
DECLARE SUB ERRORHANDLER (FileHandle%, MemSeg%)
DECLARE SUB EXITS (Prior%, Message$)
DECLARE SUB FREEMEM (MemHandle%)
DECLARE SUB MOVEMEM (FileHandle%, MemSeg%, nBytes%)
DECLARE SUB PRINTVALUES (MemSeg%, FileSize&)
DECLARE SUB SEEKFILE (FileHandle%, Origin%, nBytes&)
DECLARE SUB SETSCREEN ()
DECLARE SUB WRITESTATUS (Message$)

CONST TRUE = -1
CONST FALSE = 0

CONST CF = 1

CONST NO = 7
CONST LO = 14
CONST HI = 4

CONST SEEKSET = 0
CONST SEEKCUR = 1
CONST SEEKEND = 2

DIM SHARED ErrorFlag AS INTEGER
DIM SHARED ErrorCode AS INTEGER
DIM SHARED ErrorStrn AS STRING

DIM SHARED VideoMode AS INTEGER

DIM SHARED AscTab(0 TO 255) AS STRING * 1
DIM SHARED HexTab(0 TO 255) AS STRING * 3

LET ErrorFlag = FALSE
LET ErrorCode = 0

DIM iN AS INTEGER
FOR iN = 0 TO 255
  IF (iN > 31) THEN LET AscTab(iN) = CHR$(iN) ELSE LET AscTab(iN) = CHR$(46)
NEXT iN
FOR iN = 0 TO 255
  IF (iN < &H10) THEN
    LET HexTab(iN) = CHR$(48) + HEX$(iN) + CHR$(32)
  ELSE
    LET HexTab(iN) = HEX$(iN) + CHR$(32)
  END IF
NEXT iN

SETSCREEN
DRAWSCREEN

WRITESTATUS "Allocating memory"
DIM MemSeg AS INTEGER
LET MemSeg = GETMEM%(22)
IF (ErrorFlag) THEN ERRORHANDLER 0, 0

WRITESTATUS "Getting file to open"
DIM FileName$
LET FileName$ = GETFILENAME$
IF (FileName$ = "") THEN
  FREEMEM MemSeg
  EXITS HI, "Must specify a file to open"
END IF

WRITESTATUS "Opening file"
DIM FileHandle AS INTEGER
LET FileHandle = OPENFILE%(FileName$ + CHR$(0))
IF (ErrorFlag) THEN ERRORHANDLER 0, MemSeg

WRITESTATUS "Getting file size"
DIM SHARED FileSize AS LONG
LET FileSize = GETFILESIZE&(FileHandle, TRUE)
IF (ErrorFlag) THEN ERRORHANDLER FileHandle, MemSeg

WRITESTATUS "Reading data from file"
DIM BytesRead AS INTEGER
LET BytesRead = FILEREAD%(FileHandle, MemSeg, 0, 336)
IF (ErrorFlag) THEN ERRORHANDLER FileHandle, MemSeg

WRITESTATUS " [ESC] Quit  |  [F1] Help"

DEF SEG = &H40
POKE &H1A, PEEK(&H1C)
DEF SEG

DIM Key$
DIM SHARED FilePointer AS LONG
LET FilePointer = 0

DO
 
  PRINTVALUES MemSeg, FileSize

  LET Key$ = ""
  DO UNTIL (Key$ <> "")
    LET Key$ = UCASE$(INKEY$)
  LOOP
  DEF SEG = &H40
  POKE &H1A, PEEK(&H1C)
  DEF SEG

  SELECT CASE Key$
    CASE CHR$(0) + CHR$(59)
    DISPLAYHELP
    DRAWSCREEN
   
    CASE CHR$(0) + CHR$(72)
    IF (FilePointer > 16) THEN
      MOVEMEM FileHandle, MemSeg, -16
      LET FilePointer = FilePointer - 16
    ELSE
      MOVEMEM FileHandle, MemSeg, -FilePointer
      LET FilePointer = 0
    END IF

    CASE CHR$(0) + CHR$(73)
    IF (FilePointer > 336) THEN
      MOVEMEM FileHandle, MemSeg, -336
      LET FilePointer = FilePointer - 336
    ELSE
      MOVEMEM FileHandle, MemSeg, -FilePointer
      LET FilePointer = 0
    END IF

    CASE CHR$(0) + CHR$(80)
    IF (FileSize > FilePointer + 16) THEN
      MOVEMEM FileHandle, MemSeg, 16
      LET FilePointer = FilePointer + 16
    ELSE
      MOVEMEM FileHandle, MemSeg, (FileSize - FilePointer)
      LET FilePointer = FileSize
    END IF

    CASE CHR$(0) + CHR$(81)
    IF (FileSize > FilePointer + 336) THEN
      MOVEMEM FileHandle, MemSeg, 336
      LET FilePointer = FilePointer + 336
    ELSE
      MOVEMEM FileHandle, MemSeg, (FileSize - FilePointer)
      LET FilePointer = FileSize
    END IF
   
    CASE CHR$(27)
    EXIT DO
   
    CASE CHR$(43)
    IF (FileSize > FilePointer + 1) THEN
      MOVEMEM FileHandle, MemSeg, 1
      LET FilePointer = FilePointer + 1
    END IF
   
    CASE CHR$(45)
    IF (FilePointer > 0) THEN
      MOVEMEM FileHandle, MemSeg, -1
      LET FilePointer = FilePointer - 1
    END IF

    CASE CHR$(79)
    WRITESTATUS "Getting file to open"
    LET FileName$ = GETFILENAME$
    IF (FileName$ <> "") THEN
      WRITESTATUS "Opening file"
      LET FileHandle = OPENFILE%(FileName$ + CHR$(0))
      IF (ErrorFlag) THEN ERRORHANDLER FileHandle, MemSeg

      WRITESTATUS "Getting file size"
      LET FileSize = GETFILESIZE&(FileHandle, TRUE)
      IF (ErrorFlag) THEN ERRORHANDLER FileHandle, MemSeg

      WRITESTATUS "Reading data from file"
      LET BytesRead = FILEREAD%(FileHandle, MemSeg, 0, 336)
      IF (ErrorFlag) THEN ERRORHANDLER FileHandle, MemSeg

      WRITESTATUS " [ESC] Quit  |  [F1] Help"
      LET FilePointer = 0
    ELSE
      WRITESTATUS " [ESC] Quit  |  [F1] Help"
    END IF
  END SELECT

  IF (ErrorFlag) THEN ERRORHANDLER FileHandle, MemSeg

LOOP

FREEMEM MemSeg
CLOSEFILE FileHandle
EXITS NO, ""

SUB CENTER (Ln%, Message$)
LOCATE Ln%, (80 - LEN(Message$)) / 2
PRINT Message$
END SUB

SUB CLOSEFILE (FileHandle%)

DIM Regs AS RegType
LET Regs.ax = &H3E00
LET Regs.bx = FileHandle%
INTERRUPT &H21, Regs, Regs

END SUB

SUB DISPLAYHELP

COLOR 14, 4

DIM EmpLn$
DIM BrdLn$

LET EmpLn$ = CHR$(38) + STRING$(68, 0) + CHR$(38)
LET BrdLn$ = CHR$(38) + STRING$(68, 196) + CHR$(38)

DIM iN AS INTEGER

LOCATE 3, 6: PRINT USING BrdLn$; CHR$(218); CHR$(191)
FOR iN = 4 TO 22
  LOCATE iN, 6: PRINT USING EmpLn$; CHR$(179); CHR$(179)
NEXT iN
LOCATE 23, 6: PRINT USING BrdLn$; CHR$(192); CHR$(217)

CENTER 4, "HELP SYSTEM!"
LOCATE 6, 10: PRINT "<O>            Opens a new file (Closing this one)"

LOCATE 8, 10: PRINT "<" + CHR$(24) + ", " + CHR$(25) + ">         Moves one line (paragraph, 16 bytes)"
LOCATE 9, 10: PRINT "<+, ->          Moves one byte"
LOCATE 10, 10: PRINT "<PgUp, PgDn>    Moves one page (336 bytes)"

LOCATE 20, 10: PRINT "<ESC>           Leaves the program"
CENTER 22, "(Press any key to leave)"

SLEEP
DEF SEG = &H40
POKE &H1A, PEEK(&H1C)
DEF SEG
DRAWSCREEN

END SUB

SUB DRAWSCREEN

DIM EmpLn$
DIM BrdLn$

LET EmpLn$ = CHR$(38) + STRING$(78, 0) + CHR$(38)
LET BrdLn$ = CHR$(38) + STRING$(78, 196) + CHR$(38)

COLOR 0, 7
LOCATE 1, 1
PRINT STRING$(80, 0)

LOCATE 1, 8
PRINT "Thanks for using ";
COLOR 15
PRINT "HEX Viewer v1.0";
COLOR 0
PRINT " by Lucas K. Tavares - LKT153"

COLOR 15, 1
PRINT USING BrdLn$; CHR$(218); CHR$(191)
DIM iN AS INTEGER
FOR iN = 2 TO 22
  PRINT USING EmpLn$; CHR$(179); CHR$(179);
NEXT iN
PRINT USING BrdLn$; CHR$(192); CHR$(217);

COLOR 7, 1

END SUB

SUB ERRORHANDLER (FileHandle%, MemSeg%)

IF (FileHandle% <> 0) THEN CLOSEFILE FileHandle%
IF (MemSeg% <> 0) THEN FREEMEM MemSeg%
SELECT CASE ErrorCode
  CASE &H2: EXITS LO, "File not found, make sure that the file exists"
  CASE &H3: EXITS LO, "Path not found, make sure the file is in the same path as the program"
  CASE &H4: EXITS HI, "Too many open files, no handles left"
  CASE &H5: EXITS HI, "Access denied"
  CASE &H6: EXITS HI, "Invalid handle"
  CASE &H8: EXITS HI, "Not enough memory"
  CASE &HC: EXITS LO, "Invalid open mode"
  CASE ELSE: EXITS HI, "Unknown error. Code: " + HEX$(ErrorCode)
END SELECT

END SUB

SUB EXITS (Prior%, Message$)

COLOR 7, 0
CLS
COLOR 7: PRINT "Thanks for using ";
COLOR 15: PRINT "HEX Viewer v1.0";
COLOR 7: PRINT " by Lucas K. Tavares - LKT153"
IF (Message$ <> "") THEN
  COLOR 7
  PRINT "Error occurred while: " + ErrorStrn
  PRINT "Error: ";
  COLOR Prior%
  PRINT Message$
END IF
SLEEP

DIM Regs AS RegType
LET Regs.ax = VideoMode
INTERRUPT &H10, Regs, Regs
COLOR 7
SYSTEM

END SUB

FUNCTION FILEREAD% (FileHandle%, MemSeg%, Start%, Size%)

DIM Regs AS RegTypeX

LET Regs.ax = &H3F00
LET Regs.bx = FileHandle%
LET Regs.cx = Size%
LET Regs.dx = Start%
LET Regs.ds = MemSeg%
INTERRUPTX &H21, Regs, Regs
IF (Regs.flags AND CF) THEN
  LET ErrorFlag = TRUE
  LET ErrorCode = Regs.ax
END IF
LET FILEREAD% = Regs.ax

END FUNCTION

SUB FREEMEM (MemHandle%)

DIM Regs AS RegTypeX
LET Regs.ax = &H4900
LET Regs.es = MemHandle%
INTERRUPTX &H21, Regs, Regs

END SUB

FUNCTION GETFILENAME$

COLOR 14, 4

DIM FlNLn$
DIM BrdLn$

LET FlNLn$ = CHR$(179) + " File Name: " + STRING$(16, 0) + CHR$(179)
LET BrdLn$ = CHR$(38) + STRING$(28, 196) + CHR$(38)

LOCATE 12, 25: PRINT USING BrdLn$; CHR$(218); CHR$(191)
LOCATE 13, 25: PRINT FlNLn$
LOCATE 14, 25: PRINT USING BrdLn$; CHR$(192); CHR$(217)

DIM File$, Inval$, Key$
DIM isDotted AS INTEGER, DotPos AS INTEGER

LET Inval$ = "\/:*?" + CHR$(34) + "<>|"

LET File$ = ""
LET Key$ = ""
LET isDotted = FALSE
LET DotPos = 0

DO
  COLOR 14
  LOCATE 13, 27: PRINT "File Name: " + STRING$(14, 0)
  LOCATE 13, 38: PRINT File$; : COLOR 30: PRINT "_"

  LET Key$ = ""
  DO UNTIL (LEN(Key$) = 1)
    LET Key$ = UCASE$(INKEY$)
  LOOP
 
  SELECT CASE Key$
    CASE CHR$(8)
    IF (LEN(File$)) THEN
      IF (isDotted) THEN
IF (RIGHT$(File$, 1) = CHR$(46)) THEN
  LET File$ = LEFT$(File$, LEN(File$) - 2)
  LET isDotted = FALSE
  LET DotPos = 0
ELSE
  LET File$ = LEFT$(File$, LEN(File$) - 1)
END IF
      ELSE
LET File$ = LEFT$(File$, LEN(File$) - 1)
      END IF
    END IF

    CASE CHR$(13)
    LET GETFILENAME$ = File$
    EXIT DO

    CASE CHR$(27)
    LET GETFILENAME$ = ""
    EXIT DO

    CASE ELSE
    IF (INSTR(Inval$, Key$) = 0) THEN
      IF (isDotted) THEN
IF (LEN(File$) <= DotPos + 3) AND (Key$ <> CHR$(46)) THEN LET File$ = File$ + Key$
      ELSE
IF (Key$ <> CHR$(46)) THEN
  IF (LEN(File$) = 8) THEN
    LET isDotted = TRUE
    LET DotPos = 8
    LET File$ = File$ + CHR$(46) + Key$
  ELSE
    LET File$ = File$ + Key$
  END IF
ELSE
  LET isDotted = TRUE
  LET DotPos = LEN(File$)
  LET File$ = File$ + CHR$(46)
END IF
      END IF
    END IF
  END SELECT
LOOP
DRAWSCREEN

END FUNCTION

FUNCTION GETFILESIZE& (FileHandle%, Res%)

DIM Regs AS RegType

LET Regs.ax = &H4200 + SEEKEND
LET Regs.bx = FileHandle%
LET Regs.cx = 0
LET Regs.dx = 0
INTERRUPT &H21, Regs, Regs
IF (Regs.flags AND CF) THEN
  LET ErrorFlag = TRUE
  LET ErrorCode = Regs.ax
  EXIT FUNCTION
END IF
LET GETFILESIZE& = VAL("&H" + HEX$(Regs.dx) + HEX$(Regs.ax))

IF (Res% = FALSE) THEN EXIT FUNCTION
SEEKFILE FileHandle%, SEEKSET, 0

END FUNCTION

FUNCTION GETMEM% (Paras%)

DIM Regs AS RegType
LET Regs.ax = &H4800
LET Regs.bx = Paras%
INTERRUPT &H21, Regs, Regs
IF (Regs.flags AND CF) THEN
  LET ErrorFlag = TRUE
  LET ErrorCode = Regs.ax
END IF
LET GETMEM% = Regs.ax

END FUNCTION

SUB MOVEMEM (FileHandle%, MemSeg%, nBytes%)
DEF SEG = MemSeg%

DIM BytesRead AS INTEGER
DIM iN AS INTEGER

IF (nBytes% > 0) THEN
  FOR iN = 0 TO (336 - nBytes%)
    POKE iN, PEEK(iN + nBytes%)
  NEXT iN
  LET BytesRead = FILEREAD%(FileHandle%, MemSeg%, (336 - nBytes%), ABS(nBytes%))
ELSE
  FOR iN = 336 TO ABS(nBytes%) STEP -1
    POKE iN, PEEK(iN + nBytes%)
  NEXT iN
  SEEKFILE FileHandle%, SEEKSET, FilePointer - 1
  LET BytesRead = FILEREAD%(FileHandle%, MemSeg%, 0, ABS(nBytes%))
  SEEKFILE FileHandle%, SEEKCUR, 336
END IF

DEF SEG
END SUB

FUNCTION OPENFILE% (FileName$)

DIM Regs AS RegTypeX

LET Regs.ax = &H3D00
LET Regs.ds = VARSEG(FileName$)
LET Regs.dx = SADD(FileName$)
INTERRUPTX &H21, Regs, Regs
IF (Regs.flags AND CF) THEN
  LET ErrorFlag = TRUE
  LET ErrorCode = Regs.ax
END IF
LET OPENFILE% = Regs.ax

END FUNCTION

SUB PRINTVALUES (MemSeg%, FileSize&)
DEF SEG = MemSeg%

DIM iM AS INTEGER
DIM iN AS INTEGER

DIM tI AS INTEGER
DIM tS AS STRING * 16

DIM iInc AS INTEGER

FOR iN = 0 TO 20
  IF (FileSize > (FilePointer + iInc)) THEN
    LOCATE iN + 3, 3
    LET iInc = iN * 16
    PRINT USING "########## "; (FilePointer + iInc);
    FOR iM = 0 TO 15
      LET tI = PEEK(iInc + iM)
      PRINT HexTab(tI);
      MID$(tS, iM + 1, 1) = AscTab(tI)
      IF (iM = 7) THEN PRINT CHR$(32);
    NEXT iM
    PRINT tS
  ELSE
    EXIT FOR
  END IF
NEXT iN

DEF SEG
END SUB

SUB SEEKFILE (FileHandle%, Origin%, nBytes&)

DIM Regs AS RegType
LET Regs.ax = &H4200 + Origin%
LET Regs.bx = FileHandle%
LET Regs.cx = (nBytes& AND &HFFFF0000) / &HFFFF
LET Regs.dx = nBytes& AND &HFFFF
INTERRUPT &H21, Regs, Regs
IF (Regs.flags AND CF) THEN
  LET ErrorFlag = TRUE
  LET ErrorCode = Regs.ax
END IF

END SUB

SUB SETSCREEN

DIM Regs AS RegType
LET Regs.ax = &HF00
INTERRUPT &H10, Regs, Regs
LET VideoMode = Regs.ax AND &HFF

SCREEN 0
WIDTH 80, 25
COLOR 7, 1
CLS

END SUB

SUB WRITESTATUS (Message$)

COLOR 0, 3
LET ErrorStrn = Message$
LOCATE 25, 1: PRINT STRING$(80, 0);
LOCATE 25, 1: PRINT Message$;
COLOR 7, 1

END SUB

--

PS: I'm not sure if the indenting will come out, if it doesn't in the next correction I'll make it come out... hehe

 
 Respond to this message   
Response TitleAuthorDate
 * "think" not "tihng"lkt153Apr 23, 2003
 Fully Functional version of the abovelkt153Apr 24, 2003
 Updatelkt153Jun 10, 2003
 Copyright © 1999-2014 Network54. All rights reserved.   Terms of Use   Privacy Statement