]> git.sesse.net Git - pistorm/blob - a314/a314device/startup.c
Add A314 emulation
[pistorm] / a314 / a314device / startup.c
1 #include <exec/types.h>
2 #include <exec/memory.h>
3 #include <exec/tasks.h>
4 #include <hardware/intbits.h>
5
6 #include <proto/exec.h>
7
8 #include "a314.h"
9 #include "device.h"
10 #include "protocol.h"
11 #include "startup.h"
12 #include "fix_mem_region.h"
13 #include "debug.h"
14
15 #define TASK_PRIORITY 80
16 #define TASK_STACK_SIZE 1024
17
18 struct MsgPort task_mp;
19 struct Task *task;
20 struct ComArea *ca;
21
22 struct Interrupt ports_interrupt;
23
24 extern void task_main();
25 extern void init_sockets();
26 extern void IntServer();
27
28 void NewList(struct List *l)
29 {
30         l->lh_Head = (struct Node *)&(l->lh_Tail);
31         l->lh_Tail = NULL;
32         l->lh_TailPred = (struct Node *)&(l->lh_Head);
33 }
34
35 static struct Task *create_task(char *name, long priority, char *initialPC, unsigned long stacksize)
36 {
37         char *stack = AllocMem(stacksize, MEMF_CLEAR);
38         if (stack == NULL)
39                 return NULL;
40
41         struct Task *tc = AllocMem(sizeof(struct Task), MEMF_CLEAR | MEMF_PUBLIC);
42         if (tc == NULL)
43         {
44                 FreeMem(stack, stacksize);
45                 return NULL;
46         }
47
48         tc->tc_Node.ln_Type = NT_TASK;
49         tc->tc_Node.ln_Pri = priority;
50         tc->tc_Node.ln_Name = name;
51         tc->tc_SPLower = (APTR)stack;
52         tc->tc_SPUpper = (APTR)(stack + stacksize);
53         tc->tc_SPReg = (APTR)(stack + stacksize);
54
55         AddTask(tc, initialPC, 0);
56         return tc;
57 }
58
59 static void init_message_port()
60 {
61         task_mp.mp_Node.ln_Name = device_name;
62         task_mp.mp_Node.ln_Pri = 0;
63         task_mp.mp_Node.ln_Type = NT_MSGPORT;
64         task_mp.mp_Flags = PA_SIGNAL;
65         task_mp.mp_SigBit = SIGB_MSGPORT;
66         task_mp.mp_SigTask = task;
67         NewList(&(task_mp.mp_MsgList));
68 }
69
70 static void add_interrupt_handler()
71 {
72         ports_interrupt.is_Node.ln_Type = NT_INTERRUPT;
73         ports_interrupt.is_Node.ln_Pri = 0;
74         ports_interrupt.is_Node.ln_Name = device_name;
75         ports_interrupt.is_Data = (APTR)task;
76         ports_interrupt.is_Code = IntServer;
77
78         AddIntServer(INTB_PORTS, &ports_interrupt);
79 }
80
81 BOOL task_start()
82 {
83         if (!fix_memory())
84                 return FALSE;
85
86         ca = (struct ComArea *)COM_AREA_BASE;
87
88         task = create_task(device_name, TASK_PRIORITY, (void *)task_main, TASK_STACK_SIZE);
89         if (task == NULL)
90         {
91                 debug_printf("Unable to create task\n");
92                 return FALSE;
93         }
94
95         init_message_port();
96         init_sockets();
97
98         ca->a_enable = 0;
99         unsigned char discard_value = ca->a_events;
100
101         ca->r_events = R_EVENT_STARTED;
102
103         add_interrupt_handler();
104
105         ca->a_enable = A_EVENT_R2A_TAIL;
106
107         return TRUE;
108 }