~ubuntu-branches/ubuntu/hardy/kvm/hardy-backports

« back to all changes in this revision

Viewing changes to vgabios/vbe.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2008-01-03 10:39:25 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20080103103925-8480u7sq2646hvbh
Tags: 1:59+dfsg-0ubuntu1
* New upstream release
* Build with alsa support (cherry pick from 57+dfsg-2)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ============================================================================================
 
2
//  
 
3
//  Copyright (C) 2002 Jeroen Janssen
 
4
//
 
5
//  This library is free software; you can redistribute it and/or
 
6
//  modify it under the terms of the GNU Lesser General Public
 
7
//  License as published by the Free Software Foundation; either
 
8
//  version 2 of the License, or (at your option) any later version.
 
9
//
 
10
//  This library is distributed in the hope that it will be useful,
 
11
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
//  Lesser General Public License for more details.
 
14
//
 
15
//  You should have received a copy of the GNU Lesser General Public
 
16
//  License along with this library; if not, write to the Free Software
 
17
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
18
// 
 
19
// ============================================================================================
 
20
//  
 
21
//  This VBE is part of the VGA Bios specific to the plex86/bochs Emulated VGA card. 
 
22
//  You can NOT drive any physical vga card with it. 
 
23
//
 
24
// ============================================================================================
 
25
//  
 
26
//  This VBE Bios is based on information taken from :
 
27
//   - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org
 
28
//
 
29
// ============================================================================================
 
30
 
 
31
 
 
32
// defines available
 
33
 
 
34
// disable VESA/VBE2 check in vbe info
 
35
//#define VBE2_NO_VESA_CHECK
 
36
 
 
37
 
 
38
#include "vbe.h"
 
39
#include "vbetables.h"
 
40
 
 
41
#define VBE_TOTAL_VIDEO_MEMORY_DIV_64K (VBE_DISPI_TOTAL_VIDEO_MEMORY_MB*1024/64)
 
42
 
 
43
// The current OEM Software Revision of this VBE Bios
 
44
#define VBE_OEM_SOFTWARE_REV 0x0002;
 
45
 
 
46
extern char vbebios_copyright;
 
47
extern char vbebios_vendor_name;
 
48
extern char vbebios_product_name;
 
49
extern char vbebios_product_revision;
 
50
 
 
51
ASM_START
 
52
// FIXME: 'merge' these (c) etc strings with the vgabios.c strings?
 
53
_vbebios_copyright:
 
54
.ascii       "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/"
 
55
.byte        0x00
 
56
 
 
57
_vbebios_vendor_name:
 
58
.ascii       "Bochs/Plex86 Developers"
 
59
.byte        0x00
 
60
 
 
61
_vbebios_product_name:
 
62
.ascii       "Bochs/Plex86 VBE Adapter"
 
63
.byte        0x00
 
64
 
 
65
_vbebios_product_revision:
 
66
.ascii       "$Id: vbe.c,v 1.58 2006/08/19 09:39:43 vruppert Exp $"
 
67
.byte        0x00
 
68
 
 
69
_vbebios_info_string:
 
70
.ascii      "Bochs VBE Display Adapter enabled"
 
71
.byte   0x0a,0x0d
 
72
.byte   0x0a,0x0d
 
73
.byte   0x00
 
74
 
 
75
_no_vbebios_info_string:
 
76
.ascii      "NO Bochs VBE Support available!"
 
77
.byte   0x0a,0x0d
 
78
.byte   0x0a,0x0d
 
79
.byte 0x00
 
80
 
 
81
#if defined(USE_BX_INFO) || defined(DEBUG)
 
82
msg_vbe_init:
 
83
.ascii      "VBE Bios $Id: vbe.c,v 1.58 2006/08/19 09:39:43 vruppert Exp $"
 
84
.byte   0x0a,0x0d, 0x00
 
85
#endif
 
86
 
 
87
  .align 2
 
88
vesa_pm_start:
 
89
  dw vesa_pm_set_window - vesa_pm_start
 
90
  dw vesa_pm_set_display_start - vesa_pm_start
 
91
  dw vesa_pm_unimplemented - vesa_pm_start
 
92
  dw vesa_pm_io_ports_table - vesa_pm_start
 
93
vesa_pm_io_ports_table:
 
94
  dw VBE_DISPI_IOPORT_INDEX
 
95
  dw VBE_DISPI_IOPORT_INDEX + 1
 
96
  dw VBE_DISPI_IOPORT_DATA
 
97
  dw VBE_DISPI_IOPORT_DATA + 1
 
98
  dw 0xffff
 
99
  dw 0xffff
 
100
 
 
101
  USE32
 
102
vesa_pm_set_window:
 
103
  cmp  bx, #0x00
 
104
  je  vesa_pm_set_display_window1
 
105
  mov  ax, #0x0100
 
106
  ret
 
107
vesa_pm_set_display_window1:
 
108
  mov  ax, dx
 
109
  push dx
 
110
  push ax
 
111
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
112
  mov  ax, # VBE_DISPI_INDEX_BANK
 
113
  out  dx, ax
 
114
  pop  ax
 
115
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
116
  out  dx, ax
 
117
  in   ax, dx
 
118
  pop  dx
 
119
  cmp  dx, ax
 
120
  jne  illegal_window
 
121
  mov  ax, #0x004f
 
122
  ret
 
123
illegal_window:
 
124
  mov  ax, #0x014f
 
125
  ret
 
126
 
 
127
vesa_pm_set_display_start:
 
128
  cmp  bl, #0x80
 
129
  je   vesa_pm_set_display_start1
 
130
  cmp  bl, #0x00
 
131
  je   vesa_pm_set_display_start1
 
132
  mov  ax, #0x0100
 
133
  ret
 
134
vesa_pm_set_display_start1:
 
135
; convert offset to (X, Y) coordinate 
 
136
; (would be simpler to change Bochs VBE API...)
 
137
  push eax
 
138
  push ecx
 
139
  push edx
 
140
  push esi
 
141
  push edi
 
142
  shl edx, #16
 
143
  and ecx, #0xffff
 
144
  or ecx, edx
 
145
  shl ecx, #2
 
146
  mov eax, ecx
 
147
 
 
148
  push eax
 
149
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
150
  mov  ax, # VBE_DISPI_INDEX_VIRT_WIDTH
 
151
  out  dx, ax
 
152
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
153
  in   ax, dx
 
154
  movzx ecx, ax
 
155
 
 
156
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
157
  mov  ax, # VBE_DISPI_INDEX_BPP
 
158
  out  dx, ax
 
159
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
160
  in   ax, dx
 
161
  movzx esi, ax
 
162
  pop  eax
 
163
 
 
164
  cmp esi, #4
 
165
  jz bpp4_mode
 
166
  add esi, #7
 
167
  shr esi, #3
 
168
  imul ecx, esi
 
169
  xor edx, edx
 
170
  div ecx
 
171
  mov edi, eax
 
172
  mov eax, edx
 
173
  xor edx, edx
 
174
  div esi
 
175
  jmp set_xy_regs
 
176
 
 
177
bpp4_mode:
 
178
  shr ecx, #1
 
179
  xor edx, edx
 
180
  div ecx
 
181
  mov edi, eax
 
182
  mov eax, edx
 
183
  shl eax, #1
 
184
 
 
185
set_xy_regs:
 
186
  push dx
 
187
  push ax
 
188
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
189
  mov  ax, # VBE_DISPI_INDEX_X_OFFSET
 
190
  out  dx, ax
 
191
  pop  ax
 
192
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
193
  out  dx, ax
 
194
  pop  dx
 
195
 
 
196
  mov  ax, di
 
197
  push dx
 
198
  push ax
 
199
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
200
  mov  ax, # VBE_DISPI_INDEX_Y_OFFSET
 
201
  out  dx, ax
 
202
  pop  ax
 
203
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
204
  out  dx, ax
 
205
  pop  dx
 
206
 
 
207
  pop edi
 
208
  pop esi
 
209
  pop edx
 
210
  pop ecx
 
211
  pop eax
 
212
  mov  ax, #0x004f
 
213
  ret
 
214
 
 
215
vesa_pm_unimplemented:
 
216
  mov ax, #0x014f
 
217
  ret
 
218
  USE16
 
219
vesa_pm_end:
 
220
 
 
221
; DISPI ioport functions
 
222
 
 
223
dispi_get_id:
 
224
  push dx
 
225
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
226
  mov  ax, # VBE_DISPI_INDEX_ID
 
227
  out  dx, ax
 
228
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
229
  in   ax, dx
 
230
  pop  dx
 
231
  ret
 
232
 
 
233
dispi_set_id:
 
234
  push dx
 
235
  push ax
 
236
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
237
  mov  ax, # VBE_DISPI_INDEX_ID
 
238
  out  dx, ax
 
239
  pop  ax
 
240
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
241
  out  dx, ax
 
242
  pop  dx
 
243
  ret
 
244
ASM_END
 
245
 
 
246
static void dispi_set_xres(xres)
 
247
  Bit16u xres;
 
248
{
 
249
ASM_START
 
250
  push bp
 
251
  mov  bp, sp
 
252
  push ax
 
253
  push dx
 
254
 
 
255
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
256
  mov  ax, # VBE_DISPI_INDEX_XRES
 
257
  out  dx, ax
 
258
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
259
  mov  ax, 4[bp] ; xres
 
260
  out  dx, ax
 
261
 
 
262
  pop  dx
 
263
  pop  ax
 
264
  pop  bp
 
265
ASM_END
 
266
}
 
267
 
 
268
static void dispi_set_yres(yres)
 
269
  Bit16u yres;
 
270
{
 
271
  outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES);
 
272
  outw(VBE_DISPI_IOPORT_DATA,yres);
 
273
}
 
274
 
 
275
static void dispi_set_bpp(bpp)
 
276
  Bit16u bpp;
 
277
{
 
278
  outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP);
 
279
  outw(VBE_DISPI_IOPORT_DATA,bpp);
 
280
}
 
281
 
 
282
ASM_START
 
283
; AL = bits per pixel / AH = bytes per pixel
 
284
dispi_get_bpp:
 
285
  push dx
 
286
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
287
  mov  ax, # VBE_DISPI_INDEX_BPP
 
288
  out  dx, ax
 
289
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
290
  in   ax, dx
 
291
  mov  ah, al
 
292
  shr  ah, 3
 
293
  test al, #0x07
 
294
  jz   get_bpp_noinc
 
295
  inc  ah
 
296
get_bpp_noinc:
 
297
  pop  dx
 
298
  ret
 
299
 
 
300
; get display capabilities
 
301
 
 
302
_dispi_get_max_xres:
 
303
  push dx
 
304
  push bx
 
305
  call dispi_get_enable
 
306
  mov  bx, ax
 
307
  or   ax, # VBE_DISPI_GETCAPS
 
308
  call _dispi_set_enable
 
309
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
310
  mov  ax, # VBE_DISPI_INDEX_XRES
 
311
  out  dx, ax
 
312
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
313
  in   ax, dx
 
314
  push ax
 
315
  mov  ax, bx
 
316
  call _dispi_set_enable
 
317
  pop  ax
 
318
  pop  bx
 
319
  pop  dx
 
320
  ret
 
321
 
 
322
_dispi_get_max_bpp:
 
323
  push dx
 
324
  push bx
 
325
  call dispi_get_enable
 
326
  mov  bx, ax
 
327
  or   ax, # VBE_DISPI_GETCAPS
 
328
  call _dispi_set_enable
 
329
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
330
  mov  ax, # VBE_DISPI_INDEX_BPP
 
331
  out  dx, ax
 
332
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
333
  in   ax, dx
 
334
  push ax
 
335
  mov  ax, bx
 
336
  call _dispi_set_enable
 
337
  pop  ax
 
338
  pop  bx
 
339
  pop  dx
 
340
  ret
 
341
 
 
342
_dispi_set_enable:
 
343
  push dx
 
344
  push ax
 
345
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
346
  mov  ax, # VBE_DISPI_INDEX_ENABLE
 
347
  out  dx, ax
 
348
  pop  ax
 
349
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
350
  out  dx, ax
 
351
  pop  dx
 
352
  ret
 
353
 
 
354
dispi_get_enable:
 
355
  push dx
 
356
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
357
  mov  ax, # VBE_DISPI_INDEX_ENABLE
 
358
  out  dx, ax
 
359
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
360
  in   ax, dx
 
361
  pop  dx
 
362
  ret
 
363
 
 
364
_dispi_set_bank:
 
365
  push dx
 
366
  push ax
 
367
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
368
  mov  ax, # VBE_DISPI_INDEX_BANK
 
369
  out  dx, ax
 
370
  pop  ax
 
371
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
372
  out  dx, ax
 
373
  pop  dx
 
374
  ret
 
375
 
 
376
dispi_get_bank:
 
377
  push dx
 
378
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
379
  mov  ax, # VBE_DISPI_INDEX_BANK
 
380
  out  dx, ax
 
381
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
382
  in   ax, dx
 
383
  pop  dx
 
384
  ret
 
385
ASM_END
 
386
 
 
387
static void dispi_set_bank_farcall()
 
388
{
 
389
ASM_START
 
390
  cmp bx,#0x0100
 
391
  je dispi_set_bank_farcall_get
 
392
  or bx,bx
 
393
  jnz dispi_set_bank_farcall_error
 
394
  mov ax,dx
 
395
  push dx
 
396
  push ax
 
397
  mov ax,# VBE_DISPI_INDEX_BANK
 
398
  mov dx,# VBE_DISPI_IOPORT_INDEX
 
399
  out dx,ax
 
400
  pop ax
 
401
  mov dx,# VBE_DISPI_IOPORT_DATA
 
402
  out dx,ax
 
403
  in  ax,dx
 
404
  pop dx
 
405
  cmp dx,ax
 
406
  jne dispi_set_bank_farcall_error
 
407
  mov ax, #0x004f
 
408
  retf
 
409
dispi_set_bank_farcall_get:
 
410
  mov ax,# VBE_DISPI_INDEX_BANK
 
411
  mov dx,# VBE_DISPI_IOPORT_INDEX
 
412
  out dx,ax
 
413
  mov dx,# VBE_DISPI_IOPORT_DATA
 
414
  in ax,dx
 
415
  mov dx,ax
 
416
  retf
 
417
dispi_set_bank_farcall_error:
 
418
  mov ax,#0x014F
 
419
  retf
 
420
ASM_END
 
421
}
 
422
 
 
423
ASM_START
 
424
dispi_set_x_offset:
 
425
  push dx
 
426
  push ax
 
427
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
428
  mov  ax, # VBE_DISPI_INDEX_X_OFFSET
 
429
  out  dx, ax
 
430
  pop  ax
 
431
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
432
  out  dx, ax
 
433
  pop  dx
 
434
  ret
 
435
 
 
436
dispi_get_x_offset:
 
437
  push dx
 
438
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
439
  mov  ax, # VBE_DISPI_INDEX_X_OFFSET
 
440
  out  dx, ax
 
441
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
442
  in   ax, dx
 
443
  pop  dx
 
444
  ret
 
445
 
 
446
dispi_set_y_offset:
 
447
  push dx
 
448
  push ax
 
449
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
450
  mov  ax, # VBE_DISPI_INDEX_Y_OFFSET
 
451
  out  dx, ax
 
452
  pop  ax
 
453
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
454
  out  dx, ax
 
455
  pop  dx
 
456
  ret
 
457
 
 
458
dispi_get_y_offset:
 
459
  push dx
 
460
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
461
  mov  ax, # VBE_DISPI_INDEX_Y_OFFSET
 
462
  out  dx, ax
 
463
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
464
  in   ax, dx
 
465
  pop  dx
 
466
  ret
 
467
 
 
468
vga_set_virt_width:
 
469
  push ax
 
470
  push bx
 
471
  push dx
 
472
  mov  bx, ax
 
473
  call dispi_get_bpp
 
474
  cmp  al, #0x04
 
475
  ja   set_width_svga
 
476
  shr  bx, #1
 
477
set_width_svga:
 
478
  shr  bx, #3
 
479
  mov  dx, # VGAREG_VGA_CRTC_ADDRESS
 
480
  mov  ah, bl
 
481
  mov  al, #0x13
 
482
  out  dx, ax
 
483
  pop  dx
 
484
  pop  bx
 
485
  pop  ax
 
486
  ret
 
487
 
 
488
dispi_set_virt_width:
 
489
  call vga_set_virt_width
 
490
  push dx
 
491
  push ax
 
492
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
493
  mov  ax, # VBE_DISPI_INDEX_VIRT_WIDTH
 
494
  out  dx, ax
 
495
  pop  ax
 
496
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
497
  out  dx, ax
 
498
  pop  dx
 
499
  ret
 
500
 
 
501
dispi_get_virt_width:
 
502
  push dx
 
503
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
504
  mov  ax, # VBE_DISPI_INDEX_VIRT_WIDTH
 
505
  out  dx, ax
 
506
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
507
  in   ax, dx
 
508
  pop  dx
 
509
  ret
 
510
 
 
511
dispi_get_virt_height:
 
512
  push dx
 
513
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
514
  mov  ax, # VBE_DISPI_INDEX_VIRT_HEIGHT
 
515
  out  dx, ax
 
516
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
517
  in   ax, dx
 
518
  pop  dx
 
519
  ret
 
520
 
 
521
_vga_compat_setup:
 
522
  push ax
 
523
  push dx
 
524
 
 
525
  ; set CRT X resolution
 
526
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
527
  mov  ax, # VBE_DISPI_INDEX_XRES
 
528
  out  dx, ax
 
529
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
530
  in   ax, dx
 
531
  push ax
 
532
  mov  dx, # VGAREG_VGA_CRTC_ADDRESS
 
533
  mov  ax, #0x0011
 
534
  out  dx, ax
 
535
  pop  ax
 
536
  push ax
 
537
  shr  ax, #3
 
538
  dec  ax
 
539
  mov  ah, al
 
540
  mov  al, #0x01
 
541
  out  dx, ax
 
542
  pop  ax
 
543
  call vga_set_virt_width
 
544
 
 
545
  ; set CRT Y resolution
 
546
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
547
  mov  ax, # VBE_DISPI_INDEX_YRES
 
548
  out  dx, ax
 
549
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
550
  in   ax, dx
 
551
  dec  ax
 
552
  push ax
 
553
  mov  dx, # VGAREG_VGA_CRTC_ADDRESS
 
554
  mov  ah, al
 
555
  mov  al, #0x12
 
556
  out  dx, ax
 
557
  pop  ax
 
558
  mov  al, #0x07
 
559
  out  dx, al
 
560
  inc  dx
 
561
  in   al, dx
 
562
  and  al, #0xbd
 
563
  test ah, #0x01
 
564
  jz   bit8_clear
 
565
  or   al, #0x02
 
566
bit8_clear:
 
567
  test ah, #0x02
 
568
  jz   bit9_clear
 
569
  or   al, #0x40
 
570
bit9_clear:
 
571
  out  dx, al
 
572
 
 
573
  ; other settings
 
574
  mov  dx, # VGAREG_VGA_CRTC_ADDRESS
 
575
  mov  ax, #0x0009
 
576
  out  dx, ax
 
577
  mov  al, #0x17
 
578
  out  dx, al
 
579
  mov  dx, # VGAREG_VGA_CRTC_DATA
 
580
  in   al, dx
 
581
  or   al, #0x03
 
582
  out  dx, al
 
583
  mov  dx, # VGAREG_ACTL_RESET
 
584
  in   al, dx
 
585
  mov  dx, # VGAREG_ACTL_ADDRESS
 
586
  mov  al, #0x10
 
587
  out  dx, al
 
588
  mov  dx, # VGAREG_ACTL_READ_DATA
 
589
  in   al, dx
 
590
  or   al, #0x01
 
591
  mov  dx, # VGAREG_ACTL_ADDRESS
 
592
  out  dx, al
 
593
  mov  al, #0x20
 
594
  out  dx, al
 
595
  mov  dx, # VGAREG_GRDC_ADDRESS
 
596
  mov  ax, #0x0506
 
597
  out  dx, ax
 
598
  mov  dx, # VGAREG_SEQU_ADDRESS
 
599
  mov  ax, #0x0f02
 
600
  out  dx, ax
 
601
 
 
602
  ; settings for >= 8bpp
 
603
  mov  dx, # VBE_DISPI_IOPORT_INDEX
 
604
  mov  ax, # VBE_DISPI_INDEX_BPP
 
605
  out  dx, ax
 
606
  mov  dx, # VBE_DISPI_IOPORT_DATA
 
607
  in   ax, dx
 
608
  cmp  al, #0x08
 
609
  jb   vga_compat_end
 
610
  mov  dx, # VGAREG_VGA_CRTC_ADDRESS
 
611
  mov  al, #0x14
 
612
  out  dx, al
 
613
  mov  dx, # VGAREG_VGA_CRTC_DATA
 
614
  in   al, dx
 
615
  or   al, #0x40
 
616
  out  dx, al
 
617
  mov  dx, # VGAREG_ACTL_RESET
 
618
  in   al, dx
 
619
  mov  dx, # VGAREG_ACTL_ADDRESS
 
620
  mov  al, #0x10
 
621
  out  dx, al
 
622
  mov  dx, # VGAREG_ACTL_READ_DATA
 
623
  in   al, dx
 
624
  or   al, #0x40
 
625
  mov  dx, # VGAREG_ACTL_ADDRESS
 
626
  out  dx, al
 
627
  mov  al, #0x20
 
628
  out  dx, al
 
629
  mov  dx, # VGAREG_SEQU_ADDRESS
 
630
  mov  al, #0x04
 
631
  out  dx, al
 
632
  mov  dx, # VGAREG_SEQU_DATA
 
633
  in   al, dx
 
634
  or   al, #0x08
 
635
  out  dx, al
 
636
  mov  dx, # VGAREG_GRDC_ADDRESS
 
637
  mov  al, #0x05
 
638
  out  dx, al
 
639
  mov  dx, # VGAREG_GRDC_DATA
 
640
  in   al, dx
 
641
  and  al, #0x9f
 
642
  or   al, #0x40
 
643
  out  dx, al
 
644
 
 
645
vga_compat_end:
 
646
  pop  dx
 
647
  pop  ax
 
648
ASM_END
 
649
 
 
650
 
 
651
// ModeInfo helper function
 
652
static ModeInfoListItem* mode_info_find_mode(mode, using_lfb)
 
653
  Bit16u mode; Boolean using_lfb;
 
654
{
 
655
  ModeInfoListItem  *cur_info=&mode_info_list;
 
656
 
 
657
  while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST)
 
658
  {
 
659
    if (cur_info->mode == mode)
 
660
    {
 
661
      if (!using_lfb)
 
662
      {
 
663
        return cur_info;
 
664
      }
 
665
      else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE)
 
666
      {
 
667
        return cur_info;
 
668
      }
 
669
      else
 
670
      {
 
671
        cur_info++;
 
672
      }
 
673
    }
 
674
    else
 
675
    {
 
676
      cur_info++;
 
677
    }
 
678
  }
 
679
 
 
680
  return 0;
 
681
}
 
682
 
 
683
ASM_START
 
684
 
 
685
; Has VBE display - Returns true if VBE display detected
 
686
 
 
687
_vbe_has_vbe_display:
 
688
  push ds
 
689
  push bx
 
690
  mov  ax, # BIOSMEM_SEG
 
691
  mov  ds, ax
 
692
  mov  bx, # BIOSMEM_VBE_FLAG
 
693
  mov  al, [bx]
 
694
  and  al, #0x01
 
695
  xor  ah, ah
 
696
  pop  bx
 
697
  pop  ds
 
698
  ret
 
699
 
 
700
; VBE Init - Initialise the Vesa Bios Extension Code
 
701
; This function does a sanity check on the host side display code interface.
 
702
 
 
703
vbe_init:
 
704
  mov  ax, # VBE_DISPI_ID0
 
705
  call dispi_set_id
 
706
  call dispi_get_id
 
707
  cmp  ax, # VBE_DISPI_ID0
 
708
  jne  no_vbe_interface
 
709
  push ds
 
710
  push bx
 
711
  mov  ax, # BIOSMEM_SEG
 
712
  mov  ds, ax
 
713
  mov  bx, # BIOSMEM_VBE_FLAG
 
714
  mov  al, #0x01
 
715
  mov  [bx], al
 
716
  pop  bx
 
717
  pop  ds
 
718
  mov  ax, # VBE_DISPI_ID4
 
719
  call dispi_set_id
 
720
no_vbe_interface:
 
721
#if defined(USE_BX_INFO) || defined(DEBUG)
 
722
  mov  bx, #msg_vbe_init
 
723
  push bx
 
724
  call _printf
 
725
  inc  sp
 
726
  inc  sp
 
727
#endif
 
728
  ret
 
729
 
 
730
; VBE Display Info - Display information on screen about the VBE
 
731
 
 
732
vbe_display_info:
 
733
  call _vbe_has_vbe_display
 
734
  test ax, ax
 
735
  jz   no_vbe_flag
 
736
  mov  ax, #0xc000
 
737
  mov  ds, ax
 
738
  mov  si, #_vbebios_info_string
 
739
  jmp  _display_string
 
740
no_vbe_flag:
 
741
  mov  ax, #0xc000
 
742
  mov  ds, ax
 
743
  mov  si, #_no_vbebios_info_string
 
744
  jmp  _display_string
 
745
ASM_END  
 
746
 
 
747
/** Function 00h - Return VBE Controller Information
 
748
 * 
 
749
 * Input:
 
750
 *              AX      = 4F00h
 
751
 *              ES:DI   = Pointer to buffer in which to place VbeInfoBlock structure
 
752
 *                        (VbeSignature should be VBE2 when VBE 2.0 information is desired and
 
753
 *                        the info block is 512 bytes in size)
 
754
 * Output:
 
755
 *              AX      = VBE Return Status
 
756
 * 
 
757
 */
 
758
void vbe_biosfn_return_controller_information(AX, ES, DI)
 
759
Bit16u *AX;Bit16u ES;Bit16u DI;
 
760
{
 
761
        Bit16u            ss=get_SS();
 
762
        VbeInfoBlock      vbe_info_block;
 
763
        Bit16u            status;
 
764
        Bit16u            result;
 
765
        Bit16u            vbe2_info;
 
766
        Bit16u            cur_mode=0;
 
767
        Bit16u            cur_ptr=34;
 
768
        ModeInfoListItem  *cur_info=&mode_info_list;
 
769
        
 
770
        status = read_word(ss, AX);
 
771
        
 
772
#ifdef DEBUG
 
773
        printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status);
 
774
#endif
 
775
 
 
776
        vbe2_info = 0;
 
777
#ifdef VBE2_NO_VESA_CHECK
 
778
#else
 
779
        // get vbe_info_block into local variable
 
780
        memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block));
 
781
 
 
782
        // check for VBE2 signature
 
783
        if (((vbe_info_block.VbeSignature[0] == 'V') &&
 
784
             (vbe_info_block.VbeSignature[1] == 'B') &&
 
785
             (vbe_info_block.VbeSignature[2] == 'E') &&
 
786
             (vbe_info_block.VbeSignature[3] == '2')) ||
 
787
             
 
788
            ((vbe_info_block.VbeSignature[0] == 'V') &&
 
789
             (vbe_info_block.VbeSignature[1] == 'E') &&
 
790
             (vbe_info_block.VbeSignature[2] == 'S') &&
 
791
             (vbe_info_block.VbeSignature[3] == 'A')) )
 
792
        {
 
793
                vbe2_info = 1;
 
794
#ifdef DEBUG
 
795
                printf("VBE correct VESA/VBE2 signature found\n");
 
796
#endif
 
797
        }
 
798
#endif
 
799
                
 
800
        // VBE Signature
 
801
        vbe_info_block.VbeSignature[0] = 'V';
 
802
        vbe_info_block.VbeSignature[1] = 'E';
 
803
        vbe_info_block.VbeSignature[2] = 'S';
 
804
        vbe_info_block.VbeSignature[3] = 'A';
 
805
        
 
806
        // VBE Version supported
 
807
        vbe_info_block.VbeVersion = 0x0200;
 
808
        
 
809
        // OEM String
 
810
        vbe_info_block.OemStringPtr_Seg = 0xc000;
 
811
        vbe_info_block.OemStringPtr_Off = &vbebios_copyright;
 
812
        
 
813
        // Capabilities
 
814
        vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC;
 
815
        vbe_info_block.Capabilities[1] = 0;
 
816
        vbe_info_block.Capabilities[2] = 0;
 
817
        vbe_info_block.Capabilities[3] = 0;
 
818
 
 
819
        // VBE Video Mode Pointer (dynamicly generated from the mode_info_list)
 
820
        vbe_info_block.VideoModePtr_Seg= ES ;
 
821
        vbe_info_block.VideoModePtr_Off= DI + 34;
 
822
 
 
823
        // VBE Total Memory (in 64b blocks)
 
824
        vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K;
 
825
 
 
826
        if (vbe2_info)
 
827
        {
 
828
                // OEM Stuff
 
829
                vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV;
 
830
                vbe_info_block.OemVendorNamePtr_Seg = 0xc000;
 
831
                vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name;
 
832
                vbe_info_block.OemProductNamePtr_Seg = 0xc000;
 
833
                vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name;
 
834
                vbe_info_block.OemProductRevPtr_Seg = 0xc000;
 
835
                vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision;
 
836
 
 
837
                // copy updates in vbe_info_block back
 
838
                memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block));
 
839
        }
 
840
        else
 
841
        {
 
842
                // copy updates in vbe_info_block back (VBE 1.x compatibility)
 
843
                memcpyb(ES, DI, ss, &vbe_info_block, 256);
 
844
        }
 
845
                
 
846
        do
 
847
        {
 
848
                if ((cur_info->info.XResolution <= dispi_get_max_xres()) &&
 
849
                    (cur_info->info.BitsPerPixel <= dispi_get_max_bpp())) {
 
850
#ifdef DEBUG
 
851
                  printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode);
 
852
#endif
 
853
                  write_word(ES, DI + cur_ptr, cur_info->mode);
 
854
                  cur_mode++;
 
855
                  cur_ptr+=2;
 
856
                }
 
857
                cur_info++;
 
858
        } while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST);
 
859
        
 
860
        // Add vesa mode list terminator
 
861
        write_word(ES, DI + cur_ptr, cur_info->mode);
 
862
 
 
863
        result = 0x4f;
 
864
 
 
865
        write_word(ss, AX, result);
 
866
}
 
867
 
 
868
 
 
869
/** Function 01h - Return VBE Mode Information
 
870
 * 
 
871
 * Input:
 
872
 *              AX      = 4F01h
 
873
 *              CX      = Mode Number
 
874
 *              ES:DI   = Pointer to buffer in which to place ModeInfoBlock structure
 
875
 * Output:
 
876
 *              AX      = VBE Return Status
 
877
 * 
 
878
 */
 
879
void vbe_biosfn_return_mode_information(AX, CX, ES, DI)
 
880
Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
 
881
{
 
882
        Bit16u            result=0x0100;
 
883
        Bit16u            ss=get_SS();
 
884
        ModeInfoBlock     info;
 
885
        ModeInfoListItem  *cur_info;
 
886
        Boolean           using_lfb;
 
887
 
 
888
#ifdef DEBUG
 
889
        printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX);
 
890
#endif
 
891
 
 
892
        using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
 
893
        
 
894
        CX = (CX & 0x1ff);
 
895
        
 
896
        cur_info = mode_info_find_mode(CX, using_lfb, &cur_info);
 
897
 
 
898
        if (cur_info != 0)
 
899
        {
 
900
#ifdef DEBUG
 
901
                printf("VBE found mode %x\n",CX);
 
902
#endif        
 
903
                memsetb(ss, &info, 0, sizeof(ModeInfoBlock));
 
904
                memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact));
 
905
                if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) {
 
906
                  info.WinFuncPtr = 0xC0000000UL;
 
907
                  *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall);
 
908
                }
 
909
                
 
910
                result = 0x4f;
 
911
        }
 
912
        else
 
913
        {
 
914
#ifdef DEBUG
 
915
                printf("VBE *NOT* found mode %x\n",CX);
 
916
#endif
 
917
                result = 0x100;
 
918
        }
 
919
        
 
920
        if (result == 0x4f)
 
921
        {
 
922
                // copy updates in mode_info_block back
 
923
                memcpyb(ES, DI, ss, &info, sizeof(info));
 
924
        }
 
925
 
 
926
        write_word(ss, AX, result);
 
927
}
 
928
 
 
929
/** Function 02h - Set VBE Mode
 
930
 * 
 
931
 * Input:
 
932
 *              AX      = 4F02h
 
933
 *              BX      = Desired Mode to set
 
934
 *              ES:DI   = Pointer to CRTCInfoBlock structure
 
935
 * Output:
 
936
 *              AX      = VBE Return Status
 
937
 * 
 
938
 */
 
939
void vbe_biosfn_set_mode(AX, BX, ES, DI)
 
940
Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI;
 
941
{
 
942
        Bit16u            ss = get_SS();
 
943
        Bit16u            result;
 
944
        ModeInfoListItem  *cur_info;
 
945
        Boolean           using_lfb;
 
946
        Bit8u             no_clear;
 
947
        Bit8u             lfb_flag;
 
948
 
 
949
        using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
 
950
        lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0;
 
951
        no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0;
 
952
 
 
953
        BX = (BX & 0x1ff);
 
954
 
 
955
        //result=read_word(ss,AX);
 
956
        
 
957
        // check for non vesa mode
 
958
        if (BX<VBE_MODE_VESA_DEFINED)
 
959
        {
 
960
                Bit8u   mode;
 
961
                
 
962
                dispi_set_enable(VBE_DISPI_DISABLED);
 
963
                // call the vgabios in order to set the video mode
 
964
                // this allows for going back to textmode with a VBE call (some applications expect that to work)
 
965
                
 
966
                mode=(BX & 0xff);
 
967
                biosfn_set_video_mode(mode);
 
968
                result = 0x4f;
 
969
        }
 
970
        
 
971
        cur_info = mode_info_find_mode(BX, using_lfb, &cur_info);
 
972
 
 
973
        if (cur_info != 0)
 
974
        {
 
975
#ifdef DEBUG
 
976
                printf("VBE found mode %x, setting:\n", BX);
 
977
                printf("\txres%x yres%x bpp%x\n",
 
978
                        cur_info->info.XResolution,
 
979
                        cur_info->info.YResolution,
 
980
                        cur_info->info.BitsPerPixel);
 
981
#endif
 
982
                
 
983
                // first disable current mode (when switching between vesa modi)
 
984
                dispi_set_enable(VBE_DISPI_DISABLED);
 
985
 
 
986
                if (cur_info->info.BitsPerPixel == 4)
 
987
                {
 
988
                  biosfn_set_video_mode(0x6a);
 
989
                }
 
990
 
 
991
                dispi_set_bpp(cur_info->info.BitsPerPixel);
 
992
                dispi_set_xres(cur_info->info.XResolution);
 
993
                dispi_set_yres(cur_info->info.YResolution);
 
994
                dispi_set_bank(0);
 
995
                dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag);
 
996
                vga_compat_setup();
 
997
 
 
998
                write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX);
 
999
                write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear));
 
1000
 
 
1001
                result = 0x4f;                  
 
1002
        }
 
1003
        else
 
1004
        {
 
1005
#ifdef DEBUG
 
1006
                printf("VBE *NOT* found mode %x\n" , BX);
 
1007
#endif        
 
1008
                result = 0x100;
 
1009
                
 
1010
                // FIXME: redirect non VBE modi to normal VGA bios operation
 
1011
                //        (switch back to VGA mode
 
1012
                if (BX == 3)
 
1013
                        result = 0x4f;
 
1014
        }
 
1015
 
 
1016
        write_word(ss, AX, result);
 
1017
}
 
1018
 
 
1019
/** Function 03h - Return Current VBE Mode
 
1020
 * 
 
1021
 * Input:
 
1022
 *              AX      = 4F03h
 
1023
 * Output:
 
1024
 *              AX      = VBE Return Status
 
1025
 *              BX      = Current VBE Mode
 
1026
 * 
 
1027
 */
 
1028
ASM_START
 
1029
vbe_biosfn_return_current_mode:
 
1030
  push ds
 
1031
  mov  ax, # BIOSMEM_SEG
 
1032
  mov  ds, ax
 
1033
  call dispi_get_enable
 
1034
  and  ax, # VBE_DISPI_ENABLED
 
1035
  jz   no_vbe_mode
 
1036
  mov  bx, # BIOSMEM_VBE_MODE
 
1037
  mov  ax, [bx]
 
1038
  mov  bx, ax
 
1039
  jnz  vbe_03_ok
 
1040
no_vbe_mode:
 
1041
  mov  bx, # BIOSMEM_CURRENT_MODE
 
1042
  mov  al, [bx]
 
1043
  mov  bl, al
 
1044
  xor  bh, bh
 
1045
vbe_03_ok:
 
1046
  mov  ax, #0x004f
 
1047
  pop  ds
 
1048
  ret
 
1049
ASM_END
 
1050
 
 
1051
 
 
1052
Bit16u vbe_biosfn_read_video_state_size()
 
1053
{
 
1054
    return 9 * 2;
 
1055
}
 
1056
 
 
1057
void vbe_biosfn_save_video_state(ES, BX)
 
1058
     Bit16u ES; Bit16u BX;
 
1059
{
 
1060
    Bit16u enable, i;
 
1061
 
 
1062
    outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
 
1063
    enable = inw(VBE_DISPI_IOPORT_DATA);
 
1064
    write_word(ES, BX, enable);
 
1065
    BX += 2;
 
1066
    if (!(enable & VBE_DISPI_ENABLED)) 
 
1067
        return;
 
1068
    for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
 
1069
        if (i != VBE_DISPI_INDEX_ENABLE) {
 
1070
            outw(VBE_DISPI_IOPORT_INDEX, i);
 
1071
            write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA));
 
1072
            BX += 2;
 
1073
        }
 
1074
    }
 
1075
}
 
1076
 
 
1077
 
 
1078
void vbe_biosfn_restore_video_state(ES, BX)
 
1079
     Bit16u ES; Bit16u BX;
 
1080
{
 
1081
    Bit16u enable, i;
 
1082
 
 
1083
    enable = read_word(ES, BX);
 
1084
    BX += 2;
 
1085
    
 
1086
    if (!(enable & VBE_DISPI_ENABLED)) {
 
1087
        outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
 
1088
        outw(VBE_DISPI_IOPORT_DATA, enable);
 
1089
    } else {
 
1090
        outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
 
1091
        outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
 
1092
        BX += 2;
 
1093
        outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
 
1094
        outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
 
1095
        BX += 2;
 
1096
        outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
 
1097
        outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
 
1098
        BX += 2;
 
1099
        outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
 
1100
        outw(VBE_DISPI_IOPORT_DATA, enable);
 
1101
 
 
1102
        for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
 
1103
            outw(VBE_DISPI_IOPORT_INDEX, i);
 
1104
            outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
 
1105
            BX += 2;
 
1106
        }
 
1107
    }
 
1108
}
 
1109
 
 
1110
/** Function 04h - Save/Restore State
 
1111
 * 
 
1112
 * Input:
 
1113
 *              AX      = 4F04h
 
1114
 *              DL      = 00h Return Save/Restore State buffer size
 
1115
 *                        01h Save State
 
1116
 *                        02h Restore State
 
1117
 *              CX      = Requested states
 
1118
 *              ES:BX   = Pointer to buffer (if DL <> 00h)
 
1119
 * Output:
 
1120
 *              AX      = VBE Return Status
 
1121
 *              BX      = Number of 64-byte blocks to hold the state buffer (if DL=00h)
 
1122
 * 
 
1123
 */
 
1124
void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX)
 
1125
Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX;
 
1126
{
 
1127
    Bit16u ss=get_SS();
 
1128
    Bit16u result, val;
 
1129
 
 
1130
    result = 0x4f;
 
1131
    switch(GET_DL()) {
 
1132
    case 0x00:
 
1133
        val = biosfn_read_video_state_size2(CX);
 
1134
#ifdef DEBUG
 
1135
        printf("VGA state size=%x\n", val);
 
1136
#endif
 
1137
        if (CX & 8)
 
1138
            val += vbe_biosfn_read_video_state_size();
 
1139
        write_word(ss, BX, val);
 
1140
        break;
 
1141
    case 0x01:
 
1142
        val = read_word(ss, BX);
 
1143
        val = biosfn_save_video_state(CX, ES, val);
 
1144
#ifdef DEBUG
 
1145
        printf("VGA save_state offset=%x\n", val);
 
1146
#endif
 
1147
        if (CX & 8)
 
1148
            vbe_biosfn_save_video_state(ES, val);
 
1149
        break;
 
1150
    case 0x02:
 
1151
        val = read_word(ss, BX);
 
1152
        val = biosfn_restore_video_state(CX, ES, val);
 
1153
#ifdef DEBUG
 
1154
        printf("VGA restore_state offset=%x\n", val);
 
1155
#endif
 
1156
        if (CX & 8)
 
1157
            vbe_biosfn_restore_video_state(ES, val);
 
1158
        break;
 
1159
    default:
 
1160
        // function failed
 
1161
        result = 0x100;
 
1162
        break;
 
1163
    }
 
1164
    write_word(ss, AX, result);
 
1165
}
 
1166
 
 
1167
/** Function 05h - Display Window Control
 
1168
 * 
 
1169
 * Input:
 
1170
 *              AX      = 4F05h
 
1171
 *     (16-bit) BH      = 00h Set memory window
 
1172
 *                      = 01h Get memory window
 
1173
 *              BL      = Window number
 
1174
 *                      = 00h Window A
 
1175
 *                      = 01h Window B
 
1176
 *              DX      = Window number in video memory in window
 
1177
 *                        granularity units (Set Memory Window only)
 
1178
 * Note:
 
1179
 *              If this function is called while in a linear frame buffer mode,
 
1180
 *              this function must fail with completion code AH=03h
 
1181
 * 
 
1182
 * Output:
 
1183
 *              AX      = VBE Return Status
 
1184
 *              DX      = Window number in window granularity units
 
1185
 *                        (Get Memory Window only)
 
1186
 */
 
1187
ASM_START
 
1188
vbe_biosfn_display_window_control:
 
1189
  cmp  bl, #0x00
 
1190
  jne  vbe_05_failed
 
1191
  cmp  bh, #0x01
 
1192
  je   get_display_window
 
1193
  jb   set_display_window
 
1194
  mov  ax, #0x0100
 
1195
  ret
 
1196
set_display_window:
 
1197
  mov  ax, dx
 
1198
  call _dispi_set_bank
 
1199
  call dispi_get_bank
 
1200
  cmp  ax, dx
 
1201
  jne  vbe_05_failed
 
1202
  mov  ax, #0x004f
 
1203
  ret
 
1204
get_display_window:
 
1205
  call dispi_get_bank
 
1206
  mov  dx, ax
 
1207
  mov  ax, #0x004f
 
1208
  ret
 
1209
vbe_05_failed:
 
1210
  mov  ax, #0x014f
 
1211
  ret
 
1212
ASM_END
 
1213
 
 
1214
 
 
1215
/** Function 06h - Set/Get Logical Scan Line Length
 
1216
 *
 
1217
 * Input:
 
1218
 *              AX      = 4F06h
 
1219
 *              BL      = 00h Set Scan Line Length in Pixels
 
1220
 *                      = 01h Get Scan Line Length
 
1221
 *                      = 02h Set Scan Line Length in Bytes
 
1222
 *                      = 03h Get Maximum Scan Line Length
 
1223
 *              CX      = If BL=00h Desired Width in Pixels
 
1224
 *                        If BL=02h Desired Width in Bytes
 
1225
 *                        (Ignored for Get Functions)
 
1226
 * 
 
1227
 * Output: 
 
1228
 *              AX      = VBE Return Status
 
1229
 *              BX      = Bytes Per Scan Line
 
1230
 *              CX      = Actual Pixels Per Scan Line
 
1231
 *                        (truncated to nearest complete pixel)
 
1232
 *              DX      = Maximum Number of Scan Lines 
 
1233
 */
 
1234
ASM_START
 
1235
vbe_biosfn_set_get_logical_scan_line_length:
 
1236
  mov  ax, cx
 
1237
  cmp  bl, #0x01
 
1238
  je   get_logical_scan_line_length
 
1239
  cmp  bl, #0x02
 
1240
  je   set_logical_scan_line_bytes
 
1241
  jb   set_logical_scan_line_pixels
 
1242
  mov  ax, #0x0100
 
1243
  ret
 
1244
set_logical_scan_line_bytes:
 
1245
  push ax
 
1246
  call dispi_get_bpp
 
1247
  xor  bh, bh
 
1248
  mov  bl, ah
 
1249
  or   bl, bl
 
1250
  jnz  no_4bpp_1
 
1251
  shl  ax, #3
 
1252
  mov  bl, #1
 
1253
no_4bpp_1:
 
1254
  xor  dx, dx
 
1255
  pop  ax
 
1256
  div  bx
 
1257
set_logical_scan_line_pixels:
 
1258
  call dispi_set_virt_width
 
1259
get_logical_scan_line_length:
 
1260
  call dispi_get_bpp
 
1261
  xor  bh, bh
 
1262
  mov  bl, ah
 
1263
  call dispi_get_virt_width
 
1264
  mov  cx, ax
 
1265
  or   bl, bl
 
1266
  jnz  no_4bpp_2
 
1267
  shr  ax, #3
 
1268
  mov  bl, #1
 
1269
no_4bpp_2:
 
1270
  mul  bx
 
1271
  mov  bx, ax
 
1272
  call dispi_get_virt_height
 
1273
  mov  dx, ax
 
1274
  mov  ax, #0x004f
 
1275
  ret
 
1276
ASM_END
 
1277
 
 
1278
 
 
1279
/** Function 07h - Set/Get Display Start
 
1280
 * 
 
1281
 * Input(16-bit):
 
1282
 *              AX      = 4F07h
 
1283
 *              BH      = 00h Reserved and must be 00h
 
1284
 *              BL      = 00h Set Display Start
 
1285
 *                      = 01h Get Display Start
 
1286
 *                      = 02h Schedule Display Start (Alternate)
 
1287
 *                      = 03h Schedule Stereoscopic Display Start
 
1288
 *                      = 04h Get Scheduled Display Start Status
 
1289
 *                      = 05h Enable Stereoscopic Mode
 
1290
 *                      = 06h Disable Stereoscopic Mode
 
1291
 *                      = 80h Set Display Start during Vertical Retrace
 
1292
 *                      = 82h Set Display Start during Vertical Retrace (Alternate)
 
1293
 *                      = 83h Set Stereoscopic Display Start during Vertical Retrace
 
1294
 *              ECX     = If BL=02h/82h Display Start Address in bytes
 
1295
 *                        If BL=03h/83h Left Image Start Address in bytes
 
1296
 *              EDX     = If BL=03h/83h Right Image Start Address in bytes
 
1297
 *              CX      = If BL=00h/80h First Displayed Pixel In Scan Line
 
1298
 *              DX      = If BL=00h/80h First Displayed Scan Line
 
1299
 *
 
1300
 * Output:
 
1301
 *              AX      = VBE Return Status
 
1302
 *              BH      = If BL=01h Reserved and will be 0
 
1303
 *              CX      = If BL=01h First Displayed Pixel In Scan Line
 
1304
 *                        If BL=04h 0 if flip has not occurred, not 0 if it has
 
1305
 *              DX      = If BL=01h First Displayed Scan Line
 
1306
 *
 
1307
 * Input(32-bit): 
 
1308
 *              BH      = 00h Reserved and must be 00h
 
1309
 *              BL      = 00h Set Display Start
 
1310
 *                      = 80h Set Display Start during Vertical Retrace
 
1311
 *              CX      = Bits 0-15 of display start address
 
1312
 *              DX      = Bits 16-31 of display start address
 
1313
 *              ES      = Selector for memory mapped registers 
 
1314
 */
 
1315
ASM_START
 
1316
vbe_biosfn_set_get_display_start:
 
1317
  cmp  bl, #0x80
 
1318
  je   set_display_start
 
1319
  cmp  bl, #0x01
 
1320
  je   get_display_start
 
1321
  jb   set_display_start
 
1322
  mov  ax, #0x0100
 
1323
  ret
 
1324
set_display_start:
 
1325
  mov  ax, cx
 
1326
  call dispi_set_x_offset
 
1327
  mov  ax, dx
 
1328
  call dispi_set_y_offset
 
1329
  mov  ax, #0x004f
 
1330
  ret
 
1331
get_display_start:
 
1332
  call dispi_get_x_offset
 
1333
  mov  cx, ax
 
1334
  call dispi_get_y_offset
 
1335
  mov  dx, ax
 
1336
  xor  bh, bh
 
1337
  mov  ax, #0x004f
 
1338
  ret
 
1339
ASM_END
 
1340
  
 
1341
 
 
1342
/** Function 08h - Set/Get Dac Palette Format
 
1343
 * 
 
1344
 * Input:
 
1345
 *              AX      = 4F08h
 
1346
 *              BL      = 00h set DAC palette width
 
1347
 *                      = 01h get DAC palette width
 
1348
 *              BH      = If BL=00h: desired number of bits per primary color
 
1349
 * Output:
 
1350
 *              AX      = VBE Return Status
 
1351
 *              BH      = current number of bits per primary color (06h = standard VGA)
 
1352
 */
 
1353
ASM_START
 
1354
vbe_biosfn_set_get_dac_palette_format:
 
1355
  cmp  bl, #0x01
 
1356
  je   get_dac_palette_format
 
1357
  jb   set_dac_palette_format
 
1358
  mov  ax, #0x0100
 
1359
  ret
 
1360
set_dac_palette_format:
 
1361
  call dispi_get_enable
 
1362
  cmp  bh, #0x06
 
1363
  je   set_normal_dac
 
1364
  cmp  bh, #0x08
 
1365
  jne  vbe_08_unsupported
 
1366
  or   ax, # VBE_DISPI_8BIT_DAC
 
1367
  jnz  set_dac_mode
 
1368
set_normal_dac:
 
1369
  and  ax, #~ VBE_DISPI_8BIT_DAC
 
1370
set_dac_mode:
 
1371
  call _dispi_set_enable
 
1372
get_dac_palette_format:
 
1373
  mov  bh, #0x06
 
1374
  call dispi_get_enable
 
1375
  and  ax, # VBE_DISPI_8BIT_DAC
 
1376
  jz   vbe_08_ok
 
1377
  mov  bh, #0x08
 
1378
vbe_08_ok:
 
1379
  mov  ax, #0x004f
 
1380
  ret
 
1381
vbe_08_unsupported:
 
1382
  mov  ax, #0x014f
 
1383
  ret
 
1384
ASM_END
 
1385
 
 
1386
 
 
1387
/** Function 09h - Set/Get Palette Data
 
1388
 * 
 
1389
 * Input:
 
1390
 *              AX      = 4F09h
 
1391
 * Output:
 
1392
 *              AX      = VBE Return Status
 
1393
 *
 
1394
 * FIXME: incomplete API description, Input & Output
 
1395
 */
 
1396
void vbe_biosfn_set_get_palette_data(AX)
 
1397
{
 
1398
}
 
1399
 
 
1400
/** Function 0Ah - Return VBE Protected Mode Interface
 
1401
 * Input:    AX   = 4F0Ah   VBE 2.0 Protected Mode Interface
 
1402
 *           BL   = 00h          Return protected mode table
 
1403
 *
 
1404
 *
 
1405
 * Output:   AX   =         Status
 
1406
 *           ES   =         Real Mode Segment of Table
 
1407
 *           DI   =         Offset of Table
 
1408
 *           CX   =         Length of Table including protected mode code
 
1409
 *                          (for copying purposes)
 
1410
 */
 
1411
ASM_START
 
1412
vbe_biosfn_return_protected_mode_interface:
 
1413
  test bl, bl
 
1414
  jnz _fail
 
1415
  mov di, #0xc000
 
1416
  mov es, di
 
1417
  mov di, # vesa_pm_start
 
1418
  mov cx, # vesa_pm_end
 
1419
  sub cx, di
 
1420
  mov ax, #0x004f
 
1421
  ret
 
1422
_fail:
 
1423
  mov ax, #0x014f
 
1424
  ret
 
1425
ASM_END