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

Subversion Repositories zet86

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

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

powered by: WebSVN 2.1.0

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