|
|
1.1 root 1: /* netboot
2: *
3: * misc.c,v
4: * Revision 1.1 1993/07/08 16:04:03 brezak
5: * Diskless boot prom code from Jim McKim ([email protected])
6: *
7: * Revision 1.3 1993/06/30 20:17:54 mckim
8: * Exit to BIOS in exit().
9: *
10: * Revision 1.2 1993/06/08 14:22:37 mckim
11: * Fast in line assembly bcopy(), bzero().
12: *
13: * Revision 1.1.1.1 1993/05/28 11:41:07 mckim
14: * Initial version.
15: *
16: */
17:
18: #include "proto.h"
19:
20: #if defined(DEBUG)
21:
22: void
23: DUMP_STRUCT(char *s, u_char *p, u_int ps) {
24: int i;
25: printf("struct %s (@0x%x %d bytes): ", s, p, ps);
26: for (i=0; i<ps; i++)
27: printf("%x ", *(p+i));
28: printf("\n");
29: }
30:
31: #else
32:
33: void
34: DUMP_STRUCT(char *s, u_char *p, u_int ps) {
35: }
36:
37:
38: #endif
39:
40:
41: char *
42: strncpy(char *dst, const char *src, int len) {
43: char *p=dst;
44: while (*src && len--)
45: *p++ = *src++;
46: *p = 0;
47: return dst;
48: }
49:
50:
51: int
52: strlen(const char *s) {
53: int len = 0;
54: while (*s++)
55: len++;
56: return len;
57: }
58:
59:
60: char *
61: strncat(char *s, const char *append, int len) {
62: int offset = strlen(s);
63: strncpy(s+offset, append, len);
64: return s;
65: }
66:
67:
68: int
69: strcmp(const char *s, const char *t) {
70: while (*s == *t++)
71: if (*s++ == '\0')
72: return 0;
73: return *s - *--t;
74: }
75:
76:
77: int
78: bcmp(const void *p, const void *q, int len) {
79: while (len--)
80: if (*((const char *)p)++ != *((const char *)q)++)
81: return 1;
82: return 0;
83: }
84:
85:
86: void volatile exit(int v) {
87: #ifdef DEBUG
88: L: goto L;
89: #else
90: ExitToBios();
91: #endif
92: }
93:
94:
95: #define RTC_ADDR 0x70
96: #define RTC_DATA 0x71
97:
98: #define RTC_SECONDS 0x00
99: #define RTC_MINUTES 0x02
100: #define RTC_HOURS 0x04
101: #define RTC_STATUS_A 0x0a
102: #define RTC_BASEMEM_LO 0x15
103: #define RTC_BASEMEM_HI 0x16
104: #define RTC_EXPMEM_LO 0x30
105: #define RTC_EXPMEM_HI 0x31
106:
107: static u_char
108: ReadRtcRam(u_short addr) {
109: for (;;) {
110: /* wait if updating */
111: outb(RTC_ADDR, RTC_STATUS_A);
112: if (!(inb(RTC_DATA) & 0x80))
113: break;
114: }
115: outb(RTC_ADDR, addr);
116: return inb(RTC_DATA);
117: }
118:
119: static void
120: getrtc(u_long *hrs, u_long *mins, u_long *secs) {
121: /* TBD - replace args with single arg - struct or sec of day */
122: /*
123: * Get real time clock values (they are in BCD)
124: */
125: #ifdef USE_BIOS
126: asm("
127: call _prot_to_real
128: movb $0x02,%ah # read real time clock
129: int $0x1a
130: .byte 0x66
131: call _real_to_prot
132:
133: xor %eax, %eax
134: movb %dh, %al
135: mov %%eax, %0
136: movb %cl, %al
137: mov %eax, %1
138: movb %ch, %al
139: mov %eax, %2
140: " : "=g" (secs), "=g" (mins), "=g" (hrs));
141: #else
142: *secs = ReadRtcRam(RTC_SECONDS);
143: *mins = ReadRtcRam(RTC_MINUTES);
144: *hrs = ReadRtcRam(RTC_HOURS);
145: #endif
146: }
147:
148: static inline u_long
149: bcd2dec(u_long arg) {
150: return ((arg & 0xF0) >> 4) * 10 + (arg & 0x0F);
151: }
152:
153:
154: u_long
155: timer(void) {
156: /* TBD - replace with StartCountdown()/CountdownAtZero() routines,
157: isolate the span-midnight problem to inside these routines
158: */
159: /*
160: * Return the current time in seconds
161: */
162:
163: u_long sec, min, hour;
164:
165: /* BIOS time is stored in bcd */
166: getrtc(&hour, &min, &sec);
167: sec = bcd2dec(sec);
168: min = bcd2dec(min);
169: hour = bcd2dec(hour);
170: #if 0
171: printe("time h%d m%d s%d = sum%d\n", hour, min, sec, hour * 3600L + min * 60L + sec);
172: #endif
173: return hour * 3600L + min * 60L + sec;
174: }
175:
176: /*
177: * Simple random generator
178: */
179: static u_long next = 1;
180:
181: void
182: srand(u_int seed) {
183: next = seed;
184: }
185:
186: int
187: rand(void) {
188: next = next * 1103515245L + 12345;
189: return (u_int)(next / 65536) % 32768;
190: }
191:
192: u_short
193: GetMemSize(u_short s) {
194: #ifdef USE_BIOS
195: u_short result;
196: asm("
197: push %%ebx
198: mov %1, %%ebx
199: call _prot_to_real
200: cmpb $0x1, %%bl
201: .byte 0x66
202: je 1f
203: sti
204: int $0x12
205: cli
206: .byte 0x66
207: jmp 2f
208: 1: movb $0x88, %%ah
209: sti
210: int $0x15
211: cli
212: 2: mov %%eax, %%ebx
213: .byte 0x66
214: call _real_to_prot
215: mov %%bx, %0
216: pop %%ebx
217: " : "=g" (result) : "g" (s));
218: return result;
219: #else
220: u_long result;
221: if (s)
222: result = ((u_long)ReadRtcRam(RTC_EXPMEM_HI)<<8) + ReadRtcRam(RTC_EXPMEM_LO);
223: else
224: result = ((u_long)ReadRtcRam(RTC_BASEMEM_HI)<<8) + ReadRtcRam(RTC_BASEMEM_LO);
225: return result;
226: #endif
227: }
228:
229: void
230: ResetCpu(void) {
231: #ifdef USE_BIOS
232: asm("
233: call _prot_to_real # enter real mode
234: int $0x19
235: " );
236: #else
237: while (inb(0x64)&2); /* wait input ready */
238: outb(0x64, 0xFE); /* Reset Command */
239: #endif
240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.