Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
amiga:development_environments:basic:amos_professional:extension_development [2023/02/04 21:47] Topazamiga:development_environments:basic:amos_professional:extension_development [2024/03/18 21:15] (current) Topaz
Line 1: Line 1:
 # AMOS Professional Extension Development # AMOS Professional Extension Development
 +
 +[[amiga:development_environments:basic:amos_professional|AMOS Professional]] extensions are written in [[m68k:development:m68k_assembly_language|Motorola 68000 Assembly Language]]. 
  
 ## Original Notes ## Original Notes
Line 64: Line 66:
 When you want to demand string space, you apply for it with `L_Demande`. When you want to demand string space, you apply for it with `L_Demande`.
  
-The requested length goes into D3. It does not have to be even. You get the base address in both A0 and A1.+The requested length goes into D3. It has to be even. You get the base address in both A0 and A1.
  
 This is an AMOS string, so the first two bytes are the size of the string as a word. Then the string comes after. This is an AMOS string, so the first two bytes are the size of the string as a word. Then the string comes after.
  
-Then, you have to eventually hand `HiChaine(A5)` (be sure to preserve A5) the ending address of the string, rounded up to the nearest 2. I guess this is so it can be tracked in the garbage collector.+Then, you have to eventually hand `HiChaine(A5)` (be sure to preserve A5) the ending address of the string.
  
 Make sure you don't try to allocate a zero width string with this! It will fail hard. Make sure you don't try to allocate a zero width string with this! It will fail hard.
Line 95: Line 97:
  and.w #$0001,d1 ; keep the lowest bit  and.w #$0001,d1 ; keep the lowest bit
  add.w d1,a1 ; add the current address to a1  add.w d1,a1 ; add the current address to a1
- move.l a1,HiChaine(a5) ; mark our completed string+ move.l a1,HiChaine(a5) ; update the high end of string memory
  moveq #2,d2  moveq #2,d2
  rts  rts
Line 101: Line 103:
  moveq #2,d2  moveq #2,d2
  rts  rts
 +```
 +
 +Here's a better version:
 +
 +```asm
 +    ; D4 contains your string length
 +    MOVE.L D4,D3
 +    AND.W #$FFFE,D3
 +    ADDQ #2,D3 ; round up to the nearest 2
 +
 +    Rjsr L_Demande ; string is in A0/A1
 +    LEA 2(A0,D3.W),A1
 +    MOVE.L A1,HiChaine(A5)
 +    MOVE.L A0,A1 ; put A1 back
 +    MOVE.W D4,(A0)+ ; put length of string at start of memory
 +.stringstuff
 +    MOVE.B (A2)+,(A0)+
 +    BNE .stringstuff ; copy until null terminator
 +```
 +
 +You know your string code is working if you can do this:
 +
 +```basic
 +A$=My String Function$ ' returns "wow"
 +Print "cat" + A$ + "dog" ' "catwowdog"
 ``` ```
  
Line 153: Line 180:
 * You don't seem to be able to `INCLUDE` a file that contains `Lib_Def` code. * You don't seem to be able to `INCLUDE` a file that contains `Lib_Def` code.
 * If you discovered you had been unwinding stacks incorrectly or anything else that could screw AMOS up, just reboot. * If you discovered you had been unwinding stacks incorrectly or anything else that could screw AMOS up, just reboot.
 +* **Don't use A5 for stuff!** Unless you put it back right away. That's where extension memory is located.
 +
 +---
 +
 +## How-Tos
 +
 +### Add a new command to be used in the Editor
 +
 +These use a bunch of macros I built for the BSD Socket extension:
 +
 +* Add a new function definition to the token table:
 +
 +```asm
 +C_Tk dc.w 1,0
 +;...
 +  ; if something that accepts parameters and returns a value
 +  AddTokenFunction MyNewFunction
 +  dc.b "my new functio","n"+$80,"00,0",-1
 +  
 +  ; if something that returns nothing and just has side effects
 +  AddTokenInstruction MyNewInstruction
 +  dc.b "my new instructio"."n"+$80,"I",-1
 +```
 +
 +* Add a new `Lib_Par` section to the bottom of the file
 +
 +```asm
 +  Lib_Par MyNewFunction
 +  
 +  PreserveStackFunction
 +  RestoreStackFunction
 +  Ret_Int
 +```
 +
 +* For functions with more than one parameter, peel off the parameters from `A3` in reverse order:
 +
 +```asm
 +  ; takes four parameters
 +  Lib_Par MyNewFunction
 +  
 +  PreserveStackFunction
 +  
 +  MOVE.L D3,D4 ; last parameter
 +  MOVE.L (A3)+,D3 ; second-to-last
 +  MOVE.L (A3)+,D2 ; second-to-first
 +  MOVE.L (A3)+,D1 ; first
 +  
 +  RestoreStackFunction
 +  Ret_Int
 +```
 +
 +* If returning an integer, put it in `D3`:
 +
 +```asm
 +  Lib_Par MyNewFunction
 +  
 +  PreserveStackFunction
 +  MOVE.L (A0),D3 ; return value
 +  RestoreStackFunction
 +  Ret_Int
 +```