OpenCores
URL https://opencores.org/ocsvn/zet86/zet86/trunk

Subversion Repositories zet86

[/] [zet86/] [trunk/] [soc/] [bios/] [vgabios.c] - Blame information for rev 37

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 zeus
#include "vgabios.h"
2
 
3
/* Declares */
4
static Bit8u          read_byte();
5
static Bit16u         read_word();
6
static void           write_byte();
7
static void           write_word();
8
static Bit8u          inb();
9
static Bit16u         inw();
10
static void           outb();
11
static void           outw();
12
 
13
static Bit16u         get_SS();
14
 
15
static Bit8u find_vga_entry();
16
 
17
static void memsetb();
18
static void memsetw();
19
static void memcpyb();
20
static void memcpyw();
21
 
22
static void biosfn_set_video_mode();
23
static void biosfn_set_cursor_pos();
24
static void biosfn_get_cursor_pos();
25
static void biosfn_scroll();
26
static void biosfn_write_teletype();
27
static void biosfn_write_string();
28
extern Bit8u video_save_pointer_table[];
29
 
30
// This is for compiling with gcc2 and gcc3
31
#define ASM_START #asm
32
#define ASM_END   #endasm
33
 
34
ASM_START
35
 
36
MACRO SET_INT_VECTOR
37
  push ds
38
  xor ax, ax
39
  mov ds, ax
40
  mov ax, ?3
41
  mov ?1*4, ax
42
  mov ax, ?2
43
  mov ?1*4+2, ax
44
  pop ds
45
MEND
46
 
47
ASM_END
48
 
49
ASM_START
50
.text
51
.rom
52
.org 0
53
 
54
use16 8086
55
 
56
vgabios_start:
57
.byte   0x55, 0xaa      /* BIOS signature, required for BIOS extensions */
58
 
59
.byte   0x40            /* BIOS extension length in units of 512 bytes */
60
 
61
 
62
vgabios_entry_point:
63
 
64
  jmp vgabios_init_func
65
 
66
vgabios_name:
67 37 zeus
.ascii  "Zet/Bochs VGABios"
68 34 zeus
.ascii  " "
69
.byte   0x00
70
 
71
// Info from Bart Oldeman
72
.org 0x1e
73
.ascii  "IBM"
74
.byte   0x00
75
 
76
vgabios_version:
77
#ifndef VGABIOS_VERS
78
.ascii  "current-cvs"
79
#else
80
.ascii VGABIOS_VERS
81
#endif
82
.ascii  " "
83
 
84
vgabios_date:
85
.ascii  VGABIOS_DATE
86
.byte   0x0a,0x0d
87
.byte   0x00
88
 
89
vgabios_copyright:
90
.ascii  "(C) 2003 the LGPL VGABios developers Team"
91
.byte   0x0a,0x0d
92
.byte   0x00
93
 
94
vgabios_license:
95
.ascii  "This VGA/VBE Bios is released under the GNU LGPL"
96
.byte   0x0a,0x0d
97
.byte   0x0a,0x0d
98
.byte   0x00
99
 
100
vgabios_website:
101
.ascii  "Please visit :"
102
.byte   0x0a,0x0d
103
;;.ascii  " . http://www.plex86.org"
104
;;.byte 0x0a,0x0d
105 37 zeus
.ascii  " . http://zet.aluzina.org"
106
.byte   0x0a,0x0d
107 34 zeus
.ascii  " . http://bochs.sourceforge.net"
108
.byte   0x0a,0x0d
109
.ascii  " . http://www.nongnu.org/vgabios"
110
.byte   0x0a,0x0d
111
.byte   0x0a,0x0d
112
.byte   0x00
113
 
114
 
115
;; ========================================================
116
;;
117
;; Init Entry point
118
;;
119
;; ========================================================
120
vgabios_init_func:
121
 
122
;; init basic bios vars
123
  call init_bios_area
124
 
125
;; set int10 vect
126
  SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
127
 
128
;; display splash screen
129
  call _display_splash_screen
130 37 zeus
 
131 34 zeus
;; init video mode and clear the screen
132
  mov ax,#0x0003
133
  int #0x10
134
 
135
;; show info
136
  call _display_info
137
 
138
  retf
139
ASM_END
140
 
141
/*
142
 *  int10 handled here
143
 */
144
ASM_START
145
vgabios_int10_handler:
146
  pushf
147
 
148
int10_normal:
149
  push es
150
  push ds
151
  ;pusha ; we do this instead:
152
 
153
  push ax
154
  push cx
155
  push dx
156
  push bx
157
  push sp
158
  mov  bx, sp
159
  add  [bx], #10
160
  mov  bx, [bx+2]
161
  push bp
162
  push si
163
  push di
164
 
165
;; We have to set ds to access the right data segment
166
  mov   bx, #0xc000
167
  mov   ds, bx
168 37 zeus
 
169 34 zeus
  call _int10_func
170
 
171
  ; popa ; we do this instead:
172
  pop di
173
  pop si
174
  pop bp
175
  add sp, #2
176
  pop bx
177
  pop dx
178
  pop cx
179
  pop ax
180
 
181
  pop ds
182
  pop es
183
int10_end:
184
  popf
185
  iret
186
ASM_END
187
 
188
#include "vgatables.h"
189
 
190
// --------------------------------------------------------
191
/*
192
 *  Boot time bios area inits
193
 */
194
ASM_START
195
init_bios_area:
196
  push  ds
197
  mov   ax, # BIOSMEM_SEG
198
  mov   ds, ax
199
 
200
;; init detected hardware BIOS Area
201
  mov   bx, # BIOSMEM_INITIAL_MODE
202
  mov   ax, [bx]
203
  and   ax, #0xffcf
204
;; set 80x25 color (not clear from RBIL but usual)
205
  or    ax, #0x0020
206
  mov   [bx], ax
207
 
208
;; Just for the first int10 find its children
209
 
210
;; the default char height
211
  mov   bx, # BIOSMEM_CHAR_HEIGHT
212
  mov   al, #0x10
213
  mov   [bx], al
214
 
215
;; Clear the screen
216
  mov   bx, # BIOSMEM_VIDEO_CTL
217
  mov   al, #0x60
218
  mov   [bx], al
219
 
220
;; Set the basic screen we have
221
  mov   bx, # BIOSMEM_SWITCHES
222
  mov   al, #0xf9
223
  mov   [bx], al
224
 
225
;; Set the basic modeset options
226
  mov   bx, # BIOSMEM_MODESET_CTL
227
  mov   al, #0x51
228
  mov   [bx], al
229
 
230
;; Set the  default MSR
231
  mov   bx, # BIOSMEM_CURRENT_MSR
232
  mov   al, #0x09
233
  mov   [bx], al
234
 
235
  pop ds
236
  ret
237
 
238
_video_save_pointer_table:
239
  .word _video_param_table
240
  .word 0xc000
241
 
242
  .word 0 /* XXX: fill it */
243
  .word 0
244
 
245
  .word 0 /* XXX: fill it */
246
  .word 0
247
 
248
  .word 0 /* XXX: fill it */
249
  .word 0
250
 
251
  .word 0 /* XXX: fill it */
252
  .word 0
253
 
254
  .word 0 /* XXX: fill it */
255
  .word 0
256
 
257
  .word 0 /* XXX: fill it */
258
  .word 0
259
 
260
ASM_END
261
 
262
// --------------------------------------------------------
263
/*
264
 *  Boot time Splash screen
265
 */
266
static void display_splash_screen()
267
{
268
  write_byte (0xb800, 0x0, 'H');
269 37 zeus
//  write_byte (0xb800, 0x2, 'o');
270 34 zeus
}
271
 
272
// --------------------------------------------------------------------------------------------
273
/*
274
 *  Tell who we are
275
 */
276
 
277
static void display_info()
278
{
279
ASM_START
280
 mov ax,#0xc000
281
 mov ds,ax
282
 mov si,#vgabios_name
283
 call _display_string
284
 mov si,#vgabios_version
285
 call _display_string
286 37 zeus
 
287 34 zeus
 ;;mov si,#vgabios_copyright
288
 ;;call _display_string
289
 ;;mov si,#crlf
290
 ;;call _display_string
291
 
292
 mov si,#vgabios_license
293
 call _display_string
294
 mov si,#vgabios_website
295
 call _display_string
296
ASM_END
297
}
298
 
299
static void display_string()
300
{
301
 // Get length of string
302
ASM_START
303
 mov ax,ds
304
 mov es,ax
305
 mov di,si
306
 xor cx,cx
307
 not cx
308
 xor al,al
309
 cld
310
 repne
311
  scasb
312
 not cx
313
 dec cx
314
 push cx
315
 
316
 mov ax,#0x0300
317
 mov bx,#0x0000
318
 int #0x10
319 37 zeus
 
320 34 zeus
 pop cx
321
 mov ax,#0x1301
322
 mov bx,#0x000b
323
 mov bp,si
324
 int #0x10
325
ASM_END
326
}
327
 
328
// --------------------------------------------------------
329
/*
330
 * int10 main dispatcher
331
 */
332
static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
333
  Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
334
{
335
 // BIOS functions
336
 switch(GET_AH())
337
  {
338
   case 0x00:
339
     biosfn_set_video_mode(GET_AL());
340
     switch(GET_AL()&0x7F)
341 37 zeus
      {case 6:
342 34 zeus
        SET_AL(0x3F);
343
        break;
344
       case 0:
345
       case 1:
346
       case 2:
347
       case 3:
348
       case 4:
349
       case 5:
350
       case 7:
351
        SET_AL(0x30);
352
        break;
353
      default:
354
        SET_AL(0x20);
355
      }
356
     break;
357 37 zeus
   case 0x02:
358
     biosfn_set_cursor_pos(GET_BH(),DX);
359
     break;
360 34 zeus
   case 0x03:
361
     biosfn_get_cursor_pos(GET_BH(),&CX,&DX);
362
     break;
363
   case 0x0E:
364
     // Ralf Brown Interrupt list is WRONG on bh(page)
365
     // We do output only on the current page !
366
     biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);
367
     break;
368
   case 0x13:
369
     biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
370
     break;
371
  }
372
}
373
 
374
// ============================================================================================
375
// 
376
// BIOS functions
377
// 
378
// ============================================================================================
379
 
380
static void biosfn_set_video_mode(mode) Bit8u mode;
381
{// mode: Bit 7 is 1 if no clear screen
382
 
383
 // Should we clear the screen ?
384
 Bit8u noclearmem=mode&0x80;
385
 Bit8u line,mmask,*palette,vpti;
386
 Bit16u i,twidth,theightm1,cheight;
387
 Bit8u modeset_ctl,video_ctl,vga_switches;
388
 Bit16u crtc_addr;
389 37 zeus
 
390 34 zeus
 // The real mode
391
 mode=mode&0x7f;
392
 
393
 // find the entry in the video modes
394
 line=find_vga_entry(mode);
395
 
396
 if(line==0xFF)
397
  return;
398
 
399
 vpti=line_to_vpti[line];
400
 twidth=video_param_table[vpti].twidth;
401
 theightm1=video_param_table[vpti].theightm1;
402
 cheight=video_param_table[vpti].cheight;
403
 
404
 // Read the bios vga control
405
 video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
406
 
407
 // Read the bios vga switches
408
 vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES);
409
 
410
 // Read the bios mode set control
411
 modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
412
 
413
 // Set CRTC address VGA or MDA 
414
 crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
415
 
416
 // Set the BIOS mem
417
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
418
 write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth);
419
 write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l);
420
 write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
421
 write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
422
 write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
423
 write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
424
 write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
425
 write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
426
 
427
 // FIXME We nearly have the good tables. to be reworked
428
 write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08);    // 8 is VGA should be ok for now
429
 write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table);
430
 write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000);
431
 
432
 // FIXME
433
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but...
434
 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...
435
 
436
}
437
 
438
// --------------------------------------------------------------------------------------------
439
static void biosfn_set_cursor_pos (page, cursor)
440
Bit8u page;Bit16u cursor;
441
{
442
 Bit8u xcurs,ycurs,current;
443
 Bit16u nbcols,nbrows,address,crtc_addr;
444
 
445
 // Should not happen...
446
 if(page>7)return;
447
 
448
 // Bios cursor pos
449
 write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor);
450
 
451
 // Set the hardware cursor
452
 current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
453
 if(page==current)
454
  {
455
   // Get the dimensions
456
   nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
457
   nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
458
 
459
   xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
460
 
461
   // Calculate the address knowing nbcols nbrows and page num
462
   address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols;
463
 
464
   // CRTC regs 0x0e and 0x0f
465
   crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
466
   outb(crtc_addr,0x0e);
467
   outb(crtc_addr+1,(address&0xff00)>>8);
468
   outb(crtc_addr,0x0f);
469
   outb(crtc_addr+1,address&0x00ff);
470
  }
471
}
472
 
