2 Copyright © 2009, The AROS Development Team. All rights reserved.
5 Desc: functions for memory-stored RawIOInit/RawPutChar
9 #include <proto/exec.h>
14 #define BLOCK_SIZE (256 * 1024)
15 #define TASK_PRIORITY 0
16 #define STACK_SIZE 4096
19 static const TEXT name
[] = "bifteck";
20 static const TEXT data_missed_msg
[] = "<*** GAP IN DATA ***>\n";
25 ULONG length
; /* number of data bytes that follow */
30 struct SignalSemaphore lock
;
31 struct MinList buffers
;
32 struct LogBlock
*block
;
38 static void LogTask();
40 static struct LogData
*data
;
41 static struct Task
*task
;
42 static BOOL data_missed
= FALSE
;
43 static struct LogBlock
*next_block
= NULL
;
46 /*****i***********************************************************************
49 AROS_LH0(void, MemoryRawIOInit
,
52 struct ExecBase
*, SysBase
, 84, Exec
)
55 This is a private function. It initializes raw IO. After you
56 have called this function, you can use (!RawMayGetChar()) and
66 This function is for very low level debugging only.
73 RawPutChar(), RawMayGetChar()
77 *****************************************************************************/
84 /* Initialise data struct, memory pool and semaphore */
86 data
= AllocMem(sizeof(struct LogData
), MEMF_PUBLIC
| MEMF_CLEAR
);
92 data
->pool
= CreatePool(MEMF_PUBLIC
, BLOCK_SIZE
, BLOCK_SIZE
);
93 NEWLIST(&data
->buffers
);
94 InitSemaphore(&data
->lock
);
95 data
->lock
.ss_Link
.ln_Name
= (char *)name
;
96 if (data
->pool
== NULL
)
103 /* Allocate initial buffer */
105 data
->block
= (struct LogBlock
*)AllocPooled(data
->pool
, BLOCK_SIZE
);
106 data
->block
->length
= BLOCK_SIZE
- sizeof(struct LogBlock
);
107 if (data
->block
== NULL
)
113 /* Add semaphore/data to public list along with initial buffer */
115 AddTail((struct List
*)&data
->buffers
, (struct Node
*)data
->block
);
116 AddSemaphore(&data
->lock
);
121 /* Create a task that will allocate buffers as needed */
124 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
125 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
126 if (task
== NULL
|| stack
== NULL
)
132 /* Initialise and start task */
134 task
->tc_Node
.ln_Type
= NT_TASK
;
135 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
136 task
->tc_Node
.ln_Name
= (char *)name
;
137 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
138 task
->tc_SPLower
= stack
;
139 task
->tc_SPReg
= stack
+ STACK_SIZE
;
140 NEWLIST(&task
->tc_MemEntry
);
141 task
->tc_UserData
= data
;
143 if (AddTask(task
, LogTask
, NULL
) == NULL
)
149 /* Signal task to allocate the second buffer */
151 Signal(task
, SIGF_SINGLE
);
162 /*****i***********************************************************************
165 AROS_LH1(void, MemoryRawPutChar
,
168 AROS_LHA(UBYTE
, chr
, D0
),
171 struct ExecBase
*, SysBase
, 86, Exec
)
174 Emits a single character.
177 chr - The character to emit
183 This function is for very low level debugging only.
190 RawIOInit(), RawPutChar(), RawMayGetChar()
194 *****************************************************************************/
198 struct LogBlock
*new_block
;
200 /* Write to screen as well */
204 /* Check if we need to move on to a new block */
206 if (data
->block_pos
== data
->block
->length
)
208 /* Move on to the next block if it exists */
211 if ((new_block
= next_block
) != NULL
)
215 if (new_block
!= NULL
)
217 data
->block
= new_block
;
220 /* If data was missed, add a warning to the log */
224 CopyMem(data_missed_msg
,
225 (UBYTE
*)data
->block
+ sizeof(struct LogBlock
),
226 strlen(data_missed_msg
));
227 data
->block_pos
+= strlen(data_missed_msg
);
231 /* Ask for another new block, which will hopefully be allocated
232 * by the time we need it */
234 Signal(task
, SIGF_SINGLE
);
238 /* Store character in buffer if there's space */
240 if (data
->block_pos
!= data
->block
->length
)
243 ((UBYTE
*)data
->block
)[sizeof(struct LogBlock
) + data
->block_pos
++] =
253 static void LogTask()
255 struct LogBlock
*block
;
257 /* Add a new buffer block to the list each time we're signalled */
259 while (Wait(SIGF_SINGLE
))
261 block
= (struct LogBlock
*)AllocPooled(data
->pool
, BLOCK_SIZE
);
264 block
->length
= BLOCK_SIZE
- sizeof(struct LogBlock
);
270 ObtainSemaphore(&data
->lock
);
271 AddTail((struct List
*)&data
->buffers
, (struct Node
*)block
);
272 ReleaseSemaphore(&data
->lock
);