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