  DEFINT a-z

  WINDOW 1,,(417,11)-(617,59),31,-1
  MENU 1,0,0,"":MENU 2,0,0,"":MENU 3,0,0,"":MENU 4,0,0,""

  at&=0:text&=0:printat&=0:shadow&=0:sxy&=0:scolr&=0:sbox&=0:dbox&=0
  drawmode&=0:title&=0:loadfont&=0:usefont&=0:killfont&=0:style&=0
  refresh&=0:iffload&=0:iffsave&=0:loadRGB&=0:saveRGB&=0:request&=0
  checkfile&=0:bload&=0:bsave&=0:bopenr&=0:bopenw&=0:bread&=0:bwrite&=0
  seek&=0:bclose&=0:getmem&=0:freemem&=0:zero&=0:copy&=0:w7&=0:bye&=0

  filesize&=0:address&=0
  nl$=CHR$(0):hex16$=STRING$(50,0):ascii$=STRING$(20,0)
  stacksize=9:DIM jstack&(stacksize):stackptr=-1
  DIM flash(240):flash(0)=80:flash(1)=12:flash(2)=2
  FOR i=3 TO 240:flash(i)=-1:NEXT

  mlsize=200
  mlsize=mlsize/2-1
  DIM ml(mlsize)
  OPEN "ml_loader" FOR INPUT AS #1
     FOR i=0 TO mlsize:ml(i)=CVI(INPUT$(2,1)):NEXT
  CLOSE #1
  ml&=VARPTR(ml(0)):ml& SADD("jlib"+nl$),VARPTR(at&),WINDOW(7)
  ERASE ml

  checkfile& SADD("hex.o"+nl$),VARPTR(filesize&)
  IF filesize&<=0 THEN slowquit
  DIM hex16(filesize&/2)
  bload& SADD("hex.o"+nl$),VARPTR(hex16(0)),filesize&

  WINDOW CLOSE 1
  SCREEN 1,640,200,2,2
  WINDOW 2,,,16,1
  w7& WINDOW(7)

  LINE (0,0)-STEP(630,12),2,bf:LINE (0,13)-STEP(630,0),1
  scolr& 1,3:sxy& 2,1:style& 1
  shadow& 5,2,SADD("Memory Monitor - v1.0"+nl$)
  scolr& 1,0:sxy& 5,2:style& 0
  shadow& 208,2,SADD("Starting Address:  (hex)         (decimal)"+nl$)
  scolr& 1,2
  FOR y=0 TO 15:shadow& 10,10*y+18,SADD(RIGHT$("  "+STR$(16*y),3)+nl$):NEXT
  LINE (0,179)-STEP(630,0),1:LINE (0,180)-STEP(630,16),2,bf
  scolr& 1,2
  sbox& 5,182,3,SADD("Quit"+nl$)
  sbox& 53,182,3,SADD("Forward"+nl$)
  sbox& 125,182,3,SADD("Reverse"+nl$)
  sbox& 197,182,3,SADD("Jump"+nl$)
  sbox& 245,182,3,SADD("UnJump"+nl$)
  sbox& 309,182,3,SADD("Window"+nl$)
  sbox& 373,182,3,SADD("Variables"+nl$)
  sbox& 461,182,3,SADD("KickStart"+nl$)
  sbox& 549,182,3,SADD("Dummy"+nl$)
  sbox& 605,182,3,SADD("0"+nl$)

display:
  IF address&<0 THEN address&=0
  IF address&=>10485760& AND address&<13631488& THEN address&=10485760&-256
  IF address&=>13631488& AND address&<16252928& THEN address&=16252928&
  IF address&>2^24-256 THEN address&=2^24-256
  address&=2*INT(address&/2)
  scolr& 1,2
  sbox& 410,0,3,SADD(RIGHT$("00000"+HEX$(address&),6)+nl$)
  sbox& 553,0,3,SADD(RIGHT$("       "+MID$(STR$(address&),2),8)+nl$)
  FOR y=0 TO 15
    LINE (46,10*y+18)-STEP(580,9),0,bf
    hex16&=VARPTR(hex16(0)):hex16& 16*y+address&,SADD(hex16$),SADD(ascii$)
    scolr& 3,2:shadow& 46,10*y+18,SADD(RIGHT$("00000"+HEX$(16*y+address&),6)+nl$)
    scolr& 1,2:shadow& 106,10*y+18,SADD(hex16$)
    scolr& 3,2:shadow& 494,10*y+18,SADD(ascii$)
  NEXT
  IF fx THEN PUT (fx,fy),flash
  jumpflag=0:jumpadd&=0
loop:
  CALL whoa:x=MOUSE(3):y=MOUSE(4)
  IF y<11 THEN
    IF x>404 AND x<460 THEN
      getnum 6
    ELSEIF x>556 AND x<628 THEN
      getnum 8
    END IF
    fx=0:GOTO display
  END IF
  IF x>106 AND x<482 AND y>18 AND y<179 THEN jumpwhere
  IF y>181 AND y<194 THEN buttonpressed
  GOTO loop

jumpwhere:
  IF jumpflag THEN PUT (fx,fy),flash
  ax=INT((x-106)/48):fx=48*ax+106
  ay=INT((y-18)/10):fy=10*ay+18
  jumpadd&=PEEKL(16*ay+2*ax+address&)
  flash(0)=92:flash(1)=9
  PUT (fx,fy),flash:jumpflag=-1
  GOTO loop

buttonpressed:
  IF jumpflag THEN PUT (fx,fy),flash
  fy=182:flash(1)=12
  IF x>5 AND x<45 THEN                 'quit
    fx=5:flash(0)=40
    GOTO quit
  ELSEIF x>53 AND x<117 THEN           'forward
    fx=53:flash(0)=64
    address&=address&+256
  ELSEIF x>125 AND x<189 THEN          'reverse
    fx=125:flash(0)=64
    address&=address&-256
  ELSEIF x>197 AND x<237 THEN          'jump
    IF jumpadd&=0 THEN jumpflag=0:jumpadd&=0:GOTO loop
    fx=197:flash(0)=40
    IF stackptr=stacksize THEN
      stackptr=stackptr-1
      copy& VARPTR(jstack&(1)),VARPTR(jstack&(0)),2*stacksize
    END IF
    stackptr=stackptr+1:IF stackptr=stacksize THEN SOUND 1000,1,255
    jstack&(stackptr)=address&:address&=jumpadd&
  ELSEIF x>245 AND x<301 THEN          'unjump
    IF stackptr<0 THEN jumpflag=0:jumpadd&=0:GOTO loop
    fx=245:flash(0)=56
    address&=jstack&(stackptr)
    stackptr=stackptr-1
  ELSEIF x>309 AND x<365 THEN          'window
    fx=309:flash(0)=56
    address&=WINDOW(7)
  ELSEIF x>373 AND x<453 THEN          'variables
    fx=373:flash(0)=80
    address&=VARPTR(at&)
  ELSEIF x>461 AND x<541 THEN          'kickstart
    fx=461:flash(0)=80
    address&=16515072&
  ELSEIF x>549 AND x<597 THEN          'Basic (unused)
    jumpflag=0:jumpadd&=0:GOTO loop
    fx=549:flash(0)=48
  ELSEIF x>605 AND x<621 THEN          '0
    fx=605:flash(0)=16
    address&=0:stackptr=-1
  ELSE
    fx=0
  END IF
  jumpflag=0:jumpadd&=0
  IF fx THEN PUT (fx,fy),flash
  GOTO display

slowquit:
  BEEP:whoa
quit:
  MENU RESET
  WINDOW CLOSE 2
  SCREEN CLOSE 1
  WINDOW 1
  IF bye&>0 THEN CALL bye&
  END

SUB whoa STATIC
  SHARED key$
  WHILE INKEY$<>"":WEND
  WHILE MOUSE(0)<>0:WEND
  key$="":WHILE MOUSE(0)=0 AND key$="":SLEEP:key$=UCASE$(INKEY$):WEND
END SUB

SUB getnum(length) STATIC
  SHARED address&,sxy&,scolr&,shadow&,sbox&,nl$,msg$
  sxy& 2,1:position=1:x=553:in$="0123456789":msg$=""
  IF length=6 THEN x=410:in$=in$+"ABCDEF"
getmore:
  IF position>length THEN position=length
  IF position<1 THEN position=1
  msg$=LEFT$(msg$+STRING$(length,"_"),length)
  scolr& 1,2:sbox& x,0,3,SADD(msg$+nl$)
  scolr& 1,3:shadow& 8*position+x-4,2,SADD(MID$(msg$,position,1)+nl$)
  key$="":WHILE key$="":key$=UCASE$(INKEY$):SLEEP:WEND
  value=ASC(key$)
  IF value=30 THEN
    position=position+1
  ELSEIF value=31 THEN
    position=position-1
  ELSEIF value=8 THEN
    IF position>1 THEN msg$=LEFT$(msg$,position-2)+MID$(msg$,position)
    position=position-1
  ELSEIF value=127 AND position<length THEN
    msg$=LEFT$(msg$,position-1)+MID$(msg$,position+1)
  ELSEIF value=27 THEN
    msg$=STRING$(length,"_"):position=1
  ELSEIF INSTR(in$,key$)>0 THEN
    IF position=1 THEN
      msg$=key$+MID$(msg$,position)
    ELSE
      msg$=LEFT$(msg$,position-1)+key$+MID$(msg$,position)
    END IF
    position=position+1
  END IF
  IF value<>13 THEN getmore
  scolr& 1,0:shadow& 8*x-8,2,SADD(msg$+nl$)
  sxy& 5,2
  WHILE RIGHT$(msg$,1)="_":msg$=LEFT$(msg$,LEN(msg$)-1):WEND
  IF msg$<>"" THEN
    IF length=6 THEN
      msg$=RIGHT$("00000"+msg$,6)
      address&=4096&*VAL("&h"+LEFT$(msg$,LEN(msg$)-3))+VAL("&h"+RIGHT$(msg$,3))
    ELSE
      address&=VAL(msg$)
    END IF
  END IF
END SUB
