OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [software/] [FMTK/] [source/] [kernel/] [FMTKc.c] - Rev 23

Compare with Previous | Blame | View Log

// ============================================================================
//        __
//   \\__/ o\    (C) 2012-2016  Robert Finch, Stratford
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
//
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
//                                                                          
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
// ============================================================================
//
#include "config.h"
#include "const.h"
#include "types.h"
#include "proto.h"
#include "glo.h"
 
extern int shell();
extern void KeybdIRQ();
extern pascal int putstr(char *, int);
extern int printf(char *, ...);
void panic(char *msg);
extern int FMTK_FreeMbx(hMBX);
 
int irq_stack[512];
int sp_tmp;
int FMTK_Inited;
JCB jcbs[NR_JCB];
extern TCB tcbs[NR_TCB];
extern hTCB readyQ[8];
int sysstack[1024];
int stacks[NR_TCB][1024];
int sys_stacks[NR_TCB][512];
int bios_stacks[NR_TCB][512];
int fmtk_irq_stack[512];
int fmtk_sys_stack[512];
MBX mailbox[NR_MBX];
MSG message[NR_MSG];
int nMsgBlk;
int nMailbox;
hJCB freeJCB;
hMSG freeMSG;
hMBX freeMBX;
JCB *IOFocusNdx;
int IOFocusTbl[4];
int iof_switch;
int BIOS1_sema;
int iof_sema;
int sys_sema;
int BIOS_RespMbx;
char hasUltraHighPriorityTasks;
int missed_ticks;
 
short int video_bufs[NR_JCB][4096];
extern hTCB TimeoutList;
 
extern void gfx_demo();
 
// This table needed in case we want to call the OS routines directly.
// It is also used by the system call interrupt as a vector table.
 
naked void FMTK_BrTbl()
{
      asm {
		  align 4
dh	FMTKInitialize_
dh	FMTK_StartTask_
dh	FMTK_ExitTask_
dh	FMTK_KillTask_
dh	FMTK_SetTaskPriority_
dh	FMTK_Sleep_
dh	FMTK_AllocMbx_
dh	FMTK_FreeMbx_
dh	FMTK_PostMsg_
dh	FMTK_SendMsg_
dh	FMTK_WaitMsg_
dh	FMTK_CheckMsg_
      }
}
 
naked int GetVecno()
{
    asm {
        mfspr  r1,12
        rts
    }
}
 
naked void DisplayIRQLive()
{
     asm {
         lh       r1,hs:328
         addui    r1,r1,#1
         sh       r1,hs:328
     }
}
 
JCB *GetJCBPtr()
{
    return &jcbs[tcbs[GetRunningTCB()].hJob];
}
 
 
// ----------------------------------------------------------------------------
// Select a task to run.
// ----------------------------------------------------------------------------
 
private const __int8 startQ[32] = { 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 1, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 1, 0, 7, 0, 0, 0, 0 };
private __int8 startQNdx;
 
private hTCB SelectTaskToRun()
{
	int nn,kk;
	TCB *p, *q;
	int qToCheck;
    hTCB h;
 
	startQNdx++;
	startQNdx &= 31;
	qToCheck = startQ[startQNdx];
	qToCheck &= 7;
	for (nn = 0; nn < 8; nn++) {
		h = readyQ[qToCheck];
		if (h >= 0 && h < NR_TCB) {
    		p = &tcbs[h];
            kk = 0;
            // Can run the head of a lower Q level if it's not the running
            // task, otherwise look to the next task.
            if (h != GetRunningTCB())
           		q = p;
    		else
           		q = &tcbs[p->next];
            do {  
                if (!(q->status & TS_RUNNING)) {
                    if (q->affinity == getCPU()) {
        			   readyQ[qToCheck] = q - tcbs;
        			   return q - tcbs;
                    }
                }
                q = &tcbs[q->next];
                kk = kk + 1;
            } while (q != p && kk < NR_TCB);
        }
		qToCheck++;
		qToCheck &= 7;
	}
	return GetRunningTCB();
	panic("No entries in ready queue.");
}
 
// ----------------------------------------------------------------------------
// There isn't any 'C' code in the SystemCall() function. If there were it
// would have to be arranged like the TimerIRQ() or RescheduleIRQ() functions.
// ----------------------------------------------------------------------------
 
naked FMTK_SystemCall()
{
	asm {
		sync
		sw		r2,TCB_r2[tr]
		sw		r3,TCB_r3[tr]
		sw		r4,TCB_r4[tr]
		sw		r5,TCB_r5[tr]
		sw		r6,TCB_r6[tr]
		sw		r7,TCB_r7[tr]
		sw		r8,TCB_r8[tr]
		sw		r9,TCB_r9[tr]
		sw		r10,TCB_r10[tr]
		sw		r11,TCB_r11[tr]
		sw		r12,TCB_r12[tr]
		sw		r13,TCB_r13[tr]
		sw		r14,TCB_r14[tr]
		sw		r15,TCB_r15[tr]
		sw		r16,TCB_r16[tr]
		sw		r17,TCB_r17[tr]
		sw		r18,TCB_r18[tr]
		sw		r19,TCB_r19[tr]
		sw		r20,TCB_r20[tr]
		sw		r21,TCB_r21[tr]
		sw		r22,TCB_r22[tr]
		sw		r23,TCB_r23[tr]
		sw		r24,TCB_r24[tr]
		sw		r25,TCB_r25[tr]
		sw		r26,TCB_r26[tr]
		sw		r27,TCB_r27[tr]
		sws		ds,TCB_ds[tr]
		sws		es,TCB_es[tr]
		sws		fs,TCB_fs[tr]
		sws		gs,TCB_gs[tr]
		sws		hs,TCB_hs[tr]
		sws		ss,TCB_ss[tr]
		sws		cs,TCB_cs[tr]
		sws		ds.lmt,TCB_dslmt[tr]
		sws		es.lmt,TCB_eslmt[tr]
		sws		fs.lmt,TCB_fslmt[tr]
		sws		gs.lmt,TCB_gslmt[tr]
		sws		hs.lmt,TCB_hslmt[tr]
		sws		ss.lmt,TCB_sslmt[tr]
		sws		cs.lmt,TCB_cslmt[tr]
		sws		c1,TCB_c1[tr]
		sws		c2,TCB_c2[tr]
		sws		c3,TCB_c3[tr]
		sws		c4,TCB_c4[tr]
		sws		c5,TCB_c5[tr]
		sws		c6,TCB_c6[tr]
		sws		c7,TCB_c7[tr]
		sws		c8,TCB_c8[tr]
		sws		c9,TCB_c9[tr]
		sws		c10,TCB_c10[tr]
		sws		c11,TCB_c11[tr]
		sws		c13,TCB_c13[tr]
		sws		c14,TCB_c14[tr]
		sws		pregs,TCB_pregs[tr]
	}
    asm {
		ldi		sp,#sysstack_+1023*8	; switch to system stack
		mtspr	ss,r0
		ldi		ss.lmt,#-1
		mtspr	ds,r0			; and data segment
		ldi		ds.lmt,#-1
		mfspr	r6,c13			; r6 = return address
    	lbu	    r7,[r6]			; r7 = static call number parameter
		addui	r6,r6,#1
		mtspr	c13,r6
		sws		c13,TCB_c13[tr]	; save c13 in task image
    	cmpi	p0,r7,#20
p0.gtu  ldi     r1,#E_BadFuncno
p0.gtu	br		.0001
		addui	sp,sp,#-40
		sw		r1,[sp]
		sw		r2,8[sp]
		sw		r3,16[sp]
		sw		r4,24[sp]
		sw		r5,32[sp]
		jhi		c1,cs:FMTK_BrTbl_[r7]	; do the system function
.0001:
		; leave r1 as system call result
		lw		r2,TCB_r2[tr]
		lw		r3,TCB_r3[tr]
		lw		r4,TCB_r4[tr]
		lw		r5,TCB_r5[tr]
		lw		r6,TCB_r6[tr]
		lw		r7,TCB_r7[tr]
		lw		r8,TCB_r8[tr]
		lw		r9,TCB_r9[tr]
		lw		r10,TCB_r10[tr]
		lw		r11,TCB_r11[tr]
		lw		r12,TCB_r12[tr]
		lw		r13,TCB_r13[tr]
		lw		r14,TCB_r14[tr]
		lw		r15,TCB_r15[tr]
		lw		r16,TCB_r16[tr]
		lw		r17,TCB_r17[tr]
		lw		r18,TCB_r18[tr]
		lw		r19,TCB_r19[tr]
		lw		r20,TCB_r20[tr]
		lw		r21,TCB_r21[tr]
		lw		r22,TCB_r22[tr]
		lw		r23,TCB_r23[tr]
		lw		r24,TCB_r24[tr]
		lw		r25,TCB_r25[tr]
		lw		r26,TCB_r26[tr]
		lw		r27,TCB_r27[tr]
		lws		ds,TCB_ds[tr]
		lws		es,TCB_es[tr]
		lws		fs,TCB_fs[tr]
		lws		gs,TCB_gs[tr]
		lws		hs,TCB_hs[tr]
		lws		ss,TCB_ss[tr]
		lws		cs,TCB_cs[tr]
		lws		ds.lmt,TCB_dslmt[tr]
		lws		es.lmt,TCB_eslmt[tr]
		lws		fs.lmt,TCB_fslmt[tr]
		lws		gs.lmt,TCB_gslmt[tr]
		lws		hs.lmt,TCB_hslmt[tr]
		lws		ss.lmt,TCB_sslmt[tr]
		lws		cs.lmt,TCB_cslmt[tr]
		lws		c1,TCB_c1[tr]
		lws		c2,TCB_c2[tr]
		lws		c3,TCB_c3[tr]
		lws		c4,TCB_c4[tr]
		lws		c5,TCB_c5[tr]
		lws		c6,TCB_c6[tr]
		lws		c7,TCB_c7[tr]
		lws		c8,TCB_c8[tr]
		lws		c9,TCB_c9[tr]
		lws		c10,TCB_c10[tr]
		lws		c11,TCB_c11[tr]
		lws		c13,TCB_c13[tr]
		lws		c14,TCB_c14[tr]
		lws		pregs,TCB_pregs[tr]
		sync
		rte
    }
}
 
// ----------------------------------------------------------------------------
// If timer interrupts are enabled during a priority #0 task, this routine
// only updates the missed ticks and remains in the same task. No timeouts
// are updated and no task switches will occur. The timer tick routine
// basically has a fixed latency when priority #0 is present.
// ----------------------------------------------------------------------------
 
void FMTK_SchedulerIRQ()
{
	TCB *t;
 
	prolog asm {
		sync
		sw		r1,TCB_ir1[tr]
		sw		r2,TCB_ir2[tr]
		sw		r3,TCB_ir3[tr]
		sw		r4,TCB_ir4[tr]
		sw		r5,TCB_ir5[tr]
		sw		r6,TCB_ir6[tr]
		sw		r7,TCB_ir7[tr]
		sw		r8,TCB_ir8[tr]
		sw		r9,TCB_ir9[tr]
		sw		r10,TCB_ir10[tr]
		sw		r11,TCB_ir11[tr]
		sw		r12,TCB_ir12[tr]
		sw		r13,TCB_ir13[tr]
		sw		r14,TCB_ir14[tr]
		sw		r15,TCB_ir15[tr]
		sw		r16,TCB_ir16[tr]
		sw		r17,TCB_ir17[tr]
		sw		r18,TCB_ir18[tr]
		sw		r19,TCB_ir19[tr]
		sw		r20,TCB_ir20[tr]
		sw		r21,TCB_ir21[tr]
		sw		r22,TCB_ir22[tr]
		sw		r23,TCB_ir23[tr]
		sw		r24,TCB_ir24[tr]
		sw		r25,TCB_ir25[tr]
		sw		r26,TCB_ir26[tr]
		sw		r27,TCB_ir27[tr]
		sws		ds,TCB_ids[tr]
		sws		es,TCB_ies[tr]
		sws		fs,TCB_ifs[tr]
		sws		gs,TCB_igs[tr]
		sws		hs,TCB_ihs[tr]
		sws		ss,TCB_iss[tr]
		sws		cs,TCB_ics[tr]
		sws		ds.lmt,TCB_idslmt[tr]
		sws		es.lmt,TCB_ieslmt[tr]
		sws		fs.lmt,TCB_ifslmt[tr]
		sws		gs.lmt,TCB_igslmt[tr]
		sws		hs.lmt,TCB_ihslmt[tr]
		sws		ss.lmt,TCB_isslmt[tr]
		sws		cs.lmt,TCB_icslmt[tr]
		sws		c1,TCB_ic1[tr]
		sws		c2,TCB_ic2[tr]
		sws		c3,TCB_ic3[tr]
		sws		c4,TCB_ic4[tr]
		sws		c5,TCB_ic5[tr]
		sws		c6,TCB_ic6[tr]
		sws		c7,TCB_ic7[tr]
		sws		c8,TCB_ic8[tr]
		sws		c9,TCB_ic9[tr]
		sws		c10,TCB_ic10[tr]
		sws		c11,TCB_ic11[tr]
		sws		c13,TCB_ic13[tr]
		sws		c14,TCB_ic14[tr]
		sws		pregs,TCB_ipregs[tr]
 
		ldi		sp,#irq_stack_+511*8	; setup system stack and data segments
		mtspr	ss,r0
		ldis	ss.lmt,#-1
		mtspr	ds,r0
		ldis	ds.lmt,#-1
		ldi		hs,#$FFD00000
		ldi		hs.lmt,#$100000
		ldi		r1,#2					; reset edge sense circuit
		sh		r1,hs:PIC_ESR
	}
	DisplayIRQLive();
	if (LockSemaphore(&sys_sema,10)) {
		t = GetRunningTCBPtr();
		t->ticks = t->ticks + (t->endTick - t->startTick);
		if (t->priority != 000) {
			t->status = TS_PREEMPT;
			while (TimeoutList >= 0 && TimeoutList < NR_TCB) {
				if (tcbs[TimeoutList].timeout<=0)
					InsertIntoReadyList(PopTimeoutList());
				else {
					tcbs[TimeoutList].timeout = tcbs[TimeoutList].timeout - missed_ticks - 1;
					missed_ticks = 0;
					break;
				}
			}
			if (t->priority > 002)
			SetRunningTCB(SelectTaskToRun());
			GetRunningTCBPtr()->status = TS_RUNNING;
		}
		else {
			missed_ticks++;
		}
		UnlockSemaphore(&sys_sema);
	}
	else {
		missed_ticks++;
	}
	// If an exception was flagged (eg CTRL-C) return to the catch handler
	// not the interrupted code.
	t = GetRunningTCBPtr();
	if (t->exception) {
		t->icregs[1] = t->icregs[11];    // set link register to catch handler
		t->icregs[13] = t->icregs[11];   // and the PC register
		t->iregs[1] = t->exception;    // r1 = exception value
		t->exception = 0;
		t->iregs[2] = 24;              // r2 = exception type
	}
	epilog asm {
		lw		r1,TCB_ir1[tr]
		lw		r2,TCB_ir2[tr]
		lw		r3,TCB_ir3[tr]
		lw		r4,TCB_ir4[tr]
		lw		r5,TCB_ir5[tr]
		lw		r6,TCB_ir6[tr]
		lw		r7,TCB_ir7[tr]
		lw		r8,TCB_ir8[tr]
		lw		r9,TCB_ir9[tr]
		lw		r10,TCB_ir10[tr]
		lw		r11,TCB_ir11[tr]
		lw		r12,TCB_ir12[tr]
		lw		r13,TCB_ir13[tr]
		lw		r14,TCB_ir14[tr]
		lw		r15,TCB_ir15[tr]
		lw		r16,TCB_ir16[tr]
		lw		r17,TCB_ir17[tr]
		lw		r18,TCB_ir18[tr]
		lw		r19,TCB_ir19[tr]
		lw		r20,TCB_ir20[tr]
		lw		r21,TCB_ir21[tr]
		lw		r22,TCB_ir22[tr]
		lw		r23,TCB_ir23[tr]
		lw		r24,TCB_ir24[tr]
		lw		r25,TCB_ir25[tr]
		lw		r26,TCB_ir26[tr]
		lw		r27,TCB_ir27[tr]
		lws		ds,TCB_ids[tr]
		lws		es,TCB_ies[tr]
		lws		fs,TCB_ifs[tr]
		lws		gs,TCB_igs[tr]
		lws		hs,TCB_ihs[tr]
		lws		ss,TCB_iss[tr]
		lws		cs,TCB_ics[tr]
		lws		ds.lmt,TCB_idslmt[tr]
		lws		es.lmt,TCB_ieslmt[tr]
		lws		fs.lmt,TCB_ifslmt[tr]
		lws		gs.lmt,TCB_igslmt[tr]
		lws		hs.lmt,TCB_ihslmt[tr]
		lws		ss.lmt,TCB_isslmt[tr]
		lws		cs.lmt,TCB_icslmt[tr]
		lws		c1,TCB_ic1[tr]
		lws		c2,TCB_ic2[tr]
		lws		c3,TCB_ic3[tr]
		lws		c4,TCB_ic4[tr]
		lws		c5,TCB_ic5[tr]
		lws		c6,TCB_ic6[tr]
		lws		c7,TCB_ic7[tr]
		lws		c8,TCB_ic8[tr]
		lws		c9,TCB_ic9[tr]
		lws		c10,TCB_ic10[tr]
		lws		c11,TCB_ic11[tr]
		lws		c13,TCB_ic13[tr]
		lws		c14,TCB_ic14[tr]
		lws		pregs,TCB_ipregs[tr]
		sync
		rti
	}
}
 
