home *** CD-ROM | disk | FTP | other *** search
/ Dream 53 / Amiga_Dream_53.iso / Amiga / Docs / epic13.lha / EpicV1.3 / Epic.E < prev    next >
Text File  |  1997-01-28  |  19KB  |  687 lines

  1. /*
  2.  * A serial mode PIC16C84 programmer ⌐ Stephen Marsden
  3.  *
  4.  *
  5.  */
  6.  
  7. OPT OSVERSION=37
  8.  
  9.     /* Required Libraries */
  10. MODULE 'tools/file'
  11. MODULE 'tools/easygui'
  12. MODULE 'asl', 'libraries/ASL'
  13. MODULE 'amigalib/time'
  14. MODULE 'resources/misc'
  15. MODULE 'intuition/intuition'
  16.  
  17.     /* Parallel Port Data Bits */
  18. CONST IN=0              -> Pin 2 
  19. CONST OUT=0             -> Pin 2 
  20. CONST CLK=1             -> Pin 3 
  21. CONST RST=2             -> Pin 4 
  22.  
  23.     /* PIC16C84 Programming Commands */ 
  24. CONST LDCONF=0          -> Load configuration
  25. CONST LDPROG=2          -> Load data to Program Memory
  26. CONST RDPROG=4          -> Read data from Program Memory (Verify)
  27. CONST INCADD=6          -> Increment address counter
  28. CONST BEGPRG=8          -> Begin programming
  29. CONST LDDATA=3          -> Load data to Data Memory
  30. CONST RDDATA=5          -> Read data from Data Memory (Verify)
  31. CONST EPMODE=10         -> Enter parallel mode (Not used)
  32.  
  33.     /* Timing Requirements for Programming (in microseconds) */
  34. CONST VPPDLY=200000     -> Time for programming voltage to settle
  35. CONST PRGDLY=10000      -> Begin programming delay
  36. CONST TSET=1            -> Data in setup time before clock low
  37. CONST THLD=1            -> Data in hold time after clock
  38. CONST TDLY=2            -> Delay between commands
  39.  
  40.     /* Memory Definitions */
  41. CONST PROGRAM=0
  42. CONST DATA=1
  43. CONST PSIZE=1024        -> Program memory size
  44. CONST DSIZE=64          -> Data memory size
  45.  
  46.     /* Configuration Fuses */
  47. CONST CP=16             -> Code protection bit.  0=On, 1=Off
  48. CONST PWRTE=8           -> Power-up timer bit.   0=Disabled, 1=Enabled
  49. CONST WDTE=4            -> Watchdog timer bit.   0=Disabled, 1=Enabled
  50. CONST RC=3              -> Resistor capacitor oscillator
  51. CONST HS=2              -> High-speed crystal oscillator
  52. CONST XT=1              -> Crystal oscillator
  53. CONST LP=0              -> Power-saving, low-frequency crystal oscillator
  54.  
  55.     /* Intel Hex File-Formats */
  56. CONST INHX16=1
  57. CONST INHX8M=0
  58.  
  59.     /* Programming Speed */
  60. CONST FAST=0
  61. CONST SLOW=1
  62.  
  63. CONST NO_OP=$20         -> Fill byte used to clear program memory
  64. CONST EOF=-1            -> End of file character
  65. CONST TASKPRI=2         -> Increase task priority to maintain correct timing
  66.  
  67.     /* Global Program Variables */
  68. DEF fuses
  69. DEF oscillator=RC, cp=CP, wdt=0, pwrt=PWRTE     -> Default fuse settings
  70. DEF prog_speed=SLOW
  71.  
  72.     /* File Handling Variables */
  73. DEF progbuf[PSIZE]:ARRAY OF INT
  74. DEF databuf[DSIZE]:ARRAY OF INT
  75. DEF buffer[256]:ARRAY
  76. DEF programfileStr[200]:STRING, datafileStr[200]:STRING
  77. DEF fh, filename
  78. DEF checksum            -> Check integrity of file
  79. DEF hextype=INHX8M      -> Default file-type
  80.  
  81.     /* GUI Variables */
  82. DEF gh=NIL:PTR TO guihandle
  83. DEF programfileGad, datafileGad, progressgad, realgad:PTR TO gadget
  84. DEF oscillatorGad, protectGad, wdtimerGad, pwrtimerGad
  85. DEF win:PTR TO window
  86.  
  87.     /* Hardware Variables */
  88. DEF hi=1                -> 1=Positive Logic, 0=Negative Logic
  89. DEF lo=0                -> 0=Positive Logic, 1=Negative Logic
  90. DEF port_bits=0         -> Temp. store for parallel port (only upper byte used)
  91.  
  92.  
  93. PROC main() HANDLE              -> Turn on exception handling
  94. DEF portowner=-1
  95. DEF miscbase, my_task, oldtaskpri
  96.     my_task:=FindTask(0)        -> Find pointer to current task.
  97.     oldtaskpri:=SetTaskPri(my_task,TASKPRI) 
  98.     IF (miscbase:=OpenResource('misc.resource'))=0 THEN Raise("MISC")
  99.     portowner:='PIC_Programmer'
  100.         MOVE.L  miscbase,A6     -> Takeover parallel port
  101.         MOVE.L  portowner,A1
  102.         MOVEQ   #MR_PARALLELPORT,D0
  103.         JSR     MR_ALLOCMISCRESOURCE(A6)
  104.         MOVE.L  D0,portowner
  105.     IF portowner THEN Raise("PORT")
  106.  
  107.     setup()
  108.     StrCopy(programfileStr,'.hex')      -> Default file name
  109.     StrCopy(datafileStr,'.hex')
  110.     JUMP start
  111.  
  112. CHAR '\0$VER: Epic 1.2 (24.01.97)\0'    -> For AmigaDOS 'version' command
  113.  
  114. start:
  115.     IF myeasygui('Epic V1.2  ⌐ Copyright 1997 Stephen Marsden',
  116.         [ROWS,
  117.             [TEXT,'            PIC16C84 Microcontroller Programmer            ',NIL,FALSE,3],
  118.             [COLS,
  119.                 [BEVEL,
  120.                 [ROWS,
  121.                     [TEXT,'  Oscillator Type',NIL,FALSE,3],
  122.                     oscillatorGad:=[MX,{changetype},NIL,['LP','XT','HS','RC',NIL],FALSE,oscillator]
  123.                 ]
  124.                 ],
  125.                 [ROWS,
  126.                     [BEVEL,
  127.                     [EQROWS,
  128.                         [TEXT,'       Fuses',NIL,FALSE,3],
  129.                         protectGad:=[CHECK,{protect},'Code Protection',Eor(cp,CP),FALSE],
  130.                         wdtimerGad:=[CHECK,{wdtimer},'Watchdog Timer',wdt,FALSE],
  131.                         pwrtimerGad:=[CHECK,{pwrtimer},'Power-up Timer',pwrt,FALSE],
  132.                         [SPACE]
  133.                     ]
  134.                     ]
  135.                 ]
  136.             ],
  137.             [COLS,
  138.                 programfileGad:=[STR,{enter_program_str},' Program File',programfileStr,200,3],
  139.                 [BUTTON,{get_program_file},'Get']      
  140.             ],
  141.             [COLS,
  142.                 datafileGad:=[STR,{enter_data_str},' Data File',datafileStr,200,3],
  143.                 [BUTTON,{get_data_file},'Get']      
  144.             ],
  145.             [COLS,
  146.                 [CYCLE,{format},'Hex Format:',['INHX8M','INHX16',NIL],hextype],
  147.                 [CYCLE,{speed},'  Speed:',['Turbo','Normal',NIL],prog_speed]
  148.             ],
  149.             progressgad:=[TEXT,' ',NIL,TRUE,3],
  150.             [BAR],
  151.             [COLS,
  152.                 [BUTTON,{progmem},'Write Program'],
  153.                 [BUTTON,{verifymem},'Verify Program']
  154.             ],
  155.             [BAR],
  156.             [COLS,
  157.                 [BUTTON,{progdata},'Write Data'],
  158.                 [BUTTON,{verifydata},'Verify Data'],
  159.                 [BUTTON,{config},'Blow Fuses']
  160.             ]
  161.         ]) THEN JUMP start
  162.         
  163.         
  164. EXCEPT DO       -> Cleanup system on exit or fatal error
  165.     SetTaskPri(my_task,oldtaskpri)      -> Task priority back to normal.
  166.     IF portowner=NIL
  167.         MOVE.L  miscbase,A6     -> Return parallel port to system
  168.         MOVEQ   #MR_PARALLELPORT,D0
  169.         JSR     MR_FREEMISCRESOURCE(A6)
  170.     ENDIF
  171.     SELECT exception
  172.         CASE "MISC";    request('Could not open misc.resource!','Ok')
  173.         CASE "PORT";    request('Parallel port already allocated to\n%s','Ok',[portowner])
  174.         CASE "OPEN";    request('Could not open file!','Ok')
  175.         CASE "IN";      request('Error reading file!','Ok')
  176.         CASE "MEM";     request('Out of memory!','Ok')
  177.         CASE "GUI";     request('Gui error!','Ok')
  178.         CASE "GT";      request('Could not open gadtools.library','Ok')
  179.         CASE "bigg";    request('Screen too small or font too big!','Ok')
  180.         CASE "Egui";    request('Gui design error!','Ok')
  181.     ENDSELECT
  182. ENDPROC
  183.  
  184.  
  185.     /* Load Program File Via Requester */
  186. PROC get_program_file(info)
  187.     filename:=requestfile('Select hex file')
  188.     setstr(gh,programfileGad,filename)
  189.     IF fh:=Open(filename,OLDFILE)
  190.         loadhex(fh, progbuf, PSIZE)
  191.         Close(fh)
  192.     ELSE
  193.     request('Could not open file!','Ok')
  194.     filename:='.hex'
  195.     setstr(gh,programfileGad,filename)
  196.     ENDIF
  197. ENDPROC
  198.  
  199.  
  200.     /* Load Program File Via Entered Text */
  201. PROC enter_program_str(info,str)
  202.     filename:=str
  203.     IF fh:=Open(filename,OLDFILE)
  204.         loadhex(fh, progbuf, PSIZE)
  205.         Close(fh)
  206.     ELSE
  207.     request('Could not open file!','Ok')
  208.     filename:='.hex'
  209.     setstr(gh,programfileGad,filename)
  210.     ENDIF
  211. ENDPROC
  212.  
  213.  
  214.     /* Load Program File Via Requester */
  215. PROC get_data_file(info)
  216.     filename:=requestfile('Select hex file')
  217.     setstr(gh,datafileGad,filename)
  218.     IF fh:=Open(filename,OLDFILE)
  219.         loadhex(fh, databuf, DSIZE)
  220.         Close(fh)
  221.     ELSE
  222.     request('Could not open file!','Ok')
  223.     filename:='.hex'
  224.     setstr(gh,datafileGad,filename)
  225.     ENDIF
  226. ENDPROC
  227.  
  228.  
  229.     /* Load Program File Via Entered Text */
  230. PROC enter_data_str(info,str)
  231.     filename:=str
  232.     IF fh:=Open(filename,OLDFILE)
  233.         loadhex(fh, databuf, DSIZE)
  234.         Close(fh)
  235.     ELSE
  236.     request('Could not open file!','Ok')
  237.     filename:='.hex'
  238.     setstr(gh,datafileGad,filename)
  239.     ENDIF
  240. ENDPROC
  241.  
  242.  
  243.     /* Configuration Changes Initiated By GUI */
  244. PROC changetype(x,y) IS oscillator:=y
  245. PROC protect(x,y) IS cp:=IF y THEN 0 ELSE CP
  246. PROC wdtimer(x,y) IS wdt:=IF y THEN WDTE ELSE 0
  247. PROC pwrtimer(x,y) IS pwrt:=IF y THEN PWRTE ELSE 0
  248. PROC format(x,y) IS hextype:=IF y THEN INHX16 ELSE INHX8M
  249. PROC speed(x,y) IS prog_speed:=IF y THEN SLOW ELSE FAST
  250.  
  251.  
  252.     /* Change State Of CLK Line (not immediate) */
  253. PROC clk(state) 
  254.     IF state=1
  255.         BSET.B  #CLK,port_bits      -> CLK=1
  256.     ELSE
  257.         BCLR.B  #CLK,port_bits      -> CLK=0
  258.     ENDIF
  259. ENDPROC
  260.  
  261.  
  262.     /* Change State Of OUT Line (not immediate) */
  263. PROC out(state) 
  264.     IF state=1
  265.         BSET.B  #OUT,port_bits      -> OUT=1
  266.     ELSE
  267.         BCLR.B  #OUT,port_bits      -> OUT=0
  268.     ENDIF
  269. ENDPROC
  270.  
  271.  
  272.     /* Change State Of RST Line (immediate) */
  273. PROC reset()
  274.     BSET.B  #RST,port_bits
  275.     assert()
  276.     timeDelay(0,0,VPPDLY)
  277.     BCLR.B  #RST,port_bits
  278.     assert()
  279. ENDPROC    
  280.  
  281.  
  282.     /* Set State Of All Parallel Port Outputs (immediate) */
  283. PROC assert()
  284.     MOVE.B  port_bits,$BFE101
  285. ENDPROC
  286.  
  287.  
  288.     /* Check State of IN Bit (immediate) */
  289. PROC inbit()
  290.     MOVEQ   #0,D0
  291.     BSET.B  #IN,D0
  292.     AND.B   $BFE101,D0    
  293. ENDPROC D0
  294.  
  295.  
  296.     /* Inform Chip That We Are About To Program It */
  297. PROC prog_mode()
  298.     clk(lo)
  299.     out(lo)
  300.     reset()
  301.     timeDelay(0,0,VPPDLY)
  302. ENDPROC
  303.  
  304.  
  305.     /* Setup CIA Hardware And Clear Memory Buffers */
  306. PROC setup()
  307. DEF i
  308.         MOVE.W  #$7,D0         -> D0,D1,D2=Output mode
  309.         MOVE.B  D0,$BFE301     -> CIA direction register        
  310.     clk(lo)
  311.     out(lo)
  312.     assert()
  313.         /* Clean buffers */
  314.     FOR i:=0 TO PSIZE-1
  315.         progbuf[i]:=NO_OP    -> Machine-code value for NO OPERAND
  316.     ENDFOR
  317.     FOR i:=0 TO DSIZE-1
  318.         databuf[i]:=1
  319.     ENDFOR
  320. ENDPROC
  321.  
  322.  
  323.     /* Send Data To Parallel Port */
  324. PROC clock_out(bit)
  325.     IF bit THEN out(hi) ELSE out(lo)
  326.     clk(hi)
  327.     assert()
  328.     IF prog_speed THEN timeDelay(0,0,TSET)
  329.     clk(lo)
  330.     assert()
  331.     IF prog_speed THEN timeDelay(0,0,THLD)
  332.     out(lo)
  333.     assert()
  334. ENDPROC
  335.  
  336.  
  337.     /* Read Data From Parallel Port */
  338. PROC clock_in()
  339. DEF b
  340.     out(hi)
  341.     clk(hi)
  342.     assert()
  343.     IF prog_speed THEN timeDelay(0,0,TSET)
  344.     clk(lo)
  345.     assert()
  346.     b:=IF inbit() THEN hi ELSE lo
  347.     IF prog_speed THEN timeDelay(0,0,THLD)
  348. ENDPROC b
  349.  
  350.  
  351.     /* Send Word To Chip */
  352. PROC out_word(w)
  353. DEF c
  354.     clock_out(0)
  355.     FOR c:=0 TO 13 DO clock_out(w AND Shl(1,c))
  356.     clock_out(0)
  357. ENDPROC
  358.  
  359.  
  360.     /* Read Word From Chip */
  361. PROC in_word()
  362. DEF b, word
  363.         MOVE.W  #$6,D0         -> D0=Input  D1,D2=Output
  364.         MOVE.B  D0,$BFE301     -> CIA direction register         
  365.     clock_in()
  366.     word:=0
  367.     FOR b:=0 TO 13 DO word:=word+Shl(clock_in(),b)
  368.     clock_in()
  369.         MOVE.W  #$7,D0         -> D0,D1,D2=Output
  370.         MOVE.B  D0,$BFE301     -> CIA direction register             
  371. ENDPROC word
  372.  
  373.  
  374.     /* Send Command To Chip */
  375. PROC command(cmd)
  376. DEF b
  377.     out(lo)
  378.     assert()
  379.     IF prog_speed THEN timeDelay(0,0,TDLY)
  380.     FOR b:=0 TO 5 DO clock_out(cmd AND Shl(1,b) )
  381.     out(hi)
  382.     assert()
  383.     IF prog_speed THEN timeDelay(0,0,TDLY)
  384. ENDPROC
  385.  
  386.  
  387.     /* Erase All Memory On Chip */
  388. PROC erase()
  389. DEF i
  390.     prog_mode()
  391.     command(LDCONF)
  392.     out_word($3FFF)                     -> Disable code protection
  393.     FOR i:=0 TO 6 DO command(INCADD)    -> Increment to fuse location $2007
  394.     command(1)                          -> Undocumented command
  395.     command(7)                          -> Undocumented command
  396.     command(BEGPRG)
  397.     timeDelay(0,0,PRGDLY)
  398.     command(1)                          -> Repeat sequence
  399.     command(7)
  400. ENDPROC
  401.  
  402.  
  403.     /* Display Progress Bar For User Feedback */
  404. PROC progress(percentage)
  405. DEF x1, y1, width, height
  406.     IF percentage>100 THEN percentage:=100
  407.     IF realgad:=findgadget(gh,progressgad)
  408.         x1:=realgad.leftedge+2
  409.         y1:=realgad.topedge+1
  410.         width:=realgad.width-5
  411.         height:=realgad.height-3
  412.         Box(x1,y1,x1+(width*percentage/100),y1+height,3)
  413.     ENDIF
  414. ENDPROC
  415.  
  416.  
  417.     /* Clear Progress Bar */
  418. PROC clearprogress()
  419. DEF x1, y1, width, height
  420.     IF realgad:=findgadget(gh,progressgad)
  421.         x1:=realgad.leftedge+2
  422.         y1:=realgad.topedge+1
  423.         width:=realgad.width-5
  424.         height:=realgad.height-3
  425.         Box(x1,y1,x1+width,y1+height,0)
  426.     ENDIF
  427. ENDPROC
  428.         
  429.  
  430. PROC progmem() IS program(PROGRAM)
  431. PROC progdata() IS program(DATA)
  432.  
  433.  
  434.     /* Write to PROGRAM or DATA Memory on Chip */
  435. PROC program(mem_type)
  436. DEF i, n, w, mask, ldcmd, rdcmd, buf:PTR TO INT
  437.     request('Make sure PIC is inserted correctly\nand placed in program mode i.e 12V','Continue')
  438.     IF (mem_type=PROGRAM)
  439.     erase()
  440.         buf:=progbuf
  441.         n:=PSIZE
  442.         mask:=$3FFF
  443.         ldcmd:=LDPROG
  444.         rdcmd:=RDPROG
  445.     ELSE 
  446.         buf:=databuf
  447.         n:=DSIZE
  448.         mask:=$FF
  449.         ldcmd:=LDDATA
  450.         rdcmd:=RDDATA
  451.     ENDIF
  452.     clearprogress()
  453.     prog_mode()
  454.     FOR i:=0 TO n-1 
  455.         command(ldcmd)
  456.         out_word(buf[i])
  457.         command(BEGPRG)
  458.         timeDelay(0,0,PRGDLY)
  459.         IF prog_speed
  460.             command(rdcmd)
  461.             w:=in_word() AND mask
  462.             IF (buf[i] <> w)
  463.                 request('Write error during programming','Ok')
  464.                 RETURN
  465.             ENDIF
  466.         ENDIF
  467.         command(INCADD)
  468.         IF (i AND 2) THEN progress(i*100/(n-1))
  469.     ENDFOR
  470. ENDPROC
  471.  
  472.  
  473. PROC verifymem() IS verify(PROGRAM)
  474. PROC verifydata() IS verify(DATA)
  475.  
  476.  
  477.     /* Verify Contents of PROGRAM or DATA Memory */
  478. PROC verify(mem_type)
  479. DEF i, n, w, mask, rdcmd, buf:PTR TO INT
  480.     IF (mem_type = PROGRAM)
  481.         buf:=progbuf
  482.         n:=PSIZE
  483.         mask:=$3FFF
  484.         rdcmd:=RDPROG
  485.     ELSE      
  486.         buf:= databuf
  487.         n:=DSIZE
  488.         mask:=$FF
  489.         rdcmd:=RDDATA
  490.     ENDIF
  491.     clearprogress()
  492.     prog_mode()
  493.     FOR i:=0 TO n-1 
  494.         command(rdcmd)
  495.         w:=in_word() AND mask
  496.         IF (buf[i] <> w) 
  497.             request('Verify failed','Ok')
  498.             RETURN
  499.       ENDIF
  500.       command(INCADD)
  501.         IF (i AND 2) THEN progress(i*100/(n-1))
  502.     ENDFOR
  503. ENDPROC
  504.  
  505.  
  506.     /* Write Fuse Information To Chip */
  507. PROC config()
  508. DEF i
  509.     fuses:=oscillator+cp+wdt+pwrt
  510.     clearprogress()
  511.     prog_mode()
  512.     command(LDCONF)
  513.     out_word(fuses)
  514.     progress(20)
  515.     FOR i:=0 TO 6 DO command(INCADD)
  516.     progress(40)
  517.     command(LDPROG)
  518.     out_word(fuses)
  519.     progress(60)
  520.     command(BEGPRG)
  521.     timeDelay(0,0,PRGDLY)
  522.     progress(80)
  523.     command(RDPROG)
  524.     IF (fuses <> (in_word() AND $1F))
  525.         request('Fuse failure','Ok')
  526.         RETURN
  527.     ENDIF
  528.     progress(100)
  529. ENDPROC
  530.  
  531.  
  532.     /* Read A Single Hex Symbol From File */
  533. PROC hexdigit(fp)
  534. DEF c
  535.     IF ((c:=FgetC(fp))=EOF) THEN Throw("HEX",'File error!\nUnexpected EOF in line')
  536.     IF c>"9" THEN c:=c-"A"+10 ELSE c:=c-"0"
  537.     IF (c<0 OR c>$F) THEN Throw("HEX",'File error!\nHex digit expected in line')
  538. ENDPROC c
  539.  
  540.  
  541.     /* Read Two Hex Symbols From File */
  542. PROC hexbyte(fp)
  543. DEF b
  544.     b:=hexdigit(fp)
  545.     b:=Shl(b,4) + hexdigit(fp)
  546.     checksum:=checksum+b
  547. ENDPROC b
  548.  
  549.  
  550.     /* Read Four Hex Symbols From File */
  551. PROC hexword(fp)
  552. DEF w
  553.     w:=hexbyte(fp)
  554.     w:=Shl(w,8) + hexbyte(fp)
  555. ENDPROC w
  556.  
  557.  
  558.     /* Used During Loading/Converting Of Intel Hex Files */
  559. PROC swab(w)
  560.     MOVE.L  w,D0
  561.     ROR.W   #8,D0       -> Swap upper and lower bytes of a word
  562. ENDPROC D0
  563.  
  564.  
  565.     /* Load An Intel Hex File */
  566. PROC loadhex(fp, buf:PTR TO INT, bufsize) HANDLE
  567. DEF type, nwords, i, address, w, line, bits
  568.     type:=0
  569.     line:=0
  570.     WHILE (type<>1) 
  571.         INC line
  572.         IF (FgetC(fp)<>":") THEN Throw("HEX",'File error!\nError in line %ld\n":" Expected')
  573.         checksum:=0
  574.         w:=hexbyte(fp)
  575.         nwords:=IF (hextype=INHX8M) THEN w/2 ELSE w
  576.         w:=hexword(fp)
  577.         address:=IF (hextype=INHX8M) THEN w/2 ELSE w
  578.         type:=hexbyte(fp)
  579.         IF address=$2008        -> Handle PARALLAX device info
  580.             IF hexbyte(fp)<>1 THEN Throw("HEX",'Error!\nin line %ld\nFile has not been compiled for 16C84')
  581.             hexbyte(fp)
  582.             JUMP file_check
  583.         ENDIF
  584.         IF ((address>=$2000) AND (address<$2007))
  585.             hexbyte(fp)         -> Handle PARALLAX ID info (ignored at present)
  586.             hexbyte(fp)
  587.             JUMP file_check
  588.         ENDIF
  589.         IF address=$2007        -> Handle PARALLAX fuse info
  590.             bits:=hexbyte(fp)
  591.             oscillator:=bits AND 3
  592.             setmx(gh,oscillatorGad,oscillator)  -> Update fuse gadgets in GUI
  593.             IF (bits AND 4)
  594.                 wdtimer(0,TRUE)
  595.                 setcheck(gh,wdtimerGad,TRUE)
  596.             ELSE
  597.                 wdtimer(0,FALSE)
  598.                 setcheck(gh,wdtimerGad,FALSE)
  599.             ENDIF
  600.             IF (bits AND 8)
  601.                 pwrtimer(0,TRUE)
  602.                 setcheck(gh,pwrtimerGad,TRUE)
  603.             ELSE
  604.                 pwrtimer(0,FALSE)
  605.                 setcheck(gh,pwrtimerGad,FALSE)
  606.             ENDIF
  607.             IF (bits AND 16)
  608.                 protect(0,FALSE)
  609.                 setcheck(gh,protectGad,FALSE)
  610.             ELSE
  611.                 protect(0,TRUE)
  612.                 setcheck(gh,protectGad,TRUE)
  613.             ENDIF
  614.             hexbyte(fp)
  615.             JUMP file_check
  616.         ENDIF
  617.         FOR i:=0 TO nwords-1 
  618.             IF (address < bufsize)      -> Copy to PROGRAM buffer
  619.                 w:=hexword(fp)
  620.                 buf[address]:=IF (hextype = INHX8M) THEN swab(w) ELSE w
  621.                 INC address
  622.             ELSEIF (address>=$2100) AND (address<$2140) -> Copy to DATA buffer
  623.                 w:=hexword(fp)
  624.                 databuf[address]:=IF (hextype = INHX8M) THEN swab(w) ELSE w
  625.                 INC address
  626.                 filename:='***Data Embedded In Program File***' -> Inform user
  627.                 setstr(gh,datafileGad,filename)
  628.             ELSE
  629.                 Throw("HEX",'File error!\nImpossible address in line %ld')
  630.             ENDIF
  631.         ENDFOR
  632. file_check:
  633.         hexbyte(fp)
  634.         IF FgetC(fp)=$0D THEN FgetC(fp)
  635.         IF (checksum AND $FF) THEN Throw("HEX",'Checksum error!\nin line %ld')
  636.     ENDWHILE
  637. EXCEPT
  638.     IF exception="HEX" THEN request(exceptioninfo,'Ok',[line]) ELSE ReThrow()
  639. ENDPROC
  640.  
  641.  
  642. /*    Presents an ASL load-file requester.  If the user selected a file,
  643.       it is expanded to a full path-name */
  644. PROC requestfile(title)
  645. DEF fr:PTR TO filerequester
  646.     IF aslbase:=OpenLibrary('asl.library',36)
  647.         IF fr:=AllocAslRequest(ASL_FILEREQUEST,[ASLFR_TITLETEXT,title,0])
  648.             IF AslRequest(fr,0)
  649.                     /* strcpy() */
  650.                 MOVE.L  fr,A0
  651.                 MOVE.L  8(A0),A0    -> directory pointer from 'filerequester'
  652.                 MOVE.L  buffer,A1
  653. np:             MOVE.B  (A0)+,(A1)+
  654.                 BNE.S   np
  655.                 AddPart(buffer,fr.file,256)
  656.             ENDIF
  657.             FreeAslRequest(fr)
  658.         ENDIF
  659.         CloseLibrary(aslbase)
  660.     ENDIF
  661. ENDPROC buffer
  662.  
  663.  
  664.     /* Simple requester */
  665. PROC request(body,gadgets,args=NIL)
  666. ENDPROC EasyRequestArgs(0,[20,0,0,body,gadgets],0,args)
  667.  
  668.  
  669.     /* Use global gui-handler (gh) instead of a local one */
  670. PROC myeasygui(windowtitle,gui,info=NIL,screen=NIL,textattr=NIL) HANDLE
  671. DEF res=-1
  672.     gh:=guiinit(windowtitle,gui,info,screen,textattr)
  673.     win:=gh.wnd
  674.     WindowLimits(win,win.width,win.height,win.width,win.height)
  675.     WHILE res<0
  676.         Wait(gh.sig)
  677.         res:=guimessage(gh)
  678.     ENDWHILE
  679. EXCEPT DO
  680.     cleangui(gh)
  681.     ReThrow()
  682. ENDPROC res
  683.  
  684.  
  685.  
  686.  
  687.