	.module semlib.c
	.area text
;          ?temp -> -6,x
;          ?temp -> -4,x
;          ?temp -> -2,x
;            rid -> 3,x
_sem_get::
	pshd
	pshx
	tfr s,x
	leas -8,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 {
; 	 	void (*address)();			   		// Address of the task
; 	 	unsigned char id; 			  		// ID of task
; 		char name[9];	  					// Name
; 		enum task_state state;				// State
; 		unsigned char priority;				// Priority
; 		unsigned 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[2];		// 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
; 		char name[5];	  					// Name of resource
; 		enum resource_state state;			// State (busy, free...)
; 		unsigned char owner;				// Current resource owner
; 		signed char queue[3];				// Tasks waiting on resource
; 		unsigned char queue_ptr;			// Next free spot in queue
; 		};
; 		
; 
; extern struct task_block *task[NUMTASKS];
; extern struct resource_block resource[NUMRESOURCES];
; 
; extern char error_msg[9][25];
; extern char error_src[5][18];
; 
; 
; 
; 
; 
; 
; 
; int sem_get(char rid) {
; 
; 	 /* 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[rid].state == NOTBUSY) {
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	addd #_resource+6
	xgdy
	tst 0,y
	bne L4
; 	 	resource[rid].state = BUSY;
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	addd #_resource+6
	xgdy
	ldab #1
	stab 0,y
; 		resource[rid].owner = current;
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	addd #_resource+7
	xgdy
	ldd _current
	stab 0,y
; 		
; 		INTR_ON();
		cli

; 		return rid;
	ldab 3,x
	clra
	lbra L3
L4:
; 	 	}
; 	 
; 	 // resource is taken/busy so make task wait
; 	 else {
; 		  task[current]->message |= STATE_FLAG;
	ldd _current
	lsld
	addd #_task
	xgdy
	ldd 0,y
	addd #18
	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 _current
	lsld
	addd #_task
	xgdy
	ldy 0,y
	ldab #3
	stab 19,y
; 		
; 		  // put waiting task into the resources queue if there's space
; 		  if (resource[rid].queue_ptr < 3) {
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	addd #_resource+11
	xgdy
	ldab 0,y
	cmpb #3
	bhs L9
; 		   	 resource[rid].queue[resource[rid].queue_ptr] = current;
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	std -4,x
	addd #_resource+11
	xgdy
	ldab 0,y
	clra
	pshd ; spill
	ldd -4,x
	addd #_resource+8
	std -8,x
	puld ; reload
	addd -8,x
	xgdy
	ldab _current+1
	stab 0,y
; 		   	 resource[rid].queue_ptr++;
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	addd #_resource+11
	std -6,x
	tfr d,y
	ldab 0,y
	clra
	addd #1
	ldy -6,x
	stab 0,y
; 		   	 }
L9:
; 		
; 		  INTR_ON();
		cli

; 		  return -1;
	ldd #-1
L3:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
;            rid -> 3,x
_sem_give::
	pshd
	pshx
	tfr s,x
; 	 	  } 	 
; 		
; }
; 
; 
; 
; 
; int sem_give(char rid) {
; 
; 	/* 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[rid].state = NOTBUSY;
	ldab 3,x
	clra
	xgdy
	ldd #12
	emuls
	addd #_resource+6
	xgdy
	clr 0,y
; 	//resource[rid].owner = NULL;
; 	
; 	INTR_ON();
		cli

; 	
; 	return 0;
	ldd #0
L15:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts

