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 jmpi 0x1000,KERNEL_CS ! jmp offset 1000 of segment 0x10 (cs)
348
349 ! This routine checks that the keyboard command queue is empty
350 ! (after emptying the output buffers)
351 !
352 ! No timeout is used - if this hangs there is something wrong with
353 ! the machine, and we probably couldn't proceed anyway.
354 empty_8042:
355 call delay
356 in al,#0x64 ! 8042 status port
357 test al,#1 ! output buffer?
358 jz no_output
359 call delay
360 in al,#0x60 ! read it
361 jmp empty_8042
362 no_output:
363 test al,#2 ! is input buffer full?
364 jnz empty_8042 ! yes - loop
365 ret
366 !
367 ! Read a key and return the (US-)ascii code in al, scan code in ah
368 !
369 getkey:
370 xor ah,ah
371 int 0x16
372 ret
373
374 !
375 ! Read a key with a timeout of 30 seconds. The cmos clock is used to get
376 ! the time.
377 !
378 getkt:
379 call gettime
380 add al,#30 ! wait 30 seconds
381 cmp al,#60
382 jl lminute
383 sub al,#60
384 lminute:
385 mov cl,al
386 again: mov ah,#0x01
387 int 0x16
388 jnz getkey ! key pressed, so get it
389 call gettime
390 cmp al,cl
391 jne again
392 mov al,#0x20 ! timeout, return default char `space'
393 ret
394
395 !
396 ! Flush the keyboard buffer
397 !
398 flush: mov ah,#0x01
399 int 0x16
400 jz empty
401 xor ah,ah
402 int 0x16
403 jmp flush
404 empty: ret
405
406 !
407 ! Read the cmos clock. Return the seconds in al
408 !
409 gettime:
410 push cx
411 mov ah,#0x02
412 int 0x1a
413 mov al,dh ! dh contains the seconds
414 and al,#0x0f
415 mov ah,dh
416 mov cl,#0x04
417 shr ah,cl
418 aad
419 pop cx
420 ret
421
422 !
423 ! Delay is needed after doing i/o
424 !
425 delay:
426 .word 0x00eb ! jmp $+2
427 ret
428
429 ! Routine trying to recognize type of SVGA-board present (if any)
430 ! and if it recognize one gives the choices of resolution it offers.
431 ! If one is found the resolution chosen is given by al,ah (rows,cols).
432
433 chsvga: cld
434 push ds
435 push cs
436 mov ax,[0x01fa]
437 pop ds
438 mov modesave,ax
439 mov ax,#0xc000
440 mov es,ax
441 mov ax,modesave
442 cmp ax,#NORMAL_VGA
443 je defvga
444 cmp ax,#EXTENDED_VGA
445 je vga50
446 cmp ax,#ASK_VGA
447 jne svga
448 lea si,msg1
449 call prtstr
450 call flush
451 nokey: call getkt
452 cmp al,#0x0d ! enter ?
453 je svga ! yes - svga selection
454 cmp al,#0x20 ! space ?
455 je defvga ! no - repeat
456 call beep
457 jmp nokey
458 defvga: mov ax,#0x5019
459 pop ds
460 ret
461
462 vga50:
463 mov ax,#0x1112
464 xor bl,bl
465 int 0x10 ! use 8x8 font set (50 lines on VGA)
466 mov ax,#0x1200
467 mov bl,#0x20
468 int 0x10 ! use alternate print screen
469 mov ax,#0x1201
470 mov bl,#0x34
471 int 0x10 ! turn off cursor emulation
472 mov ah,#0x01
473 mov cx,#0x0607
474 int 0x10 ! turn on cursor (scan lines 6 to 7)
475 pop ds
476 mov ax,#0x5032 ! return 80x50
477 ret
478
479 vga28:
480 pop ax ! clean the stack
481 mov ax,#0x1111
482 xor bl,bl
483 int 0x10 ! use 9x14 fontset (28 lines on VGA)
484 mov ah, #0x01
485 mov cx,#0x0b0c
486 int 0x10 ! turn on cursor (scan lines 11 to 12)
487 pop ds
488 mov ax,#0x501c ! return 80x28
489 ret
490
491 !
492 ! test for presence of an S3 VGA chip. The algorithm was taken
493 ! from the SuperProbe package of XFree86 1.2.1
494 ! report bugs to Christoph.Niemann@linux.org
495 !
496 svga: cld
497 mov cx,#0x0f35 ! we store some constants in cl/ch
498 mov dx,#0x03d4
499 movb al,#0x38
500 call inidx
501 mov bh,al ! store current value of CRT-register 0x38
502 mov ax,#0x0038
503 call outidx ! disable writing to special regs
504 movb al,cl ! check whether we can write special reg 0x35
505 call inidx
506 movb bl,al ! save the current value of CRT reg 0x35
507 andb al,#0xf0 ! clear bits 0-3
508 movb ah,al
509 movb al,cl ! and write it to CRT reg 0x35
510 call outidx
511 call inidx ! now read it back
512 andb al,ch ! clear the upper 4 bits
513 jz s3_2 ! the first test failed. But we have a
514 movb ah,bl ! second chance
515 mov al,cl
516 call outidx
517 jmp s3_1 ! do the other tests
518 s3_2: mov ax,cx ! load ah with 0xf and al with 0x35
519 orb ah,bl ! set the upper 4 bits of ah with the orig value
520 call outidx ! write ...
521 call inidx ! ... and reread
522 andb al,cl ! turn off the upper 4 bits
523 push ax
524 movb ah,bl ! restore old value in register 0x35
525 movb al,cl
526 call outidx
527 pop ax
528 cmp al,ch ! setting lower 4 bits was successful => bad
529 je no_s3 ! writing is allowed => this is not an S3
530 s3_1: mov ax,#0x4838 ! allow writing to special regs by putting
531 call outidx ! magic number into CRT-register 0x38
532 movb al,cl ! check whether we can write special reg 0x35
533 call inidx
534 movb bl,al
535 andb al,#0xf0
536 movb ah,al
537 movb al,cl
538 call outidx
539 call inidx
540 andb al,ch
541 jnz no_s3 ! no, we can't write => no S3
542 mov ax,cx
543 orb ah,bl
544 call outidx
545 call inidx
546 andb al,ch
547 push ax
548 movb ah,bl ! restore old value in register 0x35
549 movb al,cl
550 call outidx
551 pop ax
552 cmp al,ch
553 jne no_s31 ! writing not possible => no S3
554 movb al,#0x30
555 call inidx ! now get the S3 id ...
556 lea di,idS3
557 mov cx,#0x10
558 repne
559 scasb
560 je no_s31
561 lea si,dsc_S3 ! table of descriptions of video modes for BIOS
562 lea di,mo_S3 ! table of sizes of video modes for my BIOS
563 movb ah,bh
564 movb al,#0x38
565 call outidx ! restore old value of CRT register 0x38
566 br selmod ! go ask for video mode
567 no_s3: movb al,#0x35 ! restore CRT register 0x35
568 movb ah,bl
569 call outidx
570 no_s31: movb ah,bh
571 movb al,#0x38
572 call outidx ! restore old value of CRT register 0x38
573
574 lea si,idati ! Check ATI 'clues'
575 mov di,#0x31
576 mov cx,#0x09
577 repe
578 cmpsb
579 jne noati
580 lea si,dscati
581 lea di,moati
582 br selmod
583 noati: mov ax,#0x200f ! Check Ahead 'clues'
584 mov dx,#0x3ce
585 out dx,ax
586 inc dx
587 in al,dx
588 cmp al,#0x20
589 je isahed
590 cmp al,#0x21
591 jne noahed
592 isahed: lea si,dscahead
593 lea di,moahead
594 br selmod
595 noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues'
596 in al,dx
597 or al,#0x10
598 out dx,al
599 mov dx,#0x104
600 in al,dx
601 mov bl,al
602 mov dx,#0x3c3
603 in al,dx
604 and al,#0xef
605 out dx,al
606 cmp bl,[idcandt]
607 jne nocant
608 lea si,dsccandt
609 lea di,mocandt
610 br selmod
611 nocant: mov dx,#0x3d4 ! Check Cirrus 'clues'
612 mov al,#0x0c
613 out dx,al
614 inc dx
615 in al,dx
616 mov bl,al
617 xor al,al
618 out dx,al
619 dec dx
620 mov al,#0x1f
621 out dx,al
622 inc dx
623 in al,dx
624 mov bh,al
625 xor ah,ah
626 shl al,#4
627 mov cx,ax
628 mov al,bh
629 shr al,#4
630 add cx,ax
631 shl cx,#8
632 add cx,#6
633 mov ax,cx
634 mov dx,#0x3c4
635 out dx,ax
636 inc dx
637 in al,dx
638 and al,al
639 jnz nocirr
640 mov al,bh
641 out dx,al
642 in al,dx
643 cmp al,#0x01
644 jne nocirr
645 call rst3d4
646 lea si,dsccirrus
647 lea di,mocirrus
648 br selmod
649 rst3d4: mov dx,#0x3d4
650 mov al,bl
651 xor ah,ah
652 shl ax,#8
653 add ax,#0x0c
654 out dx,ax
655 ret
656 nocirr: call rst3d4 ! Check Everex 'clues'
657 mov ax,#0x7000
658 xor bx,bx
659 int 0x10
660 cmp al,#0x70
661 jne noevrx
662 shr dx,#4
663 cmp dx,#0x678
664 je istrid
665 cmp dx,#0x236
666 je istrid
667 lea si,dsceverex
668 lea di,moeverex
669 br selmod
670 istrid: lea cx,ev2tri
671 jmp cx
672 noevrx: lea si,idgenoa ! Check Genoa 'clues'
673 xor ax,ax
674 seg es
675 mov al,[0x37]
676 mov di,ax
677 mov cx,#0x04
678 dec si
679 dec di
680 l1: inc si
681 inc di
682 mov al,(si)
683 test al,al
684 jz l2
685 seg es
686 cmp al,(di)
687 l2: loope l1
688 cmp cx,#0x00
689 jne nogen
690 lea si,dscgenoa
691 lea di,mogenoa
692 br selmod
693 nogen: cld
694 lea si,idoakvga
695 mov di,#0x08
696 mov cx,#0x08
697 repe
698 cmpsb
699 jne nooak
700 lea si,dscoakvga
701 lea di,mooakvga
702 br selmod
703 nooak: cld
704 lea si,idparadise ! Check Paradise 'clues'
705 mov di,#0x7d
706 mov cx,#0x04
707 repe
708 cmpsb
709 jne nopara
710 lea si,dscparadise
711 lea di,moparadise
712 br selmod
713 nopara: mov dx,#0x3c4 ! Check Trident 'clues'
714 mov al,#0x0e
715 out dx,al
716 inc dx
717 in al,dx
718 xchg ah,al
719 xor al,al
720 out dx,al
721 in al,dx
722 xchg al,ah
723 mov bl,al ! Strange thing ... in the book this wasn't
724 and bl,#0x02 ! necessary but it worked on my card which
725 jz setb2 ! is a trident. Without it the screen goes
726 and al,#0xfd ! blurred ...
727 jmp clrb2 !
728 setb2: or al,#0x02 !
729 clrb2: out dx,al
730 and ah,#0x0f
731 cmp ah,#0x02
732 jne notrid
733 ev2tri: lea si,dsctrident
734 lea di,motrident
735 jmp selmod
736 notrid: mov dx,#0x3cd ! Check Tseng 'clues'
737 in al,dx ! Could things be this simple ! :-)
738 mov bl,al
739 mov al,#0x55
740 out dx,al
741 in al,dx
742 mov ah,al
743 mov al,bl
744 out dx,al
745 cmp ah,#0x55
746 jne notsen
747 lea si,dsctseng
748 lea di,motseng
749 jmp selmod
750 notsen: mov dx,#0x3cc ! Check Video7 'clues'
751 in al,dx
752 mov dx,#0x3b4
753 and al,#0x01
754 jz even7
755 mov dx,#0x3d4
756 even7: mov al,#0x0c
757 out dx,al
758 inc dx
759 in al,dx
760 mov bl,al
761 mov al,#0x55
762 out dx,al
763 in al,dx
764 dec dx
765 mov al,#0x1f
766 out dx,al
767 inc dx
768 in al,dx
769 mov bh,al
770 dec dx
771 mov al,#0x0c
772 out dx,al
773 inc dx
774 mov al,bl
775 out dx,al
776 mov al,#0x55
777 xor al,#0xea
778 cmp al,bh
779 jne novid7
780 lea si,dscvideo7
781 lea di,movideo7
782 jmp selmod
783 novid7: lea si,dsunknown
784 lea di,mounknown
785 selmod: xor cx,cx
786 mov cl,(di)
787 mov ax,modesave
788 cmp ax,#ASK_VGA
789 je askmod
790 cmp ax,#NORMAL_VGA
791 je askmod
792 cmp al,cl
793 jl gotmode
794 push si
795 lea si,msg4
796 call prtstr
797 pop si
798 askmod: push si
799 lea si,msg2
800 call prtstr
801 pop si
802 push si
803 push cx
804 tbl: pop bx
805 push bx
806 mov al,bl
807 sub al,cl
808 call modepr
809 lodsw
810 xchg al,ah
811 call dprnt
812 xchg ah,al
813 push ax
814 mov al,#0x78
815 call prnt1
816 pop ax
817 call dprnt
818 push si
819 lea si,crlf ! print CR+LF
820 call prtstr
821 pop si
822 loop tbl
823 pop cx
824 lea si,msg3
825 call prtstr
826 pop si
827 add cl,#0x30
828 jmp nonum
829 nonumb: call beep
830 nonum: call getkey
831 cmp al,#0x30 ! ascii `0'
832 jb nonumb
833 cmp al,#0x3a ! ascii `9'
834 jbe number
835 cmp al,#0x61 ! ascii `a'
836 jb nonumb
837 cmp al,#0x7a ! ascii `z'
838 ja nonumb
839 sub al,#0x27
840 cmp al,cl
841 jae nonumb
842 sub al,#0x30
843 jmp gotmode
844 number: cmp al,cl
845 jae nonumb
846 sub al,#0x30
847 gotmode: xor ah,ah
848 or al,al
849 beq vga50
850 push ax
851 dec ax
852 beq vga28
853 add di,ax
854 mov al,(di)
855 int 0x10
856 pop ax
857 shl ax,#1
858 add si,ax
859 lodsw
860 pop ds
861 ret
862
863 ! Routine to write al into a VGA-register that is
864 ! accessed via an index register
865 !
866 ! dx contains the address of the index register
867 ! al contains the index
868 ! ah contains the value to write to the data register (dx + 1)
869 !
870 ! no registers are changed
871
872 outidx: out dx,al
873 push ax
874 mov al,ah
875 inc dx
876 out dx,al
877 dec dx
878 pop ax
879 ret
880 inidx: out dx,al
881 inc dx
882 in al,dx
883 dec dx
884 ret
885
886 ! Routine to print a decimal value on screen, the value to be
887 ! printed is put in al (i.e 0-255).
888
889 dprnt: push ax
890 push cx
891 xor ah,ah ! Clear ah
892 mov cl,#0x0a
893 idiv cl
894 cmp al,#0x09
895 jbe lt100
896 call dprnt
897 jmp skip10
898 lt100: add al,#0x30
899 call prnt1
900 skip10: mov al,ah
901 add al,#0x30
902 call prnt1
903 pop cx
904 pop ax
905 ret
906
907 !
908 ! Routine to print the mode number key on screen. Mode numbers
909 ! 0-9 print the ascii values `0' to '9', 10-35 are represented by
910 ! the letters `a' to `z'. This routine prints some spaces around the
911 ! mode no.
912 !
913
914 modepr: push ax
915 cmp al,#0x0a
916 jb digit ! Here is no check for number > 35
917 add al,#0x27
918 digit: add al,#0x30
919 mov modenr, al
920 push si
921 lea si, modestring
922 call prtstr
923 pop si
924 pop ax
925 ret
926
927 gdt:
928 .word 0,0,0,0 ! dummy
929
930 .word 0,0,0,0 ! unused
931
932 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
933 .word 0x0000 ! base address=0
934 .word 0x9A00 ! code read/exec
935 .word 0x00C0 ! granularity=4096, 386
936
937 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
938 .word 0x0000 ! base address=0
939 .word 0x9200 ! data read/write
940 .word 0x00C0 ! granularity=4096, 386
941
942 idt_48:
943 .word 0 ! idt limit=0
944 .word 0,0 ! idt base=0L
945
946 gdt_48:
947 .word 0x800 ! gdt limit=2048, 256 GDT entries
948 .word 512+gdt,0x9 ! gdt base = 0X9xxxx
949
950 msg1: .ascii "Press <RETURN> to see SVGA-modes available, <SPACE> to continue or wait 30 secs."
951 db 0x0d, 0x0a, 0x0a, 0x00
952 msg2: .ascii "Mode: COLSxROWS:"
953 db 0x0d, 0x0a, 0x0a, 0x00
954 msg3: db 0x0d, 0x0a
955 .ascii "Choose mode by pressing the corresponding number or letter."
956 crlf: db 0x0d, 0x0a, 0x00
957 msg4: .ascii "You passed an undefined mode number to setup. Please choose a new mode."
958 db 0x0d, 0x0a, 0x0a, 0x07, 0x00
959 modestring: .ascii " "
960 modenr: db 0x00 ! mode number
961 .ascii ": "
962 db 0x00
963
964 idati: .ascii "761295520"
965 idcandt: .byte 0xa5
966 idgenoa: .byte 0x77, 0x00, 0x99, 0x66
967 idparadise: .ascii "VGA="
968 idoakvga: .ascii "OAK VGA "
969 idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
970 .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
971
972 ! Manufacturer: Numofmodes+2: Mode:
973 ! Number of modes is the number of chip-specific svga modes plus the extended
974 ! modes available on any vga (currently 2)
975
976 moati: .byte 0x06, 0x23, 0x33, 0x22, 0x21
977 moahead: .byte 0x07, 0x22, 0x23, 0x24, 0x2f, 0x34
978 mocandt: .byte 0x04, 0x60, 0x61
979 mocirrus: .byte 0x06, 0x1f, 0x20, 0x22, 0x31
980 moeverex: .byte 0x0c, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
981 mogenoa: .byte 0x0c, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
982 moparadise: .byte 0x04, 0x55, 0x54
983 motrident: .byte 0x09, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
984 motseng: .byte 0x07, 0x26, 0x2a, 0x23, 0x24, 0x22
985 movideo7: .byte 0x08, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
986 mooakvga: .byte 0x08, 0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
987 mo_S3: .byte 0x04, 0x54, 0x55
988 mounknown: .byte 0x02
989
990 ! msb = Cols lsb = Rows:
991 ! The first two modes are standard vga modes available on any vga.
992 ! mode 0 is 80x50 and mode 1 is 80x28
993
994 dscati: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x641e, 0x6419
995 dscahead: .word 0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042
996 dsccandt: .word 0x5032, 0x501c, 0x8419, 0x8432
997 dsccirrus: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425
998 dsceverex: .word 0x5032, 0x501c, 0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e
999 dscgenoa: .word 0x5032, 0x501c, 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b
1000 dscparadise: .word 0x5032, 0x501c, 0x8419, 0x842c
1001 dsctrident: .word 0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
1002 dsctseng: .word 0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
1003 dscvideo7: .word 0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
1004 dscoakvga: .word 0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
1005 dsc_S3: .word 0x5032, 0x501c, 0x842b, 0x8419
1006 dsunknown: .word 0x5032, 0x501c
1007 modesave: .word SVGA_MODE
1008
1009 ! This must be last
1010 setup_sig1: .word SIG1
1011 setup_sig2: .word SIG2
1012
1013 .text
1014 endtext:
1015 .data
1016 enddata:
1017 .bss
1018 endbss: