1 !
2 ! setup.S Copyright (C) 1991, 1992 Linus Torvalds
3 !
4 ! setup.s is responsible for getting the system data from the BIOS,
5 ! and putting them into the appropriate places in system memory.
6 ! both setup.s and system has been loaded by the bootblock.
7 !
8 ! This code asks the bios for memory/disk/other parameters, and
9 ! puts them in a "safe" place: 0x90000-0x901FF, ie where the
10 ! boot-block used to be. It is then up to the protected mode
11 ! system to read them from there before the area is overwritten
12 ! for buffer-blocks.
13 !
14 ! Move PS/2 aux init code to psaux.c
15 ! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
16 !
17 ! some changes and additional features by Christoph Niemann,
18 ! March 1993/June 1994 (Christoph.Niemann@linux.org)
19 !
20
21 ! NOTE! These had better be the same as in bootsect.s!
22 #include <linux/config.h>
23 #include <linux/segment.h>
24
25 #ifndef SVGA_MODE
26 #define SVGA_MODE ASK_VGA
27 #endif
28
29 ! Signature words to ensure LILO loaded us right
30 #define SIG1 0xAA55
31 #define SIG2 0x5A5A
32
33 INITSEG = DEF_INITSEG ! we move boot here - out of the way
34 SYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).
35 SETUPSEG = DEF_SETUPSEG ! this is the current segment
36
37 .globl begtext, begdata, begbss, endtext, enddata, endbss
38 .text
39 begtext:
40 .data
41 begdata:
42 .bss
43 begbss:
44 .text
45
46 entry start
47 start:
48 ! Check signature at end of setup
49 mov ax,#SETUPSEG
50 mov ds,ax
51 cmp setup_sig1,#SIG1
52 jne bad_sig
53 cmp setup_sig2,#SIG2
54 jne bad_sig
55 jmp good_sig1
56
57 ! Routine to print asciiz-string at DS:SI
58
59 prtstr: lodsb
60 and al,al
61 jz fin
62 call prnt1
63 jmp prtstr
64 fin: ret
65
66 ! Part of above routine, this one just prints ascii al
67
68 prnt1: push ax
69 push cx
70 xor bh,bh
71 mov cx,#0x01
72 mov ah,#0x0e
73 int 0x10
74 pop cx
75 pop ax
76 ret
77
78 beep: mov al,#0x07
79 jmp prnt1
80
81 no_sig_mess: .ascii "No setup signature found ..."
82 db 0x00
83 start_sys_seg: .word SYSSEG
84
85 good_sig1:
86 jmp good_sig
87
88 ! We now have to find the rest of the setup code/data
89 bad_sig:
90 mov ax,#INITSEG
91 mov ds,ax
92 xor bh,bh
93 mov bl,[497] ! get setup sects from boot sector
94 sub bx,#4 ! LILO loads 4 sectors of setup
95 shl bx,#8 ! convert to words
96 mov cx,bx
97 shr bx,#3 ! convert to segment
98 add bx,#SYSSEG
99 seg cs
100 mov start_sys_seg,bx
101
102 ! Move rest of setup code/data to here
103 mov di,#2048 ! four sectors loaded by LILO
104 sub si,si
105 mov ax,#SETUPSEG
106 mov es,ax
107 mov ax,#SYSSEG
108 mov ds,ax
109 rep
110 movsw
111
112 mov ax,#SETUPSEG
113 mov ds,ax
114 cmp setup_sig1,#SIG1
115 jne no_sig
116 cmp setup_sig2,#SIG2
117 jne no_sig
118 jmp good_sig
119
120 no_sig:
121 lea si,no_sig_mess
122 call prtstr
123 no_sig_loop:
124 jmp no_sig_loop
125
126 good_sig:
127 mov ax,#INITSEG
128 mov ds,ax
129
130 ! Get memory size (extended mem, kB)
131
132 mov ah,#0x88
133 int 0x15
134 mov [2],ax
135
136 ! set the keyboard repeat rate to the max
137
138 mov ax,#0x0305
139 xor bx,bx ! clear bx
140 int 0x16
141
142 ! check for EGA/VGA and some config parameters
143
144 mov ah,#0x12
145 mov bl,#0x10
146 int 0x10
147 mov [8],ax
148 mov [10],bx
149 mov [12],cx
150 mov ax,#0x5019
151 cmp bl,#0x10
152 je novga
153 mov ax,#0x1a00 ! Added check for EGA/VGA discrimination
154 int 0x10
155 mov bx,ax
156 mov ax,#0x5019
157 cmp bl,#0x1a ! 1a means VGA, anything else EGA or lower
158 jne novga
159 call chsvga
160 novga: mov [14],ax
161 mov ah,#0x03 ! read cursor pos
162 xor bh,bh ! clear bh
163 int 0x10 ! save it in known place, con_init fetches
164 mov [0],dx ! it from 0x90000.
165
166 ! Get video-card data:
167
168 mov ah,#0x0f
169 int 0x10
170 mov [4],bx ! bh = display page
171 mov [6],ax ! al = video mode, ah = window width
172
173 ! Get hd0 data
174
175 xor ax,ax ! clear ax
176 mov ds,ax
177 lds si,[4*0x41]
178 mov ax,#INITSEG
179 push ax
180 mov es,ax
181 mov di,#0x0080
182 mov cx,#0x10
183 push cx
184 cld
185 rep
186 movsb
187
188 ! Get hd1 data
189
190 xor ax,ax ! clear ax
191 mov ds,ax
192 lds si,[4*0x46]
193 pop cx
194 pop es
195 mov di,#0x0090
196 rep
197 movsb
198
199 ! Check that there IS a hd1 :-)
200
201 mov ax,#0x01500
202 mov dl,#0x81
203 int 0x13
204 jc no_disk1
205 cmp ah,#3
206 je is_disk1
207 no_disk1:
208 mov ax,#INITSEG
209 mov es,ax
210 mov di,#0x0090
211 mov cx,#0x10
212 xor ax,ax ! clear ax
213 cld
214 rep
215 stosb
216 is_disk1:
217
218 ! check for PS/2 pointing device
219
220 mov ax,#INITSEG
221 mov ds,ax
222 mov [0x1ff],#0 ! default is no pointing device
223 int 0x11 ! int 0x11: equipment determination
224 test al,#0x04 ! check if pointing device installed
225 jz no_psmouse
226 mov [0x1ff],#0xaa ! device present
227 no_psmouse:
228 ! now we want to move to protected mode ...
229
230 cli ! no interrupts allowed !
231 mov al,#0x80 ! disable NMI for the bootup sequence
232 out #0x70,al
233
234 ! first we move the system to its rightful place
235
236 mov ax,#0x100 ! start of destination segment
237 seg cs
238 mov bx,start_sys_seg ! start of source segment
239 cld ! 'direction'=0, movs moves forward
240 do_move:
241 mov es,ax ! destination segment
242 inc ah ! instead of add ax,#0x100
243 cmp ax,#0x9000
244 jz end_move
245 mov ds,bx ! source segment
246 add bx,#0x100
247 sub di,di
248 sub si,si
249 mov cx,#0x800
250 rep
251 movsw
252 jmp do_move
253
254 ! then we load the segment descriptors
255
256 end_move:
257 mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)
258 mov ds,ax
259 lidt idt_48 ! load idt with 0,0
260 lgdt gdt_48 ! load gdt with whatever appropriate
261
262 ! that was painless, now we enable A20
263
264 call empty_8042
265 mov al,#0xD1 ! command write
266 out #0x64,al
267 call empty_8042
268 mov al,#0xDF ! A20 on
269 out #0x60,al
270 call empty_8042
271
272 ! make sure any possible coprocessor is properly reset..
273
274 xor ax,ax
275 out #0xf0,al
276 call delay
277 out #0xf1,al
278 call delay
279
280 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
281 ! we put them right after the intel-reserved hardware interrupts, at
282 ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
283 ! messed this up with the original PC, and they haven't been able to
284 ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
285 ! which is used for the internal hardware interrupts as well. We just
286 ! have to reprogram the 8259's, and it isn't fun.
287
288 mov al,#0x11 ! initialization sequence
289 out #0x20,al ! send it to 8259A-1
290 call delay
291 out #0xA0,al ! and to 8259A-2
292 call delay
293 mov al,#0x20 ! start of hardware int's (0x20)
294 out #0x21,al
295 call delay
296 mov al,#0x28 ! start of hardware int's 2 (0x28)
297 out #0xA1,al
298 call delay
299 mov al,#0x04 ! 8259-1 is master
300 out #0x21,al
301 call delay
302 mov al,#0x02 ! 8259-2 is slave
303 out #0xA1,al
304 call delay
305 mov al,#0x01 ! 8086 mode for both
306 out #0x21,al
307 call delay
308 out #0xA1,al
309 call delay
310 mov al,#0xFF ! mask off all interrupts for now
311 out #0xA1,al
312 call delay
313 mov al,#0xFB ! mask all irq's but irq2 which
314 out #0x21,al ! is cascaded
315
316 ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
317 ! need no steenking BIOS anyway (except for the initial loading :-).
318 ! The BIOS-routine wants lots of unnecessary data, and it's less
319 ! "interesting" anyway. This is how REAL programmers do it.
320 !
321 ! Well, now's the time to actually move into protected mode. To make
322 ! things as simple as possible, we do no register set-up or anything,
323 ! we let the gnu-compiled 32-bit programs do that. We just jump to
324 ! absolute address 0x00000, in 32-bit protected mode.
325 !
326 ! Note that the short jump isn't strictly needed, although there are
327 ! reasons why it might be a good idea. It won't hurt in any case.
328 !
329 xor ax,ax
330 inc ax ! protected mode (PE) bit
331 lmsw ax ! This is it!
332 jmp flush_instr
333 flush_instr:
334 jmpi 0x1000,KERNEL_CS ! jmp offset 1000 of segment 0x10 (cs)
335
336 ! This routine checks that the keyboard command queue is empty
337 ! (after emptying the output buffers)
338 !
339 ! No timeout is used - if this hangs there is something wrong with
340 ! the machine, and we probably couldn't proceed anyway.
341 empty_8042:
342 call delay
343 in al,#0x64 ! 8042 status port
344 test al,#1 ! output buffer?
345 jz no_output
346 call delay
347 in al,#0x60 ! read it
348 jmp empty_8042
349 no_output:
350 test al,#2 ! is input buffer full?
351 jnz empty_8042 ! yes - loop
352 ret
353 !
354 ! Read a key and return the (US-)ascii code in al, scan code in ah
355 !
356 getkey:
357 xor ah,ah
358 int 0x16
359 ret
360
361 !
362 ! Read a key with a timeout of 30 seconds. The cmos clock is used to get
363 ! the time.
364 !
365 getkt:
366 call gettime
367 add al,#30 ! wait 30 seconds
368 cmp al,#60
369 jl lminute
370 sub al,#60
371 lminute:
372 mov cl,al
373 again: mov ah,#0x01
374 int 0x16
375 jnz getkey ! key pressed, so get it
376 call gettime
377 cmp al,cl
378 jne again
379 mov al,#0x20 ! timeout, return default char `space'
380 ret
381
382 !
383 ! Flush the keyboard buffer
384 !
385 flush: mov ah,#0x01
386 int 0x16
387 jz empty
388 xor ah,ah
389 int 0x16
390 jmp flush
391 empty: ret
392
393 !
394 ! Read the cmos clock. Return the seconds in al
395 !
396 gettime:
397 push cx
398 mov ah,#0x02
399 int 0x1a
400 mov al,dh ! dh contains the seconds
401 and al,#0x0f
402 mov ah,dh
403 mov cl,#0x04
404 shr ah,cl
405 aad
406 pop cx
407 ret
408
409 !
410 ! Delay is needed after doing i/o
411 !
412 delay:
413 .word 0x00eb ! jmp $+2
414 ret
415
416 ! Routine trying to recognize type of SVGA-board present (if any)
417 ! and if it recognize one gives the choices of resolution it offers.
418 ! If one is found the resolution chosen is given by al,ah (rows,cols).
419
420 chsvga: cld
421 push ds
422 push cs
423 mov ax,[0x01fa]
424 pop ds
425 mov modesave,ax
426 mov ax,#0xc000
427 mov es,ax
428 mov ax,modesave
429 cmp ax,#NORMAL_VGA
430 je defvga
431 cmp ax,#EXTENDED_VGA
432 je vga50
433 cmp ax,#ASK_VGA
434 jne svga
435 lea si,msg1
436 call prtstr
437 call flush
438 nokey: call getkt
439 cmp al,#0x0d ! enter ?
440 je svga ! yes - svga selection
441 cmp al,#0x20 ! space ?
442 je defvga ! no - repeat
443 call beep
444 jmp nokey
445 defvga: mov ax,#0x5019
446 pop ds
447 ret
448
449 vga50:
450 mov ax,#0x1112
451 xor bl,bl
452 int 0x10 ! use 8x8 font set (50 lines on VGA)
453 mov ax,#0x1200
454 mov bl,#0x20
455 int 0x10 ! use alternate print screen
456 mov ax,#0x1201
457 mov bl,#0x34
458 int 0x10 ! turn off cursor emulation
459 mov ah,#0x01
460 mov cx,#0x0607
461 int 0x10 ! turn on cursor (scan lines 6 to 7)
462 pop ds
463 mov ax,#0x5032 ! return 80x50
464 ret
465
466 vga28:
467 pop ax ! clean the stack
468 mov ax,#0x1111
469 xor bl,bl
470 int 0x10 ! use 9x14 fontset (28 lines on VGA)
471 mov ah, #0x01
472 mov cx,#0x0b0c
473 int 0x10 ! turn on cursor (scan lines 11 to 12)
474 pop ds
475 mov ax,#0x501c ! return 80x28
476 ret
477
478 !
479 ! test for presence of an S3 VGA chip. The algorithm was taken
480 ! from the SuperProbe package of XFree86 1.2.1
481 ! report bugs to Christoph.Niemann@linux.org
482 !
483 svga: cld
484 mov cx,#0x0f35 ! we store some constants in cl/ch
485 mov dx,#0x03d4
486 movb al,#0x38
487 call inidx
488 mov bh,al ! store current value of CRT-register 0x38
489 mov ax,#0x0038
490 call outidx ! disable writing to special regs
491 movb al,cl ! check whether we can write special reg 0x35
492 call inidx
493 movb bl,al ! save the current value of CRT reg 0x35
494 andb al,#0xf0 ! clear bits 0-3
495 movb ah,al
496 movb al,cl ! and write it to CRT reg 0x35
497 call outidx
498 call inidx ! now read it back
499 andb al,ch ! clear the upper 4 bits
500 jz s3_2 ! the first test failed. But we have a
501 movb ah,bl ! second chance
502 mov al,cl
503 call outidx
504 jmp s3_1 ! do the other tests
505 s3_2: mov ax,cx ! load ah with 0xf and al with 0x35
506 orb ah,bl ! set the upper 4 bits of ah with the orig value
507 call outidx ! write ...
508 call inidx ! ... and reread
509 andb al,cl ! turn off the upper 4 bits
510 push ax
511 movb ah,bl ! restore old value in register 0x35
512 movb al,cl
513 call outidx
514 pop ax
515 cmp al,ch ! setting lower 4 bits was successful => bad
516 je no_s3 ! writing is allowed => this is not an S3
517 s3_1: mov ax,#0x4838 ! allow writing to special regs by putting
518 call outidx ! magic number into CRT-register 0x38
519 movb al,cl ! check whether we can write special reg 0x35
520 call inidx
521 movb bl,al
522 andb al,#0xf0
523 movb ah,al
524 movb al,cl
525 call outidx
526 call inidx
527 andb al,ch
528 jnz no_s3 ! no, we can't write => no S3
529 mov ax,cx
530 orb ah,bl
531 call outidx
532 call inidx
533 andb al,ch
534 push ax
535 movb ah,bl ! restore old value in register 0x35
536 movb al,cl
537 call outidx
538 pop ax
539 cmp al,ch
540 jne no_s31 ! writing not possible => no S3
541 movb al,#0x30
542 call inidx ! now get the S3 id ...
543 lea di,idS3
544 mov cx,#0x10
545 repne
546 scasb
547 je no_s31
548 lea si,dsc_S3 ! table of descriptions of video modes for BIOS
549 lea di,mo_S3 ! table of sizes of video modes for my BIOS
550 movb ah,bh
551 movb al,#0x38
552 call outidx ! restore old value of CRT register 0x38
553 br selmod ! go ask for video mode
554 no_s3: movb al,#0x35 ! restore CRT register 0x35
555 movb ah,bl
556 call outidx
557 no_s31: movb ah,bh
558 movb al,#0x38
559 call outidx ! restore old value of CRT register 0x38
560
561 lea si,idati ! Check ATI 'clues'
562 mov di,#0x31
563 mov cx,#0x09
564 repe
565 cmpsb
566 jne noati
567 lea si,dscati
568 lea di,moati
569 br selmod
570 noati: mov ax,#0x200f ! Check Ahead 'clues'
571 mov dx,#0x3ce
572 out dx,ax
573 inc dx
574 in al,dx
575 cmp al,#0x20
576 je isahed
577 cmp al,#0x21
578 jne noahed
579 isahed: lea si,dscahead
580 lea di,moahead
581 br selmod
582 noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues'
583 in al,dx
584 or al,#0x10
585 out dx,al
586 mov dx,#0x104
587 in al,dx
588 mov bl,al
589 mov dx,#0x3c3
590 in al,dx
591 and al,#0xef
592 out dx,al
593 cmp bl,[idcandt]
594 jne nocant
595 lea si,dsccandt
596 lea di,mocandt
597 br selmod
598 nocant: mov dx,#0x3d4 ! Check Cirrus 'clues'
599 mov al,#0x0c
600 out dx,al
601 inc dx
602 in al,dx
603 mov bl,al
604 xor al,al
605 out dx,al
606 dec dx
607 mov al,#0x1f
608 out dx,al
609 inc dx
610 in al,dx
611 mov bh,al
612 xor ah,ah
613 shl al,#4
614 mov cx,ax
615 mov al,bh
616 shr al,#4
617 add cx,ax
618 shl cx,#8
619 add cx,#6
620 mov ax,cx
621 mov dx,#0x3c4
622 out dx,ax
623 inc dx
624 in al,dx
625 and al,al
626 jnz nocirr
627 mov al,bh
628 out dx,al
629 in al,dx
630 cmp al,#0x01
631 jne nocirr
632 call rst3d4
633 lea si,dsccirrus
634 lea di,mocirrus
635 br selmod
636 rst3d4: mov dx,#0x3d4
637 mov al,bl
638 xor ah,ah
639 shl ax,#8
640 add ax,#0x0c
641 out dx,ax
642 ret
643 nocirr: call rst3d4 ! Check Everex 'clues'
644 mov ax,#0x7000
645 xor bx,bx
646 int 0x10
647 cmp al,#0x70
648 jne noevrx
649 shr dx,#4
650 cmp dx,#0x678
651 je istrid
652 cmp dx,#0x236
653 je istrid
654 lea si,dsceverex
655 lea di,moeverex
656 br selmod
657 istrid: lea cx,ev2tri
658 jmp cx
659 noevrx: lea si,idgenoa ! Check Genoa 'clues'
660 xor ax,ax
661 seg es
662 mov al,[0x37]
663 mov di,ax
664 mov cx,#0x04
665 dec si
666 dec di
667 l1: inc si
668 inc di
669 mov al,(si)
670 test al,al
671 jz l2
672 seg es
673 cmp al,(di)
674 l2: loope l1
675 cmp cx,#0x00
676 jne nogen
677 lea si,dscgenoa
678 lea di,mogenoa
679 br selmod
680 nogen: cld
681 lea si,idoakvga
682 mov di,#0x08
683 mov cx,#0x08
684 repe
685 cmpsb
686 jne nooak
687 lea si,dscoakvga
688 lea di,mooakvga
689 br selmod
690 nooak: cld
691 lea si,idparadise ! Check Paradise 'clues'
692 mov di,#0x7d
693 mov cx,#0x04
694 repe
695 cmpsb
696 jne nopara
697 lea si,dscparadise
698 lea di,moparadise
699 br selmod
700 nopara: mov dx,#0x3c4 ! Check Trident 'clues'
701 mov al,#0x0e
702 out dx,al
703 inc dx
704 in al,dx
705 xchg ah,al
706 xor al,al
707 out dx,al
708 in al,dx
709 xchg al,ah
710 mov bl,al ! Strange thing ... in the book this wasn't
711 and bl,#0x02 ! necessary but it worked on my card which
712 jz setb2 ! is a trident. Without it the screen goes
713 and al,#0xfd ! blurred ...
714 jmp clrb2 !
715 setb2: or al,#0x02 !
716 clrb2: out dx,al
717 and ah,#0x0f
718 cmp ah,#0x02
719 jne notrid
720 ev2tri: lea si,dsctrident
721 lea di,motrident
722 jmp selmod
723 notrid: mov dx,#0x3cd ! Check Tseng 'clues'
724 in al,dx ! Could things be this simple ! :-)
725 mov bl,al
726 mov al,#0x55
727 out dx,al
728 in al,dx
729 mov ah,al
730 mov al,bl
731 out dx,al
732 cmp ah,#0x55
733 jne notsen
734 lea si,dsctseng
735 lea di,motseng
736 jmp selmod
737 notsen: mov dx,#0x3cc ! Check Video7 'clues'
738 in al,dx
739 mov dx,#0x3b4
740 and al,#0x01
741 jz even7
742 mov dx,#0x3d4
743 even7: mov al,#0x0c
744 out dx,al
745 inc dx
746 in al,dx
747 mov bl,al
748 mov al,#0x55
749 out dx,al
750 in al,dx
751 dec dx
752 mov al,#0x1f
753 out dx,al
754 inc dx
755 in al,dx
756 mov bh,al
757 dec dx
758 mov al,#0x0c
759 out dx,al
760 inc dx
761 mov al,bl
762 out dx,al
763 mov al,#0x55
764 xor al,#0xea
765 cmp al,bh
766 jne novid7
767 lea si,dscvideo7
768 lea di,movideo7
769 jmp selmod
770 novid7: lea si,dsunknown
771 lea di,mounknown
772 selmod: xor cx,cx
773 mov cl,(di)
774 mov ax,modesave
775 cmp ax,#ASK_VGA
776 je askmod
777 cmp ax,#NORMAL_VGA
778 je askmod
779 cmp al,cl
780 jl gotmode
781 push si
782 lea si,msg4
783 call prtstr
784 pop si
785 askmod: push si
786 lea si,msg2
787 call prtstr
788 pop si
789 push si
790 push cx
791 tbl: pop bx
792 push bx
793 mov al,bl
794 sub al,cl
795 call modepr
796 lodsw
797 xchg al,ah
798 call dprnt
799 xchg ah,al
800 push ax
801 mov al,#0x78
802 call prnt1
803 pop ax
804 call dprnt
805 push si
806 lea si,crlf ! print CR+LF
807 call prtstr
808 pop si
809 loop tbl
810 pop cx
811 lea si,msg3
812 call prtstr
813 pop si
814 add cl,#0x30
815 jmp nonum
816 nonumb: call beep
817 nonum: call getkey
818 cmp al,#0x30 ! ascii `0'
819 jb nonumb
820 cmp al,#0x3a ! ascii `9'
821 jbe number
822 cmp al,#0x61 ! ascii `a'
823 jb nonumb
824 cmp al,#0x7a ! ascii `z'
825 ja nonumb
826 sub al,#0x27
827 cmp al,cl
828 jae nonumb
829 sub al,#0x30
830 jmp gotmode
831 number: cmp al,cl
832 jae nonumb
833 sub al,#0x30
834 gotmode: xor ah,ah
835 or al,al
836 beq vga50
837 push ax
838 dec ax
839 beq vga28
840 add di,ax
841 mov al,(di)
842 int 0x10
843 pop ax
844 shl ax,#1
845 add si,ax
846 lodsw
847 pop ds
848 ret
849
850 ! Routine to write al into a VGA-register that is
851 ! accessed via an index register
852 !
853 ! dx contains the address of the index register
854 ! al contains the index
855 ! ah contains the value to write to the data register (dx + 1)
856 !
857 ! no registers are changed
858
859 outidx: out dx,al
860 push ax
861 mov al,ah
862 inc dx
863 out dx,al
864 dec dx
865 pop ax
866 ret
867 inidx: out dx,al
868 inc dx
869 in al,dx
870 dec dx
871 ret
872
873 ! Routine to print a decimal value on screen, the value to be
874 ! printed is put in al (i.e 0-255).
875
876 dprnt: push ax
877 push cx
878 xor ah,ah ! Clear ah
879 mov cl,#0x0a
880 idiv cl
881 cmp al,#0x09
882 jbe lt100
883 call dprnt
884 jmp skip10
885 lt100: add al,#0x30
886 call prnt1
887 skip10: mov al,ah
888 add al,#0x30
889 call prnt1
890 pop cx
891 pop ax
892 ret
893
894 !
895 ! Routine to print the mode number key on screen. Mode numbers
896 ! 0-9 print the ascii values `0' to '9', 10-35 are represented by
897 ! the letters `a' to `z'. This routine prints some spaces around the
898 ! mode no.
899 !
900
901 modepr: push ax
902 cmp al,#0x0a
903 jb digit ! Here is no check for number > 35
904 add al,#0x27
905 digit: add al,#0x30
906 mov modenr, al
907 push si
908 lea si, modestring
909 call prtstr
910 pop si
911 pop ax
912 ret
913
914 gdt:
915 .word 0,0,0,0 ! dummy
916
917 .word 0,0,0,0 ! unused
918
919 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
920 .word 0x0000 ! base address=0
921 .word 0x9A00 ! code read/exec
922 .word 0x00C0 ! granularity=4096, 386
923
924 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
925 .word 0x0000 ! base address=0
926 .word 0x9200 ! data read/write
927 .word 0x00C0 ! granularity=4096, 386
928
929 idt_48:
930 .word 0 ! idt limit=0
931 .word 0,0 ! idt base=0L
932
933 gdt_48:
934 .word 0x800 ! gdt limit=2048, 256 GDT entries
935 .word 512+gdt,0x9 ! gdt base = 0X9xxxx
936
937 msg1: .ascii "Press <RETURN> to see SVGA-modes available, <SPACE> to continue or wait 30 secs."
938 db 0x0d, 0x0a, 0x0a, 0x00
939 msg2: .ascii "Mode: COLSxROWS:"
940 db 0x0d, 0x0a, 0x0a, 0x00
941 msg3: db 0x0d, 0x0a
942 .ascii "Choose mode by pressing the corresponding number or letter."
943 crlf: db 0x0d, 0x0a, 0x00
944 msg4: .ascii "You passed an undefined mode number to setup. Please choose a new mode."
945 db 0x0d, 0x0a, 0x0a, 0x07, 0x00
946 modestring: .ascii " "
947 modenr: db 0x00 ! mode number
948 .ascii ": "
949 db 0x00
950
951 idati: .ascii "761295520"
952 idcandt: .byte 0xa5
953 idgenoa: .byte 0x77, 0x00, 0x99, 0x66
954 idparadise: .ascii "VGA="
955 idoakvga: .ascii "OAK VGA "
956 idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
957 .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
958
959 ! Manufacturer: Numofmodes+2: Mode:
960 ! Number of modes is the number of chip-specific svga modes plus the extended
961 ! modes available on any vga (currently 2)
962
963 moati: .byte 0x06, 0x23, 0x33, 0x22, 0x21
964 moahead: .byte 0x07, 0x22, 0x23, 0x24, 0x2f, 0x34
965 mocandt: .byte 0x04, 0x60, 0x61
966 mocirrus: .byte 0x06, 0x1f, 0x20, 0x22, 0x31
967 moeverex: .byte 0x0c, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
968 mogenoa: .byte 0x0c, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
969 moparadise: .byte 0x04, 0x55, 0x54
970 motrident: .byte 0x09, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
971 motseng: .byte 0x07, 0x26, 0x2a, 0x23, 0x24, 0x22
972 movideo7: .byte 0x08, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
973 mooakvga: .byte 0x08, 0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
974 mo_S3: .byte 0x04, 0x54, 0x55
975 mounknown: .byte 0x02
976
977 ! msb = Cols lsb = Rows:
978 ! The first two modes are standard vga modes available on any vga.
979 ! mode 0 is 80x50 and mode 1 is 80x28
980
981 dscati: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x641e, 0x6419
982 dscahead: .word 0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042
983 dsccandt: .word 0x5032, 0x501c, 0x8419, 0x8432
984 dsccirrus: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425
985 dsceverex: .word 0x5032, 0x501c, 0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e
986 dscgenoa: .word 0x5032, 0x501c, 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b
987 dscparadise: .word 0x5032, 0x501c, 0x8419, 0x842c
988 dsctrident: .word 0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
989 dsctseng: .word 0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
990 dscvideo7: .word 0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
991 dscoakvga: .word 0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
992 dsc_S3: .word 0x5032, 0x501c, 0x842b, 0x8419
993 dsunknown: .word 0x5032, 0x501c
994 modesave: .word SVGA_MODE
995
996 ! This must be last
997 setup_sig1: .word SIG1
998 setup_sig2: .word SIG2
999
1000 .text
1001 endtext:
1002 .data
1003 enddata:
1004 .bss
1005 endbss: