home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 215.lha / FixFD / ReadMe < prev    next >
Text File  |  1996-02-14  |  24KB  |  1,016 lines

  1.  
  2.  To : Aspiring M68000 Programmers
  3.  
  4. From: Peter Wyspianski
  5.  
  6. Date: 01 Jan 89
  7.  
  8.  
  9. As I was getting ready to archive my 'FixFD' utility, it occured to me that
  10. some aspects of programming the Amiga would have been a LOT easier to learn if
  11. I just had a few examples to look over.
  12.  
  13. I came to the Amiga programming enviroment from the MacIntosh.  So I was no
  14. stranger to the M68000 or the sort of things you have to do with it in such a
  15. complex enviroment.  Still, it has been a struggle.  While writing this utility
  16. I had to learn how to detect the user hitting 'ctrl-c' to abort the program. 
  17. No big deal, but I wasted a couple hours looking in the wrong places for the
  18. information (the AmigaDOS manual and some magazines).  Turns out it is not
  19. really documented anywhere, at least not specifically.
  20.  
  21. But I wonder where I would be now if I was a complete novice M68000 programmer?
  22. It's not like the 6502 days when you could just drop into a machine language
  23. monitor and hand-code some instructions to see what they do (that is how I
  24. first learned ML).
  25.  
  26. I have decided to include the source code for the main program.  You may study
  27. it, and even use the routines if you like.  I just hope you learn something.
  28.  
  29. I have NOT included my 'Std_Macs68k' file.  This file just contains a bunch of
  30. macros that match my programming style.  For example, if I am testing a
  31. register for zero, I like to be able to code 'bz.s xxx' rather then the more
  32. ambiguous 'beq.s xxx'.  So in my macro file I have a macro called 'bz'.
  33.  
  34. I have also not included the 'dos_lib.i' file.  This file can be created by
  35. using FixFD like so:
  36.  
  37. >FixFD dos_lib.fd dos_lib.i
  38.  
  39. in my case, I then edited the dos_lib.i file to add a 'PREASM' option and ran
  40. it through the assembler (CAPE68k from Inovatronics).  This feature of CAPE
  41. lets it inhale the 'INCLUDE' file without pausing to assemble it.  A real
  42. timesaver in larger projects.  This step is entirely optional.
  43.  
  44. Finally, the code must be linked with Std_Startup.obj.  This file is my
  45. customized version of AStartup.obj.  I have included 'Std_Startup.obj' but not
  46. the source code for it.  If you want to play around with FixFD, you could link
  47. with AStartup.obj instead.  Here is how you get the link to work:
  48.  
  49. >BLink with FixFD.link
  50.  
  51. if you don't happen to have the freely-redistributable 'BLink' then substitute
  52. the name of your linker (probably 'ALink').  The file 'FixFD.link' is also
  53. included.  Take a look at it, because it expects to find everything in 'RAM:'.
  54.  
  55. Good luck!  Remember to read the docs.  And if you have any questions or
  56. comments then please send me a postcard (my address is in the docs).
  57.  
  58. -Peter W.SHAR_EOF
  59. cat << \SHAR_EOF > FixFD.asm
  60. ; file:FixFD.asm
  61. ;-----------------------------
  62. ;          Fix FD
  63. ;-----------------------------
  64. ; A utility to convert FD files to EQU files.
  65. ;
  66. ; Copyright (c) 1988 by Peter Wyspianski
  67. ;
  68. ; Revision History
  69. ; ----------------
  70. ; 30 Dec 88  created
  71. ; 01 Jan 89  changed to use the 'dos_lib.i' file
  72.  
  73. ;----------------------------------------
  74. ; Constants
  75.  
  76. null    equ     $00
  77. bs    equ    $08
  78. tab    equ    $09
  79. lf    equ     $0a ; amiga eoln
  80. cr    equ     $0d ; CR only
  81. esc    equ    $1b
  82. csi    equ    $9b ; control sequence introducer
  83.  
  84. ; DOS Constants:
  85.  
  86. MODE_OLDFILE    equ 1005
  87. MODE_NEWFILE    equ 1006
  88.  
  89. SIGBREAKB_CTRL_C    EQU    $0C
  90. SIGBREAKB_CTRL_D    EQU    $0D
  91. SIGBREAKB_CTRL_E    EQU    $0E
  92. SIGBREAKB_CTRL_F    EQU    $0F
  93.  
  94. SIGBREAKF_CTRL_C    EQU    $1000
  95. SIGBREAKF_CTRL_D    EQU    $2000
  96. SIGBREAKF_CTRL_E    EQU    $4000
  97. SIGBREAKF_CTRL_F    EQU    $8000
  98.  
  99. ;**SIGBREAK_ANY        equ    $F000
  100. SIGBREAK_ANY        equ    $1000
  101.  
  102. ; Exec Base Offsets:
  103.  
  104. ThisTask    EQU    $114
  105.  
  106. ; Task Control Structure Offsets:
  107.  
  108. TC_SIGRECVD    EQU    $1A
  109. TC_SIGALLOC    EQU    $12
  110.  
  111. ;----------------------------------------
  112. ; Includes
  113.  
  114.     MACFILE "RAM:Std_Macs68k"
  115.     INCLUDE "RAM:dos_lib.i"
  116.  
  117. ;----------------------------------------
  118. ; Publics
  119.  
  120.     XDEF    _main
  121.     XDEF    Exit
  122.     
  123. ;----------------------------------------
  124. ; Externals:
  125.  
  126. ; from std.startup:
  127.  
  128.     XREF    _exit
  129.     XREF    _stdin,_stdout,_SysBase,_DOSBase
  130.  
  131. ;----------------------------------------
  132. ; The beginning
  133.  
  134.     SECTION Main,CODE
  135.  
  136. ; just a little something to brighten some file-zapper's day:
  137.  
  138.     dc.b    'Be Happy!',null
  139.     cnop    0,2
  140.  
  141. ;-------------------------------
  142. ; BCD_Left  [18 Nov 88]
  143. ;
  144. ; - converts hex word to a string of one to five left justified BCD digits
  145. ; - string is null terminated
  146. ;
  147. ; Inputs :  d0.w = hex word
  148. ;           a0.l = starting address of string
  149. ; Outputs:  all regs preserved
  150. ;
  151. ; Notes  :  - from 1 to five digits can be returned plus the zero termination
  152. ;             for a total of up to six characters
  153. ;           - starts by determining number of digits in the string
  154.  
  155. BCD_Left
  156.  
  157.     pushm    d0-d3/a0-a1
  158.     
  159.     move.w    #3,d2        ; # digits - 2
  160.     lea    LBCDTAB,a1    ; point to ten thousands
  161.  
  162. 1$    cmp.w    (a1)+,d0    ; determine number of digits in result
  163.     bcc.s    2$        ; (ubge) taken if right size
  164.     dbra    d2,1$        ; taken for 10K through 10
  165.     bra.s    6$        ; we have just a ones digit
  166.  
  167. 2$    subq.l    #2,a1        ; compensate for following pre-decrement
  168.  
  169. 3$    move.w    (a1)+,d1    ; d1=BCD digit weight
  170.     move.b    #'0',d3        ; init digit to ASCII '0'
  171. 4$    cmp.w    d1,d0        ; digit weight ? remainder
  172.     blt    5$        ; taken if done with this digit
  173.     addq.b    #1,d3        ; inc BCD digit result
  174.     sub.w    d1,d0        ; decrement total
  175.     bnz.s    4$        ; go for more
  176. 5$    move.b    d3,(a0)+    ; stash digit
  177.     dbra    d2,3$        ; next digit position
  178. 6$    or.b    #'0',d0        ; form ones digit
  179.     move.b    d0,(a0)+
  180.     clr.b    (a0)        ; form zero terminator
  181.  
  182.     pullm    d0-d3/a0-a1
  183.     rts
  184.  
  185. LBCDTAB    dc.w    10000,1000,100,10
  186.  
  187. ;----------------------------------------
  188. ; GetDec  [30 Dec 88]
  189. ;
  190. ; - converts a decimal string to a hex value
  191. ;
  192. ; Inputs : a0 = ^ string
  193. ; Outputs: d0.l = value
  194. ;
  195. ; Reg Use: d1,a0-a1
  196. ;
  197. ; Calls  : none
  198. ; Uses   : none
  199. ;
  200. ; Notes  : - Non-numeric input produces garbage (GIGO applies).
  201. ;       - Excessively long strings cause wrap-around.
  202.  
  203. GetDec:
  204.  
  205.     clr.l    d0        ; result
  206. 1$    move.b    (a0)+,d1    ; fetch next digit
  207.     bz.s    2$        ; if 'digit' is a null then all done
  208.  
  209. ; here the running result is multiplied by ten:
  210.  
  211.     asl.l    #1,d0        ; x2
  212.     move.l    d0,a1        ; save the x2 value (a1 = scratch)
  213.     asl.l    #2,d0        ; x4 x8
  214.     add.l    a1,d0        ; x8 + x2 = x10
  215.     
  216. ; the latest 'units' digit is added to the result:
  217.  
  218.     sub.b    #'0',d1        ; force digit to range 0-9
  219.     add.l    d1,d0        ; splice into result
  220.     bra.s    1$        ; and go for more!
  221.  
  222. 2$    rts
  223.  
  224. ;----------------------------------------
  225. ; PrStr   [31 Dec 88] _stdout
  226. ; FPrStr  [31 Dec 88] a file
  227. ;
  228. ; - sends a null terminated string to a file (_stdout)
  229. ;
  230. ; Inputs : a0 = ^string
  231. ;       a1 = file handle (FPrStr only)
  232. ;
  233. ; Outputs: none
  234. ;
  235. ; Calls  : Write    (DOS.Library)
  236. ; Uses   : _DOSBase (library base)
  237. ;       _stdout
  238. ;
  239. ; Notes  : exits via the call to Write
  240.  
  241. PrStr:
  242.     move.l    _stdout,a1
  243. FPrStr:
  244.     push.l    a1    ; save file handle
  245.  
  246.     move.l    a0,a1    ; find the string length
  247. 1$    tst.b    (a1)+
  248.     bnz.s    1$    ; loop until end of string
  249.     sub.l    a0,a1    ; start-end+1 = len+1
  250.     sub.l    #1,a1    ; fix the length
  251.  
  252.     pull.l    d1    ; recover file handle
  253.     move.l    a0,d2    ; ^buffer
  254.     move.l    a1,d3    ; length
  255.     move.l    _DOSBase,a6
  256.     jmp    _LVOWrite(a6)    ; exit via this routine
  257.  
  258. ;----------------------------------------
  259. ; ReadLn   [31 Dec 88] from _stdin
  260. ; FReadLn  [31 Dec 88] from a file
  261. ;
  262. ; - reads a line from a file (_stdin)
  263. ; - terminator (lf) is NOT stored
  264. ; - string is returned null-terminated
  265. ;
  266. ; Inputs : a0 = ^string buffer
  267. ;       a1 = file handle (FReadLn only)
  268. ;
  269. ; Outputs: d0 = result: 1 = ok, 0 = eof, -1 = error
  270. ;
  271. ; Reg Use: d0-d3/a0-a2
  272. ;
  273. ; Calls  : Read    (DOS.Library)
  274. ; Uses   : _DOSBase (library base)
  275.  
  276. ReadLn:
  277.     move.l    _stdin,a1
  278.  
  279. FReadLn:
  280.  
  281.     move.l    a0,a2        ; keep ^buffer safe
  282.     move.l    a1,a3        ; keep file handle safe
  283.     
  284. 1$    move.l    a3,d1        ; file handle
  285.     move.l    a2,d2        ; ^buffer
  286.     move.l    #1,d3        ; read one char
  287.     CallDOS    Read
  288.     cmp.l    #1,d0        ; what was returned?
  289.     bne.s    2$        ; exit if error or eof
  290.     
  291.     move.b    (a2)+,d1    ; fetch character and bump ^buffer
  292.     cmp.b    #lf,d1        ; end of line?
  293.     bne.s    1$        ; taken if not
  294.  
  295. 2$    move.b    #null,-1(a2)    ; null terminate the string
  296.     rts            ; and exit
  297.  
  298. ;----------------------------------------
  299. ; FileOpenError  [31 Dec 88]
  300. ;
  301. ; - calls IoErr to get a specific error number for a failed file open.
  302. ; - prints an error message of the form:
  303. ;
  304. ;   Error #xxx opening file "yyyy".
  305. ;
  306. ;
  307. ; Inputs : a0 = ^filename
  308. ; Outputs: none
  309. ;
  310. ; Reg Use: d0-d1/a0-a1
  311. ;
  312. ; Calls  : IoErr    (DOS.Library)
  313. ;       BCD_Left
  314. ;       PrStr
  315. ; Uses   : _DOSBase (library base)
  316. ;       BCDBuff
  317.  
  318. FileOpenError:
  319.  
  320.     push.l    a0        ; save ^file name
  321.  
  322.     CallDOS    IoErr        ; must do this FIRST
  323.     push.w    d0        ; save the bad news
  324.  
  325.     lea    BadOpenMsg,a0
  326.     jsr    PrStr
  327.  
  328.     pull.w    d0        ; recover error number
  329.     lea    BCDBuff,a0
  330.     jsr    BCD_Left
  331.     
  332.     lea    BCDBuff,a0
  333.     jsr    PrStr        ; show the number
  334.     
  335.     lea    BadOpenMsg1,a0    ; second half of error message
  336.     jsr    PrStr
  337.     
  338.     pull.l    a0        ; fetch ^file name
  339.     jsr    PrStr
  340.     
  341.     lea    BadOpenMsg2,a0    ; third half of error message
  342.     jsr    PrStr
  343.     
  344.     rts
  345.  
  346. *----------------------------------------
  347. * Main  [30 Dec 88]
  348. *
  349. * here is a picture of the entry stack:
  350. *
  351. *   12  ---        not ours!
  352. *    8  ^argvArray pointer to argvArray
  353. *    4  argc       argument count
  354. * sp 0  RA     our return address
  355.  
  356. _main:
  357.     clr.l    TheError    ; default good return
  358.     
  359.     move.l  sp,savesp    ; to ensure that we clean up on exit
  360.     pull.l    ReturnAddr    ; just in case we need it...
  361.  
  362. ; make a pointer to our TC_SIGRECVD:
  363.  
  364.     move.l    _SysBase,a0    ; base of the Exec library
  365.     move.l    ThisTask(a0),a0    ; ^Task Control Structure (that's us!)
  366.     lea    TC_SIGRECVD(a0),a0 ; ^the flags
  367.     move.l    a0,TaskSigs    ; save the pointer for later
  368.  
  369. ; and we're off:
  370.  
  371.     lea    GreetMsg,a0    ; say hello
  372.     jsr    PrStr
  373.  
  374.     pull.l    argc        ; argc (argument count)
  375.     pull.l    argv        ; ^argv (argument array)
  376.     
  377.     move.l    argc,d0        ; argv format: <name> <source> <dest>
  378.     cmp.l    #3,d0        ; we need three arguments...
  379.     blt.l    Help        ; ...taken if 'confused user' error!
  380.  
  381.     move.l    argv,a0        ; fetch ^argv
  382.     move.l    4(a0),a0    ; point to first argument
  383.     move.l    a0,SName    ; save ^source file name
  384.  
  385.     move.l    argv,a0        ; fetch ^argv
  386.     move.l    8(a0),a0    ; point to second argument
  387.     move.l    a0,DName    ; save ^dest file name
  388.  
  389. ; open the input file:
  390.  
  391.     move.l    SName,d1
  392.     move.l    #MODE_OLDFILE,d2    ; must already exist
  393.     CallDOS    Open
  394.  
  395.     move.l    d0,sfile    ; save source file handle
  396.     bnz.s    1$        ; taken if ok
  397.  
  398. ; handle problems opening the input file:
  399.  
  400.     move.l    SName,a0
  401.     jsr    FileOpenError
  402.     move.l    #30,TheError
  403.     bra.l    Exit            ; bye!
  404.  
  405. ; open the output file:
  406.  
  407. 1$    move.l    DName,d1
  408.     move.l    #MODE_NEWFILE,d2
  409.     CallDOS    Open
  410.  
  411.     move.l    d0,dfile    ; save dest file handle
  412.     bnz.s    ScanFD        ; taken if ok
  413.  
  414. ; handle problems opening the output file:
  415.  
  416.     move.l    DName,a0
  417.     jsr    FileOpenError
  418.     move.l    #30,TheError
  419.     bra.l    Exit2
  420.     
  421. ; read lines of the input file until EOF is true:
  422.  
  423. ScanFD:
  424.  
  425. ; If the output file is acutally the tube then we don't want
  426. ; line numbers cluttering the display:
  427.  
  428.     move.l    dfile,d1    ; output file handle
  429.     CallDOS    IsInteractive
  430.     move.b    d0,TubeOut    ; -1 = yeah, 0 = nope
  431.     
  432.     lea    HeaderMsg,a0
  433.     move.l    dfile,a1    ; output file handle
  434.     jsr    FPrStr
  435.  
  436.     move.l    DName,a0
  437.     move.l    dfile,a1    ; output file handle
  438.     jsr    FPrStr
  439.     
  440.     lea    HeaderMsg1,a0
  441.     move.l    dfile,a1    ; output file handle
  442.     jsr    FPrStr
  443.  
  444.     tst.b    TubeOut        ; skip screen formatting if outfile...
  445.     bnz.s    1$        ; ... is connected to the tube.
  446.     
  447.     lea    StatusMsg,a0
  448.     jsr    PrStr
  449.  
  450.     lea    CursorOff,a0
  451.     jsr    PrStr
  452.  
  453. 1$    move.w    line,d0        ; bump line number
  454.     add.w    #1,d0
  455.     move.w    d0,line
  456.  
  457.     tst.b    TubeOut        ; gonna use the tube?
  458.     bnz.s    8$        ; taken if not (being used by out file)
  459.  
  460.     lea    BCDBuff,a0    ; convert line number to a dec string
  461.     jsr    BCD_Left
  462.  
  463.     lea    BCDBuff,a0    ; show the line number
  464.     jsr    PrStr
  465.  
  466. ; This gets REAL fancy by adding one 'bs' to StrBuff for every
  467. ; non-null char in BCDBuff:
  468.  
  469.     lea    BCDBuff,a0
  470.     lea    StrBuff,a1
  471.     
  472. 2$    move.b    #bs,(a1)+    ; put one in there
  473.     tst.b    (a0)+        ; check for a null
  474.     bnz.s    2$        ; taken if not
  475.     
  476.     move.b    #null,-1(a1)    ; kill the last bs and null terminate
  477.  
  478.     lea    StrBuff,a0    ; backup
  479.     jsr    PrStr
  480.  
  481. 8$    move.l    TaskSigs,a0    ; see if the user hit ctrl-c thru ctrl-f
  482.     move.l    (a0),d0        ; d0 = SigsRecvd
  483.     and.l    #SIGBREAK_ANY,d0    ; mask all but ours
  484.     bnz.l    Abort        ; taken if we hit
  485.  
  486.     lea    StrBuff,a0    ; fetch a line from the input file
  487.     move.l    sfile,a1
  488.     jsr    FReadLn    
  489.  
  490.     tst.l    d0        ; see what's up!
  491.     
  492.     bz.l    Exit0        ; taken if EOF
  493.     bmi.l    Exit0        ; taken if error
  494.  
  495. ;----------------------------------------
  496. ; determine what sort of line it is here:
  497. ;
  498. ;         # = option (process further)
  499. ; A-Z,a-z,'_','.' = FD entry (strip)
  500. ;
  501. ; all others are ignored ('*',';', and anything else)
  502.  
  503.     move.b    StrBuff,d0    ; fetch first char
  504.     
  505.     cmp.b    #'#',d0        ; option?
  506.     beq    6$        ; taken if so
  507.     
  508.     cmp.b    #'.',d0        ; fd entry?
  509.     beq.s    3$        ; taken if so
  510.     
  511.     cmp.b    #'_',d0        ; fd entry?
  512.     beq.s    3$        ; taken if so
  513.     
  514.     cmp.b    #'A',d0        ; fd entry?
  515.     blt.l    1$        ; taken if NOT (ignore)
  516.     
  517.     or.b    #$20,d0        ; force to lowercase
  518.     cmp.b    #'z',d0        ; fd entry?
  519.     bgt.l    1$        ; taken if NOT (ignore)
  520.  
  521. ;---------------------------------------------------------------
  522. ; strip the line (scan for a space, open paren, or end of line)
  523. ; there are NO blank lines here (eliminated above):
  524. ;
  525.  
  526. 3$    lea    LVOMsg,a0    ; prefix the routine name with '_LVO'
  527.     move.l    dfile,a1
  528.     jsr    FPrStr
  529.     
  530.     lea    StrBuff,a0
  531. 5$    move.b    (a0)+,d0    ; fetch a char and bump pointer
  532.     bz.s    4$        ; taken if end of line
  533.     cmp.b    #' ',d0        ; space?
  534.     beq.s    4$        ; taken if so
  535.     cmp.b    #'(',d0        ; open paren?
  536.     bne.s    5$        ; taken if so
  537.  
  538. 4$    move.b    #null,-1(a0)    ; null-terminate right AT the 1st excess char
  539.  
  540.     pea    -1(a0)        ; save ^end of string (for later)
  541.     
  542.     lea    StrBuff,a0    ; show the line
  543.     move.l    dfile,a1    ; output file handle
  544.     jsr    FPrStr
  545.     
  546.     lea    StrBuff,a0
  547.     pull.l    d0        ; fetch ^end of string
  548. ;***    sub.l    a0,d0        ; d0 = string len
  549. ;***    lea    EQU8Msg,a0    ; <tab> <tab> equ <tab>-
  550. ;***    cmp.l    #8,d0        ; seven chars or less?
  551. ;***    blt.s    44$        ; taken if so (output extra tab)
  552.  
  553.     lea    EQUMsg,a0    ; <tab> equ <tab>-
  554. 44$    move.l    dfile,a1    ; output file handle
  555.     jsr    FPrStr
  556.     
  557.     move.w    bias,d0        ; convert the bias to a decimal string
  558.     lea    BCDBuff,a0
  559.     jsr    BCD_Left
  560.     
  561.     lea    BCDBuff,a0
  562.     move.l    dfile,a1    ; output file handle
  563.     jsr    FPrStr        ; show the bias
  564.  
  565.     lea    EQUMsg1,a0    ; finish the line off
  566.     move.l    dfile,a1    ; output file handle
  567.     jsr    FPrStr
  568.  
  569.     move.w    #6,d0        ; bump bias
  570.     add.w    d0,bias
  571.  
  572.     bra.l    1$        ; and go again!
  573.  
  574. ;----------------------------------------
  575. ; check for the '##bias' option:
  576.  
  577. 6$    move.l    StrBuff+2,d0    ; fetch 4 chars (should be 'bias')
  578.     or.l    #$20202020,d0    ; force to lowercase
  579.     cmp.l    #'bias',d0
  580.     bne.l    1$        ; ignore if not the option
  581.  
  582. ; scan for a space:
  583.  
  584.     lea    StrBuff+6,a0    ; skip the '##bias'
  585.  
  586. 7$    move.b    (a0)+,d0    ; fetch a char and bump pointer
  587.     bz.l    1$        ; taken if end of line (ignore)
  588.     cmp.b    #' ',d0        ; space?
  589.     bne.s    7$        ; taken if not
  590.  
  591. ; fetch and show the bias:
  592.  
  593.     jsr    GetDec        ; a0 should be pointing at the number
  594.     move.w    d0,bias        ; save it
  595.     
  596. ; show the 'bias = ' message:
  597.  
  598.     lea    BiasMsg,a0
  599.     move.l    dfile,a1    ; output file handle
  600.     jsr    FPrStr
  601.  
  602.     move.w    bias,d0        ; convert the bias to a decimal string
  603.     lea    BCDBuff,a0
  604.     jsr    BCD_Left
  605.     
  606.     lea    BCDBuff,a0
  607.     move.l    dfile,a1    ; output file handle
  608.     jsr    FPrStr        ; show the bias
  609.  
  610.     lea    BiasMsg1,a0
  611.     move.l    dfile,a1    ; output file handle
  612.     jsr    FPrStr
  613.     
  614.     bra.l    1$        ; go for another line
  615.  
  616.  
  617. ;-------------------------------------------
  618. ; show the help message and exit:
  619.  
  620. Help:
  621.     lea    HelpMsg,a0
  622.     jsr    PrStr
  623.     bra.s    Exit
  624.  
  625. ;-------------------------------------------
  626. ; show the 'break...' message and exit:
  627.  
  628. Abort:
  629.     lea    BreakMsg,a0
  630.     jsr    PrStr
  631.     bra.s    ExitA
  632.  
  633. ;-----------------------------
  634. ; Exit routines  [30 Dec 88]
  635. ;
  636.  
  637. Exit0:
  638.  
  639.     lea    DoneMsg,a0
  640.     jsr    PrStr
  641.  
  642. ExitA:
  643.     lea    CursorOn,a0
  644.     jsr    PrStr
  645.  
  646. Exit1:
  647.     move.l    dfile,d1    ; close the dest file
  648.     CallDOS    Close
  649.  
  650. Exit2:
  651.     move.l    sfile,d1    ; close the source file
  652.     CallDOS    Close
  653.  
  654. Exit:
  655.     push.l    TheError    ; error code
  656.     jsr    _exit        ; and wind it up
  657.  
  658. ;----------------------------------------
  659. ; constants
  660.  
  661.     SECTION Constants,DATA
  662.  
  663. GreetMsg:
  664.     dc.b    lf
  665.     dc.b    csi,'0;33;40m'
  666.     dc.b    ' FixFD '
  667.     dc.b    csi,'0;31;40m'
  668.     dc.b    'v1.0 - Copyright ',$a9
  669.     dc.b    ' 1988, Peter Wyspianski',lf,lf
  670.     dc.b    null
  671.  
  672. HelpMsg
  673.     dc.b    ' This utility takes an ''.FD'' file and generates a set of',lf
  674.     dc.b    ' EQUates that can be used by an assembler.',lf,lf
  675.     dc.b    ' Parameters: source_file dest_file.',lf,lf
  676.     dc.b    ' See the docs for more info! -PW',lf,lf,null
  677.  
  678. BadOpenMsg:
  679.     dc.b    csi,'0;33;40m'
  680.     dc.b    ' Error '
  681.     dc.b    csi,'0;31;40m'
  682.     dc.b    '#'
  683.     dc.b    null
  684.  
  685. BadOpenMsg1:
  686.     dc.b    ' opening file "',null
  687.  
  688. BadOpenMsg2:
  689.     dc.b    '"',lf,lf,null
  690.  
  691. CursorOff
  692.     dc.b    csi
  693.     dc.b    '0 p'
  694.     dc.b    null
  695.  
  696. CursorOn
  697.     dc.b    csi
  698.     dc.b    ' p'
  699.     dc.b    null
  700.  
  701. StatusMsg:
  702.     dc.b    '   Reading line '
  703.     dc.b    null
  704.  
  705. DoneMsg
  706.     dc.b    lf,lf
  707.     dc.b    csi,'0;33;40m'
  708.     dc.b    ' Finished.'
  709.     dc.b    csi,'0;31;40m'
  710.     dc.b    lf,lf,null
  711.  
  712. BreakMsg
  713.     dc.b    lf,lf
  714. ;***    dc.b    csi,'0;33;40m'
  715.     dc.b    '*** BREAK'
  716. ;***    dc.b    csi,'0;31;40m'
  717.     dc.b    lf,lf,null
  718.     
  719. HeaderMsg
  720.     dc.b    '; file:',null
  721.  
  722. HeaderMsg1
  723.     dc.b    lf
  724.     dc.b    ';',lf
  725.     dc.b    '; generated by FixFD v1.0',lf
  726.     dc.b    ';',lf
  727.     dc.b    null
  728.  
  729. BiasMsg
  730.     dc.b    '; Bias = ',null
  731.     
  732. BiasMsg1
  733.     dc.b    lf
  734.     dc.b    ';',lf
  735.     dc.b    null
  736.  
  737. LVOMsg
  738.     dc.b    '_LVO',null
  739.     
  740. EQU8Msg
  741.     dc.b    tab
  742. EQUMsg
  743.     dc.b    tab
  744.     dc.b    'equ -'
  745.     dc.b    null
  746.  
  747. EQUMsg1
  748.     dc.b    lf
  749.     dc.b    null
  750.  
  751. ;----------------------------------------
  752. ; Uninitialized storage
  753.  
  754.     SECTION Variables,BSS
  755.  
  756. TaskSigs    ds.l    1    ; pointer to our TC_SIGRECVD
  757.  
  758. TheError    ds.l    1    ; error return code
  759.  
  760. SName        ds.l    1    ; ^source file name
  761. DName        ds.l    1    ; ^dest file name
  762.  
  763. sfile        ds.l    1    ; source file handle
  764. dfile        ds.l    1    ; dest file handle
  765.  
  766. savesp        ds.l    1    ; entry stack pointer
  767.  
  768. argc        ds.l    1    ; argument count
  769. argv        ds.l    1    ; argument array pointer
  770.  
  771. ReturnAddr    ds.l    1    ; program return address
  772.  
  773. bias        ds.w    1    ; library entry bias
  774. line        ds.w    1    ; current line number
  775.  
  776. TubeOut        ds.b    1    ; -1 = yes, 0 = nope
  777.         ds.b    1    ; alignment
  778.  
  779. BCDBuff        ds.b    6    ; bcd string buffer
  780.  
  781. StrBuff        ds.b    256    ; longest possible string
  782.  
  783.         ENDSHAR_EOF
  784. cat << \SHAR_EOF > FixFD.docs
  785.  
  786.  FixFD v1.0
  787.  User Manual
  788.  
  789. Copyright (C) 1988 by Peter Wyspianski
  790.  
  791. [31 Dec 88]
  792.  
  793.  
  794. ----------------------
  795. Please Read The Manual
  796. ----------------------
  797.  
  798. The FixFD utility is not complicated, but please take a couple minutes to read
  799. through this manual before you try it.  Thanks!
  800.  
  801.  
  802. --------
  803. Abstract
  804. --------
  805.  
  806. FixFD is a utility for the Amiga series of computers that reads an '.FD' file
  807. to produce an assembler 'include' file.
  808.  
  809.  
  810. -----------
  811. Legal Stuff
  812. -----------
  813.  
  814. Amiga is a trademark of Commodore-Amiga, Inc.
  815. The author is in no way connected with Commodore-Amiga, Inc.
  816.  
  817. The FixFD utility package, consisting of the program and documentation file, is
  818. copyrighted.  Permission is granted for NON-COMMERCIAL distribution of
  819. UNMODIFIED copies of the entire package.  All other rights are reserved. 
  820. Distribution of separate parts of the package, or of modified copies is
  821. specifically prohibited.  Failure to abide by these rules may result in a fine,
  822. and/or jail term.  Additionally you may get a guilty conscience and I certainly
  823. won't visit you.  Pass the word, pass this program!
  824.  
  825.  
  826. -----------------------
  827. Who Needs This Utility?
  828. -----------------------
  829.  
  830. If you are an Amiga assembly language programmer (or want to be), then read on.
  831. Otherwise, this utility is NOT for you (sorry)!
  832.  
  833.  
  834. -----------
  835. The Problem
  836. -----------
  837.  
  838. When you're programming in assembly language, the most common way to define a
  839. 'Library Vector Offset' (LVO) is to use the XLIB macro like so:
  840.  
  841.     XLIB    Open    ; DOS.Library
  842.     XLIB    Close    ; DOS.Library
  843.     
  844. where the 'XLIB' macro looks something like this:
  845.  
  846. XLIB    macro        ; <routine name>
  847.     xref    _LVO\1
  848.     endm
  849.  
  850. so by the time the assembler has sorted out those first couple of definitions
  851. here is what you got:
  852.  
  853.     xref    _LVOOpen
  854.     xref    _LVOClose
  855.     
  856. Later on in the program you may want to call the 'Open' routine:
  857.  
  858.     move.l    DOSBase,a6
  859.     jsr    _LVOOpen(a6)
  860.  
  861. Of course most of us use a macro for those lines.  But here is a question -
  862. just where IS the actual value of the symbol '_LVOOpen' defined?  It is defined
  863. in the scanned library 'Amiga.Lib'!
  864.  
  865. The problem is that Amiga.Lib is about 80K bytes long, and contains a LOT of
  866. things besides the _LVO definitions.  Having the _LVOs defined in Amiga.Lib
  867. requires that you ALWAYS link your code with Amiga.Lib.  This effectively
  868. neutralizes assemblers that produce loadable object files.  It also makes for
  869. some very long link times.
  870.  
  871.  
  872. ------------
  873. The Solution
  874. ------------
  875.  
  876. The ideal solution to the problem of having the LVOs defined in Amiga.Lib is to
  877. just equate them to their proper values:
  878.  
  879. _LVOOpen    EQU    -30
  880. _LVOClose    EQU    -36
  881.  
  882. Now you don't have to link with Amiga.Lib and the assembler will probably get
  883. done a bit sooner as it doesn't have to do as much work.  To get these equates
  884. you simply use FixFD!
  885.  
  886.  
  887. ------------
  888. What It Does
  889. ------------
  890.  
  891. The Extras disk includes a drawer called 'FDx.x' (where x.x is the operating
  892. system revision, currently '1.3'.  Within this drawer are a number of files
  893. whose names end with '.FD'.  These '.FD' files all have a standard format. 
  894. They completely define all the LVOs within a particular library.  The '.FD'
  895. files are updated with every new revision of the operating system.
  896.  
  897. FixFD simply reads an '.FD' format file and cranks out a file that your
  898. assembler can read (using 'INCLUDE').  And thats all there is to it!
  899.  
  900. You have a lot of choices when it comes to putting the resultant 'include'
  901. files to use.  Adding a bunch of 'INCLUDE' statements is one possibility.  Or
  902. you could merge them into one big include file.  If your assembler supports
  903. 'preassembled symbols' then you can preassemble the LVO file(s) for lightning
  904. assembly speed!
  905.  
  906. I like to have all the LVOs in one big file.  That way I can use the cut-and-
  907. paste features of my text editor to put just the LVOs I need right into the
  908. assembly file I'm working on.
  909.  
  910. There is probably a utility somewhere out there that does exactly the same
  911. thing as FixFD.  Too bad I haven't seen it (yet)!  So here is my contribution. 
  912. Incidentally, it would have been far quicker to write this in something like
  913. BASIC, but I simply wanted some practice at working with DOS files from
  914. assembly.
  915.  
  916.  
  917. -----------
  918. Using FixFD
  919. -----------
  920.  
  921. From the CLI (Command Line Interpreter) or Shell type:
  922.  
  923. >fixfc source_file dest_file
  924.  
  925. where 'source_file' is the name of the '.FD' file you want to read
  926.  and   'dest_file'  is the name of the new file you want to make
  927.  
  928. You can use an asterix ('*') for the dest file, to send output to the CLI
  929. window.  In that case the fancy line number display is suppressed so it doesn't
  930. tangle up the output.
  931.  
  932. FixFD can be aborted in the usual way (ctrl-c).  And if you forget one of the
  933. file names (or use '?'), you get a little blurb reminding you what to do.
  934.  
  935. It DOESN'T work from WorkBench so don't try it (crashes the system).  I could
  936. make it WorkBench compatible but why bother?
  937.  
  938. Thats about it.  I sure hope you like it!
  939.  
  940.  
  941. --------------------
  942. So How Does It Work?
  943. --------------------
  944.  
  945. [This section is for the curious; it may be safely skipped by others.]
  946.  
  947.  
  948. FixFD scans each line of the input file looking for one of the following:
  949.  
  950. ##bias xx
  951.  
  952. Where xx is a decimal number 0-65535.  Sets the base from which subsequent LVOs
  953. are calculated.  Defaults to zero.  The usual value is 30.
  954.  
  955. <LVO name> <whatever>
  956.  
  957. An LVO name is any line that starts with one of these characters:
  958.  
  959.     a-z, A-Z, period ('.'), underline ('_')
  960.     
  961. When an LVO name is found, the line is scaned for an open paren ('(') or space.
  962. If one is found, the line is chopped from that point on.  In any case, the LVO
  963. name is written to the dest file with the prefix '_LVO'.  Following the name is
  964. a tab, the word 'equ', another tab, and the decimal offset of the LVO.
  965.  
  966. All other lines (including blank lines, and lines beginning with ';' or '*')
  967. are ignored.
  968.  
  969.  
  970. -------------------------
  971. Send Postcards Not Money!
  972. -------------------------
  973.  
  974. The Author enjoys getting mail.  Especially picture post cards.  If you like
  975. this program, hate it, or want to see some improvements, please send me a
  976. post card:
  977.  
  978. Peter Wyspianski
  979. 5-10A Brock Cres
  980. Kingston, Ont
  981. CANADA  K7K 5K6
  982.  
  983. Don't bother sending money.  However, all offers of employment will be
  984. seriously considered.
  985.  
  986.  
  987. -----------------
  988. End of the Manual
  989. -----------------
  990.  
  991. Congradulations on having read this far.  Current research indicates that you
  992. are one of only 9.23% of users who bother to read the manual.
  993.  
  994.  
  995. -------------------------
  996. Technical Details/Credits
  997. -------------------------
  998.  
  999. FixFD is written in M68000 Assembly Language.  Total development time was about
  1000. eight hours, including writing this doc file.  I had to write most of the DOS
  1001. file code from scratch.  I already had the decimal conversion and formatting
  1002. routines.
  1003.  
  1004. Some of the better products used in the development of this utility include:
  1005.  
  1006. CAPE 68010 Assembler (Inovatronics)
  1007. BLink (Software Distillery)
  1008. Uedit (Rick Stiles)
  1009.  
  1010. (The preceeding was an unsolicited endorsement).
  1011.  
  1012. Special Thanks: Sharon W.
  1013.  
  1014.  
  1015.  
  1016.