void FMTK_SchedulerIRQ2()
{
     TCB *t;
 
	prolog asm {
		sync
		sw		r1,TCB_ir1[tr]
		sw		r2,TCB_ir2[tr]
		sw		r3,TCB_ir3[tr]
		sw		r4,TCB_ir4[tr]
		sw		r5,TCB_ir5[tr]
		sw		r6,TCB_ir6[tr]
		sw		r7,TCB_ir7[tr]
		sw		r8,TCB_ir8[tr]
		sw		r9,TCB_ir9[tr]
		sw		r10,TCB_ir10[tr]
		sw		r11,TCB_ir11[tr]
		sw		r12,TCB_ir12[tr]
		sw		r13,TCB_ir13[tr]
		sw		r14,TCB_ir14[tr]
		sw		r15,TCB_ir15[tr]
		sw		r16,TCB_ir16[tr]
		sw		r17,TCB_ir17[tr]
		sw		r18,TCB_ir18[tr]
		sw		r19,TCB_ir19[tr]
		sw		r20,TCB_ir20[tr]
		sw		r21,TCB_ir21[tr]
		sw		r22,TCB_ir22[tr]
		sw		r23,TCB_ir23[tr]
		sw		r24,TCB_ir24[tr]
		sw		r25,TCB_ir25[tr]
		sw		r26,TCB_ir26[tr]
		sw		r27,TCB_ir27[tr]
		sws		ds,TCB_ids[tr]
		sws		es,TCB_ies[tr]
		sws		fs,TCB_ifs[tr]
		sws		gs,TCB_igs[tr]
		sws		hs,TCB_ihs[tr]
		sws		ss,TCB_iss[tr]
		sws		cs,TCB_ics[tr]
		sws		ds.lmt,TCB_idslmt[tr]
		sws		es.lmt,TCB_ieslmt[tr]
		sws		fs.lmt,TCB_ifslmt[tr]
		sws		gs.lmt,TCB_igslmt[tr]
		sws		hs.lmt,TCB_ihslmt[tr]
		sws		ss.lmt,TCB_isslmt[tr]
		sws		cs.lmt,TCB_icslmt[tr]
		sws		c1,TCB_ic1[tr]
		sws		c2,TCB_ic2[tr]
		sws		c3,TCB_ic3[tr]
		sws		c4,TCB_ic4[tr]
		sws		c5,TCB_ic5[tr]
		sws		c6,TCB_ic6[tr]
		sws		c7,TCB_ic7[tr]
		sws		c8,TCB_ic8[tr]
		sws		c9,TCB_ic9[tr]
		sws		c10,TCB_ic10[tr]
		sws		c11,TCB_ic11[tr]
		sws		c13,TCB_ic13[tr]
		sws		c14,TCB_ic14[tr]
		sws		pregs,TCB_ipregs[tr]
 
		ldi		sp,#irq_stack_+511*8	; setup system stack and data segments
		mtspr	ss,r0
		ldis	ss.lmt,#-1
		mtspr	ds,r0
		ldis	ds.lmt,#-1
		ldi		hs,#$FFD00000
		ldi		hs.lmt,#$100000
		ldi		r1,#2					; reset edge sense circuit
		sh		r1,hs:PIC_ESR
	}
	 t->icregs[14] += 4;		// update return address
     // Explicit rescheduling request.
     t = GetRunningTCBPtr();
     t->ticks = t->ticks + (t->endTick - t->startTick);
     t->status = TS_GIVEAWAY;
     //t->iipc = t->iipc + 4;  // advance the return address
     SetRunningTCB(SelectTaskToRun());
     t = GetRunningTCBPtr();
     t->status = TS_RUNNING;
     // If an exception was flagged (eg CTRL-C) return to the catch handler
     // not the interrupted code.
     if (t->exception) {
         t->cregs[1] = t->cregs[11];   // set link register to catch handler
         t->cregs[13] = t->cregs[11];  // and the PC register
         t->regs[1] = t->exception;    // r1 = exception value
         t->exception = 0;
         t->regs[2] = 24;              // r2 = exception type
     }
     // Restore the processor registers and return using an RTE.
	epilog asm {
		lw		r1,TCB_ir1[tr]
		lw		r2,TCB_ir2[tr]
		lw		r3,TCB_ir3[tr]
		lw		r4,TCB_ir4[tr]
		lw		r5,TCB_ir5[tr]
		lw		r6,TCB_ir6[tr]
		lw		r7,TCB_ir7[tr]
		lw		r8,TCB_ir8[tr]
		lw		r9,TCB_ir9[tr]
		lw		r10,TCB_ir10[tr]
		lw		r11,TCB_ir11[tr]
		lw		r12,TCB_ir12[tr]
		lw		r13,TCB_ir13[tr]
		lw		r14,TCB_ir14[tr]
		lw		r15,TCB_ir15[tr]
		lw		r16,TCB_ir16[tr]
		lw		r17,TCB_ir17[tr]
		lw		r18,TCB_ir18[tr]
		lw		r19,TCB_ir19[tr]
		lw		r20,TCB_ir20[tr]
		lw		r21,TCB_ir21[tr]
		lw		r22,TCB_ir22[tr]
		lw		r23,TCB_ir23[tr]
		lw		r24,TCB_ir24[tr]
		lw		r25,TCB_ir25[tr]
		lw		r26,TCB_ir26[tr]
		lw		r27,TCB_ir27[tr]
		lws		ds,TCB_ids[tr]
		lws		es,TCB_ies[tr]
		lws		fs,TCB_ifs[tr]
		lws		gs,TCB_igs[tr]
		lws		hs,TCB_ihs[tr]
		lws		ss,TCB_iss[tr]
		lws		cs,TCB_ics[tr]
		lws		ds.lmt,TCB_idslmt[tr]
		lws		es.lmt,TCB_ieslmt[tr]
		lws		fs.lmt,TCB_ifslmt[tr]
		lws		gs.lmt,TCB_igslmt[tr]
		lws		hs.lmt,TCB_ihslmt[tr]
		lws		ss.lmt,TCB_isslmt[tr]
		lws		cs.lmt,TCB_icslmt[tr]
		lws		c1,TCB_ic1[tr]
		lws		c2,TCB_ic2[tr]
		lws		c3,TCB_ic3[tr]
		lws		c4,TCB_ic4[tr]
		lws		c5,TCB_ic5[tr]
		lws		c6,TCB_ic6[tr]
		lws		c7,TCB_ic7[tr]
		lws		c8,TCB_ic8[tr]
		lws		c9,TCB_ic9[tr]
		lws		c10,TCB_ic10[tr]
		lws		c11,TCB_ic11[tr]
		lws		c13,TCB_ic13[tr]
		lws		c14,TCB_ic14[tr]
		lws		pregs,TCB_ipregs[tr]
		sync
		rti
	}
}
 
