.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 -> -23,x ; result -> -21,x ; temp_heap_ptr -> -19,x ; last_task -> -17,x ; temp -> -15,x ; temp_heap_size -> -14,x ; next_task -> -12,x ; i -> -10,x 102A _main:: 102A 34 pshx 102B B775 tfr s,x 102D 1BF1E2 leas -30,sp 1030 ; /* RLPOS: RLPotter Operating System 1030 ; 1030 ; Version 0.4 for the 68HC12D60A microcontroller 1030 ; by Ryan Potter 1030 ; ryan@rlpotter.com 1030 ; 1030 ; 1030 ; v0.4 April 13, 2004: 8043 bytes 1030 ; - gerneralized the shell command-line input parser: 1030 ; cmd (up to 32 chars) 1030 ; - added kernel and shell functions 1030 ; v0.3 April 12, 2003: 6090 bytes 1030 ; - added a beginning shell user interface. 1030 ; - added a resource control block and basic semaphore functions. 1030 ; - added basic kernel functions 1030 ; v0.2 April 9, 2003: 1030 ; - able to round-robin with RTI interrupt. 1030 ; - bonified/certified multitasking with 3 tasks. :) 1030 ; v0.1 April 3, 2003: 1030 ; - able to round-robin without interrupts. 1030 ; - not multitasking, really. 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 ; 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 ; 3) kernel takes up too large a fraction of the processing time 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 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[4]; // 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 6CE1EF std -17,x 1036 ; unsigned int next_task = 0; 1036 CC0000 ldd #0 1039 6C14 std -12,x 103B ; unsigned char *temp_heap_ptr, temp; 103B ; 103B ; 103B ; // INITIALIZE GLOBAL VARIABLES 103B ; extern int _bss_end, _textmode; 103B ; extern unsigned int current; 103B ; extern unsigned long int system_tick; 103B ; 103B ; 103B ; _textmode = 1; 103B CC0001 ldd #1 103E 7C0291 std __textmode 1041 ; current = 0; 1041 CC0000 ldd #0 1044 7C028F std _current 1047 ; system_tick = 0; 1047 CD137F ldy #L4 104A 1802401C movw 0,y,-4,x 104E 1802421E movw 2,y,-2,x 1052 CD028B ldy #_system_tick 1055 18021C40 movw -4,x,0,y 1059 18021E42 movw -2,x,2,y 105D CC0000 ldd #0 1060 6C16 std -10,x 1062 2064 bra L8 1064 L5: 1064 CC0009 ldd #9 1067 ED16 ldy -10,x 1069 13 emul 106A C30270 addd #_task 106D B7C6 xgdy 106F EC16 ldd -10,x 1071 6B40 stab 0,y 1073 CC0009 ldd #9 1076 ED16 ldy -10,x 1078 13 emul 1079 C30271 addd #_task+1 107C B7C6 xgdy 107E C604 ldab #4 1080 6B40 stab 0,y 1082 CC0009 ldd #9 1085 ED16 ldy -10,x 1087 13 emul 1088 C30272 addd #_task+2 108B B7C6 xgdy 108D C6FF ldab #255 108F 6B40 stab 0,y 1091 CC0009 ldd #9 1094 ED16 ldy -10,x 1096 13 emul 1097 C30273 addd #_task+3 109A B7C6 xgdy 109C CC0000 ldd #0 109F 6C40 std 0,y 10A1 CC0009 ldd #9 10A4 ED16 ldy -10,x 10A6 13 emul 10A7 C30275 addd #_task+5 10AA B7C6 xgdy 10AC CC0000 ldd #0 10AF 6C40 std 0,y 10B1 CC0009 ldd #9 10B4 ED16 ldy -10,x 10B6 13 emul 10B7 C30277 addd #_task+7 10BA B7C6 xgdy 10BC CC0000 ldd #0 10BF 6C40 std 0,y 10C1 L6: 10C1 EC16 ldd -10,x 10C3 C30001 addd #1 10C6 6C16 std -10,x 10C8 L8: 10C8 ; 10C8 ; 10C8 ; // initialize the task structures 10C8 ; for (i=0; i= numtasks) 124D EC14 ldd -12,x 124F 8C0003 cpd #3 1252 2505 blo L49 1254 ; next_task = 0; 1254 CC0000 ldd #0 1257 6C14 std -12,x 1259 L49: 1259 L24: 1259 1820FED9 lbra L23 125D X2: 125D ; 125D ; 125D ; 125D ; // diagnostic 125D ; //putchar(':'); 125D ; 125D ; } // end 'while(1)' 125D ; 125D ; return 0; 125D CC0000 ldd #0 1260 L3: 1260 B757 tfr x,s 1262 30 pulx 1263 .dbline 0 ; func end 1263 3D rts 1264 ; lreg1 -> -4,x 1264 ; lreg2 -> -8,x 1264 ; ?temp -> -16,x 1264 ; local_thp -> -14,x 1264 ; frame_size -> -12,x 1264 ; i -> -10,x 1264 _RTI_handler:: 1264 34 pshx 1265 B775 tfr s,x 1267 1BF1EC leas -20,sp 126A ; } 126A ; 126A ; 126A ; 126A ; #pragma interrupt_handler RTI_handler() 126A ; 126A ; void RTI_handler(void) { 126A ; 126A ; size_t frame_size; 126A ; unsigned int i; 126A ; unsigned char *local_thp; 126A ; 126A ; 126A ; //ACKNOWLEDGE THE INTERRUPT 126A ; INTR_OFF(); // redundant. automatically done by the processor 126A 1410 sei 126C 126C ; RTIFLG = 0x0080; // acknowledge/clear the interrupt 126C C680 ldab #128 126E 7B0015 stab 0x15 1271 ; 1271 ; 1271 ; 1271 ; //putchar('I'); 1271 ; //putchar(current + 48); 1271 ; //putchar('('); 1271 ; 1271 ; 1271 ; 1271 ; // SET THE FRAME POINTER for the interupted task. 1271 ; // should point to the CCR entry on the stack. 1271 ; asm("TFR x,d"); // start of RTI stack 1271 B754 TFR x,d 1273 1273 ; asm("ADDD #2"); // adjust to CCR stack entry 1273 C30002 ADDD #2 1276 1276 ; asm("STD _temp_task_frame_ptr"); // put into task_frame_ptr 1276 7C020A STD _temp_task_frame_ptr 1279 1279 ; task[current].frame_ptr = temp_task_frame_ptr; 1279 CC0009 ldd #9 127C FD028F ldy _current 127F 13 emul 1280 C30277 addd #_task+7 1283 B7C6 xgdy 1285 FC020A ldd _temp_task_frame_ptr 1288 6C40 std 0,y 128A ; 128A ; 128A ; 128A ; //PLACE CURRENT TASK CONTEXT ONTO THE HEAP 128A ; // determine size of heap segment needed 128A ; frame_size = main_frame_ptr - temp_task_frame_ptr; // always positive 128A FC0206 ldd _main_frame_ptr 128D B3020A subd _temp_task_frame_ptr 1290 6C14 std -12,x 1292 ; task[current].heap_size = (int)frame_size; 1292 CC0009 ldd #9 1295 FD028F ldy _current 1298 13 emul 1299 C30275 addd #_task+5 129C B7C6 xgdy 129E EC14 ldd -12,x 12A0 6C40 std 0,y 12A2 ; 12A2 ; // reallocate heap memory 12A2 ; task[current].heap_ptr = realloc(task[current].heap_ptr, frame_size); 12A2 18021480 movw -12,x,0,sp 12A6 CC0009 ldd #9 12A9 FD028F ldy _current 12AC 13 emul 12AD 6C10 std -16,x 12AF C30273 addd #_task+3 12B2 B7C6 xgdy 12B4 EC40 ldd 0,y 12B6 162D47 jsr _realloc 12B9 6CE1EE std -18,x 12BC EC10 ldd -16,x 12BE C30273 addd #_task+3 12C1 B7C6 xgdy 12C3 ECE1EE ldd -18,x 12C6 6C40 std 0,y 12C8 ; local_thp = task[current].heap_ptr; 12C8 CC0009 ldd #9 12CB FD028F ldy _current 12CE 13 emul 12CF C30273 addd #_task+3 12D2 B7C6 xgdy 12D4 ED40 ldy 0,y 12D6 6D12 sty -14,x 12D8 ; 12D8 ; if (local_thp == NULL) { 12D8 EC12 ldd -14,x 12DA 260C bne L57 12DC ; puts("out of heap space!"); 12DC CC1344 ldd #L59 12DF 162A16 jsr _puts 12E2 ; exit(0); 12E2 CC0000 ldd #0 12E5 161028 jsr _exit 12E8 ; } 12E8 L57: 12E8 CC0000 ldd #0 12EB 6C16 std -10,x 12ED 201A bra L63 12EF L60: 12EF EC16 ldd -10,x 12F1 F3020A addd _temp_task_frame_ptr 12F4 B7C6 xgdy 12F6 E640 ldab 0,y 12F8 3B pshd ; spill 12F9 EC16 ldd -10,x 12FB E312 addd -14,x 12FD B7C6 xgdy 12FF 3A puld ; reload 1300 6B40 stab 0,y 1302 L61: 1302 EC16 ldd -10,x 1304 C30001 addd #1 1307 6C16 std -10,x 1309 L63: 1309 ; 1309 ; // transfer task frame to the heap one byte at a time. 1309 ; // assumes the heap grows from low to high addr. 1309 ; 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 1383 _shell:: 1383 34 pshx 1384 B775 tfr s,x 1386 1BF1C4 leas -60,sp 1389 ; // shell.c 1389 ; 1389 ; 1389 ; #include <912d60.h> 1389 ; #include 1389 ; #include 1389 ; #include 1389 ; #include 1389 ; #include "kernel.h" 1389 ; #include "semlib.h" 1389 ; 1389 ; 1389 ; 1389 ; 1389 ; // FUNCTION PROTOTYPES 1389 ; void shellcmd_help(char *argv1); 1389 ; void shellcmd_tcb(void); 1389 ; void shellcmd_rcb(void); 1389 ; void shellcmd_ticks(void); 1389 ; void shellcmd_start_task(unsigned char id); 1389 ; 1389 ; /*void shellcmd_stop_task(unsigned char id); 1389 ; void shellcmd_set_task_priority(unsigned char id, unsigned char priority); 1389 ; void shellcmd_quit_shell(void);*/ 1389 ; 1389 ; 1389 ; 1389 ; 1389 ; // GLOBAL VARIABLES 1389 ; extern unsigned long int system_tick; 1389 ; extern unsigned int current; // current task id number 1389 ; 1389 ; 1389 ; // LOCAL GLOBAL VARIABLES (context is this file only) 1389 ; static char error[4][21] = {"shell: out of memory", // error[0] 1389 ; "shell: syntax error", // error[1] 1389 ; "shell: 32 chars max", // error[2] 1389 ; "shell: unimplimented" // error[3] 1389 ; }; 1389 ; 1389 ; 1389 ; void shell(void) { 1389 ; 1389 ; // LOCAL CONSTANTS 1389 ; #define cmd_size (32+1) 1389 ; 1389 ; 1389 ; 1389 ; // LOCAL ENUMERATIONS 1389 ; enum command_type { help = 1, 1389 ; tcb, 1389 ; rcb, 1389 ; ticks, 1389 ; start, 1389 ; stop, 1389 ; priority, 1389 ; quit 1389 ; }; 1389 ; 1389 ; 1389 ; 1389 ; // LOCAL VARIABLES 1389 ; char command[cmd_size], i, j, **argv, *cursor1, *cursor2; 1389 ; int cmd_length, argc; 1389 ; enum command_type cmd; 1389 ; 1389 ; 1389 ; 1389 ; 1389 ; // INITIALIZE SHELL 1389 ; sem_get(COM1); // get comm port 1 semaphore 1389 CC0000 ldd #0 138C 161DE6 jsr _sem_get 138F ; INTR_ON(); // enable interrupts 138F 10EF cli 1391 1391 18200445 lbra L5 1395 L4: 1395 ; 1395 ; 1395 ; 1395 ; // SHELL COMMAND LINE INTERPRETER 1395 ; while (1) { 1395 ; 1395 ; i = 0; 1395 691F clr -1,x 1397 ; cursor1 = command; 1397 19E1DE leay -34,x 139A 6DE1D9 sty -39,x 139D ; cursor2 = command; 139D 19E1DE leay -34,x 13A0 6DE1DC sty -36,x 13A3 ; 13A3 ; 13A3 ; // put a PROMPT 13A3 ; putchar('>'); putchar('>'); putchar(' '); 13A3 CC003E ldd #62 13A6 16248B jsr _putchar 13A9 CC003E ldd #62 13AC 16248B jsr _putchar 13AF CC0020 ldd #32 13B2 16248B jsr _putchar 13B5 2056 bra L8 13B7 L7: 13B7 ; 13B7 ; 13B7 ; // GET AND ECHO THE COMMAND on the console 13B7 ; while (((command[i]=getchar()) != 0xD) && (i -- required arguments"); 16D2 CC1A74 ldd #L69 16D5 162A16 jsr _puts 16D8 ; puts("[] -- optional arguments\n"); 16D8 CC1A5A ldd #L70 16DB 162A16 jsr _puts 16DE ; puts("help [cmd] -- help on a specific command"); 16DE CC1A31 ldd #L71 16E1 162A16 jsr _puts 16E4 ; puts("tcb [task_id] -- prints task control block"); 16E4 CC1A06 ldd #L72 16E7 162A16 jsr _puts 16EA ; puts("rcb [task_id] -- prints resource control block"); 16EA CC19D7 ldd #L73 16ED 162A16 jsr _puts 16F0 ; puts("ticks -- shows system tick"); 16F0 CC19BC ldd #L74 16F3 162A16 jsr _puts 16F6 ; puts("start -- start a task"); 16F6 CC199C ldd #L75 16F9 162A16 jsr _puts 16FC ; puts("stop -- stop a task"); 16FC CC197D ldd #L76 16FF 162A16 jsr _puts 1702 ; puts("priority -- change prio"); 1702 CC194B ldd #L77 1705 162A16 jsr _puts 1708 ; puts("quit -- quit the shell (carefull!)"); 1708 CC1928 ldd #L78 170B 162A16 jsr _puts 170E ; putchar('\n'); 170E CC000A ldd #10 1711 16248B jsr _putchar 1714 ; } 1714 18200094 lbra L63 1718 L66: 1718 ; else if (argc == 2) 1718 ECE1D5 ldd -43,x 171B 8C0002 cpd #2 171E 1826008A lbne L63 1722 ; shellcmd_help(argv[1]); 1722 EDE1D7 ldy -41,x 1725 EC42 ldd 2,y 1727 1617EA jsr _shellcmd_help 172A ; break; 172A 1820007E lbra L63 172E L81: 172E ; case tcb: 172E ; if (argc == 1) 172E ECE1D5 ldd -43,x 1731 8C0001 cpd #1 1734 2605 bne L82 1736 ; shellcmd_tcb(); 1736 1617F1 jsr _shellcmd_tcb 1739 2071 bra L63 173B L82: 173B ; else if (argc > 1) 173B ECE1D5 ldd -43,x 173E 8C0001 cpd #1 1741 2F69 ble L63 1743 ; puts(error[3]); 1743 CC024B ldd #_error+63 1746 162A16 jsr _puts 1749 ; break; 1749 2061 bra L63 174B L87: 174B ; case rcb: 174B ; puts(error[3]); 174B CC024B ldd #_error+63 174E 162A16 jsr _puts 1751 ; break; 1751 2059 bra L63 1753 L89: 1753 ; case ticks: 1753 ; if (argc > 1) 1753 ECE1D5 ldd -43,x 1756 8C0001 cpd #1 1759 2F08 ble L90 175B ; puts(error[1]); 175B CC0221 ldd #_error+21 175E 162A16 jsr _puts 1761 2049 bra L63 1763 L90: 1763 ; else 1763 ; shellcmd_ticks(); 1763 161843 jsr _shellcmd_ticks 1766 ; break; 1766 2044 bra L63 1768 L93: 1768 ; case start: 1768 ; if ((argc != 2) || 1768 ECE1D5 ldd -43,x 176B 8C0002 cpd #2 176E 2610 bne L96 1770 EDE1D7 ldy -41,x 1773 ED42 ldy 2,y 1775 E640 ldab 0,y 1777 87 clra 1778 162C20 jsr _isdigit 177B 8C0000 cpd #0 177E 2608 bne L94 1780 L96: 1780 ; (!isdigit(*argv[1]))) 1780 ; puts(error[1]); 1780 CC0221 ldd #_error+21 1783 162A16 jsr _puts 1786 2024 bra L63 1788 L94: 1788 ; else 1788 ; shellcmd_start_task(atoi(argv[1])); 1788 EDE1D7 ldy -41,x 178B EC42 ldd 2,y 178D 162E7B jsr _atoi 1790 87 clra 1791 16186B jsr _shellcmd_start_task 1794 ; break; 1794 2016 bra L63 1796 L98: 1796 ; case stop: 1796 ; puts(error[3]); 1796 CC024B ldd #_error+63 1799 162A16 jsr _puts 179C ; break; 179C 200E bra L63 179E L100: 179E ; case priority: 179E ; puts(error[3]); 179E CC024B ldd #_error+63 17A1 162A16 jsr _puts 17A4 ; break; 17A4 2006 bra L63 17A6 L102: 17A6 ; case quit: 17A6 ; puts(error[3]); 17A6 CC024B ldd #_error+63 17A9 162A16 jsr _puts 17AC ; break; 17AC ; default: 17AC ; break; 17AC L63: 17AC ; }} 17AC L60: 17AC ; 17AC ; 17AC ; 17AC ; // free the argc and argv array memory 17AC ; for (i=0; i 2,x 17EA _shellcmd_help:: 17EA ; 17EA ; 17EA ; 17EA ; 17EA ; void shellcmd_help(char *argv1) { 17EA ; 17EA ; puts(error[3]); 17EA CC024B ldd #_error+63 17ED 162A16 jsr _puts 17F0 ; } 17F0 L108: 17F0 .dbline 0 ; func end 17F0 3D rts 17F1 ; id -> -2,x 17F1 _shellcmd_tcb:: 17F1 34 pshx 17F2 B775 tfr s,x 17F4 1B96 leas -10,sp 17F6 ; 17F6 ; 17F6 ; 17F6 ; void shellcmd_tcb(void) { 17F6 ; 17F6 ; // LOCAL VARIABLES 17F6 ; int id; 17F6 ; 17F6 ; 17F6 ; /* this takes a while, so treat as a critical section in order 17F6 ; to get reliable data */ 17F6 ; INTR_OFF(); 17F6 1410 sei 17F8 17F8 CC0000 ldd #0 17FB 6C1E std -2,x 17FD L111: 17FD CC1906 ldd #L115 1800 162A16 jsr _puts 1803 EC1E ldd -2,x 1805 87 clra 1806 161B5D jsr _get_task_state 1809 6C1C std -4,x 180B EC1E ldd -2,x 180D 87 clra 180E 161B8B jsr _get_task_priority 1811 87 clra 1812 6C84 std 4,sp 1814 EC1C ldd -4,x 1816 87 clra 1817 6C82 std 2,sp 1819 18021E80 movw -2,x,0,sp 181D CC18E3 ldd #L116 1820 162A4E jsr _printf 1823 L112: 1823 ; 1823 ; for (id=0; id -4,x 1843 ; lreg2 -> -8,x 1843 _shellcmd_ticks:: 1843 34 pshx 1844 B775 tfr s,x 1846 1B94 leas -12,sp 1848 ; 1848 ; 1848 ; 1848 ; 1848 ; void shellcmd_ticks(void) { 1848 ; 1848 ; INTR_OFF(); 1848 1410 sei 184A 184A ; printf("Ticks: %ld\n", system_tick); 184A CD028B ldy #_system_tick 184D 1802401C movw 0,y,-4,x 1851 1802421E movw 2,y,-2,x 1855 1980 leay 0,sp 1857 18021C40 movw -4,x,0,y 185B 18021E42 movw -2,x,2,y 185F CC18A3 ldd #L119 1862 162A4E jsr _printf 1865 ; INTR_ON(); 1865 10EF cli 1867 1867 ; } 1867 L118: 1867 B757 tfr x,s 1869 30 pulx 186A .dbline 0 ; func end 186A 3D rts 186B ; id -> 3,x 186B _shellcmd_start_task:: 186B 3B pshd 186C 34 pshx 186D B775 tfr s,x 186F 1B9E leas -2,sp 1871 ; 1871 ; 1871 ; 1871 ; 1871 ; void shellcmd_start_task(unsigned char id) { 1871 ; 1871 ; if (set_task_state(id, pending) == 0) 1871 CC0001 ldd #1 1874 6C80 std 0,sp 1876 E603 ldab 3,x 1878 87 clra 1879 161BDC jsr _set_task_state 187C 8C0000 cpd #0 187F 260B bne L121 1881 ; printf("task %d started\n", id); 1881 E603 ldab 3,x 1883 87 clra 1884 6C80 std 0,sp 1886 CC1892 ldd #L123 1889 162A4E jsr _printf 188C L121: 188C ; } 188C L120: 188C B757 tfr x,s 188E 30 pulx 188F 1B82 leas 2,sp 1891 .dbline 0 ; func end 1891 3D rts 1892 L123: 1892 7461736B20256420737461727465640A .byte 't,'a,'s,'k,32,37,'d,32,'s,'t,'a,'r,'t,'e,'d,10 18A2 00 .byte 0 18A3 L119: 18A3 5469636B733A20256C640A00 .byte 'T,'i,'c,'k,'s,58,32,37,'l,'d,10,0 18AF L117: 18AF 49646C653D302C2050656E64696E673D .byte 'I,'d,'l,'e,61,48,44,32,'P,'e,'n,'d,'i,'n,'g,61 18BF 312C2052756E6E696E673D322C205761 .byte 49,44,32,'R,'u,'n,'n,'i,'n,'g,61,50,44,32,'W,'a 18CF 6974696E673D332C2046696E69736865 .byte 'i,'t,'i,'n,'g,61,51,44,32,'F,'i,'n,'i,'s,'h,'e 18DF 643D3400 .byte 'd,61,52,0 18E3 L116: 18E3 5461736B49443A202564207C20537461 .byte 'T,'a,'s,'k,'I,'D,58,32,37,'d,32,124,32,'S,'t,'a 18F3 74653A202564207C205072696F3A2025 .byte 't,'e,58,32,37,'d,32,124,32,'P,'r,'i,'o,58,32,37 1903 640A00 .byte 'd,10,0 1906 L115: 1906 2D2D2D2D2D2D2D2D2D2D2B2D2D2D2D2D .byte 45,45,45,45,45,45,45,45,45,45,43,45,45,45,45,45 1916 2D2D2D2D2D2B2D2D2D2D2D2D2D2D2D2D .byte 45,45,45,45,45,43,45,45,45,45,45,45,45,45,45,45 1926 2B00 .byte 43,0 1928 L78: 1928 71756974202D2D207175697420746865 .byte 'q,'u,'i,'t,32,45,45,32,'q,'u,'i,'t,32,'t,'h,'e 1938 207368656C6C20286361726566756C6C .byte 32,'s,'h,'e,'l,'l,32,40,'c,'a,'r,'e,'f,'u,'l,'l 1948 212900 .byte 33,41,0 194B L77: 194B 7072696F72697479203C7461736B5F69 .byte 'p,'r,'i,'o,'r,'i,'t,'y,32,60,'t,'a,'s,'k,95,'i 195B 642C207461736B5F7072696F72697479 .byte 'd,44,32,'t,'a,'s,'k,95,'p,'r,'i,'o,'r,'i,'t,'y 196B 3E20202D2D206368616E676520707269 .byte 62,32,32,45,45,32,'c,'h,'a,'n,'g,'e,32,'p,'r,'i 197B 6F00 .byte 'o,0 197D L76: 197D 73746F70203C7461736B5F69643E2020 .byte 's,'t,'o,'p,32,60,'t,'a,'s,'k,95,'i,'d,62,32,32 198D 2D2D2073746F702061207461736B00 .byte 45,45,32,'s,'t,'o,'p,32,'a,32,'t,'a,'s,'k,0 199C L75: 199C 7374617274203C7461736B5F69643E20 .byte 's,'t,'a,'r,'t,32,60,'t,'a,'s,'k,95,'i,'d,62,32 19AC 2D2D2073746172742061207461736B00 .byte 45,45,32,'s,'t,'a,'r,'t,32,'a,32,'t,'a,'s,'k,0 19BC L74: 19BC 7469636B73202D2D2073686F77732073 .byte 't,'i,'c,'k,'s,32,45,45,32,'s,'h,'o,'w,'s,32,'s 19CC 797374656D207469636B00 .byte 'y,'s,'t,'e,'m,32,'t,'i,'c,'k,0 19D7 L73: 19D7 726362205B7461736B5F69645D202D2D .byte 'r,'c,'b,32,91,'t,'a,'s,'k,95,'i,'d,93,32,45,45 19E7 207072696E7473207265736F75726365 .byte 32,'p,'r,'i,'n,'t,'s,32,'r,'e,'s,'o,'u,'r,'c,'e 19F7 20636F6E74726F6C20626C6F636B00 .byte 32,'c,'o,'n,'t,'r,'o,'l,32,'b,'l,'o,'c,'k,0 1A06 L72: 1A06 746362205B7461736B5F69645D202D2D .byte 't,'c,'b,32,91,'t,'a,'s,'k,95,'i,'d,93,32,45,45 1A16 207072696E7473207461736B20636F6E .byte 32,'p,'r,'i,'n,'t,'s,32,'t,'a,'s,'k,32,'c,'o,'n 1A26 74726F6C20626C6F636B00 .byte 't,'r,'o,'l,32,'b,'l,'o,'c,'k,0 1A31 L71: 1A31 68656C70205B636D645D202D2D206865 .byte 'h,'e,'l,'p,32,91,'c,'m,'d,93,32,45,45,32,'h,'e 1A41 6C70206F6E2061207370656369666963 .byte 'l,'p,32,'o,'n,32,'a,32,'s,'p,'e,'c,'i,'f,'i,'c 1A51 20636F6D6D616E6400 .byte 32,'c,'o,'m,'m,'a,'n,'d,0 1A5A L70: 1A5A 5B5D202D2D206F7074696F6E616C2061 .byte 91,93,32,45,45,32,'o,'p,'t,'i,'o,'n,'a,'l,32,'a 1A6A 7267756D656E74730A00 .byte 'r,'g,'u,'m,'e,'n,'t,'s,10,0 1A74 L69: 1A74 3C3E202D2D2072657175697265642061 .byte 60,62,32,45,45,32,'r,'e,'q,'u,'i,'r,'e,'d,32,'a 1A84 7267756D656E747300 .byte 'r,'g,'u,'m,'e,'n,'t,'s,0 1A8D L68: 1A8D 2D2D2D48454C502D2D2D0A00 .byte 45,45,45,'H,'E,'L,'P,45,45,45,10,0 1A99 L58: 1A99 00 .byte 0 1A9A L55: 1A9A 7175697400 .byte 'q,'u,'i,'t,0 1A9F L52: 1A9F 7072696F7269747900 .byte 'p,'r,'i,'o,'r,'i,'t,'y,0 1AA8 L49: 1AA8 73746F7000 .byte 's,'t,'o,'p,0 1AAD L46: 1AAD 737461727400 .byte 's,'t,'a,'r,'t,0 1AB3 L43: 1AB3 7469636B7300 .byte 't,'i,'c,'k,'s,0 1AB9 L40: 1AB9 72636200 .byte 'r,'c,'b,0 1ABD L37: 1ABD 74636200 .byte 't,'c,'b,0 1AC1 L34: 1AC1 68656C7000 .byte 'h,'e,'l,'p,0 .module task1.c .area text ; i -> -2,x 1AC6 _task1:: 1AC6 34 pshx 1AC7 B775 tfr s,x 1AC9 1B9E leas -2,sp 1ACB ; #include 1ACB ; #include <912d60.h> 1ACB ; #include "semlib.h" 1ACB ; 1ACB ; 1ACB ; 1ACB ; /* dummy task to eat up time, and to give the kernel 1ACB ; something to multitask with */ 1ACB ; void task1 (void) { 1ACB ; 1ACB ; int i; 1ACB ; 1ACB ; sem_get(COM1); 1ACB CC0000 ldd #0 1ACE 161DE6 jsr _sem_get 1AD1 ; INTR_ON(); 1AD1 10EF cli 1AD3 1AD3 CC0000 ldd #0 1AD6 6C1E std -2,x 1AD8 L4: 1AD8 L5: 1AD8 ; 1AD8 ; 1AD8 ; //puts("T1 Starting"); 1AD8 ; for (i=0; i<0x1800; i++); 1AD8 EC1E ldd -2,x 1ADA C30001 addd #1 1ADD 6C1E std -2,x 1ADF EC1E ldd -2,x 1AE1 8C1800 cpd #6144 1AE4 2DF2 blt L4 1AE6 CC0000 ldd #0 1AE9 6C1E std -2,x 1AEB L8: 1AEB L9: 1AEB ; //puts("T1.1"); 1AEB ; 1AEB ; for (i=0; i<0x1A00; i++); 1AEB EC1E ldd -2,x 1AED C30001 addd #1 1AF0 6C1E std -2,x 1AF2 EC1E ldd -2,x 1AF4 8C1A00 cpd #6656 1AF7 2DF2 blt L8 1AF9 CC0000 ldd #0 1AFC 6C1E std -2,x 1AFE L12: 1AFE L13: 1AFE ; //puts("T1.2"); 1AFE ; 1AFE ; for (i=0; i<0x2C00; i++); 1AFE EC1E ldd -2,x 1B00 C30001 addd #1 1B03 6C1E std -2,x 1B05 EC1E ldd -2,x 1B07 8C2C00 cpd #11264 1B0A 2DF2 blt L12 1B0C CC0000 ldd #0 1B0F 6C1E std -2,x 1B11 L16: 1B11 L17: 1B11 ; //puts("T1.3"); 1B11 ; 1B11 ; for (i=0; i<0x2E00; i++); 1B11 EC1E ldd -2,x 1B13 C30001 addd #1 1B16 6C1E std -2,x 1B18 EC1E ldd -2,x 1B1A 8C2E00 cpd #11776 1B1D 2DF2 blt L16 1B1F ; //puts("T1 Finished"); 1B1F ; 1B1F ; //puts("-T1-"); 1B1F ; 1B1F ; 1B1F ; INTR_OFF(); 1B1F 1410 sei 1B21 1B21 ; sem_give(COM1); 1B21 CC0000 ldd #0 1B24 161E5F jsr _sem_give 1B27 ; 1B27 ; } 1B27 L3: 1B27 B757 tfr x,s 1B29 30 pulx 1B2A .dbline 0 ; func end 1B2A 3D rts .module task2.c .area text ; i -> -2,x 1B2B _task2:: 1B2B 34 pshx 1B2C B775 tfr s,x 1B2E 1B9E leas -2,sp 1B30 ; #include 1B30 ; #include <912d60.h> 1B30 ; #include "kernel.h" 1B30 ; 1B30 ; 1B30 ; 1B30 ; /* dummy task to eat up time, and to give the kernel 1B30 ; something to multitask with */ 1B30 ; void task2 (void) { 1B30 ; 1B30 ; int i; 1B30 ; 1B30 ; INTR_ON(); 1B30 10EF cli 1B32 1B32 CC0000 ldd #0 1B35 6C1E std -2,x 1B37 2007 bra L7 1B39 L4: 1B39 L5: 1B39 EC1E ldd -2,x 1B3B C30001 addd #1 1B3E 6C1E std -2,x 1B40 L7: 1B40 ; 1B40 ; for (i=0; i<0xA000; i++); 1B40 EC1E ldd -2,x 1B42 8CA000 cpd #0xa000 1B45 25F2 blo L4 1B47 ; //puts("-T2-"); 1B47 ; 1B47 ; INTR_OFF(); 1B47 1410 sei 1B49 1B49 ; 1B49 ; } 1B49 L3: 1B49 B757 tfr x,s 1B4B 30 pulx 1B4C .dbline 0 ; func end 1B4C 3D rts .module kernel.c .area text 1B4D _get_task_id:: 1B4D ; //kernel.c 1B4D ; 1B4D ; #include <912d60.h> 1B4D ; #include 1B4D ; #include "kernel.h" 1B4D ; 1B4D ; 1B4D ; // GLOBAL VARIABLE DEFINITIONS 1B4D ; unsigned int current; // current task id number 1B4D ; unsigned long int system_tick; 1B4D ; 1B4D ; 1B4D ; // task control block 1B4D ; typedef struct task_block { 1B4D ; unsigned char id; // ID of task 1B4D ; enum task_state state; // State 1B4D ; unsigned char priority; // Priority 1B4D ; unsigned char *heap_ptr; // heap addr while not current task 1B4D ; unsigned int heap_size; // heap size 1B4D ; unsigned char *frame_ptr; // CCR pointer 1B4D ; }; 1B4D ; 1B4D ; 1B4D ; // resource control block 1B4D ; typedef struct resource_block { 1B4D ; unsigned char id; // ID of resource 1B4D ; enum resource_state state; // State (busy, free...) 1B4D ; unsigned char user; // Current resource user/owner 1B4D ; signed char queue[4]; // Tasks waiting on resource 1B4D ; unsigned char queue_pos; // Next free spot in queue 1B4D ; }; 1B4D ; 1B4D ; 1B4D ; struct task_block task[numtasks]; 1B4D ; struct resource_block resource[numresources]; 1B4D ; 1B4D ; 1B4D ; 1B4D ; // FUNCTIONS 1B4D ; 1B4D ; unsigned char get_task_id() { 1B4D ; return task[current].id; 1B4D CC0009 ldd #9 1B50 FD028F ldy _current 1B53 13 emul 1B54 C30270 addd #_task 1B57 B7C6 xgdy 1B59 E640 ldab 0,y 1B5B 87 clra 1B5C L3: 1B5C .dbline 0 ; func end 1B5C 3D rts 1B5D ; id -> 3,x 1B5D _get_task_state:: 1B5D 3B pshd 1B5E 34 pshx 1B5F B775 tfr s,x 1B61 ; } 1B61 ; 1B61 ; 1B61 ; 1B61 ; unsigned char get_task_state(unsigned char id) { 1B61 ; 1B61 ; if (id > (numtasks-1)) { 1B61 E603 ldab 3,x 1B63 C102 cmpb #2 1B65 230C bls L5 1B67 ; puts("kernel: illegal task id"); 1B67 CC1DCE ldd #L7 1B6A 162A16 jsr _puts 1B6D ; return -1; 1B6D CCFFFF ldd #-1 1B70 87 clra 1B71 2012 bra L4 1B73 L5: 1B73 ; } 1B73 ; else 1B73 ; return task[id].state; 1B73 E603 ldab 3,x 1B75 87 clra 1B76 B7C6 xgdy 1B78 CC0009 ldd #9 1B7B 1813 emuls 1B7D C30271 addd #_task+1 1B80 B7C6 xgdy 1B82 E640 ldab 0,y 1B84 87 clra 1B85 L4: 1B85 B757 tfr x,s 1B87 30 pulx 1B88 1B82 leas 2,sp 1B8A .dbline 0 ; func end 1B8A 3D rts 1B8B ; id -> 3,x 1B8B _get_task_priority:: 1B8B 3B pshd 1B8C 34 pshx 1B8D B775 tfr s,x 1B8F ; } 1B8F ; 1B8F ; 1B8F ; 1B8F ; unsigned char get_task_priority(unsigned char id) { 1B8F ; 1B8F ; if (id > (numtasks-1)) { 1B8F E603 ldab 3,x 1B91 C102 cmpb #2 1B93 230C bls L10 1B95 ; puts("kernel: illegal task id"); 1B95 CC1DCE ldd #L7 1B98 162A16 jsr _puts 1B9B ; return -1; 1B9B CCFFFF ldd #-1 1B9E 87 clra 1B9F 2012 bra L9 1BA1 L10: 1BA1 ; } 1BA1 ; else 1BA1 ; return task[id].priority; 1BA1 E603 ldab 3,x 1BA3 87 clra 1BA4 B7C6 xgdy 1BA6 CC0009 ldd #9 1BA9 1813 emuls 1BAB C30272 addd #_task+2 1BAE B7C6 xgdy 1BB0 E640 ldab 0,y 1BB2 87 clra 1BB3 L9: 1BB3 B757 tfr x,s 1BB5 30 pulx 1BB6 1B82 leas 2,sp 1BB8 .dbline 0 ; func end 1BB8 3D rts 1BB9 L14: 1BB9 6B65726E656C3A20696C6C6567616C20 .byte 'k,'e,'r,'n,'e,'l,58,32,'i,'l,'l,'e,'g,'a,'l,32 1BC9 7461736B207374617465207265717565 .byte 't,'a,'s,'k,32,'s,'t,'a,'t,'e,32,'r,'e,'q,'u,'e 1BD9 737400 .byte 's,'t,0 1BDC ; ?temp -> -37,x 1BDC ; error_msg -> -35,x 1BDC ; state -> 7,x 1BDC ; id -> 3,x 1BDC _set_task_state:: 1BDC 3B pshd 1BDD 34 pshx 1BDE B775 tfr s,x 1BE0 1BF1DA leas -38,sp 1BE3 ; } 1BE3 ; 1BE3 ; 1BE3 ; 1BE3 ; int set_task_state(unsigned char id, unsigned char state) { 1BE3 ; 1BE3 ; // LOCAL VARIABLES 1BE3 ; char error_msg[35] = "kernel: illegal task state request"; 1BE3 19E1DD leay -35,x 1BE6 B7C6 xgdy 1BE8 CD1BB9 ldy #L14 1BEB 34 pshx 1BEC B745 tfr d,x 1BEE CC0011 ldd #17 1BF1 X0: 1BF1 18027131 movw 2,y+,2,x+ 1BF5 0434F9 dbne d,X0 1BF8 180A4000 movb 0,y,0,x 1BFC 30 pulx 1BFD ; //INTR_OFF(); 1BFD ; 1BFD ; if (id > (numtasks-1)) { 1BFD E603 ldab 3,x 1BFF C102 cmpb #2 1C01 230D bls L15 1C03 ; puts("kernel: illegal task id"); 1C03 CC1DCE ldd #L7 1C06 162A16 jsr _puts 1C09 ; return -1; 1C09 CCFFFF ldd #-1 1C0C 18200144 lbra L13 1C10 L15: 1C10 E607 ldab 7,x 1C12 C104 cmpb #4 1C14 2204 bhi L19 1C16 E707 tst 7,x 1C18 240F bhs L17 1C1A L19: 1C1A ; } 1C1A ; if ((state > 4) || (state < 0)) { 1C1A ; puts(error_msg); 1C1A 19E1DD leay -35,x 1C1D B7C6 xgdy 1C1F 162A16 jsr _puts 1C22 ; return -1; 1C22 CCFFFF ldd #-1 1C25 1820012B lbra L13 1C29 L17: 1C29 ; } 1C29 ; if (state == running) { 1C29 E607 ldab 7,x 1C2B C102 cmpb #2 1C2D 260F bne L20 1C2F ; puts(error_msg); 1C2F 19E1DD leay -35,x 1C32 B7C6 xgdy 1C34 162A16 jsr _puts 1C37 ; return -1; 1C37 CCFFFF ldd #-1 1C3A 18200116 lbra L13 1C3E L20: 1C3E E603 ldab 3,x 1C40 87 clra 1C41 B7C6 xgdy 1C43 CC0009 ldd #9 1C46 1813 emuls 1C48 C30271 addd #_task+1 1C4B B7C6 xgdy 1C4D E640 ldab 0,y 1C4F 87 clra 1C50 6CE1DB std -37,x 1C53 2720 beq L26 1C55 ECE1DB ldd -37,x 1C58 8C0001 cpd #1 1C5B 2752 beq L32 1C5D ECE1DB ldd -37,x 1C60 8C0003 cpd #3 1C63 1827007E lbeq L38 1C67 ECE1DB ldd -37,x 1C6A 8C0004 cpd #4 1C6D 1827008A lbeq L42 1C71 182000D6 lbra L22 1C75 X1: 1C75 ; } 1C75 ; 1C75 ; switch (task[id].state) { 1C75 L26: 1C75 ; case idle: 1C75 ; if (state == idle) 1C75 E707 tst 7,x 1C77 2607 bne L27 1C79 ; return 0; 1C79 CC0000 ldd #0 1C7C 182000D4 lbra L13 1C80 L27: 1C80 ; if (state == pending) { 1C80 E607 ldab 7,x 1C82 C101 cmpb #1 1C84 261A bne L29 1C86 ; task[id].state = pending; 1C86 E603 ldab 3,x 1C88 87 clra 1C89 B7C6 xgdy 1C8B CC0009 ldd #9 1C8E 1813 emuls 1C90 C30271 addd #_task+1 1C93 B7C6 xgdy 1C95 C601 ldab #1 1C97 6B40 stab 0,y 1C99 ; return 0; 1C99 CC0000 ldd #0 1C9C 182000B4 lbra L13 1CA0 L29: 1CA0 ; } 1CA0 ; else { 1CA0 ; puts(error_msg); 1CA0 19E1DD leay -35,x 1CA3 B7C6 xgdy 1CA5 162A16 jsr _puts 1CA8 ; return -1; 1CA8 CCFFFF ldd #-1 1CAB 182000A5 lbra L13 1CAF X2: 1CAF ; } 1CAF ; break; 1CAF L32: 1CAF ; case pending: 1CAF ; if (state == pending) 1CAF E607 ldab 7,x 1CB1 C101 cmpb #1 1CB3 2607 bne L33 1CB5 ; return 0; 1CB5 CC0000 ldd #0 1CB8 18200098 lbra L13 1CBC L33: 1CBC ; if (state == idle) { 1CBC E707 tst 7,x 1CBE 2618 bne L35 1CC0 ; task[id].state = idle; 1CC0 E603 ldab 3,x 1CC2 87 clra 1CC3 B7C6 xgdy 1CC5 CC0009 ldd #9 1CC8 1813 emuls 1CCA C30271 addd #_task+1 1CCD B7C6 xgdy 1CCF 6940 clr 0,y 1CD1 ; return 0; 1CD1 CC0000 ldd #0 1CD4 1820007C lbra L13 1CD8 L35: 1CD8 ; } 1CD8 ; else { 1CD8 ; puts(error_msg); 1CD8 19E1DD leay -35,x 1CDB B7C6 xgdy 1CDD 162A16 jsr _puts 1CE0 ; return -1; 1CE0 CCFFFF ldd #-1 1CE3 206F bra L13 1CE5 X3: 1CE5 ; } 1CE5 ; break; 1CE5 L38: 1CE5 ; case waiting: 1CE5 ; if (state == waiting) 1CE5 E607 ldab 7,x 1CE7 C103 cmpb #3 1CE9 2605 bne L39 1CEB ; return 0; 1CEB CC0000 ldd #0 1CEE 2064 bra L13 1CF0 L39: 1CF0 ; else { 1CF0 ; puts("kernel: unimplimented"); 1CF0 CC1DB8 ldd #L41 1CF3 162A16 jsr _puts 1CF6 ; return -1; 1CF6 CCFFFF ldd #-1 1CF9 2059 bra L13 1CFB X4: 1CFB ; } 1CFB ; break; 1CFB L42: 1CFB ; case finished: 1CFB ; if (state == finished) 1CFB E607 ldab 7,x 1CFD C104 cmpb #4 1CFF 2605 bne L43 1D01 ; return 0; 1D01 CC0000 ldd #0 1D04 204E bra L13 1D06 L43: 1D06 ; if (state == idle) { 1D06 E707 tst 7,x 1D08 2616 bne L45 1D0A ; task[id].state = idle; 1D0A E603 ldab 3,x 1D0C 87 clra 1D0D B7C6 xgdy 1D0F CC0009 ldd #9 1D12 1813 emuls 1D14 C30271 addd #_task+1 1D17 B7C6 xgdy 1D19 6940 clr 0,y 1D1B ; return 0; 1D1B CC0000 ldd #0 1D1E 2034 bra L13 1D20 L45: 1D20 ; } 1D20 ; else if (state == pending) { 1D20 E607 ldab 7,x 1D22 C101 cmpb #1 1D24 2618 bne L48 1D26 ; task[id].state = pending; 1D26 E603 ldab 3,x 1D28 87 clra 1D29 B7C6 xgdy 1D2B CC0009 ldd #9 1D2E 1813 emuls 1D30 C30271 addd #_task+1 1D33 B7C6 xgdy 1D35 C601 ldab #1 1D37 6B40 stab 0,y 1D39 ; return 0; 1D39 CC0000 ldd #0 1D3C 2016 bra L13 1D3E L48: 1D3E ; } 1D3E ; else { 1D3E ; puts(error_msg); 1D3E 19E1DD leay -35,x 1D41 B7C6 xgdy 1D43 162A16 jsr _puts 1D46 ; return -1; 1D46 CCFFFF ldd #-1 1D49 2009 bra L13 1D4B X5: 1D4B ; } 1D4B ; break; 1D4B L22: 1D4B ; default: 1D4B ; puts("kernel: unimplimented"); 1D4B CC1DB8 ldd #L41 1D4E 162A16 jsr _puts 1D51 ; return -1; 1D51 CCFFFF ldd #-1 1D54 ; break; 1D54 L13: 1D54 B757 tfr x,s 1D56 30 pulx 1D57 1B82 leas 2,sp 1D59 .dbline 0 ; func end 1D59 3D rts 1D5A ; priority -> 7,x 1D5A ; id -> 3,x 1D5A _set_task_priority:: 1D5A 3B pshd 1D5B 34 pshx 1D5C B775 tfr s,x 1D5E ; } 1D5E ; 1D5E ; 1D5E ; //INTR_ON(); 1D5E ; //return -1; 1D5E ; } 1D5E ; 1D5E ; 1D5E ; 1D5E ; void set_task_priority(unsigned char id, unsigned char priority) { 1D5E ; 1D5E ; if (priority == 0) priority = 1; 1D5E E707 tst 7,x 1D60 2604 bne L52 1D62 C601 ldab #1 1D64 6B07 stab 7,x 1D66 L52: 1D66 ; if (id > (numtasks-1)) 1D66 E603 ldab 3,x 1D68 C102 cmpb #2 1D6A 2308 bls L54 1D6C ; puts("kernel: illegal task id"); 1D6C CC1DCE ldd #L7 1D6F 162A16 jsr _puts 1D72 2025 bra L55 1D74 L54: 1D74 ; else if ((priority > 255) || (priority < 0)) 1D74 E607 ldab 7,x 1D76 C1FF cmpb #255 1D78 2204 bhi L58 1D7A E707 tst 7,x 1D7C 2408 bhs L56 1D7E L58: 1D7E ; puts("kernel: illegal priority"); 1D7E CC1D9F ldd #L59 1D81 162A16 jsr _puts 1D84 2013 bra L57 1D86 L56: 1D86 ; else 1D86 ; task[id].priority=priority; 1D86 E603 ldab 3,x 1D88 87 clra 1D89 B7C6 xgdy 1D8B CC0009 ldd #9 1D8E 1813 emuls 1D90 C30272 addd #_task+2 1D93 B7C6 xgdy 1D95 E607 ldab 7,x 1D97 6B40 stab 0,y 1D99 L57: 1D99 L55: 1D99 ; } 1D99 L51: 1D99 B757 tfr x,s 1D9B 30 pulx 1D9C 1B82 leas 2,sp 1D9E .dbline 0 ; func end 1D9E 3D rts .area bss 0260 _resource:: 0260 .blkb 16 0270 _task:: 0270 .blkb 27 028B _system_tick:: 028B .blkb 4 028F _current:: 028F .blkb 2 .area text --- 0252 L59: --- 0252 6B65726E656C3A20696C6C6567616C20 .byte 'k,'e,'r,'n,'e,'l,58,32,'i,'l,'l,'e,'g,'a,'l,32 --- 0262 7072696F7269747900 .byte 'p,'r,'i,'o,'r,'i,'t,'y,0 --- 026B L41: --- 026B 6B65726E656C3A20756E696D706C696D .byte 'k,'e,'r,'n,'e,'l,58,32,'u,'n,'i,'m,'p,'l,'i,'m --- 027B 656E74656400 .byte 'e,'n,'t,'e,'d,0 --- 0281 L7: --- 0281 6B65726E656C3A20696C6C6567616C20 .byte 'k,'e,'r,'n,'e,'l,58,32,'i,'l,'l,'e,'g,'a,'l,32 --- 0291 7461736B20696400 .byte 't,'a,'s,'k,32,'i,'d,0 .module semlib.c .area text ; resource_id -> 3,x 1DE6 _sem_get:: 1DE6 3B pshd 1DE7 34 pshx 1DE8 B775 tfr s,x 1DEA ; // semlib.c 1DEA ; #include <912d60.h> 1DEA ; #include "kernel.h" 1DEA ; #include "semlib.h" 1DEA ; 1DEA ; 1DEA ; 1DEA ; 1DEA ; // GLOBAL VARIABLES 1DEA ; extern unsigned int current; // current task id number 1DEA ; 1DEA ; // task control block 1DEA ; extern struct task_block { 1DEA ; unsigned char id; // ID of task 1DEA ; enum task_state state; // State 1DEA ; unsigned char priority; // Priority 1DEA ; unsigned char *heap_ptr; // heap addr while not current task 1DEA ; unsigned int heap_size; // heap size 1DEA ; unsigned char *frame_ptr; // CCR pointer 1DEA ; }; 1DEA ; 1DEA ; 1DEA ; // resource control block 1DEA ; extern struct resource_block { 1DEA ; unsigned char id; // ID of resource 1DEA ; enum resource_state state; // State (busy, free...) 1DEA ; unsigned char user; // Current resource user/owner 1DEA ; signed char queue[4]; // Tasks waiting on resource 1DEA ; unsigned char queue_pos; // Next free spot in queue 1DEA ; }; 1DEA ; 1DEA ; 1DEA ; extern struct task_block task[numtasks]; 1DEA ; extern struct resource_block resource[numresources]; 1DEA ; 1DEA ; 1DEA ; 1DEA ; 1DEA ; 1DEA ; 1DEA ; 1DEA ; signed char sem_get(char resource_id) { 1DEA ; 1DEA ; /* Gives a resource to a requesting task. 1DEA ; returns the resource id number (0,1,2,...) if free. 1DEA ; otherwise returns -1. 1DEA ; 1DEA ; At this point, semaphores are a procedural control 1DEA ; that the tasks have to follow to avoid resource contention. 1DEA ; There is no kernel control over resources yet. */ 1DEA ; 1DEA ; 1DEA ; // critical section 1DEA ; INTR_OFF(); 1DEA 1410 sei 1DEC 1DEC ; 1DEC ; 1DEC ; // GET SEMAPHORE 1DEC ; // give semaphore to task 1DEC ; if (resource[resource_id].state == notbusy) { 1DEC E603 ldab 3,x 1DEE 87 clra 1DEF 59 lsld 1DF0 59 lsld 1DF1 59 lsld 1DF2 C30261 addd #_resource+1 1DF5 B7C6 xgdy 1DF7 E740 tst 0,y 1DF9 2649 bne L4 1DFB ; resource[resource_id].state = busy; 1DFB E603 ldab 3,x 1DFD 87 clra 1DFE 59 lsld 1DFF 59 lsld 1E00 59 lsld 1E01 C30261 addd #_resource+1 1E04 B7C6 xgdy 1E06 C601 ldab #1 1E08 6B40 stab 0,y 1E0A ; resource[resource_id].user = current; 1E0A E603 ldab 3,x 1E0C 87 clra 1E0D 59 lsld 1E0E 59 lsld 1E0F 59 lsld 1E10 C30262 addd #_resource+2 1E13 B7C6 xgdy 1E15 FC028F ldd _current 1E18 6B40 stab 0,y 1E1A ; if (task[current].state == waiting) 1E1A CC0009 ldd #9 1E1D FD028F ldy _current 1E20 13 emul 1E21 C30271 addd #_task+1 1E24 B7C6 xgdy 1E26 E640 ldab 0,y 1E28 C103 cmpb #3 1E2A 2610 bne L9 1E2C ; task[current].state = running; 1E2C CC0009 ldd #9 1E2F FD028F ldy _current 1E32 13 emul 1E33 C30271 addd #_task+1 1E36 B7C6 xgdy 1E38 C602 ldab #2 1E3A 6B40 stab 0,y 1E3C L9: 1E3C ; INTR_ON(); 1E3C 10EF cli 1E3E 1E3E ; return resource_id; 1E3E E603 ldab 3,x 1E40 B714 tfr b,d 1E42 2015 bra L3 1E44 L4: 1E44 ; } 1E44 ; // busy 1E44 ; else { 1E44 ; task[current].state = waiting; 1E44 CC0009 ldd #9 1E47 FD028F ldy _current 1E4A 13 emul 1E4B C30271 addd #_task+1 1E4E B7C6 xgdy 1E50 C603 ldab #3 1E52 6B40 stab 0,y 1E54 ; INTR_ON(); 1E54 10EF cli 1E56 1E56 ; return -1; 1E56 CCFFFF ldd #-1 1E59 L3: 1E59 B757 tfr x,s 1E5B 30 pulx 1E5C 1B82 leas 2,sp 1E5E .dbline 0 ; func end 1E5E 3D rts 1E5F ; resource_id -> 3,x 1E5F _sem_give:: 1E5F 3B pshd 1E60 34 pshx 1E61 B775 tfr s,x 1E63 ; } 1E63 ; } 1E63 ; 1E63 ; 1E63 ; 1E63 ; 1E63 ; void sem_give(char resource_id) { 1E63 ; 1E63 ; /* Takes a resource back from a task. 1E63 ; will (eventually) pass a message to a waiting task. 1E63 ; 1E63 ; At this point, semaphores are a procedural control 1E63 ; that the tasks have to follow to avoid resource contention. 1E63 ; There is no kernel control over resources yet. */ 1E63 ; 1E63 ; 1E63 ; // critical section 1E63 ; INTR_OFF(); 1E63 1410 sei 1E65 1E65 ; 1E65 ; 1E65 ; // return the resource 1E65 ; resource[resource_id].state = notbusy; 1E65 E603 ldab 3,x 1E67 87 clra 1E68 59 lsld 1E69 59 lsld 1E6A 59 lsld 1E6B C30261 addd #_resource+1 1E6E B7C6 xgdy 1E70 6940 clr 0,y 1E72 ; 1E72 ; INTR_ON(); 1E72 10EF cli 1E74 1E74 ; 1E74 ; } 1E74 L14: 1E74 B757 tfr x,s 1E76 30 pulx 1E77 1B82 leas 2,sp 1E79 .dbline 0 ; func end 1E79 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 1264 .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