home *** CD-ROM | disk | FTP | other *** search
- unit XTreem; {by Sean Palmer}
- {with a little help from:
- Matt Pritchard, Bas Van Gaalen, Michael Abrash, Keld Hansen, Bresenham}
- {public domain}
- {credit me if you use any of this}
-
- interface
-
- {A physical display mode is formed by combining a table for the desired
- horizontal resolution with a table for the desired vertical resolution.
- Logical screen resolutions can be greater than physical resolutions, and
- if so, window scrolling is possible. The total memory required by a mode
- is (logXRes*logYRes)div 4, and cannot exceed 64k. If more than one page
- will fit in 64k, you can use page flipping to get smoother animation.
- Some modes or combinations of modes may fry your monitor or whatnot, I
- make no guarantees about any of these modes. Use them at your own risk.
- Some are more stable than others.}
-
- {HORIZONTAL MODES}
- {low byte of crtc data indicates the following crtc registers:}
- {00=H total}
- {01=H displayed}
- {02=H start blank}
- {03=H end blank}
- {04=H start sync}
- {05=H end sync}
- {format for table: hRes, miscReg, crtc regs, 0}
- {Dot clocks available for miscReg: (3=25MHz,7=28MHz,$B=reserved) }
- {This also has the effect of forcing the VGA to use $3Dx port addresses}
- {any VGA should be able to handle these first 2 horizontal modes}
- const mode320x:array[0..02]of word=(320,$03,0);
- const mode360x:array[0..08]of word=(360,$07,$6B00,$5901,$5A02,$8E03,$5E04,$8A05,0);
- {the following modes are nonstandard and should be used with extreme caution!}
- const mode256x:array[0..08]of word=(256,$03,$5F00,$3F01,$4002,$8203,$4E04,$9A05,0);
- const mode376x:array[0..08]of word=(376,$07,$6E00,$5D01,$5E02,$9103,$6204,$8F05,0);
- {I made these myself. See above warning.}
- const mode128x:array[0..08]of word=(128,$03,$2D00,$1F01,$2002,$9003,$2404,$8F05,0);
- const mode264x:array[0..08]of word=(264,$03,$6100,$4101,$4202,$8403,$5004,$9C05,0);
- const mode304x:array[0..08]of word=(304,$03,$5B00,$4B01,$4C02,$9E03,$5004,$1C05,0);
- const mode312x:array[0..08]of word=(312,$03,$5D00,$4D01,$4E02,$8003,$5204,$9E05,0);
- const mode328x:array[0..08]of word=(328,$07,$6300,$5101,$5202,$8603,$5604,$8205,0);
- const mode336x:array[0..08]of word=(336,$07,$6500,$5301,$5402,$8803,$5804,$8405,0);
- const mode344x:array[0..08]of word=(344,$07,$6700,$5501,$5602,$8A03,$5A04,$8605,0);
- const mode352x:array[0..08]of word=(352,$07,$6900,$5701,$5802,$8C03,$5C04,$8805,0);
- const mode368x:array[0..08]of word=(368,$07,$6C00,$5B01,$5C02,$8903,$6004,$8D05,0);
- const mode384x:array[0..08]of word=(384,$07,$7000,$5F01,$6002,$9303,$6404,$9105,0);
- const mode392x:array[0..08]of word=(392,$07,$7200,$6101,$6202,$9503,$6604,$9305,0);
- const mode400x:array[0..08]of word=(400,$07,$7200,$6301,$6302,$9503,$6704,$9305,0);
-
- {VERTICAL MODES}
- {low byte of crtc data indicates the following crtc registers:}
- {06=V total}
- {07=overflow}
- {09=cell height/max scan, doubling on}
- {10=V start retrace}
- {11=V end retrace and protect}
- {12=V display enable end}
- {15=V start blank}
- {16=V end blank}
- {format for table: vRes, miscReg, crtc regs, 0}
- {lines available for miscReg: ($A0=350,$60=400,$E0=480)}
- {any VGA should be able to handle these first 4 vertical modes}
- const mode200y:array[0..02]of word=(200,$60,0);
- const mode240y:array[0..09]of word=(240,$E0,$0D06,$3E07,$EA10,$AC11,$DF12,$E715,$0616,0);
- const mode400y:array[0..03]of word=(400,$60,$4009,0);
- const mode480y:array[0..10]of word=(480,$E0,$0D06,$3E07,$4009,$EA10,$AC11,$DF12,$E715,$0616,0);
- {the following modes are nonstandard and should be used with extreme caution!}
- const mode256y:array[0..10]of word=(256,$E0,$2306,$B207,$6109,$0A10,$AC11,$FF12,$0715,$1716,0);
- const mode282y:array[0..10]of word=(282,$E0,$6206,$E007,$6109,$3710,$0911,$3312,$3C15,$5C16,0);
- const mode308y:array[0..10]of word=(308,$E0,$6206,$0F07,$4009,$3710,$8911,$3312,$3C15,$5C16,0);
- const mode360y:array[0..08]of word=(360,$E0, $4009,$8810,$8511,$6712,$6D15,$BA16,0);{gap}
- const mode564y:array[0..10]of word=(564,$E0,$6206,$E007,$6009,$3710,$0911,$3312,$3C15,$5C16,0);
- {I made these myself. See above warning.}
- const mode64y: array[0..10]of word=( 64,$E0,$2306,$B207,$6709,$0A10,$AC11,$FF12,$0715,$1716,0);
- const mode90y: array[0..08]of word=( 90,$E0, $4309,$8810,$8511,$6712,$6D15,$BA16,0);{gap}
- const mode94y: array[0..10]of word=( 94,$E0,$6206,$E007,$6509,$3710,$0911,$3312,$3C15,$5C16,0);
- const mode100y:array[0..03]of word=(100,$60,$4309,0);
- const mode120y:array[0..10]of word=(120,$E0,$0D06,$3E07,$4309,$EA10,$AC11,$DF12,$E715,$0616,0);
- const mode128y:array[0..10]of word=(128,$E0,$2306,$B207,$6309,$0A10,$AC11,$FF12,$0715,$1716,0);
- const mode141y:array[0..10]of word=(141,$E0,$6206,$E007,$6309,$3710,$0911,$3312,$3C15,$5C16,0);
- const mode154y:array[0..10]of word=(154,$E0,$6206,$0F07,$4109,$3710,$8911,$3312,$3C15,$5C16,0);
- const mode180y:array[0..08]of word=(180,$E0, $4109,$8810,$8511,$6712,$6D15,$BA16,0);{gap}
- const mode188y:array[0..10]of word=(188,$E0,$6206,$E007,$6209,$3710,$0911,$3312,$3C15,$5C16,0);
- const mode512y:array[0..10]of word=(512,$E0,$2306,$B207,$6009,$0A10,$AC11,$FF12,$0715,$1716,0);
-
- {I also have an X640X400 unit that uses a VESA tweak to get 640x400x256 mode X}
- {If anyone has any other CRTC values that work, such as 600y or 160x, drop me
- a line at sean.palmer@delta.com}
-
- var
- xRes:word; {width of physical screen in pixels}
- yRes:word; {height of physical screen in pixels}
- lxRes:word; {width of virtual screen in pixels}
- lyRes:word; {height of virtual screen in pixels}
-
- {these provided for low-level external routines}
- const
- seqPort=$3C4; {VGA Sequencer}
- var
- lxBytes:word; {width of virtual screen in bytes per plane}
- pgBytes:word; {size of a page in bytes per plane}
- pgStart:pointer; {offset of current write page in bytes}
- pgShown:pointer; {offset of currently visible display page in bytes}
-
- var yTab:array[0..563]of word; {scan line lookup table. Big enough to handle 564 rows}
-
- type tSpriteHeader=record
- width,height,hOfs,vOfs:word;
- end; {sprite data follows}
-
- procedure clear(color:byte);
- procedure plot(x,y:word; color:byte);
- function scrn(x,y:word):byte;
- procedure hlin(x,x2,y:word; color:byte);
- procedure vlin(x,y,y2:word; color:byte);
- procedure rect(x,y,x2,y2:word; color:byte);
- procedure pane(x,y,x2,y2:word; color:byte);
- procedure line(x,y,x2,y2:word; color:byte);
- procedure curve(x1,y1,x2,y2,x3,y3:integer; color:byte; steps:word);
- procedure circle(xc,yc:integer; r:word; color:byte);
- procedure oval(xc,yc,a,b:integer; color:byte);
- procedure disk(xc,yc,a,b:integer; color:byte);
- procedure fill(x,y:integer; color:byte);
-
- procedure polygon(var pts; count:word; c:byte);
-
- procedure drawSprite(var sprite; x,y:integer);
- procedure drawTile(var tile; x,y:integer);
-
- procedure setColor(color,r,g,b:byte); {rgb vals are from 0-63}
- function getColor(color:byte):longint; {returns $00rrggbb format}
- procedure setPalette(color:byte;num:word;var rgb); {rgb is list of 3-byte rgb vals}
- procedure getPalette(color:byte;num:word;var rgb);
-
- procedure memBlt(memPage:pointer);
- procedure pageFlip;
- procedure setWritePage(adr:word);
- procedure setDisplayPage(adr:word);
- procedure setWindow(x,y:integer);
-
- procedure waitRetrace;
- procedure setSplitScreen(adr:word);
-
- function setModeX(var tblX,tblY; logX,logY:word):boolean;
- procedure setText;
-
- function rgb(r,g,b:byte):byte;
- procedure setUniformPalette;
-
- var exitMsg:string[80];
-
- implementation
-
- {$L XTREEM.OBJ}
-
- procedure clear(color:byte);external;
- procedure plot(x,y:word;color:byte);external;
- function scrn(x,y:word):byte;external;
- procedure hLin(x,x2,y:word; color:byte);external;
- procedure vLin(x,y,y2:word; color:byte);external;
-
- procedure rect(x,y,x2,y2:word; color:byte);begin
- hlin(x,x2,y,color);
- hlin(x,x2,y2,color);
- vlin(x,y+1,y2-1,color);
- vlin(x2,y+1,y2-1,color);
- end;
-
- procedure pane(x,y,x2,y2:word; color:byte);external;
-
- procedure line(x,y,x2,y2:word; color:byte);
- var d,dx,dy,ai,bi,xi,yi:integer;
- begin
- if(x<x2)then begin xi:=1;dx:=x2-x;end else begin xi:=-1;dx:=x-x2;end;
- if(y<y2)then begin yi:=1;dy:=y2-y;end else begin yi:=-1;dy:=y-y2;end;
- plot(x,y,color);
- if (dx or dy=0)then exit;
- if dx>dy then begin ai:=(dy-dx)*2;bi:=dy*2; d:=bi-dx;
- repeat
- if(d>=0)then begin inc(y,yi);inc(d,ai);end else inc(d,bi);
- inc(x,xi);
- if (x>=0) and (y<lxRes)and(y>=0)and(y<lyRes) then
- plot(x,y,color);
- until(x=x2);
- end
- else begin ai:=(dx-dy)*2;bi:=dx*2; d:=bi-dy;
- repeat
- if(d>=0)then begin inc(x,xi);inc(d,ai);end else inc(d,bi);
- inc(y,yi);
- if (x>=0) and (y<lxRes)and(y>=0)and(y<lyRes) then
- plot(x,y,color);
- until(y=y2);
- end;
- end;
-
- procedure curve(x1,y1,x2,y2,x3,y3:integer; color:byte; steps:word);external;
-
- procedure circle(xc,yc:integer; r:word; color:byte);external;
-
- procedure oval(xc,yc,a,b:integer;color:byte);
- var x,y:integer;aa,aa2,bb,bb2,d,dx,dy:longint;
- begin
- x:=0;y:=b; aa:=longint(a)*a;aa2:=2*aa; bb:=longint(b)*b;bb2:=2*bb;
- d:=bb-aa*b+aa div 4; dx:=0;dy:=aa2*b;
- plot(xc,yc-y,color);plot(xc,yc+y,color);
- plot(xc-a,yc,color);plot(xc+a,yc,color);
- while(dx<dy)do begin
- if(d>0)then begin dec(y); dec(dy,aa2); dec(d,dy); end;
- inc(x); inc(dx,bb2); inc(d,bb+dx);
- plot(xc+x,yc+y,color); plot(xc-x,yc+y,color);
- plot(xc+x,yc-y,color); plot(xc-x,yc-y,color);
- end;
- inc(d,(3*(aa-bb)div 2-(dx+dy))div 2);
- while(y>0)do begin
- if(d<0)then begin inc(x); inc(dx,bb2); inc(d,bb+dx); end;
- dec(y); dec(dy,aa2); inc(d,aa-dy);
- plot(xc+x,yc+y,color); plot(xc-x,yc+y,color);
- plot(xc+x,yc-y,color); plot(xc-x,yc-y,color);
- end;
- end;
-
- procedure disk(xc,yc,a,b:integer;color:byte);
- var x,y:integer;aa,aa2,bb,bb2,d,dx,dy:longint;
- begin
- x:=0;y:=b; aa:=longint(a)*a;aa2:=2*aa; bb:=longint(b)*b;bb2:=2*bb;
- d:=bb-aa*b+aa div 4; dx:=0;dy:=aa2*b;
- vLin(xc,yc-y,yc+y,color);
- while(dx<dy)do begin
- if(d>0)then begin dec(y); dec(dy,aa2); dec(d,dy); end;
- inc(x); inc(dx,bb2); inc(d,bb+dx);
- vLin(xc-x,yc-y,yc+y,color);vLin(xc+x,yc-y,yc+y,color);
- end;
- inc(d,(3*(aa-bb)div 2-(dx+dy))div 2);
- while(y>=0)do begin
- if(d<0)then begin
- inc(x); inc(dx,bb2); inc(d,bb+dx);
- vLin(xc-x,yc-y,yc+y,color);vLin(xc+x,yc-y,yc+y,color);
- end;
- dec(y); dec(dy,aa2); inc(d,aa-dy);
- end;
- end;
-
- var fillVal:byte;
- {This routine only called by fill}
- function lineFill(x,y,d,prevXL,prevXR:integer;color:byte):integer;var xl,xr,i:integer;label _1,_2,_3;begin
- xl:=x;xr:=x;
- repeat dec(xl); until(scrn(xl,y)<>fillVal)or(xl<0); inc(xl);
- repeat inc(xr); until(scrn(xr,y)<>fillVal)or(xr>=xRes); dec(xr);
- hLin(xl,xr,y,color);
- inc(y,d);
- if word(y)<yRes then
- for x:=xl to xr do
- if(scrn(x,y)=fillVal)then begin
- x:=lineFill(x,y,d,xl,xr,color);
- if word(x)>xr then goto _1;
- end;
- _1:dec(y,d+d); asm neg d;end;
- if word(y)<yRes then begin
- for x:=xl to prevXL do
- if(scrn(x,y)=fillVal)then begin
- i:=lineFill(x,y,d,xl,xr,color);
- if word(x)>prevXL then goto _2;
- end;
- _2:for x:=prevXR to xr do
- if(scrn(x,y)=fillVal)then begin
- i:=lineFill(x,y,d,xl,xr,color);
- if word(x)>xr then goto _3;
- end;
- _3:end;
- lineFill:=xr;
- end;
-
- procedure fill(x,y:integer;color:byte);begin
- fillVal:=scrn(x,y);if fillVal<>color then lineFill(x,y,1,x,x,color);
- end;
-
-
- function maxi(a,b:integer):integer; inline(
- $58/ { pop ax }
- $5b/ { pop bx }
- $3b/$c3/ { cmp ax,bx }
- $7f/$01/ { jg +1 }
- $93); { xchg ax,bx }
-
- function mini(a,b:integer):integer; inline(
- $58/ { pop ax }
- $5b/ { pop bx }
- $3b/$c3/ { cmp ax,bx }
- $7c/$01/ { jl +1 }
- $93); { xchg ax,bx }
-
- procedure calcEdge(x,y,x2,y2:integer; var table);near;external;
-
- procedure rowList(startY,count:word; var tbl;color:byte);far;external;
-
- procedure polygon(var pts; count:word; c:byte);
- var i,i2,ly,gy,y:integer; pos:array[0..563,0..1] of integer;
- var p:array[0..99]of record x,y:integer end absolute pts;
- begin
- ly:=lyRes; gy:=-1;
- for i:=count-1 downto 0 do with p[i] do begin
- ly:=maxi(mini(ly,y),0); {determine high and low range}
- gy:=mini(maxi(gy,y),lyRes-1);
- if i=0 then i2:=count-1 else i2:=i-1;
- calcEdge(p[i2].x,p[i2].y,x,y,pos);
- end;
- if (ly<lyRes)and(gy>=0) then { vertical offscreen checking }
- rowlist(ly,gy-ly+1,pos,c);
- end;
-
- procedure drawSprite(var sprite; x,y:integer);external;
- procedure drawTile(var tile; x,y:integer);external;
- procedure setColor(color,r,g,b:byte);external;
- function getColor(color:byte):longint;external;
-
- procedure setPalette(color:byte;num:word;var rgb);external;
- procedure getPalette(color:byte;num:word;var rgb);external;
-
- procedure setSplitScreen(adr:word); assembler;
- asm
- mov dx,3D4h {crtcPort}
- mov al,18h
- mov ah,[byte(adr)]
- out dx,ax
- mov al,7
- out dx,al
- inc dx
- in al,dx
- dec dx
- mov ah,[byte(adr)+1]
- and ah,00000001b
- shl ah,4
- and al,11101111b
- or al,ah
- mov ah,al
- mov al,7
- out dx,ax
-
- mov al,9
- out dx,al
- inc dx
- in al,dx
- dec dx
- mov ah,[byte(adr)+1]
- and ah,00000010b
- shl ah,5
- and al,10111111b
- or al,ah
- mov ah,al
- mov al,9
- out dx,ax
- end;
-
- procedure memBlt(memPage:pointer);external;
-
- procedure setWritePage(adr:word);external;
- procedure setDisplayPage(adr:word);external;
- procedure setWindow(x,y:integer);external;
-
- procedure pageFlip;begin {keep in mind some modes are too big to page flip}
- setDisplayPage(word(pgStart));
- setWritePage(word(pgStart)xor pgBytes);
- end;
-
- procedure waitRetrace;external;
-
- var oldMode:byte;
-
- function setModeX(var tblX,tblY; logX,logY:word):boolean;external;
- procedure setText;external;
-
- function rgb(r,g,b:byte):byte;begin {gives index into uniform palette}
- if (r=g)and(g=b) then rgb:=word(r)*31 div 255
- else rgb:=((((word(r)*6+127) div 255)shl 5)or
- ((g shr 5)shl 2)or
- (b shr 6)
- )+32;
- end;
-
- procedure set884palette;var y,v,c:word;begin
- port[$3c8]:=0;
- for y:=0 to 255 do begin
- v:=(y and $E0)shr 2; port[$3c9]:=v or(v shr 3);
- v:=y and $1C; port[$3c9]:=(v shl 1)or(v shr 2);
- v:=y and 3; port[$3c9]:=(v shl 4)or(v shl 2)or v;
- end;
- end;
- procedure setUniformPalette;var i,j,r,g,b:word;begin
- for i:=0 to 31 do begin j:=i*63 div 31; setColor(i,j,j,j); end;
- for i:=0 to 223 do begin
- b:=i and 3;
- g:=(i shr 2)and 7;
- r:=(i shr 5)and 7;
- setColor(i+32,r*63 div 6,g*63 div 7,b*63 div 3);
- end;
- end;
-
- var savedExitProc:pointer;
-
- procedure exitModeX; far; begin
- exitProc:=savedExitProc;
- setText;
- write(exitMsg);
- end;
-
- begin
- savedExitProc:=exitProc; exitProc:=@exitModeX;
- end.
-
-