dat 00000 000 org 0 00000 000 entry 00000 000 f20ff000 cmp ptra, #0 wz 00004 001 5d900014 if_ne jmp #spininit 00008 002 f603f030 mov ptra, ptr_stackspace_ 0000c 003 fd65fe00 hubset #255 00010 004 fdc0042c calla #@_program 00014 005 cogexit 00014 005 fd607601 cogid arg1 00018 006 fd607603 cogstop arg1 0001c 007 spininit 0001c 007 fb045700 rdlong objptr, ptra 00020 008 f107f004 add ptra, #4 00024 009 fb046300 rdlong result1, ptra 00028 00a f107f004 add ptra, #4 0002c 00b fd60622e calla result1 00030 00c fd9fffe0 jmp #cogexit 00034 00d multiply_ 00034 00d f600544e mov itmp2_, muldiva_ 00038 00e f560544f xor itmp2_, muldivb_ 0003c 00f f6409c4e abs muldiva_, muldiva_ 00040 010 f6409e4f abs muldivb_, muldivb_ 00044 011 fd009c4f qmul muldiva_, muldivb_ 00048 012 fd609c18 getqx muldiva_ 0004c 013 fd609e19 getqy muldivb_ 00050 014 f04c541f shr itmp2_, #31 wz 00054 015 56609e4f if_nz neg muldivb_, muldivb_ 00058 016 56689c4e if_nz neg muldiva_, muldiva_ wz 0005c 017 51849e01 if_nz sub muldivb_, #1 00060 018 fd64002e reta 00064 019 unsdivide_ 00064 019 fd640028 setq #0 00068 01a fd109c4f qdiv muldiva_, muldivb_ 0006c 01b fd609e18 getqx muldivb_ 00070 01c fd609c19 getqy muldiva_ 00074 01d fd64002e reta 00078 01e divide_ 00078 01e f6509c4e abs muldiva_,muldiva_ wc 'abs(x) 0007c 01f f5845403 muxc itmp2_,#%11 'store sign of x 00080 020 f6589e4f abs muldivb_,muldivb_ wcz 'abs(y) 00084 021 c5645402 if_c xor itmp2_,#%10 'store sign of y 00088 022 fdbfffd8 call #unsdivide_ 0008c 023 f7d45401 test itmp2_,#1 wc 'restore sign, remainder 00090 024 f6809c4e negc muldiva_,muldiva_ 00094 025 f7d45402 test itmp2_,#%10 wc 'restore sign, division result 00098 026 f6809e4f negc muldivb_,muldivb_ 0009c 027 fd64002e reta 000a0 028 fp 000a0 028 00000000 long 0 000a4 029 itmp1_ 000a4 029 00000000 long 0 000a8 02a itmp2_ 000a8 02a 00000000 long 0 000ac 02b objptr 000ac 02b 000015a8 long @objmem 000b0 02c ptr_L__0130_ 000b0 02c 00001428 long @LR__0061 000b4 02d ptr_L__0131_ 000b4 02d 00001437 long @LR__0062 000b8 02e ptr_L__0132_ 000b8 02e 0000143b long @LR__0063 000bc 02f ptr___system__dat__ 000bc 02f 00001440 long @__system__dat_ 000c0 030 ptr_stackspace_ 000c0 030 000015b0 long @stackspace 000c4 031 result1 000c4 031 00000000 long 0 000c8 032 result2 000c8 032 00000000 long 0 000cc 033 COG_BSS_START 000cc 033 fit 496 00400 orgh $400 00400 04c4b400 long 80000000 00404 00000064 long 100 00408 hubentry ' ' sub getlabelvals() 00408 _getlabelvals ' asm 00408 fe90001c loc pa, #@label 0040c fea00428 loc pb, #\@label 00410 f6006df6 mov _var_00, pa 00414 f6006ff7 mov _var_01, pb ' paval = x 00418 fc606c2b wrlong _var_00, objptr ' pbval = y 0041c f1045604 add objptr, #4 00420 fc606e2b wrlong _var_01, objptr 00424 f1845604 sub objptr, #4 ' label: 00428 label 00428 _getlabelvals_ret 00428 fd64002e reta 0042c _program ' ' pausems 1000 0042c ff000001 mov arg1, ##1000 00430 f60477e8 00434 fdd005e4 calla #@__system__pausems 00438 f600782c mov arg2, ptr_L__0130_ 0043c f6047600 mov arg1, #0 00440 f6047a00 mov arg3, #0 00444 fdd00194 calla #@__system___basic_print_string 00448 f6047600 mov arg1, #0 0044c fdd005a8 calla #@__system___basic_print_nl ' getlabelvals 00450 fddfffb4 calla #@_getlabelvals 00454 f600782d mov arg2, ptr_L__0131_ 00458 f6047600 mov arg1, #0 0045c f6047a00 mov arg3, #0 00460 fdd00178 calla #@__system___basic_print_string 00464 fb00782b rdlong arg2, objptr 00468 f6047600 mov arg1, #0 0046c f6047a00 mov arg3, #0 00470 f6047c0a mov arg4, #10 00474 fdd00500 calla #@__system___basic_print_unsigned 00478 f600782e mov arg2, ptr_L__0132_ 0047c f6047600 mov arg1, #0 00480 f6047a00 mov arg3, #0 00484 fdd00154 calla #@__system___basic_print_string 00488 f6047600 mov arg1, #0 0048c f6047809 mov arg2, #9 00490 fdd000dc calla #@__system___basic_print_char 00494 f1045604 add objptr, #4 00498 fb00782b rdlong arg2, objptr 0049c f1845604 sub objptr, #4 004a0 f6047600 mov arg1, #0 004a4 f6047a00 mov arg3, #0 004a8 f6047c0a mov arg4, #10 004ac fdd004c8 calla #@__system___basic_print_unsigned 004b0 f6047600 mov arg1, #0 004b4 fdd00540 calla #@__system___basic_print_nl 004b8 _program_ret 004b8 fd64002e reta 004bc hubexit 004bc fd800005 jmp #cogexit ' OFF_LINK = 6 004c0 __system___tx 004c0 fc648161 wrlong local01, ptra++ 004c4 fc648361 wrlong local02, ptra++ 004c8 fc648561 wrlong local03, ptra++ 004cc ff200000 mov local01, ##1073741824 004d0 f6048000 ' 004d4 ff200000 or dirb, ##1073741824 004d8 f547f600 ' ' special offsets for block 0 004dc ff200000 or outb, ##1073741824 004e0 f547fa00 ' OFF_USED_LINK = 8 004e4 f600823b mov local02, arg1 004e8 f5448300 or local02, #256 004ec f0648201 shl local02, #1 ' ' 004f0 fd60621a getct result1 ' Allocate memory with "ptr = _gc_alloc(size)" 004f4 f6008431 mov local03, result1 ' ' magic constant added to pointers so we can spot them 004f8 fcdc0c0a rep @LR__0002, #10 004fc LR__0001 ' ' more easily 004fc ff000001 add local03, ##694 00500 f10484b6 00504 f6007642 mov arg1, local03 ' initial reference is from COG memory we do not want to accidentally 00508 fa647600 addct1 arg1, #0 0050c fd602224 waitct1 ' POINTER_MAGIC = $63800000 00510 f0548201 shr local02, #1 wc 00514 f583fa40 muxc outb, local01 ' POINTER_MAGIC_MASK = $fff00000 00518 LR__0002 00518 fb04855f rdlong local03, --ptra 0051c fb04835f rdlong local02, --ptra 00520 fb04815f rdlong local01, --ptra 00524 __system___tx_ret 00524 fd64002e reta ' free the memory pointed to by "ptr" and re-allocate it for other purposes. 00528 __system__strsize ' 00528 f6046c00 mov _var_00, #0 ' There's also a _gc_alloc_managed call which is like a combination of 0052c LR__0003 0052c fac8663b rdbyte _tmp001_, arg1 wz ' _gc_alloc followed immediately by _gc_manage. 00530 51046c01 if_ne add _var_00, #1 ' 00534 51047601 if_ne add arg1, #1 00538 5d9ffff0 if_ne jmp #@LR__0003 0053c f6006236 mov result1, _var_00 00540 __system__strsize_ret 00540 fd64002e reta ' '' ' PRI _gc_ptrs | base, end, size 00544 __system___call_method 00544 f6006e3b mov _var_01, arg1 00548 f600703c mov _var_02, arg2 0054c f600723d mov _var_03, arg3 ' base := @_gc_heap_base 00550 fc645700 wrlong objptr, ptra 00554 f107f004 add ptra, #4 00558 f6005637 mov objptr, _var_01 0055c f6007639 mov arg1, _var_03 00560 fd60702d call _var_02 00564 f187f004 sub ptra, #4 00568 fb045700 rdlong objptr, ptra ' word[base + OFF_FLAGS] := GC_MAGIC | GC_FLAG_FREE 0056c __system___call_method_ret 0056c fd64002e reta ' PRI _gc_pageindex(heapbase, ptr) ' if (ptr == 0) 00570 __system___basic_print_char 00570 fc648161 wrlong local01, ptra++ 00574 fc648361 wrlong local02, ptra++ 00578 fc648561 wrlong local03, ptra++ 0057c fc648761 wrlong local04, ptra++ 00580 f600803c mov local01, arg2 ' return 0 00584 f0647602 shl arg1, #2 00588 f1045e08 add ptr___system__dat__, #8 0058c f100762f add arg1, ptr___system__dat__ 00590 fb08823b rdlong local02, arg1 wz ' return (ptr - heapbase) >> pagesizeshift ' 00594 f1845e08 sub ptr___system__dat__, #8 00598 ad90002c if_e jmp #@LR__0006 ' PRI _gc_isFree(ptr) 0059c fb008441 rdlong local03, local02 ' return word[ptr + OFF_FLAGS] == GC_MAGIC + GC_FLAG_FREE 005a0 f1048204 add local02, #4 005a4 fb088641 rdlong local04, local02 wz ' 005a8 5d90000c if_ne jmp #@LR__0004 ' ' go to the next block in the global list of blocks 005ac f6007640 mov arg1, local01 005b0 fddfff0c calla #@__system___tx ' PRI _gc_nextBlockPtr(ptr) 005b4 fd900010 jmp #@LR__0005 005b8 LR__0004 ' return ptr + (word[ptr + OFF_SIZE] << pagesizeshift) 005b8 f6007642 mov arg1, local03 005bc f6007843 mov arg2, local04 005c0 f6007a40 mov arg3, local01 005c4 fddfff7c calla #@__system___call_method 005c8 LR__0005 005c8 LR__0006 005c8 fb04875f rdlong local04, --ptra 005cc fb04855f rdlong local03, --ptra 005d0 fb04835f rdlong local02, --ptra 005d4 fb04815f rdlong local01, --ptra 005d8 __system___basic_print_char_ret 005d8 fd64002e reta ' if (ptr == 0) ' return ptr 005dc __system___basic_print_string 005dc fc648161 wrlong local01, ptra++ 005e0 fc648361 wrlong local02, ptra++ 005e4 fc648561 wrlong local03, ptra++ 005e8 fc648761 wrlong local04, ptra++ 005ec fc648961 wrlong local05, ptra++ 005f0 fc648b61 wrlong local06, ptra++ 005f4 fc648d61 wrlong local07, ptra++ 005f8 fc648f61 wrlong local08, ptra++ 005fc fc649161 wrlong local09, ptra++ 00600 fc649361 wrlong local10, ptra++ 00604 fc649561 wrlong local11, ptra++ 00608 f600803b mov local01, arg1 0060c f600823c mov local02, arg2 00610 f600843d mov local03, arg3 ' 00614 f6008642 mov local04, local03 00618 f50486ff and local04, #255 ' linkindex := word[ptr + OFF_LINK] 0061c f6008842 mov local05, local03 00620 f0448808 shr local05, #8 00624 f5048803 and local05, #3 ' 00628 f6007641 mov arg1, local02 0062c fddffef8 calla #@__system__strsize 00630 f6008a31 mov local06, result1 00634 f6008c45 mov local07, local06 ' '' carve off free space if necessary 00638 f6048e00 mov local08, #0 0063c f6049000 mov local09, #0 ' if (size < availsize) 00640 f25c8600 cmps local04, #0 wcz 00644 ed900088 if_be jmp #@LR__0013 00648 f2588c43 cmps local07, local04 wcz 0064c 3d900080 if_ae jmp #@LR__0013 ' '' shrink this block, link to newly created block 00650 f20c8800 cmp local05, #0 wz 00654 5d900010 if_ne jmp #@LR__0007 ' word[ptr + OFF_SIZE] := size 00658 f6009243 mov local10, local04 0065c f1809246 sub local10, local07 00660 f6008e49 mov local08, local10 00664 fd900040 jmp #@LR__0010 00668 LR__0007 ' nextptr := ptr + (size<> pagesizeshift 00800 f6007640 mov arg1, local01 00804 f6007841 mov arg2, local02 00808 f6007a42 mov arg3, local03 0080c f6007c43 mov arg4, local04 00810 f6007e44 mov arg5, local05 00814 f1847e01 sub arg5, #1 00818 fddfff50 calla #@__system___basic_fmt_in_str 0081c f6008e31 mov local08, result1 ' 00820 fd900004 jmp #@LR__0022 00824 LR__0021 ' ' try to find a free block big enough 00824 f6048e00 mov local08, #0 00828 LR__0022 ' ptr := _gc_tryalloc(size, reserveflag) 00828 f6008a40 mov local06, local01 0082c f1008a47 add local06, local08 00830 fc408c45 wrbyte local07, local06 ' if (ptr == 0) 00834 f1048e01 add local08, #1 00838 f6006247 mov result1, local08 0083c LR__0023 0083c fb048f5f rdlong local08, --ptra 00840 fb048d5f rdlong local07, --ptra 00844 fb048b5f rdlong local06, --ptra 00848 fb04895f rdlong local05, --ptra 0084c fb04875f rdlong local04, --ptra 00850 fb04855f rdlong local03, --ptra 00854 fb04835f rdlong local02, --ptra 00858 fb04815f rdlong local01, --ptra 0085c __system___basic_fmt_in_str_ret 0085c fd64002e reta ' '' run garbage collection here ' _gc_collect 00860 __system___basic_fmt_uinteger 00860 fc648161 wrlong local01, ptra++ 00864 fc648361 wrlong local02, ptra++ 00868 fc648561 wrlong local03, ptra++ 0086c fc648761 wrlong local04, ptra++ 00870 fc648961 wrlong local05, ptra++ 00874 fc648b61 wrlong local06, ptra++ 00878 fc648d61 wrlong local07, ptra++ 0087c fc648f61 wrlong local08, ptra++ 00880 fc649161 wrlong local09, ptra++ 00884 fc649361 wrlong local10, ptra++ 00888 fc649561 wrlong local11, ptra++ 0088c fc649761 wrlong local12, ptra++ 00890 fc649961 wrlong local13, ptra++ 00894 fc649b61 wrlong local14, ptra++ 00898 f600803b mov local01, arg1 0089c f600823c mov local02, arg2 008a0 f600843d mov local03, arg3 008a4 f608863e mov local04, arg4 wz 008a8 f600883f mov local05, arg5 ' 008ac 5d900010 if_ne jmp #@LR__0024 ' ' see if gc freed up enough space 008b0 f25c820a cmps local02, #10 wcz 008b4 c6048a21 if_b mov local06, #33 008b8 36048a0b if_ae mov local06, #11 008bc f6008645 mov local04, local06 008c0 LR__0024 ' ptr := _gc_tryalloc(size, reserveflag) 008c0 f6007643 mov arg1, local04 008c4 f1047601 add arg1, #1 ' return _gc_doalloc(size, 0) 008c8 f6047800 mov arg2, #0 008cc fdd004ac calla #@__system___gc_doalloc 008d0 f6008c31 mov local07, result1 008d4 f6088e46 mov local08, local07 wz ' if ptr ' ' zero the returned memory 008d8 a6006247 if_e mov result1, local08 008dc ad90005c if_e jmp #@LR__0027 ' size := ((size << pagesizeshift) - 8)/4 008e0 f20c8800 cmp local05, #0 wz 008e4 ad900014 if_e jmp #@LR__0026 ' zptr := ptr ' skip the header ' repeat size 008e8 fc408846 wrbyte local05, local07 ' long[zptr] := 0 008ec f1048c01 add local07, #1 008f0 fb6c8602 djnz local04, #@LR__0025 ' zptr += 4 008f4 f6006247 mov result1, local08 008f8 fd900040 jmp #@LR__0027 008fc LR__0025 008fc LR__0026 ' return ptr 008fc f6009041 mov local09, local02 00900 f6009242 mov local10, local03 00904 f6009443 mov local11, local04 00908 f6007646 mov arg1, local07 0090c f6007840 mov arg2, local01 00910 f6007a48 mov arg3, local09 00914 f6007c49 mov arg4, local10 00918 f6007e4a mov arg5, local11 0091c fddffe4c calla #@__system___basic_fmt_in_str 00920 f6009631 mov local12, result1 00924 f600984b mov local13, local12 ' 00928 f6008a46 mov local06, local07 0092c f1008a4c add local06, local13 00930 f6049a00 mov local14, #0 00934 fc409a45 wrbyte local14, local06 ' ' 00938 f6006247 mov result1, local08 0093c LR__0027 0093c fb049b5f rdlong local14, --ptra 00940 fb04995f rdlong local13, --ptra 00944 fb04975f rdlong local12, --ptra 00948 fb04955f rdlong local11, --ptra 0094c fb04935f rdlong local10, --ptra 00950 fb04915f rdlong local09, --ptra 00954 fb048f5f rdlong local08, --ptra 00958 fb048d5f rdlong local07, --ptra 0095c fb048b5f rdlong local06, --ptra 00960 fb04895f rdlong local05, --ptra 00964 fb04875f rdlong local04, --ptra 00968 fb04855f rdlong local03, --ptra 0096c fb04835f rdlong local02, --ptra 00970 fb04815f rdlong local01, --ptra 00974 __system___basic_fmt_uinteger_ret 00974 fd64002e reta ' ' returns 0 if ptr is not a valid pointer ' ' otherwise returns the start of the block it 00978 __system___basic_print_unsigned 00978 fc648161 wrlong local01, ptra++ 0097c fc648361 wrlong local02, ptra++ 00980 fc648561 wrlong local03, ptra++ 00984 fc648761 wrlong local04, ptra++ 00988 fc648961 wrlong local05, ptra++ 0098c f600803b mov local01, arg1 00990 f600823d mov local02, arg3 ' ' points to 00994 f6008441 mov local03, local02 00998 f50484ff and local03, #255 ' ' 0099c f6008641 mov local04, local02 009a0 f0448610 shr local04, #16 009a4 f50c861f and local04, #31 wz ' PRI _gc_isvalidptr(base, heap_end, ptr) | t ' ' make sure the poiter came from alloc 009a8 a6048601 if_e mov local04, #1 ' if (ptr & POINTER_MAGIC_MASK) <> POINTER_MAGIC 009ac f600763c mov arg1, arg2 009b0 f600783e mov arg2, arg4 009b4 f6007a43 mov arg3, local04 009b8 f6007c42 mov arg4, local03 009bc f6047e00 mov arg5, #0 009c0 fddffe9c calla #@__system___basic_fmt_uinteger 009c4 f6008831 mov local05, result1 ' return 0 009c8 f6007640 mov arg1, local01 009cc f6007844 mov arg2, local05 009d0 f6007a41 mov arg3, local02 009d4 fddffc04 calla #@__system___basic_print_string ' ' step back to the header 009d8 f6007644 mov arg1, local05 009dc fdd004f0 calla #@__system___gc_free 009e0 fb04895f rdlong local05, --ptra 009e4 fb04875f rdlong local04, --ptra 009e8 fb04855f rdlong local03, --ptra 009ec fb04835f rdlong local02, --ptra 009f0 fb04815f rdlong local01, --ptra 009f4 __system___basic_print_unsigned_ret 009f4 fd64002e reta ' nextptr := _gc_nextBlockPtr(ptr) ' repeat 009f8 __system___basic_print_nl 009f8 fc648161 wrlong local01, ptra++ ' '' walk back the chain to the last previous free block 009fc f600803b mov local01, arg1 00a00 f604780d mov arg2, #13 00a04 fddffb68 calla #@__system___basic_print_char ' prevptr := _gc_pageptr(heapbase, word[prevptr + OFF_PREV]) 00a08 f6007640 mov arg1, local01 00a0c f604780a mov arg2, #10 00a10 fddffb5c calla #@__system___basic_print_char 00a14 fb04815f rdlong local01, --ptra 00a18 __system___basic_print_nl_ret 00a18 fd64002e reta 00a1c __system__pausems 00a1c fc648161 wrlong local01, ptra++ ' size is 0. Otherwise it returns a pointer to memory. 00a20 fd60621a getct result1 ' garbage collector will never free it. This is because the garbage 00a24 f6008031 mov local01, result1 00a28 ff000002 rdlong muldiva_, ##1024 00a2c fb049c00 00a30 ff000001 mov muldivb_, ##1000 00a34 f6049fe8 00a38 fdc0001e calla #divide_ 00a3c f6009c3b mov muldiva_, arg1 00a40 fdc0000d calla #multiply_ ' initial reference is from COG memory we do not want to accidentally 00a44 fa60804e addct1 local01, muldiva_ 00a48 fd602224 waitct1 00a4c fb04815f rdlong local01, --ptra 00a50 __system__pausems_ret 00a50 fd64002e reta ' ' ' '' ' '' return gc pointers ' '' if called before gc pointers are set up, initialize ' '' the heap ' '' ' PRI _gc_ptrs | base, end, size 00a54 __system___gc_ptrs ' base := @_gc_heap_base 00a54 f1045e68 add ptr___system__dat__, #104 00a58 f600702f mov _var_02, ptr___system__dat__ ' end := @_gc_heap_end 00a5c f1045f00 add ptr___system__dat__, #256 00a60 f600722f mov _var_03, ptr___system__dat__ ' if (long[base] == 0) 00a64 fb086638 rdlong _tmp001_, _var_02 wz 00a68 f1845f68 sub ptr___system__dat__, #360 00a6c 5d900098 if_ne jmp #@LR__0028 ' size := end - base 00a70 f6007439 mov _var_04, _var_03 00a74 f1807438 sub _var_04, _var_02 ' word[base + OFF_SIZE] := 1 00a78 f6046801 mov _tmp002_, #1 00a7c fc506838 wrword _tmp002_, _var_02 ' word[base + OFF_FLAGS] := GC_MAGIC | GC_FLAG_RESERVED 00a80 f6006638 mov _tmp001_, _var_02 00a84 f1046602 add _tmp001_, #2 00a88 ff000036 mov _tmp002_, ##27792 00a8c f6046890 00a90 fc506833 wrword _tmp002_, _tmp001_ ' word[base + OFF_PREV] := 0 00a94 f6006638 mov _tmp001_, _var_02 00a98 f1046604 add _tmp001_, #4 00a9c f6046800 mov _tmp002_, #0 00aa0 fc506833 wrword _tmp002_, _tmp001_ ' word[base + OFF_LINK] := 1 00aa4 f6006638 mov _tmp001_, _var_02 00aa8 f1046606 add _tmp001_, #6 00aac f6046801 mov _tmp002_, #1 00ab0 fc506833 wrword _tmp002_, _tmp001_ ' base += pagesize 00ab4 f1047010 add _var_02, #16 ' word[base + OFF_SIZE] := (size / pagesize) - 1 00ab8 f650683a abs _tmp002_, _var_04 wc 00abc f0446804 shr _tmp002_, #4 00ac0 c6606834 if_b neg _tmp002_, _tmp002_ 00ac4 f1846801 sub _tmp002_, #1 00ac8 fc506838 wrword _tmp002_, _var_02 ' word[base + OFF_FLAGS] := GC_MAGIC | GC_FLAG_FREE 00acc f6006638 mov _tmp001_, _var_02 00ad0 f1046602 add _tmp001_, #2 00ad4 ff000036 mov _tmp002_, ##27791 00ad8 f604688f 00adc fc506833 wrword _tmp002_, _tmp001_ ' word[base + OFF_PREV] := 0 00ae0 f6006638 mov _tmp001_, _var_02 00ae4 f1046604 add _tmp001_, #4 00ae8 f6046800 mov _tmp002_, #0 00aec fc506833 wrword _tmp002_, _tmp001_ ' word[base + OFF_LINK] := 0 00af0 f6006638 mov _tmp001_, _var_02 00af4 f1046606 add _tmp001_, #6 00af8 fc506833 wrword _tmp002_, _tmp001_ ' base -= pagesize 00afc f6006638 mov _tmp001_, _var_02 00b00 f1846610 sub _tmp001_, #16 00b04 f6007033 mov _var_02, _tmp001_ 00b08 LR__0028 ' return (base, end) 00b08 f6006238 mov result1, _var_02 00b0c f6006439 mov result2, _var_03 00b10 __system___gc_ptrs_ret 00b10 fd64002e reta ' ' { return a pointer to page i in the heap } ' PRI _gc_pageptr(heapbase, i) 00b14 __system___gc_pageptr ' if (i == 0) 00b14 f20c7800 cmp arg2, #0 wz ' return 0 00b18 a6046200 if_e mov result1, #0 ' return heapbase + (i << pagesizeshift) 00b1c 50647804 if_ne shl arg2, #4 00b20 5100763c if_ne add arg1, arg2 00b24 5600623b if_ne mov result1, arg1 00b28 __system___gc_pageptr_ret 00b28 fd64002e reta ' ' PRI _gc_pageindex(heapbase, ptr) 00b2c __system___gc_pageindex ' if (ptr == 0) 00b2c f20c7800 cmp arg2, #0 wz ' return 0 00b30 a6046200 if_e mov result1, #0 ' return (ptr - heapbase) >> pagesizeshift 00b34 5180783b if_ne sub arg2, arg1 00b38 50447804 if_ne shr arg2, #4 00b3c 5600623c if_ne mov result1, arg2 00b40 __system___gc_pageindex_ret 00b40 fd64002e reta ' ' PRI _gc_isFree(ptr) 00b44 __system___gc_isfree ' return word[ptr + OFF_FLAGS] == GC_MAGIC + GC_FLAG_FREE 00b44 f6046600 mov _tmp001_, #0 00b48 f1047602 add arg1, #2 00b4c fae06a3b rdword _tmp003_, arg1 00b50 ff000036 cmp _tmp003_, ##27791 wz 00b54 f20c6a8f 00b58 af7fffff if_e mov _tmp001_, ##-1 00b5c a60467ff 00b60 f6006233 mov result1, _tmp001_ 00b64 __system___gc_isfree_ret 00b64 fd64002e reta ' ' ' go to the next block in the global list of blocks ' PRI _gc_nextBlockPtr(ptr) 00b68 __system___gc_nextblockptr ' return ptr + (word[ptr + OFF_SIZE] << pagesizeshift) 00b68 fae0683b rdword _tmp002_, arg1 00b6c f0646804 shl _tmp002_, #4 00b70 f1007634 add arg1, _tmp002_ 00b74 f600623b mov result1, arg1 00b78 __system___gc_nextblockptr_ret 00b78 fd64002e reta ' ' PRI _gc_tryalloc(size, reserveflag) | ptr, availsize, lastptr, nextptr, heap_base, heap_end, saveptr, linkindex 00b7c __system___gc_tryalloc 00b7c fc648161 wrlong local01, ptra++ 00b80 fc648361 wrlong local02, ptra++ 00b84 fc648561 wrlong local03, ptra++ 00b88 fc648761 wrlong local04, ptra++ 00b8c fc648961 wrlong local05, ptra++ 00b90 fc648b61 wrlong local06, ptra++ 00b94 fc648d61 wrlong local07, ptra++ 00b98 fc648f61 wrlong local08, ptra++ 00b9c fc649161 wrlong local09, ptra++ 00ba0 fc649361 wrlong local10, ptra++ 00ba4 fc649561 wrlong local11, ptra++ 00ba8 fc649761 wrlong local12, ptra++ 00bac fc649961 wrlong local13, ptra++ 00bb0 fc649b61 wrlong local14, ptra++ 00bb4 f600803b mov local01, arg1 00bb8 f600823c mov local02, arg2 ' (heap_base, heap_end) := _gc_ptrs 00bbc fddffe94 calla #@__system___gc_ptrs 00bc0 f6008431 mov local03, result1 00bc4 f6008632 mov local04, result2 ' ptr := heap_base 00bc8 f6008842 mov local05, local03 ' repeat 00bcc LR__0029 ' lastptr := ptr 00bcc f6008a44 mov local06, local05 ' ptr := _gc_pageptr(heap_base, word[ptr+OFF_LINK]) 00bd0 f1048806 add local05, #6 00bd4 fae07844 rdword arg2, local05 00bd8 f6007642 mov arg1, local03 00bdc fddfff34 calla #@__system___gc_pageptr 00be0 f6008c31 mov local07, result1 00be4 f6088846 mov local05, local07 wz ' availsize := word[ptr+OFF_SIZE] 00be8 f6008e44 mov local08, local05 00bec fae09047 rdword local09, local08 00bf0 ad900008 if_e jmp #@LR__0030 00bf4 f2588048 cmps local01, local09 wcz 00bf8 1d9fffd0 if_a jmp #@LR__0029 00bfc LR__0030 ' while ptr and size > availsize ' ' if (ptr == 0) 00bfc f20c8800 cmp local05, #0 wz ' return ptr 00c00 a6006244 if_e mov result1, local05 00c04 ad900138 if_e jmp #@LR__0033 ' ' linkindex := word[ptr + OFF_LINK] 00c08 f6008e44 mov local08, local05 00c0c f1048e06 add local08, #6 00c10 fae09247 rdword local10, local08 ' ' '' carve off free space if necessary ' if (size < availsize) 00c14 f2588048 cmps local01, local09 wcz 00c18 3d9000ac if_ae jmp #@LR__0032 ' '' shrink this block, link to newly created block ' word[ptr + OFF_SIZE] := size 00c1c fc508044 wrword local01, local05 ' nextptr := ptr + (size<> pagesizeshift 00db0 f0448004 shr local01, #4 ' ' ' try to find a free block big enough ' ptr := _gc_tryalloc(size, reserveflag) 00db4 f6007640 mov arg1, local01 00db8 f6007841 mov arg2, local02 00dbc fddffdbc calla #@__system___gc_tryalloc 00dc0 f6008431 mov local03, result1 00dc4 f6088642 mov local04, local03 wz ' if (ptr == 0) 00dc8 5d900014 if_ne jmp #@LR__0034 ' '' run garbage collection here ' _gc_collect 00dcc fdd003b0 calla #@__system___gc_collect ' ' ' see if gc freed up enough space ' ptr := _gc_tryalloc(size, reserveflag) 00dd0 f6007640 mov arg1, local01 00dd4 f6007841 mov arg2, local02 00dd8 fddffda0 calla #@__system___gc_tryalloc 00ddc f6008631 mov local04, result1 00de0 LR__0034 ' if ptr 00de0 f20c8600 cmp local04, #0 wz 00de4 ad900038 if_e jmp #@LR__0037 ' ' zero the returned memory ' size := ((size << pagesizeshift) - 8)/4 00de8 f0648004 shl local01, #4 00dec f1848008 sub local01, #8 00df0 f6508040 abs local01, local01 wc 00df4 f0448002 shr local01, #2 00df8 c6608040 if_b neg local01, local01 ' zptr := ptr ' skip the header 00dfc f6008843 mov local05, local04 ' repeat size 00e00 f6088a40 mov local06, local01 wz 00e04 ad900018 if_e jmp #@LR__0036 00e08 LR__0035 ' long[zptr] := 0 00e08 f6048c00 mov local07, #0 00e0c fc608c44 wrlong local07, local05 ' zptr += 4 00e10 f1048804 add local05, #4 00e14 f1848a01 sub local06, #1 00e18 f6088a45 mov local06, local06 wz 00e1c 5d9fffe8 if_ne jmp #@LR__0035 00e20 LR__0036 00e20 LR__0037 ' return ptr 00e20 f6006243 mov result1, local04 00e24 LR__0038 00e24 fb048d5f rdlong local07, --ptra 00e28 fb048b5f rdlong local06, --ptra 00e2c fb04895f rdlong local05, --ptra 00e30 fb04875f rdlong local04, --ptra 00e34 fb04855f rdlong local03, --ptra 00e38 fb04835f rdlong local02, --ptra 00e3c fb04815f rdlong local01, --ptra 00e40 __system___gc_doalloc_ret 00e40 fd64002e reta ' ' ' ' ' returns 0 if ptr is not a valid pointer ' ' otherwise returns the start of the block it ' ' points to ' ' ' PRI _gc_isvalidptr(base, heap_end, ptr) | t 00e44 __system___gc_isvalidptr 00e44 f600723d mov _var_03, arg3 ' ' make sure the poiter came from alloc ' if (ptr & POINTER_MAGIC_MASK) <> POINTER_MAGIC 00e48 f6006639 mov _tmp001_, _var_03 00e4c ff7ff800 and _tmp001_, ##-1048576 00e50 f5046600 00e54 ff31c000 cmp _tmp001_, ##1669332992 wz 00e58 f20c6600 ' return 0 00e5c 56046200 if_ne mov result1, #0 00e60 5d900068 if_ne jmp #@__system___gc_isvalidptr_ret ' ' step back to the header ' ptr := (ptr - headersize) & (!POINTER_MAGIC_MASK) 00e64 f6006639 mov _tmp001_, _var_03 00e68 f1846608 sub _tmp001_, #8 00e6c f6007233 mov _var_03, _tmp001_ 00e70 ff7ff800 andn _var_03, ##-1048576 00e74 f5247200 ' ' make sure it is in the heap ' if (ptr < base) or (ptr => heap_end) 00e78 f258723b cmps _var_03, arg1 wcz 00e7c cd900008 if_b jmp #@LR__0039 00e80 f258723c cmps _var_03, arg2 wcz 00e84 cd900008 if_b jmp #@LR__0040 00e88 LR__0039 ' return 0 00e88 f6046200 mov result1, #0 00e8c fd90003c jmp #@__system___gc_isvalidptr_ret 00e90 LR__0040 ' ' ' and appropriately aligned (same as _gc_heap_base) ' if ( (ptr ^ base) & pagemask) <> 0 00e90 f6006839 mov _tmp002_, _var_03 00e94 f560683b xor _tmp002_, arg1 00e98 f6006634 mov _tmp001_, _tmp002_ 00e9c f50c660f and _tmp001_, #15 wz ' return 0 00ea0 56046200 if_ne mov result1, #0 00ea4 5d900024 if_ne jmp #@__system___gc_isvalidptr_ret ' ' ' and make sure the GC_MAGIC bits are set in flags ' t := word[ptr + OFF_FLAGS] 00ea8 f6006639 mov _tmp001_, _var_03 00eac f1046602 add _tmp001_, #2 00eb0 fae06633 rdword _tmp001_, _tmp001_ ' if (t & GC_MAGIC_MASK) <> GC_MAGIC 00eb4 ff00007f and _tmp001_, ##65472 00eb8 f50467c0 00ebc ff000036 cmp _tmp001_, ##27776 wz 00ec0 f20c6680 ' return 0 00ec4 56046200 if_ne mov result1, #0 ' return ptr 00ec8 a6006239 if_e mov result1, _var_03 00ecc __system___gc_isvalidptr_ret 00ecc fd64002e reta ' ' ' ' ' free a pointer previously returned by alloc ' ' ' PRI _gc_free(ptr) | heapbase, heapend 00ed0 __system___gc_free 00ed0 fc648161 wrlong local01, ptra++ 00ed4 f600803b mov local01, arg1 ' (heapbase, heapend) := _gc_ptrs 00ed8 fddffb78 calla #@__system___gc_ptrs 00edc f6007631 mov arg1, result1 00ee0 f6007832 mov arg2, result2 ' ptr := _gc_isvalidptr(heapbase, heapend, ptr) 00ee4 f6007a40 mov arg3, local01 00ee8 fddfff58 calla #@__system___gc_isvalidptr 00eec f6088031 mov local01, result1 wz ' if (ptr) 00ef0 ad900008 if_e jmp #@LR__0041 ' _gc_dofree(ptr) 00ef4 f6007640 mov arg1, local01 00ef8 fdd00008 calla #@__system___gc_dofree 00efc LR__0041 00efc fb04815f rdlong local01, --ptra 00f00 __system___gc_free_ret 00f00 fd64002e reta ' ' ' ' ' internal routine for freeing a block of memory ' ' ptr points to the start of the block ' ' returns a pointer to the next non-free block(useful for ' ' garbage collection, to handle cases where memory is coalesced) ' ' ' PRI _gc_dofree(ptr) | prevptr, tmpptr, nextptr, heapbase, heapend, n 00f04 __system___gc_dofree 00f04 fc648161 wrlong local01, ptra++ 00f08 fc648361 wrlong local02, ptra++ 00f0c fc648561 wrlong local03, ptra++ 00f10 fc648761 wrlong local04, ptra++ 00f14 fc648961 wrlong local05, ptra++ 00f18 fc648b61 wrlong local06, ptra++ 00f1c fc648d61 wrlong local07, ptra++ 00f20 fc648f61 wrlong local08, ptra++ 00f24 fc649161 wrlong local09, ptra++ 00f28 fc649361 wrlong local10, ptra++ 00f2c fc649561 wrlong local11, ptra++ 00f30 f600803b mov local01, arg1 ' (heapbase, heapend) := _gc_ptrs 00f34 fddffb1c calla #@__system___gc_ptrs 00f38 f6008231 mov local02, result1 00f3c f6008432 mov local03, result2 ' word[ptr + OFF_FLAGS] := GC_MAGIC + GC_FLAG_FREE 00f40 f6008640 mov local04, local01 00f44 f1048602 add local04, #2 00f48 ff000036 mov local05, ##27791 00f4c f604888f 00f50 fc508843 wrword local05, local04 ' prevptr := ptr 00f54 f6008a40 mov local06, local01 ' nextptr := _gc_nextBlockPtr(ptr) 00f58 f6007640 mov arg1, local01 00f5c fddffc08 calla #@__system___gc_nextblockptr 00f60 f6008c31 mov local07, result1 ' repeat 00f64 LR__0042 ' '' walk back the chain to the last previous free block ' prevptr := _gc_pageptr(heapbase, word[prevptr + OFF_PREV]) 00f64 f1048a04 add local06, #4 00f68 fae07845 rdword arg2, local06 00f6c f6007641 mov arg1, local02 00f70 fddffba0 calla #@__system___gc_pageptr 00f74 f6008e31 mov local08, result1 00f78 f6088a47 mov local06, local08 wz 00f7c ad900014 if_e jmp #@LR__0043 00f80 f6008645 mov local04, local06 00f84 f6007643 mov arg1, local04 00f88 fddffbb8 calla #@__system___gc_isfree 00f8c f6088831 mov local05, result1 wz 00f90 ad9fffd0 if_e jmp #@LR__0042 00f94 LR__0043 ' until prevptr == 0 or _gc_isFree(prevptr) ' if (prevptr == 0) 00f94 f20c8a00 cmp local06, #0 wz ' prevptr := heapbase 00f98 a6008a41 if_e mov local06, local02 ' ' word[ptr + OFF_LINK] := word[prevptr + OFF_LINK] 00f9c f6008640 mov local04, local01 00fa0 f1048606 add local04, #6 00fa4 f6008845 mov local05, local06 00fa8 f1048806 add local05, #6 00fac fae09044 rdword local09, local05 00fb0 fc509043 wrword local09, local04 ' word[prevptr + OFF_LINK] := _gc_pageindex(heapbase, ptr) 00fb4 f6008645 mov local04, local06 00fb8 f1048606 add local04, #6 00fbc f6007840 mov arg2, local01 00fc0 f6007641 mov arg1, local02 00fc4 fddffb64 calla #@__system___gc_pageindex 00fc8 f6008e31 mov local08, result1 00fcc fc508e43 wrword local08, local04 ' ' ' see if we should merge with the previous block ' if (prevptr <> heapbase) 00fd0 f2088a41 cmp local06, local02 wz 00fd4 ad900094 if_e jmp #@LR__0046 ' tmpptr := _gc_nextBlockPtr(prevptr) 00fd8 f6007645 mov arg1, local06 00fdc fddffb88 calla #@__system___gc_nextblockptr 00fe0 f6009231 mov local10, result1 ' if (tmpptr == ptr) 00fe4 f2089240 cmp local10, local01 wz 00fe8 5d900080 if_ne jmp #@LR__0045 ' word[prevptr + OFF_SIZE] += word[ptr + OFF_SIZE] 00fec fae08845 rdword local05, local06 00ff0 f6008e40 mov local08, local01 00ff4 fae09447 rdword local11, local08 00ff8 f100884a add local05, local11 00ffc fc508845 wrword local05, local06 ' word[ptr + OFF_FLAGS] := 0 01000 f6008640 mov local04, local01 01004 f1048602 add local04, #2 01008 f6048800 mov local05, #0 0100c fc508843 wrword local05, local04 ' ' adjust prev link in next block ' nextptr := _gc_nextBlockPtr(ptr) 01010 f6007640 mov arg1, local01 01014 fddffb50 calla #@__system___gc_nextblockptr 01018 f6008c31 mov local07, result1 ' if (nextptr < heapend) 0101c f2588c42 cmps local07, local03 wcz 01020 3d90001c if_ae jmp #@LR__0044 ' word[nextptr + OFF_PREV] := _gc_pageindex(heapbase, prevptr) 01024 f6008646 mov local04, local07 01028 f1048604 add local04, #4 0102c f6007641 mov arg1, local02 01030 f6007845 mov arg2, local06 01034 fddffaf4 calla #@__system___gc_pageindex 01038 f6008e31 mov local08, result1 0103c fc508e43 wrword local08, local04 01040 LR__0044 ' word[prevptr + OFF_LINK] := word[ptr + OFF_LINK] 01040 f6008645 mov local04, local06 01044 f1048606 add local04, #6 01048 f6008840 mov local05, local01 0104c f1048806 add local05, #6 01050 fae09044 rdword local09, local05 01054 fc509043 wrword local09, local04 ' word[ptr + OFF_LINK] := 0 01058 f6008640 mov local04, local01 0105c f1048606 add local04, #6 01060 f6048800 mov local05, #0 01064 fc508843 wrword local05, local04 ' ptr := prevptr 01068 f6008045 mov local01, local06 0106c LR__0045 0106c LR__0046 ' ' '' see if we should merge with following block ' tmpptr := _gc_nextBlockPtr(ptr) 0106c f6007640 mov arg1, local01 01070 fddffaf4 calla #@__system___gc_nextblockptr 01074 f6009231 mov local10, result1 ' if (tmpptr < heapend) and _gc_isFree(tmpptr) 01078 f2589242 cmps local10, local03 wcz 0107c 3d9000a4 if_ae jmp #@LR__0048 01080 f6007649 mov arg1, local10 01084 fddffabc calla #@__system___gc_isfree 01088 f20c6200 cmp result1, #0 wz 0108c ad900094 if_e jmp #@LR__0048 ' prevptr := ptr 01090 f6008a40 mov local06, local01 ' ptr := tmpptr 01094 f6008049 mov local01, local10 ' word[prevptr + OFF_SIZE] += word[ptr + OFF_SIZE] 01098 fae08845 rdword local05, local06 0109c f6008e40 mov local08, local01 010a0 fae09447 rdword local11, local08 010a4 f100884a add local05, local11 010a8 fc508845 wrword local05, local06 ' word[prevptr + OFF_LINK] := word[ptr + OFF_LINK] 010ac f6008645 mov local04, local06 010b0 f1048606 add local04, #6 010b4 f6008840 mov local05, local01 010b8 f1048806 add local05, #6 010bc fae09044 rdword local09, local05 010c0 fc509043 wrword local09, local04 ' word[ptr + OFF_FLAGS] := $AA 010c4 f6008640 mov local04, local01 010c8 f1048602 add local04, #2 010cc f60488aa mov local05, #170 010d0 fc508843 wrword local05, local04 ' word[ptr + OFF_LINK] := 0 010d4 f6008640 mov local04, local01 010d8 f1048606 add local04, #6 010dc f6048800 mov local05, #0 010e0 fc508843 wrword local05, local04 ' nextptr := _gc_nextBlockPtr(ptr) 010e4 f6008640 mov local04, local01 010e8 f6007643 mov arg1, local04 010ec fddffa78 calla #@__system___gc_nextblockptr 010f0 f6008831 mov local05, result1 010f4 f6008c44 mov local07, local05 ' if (nextptr < heapend) 010f8 f2588c42 cmps local07, local03 wcz 010fc 3d900024 if_ae jmp #@LR__0047 ' word[nextptr + OFF_PREV] := _gc_pageindex(heapbase, prevptr) 01100 f6008646 mov local04, local07 01104 f1048604 add local04, #4 01108 f6008841 mov local05, local02 0110c f6009045 mov local09, local06 01110 f6007644 mov arg1, local05 01114 f6007848 mov arg2, local09 01118 fddffa10 calla #@__system___gc_pageindex 0111c f6008e31 mov local08, result1 01120 fc508e43 wrword local08, local04 01124 LR__0047 01124 LR__0048 ' ' return nextptr 01124 f6006246 mov result1, local07 01128 fb04955f rdlong local11, --ptra 0112c fb04935f rdlong local10, --ptra 01130 fb04915f rdlong local09, --ptra 01134 fb048f5f rdlong local08, --ptra 01138 fb048d5f rdlong local07, --ptra 0113c fb048b5f rdlong local06, --ptra 01140 fb04895f rdlong local05, --ptra 01144 fb04875f rdlong local04, --ptra 01148 fb04855f rdlong local03, --ptra 0114c fb04835f rdlong local02, --ptra 01150 fb04815f rdlong local01, --ptra 01154 __system___gc_dofree_ret 01154 fd64002e reta ' ' PRI __topofstack(ptr) 01158 __system____topofstack 01158 fc645161 wrlong fp, ptra++ 0115c f60051f8 mov fp, ptra 01160 f107f008 add ptra, #8 01164 f1045004 add fp, #4 01168 fc607628 wrlong arg1, fp ' return @ptr 0116c f6006228 mov result1, fp 01170 f1845004 sub fp, #4 01174 f603f028 mov ptra, fp 01178 fb04515f rdlong fp, --ptra 0117c __system____topofstack_ret 0117c fd64002e reta ' ' '' ' '' actual garbage collection routine ' '' ' PRI _gc_collect | ptr, nextptr, startheap, endheap, flags, ourid 01180 __system___gc_collect 01180 fc648161 wrlong local01, ptra++ 01184 fc648361 wrlong local02, ptra++ 01188 fc648561 wrlong local03, ptra++ 0118c fc648761 wrlong local04, ptra++ 01190 fc648961 wrlong local05, ptra++ 01194 fc648b61 wrlong local06, ptra++ 01198 fc648d61 wrlong local07, ptra++ 0119c fc648f61 wrlong local08, ptra++ 011a0 fc649161 wrlong local09, ptra++ ' ' (startheap, endheap) := _gc_ptrs 011a4 fddff8ac calla #@__system___gc_ptrs 011a8 f6008032 mov local01, result2 011ac f6008231 mov local02, result1 ' ' clear the "IN USE" flags for all blocks ' ptr := _gc_nextBlockPtr(startheap) 011b0 f6007641 mov arg1, local02 011b4 fddff9b0 calla #@__system___gc_nextblockptr 011b8 f6008431 mov local03, result1 ' ourid := cogid ' unmodified pointer returned from _gc_alloc. 011bc fd606201 cogid result1 ' case the memory will be left up to the garbage collector. If you want 011c0 f6008631 mov local04, result1 ' repeat while ptr < endheap 011c4 LR__0049 011c4 f2588440 cmps local03, local01 wcz 011c8 3d90002c if_ae jmp #@LR__0050 ' word[ptr + OFF_FLAGS] &= !GC_FLAG_INUSE 011cc f6008842 mov local05, local03 011d0 f1048802 add local05, #2 011d4 f6008a42 mov local06, local03 011d8 f1048a02 add local06, #2 011dc fae08c45 rdword local07, local06 011e0 f5248c20 andn local07, #32 011e4 fc508c44 wrword local07, local05 ' ptr := _gc_nextBlockPtr(ptr) 011e8 f6007642 mov arg1, local03 011ec fddff978 calla #@__system___gc_nextblockptr 011f0 f6008431 mov local03, result1 011f4 fd9fffcc jmp #@LR__0049 011f8 LR__0050 ' ' ' now mark pointers found in HUB memory ' ' this encompasses more than we need; ' ' find a way to get the end of code and ' ' start of stack?? ' _gc_markhub(0, __topofstack(0)) 011f8 f6048800 mov local05, #0 011fc f6047600 mov arg1, #0 01200 fddfff54 calla #@__system____topofstack 01204 f6008a31 mov local06, result1 01208 f6007644 mov arg1, local05 0120c f6007845 mov arg2, local06 01210 fdd000a8 calla #@__system___gc_markhub ' ' ' FIXME: ideally the above would get just the data section and stack ' ' and we would _gc_markhub() here for the heap ' ' 'now mark everything found in COG memory ' _gc_markcog 01214 fdd0016c calla #@__system___gc_markcog ' ' ' now free all pointers that aren't in use ' ' or reserved (or under another COG's control) ' ' ' there will always be at least one block after startheap, ' ' so nextptr will be valid at first ' nextptr := _gc_nextBlockPtr(startheap) 01218 f6007641 mov arg1, local02 0121c fddff948 calla #@__system___gc_nextblockptr 01220 f6008e31 mov local08, result1 ' repeat 01224 LR__0051 ' ptr := nextptr 01224 f6008447 mov local03, local08 ' nextptr := _gc_nextBlockPtr(ptr) 01228 f6007642 mov arg1, local03 0122c fddff938 calla #@__system___gc_nextblockptr 01230 f6008e31 mov local08, result1 ' flags := word[ptr + OFF_FLAGS] 01234 f6008842 mov local05, local03 01238 f1048802 add local05, #2 0123c fae09044 rdword local09, local05 ' if ( (not (flags & GC_FLAG_INUSE)) and (not (flags & GC_FLAG_RESERVED)) ) 01240 f7cc9020 test local09, #32 wz 01244 5d90003c if_ne jmp #@LR__0054 01248 f6008c48 mov local07, local09 0124c f50c8c10 and local07, #16 wz 01250 5d900030 if_ne jmp #@LR__0054 ' flags &= GC_OWNER_MASK 01254 f6008848 mov local05, local09 01258 f504880f and local05, #15 0125c f6009044 mov local09, local05 ' if (flags == ourid) or (flags == GC_OWNER_HUB) 01260 f2089043 cmp local09, local04 wz 01264 ad900008 if_e jmp #@LR__0052 01268 f20c900e cmp local09, #14 wz 0126c 5d900014 if_ne jmp #@LR__0053 01270 LR__0052 ' nextptr := _gc_dofree(ptr) ' dofree returns address of next block 01270 f6008842 mov local05, local03 01274 f6007644 mov arg1, local05 01278 fddffc88 calla #@__system___gc_dofree 0127c f6008c31 mov local07, result1 01280 f6008e46 mov local08, local07 01284 LR__0053 01284 LR__0054 01284 f20c8e00 cmp local08, #0 wz 01288 ad900008 if_e jmp #@LR__0055 0128c f2588e40 cmps local08, local01 wcz 01290 cd9fff90 if_b jmp #@LR__0051 01294 LR__0055 01294 fb04915f rdlong local09, --ptra 01298 fb048f5f rdlong local08, --ptra 0129c fb048d5f rdlong local07, --ptra 012a0 fb048b5f rdlong local06, --ptra 012a4 fb04895f rdlong local05, --ptra 012a8 fb04875f rdlong local04, --ptra 012ac fb04855f rdlong local03, --ptra 012b0 fb04835f rdlong local02, --ptra 012b4 fb04815f rdlong local01, --ptra 012b8 __system___gc_collect_ret 012b8 fd64002e reta ' ' while (nextptr <> 0) and (nextptr < endheap) ' ' ' ' ' mark as used any pointers found in HUB between startaddr and endaddr ' ' ' PRI _gc_markhub(startaddr, endaddr) | ptr, flags, heap_base, heap_end 012bc __system___gc_markhub 012bc fc648161 wrlong local01, ptra++ 012c0 fc648361 wrlong local02, ptra++ 012c4 fc648561 wrlong local03, ptra++ 012c8 fc648761 wrlong local04, ptra++ 012cc fc648961 wrlong local05, ptra++ 012d0 fc648b61 wrlong local06, ptra++ 012d4 fc648d61 wrlong local07, ptra++ 012d8 fc648f61 wrlong local08, ptra++ 012dc fc649161 wrlong local09, ptra++ 012e0 fc649361 wrlong local10, ptra++ 012e4 f600803b mov local01, arg1 012e8 f600823c mov local02, arg2 ' (heap_base, heap_end) := _gc_ptrs 012ec fddff764 calla #@__system___gc_ptrs 012f0 f6008431 mov local03, result1 012f4 f6008632 mov local04, result2 ' repeat while (startaddr < endaddr) 012f8 LR__0056 012f8 f2588041 cmps local01, local02 wcz 012fc 3d900058 if_ae jmp #@LR__0058 ' ptr := long[startaddr] 01300 fb008840 rdlong local05, local01 ' startaddr += 4 01304 f1048004 add local01, #4 ' ptr := _gc_isvalidptr(heap_base, heap_end, ptr) 01308 f6007642 mov arg1, local03 0130c f6007843 mov arg2, local04 01310 f6007a44 mov arg3, local05 01314 fddffb2c calla #@__system___gc_isvalidptr 01318 f6008a31 mov local06, result1 0131c f6088c45 mov local07, local06 wz ' if ptr and not _gc_isFree(ptr) 01320 ad900030 if_e jmp #@LR__0057 01324 f6007646 mov arg1, local07 01328 fddff818 calla #@__system___gc_isfree 0132c f6088e31 mov local08, result1 wz 01330 5d900020 if_ne jmp #@LR__0057 ' flags := word[ptr + OFF_FLAGS] 01334 f6009046 mov local09, local07 01338 f1049002 add local09, #2 0133c fae09248 rdword local10, local09 ' flags &= !GC_OWNER_MASK 01340 f524920f andn local10, #15 ' flags |= GC_FLAG_INUSE | GC_OWNER_HUB 01344 f544922e or local10, #46 ' word[ptr + OFF_FLAGS] := flags 01348 f6009046 mov local09, local07 0134c f1049002 add local09, #2 01350 fc509248 wrword local10, local09 01354 LR__0057 01354 fd9fffa0 jmp #@LR__0056 01358 LR__0058 01358 fb04935f rdlong local10, --ptra 0135c fb04915f rdlong local09, --ptra 01360 fb048f5f rdlong local08, --ptra 01364 fb048d5f rdlong local07, --ptra 01368 fb048b5f rdlong local06, --ptra 0136c fb04895f rdlong local05, --ptra 01370 fb04875f rdlong local04, --ptra 01374 fb04855f rdlong local03, --ptra 01378 fb04835f rdlong local02, --ptra 0137c fb04815f rdlong local01, --ptra 01380 __system___gc_markhub_ret 01380 fd64002e reta ' ' PRI _gc_markcog | cogaddr, ptr, heap_base, heap_end 01384 __system___gc_markcog 01384 fc648161 wrlong local01, ptra++ 01388 fc648361 wrlong local02, ptra++ 0138c fc648561 wrlong local03, ptra++ 01390 fc648761 wrlong local04, ptra++ 01394 fc648961 wrlong local05, ptra++ 01398 fc648b61 wrlong local06, ptra++ 0139c fc648d61 wrlong local07, ptra++ ' (heap_base, heap_end) := _gc_ptrs 013a0 fddff6b0 calla #@__system___gc_ptrs 013a4 f6008031 mov local01, result1 013a8 f6008232 mov local02, result2 ' repeat cogaddr from 0 to 495 013ac f6048400 mov local03, #0 013b0 LR__0059 ' ptr := spr[496 - cogaddr] 013b0 f60487f0 mov local04, #496 013b4 f1808642 sub local04, local03 013b8 f60489f0 mov local05, #496 013bc f1008843 add local05, local04 013c0 f9948800 alts local05, #0 013c4 f6008a44 mov local06, local05 ' ptr := _gc_isvalidptr(heap_base, heap_end, ptr) 013c8 f6007640 mov arg1, local01 013cc f6007841 mov arg2, local02 013d0 f6007a45 mov arg3, local06 013d4 fddffa6c calla #@__system___gc_isvalidptr 013d8 f6088a31 mov local06, result1 wz ' if ptr 013dc ad90001c if_e jmp #@LR__0060 ' word[ptr + OFF_FLAGS] |= GC_FLAG_INUSE 013e0 f6008845 mov local05, local06 013e4 f1048802 add local05, #2 013e8 f6008c45 mov local07, local06 013ec f1048c02 add local07, #2 013f0 fae08646 rdword local04, local07 013f4 f5448620 or local04, #32 013f8 fc508644 wrword local04, local05 013fc LR__0060 013fc f1048401 add local03, #1 01400 f25c85f0 cmps local03, #496 wcz 01404 cd9fffa8 if_b jmp #@LR__0059 01408 fb048d5f rdlong local07, --ptra 0140c fb048b5f rdlong local06, --ptra 01410 fb04895f rdlong local05, --ptra 01414 fb04875f rdlong local04, --ptra 01418 fb04855f rdlong local03, --ptra 0141c fb04835f rdlong local02, --ptra 01420 fb04815f rdlong local01, --ptra 01424 __system___gc_markcog_ret 01424 fd64002e reta 01428 LR__0061 01428 74746567 byte "getting values" 01436 00 byte 0 01437 LR__0062 01437 3d6170 byte "pa=" 0143a 00 byte 0 0143b LR__0063 0143b 3d627020 byte " pb=" 0143f 00 byte 0 01440 alignl 01440 __system__dat_ '-' OFF_SIZE = 0 '-' OFF_FLAGS = 2 '-' OFF_PREV = 4 01440 00000000 byte $00, $00, $00, $00 '-' OFF_LINK = 6 01444 00000000 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 01448 00001440 long @@@__system__dat_ '-' POINTER_MAGIC_MASK = $fff00000 0144c 00000000 byte $00[28] '-' __REAL_HEAPSIZE__ = 64 ' redefined based on user options '-' 01468 00001440 long @@@__system__dat_ '-' DAT 0146c 00000000 byte $00[28] '-' _gc_heap_base '-' long 0[__REAL_HEAPSIZE__] 01488 00000000 byte $00[32] '-' _gc_heap_base '-' long 0[__REAL_HEAPSIZE__] 014a8 00000000 byte $00[256] 015a8 objmem 015a8 00000000 long 0[2] 015b0 stackspace 015b0 00000000 long 0[1] 015b4 033 org COG_BSS_START 015b4 033 _tmp001_ 015b4 033 res 1 015b4 034 _tmp002_ 015b4 034 res 1 015b4 035 _tmp003_ 015b4 035 res 1 015b4 036 _var_00 015b4 036 res 1 015b4 037 _var_01 015b4 037 res 1 015b4 038 _var_02 015b4 038 res 1 015b4 039 _var_03 015b4 039 res 1 015b4 03a _var_04 015b4 03a res 1 015b4 03b arg1 015b4 03b res 1 015b4 03c arg2 015b4 03c res 1 015b4 03d arg3 015b4 03d res 1 015b4 03e arg4 015b4 03e res 1 015b4 03f arg5 015b4 03f res 1 015b4 040 local01 015b4 040 res 1 015b4 041 local02 015b4 041 res 1 015b4 042 local03 015b4 042 res 1 015b4 043 local04 015b4 043 res 1 015b4 044 local05 015b4 044 res 1 015b4 045 local06 015b4 045 res 1 015b4 046 local07 015b4 046 res 1 015b4 047 local08 015b4 047 res 1 015b4 048 local09 015b4 048 res 1 015b4 049 local10 015b4 049 res 1 015b4 04a local11 015b4 04a res 1 015b4 04b local12 015b4 04b res 1 015b4 04c local13 015b4 04c res 1 015b4 04d local14 015b4 04d res 1 015b4 04e muldiva_ 015b4 04e res 1 015b4 04f muldivb_ 015b4 04f res 1 015b4 050 fit 496