fastspin Basic simple stuff
in Propeller 1
This is really straight forward stuff, or so I thought. When I run the program I expect the LED to turn on, it does not. When I add the pausems 4000, then the LED stays on for four seconds, and turns off. What do you have to do too keep the LED on, and then give it another command to turn it off.
Ray
Ray
const pin = 26
direction(pin) = output
output(pin) = 1 ' LED turns on.
'pausems 4000
Comments
You can add an empty
do : loop
to keep the cog twiddle its thumbs forever.Not sure if I could tweak the code, and besides if you did tweak it, how would you be able to run the tweaked code.
Ray
con pin = 26 pub main coginit(0, @entry, 0) dat org 0 entry mov arg01, par wz call #_program cogexit cogid arg01 cogstop arg01 _program or dira, imm_67108864_ or outa, imm_67108864_ _program_ret ret imm_67108864_ long 67108864 COG_BSS_START fit 496 hubexit jmp #cogexit org COG_BSS_START arg01 res 1 fit 496
Ray
print "hello!"
pub main coginit(0, @entry, 0) dat org 0 entry mov arg01, par wz call #_program cogexit cogid arg01 cogstop arg01 _program mov arg02, ptr_L__0023_ mov arg01, #0 mov arg03, #0 call #__system___basic_print_string mov arg01, #0 call #__system___basic_print_nl _program_ret ret ' '' ' pri _gc_ptrs | base, end, size __system___tx mov __system___tx_val, arg01 ' base := @_gc_heap_base rdlong __system___tx_bitcycles, ptr___system__dat__ ' end := base + __real_heapsize__ or outa, imm_1073741824_ ' if (long[base] == 0) or dira, imm_1073741824_ ' size := end - base or __system___tx_val, #256 shl __system___tx_val, #1 ' word[base + OFF_SIZE] := 1 mov __system___tx_nextcnt, cnt ' word[base + OFF_FLAGS] := GC_MAGIC | GC_FLAG_RESERVED mov __system___tx__idx__90001, #10 LR__0001 ' word[base + OFF_PREV] := 0 add __system___tx_nextcnt, __system___tx_bitcycles mov arg01, __system___tx_nextcnt ' {{ waitcnt arg01, #0 ' word[base + OFF_LINK] := 1 shr __system___tx_val, #1 wc muxc outa, imm_1073741824_ ' base += pagesize djnz __system___tx__idx__90001, #LR__0001 __system___tx_ret ret ' ' pri _gc_isFree(ptr) __system___call_method ' return word[ptr + OFF_FLAGS] == GC_MAGIC + GC_FLAG_FREE wrlong objptr, sp add sp, #4 mov objptr, arg01 mov arg01, arg03 call arg02 sub sp, #4 rdlong objptr, sp ' lastptr := ptr __system___call_method_ret ret ' free the memory pointed to by "ptr" and re-allocate it for other purposes. __system____builtin_strlen ' mov _var01, #0 ' There's also a _gc_alloc_managed call which is like a combination of LR__0002 rdbyte _var02, arg01 wz ' _gc_alloc followed immediately by _gc_manage. if_ne add _var01, #1 ' if_ne add arg01, #1 if_ne jmp #LR__0002 mov result1, _var01 __system____builtin_strlen_ret ret ' word[base + OFF_FLAGS] := GC_MAGIC | GC_FLAG_FREE ' word[base + OFF_PREV] := 0 __system___basic_print_char mov __system___basic_print_char_h, arg01 mov __system___basic_print_char_c, arg02 mov __system___basic_print_char_fmt, arg03 ' word[base + OFF_LINK] := 0 mov _system___basic_print_char_tmp001_, __system___basic_print_char_h shl _system___basic_print_char_tmp001_, #2 add ptr___system__dat__, #12 mov _system___basic_print_char_tmp002_, ptr___system__dat__ add _system___basic_print_char_tmp001_, _system___basic_print_char_tmp002_ rdlong __system___basic_print_char_t, _system___basic_print_char_tmp001_ wz ' base -= pagesize ' return (base, end) sub ptr___system__dat__, #12 if_e jmp #__system___basic_print_char_ret ' rdlong __system___basic_print_char_o, __system___basic_print_char_t ' { return a pointer to page i in the heap } add __system___basic_print_char_t, #4 rdlong __system___basic_print_char_f, __system___basic_print_char_t wz ' pri _gc_pageptr(heapbase, i) if_ne jmp #LR__0003 ' if (i == 0) mov arg01, __system___basic_print_char_c call #__system___tx ' return 0 jmp #LR__0004 LR__0003 ' return heapbase + (i << pagesizeshift) mov arg01, __system___basic_print_char_o mov arg02, __system___basic_print_char_f mov arg03, __system___basic_print_char_c call #__system___call_method LR__0004 __system___basic_print_char_ret ret ' pri _gc_nextBlockPtr(ptr) ' return ptr + (word[ptr + OFF_SIZE] << pagesizeshift) __system___basic_print_string mov __system___basic_print_string_h, arg01 mov __system___basic_print_string_ptr, arg02 mov __system___basic_print_string_fmt, arg03 ' mov __system___basic_print_string_w, __system___basic_print_string_fmt and __system___basic_print_string_w, #255 ' pri _gc_tryalloc(size, reserveflag) | ptr, availsize, lastptr, nextptr, heap_base, heap_end, saveptr, linkindex mov __system___basic_print_string_justify, __system___basic_print_string_fmt shr __system___basic_print_string_justify, #8 and __system___basic_print_string_justify, #3 ' (heap_base, heap_end) := _gc_ptrs mov arg01, __system___basic_print_string_ptr call #__system____builtin_strlen mov _system___basic_print_string_tmp002_, result1 mov __system___basic_print_string_len, _system___basic_print_string_tmp002_ ' ptr := heap_base mov __system___basic_print_string_wright, #0 mov __system___basic_print_string_wleft, #0 ' repeat cmps __system___basic_print_string_w, #0 wc,wz if_be jmp #LR__0011 cmps __system___basic_print_string_len, __system___basic_print_string_w wc,wz if_ae jmp #LR__0011 ' lastptr := ptr cmp __system___basic_print_string_justify, #0 wz if_ne jmp #LR__0005 ' ptr := _gc_pageptr(heap_base, word[ptr+OFF_LINK]) mov _system___basic_print_string_tmp001_, __system___basic_print_string_w sub _system___basic_print_string_tmp001_, __system___basic_print_string_len mov __system___basic_print_string_wright, _system___basic_print_string_tmp001_ jmp #LR__0008 LR__0005 ' availsize := word[ptr+OFF_SIZE] cmp __system___basic_print_string_justify, #1 wz if_ne jmp #LR__0006 ' while ptr and size > availsize mov _system___basic_print_string_tmp001_, __system___basic_print_string_w sub _system___basic_print_string_tmp001_, __system___basic_print_string_len mov __system___basic_print_string_wleft, _system___basic_print_string_tmp001_ ' jmp #LR__0007 LR__0006 ' if (ptr == 0) mov _system___basic_print_string_tmp001_, __system___basic_print_string_w sub _system___basic_print_string_tmp001_, __system___basic_print_string_len abs __system___basic_print_string_wleft, _system___basic_print_string_tmp001_ wc shr __system___basic_print_string_wleft, #1 if_b neg __system___basic_print_string_wleft, __system___basic_print_string_wleft ' return ptr mov _system___basic_print_string_tmp002_, __system___basic_print_string_w sub _system___basic_print_string_tmp002_, __system___basic_print_string_len mov _system___basic_print_string_tmp001_, _system___basic_print_string_tmp002_ sub _system___basic_print_string_tmp001_, __system___basic_print_string_wleft mov __system___basic_print_string_wright, _system___basic_print_string_tmp001_ LR__0007 LR__0008 ' ' linkindex := word[ptr + OFF_LINK] LR__0009 cmps __system___basic_print_string_wleft, #0 wc,wz if_be jmp #LR__0010 ' mov _system___basic_print_string_tmp002_, #32 mov _system___basic_print_string_tmp003_, #0 mov arg01, __system___basic_print_string_h mov arg02, #32 mov arg03, #0 call #__system___basic_print_char ' '' carve off free space if necessary mov _system___basic_print_string_tmp001_, __system___basic_print_string_wleft sub _system___basic_print_string_tmp001_, #1 mov __system___basic_print_string_wleft, _system___basic_print_string_tmp001_ jmp #LR__0009 LR__0010 LR__0011 ' if (size < availsize) cmp __system___basic_print_string_w, #0 wz ' '' shrink this block, link to newly created block if_e mov __system___basic_print_string_w, imm_65535_ ' word[ptr + OFF_SIZE] := size LR__0012 rdbyte __system___basic_print_string_c, __system___basic_print_string_ptr wz add __system___basic_print_string_ptr, #1 if_e jmp #LR__0013 cmps __system___basic_print_string_w, #0 wc,wz if_be jmp #LR__0013 ' nextptr := ptr + (size<<pagesizeshift) mov _system___basic_print_string_tmp002_, __system___basic_print_string_c mov _system___basic_print_string_tmp003_, #0 mov arg01, __system___basic_print_string_h mov arg02, _system___basic_print_string_tmp002_ mov arg03, #0 call #__system___basic_print_char ' word[nextptr + OFF_SIZE] := availsize - size mov _system___basic_print_string_tmp001_, __system___basic_print_string_w sub _system___basic_print_string_tmp001_, #1 mov __system___basic_print_string_w, _system___basic_print_string_tmp001_ jmp #LR__0012 LR__0013 ' word[nextptr + OFF_FLAGS] := GC_MAGIC | GC_FLAG_FREE LR__0014 cmps __system___basic_print_string_wright, #0 wc,wz if_be jmp #LR__0015 ' word[nextptr + OFF_PREV] := _gc_pageindex(heap_base, ptr) mov arg01, __system___basic_print_string_h mov arg02, #32 mov arg03, #0 call #__system___basic_print_char ' word[nextptr + OFF_LINK] := word[ptr + OFF_LINK] sub __system___basic_print_string_wright, #1 jmp #LR__0014 LR__0015 ' '' advance to next in chain __system___basic_print_string_ret ret ' ' internal routine for freeing a block of memory ' ' ptr points to the start of the block __system___basic_print_nl ' ' returns a pointer to the next non-free block(useful for mov __system___basic_print_nl_h, arg01 mov arg02, #13 mov arg03, #0 call #__system___basic_print_char ' ' garbage collection, to handle cases where memory is coalesced) mov arg01, __system___basic_print_nl_h mov arg02, #10 mov arg03, #0 call #__system___basic_print_char __system___basic_print_nl_ret ret imm_1073741824_ long 1073741824 imm_65535_ long 65535 objptr long @@@objmem ptr_L__0023_ long @@@LR__0016 ptr___system__dat__ long @@@__system__dat_ result1 long 0 sp long @@@stackspace COG_BSS_START fit 496 hubexit jmp #cogexit LR__0016 byte "hello!" byte 0 long __system__dat_ '-' '' the heap byte $b6, $02, $00, $00 '-' OFF_SIZE = 0 '-' OFF_FLAGS = 2 '-' OFF_PREV = 4 byte $00, $00, $00, $00 '-' OFF_LINK = 6 byte $00, $00, $00, $00 '-' '-' ' special offsets for block 0 '-' OFF_USED_LINK = 8 '-' '-' ' magic constant added to pointers so we can spot them '-' ' more easily '-' POINTER_MAGIC = $63800000 long @@@__system__dat_ + 4 '-' POINTER_MAGIC_MASK = $fff00000 byte $00[28] '-' __real_heapsize__ = 256 ' redefined based on user options '-' long @@@__system__dat_ + 4 '-' dat byte $00[28] '-' long '-' _gc_heap_base byte $00[32] '-' long '-' _gc_heap_base '-' byte 0[__real_heapsize__] byte $00[256] objmem long 0[0] stackspace long 0[1] org COG_BSS_START __system___basic_print_char_c res 1 __system___basic_print_char_f res 1 __system___basic_print_char_fmt res 1 __system___basic_print_char_h res 1 __system___basic_print_char_o res 1 __system___basic_print_char_t res 1 __system___basic_print_nl_h res 1 __system___basic_print_string_c res 1 __system___basic_print_string_fmt res 1 __system___basic_print_string_h res 1 __system___basic_print_string_justify res 1 __system___basic_print_string_len res 1 __system___basic_print_string_ptr res 1 __system___basic_print_string_w res 1 __system___basic_print_string_wleft res 1 __system___basic_print_string_wright res 1 __system___tx__idx__90001 res 1 __system___tx_bitcycles res 1 __system___tx_nextcnt res 1 __system___tx_val res 1 _system___basic_print_char_tmp001_ res 1 _system___basic_print_char_tmp002_ res 1 _system___basic_print_string_tmp001_ res 1 _system___basic_print_string_tmp002_ res 1 _system___basic_print_string_tmp003_ res 1 _var01 res 1 _var02 res 1 arg01 res 1 arg02 res 1 arg03 res 1 fit 496
void arm_mic_a() { DIRA |= 0 << mic_a_pin; // Set to input CTRA = (0b01110 << 26) + mic_a_pin; // Set CTRA to NegEdge mode FRQA = 1; // Adds 1 to PHSA on each rising edge while (PHSA == 0); // Wait for negedge on mic A mic_a_cnt = CNT; }
which generates002e0 0b0 | _arm_mic_a 002e0 0b0 00 A4 FD A0 | mov _var01, #0 002e4 0b1 F4 56 FD 80 | add ptr__dat__, #244 002e8 0b2 AB A6 BD 08 | rdlong _var02, ptr__dat__ 002ec 0b3 D3 A4 BD 2C | shl _var01, _var02 002f0 0b4 D2 EC BF 68 | or dira, _var01 002f4 0b5 A2 A8 BD A0 | mov _var03, imm_939524096_ 002f8 0b6 F4 56 FD 84 | sub ptr__dat__, #244 002fc 0b7 D3 A8 BD 80 | add _var03, _var02 00300 0b8 D4 F0 BF A0 | mov ctra, _var03 00304 0b9 01 F4 FF A0 | mov frqa, #1 00308 0ba 44 AE FC 5C | call #LMM_FCACHE_LOAD 0030c 0bb 08 00 00 00 | long (@@@LR__0002-@@@LR__0001) 00310 0bc | ' { 00310 0bc | ' _DIRA |= 0 << mic_a_pin; 00310 0bc | ' 00310 0bc | ' _CTRA = (0b01110 << 26) + mic_a_pin; 00310 0bc | ' _FRQA = 1; 00310 0bc | ' while ( _PHSA == 0); 00310 0bc 00310 0bc | LR__0001 00310 0bc 00 F8 7F 86 | cmp phsa, #0 wz 00314 0bd EA 00 68 5C | if_e jmp #LMM_FCACHE_START + (LR__0001 - LR__0001) 00318 0be 00318 0be | LR__0002 00318 0be F1 AB BD A0 | mov _var04, cnt 0031c 0bf D4 56 FD 80 | add ptr__dat__, #212 00320 0c0 AB AA 3D 08 | wrlong _var04, ptr__dat__ 00324 0c1 D4 56 FD 84 | sub ptr__dat__, #212 00328 0c2 00328 0c2 | _arm_mic_a_ret 00328 0c2 3C 86 FC 5C | call #LMM_RET
Works wonderfully with sub microsecond resolution though the counter takes care of that, to be fair.Mike R.
Fits using LMM:
$ fastspin mandelbrot-float-using-printf.c Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc. Version 3.9.26-beta-dbdaa382 Compiled on: Apr 28 2019 mandelbrot-float-using-printf.c mandelbrot-float-using-printf.pasm Done. Program size is 3240 bytes
Error with "--code=cog":$ fastspin --code=cog mandelbrot-float-using-printf.c Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc. Version 3.9.26-beta-dbdaa382 Compiled on: Apr 28 2019 mandelbrot-float-using-printf.c mandelbrot-float-using-printf.pasm mandelbrot-float-using-printf.pasm(616) error: fit 496 failed: pc is 501 mandelbrot-float-using-printf.pasm(827) error: fit 496 failed: pc is 597 Done.
The problem with BASIC's "print" has a different flavour.
Let's ask the master: @ersmith ;-)
Yes, most certainly he'll know.
Mike R.
Yes. Actually any attempt to call a function through a pointer will fail with --code=cog on P1. I don't think I will fix that, but I will add an error. (The root cause is the calling convention for COG code; on P1 doing "call #foo" actually generates "jmpret foo_ret, #foo". This doesn't support indirect calls. It is possible to generate the "jmpret" directly, but it would have to be done for all functions and would make the COG code a lot less readable, and it's an edge case (--code=cog isn't really practical for BASIC code anyway).
Getting a hint what's going on will be enough in this context.
$ cat hw.bas print"Hello, world!" $ fastspin hw.bas --code=cog Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc. Version 3.9.26-beta-d6b911c3 Compiled on: May 1 2019 hw.bas warning: : indirect function calls are not supported in COG mode hw.pasm hw.pasm(286) error: Unknown symbol arg02_ret Done.
That warning really helps... \o/Thanks!