2 #define FFRBR ( 0x40100000 ) // Receive Buffer Register (read only)
3 #define FFTHR ( 0x40100000 ) // Transmit Holding Register (write only)
4 #define FFIER ( 0x40100004 ) // Interrupt Enable Register (read/write)
5 #define FFIIR ( 0x40100008 ) // Interrupt ID Register (read only)
6 #define FFFCR ( 0x40100008 ) // FIFO Control Register (write only)
7 #define FFLCR ( 0x4010000C ) // Line Control Register (read/write)
8 #define FFMCR ( 0x40100010 ) // Modem Control Register (read/write)
9 #define FFLSR ( 0x40100014 ) // Line Status Register (read only)
10 #define FFMSR ( 0x40100018 ) // Modem Status Register (read only)
11 #define FFSPR ( 0x4010001C ) // Scratch Pad Register (read/write)
12 #define FFDLL ( 0x40100000 ) // baud divisor lower byte (read/write)
13 #define FFDLH ( 0x40100004 ) // baud divisor higher byte (read/write)
14 #define FFISR ( 0x40100020 ) // slow Infrared Select Register (read/write)
17 #define ANY_DISP_SEG 0x8000 // Set if should be displayed as segmented
22 typedef unsigned long DWORD;
23 typedef unsigned short WORD;
24 typedef unsigned char BYTE;
30 typedef DWORD * PDWORD;
35 typedef const char * PCSTR;
38 typedef DWORD ROMDWORD;
41 typedef PCSTR PROMCHAR;
44 typedef void (* WRITECHAR)(BYTE);
49 // Address structure for printf %la and ScanAddress:
56 } AnyAddress, * FPANYADDRESS;
61 if (value >= 'A' && value <='Z')
62 return (value + 0x20);
69 static void iprintf(char * format, ...); // Internal printf
71 static WRITECHAR writechar;
74 ** define global storage for the sprint routine
77 unsigned short sbindex;
82 static void output_char(unsigned char data) {
83 while(!((*(volatile unsigned long int *)FFLSR) & 0x40)); // wait here for fifo not full
84 *(volatile unsigned long int *)FFTHR = (unsigned long int) data;
90 /////////////////////////////////////////////////////////////////////////
91 // FillSpaces() prints out a given number of spaces or zeroes
93 static void FillSpaces(int Size, BOOL DoIt, BOOL FillZero)
97 writechar((char) (FillZero ? '0' : ' '));
100 /////////////////////////////////////////////////////////////////////////
101 // HexDigit() returns the correct hexadecimal digit for a number
103 char HexDigit(DWORD value, char UpperLower)
106 return (char)(value + '0');
108 return (char)(value-10 + 'A' + UpperLower - 'X');
111 /////////////////////////////////////////////////////////////////////////
112 // PrintAddress prints a standard (segment:offset) or long address.
113 // It is an internal routine used by printf.
115 static void PrintAddress(PDWORD param, BOOL Long, WORD StringIndex)
117 static BYTE string0[] = "%04X:%04lX";
118 static BYTE string1[] = "%04x:%04lx";
119 static BYTE string2[] = "%01X/%07lX";
120 static BYTE string3[] = "%01x/%07lx";
122 static BYTE * strings[] = {string0,string1,string2,string3};
126 DWORD LinearAddress = param[0];
127 DWORD MemSpace = param[1];
132 a = (FPANYADDRESS)*((PDWORD)param);
133 LinearAddress = a->LinearAddress;
134 MemSpace = a->MemSpace;
137 if ((a->Flags & ANY_DISP_SEG) == 0)
141 MemSpace = ((WORD)(LinearAddress >> 4) - SegValue);
143 MemSpace += SegValue;
144 LinearAddress -= ((DWORD)MemSpace << 4);
147 iprintf(strings[StringIndex],MemSpace,LinearAddress);
150 /////////////////////////////////////////////////////////////////////////
151 // Minimal printf implementation. Supports:
152 // % [-] [0] [<length>] [l] [s|c|x|i|d|u]
155 // 0 == Fill field with zeroes
156 // length == Minimum field width
157 // l == Doubleword for x|i|d|u
158 // s == string pointer
159 // c == single character
161 // i,d == signed decimal number
162 // u == unsigned number
163 // a == address (segment:offset)
164 // la == long address (AnyAddress type)
166 void vpprintf(WRITECHAR outroutine, PCSTR * ptrptr)
168 static BYTE Percent[] = "%";
169 static BYTE PercentQuery[] = "%???";
170 static BYTE NullMsg[] = "";
173 PDWORD param = (PDWORD)(ptrptr+1);
177 enum {ParseIncomplete, ParseString, ParseNum, ParsePercent,
178 ParseAddress, ParseNonsense} ParseType;
184 char NumString[16]; // Holds largest number
186 writechar = outroutine;
190 switch (ch = *(ptr++))
202 ParseType = ParseIncomplete;
203 while (ParseType == ParseIncomplete)
204 switch (tolower(ch = *(ptr++)))
208 ParseType = ParseNonsense;
223 MinWidth = MinWidth*10 + ch - '0';
231 sPtr = (PSTR)(param++);
233 ParseType = ParseString;
236 sPtr = (PSTR)param[0];
238 ParseType = ParseString;
242 ParseType = ParseNum;
248 ParseType = ParseNum;
251 ParseType = ParseAddress;
254 ParseType = ParsePercent;
257 ParseType = ParseNonsense;
263 sPtr = (PSTR)Percent;
266 sPtr = (PSTR)PercentQuery;
271 FillSpaces(MinWidth,!LeftJustify,ZeroFill);
272 PrintAddress(param,Long,(WORD)(ch=='a'));
273 sPtr = (PSTR)NullMsg;
281 ** The following modification made to support the Microsoft 32 bit
282 ** compiler (which is required because the MaCraigor API uses a
283 ** DLL, which is only supported by the 32 bit compiler).
285 ** The 16 bit compiler aligns stack parameters as 16 bit words. Thus
286 ** a byte value passed as a parameter to the printf will be padded by
287 ** a zero to take up one word on the stack. The else statement below
288 ** would correctly get the byte value and then bump the parameter pointer
289 ** past the pad char to point at the next parameter.
291 ** But in the 32 bit compiler, parameters are passed as DWORDs, or unsigned
292 ** longs, and take up 32 bits on the stack. Thus, the if(Long) is
293 ** always true for the purposes of incrementing the param pointer. param
294 ** is of type LPWORD, so one increment moves it by two bytes.
298 value = *((PDWORD)param);
302 // value = *(((LPWORD)param)++);
305 Signed = (value >= (0x8000UL << (16*Long)));
314 sPtr = &NumString[sizeof(NumString)];
317 *(--sPtr) = HexDigit(value % NumBase,ch);
324 MinWidth -= strlen(sPtr);
325 FillSpaces(MinWidth,!LeftJustify,ZeroFill);
327 writechar(*(sPtr++));
328 FillSpaces(MinWidth,LeftJustify,FALSE);
333 // if this was a line feed, also add a Carriage return
334 if(ch == 0xa) writechar(0xd);
340 /////////////////////////////////////////////////////////////////////////
341 // iprintf - Internal printf for recursion, doesn't alter writechar
343 static void iprintf(char * format, ...)
345 vpprintf(writechar,(PCSTR *)&format);
348 /////////////////////////////////////////////////////////////////////////
351 void dprintf(char * format, ...)
353 vpprintf(output_char,(PCSTR *)&format);
356 /* character write routine for sprintf */
357 void putspbuf(char data)
359 sprintbuf[sbindex++] = data;
361 /////////////////////////////////////////////////////////////////////////
364 void sprintf(char * buffer, char * format, ...)
367 vpprintf((WRITECHAR)putspbuf,(PCSTR *)&format);
369 strcpy(buffer,sprintbuf);