	.module semlib.c
	.area text
;    resource_id -> 3,x
_sem_get::
	pshd
	pshx
	tfr s,x
; // 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 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[4];				// 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];
; 
; 
; 
; 
; 
; 
; 
; signed char 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
	lsld
	lsld
	lsld
	addd #_resource+1
	xgdy
	tst 0,y
	bne L4
; 	 	resource[resource_id].state = busy;
	ldab 3,x
	clra
	lsld
	lsld
	lsld
	addd #_resource+1
	xgdy
	ldab #1
	stab 0,y
; 		resource[resource_id].user = current;
	ldab 3,x
	clra
	lsld
	lsld
	lsld
	addd #_resource+2
	xgdy
	ldd _current
	stab 0,y
; 		if (task[current].state == waiting)
	ldd #9
	ldy _current
	emul
	addd #_task+1
	xgdy
	ldab 0,y
	cmpb #3
	bne L9
; 		   task[current].state = running;
	ldd #9
	ldy _current
	emul
	addd #_task+1
	xgdy
	ldab #2
	stab 0,y
L9:
; 		INTR_ON();
		cli

; 		return resource_id;
	ldab 3,x
	tfr b,d
	bra L3
L4:
; 	 }
; 	 // busy
; 	else {
; 		task[current].state = waiting;
	ldd #9
	ldy _current
	emul
	addd #_task+1
	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
; 	} 	 
; }
; 
; 
; 
; 
; void 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
	lsld
	lsld
	lsld
	addd #_resource+1
	xgdy
	clr 0,y
; 	
; 	INTR_ON();
		cli

; 	  
; }
L14:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts

