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