*
*	@(#)Kernoel.asm
*
*	C40 Mini Kernel for task reloading
*
*	Copyright 2001 Oliver Gerler
*

VERSION			.equ	0
REVISION		.equ	332

* ATTENTION: If ever add .data, change DOWNLOAD1 accordingly to protect the area.

				.bss	ivt, 040h		; interrupt vector table (has to be on 256-byte-boundary)
				.bss	statdata, 18
						; 00: size of packet to load (has to be initialised to size - 2 (one for DBU, one for CRC-value sent by host))
						; 01: load address
						; 02: run mode
						; 03: schedule flag
						; 04: time interval
						; 05: start mode
						; 06: start mode - temp (store from first to second download packet)
						; 07: start address
						; 08: CRC (host-> DSP, calc'd by DSP)
						; 09: external stack pointer, to retain for task and to restore on exit
						; 10: AR2
						; 11: R2
						; 12: R3
						; 13: RC
						; 14: RS
						; 15: RE
						; 16: return address for kernel in task mode
						; 17: packet size for forwarded download

				.bss	packetdown, 16	; packet from host to DSP
				.bss	packetup, 15	; packet from DSP to host (no word for CRC needed)

endbss			.bss	dummy,0	; MUST be last entry for .bss!!!


				.text
				.global	_main
				.global	statdata

_main:
* save registers used for parameters by C call (p.4-17, "Optimizing C Compiler")
* registers to save: AR2, R2, R3, RC, RS, RE
	LDP		@statdataaddr
	STI		AR2, @statdata+10
	STI		R2, @statdata+11
	STI		R3, @statdata+12
	STI		RC, @statdata+13
	STI		RS, @statdata+14
	STI		RE, @statdata+15
* init stackpointer
	LDHI	00030h, R0
	SUBI	R0, SP, R1
	BGE		nostackinit		; for values > 0x00300000
	LDI		SP, R1			; to set N and Z bits accordingly
	BN		nostackinit		; for values > (<, negative) 0x80000000 == <0
	LDI		R0, SP			; set stack to valid address, as it is not already set
nostackinit
	LDI		SP, AR0			; popping last value of old stack == return address
	LDI		*+AR0(0), AR0
	STI		AR0, @statdata+16	; return address for kernel in task mode
	STI		SP, @statdata+09	; save external stack pointer for task
	LDI		@stackaddr, SP		; use our own stackpointer

* Initialise registers
	LDHI	0010h,AR0	; CPCR3 address MSW - port 3 on TIM1 for host comm.
	OR		0070h,AR0	; CPCR3 address LSW

	LDI		0,R5		; init test value

	LDI		0, R0
	STI		R0, @statdata+0	; size of section to load
	STI		R0, @statdata+1	; load address
	LDI		1, R0
	STI		R0, @statdata+2	; run standalone
	LDI		2, R0
	STI		R0, @statdata+3	; schedule ok
	LDI		0, R0
	STI		R0, @statdata+4	; time interval for watchdog inactive
	LDHI	1, R0
	OR		1, R0
	STI		R0, @statdata+5	; start mode: download only
	STI		R0, @statdata+6	; start mode-temp: download only
	LDP		@taskaddr
	LDI		@taskaddr, R0
	LDP		@statdataaddr
	STI		R0, @statdata+7	; initial start address
	LDHI	0ffffh, R0
	OR		0ffffh, R0
	STI		R0, @statdata+8	; CRC32_XINIT
* disbaling interrupts by initializing ST
	LDI		0h, ST
* init timer (chap. 13.8)
	LDP		0100000h
	STI		0, @020h	; clear GO and HLD in control
	LDI		0201h, R0
	STI		R0, @020h	; configure control (with GO==HLD==0))
* init IVT and IVTP
	LDP		@statdataaddr
	LDI		@israddr, R0
	STI		R0, @ivt+2		; pointer to isr
	LDI		@ivtaddr, R0
	LDPE	R0, IVTP		; pointer to vector table

LOOP:
	LDP		@statdataaddr			; set Data Page Pointer to correct page
* test if input word present
	LDI		*+AR0(0),R1
	LSH		-9,R1
* if data present (R1 != 0): CTRLENV
	BNZ		CTRLENV		; bits 13-31 read as zero - otherwise: mask them out

* if no data present: call task to run on each cycle
	LDI		@statdata+5, R0	; load "startmode"
	LDHI	0001h, R1		; flag for "download only"
	OR		0001h, R1
	CMPI	R0, R1			; branch to TASKDEMON if "download only"
	BZ 		TASKDEMON		; decision for run mode: task/standalone

* fill registers with parameter for calling as C function and give stack to task
	LDI		@statdata+7, AR1	; start addr for task
	LDI		@statdata+9, SP
	LDI		@statdata+10, AR2
	LDI		@statdata+11, R2
	LDI		@statdata+12, R3
	LDI		@statdata+13, RC
	LDI		@statdata+14, RS
	LDI		@statdata+15, RE

* test if watchdog active
	LDI		@statdata+4, R0
	BZ		call			; do not start timers and interrupts if interval==0

* allow TINT0, set GIE and timer period and start timer
*	LDP		@statdataaddr
	OR		01h, IIE		; set bit 1, ETINT0 (p. 3-12)
*	LDI		@statdata+4, R0
	LDP		0100000h
	STI		R0, @028h		; set period with interval value
	LDI		02c1h, R0
	STI		R0, @020h		; start counter in timer 0 (chap. 13.8)
	OR		02000h, ST		; set bit 13, GIE (p.3-7)
	LDP		@statdataaddr	; to load correct pointer to task

* call task
call:
	LH1		AR1, DP			; set correct data page pointer (DO NOT CHANGE!! LDP only uses 'immediate')
	CALLU	AR1

* disable interrupts by initializing ST
	LDI		0h, ST
* stop timer
	LDP		0100000h
	LDI		0201h, R0
	STI		R0, @020h	; stop counter in timer 0
                  
* test if 'run once'
isrreturn:		; we want to jump here after interrupt occurred (RETIU re-enables GIE)
	LDP		@statdataaddr	; set correct data page pointer
    LDI		@statdata+5, R0	; load "startmode"
	LDHI	0001h, R1		; flag for "run once"
	OR		0002h, R1
	CMPI	R0, R1
	BNZ		LOOP			; loop if not "run once", i.e. "run continously"
	
* if 'run once', do not run again
*	LDHI	0001h, R1		; flag for "download only", i.e. do not run task in net loop
*	OR		0001h, R1
*	STI		R1, @statdata+5
TASKDEMON:				; if standlone, loop; else RETSU (which stack?)
	LDI		@statdata+2, R0
	LDI		1, R1
	CMPI	R0, R1	; run standalone, if 0x00000001
	BZ		LOOP
	LDI		@statdata+16, R0
	PUSH	R0		; stack: if returned nicely: stack okay; if not: stack set by isr
	RETSU			; else return to calling executive

* control environment
CTRLENV:

* download and crc packet
	LDHI	0ffffh, R0
	OR		0ffffh, R0				; CRC32_XINIT
	LDA		@crctableaddr, AR1
	LDI		13, AR2			; counter: 16 packets (-1: DBU, -1: CRC from host, -1: word 0)
	LDI		@packetdownaddr, AR3
	LDI		*+AR0(1), R1
* test if packet is for us
	LDI		0f00h, R2
	AND		R1, R2, R2
	BNZ		FORWARDPACKET
* process locally
	STI		R1, *AR3++(1)	; store token in first word of packet buffer
	XOR		R0, R1, R3			; \
	LDI		000ffh, R2			;  \
	AND		R2, R3, IR1			;   \  calc CRC
	LDI		*+AR1(IR1), R3		;   /  iteratively
	LSH		-8, R0, R2			;  /
	XOR		R3, R2, R0			; /

	CMPI	2, R1		; compare if token is download packet
	BNZ		packetdownloop
	LDI		@statdata+0, AR2		; download that many words
	SUBI	1, AR2
	LDI		@statdata+1, AR3		; load address
packetdownloop:
*	TODO: in case of error: load only as many words as in input FIFO, i.e. flush it
	LDI		*+AR0(1), R1
	STI		R1, *AR3++(1)   	; AR3 holds end address after loop finishes
	XOR		R0, R1, R1			; \
	LDI		000ffh, R2			;  \
	AND		R2, R1, IR1			;   \  calc CRC
	LDI		*+AR1(IR1), R1		;   /  iteratively
	LSH		-8, R0, R2			;  /
	XOR		R1, R2, R0			; /
	DBU		AR2, packetdownloop
	STI		R0, @statdata+8		; store calc'd CRC

	LDI		*+AR0(1), R1                                                                             
	STI		R1, @packetdown+15	; store CRC (host->DSP, calc'd by host) in last word of packtedown buffer

* react on packet
	LDI		@packetdown+0, R0        	; word 0
	BZ		STATUS		; request status				(00000000)
	SUBI	1, R0
	BZ		DOWNLOAD1	; download task, handshake		(00000001)
	SUBI	1, R0
	BZ		DOWNLOAD2	; download task, download data	(00000002)
	SUBI	1, R0
	BZ		STARTTASK	; start task					(00000003)
	SUBI	1, R0
	BZ		STOPTASK	; stop task						(00000004)
	SUBI	1, R0
	BZ		UPLOAD		; send buffer to host			(00000005)
	SUBI	1, R0
	BZ		SETMODE		; set mode						(00000006)
	BR		ERROR


STATUS
* nothing to do with 16 words sent by host
* fill packetup
	STI		0, @packetup+0	; STATUS (word 0)

	LDHI	VERSION, R1
	OR		REVISION, R1
	STI		R1, @packetup+1	; kernel version (word 1)

*	ADDI	0, R5, R1
	LDP		00100000h
	LDI		@24h, R1
	LDP		@statdataaddr
	STI		R1, @packetup+2	; test value (word 2)

	LDI		@statdata+3, R1
	STI		R1, @packetup+3	; schedule flag (word 3)

	LDI		@statdata+4, R1
	STI		R1, @packetup+4 ; time interval (word 4)

	LDI		@statdata+2, R1
	STI		R1, @packetup+5	; run mode (word 5)

	LDI		@statdata+5, R1
	STI		R1, @packetup+6	; start mode (word 6)

	LDI		0, R1
	STI		R1, @packetup+7	; word 7
	STI		R1, @packetup+8	; word 8
	STI		R1, @packetup+9	; word 9
	STI		R1, @packetup+10; word 10
	STI		R1, @packetup+11; word 11
	STI		R1, @packetup+12; word 12
	STI		R1, @packetup+13; word 13
	
	LDI		14, AR2
	LDI		@packetupaddr, AR3
	BR SENDPACKET
 
DOWNLOAD1:
* handle packetdown
	LDI		@packetdown+2, R1	; size of section to load (word 2)
	STI		R1, @statdata+0

	LDI		@packetdown+3, R1	; load address of section (word 3)
	STI		R1, @statdata+1

	LDI		@packetdown+4, R1	; start mode (word 4)
	STI		R1, @statdata+6		; store in startmode-temp

* decide if download allowed
	LDHI	00001h,R0
	OR		00001h,R0			; download allowed (0x00010001)

	LDI		@startbssaddr, R1	; start of .bss
	LDI		@endbssaddr, R2
	SUBI	1, R2				; endbss points to end of .bss plus 1

* start section > end area  (section: to download, area: on DSP)
	LDI		@statdata+1, R3		; load address (R3) must be higher than endbss (R2)
	SUBI	R2, R3, R4			; if R4>0, load address okay
	BP		testnextarea		; tests if (~N AND ~Z) set (P == positive)

* end section < start area
	LDI		@statdata+0, R5		; length of section
	ADDI	R3, R5, R6			
	SUBI 1, R6					; end of section (R6) must be lower than statdataaddr (R1)
	SUBI	R6, R1, R7			; if R7>0, length okay
	BP		testnextarea
	
	LDHI	00001h, R0
	OR		00002h, R0			; download denied (0x00010002)
	BR		senddownload1

testnextarea:
	LDI		@starttextaddr, R1		; start of .text
	LDI		@endtextaddr, R2	; end of .text

* start section > end area  (section: to download, area: on DSP)
	LDI		@statdata+1, R3		; load address (R3) must be higher than endbss (R2)
	SUBI	R2, R3, R4			; if R4>0, load address okay
*	BP		testnextarea		; tests if (~N AND ~Z) set (P == positive)
	BP		senddownload1

* end section < start area
	LDI		@statdata+0, R5		; length of section
	ADDI	R3, R5, R6			
	SUBI 1, R6					; end of section (R6) must be lower than statdataaddr (R1)
	SUBI	R6, R1, R7			; if R7>0, length okay
*	BP		testnextarea
	BP		senddownload1
	
	LDHI	00001h, R0
	OR		00002h, R0			; download denied (0x00010002)
*	BR		senddownload1
	
* fill packetup
senddownload1
	LDI		1, R1
	STI		R1, @packetup+0		; DOWNLOAD handshake1 (word 0)
	
	LDI		1, R1
	STI		R1, @packetup+1		; number of sections to load (word 1)

	LDI		@statdata+0, R1
	STI		R1, @packetup+2		; size of section to load (word 2)
	            
	LDI		@statdata+1, R1
	STI		R1, @packetup+3		; address of section to load (word 3)

	STI		R0, @packetup+4		; download status (word 4)

	LDI 	0, R1
	STI		R1, @packetup+5	; word 5
	STI		R1, @packetup+6	; word 6
	STI		R1, @packetup+7	; word 7
	STI		R1, @packetup+8	; word 8
	STI		R1, @packetup+9	; word 9
	STI		R1, @packetup+10; word 10
	STI		R1, @packetup+11; word 11
	STI		R1, @packetup+12; word 12
	STI		R1, @packetup+13; word 13
	
	LDI		14, AR2
	LDI		@packetupaddr, AR3
	BR SENDPACKET
	
DOWNLOAD2:
* data already downloaded, CRC in packetdown+15

* fill packetup
	LDI		2, R1
	STI		R1, @packetup+0		; 00000002 packet identifier (word 0)
                        
	LDI		1, R1
	STI		R1, @packetup+1		; number of sections loaded (word 1)
                          
	LDI		@statdata+1, AR2                          
	SUBI3	AR2, AR3, R1
	STI		R1, @packetup+2		; size of section loaded (word 2) (AR3: end address, AR2: start)
	
	LDI		@statdata+1, R1	
	STI		R1, @packetup+3		; address at which section is loaded (word 3)
	                         
	LDHI	00002h,R2
	OR		00001h,R2
	STI		R2, @packetup+4		; download successful (word 4)
	
	LDI		@statdata+6, R1	; load "startmode-temp"
	STI		R1, @statdata+5	; store in "startmode"
	LHU0	R1, R2
	LDHI	00002h, R1
	OR3		R1, R2, R1
	STI		R1, @packetup+5		; task started or downloaded only (word 5)

	LDI 	0, R1
	STI		R1, @packetup+6	; word 6
	STI		R1, @packetup+7	; word 7
	STI		R1, @packetup+8	; word 8
	STI		R1, @packetup+9	; word 9
	STI		R1, @packetup+10; word 10
	STI		R1, @packetup+11; word 11
	STI		R1, @packetup+12; word 12
	STI		R1, @packetup+13; word 13
	
	LDI		14, AR2
	LDI		@packetupaddr, AR3
	BR SENDPACKET

STARTTASK:   
* handle packetdown
	LDI		@packetdown+1, R1        	; start address (word 1)
	STI		R1, @statdata+7

	LDI		@packetdown+2, R1        	; start mode (word 2)
	LHU0	R1, R3
	LDHI	00001h, R4
	OR3		R4, R3, R3
	STI		R3, @statdata+5
	                      
	LDI		@packetdown+3, R1			; time interval (word 3)
	STI		R1, @statdata+4
	
	LDI		@packetdown+4, R1			; stack pointer (word 4)
	STI		R1, @statdata+9

* reset flag (will be set until next START_TASK or SET_MODE if an interrupt occurred at least once)
	STI		2, @statdata+3		; schedule okay
	
* fill packetup    
	LDI		3, R1
	STI		R1, @packetup+0	; STARTTASK (word 0)
	
	LDI		@statdata+7, R1
	STI		R1, @packetup+1	; start address (word 1)
   
    LDI		@statdata+5, R1
	LHU0	R1, R2
	LDHI	00003h, R1
	OR3		R1, R2, R1
	STI		R1, @packetup+2	; start mode (word 2)

	LDI		@statdata+4, R1
	STI		R1, @packetup+3	; time interval (word 3)

	LDI		@statdata+9, R1
	STI		R1, @packetup+4	; stack pointer (word 4)

	LDI		0, R1
	STI		R1, @packetup+5		; word 5
	STI		R1, @packetup+6		; word 6
	STI		R1, @packetup+7		; word 7
	STI		R1, @packetup+8		; word 8
	STI		R1, @packetup+9		; word 9
	STI		R1, @packetup+10    ; word 10
	STI		R1, @packetup+11	; word 11
	STI		R1, @packetup+12	; word 12
	STI		R1, @packetup+13	; word 13

	LDI		14, AR2
	LDI		@packetupaddr, AR3
	BR		SENDPACKET
	
STOPTASK:
* handle packetdown
	LDI		@packetdown+1, R1        	; start address (word 1)
	STI		R1, @statdata+7

	LDI		@packetdown+2, R1        	; kill mode (word 2)
	LHU0	R1, R3
	LDHI	00001h, R4
	OR3		R4, R3, R3
	STI		R3, @statdata+5

* fill packetup
	LDI		4, R1
	STI		R1, @packetup+0		; STOPTASK (word 0)
	
	LDI		@statdata+7, R1
	STI		R1, @packetup+1		; start address (word 1)
    
    LDI		@statdata+5, R1
	LHU0	R1, R2
	LDHI	00004h, R1
	OR3		R1, R2, R2
	STI		R2, @packetup+2		; kill mode (word 2)

	LDI		0, R1
	STI		R1, @packetup+3		; word 3
	STI		R1, @packetup+4		; word 4
	STI		R1, @packetup+5		; word 5
	STI		R1, @packetup+6		; word 6
	STI		R1, @packetup+7		; word 7
	STI		R1, @packetup+8		; word 8
	STI		R1, @packetup+9		; word 9
	STI		R1, @packetup+10    ; word 10
	STI		R1, @packetup+11	; word 11
	STI		R1, @packetup+12	; word 12
	STI		R1, @packetup+13	; word 13

	LDI		14, AR2
	LDI		@packetupaddr, AR3
	BR		SENDPACKET

UPLOAD:
	LDI		@packetdown+2, AR2		; size of block
	LDI		@packetdown+3, AR3		; start address
	BR		SENDPACKET

SETMODE:
* handle packetdown
	LDI		@packetdown+1, R1		; time interval (word 1)
	STI		R1, @statdata+4
	
	LDI		@packetdown+2, R1		; run mode (word 2)
	LHU0	R1, R2
	LDHI	00000h, R1
	OR3		R1, R2, R1
	STI		R1, @statdata+2

* reset flag (will be set until next START_TASK or SET_MODE if an interrupt occurred at least once)
	STI		2, @statdata+3			; schedule okay

* fill packetup
	LDI		6, R1
	STI		R1, @packetup+0			; SETMODE (word 0)

	LDI		@statdata+4, R1
	STI		R1, @packetup+1			; time interval (word 1)

	LDI		@statdata+2, R1
	LHU0	R1, R2
	LDHI	00006h, R1
	OR3		R1, R2, R1
	STI		R1, @packetup+2			; run mode (word 2)

	LDI		0, R1
	STI		R1, @packetup+3
	STI		R1, @packetup+4		; word 4
	STI		R1, @packetup+5		; word 5
	STI		R1, @packetup+6		; word 6
	STI		R1, @packetup+7		; word 7
	STI		R1, @packetup+8		; word 8
	STI		R1, @packetup+9		; word 9
	STI		R1, @packetup+10    ; word 10
	STI		R1, @packetup+11	; word 11
	STI		R1, @packetup+12	; word 12
	STI		R1, @packetup+13	; word 13

	LDI		14, AR2
	LDI		@packetupaddr, AR3
	BR		SENDPACKET

ERROR:
* packetdown already filled

*	send 16 error words
*	TODO: send only if output FIFO is empty (busy wait)
	LDHI	5555h, R1
	OR		5555h, R1
	STI		R1, @packetup+0	; error token (word 0)
	          
	LDI		@packetdown+0, R1	          
	STI		R1, @packetup+1	; bits found instead of token (word 1)

	LDI		0, R1
	STI		R1, @packetup+2		; word 2
	STI		R1, @packetup+4		; word 4
	STI		R1, @packetup+5		; word 5
	STI		R1, @packetup+6		; word 6
	STI		R1, @packetup+7		; word 7
	STI		R1, @packetup+8		; word 8
	STI		R1, @packetup+9		; word 9
	STI		R1, @packetup+10    ; word 10
	STI		R1, @packetup+11	; word 11
	STI		R1, @packetup+12	; word 12
	STI		R1, @packetup+13	; word 13

	LDI		14, AR2
	LDI		@packetupaddr, AR3
*	BR		SENDPACKET

SENDPACKET:               ; AR2: # of words (without CRCs == packetlength - 2), AR3: start address
	LDHI	0ffffh, R0
	OR		0ffffh, R0				; CRC32_XINIT
	LDA		@crctableaddr, AR1
*	LDI		14, AR2			; counter: 16 packets (-1: DBU, -1 CRC from host)
*	LDI		@packetupaddr, AR3
	SUBI	1, AR2
packetuploop:
	LDI		*AR3++(1), R1
	STI		R1, *+AR0(2)
	XOR		R0, R1, R1			; \
	LDI		000ffh, R2			;  \
	AND		R2, R1, IR1			;   \  calc CRC
	LDI		*+AR1(IR1), R1		;   /  iteratively
	LSH		-8, R0, R2			;  /
	XOR		R1, R2, R0			; /
	DBU		AR2, packetuploop                                       

	LDI		@statdata+8, R1		; CRC (host->DSP, calc'd by DSP)
	STI		R1, *+AR0(2)
	XOR		R0, R1, R1			; \
	LDI		000ffh, R2			;  \
	AND		R2, R1, IR1			;   \  calc CRC
	LDI		*+AR1(IR1), R1		;   /  iteratively
	LSH		-8, R0, R2			;  /
	XOR		R1, R2, R0			; /

	STI		R0, *+AR0(2)		; send CRC of uppacket, as calc'd by DSP
	BR LOOP
	
FORWARDPACKET:	; R1 full command line
	LDI		0ffh, R2
	AND		R2, R1, R2		; R2: command
	ADDI	0, R2, R4		; save R2 in R4
	LSH		-4, R1
	LDHI	0ffffh, R3
	OR		0ff00h, R3
	AND		R1, R3, R3
	OR		R2, R3, R2		; R2: new command (word 0)
	AND		0f0h, R1
	LDHI	010h, R3
	OR		R1, R3, AR3		; R1: FIFO out address
	; send packet unprocessed to next DSP (read out packet number if 0x01, adjust packet size for 0x02)
					; AR0 is up stream from/to host (base address)
					; AR3 is down stream to next DSP (base address)
	STI		R2, *+AR3(2)	; send new command
	LDI 	14, AR2			; counter down packet (only 15 words to send)
	LDI		15, AR4			; counter up packet (16 words)
	CMPI	5, R4
	BNZ		nexttest		; if not command "send buffer to host"
	LDI		*+AR0(1), R1
	STI		R1, *+AR3(2)
	LDI		*+AR0(1), R1
	STI		R1, *+AR3(2)
	ADDI	1, R1, AR4			; save size for uploadpacket in counter (+2: CRCs, -1: DBU)
	SUBI	2, AR2				; adapt downloadcounter
	BR		forwarddownloop
nexttest:
	CMPI	1, R2			
	BNZ		furthertest		; if not command "init download"
	LDI		*+AR0(1), R1
	STI		R1, *+AR3(2)
	LDI		*+AR0(1), R1
	STI		R1, *+AR3(2)		
	STI		R1, @statdata+17	; save data size for download packet
	SUBI	2, AR2				; adapt downloadcounter
	BR		forwarddownloop
furthertest:
	CMPI	2, R2			; if not command "download packet"
	BNZ		forwarddownloop
	LDI		@statdata+17, AR2	; restore packet size counter for down packet
forwarddownloop:
	LDI		*+AR0(1), R1
	STI		R1, *+AR3(2)
	DBU		AR2, forwarddownloop                                       
	
	; wait for up packet and send unprocessed to host (adjust packet size for 0x05)
forwarduploop:
	LDI		*+AR3(1), R1
	STI		R1, *+AR0(2)
	DBU		AR4, forwarduploop
	BR LOOP

isr:
* disable interrupts by initializing ST (and hereby clearing PGIE!!!)
	LDI		0h, ST
* stop counter in timer 0
	LDP		0100000h
	LDI		0201h, R0
	STI		R0, @020h	; control in timer 0 (chap. 13.8)
* clear IIF TINT0
	LDHI	0feffh, R0
	OR		0ffffh, R0
	AND		R0, IIF
* set schedule flag
	LDP		@statdataaddr
	STI		1, @statdata+3	; schedule flag
* manipulate stack
	LDI		@stackaddr, SP
	LDI		@isrreturnaddr, R0
	PUSH	R0		; we *do* want to return to out kernelloop, right after task
* TODO: the question is, if we really came from the task and not from somewhere else.
* RETI
	RETI

	.sect ".task"
TASK:      
*	LDHI	01111h, R5
*	OR		01111h, R5
       
    LDHI	00010h, AR2
	OR		00080h, AR2
	LDI		*+AR2(1),R9
	ASH		-16,R9,R9
	LSH		16,R9,R0
	OR		1,R0,R0
	LDHI	00010h, AR2
	OR		00050h, AR2
	STI		R0,*+AR2(2)
	
	RETS					; return from subroutine unconditionally
*	IDLE

	.text
startbssaddr
ivtaddr			.word	ivt			; .bss start
statdataaddr	.word	statdata
packetdownaddr	.word	packetdown
packetupaddr	.word	packetup
endbssaddr		.word	endbss		; .bss end
starttextaddr
mainaddr		.word	_main		; .text start
crctableaddr	.word	crctable
taskaddr		.word	TASK
israddr			.word	isr
isrreturnaddr	.word	isrreturn
endtextaddr		.word	endtext     ; .text end

stackaddr		.word	stack

crctable:
	.word 000000000h, 077073096h, 0EE0E612Ch, 0990951BAh, 0076DC419h, 0706AF48Fh, 0E963A535h, 09E6495A3h
	.word 00EDB8832h, 079DCB8A4h, 0E0D5E91Eh, 097D2D988h, 009B64C2Bh, 07EB17CBDh, 0E7B82D07h, 090BF1D91h
 	.word 01DB71064h, 06AB020F2h, 0F3B97148h, 084BE41DEh, 01ADAD47Dh, 06DDDE4EBh, 0F4D4B551h, 083D385C7h
	.word 0136C9856h, 0646BA8C0h, 0FD62F97Ah, 08A65C9ECh, 014015C4Fh, 063066CD9h, 0FA0F3D63h, 08D080DF5h
	.word 03B6E20C8h, 04C69105Eh, 0D56041E4h, 0A2677172h, 03C03E4D1h, 04B04D447h, 0D20D85FDh, 0A50AB56Bh
	.word 035B5A8FAh, 042B2986Ch, 0DBBBC9D6h, 0ACBCF940h, 032D86CE3h, 045DF5C75h, 0DCD60DCFh, 0ABD13D59h
	.word 026D930ACh, 051DE003Ah, 0C8D75180h, 0BFD06116h, 021B4F4B5h, 056B3C423h, 0CFBA9599h, 0B8BDA50Fh
	.word 02802B89Eh, 05F058808h, 0C60CD9B2h, 0B10BE924h, 02F6F7C87h, 058684C11h, 0C1611DABh, 0B6662D3Dh
	.word 076DC4190h, 001DB7106h, 098D220BCh, 0EFD5102Ah, 071B18589h, 006B6B51Fh, 09FBFE4A5h, 0E8B8D433h
	.word 07807C9A2h, 00F00F934h, 09609A88Eh, 0E10E9818h, 07F6A0DBBh, 0086D3D2Dh, 091646C97h, 0E6635C01h
	.word 06B6B51F4h, 01C6C6162h, 0856530D8h, 0F262004Eh, 06C0695EDh, 01B01A57Bh, 08208F4C1h, 0F50FC457h
	.word 065B0D9C6h, 012B7E950h, 08BBEB8EAh, 0FCB9887Ch, 062DD1DDFh, 015DA2D49h, 08CD37CF3h, 0FBD44C65h
	.word 04DB26158h, 03AB551CEh, 0A3BC0074h, 0D4BB30E2h, 04ADFA541h, 03DD895D7h, 0A4D1C46Dh, 0D3D6F4FBh
	.word 04369E96Ah, 0346ED9FCh, 0AD678846h, 0DA60B8D0h, 044042D73h, 033031DE5h, 0AA0A4C5Fh, 0DD0D7CC9h
	.word 05005713Ch, 0270241AAh, 0BE0B1010h, 0C90C2086h, 05768B525h, 0206F85B3h, 0B966D409h, 0CE61E49Fh
	.word 05EDEF90Eh, 029D9C998h, 0B0D09822h, 0C7D7A8B4h, 059B33D17h, 02EB40D81h, 0B7BD5C3Bh, 0C0BA6CADh
	.word 0EDB88320h, 09ABFB3B6h, 003B6E20Ch, 074B1D29Ah, 0EAD54739h, 09DD277AFh, 004DB2615h, 073DC1683h
	.word 0E3630B12h, 094643B84h, 00D6D6A3Eh, 07A6A5AA8h, 0E40ECF0Bh, 09309FF9Dh, 00A00AE27h, 07D079EB1h
	.word 0F00F9344h, 08708A3D2h, 01E01F268h, 06906C2FEh, 0F762575Dh, 0806567CBh, 0196C3671h, 06E6B06E7h
	.word 0FED41B76h, 089D32BE0h, 010DA7A5Ah, 067DD4ACCh, 0F9B9DF6Fh, 08EBEEFF9h, 017B7BE43h, 060B08ED5h
	.word 0D6D6A3E8h, 0A1D1937Eh, 038D8C2C4h, 04FDFF252h, 0D1BB67F1h, 0A6BC5767h, 03FB506DDh, 048B2364Bh
	.word 0D80D2BDAh, 0AF0A1B4Ch, 036034AF6h, 041047A60h, 0DF60EFC3h, 0A867DF55h, 0316E8EEFh, 04669BE79h
	.word 0CB61B38Ch, 0BC66831Ah, 0256FD2A0h, 05268E236h, 0CC0C7795h, 0BB0B4703h, 0220216B9h, 05505262Fh
	.word 0C5BA3BBEh, 0B2BD0B28h, 02BB45A92h, 05CB36A04h, 0C2D7FFA7h, 0B5D0CF31h, 02CD99E8Bh, 05BDEAE1Dh
	.word 09B64C2B0h, 0EC63F226h, 0756AA39Ch, 0026D930Ah, 09C0906A9h, 0EB0E363Fh, 072076785h, 005005713h
	.word 095BF4A82h, 0E2B87A14h, 07BB12BAEh, 00CB61B38h, 092D28E9Bh, 0E5D5BE0Dh, 07CDCEFB7h, 00BDBDF21h
	.word 086D3D2D4h, 0F1D4E242h, 068DDB3F8h, 01FDA836Eh, 081BE16CDh, 0F6B9265Bh, 06FB077E1h, 018B74777h
	.word 088085AE6h, 0FF0F6A70h, 066063BCAh, 011010B5Ch, 08F659EFFh, 0F862AE69h, 0616BFFD3h, 0166CCF45h
	.word 0A00AE278h, 0D70DD2EEh, 04E048354h, 03903B3C2h, 0A7672661h, 0D06016F7h, 04969474Dh, 03E6E77DBh
	.word 0AED16A4Ah, 0D9D65ADCh, 040DF0B66h, 037D83BF0h, 0A9BCAE53h, 0DEBB9EC5h, 047B2CF7Fh, 030B5FFE9h
	.word 0BDBDF21Ch, 0CABAC28Ah, 053B39330h, 024B4A3A6h, 0BAD03605h, 0CDD70693h, 054DE5729h, 023D967BFh
	.word 0B3667A2Eh, 0C4614AB8h, 05D681B02h, 02A6F2B94h, 0B40BBE37h, 0C30C8EA1h, 05A05DF1Bh
endtext:
	.word 02D02EF8Dh
stack:
	.end

