]> git.sesse.net Git - pistorm/blob - a314/a314device/startup.c
Add Meson build files.
[pistorm] / a314 / a314device / startup.c
1 /*
2  * Copyright 2020-2021 Niklas Ekström
3  */
4
5 #include <exec/types.h>
6 #include <exec/memory.h>
7 #include <exec/tasks.h>
8 #include <hardware/intbits.h>
9 #include <libraries/expansion.h>
10 #include <libraries/expansionbase.h>
11
12 #include <proto/exec.h>
13 #include <proto/expansion.h>
14
15 #include <exec/nodes.h>
16 #include <exec/interrupts.h>
17
18 #include "a314.h"
19 #include "device.h"
20 #include "protocol.h"
21 #include "startup.h"
22 #include "fix_mem_region.h"
23 #include "debug.h"
24
25 #define A314_MANUFACTURER 0x07db
26 #define A314_PRODUCT 0xa3
27
28 #define TASK_PRIORITY 80
29 #define TASK_STACK_SIZE 1024
30
31 struct ExpansionBase *ExpansionBase;
32 struct MsgPort task_mp;
33 struct Task *task;
34 struct ComArea *ca;
35
36 struct InterruptData
37 {
38         struct Task *task;
39         struct ComArea *ca;
40 };
41
42 struct InterruptData interrupt_data;
43 struct Interrupt ports_interrupt;
44
45 extern void task_main();
46 extern void init_sockets();
47 extern void IntServer();
48
49 void NewList(struct List *l)
50 {
51         l->lh_Head = (struct Node *)&(l->lh_Tail);
52         l->lh_Tail = NULL;
53         l->lh_TailPred = (struct Node *)&(l->lh_Head);
54 }
55
56 static struct Task *create_task(char *name, long priority, char *initialPC, unsigned long stacksize)
57 {
58         char *stack = AllocMem(stacksize, MEMF_CLEAR);
59         if (stack == NULL)
60                 return NULL;
61
62         struct Task *tc = AllocMem(sizeof(struct Task), MEMF_CLEAR | MEMF_PUBLIC);
63         if (tc == NULL)
64         {
65                 FreeMem(stack, stacksize);
66                 return NULL;
67         }
68
69         tc->tc_Node.ln_Type = NT_TASK;
70         tc->tc_Node.ln_Pri = priority;
71         tc->tc_Node.ln_Name = name;
72         tc->tc_SPLower = (APTR)stack;
73         tc->tc_SPUpper = (APTR)(stack + stacksize);
74         tc->tc_SPReg = (APTR)(stack + stacksize);
75
76         AddTask(tc, initialPC, 0);
77         return tc;
78 }
79
80 static void init_message_port()
81 {
82         task_mp.mp_Node.ln_Name = device_name;
83         task_mp.mp_Node.ln_Pri = 0;
84         task_mp.mp_Node.ln_Type = NT_MSGPORT;
85         task_mp.mp_Flags = PA_SIGNAL;
86         task_mp.mp_SigBit = SIGB_MSGPORT;
87         task_mp.mp_SigTask = task;
88         NewList(&(task_mp.mp_MsgList));
89 }
90
91 static void add_interrupt_handler()
92 {
93         interrupt_data.task = task;
94         interrupt_data.ca = ca;
95
96         ports_interrupt.is_Node.ln_Type = NT_INTERRUPT;
97         ports_interrupt.is_Node.ln_Pri = 0;
98         ports_interrupt.is_Node.ln_Name = device_name;
99         ports_interrupt.is_Data = (APTR)&interrupt_data;
100         ports_interrupt.is_Code = IntServer;
101
102         AddIntServer(INTB_PORTS, &ports_interrupt);
103 }
104
105 BOOL task_start()
106 {
107         ExpansionBase = (struct ExpansionBase *)OpenLibrary(EXPANSIONNAME, 0);
108         if (!ExpansionBase)
109                 return FALSE;
110
111         struct ConfigDev *cd = FindConfigDev(NULL, A314_MANUFACTURER, A314_PRODUCT);
112         if (!cd)
113         {
114                 CloseLibrary((struct Library *)ExpansionBase);
115                 return FALSE;
116         }
117
118         ca = (struct ComArea *)cd->cd_BoardAddr;
119
120         if (!fix_memory())
121                 return FALSE;
122
123         task = create_task(device_name, TASK_PRIORITY, (void *)task_main, TASK_STACK_SIZE);
124         if (task == NULL)
125         {
126                 debug_printf("Unable to create task\n");
127                 return FALSE;
128         }
129
130         init_message_port();
131         init_sockets();
132
133         ca->a_enable = 0;
134         unsigned char discard_value = ca->a_events;
135
136         ca->r_events = R_EVENT_STARTED;
137
138         add_interrupt_handler();
139
140         ca->a_enable = A_EVENT_R2A_TAIL;
141
142         return TRUE;
143 }