2 * AcessOS EDI Interface
5 * By John Hodge (thePowersGang)
7 * This file has been released into the public domain.
8 * You are free to use it as you wish.
14 uint16_t State; // 0: Unallocated, 1: Allocated, 2: Initialised, (Bit 0x8000 set if in heap)
19 #define NUM_PREALLOC_PORTS 128
20 tEdiPort gEdi_PortObjects[NUM_PREALLOC_PORTS];
24 * \fn object_pointer Edi_Int_IO_Construct(void)
25 * \brief Creates a new IO Port Object
26 * \return Pointer to object
28 object_pointer Edi_Int_IO_Construct(void)
32 // Search for a free preallocated port
33 for( i = 0; i < NUM_PREALLOC_PORTS; i ++ )
35 if(gEdi_PortObjects[i].State) continue;
36 gEdi_PortObjects[i].State = 1;
37 gEdi_PortObjects[i].Num = 0;
38 return &gEdi_PortObjects[i];
40 // Else, use heap space
41 ret = malloc( sizeof(tEdiPort) );
48 * \fn void Edi_Int_IO_Destruct(object_pointer Object)
49 * \brief Destruct an IO Port Object
50 * \param Object Object to destroy
52 void Edi_Int_IO_Destruct(object_pointer Object)
56 VALIDATE_PTR(Object,);
57 obj = GET_DATA(Object);
59 if(obj->State & 0x8000) { // If in heap, free
61 } else { // Otherwise, mark as unallocated
67 * \fn int32_t Edi_Int_IO_InitPort(object_pointer Object, uint16_t Port)
68 * \brief Initialises an IO Port
69 * \param Object Object Pointer (this)
70 * \param Port Port Number to use
72 int32_t Edi_Int_IO_InitPort(object_pointer Object, uint16_t Port)
76 VALIDATE_PTR(Object, 0);
77 obj = GET_DATA(Object);
79 if( !obj->State ) return 0;
81 obj->State &= ~0x3FFF;
82 obj->State |= 2; // Set initialised flag
87 * \fn uint16_t Edi_Int_IO_GetPortNum(object_pointer Object)
88 * \brief Returns the port number associated with the object
89 * \param Object Port Object to get number from
92 uint16_t Edi_Int_IO_GetPortNum(object_pointer Object)
96 VALIDATE_PTR(Object, 0);
97 obj = GET_DATA(Object);
99 if( !obj->State ) return 0;
105 * \fn int32_t Edi_Int_IO_ReadByte(object_pointer Object, uint8_t *out)
106 * \brief Read a byte from an IO port
107 * \param Object Port Object
108 * \param out Pointer to put read data
110 int32_t Edi_Int_IO_ReadByte(object_pointer Object, uint8_t *out)
114 VALIDATE_PTR(Object, 0);
115 obj = GET_DATA(Object);
117 if( !obj->State ) return 0;
118 if( obj->State & 1 ) return -1; // Unintialised
120 __asm__ __volatile__ ( "inb %%dx, %%al" : "=a" (*out) : "d" ( obj->Num ) );
126 * \fn int32_t Edi_Int_IO_ReadWord(object_pointer Object, uint16_t *out)
127 * \brief Read a word from an IO port
128 * \param Object Port Object
129 * \param out Pointer to put read data
131 int32_t Edi_Int_IO_ReadWord(object_pointer Object, uint16_t *out)
136 VALIDATE_PTR(Object, 0);
137 obj = GET_DATA(Object);
138 if( !obj->State ) return 0;
139 if( obj->State & 1 ) return -1; // Unintialised
141 __asm__ __volatile__ ( "inw %%dx, %%ax" : "=a" (*out) : "d" ( obj->Num ) );
147 * \fn int32_t Edi_Int_IO_ReadDWord(object_pointer Object, uint32_t *out)
148 * \brief Read a double word from an IO port
149 * \param Object Port Object
150 * \param out Pointer to put read data
152 int32_t Edi_Int_IO_ReadDWord(object_pointer Object, uint32_t *out)
157 VALIDATE_PTR(Object, 0);
158 obj = GET_DATA(Object);
159 if( !obj->State ) return 0;
160 if( obj->State & 1 ) return -1; // Unintialised
162 __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*out) : "d" ( obj->Num ) );
168 * \fn int32_t Edi_Int_IO_ReadQWord(object_pointer Object, uint64_t *out)
169 * \brief Read a quad word from an IO port
170 * \param Object Port Object
171 * \param out Pointer to put read data
173 int32_t Edi_Int_IO_ReadQWord(object_pointer Object, uint64_t *out)
175 uint32_t *out32 = (uint32_t*)out;
178 VALIDATE_PTR(Object, 0);
179 obj = GET_DATA(Object);
180 if( !obj->State ) return 0;
181 if( obj->State & 1 ) return -1; // Unintialised
183 __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*out32) : "d" ( obj->Num ) );
184 __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*(out32+1)) : "d" ( obj->Num+4 ) );
190 * \fn int32_t Edi_Int_IO_ReadString(object_pointer Object, uint32_t Length, uint8_t *out)
191 * \brief Read a byte from an IO port
192 * \param Object Port Object
193 * \param Length Number of bytes to read
194 * \param out Pointer to put read data
196 int32_t Edi_Int_IO_ReadString(object_pointer Object, uint32_t Length, uint8_t *out)
200 VALIDATE_PTR(Object, 0);
201 obj = GET_DATA(Object);
202 if( !obj->State ) return 0;
203 if( obj->State & 1 ) return -1; // Unintialised
205 __asm__ __volatile__ ( "rep insb" : : "c" (Length), "D" (out), "d" ( obj->Num ) );
211 * \fn int32_t Edi_Int_IO_WriteByte(object_pointer Object, uint8_t in)
212 * \brief Write a byte from an IO port
213 * \param Object Port Object
214 * \param in Data to write
216 int32_t Edi_Int_IO_WriteByte(object_pointer Object, uint8_t in)
220 VALIDATE_PTR(Object, 0);
221 obj = GET_DATA(Object);
222 if( !obj->State ) return 0;
223 if( obj->State & 1 ) return -1; // Unintialised
225 __asm__ __volatile__ ( "outb %%al, %%dx" : : "a" (in), "d" ( obj->Num ) );
231 * \fn int32_t Edi_Int_IO_WriteWord(object_pointer Object, uint16_t in)
232 * \brief Write a word from an IO port
233 * \param Object Port Object
234 * \param in Data to write
236 int32_t Edi_Int_IO_WriteWord(object_pointer Object, uint16_t in)
240 VALIDATE_PTR(Object, 0);
241 obj = GET_DATA(Object);
242 if( !obj->State ) return 0;
243 if( obj->State & 1 ) return -1; // Unintialised
245 __asm__ __volatile__ ( "outw %%ax, %%dx" : : "a" (in), "d" ( obj->Num ) );
251 * \fn int32_t Edi_Int_IO_WriteDWord(object_pointer Object, uint32_t in)
252 * \brief Write a double word from an IO port
253 * \param Object Port Object
254 * \param in Data to write
256 int32_t Edi_Int_IO_WriteDWord(object_pointer Object, uint32_t in)
260 VALIDATE_PTR(Object, 0);
261 obj = GET_DATA(Object);
262 if( !obj->State ) return 0;
263 if( obj->State & 1 ) return -1; // Unintialised
265 __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (in), "d" ( obj->Num ) );
271 * \fn int32_t Edi_Int_IO_WriteQWord(object_pointer Object, uint64_t in)
272 * \brief Write a quad word from an IO port
273 * \param Object Port Object
274 * \param in Data to write
276 int32_t Edi_Int_IO_WriteQWord(object_pointer Object, uint64_t in)
278 uint32_t *in32 = (uint32_t*)∈
281 VALIDATE_PTR(Object, 0);
282 obj = GET_DATA(Object);
283 if( !obj->State ) return 0;
284 if( obj->State & 1 ) return -1; // Unintialised
286 __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (*in32), "d" ( obj->Num ) );
287 __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (*(in32+1)), "d" ( obj->Num+4 ) );
293 * \fn int32_t Edi_Int_IO_WriteString(object_pointer Object, uint32_t Length, uint8_t *in)
294 * \brief Read a byte from an IO port
295 * \param Object Port Object
296 * \param Length Number of bytes to write
297 * \param in Pointer to of data to write
299 int32_t Edi_Int_IO_WriteString(object_pointer Object, uint32_t Length, uint8_t *in)
303 VALIDATE_PTR(Object, 0);
304 obj = GET_DATA(Object);
305 if( !obj->State ) return 0;
306 if( obj->State & 1 ) return -1; // Unintialised
308 __asm__ __volatile__ ( "rep outsb" : : "c" (Length), "D" (in), "d" ( obj->Num ) );
313 // === CLASS DECLARATION ===
314 /*static edi_variable_declaration_t *scEdi_Int_Variables_IO[] = {
316 {"pointer", "port_object", 0},
317 {"uint16_t", "port", 0}
320 {"pointer", "port_object", 0}
323 {"pointer", "port_object", 0},
324 {"pointer int8_t", "out", 0}
327 static edi_function_declaration_t scEdi_Int_Functions_IO[] = {
328 {"int32_t", "init_io_port", 1, 2, NULL, //scEdi_Int_Variables_IO[0],
329 (function_pointer)Edi_Int_IO_InitPort
331 {"uint16_t", "get_port_number", 1, 1, NULL, //scEdi_Int_Variables_IO[1],
332 (function_pointer)Edi_Int_IO_GetPortNum
334 {"int32_t", "read_byte_io_port", 1, 2, NULL, //scEdi_Int_Variables_IO[2],
335 (function_pointer)Edi_Int_IO_ReadByte
337 {"int32_t", "read_word_io_port", 1, 2, NULL/*{
338 {"pointer", "port_object", 0},
339 {"pointer int16_t", "out", 0}
341 (function_pointer)Edi_Int_IO_ReadWord
343 {"int32_t", "read_long_io_port", 1, 2, NULL/*{
344 {"pointer", "port_object", 0},
345 {"pointer int32_t", "out", 0}
347 (function_pointer)Edi_Int_IO_ReadDWord
349 {"int32_t", "read_longlong_io_port", 1, 2, NULL/*{
350 {"pointer", "port_object", 0},
351 {"pointer int64_t", "out", 0}
353 (function_pointer)Edi_Int_IO_ReadQWord
355 {"int32_t", "read_string_io_port", 1, 3, NULL/*{
356 {"pointer", "port_object", 0},
357 {"int32_T", "data_length", 0},
358 {"pointer int64_t", "out", 0}
360 (function_pointer)Edi_Int_IO_ReadString
363 {"int32_t", "write_byte_io_port", 1, 2, NULL/*{
364 {"pointer", "port_object", 0},
367 (function_pointer)Edi_Int_IO_WriteByte},
368 {"int32_t", "write_word_io_port", 1, 2, NULL/*{
369 {"pointer", "port_object", 0},
372 (function_pointer)Edi_Int_IO_WriteWord},
373 {"int32_t", "write_long_io_port", 1, 2, NULL/*{
374 {"pointer", "port_object", 0},
377 (function_pointer)Edi_Int_IO_WriteDWord},
378 {"int32_t", "write_longlong_io_port", 1, 2, NULL/*{
379 {"pointer", "port_object", 0},
382 (function_pointer)Edi_Int_IO_WriteQWord}
384 static edi_class_declaration_t scEdi_Int_Class_IO =
386 IO_PORT_CLASS, 1, 12,
387 scEdi_Int_Functions_IO,
388 Edi_Int_IO_Construct,