473
// --------------------------------------------------------------------------------------------
474
static void biosfn_get_cursor_pos (page,shape, pos)
475
Bit8u page;Bit16u *shape;Bit16u *pos;
476
{
477
 Bit16u ss=get_SS();
478
 
479
 // Default
480
 write_word(ss, shape, 0);
481
 write_word(ss, pos, 0);
482
 
483
 if(page>7)return;
484
 // FIXME should handle VGA 14/16 lines
485
 write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE));
486
 write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2));
487
}
488
 
489
// --------------------------------------------------------------------------------------------
490
static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)
491
Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;
492
{
493
 // page == 0xFF if current
494
 
495
 Bit8u mode,line,cheight,bpp,cols;
496
 Bit16u nbcols,nbrows,i;
497
 Bit16u address;
498
 
499
 if(rul>rlr)return;
500
 if(cul>clr)return;
501
 
502
 // Get the mode
503
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
504
 line=find_vga_entry(mode);
505
 if(line==0xFF)return;
506
 
507
 // Get the dimensions
508
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
509
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
510
 
511
 // Get the current page
512
 if(page==0xFF)
513
  page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
514
 
515
 if(rlr>=nbrows)rlr=nbrows-1;
516
 if(clr>=nbcols)clr=nbcols-1;
517
 if(nblines>nbrows)nblines=0;
518
 cols=clr-cul+1;
519
 
520
 if(vga_modes[line].class==TEXT)
521
  {
522
   // Compute the address
523
   address=SCREEN_MEM_START(nbcols,nbrows,page);
524
#ifdef DEBUG
525
   printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);
526
#endif
527
 
528
   if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
529
    {
530
     memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);
531
    }
532
   else
533
    {// if Scroll up
534
     if(dir==SCROLL_UP)
535
      {for(i=rul;i<=rlr;i++)
536
        {
537
         if((i+nblines>rlr)||(nblines==0))
538
          memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
539
         else
540
          memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);
541
        }
542
      }
543
     else
544
      {for(i=rlr;i>=rul;i--)
545
        {
546
         if((i<rul+nblines)||(nblines==0))
547
          memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
548
         else
549
          memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);
550
         if (i>rlr) break;
551
        }
552
      }
553
    }
554
  }
555
}
556
 
557
// --------------------------------------------------------------------------------------------
558
static void biosfn_write_teletype (car, page, attr, flag)
559
Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
560
{// flag = WITH_ATTR / NO_ATTR
561
 
562
 Bit8u cheight,xcurs,ycurs,mode,line,bpp;
563
 Bit16u nbcols,nbrows,address;
564
 Bit16u cursor,dummy;
565
 
566
 // special case if page is 0xff, use current page
567
 if(page==0xff)
568
  page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
569
 
570
 // Get the mode
571
 mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
572
 line=find_vga_entry(mode);
573
 if(line==0xFF)return;
574
 
575
 // Get the cursor pos for the page
576
 biosfn_get_cursor_pos(page,&dummy,&cursor);
577
 xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
578
 
579
 // Get the dimensions
580
 nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
581
 nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
582
 
583
 switch(car)
584
  {
585
   case 7:
586
    //FIXME should beep
587
    break;
588
 
589
   case 8:
590
    if(xcurs>0)xcurs--;
591
    break;
592
 
593
   case '\r':
594
    xcurs=0;
595
    break;
596
 
597
   case '\n':
598
    ycurs++;
599
    break;
600
 
601
   case '\t':
602
    do
603
     {
604
      biosfn_write_teletype(' ',page,attr,flag);
605
      biosfn_get_cursor_pos(page,&dummy,&cursor);
606
      xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
607
     }while(xcurs%8==0);
608
    break;
609
 
610
   default:
611
 
612
    if(vga_modes[line].class==TEXT)
613
     {
614
      // Compute the address  
615
      address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
616
 
617
      // Write the char 
618
      write_byte(vga_modes[line].sstart,address,car);
619
 
620
      if(flag==WITH_ATTR)
621
       write_byte(vga_modes[line].sstart,address+1,attr);
622
     }
623
    xcurs++;
624
  }
625
 
626
 // Do we need to wrap ?
627
 if(xcurs==nbcols)
628
  {xcurs=0;
629
   ycurs++;
630
  }
631
 
632
 // Do we need to scroll ?
633
 if(ycurs==nbrows)
634
  {
635
   if(vga_modes[line].class==TEXT)
636
    {
637
     biosfn_scroll(0x01,0x07,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
638
    }
639
   ycurs-=1;
640
  }
641
 
642
 // Set the cursor for the page
643
 cursor=ycurs; cursor<<=8; cursor+=xcurs;
644
 biosfn_set_cursor_pos(page,cursor);
645
}
646
 
647
// --------------------------------------------------------------------------------------------
648
static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset)
649
Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset;
650
{
651
 Bit16u newcurs,oldcurs,dummy;
652
 Bit8u car,carattr;
653
 
654
 // Read curs info for the page
655
 biosfn_get_cursor_pos(page,&dummy,&oldcurs);
656
 
657
 // if row=0xff special case : use current cursor position
658
 if(row==0xff)
659
  {col=oldcurs&0x00ff;
660
   row=(oldcurs&0xff00)>>8;
661
  }
662
 
663
 newcurs=row; newcurs<<=8; newcurs+=col;
664
 biosfn_set_cursor_pos(page,newcurs);
665
 
666
 while(count--!=0)
667
  {
668
   car=read_byte(seg,offset++);
669
   if((flag&0x02)!=0)
670
    attr=read_byte(seg,offset++);
671
 
672
   biosfn_write_teletype(car,page,attr,WITH_ATTR);
673
  }
674
 
675
 // Set back curs pos 
676
 if((flag&0x01)==0)
677
  biosfn_set_cursor_pos(page,oldcurs);
678
}
679
 
680
// ============================================================================================
681
//
682
// Video Utils
683
//
684
// ============================================================================================
685
 
686
// --------------------------------------------------------------------------------------------
687
static Bit8u find_vga_entry(mode)
688
Bit8u mode;
689
{
690
 Bit8u i,line=0xFF;
691
 for(i=0;i<=MODE_MAX;i++)
692
  if(vga_modes[i].svgamode==mode)
693
   {line=i;
694
    break;
695
   }
696
 return line;
697
}
698
 
699
// --------------------------------------------------------------------------------------------
700
static void memsetw(seg,offset,value,count)
701
  Bit16u seg;
702
  Bit16u offset;
703
  Bit16u value;
704
  Bit16u count;
705
{
706
ASM_START
707
  push bp
708
  mov  bp, sp
709
 
710
    push ax
711
    push cx
712
    push es
713
    push di
714
 
715
    mov  cx, 10[bp] ; count
716
    cmp  cx, #0x00
717
    je   memsetw_end
718
    mov  ax, 4[bp] ; segment
719
    mov  es, ax
720
    mov  ax, 6[bp] ; offset
721
    mov  di, ax
722
    mov  ax, 8[bp] ; value
723
    cld
724
    rep
725
     stosw
726
 
727
memsetw_end:
728
    pop di
729
    pop es
730
    pop cx
731
    pop ax
732
 
733
  pop bp
734
ASM_END
735
}
736
 
737
// --------------------------------------------------------------------------------------------
738
static void memcpyw(dseg,doffset,sseg,soffset,count)
739
  Bit16u dseg;
740
  Bit16u doffset;
741
  Bit16u sseg;
742
  Bit16u soffset;
743
  Bit16u count;
744
{
745
ASM_START
746
  push bp
747
  mov  bp, sp
748
 
749
    push ax
750
    push cx
751
    push es
752
    push di
753
    push ds
754
    push si
755
 
756
    mov  cx, 12[bp] ; count
757
    cmp  cx, #0x0000
758
    je   memcpyw_end
759
    mov  ax, 4[bp] ; dsegment
760
    mov  es, ax
761
    mov  ax, 6[bp] ; doffset
762
    mov  di, ax
763
    mov  ax, 8[bp] ; ssegment
764
    mov  ds, ax
765
    mov  ax, 10[bp] ; soffset
766
    mov  si, ax
767
    cld
768
    rep
769
     movsw
770
 
771
memcpyw_end:
772
    pop si
773
    pop ds
774
    pop di
775
    pop es
776
    pop cx
777
    pop ax
778
 
779
  pop bp
780
ASM_END
781
}
782
 
783
// --------------------------------------------------------------------------------------------
784
static Bit8u
785
read_byte(seg, offset)
786
  Bit16u seg;
787
  Bit16u offset;
788
{
789
ASM_START
790
  push bp
791
  mov  bp, sp
792
 
793
    push bx
794
    push ds
795
    mov  ax, 4[bp] ; segment
796
    mov  ds, ax
797
    mov  bx, 6[bp] ; offset
798
    mov  al, [bx]
799
    ;; al = return value (byte)
800
    pop  ds
801
    pop  bx
802
 
803
  pop  bp
804
ASM_END
805
}
806
 
807
// --------------------------------------------------------------------------------------------
808
static Bit16u
809
read_word(seg, offset)
810
  Bit16u seg;
811
  Bit16u offset;
812
{
813
ASM_START
814
  push bp
815
  mov  bp, sp
816
 
817
    push bx
818
    push ds
819
    mov  ax, 4[bp] ; segment
820
    mov  ds, ax
821
    mov  bx, 6[bp] ; offset
822
    mov  ax, [bx]
823
    ;; ax = return value (word)
824
    pop  ds
825
    pop  bx
826
 
827
  pop  bp
828
ASM_END
829
}
830
 
831
// --------------------------------------------------------------------------------------------
832
static void
833
write_byte(seg, offset, data)
834
  Bit16u seg;
835
  Bit16u offset;
836
  Bit8u  data;
837
{
838
ASM_START
839
  push bp
840
  mov  bp, sp
841
 
842
    push ax
843
    push bx
844
    push ds
845
    mov  ax, 4[bp] ; segment
846
    mov  ds, ax
847
    mov  bx, 6[bp] ; offset
848
    mov  al, 8[bp] ; data byte
849
    mov  [bx], al  ; write data byte
850
    pop  ds
851
    pop  bx
852
    pop  ax
853
 
854
  pop  bp
855
ASM_END
856
}
857
 
858
// --------------------------------------------------------------------------------------------
859
static void
860
write_word(seg, offset, data)
861
  Bit16u seg;
862
  Bit16u offset;
863
  Bit16u data;
864
{
865
ASM_START
866
  push bp
867
  mov  bp, sp
868
 
869
    push ax
870
    push bx
871
    push ds
872
    mov  ax, 4[bp] ; segment
873
    mov  ds, ax
874
    mov  bx, 6[bp] ; offset
875
    mov  ax, 8[bp] ; data word
876
    mov  [bx], ax  ; write data word
877
    pop  ds
878
    pop  bx
879
    pop  ax
880
 
881
  pop  bp
882
ASM_END
883
}
884
 
885
// --------------------------------------------------------------------------------------------
886
 Bit8u
887
inb(port)
888
  Bit16u port;
889
{
890
ASM_START
891
  push bp
892
  mov  bp, sp
893
 
894
    push dx
895
    mov  dx, 4[bp]
896
    in   al, dx
897
    pop  dx
898
 
899
  pop  bp
900
ASM_END
901
}
902
 
903
  Bit16u
904
inw(port)
905
  Bit16u port;
906
{
907
ASM_START
908
  push bp
909
  mov  bp, sp
910
 
911
    push dx
912
    mov  dx, 4[bp]
913
    in   ax, dx
914
    pop  dx
915
 
916
  pop  bp
917
ASM_END
918
}
919
 
920
// --------------------------------------------------------------------------------------------
921
  void
922
outb(port, val)
923
  Bit16u port;
924
  Bit8u  val;
925
{
926
ASM_START
927
  push bp
928
  mov  bp, sp
929
 
930
    push ax
931
    push dx
932
    mov  dx, 4[bp]
933
    mov  al, 6[bp]
934
    out  dx, al
935
    pop  dx
936
    pop  ax
937
 
938
  pop  bp
939
ASM_END
940
}
941
 
942
// --------------------------------------------------------------------------------------------
943
  void
944
outw(port, val)
945
  Bit16u port;
946
  Bit16u  val;
947
{
948
ASM_START
949
  push bp
950
  mov  bp, sp
951
 
952
    push ax
953
    push dx
954
    mov  dx, 4[bp]
955
    mov  ax, 6[bp]
956
    out  dx, ax
957
    pop  dx
958
    pop  ax
959
 
960
  pop  bp
961
ASM_END
962
}
963
 
964
Bit16u get_SS()
965
{
966
ASM_START
967
  mov  ax, ss
968
ASM_END
969
}
970
 
971
// --------------------------------------------------------------------------------------------
972
 
973
ASM_START
974
;; DATA_SEG_DEFS_HERE
975
ASM_END
976
 
977
ASM_START
978
.ascii "vgabios ends here"
979
.byte  0x00
980
vgabios_end:
981
.byte 0xCB
982
;; BLOCK_STRINGS_BEGIN
983
ASM_END

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.