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