.module semlib.c .area text ; ?temp -> -2,x ; ?temp -> -2,x ; resource_id -> 3,x 0000 _sem_get:: 0000 3B pshd 0001 34 pshx 0002 B775 tfr s,x 0004 1B9E leas -2,sp 0006 ; // semlib.c 0006 ; #include <912d60.h> 0006 ; #include "kernel.h" 0006 ; #include "semlib.h" 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; // GLOBAL VARIABLES 0006 ; extern unsigned int current; // current task id number 0006 ; 0006 ; // task control block 0006 ; extern struct task_block { 0006 ; unsigned char id; // ID of task 0006 ; enum task_state state; // State 0006 ; unsigned char priority; // Priority 0006 ; unsigned long int period_tick; // for determining if deadline is up 0006 ; unsigned int interrupt_msg_box; // flags for pending interrupts 0006 ; enum message_box message; // misc flags 0006 ; unsigned char message_data[8]; // data for misc_msg_box flags 0006 ; unsigned char *heap_ptr; // heap addr while not current task 0006 ; unsigned int heap_size; // heap size 0006 ; unsigned char *frame_ptr; // CCR pointer 0006 ; }; 0006 ; 0006 ; 0006 ; // resource control block 0006 ; extern struct resource_block { 0006 ; unsigned char id; // ID of resource 0006 ; enum resource_state state; // State (busy, free...) 0006 ; unsigned char user; // Current resource user/owner 0006 ; signed char queue[3]; // Tasks waiting on resource 0006 ; unsigned char queue_pos; // Next free spot in queue 0006 ; }; 0006 ; 0006 ; 0006 ; extern struct task_block task[numtasks]; 0006 ; extern struct resource_block resource[numresources]; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; int sem_get(char resource_id) { 0006 ; 0006 ; /* Gives a resource to a requesting task. 0006 ; returns the resource id number (0,1,2,...) if free. 0006 ; otherwise returns -1. 0006 ; 0006 ; At this point, semaphores are a procedural control 0006 ; that the tasks have to follow to avoid resource contention. 0006 ; There is no kernel control over resources yet. */ 0006 ; 0006 ; 0006 ; // critical section 0006 ; INTR_OFF(); 0006 1410 sei 0008 0008 ; 0008 ; 0008 ; // GET SEMAPHORE 0008 ; // give semaphore to task 0008 ; if (resource[resource_id].state == notbusy) { 0008 E603 ldab 3,x 000A 87 clra 000B B7C6 xgdy 000D CC0007 ldd #7 0010 1813 emuls 0012 C30001 addd #_resource+1 0015 B7C6 xgdy 0017 E740 tst 0,y 0019 18260065 lbne L4 001D ; resource[resource_id].state = busy; 001D E603 ldab 3,x 001F 87 clra 0020 B7C6 xgdy 0022 CC0007 ldd #7 0025 1813 emuls 0027 C30001 addd #_resource+1 002A B7C6 xgdy 002C C601 ldab #1 002E 6B40 stab 0,y 0030 ; resource[resource_id].user = current; 0030 E603 ldab 3,x 0032 87 clra 0033 B7C6 xgdy 0035 CC0007 ldd #7 0038 1813 emuls 003A C30002 addd #_resource+2 003D B7C6 xgdy 003F FC0000 ldd _current 0042 6B40 stab 0,y 0044 ; 0044 ; if (task[current].state == waiting) 0044 CC0018 ldd #24 0047 FD0000 ldy _current 004A 13 emul 004B C30001 addd #_task+1 004E B7C6 xgdy 0050 E640 ldab 0,y 0052 C103 cmpb #3 0054 2615 bne L9 0056 ; task[current].message |= state_flag; 0056 CC0018 ldd #24 0059 FD0000 ldy _current 005C 13 emul 005D C30009 addd #_task+9 0060 6C1E std -2,x 0062 B746 tfr d,y 0064 35 pshy ; spill 0065 ED1E ldy -2,x 0067 31 puly ; reload 0068 0C4001 bset 0,y,#1 006B L9: 006B ; task[current].message_data[state_box] = running; 006B CC0018 ldd #24 006E FD0000 ldy _current 0071 13 emul 0072 C3000A addd #_task+10 0075 B7C6 xgdy 0077 C602 ldab #2 0079 6B40 stab 0,y 007B ; 007B ; INTR_ON(); 007B 10EF cli 007D 007D ; return resource_id; 007D E603 ldab 3,x 007F 87 clra 0080 202A bra L3 0082 L4: 0082 ; } 0082 ; 0082 ; // resource is taken/busy 0082 ; else { 0082 ; task[current].message |= state_flag; 0082 CC0018 ldd #24 0085 FD0000 ldy _current 0088 13 emul 0089 C30009 addd #_task+9 008C 6C1E std -2,x 008E B746 tfr d,y 0090 35 pshy ; spill 0091 ED1E ldy -2,x 0093 31 puly ; reload 0094 0C4001 bset 0,y,#1 0097 ; task[current].message_data[state_box] = waiting; 0097 CC0018 ldd #24 009A FD0000 ldy _current 009D 13 emul 009E C3000A addd #_task+10 00A1 B7C6 xgdy 00A3 C603 ldab #3 00A5 6B40 stab 0,y 00A7 ; 00A7 ; INTR_ON(); 00A7 10EF cli 00A9 00A9 ; return -1; 00A9 CCFFFF ldd #-1 00AC L3: 00AC B757 tfr x,s 00AE 30 pulx 00AF 1B82 leas 2,sp 00B1 .dbline 0 ; func end 00B1 3D rts 00B2 ; resource_id -> 3,x 00B2 _sem_give:: 00B2 3B pshd 00B3 34 pshx 00B4 B775 tfr s,x 00B6 ; } 00B6 ; } 00B6 ; 00B6 ; 00B6 ; 00B6 ; 00B6 ; int sem_give(char resource_id) { 00B6 ; 00B6 ; /* Takes a resource back from a task. 00B6 ; will (eventually) pass a message to a waiting task. 00B6 ; 00B6 ; At this point, semaphores are a procedural control 00B6 ; that the tasks have to follow to avoid resource contention. 00B6 ; There is no kernel control over resources yet. */ 00B6 ; 00B6 ; 00B6 ; // critical section 00B6 ; INTR_OFF(); 00B6 1410 sei 00B8 00B8 ; 00B8 ; 00B8 ; // return the resource 00B8 ; resource[resource_id].state = notbusy; 00B8 E603 ldab 3,x 00BA 87 clra 00BB B7C6 xgdy 00BD CC0007 ldd #7 00C0 1813 emuls 00C2 C30001 addd #_resource+1 00C5 B7C6 xgdy 00C7 6940 clr 0,y 00C9 ; 00C9 ; INTR_ON(); 00C9 10EF cli 00CB 00CB ; 00CB ; return 0; 00CB CC0000 ldd #0 00CE L16: 00CE B757 tfr x,s 00D0 30 pulx 00D1 1B82 leas 2,sp 00D3 .dbline 0 ; func end 00D3 3D rts