	.module semlib.c
	.area text
;          ?temp -> -2,x
;          ?temp -> -2,x
;    resource_id -> 3,x
_sem_get::
	pshd
	pshx
	tfr s,x
	leas -2,sp
; // semlib.c
; #include <912d60.h>
; #include "kernel.h"
; #include "semlib.h"
; 
; 
; 
; 
; // GLOBAL VARIABLES
; extern unsigned int current;		   	 	// current task id number
; 
; // task control block
; extern struct task_block {
; 	 	unsigned char id; 			  		// ID of task
; 		enum task_state state;				// State
; 		unsigned char priority;				// Priority
; 		unsigned long int period_tick;		// for determining if deadline is up
; 		unsigned int interrupt_msg_box;		// flags for pending interrupts
; 		enum message_box message;			// misc flags
; 		unsigned char message_data[8];		// data for misc_msg_box flags
; 	 	unsigned char *heap_ptr;			// heap addr while not current task
; 		unsigned int heap_size;				// heap size
; 		unsigned char *frame_ptr;			// CCR pointer
; 		};
; 
; 
; // resource control block
; extern struct resource_block {
; 		unsigned char id;	   				// ID of resource
; 		enum resource_state state;			// State (busy, free...)
; 		unsigned char user;					// Current resource user/owner
; 		signed char queue[3];				// Tasks waiting on resource
; 		unsigned char queue_pos;			// Next free spot in queue
; 		};
; 		
; 
; extern struct task_block task[numtasks];
; extern struct resource_block resource[numresources];
; 
; 
; 
; 
; 
; 
; 
; int sem_get(char resource_id) {
; 
; 	 /* Gives a resource to a requesting task.
; 	 	returns the resource id number (0,1,2,...) if free.
; 	 	otherwise returns -1.
; 		
; 		At this point, semaphores are a procedural control
; 		that the tasks have to follow to avoid resource contention.
; 		There is no kernel control over resources yet.  */
; 	 
; 	 
; 	 // critical section
; 	 INTR_OFF();
		sei

; 	 
; 	 
; 	 // GET SEMAPHORE
; 	 // give semaphore to task
; 	 if (resource[resource_id].state == notbusy) {
	ldab 3,x
	clra
	xgdy
	ldd #7
	emuls
	addd #_resource+1
	xgdy
	tst 0,y
	lbne L4
; 	 	resource[resource_id].state = busy;
	ldab 3,x
	clra
	xgdy
	ldd #7
	emuls
	addd #_resource+1
	xgdy
	ldab #1
	stab 0,y
; 		resource[resource_id].user = current;
	ldab 3,x
	clra
	xgdy
	ldd #7
	emuls
	addd #_resource+2
	xgdy
	ldd _current
	stab 0,y
; 		
; 		if (task[current].state == waiting)
	ldd #24
	ldy _current
	emul
	addd #_task+1
	xgdy
	ldab 0,y
	cmpb #3
	bne L9
; 		   task[current].message |= state_flag;
	ldd #24
	ldy _current
	emul
	addd #_task+9
	std -2,x
	tfr d,y
	pshy ; spill
	ldy -2,x
	puly ; reload
	bset 0,y,#1
L9:
; 		   task[current].message_data[state_box] = running;
	ldd #24
	ldy _current
	emul
	addd #_task+10
	xgdy
	ldab #2
	stab 0,y
; 		   
; 		INTR_ON();
		cli

; 		return resource_id;
	ldab 3,x
	clra
	bra L3
L4:
; 	 }
; 	 
; 	 // resource is taken/busy
; 	 else {
; 		task[current].message |= state_flag;
	ldd #24
	ldy _current
	emul
	addd #_task+9
	std -2,x
	tfr d,y
	pshy ; spill
	ldy -2,x
	puly ; reload
	bset 0,y,#1
; 		task[current].message_data[state_box] = waiting;
	ldd #24
	ldy _current
	emul
	addd #_task+10
	xgdy
	ldab #3
	stab 0,y
; 		
; 		INTR_ON();
		cli

; 		return -1;
	ldd #-1
L3:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
;    resource_id -> 3,x
_sem_give::
	pshd
	pshx
	tfr s,x
; 	 } 	 
; }
; 
; 
; 
; 
; int sem_give(char resource_id) {
; 
; 	/* Takes a resource back from a task.
; 	   will (eventually) pass a message to a waiting task.  
; 	   
; 	   	At this point, semaphores are a procedural control
; 		that the tasks have to follow to avoid resource contention.
; 		There is no kernel control over resources yet.  */
; 	
; 	
; 	// critical section
; 	INTR_OFF();
		sei

; 	
; 	
; 	// return the resource
; 	resource[resource_id].state = notbusy;
	ldab 3,x
	clra
	xgdy
	ldd #7
	emuls
	addd #_resource+1
	xgdy
	clr 0,y
; 	
; 	INTR_ON();
		cli

; 	
; 	return 0;
	ldd #0
L16:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts

