.module rlpos.c .area data 0000 _main_frame_ptr:: 0000 .blkb 2 .area idata 0000 0000 .word 0 .area data 0002 _main_frame_x_ptr:: 0002 .blkb 2 .area idata 0002 0000 .word 0 .area data 0004 _temp_task_frame_ptr:: 0004 .blkb 2 .area idata 0004 0000 .word 0 .area data .area text ; lreg1 -> -4,x ; lreg2 -> -8,x ; ?temp -> -26,x ; ?temp -> -26,x ; ?temp -> -26,x ; ?temp -> -28,x ; ?temp -> -26,x ; addr -> -24,x ; id -> -22,x ; result -> -20,x ; temp_heap_ptr -> -18,x ; temp -> -16,x ; temp_heap_size -> -15,x ; priority_check -> -13,x ; deadline -> -12,x ; i -> -10,x 0000 _main:: 0000 34 pshx 0001 B775 tfr s,x 0003 1BF1DC leas -36,sp 0006 ; /* RLPOS: RLPotter Operating System 0006 ; 0006 ; Version 0.6 for the 68HC12D60A microcontroller 0006 ; by Ryan Potter 0006 ; ryan@rlpotter.com 0006 ; 0006 ; 0006 ; v0.6 April 24, 2003: 11042 bytes 0006 ; - made the task block and the task control block dynamic, so that 0006 ; now tasks can create tasks, and can also start/stop them 0006 ; - implemented the sysInit() task for kicking off a user system 0006 ; - implemented a kernel debug command for tracing code execution 0006 ; - implemented small msg box system in kernel for tasks 0006 ; - implemented COP watchdog reset timer 0006 ; - added system resources to semlib 0006 ; - added skeleton ISR_handler() code for the other interrupts 0006 ; - implemented _HC12Setup.c to initialize/harden the system 0006 ; 0006 ; v0.5 April 16, 2003: 0006 ; - added priority preemption 0006 ; - finished kernel task state switcher 0006 ; - it is now officially a legitimate 0006 ; rate monotonic 0006 ; priority preemptive 0006 ; multitasking 0006 ; Real Time Operating System :) 0006 ; - made kernel.c and semlib.c consistent with the 0006 ; rest of the kernel 0006 ; - included the early framework for a msg box system 0006 ; 0006 ; v0.4 April 13, 2003: 8096 bytes 0006 ; - gerneralized the shell command-line input parser: 0006 ; cmd (up to 32 chars) 0006 ; - added kernel and shell functions 0006 ; 0006 ; v0.3 April 12, 2003: 6155 bytes 0006 ; - added a beginning shell user interface. 0006 ; - added a resource control block and basic semaphore functions. 0006 ; - added basic kernel functions 0006 ; 0006 ; v0.2 April 9, 2003: 0006 ; - able to round-robin with RTI interrupt. 0006 ; - bonified/certified multitasking with 3 tasks. :) 0006 ; 0006 ; v0.1 April 3, 2003: 0006 ; - able to round-robin without interrupts. 0006 ; - not multitasking, really. 0006 ; 0006 ; v0.0 started April 1, 2003; 0 bytes 0006 ; - no idea where to start. 0006 ; - don't want to look at anyone else's work. ;0) 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; Architecture/C assumptions: 0006 ; 1) 'D' register is the accumulator 0006 ; 2) 'X' register points to the top of the current stack 0006 ; 3) 'Y' register is for general use in indexed operations 0006 ; 4) the heap grows upward and mem segments allocated by malloc, 0006 ; realloc, and calloc are linear and contiguous. 0006 ; 5) the stack grows downwards, and there is no boundary checking. 0006 ; 0006 ; Potential problem areas: 0006 ; 1) 'running' section of the kernel get's compiled using extra 0006 ; push and pop instructions 0006 ; 2) run out of ram (global + stack + heap) 0006 ; 0006 ; */ 0006 ; 0006 ; 0006 ; 0006 ; #include <912d60.h> 0006 ; #include 0006 ; #include 0006 ; #include 0006 ; #include "kernel.h" 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; // FUNCTION PROTOTYPES 0006 ; void RTI_handler(void); 0006 ; void sysInit(void); 0006 ; void shell(void); 0006 ; void sysTime(void); 0006 ; void (*task_ptr[MAXTASKS])(void); 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; // GLOBAL VARIABLES 0006 ; unsigned char *main_frame_ptr = NULL; // bottom of main() frame 0006 ; unsigned char *main_frame_x_ptr = NULL; // top of main() frame (x-reg ptr) 0006 ; unsigned char *temp_task_frame_ptr = NULL; // temp CCR pointer for RTI 0006 ; 0006 ; 0006 ; extern unsigned int current; // current task id number 0006 ; extern unsigned long int system_tick; 0006 ; extern unsigned int cop_cycle; 0006 ; 0006 ; 0006 ; // task control block 0006 ; extern struct task_block { 0006 ; void (*address)(); // Address of the task 0006 ; unsigned char id; // ID of task 0006 ; char name[9]; // Name 0006 ; enum task_state state; // State 0006 ; unsigned char priority; // Priority 0006 ; unsigned long int period_tick; // for determining if deadline is up 0006 ; unsigned int interrupt_msg_box; // flags for pending interrupts 0006 ; enum message_box message; // misc flags 0006 ; unsigned char message_data[2]; // data for misc_msg_box flags 0006 ; unsigned char *heap_ptr; // heap addr while not current task 0006 ; unsigned int heap_size; // heap size 0006 ; unsigned char *frame_ptr; // CCR pointer 0006 ; }; 0006 ; 0006 ; 0006 ; // resource control block 0006 ; extern struct resource_block { 0006 ; unsigned char id; // ID of resource 0006 ; char name[5]; // Name of resource 0006 ; enum resource_state state; // State (busy, free...) 0006 ; unsigned char owner; // Current resource owner 0006 ; signed char queue[3]; // Tasks waiting on resource 0006 ; unsigned char queue_ptr; // Next free spot in queue 0006 ; }; 0006 ; 0006 ; 0006 ; extern struct task_block *task[MAXTASKS]; 0006 ; extern struct resource_block resource[NUMRESOURCES]; 0006 ; 0006 ; 0006 ; extern char error_msg[9][25]; 0006 ; extern char error_src[5][18]; 0006 ; 0006 ; 0006 ; extern char kdb_trace; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; main() { 0006 ; 0006 ; // LOCAL VARIABLES 0006 ; int result, id; 0006 ; unsigned int i, addr, temp_heap_size; 0006 ; unsigned char *temp_heap_ptr, temp, priority_check; 0006 ; unsigned int deadline; 0006 ; 0006 ; extern int _bss_end, _textmode; 0006 ; 0006 ; _textmode = 1; // maps '\n' to "CR/LF" for Windows terminals 0006 CC0001 ldd #1 0009 7C0000 std __textmode 000C ; current = 0; // start the shell first 000C CC0000 ldd #0 000F 7C0000 std _current 0012 ; cop_cycle = 0; // fresh watchdog 0012 CC0000 ldd #0 0015 7C0000 std _cop_cycle 0018 CC0000 ldd #0 001B 6C16 std -10,x 001D 2021 bra L7 001F L4: 001F EC16 ldd -10,x 0021 59 lsld 0022 C30000 addd #_task_ptr 0025 B7C6 xgdy 0027 CC0000 ldd #0 002A 6C40 std 0,y 002C EC16 ldd -10,x 002E 59 lsld 002F C30000 addd #_task 0032 B7C6 xgdy 0034 CC0000 ldd #0 0037 6C40 std 0,y 0039 L5: 0039 EC16 ldd -10,x 003B C30001 addd #1 003E 6C16 std -10,x 0040 L7: 0040 ; 0040 ; 0040 ; // initialize the task pointer array and the tcb array. 0040 ; for (i=0; imessage && STATE_FLAG) { 0169 EC16 ldd -10,x 016B 59 lsld 016C C30000 addd #_task 016F B7C6 xgdy 0171 ED40 ldy 0,y 0173 E7E814 tst 20,y 0176 2732 beq L46 0178 ; // set task state to what the message says 0178 ; task[i]->state = task[i]->message_data[STATE_BOX]; 0178 EC16 ldd -10,x 017A 59 lsld 017B C30000 addd #_task 017E B7C6 xgdy 0180 ED40 ldy 0,y 0182 6DE1E6 sty -26,x 0185 EDE1E6 ldy -26,x 0188 E6E815 ldab 21,y 018B EDE1E6 ldy -26,x 018E 6B4C stab 12,y 0190 ; // clear the STATE_FLAG 0190 ; task[i]->message &= ~(STATE_FLAG); 0190 EC16 ldd -10,x 0192 59 lsld 0193 C30000 addd #_task 0196 B7C6 xgdy 0198 EC40 ldd 0,y 019A C30014 addd #20 019D 6CE1E4 std -28,x 01A0 B746 tfr d,y 01A2 35 pshy ; spill 01A3 EDE1E4 ldy -28,x 01A6 31 puly ; reload 01A7 0D4001 bclr 0,y,#0x1 01AA ; #ifdef KDB_TRACE_LEVEL_2 01AA ; if (kdb_trace) puts("kDB2.3-2a"); 01AA ; #endif 01AA ; } 01AA L46: 01AA L41: 01AA EC16 ldd -10,x 01AC C30001 addd #1 01AF 6C16 std -10,x 01B1 L43: 01B1 EC16 ldd -10,x 01B3 8C0008 cpd #8 01B6 25A3 blo L40 01B8 ; #ifdef KDB_TRACE_LEVEL_2 01B8 ; if (kdb_trace) puts("kDB2.3-2b"); 01B8 ; #endif 01B8 ; } 01B8 ; #ifdef KDB_TRACE_LEVEL_1 01B8 ; if (kdb_trace) puts("kDB2.3-1"); 01B8 F70000 tst _kdb_trace 01BB 2706 beq L48 01BD CC0579 ldd #L50 01C0 160000 jsr _puts 01C3 L48: 01C3 CC0000 ldd #0 01C6 6C16 std -10,x 01C8 206A bra L54 01CA L51: 01CA ; #endif 01CA ; 01CA ; 01CA ; 01CA ; // RT PRIORITY BLOCK: 01CA ; // set the current task id based on priority and deadline 01CA ; 01CA ; // determine if the deadline is up for idle tasks 01CA ; /* deadline, is equal to period plus an initial time (t0) reference 01CA ; (t0 = system_tick). Period = priority + 1. 01CA ; Changing the state from idle to PENDING occurs here. */ 01CA ; for (i=0; istate == IDLE) { 01CA EC16 ldd -10,x 01CC 59 lsld 01CD C30000 addd #_task 01D0 B7C6 xgdy 01D2 ED40 ldy 0,y 01D4 E74C tst 12,y 01D6 2655 bne L55 01D8 ; deadline = task[i]->period_tick + (task[i]->priority + 1); 01D8 EC16 ldd -10,x 01DA 59 lsld 01DB C30000 addd #_task 01DE B7C6 xgdy 01E0 ED40 ldy 0,y 01E2 6DE1E6 sty -26,x 01E5 EDE1E6 ldy -26,x 01E8 E64D ldab 13,y 01EA 87 clra 01EB C30001 addd #1 01EE 160000 jsr __d2lreg2 01F1 EDE1E6 ldy -26,x 01F4 194E leay 14,y 01F6 1802401C movw 0,y,-4,x 01FA 1802421E movw 2,y,-2,x 01FE 160000 jsr __ladd 0201 160000 jsr __lreg2d 0204 6C14 std -12,x 0206 ; if (system_tick >= deadline) { 0206 CD0000 ldy #_system_tick 0209 1802401C movw 0,y,-4,x 020D 1802421E movw 2,y,-2,x 0211 EC14 ldd -12,x 0213 6C1A std -6,x 0215 1800180000 movw #0,-8,x 021A 160000 jsr __lcmp 021D 250E blo L57 021F ; task[i]->state = PENDING; // change state at deadline 021F EC16 ldd -10,x 0221 59 lsld 0222 C30000 addd #_task 0225 B7C6 xgdy 0227 ED40 ldy 0,y 0229 C601 ldab #1 022B 6B4C stab 12,y 022D ; #ifdef KDB_TRACE_LEVEL_2 022D ; if (kdb_trace) puts("kDB2.4-2"); 022D ; #endif 022D ; } 022D L57: 022D ; } 022D L55: 022D L52: 022D EC16 ldd -10,x 022F C30001 addd #1 0232 6C16 std -10,x 0234 L54: 0234 EC16 ldd -10,x 0236 8C0008 cpd #8 0239 258F blo L51 023B ; // if (task[i]->message) {} ??? 023B ; } 023B ; #ifdef KDB_TRACE_LEVEL_1 023B ; if (kdb_trace) puts("kDB2.4-1"); 023B F70000 tst _kdb_trace 023E 2706 beq L59 0240 CC0570 ldd #L61 0243 160000 jsr _puts 0246 L59: 0246 ; #endif 0246 ; 0246 ; 0246 ; // set current = to highest priority pending/running task. 0246 ; priority_check = 255; // lowest possible 0246 C6FF ldab #255 0248 6B13 stab -13,x 024A CC0000 ldd #0 024D 6C16 std -10,x 024F 2053 bra L65 0251 L62: 0251 ; 0251 ; for (i=0; istate == PENDING) || (task[i]->state == RUNNING)) { 027A ; if (task[i]->priority <= priority_check) { 027A EC16 ldd -10,x 027C 59 lsld 027D C30000 addd #_task 0280 B7C6 xgdy 0282 ED40 ldy 0,y 0284 E64D ldab 13,y 0286 E113 cmpb -13,x 0288 2213 bhi L71 028A ; current = i; 028A 1805160000 movw -10,x,_current 028F ; priority_check = task[i]->priority; 028F EC16 ldd -10,x 0291 59 lsld 0292 C30000 addd #_task 0295 B7C6 xgdy 0297 ED40 ldy 0,y 0299 E64D ldab 13,y 029B 6B13 stab -13,x 029D ; #ifdef KDB_TRACE_LEVEL_2 029D ; if (kdb_trace) puts("kDB2.5-2"); 029D ; #endif 029D ; } 029D L71: 029D ; } 029D L68: 029D ; } 029D L66: 029D L63: 029D EC16 ldd -10,x 029F C30001 addd #1 02A2 6C16 std -10,x 02A4 L65: 02A4 EC16 ldd -10,x 02A6 8C0008 cpd #8 02A9 25A6 blo L62 02AB ; } 02AB ; #ifdef KDB_TRACE_LEVEL_1 02AB ; if (kdb_trace) puts("kDB2.5-1"); 02AB F70000 tst _kdb_trace 02AE 2706 beq L73 02B0 CC0567 ldd #L75 02B3 160000 jsr _puts 02B6 L73: 02B6 FC0000 ldd _current 02B9 59 lsld 02BA C30000 addd #_task 02BD B7C6 xgdy 02BF ED40 ldy 0,y 02C1 E64C ldab 12,y 02C3 87 clra 02C4 6CE1E6 std -26,x 02C7 272A beq L79 02C9 ECE1E6 ldd -26,x 02CC 8C0001 cpd #1 02CF 2733 beq L83 02D1 ECE1E6 ldd -26,x 02D4 8C0002 cpd #2 02D7 18270090 lbeq L90 02DB ECE1E6 ldd -26,x 02DE 8C0003 cpd #3 02E1 182700FB lbeq L98 02E5 ECE1E6 ldd -26,x 02E8 8C0004 cpd #4 02EB 182700FE lbeq L102 02EF 18200107 lbra L76 02F3 X0: 02F3 ; #endif 02F3 ; 02F3 ; 02F3 ; 02F3 ; // DISPATCH, or otherwise deal with the current task 02F3 ; // KDB_TRACE Section 3 02F3 ; 02F3 ; #ifdef KDB_TRACE_LEVEL_2 02F3 ; if (kdb_trace) { 02F3 ; printf("task[%d]->state = %d\n", current, task[current]->state); 02F3 ; printf("task[%d]->prior = %d\n", current, task[current]->priority); 02F3 ; } 02F3 ; #endif 02F3 ; 02F3 ; switch (task[current]->state) { 02F3 L79: 02F3 ; case IDLE: // skip task 02F3 ; #ifdef KDB_TRACE_LEVEL_1 02F3 ; if (kdb_trace) puts("kDB3.1-1"); 02F3 F70000 tst _kdb_trace 02F6 1827010C lbeq L77 02FA CC055E ldd #L82 02FD 160000 jsr _puts 0300 ; #endif 0300 ; break; 0300 18200102 lbra L77 0304 L83: 0304 ; case PENDING: // ready and waiting to run 0304 ; task[current]->state = RUNNING; 0304 FC0000 ldd _current 0307 59 lsld 0308 C30000 addd #_task 030B B7C6 xgdy 030D ED40 ldy 0,y 030F C602 ldab #2 0311 6B4C stab 12,y 0313 ; task[current]->period_tick = system_tick; 0313 FC0000 ldd _current 0316 59 lsld 0317 C30000 addd #_task 031A B7C6 xgdy 031C ED40 ldy 0,y 031E 194E leay 14,y 0320 35 pshy ; spill 0321 CD0000 ldy #_system_tick 0324 1802401C movw 0,y,-4,x 0328 1802421E movw 2,y,-2,x 032C 31 puly ; reload 032D 18021C40 movw -4,x,0,y 0331 18021E42 movw -2,x,2,y 0335 ; #ifdef KDB_TRACE_LEVEL_1 0335 ; if (kdb_trace) puts("kDB3.2-1"); 0335 F70000 tst _kdb_trace 0338 2706 beq L84 033A CC0555 ldd #L86 033D 160000 jsr _puts 0340 L84: 0340 ; #endif 0340 ; #ifdef KDB_TRACE_LEVEL_2 0340 ; if (kdb_trace) { 0340 ; //puts("kDB3.2-2"); 0340 ; putchar('S'); 0340 ; putchar(current+48); 0340 ; putchar('\n'); 0340 ; } 0340 ; #endif 0340 ; (*task_ptr[current])(); // start the task 0340 FC0000 ldd _current 0343 59 lsld 0344 C30000 addd #_task_ptr 0347 B7C6 xgdy 0349 ED40 ldy 0,y 034B 1540 jsr 0,y 034D ; task[current]->state = IDLE; // task finished 034D FC0000 ldd _current 0350 59 lsld 0351 C30000 addd #_task 0354 B7C6 xgdy 0356 ED40 ldy 0,y 0358 694C clr 12,y 035A ; #ifdef KDB_TRACE_LEVEL_1 035A ; if (kdb_trace) puts("kDB3.3-1"); 035A F70000 tst _kdb_trace 035D 182700A5 lbeq L77 0361 CC054C ldd #L89 0364 160000 jsr _puts 0367 ; #endif 0367 ; #ifdef KDB_TRACE_LEVEL_2 0367 ; if (kdb_trace) { 0367 ; //puts("kDB3.3-2"); 0367 ; putchar('S'); 0367 ; putchar(current+48); 0367 ; putchar('\n'); 0367 ; } 0367 ; #endif 0367 ; break; 0367 1820009B lbra L77 036B L90: 036B ; case RUNNING: // interrupted. continue running. 036B ; // restore the task heap to the stack 036B ; #ifdef KDB_TRACE_LEVEL_1 036B ; if (kdb_trace) puts("kDB3.4-1"); 036B F70000 tst _kdb_trace 036E 2706 beq L91 0370 CC0543 ldd #L93 0373 160000 jsr _puts 0376 L91: 0376 ; #endif 0376 ; #ifdef KDB_TRACE_LEVEL_2 0376 ; if (kdb_trace) { 0376 ; //puts("kDB3.4-2"); 0376 ; putchar('R'); 0376 ; putchar(current+48); 0376 ; putchar('\n'); 0376 ; } 0376 ; #endif 0376 ; temp_heap_size = task[current]->heap_size; 0376 FC0000 ldd _current 0379 59 lsld 037A C30000 addd #_task 037D B7C6 xgdy 037F ED40 ldy 0,y 0381 EDE819 ldy 25,y 0384 6D11 sty -15,x 0386 ; temp_heap_ptr = task[current]->heap_ptr; 0386 FC0000 ldd _current 0389 59 lsld 038A C30000 addd #_task 038D B7C6 xgdy 038F ED40 ldy 0,y 0391 EDE817 ldy 23,y 0394 6DE1EE sty -18,x 0397 CC0000 ldd #0 039A 6C16 std -10,x 039C 2025 bra L97 039E L94: 039E EC16 ldd -10,x 03A0 E3E1EE addd -18,x 03A3 B7C6 xgdy 03A5 E640 ldab 0,y 03A7 6B10 stab -16,x 03A9 FC0000 ldd _main_frame_ptr 03AC A311 subd -15,x 03AE 6CE1E2 std -30,x 03B1 EC16 ldd -10,x 03B3 E3E1E2 addd -30,x 03B6 B7C6 xgdy 03B8 E610 ldab -16,x 03BA 6B40 stab 0,y 03BC L95: 03BC EC16 ldd -10,x 03BE C30001 addd #1 03C1 6C16 std -10,x 03C3 L97: 03C3 ; for (i=0; iframe_ptr; 03C9 FC0000 ldd _current 03CC 59 lsld 03CD C30000 addd #_task 03D0 B7C6 xgdy 03D2 ED40 ldy 0,y 03D4 EDE81B ldy 27,y 03D7 7D0004 sty _temp_task_frame_ptr 03DA ; asm("LDS _temp_task_frame_ptr"); 03DA FF0004 LDS _temp_task_frame_ptr 03DD 03DD ; asm("RTI"); 03DD 0B RTI 03DE 03DE ; break; 03DE 2026 bra L77 03E0 L98: 03E0 ; case WAITING: // waiting on a resource 03E0 ; #ifdef KDB_TRACE_LEVEL_1 03E0 ; if (kdb_trace) puts("kDB3.5-1"); 03E0 F70000 tst _kdb_trace 03E3 2721 beq L77 03E5 CC053A ldd #L101 03E8 160000 jsr _puts 03EB ; #endif 03EB ; break; 03EB 2019 bra L77 03ED L102: 03ED ; case STOPPED: // done running until later 03ED ; #ifdef KDB_TRACE_LEVEL_1 03ED ; if (kdb_trace) puts("kDB3.6-1"); 03ED F70000 tst _kdb_trace 03F0 2714 beq L77 03F2 CC0531 ldd #L105 03F5 160000 jsr _puts 03F8 ; #endif 03F8 ; break; 03F8 200C bra L77 03FA L76: 03FA ; default: // shouldn't happen, but, error if so. 03FA ; puts("KERNEL: task state error\n"); 03FA CC0517 ldd #L106 03FD 160000 jsr _puts 0400 ; exit(1); 0400 CC0001 ldd #1 0403 160000 jsr _exit 0406 ; } // end switch 0406 L77: 0406 L30: 0406 1820FD1A lbra L29 040A X1: 040A ; 040A ; } // end while(1) 040A ; 040A ; return 0; 040A CC0000 ldd #0 040D L3: 040D B757 tfr x,s 040F 30 pulx 0410 .dbline 0 ; func end 0410 3D rts 0411 ; lreg1 -> -4,x 0411 ; lreg2 -> -8,x 0411 ; ?temp -> -16,x 0411 ; local_thp -> -14,x 0411 ; frame_size -> -12,x 0411 ; i -> -10,x 0411 _RTI_handler:: 0411 34 pshx 0412 B775 tfr s,x 0414 1BF1EC leas -20,sp 0417 ; 0417 ; } // end main() 0417 ; 0417 ; 0417 ; 0417 ; #pragma interrupt_handler RTI_handler() 0417 ; 0417 ; void RTI_handler(void) { 0417 ; 0417 ; size_t frame_size; 0417 ; unsigned int i; 0417 ; unsigned char *local_thp; 0417 ; 0417 ; 0417 ; //ACKNOWLEDGE THE INTERRUPT 0417 ; INTR_OFF(); // redundant. automatically done by the processor 0417 1410 sei 0419 0419 ; RTIFLG = 0x0080; // acknowledge/clear the interrupt 0419 C680 ldab #128 041B 7B0015 stab 0x15 041E ; 041E ; 041E ; #ifdef KDB_TRACE_LEVEL_1 041E ; if (kdb_trace) putchar('.'); 041E F70000 tst _kdb_trace 0421 2706 beq L108 0423 CC002E ldd #46 0426 160000 jsr _putchar 0429 L108: 0429 ; #endif 0429 ; 0429 ; 0429 ; // SET THE FRAME POINTER for the interupted task. 0429 ; // should point to the CCR entry on the stack. 0429 ; asm("TFR x,d"); // start of RTI stack 0429 B754 TFR x,d 042B 042B ; asm("ADDD #2"); // adjust to CCR stack entry 042B C30002 ADDD #2 042E 042E ; asm("STD _temp_task_frame_ptr"); // put into task_frame_ptr 042E 7C0004 STD _temp_task_frame_ptr 0431 0431 ; task[current]->frame_ptr = temp_task_frame_ptr; 0431 FC0000 ldd _current 0434 59 lsld 0435 C30000 addd #_task 0438 B7C6 xgdy 043A ED40 ldy 0,y 043C FC0004 ldd _temp_task_frame_ptr 043F 6CE81B std 27,y 0442 ; 0442 ; 0442 ; 0442 ; //PLACE CURRENT TASK CONTEXT ONTO THE HEAP 0442 ; // determine size of heap segment needed 0442 ; frame_size = main_frame_ptr - temp_task_frame_ptr; // always positive 0442 FC0000 ldd _main_frame_ptr 0445 B30004 subd _temp_task_frame_ptr 0448 6C14 std -12,x 044A ; task[current]->heap_size = (int)frame_size; 044A FC0000 ldd _current 044D 59 lsld 044E C30000 addd #_task 0451 B7C6 xgdy 0453 ED40 ldy 0,y 0455 EC14 ldd -12,x 0457 6CE819 std 25,y 045A ; //printf("frame size: %d\n", frame_size); 045A ; 045A ; // reallocate heap memory 045A ; //printf("heap_ptr = %d\n", task[current]->heap_ptr); 045A ; task[current]->heap_ptr = realloc(task[current]->heap_ptr, frame_size); 045A 18021480 movw -12,x,0,sp 045E FC0000 ldd _current 0461 59 lsld 0462 C30000 addd #_task 0465 B7C6 xgdy 0467 EC40 ldd 0,y 0469 C30017 addd #23 046C 6C10 std -16,x 046E ECE3FFF0 ldd [-16,x] 0472 160000 jsr _realloc 0475 6CE1EE std -18,x 0478 ED10 ldy -16,x 047A ECE1EE ldd -18,x 047D 6C40 std 0,y 047F ; local_thp = task[current]->heap_ptr; 047F FC0000 ldd _current 0482 59 lsld 0483 C30000 addd #_task 0486 B7C6 xgdy 0488 ED40 ldy 0,y 048A EDE817 ldy 23,y 048D 6D12 sty -14,x 048F ; 048F ; 048F ; if (local_thp == NULL) { 048F EC12 ldd -14,x 0491 260C bne L110 0493 ; #ifdef KERNEL_ERROR_MSGS 0493 ; //printf("local_thp: %d\n", local_thp); 0493 ; //printf("heap: %d bytes\n", get_free_memory()); 0493 ; puts("out of heap space!"); 0493 CC0504 ldd #L112 0496 160000 jsr _puts 0499 ; #endif 0499 ; exit(0); 0499 CC0000 ldd #0 049C 160000 jsr _exit 049F ; } 049F L110: 049F CC0000 ldd #0 04A2 6C16 std -10,x 04A4 201A bra L116 04A6 L113: 04A6 EC16 ldd -10,x 04A8 F30004 addd _temp_task_frame_ptr 04AB B7C6 xgdy 04AD E640 ldab 0,y 04AF 3B pshd ; spill 04B0 EC16 ldd -10,x 04B2 E312 addd -14,x 04B4 B7C6 xgdy 04B6 3A puld ; reload 04B7 6B40 stab 0,y 04B9 L114: 04B9 EC16 ldd -10,x 04BB C30001 addd #1 04BE 6C16 std -10,x 04C0 L116: 04C0 ; 04C0 ; // transfer task frame to the heap one byte at a time. 04C0 ; // assumes the heap grows from low to high addr. 04C0 ; for(i=0; i