|
|
1.1 root 1: /* builtin.c -- builtin routines for tboot.
2: *
3: * Add new ones by adding a check for them in interpret().
4: *
5: * La Monte H. Yarroll <[email protected]>, September 1991
6: */
7:
8: #include <string.h>
9: #include <sys/inode.h>
10: #include <sys/ino.h>
11: #include <sys/dir.h>
12: #include "tboot.h"
13:
14: /* If possible, execute "command".
15: * Return "true" if the command exists, "false" otherwise.
16: */
17: int
18: interpret(command)
19: char *command;
20: {
21: if (0 == strcmp(command, "info")) {
22: dpb();
23: return(TRUE);
24: } else if ((0 == strcmp(command, "dir")) ||
25: (0 == strcmp(command, "ls") ) ||
26: (0 == strcmp(command, "lc") )) {
27: dir();
28: return(TRUE);
29: } else if ( (0 == strncmp(command, "sys_base", strlen("sys_base")) ) ||
30: (0 == strncmp(command, "scs", strlen("scs")) )
31: ) {
32: char lbuf[5]; /* 5 == strlen("0000") + 1 */
33: if (NULL != strchr(command, '=')){
34: puts("Setting sys_base.\r\n");
35: sys_base_set = (1==1);
36: sys_base = (uint16)
37: basetoi(1 + strchr(command, '='), 16);
38: }
39: if (!sys_base_set) {
40: puts("sys_base will default to ");
41: print16(DEF_SYS_BASE);
42: puts(" for l.out executables,\r\n and to ");
43: print16(COFF_SYS_BASE);
44: puts(" for COFF executables.\r\n");
45: } else {
46: puts("sys_base is ");
47: itobase((uint16) sys_base, lbuf, 16);
48: puts(lbuf);
49: puts("\r\n");
50: }
51: return(TRUE);
52: } else if (0 == strcmp(command, "monitor")) {
53: monitor();
54: return(TRUE);
55: } else if ((0 == strcmp(command, "gift"))) {
56: dump_gift(); /* Dump boot_gift. */
57: return(TRUE);
58: } else if ((0 == strcmp(command, "test arg"))) {
59: if (arg_exist("arg")) {
60: puts("Yep.\r\n");
61: } else {
62: puts("Nope.\r\n");
63: }
64: return(TRUE);
65: } else if ((0 == strcmp(command, "help")) ||
66: (0 == strcmp(command, "?")) ) {
67: puts("info Print disk information.\r\n");
68: puts("dir|ls List contents of /.\r\n");
69: puts("?|help Print this list.\r\n");
70: return(TRUE);
71: } else if (0 == strcmp(command, "mon_on")) {
72: want_monitor = TRUE;
73: puts("Mini-monitor will autoinvoke before running kernel.\r\n");
74: return(TRUE);
75: } else if (0 == strcmp(command, "??")) {
76: puts("UNSUPPORTED FEATURES: (don't call :-)\r\n");
77: puts("sys_base|scs Print current load segment.\r\n");
78: puts("sys_base=tttt Set current load segment to 0xtttt.\r\n");
79: puts("test arg Test for the presence of arg.\r\n");
80: puts("monitor Invoke the mini-monitor.\r\n");
81: puts("mon_on Autoinvoke the mini-monitor before kernel.\r\n");
82: return(TRUE);
83: } else {
84: return(FALSE);
85: }
86: puts("\r\nUNREACHABLE CODE IN interpret() EXECUTED.\r\n");
87: puts("There is probably a missing return() in interpret().\r\n");
88: return(FALSE); /* This should be an unreachable line. */
89: } /* interpret() */
90:
91: /* Display the BIOS parameters loaded up by the startup code. */
92: void
93: dpb()
94: {
95: char buffer[BLOCK];
96: int i;
97: int num_of_drives;
98: struct reg r;
99:
100:
101: num_of_drives = get_num_of_drives();
102:
103: puts("\r\nHere are the BIOS parameters for your hard drive");
104: if (num_of_drives > 1) { putchar('s'); }
105: puts(".\r\n");
106: puts("Write them down for use during installation.\r\n");
107:
108: for (i = 0; i < num_of_drives; ++i) {
109:
110: r.r_ax = DISK_PARAMS;
111: r.r_dx = HARD_DRIVE + i;
112:
113: intcall(&r, &r, DISKINT); /* Ask the BIOS. */
114:
115: puts("Drive ");
116: itobase((uint16) i, buffer, 10);
117: puts(buffer);
118:
119:
120: /* ch is the lower 8 bits of number of cylinders.
121: * The high two bits of cl are the top two bits of
122: * 10 bit number of cylinders.
123: *
124: * The cylinder count is actually 1 short.
125: */
126: puts(": Cylinders=");
127: itobase((uint16) (
128: ((LOW(r.r_cx) >> 6) * 256) + /* Top two bits... */
129: (HIGH(r.r_cx) + 1)
130: ),
131: buffer, 10);
132: puts(buffer);
133:
134: /* The head count is actually 1 short. */
135: puts(" Heads=");
136: itobase((uint16) HIGH(r.r_dx) + 1, buffer, 10);
137: puts(buffer);
138:
139: /* Only the lower 6 bits of cl are the sectors per track. */
140: puts(" Sectors per track=");
141: itobase((uint16) SIXBITS & LOW(r.r_cx), buffer, 10);
142: puts(buffer);
143:
144: puts("\r\n");
145: } /* for i = 0 to num_of_drives - 1 */
146: } /* dpb() */
147:
148:
149: /* Ask the BIOS how many drives are attached. */
150: int get_num_of_drives()
151: {
152: struct reg r;
153:
154: r.r_ax = DISK_PARAMS; /* ah = 8 -- Return disk drive parameters */
155: r.r_dx = HARD_DRIVE; /* set bit 7 of dl for hard disk info. */
156:
157: intcall(&r, &r, DISKINT);
158:
159: return(LOW(r.r_dx));
160: } /* get_num_of_drives() */
161:
162: /* Create a listing of file names in /. */
163: void
164: dir()
165: {
166: int i, j;
167: char outbuff[LINESIZE]; /* Buffer for outputing numbers. */
168: struct inode rootinode;
169: struct direct dirent;
170:
171: /* Open "/" and print out the direct block file entries. */
172: iopen(&rootinode, (ino_t) 2);
173:
174: /* Read each directory entry one at a time. */
175: /* We are careful to print an even fraction of 80 for each
176: * directory entry, so that everything lines up nicely.
177: */
178: for (i = 0; i < rootinode.i_size; i += sizeof(struct direct)) {
179:
180: iread(&rootinode, (char *) &dirent, (fsize_t) i,
181: (uint16) sizeof(struct direct));
182:
183: /* If the entry is not active, skip the rest. */
184: if (0 == dirent.d_ino) {
185: continue;
186: }
187:
188: /* NUL terminate the name. */
189: strncpy(outbuff,
190: dirent.d_name,
191: DIRSIZ);
192: outbuff[DIRSIZ] = '\0';
193: /* Print the file name. */
194: puts(outbuff);
195: for (j = DIRSIZ - strlen(outbuff); j > 0; --j) {
196: putchar(' ');
197: }
198: puts(" :"); /* Bring total to 16 (80/5) characters. */
199: }
200: puts("\r\n");
201:
202: } /* dir() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.