~ubuntu-branches/debian/wheezy/vgabios/wheezy

« back to all changes in this revision

Viewing changes to .pc/02-Add-defines-for-PCI-IDs/vgabios.c

  • Committer: Package Import Robot
  • Author(s): Guillem Jover
  • Date: 2011-11-01 00:57:42 UTC
  • mfrom: (1.2.5)
  • Revision ID: package-import@ubuntu.com-20111101005742-0upqeej55wzvdrpq
Tags: 0.7a-1
* New upstream release.
  - debian/patches/01-Makefile-cleanup: Remove, merged upstream.
  - debian/patches/02-Add-defines-for-PCI-IDs: Likewise.
  - debian/patches/03-Add-qemu-stdvga-pci-bios: Likewise.
  - debian/patches/04-update-pci_get_lfb_addr-for-vmware-vga: Likewise.
  - debian/patches/05-Add-qemu-vmware-vga-pci-bios: Refreshed.
  - debian/patches/06-Add-qemu-qxl-vga-pci-bios: Likewise.
* Add compatibility symlinks from stdvga vgabios to the default vgabios
  ROM, as the latter is now exactly the same as the former.
* Now using Standards-Version 3.9.2 (no changes needed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ============================================================================================
2
 
/*
3
 
 * vgabios.c
4
 
 */
5
 
// ============================================================================================
6
 
//  
7
 
//  Copyright (C) 2001-2008 the LGPL VGABios developers Team
8
 
//
9
 
//  This library is free software; you can redistribute it and/or
10
 
//  modify it under the terms of the GNU Lesser General Public
11
 
//  License as published by the Free Software Foundation; either
12
 
//  version 2 of the License, or (at your option) any later version.
13
 
//
14
 
//  This library is distributed in the hope that it will be useful,
15
 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 
//  Lesser General Public License for more details.
18
 
//
19
 
//  You should have received a copy of the GNU Lesser General Public
20
 
//  License along with this library; if not, write to the Free Software
21
 
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22
 
// 
23
 
// ============================================================================================
24
 
//  
25
 
//  This VGA Bios is specific to the plex86/bochs Emulated VGA card. 
26
 
//  You can NOT drive any physical vga card with it. 
27
 
//     
28
 
// ============================================================================================
29
 
//  
30
 
//  This file contains code ripped from :
31
 
//   - rombios.c of plex86 
32
 
//
33
 
//  This VGA Bios contains fonts from :
34
 
//   - fntcol16.zip (c) by Joseph Gil avalable at :
35
 
//      ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
36
 
//     These fonts are public domain 
37
 
//
38
 
//  This VGA Bios is based on information taken from :
39
 
//   - Kevin Lawton's vga card emulation for bochs/plex86
40
 
//   - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html
41
 
//   - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/
42
 
//   - Michael Abrash's Graphics Programming Black Book
43
 
//   - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex
44
 
//   - DOSEMU 1.0.1 source code for several tables values and formulas
45
 
//
46
 
// Thanks for patches, comments and ideas to :
47
 
//   - techt@pikeonline.net
48
 
//
49
 
// ============================================================================================
50
 
 
51
 
#include "vgabios.h"
52
 
 
53
 
#ifdef VBE
54
 
#include "vbe.h"
55
 
#endif
56
 
 
57
 
#define USE_BX_INFO
58
 
 
59
 
/* Declares */
60
 
static Bit8u          read_byte();
61
 
static Bit16u         read_word();
62
 
static void           write_byte();
63
 
static void           write_word();
64
 
static Bit8u          inb();
65
 
static Bit16u         inw();
66
 
static void           outb();
67
 
static void           outw();
68
 
 
69
 
static Bit16u         get_SS();
70
 
 
71
 
// Output
72
 
static void           printf();
73
 
static void           unimplemented();
74
 
static void           unknown();
75
 
 
76
 
static Bit8u find_vga_entry();
77
 
 
78
 
static void memsetb();
79
 
static void memsetw();
80
 
static void memcpyb();
81
 
static void memcpyw();
82
 
 
83
 
static void biosfn_set_video_mode();
84
 
static void biosfn_set_cursor_shape();
85
 
static void biosfn_set_cursor_pos();
86
 
static void biosfn_get_cursor_pos();
87
 
static void biosfn_set_active_page();
88
 
static void biosfn_scroll();
89
 
static void biosfn_read_char_attr();
90
 
static void biosfn_write_char_attr();
91
 
static void biosfn_write_char_only();
92
 
static void biosfn_write_pixel();
93
 
static void biosfn_read_pixel();
94
 
static void biosfn_write_teletype();
95
 
static void biosfn_perform_gray_scale_summing();
96
 
static void biosfn_load_text_user_pat();
97
 
static void biosfn_load_text_8_14_pat();
98
 
static void biosfn_load_text_8_8_pat();
99
 
static void biosfn_load_text_8_16_pat();
100
 
static void biosfn_load_gfx_8_8_chars();
101
 
static void biosfn_load_gfx_user_chars();
102
 
static void biosfn_load_gfx_8_14_chars();
103
 
static void biosfn_load_gfx_8_8_dd_chars();
104
 
static void biosfn_load_gfx_8_16_chars();
105
 
static void biosfn_get_font_info();
106
 
static void biosfn_alternate_prtsc();
107
 
static void biosfn_switch_video_interface();
108
 
static void biosfn_enable_video_refresh_control();
109
 
static void biosfn_write_string();
110
 
static void biosfn_read_state_info();
111
 
static void biosfn_read_video_state_size();
112
 
static Bit16u biosfn_save_video_state();
113
 
static Bit16u biosfn_restore_video_state();
114
 
extern Bit8u video_save_pointer_table[];
115
 
 
116
 
// This is for compiling with gcc2 and gcc3
117
 
#define ASM_START #asm
118
 
#define ASM_END   #endasm
119
 
 
120
 
ASM_START
121
 
 
122
 
MACRO SET_INT_VECTOR
123
 
  push ds
124
 
  xor ax, ax
125
 
  mov ds, ax
126
 
  mov ax, ?3
127
 
  mov ?1*4, ax
128
 
  mov ax, ?2
129
 
  mov ?1*4+2, ax
130
 
  pop ds
131
 
MEND
132
 
 
133
 
ASM_END
134
 
 
135
 
ASM_START
136
 
.text
137
 
.rom
138
 
.org 0
139
 
 
140
 
use16 386
141
 
 
142
 
vgabios_start:
143
 
.byte   0x55, 0xaa      /* BIOS signature, required for BIOS extensions */
144
 
 
145
 
.byte   0x40            /* BIOS extension length in units of 512 bytes */
146
 
 
147
 
 
148
 
vgabios_entry_point:
149
 
           
150
 
  jmp vgabios_init_func
151
 
 
152
 
#ifdef PCIBIOS
153
 
.org 0x18
154
 
.word vgabios_pci_data
155
 
#endif
156
 
 
157
 
// Info from Bart Oldeman
158
 
.org 0x1e
159
 
.ascii  "IBM"
160
 
.byte   0x00
161
 
 
162
 
vgabios_name:
163
 
.ascii  "Plex86/Bochs VGABios"
164
 
#ifdef PCIBIOS
165
 
.ascii  " (PCI)"
166
 
#endif
167
 
.ascii  " "
168
 
.byte   0x00
169
 
 
170
 
vgabios_version:
171
 
#ifndef VGABIOS_VERS
172
 
.ascii  "current-cvs"
173
 
#else
174
 
.ascii VGABIOS_VERS
175
 
#endif
176
 
.ascii  " "
177
 
 
178
 
vgabios_date:
179
 
.ascii  VGABIOS_DATE
180
 
.byte   0x0a,0x0d
181
 
.byte   0x00
182
 
 
183
 
vgabios_copyright:
184
 
.ascii  "(C) 2008 the LGPL VGABios developers Team"
185
 
.byte   0x0a,0x0d
186
 
.byte   0x00
187
 
 
188
 
vgabios_license:
189
 
.ascii  "This VGA/VBE Bios is released under the GNU LGPL"
190
 
.byte   0x0a,0x0d
191
 
.byte   0x0a,0x0d
192
 
.byte   0x00
193
 
 
194
 
vgabios_website:
195
 
.ascii  "Please visit :"
196
 
.byte   0x0a,0x0d
197
 
;;.ascii  " . http://www.plex86.org"
198
 
;;.byte 0x0a,0x0d
199
 
.ascii  " . http://bochs.sourceforge.net"
200
 
.byte   0x0a,0x0d
201
 
.ascii  " . http://www.nongnu.org/vgabios"
202
 
.byte   0x0a,0x0d
203
 
.byte   0x0a,0x0d
204
 
.byte   0x00
205
 
 
206
 
#ifdef PCIBIOS
207
 
vgabios_pci_data:
208
 
.ascii "PCIR"
209
 
#ifdef CIRRUS
210
 
.word 0x1013
211
 
.word 0x00b8 // CLGD5446
212
 
#else
213
 
#error "Unknown PCI vendor and device id"
214
 
#endif
215
 
.word 0 // reserved
216
 
.word 0x18 // dlen
217
 
.byte 0 // revision
218
 
.byte 0x0 // class,hi: vga display
219
 
.word 0x300 // class,lo: vga display
220
 
.word 0x40 // bios size
221
 
.word 1 // revision
222
 
.byte 0 // intel x86 data
223
 
.byte 0x80 // last image
224
 
.word 0 // reserved
225
 
#endif
226
 
 
227
 
 
228
 
;; ============================================================================================
229
 
;;
230
 
;; Init Entry point
231
 
;;
232
 
;; ============================================================================================
233
 
vgabios_init_func:
234
 
 
235
 
;; init vga card
236
 
  call init_vga_card
237
 
 
238
 
;; init basic bios vars
239
 
  call init_bios_area
240
 
 
241
 
#ifdef VBE  
242
 
;; init vbe functions
243
 
  call vbe_init  
244
 
#endif
245
 
 
246
 
;; set int10 vect
247
 
  SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
248
 
 
249
 
#ifdef CIRRUS
250
 
  call cirrus_init
251
 
#endif
252
 
 
253
 
;; display splash screen
254
 
  call _display_splash_screen
255
 
 
256
 
;; init video mode and clear the screen
257
 
  mov ax,#0x0003
258
 
  int #0x10
259
 
 
260
 
;; show info
261
 
  call _display_info
262
 
 
263
 
#ifdef VBE  
264
 
;; show vbe info
265
 
  call vbe_display_info  
266
 
#endif
267
 
 
268
 
#ifdef CIRRUS
269
 
;; show cirrus info
270
 
  call cirrus_display_info
271
 
#endif
272
 
 
273
 
  retf
274
 
ASM_END
275
 
 
276
 
/*
277
 
 *  int10 handled here
278
 
 */
279
 
ASM_START
280
 
vgabios_int10_handler:
281
 
  pushf
282
 
#ifdef DEBUG
283
 
  push es
284
 
  push ds
285
 
  pusha
286
 
  mov   bx, #0xc000
287
 
  mov   ds, bx
288
 
  call _int10_debugmsg
289
 
  popa
290
 
  pop ds
291
 
  pop es
292
 
#endif
293
 
  cmp   ah, #0x0f
294
 
  jne   int10_test_1A
295
 
  call  biosfn_get_video_mode
296
 
  jmp   int10_end
297
 
int10_test_1A:
298
 
  cmp   ah, #0x1a
299
 
  jne   int10_test_0B
300
 
  call  biosfn_group_1A
301
 
  jmp   int10_end
302
 
int10_test_0B:
303
 
  cmp   ah, #0x0b
304
 
  jne   int10_test_1103
305
 
  call  biosfn_group_0B
306
 
  jmp   int10_end
307
 
int10_test_1103:
308
 
  cmp   ax, #0x1103
309
 
  jne   int10_test_12
310
 
  call  biosfn_set_text_block_specifier
311
 
  jmp   int10_end
312
 
int10_test_12:
313
 
  cmp   ah, #0x12
314
 
  jne   int10_test_101B
315
 
  cmp   bl, #0x10
316
 
  jne   int10_test_BL30
317
 
  call  biosfn_get_ega_info
318
 
  jmp   int10_end
319
 
int10_test_BL30:
320
 
  cmp   bl, #0x30
321
 
  jne   int10_test_BL31
322
 
  call  biosfn_select_vert_res
323
 
  jmp   int10_end
324
 
int10_test_BL31:
325
 
  cmp   bl, #0x31
326
 
  jne   int10_test_BL32
327
 
  call  biosfn_enable_default_palette_loading
328
 
  jmp   int10_end
329
 
int10_test_BL32:
330
 
  cmp   bl, #0x32
331
 
  jne   int10_test_BL33
332
 
  call  biosfn_enable_video_addressing
333
 
  jmp   int10_end
334
 
int10_test_BL33:
335
 
  cmp   bl, #0x33
336
 
  jne   int10_test_BL34
337
 
  call  biosfn_enable_grayscale_summing
338
 
  jmp   int10_end
339
 
int10_test_BL34:
340
 
  cmp   bl, #0x34
341
 
  jne   int10_normal
342
 
  call  biosfn_enable_cursor_emulation
343
 
  jmp   int10_end
344
 
int10_test_101B:
345
 
  cmp   ax, #0x101b
346
 
  je    int10_normal
347
 
  cmp   ah, #0x10
348
 
#ifndef VBE
349
 
  jne   int10_normal
350
 
#else
351
 
  jne   int10_test_4F
352
 
#endif
353
 
  call  biosfn_group_10
354
 
  jmp   int10_end
355
 
#ifdef VBE
356
 
int10_test_4F:
357
 
  cmp   ah, #0x4f
358
 
  jne   int10_normal
359
 
  cmp   al, #0x03
360
 
  jne   int10_test_vbe_05
361
 
  call  vbe_biosfn_return_current_mode
362
 
  jmp   int10_end
363
 
int10_test_vbe_05:
364
 
  cmp   al, #0x05
365
 
  jne   int10_test_vbe_06
366
 
  call  vbe_biosfn_display_window_control
367
 
  jmp   int10_end
368
 
int10_test_vbe_06:
369
 
  cmp   al, #0x06
370
 
  jne   int10_test_vbe_07
371
 
  call  vbe_biosfn_set_get_logical_scan_line_length
372
 
  jmp   int10_end
373
 
int10_test_vbe_07:
374
 
  cmp   al, #0x07
375
 
  jne   int10_test_vbe_08
376
 
  call  vbe_biosfn_set_get_display_start
377
 
  jmp   int10_end
378
 
int10_test_vbe_08:
379
 
  cmp   al, #0x08
380
 
  jne   int10_test_vbe_0A
381
 
  call  vbe_biosfn_set_get_dac_palette_format
382
 
  jmp   int10_end
383
 
int10_test_vbe_0A:
384
 
  cmp   al, #0x0A
385
 
  jne   int10_normal
386
 
  call  vbe_biosfn_return_protected_mode_interface
387
 
  jmp   int10_end
388
 
#endif
389
 
 
390
 
int10_normal:
391
 
  push es
392
 
  push ds
393
 
  pusha
394
 
 
395
 
;; We have to set ds to access the right data segment
396
 
  mov   bx, #0xc000
397
 
  mov   ds, bx
398
 
  call _int10_func
399
 
 
400
 
  popa
401
 
  pop ds
402
 
  pop es
403
 
int10_end:
404
 
  popf
405
 
  iret
406
 
ASM_END
407
 
 
408
 
#include "vgatables.h"
409
 
#include "vgafonts.h"
410
 
 
411
 
/*
412
 
 * Boot time harware inits 
413
 
 */
414
 
ASM_START
415
 
init_vga_card:
416
 
;; switch to color mode and enable CPU access 480 lines
417
 
  mov dx, #0x3C2
418
 
  mov al, #0xC3
419
 
  outb dx,al
420
 
 
421
 
;; more than 64k 3C4/04
422
 
  mov dx, #0x3C4
423
 
  mov al, #0x04
424
 
  outb dx,al
425
 
  mov dx, #0x3C5
426
 
  mov al, #0x02
427
 
  outb dx,al
428
 
 
429
 
#if defined(USE_BX_INFO) || defined(DEBUG)
430
 
  mov  bx, #msg_vga_init
431
 
  push bx
432
 
  call _printf
433
 
#endif
434
 
  inc  sp
435
 
  inc  sp
436
 
  ret
437
 
 
438
 
#if defined(USE_BX_INFO) || defined(DEBUG)
439
 
msg_vga_init:
440
 
.ascii "VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $"
441
 
.byte 0x0d,0x0a,0x00
442
 
#endif
443
 
ASM_END
444
 
 
445
 
// --------------------------------------------------------------------------------------------
446
 
/*
447
 
 *  Boot time bios area inits 
448
 
 */
449
 
ASM_START
450
 
init_bios_area:
451
 
  push  ds
452
 
  mov   ax, # BIOSMEM_SEG
453
 
  mov   ds, ax
454
 
 
455
 
;; init detected hardware BIOS Area
456
 
  mov   bx, # BIOSMEM_INITIAL_MODE
457
 
  mov   ax, [bx]
458
 
  and   ax, #0xffcf
459
 
;; set 80x25 color (not clear from RBIL but usual)
460
 
  or    ax, #0x0020
461
 
  mov   [bx], ax
462
 
 
463
 
;; Just for the first int10 find its children
464
 
 
465
 
;; the default char height
466
 
  mov   bx, # BIOSMEM_CHAR_HEIGHT
467
 
  mov   al, #0x10
468
 
  mov   [bx], al
469
 
 
470
 
;; Clear the screen 
471
 
  mov   bx, # BIOSMEM_VIDEO_CTL
472
 
  mov   al, #0x60
473
 
  mov   [bx], al
474
 
 
475
 
;; Set the basic screen we have
476
 
  mov   bx, # BIOSMEM_SWITCHES
477
 
  mov   al, #0xf9
478
 
  mov   [bx], al
479
 
 
480
 
;; Set the basic modeset options
481
 
  mov   bx, # BIOSMEM_MODESET_CTL
482
 
  mov   al, #0x51
483
 
  mov   [bx], al
484
 
 
485
 
;; Set the  default MSR
486
 
  mov   bx, # BIOSMEM_CURRENT_MSR
487
 
  mov   al, #0x09
488
 
  mov   [bx], al
489
 
 
490
 
  pop ds
491
 
  ret
492
 
 
493
 
_video_save_pointer_table:
494
 
  .word _video_param_table
495
 
  .word 0xc000
496
 
 
497
 
  .word 0 /* XXX: fill it */
498
 
  .word 0
499
 
 
500
 
  .word 0 /* XXX: fill it */
501
 
  .word 0
502
 
 
503
 
  .word 0 /* XXX: fill it */
504
 
  .word 0
505
 
 
506
 
  .word 0 /* XXX: fill it */
507
 
  .word 0
508
 
 
509
 
  .word 0 /* XXX: fill it */
510
 
  .word 0
511
 
 
512
 
  .word 0 /* XXX: fill it */
513
 
  .word 0
514
 
 
515
 
ASM_END
516
 
 
517
 
// --------------------------------------------------------------------------------------------
518
 
/*
519
 
 *  Boot time Splash screen
520
 
 */
521
 
static void display_splash_screen()
522
 
{
523
 
}
524
 
 
525
 
// --------------------------------------------------------------------------------------------
526
 
/*
527
 
 *  Tell who we are
528
 
 */
529
 
 
530
 
static void display_info()
531
 
{
532
 
ASM_START
533
 
 mov ax,#0xc000
534
 
 mov ds,ax
535
 
 mov si,#vgabios_name
536
 
 call _display_string
537
 
 mov si,#vgabios_version
538
 
 call _display_string
539
 
 
540
 
 ;;mov si,#vgabios_copyright
541
 
 ;;call _display_string
542
 
 ;;mov si,#crlf
543
 
 ;;call _display_string
544
 
 
545
 
 mov si,#vgabios_license
546
 
 call _display_string
547
 
 mov si,#vgabios_website
548
 
 call _display_string
549
 
ASM_END
550
 
}
551
 
 
552
 
static void display_string()
553
 
{
554
 
 // Get length of string
555
 
ASM_START
556
 
 mov ax,ds
557
 
 mov es,ax
558
 
 mov di,si
559
 
 xor cx,cx
560
 
 not cx
561
 
 xor al,al
562
 
 cld
563
 
 repne 
564
 
  scasb
565
 
 not cx
566
 
 dec cx
567
 
 push cx
568
 
 
569
 
 mov ax,#0x0300
570
 
 mov bx,#0x0000
571
 
 int #0x10
572
 
 
573
 
 pop cx
574
 
 mov ax,#0x1301
575
 
 mov bx,#0x000b
576
 
 mov bp,si
577
 
 int #0x10
578
 
ASM_END
579
 
}
580
 
 
581
 
// --------------------------------------------------------------------------------------------
582
 
#ifdef DEBUG
583
 
static void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
584
 
  Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
585
 
{
586
 
 // 0E is write char...
587
 
 if(GET_AH()!=0x0E)
588
 
  printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);
589
 
}
590
 
#endif
591
 
 
592
 
// --------------------------------------------------------------------------------------------
593
 
/*
594
 
 * int10 main dispatcher
595
 
 */
596
 
static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
597
 
  Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
598
 
{
599
 
 
600
 
 // BIOS functions
601
 
 switch(GET_AH())
602
 
  {
603
 
   case 0x00:
604
 
     biosfn_set_video_mode(GET_AL());
605
 
     switch(GET_AL()&0x7F)
606
 
      {case 6: 
607
 
        SET_AL(0x3F);
608
 
        break;
609
 
       case 0:
610
 
       case 1:
611
 
       case 2:
612
 
       case 3:
613
 
       case 4:
614
 
       case 5:
615
 
       case 7:
616
 
        SET_AL(0x30);
617
 
        break;
618
 
      default:
619
 
        SET_AL(0x20);
620
 
      }
621
 
     break;
622
 
   case 0x01:
623
 
     biosfn_set_cursor_shape(GET_CH(),GET_CL());
624
 
     break;
625
 
   case 0x02:
626
 
     biosfn_set_cursor_pos(GET_BH(),DX);
627
 
     break;
628
 
   case 0x03:
629
 
     biosfn_get_cursor_pos(GET_BH(),&CX,&DX);
630
 
     break;
631
 
   case 0x04:
632
 
     // Read light pen pos (unimplemented)
633
 
#ifdef DEBUG
634
 
     unimplemented();
635
 
#endif
636
 
     AX=0x00;
637
 
     BX=0x00;
638
 
     CX=0x00;
639
 
     DX=0x00;
640
 
     break;
641
 
   case 0x05:
642
 
     biosfn_set_active_page(GET_AL());
643
 
     break;
644
 
   case 0x06:
645
 
     biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP);
646
 
     break;
647
 
   case 0x07:
648
 
     biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN);
649
 
     break;
650
 
   case 0x08:
651
 
     biosfn_read_char_attr(GET_BH(),&AX);
652
 
     break;
653
 
   case 0x09:
654
 
     biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX);
655
 
     break;
656
 
   case 0x0A:
657
 
     biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX);
658
 
     break;
659
 
   case 0x0C:
660
 
     biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX);
661
 
     break;
662
 
   case 0x0D:
663
 
     biosfn_read_pixel(GET_BH(),CX,DX,&AX);
664
 
     break;
665
 
   case 0x0E:
666
 
     // Ralf Brown Interrupt list is WRONG on bh(page)
667
 
     // We do output only on the current page !
668
 
     biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);
669
 
     break;
670
 
   case 0x10:
671
 
     // All other functions of group AH=0x10 rewritten in assembler
672
 
     biosfn_perform_gray_scale_summing(BX,CX);
673
 
     break;
674
 
   case 0x11:
675
 
     switch(GET_AL())
676
 
      {
677
 
       case 0x00:
678
 
       case 0x10:
679
 
        biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH());
680
 
        break;
681
 
       case 0x01:
682
 
       case 0x11:
683
 
        biosfn_load_text_8_14_pat(GET_AL(),GET_BL());
684
 
        break;
685
 
       case 0x02:
686
 
       case 0x12:
687
 
        biosfn_load_text_8_8_pat(GET_AL(),GET_BL());
688
 
        break;
689
 
       case 0x04:
690
 
       case 0x14:
691
 
        biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
692
 
        break;
693
 
       case 0x20:
694
 
        biosfn_load_gfx_8_8_chars(ES,BP);
695
 
        break;
696
 
       case 0x21:
697
 
        biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL());
698
 
        break;
699
 
       case 0x22:
700
 
        biosfn_load_gfx_8_14_chars(GET_BL());
701
 
        break;
702
 
       case 0x23:
703
 
        biosfn_load_gfx_8_8_dd_chars(GET_BL());
704
 
        break;
705
 
       case 0x24:
706
 
        biosfn_load_gfx_8_16_chars(GET_BL());
707
 
        break;
708
 
       case 0x30:
709
 
        biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX);
710
 
        break;
711
 
#ifdef DEBUG
712
 
       default:
713
 
        unknown();
714
 
#endif
715
 
      }
716
 
     
717
 
     break;
718
 
   case 0x12:
719
 
     switch(GET_BL())
720
 
      {
721
 
       case 0x20:
722
 
        biosfn_alternate_prtsc();
723
 
        break;
724
 
       case 0x35:
725
 
        biosfn_switch_video_interface(GET_AL(),ES,DX);
726
 
        SET_AL(0x12);
727
 
        break;
728
 
       case 0x36:
729
 
        biosfn_enable_video_refresh_control(GET_AL());
730
 
        SET_AL(0x12);
731
 
        break;
732
 
#ifdef DEBUG
733
 
       default:
734
 
        unknown();
735
 
#endif
736
 
      }
737
 
     break;
738
 
   case 0x13:
739
 
     biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
740
 
     break;
741
 
   case 0x1B:
742
 
     biosfn_read_state_info(BX,ES,DI);
743
 
     SET_AL(0x1B);
744
 
     break;
745
 
   case 0x1C:
746
 
     switch(GET_AL())
747
 
      {
748
 
       case 0x00:
749
 
        biosfn_read_video_state_size(CX,&BX);
750
 
        break;
751
 
       case 0x01:
752
 
        biosfn_save_video_state(CX,ES,BX);
753
 
        break;
754
 
       case 0x02:
755
 
        biosfn_restore_video_state(CX,ES,BX);
756
 
        break;
757
 
#ifdef DEBUG
758
 
       default:
759
 
        unknown();
760
 
#endif
761
 
      }
762
 
     SET_AL(0x1C);
763
 
     break;
764
 
 
765
 
#ifdef VBE 
766
 
   case 0x4f:
767
 
     if (vbe_has_vbe_display()) {
768
 
       switch(GET_AL())
769
 
       {
770
 
         case 0x00:
771
 
          vbe_biosfn_return_controller_information(&AX,ES,DI);
772
 
          break;
773
 
         case 0x01:
774
 
          vbe_biosfn_return_mode_information(&AX,CX,ES,DI);
775
 
          break;
776
 
         case 0x02:
777
 
          vbe_biosfn_set_mode(&AX,BX,ES,DI);
778
 
          break;
779
 
         case 0x04:
780
 
          vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
781
 
          break;
782
 
         case 0x09:
783
 
          //FIXME
784
 
#ifdef DEBUG
785
 
          unimplemented();
786
 
#endif
787
 
          // function failed
788
 
          AX=0x100;
789
 
          break;
790
 
         case 0x0A:
791
 
          //FIXME
792
 
#ifdef DEBUG
793
 
          unimplemented();
794
 
#endif
795
 
          // function failed
796
 
          AX=0x100;
797
 
          break;
798
 
         default:
799
 
#ifdef DEBUG
800
 
          unknown();
801
 
#endif                   
802
 
          // function failed
803
 
          AX=0x100;
804
 
          }
805
 
        }
806
 
        else {
807
 
          // No VBE display
808
 
          AX=0x0100;
809
 
          }
810
 
        break;
811
 
#endif
812
 
 
813
 
#ifdef DEBUG
814
 
   default:
815
 
     unknown();
816
 
#endif
817
 
  }
818
 
}
819
 
 
820
 
// ============================================================================================
821
 
// 
822
 
// BIOS functions
823
 
// 
824
 
// ============================================================================================
825
 
 
826
 
static void biosfn_set_video_mode(mode) Bit8u mode; 
827
 
{// mode: Bit 7 is 1 if no clear screen
828
 
 
829
 
 // Should we clear the screen ?
830
 
 Bit8u noclearmem=mode&0x80;
831
 
 Bit8u line,mmask,*palette,vpti;
832
 
 Bit16u i,twidth,theightm1,cheight;
833
 
 Bit8u modeset_ctl,video_ctl,vga_switches;
834
 
 Bit16u crtc_addr;
835
 
 
836
 
#ifdef VBE
837
 
 if (vbe_has_vbe_display()) { 
838
 
   dispi_set_enable(VBE_DISPI_DISABLED);
839
 
  }
840
 
#endif // def VBE
841
 
 
842
 
 // The real mode
843
 
 mode=mode&0x7f;
844
 
 
845
 
 // find the entry in the video modes
846
 
 line=find_vga_entry(mode);
847
 
 
848
 
#ifdef DEBUG
849
 
 printf("mode search %02x found line %02x\n",mode,line);
850
 
#endif
851
 
 
852
 
 if(line==0xFF)
853
 
  return;
854
 
 
855
 
 vpti=line_to_vpti[line];
856
 
 twidth=video_param_table[vpti].twidth;
857
 
 theightm1=video_param_table[vpti].theightm1;
858
 
 cheight=video_param_table[vpti].cheight;
859
 
 
860
 
 // Read the bios vga control
861
 
 video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
862
 
 
863
 
 // Read the bios vga switches
864
 
 vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES);
865
 
 
866
 
 // Read the bios mode set control
867
 
 modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
868
 
 
869
 
 // Then we know the number of lines
870
 
// FIXME
871
 
 
872
 
 // if palette loading (bit 3 of modeset ctl = 0)
873
 
 if((modeset_ctl&0x08)==0)
874
 
  {// Set the PEL mask
875
 
   outb(VGAREG_PEL_MASK,vga_modes[line].pelmask);
876
 
 
877
 
   // Set the whole dac always, from 0
878
 
   outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
879
 
 
880
 
   // From which palette
881
 
   switch(vga_modes[line].dacmodel)
882
 
    {case 0:
883
 
      palette=&palette0;
884
 
      break;
885
 
     case 1:
886
 
      palette=&palette1;
887
 
      break;
888
 
     case 2:
889
 
      palette=&palette2;
890
 
      break;
891
 
     case 3:
892
 
      palette=&palette3;
893
 
      break;
894
 
    }
895
 
   // Always 256*3 values
896
 
   for(i=0;i<0x0100;i++)
897
 
    {if(i<=dac_regs[vga_modes[line].dacmodel])
898
 
      {outb(VGAREG_DAC_DATA,palette[(i*3)+0]);
899
 
       outb(VGAREG_DAC_DATA,palette[(i*3)+1]);
900
 
       outb(VGAREG_DAC_DATA,palette[(i*3)+2]);
901
 
      }
902
 
     else
903
 
      {outb(VGAREG_DAC_DATA,0);
904
 
       outb(VGAREG_DAC_DATA,0);
905
 
       outb(VGAREG_DAC_DATA,0);
906
 
      }
907
 
    }
908
 
   if((modeset_ctl&0x02)==0x02)
909
 
    {
910
 
     biosfn_perform_gray_scale_summing(0x00, 0x100);
911
 
    }
912
 
  }
913
 
 
914
 
 // Reset Attribute Ctl flip-flop
915
 
 inb(VGAREG_ACTL_RESET);
916
 
 
917
 
 // Set Attribute Ctl
918
 
 for(i=0;i<=0x13;i++)
919
 
  {outb(VGAREG_ACTL_ADDRESS,i);
920
 
   outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);
921
 
  }
922
 
 outb(VGAREG_ACTL_ADDRESS,0x14);
923
 
 outb(VGAREG_ACTL_WRITE_DATA,0x00);
924
 
 
925
 
 // Set Sequencer Ctl
926
 
 outb(VGAREG_SEQU_ADDRESS,0);
927
 
 outb(VGAREG_SEQU_DATA,0x03);
928
 
 for(i=1;i<=4;i++)
929
 
  {outb(VGAREG_SEQU_ADDRESS,i);
930
 
   outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);
931
 
  }
932
 
 
933
 
 // Set Grafx Ctl
934
 
 for(i=0;i<=8;i++)
935
 
  {outb(VGAREG_GRDC_ADDRESS,i);
936
 
   outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);
937
 
  }
938
 
 
939
 
 // Set CRTC address VGA or MDA 
940
 
 crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
941
 
 
942
 
 // Disable CRTC write protection
943
 
 outw(crtc_addr,0x0011);
944
 
 // Set CRTC regs
945
 
 for(i=0;i<=0x18;i++)
946
 
  {outb(crtc_addr,i);
947
 
   outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);
948
 
  }
949
 
 
950
 
 // Set the misc register
951
 
 outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg);
952
 
 
953
 
 // Enable video
954
 
 outb(VGAREG_ACTL_ADDRESS,0x20);
955
 
 inb(VGAREG_ACTL_RESET);
956
 
 
957
 
 if(noclearmem==0x00)
958
 
  {
959
 
   if(vga_modes[line].class==TEXT)
960
 
    {
961
 
     memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k
962
 
    }
963
 
   else
964
 
    {
965
 
     if(mode<0x0d)
966
 
      {
967
 
       memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k
968
 
      }
969
 
     else
970
 
      {
971
 
       outb( VGAREG_SEQU_ADDRESS, 0x02 );
972
 
       mmask = inb( VGAREG_SEQU_DATA );
973
 
       outb( VGAREG_SEQU_DATA, 0x0f ); // all planes
974
 
       memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k
975
 
       outb( VGAREG_SEQU_DATA, mmask );
976
 
      }
977
 
    }
978
 
  }
979
 
 
980
 
 // Set the BIOS mem
981
 
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
982
 
 write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth);
983
 
 write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l);
984
 
 write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
985
 
 write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
986
 
 write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
987
 
 write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
988
 
 write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
989
 
 write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
990
 
 
991
 
 // FIXME We nearly have the good tables. to be reworked
992
 
 write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08);    // 8 is VGA should be ok for now
993
 
 write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table);
994
 
 write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000);
995
 
 
996
 
 // FIXME
997
 
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but...
998
 
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...
999
 
 
1000
 
 // Set cursor shape
1001
 
 if(vga_modes[line].class==TEXT)
1002
 
  {
1003
 
   biosfn_set_cursor_shape(0x06,0x07);
1004
 
  }
1005
 
 
1006
 
 // Set cursor pos for page 0..7
1007
 
 for(i=0;i<8;i++)
1008
 
  biosfn_set_cursor_pos(i,0x0000);
1009
 
 
1010
 
 // Set active page 0
1011
 
 biosfn_set_active_page(0x00);
1012
 
 
1013
 
 // Write the fonts in memory
1014
 
 if(vga_modes[line].class==TEXT)
1015
 
  { 
1016
 
ASM_START
1017
 
  ;; copy and activate 8x16 font
1018
 
  mov ax, #0x1104
1019
 
  mov bl, #0x00
1020
 
  int #0x10
1021
 
  mov ax, #0x1103
1022
 
  mov bl, #0x00
1023
 
  int #0x10
1024
 
ASM_END
1025
 
  }
1026
 
 
1027
 
 // Set the ints 0x1F and 0x43
1028
 
ASM_START
1029
 
 SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8)
1030
 
ASM_END
1031
 
 
1032
 
  switch(cheight)
1033
 
   {case 8:
1034
 
ASM_START
1035
 
     SET_INT_VECTOR(0x43, #0xC000, #_vgafont8)
1036
 
ASM_END
1037
 
     break;
1038
 
    case 14:
1039
 
ASM_START
1040
 
     SET_INT_VECTOR(0x43, #0xC000, #_vgafont14)
1041
 
ASM_END
1042
 
     break;
1043
 
    case 16:
1044
 
ASM_START
1045
 
     SET_INT_VECTOR(0x43, #0xC000, #_vgafont16)
1046
 
ASM_END
1047
 
     break;
1048
 
   }
1049
 
}
1050
 
 
1051
 
// --------------------------------------------------------------------------------------------
1052
 
static void biosfn_set_cursor_shape (CH,CL) 
1053
 
Bit8u CH;Bit8u CL; 
1054
 
{Bit16u cheight,curs,crtc_addr;
1055
 
 Bit8u modeset_ctl;
1056
 
 
1057
 
 CH&=0x3f;
1058
 
 CL&=0x1f;
1059
 
 
1060
 
 curs=(CH<<8)+CL;
1061
 
 write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs);
1062
 
 
1063
 
 modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
1064
 
 cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
1065
 
 if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))
1066
 
  {
1067
 
   if(CL!=(CH+1))
1068
 
    {
1069
 
     CH = ((CH+1) * cheight / 8) -1;
1070
 
    }
1071
 
   else
1072
 
    {
1073
 
     CH = ((CL+1) * cheight / 8) - 2;
1074
 
    }
1075
 
   CL = ((CL+1) * cheight / 8) - 1;
1076
 
  }
1077
 
 
1078
 
 // CTRC regs 0x0a and 0x0b
1079
 
 crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
1080
 
 outb(crtc_addr,0x0a);
1081
 
 outb(crtc_addr+1,CH);
1082
 
 outb(crtc_addr,0x0b);
1083
 
 outb(crtc_addr+1,CL);
1084
 
}
1085
 
 
1086
 
// --------------------------------------------------------------------------------------------
1087
 
static void biosfn_set_cursor_pos (page, cursor) 
1088
 
Bit8u page;Bit16u cursor;
1089
 
{
1090
 
 Bit8u xcurs,ycurs,current;
1091
 
 Bit16u nbcols,nbrows,address,crtc_addr;
1092
 
 
1093
 
 // Should not happen...
1094
 
 if(page>7)return;
1095
 
 
1096
 
 // Bios cursor pos
1097
 
 write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor);
1098
 
 
1099
 
 // Set the hardware cursor
1100
 
 current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
1101
 
 if(page==current)
1102
 
  {
1103
 
   // Get the dimensions
1104
 
   nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1105
 
   nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1106
 
 
1107
 
   xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1108
 
 
1109
 
   // Calculate the address knowing nbcols nbrows and page num
1110
 
   address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols;
1111
 
   
1112
 
   // CRTC regs 0x0e and 0x0f
1113
 
   crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
1114
 
   outb(crtc_addr,0x0e);
1115
 
   outb(crtc_addr+1,(address&0xff00)>>8);
1116
 
   outb(crtc_addr,0x0f);
1117
 
   outb(crtc_addr+1,address&0x00ff);
1118
 
  }
1119
 
}
1120
 
 
1121
 
// --------------------------------------------------------------------------------------------
1122
 
static void biosfn_get_cursor_pos (page,shape, pos) 
1123
 
Bit8u page;Bit16u *shape;Bit16u *pos;
1124
 
{
1125
 
 Bit16u ss=get_SS();
1126
 
 
1127
 
 // Default
1128
 
 write_word(ss, shape, 0);
1129
 
 write_word(ss, pos, 0);
1130
 
 
1131
 
 if(page>7)return;
1132
 
 // FIXME should handle VGA 14/16 lines
1133
 
 write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE));
1134
 
 write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2));
1135
 
}
1136
 
 
1137
 
// --------------------------------------------------------------------------------------------
1138
 
static void biosfn_set_active_page (page) 
1139
 
Bit8u page;
1140
 
{
1141
 
 Bit16u cursor,dummy,crtc_addr;
1142
 
 Bit16u nbcols,nbrows,address;
1143
 
 Bit8u mode,line;
1144
 
 
1145
 
 if(page>7)return;
1146
 
 
1147
 
 // Get the mode
1148
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1149
 
 line=find_vga_entry(mode);
1150
 
 if(line==0xFF)return;
1151
 
 
1152
 
 // Get pos curs pos for the right page 
1153
 
 biosfn_get_cursor_pos(page,&dummy,&cursor);
1154
 
 
1155
 
 if(vga_modes[line].class==TEXT)
1156
 
  {
1157
 
   // Get the dimensions
1158
 
   nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1159
 
   nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1160
 
 
1161
 
   // Calculate the address knowing nbcols nbrows and page num
1162
 
   address=SCREEN_MEM_START(nbcols,nbrows,page);
1163
 
   write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address);
1164
 
 
1165
 
   // Start address
1166
 
   address=SCREEN_IO_START(nbcols,nbrows,page);
1167
 
  }
1168
 
 else
1169
 
  {
1170
 
   address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l);
1171
 
  }
1172
 
 
1173
 
 // CRTC regs 0x0c and 0x0d
1174
 
 crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
1175
 
 outb(crtc_addr,0x0c);
1176
 
 outb(crtc_addr+1,(address&0xff00)>>8);
1177
 
 outb(crtc_addr,0x0d);
1178
 
 outb(crtc_addr+1,address&0x00ff);
1179
 
 
1180
 
 // And change the BIOS page
1181
 
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page);
1182
 
 
1183
 
#ifdef DEBUG
1184
 
 printf("Set active page %02x address %04x\n",page,address);
1185
 
#endif
1186
 
 
1187
 
 // Display the cursor, now the page is active
1188
 
 biosfn_set_cursor_pos(page,cursor);
1189
 
}
1190
 
 
1191
 
// --------------------------------------------------------------------------------------------
1192
 
static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight)
1193
 
Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight;
1194
 
{
1195
 
 Bit16u src,dest;
1196
 
 Bit8u i;
1197
 
 
1198
 
 src=ysrc*cheight*nbcols+xstart;
1199
 
 dest=ydest*cheight*nbcols+xstart;
1200
 
 outw(VGAREG_GRDC_ADDRESS, 0x0105);
1201
 
 for(i=0;i<cheight;i++)
1202
 
  {
1203
 
   memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols);
1204
 
  }
1205
 
 outw(VGAREG_GRDC_ADDRESS, 0x0005);
1206
 
}
1207
 
 
1208
 
// --------------------------------------------------------------------------------------------
1209
 
static void vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr)
1210
 
Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr;
1211
 
{
1212
 
 Bit16u dest;
1213
 
 Bit8u i;
1214
 
 
1215
 
 dest=ystart*cheight*nbcols+xstart;
1216
 
 outw(VGAREG_GRDC_ADDRESS, 0x0205);
1217
 
 for(i=0;i<cheight;i++)
1218
 
  {
1219
 
   memsetb(0xa000,dest+i*nbcols,attr,cols);
1220
 
  }
1221
 
 outw(VGAREG_GRDC_ADDRESS, 0x0005);
1222
 
}
1223
 
 
1224
 
// --------------------------------------------------------------------------------------------
1225
 
static void vgamem_copy_cga(xstart,ysrc,ydest,cols,nbcols,cheight)
1226
 
Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight;
1227
 
{
1228
 
 Bit16u src,dest;
1229
 
 Bit8u i;
1230
 
 
1231
 
 src=((ysrc*cheight*nbcols)>>1)+xstart;
1232
 
 dest=((ydest*cheight*nbcols)>>1)+xstart;
1233
 
 for(i=0;i<cheight;i++)
1234
 
  {
1235
 
   if (i & 1)
1236
 
     memcpyb(0xb800,0x2000+dest+(i>>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols);
1237
 
   else
1238
 
     memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols);
1239
 
  }
1240
 
}
1241
 
 
1242
 
// --------------------------------------------------------------------------------------------
1243
 
static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr)
1244
 
Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr;
1245
 
{
1246
 
 Bit16u dest;
1247
 
 Bit8u i;
1248
 
 
1249
 
 dest=((ystart*cheight*nbcols)>>1)+xstart;
1250
 
 for(i=0;i<cheight;i++)
1251
 
  {
1252
 
   if (i & 1)
1253
 
     memsetb(0xb800,0x2000+dest+(i>>1)*nbcols,attr,cols);
1254
 
   else
1255
 
     memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols);
1256
 
  }
1257
 
}
1258
 
 
1259
 
// --------------------------------------------------------------------------------------------
1260
 
static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)
1261
 
Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;
1262
 
{
1263
 
 // page == 0xFF if current
1264
 
 
1265
 
 Bit8u mode,line,cheight,bpp,cols;
1266
 
 Bit16u nbcols,nbrows,i;
1267
 
 Bit16u address;
1268
 
 
1269
 
 if(rul>rlr)return;
1270
 
 if(cul>clr)return;
1271
 
 
1272
 
 // Get the mode
1273
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1274
 
 line=find_vga_entry(mode);
1275
 
 if(line==0xFF)return;
1276
 
 
1277
 
 // Get the dimensions
1278
 
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1279
 
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1280
 
 
1281
 
 // Get the current page
1282
 
 if(page==0xFF)
1283
 
  page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
1284
 
 
1285
 
 if(rlr>=nbrows)rlr=nbrows-1;
1286
 
 if(clr>=nbcols)clr=nbcols-1;
1287
 
 if(nblines>nbrows)nblines=0;
1288
 
 cols=clr-cul+1;
1289
 
 
1290
 
 if(vga_modes[line].class==TEXT)
1291
 
  {
1292
 
   // Compute the address
1293
 
   address=SCREEN_MEM_START(nbcols,nbrows,page);
1294
 
#ifdef DEBUG
1295
 
   printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);
1296
 
#endif
1297
 
 
1298
 
   if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
1299
 
    {
1300
 
     memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);
1301
 
    }
1302
 
   else
1303
 
    {// if Scroll up
1304
 
     if(dir==SCROLL_UP)
1305
 
      {for(i=rul;i<=rlr;i++)
1306
 
        {
1307
 
         if((i+nblines>rlr)||(nblines==0))
1308
 
          memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
1309
 
         else
1310
 
          memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);
1311
 
        }
1312
 
      }
1313
 
     else
1314
 
      {for(i=rlr;i>=rul;i--)
1315
 
        {
1316
 
         if((i<rul+nblines)||(nblines==0))
1317
 
          memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
1318
 
         else
1319
 
          memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);
1320
 
         if (i>rlr) break;
1321
 
        }
1322
 
      }
1323
 
    }
1324
 
  }
1325
 
 else
1326
 
  {
1327
 
   // FIXME gfx mode not complete
1328
 
   cheight=video_param_table[line_to_vpti[line]].cheight;
1329
 
   switch(vga_modes[line].memmodel)
1330
 
    {
1331
 
     case PLANAR4:
1332
 
     case PLANAR1:
1333
 
       if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
1334
 
        {
1335
 
         outw(VGAREG_GRDC_ADDRESS, 0x0205);
1336
 
         memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight);
1337
 
         outw(VGAREG_GRDC_ADDRESS, 0x0005);
1338
 
        }
1339
 
       else
1340
 
        {// if Scroll up
1341
 
         if(dir==SCROLL_UP)
1342
 
          {for(i=rul;i<=rlr;i++)
1343
 
            {
1344
 
             if((i+nblines>rlr)||(nblines==0))
1345
 
              vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
1346
 
             else
1347
 
              vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight);
1348
 
            }
1349
 
          }
1350
 
         else
1351
 
          {for(i=rlr;i>=rul;i--)
1352
 
            {
1353
 
             if((i<rul+nblines)||(nblines==0))
1354
 
              vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
1355
 
             else
1356
 
              vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight);
1357
 
             if (i>rlr) break;
1358
 
            }
1359
 
          }
1360
 
        }
1361
 
       break;
1362
 
     case CGA:
1363
 
       bpp=vga_modes[line].pixbits;
1364
 
       if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
1365
 
        {
1366
 
         memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp);
1367
 
        }
1368
 
       else
1369
 
        {
1370
 
         if(bpp==2)
1371
 
          {
1372
 
           cul<<=1;
1373
 
           cols<<=1;
1374
 
           nbcols<<=1;
1375
 
          }
1376
 
         // if Scroll up
1377
 
         if(dir==SCROLL_UP)
1378
 
          {for(i=rul;i<=rlr;i++)
1379
 
            {
1380
 
             if((i+nblines>rlr)||(nblines==0))
1381
 
              vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr);
1382
 
             else
1383
 
              vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight);
1384
 
            }
1385
 
          }
1386
 
         else
1387
 
          {for(i=rlr;i>=rul;i--)
1388
 
            {
1389
 
             if((i<rul+nblines)||(nblines==0))
1390
 
              vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr);
1391
 
             else
1392
 
              vgamem_copy_cga(cul,i,i-nblines,cols,nbcols,cheight);
1393
 
             if (i>rlr) break;
1394
 
            }
1395
 
          }
1396
 
        }
1397
 
       break;
1398
 
#ifdef DEBUG
1399
 
     default:
1400
 
       printf("Scroll in graphics mode ");
1401
 
       unimplemented();
1402
 
#endif
1403
 
    }
1404
 
  }
1405
 
}
1406
 
 
1407
 
// --------------------------------------------------------------------------------------------
1408
 
static void biosfn_read_char_attr (page,car) 
1409
 
Bit8u page;Bit16u *car;
1410
 
{Bit16u ss=get_SS();
1411
 
 Bit8u xcurs,ycurs,mode,line;
1412
 
 Bit16u nbcols,nbrows,address;
1413
 
 Bit16u cursor,dummy;
1414
 
 
1415
 
 // Get the mode
1416
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1417
 
 line=find_vga_entry(mode);
1418
 
 if(line==0xFF)return;
1419
 
 
1420
 
 // Get the cursor pos for the page
1421
 
 biosfn_get_cursor_pos(page,&dummy,&cursor);
1422
 
 xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1423
 
 
1424
 
 // Get the dimensions
1425
 
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1426
 
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1427
 
 
1428
 
 if(vga_modes[line].class==TEXT)
1429
 
  {
1430
 
   // Compute the address
1431
 
   address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1432
 
 
1433
 
   write_word(ss,car,read_word(vga_modes[line].sstart,address));
1434
 
  }
1435
 
 else
1436
 
  {
1437
 
   // FIXME gfx mode
1438
 
#ifdef DEBUG
1439
 
   unimplemented();
1440
 
#endif
1441
 
  }
1442
 
}
1443
 
 
1444
 
// --------------------------------------------------------------------------------------------
1445
 
static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight)
1446
 
Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight;
1447
 
{
1448
 
 Bit8u i,j,mask;
1449
 
 Bit8u *fdata;
1450
 
 Bit16u addr,dest,src;
1451
 
 
1452
 
 switch(cheight)
1453
 
  {case 14:
1454
 
    fdata = &vgafont14;
1455
 
    break;
1456
 
   case 16:
1457
 
    fdata = &vgafont16;
1458
 
    break;
1459
 
   default:
1460
 
    fdata = &vgafont8;
1461
 
  }
1462
 
 addr=xcurs+ycurs*cheight*nbcols;
1463
 
 src = car * cheight;
1464
 
 outw(VGAREG_SEQU_ADDRESS, 0x0f02);
1465
 
 outw(VGAREG_GRDC_ADDRESS, 0x0205);
1466
 
 if(attr&0x80)
1467
 
  {
1468
 
   outw(VGAREG_GRDC_ADDRESS, 0x1803);
1469
 
  }
1470
 
 else
1471
 
  {
1472
 
   outw(VGAREG_GRDC_ADDRESS, 0x0003);
1473
 
  }
1474
 
 for(i=0;i<cheight;i++)
1475
 
  {
1476
 
   dest=addr+i*nbcols;
1477
 
   for(j=0;j<8;j++)
1478
 
    {
1479
 
     mask=0x80>>j;
1480
 
     outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);
1481
 
     read_byte(0xa000,dest);
1482
 
     if(fdata[src+i]&mask)
1483
 
      {
1484
 
       write_byte(0xa000,dest,attr&0x0f);
1485
 
      }
1486
 
     else
1487
 
      {
1488
 
       write_byte(0xa000,dest,0x00);
1489
 
      }
1490
 
    }
1491
 
  }