void panic(char *msg)
{
     putstr(msg,84);
j1:  goto j1;
}
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
void IdleTask()
{
     int ii;
     __int32 *screen = (__int32 *)0xFFD00000;
 
//     try {
j1:  ;
         forever {
             try {
                 ii++;
                 if (getCPU()==0)
					 outh(&screen[81],ii);
             }
             catch(static __exception ex=0) {
                 if (ex&0xFFFFFFFFL==515) {
                     printf("IdleTask: CTRL-C pressed.\r\n");
                 }
                 else
                     throw ex;
             }
         }
/*
     }
     catch (static __exception ex1=0) {
         printf("IdleTask: exception %d.\r\n", ex1);
         goto j1;
     }
*/
}
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
int FMTK_KillTask(int taskno)
{
    hTCB ht;
    int nn;
    JCB *j;
 
    check_privilege();
    ht = taskno;
    if (LockSemaphore(&sys_sema,-1)) {
        RemoveFromReadyList(ht);
        RemoveFromTimeoutList(ht);
        for (nn = 0; nn < 4; nn++)
            if (tcbs[ht].hMailboxes[nn] >= 0 && tcbs[ht].hMailboxes[nn] < NR_MBX) {
                FMTK_FreeMbx(tcbs[ht].hMailboxes[nn]);
                tcbs[ht].hMailboxes[nn] = -1;
            }
        // remove task from job's task list
        j = &jcbs[tcbs[ht].hJob];
        for (nn = 0; nn < 8; nn++) {
            if (j->tasks[nn]==ht)
                j->tasks[nn] = -1;
        }
        // If the job no longer has any tasks associated with it, it is 
        // finished.
        for (nn = 0; nn < 8; nn++)
            if (j->tasks[nn]!=-1)
                break;
        if (nn == 8) {
            j->next = freeJCB;
            freeJCB = j - jcbs;
        }
        UnlockSemaphore(&sys_sema);
    }
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
int FMTK_ExitTask()
{
    check_privilege();
    KillTask(GetRunningTCB());
    asm { 
		db	$01
		db	$A6		; INT
		db	$CE
		db	$02
	}     // reschedule
j1: goto j1;
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
int FMTK_StartTask(int priority, int affinity, int adr, int parm, hJCB job)
{
    hTCB ht;
    TCB *t;
    int nn;
 
	try {
        asm {
            ldi   r1,#66
            sc    r1,hs:LEDS
        }
    check_privilege();
        asm {
            ldi   r1,#60
            sc    r1,hs:LEDS
        }
    if (LockSemaphore(&sys_sema,-1)) {
        ht = freeTCB;
        freeTCB = tcbs[ht].next;
        UnlockSemaphore(&sys_sema);
    }
        asm {
            ldi   r1,#61
            sc    r1,hs:LEDS
        }
    t = &tcbs[ht];
    t->affinity = affinity;
    t->priority = priority;
    t->hJob = job;
    // Insert into the job's list of tasks.
    for (nn = 0; nn < 8; nn++) {
        if (jcbs[job].tasks[nn]<0) {
            jcbs[job].tasks[nn] = ht;
            break;
        }
    }
        asm {
            ldi   r1,#62
            sc    r1,hs:LEDS
        }
    if (nn == 8) {
        if (LockSemaphore(&sys_sema,-1)) {
            tcbs[ht].next = freeTCB;
            freeTCB = ht;
            UnlockSemaphore(&sys_sema);
        }
        return E_TooManyTasks;
    }
        asm {
            ldi   r1,#63
            sc    r1,hs:LEDS
        }
    t->iregs[1] = parm;
    t->icregs[1] = FMTK_ExitTask;
    t->iregs[27] = (unsigned int)t->stack + 1023*8;
    t->icregs[13] = adr;
    t->icregs[14] = adr;
//    t->icr0 = 0x140000000L;
    t->startTick = 0;
    t->endTick = 0;
    t->ticks = 0;
    t->exception = 0;
        asm {
            ldi   r1,#64
            sc    r1,hs:LEDS
        }
    if (LockSemaphore(&sys_sema,-1)) {
        InsertIntoReadyList(ht);
        UnlockSemaphore(&sys_sema);
    }
        asm {
            ldi   r1,#65
            sc    r1,hs:LEDS
        }
	}
	catch(static int ex)
		printf("StartTask error: %d\r\n", ex);
    return E_Ok;
}
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
int FMTK_Sleep(int timeout)
{
    hTCB ht;
 
    check_privilege();
    if (LockSemaphore(&sys_sema,-1)) {
        ht = GetRunningTCB();
        RemoveFromReadyList(ht);
        InsertIntoTimeoutList(ht, timeout);
        UnlockSemaphore(&sys_sema);
    }
    asm { 
		db	$01
		db	$A6		; INT
		db	$CE
		db	$02
	}     // reschedule
    return E_Ok;
}
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
int FMTK_SetTaskPriority(hTCB ht, int priority)
{
    TCB *t;
 
    check_privilege();
    if (priority > 077 || priority < 000)
       return E_Arg;
    if (LockSemaphore(&sys_sema,-1)) {
        t = &tcbs[ht];
        if (t->status & (TS_RUNNING | TS_READY)) {
            RemoveFromReadyList(ht);
            t->priority = priority;
            InsertIntoReadyList(ht);
        }
        else
            t->priority = priority;
        UnlockSemaphore(&sys_sema);
    }
    return E_Ok;
}
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
void FMTKInitialize()
{
	int nn,jj;
 
    check_privilege();
//    firstcall
    {
        asm {
            ldi   r1,#20
            sc    r1,hs:LEDS
        }
        hasUltraHighPriorityTasks = 0;
        missed_ticks = 0;
 
        IOFocusTbl[0] = 0;
        IOFocusNdx = null;
        iof_switch = 0;
 
    	SetRunningTCB(0);
		tcbs[0].hJob = 0;
        UnlockSemaphore(&sys_sema);
        UnlockSemaphore(&iof_sema);
        UnlockSemaphore(&kbd_sema);
 
        for (nn = 0; nn < NR_MSG; nn++) {
            message[nn].link = nn+1;
        }
        message[NR_MSG-1].link = -1;
        freeMSG = 0;
 
        asm {
            ldi   r1,#30
            sc    r1,hs:LEDS
        }
 
        for (nn = 0; nn < NR_JCB; nn++) {
            jcbs[nn].number = nn;
            for (jj = 0; jj < 8; jj++)
                jcbs[nn].tasks[jj] = -1;
            if (nn == 0 ) {
                jcbs[nn].pVidMem = 0xFFD00000;
                jcbs[nn].pVirtVidMem = &video_bufs[nn];
                jcbs[nn].NormAttr = 0x0026B800;
				asm {
					ldi   r1,#31
					sc    r1,hs:LEDS
				}
                RequestIOFocus(&jcbs[0]);
				asm {
					ldi   r1,#34
					sc    r1,hs:LEDS
				}
           }
            else {
                 jcbs[nn].pVidMem = &video_bufs[nn];
                 jcbs[nn].pVirtVidMem = &video_bufs[nn];
                 jcbs[nn].NormAttr = 0x0026B800;
            }
				asm {
					ldi   r1,#35
					sc    r1,hs:LEDS
				}
            jcbs[nn].VideoRows = 31;
            jcbs[nn].VideoCols = 84;
            jcbs[nn].CursorRow = 0;
            jcbs[nn].CursorCol = 0;
            jcbs[nn].KeybdHead = 0;
            jcbs[nn].KeybdTail = 0;
            jcbs[nn].KeyState1 = 0;
            jcbs[nn].KeyState2 = 0;
			jcbs[nn].KeybdBufSz = 64;
        }
 
		ClearScreen();
		HomeCursor();
		printf("FMTK Initializing");
 
        asm {
            ldi   r1,#40
            sc    r1,hs:LEDS
        }
 
    	for (nn = 0; nn < 8; nn++)
    		readyQ[nn] = -1;
    	for (nn = 0; nn < NR_TCB; nn++) {
            tcbs[nn].number = nn;
    		tcbs[nn].next = nn+1;
    		tcbs[nn].prev = -1;
        asm {
            ldi   r1,#41
            sc    r1,hs:LEDS
        }
 
    		tcbs[nn].status = 0;
    		tcbs[nn].priority = 070;
    		tcbs[nn].affinity = 0;
        asm {
            ldi   r1,#46
            sc    r1,hs:LEDS
        }
 
    		tcbs[nn].sys_stack = &sys_stacks[nn] + 511;
    		tcbs[nn].bios_stack = &bios_stacks[nn] + 511;
        asm {
            ldi   r1,#42
            sc    r1,hs:LEDS
        }
 
    		tcbs[nn].stack = &stacks[nn] + 1023;
    		tcbs[nn].hJob = 0;
    		tcbs[nn].timeout = 0;
        asm {
            ldi   r1,#43
            sc    r1,hs:LEDS
        }
 
    		tcbs[nn].hMailboxes[0] = -1;
    		tcbs[nn].hMailboxes[1] = -1;
    		tcbs[nn].hMailboxes[2] = -1;
    		tcbs[nn].hMailboxes[3] = -1;
        asm {
            ldi   r1,#44
            sc    r1,hs:LEDS
        }
 
    		if (nn<2) {
                tcbs[nn].affinity = nn;
                tcbs[nn].priority = 030;
            }
            tcbs[nn].exception = 0;
        asm {
            ldi   r1,#47
            sc    r1,hs:LEDS
        }
 
    	}
    	tcbs[NR_TCB-1].next = -1;
    	freeTCB = 2;
        asm {
            ldi   r1,#48
            sc    r1,hs:LEDS
        }
    	InsertIntoReadyList(0);
    	InsertIntoReadyList(1);
    	tcbs[0].status = TS_RUNNING;
    	tcbs[1].status = TS_RUNNING;
        asm {
            ldi   r1,#49
            sc    r1,hs:LEDS
        }
    	SetRunningTCB(0);
    	TimeoutList = -1;
    	set_vector(4,FMTK_SystemCall);
    	set_vector(2,FMTK_SchedulerIRQ2);
    	set_vector(194,FMTK_SchedulerIRQ);
		set_vector(195,KeybdIRQ);
        asm {
            ldi   r1,#50
            sc    r1,hs:LEDS
        }
    	FMTK_StartTask(030, 0, FocusSwitcher, 0, 0);
        asm {
            ldi   r1,#55
            sc    r1,hs:LEDS
        }
    	FMTK_StartTask(033, 0, shell, 0, 1);
        asm {
            ldi   r1,#52
            sc    r1,hs:LEDS
        }
//    	FMTK_StartTask(055, 0, gfx_demo, 0, 1);
        FMTK_StartTask(077, 0, IdleTask, 0, 0);
        asm {
            ldi   r1,#53
            sc    r1,hs:LEDS
        }
//      FMTK_StartTask(077, 1, IdleTask, 0, 0);
    	FMTK_Inited = 0x12345678;
        asm {
            ldi   r1,#56
            sc    r1,hs:LEDS
        }
    }
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.