	.module kernel.c
	.area data
_error_msg::
	.blkb 23
	.area idata
	.byte 'u,'n,'i,'m,'p,'l,'i,'m,'e,'n,'t,'e,'d,32,'f,'u
	.byte 'n,'c,'t,'i,'o,'n,0
	.area data
	.blkb 2
	.area idata
	.byte 0,0
	.area data
	.blkb 13
	.area idata
	.byte 's,'y,'n,'t,'a,'x,32,'e,'r,'r,'o,'r,0
	.area data
	.blkb 12
	.area idata
	.word 0,0,0,0,0
	.byte 0,0
	.area data
	.blkb 16
	.area idata
	.byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'I,'D,0
	.area data
	.blkb 9
	.area idata
	.byte 0,0,0,0,0,0,0,0,0
	.area data
	.blkb 19
	.area idata
	.byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'s,'t,'a
	.byte 't,'e,0
	.area data
	.blkb 6
	.area idata
	.byte 0,0,0,0,0,0
	.area data
	.blkb 22
	.area idata
	.byte 'i,'l,'l,'e,'g,'a,'l,32,'t,'a,'s,'k,32,'p,'r,'i
	.byte 'o,'r,'i,'t,'y,0
	.area data
	.blkb 3
	.area idata
	.byte 0,0,0
	.area data
	.blkb 14
	.area idata
	.byte 'o,'u,'t,32,'o,'f,32,'m,'e,'m,'o,'r,'y,0
	.area data
	.blkb 11
	.area idata
	.word 0,0,0,0,0
	.byte 0
	.area data
_error_src::
	.blkb 14
	.area idata
	.byte 'k,'e,'r,'n,'e,'l,32,'e,'r,'r,'o,'r,58,0
	.area data
	.blkb 4
	.area idata
	.byte 0,0,0,0
	.area data
	.blkb 16
	.area idata
	.byte 'k,'e,'r,'n,'e,'l,46,'c,32,'e,'r,'r,'o,'r,58,0
	.area data
	.blkb 2
	.area idata
	.byte 0,0
	.area data
	.blkb 18
	.area idata
	.byte 'k,'e,'r,'n,'e,'l,32,'R,'T,'I,32,'e,'r,'r,'o,'r
	.byte 58,0
	.area data
	.blkb 13
	.area idata
	.byte 's,'h,'e,'l,'l,32,'e,'r,'r,'o,'r,58,0
	.area data
	.blkb 5
	.area idata
	.byte 0,0,0,0,0
	.area data
	.area text
_get_task_id::
; //kernel.c
; 
; #include <912d60.h>
; #include <stdio.h>
; #include "kernel.h"
; 
; 
; // GLOBAL VARIABLE DEFINITIONS
; unsigned int current;		   	 		    // current task id number
; unsigned long int system_tick;
; 
; 
; // task control block
; typedef 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
; typedef 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
; 		};
; 
; 		
; struct task_block task[numtasks];
; struct resource_block resource[numresources];
; 
; 
; // error massages
; char error_msg[6][25] = {"unimplimented function",	// error 0 
; 	 				  	"syntax error",				// error 1 
; 						"illegal task ID",			// error 2 
; 						"illegal task state",		// error 3 
; 						"illegal task priority",	// error 4 
; 						"out of memory"				// error 5 
; 						};
; char error_src[4][18] = {"kernel error:",			// source 0
; 	 				  	"kernel.c error:",			// source 1
; 						"kernel RTI error:",		// source 2
; 						"shell error:"				// source 3
; 						};
; 
; 
; 
; // FUNCTIONS
; 
; char get_task_id() { 
; 		 return task[current].id; 
	ldd #24
	ldy _current
	emul
	addd #_task
	xgdy
	ldab 0,y
	clra
L3:
	.dbline 0 ; func end
	rts
;             id -> 3,x
_get_task_state::
	pshd
	pshx
	tfr s,x
; }
; 
; 
; 
; int get_task_state(unsigned char id) { 
; 
; 		 if (id < numtasks) {
	ldab 3,x
	cmpb #3
	bhs L5
; 		 	return task[id].state;
	ldab 3,x
	clra
	xgdy
	ldd #24
	emuls
	addd #_task+1
	xgdy
	ldab 0,y
	clra
	bra L4
L5:
; 			}
; 		 else {
; 		 	  #ifdef KERNEL_ERROR_MSG
; 	 	 	  puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 			  #endif
; 			return -1;
	ldd #-1
L4:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
;             id -> 3,x
_get_task_messages::
	pshd
	pshx
	tfr s,x
; 		 	}
; 		  
; }
; 
; 
; 
; int get_task_messages(unsigned char id) {
; 
; 	if (id < numtasks) {
	ldab 3,x
	cmpb #3
	bhs L11
; 	   return task[id].message;
	ldab 3,x
	clra
	xgdy
	ldd #24
	emuls
	addd #_task+9
	xgdy
	ldab 0,y
	clra
	bra L10
L11:
; 	   }
; 	else {
; 		 #ifdef KERNEL_ERROR_MSG
; 	 	 puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 		 #endif
; 		 return -1;
	ldd #-1
L10:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
;             id -> 3,x
_get_task_priority::
	pshd
	pshx
	tfr s,x
; 		 }
; 
; }
; 
; 
; 
; int get_task_priority(unsigned char id) { 
; 
; 		 INTR_OFF();
		sei

; 		 
; 		 if (id < numtasks) {
	ldab 3,x
	cmpb #3
	bhs L17
; 		 	INTR_ON();
		cli

; 		 	return task[id].priority;
	ldab 3,x
	clra
	xgdy
	ldd #24
	emuls
	addd #_task+2
	xgdy
	ldab 0,y
	clra
	bra L16
L17:
; 			}
; 		 else {
; 	 	 	#ifdef KERNEL_ERROR_MSG
; 	 	 	puts(error_src[1]); puts(error_msg[4]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+100
	jsr _puts
; 			#endif
; 			INTR_ON();
		cli

; 			return -1;
	ldd #-1
L16:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
;          ?temp -> -2,x
;          state -> 7,x
;             id -> 3,x
_set_task_state::
	pshd
	pshx
	tfr s,x
	leas -2,sp
; 		 	}
; 
; }
; 
; 
; 
; int set_task_state(unsigned char id, unsigned char state) {
; 	
; 	
; 	INTR_OFF();
		sei

; 	
; 	
; 	// check id validity
; 	if (id < numtasks) {
	ldab 3,x
	cmpb #3
	lbhs L23
; 
; 	   // check state validity
; 	   if ((state == running) || 
	ldab 7,x
	cmpb #2
	beq L28
	ldab 7,x
	cmpb #3
	beq L28
	ldab 7,x
	cmpb #4
	bls L25
L28:
; 	   	  (state == waiting)  ||
; 	   	  (state > finished)) { 
; 	      		 #ifdef KERNEL_ERROR_MSG
; 	 	 	  	 puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 			  	 #endif
; 				 INTR_ON();
		cli

; 	 	  		 return -1;
	ldd #-1
	lbra L22
L25:
	ldab 3,x
	clra
	xgdy
	ldd #24
	emuls
	addd #_task+1
	xgdy
	ldab 0,y
	clra
	std -2,x
	beq L35
	ldd -2,x
	cpd #1
	lbeq L46
	ldd -2,x
	cpd #4
	lbeq L57
	lbra L31
X0:
; 	   			 }
; 	 
; 	   		switch (task[id].state) {
L35:
; 		   	  	   case idle:
; 				   		if (state == idle) {	   // no change
	tst 7,x
	bne L36
; 						   INTR_ON();
		cli

; 				 		   return 0;
	ldd #0
	lbra L22
L36:
; 						   }
; 				 		else if (state == pending) {
	ldab 7,x
	cmpb #1
	bne L38
; 				 		   // pass msg to task[id].msgbox;
; 						   #ifdef KERNEL_ERROR_MSG
; 	 	 	  			   puts(error_src[1]); puts(error_msg[0]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg
	jsr _puts
; 			  			   #endif
; 						   INTR_ON();
		cli

; 						   return -1;
	ldd #-1
	lbra L22
L38:
; 				 		   }
; 						else if (state == finished) {
	ldab 7,x
	cmpb #4
	bne L41
; 							 // pass msg to task[id].msgbox;
; 						     #ifdef KERNEL_ERROR_MSG
; 	 	 	  			     puts(error_src[1]); puts(error_msg[0]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg
	jsr _puts
; 			  			     #endif
; 							 INTR_ON();
		cli

; 						     return -1; 
	ldd #-1
	lbra L22
L41:
; 						    }
; 				 		else {	  // nothing else is legalox;
; 						   	 #ifdef KERNEL_ERROR_MSG
; 	 	 	  			   	 puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 			  			   	 #endif
; 							 INTR_ON();
		cli

; 					  		 return -1;
	ldd #-1
	lbra L22
X1:
; 				 			 }
; 				 		break;
L46:
; 		   			case pending:
; 						 if (state == pending) {	// no change
	ldab 7,x
	cmpb #1
	bne L47
; 						 	INTR_ON();
		cli

; 				 		 	return 0;
	ldd #0
	lbra L22
L47:
; 							}
; 						 else if (state == idle) {
	tst 7,x
	bne L49
; 				   		 	  // pass msg to task[id].msgbox;
; 						   	  #ifdef KERNEL_ERROR_MSG
; 	 	 	  			   	  puts(error_src[1]); puts(error_msg[0]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg
	jsr _puts
; 			  			   	  #endif
; 							  INTR_ON();
		cli

; 					  		  return -1;
	ldd #-1
	lbra L22
L49:
; 							  }
; 						 else if (state == finished) {
	ldab 7,x
	cmpb #4
	bne L52
; 				   		 	  // pass msg to task[id].msgbox;
; 						   	  #ifdef KERNEL_ERROR_MSG
; 	 	 	  			   	  puts(error_src[1]); puts(error_msg[0]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg
	jsr _puts
; 			  			   	  #endif
; 							  INTR_ON();
		cli

; 					  		  return -1;
	ldd #-1
	lbra L22
L52:
; 						 	  }	
; 						 else {
; 				   		 	  #ifdef KERNEL_ERROR_MSG
; 							  puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 							  #endif
; 							  INTR_ON();
		cli

; 							  return -1;
	ldd #-1
	lbra L22
X2:
; 						 	  }
; 						 break;
L57:
; 
; 		   			case finished:
; 		   				 if (state == finished)	{ 	// no change
	ldab 7,x
	cmpb #4
	bne L58
; 				   		 	INTR_ON();
		cli

; 							return 0;
	ldd #0
	lbra L22
L58:
; 							}
; 						 else if (state == pending) {
	ldab 7,x
	cmpb #1
	bne L60
; 				   		 	  // pass msg to task[id].msgbox;
; 						   	  #ifdef KERNEL_ERROR_MSG
; 	 	 	  			   	  puts(error_src[1]); puts(error_msg[0]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg
	jsr _puts
; 			  			   	  #endif
; 							  INTR_ON();
		cli

; 					  		  return -1;
	ldd #-1
	bra L22
L60:
; 							  }
; 						 else {
; 					 	 	  #ifdef KERNEL_ERROR_MSG
; 							  puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 							  #endif
; 							  INTR_ON();
		cli

; 							  return -1;
	ldd #-1
	bra L22
X3:
; 							  }
; 						 break;
L31:
; 		   			default:
; 		   		   			#ifdef KERNEL_ERROR_MSG
; 							puts(error_src[1]); puts(error_msg[3]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+75
	jsr _puts
; 							#endif
; 							INTR_ON();
		cli

; 							return -1;
	ldd #-1
	bra L22
X4:
; 				   			break;
L23:
; 							
; 	 				}	// end switch (task[id].state)
; 					
; 	 		}		// if 
; 			
; 		   else {
; 		   		#ifdef KERNEL_ERROR_MSG
; 				puts(error_src[1]); puts(error_msg[2]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+50
	jsr _puts
; 				#endif
; 				INTR_ON();
		cli

; 				return -1;
	ldd #-1
	bra L22
X5:
; 				}
; 
; 	 INTR_ON();
		cli

; 
; }
L22:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
;       priority -> 7,x
;             id -> 3,x
_set_task_priority::
	pshd
	pshx
	tfr s,x
; 
; 
; 
; int set_task_priority(unsigned char id, unsigned char priority) {
; 
; 	 if (priority == 0) 			 // priority 0 is reserved for the shell
	tst 7,x
	bne L70
; 	 	priority = 1;
	ldab #1
	stab 7,x
L70:
; 		
; 	 if (id >= (numtasks)) {
	ldab 3,x
	cmpb #3
	blo L72
; 	 	#ifdef KERNEL_ERROR_MSG
; 		puts(error_src[1]); puts(error_msg[4]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+100
	jsr _puts
; 		#endif
; 		return -1;
	ldd #-1
	bra L69
L72:
	ldab 7,x
	cmpb #255
	bhi L78
	tst 7,x
	bhs L76
L78:
; 		}
; 	 else if ((priority > 255) || (priority < 0)) {
; 	 	#ifdef KERNEL_ERROR_MSG
; 		puts(error_src[1]); puts(error_msg[4]);
	ldd #_error_src+18
	jsr _puts
	ldd #_error_msg+100
	jsr _puts
; 		#endif
; 		return -1;
	ldd #-1
	bra L69
L76:
; 		}
; 	 else {
; 	 	 task[id].priority=priority;
	ldab 3,x
	clra
	xgdy
	ldd #24
	emuls
	addd #_task+2
	xgdy
	ldab 7,x
	stab 0,y
; 		 return 0;
	ldd #0
L69:
	tfr x,s
	pulx
	leas 2,sp
	.dbline 0 ; func end
	rts
	.area bss
_resource::
	.blkb 14
_task::
	.blkb 72
_system_tick::
	.blkb 4
_current::
	.blkb 2

