.module semlib.c .area text ; ?temp -> -6,x ; ?temp -> -4,x ; ?temp -> -2,x ; rid -> 3,x 0000 _sem_get:: 0000 3B pshd 0001 34 pshx 0002 B775 tfr s,x 0004 1B98 leas -8,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 ; void (*address)(); // Address of the task 0006 ; unsigned char id; // ID of task 0006 ; char name[9]; // Name 0006 ; enum task_state state; // State 0006 ; unsigned char priority; // Priority 0006 ; unsigned 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[2]; // 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 ; char name[5]; // Name of resource 0006 ; enum resource_state state; // State (busy, free...) 0006 ; unsigned char owner; // Current resource owner 0006 ; signed char queue[3]; // Tasks waiting on resource 0006 ; unsigned char queue_ptr; // Next free spot in queue 0006 ; }; 0006 ; 0006 ; 0006 ; extern struct task_block *task[NUMTASKS]; 0006 ; extern struct resource_block resource[NUMRESOURCES]; 0006 ; 0006 ; extern char error_msg[9][25]; 0006 ; extern char error_src[5][18]; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; 0006 ; int sem_get(char rid) { 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 ; 0008 ; // GET SEMAPHORE 0008 ; // give semaphore to task 0008 ; if (resource[rid].state == NOTBUSY) { 0008 E603 ldab 3,x 000A 87 clra 000B B7C6 xgdy 000D CC000C ldd #12 0010 1813 emuls 0012 C30006 addd #_resource+6 0015 B7C6 xgdy 0017 E740 tst 0,y 0019 2630 bne L4 001B ; resource[rid].state = BUSY; 001B E603 ldab 3,x 001D 87 clra 001E B7C6 xgdy 0020 CC000C ldd #12 0023 1813 emuls 0025 C30006 addd #_resource+6 0028 B7C6 xgdy 002A C601 ldab #1 002C 6B40 stab 0,y 002E ; resource[rid].owner = current; 002E E603 ldab 3,x 0030 87 clra 0031 B7C6 xgdy 0033 CC000C ldd #12 0036 1813 emuls 0038 C30007 addd #_resource+7 003B B7C6 xgdy 003D FC0000 ldd _current 0040 6B40 stab 0,y 0042 ; 0042 ; INTR_ON(); 0042 10EF cli 0044 0044 ; return rid; 0044 E603 ldab 3,x 0046 87 clra 0047 18200084 lbra L3 004B L4: 004B ; } 004B ; 004B ; // resource is taken/busy so make task wait 004B ; else { 004B ; task[current]->message |= STATE_FLAG; 004B FC0000 ldd _current 004E 59 lsld 004F C30000 addd #_task 0052 B7C6 xgdy 0054 EC40 ldd 0,y 0056 C30012 addd #18 0059 6C1E std -2,x 005B B746 tfr d,y 005D 35 pshy ; spill 005E ED1E ldy -2,x 0060 31 puly ; reload 0061 0C4001 bset 0,y,#1 0064 ; task[current]->message_data[STATE_BOX] = WAITING; 0064 FC0000 ldd _current 0067 59 lsld 0068 C30000 addd #_task 006B B7C6 xgdy 006D ED40 ldy 0,y 006F C603 ldab #3 0071 6BE813 stab 19,y 0074 ; 0074 ; // put waiting task into the resources queue if there's space 0074 ; if (resource[rid].queue_ptr < 3) { 0074 E603 ldab 3,x 0076 87 clra 0077 B7C6 xgdy 0079 CC000C ldd #12 007C 1813 emuls 007E C3000B addd #_resource+11 0081 B7C6 xgdy 0083 E640 ldab 0,y 0085 C103 cmpb #3 0087 2441 bhs L9 0089 ; resource[rid].queue[resource[rid].queue_ptr] = current; 0089 E603 ldab 3,x 008B 87 clra 008C B7C6 xgdy 008E CC000C ldd #12 0091 1813 emuls 0093 6C1C std -4,x 0095 C3000B addd #_resource+11 0098 B7C6 xgdy 009A E640 ldab 0,y 009C 87 clra 009D 3B pshd ; spill 009E EC1C ldd -4,x 00A0 C30008 addd #_resource+8 00A3 6C18 std -8,x 00A5 3A puld ; reload 00A6 E318 addd -8,x 00A8 B7C6 xgdy 00AA F60001 ldab _current+1 00AD 6B40 stab 0,y 00AF ; resource[rid].queue_ptr++; 00AF E603 ldab 3,x 00B1 87 clra 00B2 B7C6 xgdy 00B4 CC000C ldd #12 00B7 1813 emuls 00B9 C3000B addd #_resource+11 00BC 6C1A std -6,x 00BE B746 tfr d,y 00C0 E640 ldab 0,y 00C2 87 clra 00C3 C30001 addd #1 00C6 ED1A ldy -6,x 00C8 6B40 stab 0,y 00CA ; } 00CA L9: 00CA ; 00CA ; INTR_ON(); 00CA 10EF cli 00CC 00CC ; return -1; 00CC CCFFFF ldd #-1 00CF L3: 00CF B757 tfr x,s 00D1 30 pulx 00D2 1B82 leas 2,sp 00D4 .dbline 0 ; func end 00D4 3D rts 00D5 ; rid -> 3,x 00D5 _sem_give:: 00D5 3B pshd 00D6 34 pshx 00D7 B775 tfr s,x 00D9 ; } 00D9 ; 00D9 ; } 00D9 ; 00D9 ; 00D9 ; 00D9 ; 00D9 ; int sem_give(char rid) { 00D9 ; 00D9 ; /* Takes a resource back from a task. 00D9 ; will (eventually) pass a message to a waiting task. 00D9 ; 00D9 ; At this point, semaphores are a procedural control 00D9 ; that the tasks have to follow to avoid resource contention. 00D9 ; There is no kernel control over resources yet. */ 00D9 ; 00D9 ; 00D9 ; // critical section 00D9 ; INTR_OFF(); 00D9 1410 sei 00DB 00DB ; 00DB ; 00DB ; // return the resource 00DB ; resource[rid].state = NOTBUSY; 00DB E603 ldab 3,x 00DD 87 clra 00DE B7C6 xgdy 00E0 CC000C ldd #12 00E3 1813 emuls 00E5 C30006 addd #_resource+6 00E8 B7C6 xgdy 00EA 6940 clr 0,y 00EC ; //resource[rid].owner = NULL; 00EC ; 00EC ; INTR_ON(); 00EC 10EF cli 00EE 00EE ; 00EE ; return 0; 00EE CC0000 ldd #0 00F1 L15: 00F1 B757 tfr x,s 00F3 30 pulx 00F4 1B82 leas 2,sp 00F6 .dbline 0 ; func end 00F6 3D rts