.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 696C6C6567616C206D75746578204944 .byte 'i,'l,'l,'e,'g,'a,'l,32,'m,'u,'t,'e,'x,32,'I,'D 00A6 00 .byte 0 00A7 0000000000000000 .byte 0,0,0,0,0,0,0,0 00AF 696C6C6567616C206D75746578207374 .byte 'i,'l,'l,'e,'g,'a,'l,32,'m,'u,'t,'e,'x,32,'s,'t 00BF 61746500 .byte 'a,'t,'e,0 00C3 0000000000 .byte 0,0,0,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 ; lreg1 -> -4,x 0129 ; lreg2 -> -8,x 0129 ; ?temp -> -19,x 0129 ; ?temp -> -19,x 0129 ; ?temp -> -19,x 0129 ; ?temp -> -21,x 0129 ; ?temp -> -19,x 0129 ; id -> -17,x 0129 ; result -> -15,x 0129 ; priority_check -> -13,x 0129 ; deadline -> -12,x 0129 ; i -> -10,x 0129 _main:: 0129 34 pshx 012A B775 tfr s,x 012C 1BF1EA leas -22,sp 012F ; /* RLPOS: RLPotter Operating System 012F ; 012F ; Version 0.8 for the 68HC12D60A microcontroller 012F ; by Ryan Potter 012F ; ryan@rlpotter.com 012F ; 012F ; Compiled with the ImageCraft ICC12 compiler v6.15A 012F ; - 912D60 Single Chip Mode 012F ; - printf option: long 012F ; 012F ; 012F ; 012F ; v0.8 April 29, 2003: 012F ; - made mutexes dynamic, and much more powerfull and complete. I had 012F ; been calling them semaphores, but they've evolved into mutexes. 012F ; - implemented the TOF_handler interrupt for use with sysTime. 012F ; brings time resolution from 64 ms to 16 ms. 012F ; - added kernel funct: get_sysTime(), set_sysTime(); shell cmd: time. 012F ; - now tasks are 'int f()', and must return a value to the kernel 012F ; when exiting. kernel doesn't handle it yet, though. 012F ; - in shell, now names of tasks are shell commands (dynamic). 012F ; - put all kernel initialization code into kernel_init(). 012F ; - added kernel funct: remove_task(). 012F ; 012F ; 012F ; v0.7 April 25, 2003: 11174 bytes: 012F ; - combined kernel.c & semlib.c with rlpos.c to make one big kernel.c. 012F ; - changed context switch mechanism to give each task a dedicated 012F ; stack, making the kernel context switches >400% faster. 012F ; - added a basic timer task that will eventually keep system time/date. 012F ; 012F ; v0.6 April 24, 2003: 11042 bytes 012F ; - made the task block and the task control block dynamic, so that 012F ; now tasks can create tasks, and can also start/stop them. 012F ; - implemented the sysInit() task for kicking off a user system. 012F ; - implemented a kernel debug command for tracing code execution. 012F ; - implemented small msg box system in kernel for tasks. 012F ; - implemented COP watchdog reset timer. 012F ; - added system resources to semlib. 012F ; - added skeleton ISR_handler() code for the other interrupts. 012F ; - implemented _HC12Setup.c to initialize/harden the system. 012F ; 012F ; v0.5 April 16, 2003: 012F ; - added priority preemption. 012F ; - finished kernel task state switcher. 012F ; - it is now officially a legitimate 012F ; rate monotonic 012F ; priority preemptive 012F ; multitasking 012F ; Real Time Operating System :) 012F ; - made kernel.c and semlib.c consistent with the 012F ; rest of the kernel. 012F ; - included the early framework for a msg box system. 012F ; 012F ; v0.4 April 13, 2003: 8096 bytes 012F ; - gerneralized the shell command-line input parser: 012F ; cmd (up to 32 chars). 012F ; - added kernel and shell functions. 012F ; 012F ; v0.3 April 12, 2003: 6155 bytes 012F ; - added a beginning shell user interface. 012F ; - added a resource control block and basic semaphore functions. 012F ; - added basic kernel functions. 012F ; 012F ; v0.2 April 9, 2003: 012F ; - able to round-robin with RTI interrupt. 012F ; - bonified/certified multitasking with 3 tasks. :) 012F ; 012F ; v0.1 April 3, 2003: 012F ; - able to round-robin without interrupts. 012F ; - not multitasking, really. 012F ; 012F ; v0.0 started April 1, 2003; 0 bytes 012F ; - no idea where to start. 012F ; - don't want to look at anyone else's work. ;0) 012F ; 012F ; 012F ; 012F ; 012F ; Architecture/C assumptions: 012F ; 1) 'D' register is the accumulator 012F ; 2) 'X' register points to the top of the current stack 012F ; 3) 'Y' register is for general use in indexed operations 012F ; 4) the heap grows upward and mem segments allocated by malloc, 012F ; realloc, and calloc are linear and contiguous. 012F ; 5) the stack grows downwards, and there is no boundary checking. 012F ; 6) chars are one byte 012F ; ints are two bytes 012F ; longs are 4 bytes 012F ; 7) only 1536 (1.5k) of the 2k ram are available 012F ; 8) register base is 0x0000 012F ; 012F ; Potential problem areas: 012F ; 1) 'running' section of the kernel get's compiled using extra 012F ; push and pop instructions 012F ; 2) run out of ram (global + stack + heap) 012F ; 012F ; */ 012F ; 012F ; 012F ; 012F ; #include <912d60.h> 012F ; #include 012F ; #include 012F ; #include 012F ; #include "kernel.h" 012F ; 012F ; 012F ; 012F ; // FUNCTION PROTOTYPES 012F ; void RTI_handler(void); 012F ; int sysInit(void); 012F ; int shell(void); 012F ; int idleTask(void); 012F ; int (*task_ptr[MAXTASKS])(void); 012F ; 012F ; 012F ; 012F ; 012F ; // GLOBAL VARIABLES 012F ; unsigned char *main_frame_ptr = NULL; // bottom of main() frame 012F ; unsigned char *main_frame_x_ptr = NULL; // top of main() frame (x-reg ptr) 012F ; unsigned char *temp_task_frame_ptr = NULL; // temp CCR pointer for RTI 012F ; 012F ; 012F ; unsigned int current; // current task id number 012F ; unsigned long int system_tick; 012F ; unsigned int cop_cycle; 012F ; 012F ; unsigned long int time_tick; // one tick every x microseconds 012F ; 012F ; 012F ; // task control block 012F ; typedef struct task_block { 012F ; int (*address)(); // Address of the task 012F ; unsigned char id; // ID of task 012F ; char name[9]; // Name 012F ; enum task_state state; // State 012F ; unsigned char priority; // Priority 012F ; unsigned long int period_tick; // for determining if deadline is up 012F ; unsigned int interrupt_msg_box; // flags for pending interrupts 012F ; enum message_box message; // misc flags 012F ; unsigned char message_data[2]; // data for misc_msg_box flags 012F ; unsigned int stack_size; // heap allocated for task stack 012F ; unsigned char *top_of_stack; // top of task stack in the heap 012F ; unsigned char *frame_ptr; // CCR pointer in idle stack 012F ; }; 012F ; 012F ; 012F ; // mutex control block 012F ; typedef struct mutex_block { 012F ; unsigned char id; // ID of mutex instance 012F ; unsigned char type; // COM1, ATD1, etc 012F ; char name[5]; // Name of mutex 012F ; enum mutex_state state; // State (busy, free...) 012F ; signed char owner; // Current mutex owner 012F ; signed char queue[3]; // Tasks waiting on mutex 012F ; unsigned char queue_ptr; // Next free spot in queue 012F ; }; 012F ; 012F ; 012F ; struct task_block *task[MAXTASKS]; 012F ; struct mutex_block *mutex[MAXMUTEXES]; 012F ; 012F ; 012F ; 012F ; int kdb_trace = 1; 012F ; int kdb_trace_cycle = 0; 012F ; 012F ; 012F ; struct time { 012F ; char hours; 012F ; char minutes; 012F ; char seconds; 012F ; int milliseconds; 012F ; }; 012F ; 012F ; int exit_status; 012F ; 012F ; 012F ; 012F ; // global interrupt flags 012F ; //unsigned int interrupt_flags_ADC; 012F ; //unsigned int interrupt_flags_TC; 012F ; 012F ; 012F ; 012F ; 012F ; // error massages 012F ; const char error_msg[][25] = {"unimplimented function", // error 0 012F ; "syntax error", // error 1 012F ; "illegal task ID", // error 2 012F ; "illegal task state", // error 3 012F ; "illegal task priority", // error 4 012F ; "out of memory", // error 5 012F ; "illegal mutex ID", // error 6 012F ; "illegal mutex state", // error 7 012F ; "cannot create task" // error 8 012F ; }; 012F ; const char error_src[][18] = {"kernel error:", // source 0 012F ; "kernel.c error:", // source 1 012F ; "kernel RTI error:", // source 2 012F ; "shell error:", // source 3 012F ; }; 012F ; 012F ; 012F ; 012F ; 012F ; 012F ; void main(void) { 012F ; 012F ; // LOCAL VARIABLES 012F ; int result, id, i; 012F ; unsigned char priority_check; 012F ; unsigned int deadline; 012F ; 012F ; 012F ; 012F ; // INITIALIZE the kernel 012F ; kernel_init(); 012F 160400 jsr _kernel_init 0132 ; 0132 ; 0132 ; // save SP value for use in the RTI 0132 ; asm("TFR s,d"); 0132 B774 TFR s,d 0134 0134 ; asm("STD _main_frame_ptr"); 0134 7C0000 STD _main_frame_ptr 0137 0137 ; // save X reg value for use in the RTI 0137 ; asm("TFR x,d"); 0137 B754 TFR x,d 0139 0139 ; asm("STD _main_frame_x_ptr"); 0139 7C0002 STD _main_frame_x_ptr 013C 013C 1820022A lbra L5 0140 L4: 0140 ; 0140 ; 0140 ; 0140 ; // MULTITASKING KERNEL: Priority Preemptive, Real Time, multitasking 0140 ; // KDB_TRACE Section 2 0140 ; while(1) { 0140 ; 0140 ; //------------------------------- 0140 ; /* REENTRY POINT after either 0140 ; 1) task finishes, or 0140 ; 2) RTI 0140 ; */ 0140 ; //------------------------------- 0140 ; 0140 ; 0140 ; if (kdb_trace_cycle >= KDB_CYCLES) 0140 FC0008 ldd _kdb_trace_cycle 0143 8C0004 cpd #4 0146 2D06 blt L7 0148 ; kdb_trace = 0; 0148 CC0000 ldd #0 014B 7C0006 std _kdb_trace 014E L7: 014E ; 014E ; #ifdef KDB_TRACE_LEVEL_1 014E ; if (kdb_trace) puts("kDB2.1"); 014E ; #endif 014E ; 014E ; 014E ; /* No RTI interrupts allowed inside of main(). Only allowed 014E ; inside of non-critical sections of tasks */ 014E ; //INTR_OFF(); 014E ; 014E ; 014E ; // PET THE DOG: cop watchdog reset timer (pet freq = 2x COP freq) 014E ; if (cop_cycle == 4) { 014E FC001E ldd _cop_cycle 0151 8C0004 cpd #4 0154 2610 bne L9 0156 ; COP_PET(0x55); 0156 C655 ldab #85 0158 7B0017 stab 0x17 015B ; COP_PET(0xAA); 015B C6AA ldab #170 015D 7B0017 stab 0x17 0160 ; cop_cycle = 0; 0160 CC0000 ldd #0 0163 7C001E std _cop_cycle 0166 ; //putchar(':'); 0166 ; } 0166 L9: 0166 CC0000 ldd #0 0169 6C16 std -10,x 016B L11: 016B ; #ifdef KDB_TRACE_LEVEL_1 016B ; if (kdb_trace) puts("kDB2.2-1"); 016B ; #endif 016B ; 016B ; 016B ; 016B ; // CHANGE STATES ACCORDING TO MESSAGES 016B ; // 'waiting' needs to have highest precedence here 016B ; for (i=0; imessage && STATE_FLAG) { 0179 EC16 ldd -10,x 017B 59 lsld 017C C3000A addd #_task 017F B7C6 xgdy 0181 ED40 ldy 0,y 0183 E7E814 tst 20,y 0186 2732 beq L17 0188 ; // set task state to what the message says 0188 ; task[i]->state = task[i]->message_data[STATE_BOX]; 0188 EC16 ldd -10,x 018A 59 lsld 018B C3000A addd #_task 018E B7C6 xgdy 0190 ED40 ldy 0,y 0192 6DE1ED sty -19,x 0195 EDE1ED ldy -19,x 0198 E6E815 ldab 21,y 019B EDE1ED ldy -19,x 019E 6B4C stab 12,y 01A0 ; // clear the STATE_FLAG 01A0 ; task[i]->message &= ~(STATE_FLAG); 01A0 EC16 ldd -10,x 01A2 59 lsld 01A3 C3000A addd #_task 01A6 B7C6 xgdy 01A8 EC40 ldd 0,y 01AA C30014 addd #20 01AD 6CE1EB std -21,x 01B0 B746 tfr d,y 01B2 35 pshy ; spill 01B3 EDE1EB ldy -21,x 01B6 31 puly ; reload 01B7 0D4001 bclr 0,y,#0x1 01BA ; #ifdef KDB_TRACE_LEVEL_2 01BA ; if (kdb_trace) puts("kDB2.3-2a"); 01BA ; #endif 01BA ; } 01BA L17: 01BA L12: 01BA EC16 ldd -10,x 01BC C30001 addd #1 01BF 6C16 std -10,x 01C1 EC16 ldd -10,x 01C3 8C0008 cpd #8 01C6 2DA3 blt L11 01C8 CC0000 ldd #0 01CB 6C16 std -10,x 01CD L19: 01CD ; #ifdef KDB_TRACE_LEVEL_2 01CD ; if (kdb_trace) puts("kDB2.3-2b"); 01CD ; #endif 01CD ; } 01CD ; #ifdef KDB_TRACE_LEVEL_1 01CD ; if (kdb_trace) puts("kDB2.3-1"); 01CD ; #endif 01CD ; 01CD ; 01CD ; 01CD ; // RT PRIORITY BLOCK: 01CD ; // set the current task id based on priority and deadline 01CD ; 01CD ; // determine if the deadline is up for idle tasks 01CD ; /* deadline, is equal to period plus an initial time (t0) reference 01CD ; (t0 = system_tick). Period = priority + 1. 01CD ; Changing the state from idle to PENDING occurs here. */ 01CD ; for (i=0; istate == IDLE) { 01CD EC16 ldd -10,x 01CF 59 lsld 01D0 C3000A addd #_task 01D3 B7C6 xgdy 01D5 ED40 ldy 0,y 01D7 E74C tst 12,y 01D9 2655 bne L23 01DB ; deadline = task[i]->period_tick + (task[i]->priority + 1); 01DB EC16 ldd -10,x 01DD 59 lsld 01DE C3000A addd #_task 01E1 B7C6 xgdy 01E3 ED40 ldy 0,y 01E5 6DE1ED sty -19,x 01E8 EDE1ED ldy -19,x 01EB E64D ldab 13,y 01ED 87 clra 01EE C30001 addd #1 01F1 160000 jsr __d2lreg2 01F4 EDE1ED ldy -19,x 01F7 194E leay 14,y 01F9 1802401C movw 0,y,-4,x 01FD 1802421E movw 2,y,-2,x 0201 160000 jsr __ladd 0204 160000 jsr __lreg2d 0207 6C14 std -12,x 0209 ; if (system_tick >= deadline) { 0209 CD0020 ldy #_system_tick 020C 1802401C movw 0,y,-4,x 0210 1802421E movw 2,y,-2,x 0214 EC14 ldd -12,x 0216 6C1A std -6,x 0218 1800180000 movw #0,-8,x 021D 160000 jsr __lcmp 0220 250E blo L25 0222 ; task[i]->state = PENDING; // change state at deadline 0222 EC16 ldd -10,x 0224 59 lsld 0225 C3000A addd #_task 0228 B7C6 xgdy 022A ED40 ldy 0,y 022C C601 ldab #1 022E 6B4C stab 12,y 0230 ; #ifdef KDB_TRACE_LEVEL_2 0230 ; if (kdb_trace) puts("kDB2.4-2"); 0230 ; #endif 0230 ; } 0230 L25: 0230 ; } 0230 L23: 0230 L20: 0230 EC16 ldd -10,x 0232 C30001 addd #1 0235 6C16 std -10,x 0237 EC16 ldd -10,x 0239 8C0008 cpd #8 023C 2D8F blt L19 023E ; // if (task[i]->message) {} ??? 023E ; } 023E ; #ifdef KDB_TRACE_LEVEL_1 023E ; if (kdb_trace) puts("kDB2.4-1"); 023E ; #endif 023E ; 023E ; 023E ; // set current = to highest priority pending/running task. 023E ; priority_check = 255; // lowest possible 023E C6FF ldab #255 0240 6B13 stab -13,x 0242 CC0000 ldd #0 0245 6C16 std -10,x 0247 L27: 0247 ; 0247 ; for (i=0; istate == PENDING) || (task[i]->state == RUNNING)) { 0270 ; if (task[i]->priority <= priority_check) { 0270 EC16 ldd -10,x 0272 59 lsld 0273 C3000A addd #_task 0276 B7C6 xgdy 0278 ED40 ldy 0,y 027A E64D ldab 13,y 027C E113 cmpb -13,x 027E 2213 bhi L36 0280 ; current = i; 0280 EC16 ldd -10,x 0282 7C0024 std _current 0285 ; priority_check = task[i]->priority; 0285 EC16 ldd -10,x 0287 59 lsld 0288 C3000A addd #_task 028B B7C6 xgdy 028D ED40 ldy 0,y 028F E64D ldab 13,y 0291 6B13 stab -13,x 0293 ; #ifdef KDB_TRACE_LEVEL_2 0293 ; if (kdb_trace) puts("kDB2.5-2"); 0293 ; #endif 0293 ; } 0293 L36: 0293 ; } 0293 L33: 0293 ; } 0293 L31: 0293 L28: 0293 EC16 ldd -10,x 0295 C30001 addd #1 0298 6C16 std -10,x 029A EC16 ldd -10,x 029C 8C0008 cpd #8 029F 2DA6 blt L27 02A1 FC0024 ldd _current 02A4 59 lsld 02A5 C3000A addd #_task 02A8 B7C6 xgdy 02AA ED40 ldy 0,y 02AC E64C ldab 12,y 02AE 87 clra 02AF 6CE1ED std -19,x 02B2 182700B4 lbeq L39 02B6 ECE1ED ldd -19,x 02B9 8C0001 cpd #1 02BC 2722 beq L42 02BE ECE1ED ldd -19,x 02C1 8C0002 cpd #2 02C4 1827007F lbeq L43 02C8 ECE1ED ldd -19,x 02CB 8C0003 cpd #3 02CE 18270098 lbeq L39 02D2 ECE1ED ldd -19,x 02D5 8C0004 cpd #4 02D8 1827008E lbeq L39 02DC 1820007E lbra L38 02E0 X0: 02E0 ; } 02E0 ; #ifdef KDB_TRACE_LEVEL_1 02E0 ; if (kdb_trace) puts("kDB2.5-1"); 02E0 ; #endif 02E0 ; 02E0 ; 02E0 ; 02E0 ; // DISPATCH, or otherwise deal with the current task 02E0 ; // KDB_TRACE Section 3 02E0 ; 02E0 ; #ifdef KDB_TRACE_LEVEL_2 02E0 ; if (kdb_trace) { 02E0 ; printf("task[%d]->state = %d\n", current, task[current]->state); 02E0 ; printf("task[%d]->prior = %d\n", current, task[current]->priority); 02E0 ; } 02E0 ; #endif 02E0 ; 02E0 ; switch (task[current]->state) { 02E0 ; case IDLE: // skip task 02E0 ; #ifdef KDB_TRACE_LEVEL_1 02E0 ; if (kdb_trace) puts("kDB3.1-1"); 02E0 ; #endif 02E0 ; break; 02E0 L42: 02E0 ; case PENDING: // ready and waiting to run 02E0 ; #ifdef KDB_TRACE_LEVEL_1 02E0 ; if (kdb_trace) puts("kDB3.2-1"); 02E0 ; #endif 02E0 ; #ifdef KDB_TRACE_LEVEL_2 02E0 ; if (kdb_trace) { 02E0 ; //puts("kDB3.2-2"); 02E0 ; putchar('S'); 02E0 ; putchar(current+48); 02E0 ; putchar('\n'); 02E0 ; } 02E0 ; #endif 02E0 ; task[current]->state = RUNNING; 02E0 FC0024 ldd _current 02E3 59 lsld 02E4 C3000A addd #_task 02E7 B7C6 xgdy 02E9 ED40 ldy 0,y 02EB C602 ldab #2 02ED 6B4C stab 12,y 02EF ; task[current]->period_tick = system_tick; 02EF FC0024 ldd _current 02F2 59 lsld 02F3 C3000A addd #_task 02F6 B7C6 xgdy 02F8 ED40 ldy 0,y 02FA 194E leay 14,y 02FC 35 pshy ; spill 02FD CD0020 ldy #_system_tick 0300 1802401C movw 0,y,-4,x 0304 1802421E movw 2,y,-2,x 0308 31 puly ; reload 0309 18021C40 movw -4,x,0,y 030D 18021E42 movw -2,x,2,y 0311 ; temp_task_frame_ptr = task[current]->top_of_stack; 0311 FC0024 ldd _current 0314 59 lsld 0315 C3000A addd #_task 0318 B7C6 xgdy 031A ED40 ldy 0,y 031C EDE819 ldy 25,y 031F 7D0004 sty _temp_task_frame_ptr 0322 ; asm("LDS _temp_task_frame_ptr"); // set the SP 0322 FF0004 LDS _temp_task_frame_ptr 0325 0325 ; exit_status = (*task_ptr[current])(); // start the task 0325 FC0024 ldd _current 0328 59 lsld 0329 C30026 addd #_task_ptr 032C B7C6 xgdy 032E ED40 ldy 0,y 0330 1540 jsr 0,y 0332 7C0000 std _exit_status 0335 ; asm("LDS _main_frame_ptr"); // reset the SP 0335 FF0000 LDS _main_frame_ptr 0338 0338 ; task[current]->state = IDLE; // task finished 0338 FC0024 ldd _current 033B 59 lsld 033C C3000A addd #_task 033F B7C6 xgdy 0341 ED40 ldy 0,y 0343 694C clr 12,y 0345 ; #ifdef KDB_TRACE_LEVEL_1 0345 ; if (kdb_trace) puts("kDB3.3-1"); 0345 ; #endif 0345 ; #ifdef KDB_TRACE_LEVEL_2 0345 ; if (kdb_trace) { 0345 ; //puts("kDB3.3-2"); 0345 ; putchar('F'); 0345 ; putchar(current+48); 0345 ; putchar('\n'); 0345 ; } 0345 ; #endif 0345 ; break; 0345 2023 bra L39 0347 L43: 0347 ; case RUNNING: // interrupted. continue running. 0347 ; // restore context and run 0347 ; temp_task_frame_ptr = task[current]->frame_ptr; 0347 FC0024 ldd _current 034A 59 lsld 034B C3000A addd #_task 034E B7C6 xgdy 0350 ED40 ldy 0,y 0352 EDE81B ldy 27,y 0355 7D0004 sty _temp_task_frame_ptr 0358 ; asm("LDS _temp_task_frame_ptr"); 0358 FF0004 LDS _temp_task_frame_ptr 035B 035B ; asm("RTI"); 035B 0B RTI 035C 035C ; break; 035C 200C bra L39 035E X1: 035E ; case WAITING: // waiting on a mutex 035E ; #ifdef KDB_TRACE_LEVEL_1 035E ; if (kdb_trace) puts("kDB3.5-1"); 035E ; #endif 035E ; break; 035E ; case STOPPED: // done running until later 035E ; #ifdef KDB_TRACE_LEVEL_1 035E ; if (kdb_trace) puts("kDB3.6-1"); 035E ; #endif 035E ; break; 035E L38: 035E ; default: // shouldn't happen, but, error if so. 035E ; puts("KERNEL: task state error\n"); 035E CC0ECC ldd #L46 0361 160000 jsr _puts 0364 ; exit(1); 0364 CC0001 ldd #1 0367 160000 jsr _exit 036A ; } // end switch 036A L39: 036A L5: 036A 1820FDD2 lbra L4 036E X2: 036E ; 036E ; 036E ; 036E ; // exit_status HANDLER 036E ; //... 036E ; 036E ; 036E ; 036E ; } // end while(1) 036E ; 036E ; 036E ; } // end main() 036E L3: 036E B757 tfr x,s 0370 30 pulx 0371 .dbline 0 ; func end 0371 3D rts 0372 ; lreg1 -> -4,x 0372 ; lreg2 -> -8,x 0372 _RTI_handler:: 0372 34 pshx 0373 B775 tfr s,x 0375 1B98 leas -8,sp 0377 ; 0377 ; 0377 ; 0377 ; #pragma interrupt_handler RTI_handler() 0377 ; 0377 ; void RTI_handler(void) { 0377 ; 0377 ; //ACKNOWLEDGE THE INTERRUPT 0377 ; RTIFLG = 0x0080; // acknowledge/clear the interrupt 0377 C680 ldab #128 0379 7B0015 stab 0x15 037C ; 037C ; 037C ; #ifdef KDB_TRACE_LEVEL_1 037C ; if (kdb_trace) putchar('.'); 037C ; #endif 037C ; //putchar('.'); 037C ; 037C ; 037C ; // SET THE FRAME POINTER for the interupted task. 037C ; // should point to the CCR entry on the stack. 037C ; asm("TFR x,d"); // start of RTI stack 037C B754 TFR x,d 037E 037E ; asm("ADDD #2"); // adjust to CCR stack entry 037E C30002 ADDD #2 0381 0381 ; asm("STD _temp_task_frame_ptr"); // put into task_frame_ptr 0381 7C0004 STD _temp_task_frame_ptr 0384 0384 ; task[current]->frame_ptr = temp_task_frame_ptr; 0384 FC0024 ldd _current 0387 59 lsld 0388 C3000A addd #_task 038B B7C6 xgdy 038D ED40 ldy 0,y 038F FC0004 ldd _temp_task_frame_ptr 0392 6CE81B std 27,y 0395 ; 0395 ; 0395 ; 0395 ; // update system time base and cop reset counter 0395 ; system_tick++; 0395 CD0020 ldy #_system_tick 0398 1802401C movw 0,y,-4,x 039C 1802421E movw 2,y,-2,x 03A0 CD0EC8 ldy #L48 03A3 18024018 movw 0,y,-8,x 03A7 1802421A movw 2,y,-6,x 03AB 160000 jsr __ladd 03AE CD0020 ldy #_system_tick 03B1 18021C40 movw -4,x,0,y 03B5 18021E42 movw -2,x,2,y 03B9 ; cop_cycle++; 03B9 FC001E ldd _cop_cycle 03BC C30001 addd #1 03BF 7C001E std _cop_cycle 03C2 ; if (time_tick > TIME_TICKS_PER_DAY) { 03C2 CD001A ldy #_time_tick 03C5 1802401C movw 0,y,-4,x 03C9 1802421E movw 2,y,-2,x 03CD CD0EC4 ldy #L51 03D0 18024018 movw 0,y,-8,x 03D4 1802421A movw 2,y,-6,x 03D8 160000 jsr __lcmp 03DB 2316 bls L49 03DD ; time_tick = 0; 03DD CD0EC0 ldy #L52 03E0 1802401C movw 0,y,-4,x 03E4 1802421E movw 2,y,-2,x 03E8 CD001A ldy #_time_tick 03EB 18021C40 movw -4,x,0,y 03EF 18021E42 movw -2,x,2,y 03F3 ; } 03F3 L49: 03F3 ; 03F3 ; 03F3 ; 03F3 ; // RETURN: simulate a RTS instruction 03F3 ; // set stack pointer for main() 03F3 ; asm("LDS _main_frame_ptr"); 03F3 FF0000 LDS _main_frame_ptr 03F6 03F6 ; asm("LDX _main_frame_x_ptr"); 03F6 FE0002 LDX _main_frame_x_ptr 03F9 03F9 ; /* return to main() at the reentry point 03F9 ; and must be adjusted after some kernel mods/compilations!! */ 03F9 ; asm("JMP $116A"); 03F9 06116A JMP $116A 03FC 03FC ; 03FC ; } 03FC L47: 03FC B757 tfr x,s 03FE 30 pulx 03FF .dbline 0 ; func end 03FF 0B rti 0400 ; lreg1 -> -4,x 0400 ; lreg2 -> -8,x 0400 ; i -> -10,x 0400 _kernel_init:: 0400 34 pshx 0401 B775 tfr s,x 0403 1BF1EE leas -18,sp 0406 ; 0406 ; 0406 ; 0406 ; 0406 ; void kernel_init(void) { 0406 ; 0406 ; // LOCAL VARIABLES 0406 ; extern int _bss_end, _textmode; 0406 ; int i; 0406 ; 0406 ; 0406 ; 0406 ; // START/INITIALIZE the os 0406 ; // KDB_TRACE Section 1 0406 ; 0406 ; 0406 ; // initialize globals 0406 ; _textmode = 1; // maps '\n' to "CR/LF" for Windows terminals 0406 CC0001 ldd #1 0409 7C0000 std __textmode 040C ; 040C ; 040C ; // create and initialize the heap (for dynamic (runtime) var allocation) 040C ; _NewHeap(&_bss_end, (char *)(&_bss_end) + (INITIAL_HEAP_SIZE)); 040C CC04FA ldd #__bss_end+1274 040F 6C80 std 0,sp 0411 CC0000 ldd #__bss_end 0414 160000 jsr __NewHeap 0417 ; 0417 ; 0417 ; // set up the serial port 0417 ; setbaud(BAUD38K); // actually running at 19K baud due to xtal speed 0417 CC000D ldd #13 041A 160000 jsr _setbaud 041D ; #ifdef KDB_TRACE_LEVEL_1 041D ; if (kdb_trace) puts("kDB1-0"); 041D ; #endif 041D ; 041D ; 041D ; // print the opening comments 041D ; puts("rlpOS v0.8\n\n"); 041D CC0EB3 ldd #L55 0420 160000 jsr _puts 0423 ; 0423 ; 0423 ; // create the shell 0423 ; if (create_task("shell", &shell, 0, PENDING, DEFAULT_SHELL_STACK_SIZE) < 0) 0423 CC015E ldd #350 0426 6C86 std 6,sp 0428 CC0001 ldd #1 042B 6C84 std 4,sp 042D CC0000 ldd #0 0430 6C82 std 2,sp 0432 CC0000 ldd #_shell 0435 6C80 std 0,sp 0437 CC0EAD ldd #L58 043A 1607FD jsr _create_task 043D 8C0000 cpd #0 0440 2C06 bge L56 0442 ; puts("shell failure"); 0442 CC0E9F ldd #L59 0445 160000 jsr _puts 0448 L56: 0448 ; #ifdef KDB_TRACE_LEVEL_1 0448 ; if (kdb_trace) puts("kDB1-2"); 0448 ; #endif 0448 ; 0448 ; 0448 ; if (create_task("idleTask", &idleTask, 255, PENDING, 32) < 0) 0448 CC0020 ldd #32 044B 6C86 std 6,sp 044D CC0001 ldd #1 0450 6C84 std 4,sp 0452 CC00FF ldd #255 0455 6C82 std 2,sp 0457 CC0000 ldd #_idleTask 045A 6C80 std 0,sp 045C CC0E96 ldd #L62 045F 1607FD jsr _create_task 0462 8C0000 cpd #0 0465 2C06 bge L60 0467 ; puts("idleTask failure"); 0467 CC0E85 ldd #L63 046A 160000 jsr _puts 046D L60: 046D ; #ifdef KDB_TRACE_LEVEL_1 046D ; if (kdb_trace) puts("kDB1-2"); 046D ; #endif 046D ; 046D ; 046D ; // create the COM1 mutex 046D ; if (create_mutex(COM1, "COM1") < 0) 046D CC0E80 ldd #L66 0470 6C80 std 0,sp 0472 CC0003 ldd #3 0475 160A74 jsr _create_mutex 0478 8C0000 cpd #0 047B 2C06 bge L64 047D ; puts("COM1 failure"); 047D CC0E73 ldd #L67 0480 160000 jsr _puts 0483 L64: 0483 ; #ifdef KDB_TRACE_LEVEL_1 0483 ; if (kdb_trace) puts("kDB1-1"); 0483 ; #endif 0483 ; 0483 ; 0483 ; system_tick = 0; 0483 CD0EC0 ldy #L52 0486 1802401C movw 0,y,-4,x 048A 1802421E movw 2,y,-2,x 048E CD0020 ldy #_system_tick 0491 18021C40 movw -4,x,0,y 0495 18021E42 movw -2,x,2,y 0499 ; current = 0; 0499 CC0000 ldd #0 049C 7C0024 std _current 049F ; cop_cycle = 0; 049F CC0000 ldd #0 04A2 7C001E std _cop_cycle 04A5 ; COP_PET(0x55); 04A5 C655 ldab #85 04A7 7B0017 stab 0x17 04AA ; COP_PET(0xAA); 04AA C6AA ldab #170 04AC 7B0017 stab 0x17 04AF ; 04AF ; 04AF ; 04AF ; /*// create the sysInit task 04AF ; if (create_task("sysInit", &sysInit, 0, PENDING, 0) < 0) 04AF ; puts("sysInit failure"); 04AF ; #ifdef KDB_TRACE_LEVEL_1 04AF ; if (kdb_trace) puts("kDB1-1"); 04AF ; #endif*/ 04AF ; sysInit(); 04AF 160000 jsr _sysInit 04B2 ; 04B2 ; } 04B2 L53: 04B2 B757 tfr x,s 04B4 30 pulx 04B5 .dbline 0 ; func end 04B5 3D rts 04B6 ; id -> 3,x 04B6 _if_task_exists:: 04B6 3B pshd 04B7 34 pshx 04B8 B775 tfr s,x 04BA ; 04BA ; 04BA ; 04BA ; // KERNEL FUNCTIONS 04BA ; 04BA ; int if_task_exists(unsigned char id) { 04BA ; 04BA ; if (task[id] == NULL) 04BA E603 ldab 3,x 04BC 87 clra 04BD 59 lsld 04BE C3000A addd #_task 04C1 B7C6 xgdy 04C3 EC40 ldd 0,y 04C5 2605 bne L69 04C7 ; return -1; 04C7 CCFFFF ldd #-1 04CA 200E bra L68 04CC L69: 04CC ; else 04CC ; return task[id]->id; 04CC E603 ldab 3,x 04CE 87 clra 04CF 59 lsld 04D0 C3000A addd #_task 04D3 B7C6 xgdy 04D5 ED40 ldy 0,y 04D7 E642 ldab 2,y 04D9 87 clra 04DA L68: 04DA B757 tfr x,s 04DC 30 pulx 04DD 1B82 leas 2,sp 04DF .dbline 0 ; func end 04DF 3D rts 04E0 ; id -> 3,x 04E0 _get_task_address:: 04E0 3B pshd 04E1 34 pshx 04E2 B775 tfr s,x 04E4 ; 04E4 ; } 04E4 ; 04E4 ; 04E4 ; 04E4 ; 04E4 ; int get_task_address(unsigned char id) { 04E4 ; 04E4 ; return (int)task[id]->address; 04E4 E603 ldab 3,x 04E6 87 clra 04E7 59 lsld 04E8 C3000A addd #_task 04EB B7C6 xgdy 04ED ECEB0000 ldd [0,y] 04F1 L71: 04F1 B757 tfr x,s 04F3 30 pulx 04F4 1B82 leas 2,sp 04F6 .dbline 0 ; func end 04F6 3D rts 04F7 _get_task_id:: 04F7 ; 04F7 ; } 04F7 ; 04F7 ; 04F7 ; 04F7 ; 04F7 ; char get_task_id() { 04F7 ; 04F7 ; return task[current]->id; 04F7 FC0024 ldd _current 04FA 59 lsld 04FB C3000A addd #_task 04FE B7C6 xgdy 0500 ED40 ldy 0,y 0502 E642 ldab 2,y 0504 87 clra 0505 L72: 0505 .dbline 0 ; func end 0505 3D rts 0506 ; id -> 3,x 0506 _get_task_name:: 0506 3B pshd 0507 34 pshx 0508 B775 tfr s,x 050A ; } 050A ; 050A ; 050A ; 050A ; char *get_task_name(unsigned char id) { 050A ; if (task[id] == NULL) 050A E603 ldab 3,x 050C 87 clra 050D 59 lsld 050E C3000A addd #_task 0511 B7C6 xgdy 0513 EC40 ldd 0,y 0515 2605 bne L74 0517 ; return NULL; 0517 CC0000 ldd #0 051A 200E bra L73 051C L74: 051C ; else 051C ; return task[id]->name; 051C E603 ldab 3,x 051E 87 clra 051F 59 lsld 0520 C3000A addd #_task 0523 B7C6 xgdy 0525 EC40 ldd 0,y 0527 C30003 addd #3 052A L73: 052A B757 tfr x,s 052C 30 pulx 052D 1B82 leas 2,sp 052F .dbline 0 ; func end 052F 3D rts 0530 ; id -> 3,x 0530 _get_task_state:: 0530 3B pshd 0531 34 pshx 0532 B775 tfr s,x 0534 ; } 0534 ; 0534 ; 0534 ; 0534 ; 0534 ; int get_task_state(unsigned char id) { 0534 ; 0534 ; if (task[id] == NULL) 0534 E603 ldab 3,x 0536 87 clra 0537 59 lsld 0538 C3000A addd #_task 053B B7C6 xgdy 053D EC40 ldd 0,y 053F 2605 bne L77 0541 ; return -1; 0541 CCFFFF ldd #-1 0544 2019 bra L76 0546 L77: 0546 ; else if (id < MAXTASKS) 0546 E603 ldab 3,x 0548 C108 cmpb #8 054A 2410 bhs L79 054C ; return task[id]->state; 054C E603 ldab 3,x 054E 87 clra 054F 59 lsld 0550 C3000A addd #_task 0553 B7C6 xgdy 0555 ED40 ldy 0,y 0557 E64C ldab 12,y 0559 87 clra 055A 2003 bra L76 055C L79: 055C ; else { 055C ; #ifdef KERNEL_ERROR_MSG 055C ; puts(error_src[1]); puts(error_msg[3]); 055C ; #endif 055C ; return -1; 055C CCFFFF ldd #-1 055F L76: 055F B757 tfr x,s 0561 30 pulx 0562 1B82 leas 2,sp 0564 .dbline 0 ; func end 0564 3D rts 0565 ; id -> 3,x 0565 _get_task_messages:: 0565 3B pshd 0566 34 pshx 0567 B775 tfr s,x 0569 ; } 0569 ; 0569 ; } 0569 ; 0569 ; 0569 ; 0569 ; int get_task_messages(unsigned char id) { 0569 ; 0569 ; if (task[id] == NULL) 0569 E603 ldab 3,x 056B 87 clra 056C 59 lsld 056D C3000A addd #_task 0570 B7C6 xgdy 0572 EC40 ldd 0,y 0574 2605 bne L82 0576 ; return -1; 0576 CCFFFF ldd #-1 0579 201A bra L81 057B L82: 057B ; else if (id < MAXTASKS) 057B E603 ldab 3,x 057D C108 cmpb #8 057F 2411 bhs L84 0581 ; return task[id]->message; 0581 E603 ldab 3,x 0583 87 clra 0584 59 lsld 0585 C3000A addd #_task 0588 B7C6 xgdy 058A ED40 ldy 0,y 058C E6E814 ldab 20,y 058F 87 clra 0590 2003 bra L81 0592 L84: 0592 ; else { 0592 ; #ifdef KERNEL_ERROR_MSG 0592 ; puts(error_src[1]); puts(error_msg[3]); 0592 ; #endif 0592 ; return -1; 0592 CCFFFF ldd #-1 0595 L81: 0595 B757 tfr x,s 0597 30 pulx 0598 1B82 leas 2,sp 059A .dbline 0 ; func end 059A 3D rts 059B ; id -> 3,x 059B _get_task_priority:: 059B 3B pshd 059C 34 pshx 059D B775 tfr s,x 059F ; } 059F ; 059F ; } 059F ; 059F ; 059F ; 059F ; int get_task_priority(unsigned char id) { 059F ; 059F ; INTR_OFF(); 059F 1410 sei 05A1 05A1 ; 05A1 ; if (id < MAXTASKS) { 05A1 E603 ldab 3,x 05A3 C108 cmpb #8 05A5 2412 bhs L87 05A7 ; INTR_ON(); 05A7 10EF cli 05A9 05A9 ; return task[id]->priority; 05A9 E603 ldab 3,x 05AB 87 clra 05AC 59 lsld 05AD C3000A addd #_task 05B0 B7C6 xgdy 05B2 ED40 ldy 0,y 05B4 E64D ldab 13,y 05B6 87 clra 05B7 2005 bra L86 05B9 L87: 05B9 ; } 05B9 ; else { 05B9 ; #ifdef KERNEL_ERROR_MSG 05B9 ; puts(error_src[1]); puts(error_msg[4]); 05B9 ; #endif 05B9 ; INTR_ON(); 05B9 10EF cli 05BB 05BB ; return -1; 05BB CCFFFF ldd #-1 05BE L86: 05BE B757 tfr x,s 05C0 30 pulx 05C1 1B82 leas 2,sp 05C3 .dbline 0 ; func end 05C3 3D rts 05C4 ; ?temp -> -4,x 05C4 ; ?temp -> -4,x 05C4 ; ?temp -> -4,x 05C4 ; ?temp -> -4,x 05C4 ; ?temp -> -4,x 05C4 ; ?temp -> -2,x 05C4 ; newstate -> 7,x 05C4 ; id -> 3,x 05C4 _set_task_state:: 05C4 3B pshd 05C5 34 pshx 05C6 B775 tfr s,x 05C8 1B9C leas -4,sp 05CA ; } 05CA ; 05CA ; } 05CA ; 05CA ; 05CA ; 05CA ; int set_task_state(unsigned char id, unsigned char newstate) { 05CA ; 05CA ; 05CA ; INTR_OFF(); 05CA 1410 sei 05CC 05CC ; 05CC ; 05CC ; // check id validity 05CC ; if (id < MAXTASKS) { 05CC E603 ldab 3,x 05CE C108 cmpb #8 05D0 182401D9 lbhs L90 05D4 ; 05D4 ; if (task[id] == NULL) { 05D4 E603 ldab 3,x 05D6 87 clra 05D7 59 lsld 05D8 C3000A addd #_task 05DB B7C6 xgdy 05DD EC40 ldd 0,y 05DF 2609 bne L92 05E1 ; #ifdef KERNEL_ERROR_MSG 05E1 ; puts(error_src[1]); puts(error_msg[2]); 05E1 ; #endif 05E1 ; INTR_ON(); 05E1 10EF cli 05E3 05E3 ; return -1; 05E3 CCFFFF ldd #-1 05E6 182001CF lbra L89 05EA L92: 05EA ; } 05EA ; 05EA ; 05EA ; // check newstate validity 05EA ; if ((newstate == RUNNING) || 05EA E607 ldab 7,x 05EC C102 cmpb #2 05EE 270C beq L97 05F0 E607 ldab 7,x 05F2 C103 cmpb #3 05F4 2706 beq L97 05F6 E607 ldab 7,x 05F8 C104 cmpb #4 05FA 2309 bls L94 05FC L97: 05FC ; (newstate == WAITING) || 05FC ; (newstate > STOPPED)) { 05FC ; #ifdef KERNEL_ERROR_MSG 05FC ; puts(error_src[1]); puts(error_msg[3]); 05FC ; #endif 05FC ; INTR_ON(); 05FC 10EF cli 05FE 05FE ; return -1; 05FE CCFFFF ldd #-1 0601 182001B4 lbra L89 0605 L94: 0605 E603 ldab 3,x 0607 87 clra 0608 59 lsld 0609 C3000A addd #_task 060C B7C6 xgdy 060E ED40 ldy 0,y 0610 E64C ldab 12,y 0612 87 clra 0613 6C1E std -2,x 0615 271F beq L101 0617 EC1E ldd -2,x 0619 8C0001 cpd #1 061C 1827009C lbeq L108 0620 EC1E ldd -2,x 0622 8C0002 cpd #2 0625 182700F0 lbeq L115 0629 EC1E ldd -2,x 062B 8C0004 cpd #4 062E 18270128 lbeq L118 0632 18200170 lbra L98 0636 X3: 0636 ; } 0636 ; 0636 ; // referenced to the task's current state: 0636 ; switch (task[id]->state) { 0636 L101: 0636 ; case IDLE: 0636 ; if (newstate == IDLE) { // no change 0636 E707 tst 7,x 0638 2609 bne L102 063A ; INTR_ON(); 063A 10EF cli 063C 063C ; return 0; 063C CC0000 ldd #0 063F 18200176 lbra L89 0643 L102: 0643 ; } 0643 ; else if (newstate == PENDING) { 0643 E607 ldab 7,x 0645 C101 cmpb #1 0647 2632 bne L104 0649 ; // pass msg to task[id]->msgbox; 0649 ; task[id]->message |= STATE_FLAG; 0649 E603 ldab 3,x 064B 87 clra 064C 59 lsld 064D C3000A addd #_task 0650 B7C6 xgdy 0652 EC40 ldd 0,y 0654 C30014 addd #20 0657 6C1C std -4,x 0659 B746 tfr d,y 065B 35 pshy ; spill 065C ED1C ldy -4,x 065E 31 puly ; reload 065F 0C4001 bset 0,y,#1 0662 ; task[id]->message_data[STATE_BOX] = PENDING; 0662 E603 ldab 3,x 0664 87 clra 0665 59 lsld 0666 C3000A addd #_task 0669 B7C6 xgdy 066B ED40 ldy 0,y 066D C601 ldab #1 066F 6BE815 stab 21,y 0672 ; INTR_ON(); 0672 10EF cli 0674 0674 ; return 0; 0674 CC0000 ldd #0 0677 1820013E lbra L89 067B L104: 067B ; } 067B ; else if (newstate == STOPPED) { 067B E607 ldab 7,x 067D C104 cmpb #4 067F 2632 bne L106 0681 ; // pass msg to task[id]->msgbox; 0681 ; task[id]->message |= STATE_FLAG; 0681 E603 ldab 3,x 0683 87 clra 0684 59 lsld 0685 C3000A addd #_task 0688 B7C6 xgdy 068A EC40 ldd 0,y 068C C30014 addd #20 068F 6C1C std -4,x 0691 B746 tfr d,y 0693 35 pshy ; spill 0694 ED1C ldy -4,x 0696 31 puly ; reload 0697 0C4001 bset 0,y,#1 069A ; task[id]->message_data[STATE_BOX] = STOPPED; 069A E603 ldab 3,x 069C 87 clra 069D 59 lsld 069E C3000A addd #_task 06A1 B7C6 xgdy 06A3 ED40 ldy 0,y 06A5 C604 ldab #4 06A7 6BE815 stab 21,y 06AA ; INTR_ON(); 06AA 10EF cli 06AC 06AC ; return 0; 06AC CC0000 ldd #0 06AF 18200106 lbra L89 06B3 L106: 06B3 ; } 06B3 ; else { // nothing else is legal; 06B3 ; #ifdef KERNEL_ERROR_MSG 06B3 ; puts(error_src[1]); puts(error_msg[3]); 06B3 ; #endif 06B3 ; INTR_ON(); 06B3 10EF cli 06B5 06B5 ; return -1; 06B5 CCFFFF ldd #-1 06B8 182000FD lbra L89 06BC X4: 06BC ; } 06BC ; break; 06BC L108: 06BC ; case PENDING: 06BC ; if (newstate == PENDING) { // no change 06BC E607 ldab 7,x 06BE C101 cmpb #1 06C0 2609 bne L109 06C2 ; INTR_ON(); 06C2 10EF cli 06C4 06C4 ; return 0; 06C4 CC0000 ldd #0 06C7 182000EE lbra L89 06CB L109: 06CB ; } 06CB ; else if (newstate == IDLE) { 06CB E707 tst 7,x 06CD 2609 bne L111 06CF ; // pass msg to task[id]->msgbox; 06CF ; #ifdef KERNEL_ERROR_MSG 06CF ; puts(error_src[1]); puts(error_msg[0]); 06CF ; #endif 06CF ; INTR_ON(); 06CF 10EF cli 06D1 06D1 ; return -1; 06D1 CCFFFF ldd #-1 06D4 182000E1 lbra L89 06D8 L111: 06D8 ; } 06D8 ; else if (newstate == STOPPED) { 06D8 E607 ldab 7,x 06DA C104 cmpb #4 06DC 2632 bne L113 06DE ; // pass msg to task[id]->msgbox; 06DE ; task[id]->message |= STATE_FLAG; 06DE E603 ldab 3,x 06E0 87 clra 06E1 59 lsld 06E2 C3000A addd #_task 06E5 B7C6 xgdy 06E7 EC40 ldd 0,y 06E9 C30014 addd #20 06EC 6C1C std -4,x 06EE B746 tfr d,y 06F0 35 pshy ; spill 06F1 ED1C ldy -4,x 06F3 31 puly ; reload 06F4 0C4001 bset 0,y,#1 06F7 ; task[id]->message_data[STATE_BOX] = STOPPED; 06F7 E603 ldab 3,x 06F9 87 clra 06FA 59 lsld 06FB C3000A addd #_task 06FE B7C6 xgdy 0700 ED40 ldy 0,y 0702 C604 ldab #4 0704 6BE815 stab 21,y 0707 ; INTR_ON(); 0707 10EF cli 0709 0709 ; return 0; 0709 CC0000 ldd #0 070C 182000A9 lbra L89 0710 L113: 0710 ; } 0710 ; else { 0710 ; #ifdef KERNEL_ERROR_MSG 0710 ; puts(error_src[1]); puts(error_msg[3]); 0710 ; #endif 0710 ; INTR_ON(); 0710 10EF cli 0712 0712 ; return -1; 0712 CCFFFF ldd #-1 0715 182000A0 lbra L89 0719 X5: 0719 ; } 0719 ; break; 0719 L115: 0719 ; case RUNNING: 0719 ; if (newstate == STOPPED) { 0719 E607 ldab 7,x 071B C104 cmpb #4 071D 2632 bne L116 071F ; // pass msg to task[id]->msgbox; 071F ; task[id]->message |= STATE_FLAG; 071F E603 ldab 3,x 0721 87 clra 0722 59 lsld 0723 C3000A addd #_task 0726 B7C6 xgdy 0728 EC40 ldd 0,y 072A C30014 addd #20 072D 6C1C std -4,x 072F B746 tfr d,y 0731 35 pshy ; spill 0732 ED1C ldy -4,x 0734 31 puly ; reload 0735 0C4001 bset 0,y,#1 0738 ; task[id]->message_data[STATE_BOX] = STOPPED; 0738 E603 ldab 3,x 073A 87 clra 073B 59 lsld 073C C3000A addd #_task 073F B7C6 xgdy 0741 ED40 ldy 0,y 0743 C604 ldab #4 0745 6BE815 stab 21,y 0748 ; 0748 ; INTR_ON(); 0748 10EF cli 074A 074A ; return 0; 074A CC0000 ldd #0 074D 18200068 lbra L89 0751 L116: 0751 ; } 0751 ; else { 0751 ; #ifdef KERNEL_ERROR_MSG 0751 ; puts(error_src[1]); puts(error_msg[3]); 0751 ; #endif 0751 ; INTR_ON(); 0751 10EF cli 0753 0753 ; return -1; 0753 CCFFFF ldd #-1 0756 1820005F lbra L89 075A X6: 075A ; } 075A ; break; 075A L118: 075A ; case STOPPED: 075A ; if (newstate == STOPPED) { // no change 075A E607 ldab 7,x 075C C104 cmpb #4 075E 2609 bne L119 0760 ; INTR_ON(); 0760 10EF cli 0762 0762 ; return 0; 0762 CC0000 ldd #0 0765 18200050 lbra L89 0769 L119: 0769 ; } 0769 ; else if (newstate == PENDING) { 0769 E607 ldab 7,x 076B C101 cmpb #1 076D 2630 bne L121 076F ; // pass msg to task[id]->msgbox; 076F ; task[id]->message |= STATE_FLAG; 076F E603 ldab 3,x 0771 87 clra 0772 59 lsld 0773 C3000A addd #_task 0776 B7C6 xgdy 0778 EC40 ldd 0,y 077A C30014 addd #20 077D 6C1C std -4,x 077F B746 tfr d,y 0781 35 pshy ; spill 0782 ED1C ldy -4,x 0784 31 puly ; reload 0785 0C4001 bset 0,y,#1 0788 ; task[id]->message_data[STATE_BOX] = PENDING; 0788 E603 ldab 3,x 078A 87 clra 078B 59 lsld 078C C3000A addd #_task 078F B7C6 xgdy 0791 ED40 ldy 0,y 0793 C601 ldab #1 0795 6BE815 stab 21,y 0798 ; INTR_ON(); 0798 10EF cli 079A 079A ; return 0; 079A CC0000 ldd #0 079D 201A bra L89 079F L121: 079F ; } 079F ; else { 079F ; #ifdef KERNEL_ERROR_MSG 079F ; puts(error_src[1]); puts(error_msg[3]); 079F ; #endif 079F ; INTR_ON(); 079F 10EF cli 07A1 07A1 ; return -1; 07A1 CCFFFF ldd #-1 07A4 2013 bra L89 07A6 X7: 07A6 ; } 07A6 ; break; 07A6 L98: 07A6 ; default: 07A6 ; #ifdef KERNEL_ERROR_MSG 07A6 ; puts(error_src[1]); puts(error_msg[3]); 07A6 ; #endif 07A6 ; INTR_ON(); 07A6 10EF cli 07A8 07A8 ; return -1; 07A8 CCFFFF ldd #-1 07AB 200C bra L89 07AD X8: 07AD ; break; 07AD L90: 07AD ; 07AD ; } // end switch (task[id]->state) 07AD ; 07AD ; } // if (id < MAXTASKS) 07AD ; 07AD ; else { 07AD ; #ifdef KERNEL_ERROR_MSG 07AD ; puts(error_src[1]); puts(error_msg[2]); 07AD ; #endif 07AD ; INTR_ON(); 07AD 10EF cli 07AF 07AF ; return -1; 07AF CCFFFF ldd #-1 07B2 2005 bra L89 07B4 X9: 07B4 ; } 07B4 ; 07B4 ; INTR_ON(); 07B4 10EF cli 07B6 07B6 ; return 0; 07B6 CC0000 ldd #0 07B9 L89: 07B9 B757 tfr x,s 07BB 30 pulx 07BC 1B82 leas 2,sp 07BE .dbline 0 ; func end 07BE 3D rts 07BF ; priority -> 7,x 07BF ; id -> 3,x 07BF _set_task_priority:: 07BF 3B pshd 07C0 34 pshx 07C1 B775 tfr s,x 07C3 ; 07C3 ; } 07C3 ; 07C3 ; 07C3 ; 07C3 ; int set_task_priority(unsigned char id, unsigned char priority) { 07C3 ; 07C3 ; if (priority == 0) // priority 0 is reserved for the shell 07C3 E707 tst 7,x 07C5 2604 bne L124 07C7 ; priority = 1; 07C7 C601 ldab #1 07C9 6B07 stab 7,x 07CB L124: 07CB ; 07CB ; if (id >= (MAXTASKS)) { 07CB E603 ldab 3,x 07CD C108 cmpb #8 07CF 2505 blo L126 07D1 ; #ifdef KERNEL_ERROR_MSG 07D1 ; puts(error_src[1]); puts(error_msg[4]); 07D1 ; #endif 07D1 ; return -1; 07D1 CCFFFF ldd #-1 07D4 2021 bra L123 07D6 L126: 07D6 E607 ldab 7,x 07D8 C1FF cmpb #255 07DA 2204 bhi L130 07DC E707 tst 7,x 07DE 2405 bhs L128 07E0 L130: 07E0 ; } 07E0 ; else if ((priority > 255) || (priority < 0)) { 07E0 ; #ifdef KERNEL_ERROR_MSG 07E0 ; puts(error_src[1]); puts(error_msg[4]); 07E0 ; #endif 07E0 ; return -1; 07E0 CCFFFF ldd #-1 07E3 2012 bra L123 07E5 L128: 07E5 ; } 07E5 ; else { 07E5 ; task[id]->priority = priority; 07E5 E603 ldab 3,x 07E7 87 clra 07E8 59 lsld 07E9 C3000A addd #_task 07EC B7C6 xgdy 07EE ED40 ldy 0,y 07F0 E607 ldab 7,x 07F2 6B4D stab 13,y 07F4 ; return 0; 07F4 CC0000 ldd #0 07F7 L123: 07F7 B757 tfr x,s 07F9 30 pulx 07FA 1B82 leas 2,sp 07FC .dbline 0 ; func end 07FC 3D rts 07FD ; lreg1 -> -4,x 07FD ; lreg2 -> -8,x 07FD ; ?temp -> -15,x 07FD ; ?temp -> -13,x 07FD ; ?temp -> -11,x 07FD ; id -> -9,x 07FD ; stack_size -> 12,x 07FD ; state -> 10,x 07FD ; priority -> 9,x 07FD ; addr -> 6,x 07FD ; name -> 2,x 07FD _create_task:: 07FD 3B pshd 07FE 34 pshx 07FF B775 tfr s,x 0801 1BF1EA leas -22,sp 0804 ; } 0804 ; } 0804 ; 0804 ; 0804 ; 0804 ; 0804 ; int create_task(char *name, 0804 ; int (*addr)(), 0804 ; unsigned char priority, 0804 ; int state, 0804 ; int stack_size) { 0804 ; 0804 ; // LOCAL VARIABLES 0804 ; unsigned char id; 0804 ; 0804 ; 0804 ; INTR_OFF(); // critical section 0804 1410 sei 0806 0806 6917 clr -9,x 0808 2015 bra L135 080A L132: 080A E617 ldab -9,x 080C 87 clra 080D 59 lsld 080E C30026 addd #_task_ptr 0811 B7C6 xgdy 0813 EC40 ldd 0,y 0815 270E beq L134 0817 L133: 0817 E617 ldab -9,x 0819 87 clra 081A C30001 addd #1 081D 6B17 stab -9,x 081F L135: 081F ; 081F ; 081F ; //if (get_free_memory() > 64) { 081F ; 081F ; // determine lowest free id available to assign to this task 081F ; for (id=0; idaddress = addr; 0857 E617 ldab -9,x 0859 87 clra 085A 59 lsld 085B C3000A addd #_task 085E B7C6 xgdy 0860 ED40 ldy 0,y 0862 EC06 ldd 6,x 0864 6C40 std 0,y 0866 ; task[id]->id = id; 0866 E617 ldab -9,x 0868 87 clra 0869 59 lsld 086A C3000A addd #_task 086D B7C6 xgdy 086F ED40 ldy 0,y 0871 E617 ldab -9,x 0873 6B42 stab 2,y 0875 ; strcpy(task[id]->name, name); 0875 18020280 movw 2,x,0,sp 0879 E617 ldab -9,x 087B 87 clra 087C 59 lsld 087D C3000A addd #_task 0880 B7C6 xgdy 0882 EC40 ldd 0,y 0884 C30003 addd #3 0887 160000 jsr _strcpy 088A ; task[id]->state = state; 088A E617 ldab -9,x 088C 87 clra 088D 59 lsld 088E C3000A addd #_task 0891 B7C6 xgdy 0893 ED40 ldy 0,y 0895 EC0A ldd 10,x 0897 6B4C stab 12,y 0899 ; task[id]->priority = priority; 0899 E617 ldab -9,x 089B 87 clra 089C 59 lsld 089D C3000A addd #_task 08A0 B7C6 xgdy 08A2 ED40 ldy 0,y 08A4 E609 ldab 9,x 08A6 6B4D stab 13,y 08A8 ; task[id]->period_tick = 0; 08A8 E617 ldab -9,x 08AA 87 clra 08AB 59 lsld 08AC C3000A addd #_task 08AF B7C6 xgdy 08B1 ED40 ldy 0,y 08B3 194E leay 14,y 08B5 35 pshy ; spill 08B6 CD0EC0 ldy #L52 08B9 1802401C movw 0,y,-4,x 08BD 1802421E movw 2,y,-2,x 08C1 31 puly ; reload 08C2 18021C40 movw -4,x,0,y 08C6 18021E42 movw -2,x,2,y 08CA ; task[id]->interrupt_msg_box = NULL; 08CA E617 ldab -9,x 08CC 87 clra 08CD 59 lsld 08CE C3000A addd #_task 08D1 B7C6 xgdy 08D3 ED40 ldy 0,y 08D5 CC0000 ldd #0 08D8 6CE812 std 18,y 08DB ; task[id]->message = NULL; 08DB E617 ldab -9,x 08DD 87 clra 08DE 59 lsld 08DF C3000A addd #_task 08E2 B7C6 xgdy 08E4 ED40 ldy 0,y 08E6 69E814 clr 20,y 08E9 ; task[id]->message_data[0] = NULL; 08E9 E617 ldab -9,x 08EB 87 clra 08EC 59 lsld 08ED C3000A addd #_task 08F0 B7C6 xgdy 08F2 ED40 ldy 0,y 08F4 69E815 clr 21,y 08F7 ; task[id]->message_data[1] = NULL; 08F7 E617 ldab -9,x 08F9 87 clra 08FA 59 lsld 08FB C3000A addd #_task 08FE B7C6 xgdy 0900 ED40 ldy 0,y 0902 69E816 clr 22,y 0905 ; if (stack_size <= 0) 0905 EC0C ldd 12,x 0907 2E05 bgt L140 0909 ; stack_size = DEFAULT_STACK_SIZE; 0909 CC0040 ldd #64 090C 6C0C std 12,x 090E L140: 090E ; task[id]->stack_size = stack_size; 090E E617 ldab -9,x 0910 87 clra 0911 59 lsld 0912 C3000A addd #_task 0915 B7C6 xgdy 0917 ED40 ldy 0,y 0919 EC0C ldd 12,x 091B 6CE817 std 23,y 091E ; task[id]->top_of_stack = malloc(task[id]->stack_size); 091E E617 ldab -9,x 0920 87 clra 0921 59 lsld 0922 C3000A addd #_task 0925 B7C6 xgdy 0927 ED40 ldy 0,y 0929 6D15 sty -11,x 092B ED15 ldy -11,x 092D ECE817 ldd 23,y 0930 160000 jsr _malloc 0933 6CE1EC std -20,x 0936 ED15 ldy -11,x 0938 ECE1EC ldd -20,x 093B 6CE819 std 25,y 093E ; task[id]->top_of_stack += task[id]->stack_size; 093E E617 ldab -9,x 0940 87 clra 0941 59 lsld 0942 C3000A addd #_task 0945 B7C6 xgdy 0947 ED40 ldy 0,y 0949 6D13 sty -13,x 094B EC13 ldd -13,x 094D C30019 addd #25 0950 6C11 std -15,x 0952 ED13 ldy -13,x 0954 ECE817 ldd 23,y 0957 E3E3FFF1 addd [-15,x] 095B ED11 ldy -15,x 095D 6C40 std 0,y 095F ; task[id]->frame_ptr = NULL; 095F E617 ldab -9,x 0961 87 clra 0962 59 lsld 0963 C3000A addd #_task 0966 B7C6 xgdy 0968 ED40 ldy 0,y 096A CC0000 ldd #0 096D 6CE81B std 27,y 0970 ; 0970 ; } 0970 ; //} 0970 ; INTR_ON(); 0970 10EF cli 0972 0972 ; 0972 ; return id; 0972 E617 ldab -9,x 0974 87 clra 0975 L131: 0975 B757 tfr x,s 0977 30 pulx 0978 1B82 leas 2,sp 097A .dbline 0 ; func end 097A 3D rts 097B ; ?temp -> -2,x 097B ; id -> 3,x 097B _remove_task:: 097B 3B pshd 097C 34 pshx 097D B775 tfr s,x 097F 1B9E leas -2,sp 0981 ; 0981 ; } 0981 ; 0981 ; 0981 ; 0981 ; int remove_task(unsigned char id) { 0981 ; 0981 ; if (task[id] == NULL) 0981 E603 ldab 3,x 0983 87 clra 0984 59 lsld 0985 C3000A addd #_task 0988 B7C6 xgdy 098A EC40 ldd 0,y 098C 2605 bne L143 098E ; return -1; 098E CCFFFF ldd #-1 0991 2047 bra L142 0993 L143: 0993 ; 0993 ; 0993 ; free(task[id]->top_of_stack - task[id]->stack_size); 0993 E603 ldab 3,x 0995 87 clra 0996 59 lsld 0997 C3000A addd #_task 099A B7C6 xgdy 099C ED40 ldy 0,y 099E 6D1E sty -2,x 09A0 ED1E ldy -2,x 09A2 ECE819 ldd 25,y 09A5 ED1E ldy -2,x 09A7 A3E817 subd 23,y 09AA 160000 jsr _free 09AD ; free(task[id]); 09AD E603 ldab 3,x 09AF 87 clra 09B0 59 lsld 09B1 C3000A addd #_task 09B4 B7C6 xgdy 09B6 EC40 ldd 0,y 09B8 160000 jsr _free 09BB ; task[id] = NULL; 09BB E603 ldab 3,x 09BD 87 clra 09BE 59 lsld 09BF C3000A addd #_task 09C2 B7C6 xgdy 09C4 CC0000 ldd #0 09C7 6C40 std 0,y 09C9 ; task_ptr[id] = NULL; 09C9 E603 ldab 3,x 09CB 87 clra 09CC 59 lsld 09CD C30026 addd #_task_ptr 09D0 B7C6 xgdy 09D2 CC0000 ldd #0 09D5 6C40 std 0,y 09D7 ; 09D7 ; return 0; 09D7 CC0000 ldd #0 09DA L142: 09DA B757 tfr x,s 09DC 30 pulx 09DD 1B82 leas 2,sp 09DF .dbline 0 ; func end 09DF 3D rts 09E0 ; id -> 3,x 09E0 _get_mutex_name:: 09E0 3B pshd 09E1 34 pshx 09E2 B775 tfr s,x 09E4 ; 09E4 ; } 09E4 ; 09E4 ; 09E4 ; 09E4 ; char *get_mutex_name(unsigned char id) { 09E4 ; 09E4 ; if (mutex[id] == NULL) 09E4 E603 ldab 3,x 09E6 87 clra 09E7 59 lsld 09E8 C30002 addd #_mutex 09EB B7C6 xgdy 09ED EC40 ldd 0,y 09EF 2605 bne L146 09F1 ; return NULL; 09F1 CC0000 ldd #0 09F4 200E bra L145 09F6 L146: 09F6 ; else 09F6 ; return mutex[id]->name; 09F6 E603 ldab 3,x 09F8 87 clra 09F9 59 lsld 09FA C30002 addd #_mutex 09FD B7C6 xgdy 09FF EC40 ldd 0,y 0A01 C30002 addd #2 0A04 L145: 0A04 B757 tfr x,s 0A06 30 pulx 0A07 1B82 leas 2,sp 0A09 .dbline 0 ; func end 0A09 3D rts 0A0A ; id -> 3,x 0A0A _get_mutex_state:: 0A0A 3B pshd 0A0B 34 pshx 0A0C B775 tfr s,x 0A0E ; } 0A0E ; 0A0E ; 0A0E ; 0A0E ; 0A0E ; int get_mutex_state(unsigned char id) { 0A0E ; 0A0E ; if (id < MAXMUTEXES) { 0A0E E603 ldab 3,x 0A10 C104 cmpb #4 0A12 2410 bhs L149 0A14 ; return mutex[id]->state; 0A14 E603 ldab 3,x 0A16 87 clra 0A17 59 lsld 0A18 C30002 addd #_mutex 0A1B B7C6 xgdy 0A1D ED40 ldy 0,y 0A1F E647 ldab 7,y 0A21 87 clra 0A22 2003 bra L148 0A24 L149: 0A24 ; } 0A24 ; else { 0A24 ; #ifdef KERNEL_ERROR_MSG 0A24 ; puts(error_src[1]); puts(error_msg[6]); 0A24 ; #endif 0A24 ; return -1; 0A24 CCFFFF ldd #-1 0A27 L148: 0A27 B757 tfr x,s 0A29 30 pulx 0A2A 1B82 leas 2,sp 0A2C .dbline 0 ; func end 0A2C 3D rts 0A2D ; id -> 3,x 0A2D _get_mutex_owner:: 0A2D 3B pshd 0A2E 34 pshx 0A2F B775 tfr s,x 0A31 ; } 0A31 ; 0A31 ; } 0A31 ; 0A31 ; 0A31 ; 0A31 ; 0A31 ; 0A31 ; int get_mutex_owner(unsigned char id) { 0A31 ; 0A31 ; if (id < MAXMUTEXES) { 0A31 E603 ldab 3,x 0A33 C104 cmpb #4 0A35 2411 bhs L152 0A37 ; return mutex[id]->owner; 0A37 E603 ldab 3,x 0A39 87 clra 0A3A 59 lsld 0A3B C30002 addd #_mutex 0A3E B7C6 xgdy 0A40 ED40 ldy 0,y 0A42 E648 ldab 8,y 0A44 B714 tfr b,d 0A46 2003 bra L151 0A48 L152: 0A48 ; } 0A48 ; else { 0A48 ; #ifdef KERNEL_ERROR_MSG 0A48 ; puts(error_src[1]); puts(error_msg[6]); 0A48 ; #endif 0A48 ; return -1; 0A48 CCFFFF ldd #-1 0A4B L151: 0A4B B757 tfr x,s 0A4D 30 pulx 0A4E 1B82 leas 2,sp 0A50 .dbline 0 ; func end 0A50 3D rts 0A51 ; id -> 3,x 0A51 _get_mutex_queuelen:: 0A51 3B pshd 0A52 34 pshx 0A53 B775 tfr s,x 0A55 ; } 0A55 ; 0A55 ; } 0A55 ; 0A55 ; 0A55 ; 0A55 ; 0A55 ; int get_mutex_queuelen(unsigned char id) { 0A55 ; 0A55 ; if (id < MAXMUTEXES) { 0A55 E603 ldab 3,x 0A57 C104 cmpb #4 0A59 2410 bhs L155 0A5B ; return mutex[id]->queue_ptr; 0A5B E603 ldab 3,x 0A5D 87 clra 0A5E 59 lsld 0A5F C30002 addd #_mutex 0A62 B7C6 xgdy 0A64 ED40 ldy 0,y 0A66 E64C ldab 12,y 0A68 87 clra 0A69 2003 bra L154 0A6B L155: 0A6B ; } 0A6B ; else { 0A6B ; #ifdef KERNEL_ERROR_MSG 0A6B ; puts(error_src[1]); puts(error_msg[6]); 0A6B ; #endif 0A6B ; return -1; 0A6B CCFFFF ldd #-1 0A6E L154: 0A6E B757 tfr x,s 0A70 30 pulx 0A71 1B82 leas 2,sp 0A73 .dbline 0 ; func end 0A73 3D rts 0A74 ; id -> -1,x 0A74 ; name -> 6,x 0A74 ; type -> 3,x 0A74 _create_mutex:: 0A74 3B pshd 0A75 34 pshx 0A76 B775 tfr s,x 0A78 1B9A leas -6,sp 0A7A ; } 0A7A ; 0A7A ; } 0A7A ; 0A7A ; 0A7A ; 0A7A ; 0A7A ; int create_mutex(unsigned char type, char *name) { 0A7A ; 0A7A ; // LOCAL VARIABLES 0A7A ; unsigned char id; 0A7A ; 0A7A ; 0A7A ; INTR_OFF(); // critical section 0A7A 1410 sei 0A7C 0A7C 691F clr -1,x 0A7E 2031 bra L161 0A80 L158: 0A80 ; 0A80 ; 0A80 ; // determine if the type already exists 0A80 ; for (id=0; idtype == type) { 0A8F E61F ldab -1,x 0A91 87 clra 0A92 59 lsld 0A93 C30002 addd #_mutex 0A96 B7C6 xgdy 0A98 ED40 ldy 0,y 0A9A E641 ldab 1,y 0A9C E103 cmpb 3,x 0A9E 2609 bne L164 0AA0 ; INTR_ON(); 0AA0 10EF cli 0AA2 0AA2 ; return 0; 0AA2 CC0000 ldd #0 0AA5 182000DD lbra L157 0AA9 L164: 0AA9 L159: 0AA9 E61F ldab -1,x 0AAB 87 clra 0AAC C30001 addd #1 0AAF 6B1F stab -1,x 0AB1 L161: 0AB1 E61F ldab -1,x 0AB3 C104 cmpb #4 0AB5 25C9 blo L158 0AB7 691F clr -1,x 0AB9 2015 bra L169 0ABB L166: 0ABB E61F ldab -1,x 0ABD 87 clra 0ABE 59 lsld 0ABF C30002 addd #_mutex 0AC2 B7C6 xgdy 0AC4 EC40 ldd 0,y 0AC6 270E beq L168 0AC8 L167: 0AC8 E61F ldab -1,x 0ACA 87 clra 0ACB C30001 addd #1 0ACE 6B1F stab -1,x 0AD0 L169: 0AD0 ; } 0AD0 ; } 0AD0 ; 0AD0 ; 0AD0 ; // determine lowest free id available to assign to this task 0AD0 ; for (id=0; idid = id; 0AF8 E61F ldab -1,x 0AFA 87 clra 0AFB 59 lsld 0AFC C30002 addd #_mutex 0AFF B7C6 xgdy 0B01 ED40 ldy 0,y 0B03 E61F ldab -1,x 0B05 6B40 stab 0,y 0B07 ; mutex[id]->type = type; 0B07 E61F ldab -1,x 0B09 87 clra 0B0A 59 lsld 0B0B C30002 addd #_mutex 0B0E B7C6 xgdy 0B10 ED40 ldy 0,y 0B12 E603 ldab 3,x 0B14 6B41 stab 1,y 0B16 ; strcpy(mutex[id]->name, name); 0B16 18020680 movw 6,x,0,sp 0B1A E61F ldab -1,x 0B1C 87 clra 0B1D 59 lsld 0B1E C30002 addd #_mutex 0B21 B7C6 xgdy 0B23 EC40 ldd 0,y 0B25 C30002 addd #2 0B28 160000 jsr _strcpy 0B2B ; mutex[id]->state = NOTBUSY; 0B2B E61F ldab -1,x 0B2D 87 clra 0B2E 59 lsld 0B2F C30002 addd #_mutex 0B32 B7C6 xgdy 0B34 ED40 ldy 0,y 0B36 6947 clr 7,y 0B38 ; mutex[id]->owner = -1; 0B38 E61F ldab -1,x 0B3A 87 clra 0B3B 59 lsld 0B3C C30002 addd #_mutex 0B3F B7C6 xgdy 0B41 ED40 ldy 0,y 0B43 C6FF ldab #-1 0B45 6B48 stab 8,y 0B47 ; mutex[id]->queue[0] = -1; 0B47 E61F ldab -1,x 0B49 87 clra 0B4A 59 lsld 0B4B C30002 addd #_mutex 0B4E B7C6 xgdy 0B50 ED40 ldy 0,y 0B52 C6FF ldab #-1 0B54 6B49 stab 9,y 0B56 ; mutex[id]->queue[1] = -1; 0B56 E61F ldab -1,x 0B58 87 clra 0B59 59 lsld 0B5A C30002 addd #_mutex 0B5D B7C6 xgdy 0B5F ED40 ldy 0,y 0B61 C6FF ldab #-1 0B63 6B4A stab 10,y 0B65 ; mutex[id]->queue[2] = -1; 0B65 E61F ldab -1,x 0B67 87 clra 0B68 59 lsld 0B69 C30002 addd #_mutex 0B6C B7C6 xgdy 0B6E ED40 ldy 0,y 0B70 C6FF ldab #-1 0B72 6B4B stab 11,y 0B74 ; mutex[id]->queue_ptr = 0; 0B74 E61F ldab -1,x 0B76 87 clra 0B77 59 lsld 0B78 C30002 addd #_mutex 0B7B B7C6 xgdy 0B7D ED40 ldy 0,y 0B7F 694C clr 12,y 0B81 ; } 0B81 ; 0B81 ; 0B81 ; INTR_ON(); 0B81 10EF cli 0B83 0B83 ; 0B83 ; return id; 0B83 E61F ldab -1,x 0B85 87 clra 0B86 L157: 0B86 B757 tfr x,s 0B88 30 pulx 0B89 1B82 leas 2,sp 0B8B .dbline 0 ; func end 0B8B 3D rts 0B8C ; ?temp -> -8,x 0B8C ; ?temp -> -6,x 0B8C ; ?temp -> -4,x 0B8C ; id -> -2,x 0B8C ; type -> 3,x 0B8C _get_mutex:: 0B8C 3B pshd 0B8D 34 pshx 0B8E B775 tfr s,x 0B90 1B96 leas -10,sp 0B92 ; 0B92 ; } 0B92 ; 0B92 ; 0B92 ; 0B92 ; 0B92 ; int get_mutex(unsigned char type) { 0B92 ; 0B92 ; /* Gives a mutex to a requesting task. 0B92 ; returns the mutex id number (0,1,2,...) if free. 0B92 ; otherwise returns -1. 0B92 ; 0B92 ; At this point, mutexs are a procedural control 0B92 ; that the tasks have to follow to avoid resource contention. 0B92 ; There is no kernel control over resources yet. */ 0B92 ; 0B92 ; 0B92 ; // LOCAL VARIABLES 0B92 ; int id; 0B92 ; 0B92 ; 0B92 ; 0B92 ; // critical section 0B92 ; INTR_OFF(); 0B92 1410 sei 0B94 0B94 CC0000 ldd #0 0B97 6C1E std -2,x 0B99 L175: 0B99 ; 0B99 ; 0B99 ; // find id for mutex type 0B99 ; for (id=0; idtype == type) 0BA7 EC1E ldd -2,x 0BA9 59 lsld 0BAA C30002 addd #_mutex 0BAD B7C6 xgdy 0BAF ED40 ldy 0,y 0BB1 E641 ldab 1,y 0BB3 E103 cmpb 3,x 0BB5 2602 bne L181 0BB7 ; break; 0BB7 200E bra L177 0BB9 L181: 0BB9 L176: 0BB9 EC1E ldd -2,x 0BBB C30001 addd #1 0BBE 6C1E std -2,x 0BC0 EC1E ldd -2,x 0BC2 8C0004 cpd #4 0BC5 2DD2 blt L175 0BC7 L177: 0BC7 ; } 0BC7 ; 0BC7 ; 0BC7 ; // GET mutex 0BC7 ; 0BC7 ; // if mutex isn't taken, give it to the requesting task 0BC7 ; if (mutex[id]->state == NOTBUSY) { 0BC7 EC1E ldd -2,x 0BC9 59 lsld 0BCA C30002 addd #_mutex 0BCD B7C6 xgdy 0BCF ED40 ldy 0,y 0BD1 E747 tst 7,y 0BD3 2625 bne L183 0BD5 ; mutex[id]->state = BUSY; 0BD5 EC1E ldd -2,x 0BD7 59 lsld 0BD8 C30002 addd #_mutex 0BDB B7C6 xgdy 0BDD ED40 ldy 0,y 0BDF C601 ldab #1 0BE1 6B47 stab 7,y 0BE3 ; mutex[id]->owner = current; 0BE3 EC1E ldd -2,x 0BE5 59 lsld 0BE6 C30002 addd #_mutex 0BE9 B7C6 xgdy 0BEB ED40 ldy 0,y 0BED F60025 ldab _current+1 0BF0 6B48 stab 8,y 0BF2 ; 0BF2 ; INTR_ON(); 0BF2 10EF cli 0BF4 0BF4 ; return id; 0BF4 EC1E ldd -2,x 0BF6 18200088 lbra L174 0BFA L183: 0BFA ; } 0BFA ; 0BFA ; // mutex is taken/busy so make task wait 0BFA ; else { 0BFA ; // put waiting task into the mutexs queue if there's space 0BFA ; if (mutex[id]->queue_ptr < 3) { 0BFA EC1E ldd -2,x 0BFC 59 lsld 0BFD C30002 addd #_mutex 0C00 B7C6 xgdy 0C02 ED40 ldy 0,y 0C04 E64C ldab 12,y 0C06 C103 cmpb #3 0C08 18240071 lbhs L185 0C0C ; task[current]->message |= STATE_FLAG; 0C0C FC0024 ldd _current 0C0F 59 lsld 0C10 C3000A addd #_task 0C13 B7C6 xgdy 0C15 EC40 ldd 0,y 0C17 C30014 addd #20 0C1A 6C1C std -4,x 0C1C B746 tfr d,y 0C1E 35 pshy ; spill 0C1F ED1C ldy -4,x 0C21 31 puly ; reload 0C22 0C4001 bset 0,y,#1 0C25 ; task[current]->message_data[STATE_BOX] = WAITING; 0C25 FC0024 ldd _current 0C28 59 lsld 0C29 C3000A addd #_task 0C2C B7C6 xgdy 0C2E ED40 ldy 0,y 0C30 C603 ldab #3 0C32 6BE815 stab 21,y 0C35 ; mutex[id]->queue[mutex[id]->queue_ptr] = current; 0C35 EC1E ldd -2,x 0C37 59 lsld 0C38 C30002 addd #_mutex 0C3B B7C6 xgdy 0C3D ED40 ldy 0,y 0C3F 6D1A sty -6,x 0C41 ED1A ldy -6,x 0C43 E64C ldab 12,y 0C45 87 clra 0C46 3B pshd ; spill 0C47 EC1A ldd -6,x 0C49 C30009 addd #9 0C4C 6C16 std -10,x 0C4E 3A puld ; reload 0C4F E316 addd -10,x 0C51 B7C6 xgdy 0C53 F60025 ldab _current+1 0C56 6B40 stab 0,y 0C58 ; mutex[id]->queue_ptr++; 0C58 EC1E ldd -2,x 0C5A 59 lsld 0C5B C30002 addd #_mutex 0C5E B7C6 xgdy 0C60 EC40 ldd 0,y 0C62 C3000C addd #12 0C65 6C18 std -8,x 0C67 B746 tfr d,y 0C69 E640 ldab 0,y 0C6B 87 clra 0C6C C30001 addd #1 0C6F ED18 ldy -8,x 0C71 6B40 stab 0,y 0C73 ; INTR_ON(); 0C73 10EF cli 0C75 0C75 ; asm("JMP $116A"); 0C75 06116A JMP $116A 0C78 0C78 ; return 0; 0C78 CC0000 ldd #0 0C7B 2005 bra L174 0C7D L185: 0C7D ; } 0C7D ; else { // can't give mutex 0C7D ; INTR_ON(); 0C7D 10EF cli 0C7F 0C7F ; return -1; 0C7F CCFFFF ldd #-1 0C82 L174: 0C82 B757 tfr x,s 0C84 30 pulx 0C85 1B82 leas 2,sp 0C87 .dbline 0 ; func end 0C87 3D rts 0C88 ; ?temp -> -10,x 0C88 ; ?temp -> -8,x 0C88 ; ?temp -> -6,x 0C88 ; ?temp -> -4,x 0C88 ; ?temp -> -2,x 0C88 ; id -> 3,x 0C88 _give_mutex:: 0C88 3B pshd 0C89 34 pshx 0C8A B775 tfr s,x 0C8C 1B96 leas -10,sp 0C8E ; } 0C8E ; } 0C8E ; 0C8E ; } 0C8E ; 0C8E ; 0C8E ; 0C8E ; 0C8E ; int give_mutex(char id) { 0C8E ; 0C8E ; /* Takes a mutex back from a task. 0C8E ; will (eventually) pass a message to a waiting task. 0C8E ; 0C8E ; At this point, mutexs are a procedural control 0C8E ; that the tasks have to follow to avoid resource contention. 0C8E ; There is no kernel control over resources yet. */ 0C8E ; 0C8E ; 0C8E ; // critical section 0C8E ; INTR_OFF(); 0C8E 1410 sei 0C90 0C90 ; 0C90 ; 0C90 ; // if any tasks are waiting on the mutex, give it to them 0C90 ; if (mutex[id]->queue_ptr > 0) { 0C90 E603 ldab 3,x 0C92 87 clra 0C93 59 lsld 0C94 C30002 addd #_mutex 0C97 B7C6 xgdy 0C99 ED40 ldy 0,y 0C9B E74C tst 12,y 0C9D 1823008B lbls L188 0CA1 ; //mutex[id]->state = BUSY; 0CA1 ; mutex[id]->owner = mutex[id]->queue[0]; 0CA1 E603 ldab 3,x 0CA3 87 clra 0CA4 59 lsld 0CA5 C30002 addd #_mutex 0CA8 B7C6 xgdy 0CAA ED40 ldy 0,y 0CAC 6D1E sty -2,x 0CAE ED1E ldy -2,x 0CB0 E649 ldab 9,y 0CB2 ED1E ldy -2,x 0CB4 6B48 stab 8,y 0CB6 ; 0CB6 ; // take the receiving task out of the waiting state 0CB6 ; task[current]->message |= STATE_FLAG; 0CB6 FC0024 ldd _current 0CB9 59 lsld 0CBA C3000A addd #_task 0CBD B7C6 xgdy 0CBF EC40 ldd 0,y 0CC1 C30014 addd #20 0CC4 6C1C std -4,x 0CC6 B746 tfr d,y 0CC8 35 pshy ; spill 0CC9 ED1C ldy -4,x 0CCB 31 puly ; reload 0CCC 0C4001 bset 0,y,#1 0CCF ; task[current]->message_data[STATE_BOX] = RUNNING; 0CCF FC0024 ldd _current 0CD2 59 lsld 0CD3 C3000A addd #_task 0CD6 B7C6 xgdy 0CD8 ED40 ldy 0,y 0CDA C602 ldab #2 0CDC 6BE815 stab 21,y 0CDF ; 0CDF ; // shift the queue 0CDF ; mutex[id]->queue[0] = mutex[id]->queue[1]; 0CDF E603 ldab 3,x 0CE1 87 clra 0CE2 59 lsld 0CE3 C30002 addd #_mutex 0CE6 B7C6 xgdy 0CE8 ED40 ldy 0,y 0CEA 6D1A sty -6,x 0CEC ED1A ldy -6,x 0CEE E64A ldab 10,y 0CF0 ED1A ldy -6,x 0CF2 6B49 stab 9,y 0CF4 ; mutex[id]->queue[1] = mutex[id]->queue[2]; 0CF4 E603 ldab 3,x 0CF6 87 clra 0CF7 59 lsld 0CF8 C30002 addd #_mutex 0CFB B7C6 xgdy 0CFD ED40 ldy 0,y 0CFF 6D18 sty -8,x 0D01 ED18 ldy -8,x 0D03 E64B ldab 11,y 0D05 ED18 ldy -8,x 0D07 6B4A stab 10,y 0D09 ; mutex[id]->queue_ptr--; 0D09 E603 ldab 3,x 0D0B 87 clra 0D0C 59 lsld 0D0D C30002 addd #_mutex 0D10 B7C6 xgdy 0D12 EC40 ldd 0,y 0D14 C3000C addd #12 0D17 6C16 std -10,x 0D19 B746 tfr d,y 0D1B E640 ldab 0,y 0D1D 87 clra 0D1E 830001 subd #1 0D21 ED16 ldy -10,x 0D23 6B40 stab 0,y 0D25 ; 0D25 ; INTR_ON(); 0D25 10EF cli 0D27 0D27 ; return 0; 0D27 CC0000 ldd #0 0D2A 2021 bra L187 0D2C L188: 0D2C ; } 0D2C ; else { 0D2C ; // return the mutex 0D2C ; mutex[id]->state = NOTBUSY; 0D2C E603 ldab 3,x 0D2E 87 clra 0D2F 59 lsld 0D30 C30002 addd #_mutex 0D33 B7C6 xgdy 0D35 ED40 ldy 0,y 0D37 6947 clr 7,y 0D39 ; mutex[id]->owner = -1; 0D39 E603 ldab 3,x 0D3B 87 clra 0D3C 59 lsld 0D3D C30002 addd #_mutex 0D40 B7C6 xgdy 0D42 ED40 ldy 0,y 0D44 C6FF ldab #-1 0D46 6B48 stab 8,y 0D48 ; INTR_ON(); 0D48 10EF cli 0D4A 0D4A ; return 0; 0D4A CC0000 ldd #0 0D4D L187: 0D4D B757 tfr x,s 0D4F 30 pulx 0D50 1B82 leas 2,sp 0D52 .dbline 0 ; func end 0D52 3D rts 0D53 ; lreg1 -> -4,x 0D53 ; lreg2 -> -8,x 0D53 ; slop -> -12,x 0D53 _get_sysTime:: 0D53 34 pshx 0D54 B775 tfr s,x 0D56 1B94 leas -12,sp 0D58 ; } 0D58 ; 0D58 ; } 0D58 ; 0D58 ; 0D58 ; 0D58 ; unsigned long int get_sysTime(void) { 0D58 ; 0D58 ; // LOCAL VARIABLES 0D58 ; unsigned long int slop; 0D58 ; 0D58 ; 0D58 ; // returns the number of milliseconds since midnight (time_tick=0); 0D58 ; slop = time_tick / 40; 0D58 CD001A ldy #_time_tick 0D5B 1802401C movw 0,y,-4,x 0D5F 1802421E movw 2,y,-2,x 0D63 CD0E6F ldy #L191 0D66 18024018 movw 0,y,-8,x 0D6A 1802421A movw 2,y,-6,x 0D6E 160000 jsr __ludiv 0D71 1914 leay -12,x 0D73 18021C40 movw -4,x,0,y 0D77 18021E42 movw -2,x,2,y 0D7B ; return (time_tick * ms_PER_TIME_TICK + slop); 0D7B CD0E6B ldy #L192 0D7E 1802401C movw 0,y,-4,x 0D82 1802421E movw 2,y,-2,x 0D86 CD001A ldy #_time_tick 0D89 18024018 movw 0,y,-8,x 0D8D 1802421A movw 2,y,-6,x 0D91 160000 jsr __lmul 0D94 1914 leay -12,x 0D96 18024018 movw 0,y,-8,x 0D9A 1802421A movw 2,y,-6,x 0D9E 160000 jsr __ladd 0DA1 160000 jsr __lret 0DA4 L190: 0DA4 B757 tfr x,s 0DA6 30 pulx 0DA7 .dbline 0 ; func end 0DA7 3D rts 0DA8 ; lreg1 -> -4,x 0DA8 ; lreg2 -> -8,x 0DA8 ; slop -> -12,x 0DA8 ; seconds -> 8,x 0DA8 ; minutes -> 6,x 0DA8 ; hours -> 2,x 0DA8 _set_sysTime:: 0DA8 3B pshd 0DA9 34 pshx 0DAA B775 tfr s,x 0DAC 1B92 leas -14,sp 0DAE ; 0DAE ; } 0DAE ; 0DAE ; 0DAE ; 0DAE ; void set_sysTime(unsigned int hours, unsigned int minutes, unsigned int seconds) { 0DAE ; 0DAE ; // LOCAL VARIABLES 0DAE ; extern unsigned long int time_tick; 0DAE ; unsigned long int slop; 0DAE ; 0DAE ; 0DAE ; time_tick = ((hours*3600)+(minutes*60)+(seconds)) * TIME_TICKS_PER_SECOND; 0DAE CC003C ldd #60 0DB1 ED06 ldy 6,x 0DB3 13 emul 0DB4 6C12 std -14,x 0DB6 CC0E10 ldd #3600 0DB9 ED02 ldy 2,x 0DBB 13 emul 0DBC E312 addd -14,x 0DBE E308 addd 8,x 0DC0 6C1A std -6,x 0DC2 1800180000 movw #0,-8,x 0DC7 CD0E67 ldy #L194 0DCA 1802401C movw 0,y,-4,x 0DCE 1802421E movw 2,y,-2,x 0DD2 160000 jsr __lmul 0DD5 CD001A ldy #_time_tick 0DD8 18021C40 movw -4,x,0,y 0DDC 18021E42 movw -2,x,2,y 0DE0 ; slop = time_tick / 40; 0DE0 CD001A ldy #_time_tick 0DE3 1802401C movw 0,y,-4,x 0DE7 1802421E movw 2,y,-2,x 0DEB CD0E6F ldy #L191 0DEE 18024018 movw 0,y,-8,x 0DF2 1802421A movw 2,y,-6,x 0DF6 160000 jsr __ludiv 0DF9 1914 leay -12,x 0DFB 18021C40 movw -4,x,0,y 0DFF 18021E42 movw -2,x,2,y 0E03 ; time_tick += slop; 0E03 1914 leay -12,x 0E05 18024018 movw 0,y,-8,x 0E09 1802421A movw 2,y,-6,x 0E0D CD001A ldy #_time_tick 0E10 1802401C movw 0,y,-4,x 0E14 1802421E movw 2,y,-2,x 0E18 160000 jsr __ladd 0E1B CD001A ldy #_time_tick 0E1E 18021C40 movw -4,x,0,y 0E22 18021E42 movw -2,x,2,y 0E26 ; 0E26 ; } 0E26 L193: 0E26 B757 tfr x,s 0E28 30 pulx 0E29 1B82 leas 2,sp 0E2B .dbline 0 ; func end 0E2B 3D rts 0E2C ; last -> -6,x 0E2C ; memory -> -4,x 0E2C ; i -> -2,x 0E2C _get_free_memory:: 0E2C 34 pshx 0E2D B775 tfr s,x 0E2F 1B98 leas -8,sp 0E31 ; 0E31 ; 0E31 ; 0E31 ; 0E31 ; int get_free_memory(void) { 0E31 ; 0E31 ; // LOCAL VARIABLES 0E31 ; char *memory, *last; 0E31 ; int i; 0E31 ; 0E31 ; 0E31 ; INTR_OFF(); 0E31 1410 sei 0E33 0E33 CC0000 ldd #0 0E36 6C1E std -2,x 0E38 L196: 0E38 ; // check for largest free memory block 0E38 ; for (i=0; i