If you're using CoC with NeoVim, you can enable a 68k Language Server Protocol server running in Node: https://github.com/grahambates/m68k-lsp
# install the language server npm i -g m68k-lsp-server # configure CoC to use the LSP :CocConfig # add to the JSON file: "languageserver": { "m68k": { "command": "m68k-lsp-server", "args": ["--stdio"], "filetypes": ["asm"], "rootPatterns": ["*.s"] } # if you're using ALE as well as CoC, ALE may complain, like a lot about the file. # I think ALE thinks it's x86 assembler. Disable ALE on that buffer: :ALEDisableBuffer
Now you can get docstrings and instruction reference:
You can set a “breakpoint” in code by triggering a memory write to a safe area of memory (https://eab.abime.net/showpost.php?p=899516&postcount=6). This will trigger the debugger at that point in code.
In your code:
; code before breakpoint CLR.W $100 ; write two zero bytes to $100 ; code you want to verify
Then, in WinUAE/FS-UAE, set a memory watchpoint. This creates watchpoint 0, looking at $100, waiting for two bytes to be written. In your user code (at least in AMOS extensions), nothing else will be writing here.
w 0 100 2
Start the code executing again with g
and UAE will break when it hits your CLR.W
.
For actually debugging:
z
for stepping forward one instruction
Remove the memory watchpoint with w 0
.
This also works in C:
int main(void) { static volatile short *debug = (volatile short*) 0x100; int a; a = 1; *(debug) = 0; a = 2; return 0; }
CUSTOM EQU $DFF000 ; bad, better reboot the Amiga MOVE.L CUSTOM,A0 MOVE.L CopperlistPointer,cop1lc(A0) ; good MOVE.L #CUSTOM,A0 MOVE.L CopperlistPointer,cop1lc(A0)
* Watch for address register usage when looking at code from other sources!
MOVE.W #$2c21,diwstrt(A0) MOVE.W #$2cc1,diwstop(A0) MOVE.W #$0038,ddfstrt(A1) ; uh oh MOVE.W #$00d0,ddfstop(A1)
The default size seems to be word, so MOVE
and MOVE.W
seem to be equivalent.
If you want to shift a high bit from one thing onto the low bit of another, ASL
, will shift off the top bit into the carry flag without wrapping it back around. Unlike 6502 assembler, ROL
will not use the carry flag. You have to do that yourself:
MOVE.L #$ffffffff,D0 MOVE.L #$1,D1 ASL.L #1,D0 SCS D2 AND.L #$1,D2 ROL.L #1,D1 ; D1 is now 2 ADD.L D2,D1 ; D1 is now 3
A bit more work than DIVU
but it allows you to work with longs. Based on finally figuring out multiplying and dividing on the 6502.
START: MOVE.L #31,D4 loop: ASL.L #1,number SCS D2 AND.L #1,D2 ROL.L #1,remainder ADD.L D2,remainder MOVE.L remainder,D3 SUB.L divisor,D3 BMI keep_going ADD.L #1,number MOVE.L D3,remainder keep_going: DBRA D4, loop move.l number,d4 ; 2 move.l remainder,d5 ; 500000 RTS number: dc.l 2500000 divisor: dc.l 1000000 remainder: dc.l 0
Remember that DBcc
checks for the condition both before and after the decrement! This is a very likely source of off-by-one errors if you get it wrong, so be mindful!
\@
in the macro code to expand to _<current macro usage number>
.CNOP 0,4
.