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