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