1492
 
ASM_START
1493
 
  mov dx, # VGAREG_GRDC_ADDRESS
1494
 
  mov ax, #0xff08
1495
 
  out dx, ax
1496
 
  mov ax, #0x0005
1497
 
  out dx, ax
1498
 
  mov ax, #0x0003
1499
 
  out dx, ax
1500
 
ASM_END
1501
 
}
1502
 
 
1503
 
// --------------------------------------------------------------------------------------------
1504
 
static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp)
1505
 
Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp;
1506
 
{
1507
 
 Bit8u i,j,mask,data;
1508
 
 Bit8u *fdata;
1509
 
 Bit16u addr,dest,src;
1510
 
 
1511
 
 fdata = &vgafont8;
1512
 
 addr=(xcurs*bpp)+ycurs*320;
1513
 
 src = car * 8;
1514
 
 for(i=0;i<8;i++)
1515
 
  {
1516
 
   dest=addr+(i>>1)*80;
1517
 
   if (i & 1) dest += 0x2000;
1518
 
   mask = 0x80;
1519
 
   if (bpp == 1)
1520
 
    {
1521
 
     if (attr & 0x80)
1522
 
      {
1523
 
       data = read_byte(0xb800,dest);
1524
 
      }
1525
 
     else
1526
 
      {
1527
 
       data = 0x00;
1528
 
      }
1529
 
     for(j=0;j<8;j++)
1530
 
      {
1531
 
       if (fdata[src+i] & mask)
1532
 
        {
1533
 
         if (attr & 0x80)
1534
 
          {
1535
 
           data ^= (attr & 0x01) << (7-j);
1536
 
          }
1537
 
         else
1538
 
          {
1539
 
           data |= (attr & 0x01) << (7-j);
1540
 
          }
1541
 
        }
1542
 
       mask >>= 1;
1543
 
      }
1544
 
     write_byte(0xb800,dest,data);
1545
 
    }
1546
 
   else
1547
 
    {
1548
 
     while (mask > 0)
1549
 
      {
1550
 
       if (attr & 0x80)
1551
 
        {
1552
 
         data = read_byte(0xb800,dest);
1553
 
        }
1554
 
       else
1555
 
        {
1556
 
         data = 0x00;
1557
 
        }
1558
 
       for(j=0;j<4;j++)
1559
 
        {
1560
 
         if (fdata[src+i] & mask)
1561
 
          {
1562
 
           if (attr & 0x80)
1563
 
            {
1564
 
             data ^= (attr & 0x03) << ((3-j)*2);
1565
 
            }
1566
 
           else
1567
 
            {
1568
 
             data |= (attr & 0x03) << ((3-j)*2);
1569
 
            }
1570
 
          }
1571
 
         mask >>= 1;
1572
 
        }
1573
 
       write_byte(0xb800,dest,data);
1574
 
       dest += 1;
1575
 
      }
1576
 
    }
1577
 
  }
1578
 
}
1579
 
 
1580
 
// --------------------------------------------------------------------------------------------
1581
 
static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols)
1582
 
Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;
1583
 
{
1584
 
 Bit8u i,j,mask,data;
1585
 
 Bit8u *fdata;
1586
 
 Bit16u addr,dest,src;
1587
 
 
1588
 
 fdata = &vgafont8;
1589
 
 addr=xcurs*8+ycurs*nbcols*64;
1590
 
 src = car * 8;
1591
 
 for(i=0;i<8;i++)
1592
 
  {
1593
 
   dest=addr+i*nbcols*8;
1594
 
   mask = 0x80;
1595
 
   for(j=0;j<8;j++)
1596
 
    {
1597
 
     data = 0x00;
1598
 
     if (fdata[src+i] & mask)
1599
 
      {
1600
 
       data = attr;
1601
 
      }
1602
 
     write_byte(0xa000,dest+j,data);
1603
 
     mask >>= 1;
1604
 
    }
1605
 
  }
1606
 
}
1607
 
 
1608
 
// --------------------------------------------------------------------------------------------
1609
 
static void biosfn_write_char_attr (car,page,attr,count) 
1610
 
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
1611
 
{
1612
 
 Bit8u cheight,xcurs,ycurs,mode,line,bpp;
1613
 
 Bit16u nbcols,nbrows,address;
1614
 
 Bit16u cursor,dummy;
1615
 
 
1616
 
 // Get the mode
1617
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1618
 
 line=find_vga_entry(mode);
1619
 
 if(line==0xFF)return;
1620
 
 
1621
 
 // Get the cursor pos for the page
1622
 
 biosfn_get_cursor_pos(page,&dummy,&cursor);
1623
 
 xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1624
 
 
1625
 
 // Get the dimensions
1626
 
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1627
 
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1628
 
 
1629
 
 if(vga_modes[line].class==TEXT)
1630
 
  {
1631
 
   // Compute the address
1632
 
   address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1633
 
 
1634
 
   dummy=((Bit16u)attr<<8)+car;
1635
 
   memsetw(vga_modes[line].sstart,address,dummy,count);
1636
 
  }
1637
 
 else
1638
 
  {
1639
 
   // FIXME gfx mode not complete
1640
 
   cheight=video_param_table[line_to_vpti[line]].cheight;
1641
 
   bpp=vga_modes[line].pixbits;
1642
 
   while((count-->0) && (xcurs<nbcols))
1643
 
    {
1644
 
     switch(vga_modes[line].memmodel)
1645
 
      {
1646
 
       case PLANAR4:
1647
 
       case PLANAR1:
1648
 
         write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
1649
 
         break;
1650
 
       case CGA:
1651
 
         write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);
1652
 
         break;
1653
 
       case LINEAR8:
1654
 
         write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
1655
 
         break;
1656
 
#ifdef DEBUG
1657
 
       default:
1658
 
         unimplemented();
1659
 
#endif
1660
 
      }
1661
 
     xcurs++;
1662
 
    }
1663
 
  }
1664
 
}
1665
 
 
1666
 
// --------------------------------------------------------------------------------------------
1667
 
static void biosfn_write_char_only (car,page,attr,count)
1668
 
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
1669
 
{
1670
 
 Bit8u cheight,xcurs,ycurs,mode,line,bpp;
1671
 
 Bit16u nbcols,nbrows,address;
1672
 
 Bit16u cursor,dummy;
1673
 
 
1674
 
 // Get the mode
1675
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1676
 
 line=find_vga_entry(mode);
1677
 
 if(line==0xFF)return;
1678
 
 
1679
 
 // Get the cursor pos for the page
1680
 
 biosfn_get_cursor_pos(page,&dummy,&cursor);
1681
 
 xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1682
 
 
1683
 
 // Get the dimensions
1684
 
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1685
 
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1686
 
 
1687
 
 if(vga_modes[line].class==TEXT)
1688
 
  {
1689
 
   // Compute the address
1690
 
   address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1691
 
 
1692
 
   while(count-->0)
1693
 
    {write_byte(vga_modes[line].sstart,address,car);
1694
 
     address+=2;
1695
 
    }
1696
 
  }
1697
 
 else
1698
 
  {
1699
 
   // FIXME gfx mode not complete
1700
 
   cheight=video_param_table[line_to_vpti[line]].cheight;
1701
 
   bpp=vga_modes[line].pixbits;
1702
 
   while((count-->0) && (xcurs<nbcols))
1703
 
    {
1704
 
     switch(vga_modes[line].memmodel)
1705
 
      {
1706
 
       case PLANAR4:
1707
 
       case PLANAR1:
1708
 
         write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
1709
 
         break;
1710
 
       case CGA:
1711
 
         write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);
1712
 
         break;
1713
 
       case LINEAR8:
1714
 
         write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
1715
 
         break;
1716
 
#ifdef DEBUG
1717
 
       default:
1718
 
         unimplemented();
1719
 
#endif
1720
 
      }
1721
 
     xcurs++;
1722
 
    }
1723
 
  }
1724
 
}
1725
 
 
1726
 
// --------------------------------------------------------------------------------------------
1727
 
ASM_START
1728
 
biosfn_group_0B:
1729
 
  cmp   bh, #0x00
1730
 
  je    biosfn_set_border_color
1731
 
  cmp   bh, #0x01
1732
 
  je    biosfn_set_palette
1733
 
#ifdef DEBUG
1734
 
  call  _unknown
1735
 
#endif
1736
 
  ret
1737
 
biosfn_set_border_color:
1738
 
  push  ax
1739
 
  push  bx
1740
 
  push  cx
1741
 
  push  dx
1742
 
  mov   dx, # VGAREG_ACTL_RESET
1743
 
  in    al, dx
1744
 
  mov   dx, # VGAREG_ACTL_ADDRESS
1745
 
  mov   al, #0x00
1746
 
  out   dx, al
1747
 
  mov   al, bl
1748
 
  and   al, #0x0f
1749
 
  test  al, #0x08
1750
 
  jz    set_low_border
1751
 
  add   al, #0x08
1752
 
set_low_border:
1753
 
  out   dx, al
1754
 
  mov   cl, #0x01
1755
 
  and   bl, #0x10
1756
 
set_intensity_loop:
1757
 
  mov   dx, # VGAREG_ACTL_ADDRESS
1758
 
  mov   al, cl
1759
 
  out   dx, al
1760
 
  mov   dx, # VGAREG_ACTL_READ_DATA
1761
 
  in    al, dx
1762
 
  and   al, #0xef
1763
 
  or    al, bl
1764
 
  mov   dx, # VGAREG_ACTL_ADDRESS
1765
 
  out   dx, al
1766
 
  inc   cl
1767
 
  cmp   cl, #0x04
1768
 
  jne   set_intensity_loop
1769
 
  mov   al, #0x20
1770
 
  out   dx, al
1771
 
  pop   dx
1772
 
  pop   cx
1773
 
  pop   bx
1774
 
  pop   ax
1775
 
  ret
1776
 
biosfn_set_palette:
1777
 
  push  ax
1778
 
  push  bx
1779
 
  push  cx
1780
 
  push  dx
1781
 
  mov   dx, # VGAREG_ACTL_RESET
1782
 
  in    al, dx
1783
 
  mov   cl, #0x01
1784
 
  and   bl, #0x01
1785
 
set_cga_palette_loop:
1786
 
  mov   dx, # VGAREG_ACTL_ADDRESS
1787
 
  mov   al, cl
1788
 
  out   dx, al
1789
 
  mov   dx, # VGAREG_ACTL_READ_DATA
1790
 
  in    al, dx
1791
 
  and   al, #0xfe
1792
 
  or    al, bl
1793
 
  mov   dx, # VGAREG_ACTL_ADDRESS
1794
 
  out   dx, al
1795
 
  inc   cl
1796
 
  cmp   cl, #0x04
1797
 
  jne   set_cga_palette_loop
1798
 
  mov   al, #0x20
1799
 
  out   dx, al
1800
 
  pop   dx
1801
 
  pop   cx
1802
 
  pop   bx
1803
 
  pop   ax
1804
 
  ret
1805
 
ASM_END
1806
 
 
1807
 
// --------------------------------------------------------------------------------------------
1808
 
static void biosfn_write_pixel (BH,AL,CX,DX) Bit8u BH;Bit8u AL;Bit16u CX;Bit16u DX;
1809
 
{
1810
 
 Bit8u mode,line,mask,attr,data;
1811
 
 Bit16u addr;
1812
 
 
1813
 
 // Get the mode
1814
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1815
 
 line=find_vga_entry(mode);
1816
 
 if(line==0xFF)return;
1817
 
 if(vga_modes[line].class==TEXT)return;
1818
 
 
1819
 
 switch(vga_modes[line].memmodel)
1820
 
  {
1821
 
   case PLANAR4:
1822
 
   case PLANAR1:
1823
 
     addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1824
 
     mask = 0x80 >> (CX & 0x07);
1825
 
     outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);
1826
 
     outw(VGAREG_GRDC_ADDRESS, 0x0205);
1827
 
     data = read_byte(0xa000,addr);
1828
 
     if (AL & 0x80)
1829
 
      {
1830
 
       outw(VGAREG_GRDC_ADDRESS, 0x1803);
1831
 
      }
1832
 
     write_byte(0xa000,addr,AL);
1833
 
ASM_START
1834
 
     mov dx, # VGAREG_GRDC_ADDRESS
1835
 
     mov ax, #0xff08
1836
 
     out dx, ax
1837
 
     mov ax, #0x0005
1838
 
     out dx, ax
1839
 
     mov ax, #0x0003
1840
 
     out dx, ax
1841
 
ASM_END
1842
 
     break;
1843
 
   case CGA:
1844
 
     if(vga_modes[line].pixbits==2)
1845
 
      {
1846
 
       addr=(CX>>2)+(DX>>1)*80;
1847
 
      }
1848
 
     else
1849
 
      {
1850
 
       addr=(CX>>3)+(DX>>1)*80;
1851
 
      }
1852
 
     if (DX & 1) addr += 0x2000;
1853
 
     data = read_byte(0xb800,addr);
1854
 
     if(vga_modes[line].pixbits==2)
1855
 
      {
1856
 
       attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
1857
 
       mask = 0x03 << ((3 - (CX & 0x03)) * 2);
1858
 
      }
1859
 
     else
1860
 
      {
1861
 
       attr = (AL & 0x01) << (7 - (CX & 0x07));
1862
 
       mask = 0x01 << (7 - (CX & 0x07));
1863
 
      }
1864
 
     if (AL & 0x80)
1865
 
      {
1866
 
       data ^= attr;
1867
 
      }
1868
 
     else
1869
 
      {
1870
 
       data &= ~mask;
1871
 
       data |= attr;
1872
 
      }
1873
 
     write_byte(0xb800,addr,data);
1874
 
     break;
1875
 
   case LINEAR8:
1876
 
     addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8);
1877
 
     write_byte(0xa000,addr,AL);
1878
 
     break;
1879
 
#ifdef DEBUG
1880
 
   default:
1881
 
     unimplemented();
1882
 
#endif
1883
 
  }
1884
 
}
1885
 
 
1886
 
// --------------------------------------------------------------------------------------------
1887
 
static void biosfn_read_pixel (BH,CX,DX,AX) Bit8u BH;Bit16u CX;Bit16u DX;Bit16u *AX;
1888
 
{
1889
 
 Bit8u mode,line,mask,attr,data,i;
1890
 
 Bit16u addr;
1891
 
 Bit16u ss=get_SS();
1892
 
 
1893
 
 // Get the mode
1894
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1895
 
 line=find_vga_entry(mode);
1896
 
 if(line==0xFF)return;
1897
 
 if(vga_modes[line].class==TEXT)return;
1898
 
 
1899
 
 switch(vga_modes[line].memmodel)
1900
 
  {
1901
 
   case PLANAR4:
1902
 
   case PLANAR1:
1903
 
     addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1904
 
     mask = 0x80 >> (CX & 0x07);
1905
 
     attr = 0x00;
1906
 
     for(i=0;i<4;i++)
1907
 
      {
1908
 
       outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04);
1909
 
       data = read_byte(0xa000,addr) & mask;
1910
 
       if (data > 0) attr |= (0x01 << i);
1911
 
      }
1912
 
     break;
1913
 
   case CGA:
1914
 
     addr=(CX>>2)+(DX>>1)*80;
1915
 
     if (DX & 1) addr += 0x2000;
1916
 
     data = read_byte(0xb800,addr);
1917
 
     if(vga_modes[line].pixbits==2)
1918
 
      {
1919
 
       attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
1920
 
      }
1921
 
     else
1922
 
      {
1923
 
       attr = (data >> (7 - (CX & 0x07))) & 0x01;
1924
 
      }
1925
 
     break;
1926
 
   case LINEAR8:
1927
 
     addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8);
1928
 
     attr=read_byte(0xa000,addr);
1929
 
     break;
1930
 
   default:
1931
 
#ifdef DEBUG
1932
 
     unimplemented();
1933
 
#endif
1934
 
     attr = 0;
1935
 
  }
1936
 
 write_word(ss,AX,(read_word(ss,AX) & 0xff00) | attr);
1937
 
}
1938
 
 
1939
 
// --------------------------------------------------------------------------------------------
1940
 
static void biosfn_write_teletype (car, page, attr, flag) 
1941
 
Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
1942
 
{// flag = WITH_ATTR / NO_ATTR
1943
 
 
1944
 
 Bit8u cheight,xcurs,ycurs,mode,line,bpp;
1945
 
 Bit16u nbcols,nbrows,address;
1946
 
 Bit16u cursor,dummy;
1947
 
 
1948
 
 // special case if page is 0xff, use current page
1949
 
 if(page==0xff)
1950
 
  page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
1951
 
 
1952
 
 // Get the mode
1953
 
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1954
 
 line=find_vga_entry(mode);
1955
 
 if(line==0xFF)return;
1956
 
 
1957
 
 // Get the cursor pos for the page
1958
 
 biosfn_get_cursor_pos(page,&dummy,&cursor);
1959
 
 xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1960
 
 
1961
 
 // Get the dimensions
1962
 
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1963
 
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1964
 
 
1965
 
 switch(car)
1966
 
  {
1967
 
   case 7:
1968
 
    //FIXME should beep
1969
 
    break;
1970
 
 
1971
 
   case 8:
1972
 
    if(xcurs>0)xcurs--;
1973
 
    break;
1974
 
 
1975
 
   case '\r':
1976
 
    xcurs=0;
1977
 
    break;
1978
 
 
1979
 
   case '\n':
1980
 
    ycurs++;
1981
 
    break;
1982
 
 
1983
 
   case '\t':
1984
 
    do
1985
 
     {
1986
 
      biosfn_write_teletype(' ',page,attr,flag);
1987
 
      biosfn_get_cursor_pos(page,&dummy,&cursor);
1988
 
      xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1989
 
     }while(xcurs%8==0);
1990
 
    break;
1991
 
 
1992
 
   default:
1993
 
 
1994
 
    if(vga_modes[line].class==TEXT)
1995
 
     {
1996
 
      // Compute the address  
1997
 
      address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1998
 
 
1999
 
      // Write the char 
2000
 
      write_byte(vga_modes[line].sstart,address,car);
2001
 
 
2002
 
      if(flag==WITH_ATTR)
2003
 
       write_byte(vga_modes[line].sstart,address+1,attr);
2004
 
     }
2005
 
    else
2006
 
     {
2007
 
      // FIXME gfx mode not complete
2008
 
      cheight=video_param_table[line_to_vpti[line]].cheight;
2009
 
      bpp=vga_modes[line].pixbits;
2010
 
      switch(vga_modes[line].memmodel)
2011
 
       {
2012
 
        case PLANAR4:
2013
 
        case PLANAR1:
2014
 
          write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
2015
 
          break;
2016
 
        case CGA:
2017
 
          write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);
2018
 
          break;
2019
 
        case LINEAR8:
2020
 
          write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
2021
 
          break;
2022
 
#ifdef DEBUG
2023
 
        default:
2024
 
          unimplemented();
2025
 
#endif
2026
 
       }
2027
 
     }
2028
 
    xcurs++;
2029
 
  }
2030
 
 
2031
 
 // Do we need to wrap ?
2032
 
 if(xcurs==nbcols)
2033
 
  {xcurs=0;
2034
 
   ycurs++;
2035
 
  }
2036
 
 
2037
 
 // Do we need to scroll ?
2038
 
 if(ycurs==nbrows)
2039
 
  {
2040
 
   if(vga_modes[line].class==TEXT)
2041
 
    {
2042
 
     address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+(ycurs-1)*nbcols)*2;
2043
 
     attr=read_byte(vga_modes[line].sstart,address+1);
2044
 
     biosfn_scroll(0x01,attr,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
2045
 
    }
2046
 
   else
2047
 
    {
2048
 
     biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
2049
 
    }
2050
 
   ycurs-=1;
2051
 
  }
2052
 
 
2053
 
 // Set the cursor for the page
2054
 
 cursor=ycurs; cursor<<=8; cursor+=xcurs;
2055
 
 biosfn_set_cursor_pos(page,cursor);
2056
 
}
2057
 
 
2058
 
// --------------------------------------------------------------------------------------------
2059
 
ASM_START
2060
 
biosfn_get_video_mode:
2061
 
  push  ds
2062
 
  mov   ax, # BIOSMEM_SEG
2063
 
  mov   ds, ax
2064
 
  push  bx
2065
 
  mov   bx, # BIOSMEM_CURRENT_PAGE
2066
 
  mov   al, [bx]
2067
 
  pop   bx
2068
 
  mov   bh, al
2069
 
  push  bx
2070
 
  mov   bx, # BIOSMEM_VIDEO_CTL
2071
 
  mov   ah, [bx]
2072
 
  and   ah, #0x80
2073
 
  mov   bx, # BIOSMEM_CURRENT_MODE
2074
 
  mov   al, [bx]
2075
 
  or    al, ah
2076
 
  mov   bx, # BIOSMEM_NB_COLS
2077
 
  mov   ah, [bx]
2078
 
  pop   bx
2079
 
  pop   ds
2080
 
  ret
2081
 
ASM_END
2082
 
 
2083
 
// --------------------------------------------------------------------------------------------
2084
 
ASM_START
2085
 
biosfn_group_10:
2086
 
  cmp   al, #0x00
2087
 
  jne   int10_test_1001
2088
 
  jmp   biosfn_set_single_palette_reg
2089
 
int10_test_1001:
2090
 
  cmp   al, #0x01
2091
 
  jne   int10_test_1002
2092
 
  jmp   biosfn_set_overscan_border_color
2093
 
int10_test_1002:
2094
 
  cmp   al, #0x02
2095
 
  jne   int10_test_1003
2096
 
  jmp   biosfn_set_all_palette_reg
2097
 
int10_test_1003:
2098
 
  cmp   al, #0x03
2099
 
  jne   int10_test_1007
2100
 
  jmp   biosfn_toggle_intensity
2101
 
int10_test_1007:
2102
 
  cmp   al, #0x07
2103
 
  jne   int10_test_1008
2104
 
  jmp   biosfn_get_single_palette_reg
2105
 
int10_test_1008:
2106
 
  cmp   al, #0x08
2107
 
  jne   int10_test_1009
2108
 
  jmp   biosfn_read_overscan_border_color
2109
 
int10_test_1009:
2110
 
  cmp   al, #0x09
2111
 
  jne   int10_test_1010
2112
 
  jmp   biosfn_get_all_palette_reg
2113
 
int10_test_1010:
2114
 
  cmp   al, #0x10
2115
 
  jne   int10_test_1012
2116
 
  jmp  biosfn_set_single_dac_reg
2117
 
int10_test_1012:
2118
 
  cmp   al, #0x12
2119
 
  jne   int10_test_1013
2120
 
  jmp   biosfn_set_all_dac_reg
2121
 
int10_test_1013:
2122
 
  cmp   al, #0x13
2123
 
  jne   int10_test_1015
2124
 
  jmp   biosfn_select_video_dac_color_page
2125
 
int10_test_1015:
2126
 
  cmp   al, #0x15
2127
 
  jne   int10_test_1017
2128
 
  jmp   biosfn_read_single_dac_reg
2129
 
int10_test_1017:
2130
 
  cmp   al, #0x17
2131
 
  jne   int10_test_1018
2132
 
  jmp   biosfn_read_all_dac_reg
2133
 
int10_test_1018:
2134
 
  cmp   al, #0x18
2135
 
  jne   int10_test_1019
2136
 
  jmp   biosfn_set_pel_mask
2137
 
int10_test_1019:
2138
 
  cmp   al, #0x19
2139
 
  jne   int10_test_101A
2140
 
  jmp   biosfn_read_pel_mask
2141
 
int10_test_101A:
2142
 
  cmp   al, #0x1a
2143
 
  jne   int10_group_10_unknown
2144
 
  jmp   biosfn_read_video_dac_state
2145
 
int10_group_10_unknown:
2146
 
#ifdef DEBUG
2147
 
  call  _unknown
2148
 
#endif
2149
 
  ret
2150
 
 
2151
 
biosfn_set_single_palette_reg:
2152
 
  cmp   bl, #0x14
2153
 
  ja    no_actl_reg1
2154
 
  push  ax
2155
 
  push  dx
2156
 
  mov   dx, # VGAREG_ACTL_RESET
2157
 
  in    al, dx
2158
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2159
 
  mov   al, bl
2160
 
  out   dx, al
2161
 
  mov   al, bh
2162
 
  out   dx, al
2163
 
  mov   al, #0x20
2164
 
  out   dx, al
2165
 
  pop   dx
2166
 
  pop   ax
2167
 
no_actl_reg1:
2168
 
  ret
2169
 
ASM_END
2170
 
 
2171
 
// --------------------------------------------------------------------------------------------
2172
 
ASM_START
2173
 
biosfn_set_overscan_border_color:
2174
 
  push  bx
2175
 
  mov   bl, #0x11
2176
 
  call  biosfn_set_single_palette_reg
2177
 
  pop   bx
2178
 
  ret
2179
 
ASM_END
2180
 
 
2181
 
// --------------------------------------------------------------------------------------------
2182
 
ASM_START
2183
 
biosfn_set_all_palette_reg:
2184
 
  push  ax
2185
 
  push  bx
2186
 
  push  cx
2187
 
  push  dx
2188
 
  mov   bx, dx
2189
 
  mov   dx, # VGAREG_ACTL_RESET
2190
 
  in    al, dx
2191
 
  mov   cl, #0x00
2192
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2193
 
set_palette_loop:
2194
 
  mov   al, cl
2195
 
  out   dx, al
2196
 
  seg   es
2197
 
  mov   al, [bx]
2198
 
  out   dx, al
2199
 
  inc   bx
2200
 
  inc   cl
2201
 
  cmp   cl, #0x10
2202
 
  jne   set_palette_loop
2203
 
  mov   al, #0x11
2204
 
  out   dx, al
2205
 
  seg   es
2206
 
  mov   al, [bx]
2207
 
  out   dx, al
2208
 
  mov   al, #0x20
2209
 
  out   dx, al
2210
 
  pop   dx
2211
 
  pop   cx
2212
 
  pop   bx
2213
 
  pop   ax
2214
 
  ret
2215
 
ASM_END
2216
 
 
2217
 
// --------------------------------------------------------------------------------------------
2218
 
ASM_START
2219
 
biosfn_toggle_intensity:
2220
 
  push  ax
2221
 
  push  bx
2222
 
  push  dx
2223
 
  mov   dx, # VGAREG_ACTL_RESET
2224
 
  in    al, dx
2225
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2226
 
  mov   al, #0x10
2227
 
  out   dx, al
2228
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2229
 
  in    al, dx
2230
 
  and   al, #0xf7
2231
 
  and   bl, #0x01
2232
 
  shl   bl, 3
2233
 
  or    al, bl
2234
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2235
 
  out   dx, al
2236
 
  mov   al, #0x20
2237
 
  out   dx, al
2238
 
  pop   dx
2239
 
  pop   bx
2240
 
  pop   ax
2241
 
  ret
2242
 
ASM_END
2243
 
 
2244
 
// --------------------------------------------------------------------------------------------
2245
 
ASM_START
2246
 
biosfn_get_single_palette_reg:
2247
 
  cmp   bl, #0x14
2248
 
  ja    no_actl_reg2
2249
 
  push  ax
2250
 
  push  dx
2251
 
  mov   dx, # VGAREG_ACTL_RESET
2252
 
  in    al, dx
2253
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2254
 
  mov   al, bl
2255
 
  out   dx, al
2256
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2257
 
  in    al, dx
2258
 
  mov   bh, al
2259
 
  mov   dx, # VGAREG_ACTL_RESET
2260
 
  in    al, dx
2261
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2262
 
  mov   al, #0x20
2263
 
  out   dx, al
2264
 
  pop   dx
2265
 
  pop   ax
2266
 
no_actl_reg2:
2267
 
  ret
2268
 
ASM_END
2269
 
 
2270
 
// --------------------------------------------------------------------------------------------
2271
 
ASM_START
2272
 
biosfn_read_overscan_border_color:
2273
 
  push  ax
2274
 
  push  bx
2275
 
  mov   bl, #0x11
2276
 
  call  biosfn_get_single_palette_reg
2277
 
  mov   al, bh
2278
 
  pop   bx
2279
 
  mov   bh, al
2280
 
  pop   ax
2281
 
  ret
2282
 
ASM_END
2283
 
 
2284
 
// --------------------------------------------------------------------------------------------
2285
 
ASM_START
2286
 
biosfn_get_all_palette_reg:
2287
 
  push  ax
2288
 
  push  bx
2289
 
  push  cx
2290
 
  push  dx
2291
 
  mov   bx, dx
2292
 
  mov   cl, #0x00
2293
 
get_palette_loop:
2294
 
  mov   dx, # VGAREG_ACTL_RESET
2295
 
  in    al, dx
2296
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2297
 
  mov   al, cl
2298
 
  out   dx, al
2299
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2300
 
  in    al, dx
2301
 
  seg   es
2302
 
  mov   [bx], al
2303
 
  inc   bx
2304
 
  inc   cl
2305
 
  cmp   cl, #0x10
2306
 
  jne   get_palette_loop
2307
 
  mov   dx, # VGAREG_ACTL_RESET
2308
 
  in    al, dx
2309
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2310
 
  mov   al, #0x11
2311
 
  out   dx, al
2312
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2313
 
  in    al, dx
2314
 
  seg   es
2315
 
  mov   [bx], al
2316
 
  mov   dx, # VGAREG_ACTL_RESET
2317
 
  in    al, dx
2318
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2319
 
  mov   al, #0x20
2320
 
  out   dx, al
2321
 
  pop   dx
2322
 
  pop   cx
2323
 
  pop   bx
2324
 
  pop   ax
2325
 
  ret
2326
 
ASM_END
2327
 
 
2328
 
// --------------------------------------------------------------------------------------------
2329
 
ASM_START
2330
 
biosfn_set_single_dac_reg:
2331
 
  push  ax
2332
 
  push  dx
2333
 
  mov   dx, # VGAREG_DAC_WRITE_ADDRESS
2334
 
  mov   al, bl
2335
 
  out   dx, al
2336
 
  mov   dx, # VGAREG_DAC_DATA
2337
 
  pop   ax
2338
 
  push  ax
2339
 
  mov   al, ah
2340
 
  out   dx, al
2341
 
  mov   al, ch
2342
 
  out   dx, al
2343
 
  mov   al, cl
2344
 
  out   dx, al
2345
 
  pop   dx
2346
 
  pop   ax
2347
 
  ret
2348
 
ASM_END
2349
 
 
2350
 
// --------------------------------------------------------------------------------------------
2351
 
ASM_START
2352
 
biosfn_set_all_dac_reg:
2353
 
  push  ax
2354
 
  push  bx
2355
 
  push  cx
2356
 
  push  dx
2357
 
  mov   dx, # VGAREG_DAC_WRITE_ADDRESS
2358
 
  mov   al, bl
2359
 
  out   dx, al
2360
 
  pop   dx
2361
 
  push  dx
2362
 
  mov   bx, dx
2363
 
  mov   dx, # VGAREG_DAC_DATA
2364
 
set_dac_loop:
2365
 
  seg   es
2366
 
  mov   al, [bx]
2367
 
  out   dx, al
2368
 
  inc   bx
2369
 
  seg   es
2370
 
  mov   al, [bx]
2371
 
  out   dx, al
2372
 
  inc   bx
2373
 
  seg   es
2374
 
  mov   al, [bx]
2375
 
  out   dx, al
2376
 
  inc   bx
2377
 
  dec   cx
2378
 
  jnz   set_dac_loop
2379
 
  pop   dx
2380
 
  pop   cx
2381
 
  pop   bx
2382
 
  pop   ax
2383
 
  ret
2384
 
ASM_END
2385
 
 
2386
 
// --------------------------------------------------------------------------------------------
2387
 
ASM_START
2388
 
biosfn_select_video_dac_color_page:
2389
 
  push  ax
2390
 
  push  bx
2391
 
  push  dx
2392
 
  mov   dx, # VGAREG_ACTL_RESET
2393
 
  in    al, dx
2394
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2395
 
  mov   al, #0x10
2396
 
  out   dx, al
2397
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2398
 
  in    al, dx
2399
 
  and   bl, #0x01
2400
 
  jnz   set_dac_page
2401
 
  and   al, #0x7f
2402
 
  shl   bh, 7
2403
 
  or    al, bh
2404
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2405
 
  out   dx, al
2406
 
  jmp   set_actl_normal
2407
 
set_dac_page:
2408
 
  push  ax
2409
 
  mov   dx, # VGAREG_ACTL_RESET
2410
 
  in    al, dx
2411
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2412
 
  mov   al, #0x14
2413
 
  out   dx, al
2414
 
  pop   ax
2415
 
  and   al, #0x80
2416
 
  jnz   set_dac_16_page
2417
 
  shl   bh, 2
2418
 
set_dac_16_page:
2419
 
  and   bh, #0x0f
2420
 
  mov   al, bh
2421
 
  out   dx, al
2422
 
set_actl_normal:
2423
 
  mov   al, #0x20
2424
 
  out   dx, al
2425
 
  pop   dx
2426
 
  pop   bx
2427
 
  pop   ax
2428
 
  ret
2429
 
ASM_END
2430
 
 
2431
 
// --------------------------------------------------------------------------------------------
2432
 
ASM_START
2433
 
biosfn_read_single_dac_reg:
2434
 
  push  ax
2435
 
  push  dx
2436
 
  mov   dx, # VGAREG_DAC_READ_ADDRESS
2437
 
  mov   al, bl
2438
 
  out   dx, al
2439
 
  pop   ax
2440
 
  mov   ah, al
2441
 
  mov   dx, # VGAREG_DAC_DATA
2442
 
  in    al, dx
2443
 
  xchg  al, ah
2444
 
  push  ax
2445
 
  in    al, dx
2446
 
  mov   ch, al
2447
 
  in    al, dx
2448
 
  mov   cl, al
2449
 
  pop   dx
2450
 
  pop   ax
2451
 
  ret
2452
 
ASM_END
2453
 
 
2454
 
// --------------------------------------------------------------------------------------------
2455
 
ASM_START
2456
 
biosfn_read_all_dac_reg:
2457
 
  push  ax
2458
 
  push  bx
2459
 
  push  cx
2460
 
  push  dx
2461
 
  mov   dx, # VGAREG_DAC_READ_ADDRESS
2462
 
  mov   al, bl
2463
 
  out   dx, al
2464
 
  pop   dx
2465
 
  push  dx
2466
 
  mov   bx, dx
2467
 
  mov   dx, # VGAREG_DAC_DATA
2468
 
read_dac_loop:
2469
 
  in    al, dx
2470
 
  seg   es
2471
 
  mov   [bx], al
2472
 
  inc   bx
2473
 
  in    al, dx
2474
 
  seg   es
2475
 
  mov   [bx], al
2476
 
  inc   bx
2477
 
  in    al, dx
2478
 
  seg   es
2479
 
  mov   [bx], al
2480
 
  inc   bx
2481
 
  dec   cx
2482
 
  jnz   read_dac_loop
2483
 
  pop   dx
2484
 
  pop   cx
2485
 
  pop   bx
2486
 
  pop   ax
2487
 
  ret
2488
 
ASM_END
2489
 
 
2490
 
// --------------------------------------------------------------------------------------------
2491
 
ASM_START
2492
 
biosfn_set_pel_mask:
2493
 
  push  ax
2494
 
  push  dx
2495
 
  mov   dx, # VGAREG_PEL_MASK
2496
 
  mov   al, bl
2497
 
  out   dx, al
2498
 
  pop   dx
2499
 
  pop   ax
2500
 
  ret
2501
 
ASM_END
2502
 
 
2503
 
// --------------------------------------------------------------------------------------------
2504
 
ASM_START
2505
 
biosfn_read_pel_mask:
2506
 
  push  ax
2507
 
  push  dx
2508
 
  mov   dx, # VGAREG_PEL_MASK
2509
 
  in    al, dx
2510
 
  mov   bl, al
2511
 
  pop   dx
2512
 
  pop   ax
2513
 
  ret
2514
 
ASM_END
2515
 
 
2516
 
// --------------------------------------------------------------------------------------------
2517
 
ASM_START
2518
 
biosfn_read_video_dac_state:
2519
 
  push  ax
2520
 
  push  dx
2521
 
  mov   dx, # VGAREG_ACTL_RESET
2522
 
  in    al, dx
2523
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2524
 
  mov   al, #0x10
2525
 
  out   dx, al
2526
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2527
 
  in    al, dx
2528
 
  mov   bl, al
2529
 
  shr   bl, 7
2530
 
  mov   dx, # VGAREG_ACTL_RESET
2531
 
  in    al, dx
2532
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2533
 
  mov   al, #0x14
2534
 
  out   dx, al
2535
 
  mov   dx, # VGAREG_ACTL_READ_DATA
2536
 
  in    al, dx
2537
 
  mov   bh, al
2538
 
  and   bh, #0x0f
2539
 
  test  bl, #0x01
2540
 
  jnz   get_dac_16_page
2541
 
  shr   bh, 2
2542
 
get_dac_16_page:
2543
 
  mov   dx, # VGAREG_ACTL_RESET
2544
 
  in    al, dx
2545
 
  mov   dx, # VGAREG_ACTL_ADDRESS
2546
 
  mov   al, #0x20
2547
 
  out   dx, al
2548
 
  pop   dx
2549
 
  pop   ax
2550
 
  ret
2551
 
ASM_END
2552
 
 
2553
 
// --------------------------------------------------------------------------------------------
2554
 
static void biosfn_perform_gray_scale_summing (start,count) 
2555
 
Bit16u start;Bit16u count;
2556
 
{Bit8u r,g,b;
2557
 
 Bit16u i;
2558
 
 Bit16u index;
2559
 
 
2560
 
 inb(VGAREG_ACTL_RESET);
2561
 
 outb(VGAREG_ACTL_ADDRESS,0x00);
2562
 
 
2563
 
 for( index = 0; index < count; index++ ) 
2564
 
  {
2565
 
   // set read address and switch to read mode
2566
 
   outb(VGAREG_DAC_READ_ADDRESS,start);
2567
 
   // get 6-bit wide RGB data values
2568
 
   r=inb( VGAREG_DAC_DATA );
2569
 
   g=inb( VGAREG_DAC_DATA );
2570
 
   b=inb( VGAREG_DAC_DATA );
2571
 
 
2572
 
   // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
2573
 
   i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8;
2574
 
 
2575
 
   if(i>0x3f)i=0x3f;
2576
 
 
2577
 
   // set write address and switch to write mode
2578
 
   outb(VGAREG_DAC_WRITE_ADDRESS,start);
2579
 
   // write new intensity value
2580
 
   outb( VGAREG_DAC_DATA, i&0xff );
2581
 
   outb( VGAREG_DAC_DATA, i&0xff );
2582
 
   outb( VGAREG_DAC_DATA, i&0xff );
2583
 
   start++;
2584
 
  }  
2585
 
 inb(VGAREG_ACTL_RESET);
2586
 
 outb(VGAREG_ACTL_ADDRESS,0x20);
2587
 
}
2588
 
 
2589
 
// --------------------------------------------------------------------------------------------
2590
 
static void get_font_access()
2591
 
{
2592
 
ASM_START
2593
 
 mov dx, # VGAREG_SEQU_ADDRESS
2594
 
 mov ax, #0x0100
2595
 
 out dx, ax
2596
 
 mov ax, #0x0402
2597
 
 out dx, ax
2598
 
 mov ax, #0x0704
2599
 
 out dx, ax
2600
 
 mov ax, #0x0300
2601
 
 out dx, ax
2602
 
 mov dx, # VGAREG_GRDC_ADDRESS
2603
 
 mov ax, #0x0204
2604
 
 out dx, ax
2605
 
 mov ax, #0x0005
2606
 
 out dx, ax
2607
 
 mov ax, #0x0406
2608
 
 out dx, ax
2609
 
ASM_END
2610
 
}
2611
 
 
2612
 
static void release_font_access()
2613
 
{
2614
 
ASM_START
2615
 
 mov dx, # VGAREG_SEQU_ADDRESS
2616
 
 mov ax, #0x0100
2617
 
 out dx, ax
2618
 
 mov ax, #0x0302
2619
 
 out dx, ax
2620
 
 mov ax, #0x0304
2621
 
 out dx, ax
2622
 
 mov ax, #0x0300
2623
 
 out dx, ax
2624
 
 mov dx, # VGAREG_READ_MISC_OUTPUT
2625
 
 in  al, dx
2626
 
 and al, #0x01
2627
 
 shl al, 2
2628
 
 or  al, #0x0a
2629
 
 mov ah, al
2630
 
 mov al, #0x06
2631
 
 mov dx, # VGAREG_GRDC_ADDRESS
2632
 
 out dx, ax
2633
 
 mov ax, #0x0004
2634
 
 out dx, ax
2635
 
 mov ax, #0x1005
2636
 
 out dx, ax
2637
 
ASM_END
2638
 
}
2639
 
 
2640
 
ASM_START
2641
 
idiv_u:
2642
 
  xor dx,dx
2643
 
  div bx
2644
 
  ret
2645
 
ASM_END
2646
 
 
2647
 
static void set_scan_lines(lines) Bit8u lines;
2648
 
{
2649
 
 Bit16u crtc_addr,cols,page,vde;
2650
 
 Bit8u crtc_r9,ovl,rows;
2651
 
 
2652
 
 crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
2653
 
 outb(crtc_addr, 0x09);
2654
 
 crtc_r9 = inb(crtc_addr+1);
2655
 
 crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
2656
 
 outb(crtc_addr+1, crtc_r9);
2657
 
 if(lines==8)
2658
 
  {
2659
 
   biosfn_set_cursor_shape(0x06,0x07);
2660
 
  }
2661
 
 else
2662
 
  {
2663
 
   biosfn_set_cursor_shape(lines-4,lines-3);
2664
 
  }
2665
 
 write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines);
2666
 
 outb(crtc_addr, 0x12);
2667
 
 vde = inb(crtc_addr+1);
2668
 
 outb(crtc_addr, 0x07);
2669
 
 ovl = inb(crtc_addr+1);
2670
 
 vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
2671
 
 rows = vde / lines;
2672
 
 write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1);
2673
 
 cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
2674
 
 write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2);
2675
 
}
2676
 
 
2677
 
static void biosfn_load_text_user_pat (AL,ES,BP,CX,DX,BL,BH) Bit8u AL;Bit16u ES;Bit16u BP;Bit16u CX;Bit16u DX;Bit8u BL;Bit8u BH;
2678
 
{
2679
 
 Bit16u blockaddr,dest,i,src;
2680
 
 
2681
 
 get_font_access();
2682
 
 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2683
 
 for(i=0;i<CX;i++)
2684
 
  {
2685
 
   src = BP + i * BH;
2686
 
   dest = blockaddr + (DX + i) * 32;
2687
 
   memcpyb(0xA000, dest, ES, src, BH);
2688
 
  }
2689
 
 release_font_access();
2690
 
 if(AL>=0x10)
2691
 
  {
2692
 
   set_scan_lines(BH);
2693
 
  }
2694
 
}
2695
 
 
2696
 
static void biosfn_load_text_8_14_pat (AL,BL) Bit8u AL;Bit8u BL;
2697
 
{
2698
 
 Bit16u blockaddr,dest,i,src;
2699
 
 
2700
 
 get_font_access();
2701
 
 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2702
 
 for(i=0;i<0x100;i++)
2703
 
  {
2704
 
   src = i * 14;
2705
 
   dest = blockaddr + i * 32;
2706
 
   memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14);
2707
 
  }
2708
 
 release_font_access();
2709
 
 if(AL>=0x10)
2710
 
  {
2711
 
   set_scan_lines(14);
2712
 
  }
2713
 
}
2714
 
 
2715
 
static void biosfn_load_text_8_8_pat (AL,BL) Bit8u AL;Bit8u BL;
2716
 
{
2717
 
 Bit16u blockaddr,dest,i,src;
2718
 
 
2719
 
 get_font_access();
2720
 
 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2721
 
 for(i=0;i<0x100;i++)
2722
 
  {
2723
 
   src = i * 8;
2724
 
   dest = blockaddr + i * 32;
2725
 
   memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8);
2726
 
  }
2727
 
 release_font_access();
2728
 
 if(AL>=0x10)
2729
 
  {
2730
 
   set_scan_lines(8);
2731
 
  }
2732
 
}
2733
 
 
2734
 
// --------------------------------------------------------------------------------------------
2735
 
ASM_START
2736
 
biosfn_set_text_block_specifier:
2737
 
  push  ax
2738
 
  push  dx
2739
 
  mov   dx, # VGAREG_SEQU_ADDRESS
2740
 
  mov   ah, bl
2741
 
  mov   al, #0x03
2742
 
  out   dx, ax
2743
 
  pop   dx
2744
 
  pop   ax
2745
 
  ret
2746
 
ASM_END
2747
 
 
2748
 
// --------------------------------------------------------------------------------------------
2749
 
static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL;
2750
 
{
2751
 
 Bit16u blockaddr,dest,i,src;
2752
 
 
2753
 
 get_font_access();
2754
 
 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2755
 
 for(i=0;i<0x100;i++)
2756
 
  {
2757
 
   src = i * 16;
2758
 
   dest = blockaddr + i * 32;
2759
 
   memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16);
2760
 
  }
2761
 
 release_font_access();
2762
 
 if(AL>=0x10)
2763
 
  {
2764
 
   set_scan_lines(16);
2765
 
  }
2766
 
}
2767
 
 
2768
 
static void biosfn_load_gfx_8_8_chars (ES,BP) Bit16u ES;Bit16u BP;
2769
 
{
2770
 
#ifdef DEBUG
2771
 
 unimplemented();
2772
 
#endif
2773
 
}
2774
 
static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL;
2775
 
{
2776
 
#ifdef DEBUG
2777
 
 unimplemented();
2778
 
#endif
2779
 
}
2780
 
static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL;
2781
 
{
2782
 
#ifdef DEBUG
2783
 
 unimplemented();
2784
 
#endif
2785
 
}
2786
 
static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL;
2787
 
{
2788
 
#ifdef DEBUG
2789
 
 unimplemented();
2790
 
#endif
2791
 
}
2792
 
static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL;
2793
 
{
2794
 
#ifdef DEBUG
2795
 
 unimplemented();
2796
 
#endif
2797
 
}
2798
 
// --------------------------------------------------------------------------------------------
2799
 
static void biosfn_get_font_info (BH,ES,BP,CX,DX) 
2800
 
Bit8u BH;Bit16u *ES;Bit16u *BP;Bit16u *CX;Bit16u *DX;
2801
 
{Bit16u ss=get_SS();
2802
 
 
2803
 
 switch(BH)
2804
 
  {case 0x00:
2805
 
    write_word(ss,ES,read_word(0x00,0x1f*4));
2806
 
    write_word(ss,BP,read_word(0x00,(0x1f*4)+2));
2807
 
    break;
2808
 
   case 0x01:
2809
 
    write_word(ss,ES,read_word(0x00,0x43*4));
2810
 
    write_word(ss,BP,read_word(0x00,(0x43*4)+2));
2811
 
    break;
2812
 
   case 0x02:
2813
 
    write_word(ss,ES,0xC000);
2814
 
    write_word(ss,BP,vgafont14);
2815
 
    break;
2816
 
   case 0x03:
2817
 
    write_word(ss,ES,0xC000);
2818
 
    write_word(ss,BP,vgafont8);
2819
 
    break;
2820
 
   case 0x04:
2821
 
    write_word(ss,ES,0xC000);
2822
 
    write_word(ss,BP,vgafont8+128*8);
2823
 
    break;
2824
 
   case 0x05:
2825
 
    write_word(ss,ES,0xC000);
2826
 
    write_word(ss,BP,vgafont14alt);
2827
 
    break;
2828
 
   case 0x06:
2829
 
    write_word(ss,ES,0xC000);
2830
 
    write_word(ss,BP,vgafont16);
2831
 
    break;
2832
 
   case 0x07:
2833
 
    write_word(ss,ES,0xC000);
2834
 
    write_word(ss,BP,vgafont16alt);
2835
 
    break;
2836
 
   default:
2837
 
    #ifdef DEBUG
2838
 
     printf("Get font info BH(%02x) was discarded\n",BH);
2839
 
    #endif
2840
 
    return;
2841
 
  }
2842
 
 // Set byte/char of on screen font
2843
 
 write_word(ss,CX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT));
2844
 
 
2845
 
 // Set Highest char row
2846
 
 write_word(ss,DX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS));
2847
 
}
2848
 
 
2849
 
// --------------------------------------------------------------------------------------------
2850
 
ASM_START
2851
 
biosfn_get_ega_info:
2852
 
  push  ds
2853
 
  push  ax
2854
 
  mov   ax, # BIOSMEM_SEG
2855
 
  mov   ds, ax
2856
 
  xor   ch, ch
2857
 
  mov   bx, # BIOSMEM_SWITCHES
2858
 
  mov   cl, [bx]
2859
 
  and   cl, #0x0f
2860
 
  mov   bx, # BIOSMEM_CRTC_ADDRESS
2861
 
  mov   ax, [bx]
2862
 
  mov   bx, #0x0003
2863
 
  cmp   ax, # VGAREG_MDA_CRTC_ADDRESS
2864
 
  jne   mode_ega_color
2865
 
  mov   bh, #0x01
2866
 
mode_ega_color:
2867
 
  pop   ax
2868
 
  pop   ds
2869
 
  ret
2870
 
ASM_END
2871
 
 
2872
 
// --------------------------------------------------------------------------------------------
2873
 
static void biosfn_alternate_prtsc()
2874
 
{
2875
 
#ifdef DEBUG
2876
 
 unimplemented();
2877
 
#endif
2878
 
}
2879
 
 
2880
 
// --------------------------------------------------------------------------------------------
2881
 
ASM_START
2882
 
biosfn_select_vert_res:
2883
 
 
2884
 
; res : 00 200 lines, 01 350 lines, 02 400 lines
2885
 
 
2886
 
  push  ds
2887
 
  push  bx
2888
 
  push  dx
2889
 
  mov   dl, al
2890
 
  mov   ax, # BIOSMEM_SEG
2891
 
  mov   ds, ax
2892
 
  mov   bx, # BIOSMEM_MODESET_CTL
2893
 
  mov   al, [bx]
2894
 
  mov   bx, # BIOSMEM_SWITCHES
2895
 
  mov   ah, [bx]
2896
 
  cmp   dl, #0x01
2897
 
  je    vert_res_350
2898
 
  jb    vert_res_200
2899
 
  cmp   dl, #0x02
2900
 
  je    vert_res_400
2901
 
#ifdef DEBUG
2902
 
  mov   al, dl
2903
 
  xor   ah, ah
2904
 
  push  ax
2905
 
  mov   bx, #msg_vert_res
2906
 
  push  bx
2907
 
  call  _printf
2908
 
  add   sp, #4
2909
 
#endif
2910
 
  jmp   set_retcode
2911
 
vert_res_400:
2912
 
 
2913
 
  ; reset modeset ctl bit 7 and set bit 4
2914
 
  ; set switches bit 3-0 to 0x09
2915
 
 
2916
 
  and   al, #0x7f
2917
 
  or    al, #0x10
2918
 
  and   ah, #0xf0
2919
 
  or    ah, #0x09
2920
 
  jnz   set_vert_res
2921
 
vert_res_350:
2922
 
 
2923
 
  ; reset modeset ctl bit 7 and bit 4
2924
 
  ; set switches bit 3-0 to 0x09
2925
 
 
2926
 
  and   al, #0x6f
2927
 
  and   ah, #0xf0
2928
 
  or    ah, #0x09
2929
 
  jnz   set_vert_res
2930
 
vert_res_200:
2931
 
 
2932
 
  ; set modeset ctl bit 7 and reset bit 4
2933
 
  ; set switches bit 3-0 to 0x08
2934
 
 
2935
 
  and   al, #0xef
2936
 
  or    al, #0x80
2937
 
  and   ah, #0xf0
2938
 
  or    ah, #0x08
2939
 
set_vert_res:
2940
 
  mov   bx, # BIOSMEM_MODESET_CTL
2941
 
  mov   [bx], al
2942
 
  mov   bx, # BIOSMEM_SWITCHES
2943
 
  mov   [bx], ah
2944
 
set_retcode:
2945
 
  mov   ax, #0x1212
2946
 
  pop   dx
2947
 
  pop   bx
2948
 
  pop   ds
2949
 
  ret
2950
 
 
2951
 
#ifdef DEBUG
2952
 
msg_vert_res:
2953
 
.ascii "Select vert res (%02x) was discarded"
2954
 
.byte 0x0d,0x0a,0x00
2955
 
#endif
2956
 
 
2957
 
 
2958
 
biosfn_enable_default_palette_loading:
2959
 
  push  ds
2960
 
  push  bx
2961
 
  push  dx
2962
 
  mov   dl, al
2963
 
  and   dl, #0x01
2964
 
  shl   dl, 3
2965
 
  mov   ax, # BIOSMEM_SEG
2966
 
  mov   ds, ax
2967
 
  mov   bx, # BIOSMEM_MODESET_CTL
2968
 
  mov   al, [bx]
2969
 
  and   al, #0xf7
2970
 
  or    al, dl
2971
 
  mov   [bx], al
2972
 
  mov   ax, #0x1212
2973
 
  pop   dx
2974
 
  pop   bx
2975
 
  pop   ds
2976
 
  ret
2977
 
 
2978
 
 
2979
 
biosfn_enable_video_addressing:
2980
 
  push  bx
2981
 
  push  dx
2982
 
  mov   bl, al
2983
 
  and   bl, #0x01
2984
 
  xor   bl, #0x01
2985
 
  shl   bl, 1
2986
 
  mov   dx, # VGAREG_READ_MISC_OUTPUT
2987
 
  in    al, dx
2988
 
  and   al, #0xfd
2989
 
  or    al, bl
2990
 
  mov   dx, # VGAREG_WRITE_MISC_OUTPUT
2991
 
  out   dx, al
2992
 
  mov   ax, #0x1212
2993
 
  pop   dx
2994
 
  pop   bx
2995
 
  ret
2996
 
 
2997
 
 
2998
 
biosfn_enable_grayscale_summing:
2999
 
  push  ds
3000
 
  push  bx
3001
 
  push  dx
3002
 
  mov   dl, al
3003
 
  and   dl, #0x01
3004
 
  xor   dl, #0x01
3005
 
  shl   dl, 1
3006
 
  mov   ax, # BIOSMEM_SEG
3007
 
  mov   ds, ax
3008
 
  mov   bx, # BIOSMEM_MODESET_CTL
3009
 
  mov   al, [bx]
3010
 
  and   al, #0xfd
3011
 
  or    al, dl
3012
 
  mov   [bx], al
3013
 
  mov   ax, #0x1212
3014
 
  pop   dx
3015
 
  pop   bx
3016
 
  pop   ds
3017
 
  ret
3018
 
 
3019
 
 
3020
 
biosfn_enable_cursor_emulation:
3021
 
  push  ds
3022
 
  push  bx
3023
 
  push  dx
3024
 
  mov   dl, al
3025
 
  and   dl, #0x01
3026
 
  xor   dl, #0x01
3027
 
  mov   ax, # BIOSMEM_SEG
3028
 
  mov   ds, ax
3029
 
  mov   bx, # BIOSMEM_MODESET_CTL
3030
 
  mov   al, [bx]
3031
 
  and   al, #0xfe
3032
 
  or    al, dl
3033
 
  mov   [bx], al
3034
 
  mov   ax, #0x1212
3035
 
  pop   dx
3036
 
  pop   bx
3037
 
  pop   ds
3038
 
  ret
3039
 
ASM_END
3040
 
 
3041
 
// --------------------------------------------------------------------------------------------
3042
 
static void biosfn_switch_video_interface (AL,ES,DX) Bit8u AL;Bit16u ES;Bit16u DX;
3043
 
{
3044
 
#ifdef DEBUG
3045
 
 unimplemented();
3046
 
#endif
3047
 
}
3048
 
static void biosfn_enable_video_refresh_control (AL) Bit8u AL;
3049
 
{
3050
 
#ifdef DEBUG
3051
 
 unimplemented();
3052
 
#endif
3053
 
}
3054
 
 
3055
 
// --------------------------------------------------------------------------------------------
3056
 
static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset) 
3057
 
Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset;
3058
 
{
3059
 
 Bit16u newcurs,oldcurs,dummy;
3060
 
 Bit8u car,carattr;
3061
 
 
3062
 
 // Read curs info for the page
3063
 
 biosfn_get_cursor_pos(page,&dummy,&oldcurs);
3064
 
 
3065
 
 // if row=0xff special case : use current cursor position
3066
 
 if(row==0xff)
3067
 
  {col=oldcurs&0x00ff;
3068
 
   row=(oldcurs&0xff00)>>8;
3069
 
  }
3070
 
 
3071
 
 newcurs=row; newcurs<<=8; newcurs+=col;
3072
 
 biosfn_set_cursor_pos(page,newcurs);
3073
 
 
3074
 
 while(count--!=0)
3075
 
  {
3076
 
   car=read_byte(seg,offset++);
3077
 
   if((flag&0x02)!=0)
3078
 
    attr=read_byte(seg,offset++);
3079
 
 
3080
 
   biosfn_write_teletype(car,page,attr,WITH_ATTR);
3081
 
  }
3082
 
 
3083
 
 // Set back curs pos 
3084
 
 if((flag&0x01)==0)
3085
 
  biosfn_set_cursor_pos(page,oldcurs);
3086
 
}
3087
 
 
3088
 
// --------------------------------------------------------------------------------------------
3089
 
ASM_START
3090
 
biosfn_group_1A:
3091
 
  cmp   al, #0x00
3092
 
  je    biosfn_read_display_code
3093
 
  cmp   al, #0x01
3094
 
  je    biosfn_set_display_code
3095
 
#ifdef DEBUG
3096
 
  call  _unknown
3097
 
#endif
3098
 
  ret
3099
 
biosfn_read_display_code:
3100
 
  push  ds
3101
 
  push  ax
3102
 
  mov   ax, # BIOSMEM_SEG
3103
 
  mov   ds, ax
3104
 
  mov   bx, # BIOSMEM_DCC_INDEX
3105
 
  mov   al, [bx]
3106
 
  mov   bl, al
3107
 
  xor   bh, bh
3108
 
  pop   ax
3109
 
  mov   al, ah
3110
 
  pop   ds
3111
 
  ret
3112
 
biosfn_set_display_code:
3113
 
  push  ds
3114
 
  push  ax
3115
 
  push  bx
3116
 
  mov   ax, # BIOSMEM_SEG
3117
 
  mov   ds, ax
3118
 
  mov   ax, bx
3119
 
  mov   bx, # BIOSMEM_DCC_INDEX
3120
 
  mov   [bx], al
3121
 
#ifdef DEBUG
3122
 
  mov   al, ah
3123
 
  xor   ah, ah
3124
 
  push  ax
3125
 
  mov   bx, #msg_alt_dcc
3126
 
  push  bx
3127
 
  call  _printf
3128
 
  add   sp, #4
3129
 
#endif
3130
 
  pop   bx
3131
 
  pop   ax
3132
 
  mov   al, ah
3133
 
  pop   ds
3134
 
  ret
3135
 
 
3136
 
#ifdef DEBUG
3137
 
msg_alt_dcc:
3138
 
.ascii "Alternate Display code (%02x) was discarded"
3139
 
.byte 0x0d,0x0a,0x00
3140
 
#endif
3141
 
ASM_END
3142
 
 
3143
 
// --------------------------------------------------------------------------------------------
3144
 
static void biosfn_read_state_info (BX,ES,DI) 
3145
 
Bit16u BX;Bit16u ES;Bit16u DI;
3146
 
{
3147
 
 // Address of static functionality table
3148
 
 write_word(ES,DI+0x00,&static_functionality);
3149
 
 write_word(ES,DI+0x02,0xC000);
3150
 
 
3151
 
 // Hard coded copy from BIOS area. Should it be cleaner ?
3152
 
 memcpyb(ES,DI+0x04,BIOSMEM_SEG,0x49,30);
3153
 
 memcpyb(ES,DI+0x22,BIOSMEM_SEG,0x84,3);
3154
 
 
3155
 
 write_byte(ES,DI+0x25,read_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX));
3156
 
 write_byte(ES,DI+0x26,0);
3157
 
 write_byte(ES,DI+0x27,16);
3158
 
 write_byte(ES,DI+0x28,0);
3159
 
 write_byte(ES,DI+0x29,8);
3160
 
 write_byte(ES,DI+0x2a,2);
3161
 
 write_byte(ES,DI+0x2b,0);
3162
 
 write_byte(ES,DI+0x2c,0);
3163
 
 write_byte(ES,DI+0x31,3);
3164
 
 write_byte(ES,DI+0x32,0);
3165
 
 
3166
 
 memsetb(ES,DI+0x33,0,13);
3167
 
}
3168
 
 
3169
 
// --------------------------------------------------------------------------------------------
3170
 
// --------------------------------------------------------------------------------------------
3171
 
static Bit16u biosfn_read_video_state_size2 (CX) 
3172
 
     Bit16u CX;
3173
 
{
3174
 
    Bit16u size;
3175
 
    size = 0;
3176
 
    if (CX & 1) {
3177
 
        size += 0x46;
3178
 
    }
3179
 
    if (CX & 2) {
3180
 
        size += (5 + 8 + 5) * 2 + 6;
3181
 
    }
3182
 
    if (CX & 4) {
3183
 
        size += 3 + 256 * 3 + 1;
3184
 
}
3185
 
    return size;
3186
 
}
3187
 
 
3188
 
static void biosfn_read_video_state_size (CX, BX) 
3189
 
     Bit16u CX; Bit16u *BX;
3190
 
{
3191
 
    Bit16u ss=get_SS();
3192
 
    write_word(ss, BX, biosfn_read_video_state_size2(CX));
3193
 
}
3194
 
 
3195
 
static Bit16u biosfn_save_video_state (CX,ES,BX) 
3196
 
     Bit16u CX;Bit16u ES;Bit16u BX;
3197
 
{
3198
 
    Bit16u i, v, crtc_addr, ar_index;
3199
 
 
3200
 
    crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS);
3201
 
    if (CX & 1) {
3202
 
        write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++;
3203
 
        write_byte(ES, BX, inb(crtc_addr)); BX++;
3204
 
        write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++;
3205
 
        inb(VGAREG_ACTL_RESET);
3206
 
        ar_index = inb(VGAREG_ACTL_ADDRESS);
3207
 
        write_byte(ES, BX, ar_index); BX++;
3208
 
        write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++;
3209
 
 
3210
 
        for(i=1;i<=4;i++){
3211
 
            outb(VGAREG_SEQU_ADDRESS, i);
3212
 
            write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++;
3213
 
        }
3214
 
        outb(VGAREG_SEQU_ADDRESS, 0);
3215
 
        write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++;
3216
 
 
3217
 
        for(i=0;i<=0x18;i++) {
3218
 
            outb(crtc_addr,i);
3219
 
            write_byte(ES, BX, inb(crtc_addr+1)); BX++;
3220
 
        }
3221
 
 
3222
 
        for(i=0;i<=0x13;i++) {
3223
 
            inb(VGAREG_ACTL_RESET);
3224
 
            outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
3225
 
            write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++;
3226
 
        }
3227
 
        inb(VGAREG_ACTL_RESET);
3228
 
 
3229
 
        for(i=0;i<=8;i++) {
3230
 
            outb(VGAREG_GRDC_ADDRESS,i);
3231
 
            write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++;
3232
 
        }
3233
 
 
3234
 
        write_word(ES, BX, crtc_addr); BX+= 2;
3235
 
 
3236
 
        /* XXX: read plane latches */
3237
 
        write_byte(ES, BX, 0); BX++;
3238
 
        write_byte(ES, BX, 0); BX++;
3239
 
        write_byte(ES, BX, 0); BX++;
3240
 
        write_byte(ES, BX, 0); BX++;
3241
 
    }
3242
 
    if (CX & 2) {
3243
 
        write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++;
3244
 
        write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2;
3245
 
        write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2;
3246
 
        write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2;
3247
 
        write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++;
3248
 
        write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2;
3249
 
        write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++;
3250
 
        write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++;
3251
 
        write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++;
3252
 
        write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2;
3253
 
        for(i=0;i<8;i++) {
3254
 
            write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i));
3255
 
            BX += 2;
3256
 
        }
3257
 
        write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2;
3258
 
        write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++;
3259
 
        /* current font */
3260
 
        write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2;
3261
 
        write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2;
3262
 
        write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2;
3263
 
        write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2;
3264
 
    }
3265
 
    if (CX & 4) {
3266
 
        /* XXX: check this */
3267
 
        write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */
3268
 
        write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */
3269
 
        write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++;
3270
 
        // Set the whole dac always, from 0
3271
 
        outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
3272
 
        for(i=0;i<256*3;i++) {
3273
 
            write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++;
3274
 
        }
3275
 
        write_byte(ES, BX, 0); BX++; /* color select register */
3276
 
    }
3277
 
    return BX;
3278
 
}
3279
 
 
3280
 
static Bit16u biosfn_restore_video_state (CX,ES,BX) 
3281
 
     Bit16u CX;Bit16u ES;Bit16u BX;
3282
 
{
3283
 
    Bit16u i, crtc_addr, v, addr1, ar_index;
3284
 
 
3285
 
    if (CX & 1) {
3286
 
        // Reset Attribute Ctl flip-flop
3287
 
        inb(VGAREG_ACTL_RESET);
3288
 
 
3289
 
        crtc_addr = read_word(ES, BX + 0x40);
3290
 
        addr1 = BX;
3291
 
        BX += 5;
3292
 
        
3293
 
        for(i=1;i<=4;i++){
3294
 
            outb(VGAREG_SEQU_ADDRESS, i);
3295
 
            outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
3296
 
        }
3297
 
        outb(VGAREG_SEQU_ADDRESS, 0);
3298
 
        outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
3299
 
 
3300
 
        // Disable CRTC write protection
3301
 
        outw(crtc_addr,0x0011);
3302
 
        // Set CRTC regs
3303
 
        for(i=0;i<=0x18;i++) {
3304
 
            if (i != 0x11) {
3305
 
                outb(crtc_addr,i);
3306
 
                outb(crtc_addr+1, read_byte(ES, BX));
3307
 
            }
3308
 
            BX++;
3309
 
        }
3310
 
        // select crtc base address
3311
 
        v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
3312
 
        if (crtc_addr = 0x3d4)
3313
 
            v |= 0x01;
3314
 
        outb(VGAREG_WRITE_MISC_OUTPUT, v);
3315
 
 
3316
 
        // enable write protection if needed
3317
 
        outb(crtc_addr, 0x11);
3318
 
        outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11));
3319
 
        
3320
 
        // Set Attribute Ctl
3321
 
        ar_index = read_byte(ES, addr1 + 0x03);
3322
 
        inb(VGAREG_ACTL_RESET);
3323
 
        for(i=0;i<=0x13;i++) {
3324
 
            outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
3325
 
            outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++;
3326
 
        }
3327
 
        outb(VGAREG_ACTL_ADDRESS, ar_index);
3328
 
        inb(VGAREG_ACTL_RESET);
3329
 
        
3330
 
        for(i=0;i<=8;i++) {
3331
 
            outb(VGAREG_GRDC_ADDRESS,i);
3332
 
            outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++;
3333
 
        }
3334
 
        BX += 2; /* crtc_addr */
3335
 
        BX += 4; /* plane latches */
3336
 
        
3337
 
        outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++;
3338
 
        outb(crtc_addr, read_byte(ES, addr1)); addr1++;
3339
 
        outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++;
3340
 
        addr1++;
3341
 
        outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++;
3342
 
    }
3343
 
    if (CX & 2) {
3344
 
        write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++;
3345
 
        write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2;
3346
 
        write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2;
3347
 
        write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2;
3348
 
        write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++;
3349
 
        write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2;
3350
 
        write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++;
3351
 
        write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++;
3352
 
        write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++;
3353
 
        write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2;
3354
 
        for(i=0;i<8;i++) {
3355
 
            write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX));
3356
 
            BX += 2;
3357
 
        }
3358
 
        write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2;
3359
 
        write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++;
3360
 
        /* current font */
3361
 
        write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2;
3362
 
        write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2;
3363
 
        write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2;
3364
 
        write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2;
3365
 
    }
3366
 
    if (CX & 4) {
3367
 
        BX++;
3368
 
        v = read_byte(ES, BX); BX++;
3369
 
        outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++;
3370
 
        // Set the whole dac always, from 0
3371
 
        outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
3372
 
        for(i=0;i<256*3;i++) {
3373
 
            outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++;
3374
 
        }
3375
 
        BX++;
3376
 
        outb(VGAREG_DAC_WRITE_ADDRESS, v);
3377
 
    }
3378
 
    return BX;
3379
 
}
3380
 
 
3381
 
// ============================================================================================
3382
 
//
3383
 
// Video Utils
3384
 
//
3385
 
// ============================================================================================
3386
 
 
3387
 
// --------------------------------------------------------------------------------------------
3388
 
static Bit8u find_vga_entry(mode) 
3389
 
Bit8u mode;
3390
 
{
3391
 
 Bit8u i,line=0xFF;
3392
 
 for(i=0;i<=MODE_MAX;i++)
3393
 
  if(vga_modes[i].svgamode==mode)
3394
 
   {line=i;
3395
 
    break;
3396
 
   }
3397
 
 return line;
3398
 
}
3399
 
 
3400
 
/* =========================================================== */
3401
 
/*
3402
 
 * Misc Utils
3403
 
*/
3404
 
/* =========================================================== */
3405
 
 
3406
 
// --------------------------------------------------------------------------------------------
3407
 
static void memsetb(seg,offset,value,count)
3408
 
  Bit16u seg;
3409
 
  Bit16u offset;
3410
 
  Bit16u value;
3411
 
  Bit16u count;
3412
 
{
3413
 
ASM_START
3414
 
  push bp
3415
 
  mov  bp, sp
3416
 
 
3417
 
    push ax
3418
 
    push cx
3419
 
    push es
3420
 
    push di
3421
 
 
3422
 
    mov  cx, 10[bp] ; count
3423
 
    cmp  cx, #0x00
3424
 
    je   memsetb_end
3425
 
    mov  ax, 4[bp] ; segment
3426
 
    mov  es, ax
3427
 
    mov  ax, 6[bp] ; offset
3428
 
    mov  di, ax
3429
 
    mov  al, 8[bp] ; value
3430
 
    cld
3431
 
    rep
3432
 
     stosb
3433
 
 
3434
 
memsetb_end:
3435
 
    pop di
3436
 
    pop es
3437
 
    pop cx
3438
 
    pop ax
3439
 
 
3440
 
  pop bp
3441
 
ASM_END
3442
 
}
3443
 
 
3444
 
// --------------------------------------------------------------------------------------------
3445
 
static void memsetw(seg,offset,value,count)
3446
 
  Bit16u seg;
3447
 
  Bit16u offset;
3448
 
  Bit16u value;
3449
 
  Bit16u count;
3450
 
{
3451
 
ASM_START
3452
 
  push bp
3453
 
  mov  bp, sp
3454
 
 
3455
 
    push ax
3456
 
    push cx
3457
 
    push es
3458
 
    push di
3459
 
 
3460
 
    mov  cx, 10[bp] ; count
3461
 
    cmp  cx, #0x00
3462
 
    je   memsetw_end
3463
 
    mov  ax, 4[bp] ; segment
3464
 
    mov  es, ax
3465
 
    mov  ax, 6[bp] ; offset
3466
 
    mov  di, ax
3467
 
    mov  ax, 8[bp] ; value
3468
 
    cld
3469
 
    rep
3470
 
     stosw
3471
 
 
3472
 
memsetw_end:
3473
 
    pop di
3474
 
    pop es
3475
 
    pop cx
3476
 
    pop ax
3477
 
 
3478
 
  pop bp
3479
 
ASM_END
3480
 
}
3481
 
 
3482
 
// --------------------------------------------------------------------------------------------
3483
 
static void memcpyb(dseg,doffset,sseg,soffset,count)
3484
 
  Bit16u dseg;
3485
 
  Bit16u doffset;
3486
 
  Bit16u sseg;
3487
 
  Bit16u soffset;
3488
 
  Bit16u count;
3489
 
{
3490
 
ASM_START
3491
 
  push bp
3492
 
  mov  bp, sp
3493
 
 
3494
 
    push ax
3495
 
    push cx
3496
 
    push es
3497
 
    push di
3498
 
    push ds
3499
 
    push si
3500
 
 
3501
 
    mov  cx, 12[bp] ; count
3502
 
    cmp  cx, #0x0000
3503
 
    je   memcpyb_end
3504
 
    mov  ax, 4[bp] ; dsegment
3505
 
    mov  es, ax
3506
 
    mov  ax, 6[bp] ; doffset
3507
 
    mov  di, ax
3508
 
    mov  ax, 8[bp] ; ssegment
3509
 
    mov  ds, ax
3510
 
    mov  ax, 10[bp] ; soffset
3511
 
    mov  si, ax
3512
 
    cld
3513
 
    rep
3514
 
     movsb
3515
 
 
3516
 
memcpyb_end:
3517
 
    pop si
3518
 
    pop ds
3519
 
    pop di
3520
 
    pop es
3521
 
    pop cx
3522
 
    pop ax
3523
 
 
3524
 
  pop bp
3525
 
ASM_END
3526
 
}
3527
 
 
3528
 
// --------------------------------------------------------------------------------------------
3529
 
static void memcpyw(dseg,doffset,sseg,soffset,count)
3530
 
  Bit16u dseg;
3531
 
  Bit16u doffset;
3532
 
  Bit16u sseg;
3533
 
  Bit16u soffset;
3534
 
  Bit16u count;
3535
 
{
3536
 
ASM_START
3537
 
  push bp
3538
 
  mov  bp, sp
3539
 
 
3540
 
    push ax
3541
 
    push cx
3542
 
    push es
3543
 
    push di
3544
 
    push ds
3545
 
    push si
3546
 
 
3547
 
    mov  cx, 12[bp] ; count
3548
 
    cmp  cx, #0x0000
3549
 
    je   memcpyw_end
3550
 
    mov  ax, 4[bp] ; dsegment
3551
 
    mov  es, ax
3552
 
    mov  ax, 6[bp] ; doffset
3553
 
    mov  di, ax
3554
 
    mov  ax, 8[bp] ; ssegment
3555
 
    mov  ds, ax
3556
 
    mov  ax, 10[bp] ; soffset
3557
 
    mov  si, ax
3558
 
    cld
3559
 
    rep
3560
 
     movsw
3561
 
 
3562
 
memcpyw_end:
3563
 
    pop si
3564
 
    pop ds
3565
 
    pop di
3566
 
    pop es
3567
 
    pop cx
3568
 
    pop ax
3569
 
 
3570
 
  pop bp
3571
 
ASM_END
3572
 
}
3573
 
 
3574
 
/* =========================================================== */
3575
 
/*
3576
 
 * These functions where ripped from Kevin's rombios.c
3577
 
*/
3578
 
/* =========================================================== */
3579
 
 
3580
 
// --------------------------------------------------------------------------------------------
3581
 
static Bit8u
3582
 
read_byte(seg, offset)
3583
 
  Bit16u seg;
3584
 
  Bit16u offset;
3585
 
{
3586
 
ASM_START
3587
 
  push bp
3588
 
  mov  bp, sp
3589
 
 
3590
 
    push bx
3591
 
    push ds
3592
 
    mov  ax, 4[bp] ; segment
3593
 
    mov  ds, ax
3594
 
    mov  bx, 6[bp] ; offset
3595
 
    mov  al, [bx]
3596
 
    ;; al = return value (byte)
3597
 
    pop  ds
3598
 
    pop  bx
3599
 
 
3600
 
  pop  bp
3601
 
ASM_END
3602
 
}
3603
 
 
3604
 
// --------------------------------------------------------------------------------------------
3605
 
static Bit16u
3606
 
read_word(seg, offset)
3607
 
  Bit16u seg;
3608
 
  Bit16u offset;
3609
 
{
3610
 
ASM_START
3611
 
  push bp
3612
 
  mov  bp, sp
3613
 
 
3614
 
    push bx
3615
 
    push ds
3616
 
    mov  ax, 4[bp] ; segment
3617
 
    mov  ds, ax
3618
 
    mov  bx, 6[bp] ; offset
3619
 
    mov  ax, [bx]
3620
 
    ;; ax = return value (word)
3621
 
    pop  ds
3622
 
    pop  bx
3623
 
 
3624
 
  pop  bp
3625
 
ASM_END
3626
 
}
3627
 
 
3628
 
// --------------------------------------------------------------------------------------------
3629
 
static void
3630
 
write_byte(seg, offset, data)
3631
 
  Bit16u seg;
3632
 
  Bit16u offset;
3633
 
  Bit8u  data;
3634
 
{
3635
 
ASM_START
3636
 
  push bp
3637
 
  mov  bp, sp
3638
 
 
3639
 
    push ax
3640
 
    push bx
3641
 
    push ds
3642
 
    mov  ax, 4[bp] ; segment
3643
 
    mov  ds, ax
3644
 
    mov  bx, 6[bp] ; offset
3645
 
    mov  al, 8[bp] ; data byte
3646
 
    mov  [bx], al  ; write data byte
3647
 
    pop  ds
3648
 
    pop  bx
3649
 
    pop  ax
3650
 
 
3651
 
  pop  bp
3652
 
ASM_END
3653
 
}
3654
 
 
3655
 
// --------------------------------------------------------------------------------------------
3656
 
static void
3657
 
write_word(seg, offset, data)
3658
 
  Bit16u seg;
3659
 
  Bit16u offset;
3660
 
  Bit16u data;
3661
 
{
3662
 
ASM_START
3663
 
  push bp
3664
 
  mov  bp, sp
3665
 
 
3666
 
    push ax
3667
 
    push bx
3668
 
    push ds
3669
 
    mov  ax, 4[bp] ; segment
3670
 
    mov  ds, ax
3671
 
    mov  bx, 6[bp] ; offset
3672
 
    mov  ax, 8[bp] ; data word
3673
 
    mov  [bx], ax  ; write data word
3674
 
    pop  ds
3675
 
    pop  bx
3676
 
    pop  ax
3677
 
 
3678
 
  pop  bp
3679
 
ASM_END
3680
 
}
3681
 
 
3682
 
// --------------------------------------------------------------------------------------------
3683
 
 Bit8u
3684
 
inb(port)
3685
 
  Bit16u port;
3686
 
{
3687
 
ASM_START
3688
 
  push bp
3689
 
  mov  bp, sp
3690
 
 
3691
 
    push dx
3692
 
    mov  dx, 4[bp]
3693
 
    in   al, dx
3694
 
    pop  dx
3695
 
 
3696
 
  pop  bp
3697
 
ASM_END
3698
 
}
3699
 
 
3700
 
  Bit16u
3701
 
inw(port)
3702
 
  Bit16u port;
3703
 
{
3704
 
ASM_START
3705
 
  push bp
3706
 
  mov  bp, sp
3707
 
 
3708
 
    push dx
3709
 
    mov  dx, 4[bp]
3710
 
    in   ax, dx
3711
 
    pop  dx
3712
 
 
3713
 
  pop  bp
3714
 
ASM_END
3715
 
}
3716
 
 
3717
 
// --------------------------------------------------------------------------------------------
3718
 
  void
3719
 
outb(port, val)
3720
 
  Bit16u port;
3721
 
  Bit8u  val;
3722
 
{
3723
 
ASM_START
3724
 
  push bp
3725
 
  mov  bp, sp
3726
 
 
3727
 
    push ax
3728
 
    push dx
3729
 
    mov  dx, 4[bp]
3730
 
    mov  al, 6[bp]
3731
 
    out  dx, al
3732
 
    pop  dx
3733
 
    pop  ax
3734
 
 
3735
 
  pop  bp
3736
 
ASM_END
3737
 
}
3738
 
 
3739
 
// --------------------------------------------------------------------------------------------
3740
 
  void
3741
 
outw(port, val)
3742
 
  Bit16u port;
3743
 
  Bit16u  val;
3744
 
{
3745
 
ASM_START
3746
 
  push bp
3747
 
  mov  bp, sp
3748
 
 
3749
 
    push ax
3750
 
    push dx
3751
 
    mov  dx, 4[bp]
3752
 
    mov  ax, 6[bp]
3753
 
    out  dx, ax
3754
 
    pop  dx
3755
 
    pop  ax
3756
 
 
3757
 
  pop  bp
3758
 
ASM_END
3759
 
}
3760
 
 
3761
 
Bit16u get_SS()
3762
 
{
3763
 
ASM_START
3764
 
  mov  ax, ss
3765
 
ASM_END
3766
 
}
3767
 
 
3768
 
#ifdef DEBUG
3769
 
void unimplemented()
3770
 
{
3771
 
 printf("--> Unimplemented\n");
3772
 
}
3773
 
 
3774
 
void unknown()
3775
 
{
3776
 
 printf("--> Unknown int10\n");
3777
 
}
3778
 
#endif
3779
 
 
3780
 
// --------------------------------------------------------------------------------------------
3781
 
#if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG)
3782
 
void printf(s)
3783
 
  Bit8u *s;
3784
 
{
3785
 
  Bit8u c, format_char;
3786
 
  Boolean  in_format;
3787
 
  unsigned format_width, i;
3788
 
  Bit16u  *arg_ptr;
3789
 
  Bit16u   arg_seg, arg, digit, nibble, shift_count;
3790
 
 
3791
 
  arg_ptr = &s;
3792
 
  arg_seg = get_SS();
3793
 
 
3794
 
  in_format = 0;
3795
 
  format_width = 0;
3796
 
 
3797
 
  while (c = read_byte(0xc000, s)) {
3798
 
    if ( c == '%' ) {
3799
 
      in_format = 1;
3800
 
      format_width = 0;
3801
 
      }
3802
 
    else if (in_format) {
3803
 
      if ( (c>='0') && (c<='9') ) {
3804
 
        format_width = (format_width * 10) + (c - '0');
3805
 
        }
3806
 
      else if (c == 'x') {
3807
 
        arg_ptr++; // increment to next arg
3808
 
        arg = read_word(arg_seg, arg_ptr);
3809
 
        if (format_width == 0)
3810
 
          format_width = 4;
3811
 
        i = 0;
3812
 
        digit = format_width - 1;
3813
 
        for (i=0; i<format_width; i++) {
3814
 
          nibble = (arg >> (4 * digit)) & 0x000f;
3815
 
          if (nibble <= 9)
3816
 
            outb(0x0500, nibble + '0');
3817
 
          else
3818
 
            outb(0x0500, (nibble - 10) + 'A');
3819
 
          digit--;
3820
 
          }
3821
 
        in_format = 0;
3822
 
        }
3823
 
      //else if (c == 'd') {
3824
 
      //  in_format = 0;
3825
 
      //  }
3826
 
      }
3827
 
    else {
3828
 
      outb(0x0500, c);
3829
 
      }
3830
 
    s ++;
3831
 
    }
3832
 
}
3833
 
#endif
3834
 
 
3835
 
ASM_START
3836
 
  ; get LFB address from PCI
3837
 
  ; in - ax: PCI device vendor
3838
 
  ; out - ax: LFB address (high 16 bit)
3839
 
  ;; NOTE - may be called in protected mode
3840
 
_pci_get_lfb_addr:
3841
 
  push bx
3842
 
  push cx
3843
 
  push dx
3844
 
  push eax
3845
 
    mov bx, ax
3846
 
    xor cx, cx
3847
 
    mov dl, #0x00
3848
 
    call pci_read_reg
3849
 
    cmp ax, #0xffff
3850
 
    jz pci_get_lfb_addr_5
3851
 
 pci_get_lfb_addr_3:
3852
 
    mov dl, #0x00
3853
 
    call pci_read_reg
3854
 
    cmp ax, bx ;; check vendor
3855
 
    jz pci_get_lfb_addr_4
3856
 
    add cx, #0x8
3857
 
    cmp cx, #0x200 ;; search bus #0 and #1
3858
 
    jb pci_get_lfb_addr_3
3859
 
 pci_get_lfb_addr_5:
3860
 
    xor dx, dx ;; no LFB
3861
 
    jmp pci_get_lfb_addr_6
3862
 
 pci_get_lfb_addr_4:
3863
 
    mov dl, #0x10 ;; I/O space #0
3864
 
    call pci_read_reg
3865
 
    test ax, #0xfff1
3866
 
    jnz pci_get_lfb_addr_5
3867
 
    shr eax, #16
3868
 
    mov dx, ax ;; LFB address
3869
 
 pci_get_lfb_addr_6:
3870
 
  pop eax
3871
 
  mov ax, dx
3872
 
  pop dx
3873
 
  pop cx
3874
 
  pop bx
3875
 
  ret
3876
 
 
3877
 
  ; read PCI register
3878
 
  ; in - cx: device/function
3879
 
  ; in - dl: register
3880
 
  ; out - eax: value
3881
 
pci_read_reg:
3882
 
  mov eax, #0x00800000
3883
 
  mov ax, cx
3884
 
  shl eax, #8
3885
 
  mov al, dl
3886
 
  mov dx, #0xcf8
3887
 
  out dx, eax
3888
 
  add dl, #4
3889
 
  in  eax, dx
3890
 
  ret
3891
 
ASM_END
3892
 
 
3893
 
#ifdef VBE
3894
 
#include "vbe.c"
3895
 
#endif
3896
 
 
3897
 
#ifdef CIRRUS
3898
 
#include "clext.c"
3899
 
#endif
3900
 
 
3901
 
// --------------------------------------------------------------------------------------------
3902
 
 
3903
 
ASM_START 
3904
 
;; DATA_SEG_DEFS_HERE
3905
 
ASM_END
3906
 
 
3907
 
ASM_START
3908
 
.ascii "vgabios ends here"
3909
 
.byte  0x00
3910
 
vgabios_end:
3911
 
.byte 0xCB
3912
 
;; BLOCK_STRINGS_BEGIN
3913
 
ASM_END