.module rlpos.c .area data 0200 _task_ptr:: 0200 .blkw 1 .area idata --- 0000 0000 .word _shell .area data --- 0002 .blkw 1 .area idata --- 0002 0000 .word _task1 .area data --- 0004 .blkw 1 .area idata --- 0004 0000 .word _task2 .area data 0206 _main_frame_ptr:: 0206 .blkb 2 .area idata --- 0006 0000 .word 0 .area data 0208 _main_frame_x_ptr:: 0208 .blkb 2 .area idata --- 0008 0000 .word 0 .area data 020A _temp_task_frame_ptr:: 020A .blkb 2 .area idata --- 000A 0000 .word 0 .area data .area text ; lreg1 -> -4,x ; lreg2 -> -8,x ; ?temp -> -26,x ; ?temp -> -26,x ; ?temp -> -26,x ; result -> -24,x ; temp_heap_ptr -> -22,x ; last_task -> -20,x ; temp -> -18,x ; temp_heap_size -> -17,x ; priority_check -> -15,x ; deadline -> -14,x ; i -> -10,x 102A _main:: 102A 34 pshx 102B B775 tfr s,x 102D 1BF1E0 leas -32,sp 1030 ; /* RLPOS: RLPotter Operating System 1030 ; 1030 ; Version 0.5 for the 68HC12D60A microcontroller 1030 ; by Ryan Potter 1030 ; ryan@rlpotter.com 1030 ; 1030 ; 1030 ; 1030 ; v0.5 April 16, 2003: 8759 bytes 1030 ; - added priority preemption 1030 ; - finished kernel task state switcher 1030 ; - it is now officially a legitimate 1030 ; rate monotonic 1030 ; priority preemptive 1030 ; multitasking 1030 ; Real Time Operating System :) 1030 ; - made kernel.c and semlib.c consistent with the 1030 ; rest of the kernel 1030 ; - included the early framework for a task message system 1030 ; 1030 ; v0.4 April 13, 2003: 8096 bytes 1030 ; - gerneralized the shell command-line input parser: 1030 ; cmd (up to 32 chars) 1030 ; - added kernel and shell functions 1030 ; 1030 ; v0.3 April 12, 2003: 6155 bytes 1030 ; - added a beginning shell user interface. 1030 ; - added a resource control block and basic semaphore functions. 1030 ; - added basic kernel functions 1030 ; 1030 ; v0.2 April 9, 2003: 1030 ; - able to round-robin with RTI interrupt. 1030 ; - bonified/certified multitasking with 3 tasks. :) 1030 ; 1030 ; v0.1 April 3, 2003: 1030 ; - able to round-robin without interrupts. 1030 ; - not multitasking, really. 1030 ; 1030 ; v0.0 started April 1, 2003; 0 bytes 1030 ; - no idea where to start. 1030 ; - don't want to look at anyone else's work. ;0) 1030 ; 1030 ; 1030 ; 1030 ; 1030 ; Architecture/C assumptions: 1030 ; 1) 'D' register is the accumulator 1030 ; 2) 'X' register points to the top of the current stack 1030 ; 3) 'Y' register is for general use in indexed operations 1030 ; 4) the heap grows upward and mem segments allocated by malloc, 1030 ; realloc, and calloc are linear and contiguous. 1030 ; 5) the stack grows downwards, and there is no boundary checking. 1030 ; 1030 ; Potential problem areas: 1030 ; 1) 'running' section of the kernel get's compiled using extra 1030 ; push and pop instructions 1030 ; 2) run out of ram (global + stack + heap) 1030 ; 1030 ; */ 1030 ; 1030 ; 1030 ; 1030 ; #include <912d60.h> 1030 ; #include 1030 ; #include 1030 ; #include "kernel.h" 1030 ; 1030 ; 1030 ; 1030 ; 1030 ; // FUNCTION PROTOTYPES 1030 ; void RTI_handler(void); 1030 ; void shell(void); 1030 ; void task1(void); 1030 ; void task2(void); 1030 ; void (*task_ptr[])(void) = {&shell, &task1, &task2}; 1030 ; 1030 ; 1030 ; 1030 ; 1030 ; // GLOBAL VARIABLES 1030 ; unsigned char *main_frame_ptr = NULL; // bottom of main() frame 1030 ; unsigned char *main_frame_x_ptr = NULL; // top of main() frame (x-reg ptr) 1030 ; unsigned char *temp_task_frame_ptr = NULL; // temp CCR pointer for RTI 1030 ; 1030 ; 1030 ; extern unsigned int current; // current task id number 1030 ; extern unsigned long int system_tick; 1030 ; 1030 ; 1030 ; // task control block 1030 ; extern struct task_block { 1030 ; unsigned char id; // ID of task 1030 ; enum task_state state; // State 1030 ; unsigned char priority; // Priority 1030 ; unsigned long int period_tick; // for determining if deadline is up 1030 ; unsigned int interrupt_msg_box; // flags for pending interrupts 1030 ; enum message_box message; // misc flags 1030 ; unsigned char message_data[8]; // data for misc_msg_box flags 1030 ; unsigned char *heap_ptr; // heap addr while not current task 1030 ; unsigned int heap_size; // heap size 1030 ; unsigned char *frame_ptr; // CCR pointer 1030 ; }; 1030 ; 1030 ; 1030 ; // resource control block 1030 ; extern struct resource_block { 1030 ; unsigned char id; // ID of resource 1030 ; enum resource_state state; // State (busy, free...) 1030 ; unsigned char user; // Current resource user/owner 1030 ; signed char queue[3]; // Tasks waiting on resource 1030 ; unsigned char queue_pos; // Next free spot in queue 1030 ; }; 1030 ; 1030 ; 1030 ; extern struct task_block task[numtasks]; 1030 ; extern struct resource_block resource[numresources]; 1030 ; 1030 ; 1030 ; 1030 ; 1030 ; 1030 ; 1030 ; main() { 1030 ; 1030 ; // LOCAL VARIABLES 1030 ; int result; 1030 ; unsigned int i, temp_heap_size; 1030 ; unsigned int last_task = 0; 1030 CC0000 ldd #0 1033 6CE1EC std -20,x 1036 ; unsigned char *temp_heap_ptr, temp, priority_check; 1036 ; unsigned long int deadline; 1036 ; 1036 ; extern int _bss_end, _textmode; 1036 ; extern unsigned int current; 1036 ; extern unsigned long int system_tick; 1036 ; 1036 ; _textmode = 1; // maps '\n' to "CR/LF" for Windows terminals 1036 CC0001 ldd #1 1039 7C0346 std __textmode 103C ; current = 0; // start the shell first 103C CC0000 ldd #0 103F 7C0344 std _current 1042 CC0000 ldd #0 1045 6C16 std -10,x 1047 18200082 lbra L7 104B L4: 104B CC0018 ldd #24 104E ED16 ldy -10,x 1050 13 emul 1051 C302F8 addd #_task 1054 B7C6 xgdy 1056 EC16 ldd -10,x 1058 6B40 stab 0,y 105A CC0018 ldd #24 105D ED16 ldy -10,x 105F 13 emul 1060 C302F9 addd #_task+1 1063 B7C6 xgdy 1065 6940 clr 0,y 1067 CC0018 ldd #24 106A ED16 ldy -10,x 106C 13 emul 106D C302FA addd #_task+2 1070 B7C6 xgdy 1072 C6FE ldab #254 1074 6B40 stab 0,y 1076 CC0018 ldd #24 1079 ED16 ldy -10,x 107B 13 emul 107C C302FB addd #_task+3 107F B7C6 xgdy 1081 35 pshy ; spill 1082 CD14BC ldy #L11 1085 1802401C movw 0,y,-4,x 1089 1802421E movw 2,y,-2,x 108D 31 puly ; reload 108E 18021C40 movw -4,x,0,y 1092 18021E42 movw -2,x,2,y 1096 CC0018 ldd #24 1099 ED16 ldy -10,x 109B 13 emul 109C C3030A addd #_task+18 109F B7C6 xgdy 10A1 CC0000 ldd #0 10A4 6C40 std 0,y 10A6 CC0018 ldd #24 10A9 ED16 ldy -10,x 10AB 13 emul 10AC C3030C addd #_task+20 10AF B7C6 xgdy 10B1 CC0000 ldd #0 10B4 6C40 std 0,y 10B6 CC0018 ldd #24 10B9 ED16 ldy -10,x 10BB 13 emul 10BC C3030E addd #_task+22 10BF B7C6 xgdy 10C1 CC0000 ldd #0 10C4 6C40 std 0,y 10C6 L5: 10C6 EC16 ldd -10,x 10C8 C30001 addd #1 10CB 6C16 std -10,x 10CD L7: 10CD ; 10CD ; 10CD ; 10CD ; // initialize the task structures 10CD ; for (i=0; i= numtasks) 11AE ; next_task = 0; 11AE ; current = next_task;*/ 11AE ; 11AE ; 11AE ; 11AE ; 11AE ; // RT PRIORITY BLOCK: 11AE ; // set the current task id based on priority and deadline 11AE ; 11AE ; // determine if the deadline is up for idle tasks 11AE ; /* deadline, is equal to period plus an initial time (t0) reference 11AE ; (t0 = system_tick). Period = priority + 1. 11AE ; Changing the state from idle to pending occurs here. */ 11AE ; for (i=0; i= deadline) { 11F1 1912 leay -14,x 11F3 18024018 movw 0,y,-8,x 11F7 1802421A movw 2,y,-6,x 11FB CD0340 ldy #_system_tick 11FE 1802401C movw 0,y,-4,x 1202 1802421E movw 2,y,-2,x 1206 162B5F jsr __lcmp 1209 250F blo L46 120B ; task[i].state = pending; // change state at deadline 120B CC0018 ldd #24 120E ED16 ldy -10,x 1210 13 emul 1211 C302F9 addd #_task+1 1214 B7C6 xgdy 1216 C601 ldab #1 1218 6B40 stab 0,y 121A ; //puts("promote"); 121A ; } 121A L46: 121A ; } 121A L41: 121A L38: 121A EC16 ldd -10,x 121C C30001 addd #1 121F 6C16 std -10,x 1221 L40: 1221 EC16 ldd -10,x 1223 8C0003 cpd #3 1226 1825FF84 lblo L37 122A ; // if (task[i].message) {} 122A ; } 122A ; 122A ; 122A ; // set current = highest priority pending/running task. 122A ; priority_check = 255; // lowest possible 122A C6FF ldab #255 122C 6B11 stab -15,x 122E CC0000 ldd #0 1231 6C16 std -10,x 1233 204E bra L52 1235 L49: 1235 ; for (i=0; i -4,x 13A1 ; lreg2 -> -8,x 13A1 ; ?temp -> -16,x 13A1 ; local_thp -> -14,x 13A1 ; frame_size -> -12,x 13A1 ; i -> -10,x 13A1 _RTI_handler:: 13A1 34 pshx 13A2 B775 tfr s,x 13A4 1BF1EC leas -20,sp 13A7 ; 13A7 ; 13A7 ; 13A7 ; #pragma interrupt_handler RTI_handler() 13A7 ; 13A7 ; void RTI_handler(void) { 13A7 ; 13A7 ; size_t frame_size; 13A7 ; unsigned int i; 13A7 ; unsigned char *local_thp; 13A7 ; 13A7 ; 13A7 ; //ACKNOWLEDGE THE INTERRUPT 13A7 ; INTR_OFF(); // redundant. automatically done by the processor 13A7 1410 sei 13A9 13A9 ; RTIFLG = 0x0080; // acknowledge/clear the interrupt 13A9 C680 ldab #128 13AB 7B0015 stab 0x15 13AE ; 13AE ; 13AE ; //putchar('.'); 13AE ; 13AE ; 13AE ; // SET THE FRAME POINTER for the interupted task. 13AE ; // should point to the CCR entry on the stack. 13AE ; asm("TFR x,d"); // start of RTI stack 13AE B754 TFR x,d 13B0 13B0 ; asm("ADDD #2"); // adjust to CCR stack entry 13B0 C30002 ADDD #2 13B3 13B3 ; asm("STD _temp_task_frame_ptr"); // put into task_frame_ptr 13B3 7C020A STD _temp_task_frame_ptr 13B6 13B6 ; task[current].frame_ptr = temp_task_frame_ptr; 13B6 CC0018 ldd #24 13B9 FD0344 ldy _current 13BC 13 emul 13BD C3030E addd #_task+22 13C0 B7C6 xgdy 13C2 FC020A ldd _temp_task_frame_ptr 13C5 6C40 std 0,y 13C7 ; 13C7 ; 13C7 ; 13C7 ; //PLACE CURRENT TASK CONTEXT ONTO THE HEAP 13C7 ; // determine size of heap segment needed 13C7 ; frame_size = main_frame_ptr - temp_task_frame_ptr; // always positive 13C7 FC0206 ldd _main_frame_ptr 13CA B3020A subd _temp_task_frame_ptr 13CD 6C14 std -12,x 13CF ; task[current].heap_size = (int)frame_size; 13CF CC0018 ldd #24 13D2 FD0344 ldy _current 13D5 13 emul 13D6 C3030C addd #_task+20 13D9 B7C6 xgdy 13DB EC14 ldd -12,x 13DD 6C40 std 0,y 13DF ; 13DF ; // reallocate heap memory 13DF ; task[current].heap_ptr = realloc(task[current].heap_ptr, frame_size); 13DF 18021480 movw -12,x,0,sp 13E3 CC0018 ldd #24 13E6 FD0344 ldy _current 13E9 13 emul 13EA 6C10 std -16,x 13EC C3030A addd #_task+18 13EF B7C6 xgdy 13F1 EC40 ldd 0,y 13F3 162F29 jsr _realloc 13F6 6CE1EE std -18,x 13F9 EC10 ldd -16,x 13FB C3030A addd #_task+18 13FE B7C6 xgdy 1400 ECE1EE ldd -18,x 1403 6C40 std 0,y 1405 ; local_thp = task[current].heap_ptr; 1405 CC0018 ldd #24 1408 FD0344 ldy _current 140B 13 emul 140C C3030A addd #_task+18 140F B7C6 xgdy 1411 ED40 ldy 0,y 1413 6D12 sty -14,x 1415 ; 1415 ; if (local_thp == NULL) { 1415 EC12 ldd -14,x 1417 260C bne L88 1419 ; puts("out of heap space!"); 1419 CC1481 ldd #L90 141C 162BF8 jsr _puts 141F ; exit(0); 141F CC0000 ldd #0 1422 161028 jsr _exit 1425 ; } 1425 L88: 1425 CC0000 ldd #0 1428 6C16 std -10,x 142A 201A bra L94 142C L91: 142C EC16 ldd -10,x 142E F3020A addd _temp_task_frame_ptr 1431 B7C6 xgdy 1433 E640 ldab 0,y 1435 3B pshd ; spill 1436 EC16 ldd -10,x 1438 E312 addd -14,x 143A B7C6 xgdy 143C 3A puld ; reload 143D 6B40 stab 0,y 143F L92: 143F EC16 ldd -10,x 1441 C30001 addd #1 1444 6C16 std -10,x 1446 L94: 1446 ; 1446 ; // transfer task frame to the heap one byte at a time. 1446 ; // assumes the heap grows from low to high addr. 1446 ; for(i=0; i -49,x ; ?temp -> -47,x ; cmd_length -> -46,x ; cmd -> -44,x ; argc -> -43,x ; argv -> -41,x ; cursor1 -> -39,x ; j -> -37,x ; cursor2 -> -36,x ; command -> -34,x ; i -> -1,x 14C0 _shell:: 14C0 34 pshx 14C1 B775 tfr s,x 14C3 1BF1C4 leas -60,sp 14C6 ; // shell.c 14C6 ; 14C6 ; 14C6 ; #include <912d60.h> 14C6 ; #include 14C6 ; #include 14C6 ; #include 14C6 ; #include 14C6 ; #include "kernel.h" 14C6 ; #include "semlib.h" 14C6 ; 14C6 ; 14C6 ; 14C6 ; 14C6 ; // FUNCTION PROTOTYPES 14C6 ; void shellcmd_help(char *argv1); 14C6 ; void shellcmd_tcb(void); 14C6 ; void shellcmd_rcb(void); 14C6 ; void shellcmd_ticks(void); 14C6 ; void shellcmd_start_task(unsigned char id); 14C6 ; 14C6 ; /*void shellcmd_stop_task(unsigned char id); 14C6 ; void shellcmd_set_task_priority(unsigned char id, unsigned char priority); 14C6 ; void shellcmd_quit_shell(void);*/ 14C6 ; 14C6 ; 14C6 ; 14C6 ; 14C6 ; // GLOBAL VARIABLES 14C6 ; extern unsigned long int system_tick; 14C6 ; extern unsigned int current; // current task id number 14C6 ; 14C6 ; 14C6 ; // LOCAL GLOBAL VARIABLES (context is this file only) 14C6 ; extern char error_msg[6][25]; 14C6 ; 14C6 ; 14C6 ; void shell(void) { 14C6 ; 14C6 ; // LOCAL CONSTANTS 14C6 ; #define cmd_size (32+1) 14C6 ; 14C6 ; 14C6 ; 14C6 ; // LOCAL ENUMERATIONS 14C6 ; enum command_type { help = 1, 14C6 ; tcb, 14C6 ; rcb, 14C6 ; ticks, 14C6 ; start, 14C6 ; stop, 14C6 ; priority, 14C6 ; quit 14C6 ; }; 14C6 ; 14C6 ; 14C6 ; 14C6 ; // LOCAL VARIABLES 14C6 ; char command[cmd_size], i, j, **argv, *cursor1, *cursor2; 14C6 ; int cmd_length, argc; 14C6 ; enum command_type cmd; 14C6 ; 14C6 ; 14C6 ; 14C6 ; 14C6 ; // INITIALIZE SHELL 14C6 ; sem_get(COM1); // get comm port 1 semaphore 14C6 CC0000 ldd #0 14C9 161D03 jsr _sem_get 14CC ; INTR_ON(); // enable interrupts 14CC 10EF cli 14CE 14CE 18200445 lbra L5 14D2 L4: 14D2 ; 14D2 ; 14D2 ; 14D2 ; // SHELL COMMAND LINE INTERPRETER 14D2 ; while (1) { 14D2 ; 14D2 ; i = 0; 14D2 691F clr -1,x 14D4 ; cursor1 = command; 14D4 19E1DE leay -34,x 14D7 6DE1D9 sty -39,x 14DA ; cursor2 = command; 14DA 19E1DE leay -34,x 14DD 6DE1DC sty -36,x 14E0 ; 14E0 ; 14E0 ; // put a PROMPT 14E0 ; putchar('>'); putchar('>'); putchar(' '); 14E0 CC003E ldd #62 14E3 16266D jsr _putchar 14E6 CC003E ldd #62 14E9 16266D jsr _putchar 14EC CC0020 ldd #32 14EF 16266D jsr _putchar 14F2 2056 bra L8 14F4 L7: 14F4 ; 14F4 ; 14F4 ; // GET AND ECHO THE COMMAND on the console 14F4 ; while (((command[i]=getchar()) != 0xD) && (i -- required arguments"); 180F CC1C2C ldd #L71 1812 162BF8 jsr _puts 1815 ; puts("[] -- optional arguments\n"); 1815 CC1C12 ldd #L72 1818 162BF8 jsr _puts 181B ; puts("help [cmd] -- help on a specific command"); 181B CC1BE9 ldd #L73 181E 162BF8 jsr _puts 1821 ; puts("tcb [task_id] -- prints task control block"); 1821 CC1BBE ldd #L74 1824 162BF8 jsr _puts 1827 ; puts("rcb [task_id] -- prints resource control block"); 1827 CC1B8F ldd #L75 182A 162BF8 jsr _puts 182D ; puts("ticks -- shows system tick"); 182D CC1B74 ldd #L76 1830 162BF8 jsr _puts 1833 ; puts("start -- start a task"); 1833 CC1B54 ldd #L77 1836 162BF8 jsr _puts 1839 ; puts("stop -- stop a task"); 1839 CC1B35 ldd #L78 183C 162BF8 jsr _puts 183F ; puts("priority , -- change prio"); 183F CC1B01 ldd #L79 1842 162BF8 jsr _puts 1845 ; puts("quit -- quit the shell (carefull!)"); 1845 CC1ADE ldd #L80 1848 162BF8 jsr _puts 184B ; putchar('\n'); 184B CC000A ldd #10 184E 16266D jsr _putchar 1851 ; } 1851 18200094 lbra L65 1855 L68: 1855 ; else if (argc == 2) 1855 ECE1D5 ldd -43,x 1858 8C0002 cpd #2 185B 1826008A lbne L65 185F ; shellcmd_help(argv[1]); 185F EDE1D7 ldy -41,x 1862 EC42 ldd 2,y 1864 161927 jsr _shellcmd_help 1867 ; break; 1867 1820007E lbra L65 186B L83: 186B ; case tcb: 186B ; if (argc == 1) 186B ECE1D5 ldd -43,x 186E 8C0001 cpd #1 1871 2605 bne L84 1873 ; shellcmd_tcb(); 1873 16192E jsr _shellcmd_tcb 1876 2071 bra L65 1878 L84: 1878 ; else if (argc > 1) 1878 ECE1D5 ldd -43,x 187B 8C0001 cpd #1 187E 2F69 ble L65 1880 ; puts(error_msg[0]); 1880 CC020C ldd #_error_msg 1883 162BF8 jsr _puts 1886 ; break; 1886 2061 bra L65 1888 L88: 1888 ; case rcb: 1888 ; puts(error_msg[0]); 1888 CC020C ldd #_error_msg 188B 162BF8 jsr _puts 188E ; break; 188E 2059 bra L65 1890 L89: 1890 ; case ticks: 1890 ; if (argc > 1) 1890 ECE1D5 ldd -43,x 1893 8C0001 cpd #1 1896 2F08 ble L90 1898 ; puts(error_msg[1]); 1898 CC0225 ldd #_error_msg+25 189B 162BF8 jsr _puts 189E 2049 bra L65 18A0 L90: 18A0 ; else 18A0 ; shellcmd_ticks(); 18A0 16198C jsr _shellcmd_ticks 18A3 ; break; 18A3 2044 bra L65 18A5 L93: 18A5 ; case start: 18A5 ; if ((argc != 2) || 18A5 ECE1D5 ldd -43,x 18A8 8C0002 cpd #2 18AB 2610 bne L96 18AD EDE1D7 ldy -41,x 18B0 ED42 ldy 2,y 18B2 E640 ldab 0,y 18B4 87 clra 18B5 162E02 jsr _isdigit 18B8 8C0000 cpd #0 18BB 2608 bne L94 18BD L96: 18BD ; (!isdigit(*argv[1]))) 18BD ; puts(error_msg[1]); 18BD CC0225 ldd #_error_msg+25 18C0 162BF8 jsr _puts 18C3 2024 bra L65 18C5 L94: 18C5 ; else 18C5 ; shellcmd_start_task(atoi(argv[1])); 18C5 EDE1D7 ldy -41,x 18C8 EC42 ldd 2,y 18CA 16305D jsr _atoi 18CD 87 clra 18CE 1619B4 jsr _shellcmd_start_task 18D1 ; break; 18D1 2016 bra L65 18D3 L98: 18D3 ; case stop: 18D3 ; puts(error_msg[0]); 18D3 CC020C ldd #_error_msg 18D6 162BF8 jsr _puts 18D9 ; break; 18D9 200E bra L65 18DB L99: 18DB ; case priority: 18DB ; puts(error_msg[0]); 18DB CC020C ldd #_error_msg 18DE 162BF8 jsr _puts 18E1 ; break; 18E1 2006 bra L65 18E3 L100: 18E3 ; case quit: 18E3 ; puts(error_msg[0]); 18E3 CC020C ldd #_error_msg 18E6 162BF8 jsr _puts 18E9 ; break; 18E9 ; default: 18E9 ; break; 18E9 L65: 18E9 ; 18E9 ; }} // end switch/if 18E9 L62: 18E9 ; 18E9 ; 18E9 ; 18E9 ; // free the argc and argv array memory 18E9 ; for (i=0; i 2,x 1927 _shellcmd_help:: 1927 ; 1927 ; 1927 ; 1927 ; 1927 ; void shellcmd_help(char *argv1) { 1927 ; 1927 ; puts(error_msg[0]); 1927 CC020C ldd #_error_msg 192A 162BF8 jsr _puts 192D ; } 192D L105: 192D .dbline 0 ; func end 192D 3D rts 192E ; id -> -2,x 192E _shellcmd_tcb:: 192E 34 pshx 192F B775 tfr s,x 1931 1B92 leas -14,sp 1933 ; 1933 ; 1933 ; 1933 ; void shellcmd_tcb(void) { 1933 CC0000 ldd #0 1936 6C1E std -2,x 1938 L107: 1938 CC1AAD ldd #L111 193B 162BF8 jsr _puts 193E EC1E ldd -2,x 1940 87 clra 1941 161DE7 jsr _get_task_state 1944 6C1C std -4,x 1946 EC1E ldd -2,x 1948 87 clra 1949 161E4D jsr _get_task_priority 194C 6C1A std -6,x 194E EC1E ldd -2,x 1950 87 clra 1951 161E1A jsr _get_task_messages 1954 6C86 std 6,sp 1956 ED1A ldy -6,x 1958 6D84 sty 4,sp 195A ED1C ldy -4,x 195C 6D82 sty 2,sp 195E 18021E80 movw -2,x,0,sp 1962 CC1A78 ldd #L112 1965 162C30 jsr _printf 1968 L108: 1968 ; 1968 ; // LOCAL VARIABLES 1968 ; int id; 1968 ; 1968 ; 1968 ; /* ??this takes a while, so treat the printf() as a critical section 1968 ; in order to get reliable data */ 1968 ; 1968 ; 1968 ; for (id=0; id -4,x 198C ; lreg2 -> -8,x 198C _shellcmd_ticks:: 198C 34 pshx 198D B775 tfr s,x 198F 1B94 leas -12,sp 1991 ; 1991 ; 1991 ; 1991 ; 1991 ; void shellcmd_ticks(void) { 1991 ; 1991 ; INTR_OFF(); 1991 1410 sei 1993 1993 ; printf("Ticks: %ld\n", system_tick); 1993 CD0340 ldy #_system_tick 1996 1802401C movw 0,y,-4,x 199A 1802421E movw 2,y,-2,x 199E 1980 leay 0,sp 19A0 18021C40 movw -4,x,0,y 19A4 18021E42 movw -2,x,2,y 19A8 CC19EC ldd #L116 19AB 162C30 jsr _printf 19AE ; INTR_ON(); 19AE 10EF cli 19B0 19B0 ; } 19B0 L115: 19B0 B757 tfr x,s 19B2 30 pulx 19B3 .dbline 0 ; func end 19B3 3D rts 19B4 ; id -> 3,x 19B4 _shellcmd_start_task:: 19B4 3B pshd 19B5 34 pshx 19B6 B775 tfr s,x 19B8 1B9E leas -2,sp 19BA ; 19BA ; 19BA ; 19BA ; 19BA ; void shellcmd_start_task(unsigned char id) { 19BA ; 19BA ; if (set_task_state(id, pending) == 0) 19BA CC0001 ldd #1 19BD 6C80 std 0,sp 19BF E603 ldab 3,x 19C1 87 clra 19C2 161E86 jsr _set_task_state 19C5 8C0000 cpd #0 19C8 260B bne L118 19CA ; printf("task %d started\n", id); 19CA E603 ldab 3,x 19CC 87 clra 19CD 6C80 std 0,sp 19CF CC19DB ldd #L120 19D2 162C30 jsr _printf 19D5 L118: 19D5 ; } 19D5 L117: 19D5 B757 tfr x,s 19D7 30 pulx 19D8 1B82 leas 2,sp 19DA .dbline 0 ; func end 19DA 3D rts 19DB L120: 19DB 7461736B20256420737461727465640A .byte 't,'a,'s,'k,32,37,'d,32,'s,'t,'a,'r,'t,'e,'d,10 19EB 00 .byte 0 19EC L116: 19EC 5469636B733A20256C640A00 .byte 'T,'i,'c,'k,'s,58,32,37,'l,'d,10,0 19F8 L114: 19F8 4D6573736167653A205B206269743720 .byte 'M,'e,'s,'s,'a,'g,'e,58,32,91,32,'b,'i,'t,55,32 1A08 7C2062697436207C2062697435207C20 .byte 124,32,'b,'i,'t,54,32,124,32,'b,'i,'t,53,32,124,32 1A18 62697434207C2062697433207C206269 .byte 'b,'i,'t,52,32,124,32,'b,'i,'t,51,32,124,32,'b,'i 1A28 7432207C207072696F207C2073746174 .byte 't,50,32,124,32,'p,'r,'i,'o,32,124,32,'s,'t,'a,'t 1A38 65205D00 .byte 'e,32,93,0 1A3C L113: 1A3C 0A53746174653A20303D69646C652C20 .byte 10,'S,'t,'a,'t,'e,58,32,48,61,'i,'d,'l,'e,44,32 1A4C 313D70656E64696E672C20323D72756E .byte 49,61,'p,'e,'n,'d,'i,'n,'g,44,32,50,61,'r,'u,'n 1A5C 6E696E672C20333D77616974696E672C .byte 'n,'i,'n,'g,44,32,51,61,'w,'a,'i,'t,'i,'n,'g,44 1A6C 20343D66696E697368656400 .byte 32,52,61,'f,'i,'n,'i,'s,'h,'e,'d,0 1A78 L112: 1A78 5461736B49443A20253264207C205374 .byte 'T,'a,'s,'k,'I,'D,58,32,37,50,'d,32,124,32,'S,'t 1A88 6174653A202564207C205072696F3A20 .byte 'a,'t,'e,58,32,37,'d,32,124,32,'P,'r,'i,'o,58,32 1A98 253364207C204D7367733A2030783025 .byte 37,51,'d,32,124,32,'M,'s,'g,'s,58,32,48,'x,48,37 1AA8 78207C0A00 .byte 'x,32,124,10,0 1AAD L111: 1AAD 2D2D2D2D2D2D2D2D2D2D2D2B2D2D2D2D .byte 45,45,45,45,45,45,45,45,45,45,45,43,45,45,45,45 1ABD 2D2D2D2D2D2D2B2D2D2D2D2D2D2D2D2D .byte 45,45,45,45,45,45,43,45,45,45,45,45,45,45,45,45 1ACD 2D2D2B2D2D2D2D2D2D2D2D2D2D2D2D2B .byte 45,45,43,45,45,45,45,45,45,45,45,45,45,45,45,43 1ADD 00 .byte 0 1ADE L80: 1ADE 71756974202D2D207175697420746865 .byte 'q,'u,'i,'t,32,45,45,32,'q,'u,'i,'t,32,'t,'h,'e 1AEE 207368656C6C20286361726566756C6C .byte 32,'s,'h,'e,'l,'l,32,40,'c,'a,'r,'e,'f,'u,'l,'l 1AFE 212900 .byte 33,41,0 1B01 L79: 1B01 7072696F72697479203C7461736B5F69 .byte 'p,'r,'i,'o,'r,'i,'t,'y,32,60,'t,'a,'s,'k,95,'i 1B11 643E2C203C7461736B5F7072696F7269 .byte 'd,62,44,32,60,'t,'a,'s,'k,95,'p,'r,'i,'o,'r,'i 1B21 74793E20202D2D206368616E67652070 .byte 't,'y,62,32,32,45,45,32,'c,'h,'a,'n,'g,'e,32,'p 1B31 72696F00 .byte 'r,'i,'o,0 1B35 L78: 1B35 73746F70203C7461736B5F69643E2020 .byte 's,'t,'o,'p,32,60,'t,'a,'s,'k,95,'i,'d,62,32,32 1B45 2D2D2073746F702061207461736B00 .byte 45,45,32,'s,'t,'o,'p,32,'a,32,'t,'a,'s,'k,0 1B54 L77: 1B54 7374617274203C7461736B5F69643E20 .byte 's,'t,'a,'r,'t,32,60,'t,'a,'s,'k,95,'i,'d,62,32 1B64 2D2D2073746172742061207461736B00 .byte 45,45,32,'s,'t,'a,'r,'t,32,'a,32,'t,'a,'s,'k,0 1B74 L76: 1B74 7469636B73202D2D2073686F77732073 .byte 't,'i,'c,'k,'s,32,45,45,32,'s,'h,'o,'w,'s,32,'s 1B84 797374656D207469636B00 .byte 'y,'s,'t,'e,'m,32,'t,'i,'c,'k,0 1B8F L75: 1B8F 726362205B7461736B5F69645D202D2D .byte 'r,'c,'b,32,91,'t,'a,'s,'k,95,'i,'d,93,32,45,45 1B9F 207072696E7473207265736F75726365 .byte 32,'p,'r,'i,'n,'t,'s,32,'r,'e,'s,'o,'u,'r,'c,'e 1BAF 20636F6E74726F6C20626C6F636B00 .byte 32,'c,'o,'n,'t,'r,'o,'l,32,'b,'l,'o,'c,'k,0 1BBE L74: 1BBE 746362205B7461736B5F69645D202D2D .byte 't,'c,'b,32,91,'t,'a,'s,'k,95,'i,'d,93,32,45,45 1BCE 207072696E7473207461736B20636F6E .byte 32,'p,'r,'i,'n,'t,'s,32,'t,'a,'s,'k,32,'c,'o,'n 1BDE 74726F6C20626C6F636B00 .byte 't,'r,'o,'l,32,'b,'l,'o,'c,'k,0 1BE9 L73: 1BE9 68656C70205B636D645D202D2D206865 .byte 'h,'e,'l,'p,32,91,'c,'m,'d,93,32,45,45,32,'h,'e 1BF9 6C70206F6E2061207370656369666963 .byte 'l,'p,32,'o,'n,32,'a,32,'s,'p,'e,'c,'i,'f,'i,'c 1C09 20636F6D6D616E6400 .byte 32,'c,'o,'m,'m,'a,'n,'d,0 1C12 L72: 1C12 5B5D202D2D206F7074696F6E616C2061 .byte 91,93,32,45,45,32,'o,'p,'t,'i,'o,'n,'a,'l,32,'a 1C22 7267756D656E74730A00 .byte 'r,'g,'u,'m,'e,'n,'t,'s,10,0 1C2C L71: 1C2C 3C3E202D2D2072657175697265642061 .byte 60,62,32,45,45,32,'r,'e,'q,'u,'i,'r,'e,'d,32,'a 1C3C 7267756D656E747300 .byte 'r,'g,'u,'m,'e,'n,'t,'s,0 1C45 L70: 1C45 2D2D2D48454C502D2D2D0A00 .byte 45,45,45,'H,'E,'L,'P,45,45,45,10,0 1C51 L60: 1C51 00 .byte 0 1C52 L57: 1C52 7175697400 .byte 'q,'u,'i,'t,0 1C57 L54: 1C57 7072696F7269747900 .byte 'p,'r,'i,'o,'r,'i,'t,'y,0 1C60 L51: 1C60 73746F7000 .byte 's,'t,'o,'p,0 1C65 L48: 1C65 737461727400 .byte 's,'t,'a,'r,'t,0 1C6B L45: 1C6B 7469636B7300 .byte 't,'i,'c,'k,'s,0 1C71 L42: 1C71 72636200 .byte 'r,'c,'b,0 1C75 L39: 1C75 74636200 .byte 't,'c,'b,0 1C79 L36: 1C79 68656C7000 .byte 'h,'e,'l,'p,0 .module task1.c .area text ; i -> -2,x 1C7E _task1:: 1C7E 34 pshx 1C7F B775 tfr s,x 1C81 1B9E leas -2,sp 1C83 ; #include 1C83 ; #include <912d60.h> 1C83 ; #include "semlib.h" 1C83 ; 1C83 ; 1C83 ; 1C83 ; /* dummy task to eat up time, and to give the kernel 1C83 ; something to multitask with */ 1C83 ; void task1 (void) { 1C83 ; 1C83 ; int i; 1C83 ; 1C83 ; sem_get(COM1); 1C83 CC0000 ldd #0 1C86 161D03 jsr _sem_get 1C89 ; INTR_ON(); 1C89 10EF cli 1C8B 1C8B CC0000 ldd #0 1C8E 6C1E std -2,x 1C90 L4: 1C90 L5: 1C90 ; 1C90 ; 1C90 ; //puts("T1 Starting"); 1C90 ; for (i=0; i<0x1000; i++); 1C90 EC1E ldd -2,x 1C92 C30001 addd #1 1C95 6C1E std -2,x 1C97 EC1E ldd -2,x 1C99 8C1000 cpd #4096 1C9C 2DF2 blt L4 1C9E CC0000 ldd #0 1CA1 6C1E std -2,x 1CA3 L8: 1CA3 L9: 1CA3 ; //puts("T1.1"); 1CA3 ; 1CA3 ; for (i=0; i<0x1800; i++); 1CA3 EC1E ldd -2,x 1CA5 C30001 addd #1 1CA8 6C1E std -2,x 1CAA EC1E ldd -2,x 1CAC 8C1800 cpd #6144 1CAF 2DF2 blt L8 1CB1 CC0000 ldd #0 1CB4 6C1E std -2,x 1CB6 L12: 1CB6 L13: 1CB6 ; //puts("T1.2"); 1CB6 ; 1CB6 ; for (i=0; i<0x2000; i++); 1CB6 EC1E ldd -2,x 1CB8 C30001 addd #1 1CBB 6C1E std -2,x 1CBD EC1E ldd -2,x 1CBF 8C2000 cpd #8192 1CC2 2DF2 blt L12 1CC4 CC0000 ldd #0 1CC7 6C1E std -2,x 1CC9 L16: 1CC9 L17: 1CC9 ; //puts("T1.3"); 1CC9 ; 1CC9 ; for (i=0; i<0x2800; i++); 1CC9 EC1E ldd -2,x 1CCB C30001 addd #1 1CCE 6C1E std -2,x 1CD0 EC1E ldd -2,x 1CD2 8C2800 cpd #10240 1CD5 2DF2 blt L16 1CD7 ; //puts("T1 Finished"); 1CD7 ; 1CD7 ; //puts("-T1-"); 1CD7 ; 1CD7 ; 1CD7 ; INTR_OFF(); 1CD7 1410 sei 1CD9 1CD9 ; sem_give(COM1); 1CD9 CC0000 ldd #0 1CDC 161DB5 jsr _sem_give 1CDF ; 1CDF ; } 1CDF L3: 1CDF B757 tfr x,s 1CE1 30 pulx 1CE2 .dbline 0 ; func end 1CE2 3D rts .module task2.c .area text ; i -> -2,x 1CE3 _task2:: 1CE3 34 pshx 1CE4 B775 tfr s,x 1CE6 1B9E leas -2,sp 1CE8 ; #include 1CE8 ; #include <912d60.h> 1CE8 ; #include "kernel.h" 1CE8 ; 1CE8 ; 1CE8 ; 1CE8 ; /* dummy task to eat up time, and to give the kernel 1CE8 ; something to multitask with */ 1CE8 ; void task2 (void) { 1CE8 ; 1CE8 ; int i; 1CE8 ; 1CE8 ; INTR_ON(); 1CE8 10EF cli 1CEA 1CEA CC0000 ldd #0 1CED 6C1E std -2,x 1CEF L4: 1CEF L5: 1CEF ; 1CEF ; //0x800 = ~ 12ms 1CEF ; for (i=0; i<0x0E00; i++); 1CEF EC1E ldd -2,x 1CF1 C30001 addd #1 1CF4 6C1E std -2,x 1CF6 EC1E ldd -2,x 1CF8 8C0E00 cpd #3584 1CFB 2DF2 blt L4 1CFD ; //puts("-T2-"); 1CFD ; 1CFD ; INTR_OFF(); 1CFD 1410 sei 1CFF 1CFF ; 1CFF ; } 1CFF L3: 1CFF B757 tfr x,s 1D01 30 pulx 1D02 .dbline 0 ; func end 1D02 3D rts .module semlib.c .area text ; ?temp -> -2,x ; ?temp -> -2,x ; resource_id -> 3,x 1D03 _sem_get:: 1D03 3B pshd 1D04 34 pshx 1D05 B775 tfr s,x 1D07 1B9E leas -2,sp 1D09 ; // semlib.c 1D09 ; #include <912d60.h> 1D09 ; #include "kernel.h" 1D09 ; #include "semlib.h" 1D09 ; 1D09 ; 1D09 ; 1D09 ; 1D09 ; // GLOBAL VARIABLES 1D09 ; extern unsigned int current; // current task id number 1D09 ; 1D09 ; // task control block 1D09 ; extern struct task_block { 1D09 ; unsigned char id; // ID of task 1D09 ; enum task_state state; // State 1D09 ; unsigned char priority; // Priority 1D09 ; unsigned long int period_tick; // for determining if deadline is up 1D09 ; unsigned int interrupt_msg_box; // flags for pending interrupts 1D09 ; enum message_box message; // misc flags 1D09 ; unsigned char message_data[8]; // data for misc_msg_box flags 1D09 ; unsigned char *heap_ptr; // heap addr while not current task 1D09 ; unsigned int heap_size; // heap size 1D09 ; unsigned char *frame_ptr; // CCR pointer 1D09 ; }; 1D09 ; 1D09 ; 1D09 ; // resource control block 1D09 ; extern struct resource_block { 1D09 ; unsigned char id; // ID of resource 1D09 ; enum resource_state state; // State (busy, free...) 1D09 ; unsigned char user; // Current resource user/owner 1D09 ; signed char queue[3]; // Tasks waiting on resource 1D09 ; unsigned char queue_pos; // Next free spot in queue 1D09 ; }; 1D09 ; 1D09 ; 1D09 ; extern struct task_block task[numtasks]; 1D09 ; extern struct resource_block resource[numresources]; 1D09 ; 1D09 ; 1D09 ; 1D09 ; 1D09 ; 1D09 ; 1D09 ; 1D09 ; int sem_get(char resource_id) { 1D09 ; 1D09 ; /* Gives a resource to a requesting task. 1D09 ; returns the resource id number (0,1,2,...) if free. 1D09 ; otherwise returns -1. 1D09 ; 1D09 ; At this point, semaphores are a procedural control 1D09 ; that the tasks have to follow to avoid resource contention. 1D09 ; There is no kernel control over resources yet. */ 1D09 ; 1D09 ; 1D09 ; // critical section 1D09 ; INTR_OFF(); 1D09 1410 sei 1D0B 1D0B ; 1D0B ; 1D0B ; // GET SEMAPHORE 1D0B ; // give semaphore to task 1D0B ; if (resource[resource_id].state == notbusy) { 1D0B E603 ldab 3,x 1D0D 87 clra 1D0E B7C6 xgdy 1D10 CC0007 ldd #7 1D13 1813 emuls 1D15 C302EB addd #_resource+1 1D18 B7C6 xgdy 1D1A E740 tst 0,y 1D1C 18260065 lbne L4 1D20 ; resource[resource_id].state = busy; 1D20 E603 ldab 3,x 1D22 87 clra 1D23 B7C6 xgdy 1D25 CC0007 ldd #7 1D28 1813 emuls 1D2A C302EB addd #_resource+1 1D2D B7C6 xgdy 1D2F C601 ldab #1 1D31 6B40 stab 0,y 1D33 ; resource[resource_id].user = current; 1D33 E603 ldab 3,x 1D35 87 clra 1D36 B7C6 xgdy 1D38 CC0007 ldd #7 1D3B 1813 emuls 1D3D C302EC addd #_resource+2 1D40 B7C6 xgdy 1D42 FC0344 ldd _current 1D45 6B40 stab 0,y 1D47 ; 1D47 ; if (task[current].state == waiting) 1D47 CC0018 ldd #24 1D4A FD0344 ldy _current 1D4D 13 emul 1D4E C302F9 addd #_task+1 1D51 B7C6 xgdy 1D53 E640 ldab 0,y 1D55 C103 cmpb #3 1D57 2615 bne L9 1D59 ; task[current].message |= state_flag; 1D59 CC0018 ldd #24 1D5C FD0344 ldy _current 1D5F 13 emul 1D60 C30301 addd #_task+9 1D63 6C1E std -2,x 1D65 B746 tfr d,y 1D67 35 pshy ; spill 1D68 ED1E ldy -2,x 1D6A 31 puly ; reload 1D6B 0C4001 bset 0,y,#1 1D6E L9: 1D6E ; task[current].message_data[state_box] = running; 1D6E CC0018 ldd #24 1D71 FD0344 ldy _current 1D74 13 emul 1D75 C30302 addd #_task+10 1D78 B7C6 xgdy 1D7A C602 ldab #2 1D7C 6B40 stab 0,y 1D7E ; 1D7E ; INTR_ON(); 1D7E 10EF cli 1D80 1D80 ; return resource_id; 1D80 E603 ldab 3,x 1D82 87 clra 1D83 202A bra L3 1D85 L4: 1D85 ; } 1D85 ; 1D85 ; // resource is taken/busy 1D85 ; else { 1D85 ; task[current].message |= state_flag; 1D85 CC0018 ldd #24 1D88 FD0344 ldy _current 1D8B 13 emul 1D8C C30301 addd #_task+9 1D8F 6C1E std -2,x 1D91 B746 tfr d,y 1D93 35 pshy ; spill 1D94 ED1E ldy -2,x 1D96 31 puly ; reload 1D97 0C4001 bset 0,y,#1 1D9A ; task[current].message_data[state_box] = waiting; 1D9A CC0018 ldd #24 1D9D FD0344 ldy _current 1DA0 13 emul 1DA1 C30302 addd #_task+10 1DA4 B7C6 xgdy 1DA6 C603 ldab #3 1DA8 6B40 stab 0,y 1DAA ; 1DAA ; INTR_ON(); 1DAA 10EF cli 1DAC 1DAC ; return -1; 1DAC CCFFFF ldd #-1 1DAF L3: 1DAF B757 tfr x,s 1DB1 30 pulx 1DB2 1B82 leas 2,sp 1DB4 .dbline 0 ; func end 1DB4 3D rts 1DB5 ; resource_id -> 3,x 1DB5 _sem_give:: 1DB5 3B pshd 1DB6 34 pshx 1DB7 B775 tfr s,x 1DB9 ; } 1DB9 ; } 1DB9 ; 1DB9 ; 1DB9 ; 1DB9 ; 1DB9 ; int sem_give(char resource_id) { 1DB9 ; 1DB9 ; /* Takes a resource back from a task. 1DB9 ; will (eventually) pass a message to a waiting task. 1DB9 ; 1DB9 ; At this point, semaphores are a procedural control 1DB9 ; that the tasks have to follow to avoid resource contention. 1DB9 ; There is no kernel control over resources yet. */ 1DB9 ; 1DB9 ; 1DB9 ; // critical section 1DB9 ; INTR_OFF(); 1DB9 1410 sei 1DBB 1DBB ; 1DBB ; 1DBB ; // return the resource 1DBB ; resource[resource_id].state = notbusy; 1DBB E603 ldab 3,x 1DBD 87 clra 1DBE B7C6 xgdy 1DC0 CC0007 ldd #7 1DC3 1813 emuls 1DC5 C302EB addd #_resource+1 1DC8 B7C6 xgdy 1DCA 6940 clr 0,y 1DCC ; 1DCC ; INTR_ON(); 1DCC 10EF cli 1DCE 1DCE ; 1DCE ; return 0; 1DCE CC0000 ldd #0 1DD1 L16: 1DD1 B757 tfr x,s 1DD3 30 pulx 1DD4 1B82 leas 2,sp 1DD6 .dbline 0 ; func end 1DD6 3D rts .module vectors.c .area memory(abs) .org 0xffd0 FFD0 _interrupt_vectors:: FFD0 FFFF .word 65535 FFD2 FFFF .word 65535 FFD4 FFFF .word 65535 FFD6 FFFF .word 65535 FFD8 FFFF .word 65535 FFDA FFFF .word 65535 FFDC FFFF .word 65535 FFDE FFFF .word 65535 FFE0 FFFF .word 65535 FFE2 FFFF .word 65535 FFE4 FFFF .word 65535 FFE6 FFFF .word 65535 FFE8 FFFF .word 65535 FFEA FFFF .word 65535 FFEC FFFF .word 65535 FFEE FFFF .word 65535 FFF0 13A1 .word _RTI_handler FFF2 FFFF .word 65535 FFF4 FFFF .word 65535 FFF6 FFFF .word 65535 FFF8 FFFF .word 65535 FFFA FFFF .word 65535 FFFC FFFF .word 65535 FFFE 1000 .word __start .area data .module kernel.c .area data 020C _error_msg:: 020C .blkb 23 .area idata --- 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 .area data --- 0017 .blkb 2 .area idata --- 0017 0000 .byte 0,0 .area data --- 0019 .blkb 13 .area idata --- 0019 73796E746178206572726F7200 .byte 's,'y,'n,'t,'a,'x,32,'e,'r,'r,'o,'r,0 .area data --- 0026 .blkb 12 .area idata --- 0026 00000000000000000000 .word 0,0,0,0,0 --- 0030 0000 .byte 0,0 .area data --- 0032 .blkb 16 .area idata --- 0032 696C6C6567616C207461736B20494400 .byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'I,'D,0 .area data --- 0042 .blkb 9 .area idata --- 0042 000000000000000000 .byte 0,0,0,0,0,0,0,0,0 .area data --- 004B .blkb 19 .area idata --- 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 .area data --- 005E .blkb 6 .area idata --- 005E 000000000000 .byte 0,0,0,0,0,0 .area data --- 0064 .blkb 22 .area idata --- 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 .area data --- 007A .blkb 3 .area idata --- 007A 000000 .byte 0,0,0 .area data --- 007D .blkb 14 .area idata --- 007D 6F7574206F66206D656D6F727900 .byte 'o,'u,'t,32,'o,'f,32,'m,'e,'m,'o,'r,'y,0 .area data --- 008B .blkb 11 .area idata --- 008B 00000000000000000000 .word 0,0,0,0,0 --- 0095 00 .byte 0 .area data 02A2 _error_src:: 02A2 .blkb 14 .area idata --- 0096 6B65726E656C206572726F723A00 .byte 'k,'e,'r,'n,'e,'l,32,'e,'r,'r,'o,'r,58,0 .area data --- 00A4 .blkb 4 .area idata --- 00A4 00000000 .byte 0,0,0,0 .area data --- 00A8 .blkb 16 .area idata --- 00A8 6B65726E656C2E63206572726F723A00 .byte 'k,'e,'r,'n,'e,'l,46,'c,32,'e,'r,'r,'o,'r,58,0 .area data --- 00B8 .blkb 2 .area idata --- 00B8 0000 .byte 0,0 .area data --- 00BA .blkb 18 .area idata --- 00BA 6B65726E656C20525449206572726F72 .byte 'k,'e,'r,'n,'e,'l,32,'R,'T,'I,32,'e,'r,'r,'o,'r --- 00CA 3A00 .byte 58,0 .area data --- 00CC .blkb 13 .area idata --- 00CC 7368656C6C206572726F723A00 .byte 's,'h,'e,'l,'l,32,'e,'r,'r,'o,'r,58,0 .area data --- 00D9 .blkb 5 .area idata --- 00D9 0000000000 .byte 0,0,0,0,0 .area data .area text 1DD7 _get_task_id:: 1DD7 ; //kernel.c 1DD7 ; 1DD7 ; #include <912d60.h> 1DD7 ; #include 1DD7 ; #include "kernel.h" 1DD7 ; 1DD7 ; 1DD7 ; // GLOBAL VARIABLE DEFINITIONS 1DD7 ; unsigned int current; // current task id number 1DD7 ; unsigned long int system_tick; 1DD7 ; 1DD7 ; 1DD7 ; // task control block 1DD7 ; typedef struct task_block { 1DD7 ; unsigned char id; // ID of task 1DD7 ; enum task_state state; // State 1DD7 ; unsigned char priority; // Priority 1DD7 ; unsigned long int period_tick; // for determining if deadline is up 1DD7 ; unsigned int interrupt_msg_box; // flags for pending interrupts 1DD7 ; enum message_box message; // misc flags 1DD7 ; unsigned char message_data[8]; // data for misc_msg_box flags 1DD7 ; unsigned char *heap_ptr; // heap addr while not current task 1DD7 ; unsigned int heap_size; // heap size 1DD7 ; unsigned char *frame_ptr; // CCR pointer 1DD7 ; }; 1DD7 ; 1DD7 ; 1DD7 ; // resource control block 1DD7 ; typedef struct resource_block { 1DD7 ; unsigned char id; // ID of resource 1DD7 ; enum resource_state state; // State (busy, free...) 1DD7 ; unsigned char user; // Current resource user/owner 1DD7 ; signed char queue[3]; // Tasks waiting on resource 1DD7 ; unsigned char queue_pos; // Next free spot in queue 1DD7 ; }; 1DD7 ; 1DD7 ; 1DD7 ; struct task_block task[numtasks]; 1DD7 ; struct resource_block resource[numresources]; 1DD7 ; 1DD7 ; 1DD7 ; // error massages 1DD7 ; char error_msg[6][25] = {"unimplimented function", // error 0 1DD7 ; "syntax error", // error 1 1DD7 ; "illegal task ID", // error 2 1DD7 ; "illegal task state", // error 3 1DD7 ; "illegal task priority", // error 4 1DD7 ; "out of memory" // error 5 1DD7 ; }; 1DD7 ; char error_src[4][18] = {"kernel error:", // source 0 1DD7 ; "kernel.c error:", // source 1 1DD7 ; "kernel RTI error:", // source 2 1DD7 ; "shell error:" // source 3 1DD7 ; }; 1DD7 ; 1DD7 ; 1DD7 ; 1DD7 ; // FUNCTIONS 1DD7 ; 1DD7 ; char get_task_id() { 1DD7 ; return task[current].id; 1DD7 CC0018 ldd #24 1DDA FD0344 ldy _current 1DDD 13 emul 1DDE C302F8 addd #_task 1DE1 B7C6 xgdy 1DE3 E640 ldab 0,y 1DE5 87 clra 1DE6 L3: 1DE6 .dbline 0 ; func end 1DE6 3D rts 1DE7 ; id -> 3,x 1DE7 _get_task_state:: 1DE7 3B pshd 1DE8 34 pshx 1DE9 B775 tfr s,x 1DEB ; } 1DEB ; 1DEB ; 1DEB ; 1DEB ; int get_task_state(unsigned char id) { 1DEB ; 1DEB ; if (id < numtasks) { 1DEB E603 ldab 3,x 1DED C103 cmpb #3 1DEF 2414 bhs L5 1DF1 ; return task[id].state; 1DF1 E603 ldab 3,x 1DF3 87 clra 1DF4 B7C6 xgdy 1DF6 CC0018 ldd #24 1DF9 1813 emuls 1DFB C302F9 addd #_task+1 1DFE B7C6 xgdy 1E00 E640 ldab 0,y 1E02 87 clra 1E03 200F bra L4 1E05 L5: 1E05 ; } 1E05 ; else { 1E05 ; #ifdef KERNEL_ERROR_MSG 1E05 ; puts(error_src[1]); puts(error_msg[3]); 1E05 CC02B4 ldd #_error_src+18 1E08 162BF8 jsr _puts 1E0B CC0257 ldd #_error_msg+75 1E0E 162BF8 jsr _puts 1E11 ; #endif 1E11 ; return -1; 1E11 CCFFFF ldd #-1 1E14 L4: 1E14 B757 tfr x,s 1E16 30 pulx 1E17 1B82 leas 2,sp 1E19 .dbline 0 ; func end 1E19 3D rts 1E1A ; id -> 3,x 1E1A _get_task_messages:: 1E1A 3B pshd 1E1B 34 pshx 1E1C B775 tfr s,x 1E1E ; } 1E1E ; 1E1E ; } 1E1E ; 1E1E ; 1E1E ; 1E1E ; int get_task_messages(unsigned char id) { 1E1E ; 1E1E ; if (id < numtasks) { 1E1E E603 ldab 3,x 1E20 C103 cmpb #3 1E22 2414 bhs L11 1E24 ; return task[id].message; 1E24 E603 ldab 3,x 1E26 87 clra 1E27 B7C6 xgdy 1E29 CC0018 ldd #24 1E2C 1813 emuls 1E2E C30301 addd #_task+9 1E31 B7C6 xgdy 1E33 E640 ldab 0,y 1E35 87 clra 1E36 200F bra L10 1E38 L11: 1E38 ; } 1E38 ; else { 1E38 ; #ifdef KERNEL_ERROR_MSG 1E38 ; puts(error_src[1]); puts(error_msg[3]); 1E38 CC02B4 ldd #_error_src+18 1E3B 162BF8 jsr _puts 1E3E CC0257 ldd #_error_msg+75 1E41 162BF8 jsr _puts 1E44 ; #endif 1E44 ; return -1; 1E44 CCFFFF ldd #-1 1E47 L10: 1E47 B757 tfr x,s 1E49 30 pulx 1E4A 1B82 leas 2,sp 1E4C .dbline 0 ; func end 1E4C 3D rts 1E4D ; id -> 3,x 1E4D _get_task_priority:: 1E4D 3B pshd 1E4E 34 pshx 1E4F B775 tfr s,x 1E51 ; } 1E51 ; 1E51 ; } 1E51 ; 1E51 ; 1E51 ; 1E51 ; int get_task_priority(unsigned char id) { 1E51 ; 1E51 ; INTR_OFF(); 1E51 1410 sei 1E53 1E53 ; 1E53 ; if (id < numtasks) { 1E53 E603 ldab 3,x 1E55 C103 cmpb #3 1E57 2416 bhs L17 1E59 ; INTR_ON(); 1E59 10EF cli 1E5B 1E5B ; return task[id].priority; 1E5B E603 ldab 3,x 1E5D 87 clra 1E5E B7C6 xgdy 1E60 CC0018 ldd #24 1E63 1813 emuls 1E65 C302FA addd #_task+2 1E68 B7C6 xgdy 1E6A E640 ldab 0,y 1E6C 87 clra 1E6D 2011 bra L16 1E6F L17: 1E6F ; } 1E6F ; else { 1E6F ; #ifdef KERNEL_ERROR_MSG 1E6F ; puts(error_src[1]); puts(error_msg[4]); 1E6F CC02B4 ldd #_error_src+18 1E72 162BF8 jsr _puts 1E75 CC0270 ldd #_error_msg+100 1E78 162BF8 jsr _puts 1E7B ; #endif 1E7B ; INTR_ON(); 1E7B 10EF cli 1E7D 1E7D ; return -1; 1E7D CCFFFF ldd #-1 1E80 L16: 1E80 B757 tfr x,s 1E82 30 pulx 1E83 1B82 leas 2,sp 1E85 .dbline 0 ; func end 1E85 3D rts 1E86 ; ?temp -> -2,x 1E86 ; state -> 7,x 1E86 ; id -> 3,x 1E86 _set_task_state:: 1E86 3B pshd 1E87 34 pshx 1E88 B775 tfr s,x 1E8A 1B9E leas -2,sp 1E8C ; } 1E8C ; 1E8C ; } 1E8C ; 1E8C ; 1E8C ; 1E8C ; int set_task_state(unsigned char id, unsigned char state) { 1E8C ; 1E8C ; 1E8C ; INTR_OFF(); 1E8C 1410 sei 1E8E 1E8E ; 1E8E ; 1E8E ; // check id validity 1E8E ; if (id < numtasks) { 1E8E E603 ldab 3,x 1E90 C103 cmpb #3 1E92 18240151 lbhs L23 1E96 ; 1E96 ; // check state validity 1E96 ; if ((state == running) || 1E96 E607 ldab 7,x 1E98 C102 cmpb #2 1E9A 270C beq L28 1E9C E607 ldab 7,x 1E9E C103 cmpb #3 1EA0 2706 beq L28 1EA2 E607 ldab 7,x 1EA4 C104 cmpb #4 1EA6 2315 bls L25 1EA8 L28: 1EA8 ; (state == waiting) || 1EA8 ; (state > finished)) { 1EA8 ; #ifdef KERNEL_ERROR_MSG 1EA8 ; puts(error_src[1]); puts(error_msg[3]); 1EA8 CC02B4 ldd #_error_src+18 1EAB 162BF8 jsr _puts 1EAE CC0257 ldd #_error_msg+75 1EB1 162BF8 jsr _puts 1EB4 ; #endif 1EB4 ; INTR_ON(); 1EB4 10EF cli 1EB6 1EB6 ; return -1; 1EB6 CCFFFF ldd #-1 1EB9 1820013F lbra L22 1EBD L25: 1EBD E603 ldab 3,x 1EBF 87 clra 1EC0 B7C6 xgdy 1EC2 CC0018 ldd #24 1EC5 1813 emuls 1EC7 C302F9 addd #_task+1 1ECA B7C6 xgdy 1ECC E640 ldab 0,y 1ECE 87 clra 1ECF 6C1E std -2,x 1ED1 2716 beq L35 1ED3 EC1E ldd -2,x 1ED5 8C0001 cpd #1 1ED8 18270065 lbeq L46 1EDC EC1E ldd -2,x 1EDE 8C0004 cpd #4 1EE1 182700B4 lbeq L57 1EE5 182000EB lbra L31 1EE9 X0: 1EE9 ; } 1EE9 ; 1EE9 ; switch (task[id].state) { 1EE9 L35: 1EE9 ; case idle: 1EE9 ; if (state == idle) { // no change 1EE9 E707 tst 7,x 1EEB 2609 bne L36 1EED ; INTR_ON(); 1EED 10EF cli 1EEF 1EEF ; return 0; 1EEF CC0000 ldd #0 1EF2 18200106 lbra L22 1EF6 L36: 1EF6 ; } 1EF6 ; else if (state == pending) { 1EF6 E607 ldab 7,x 1EF8 C101 cmpb #1 1EFA 2615 bne L38 1EFC ; // pass msg to task[id].msgbox; 1EFC ; #ifdef KERNEL_ERROR_MSG 1EFC ; puts(error_src[1]); puts(error_msg[0]); 1EFC CC02B4 ldd #_error_src+18 1EFF 162BF8 jsr _puts 1F02 CC020C ldd #_error_msg 1F05 162BF8 jsr _puts 1F08 ; #endif 1F08 ; INTR_ON(); 1F08 10EF cli 1F0A 1F0A ; return -1; 1F0A CCFFFF ldd #-1 1F0D 182000EB lbra L22 1F11 L38: 1F11 ; } 1F11 ; else if (state == finished) { 1F11 E607 ldab 7,x 1F13 C104 cmpb #4 1F15 2615 bne L41 1F17 ; // pass msg to task[id].msgbox; 1F17 ; #ifdef KERNEL_ERROR_MSG 1F17 ; puts(error_src[1]); puts(error_msg[0]); 1F17 CC02B4 ldd #_error_src+18 1F1A 162BF8 jsr _puts 1F1D CC020C ldd #_error_msg 1F20 162BF8 jsr _puts 1F23 ; #endif 1F23 ; INTR_ON(); 1F23 10EF cli 1F25 1F25 ; return -1; 1F25 CCFFFF ldd #-1 1F28 182000D0 lbra L22 1F2C L41: 1F2C ; } 1F2C ; else { // nothing else is legalox; 1F2C ; #ifdef KERNEL_ERROR_MSG 1F2C ; puts(error_src[1]); puts(error_msg[3]); 1F2C CC02B4 ldd #_error_src+18 1F2F 162BF8 jsr _puts 1F32 CC0257 ldd #_error_msg+75 1F35 162BF8 jsr _puts 1F38 ; #endif 1F38 ; INTR_ON(); 1F38 10EF cli 1F3A 1F3A ; return -1; 1F3A CCFFFF ldd #-1 1F3D 182000BB lbra L22 1F41 X1: 1F41 ; } 1F41 ; break; 1F41 L46: 1F41 ; case pending: 1F41 ; if (state == pending) { // no change 1F41 E607 ldab 7,x 1F43 C101 cmpb #1 1F45 2609 bne L47 1F47 ; INTR_ON(); 1F47 10EF cli 1F49 1F49 ; return 0; 1F49 CC0000 ldd #0 1F4C 182000AC lbra L22 1F50 L47: 1F50 ; } 1F50 ; else if (state == idle) { 1F50 E707 tst 7,x 1F52 2615 bne L49 1F54 ; // pass msg to task[id].msgbox; 1F54 ; #ifdef KERNEL_ERROR_MSG 1F54 ; puts(error_src[1]); puts(error_msg[0]); 1F54 CC02B4 ldd #_error_src+18 1F57 162BF8 jsr _puts 1F5A CC020C ldd #_error_msg 1F5D 162BF8 jsr _puts 1F60 ; #endif 1F60 ; INTR_ON(); 1F60 10EF cli 1F62 1F62 ; return -1; 1F62 CCFFFF ldd #-1 1F65 18200093 lbra L22 1F69 L49: 1F69 ; } 1F69 ; else if (state == finished) { 1F69 E607 ldab 7,x 1F6B C104 cmpb #4 1F6D 2615 bne L52 1F6F ; // pass msg to task[id].msgbox; 1F6F ; #ifdef KERNEL_ERROR_MSG 1F6F ; puts(error_src[1]); puts(error_msg[0]); 1F6F CC02B4 ldd #_error_src+18 1F72 162BF8 jsr _puts 1F75 CC020C ldd #_error_msg 1F78 162BF8 jsr _puts 1F7B ; #endif 1F7B ; INTR_ON(); 1F7B 10EF cli 1F7D 1F7D ; return -1; 1F7D CCFFFF ldd #-1 1F80 18200078 lbra L22 1F84 L52: 1F84 ; } 1F84 ; else { 1F84 ; #ifdef KERNEL_ERROR_MSG 1F84 ; puts(error_src[1]); puts(error_msg[3]); 1F84 CC02B4 ldd #_error_src+18 1F87 162BF8 jsr _puts 1F8A CC0257 ldd #_error_msg+75 1F8D 162BF8 jsr _puts 1F90 ; #endif 1F90 ; INTR_ON(); 1F90 10EF cli 1F92 1F92 ; return -1; 1F92 CCFFFF ldd #-1 1F95 18200063 lbra L22 1F99 X2: 1F99 ; } 1F99 ; break; 1F99 L57: 1F99 ; 1F99 ; case finished: 1F99 ; if (state == finished) { // no change 1F99 E607 ldab 7,x 1F9B C104 cmpb #4 1F9D 2609 bne L58 1F9F ; INTR_ON(); 1F9F 10EF cli 1FA1 1FA1 ; return 0; 1FA1 CC0000 ldd #0 1FA4 18200054 lbra L22 1FA8 L58: 1FA8 ; } 1FA8 ; else if (state == pending) { 1FA8 E607 ldab 7,x 1FAA C101 cmpb #1 1FAC 2613 bne L60 1FAE ; // pass msg to task[id].msgbox; 1FAE ; #ifdef KERNEL_ERROR_MSG 1FAE ; puts(error_src[1]); puts(error_msg[0]); 1FAE CC02B4 ldd #_error_src+18 1FB1 162BF8 jsr _puts 1FB4 CC020C ldd #_error_msg 1FB7 162BF8 jsr _puts 1FBA ; #endif 1FBA ; INTR_ON(); 1FBA 10EF cli 1FBC 1FBC ; return -1; 1FBC CCFFFF ldd #-1 1FBF 203B bra L22 1FC1 L60: 1FC1 ; } 1FC1 ; else { 1FC1 ; #ifdef KERNEL_ERROR_MSG 1FC1 ; puts(error_src[1]); puts(error_msg[3]); 1FC1 CC02B4 ldd #_error_src+18 1FC4 162BF8 jsr _puts 1FC7 CC0257 ldd #_error_msg+75 1FCA 162BF8 jsr _puts 1FCD ; #endif 1FCD ; INTR_ON(); 1FCD 10EF cli 1FCF 1FCF ; return -1; 1FCF CCFFFF ldd #-1 1FD2 2028 bra L22 1FD4 X3: 1FD4 ; } 1FD4 ; break; 1FD4 L31: 1FD4 ; default: 1FD4 ; #ifdef KERNEL_ERROR_MSG 1FD4 ; puts(error_src[1]); puts(error_msg[3]); 1FD4 CC02B4 ldd #_error_src+18 1FD7 162BF8 jsr _puts 1FDA CC0257 ldd #_error_msg+75 1FDD 162BF8 jsr _puts 1FE0 ; #endif 1FE0 ; INTR_ON(); 1FE0 10EF cli 1FE2 1FE2 ; return -1; 1FE2 CCFFFF ldd #-1 1FE5 2015 bra L22 1FE7 X4: 1FE7 ; break; 1FE7 L23: 1FE7 ; 1FE7 ; } // end switch (task[id].state) 1FE7 ; 1FE7 ; } // if 1FE7 ; 1FE7 ; else { 1FE7 ; #ifdef KERNEL_ERROR_MSG 1FE7 ; puts(error_src[1]); puts(error_msg[2]); 1FE7 CC02B4 ldd #_error_src+18 1FEA 162BF8 jsr _puts 1FED CC023E ldd #_error_msg+50 1FF0 162BF8 jsr _puts 1FF3 ; #endif 1FF3 ; INTR_ON(); 1FF3 10EF cli 1FF5 1FF5 ; return -1; 1FF5 CCFFFF ldd #-1 1FF8 2002 bra L22 1FFA X5: 1FFA ; } 1FFA ; 1FFA ; INTR_ON(); 1FFA 10EF cli 1FFC 1FFC ; 1FFC ; } 1FFC L22: 1FFC B757 tfr x,s 1FFE 30 pulx 1FFF 1B82 leas 2,sp 2001 .dbline 0 ; func end 2001 3D rts 2002 ; priority -> 7,x 2002 ; id -> 3,x 2002 _set_task_priority:: 2002 3B pshd 2003 34 pshx 2004 B775 tfr s,x 2006 ; 2006 ; 2006 ; 2006 ; int set_task_priority(unsigned char id, unsigned char priority) { 2006 ; 2006 ; if (priority == 0) // priority 0 is reserved for the shell 2006 E707 tst 7,x 2008 2604 bne L70 200A ; priority = 1; 200A C601 ldab #1 200C 6B07 stab 7,x 200E L70: 200E ; 200E ; if (id >= (numtasks)) { 200E E603 ldab 3,x 2010 C103 cmpb #3 2012 2511 blo L72 2014 ; #ifdef KERNEL_ERROR_MSG 2014 ; puts(error_src[1]); puts(error_msg[4]); 2014 CC02B4 ldd #_error_src+18 2017 162BF8 jsr _puts 201A CC0270 ldd #_error_msg+100 201D 162BF8 jsr _puts 2020 ; #endif 2020 ; return -1; 2020 CCFFFF ldd #-1 2023 2031 bra L69 2025 L72: 2025 E607 ldab 7,x 2027 C1FF cmpb #255 2029 2204 bhi L78 202B E707 tst 7,x 202D 2411 bhs L76 202F L78: 202F ; } 202F ; else if ((priority > 255) || (priority < 0)) { 202F ; #ifdef KERNEL_ERROR_MSG 202F ; puts(error_src[1]); puts(error_msg[4]); 202F CC02B4 ldd #_error_src+18 2032 162BF8 jsr _puts 2035 CC0270 ldd #_error_msg+100 2038 162BF8 jsr _puts 203B ; #endif 203B ; return -1; 203B CCFFFF ldd #-1 203E 2016 bra L69 2040 L76: 2040 ; } 2040 ; else { 2040 ; task[id].priority=priority; 2040 E603 ldab 3,x 2042 87 clra 2043 B7C6 xgdy 2045 CC0018 ldd #24 2048 1813 emuls 204A C302FA addd #_task+2 204D B7C6 xgdy 204F E607 ldab 7,x 2051 6B40 stab 0,y 2053 ; return 0; 2053 CC0000 ldd #0 2056 L69: 2056 B757 tfr x,s 2058 30 pulx 2059 1B82 leas 2,sp 205B .dbline 0 ; func end 205B 3D rts .area bss 02EA _resource:: 02EA .blkb 14 02F8 _task:: 02F8 .blkb 72 0340 _system_tick:: 0340 .blkb 4 0344 _current:: 0344 .blkb 2