summaryrefslogtreecommitdiff
path: root/v4.0-ozzie/bin/DISK2/BIOS/BUGCODE.INC
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0-ozzie/bin/DISK2/BIOS/BUGCODE.INC')
-rw-r--r--v4.0-ozzie/bin/DISK2/BIOS/BUGCODE.INC553
1 files changed, 553 insertions, 0 deletions
diff --git a/v4.0-ozzie/bin/DISK2/BIOS/BUGCODE.INC b/v4.0-ozzie/bin/DISK2/BIOS/BUGCODE.INC
new file mode 100644
index 0000000..4a87725
--- /dev/null
+++ b/v4.0-ozzie/bin/DISK2/BIOS/BUGCODE.INC
@@ -0,0 +1,553 @@
1;*** Bugcode.inc - Debug code for including into sysini.asm and ibmbio.asm
2;
3; Can't link in via buglib due to memory and relocation games played
4; by these modules. Each gets a private, local-only copy of these
5; modules.
6
7
8IFDEF DEBUGFLG
9
10
11;** DPRINTF _ Debug Printf
12;
13; Dprintf is a kernel debug print formatting package. It is intended
14; to produce conviently formatted output.
15;
16; Dprintf is called, indirectly, by a macro:
17;
18; DEBUG n,m,"string",<a1,...,an>
19;
20; string = format string
21; a1 = first argument
22; an = last argument
23;
24; The format string is an ASCIZ string which can contain 2 types of
25; specifications: data-format specifications and literal characters.
26; Data format specifications always begin with a '$' character; all
27; characters not part of a data format specification are treated as
28; literal characters.
29;
30; Literal characters
31; - any character not part of a format specification. Special
32; non-printing characters are:
33; \n - CRLF
34; \t - tab
35; \b - bell
36; \\ - \
37; \$ - $
38;
39; Format Specifications
40;
41; A format specification takes the form:
42; $ [@] <char>
43;
44; where <char> =
45;
46; x - print argument as a hex word
47; d - print argument as decimal word
48; c - print argument as ascii character
49; b - print argument as hex byte
50; For each of the above formats, the supplied argument
51; is a 16-bit word - the value to be printed. The optional @
52; (described below) allows a segmented address to be supplied,
53; instead.
54;
55; s[nn] - print argument as asciz string; if optional decimal
56; argument follows the format character this specifys
57; a maximum string length. Non printing characters are
58; printed in the form \nnn where "nnn" is the octal byte
59; value.
60; Note that this format character cannot be directly
61; followed by a digit unless that digit is to be taken
62; as the start of a length argument.
63;
64; Bnn - print argument as hex bytes. The required following
65; decimal argument is the number of bytes to print.
66;
67; Both of these formats take a long address as their argument.
68; The '@' character is thus invalid for these formats.
69;
70; WARNINGS
71; As befitting a debug routine, DPRINTF does not have a whole lot
72; of "failsafe" code in it. Supplying screwed up formats can
73; muck things up. Specifically:
74; The @ argument must NOT be specified with the 's' or 'B'
75; format
76; A string/byte-length argument of 0 is taken as 65536
77; The string "%% BAD FMT %%" appears in the output when
78; 1) an illegal format specifier is given, or
79; 2) the B format is given a 0 or missing length
80;
81; ENTRY (sp+n ) = address of format string (offset from return cs value)
82; (sp+n-2) = first argument word
83; (sp+n-4) = second argument word
84; .
85; (sp+4 ) = last argument word
86; (sp+2 ) = seg of return address
87; (sp ) = offset of return address
88; (bp) = offset of format string on the stack
89; EXIT none
90; USES flags
91
92 PUBLIC DPRINTF
93DPRINTF PROC near
94
95 push ds
96 push es
97 push bp
98 push di
99 push si
100 push dx
101 push cx
102 push bx
103 push ax ; save registers
104 cld
105
106 mov si,[bp] ; get address of format string
107 sub bp,2
108 mov bx,sp
109 mov ds,ss:20[bx] ; (ds:si) = address of format string
110 push cs
111 pop ds
112
113; Scan format string for next character
114;
115; (ds:si) = address of format string
116; (ss:bp) = address of next argument
117
118dpf1: lodsb ; (al) = format string byte
119 and al,al
120 je dpf3 ; all done
121 cmp al,'$'
122 je dpf4 ; is data escape
123 cmp al,'\'
124 jnz dpf2 ; got the character
125
126; it's an "\" escape code - crack the argument character
127
128 lodsb
129 and al,al
130 je dpf3 ; all done, ignore hanging \
131 xchg ah,al
132 mov al,0Ch
133 cmp ah,'n'
134 jne dpf1$5 ; not \n
135 mov al,0dH
136 call putchar
137 mov al,0aH
138 jmp SHORT dpf2 ; print LF
139
140dpf1$5: cmp ah,'t'
141 mov al,9
142 je dpf2 ; is \t
143 cmp ah,'b'
144 mov al,7
145 je dpf2 ; is \b
146 xchg ah,al
147dpf2: call putchar
148 jmp dpf1
149
150; have the end of the format string - exit
151
152dpf3: pop ax
153 pop bx
154 pop cx
155 pop dx
156 pop si
157 pop di
158 pop bp
159 pop es
160 pop ds
161 ret
162
163
164;* Have a '$' character - is data format escape
165;
166; Get address of data into es:di
167;
168; (bp) = address of data value
169
170dpf4: mov di,bp
171 push ss
172 pop es ; (es:di) = address of data value
173 sub bp,2 ; point to next argument
174 lodsb ; (al) = format specifier
175 cmp al,'@'
176 jne dpf5 ; not an indirect flag
177 les di,[bp]
178 sub bp,2 ; have an extra 2 for @
179 lodsb
180dpf5: cmp al,'x'
181 jne dpfd1 ; not 'x'
182
183; is 'x' format - print hex word
184
185 mov ax,es:[di]
186 call THW ; type hex word
187 jmp dpf1
188
189dpfd1: cmp al,'d'
190 jnz dpfc1 ; not 'd'
191
192; is 'd' format - print decimal word
193
194 mov ax,es:[di]
195 call TDW ; type decimal word
196 jmp dpf1
197
198dpfc1: cmp al,'c'
199 jne dpfb1
200
201; is 'c' format - print character
202
203 mov al,es:[di]
204 call putchar
205 jmp dpf1
206
207dpfb1: cmp al,'b'
208 jne dpfs1
209
210; is 'b' format - print hex byte
211
212 mov al,es:[di]
213 call THB ; type hex byte
214 jmp dpf1
215
216dpfs1: cmp al,'s'
217 jne dpfbb1
218
219; is 's' format - print ASCIZ string. First, check for
220; optional decimal limit
221
222 public SSB
223SSB: sub cx,cx ; set 65536 limit
224 les di,[bp] ; (es:DI) = fwa of string
225 sub bp,2 ; argument to 's' was two words
226 mov al,[si]
227 cmp al,'0'
228 jb dpfs2 ; not decimal
229 cmp al,'9'
230 ja dpfs2 ; not decimal
231 call atod ; (ax) = decimal value, (ds:si) updated
232 xchg cx,ax
233
234; print asciz string at es:di, max of (cx) characters
235; (cx) = 0 means max of 65536
236;
237; Other sections of code in dpf jump here to print strings
238
239dpfs2: mov al,es:[di]
240 inc di
241 and al,al
242 je dpfs3
243 call putchar
244 loop dpfs2 ; continue if not at limit
245dpfs3: jmp dpf1
246
247dpfbb1: cmp al,'B'
248 je dpfbb2 ; is 'B' format
249
250; error in format code - print message
251
252dpferr: push cs
253 pop es
254 mov di,OFFSET dpfa ; (es:di) = error message
255 sub cx,cx
256 jmp dpfs2
257
258dpfa: DB '%% BAD FMT %%',0
259
260; have B format
261
262dpfbb2: call atod ; (ax) = length specifier
263 jc dpferr ; number not there - error
264 xchg cx,ax
265 jcxz dpferr ; number is 0 - error
266 les di,[bp] ; (es:DI) = fwa of string
267 sub bp,2 ; argument to 's' was two words
268dpfbb3: mov al,es:[di]
269 call THB ; type hex byte
270 mov al,' '
271 call putchar ; space em out
272 inc di
273 loop dpfbb3 ; do em all
274 jmp dpf1
275
276DPRINTF ENDP
277
278
279;** THB - Type Hex Byte
280;
281; THB types a hex byte (via "putchar")
282;
283; ENTRY (AL) = byte
284; EXIT none
285; USES ax, flags
286
287THBA DB '0123456789abcdef'
288
289 PUBLIC THB
290THB PROC near
291
292 push ax
293 shr al,1
294 shr al,1
295 shr al,1
296 shr al,1
297 and ax,0fH
298 xchg bx,ax
299 mov bl,CS:THBA[bx]
300 xchg ax,bx
301 call putchar ; put first character
302 pop ax
303 and ax,0fH
304 xchg bx,ax
305 mov bl,CS:THBA[bx]
306 xchg ax,bx
307 call putchar
308 ret
309
310THB ENDP
311
312
313
314
315;** THW - Type Hex Word
316;
317; THW types a word in hex (via "putchar")
318;
319; ENTRY (AX) = word
320; EXIT none
321; USES AX, flags
322
323 PUBLIC THW
324THW PROC near
325
326 push ax
327 xchg ah,al
328 call THB
329 pop ax
330 call THB
331 ret
332
333THW ENDP
334
335
336
337;** TDW - Type Decimal Word
338;
339; TDW types (via "putchar") the unsigned decimal representation
340; of a 16-bit unsigned integer. Only significant digits are
341; printed; if the number is 0 a "0" is printed.
342;
343; ENTRY (AX) = number
344; EXIT none
345; USES AX, flags
346
347 PUBLIC TDW
348TDW PROC near
349
350 push cx ; preserve registers
351 push dx
352 mov cx,10
353 call tdw$ ; recurse cracking digits
354 pop dx
355 pop cx
356 ret
357
358TDW ENDP
359
360
361;* tdw$ - crack number recursively
362;
363; tdw$ cracks the least significant decimal digit. If there
364; are no higher-significant digits, print and return.
365; else, recurse for higher digits
366;
367; (AX) = value
368; (CX) = 10
369
370tdw$ PROC NEAR
371
372 sub dx,dx
373 div cx ; (ax) = quotient, (dx) = remainder
374 and ax,ax
375 jz tdw$1 ; this is highest-order, do it
376 push dx
377 call tdw$
378 pop dx
379tdw$1: xchg ax,dx
380 add al,'0'
381 call putchar
382 ret
383
384TDW$ ENDP
385
386
387
388;** ATOD - Convert ASCII string to decimal number
389;
390; ATOD is called to convert an ascii string of digits to a
391; decimal number. Digits are converted until we run out of them.
392;
393; ENTRY (DS:SI) = address of first digit
394; EXIT 'C' clear if OK
395; (AX) = value
396; (SI) updated to first non-digit
397; 'C' set if error - no digits, or result >65535
398; (DS:SI) points to error character
399; USES AX, SI, FLAGS
400
401 PUBLIC ATOD
402ATOD PROC near
403
404 push dx
405 push cx ; save registers
406 mov al,[si]
407 sub al,'0'
408 jc atod9 ; error - no digits
409 cmp al,10
410 cmc
411 jc atod9 ; error - no digits
412 sub ax,ax ; clear accumulator
413 mov cx,10 ; base 10
414
415; crack next digit
416;
417; (AX) = number accumulated so near
418; (CX) = 10
419; (DS:SI) = next character
420
421atod1: xchg dx,ax ; keep accum in dx for a while
422 lodsb ; (al) = character
423 sub al,'0'
424 jc atod7 ; not digit - all done
425 cmp al,9
426 ja atod7 ; not digit - all done
427 sub ah,ah ; (ax) = digit value (0 - 9)
428 push ax
429 xchg ax,dx
430 mul cx ; (ax) = 10*accum
431 pop dx ; (dx) = digit to add
432 jo atod8 ; overflow
433 add ax,dx
434 jmp atod1 ; go back for more
435
436; Done with number, all OK
437;
438; (dx) = number
439; (ds:si) = address+1 of first unused character
440
441atod7: clc
442
443; Done with number, error
444; 'C' set
445
446atod8: dec si ; backup over non-decimal (or error) char
447atod9: pop cx
448 xchg ax,dx ; (ax) = number iff no error
449 pop dx ; restore registers
450 ret ; exit
451
452ATOD ENDP
453
454;** putchar - put a character on the console
455;
456; ENTRY (al) = character
457; EXIT none
458; USES ax,flags
459
460
461UR_DAT = 02f8H ; COM1 = 03f8H, COM2 = 02f8H
462UR_IEN = UR_DAT+1 ; Interrupt enable
463UR_IER = UR_DAT+2 ; interrupt ID
464UR_LCR = UR_DAT+3 ; line control registers
465UR_MCR = UR_DAT+4 ; modem control register
466UR_LSR = UR_DAT+5 ; line status register
467UR_MSR = UR_DAT+6 ; modem status regiser
468UR_DLL = UR_DAT ; divisor latch least sig
469UR_DLM = UR_DAT+1 ; divisor latch most sig
470
471iflag DB 0 ; != 0 when initialized 8250
472
473;* inchr - input character
474;
475; EXIT 'z' set if no character
476; 'z' clear if char
477; (al) = char
478
479inchr: mov dx,UR_LSR
480 in al,dx
481 and al,1
482 jz inchr1
483 mov dx,UR_DAT
484 in al,dx
485 and al,07fh
486inchr1: ret
487
488
489 PUBLIC putchar
490putchar PROC NEAR
491 pushf
492 cli
493 push dx
494 push cx
495 push bx
496 push ax ; (al) = character
497 test iflag,255
498 jnz putc1 ; is initialized
499 inc iflag
500
501; program the usart
502
503 mov dx,UR_LCR
504 mov al,80h
505 out dx,al ; command it
506 sub al,al
507 mov dx,UR_DLM
508 out dx,al
509 mov dx,UR_DLL
510 mov al,12 ; 9600 baud = 12, 19.2 Kbaud = 6
511 out dx,al
512 mov al,3
513 mov dx,UR_LCR
514 out dx,al ; command normal mode
515
516; see if CTL-Q or CTL-S
517
518putc1: pushf
519 cli
520 call inchr
521 jz putc3 ; no characters incomming
522 cmp al,19 ; ctl-S?
523 jnz putc3 ; no, ignore
524
525; have ctl-s. wait till we see ctl-Q
526
527putc2: call inchr
528 jz putc2
529 cmp al,17
530 jnz putc2
531
532putc3: popf
533 mov dx,UR_LSR
534putc4: in al,dx
535 test al,020h
536 jz putc4
537
538; ready. crank it out!
539
540 mov dx,UR_DAT
541
542 pop ax
543 out dx,al
544
545 pop bx
546 pop cx
547 pop dx
548 popf
549 ret
550
551putchar ENDP
552
553ENDIF