home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / extasm / Converter_Source < prev    next >
Encoding:
Text File  |  1993-10-25  |  26.0 KB  |  883 lines

  1. ; -----------------------------------------------------------------------------
  2. ; This program will convert a basic source with FN_ADR etc. into a clean
  3. ; new source for use with extASM.
  4. ;
  5. ; The current settings will fix source written using my BasLib into fresh
  6. ; new text, ready to run through extASM.
  7. ;
  8. ; The basic source must be converted to text first (StrongED ?) and please
  9. ; remember to strip off the BASIC parts surrounding the assembler part.
  10. ;
  11. ; © Eivind Hagen, July 1993
  12. ; -----------------------------------------------------------------------------
  13.  
  14. #name convert
  15.  
  16. .Code_Start
  17.    B     Start
  18.  
  19. .New_Stack_Start
  20.    DBB      1024
  21. .New_Stack_End
  22.  
  23. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  24.  
  25. .Patch_Search    DCD   0
  26. .Patch_Replace   DCD   0
  27.  
  28. .Patch_Instructions
  29.    DCB   "FN_ADR? (*)",0
  30.    DCB   "ADR      * ",0
  31.  
  32.    DCB   "FN_LDR? (*)",0
  33.    DCB   "LDR      * ",0
  34.  
  35.    DCB   "FN_STR? (*)",0
  36.    DCB   "STR      * ",0
  37.  
  38.    DCB   "FN_SWP  (*)",0
  39.    DCB   "EXG      * ",0
  40.  
  41.    DCB   "FN_MOV  (*,*)",0
  42.    DCB   "MOV      *,#*",0
  43.  
  44.    DCB   "FN_DIVS (*,*,*,*)",0         ; div is sooooo simple to use new ;-)
  45.    DCB   "DIV      *,*,*   ",0
  46.  
  47.    DCB   "EQUS",0                      ; Silly silly...
  48.    DCB   "DCB ",0
  49.  
  50.    DCB   "FN_BLK(*)",0                 ; This is now called DBB (Declare Block of Bytes)
  51.    DCB   "DBB   *,0",0
  52.  
  53.    DCB   "FN_FILL(*,*)",0              ; This is now called DBB (Declare Block of Bytes)
  54.    DCB   "DBB   *,*",0
  55.  
  56.    DCB   "FN_Tag(",34,"*",34,",*)",0   ; Tagging (!) done easier
  57.    DCB   "DCB   ",34,"*",34," : ALIGN",0
  58.  
  59.    DCB   "FN_WIMPERROR",0              ; FN_WIMPERROR macro not available in extASM yet
  60.    DCB   ";FN_WIMPERROR",0
  61.  
  62.    DCB   "SWI*",34,"*",34,0            ; No fnutts around swi names, that's lame
  63.    DCB   "SWI** ",0
  64.  
  65.    DCB   "#ASC(",34,"*",34,")",0       ; mov r3,#ASC("X")  nah, mov r3,#"X"
  66.    DCB   "#",34,"*",34,"     ",0
  67.  
  68.    DCB   "#ASC",34,"*",34,0            ; mov r3,#ASC"X"  nah, mov r3,#"X"
  69.    DCB   "#",34,"*",34,"   ",0
  70.  
  71.    DCB   ":=",0                        ; This is JUST SILLY Mr. R. Wilson ;-))
  72.    DCB   ",",0
  73.  
  74.    DCB   ".Loop",0                     ; Make all .Loop label local (may cause trouble!)
  75.    DCB   "._Loop",0
  76.  
  77.    DCB   " Loop",0                     ; Make all .Loop label local (may cause trouble!)
  78.    DCB   " _Loop",0
  79.  
  80.    DCB   "TIME$",0                     ; TIME$ does not work in extASM (yet...)
  81.    DCB   34,"NO-TIME",34,0
  82.  
  83.    DCB   1                             ; terminator
  84.  
  85. ALIGN
  86.  
  87. ;  >============================================================<
  88. ;  >                             START                          <
  89. ;  >============================================================<
  90.  
  91. .Start
  92.    STR      R13,Old_Stack
  93.    ADR      R13,New_Stack_End
  94.    STMFD    R13!,{R0-R12,R14}
  95. ; >-------------------------------------------------------------<
  96.  
  97.    BL       Install_ExceptionHandler
  98.    BL       Initialize
  99.  
  100. ; >-------------------------------------------------------------<
  101.  
  102. .Main
  103.    BL       Load_Source
  104.    BL       Patch
  105.    BL       Save_Source
  106.  
  107. ; >-------------------------------------------------------------<
  108.  
  109. .The_End
  110.    BL       DeInstall_ExceptionHandler
  111.    B        Quit
  112.  
  113. ; >=============================================================<
  114.  
  115. .Exception_Old
  116.    DCD   6
  117.    DCD   0
  118.    DCD   0
  119.    DCD   0
  120.  
  121. .Install_ExceptionHandler
  122.    STMFD    R13!,{R0-R3,R10,R14}
  123.    MOV      R0,#6
  124.    ADR      R1,ExceptionHandler
  125.    MOV      R2,#0
  126.    ADR      R3,Exception_PC
  127.    SWI      OS_ChangeEnvironment
  128.    ADR      R10,Exception_Old
  129.    STMIA    R10,{R0-R3}
  130.    LDMFD    R13!,{R0-R3,R10,PC}^
  131.  
  132. .DeInstall_ExceptionHandler
  133.    STMFD    R13!,{R0-R3,R10,R14}
  134.    ADR      R10,Exception_Old
  135.    LDMIA    R10,{R0-R3}
  136.    SWI      OS_ChangeEnvironment
  137.    LDMFD    R13!,{R0-R3,R10,PC}^
  138.  
  139. .ExceptionHandler
  140.    ADR      R1,Exception_Msg
  141. ._Loop
  142.    LDRB     R0,[R1],#1
  143.    CMP      R0,#0
  144.    BNE      _Loop
  145.    MOV      R0,#" "
  146.    STRB     R0,[R1,#-1]
  147.    
  148.    LDR      R0,Exception_PC
  149.    BIC      R0,R0,#%11111100000000000000000000000000
  150.    BIC      R0,R0,#%00000000000000000000000000000011
  151.    MOV      R2,#10
  152.    SWI      OS_ConvertHex8
  153.  
  154.    ADR      R0,Exception_Code
  155.    MOV      R1,#%00000111
  156.    ADR      R2,Task_Name
  157.    SWI      Wimp_ReportError
  158.    CMP      R1,#1
  159.    BAL      Core_Dump
  160.  
  161.    ADR      R0,Exception_Msg
  162.    MOV      R1,#&58454241
  163.    MOV      R2,#0
  164.    SWI      OS_Exit
  165.  
  166. .Exception_PC
  167.    DCD   0
  168. .Exception_Code
  169.    DCD   0
  170. .Exception_Msg
  171.    DCB  "                                                             "
  172.    DCB  "                                                             "
  173.    DCB 0
  174.    ALIGN
  175.  
  176. ; >=============================================================<
  177. ;  --------------------------------------------------------------
  178. ;  |      ####  #####  #   #  #####  ####    ###   #            |
  179. ;  |     #      #      ##  #  #      #   #  #   #  #            |
  180. ;  |     #  ##  ###    # # #  ###    ####   #####  #            |
  181. ;  |     #   #  #      #  ##  #      #  #   #   #  #            |
  182. ;  |      ###   #####  #   #  #####  #   #  #   #  #####        |
  183. ;  --------------------------------------------------------------
  184.  
  185. ;  >============================================================<
  186. ;  >                         GENERAL DATA                       <
  187. ;  >============================================================<
  188.  
  189. .Task_Name
  190.    DCB      "Converter",0
  191.  
  192.    ALIGN
  193.  
  194. ;  >============================================================<
  195. ;  >                      GENERAL VARIABLES                     <
  196. ;  >============================================================<
  197.  
  198. .Old_Stack              DCD   0
  199.  
  200. .Param_Length           DCD   0
  201. .Param_Num              DCD   0
  202.  
  203. ;  >============================================================<
  204. ;  >                      GENERAL ROUTINES                      <
  205. ;  >============================================================<
  206.  
  207. .Initialize
  208.    STMFD    R13!,{R14}
  209.  
  210.    MOV      R0,#4                      ; Flex #0 = Original text
  211.    BL       Flex_Create
  212.  
  213.    SWI      OS_GetEnv                  ; R0-> Address of *command
  214. ._Loop
  215.    LDRB     R2,[R0],#1
  216.    CMP      R2,#0
  217.    BNE      _Loop                       ; R0-> End of CommandLine
  218.    SUB      R0,R0,R1                   ; R0 = Parameter Length
  219.    STR      R0,Param_Length
  220.    SWI      OS_GetEnv                  ; R0-> Address of *command
  221.    MVN      R1,#0                      ; R1 = -1 (Scanning)
  222.    BL       Parse_String               ;_R2 = Number of parameters
  223.    STR      R2,Param_Num
  224.  
  225.    LDR      R0,Param_Num
  226.    BL       Print_Register
  227.  
  228.    MOV      R14,#0                     ;~R14 = Error code (0=OK)
  229.    LDMFD    R13!,{PC}
  230.  
  231. ; >-------------------------------------------------------------<
  232.  
  233. .Quit
  234.    LDMFD    R13!,{R0-R12,R14}
  235.    LDR      R13,Old_Stack
  236.    SWI      OS_Exit
  237.  
  238. ; >=============================================================<
  239. ; > Entry | R0-> String to parse
  240. ; >       | R1 = Parameter[number] to return
  241. ; >
  242. ; > Exit  | R0-> Parameter
  243. ; >       | R1 = 0 if found, <> 0 if not found
  244. ; >       | R2 = Parameters scanned during parse
  245.  
  246. .Parse_String
  247.    STMFD    R13!,{R3-R12,R14}
  248.    MOV      R2,#0                      ;*R2 = Number of parameters
  249.  
  250. .Parse_Leading_Space
  251.    LDRB     R11,[R0],#1                ; R11 = Char
  252.    CMP      R11,#0
  253.    BEQ      Parse_End
  254.    CMP      R11,#" "
  255.    BEQ      Parse_Leading_Space
  256.  
  257. .Parse_Parameter
  258.    LDRB     R11,[R0],#1                ; R11 = Char
  259.    CMP      R11,#0
  260.    BEQ      Parse_End
  261.    ADD      R2,R2,#1                   ; New Parameter (first letter)
  262.    SUBS     R1,R1,#1
  263.    BEQ      Parse_Found                ; Escape if Param is found
  264. .Parse_Parameter_Word
  265.    LDRB     R11,[R0],#1                ; R11 = Char
  266.    CMP      R11,#0
  267.    BEQ      Parse_End
  268.    CMP      R11,#" "
  269.    BNE      Parse_Parameter_Word
  270. .Parse_Parameter_Space
  271.    LDRB     R11,[R0],#1                ; R11 = Char
  272.    CMP      R11,#0
  273.    BEQ      Parse_End
  274.    CMP      R11,#" "
  275.    BEQ      Parse_Parameter_Space
  276.    SUB      R0,R0,#1                   ; R0-> First letter of next parameter
  277.    B        Parse_Parameter
  278.  
  279. .Parse_Found
  280.    SUB      R0,R0,#1                   ; R0-> First letter of parameter
  281.  
  282. .Parse_End
  283.    LDMFD    R13!,{R3-R12,PC}^
  284.  
  285. ; >-------------------------------------------------------------<
  286.  
  287. .Param_Insert_Zero                     ; R0-> Param to zero terminate
  288.    STMFD    R13!,{R0-R1,R14}
  289.  
  290. ._Loop
  291.    LDRB     R1,[R0],#1
  292.    CMP      R1,#0
  293.    BEQ      Param_Insert_Zero_End
  294.    CMP      R1,#" "
  295.    BNE      _Loop
  296.    MOV      R1,#0
  297.    STRB     R1,[R0,#-1]
  298.  
  299. .Param_Insert_Zero_End
  300.    LDMFD    R13!,{R0-R1,PC}^
  301.  
  302. ; >-------------------------------------------------------------<
  303.  
  304. .Param_Remove_Zero                     ; R0-> Param to un-zero terminate
  305.    STMFD    R13!,{R0-R1,R14}
  306.  
  307. ._Loop
  308.    LDRB     R1,[R0],#1
  309.    CMP      R1,#" "
  310.    BEQ      Param_Remove_Zero_End
  311.    CMP      R1,#0
  312.    BNE      _Loop
  313.    MOV      R1,#" "
  314.    STRB     R1,[R0,#-1]
  315.  
  316. .Param_Remove_Zero_End
  317.    LDMFD    R13!,{R0-R1,PC}^
  318.  
  319. ; >-------------------------------------------------------------<
  320.  
  321. .Print_Register                        ; R0 = Value to print
  322.    STMFD    R13!,{R0-R12,R14}
  323.  
  324.    MOV      R9,R0                      ; R9 = Backup copy
  325.    SUB      R1,R13,#256                ; String buffer on stack
  326.    MOV      R2,#32                     ; 32 bytes max
  327.    SWI      OS_ConvertInteger4         ; R0-> String
  328.    SWI      OS_Write0
  329.  
  330.    SWI      OS_WriteS
  331.    DCB      "   [&",0
  332.    ALIGN
  333.  
  334.    MOV      R0,R9                      ; R9 = Backup copy
  335.    SUB      R1,R13,#256                ; String buffer on stack
  336.    MOV      R2,#32                     ; 32 bytes max
  337.    SWI      OS_ConvertHex8             ; R0-> String
  338.    SWI      OS_Write0
  339.    SWI      OS_WriteS
  340.    DCB      "]",0
  341.    ALIGN
  342.  
  343.    SWI      OS_WriteS
  344.    DCB      13,10,0
  345.    ALIGN
  346.  
  347.    LDMFD    R13!,{R0-R12,PC}^
  348.  
  349. ; >-------------------------------------------------------------<
  350.  
  351. .Load_Source
  352.    STMFD    R13!,{R0-R12,R14}
  353.  
  354.    SWI      OS_GetEnv
  355.    MOV      R1,#2
  356.    BL       Parse_String               ;_R0-> Parameter[2]
  357.    MOV      R1,R0                      ;*R1-> Source Filename
  358.    BL       Param_Insert_Zero
  359.  
  360.    STMFD    R13!,{R1}
  361.    MOV      R0,#17
  362.    SWI      XOS_File                   ; R4 = File size
  363.    ADD      R0,R4,#4                   ; Need some chars to NULL-terminate source
  364.    MOV      R1,#0                      ; Flex #0 = Source code
  365.    BL       Flex_Resize
  366.    MOV      R1,#0                      ; Flex #0 = Source code
  367.    BL       Flex_Adr                   ;_R1-> Source block
  368.    MOV      R2,R1                      ;*R2-> Source block
  369.    LDMFD    R13!,{R1}
  370.  
  371.    MOV      R0,#16
  372.    MOV      R3,#0
  373.    SWI      XOS_File
  374.    BLVS     File_Error                 ;\
  375.    BL       Param_Remove_Zero          ; ERROR HANDLING
  376.    BVS      Load_Source_Failed         ;/
  377.  
  378.    ;------> Check source, MUST NOT contain any NULL chars
  379.  
  380.    MOV      R1,#0                      ; Flex #0 = Source code
  381.    BL       Flex_Adr                   ;_R1-> Source block
  382.    MOV      R2,R4
  383. .NULL_Scan_Loop
  384.    SUBS     R2,R2,#1
  385.    BLT      NULL_Scan_End
  386.    LDRB     R0,[R1],#1
  387.    CMP      R0,#&00
  388.    BNE      NULL_Scan_Loop
  389. .NULL_Scan_End                         ; R2 = 0 if there were NO NULL's
  390.    CMP      R2,#0
  391.    BLT      NULL_Terminate
  392.  
  393. .Load_Source_Failed
  394.    MOV      R14,#1                     ;~R14 = Error code (1=Failure)
  395.    LDMFD    R13!,{R0-R12,PC}^
  396.  
  397. .NULL_Terminate
  398.    MOV      R0,#0
  399.    STRB     R0,[R1]
  400.  
  401. .Load_Source_End
  402.    MOV      R14,#0                     ;~R14 = Error code (0=OK)
  403.    LDMFD    R13!,{R0-R12,PC}^
  404.  
  405. ; >-------------------------------------------------------------<
  406.  
  407. .Save_Source
  408.    STMFD    R13!,{R0-R12,R14}
  409.  
  410.    MOV      R1,#0                      ; Flex #0 = Source code
  411.    BL       Flex_Adr                   ;_R1-> Source block
  412.    MOV      R4,R1                      ;*R4-> Start of data
  413.    MOV      R5,R4
  414. ._Loop
  415.    LDRB     R6,[R5,#1]!
  416.    CMP      R6,#0
  417.    BNE      _Loop
  418.  
  419.    SWI      OS_GetEnv
  420.    MOV      R1,#3
  421.    BL       Parse_String               ;_R0-> Parameter[3]
  422.    MOV      R1,R0                      ;*R1-> NewSource Filename
  423.    BL       Param_Insert_Zero
  424.  
  425.    MOV      R0,#10
  426.    MOV      R2,#&FFF
  427.    MOV      R3,#0
  428.    SWI      XOS_File
  429.    BLVS     File_Error                 ;\
  430.    BL       Param_Remove_Zero          ; ERROR HANDLING
  431.    BVS      Save_Source_Failed         ;/
  432.  
  433. .Save_Source_Failed
  434.    MOV      R14,#1                     ;~R14 = Error code (1=Failure)
  435.    LDMFD    R13!,{R0-R12,PC}^
  436.  
  437. .Save_Source_End
  438.    MOV      R14,#0                     ;~R14 = Error code (0=OK)
  439.    LDMFD    R13!,{R0-R12,PC}^
  440.  
  441. ; >-------------------------------------------------------------<
  442.  
  443. .File_Error
  444.    STMFD    R13!,{R0-R1,R14}
  445.  
  446.    ADR      R1,FE_Error
  447.    CMP      R0,#0
  448.    ADREQ    R1,FE_NotFound
  449.    CMP      R0,#2
  450.    ADREQ    R1,FE_DirFound
  451.    MOV      R0,R1
  452.    SWI      OS_Write0
  453.  
  454.    LDMFD    R13!,{R0-R1,PC}^
  455.  
  456. .FE_Error     DCB "File error (not found?)",13,10,0
  457. .FE_NotFound  DCB "File not found",13,10,0
  458. .FE_DirFound  DCB "Filename is a directory",13,10,0
  459.  
  460. ALIGN
  461.  
  462. ; >-------------------------------------------------------------<
  463.  
  464. .Patch_Wildcards_Adr   DCD   0
  465.  
  466. .Patch
  467.    STMFD    R13!,{R0-R12,R14}
  468.  
  469.    ADR      R0,Patch_Instructions
  470. .Patch_Loop
  471.    LDRB     R1,[R0]
  472.    CMP      R1,#1
  473.    LDMEQFD  R13!,{R0-R12,PC}^
  474.    MOV      R1,R0
  475. ._Loop
  476.    LDRB     R9,[R0],#1
  477.    CMP      R9,#0
  478.    BNE      _Loop                       ; End of search instruction
  479.    MOV      R2,R0
  480. ._Loop
  481.    LDRB     R9,[R0],#1
  482.    CMP      R9,#0
  483.    BNE      _Loop                       ; End of replace instruction
  484.    STR      R1,Patch_Search
  485.    STR      R2,Patch_Replace
  486.    BL       Convert
  487.    B        Patch_Loop
  488.  
  489.  
  490. .Convert
  491.    STMFD    R13!,{R0-R12,R14}
  492.  
  493.    MOV      R1,#0                      ; Flex #0 = Original text
  494.    BL       Flex_Locate
  495.    LDR      R0,[R2]                    ; R0 = Block #0 size
  496.    ADD      R0,R0,R0,ASR #2            ; Flex #1 = Patched text (Max 1.5 * size of original)
  497.    ADD      R0,R0,#1024                ; Pluss some extra space
  498.    BL       Flex_Create
  499.    MOV      R0,#1024                   ; Flex #2 = Wildcard strings
  500.    BL       Flex_Create
  501.    STR      R0,Patch_Wildcards_Adr
  502.  
  503.    MOV      R1,#0                      ; Flex #0 = Source code
  504.    BL       Flex_Adr                   ;_R1-> Source block
  505.    MOV      R10,R1                     ;*R10-> Source text
  506.    MOV      R1,#1                      ; Flex #1 = Source code
  507.    BL       Flex_Adr                   ;_R1-> Source block
  508.    MOV      R7,R1                      ;*R7-> Patched text
  509.  
  510. .Convert_Line
  511.    LDR      R11,Patch_Search           ;*R11-> Search string
  512.    LDR      R12,Patch_Replace          ;*R12-> Replace string
  513.    LDRB     R0,[R10],#1
  514.    BL       Skip_Blanks
  515.    LDRB     R1,[R11],#1                ; R1 = First char in search string
  516. .Conv_Search
  517.    CMP      R0,R1
  518.    BLEQ     Conv_Compare
  519.    CMP      R0,#0
  520.    STRNEB   R0,[R7],#1                 ; Write char if NOT NULL (after replace)
  521.    LDRB     R0,[R10],#1                ; R0 = New char
  522.    CMP      R0,#&00
  523.    CMPNE    R0,#&0A
  524.    BNE      Conv_Search
  525.  
  526.    ;------> Next Line
  527.  
  528.    BL       Flush_Line
  529.    STRB     R0,[R7],#1                 ; Write char
  530.    CMP      R0,#&00
  531.    BNE      Convert_Line
  532.  
  533.    ;------> Memory fuck
  534.  
  535.    MOV      R1,#2                      ; Flex #2 = Wildcard strings
  536.    BL       Flex_Delete
  537.    MOV      R1,#0                      ; Flex #0 = Original text
  538.    BL       Flex_Delete
  539.    MOV      R1,#0                      ; Flex #0 = Patched text
  540.    BL       Flex_Adr                   ; R1-> Text
  541.    MOV      R2,R1
  542. ._Loop
  543.    LDRB     R0,[R2],#1
  544.    CMP      R0,#0
  545.    BNE      _Loop
  546.    SUB      R0,R2,R1
  547.    MOV      R1,#0
  548.    BL       Flex_Resize
  549.    LDMFD    R13!,{R0-R12,PC}^
  550.  
  551.  
  552. .Conv_Compare                          ; First character matches
  553.    STMFD    R13!,{R1,R10-R12,R14}
  554.    SUB      R9,R10,#1                  ;*R9-> First char
  555.    LDR      R6,Patch_Wildcards_Adr     ;*R6-> Found wildcards
  556. .CMP_Loop
  557.    LDRB     R1,[R11],#1                ; Next search char
  558.    CMP      R1,#&00
  559.    BEQ      Conv_Replace               ; End of search string, replace!
  560.    LDRB     R2,[R10],#1                ; Next text char
  561.    CMP      R2,#&00
  562.    BEQ      CMP_End                    ; End of text
  563.    CMP      R1,#"*"                    ; String wildcard *
  564.    BNE      CMP_Wild_Single
  565. .CMP_Wild_String
  566.    LDRB     R1,[R11],#1                ; Next search char
  567. .CMPWS_Loop
  568.    CMP      R2,R1
  569.    MOVEQ    R1,#0
  570.    STREQB   R1,[R6],#1                 ; Terminate wildcard string
  571.    BEQ      CMP_Loop                   ; Wildcard string found, continue searching
  572.    STRB     R2,[R6],#1                 ; Extract wildcard string
  573.    LDRB     R2,[R10],#1                ; Next text char
  574.    CMP      R2,#&00                    ; EOL
  575.    CMPNE    R1,#&00                    ; EOT
  576.    LDMEQFD  R13!,{R1,R10-R12,PC}^      ; No match, return - R0 = Entry value
  577.    B        CMPWS_Loop
  578. .CMP_Wild_Single
  579.    CMP      R1,#"?"                    ; Single wildcard ?
  580.    BEQ      CMP_Loop
  581.    CMP      R2,R1
  582.    BEQ      CMP_Loop
  583. .CMP_End
  584.    LDMFD    R13!,{R1,R10-R12,PC}^      ; No match, return
  585.  
  586. .Conv_Replace
  587.    LDR      R11,[R13,#8]               ;*R11-> Second search char
  588.    LDR      R12,[R13,#12]              ;*R12-> First replace char
  589.    LDR      R6,Patch_Wildcards_Adr     ;*R6-> Found wildcards
  590. .REP_Loop
  591.    LDRB     R0,[R12],#1
  592.    CMP      R0,#&00
  593.    LDMEQFD  R13!,{R1,R9,R11,R12,PC}^   ; End of replace string, return  - R10 not popped!
  594.    CMP      R0,#"*"                    ; Replace wildcard ?
  595.    BEQ      REP_Wild_String
  596.    STRB     R0,[R7],#1                 ; Write char
  597.    B        REP_Loop
  598. .REP_Wild_String
  599.    LDRB     R0,[R6],#1
  600.    CMP      R0,#&00
  601.    BEQ      REP_Loop                   ; Wild string done, continue replace
  602.    STRB     R0,[R7],#1
  603.    B        REP_Wild_String  
  604.  
  605. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  606.  
  607. .Skip_Blanks                           ;_R0 = Blankish char or REAL char
  608.    CMP      R0,#" "
  609.    CMPNE    R0,#&09
  610.    STREQB   R0,[R7],#1                 ; Write char
  611.    LDREQB   R0,[R10],#1
  612.    BEQ      Skip_Blanks
  613.    MOVS     PC,R14
  614.  
  615. .Flush_Line
  616.    CMP      R0,#&0A
  617.    CMPNE    R0,#&00
  618.    STRNEB   R0,[R7],#1                 ; Write char
  619.    LDRNEB   R0,[R10],#1
  620.    BNE      Flush_Line
  621.    MOVS     PC,R14
  622.  
  623. ; >-------------------------------------------------------------<
  624. ; >               #####  #      #####  #   #
  625. ; >               #      #      #       # #
  626. ; >               ###    #      ###      #
  627. ; >               #      #      #       # #
  628. ; >               #      #####  #####  #   #
  629. ; >-------------------------------------------------------------<
  630. ; > 00 - 03 | Size of this block (offset to next block)
  631. ; > 04 - ?? | Data
  632.  
  633. .Flex_Status
  634.    STMFD    R13!,{R0-R12,R14}
  635.  
  636.    LDMFD    R13!,{R0-R12,PC}^
  637.  
  638. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  639.  
  640. .Flex_Adr                              ;_R1 = Block number, ~R1-> Block [data]
  641.    STMFD    R13!,{R2-R3,R14}
  642.  
  643.    ADR      R2,Flex_Heap
  644. ._Loop
  645.    CMP      R1,#0
  646.    BLE      FA_Found
  647.    LDR      R3,[R2],#4                 ; Read (and skip) header
  648.    ADD      R2,R2,R3
  649.    SUB      R1,R1,#1
  650.    B        _Loop
  651. .FA_Found                              ;~R2-> Block header
  652.    ADD      R1,R2,#4
  653.  
  654.    LDMFD    R13!,{R2-R3,PC}^
  655.  
  656. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  657.  
  658. .Flex_Locate                           ;_R1 = Block number, ~R2-> Block [header]
  659.    STMFD    R13!,{R1,R3,R14}
  660.  
  661.    ADR      R2,Flex_Heap
  662. ._Loop
  663.    CMP      R1,#0
  664.    BLE      FL_Found
  665.    LDR      R3,[R2],#4                 ; Read (and skip) header
  666.    ADD      R2,R2,R3
  667.    SUB      R1,R1,#1
  668.    B        _Loop
  669. .FL_Found                              ;~R2-> Block header
  670.  
  671.    LDMFD    R13!,{R1,R3,PC}^
  672.  
  673. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  674.  
  675. .Flex_Create                           ;_R0 = Size of new block, ~R0-> New block [data]
  676.    STMFD    R13!,{R1-R12,R14}
  677.  
  678.    TST      R0,#%11                    ; Ensure block is word sized
  679.    BICNE    R0,R0,#%011
  680.    ADDNE    R0,R0,#%100
  681.  
  682.    LDR      R2,Flex_Blocks
  683.    ADR      R1,Flex_Heap
  684. ._Loop
  685.    CMP      R2,#0
  686.    BLE      FC_New
  687.    LDR      R3,[R1],#4                 ; Read (and skip) header
  688.    ADD      R1,R1,R3
  689.    SUB      R2,R2,#1
  690.    B        _Loop
  691. .FC_New                                ; R1-> Free space for new block
  692.    MOV      R10,R0                     ; R10 = Size of new block
  693.    MOV      R11,R1                     ; R11-> New block
  694.    ADD      R12,R1,R0
  695.    ADD      R12,R12,#4                 ; R12-> End of new block (including header)
  696.    SUB      R0,R12,#&8000              ; R0 = Requested slot size
  697.    MVN      R1,#0                      ; R1 = -1, just read
  698.    SWI      Wimp_SlotSize              ; R0 = New slot size ?
  699.    ADD      R0,R0,#&8000               ; R0-> End of new block ?
  700.    CMP      R0,R12
  701.    BLT      FC_Error
  702.    ;------> Now create the block
  703.    LDR      R9,Flex_Blocks
  704.    ADD      R9,R9,#1
  705.    STR      R9,Flex_Blocks     
  706.    STR      R10,[R11],#4               ; Write Size (header)
  707.    MOV      R0,R11                     ;~R0-> Block [data]
  708.    ;------> Clear all data in block
  709.    MOV      R9,#0
  710. ._Loop
  711.    CMP      R10,#0
  712.    BLE      FC_End
  713.    STR      R9,[R11],#4
  714.    SUB      R10,R10,#4
  715.    B        _Loop
  716.  
  717. .FC_Error
  718.    SWI      OS_WriteS
  719.    DCB      "Not enough memory for new Flex block",0
  720.    ALIGN
  721. .FC_End
  722.    LDMFD    R13!,{R1-R12,PC}^
  723.  
  724. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  725.  
  726. .Flex_Resize                           ;_R0 = New size, _R1 = Block number
  727.    STMFD    R13!,{R0-R12,R14}
  728.  
  729.    MOV      R10,R1                     ;*R10 = Block number (to resize)
  730.  
  731.    TST      R0,#%11                    ; Ensure block is word sized
  732.    BICNE    R0,R0,#%011
  733.    ADDNE    R0,R0,#%100
  734.  
  735.    BL       Flex_Locate                ;_R2-> Block   
  736.  
  737.    LDR      R1,[R2]                    ; R1 = Old size
  738.    CMP      R0,R1                      
  739.    BGT      FR_Bigger
  740.    BLT      FR_Smaller
  741.    B        FR_End                     ; Same as before, then don't worry
  742.  
  743. .FR_Bigger                             ; R0 = New size, R1 = Old size, R2-> Block to resize
  744.    ;------> Increase by adding a new bummy block at the end
  745.    LDR      R3,Flex_Blocks             ; R3 = Blocks before dummy
  746.    STMFD    R13!,{R0-R3}
  747.    SUB      R0,R0,R1                   ; R0 = Extra space needed
  748.    MOV      R9,R0                      ;*R9 = Offset to move other blocks with
  749.    SUB      R0,R0,#4                   ; Header also gets space
  750.    BL       Flex_Create
  751.    LDMFD    R13!,{R0-R3}               ; ***** VITAL INFORMATION
  752.    LDR      R4,Flex_Blocks             ; R4 = Blocks after dummy
  753.    CMP      R3,R4
  754.    BEQ      FR_Error                   ; If no extra block, short of memory
  755.    STMFD    R13!,{R0-R2}               ; ***** HERE IT'S PUSHED BACK
  756.    ;------> Extra space is there, now waste dummy block
  757.    SUB      R4,R4,#1
  758.    STR      R4,Flex_Blocks             ; R4 = Blocks when dummy is removed
  759.    ;------> Then move data after current block
  760.    ADD      R1,R10,#1                  ; R1 = Block after current
  761.    BL       Flex_Locate                ;_R2 -> After current block
  762.    MOV      R11,R2                     ;*R11-> After current block
  763.    LDR      R1,Flex_Blocks
  764.    BL       Flex_Locate                ;_R2 -> After last block
  765.    MOV      R12,R2                     ;*R12-> Source, After last block
  766.    SUB      R10,R12,R11                ;*R10 = Number bytes to move
  767.    ADD      R11,R12,R9                 ;*R11-> Destination, After dummy block
  768. ._Loop
  769.    CMP      R10,#0
  770.    BLE      FR_Big_Move
  771.    LDR      R8,[R12,#-4]!
  772.    STR      R8,[R11,#-4]!
  773.    SUB      R10,R10,#4
  774.    B        _Loop
  775. .FR_Big_Move
  776.    ;------> Clear the gap
  777.    MOV      R8,#0
  778. ._Loop
  779.    STR      R8,[R11,#-4]!
  780.    SUBS     R9,R9,#4
  781.    BGT      _Loop
  782.    B        FR_Set_Size
  783.  
  784.  
  785. .FR_Smaller                            ; R0 = New size, R1 = Old size, R2-> Block to resize
  786.    STMFD    R13!,{R0-R2}               ; ***** VITAL INFORMATION
  787.    ;------> Move higher blocks down
  788.    SUB      R9,R1,R0                   ;*R9 = Offset to move other blocks with
  789.    ADD      R1,R10,#1
  790.    BL       Flex_Locate                ;_R2-> Block
  791.    MOV      R11,R2                     ;*R11-> Source, After current block
  792.    LDR      R1,Flex_Blocks
  793.    BL       Flex_Locate                ;_R2-> Block
  794.    MOV      R12,R2                     ;*R12-> After last block
  795.    SUB      R10,R12,R11                ;*R10 = Number bytes to move
  796.    SUB      R12,R11,R9                 ;*R12-> Destination, New location of [current+1] block
  797. ._Loop
  798.    CMP      R10,#0
  799.    BLE      FR_Small_Move
  800.    LDR      R8,[R11],#4
  801.    STR      R8,[R12],#4
  802.    SUB      R10,R10,#4
  803.    B        _Loop
  804. .FR_Small_Move                         ; R12-> After last byte needed
  805.    ;------> Now set slotsize down
  806.    SUB      R0,R12,#&8000              ; R0 = Required slot size
  807.    MVN      R1,#0                      ; R1 = -1, just read
  808.    SWI      Wimp_SlotSize              ; R0 = New slot size ?
  809.    B        FR_Set_Size
  810.  
  811.  
  812. .FR_Error
  813.    SWI      OS_WriteS
  814.    DCB      "Not enough memory to resize block",0
  815.    ALIGN
  816.    LDMFD    R13!,{R0-R12,PC}^
  817.  
  818. .FR_Set_Size
  819.    LDMFD    R13!,{R0-R2}
  820.    STR      R0,[R2]                    ; Set New block size
  821. .FR_End
  822.    LDMFD    R13!,{R0-R12,PC}^
  823.  
  824. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  825.  
  826. .Flex_Delete                           ; R1 = Block number to delete
  827.    STMFD    R13!,{R0-R12,R14}
  828.  
  829.    MOV      R10,R1
  830.    ADD      R1,R10,#1
  831.    BL       Flex_Locate                ;_R2-> Block after the one to delete
  832.    LDR      R11,[R2]                   ;_R11 = Size of next block
  833.  
  834.    MOV      R1,R10
  835.    MOV      R0,#-4
  836.    BL       Flex_Resize
  837.  
  838.    ;------> Remove block, one less
  839.    LDR      R4,Flex_Blocks
  840.    SUB      R4,R4,#1
  841.    STR      R4,Flex_Blocks
  842.  
  843.    MOV      R1,R10                     ; R1 = Next block
  844.    SUB      R2,R4,#1                   ; R2 = Last block
  845.    CMP      R1,R4
  846.    BGT      FD_End
  847.    BL       Flex_Locate                ;_R2-> Block after the one deleted
  848.    STR      R11,[R2]                   ; Set size, destroyed in previous resize...    
  849.  
  850. .FD_End
  851.    LDMFD    R13!,{R0-R12,PC}^
  852.  
  853. ; >-------------------------------------------------------------<
  854.  
  855. .Core_Dump
  856.    MVN      R0,#0
  857.    MVN      R1,#0
  858.    SWI      Wimp_SlotSize
  859.    ADD      R5,R0,#&8000
  860.  
  861.    MOV      R0,#0
  862.    ADR      R1,Core_File
  863.    MOV      R2,#&8000
  864.    MOV      R3,#&8000
  865.    MOV      R4,#&8000
  866.    SWI      XOS_File
  867.    SWI      XOS_WriteS
  868.    DCB      13,10,13,10
  869.    DCB      "Core dumped",13,10,13,10,0
  870.    ALIGN
  871.    SWI      XOS_Exit
  872.  
  873. .Core_File
  874.    DCB      "CORE",0
  875.    ALIGN
  876. .Flex_Blocks   DCD   0
  877.    DCB      "HEAP"
  878.  
  879. ; >-------------------------------------------------------------<
  880.  
  881.  
  882. .Flex_Heap
  883.