.module kernel.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 0006 _kdb_trace:: 0006 .blkb 2 .area idata 0006 0001 .word 1 .area data 0008 _kdb_trace_cycle:: 0008 .blkb 2 .area idata 0008 0000 .word 0 .area data .area text 0000 _error_msg:: 0000 756E696D706C696D656E746564206675 .byte 'u,'n,'i,'m,'p,'l,'i,'m,'e,'n,'t,'e,'d,32,'f,'u 0010 6E6374696F6E00 .byte 'n,'c,'t,'i,'o,'n,0 0017 0000 .byte 0,0 0019 73796E746178206572726F7200 .byte 's,'y,'n,'t,'a,'x,32,'e,'r,'r,'o,'r,0 0026 00000000000000000000 .word 0,0,0,0,0 0030 0000 .byte 0,0 0032 696C6C6567616C207461736B20494400 .byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'I,'D,0 0042 000000000000000000 .byte 0,0,0,0,0,0,0,0,0 004B 696C6C6567616C207461736B20737461 .byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'s,'t,'a 005B 746500 .byte 't,'e,0 005E 000000000000 .byte 0,0,0,0,0,0 0064 696C6C6567616C207461736B20707269 .byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'p,'r,'i 0074 6F7269747900 .byte 'o,'r,'i,'t,'y,0 007A 000000 .byte 0,0,0 007D 6F7574206F66206D656D6F727900 .byte 'o,'u,'t,32,'o,'f,32,'m,'e,'m,'o,'r,'y,0 008B 00000000000000000000 .word 0,0,0,0,0 0095 00 .byte 0 0096 696C6C6567616C207265736F75726365 .byte 'i,'l,'l,'e,'g,'a,'l,32,'r,'e,'s,'o,'u,'r,'c,'e 00A6 20494400 .byte 32,'I,'D,0 00AA 0000000000 .byte 0,0,0,0,0 00AF 696C6C6567616C207265736F75726365 .byte 'i,'l,'l,'e,'g,'a,'l,32,'r,'e,'s,'o,'u,'r,'c,'e 00BF 20737461746500 .byte 32,'s,'t,'a,'t,'e,0 00C6 0000 .byte 0,0 00C8 63616E6E6F7420637265617465207461 .byte 'c,'a,'n,'n,'o,'t,32,'c,'r,'e,'a,'t,'e,32,'t,'a 00D8 736B00 .byte 's,'k,0 00DB 000000000000 .byte 0,0,0,0,0,0 00E1 _error_src:: 00E1 6B65726E656C206572726F723A00 .byte 'k,'e,'r,'n,'e,'l,32,'e,'r,'r,'o,'r,58,0 00EF 00000000 .byte 0,0,0,0 00F3 6B65726E656C2E63206572726F723A00 .byte 'k,'e,'r,'n,'e,'l,46,'c,32,'e,'r,'r,'o,'r,58,0 0103 0000 .byte 0,0 0105 6B65726E656C20525449206572726F72 .byte 'k,'e,'r,'n,'e,'l,32,'R,'T,'I,32,'e,'r,'r,'o,'r 0115 3A00 .byte 58,0 0117 7368656C6C206572726F723A00 .byte 's,'h,'e,'l,'l,32,'e,'r,'r,'o,'r,58,0 0124 0000000000 .byte 0,0,0,0,0 0129 73656D6C69622E63206572726F723A00 .byte 's,'e,'m,'l,'i,'b,46,'c,32,'e,'r,'r,'o,'r,58,0 0139 0000 .byte 0,0 013B ; lreg1 -> -4,x 013B ; lreg2 -> -8,x 013B ; ?temp -> -19,x 013B ; ?temp -> -19,x 013B ; ?temp -> -19,x 013B ; ?temp -> -21,x 013B ; ?temp -> -19,x 013B ; id -> -17,x 013B ; result -> -15,x 013B ; priority_check -> -13,x 013B ; deadline -> -12,x 013B ; i -> -10,x 013B _main:: 013B 34 pshx 013C B775 tfr s,x 013E 1BF1EA leas -22,sp 0141 ; /* RLPOS: RLPotter Operating System 0141 ; 0141 ; Version 0.7.1 for the 68HC12D60A microcontroller 0141 ; by Ryan Potter 0141 ; ryan@rlpotter.com 0141 ; 0141 ; Compiled with the ImageCraft ICC12 compiler v6.15A 0141 ; - 912D60 Single Chip Mode 0141 ; - printf option: long 0141 ; 0141 ; 0141 ; v0.7.1 April 27, 2003: 0141 ; - implemented the TOF_handler interrupt for use with sysTime. 0141 ; brings time resolution from 64 ms to 16 ms. 0141 ; - added kernel funct: get_sysTime(), set_sysTime(); shell cmd: time. 0141 ; - now tasks are 'int f()', and must return a value to the kernel 0141 ; when exiting. kernel doesn't handle it yet, though. 0141 ; - in shell, now names of tasks are shell commands (dynamic). 0141 ; - put all kernel initialization code into kernel_init(). 0141 ; - added kernel funct: remove_task(). 0141 ; 0141 ; 0141 ; v0.7 April 25, 2003: 11174 bytes: 0141 ; - combined kernel.c & semlib.c with rlpos.c to make one big kernel.c. 0141 ; - changed context switch mechanism to give each task a dedicated 0141 ; stack, making the kernel context switches >400% faster. 0141 ; - added a basic timer task that will eventually keep system time/date. 0141 ; 0141 ; v0.6 April 24, 2003: 11042 bytes 0141 ; - made the task block and the task control block dynamic, so that 0141 ; now tasks can create tasks, and can also start/stop them. 0141 ; - implemented the sysInit() task for kicking off a user system. 0141 ; - implemented a kernel debug command for tracing code execution. 0141 ; - implemented small msg box system in kernel for tasks. 0141 ; - implemented COP watchdog reset timer. 0141 ; - added system resources to semlib. 0141 ; - added skeleton ISR_handler() code for the other interrupts. 0141 ; - implemented _HC12Setup.c to initialize/harden the system. 0141 ; 0141 ; v0.5 April 16, 2003: 0141 ; - added priority preemption. 0141 ; - finished kernel task state switcher. 0141 ; - it is now officially a legitimate 0141 ; rate monotonic 0141 ; priority preemptive 0141 ; multitasking 0141 ; Real Time Operating System :) 0141 ; - made kernel.c and semlib.c consistent with the 0141 ; rest of the kernel. 0141 ; - included the early framework for a msg box system. 0141 ; 0141 ; v0.4 April 13, 2003: 8096 bytes 0141 ; - gerneralized the shell command-line input parser: 0141 ; cmd (up to 32 chars). 0141 ; - added kernel and shell functions. 0141 ; 0141 ; v0.3 April 12, 2003: 6155 bytes 0141 ; - added a beginning shell user interface. 0141 ; - added a resource control block and basic semaphore functions. 0141 ; - added basic kernel functions. 0141 ; 0141 ; v0.2 April 9, 2003: 0141 ; - able to round-robin with RTI interrupt. 0141 ; - bonified/certified multitasking with 3 tasks. :) 0141 ; 0141 ; v0.1 April 3, 2003: 0141 ; - able to round-robin without interrupts. 0141 ; - not multitasking, really. 0141 ; 0141 ; v0.0 started April 1, 2003; 0 bytes 0141 ; - no idea where to start. 0141 ; - don't want to look at anyone else's work. ;0) 0141 ; 0141 ; 0141 ; 0141 ; 0141 ; Architecture/C assumptions: 0141 ; 1) 'D' register is the accumulator 0141 ; 2) 'X' register points to the top of the current stack 0141 ; 3) 'Y' register is for general use in indexed operations 0141 ; 4) the heap grows upward and mem segments allocated by malloc, 0141 ; realloc, and calloc are linear and contiguous. 0141 ; 5) the stack grows downwards, and there is no boundary checking. 0141 ; 6) chars are one byte 0141 ; ints are two bytes 0141 ; longs are 4 bytes 0141 ; 7) only 1536 (1.5k) of the 2k ram are available 0141 ; 8) register base is 0x0000 0141 ; 0141 ; Potential problem areas: 0141 ; 1) 'running' section of the kernel get's compiled using extra 0141 ; push and pop instructions 0141 ; 2) run out of ram (global + stack + heap) 0141 ; 0141 ; */ 0141 ; 0141 ; 0141 ; 0141 ; #include <912d60.h> 0141 ; #include 0141 ; #include 0141 ; #include 0141 ; #include "kernel.h" 0141 ; 0141 ; 0141 ; 0141 ; // FUNCTION PROTOTYPES 0141 ; void RTI_handler(void); 0141 ; int sysInit(void); 0141 ; int shell(void); 0141 ; int idleTask(void); 0141 ; int sysTime(void); 0141 ; int (*task_ptr[MAXTASKS])(void); 0141 ; 0141 ; 0141 ; 0141 ; 0141 ; // GLOBAL VARIABLES 0141 ; unsigned char *main_frame_ptr = NULL; // bottom of main() frame 0141 ; unsigned char *main_frame_x_ptr = NULL; // top of main() frame (x-reg ptr) 0141 ; unsigned char *temp_task_frame_ptr = NULL; // temp CCR pointer for RTI 0141 ; 0141 ; 0141 ; unsigned int current; // current task id number 0141 ; unsigned long int system_tick; 0141 ; unsigned int cop_cycle; 0141 ; 0141 ; unsigned long int time_tick; // one tick every x microseconds 0141 ; 0141 ; 0141 ; // task control block 0141 ; typedef struct task_block { 0141 ; int (*address)(); // Address of the task 0141 ; unsigned char id; // ID of task 0141 ; char name[9]; // Name 0141 ; enum task_state state; // State 0141 ; unsigned char priority; // Priority 0141 ; unsigned long int period_tick; // for determining if deadline is up 0141 ; unsigned int interrupt_msg_box; // flags for pending interrupts 0141 ; enum message_box message; // misc flags 0141 ; unsigned char message_data[2]; // data for misc_msg_box flags 0141 ; unsigned int stack_size; // heap allocated for task stack 0141 ; unsigned char *top_of_stack; // top of task stack in the heap 0141 ; unsigned char *frame_ptr; // CCR pointer in idle stack 0141 ; }; 0141 ; 0141 ; 0141 ; // resource control block 0141 ; typedef struct resource_block { 0141 ; unsigned char id; // ID of resource 0141 ; char name[5]; // Name of resource 0141 ; enum resource_state state; // State (busy, free...) 0141 ; unsigned char owner; // Current resource owner 0141 ; signed char queue[3]; // Tasks waiting on resource 0141 ; unsigned char queue_ptr; // Next free spot in queue 0141 ; }; 0141 ; 0141 ; 0141 ; struct task_block *task[MAXTASKS]; 0141 ; struct resource_block resource[NUMRESOURCES]; 0141 ; 0141 ; 0141 ; int kdb_trace = 1; 0141 ; int kdb_trace_cycle = 0; 0141 ; 0141 ; 0141 ; struct time { 0141 ; char hours; 0141 ; char minutes; 0141 ; char seconds; 0141 ; int milliseconds; 0141 ; }; 0141 ; 0141 ; int exit_status; 0141 ; 0141 ; 0141 ; 0141 ; // global interrupt flags 0141 ; //unsigned int interrupt_flags_ADC; 0141 ; //unsigned int interrupt_flags_TC; 0141 ; 0141 ; 0141 ; 0141 ; 0141 ; // error massages 0141 ; const char error_msg[][25] = {"unimplimented function", // error 0 0141 ; "syntax error", // error 1 0141 ; "illegal task ID", // error 2 0141 ; "illegal task state", // error 3 0141 ; "illegal task priority", // error 4 0141 ; "out of memory", // error 5 0141 ; "illegal resource ID", // error 6 0141 ; "illegal resource state", // error 7 0141 ; "cannot create task" // error 8 0141 ; }; 0141 ; const char error_src[][18] = {"kernel error:", // source 0 0141 ; "kernel.c error:", // source 1 0141 ; "kernel RTI error:", // source 2 0141 ; "shell error:", // source 3 0141 ; "semlib.c error:" // source 4 0141 ; }; 0141 ; 0141 ; 0141 ; 0141 ; 0141 ; 0141 ; main() { 0141 ; 0141 ; // LOCAL VARIABLES 0141 ; int result, id, i; 0141 ; unsigned char priority_check; 0141 ; unsigned int deadline; 0141 ; 0141 ; 0141 ; 0141 ; // INITIALIZE the kernel 0141 ; kernel_init(); 0141 160415 jsr _kernel_init 0144 ; 0144 ; 0144 ; // save SP value for use in the RTI 0144 ; asm("TFR s,d"); 0144 B774 TFR s,d 0146 0146 ; asm("STD _main_frame_ptr"); 0146 7C0000 STD _main_frame_ptr 0149 0149 ; // save X reg value for use in the RTI 0149 ; asm("TFR x,d"); 0149 B754 TFR x,d 014B 014B ; asm("STD _main_frame_x_ptr"); 014B 7C0002 STD _main_frame_x_ptr 014E 014E 1820022A lbra L5 0152 L4: 0152 ; 0152 ; 0152 ; 0152 ; // MULTITASKING KERNEL: Priority Preemptive, Real Time, multitasking 0152 ; // KDB_TRACE Section 2 0152 ; while(1) { 0152 ; 0152 ; //------------------------------- 0152 ; /* REENTRY POINT after either 0152 ; 1) task finishes, or 0152 ; 2) RTI 0152 ; */ 0152 ; //------------------------------- 0152 ; 0152 ; 0152 ; if (kdb_trace_cycle >= KDB_CYCLES) 0152 FC0008 ldd _kdb_trace_cycle 0155 8C0004 cpd #4 0158 2D06 blt L7 015A ; kdb_trace = 0; 015A CC0000 ldd #0 015D 7C0006 std _kdb_trace 0160 L7: 0160 ; 0160 ; #ifdef KDB_TRACE_LEVEL_1 0160 ; if (kdb_trace) puts("kDB2.1"); 0160 ; #endif 0160 ; 0160 ; 0160 ; /* No RTI interrupts allowed inside of main(). Only allowed 0160 ; inside of non-critical sections of tasks */ 0160 ; //INTR_OFF(); 0160 ; 0160 ; 0160 ; // PET THE DOG: cop watchdog reset timer (pet freq = 2x COP freq) 0160 ; if (cop_cycle == 4) { 0160 FC0046 ldd _cop_cycle 0163 8C0004 cpd #4 0166 2610 bne L9 0168 ; COP_PET(0x55); 0168 C655 ldab #85 016A 7B0017 stab 0x17 016D ; COP_PET(0xAA); 016D C6AA ldab #170 016F 7B0017 stab 0x17 0172 ; cop_cycle = 0; 0172 CC0000 ldd #0 0175 7C0046 std _cop_cycle 0178 ; //putchar(':'); 0178 ; } 0178 L9: 0178 CC0000 ldd #0 017B 6C16 std -10,x 017D L11: 017D ; #ifdef KDB_TRACE_LEVEL_1 017D ; if (kdb_trace) puts("kDB2.2-1"); 017D ; #endif 017D ; 017D ; 017D ; 017D ; // CHANGE STATES ACCORDING TO MESSAGES 017D ; // 'waiting' needs to have highest precedence here 017D ; for (i=0; imessage && STATE_FLAG) { 018B EC16 ldd -10,x 018D 59 lsld 018E C30032 addd #_task 0191 B7C6 xgdy 0193 ED40 ldy 0,y 0195 E7E814 tst 20,y 0198 2732 beq L17 019A ; // set task state to what the message says 019A ; task[i]->state = task[i]->message_data[STATE_BOX]; 019A EC16 ldd -10,x 019C 59 lsld 019D C30032 addd #_task 01A0 B7C6 xgdy 01A2 ED40 ldy 0,y 01A4 6DE1ED sty -19,x 01A7 EDE1ED ldy -19,x 01AA E6E815 ldab 21,y 01AD EDE1ED ldy -19,x 01B0 6B4C stab 12,y 01B2 ; // clear the STATE_FLAG 01B2 ; task[i]->message &= ~(STATE_FLAG); 01B2 EC16 ldd -10,x 01B4 59 lsld 01B5 C30032 addd #_task 01B8 B7C6 xgdy 01BA EC40 ldd 0,y 01BC C30014 addd #20 01BF 6CE1EB std -21,x 01C2 B746 tfr d,y 01C4 35 pshy ; spill 01C5 EDE1EB ldy -21,x 01C8 31 puly ; reload 01C9 0D4001 bclr 0,y,#0x1 01CC ; #ifdef KDB_TRACE_LEVEL_2 01CC ; if (kdb_trace) puts("kDB2.3-2a"); 01CC ; #endif 01CC ; } 01CC L17: 01CC L12: 01CC EC16 ldd -10,x 01CE C30001 addd #1 01D1 6C16 std -10,x 01D3 EC16 ldd -10,x 01D5 8C0008 cpd #8 01D8 2DA3 blt L11 01DA CC0000 ldd #0 01DD 6C16 std -10,x 01DF L19: 01DF ; #ifdef KDB_TRACE_LEVEL_2 01DF ; if (kdb_trace) puts("kDB2.3-2b"); 01DF ; #endif 01DF ; } 01DF ; #ifdef KDB_TRACE_LEVEL_1 01DF ; if (kdb_trace) puts("kDB2.3-1"); 01DF ; #endif 01DF ; 01DF ; 01DF ; 01DF ; // RT PRIORITY BLOCK: 01DF ; // set the current task id based on priority and deadline 01DF ; 01DF ; // determine if the deadline is up for idle tasks 01DF ; /* deadline, is equal to period plus an initial time (t0) reference 01DF ; (t0 = system_tick). Period = priority + 1. 01DF ; Changing the state from idle to PENDING occurs here. */ 01DF ; for (i=0; istate == IDLE) { 01DF EC16 ldd -10,x 01E1 59 lsld 01E2 C30032 addd #_task 01E5 B7C6 xgdy 01E7 ED40 ldy 0,y 01E9 E74C tst 12,y 01EB 2655 bne L23 01ED ; deadline = task[i]->period_tick + (task[i]->priority + 1); 01ED EC16 ldd -10,x 01EF 59 lsld 01F0 C30032 addd #_task 01F3 B7C6 xgdy 01F5 ED40 ldy 0,y 01F7 6DE1ED sty -19,x 01FA EDE1ED ldy -19,x 01FD E64D ldab 13,y 01FF 87 clra 0200 C30001 addd #1 0203 160000 jsr __d2lreg2 0206 EDE1ED ldy -19,x 0209 194E leay 14,y 020B 1802401C movw 0,y,-4,x 020F 1802421E movw 2,y,-2,x 0213 160000 jsr __ladd 0216 160000 jsr __lreg2d 0219 6C14 std -12,x 021B ; if (system_tick >= deadline) { 021B CD0048 ldy #_system_tick 021E 1802401C movw 0,y,-4,x 0222 1802421E movw 2,y,-2,x 0226 EC14 ldd -12,x 0228 6C1A std -6,x 022A 1800180000 movw #0,-8,x 022F 160000 jsr __lcmp 0232 250E blo L25 0234 ; task[i]->state = PENDING; // change state at deadline 0234 EC16 ldd -10,x 0236 59 lsld 0237 C30032 addd #_task 023A B7C6 xgdy 023C ED40 ldy 0,y 023E C601 ldab #1 0240 6B4C stab 12,y 0242 ; #ifdef KDB_TRACE_LEVEL_2 0242 ; if (kdb_trace) puts("kDB2.4-2"); 0242 ; #endif 0242 ; } 0242 L25: 0242 ; } 0242 L23: 0242 L20: 0242 EC16 ldd -10,x 0244 C30001 addd #1 0247 6C16 std -10,x 0249 EC16 ldd -10,x 024B 8C0008 cpd #8 024E 2D8F blt L19 0250 ; // if (task[i]->message) {} ??? 0250 ; } 0250 ; #ifdef KDB_TRACE_LEVEL_1 0250 ; if (kdb_trace) puts("kDB2.4-1"); 0250 ; #endif 0250 ; 0250 ; 0250 ; // set current = to highest priority pending/running task. 0250 ; priority_check = 255; // lowest possible 0250 C6FF ldab #255 0252 6B13 stab -13,x 0254 CC0000 ldd #0 0257 6C16 std -10,x 0259 L27: 0259 ; 0259 ; for (i=0; istate == PENDING) || (task[i]->state == RUNNING)) { 0282 ; if (task[i]->priority <= priority_check) { 0282 EC16 ldd -10,x 0284 59 lsld 0285 C30032 addd #_task 0288 B7C6 xgdy 028A ED40 ldy 0,y 028C E64D ldab 13,y 028E E113 cmpb -13,x 0290 2213 bhi L36 0292 ; current = i; 0292 EC16 ldd -10,x 0294 7C004C std _current 0297 ; priority_check = task[i]->priority; 0297 EC16 ldd -10,x 0299 59 lsld 029A C30032 addd #_task 029D B7C6 xgdy 029F ED40 ldy 0,y 02A1 E64D ldab 13,y 02A3 6B13 stab -13,x 02A5 ; #ifdef KDB_TRACE_LEVEL_2 02A5 ; if (kdb_trace) puts("kDB2.5-2"); 02A5 ; #endif 02A5 ; } 02A5 L36: 02A5 ; } 02A5 L33: 02A5 ; } 02A5 L31: 02A5 L28: 02A5 EC16 ldd -10,x 02A7 C30001 addd #1 02AA 6C16 std -10,x 02AC EC16 ldd -10,x 02AE 8C0008 cpd #8 02B1 2DA6 blt L27 02B3 FC004C ldd _current 02B6 59 lsld 02B7 C30032 addd #_task 02BA B7C6 xgdy 02BC ED40 ldy 0,y 02BE E64C ldab 12,y 02C0 87 clra 02C1 6CE1ED std -19,x 02C4 182700B4 lbeq L39 02C8 ECE1ED ldd -19,x 02CB 8C0001 cpd #1 02CE 2722 beq L42 02D0 ECE1ED ldd -19,x 02D3 8C0002 cpd #2 02D6 1827007F lbeq L43 02DA ECE1ED ldd -19,x 02DD 8C0003 cpd #3 02E0 18270098 lbeq L39 02E4 ECE1ED ldd -19,x 02E7 8C0004 cpd #4 02EA 1827008E lbeq L39 02EE 1820007E lbra L38 02F2 X0: 02F2 ; } 02F2 ; #ifdef KDB_TRACE_LEVEL_1 02F2 ; if (kdb_trace) puts("kDB2.5-1"); 02F2 ; #endif 02F2 ; 02F2 ; 02F2 ; 02F2 ; // DISPATCH, or otherwise deal with the current task 02F2 ; // KDB_TRACE Section 3 02F2 ; 02F2 ; #ifdef KDB_TRACE_LEVEL_2 02F2 ; if (kdb_trace) { 02F2 ; printf("task[%d]->state = %d\n", current, task[current]->state); 02F2 ; printf("task[%d]->prior = %d\n", current, task[current]->priority); 02F2 ; } 02F2 ; #endif 02F2 ; 02F2 ; switch (task[current]->state) { 02F2 ; case IDLE: // skip task 02F2 ; #ifdef KDB_TRACE_LEVEL_1 02F2 ; if (kdb_trace) puts("kDB3.1-1"); 02F2 ; #endif 02F2 ; break; 02F2 L42: 02F2 ; case PENDING: // ready and waiting to run 02F2 ; #ifdef KDB_TRACE_LEVEL_1 02F2 ; if (kdb_trace) puts("kDB3.2-1"); 02F2 ; #endif 02F2 ; #ifdef KDB_TRACE_LEVEL_2 02F2 ; if (kdb_trace) { 02F2 ; //puts("kDB3.2-2"); 02F2 ; putchar('S'); 02F2 ; putchar(current+48); 02F2 ; putchar('\n'); 02F2 ; } 02F2 ; #endif 02F2 ; task[current]->state = RUNNING; 02F2 FC004C ldd _current 02F5 59 lsld 02F6 C30032 addd #_task 02F9 B7C6 xgdy 02FB ED40 ldy 0,y 02FD C602 ldab #2 02FF 6B4C stab 12,y 0301 ; task[current]->period_tick = system_tick; 0301 FC004C ldd _current 0304 59 lsld 0305 C30032 addd #_task 0308 B7C6 xgdy 030A ED40 ldy 0,y 030C 194E leay 14,y 030E 35 pshy ; spill 030F CD0048 ldy #_system_tick 0312 1802401C movw 0,y,-4,x 0316 1802421E movw 2,y,-2,x 031A 31 puly ; reload 031B 18021C40 movw -4,x,0,y 031F 18021E42 movw -2,x,2,y 0323 ; temp_task_frame_ptr = task[current]->top_of_stack; 0323 FC004C ldd _current 0326 59 lsld 0327 C30032 addd #_task 032A B7C6 xgdy 032C ED40 ldy 0,y 032E EDE819 ldy 25,y 0331 7D0004 sty _temp_task_frame_ptr 0334 ; asm("LDS _temp_task_frame_ptr"); // set the SP 0334 FF0004 LDS _temp_task_frame_ptr 0337 0337 ; exit_status = (*task_ptr[current])(); // start the task 0337 FC004C ldd _current 033A 59 lsld 033B C3004E addd #_task_ptr 033E B7C6 xgdy 0340 ED40 ldy 0,y 0342 1540 jsr 0,y 0344 7C0000 std _exit_status 0347 ; asm("LDS _main_frame_ptr"); // reset the SP 0347 FF0000 LDS _main_frame_ptr 034A 034A ; task[current]->state = IDLE; // task finished 034A FC004C ldd _current 034D 59 lsld 034E C30032 addd #_task 0351 B7C6 xgdy 0353 ED40 ldy 0,y 0355 694C clr 12,y 0357 ; #ifdef KDB_TRACE_LEVEL_1 0357 ; if (kdb_trace) puts("kDB3.3-1"); 0357 ; #endif 0357 ; #ifdef KDB_TRACE_LEVEL_2 0357 ; if (kdb_trace) { 0357 ; //puts("kDB3.3-2"); 0357 ; putchar('F'); 0357 ; putchar(current+48); 0357 ; putchar('\n'); 0357 ; } 0357 ; #endif 0357 ; break; 0357 2023 bra L39 0359 L43: 0359 ; case RUNNING: // interrupted. continue running. 0359 ; // restore context and run 0359 ; temp_task_frame_ptr = task[current]->frame_ptr; 0359 FC004C ldd _current 035C 59 lsld 035D C30032 addd #_task 0360 B7C6 xgdy 0362 ED40 ldy 0,y 0364 EDE81B ldy 27,y 0367 7D0004 sty _temp_task_frame_ptr 036A ; asm("LDS _temp_task_frame_ptr"); 036A FF0004 LDS _temp_task_frame_ptr 036D 036D ; asm("RTI"); 036D 0B RTI 036E 036E ; break; 036E 200C bra L39 0370 X1: 0370 ; case WAITING: // waiting on a resource 0370 ; #ifdef KDB_TRACE_LEVEL_1 0370 ; if (kdb_trace) puts("kDB3.5-1"); 0370 ; #endif 0370 ; break; 0370 ; case STOPPED: // done running until later 0370 ; #ifdef KDB_TRACE_LEVEL_1 0370 ; if (kdb_trace) puts("kDB3.6-1"); 0370 ; #endif 0370 ; break; 0370 L38: 0370 ; default: // shouldn't happen, but, error if so. 0370 ; puts("KERNEL: task state error\n"); 0370 CC0CB6 ldd #L46 0373 160000 jsr _puts 0376 ; exit(1); 0376 CC0001 ldd #1 0379 160000 jsr _exit 037C ; } // end switch 037C L39: 037C L5: 037C 1820FDD2 lbra L4 0380 X2: 0380 ; 0380 ; 0380 ; 0380 ; // exit_status HANDLER 0380 ; //... 0380 ; 0380 ; 0380 ; 0380 ; } // end while(1) 0380 ; 0380 ; return 0; 0380 CC0000 ldd #0 0383 L3: 0383 B757 tfr x,s 0385 30 pulx 0386 .dbline 0 ; func end 0386 3D rts 0387 ; lreg1 -> -4,x 0387 ; lreg2 -> -8,x 0387 ; local_thp -> -14,x 0387 ; i -> -12,x 0387 ; frame_size -> -10,x 0387 _RTI_handler:: 0387 34 pshx 0388 B775 tfr s,x 038A 1B92 leas -14,sp 038C ; 038C ; } // end main() 038C ; 038C ; 038C ; 038C ; #pragma interrupt_handler RTI_handler() 038C ; 038C ; void RTI_handler(void) { 038C ; 038C ; size_t frame_size; 038C ; unsigned int i; 038C ; unsigned char *local_thp; 038C ; 038C ; 038C ; 038C ; //ACKNOWLEDGE THE INTERRUPT 038C ; RTIFLG = 0x0080; // acknowledge/clear the interrupt 038C C680 ldab #128 038E 7B0015 stab 0x15 0391 ; 0391 ; 0391 ; #ifdef KDB_TRACE_LEVEL_1 0391 ; if (kdb_trace) putchar('.'); 0391 ; #endif 0391 ; //putchar('.'); 0391 ; 0391 ; 0391 ; // SET THE FRAME POINTER for the interupted task. 0391 ; // should point to the CCR entry on the stack. 0391 ; asm("TFR x,d"); // start of RTI stack 0391 B754 TFR x,d 0393 0393 ; asm("ADDD #2"); // adjust to CCR stack entry 0393 C30002 ADDD #2 0396 0396 ; asm("STD _temp_task_frame_ptr"); // put into task_frame_ptr 0396 7C0004 STD _temp_task_frame_ptr 0399 0399 ; task[current]->frame_ptr = temp_task_frame_ptr; 0399 FC004C ldd _current 039C 59 lsld 039D C30032 addd #_task 03A0 B7C6 xgdy 03A2 ED40 ldy 0,y 03A4 FC0004 ldd _temp_task_frame_ptr 03A7 6CE81B std 27,y 03AA ; 03AA ; 03AA ; 03AA ; // update system time base and cop reset counter 03AA ; system_tick++; 03AA CD0048 ldy #_system_tick 03AD 1802401C movw 0,y,-4,x 03B1 1802421E movw 2,y,-2,x 03B5 CD0CB2 ldy #L48 03B8 18024018 movw 0,y,-8,x 03BC 1802421A movw 2,y,-6,x 03C0 160000 jsr __ladd 03C3 CD0048 ldy #_system_tick 03C6 18021C40 movw -4,x,0,y 03CA 18021E42 movw -2,x,2,y 03CE ; cop_cycle++; 03CE FC0046 ldd _cop_cycle 03D1 C30001 addd #1 03D4 7C0046 std _cop_cycle 03D7 ; if (time_tick > TIME_TICKS_PER_DAY) { 03D7 CD0042 ldy #_time_tick 03DA 1802401C movw 0,y,-4,x 03DE 1802421E movw 2,y,-2,x 03E2 CD0CAE ldy #L51 03E5 18024018 movw 0,y,-8,x 03E9 1802421A movw 2,y,-6,x 03ED 160000 jsr __lcmp 03F0 2316 bls L49 03F2 ; time_tick = 0; 03F2 CD0CAA ldy #L52 03F5 1802401C movw 0,y,-4,x 03F9 1802421E movw 2,y,-2,x 03FD CD0042 ldy #_time_tick 0400 18021C40 movw -4,x,0,y 0404 18021E42 movw -2,x,2,y 0408 ; } 0408 L49: 0408 ; 0408 ; 0408 ; 0408 ; // RETURN: simulate a RTS instruction 0408 ; // set stack pointer for main() 0408 ; asm("LDS _main_frame_ptr"); 0408 FF0000 LDS _main_frame_ptr 040B 040B ; asm("LDX _main_frame_x_ptr"); 040B FE0002 LDX _main_frame_x_ptr 040E 040E ; /* return to main() at the reentry point 040E ; and must be adjusted after each kernel mod/compilation!! */ 040E ; asm("JMP $117C"); 040E 06117C JMP $117C 0411 0411 ; 0411 ; } 0411 L47: 0411 B757 tfr x,s 0413 30 pulx 0414 .dbline 0 ; func end 0414 0B rti 0415 ; lreg1 -> -4,x 0415 ; lreg2 -> -8,x 0415 ; i -> -10,x 0415 _kernel_init:: 0415 34 pshx 0416 B775 tfr s,x 0418 1BF1EE leas -18,sp 041B ; 041B ; 041B ; 041B ; 041B ; void kernel_init(void) { 041B CC0000 ldd #0 041E 6C16 std -10,x 0420 L54: 0420 CC000C ldd #12 0423 ED16 ldy -10,x 0425 1813 emuls 0427 C30002 addd #_resource 042A B7C6 xgdy 042C EC16 ldd -10,x 042E 6B40 stab 0,y 0430 CC000C ldd #12 0433 ED16 ldy -10,x 0435 1813 emuls 0437 C30008 addd #_resource+6 043A B7C6 xgdy 043C 6940 clr 0,y 043E CC000C ldd #12 0441 ED16 ldy -10,x 0443 1813 emuls 0445 C30009 addd #_resource+7 0448 B7C6 xgdy 044A C6FF ldab #255 044C 6B40 stab 0,y 044E CC000C ldd #12 0451 ED16 ldy -10,x 0453 1813 emuls 0455 C3000D addd #_resource+11 0458 B7C6 xgdy 045A 6940 clr 0,y 045C L55: 045C ; 045C ; // LOCAL VARIABLES 045C ; extern int _bss_end, _textmode; 045C ; int i; 045C ; 045C ; 045C ; 045C ; // START/INITIALIZE the os 045C ; // KDB_TRACE Section 1 045C ; 045C ; // initialize the rcb pointer block 045C ; for (i=0; i 3,x 0501 _if_task_exists:: 0501 3B pshd 0502 34 pshx 0503 B775 tfr s,x 0505 ; 0505 ; 0505 ; 0505 ; // KERNEL FUNCTIONS 0505 ; 0505 ; int if_task_exists(unsigned char id) { 0505 ; 0505 ; if (task[id] == NULL) 0505 E603 ldab 3,x 0507 87 clra 0508 59 lsld 0509 C30032 addd #_task 050C B7C6 xgdy 050E EC40 ldd 0,y 0510 2605 bne L72 0512 ; return -1; 0512 CCFFFF ldd #-1 0515 200E bra L71 0517 L72: 0517 ; else 0517 ; return task[id]->id; 0517 E603 ldab 3,x 0519 87 clra 051A 59 lsld 051B C30032 addd #_task 051E B7C6 xgdy 0520 ED40 ldy 0,y 0522 E642 ldab 2,y 0524 87 clra 0525 L71: 0525 B757 tfr x,s 0527 30 pulx 0528 1B82 leas 2,sp 052A .dbline 0 ; func end 052A 3D rts 052B ; id -> 3,x 052B _get_task_address:: 052B 3B pshd 052C 34 pshx 052D B775 tfr s,x 052F ; 052F ; } 052F ; 052F ; 052F ; 052F ; 052F ; int get_task_address(unsigned char id) { 052F ; 052F ; return (int)task[id]->address; 052F E603 ldab 3,x 0531 87 clra 0532 59 lsld 0533 C30032 addd #_task 0536 B7C6 xgdy 0538 ECEB0000 ldd [0,y] 053C L74: 053C B757 tfr x,s 053E 30 pulx 053F 1B82 leas 2,sp 0541 .dbline 0 ; func end 0541 3D rts 0542 _get_task_id:: 0542 ; 0542 ; } 0542 ; 0542 ; 0542 ; 0542 ; 0542 ; char get_task_id() { 0542 ; 0542 ; return task[current]->id; 0542 FC004C ldd _current 0545 59 lsld 0546 C30032 addd #_task 0549 B7C6 xgdy 054B ED40 ldy 0,y 054D E642 ldab 2,y 054F 87 clra 0550 L75: 0550 .dbline 0 ; func end 0550 3D rts 0551 ; id -> 3,x 0551 _get_task_name:: 0551 3B pshd 0552 34 pshx 0553 B775 tfr s,x 0555 ; } 0555 ; 0555 ; 0555 ; 0555 ; char *get_task_name(unsigned char id) { 0555 ; if (task[id] == NULL) 0555 E603 ldab 3,x 0557 87 clra 0558 59 lsld 0559 C30032 addd #_task 055C B7C6 xgdy 055E EC40 ldd 0,y 0560 2605 bne L77 0562 ; return NULL; 0562 CC0000 ldd #0 0565 200E bra L76 0567 L77: 0567 ; else 0567 ; return task[id]->name; 0567 E603 ldab 3,x 0569 87 clra 056A 59 lsld 056B C30032 addd #_task 056E B7C6 xgdy 0570 EC40 ldd 0,y 0572 C30003 addd #3 0575 L76: 0575 B757 tfr x,s 0577 30 pulx 0578 1B82 leas 2,sp 057A .dbline 0 ; func end 057A 3D rts 057B ; id -> 3,x 057B _get_task_state:: 057B 3B pshd 057C 34 pshx 057D B775 tfr s,x 057F ; } 057F ; 057F ; 057F ; 057F ; 057F ; int get_task_state(unsigned char id) { 057F ; 057F ; if (task[id] == NULL) 057F E603 ldab 3,x 0581 87 clra 0582 59 lsld 0583 C30032 addd #_task 0586 B7C6 xgdy 0588 EC40 ldd 0,y 058A 2605 bne L80 058C ; return -1; 058C CCFFFF ldd #-1 058F 2019 bra L79 0591 L80: 0591 ; else if (id < MAXTASKS) 0591 E603 ldab 3,x 0593 C108 cmpb #8 0595 2410 bhs L82 0597 ; return task[id]->state; 0597 E603 ldab 3,x 0599 87 clra 059A 59 lsld 059B C30032 addd #_task 059E B7C6 xgdy 05A0 ED40 ldy 0,y 05A2 E64C ldab 12,y 05A4 87 clra 05A5 2003 bra L79 05A7 L82: 05A7 ; else { 05A7 ; #ifdef KERNEL_ERROR_MSG 05A7 ; puts(error_src[1]); puts(error_msg[3]); 05A7 ; #endif 05A7 ; return -1; 05A7 CCFFFF ldd #-1 05AA L79: 05AA B757 tfr x,s 05AC 30 pulx 05AD 1B82 leas 2,sp 05AF .dbline 0 ; func end 05AF 3D rts 05B0 ; id -> 3,x 05B0 _get_task_messages:: 05B0 3B pshd 05B1 34 pshx 05B2 B775 tfr s,x 05B4 ; } 05B4 ; 05B4 ; } 05B4 ; 05B4 ; 05B4 ; 05B4 ; int get_task_messages(unsigned char id) { 05B4 ; 05B4 ; if (task[id] == NULL) 05B4 E603 ldab 3,x 05B6 87 clra 05B7 59 lsld 05B8 C30032 addd #_task 05BB B7C6 xgdy 05BD EC40 ldd 0,y 05BF 2605 bne L85 05C1 ; return -1; 05C1 CCFFFF ldd #-1 05C4 201A bra L84 05C6 L85: 05C6 ; else if (id < MAXTASKS) 05C6 E603 ldab 3,x 05C8 C108 cmpb #8 05CA 2411 bhs L87 05CC ; return task[id]->message; 05CC E603 ldab 3,x 05CE 87 clra 05CF 59 lsld 05D0 C30032 addd #_task 05D3 B7C6 xgdy 05D5 ED40 ldy 0,y 05D7 E6E814 ldab 20,y 05DA 87 clra 05DB 2003 bra L84 05DD L87: 05DD ; else { 05DD ; #ifdef KERNEL_ERROR_MSG 05DD ; puts(error_src[1]); puts(error_msg[3]); 05DD ; #endif 05DD ; return -1; 05DD CCFFFF ldd #-1 05E0 L84: 05E0 B757 tfr x,s 05E2 30 pulx 05E3 1B82 leas 2,sp 05E5 .dbline 0 ; func end 05E5 3D rts 05E6 ; id -> 3,x 05E6 _get_task_priority:: 05E6 3B pshd 05E7 34 pshx 05E8 B775 tfr s,x 05EA ; } 05EA ; 05EA ; } 05EA ; 05EA ; 05EA ; 05EA ; int get_task_priority(unsigned char id) { 05EA ; 05EA ; INTR_OFF(); 05EA 1410 sei 05EC 05EC ; 05EC ; if (id < MAXTASKS) { 05EC E603 ldab 3,x 05EE C108 cmpb #8 05F0 2412 bhs L90 05F2 ; INTR_ON(); 05F2 10EF cli 05F4 05F4 ; return task[id]->priority; 05F4 E603 ldab 3,x 05F6 87 clra 05F7 59 lsld 05F8 C30032 addd #_task 05FB B7C6 xgdy 05FD ED40 ldy 0,y 05FF E64D ldab 13,y 0601 87 clra 0602 2005 bra L89 0604 L90: 0604 ; } 0604 ; else { 0604 ; #ifdef KERNEL_ERROR_MSG 0604 ; puts(error_src[1]); puts(error_msg[4]); 0604 ; #endif 0604 ; INTR_ON(); 0604 10EF cli 0606 0606 ; return -1; 0606 CCFFFF ldd #-1 0609 L89: 0609 B757 tfr x,s 060B 30 pulx 060C 1B82 leas 2,sp 060E .dbline 0 ; func end 060E 3D rts 060F ; ?temp -> -4,x 060F ; ?temp -> -4,x 060F ; ?temp -> -4,x 060F ; ?temp -> -4,x 060F ; ?temp -> -4,x 060F ; ?temp -> -2,x 060F ; newstate -> 7,x 060F ; id -> 3,x 060F _set_task_state:: 060F 3B pshd 0610 34 pshx 0611 B775 tfr s,x 0613 1B9C leas -4,sp 0615 ; } 0615 ; 0615 ; } 0615 ; 0615 ; 0615 ; 0615 ; int set_task_state(unsigned char id, unsigned char newstate) { 0615 ; 0615 ; 0615 ; INTR_OFF(); 0615 1410 sei 0617 0617 ; 0617 ; 0617 ; // check id validity 0617 ; if (id < MAXTASKS) { 0617 E603 ldab 3,x 0619 C108 cmpb #8 061B 182401D9 lbhs L93 061F ; 061F ; if (task[id] == NULL) { 061F E603 ldab 3,x 0621 87 clra 0622 59 lsld 0623 C30032 addd #_task 0626 B7C6 xgdy 0628 EC40 ldd 0,y 062A 2609 bne L95 062C ; #ifdef KERNEL_ERROR_MSG 062C ; puts(error_src[1]); puts(error_msg[2]); 062C ; #endif 062C ; INTR_ON(); 062C 10EF cli 062E 062E ; return -1; 062E CCFFFF ldd #-1 0631 182001CF lbra L92 0635 L95: 0635 ; } 0635 ; 0635 ; 0635 ; // check newstate validity 0635 ; if ((newstate == RUNNING) || 0635 E607 ldab 7,x 0637 C102 cmpb #2 0639 270C beq L100 063B E607 ldab 7,x 063D C103 cmpb #3 063F 2706 beq L100 0641 E607 ldab 7,x 0643 C104 cmpb #4 0645 2309 bls L97 0647 L100: 0647 ; (newstate == WAITING) || 0647 ; (newstate > STOPPED)) { 0647 ; #ifdef KERNEL_ERROR_MSG 0647 ; puts(error_src[1]); puts(error_msg[3]); 0647 ; #endif 0647 ; INTR_ON(); 0647 10EF cli 0649 0649 ; return -1; 0649 CCFFFF ldd #-1 064C 182001B4 lbra L92 0650 L97: 0650 E603 ldab 3,x 0652 87 clra 0653 59 lsld 0654 C30032 addd #_task 0657 B7C6 xgdy 0659 ED40 ldy 0,y 065B E64C ldab 12,y 065D 87 clra 065E 6C1E std -2,x 0660 271F beq L104 0662 EC1E ldd -2,x 0664 8C0001 cpd #1 0667 1827009C lbeq L111 066B EC1E ldd -2,x 066D 8C0002 cpd #2 0670 182700F0 lbeq L118 0674 EC1E ldd -2,x 0676 8C0004 cpd #4 0679 18270128 lbeq L121 067D 18200170 lbra L101 0681 X3: 0681 ; } 0681 ; 0681 ; // referenced to the task's current state: 0681 ; switch (task[id]->state) { 0681 L104: 0681 ; case IDLE: 0681 ; if (newstate == IDLE) { // no change 0681 E707 tst 7,x 0683 2609 bne L105 0685 ; INTR_ON(); 0685 10EF cli 0687 0687 ; return 0; 0687 CC0000 ldd #0 068A 18200176 lbra L92 068E L105: 068E ; } 068E ; else if (newstate == PENDING) { 068E E607 ldab 7,x 0690 C101 cmpb #1 0692 2632 bne L107 0694 ; // pass msg to task[id]->msgbox; 0694 ; task[id]->message |= STATE_FLAG; 0694 E603 ldab 3,x 0696 87 clra 0697 59 lsld 0698 C30032 addd #_task 069B B7C6 xgdy 069D EC40 ldd 0,y 069F C30014 addd #20 06A2 6C1C std -4,x 06A4 B746 tfr d,y 06A6 35 pshy ; spill 06A7 ED1C ldy -4,x 06A9 31 puly ; reload 06AA 0C4001 bset 0,y,#1 06AD ; task[id]->message_data[STATE_BOX] = PENDING; 06AD E603 ldab 3,x 06AF 87 clra 06B0 59 lsld 06B1 C30032 addd #_task 06B4 B7C6 xgdy 06B6 ED40 ldy 0,y 06B8 C601 ldab #1 06BA 6BE815 stab 21,y 06BD ; INTR_ON(); 06BD 10EF cli 06BF 06BF ; return 0; 06BF CC0000 ldd #0 06C2 1820013E lbra L92 06C6 L107: 06C6 ; } 06C6 ; else if (newstate == STOPPED) { 06C6 E607 ldab 7,x 06C8 C104 cmpb #4 06CA 2632 bne L109 06CC ; // pass msg to task[id]->msgbox; 06CC ; task[id]->message |= STATE_FLAG; 06CC E603 ldab 3,x 06CE 87 clra 06CF 59 lsld 06D0 C30032 addd #_task 06D3 B7C6 xgdy 06D5 EC40 ldd 0,y 06D7 C30014 addd #20 06DA 6C1C std -4,x 06DC B746 tfr d,y 06DE 35 pshy ; spill 06DF ED1C ldy -4,x 06E1 31 puly ; reload 06E2 0C4001 bset 0,y,#1 06E5 ; task[id]->message_data[STATE_BOX] = STOPPED; 06E5 E603 ldab 3,x 06E7 87 clra 06E8 59 lsld 06E9 C30032 addd #_task 06EC B7C6 xgdy 06EE ED40 ldy 0,y 06F0 C604 ldab #4 06F2 6BE815 stab 21,y 06F5 ; INTR_ON(); 06F5 10EF cli 06F7 06F7 ; return 0; 06F7 CC0000 ldd #0 06FA 18200106 lbra L92 06FE L109: 06FE ; } 06FE ; else { // nothing else is legal; 06FE ; #ifdef KERNEL_ERROR_MSG 06FE ; puts(error_src[1]); puts(error_msg[3]); 06FE ; #endif 06FE ; INTR_ON(); 06FE 10EF cli 0700 0700 ; return -1; 0700 CCFFFF ldd #-1 0703 182000FD lbra L92 0707 X4: 0707 ; } 0707 ; break; 0707 L111: 0707 ; case PENDING: 0707 ; if (newstate == PENDING) { // no change 0707 E607 ldab 7,x 0709 C101 cmpb #1 070B 2609 bne L112 070D ; INTR_ON(); 070D 10EF cli 070F 070F ; return 0; 070F CC0000 ldd #0 0712 182000EE lbra L92 0716 L112: 0716 ; } 0716 ; else if (newstate == IDLE) { 0716 E707 tst 7,x 0718 2609 bne L114 071A ; // pass msg to task[id]->msgbox; 071A ; #ifdef KERNEL_ERROR_MSG 071A ; puts(error_src[1]); puts(error_msg[0]); 071A ; #endif 071A ; INTR_ON(); 071A 10EF cli 071C 071C ; return -1; 071C CCFFFF ldd #-1 071F 182000E1 lbra L92 0723 L114: 0723 ; } 0723 ; else if (newstate == STOPPED) { 0723 E607 ldab 7,x 0725 C104 cmpb #4 0727 2632 bne L116 0729 ; // pass msg to task[id]->msgbox; 0729 ; task[id]->message |= STATE_FLAG; 0729 E603 ldab 3,x 072B 87 clra 072C 59 lsld 072D C30032 addd #_task 0730 B7C6 xgdy 0732 EC40 ldd 0,y 0734 C30014 addd #20 0737 6C1C std -4,x 0739 B746 tfr d,y 073B 35 pshy ; spill 073C ED1C ldy -4,x 073E 31 puly ; reload 073F 0C4001 bset 0,y,#1 0742 ; task[id]->message_data[STATE_BOX] = STOPPED; 0742 E603 ldab 3,x 0744 87 clra 0745 59 lsld 0746 C30032 addd #_task 0749 B7C6 xgdy 074B ED40 ldy 0,y 074D C604 ldab #4 074F 6BE815 stab 21,y 0752 ; INTR_ON(); 0752 10EF cli 0754 0754 ; return 0; 0754 CC0000 ldd #0 0757 182000A9 lbra L92 075B L116: 075B ; } 075B ; else { 075B ; #ifdef KERNEL_ERROR_MSG 075B ; puts(error_src[1]); puts(error_msg[3]); 075B ; #endif 075B ; INTR_ON(); 075B 10EF cli 075D 075D ; return -1; 075D CCFFFF ldd #-1 0760 182000A0 lbra L92 0764 X5: 0764 ; } 0764 ; break; 0764 L118: 0764 ; case RUNNING: 0764 ; if (newstate == STOPPED) { 0764 E607 ldab 7,x 0766 C104 cmpb #4 0768 2632 bne L119 076A ; // pass msg to task[id]->msgbox; 076A ; task[id]->message |= STATE_FLAG; 076A E603 ldab 3,x 076C 87 clra 076D 59 lsld 076E C30032 addd #_task 0771 B7C6 xgdy 0773 EC40 ldd 0,y 0775 C30014 addd #20 0778 6C1C std -4,x 077A B746 tfr d,y 077C 35 pshy ; spill 077D ED1C ldy -4,x 077F 31 puly ; reload 0780 0C4001 bset 0,y,#1 0783 ; task[id]->message_data[STATE_BOX] = STOPPED; 0783 E603 ldab 3,x 0785 87 clra 0786 59 lsld 0787 C30032 addd #_task 078A B7C6 xgdy 078C ED40 ldy 0,y 078E C604 ldab #4 0790 6BE815 stab 21,y 0793 ; 0793 ; INTR_ON(); 0793 10EF cli 0795 0795 ; return 0; 0795 CC0000 ldd #0 0798 18200068 lbra L92 079C L119: 079C ; } 079C ; else { 079C ; #ifdef KERNEL_ERROR_MSG 079C ; puts(error_src[1]); puts(error_msg[3]); 079C ; #endif 079C ; INTR_ON(); 079C 10EF cli 079E 079E ; return -1; 079E CCFFFF ldd #-1 07A1 1820005F lbra L92 07A5 X6: 07A5 ; } 07A5 ; break; 07A5 L121: 07A5 ; case STOPPED: 07A5 ; if (newstate == STOPPED) { // no change 07A5 E607 ldab 7,x 07A7 C104 cmpb #4 07A9 2609 bne L122 07AB ; INTR_ON(); 07AB 10EF cli 07AD 07AD ; return 0; 07AD CC0000 ldd #0 07B0 18200050 lbra L92 07B4 L122: 07B4 ; } 07B4 ; else if (newstate == PENDING) { 07B4 E607 ldab 7,x 07B6 C101 cmpb #1 07B8 2630 bne L124 07BA ; // pass msg to task[id]->msgbox; 07BA ; task[id]->message |= STATE_FLAG; 07BA E603 ldab 3,x 07BC 87 clra 07BD 59 lsld 07BE C30032 addd #_task 07C1 B7C6 xgdy 07C3 EC40 ldd 0,y 07C5 C30014 addd #20 07C8 6C1C std -4,x 07CA B746 tfr d,y 07CC 35 pshy ; spill 07CD ED1C ldy -4,x 07CF 31 puly ; reload 07D0 0C4001 bset 0,y,#1 07D3 ; task[id]->message_data[STATE_BOX] = PENDING; 07D3 E603 ldab 3,x 07D5 87 clra 07D6 59 lsld 07D7 C30032 addd #_task 07DA B7C6 xgdy 07DC ED40 ldy 0,y 07DE C601 ldab #1 07E0 6BE815 stab 21,y 07E3 ; INTR_ON(); 07E3 10EF cli 07E5 07E5 ; return 0; 07E5 CC0000 ldd #0 07E8 201A bra L92 07EA L124: 07EA ; } 07EA ; else { 07EA ; #ifdef KERNEL_ERROR_MSG 07EA ; puts(error_src[1]); puts(error_msg[3]); 07EA ; #endif 07EA ; INTR_ON(); 07EA 10EF cli 07EC 07EC ; return -1; 07EC CCFFFF ldd #-1 07EF 2013 bra L92 07F1 X7: 07F1 ; } 07F1 ; break; 07F1 L101: 07F1 ; default: 07F1 ; #ifdef KERNEL_ERROR_MSG 07F1 ; puts(error_src[1]); puts(error_msg[3]); 07F1 ; #endif 07F1 ; INTR_ON(); 07F1 10EF cli 07F3 07F3 ; return -1; 07F3 CCFFFF ldd #-1 07F6 200C bra L92 07F8 X8: 07F8 ; break; 07F8 L93: 07F8 ; 07F8 ; } // end switch (task[id]->state) 07F8 ; 07F8 ; } // if (id < MAXTASKS) 07F8 ; 07F8 ; else { 07F8 ; #ifdef KERNEL_ERROR_MSG 07F8 ; puts(error_src[1]); puts(error_msg[2]); 07F8 ; #endif 07F8 ; INTR_ON(); 07F8 10EF cli 07FA 07FA ; return -1; 07FA CCFFFF ldd #-1 07FD 2005 bra L92 07FF X9: 07FF ; } 07FF ; 07FF ; INTR_ON(); 07FF 10EF cli 0801 0801 ; return 0; 0801 CC0000 ldd #0 0804 L92: 0804 B757 tfr x,s 0806 30 pulx 0807 1B82 leas 2,sp 0809 .dbline 0 ; func end 0809 3D rts 080A ; priority -> 7,x 080A ; id -> 3,x 080A _set_task_priority:: 080A 3B pshd 080B 34 pshx 080C B775 tfr s,x 080E ; 080E ; } 080E ; 080E ; 080E ; 080E ; int set_task_priority(unsigned char id, unsigned char priority) { 080E ; 080E ; if (priority == 0) // priority 0 is reserved for the shell 080E E707 tst 7,x 0810 2604 bne L127 0812 ; priority = 1; 0812 C601 ldab #1 0814 6B07 stab 7,x 0816 L127: 0816 ; 0816 ; if (id >= (MAXTASKS)) { 0816 E603 ldab 3,x 0818 C108 cmpb #8 081A 2505 blo L129 081C ; #ifdef KERNEL_ERROR_MSG 081C ; puts(error_src[1]); puts(error_msg[4]); 081C ; #endif 081C ; return -1; 081C CCFFFF ldd #-1 081F 2021 bra L126 0821 L129: 0821 E607 ldab 7,x 0823 C1FF cmpb #255 0825 2204 bhi L133 0827 E707 tst 7,x 0829 2405 bhs L131 082B L133: 082B ; } 082B ; else if ((priority > 255) || (priority < 0)) { 082B ; #ifdef KERNEL_ERROR_MSG 082B ; puts(error_src[1]); puts(error_msg[4]); 082B ; #endif 082B ; return -1; 082B CCFFFF ldd #-1 082E 2012 bra L126 0830 L131: 0830 ; } 0830 ; else { 0830 ; task[id]->priority = priority; 0830 E603 ldab 3,x 0832 87 clra 0833 59 lsld 0834 C30032 addd #_task 0837 B7C6 xgdy 0839 ED40 ldy 0,y 083B E607 ldab 7,x 083D 6B4D stab 13,y 083F ; return 0; 083F CC0000 ldd #0 0842 L126: 0842 B757 tfr x,s 0844 30 pulx 0845 1B82 leas 2,sp 0847 .dbline 0 ; func end 0847 3D rts 0848 ; lreg1 -> -4,x 0848 ; lreg2 -> -8,x 0848 ; ?temp -> -15,x 0848 ; ?temp -> -13,x 0848 ; ?temp -> -11,x 0848 ; id -> -9,x 0848 ; stack_size -> 12,x 0848 ; state -> 10,x 0848 ; priority -> 9,x 0848 ; addr -> 6,x 0848 ; name -> 2,x 0848 _create_task:: 0848 3B pshd 0849 34 pshx 084A B775 tfr s,x 084C 1BF1EA leas -22,sp 084F ; } 084F ; } 084F ; 084F ; 084F ; 084F ; 084F ; int create_task(char *name, 084F ; int (*addr)(), 084F ; unsigned char priority, 084F ; int state, 084F ; int stack_size) { 084F ; 084F ; // LOCAL VARIABLES 084F ; unsigned char id; 084F ; 084F ; 084F ; INTR_OFF(); // critical section 084F 1410 sei 0851 0851 6917 clr -9,x 0853 2015 bra L138 0855 L135: 0855 E617 ldab -9,x 0857 87 clra 0858 59 lsld 0859 C3004E addd #_task_ptr 085C B7C6 xgdy 085E EC40 ldd 0,y 0860 270E beq L137 0862 L136: 0862 E617 ldab -9,x 0864 87 clra 0865 C30001 addd #1 0868 6B17 stab -9,x 086A L138: 086A ; 086A ; 086A ; //if (get_free_memory() > 64) { 086A ; 086A ; // determine lowest free id available to assign to this task 086A ; for (id=0; idaddress = addr; 08A0 E617 ldab -9,x 08A2 87 clra 08A3 59 lsld 08A4 C30032 addd #_task 08A7 B7C6 xgdy 08A9 ED40 ldy 0,y 08AB EC06 ldd 6,x 08AD 6C40 std 0,y 08AF ; task[id]->id = id; 08AF E617 ldab -9,x 08B1 87 clra 08B2 59 lsld 08B3 C30032 addd #_task 08B6 B7C6 xgdy 08B8 ED40 ldy 0,y 08BA E617 ldab -9,x 08BC 6B42 stab 2,y 08BE ; strcpy(task[id]->name, name); 08BE 18020280 movw 2,x,0,sp 08C2 E617 ldab -9,x 08C4 87 clra 08C5 59 lsld 08C6 C30032 addd #_task 08C9 B7C6 xgdy 08CB EC40 ldd 0,y 08CD C30003 addd #3 08D0 160000 jsr _strcpy 08D3 ; task[id]->state = state; 08D3 E617 ldab -9,x 08D5 87 clra 08D6 59 lsld 08D7 C30032 addd #_task 08DA B7C6 xgdy 08DC ED40 ldy 0,y 08DE EC0A ldd 10,x 08E0 6B4C stab 12,y 08E2 ; task[id]->priority = priority; 08E2 E617 ldab -9,x 08E4 87 clra 08E5 59 lsld 08E6 C30032 addd #_task 08E9 B7C6 xgdy 08EB ED40 ldy 0,y 08ED E609 ldab 9,x 08EF 6B4D stab 13,y 08F1 ; task[id]->period_tick = 0; 08F1 E617 ldab -9,x 08F3 87 clra 08F4 59 lsld 08F5 C30032 addd #_task 08F8 B7C6 xgdy 08FA ED40 ldy 0,y 08FC 194E leay 14,y 08FE 35 pshy ; spill 08FF CD0CAA ldy #L52 0902 1802401C movw 0,y,-4,x 0906 1802421E movw 2,y,-2,x 090A 31 puly ; reload 090B 18021C40 movw -4,x,0,y 090F 18021E42 movw -2,x,2,y 0913 ; task[id]->interrupt_msg_box = NULL; 0913 E617 ldab -9,x 0915 87 clra 0916 59 lsld 0917 C30032 addd #_task 091A B7C6 xgdy 091C ED40 ldy 0,y 091E CC0000 ldd #0 0921 6CE812 std 18,y 0924 ; task[id]->message = NULL; 0924 E617 ldab -9,x 0926 87 clra 0927 59 lsld 0928 C30032 addd #_task 092B B7C6 xgdy 092D ED40 ldy 0,y 092F 69E814 clr 20,y 0932 ; task[id]->message_data[0] = NULL; 0932 E617 ldab -9,x 0934 87 clra 0935 59 lsld 0936 C30032 addd #_task 0939 B7C6 xgdy 093B ED40 ldy 0,y 093D 69E815 clr 21,y 0940 ; task[id]->message_data[1] = NULL; 0940 E617 ldab -9,x 0942 87 clra 0943 59 lsld 0944 C30032 addd #_task 0947 B7C6 xgdy 0949 ED40 ldy 0,y 094B 69E816 clr 22,y 094E ; if (stack_size <= 0) 094E EC0C ldd 12,x 0950 2E05 bgt L143 0952 ; stack_size = DEFAULT_STACK_SIZE; 0952 CC0040 ldd #64 0955 6C0C std 12,x 0957 L143: 0957 ; task[id]->stack_size = stack_size; 0957 E617 ldab -9,x 0959 87 clra 095A 59 lsld 095B C30032 addd #_task 095E B7C6 xgdy 0960 ED40 ldy 0,y 0962 EC0C ldd 12,x 0964 6CE817 std 23,y 0967 ; task[id]->top_of_stack = malloc(task[id]->stack_size); 0967 E617 ldab -9,x 0969 87 clra 096A 59 lsld 096B C30032 addd #_task 096E B7C6 xgdy 0970 ED40 ldy 0,y 0972 6D15 sty -11,x 0974 ED15 ldy -11,x 0976 ECE817 ldd 23,y 0979 160000 jsr _malloc 097C 6CE1EC std -20,x 097F ED15 ldy -11,x 0981 ECE1EC ldd -20,x 0984 6CE819 std 25,y 0987 ; task[id]->top_of_stack += task[id]->stack_size; 0987 E617 ldab -9,x 0989 87 clra 098A 59 lsld 098B C30032 addd #_task 098E B7C6 xgdy 0990 ED40 ldy 0,y 0992 6D13 sty -13,x 0994 EC13 ldd -13,x 0996 C30019 addd #25 0999 6C11 std -15,x 099B ED13 ldy -13,x 099D ECE817 ldd 23,y 09A0 E3E3FFF1 addd [-15,x] 09A4 ED11 ldy -15,x 09A6 6C40 std 0,y 09A8 ; task[id]->frame_ptr = NULL; 09A8 E617 ldab -9,x 09AA 87 clra 09AB 59 lsld 09AC C30032 addd #_task 09AF B7C6 xgdy 09B1 ED40 ldy 0,y 09B3 CC0000 ldd #0 09B6 6CE81B std 27,y 09B9 ; 09B9 ; } 09B9 ; //} 09B9 ; INTR_ON(); 09B9 10EF cli 09BB 09BB ; 09BB ; return id; 09BB E617 ldab -9,x 09BD 87 clra 09BE L134: 09BE B757 tfr x,s 09C0 30 pulx 09C1 1B82 leas 2,sp 09C3 .dbline 0 ; func end 09C3 3D rts 09C4 ; ?temp -> -2,x 09C4 ; id -> 3,x 09C4 _remove_task:: 09C4 3B pshd 09C5 34 pshx 09C6 B775 tfr s,x 09C8 1B9E leas -2,sp 09CA ; 09CA ; } 09CA ; 09CA ; 09CA ; 09CA ; int remove_task(unsigned char id) { 09CA ; 09CA ; if (task[id] == NULL) 09CA E603 ldab 3,x 09CC 87 clra 09CD 59 lsld 09CE C30032 addd #_task 09D1 B7C6 xgdy 09D3 EC40 ldd 0,y 09D5 2605 bne L146 09D7 ; return -1; 09D7 CCFFFF ldd #-1 09DA 2047 bra L145 09DC L146: 09DC ; 09DC ; 09DC ; free(task[id]->top_of_stack - task[id]->stack_size); 09DC E603 ldab 3,x 09DE 87 clra 09DF 59 lsld 09E0 C30032 addd #_task 09E3 B7C6 xgdy 09E5 ED40 ldy 0,y 09E7 6D1E sty -2,x 09E9 ED1E ldy -2,x 09EB ECE819 ldd 25,y 09EE ED1E ldy -2,x 09F0 A3E817 subd 23,y 09F3 160000 jsr _free 09F6 ; free(task[id]); 09F6 E603 ldab 3,x 09F8 87 clra 09F9 59 lsld 09FA C30032 addd #_task 09FD B7C6 xgdy 09FF EC40 ldd 0,y 0A01 160000 jsr _free 0A04 ; task[id] = NULL; 0A04 E603 ldab 3,x 0A06 87 clra 0A07 59 lsld 0A08 C30032 addd #_task 0A0B B7C6 xgdy 0A0D CC0000 ldd #0 0A10 6C40 std 0,y 0A12 ; task_ptr[id] = NULL; 0A12 E603 ldab 3,x 0A14 87 clra 0A15 59 lsld 0A16 C3004E addd #_task_ptr 0A19 B7C6 xgdy 0A1B CC0000 ldd #0 0A1E 6C40 std 0,y 0A20 ; 0A20 ; return 0; 0A20 CC0000 ldd #0 0A23 L145: 0A23 B757 tfr x,s 0A25 30 pulx 0A26 1B82 leas 2,sp 0A28 .dbline 0 ; func end 0A28 3D rts 0A29 ; rid -> 3,x 0A29 _get_resource_state:: 0A29 3B pshd 0A2A 34 pshx 0A2B B775 tfr s,x 0A2D ; 0A2D ; } 0A2D ; 0A2D ; 0A2D ; 0A2D ; int get_resource_state(unsigned char rid) { 0A2D ; 0A2D ; if (rid < NUMRESOURCES) { 0A2D E603 ldab 3,x 0A2F C104 cmpb #4 0A31 2414 bhs L149 0A33 ; return resource[rid].state; 0A33 E603 ldab 3,x 0A35 87 clra 0A36 B7C6 xgdy 0A38 CC000C ldd #12 0A3B 1813 emuls 0A3D C30008 addd #_resource+6 0A40 B7C6 xgdy 0A42 E640 ldab 0,y 0A44 87 clra 0A45 2003 bra L148 0A47 L149: 0A47 ; } 0A47 ; else { 0A47 ; #ifdef KERNEL_ERROR_MSG 0A47 ; puts(error_src[1]); puts(error_msg[6]); 0A47 ; #endif 0A47 ; return -1; 0A47 CCFFFF ldd #-1 0A4A L148: 0A4A B757 tfr x,s 0A4C 30 pulx 0A4D 1B82 leas 2,sp 0A4F .dbline 0 ; func end 0A4F 3D rts 0A50 ; rid -> 3,x 0A50 _get_resource_owner:: 0A50 3B pshd 0A51 34 pshx 0A52 B775 tfr s,x 0A54 ; } 0A54 ; 0A54 ; } 0A54 ; 0A54 ; 0A54 ; 0A54 ; 0A54 ; 0A54 ; int get_resource_owner(unsigned char rid) { 0A54 ; 0A54 ; if (rid < NUMRESOURCES) { 0A54 E603 ldab 3,x 0A56 C104 cmpb #4 0A58 2414 bhs L153 0A5A ; return resource[rid].owner; 0A5A E603 ldab 3,x 0A5C 87 clra 0A5D B7C6 xgdy 0A5F CC000C ldd #12 0A62 1813 emuls 0A64 C30009 addd #_resource+7 0A67 B7C6 xgdy 0A69 E640 ldab 0,y 0A6B 87 clra 0A6C 2003 bra L152 0A6E L153: 0A6E ; } 0A6E ; else { 0A6E ; #ifdef KERNEL_ERROR_MSG 0A6E ; puts(error_src[1]); puts(error_msg[6]); 0A6E ; #endif 0A6E ; return -1; 0A6E CCFFFF ldd #-1 0A71 L152: 0A71 B757 tfr x,s 0A73 30 pulx 0A74 1B82 leas 2,sp 0A76 .dbline 0 ; func end 0A76 3D rts 0A77 ; rid -> 3,x 0A77 _get_resource_queuelen:: 0A77 3B pshd 0A78 34 pshx 0A79 B775 tfr s,x 0A7B ; } 0A7B ; 0A7B ; } 0A7B ; 0A7B ; 0A7B ; 0A7B ; 0A7B ; int get_resource_queuelen(unsigned char rid) { 0A7B ; 0A7B ; if (rid < NUMRESOURCES) { 0A7B E603 ldab 3,x 0A7D C104 cmpb #4 0A7F 2414 bhs L157 0A81 ; return resource[rid].queue_ptr; 0A81 E603 ldab 3,x 0A83 87 clra 0A84 B7C6 xgdy 0A86 CC000C ldd #12 0A89 1813 emuls 0A8B C3000D addd #_resource+11 0A8E B7C6 xgdy 0A90 E640 ldab 0,y 0A92 87 clra 0A93 2003 bra L156 0A95 L157: 0A95 ; } 0A95 ; else { 0A95 ; #ifdef KERNEL_ERROR_MSG 0A95 ; puts(error_src[1]); puts(error_msg[6]); 0A95 ; #endif 0A95 ; return -1; 0A95 CCFFFF ldd #-1 0A98 L156: 0A98 B757 tfr x,s 0A9A 30 pulx 0A9B 1B82 leas 2,sp 0A9D .dbline 0 ; func end 0A9D 3D rts 0A9E ; last -> -6,x 0A9E ; memory -> -4,x 0A9E ; i -> -2,x 0A9E _get_free_memory:: 0A9E 34 pshx 0A9F B775 tfr s,x 0AA1 1B98 leas -8,sp 0AA3 ; } 0AA3 ; 0AA3 ; } 0AA3 ; 0AA3 ; 0AA3 ; 0AA3 ; 0AA3 ; int get_free_memory(void) { 0AA3 ; 0AA3 ; // LOCAL VARIABLES 0AA3 ; char *memory, *last; 0AA3 ; int i; 0AA3 ; 0AA3 ; 0AA3 ; INTR_OFF(); 0AA3 1410 sei 0AA5 0AA5 CC0000 ldd #0 0AA8 6C1E std -2,x 0AAA L161: 0AAA ; // check for largest free memory block 0AAA ; for (i=0; i -6,x 0AD9 ; ?temp -> -4,x 0AD9 ; ?temp -> -2,x 0AD9 ; rid -> 3,x 0AD9 _sem_get:: 0AD9 3B pshd 0ADA 34 pshx 0ADB B775 tfr s,x 0ADD 1B98 leas -8,sp 0ADF ; 0ADF ; } 0ADF ; 0ADF ; 0ADF ; 0ADF ; 0ADF ; int sem_get(char rid) { 0ADF ; 0ADF ; /* Gives a resource to a requesting task. 0ADF ; returns the resource id number (0,1,2,...) if free. 0ADF ; otherwise returns -1. 0ADF ; 0ADF ; At this point, semaphores are a procedural control 0ADF ; that the tasks have to follow to avoid resource contention. 0ADF ; There is no kernel control over resources yet. */ 0ADF ; 0ADF ; 0ADF ; // critical section 0ADF ; INTR_OFF(); 0ADF 1410 sei 0AE1 0AE1 ; 0AE1 ; 0AE1 ; 0AE1 ; // GET SEMAPHORE 0AE1 ; // give semaphore to task 0AE1 ; if (resource[rid].state == NOTBUSY) { 0AE1 E603 ldab 3,x 0AE3 87 clra 0AE4 B7C6 xgdy 0AE6 CC000C ldd #12 0AE9 1813 emuls 0AEB C30008 addd #_resource+6 0AEE B7C6 xgdy 0AF0 E740 tst 0,y 0AF2 2630 bne L168 0AF4 ; resource[rid].state = BUSY; 0AF4 E603 ldab 3,x 0AF6 87 clra 0AF7 B7C6 xgdy 0AF9 CC000C ldd #12 0AFC 1813 emuls 0AFE C30008 addd #_resource+6 0B01 B7C6 xgdy 0B03 C601 ldab #1 0B05 6B40 stab 0,y 0B07 ; resource[rid].owner = current; 0B07 E603 ldab 3,x 0B09 87 clra 0B0A B7C6 xgdy 0B0C CC000C ldd #12 0B0F 1813 emuls 0B11 C30009 addd #_resource+7 0B14 B7C6 xgdy 0B16 FC004C ldd _current 0B19 6B40 stab 0,y 0B1B ; 0B1B ; INTR_ON(); 0B1B 10EF cli 0B1D 0B1D ; return rid; 0B1D E603 ldab 3,x 0B1F 87 clra 0B20 18200084 lbra L167 0B24 L168: 0B24 ; } 0B24 ; 0B24 ; // resource is taken/busy so make task wait 0B24 ; else { 0B24 ; task[current]->message |= STATE_FLAG; 0B24 FC004C ldd _current 0B27 59 lsld 0B28 C30032 addd #_task 0B2B B7C6 xgdy 0B2D EC40 ldd 0,y 0B2F C30014 addd #20 0B32 6C1E std -2,x 0B34 B746 tfr d,y 0B36 35 pshy ; spill 0B37 ED1E ldy -2,x 0B39 31 puly ; reload 0B3A 0C4001 bset 0,y,#1 0B3D ; task[current]->message_data[STATE_BOX] = WAITING; 0B3D FC004C ldd _current 0B40 59 lsld 0B41 C30032 addd #_task 0B44 B7C6 xgdy 0B46 ED40 ldy 0,y 0B48 C603 ldab #3 0B4A 6BE815 stab 21,y 0B4D ; 0B4D ; // put waiting task into the resources queue if there's space 0B4D ; if (resource[rid].queue_ptr < 3) { 0B4D E603 ldab 3,x 0B4F 87 clra 0B50 B7C6 xgdy 0B52 CC000C ldd #12 0B55 1813 emuls 0B57 C3000D addd #_resource+11 0B5A B7C6 xgdy 0B5C E640 ldab 0,y 0B5E C103 cmpb #3 0B60 2441 bhs L173 0B62 ; resource[rid].queue[resource[rid].queue_ptr] = current; 0B62 E603 ldab 3,x 0B64 87 clra 0B65 B7C6 xgdy 0B67 CC000C ldd #12 0B6A 1813 emuls 0B6C 6C1C std -4,x 0B6E C3000D addd #_resource+11 0B71 B7C6 xgdy 0B73 E640 ldab 0,y 0B75 87 clra 0B76 3B pshd ; spill 0B77 EC1C ldd -4,x 0B79 C3000A addd #_resource+8 0B7C 6C18 std -8,x 0B7E 3A puld ; reload 0B7F E318 addd -8,x 0B81 B7C6 xgdy 0B83 F6004D ldab _current+1 0B86 6B40 stab 0,y 0B88 ; resource[rid].queue_ptr++; 0B88 E603 ldab 3,x 0B8A 87 clra 0B8B B7C6 xgdy 0B8D CC000C ldd #12 0B90 1813 emuls 0B92 C3000D addd #_resource+11 0B95 6C1A std -6,x 0B97 B746 tfr d,y 0B99 E640 ldab 0,y 0B9B 87 clra 0B9C C30001 addd #1 0B9F ED1A ldy -6,x 0BA1 6B40 stab 0,y 0BA3 ; } 0BA3 L173: 0BA3 ; 0BA3 ; INTR_ON(); 0BA3 10EF cli 0BA5 0BA5 ; return -1; 0BA5 CCFFFF ldd #-1 0BA8 L167: 0BA8 B757 tfr x,s 0BAA 30 pulx 0BAB 1B82 leas 2,sp 0BAD .dbline 0 ; func end 0BAD 3D rts 0BAE ; rid -> 3,x 0BAE _sem_give:: 0BAE 3B pshd 0BAF 34 pshx 0BB0 B775 tfr s,x 0BB2 ; } 0BB2 ; 0BB2 ; } 0BB2 ; 0BB2 ; 0BB2 ; 0BB2 ; 0BB2 ; int sem_give(char rid) { 0BB2 ; 0BB2 ; /* Takes a resource back from a task. 0BB2 ; will (eventually) pass a message to a waiting task. 0BB2 ; 0BB2 ; At this point, semaphores are a procedural control 0BB2 ; that the tasks have to follow to avoid resource contention. 0BB2 ; There is no kernel control over resources yet. */ 0BB2 ; 0BB2 ; 0BB2 ; // critical section 0BB2 ; INTR_OFF(); 0BB2 1410 sei 0BB4 0BB4 ; 0BB4 ; 0BB4 ; // return the resource 0BB4 ; resource[rid].state = NOTBUSY; 0BB4 E603 ldab 3,x 0BB6 87 clra 0BB7 B7C6 xgdy 0BB9 CC000C ldd #12 0BBC 1813 emuls 0BBE C30008 addd #_resource+6 0BC1 B7C6 xgdy 0BC3 6940 clr 0,y 0BC5 ; //resource[rid].owner = NULL; 0BC5 ; 0BC5 ; INTR_ON(); 0BC5 10EF cli 0BC7 0BC7 ; 0BC7 ; return 0; 0BC7 CC0000 ldd #0 0BCA L179: 0BCA B757 tfr x,s 0BCC 30 pulx 0BCD 1B82 leas 2,sp 0BCF .dbline 0 ; func end 0BCF 3D rts 0BD0 ; lreg1 -> -4,x 0BD0 ; lreg2 -> -8,x 0BD0 ; slop -> -12,x 0BD0 _get_sysTime:: 0BD0 34 pshx 0BD1 B775 tfr s,x 0BD3 1B94 leas -12,sp 0BD5 ; 0BD5 ; } 0BD5 ; 0BD5 ; 0BD5 ; 0BD5 ; unsigned long int get_sysTime(void) { 0BD5 ; 0BD5 ; // LOCAL VARIABLES 0BD5 ; unsigned long int slop; 0BD5 ; 0BD5 ; 0BD5 ; // returns the number of milliseconds since midnight (time_tick=0); 0BD5 ; slop = time_tick / 40; 0BD5 CD0042 ldy #_time_tick 0BD8 1802401C movw 0,y,-4,x 0BDC 1802421E movw 2,y,-2,x 0BE0 CD0C6B ldy #L182 0BE3 18024018 movw 0,y,-8,x 0BE7 1802421A movw 2,y,-6,x 0BEB 160000 jsr __ludiv 0BEE 1914 leay -12,x 0BF0 18021C40 movw -4,x,0,y 0BF4 18021E42 movw -2,x,2,y 0BF8 ; return (time_tick * ms_PER_TIME_TICK + slop); 0BF8 CD0C67 ldy #L183 0BFB 1802401C movw 0,y,-4,x 0BFF 1802421E movw 2,y,-2,x 0C03 CD0042 ldy #_time_tick 0C06 18024018 movw 0,y,-8,x 0C0A 1802421A movw 2,y,-6,x 0C0E 160000 jsr __lmul 0C11 1914 leay -12,x 0C13 18024018 movw 0,y,-8,x 0C17 1802421A movw 2,y,-6,x 0C1B 160000 jsr __ladd 0C1E 160000 jsr __lret 0C21 L181: 0C21 B757 tfr x,s 0C23 30 pulx 0C24 .dbline 0 ; func end 0C24 3D rts 0C25 ; lreg1 -> -4,x 0C25 ; lreg2 -> -8,x 0C25 ; seconds -> 8,x 0C25 ; minutes -> 6,x 0C25 ; hours -> 2,x 0C25 _set_sysTime:: 0C25 3B pshd 0C26 34 pshx 0C27 B775 tfr s,x 0C29 1B96 leas -10,sp 0C2B ; 0C2B ; } 0C2B ; 0C2B ; 0C2B ; 0C2B ; void set_sysTime(unsigned int hours, unsigned int minutes, unsigned int seconds) { 0C2B ; 0C2B ; // LOCAL VARIABLES 0C2B ; extern unsigned long int time_tick; 0C2B ; 0C2B ; 0C2B ; time_tick = ((hours*3600)+(minutes*60)+(seconds)) * TIME_TICKS_PER_SECOND; 0C2B CC003C ldd #60 0C2E ED06 ldy 6,x 0C30 13 emul 0C31 6C16 std -10,x 0C33 CC0E10 ldd #3600 0C36 ED02 ldy 2,x 0C38 13 emul 0C39 E316 addd -10,x 0C3B E308 addd 8,x 0C3D 6C1A std -6,x 0C3F 1800180000 movw #0,-8,x 0C44 CD0C63 ldy #L185 0C47 1802401C movw 0,y,-4,x 0C4B 1802421E movw 2,y,-2,x 0C4F 160000 jsr __lmul 0C52 CD0042 ldy #_time_tick 0C55 18021C40 movw -4,x,0,y 0C59 18021E42 movw -2,x,2,y 0C5D ; 0C5D ; } 0C5D L184: 0C5D B757 tfr x,s 0C5F 30 pulx 0C60 1B82 leas 2,sp 0C62 .dbline 0 ; func end 0C62 3D rts .area bss 0000 _exit_status:: 0000 .blkb 2 0002 _resource:: 0002 .blkb 48 0032 _task:: 0032 .blkb 16 0042 _time_tick:: 0042 .blkb 4 0046 _cop_cycle:: 0046 .blkb 2 0048 _system_tick:: 0048 .blkb 4 004C _current:: 004C .blkb 2 004E _task_ptr:: 004E .blkb 16 .area text 0C63 L185: 0C63 0000003D .word 0,61 0C67 L183: 0C67 00000010 .word 0,16 0C6B L182: 0C6B 00000028 .word 0,40 0C6F L70: 0C6F 726C704F532076302E372E310A0A00 .byte 'r,'l,'p,'O,'S,32,'v,48,46,55,46,49,10,10,0 0C7E L69: 0C7E 737973496E6974206661696C75726500 .byte 's,'y,'s,'I,'n,'i,'t,32,'f,'a,'i,'l,'u,'r,'e,0 0C8E L68: 0C8E 737973496E697400 .byte 's,'y,'s,'I,'n,'i,'t,0 0C96 L65: 0C96 7368656C6C206661696C75726500 .byte 's,'h,'e,'l,'l,32,'f,'a,'i,'l,'u,'r,'e,0 0CA4 L64: 0CA4 7368656C6C00 .byte 's,'h,'e,'l,'l,0 0CAA L52: 0CAA 00000000 .word 0,0 0CAE L51: 0CAE 00506B80 .word 80,27520 0CB2 L48: 0CB2 00000001 .word 0,1 0CB6 L46: 0CB6 4B45524E454C3A207461736B20737461 .byte 'K,'E,'R,'N,'E,'L,58,32,'t,'a,'s,'k,32,'s,'t,'a 0CC6 7465206572726F720A00 .byte 't,'e,32,'e,'r,'r,'o,'r,10,0