graph.pp 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. This file implements the go32v2 support for the graph unit
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit Graph;
  12. interface
  13. {$i graphh.inc}
  14. {$i vesah.inc}
  15. CONST
  16. m640x200x16 = VGALo;
  17. m640x400x16 = VGAMed;
  18. m640x480x16 = VGAHi;
  19. { VESA Specific video modes. }
  20. m320x200x32k = $10D;
  21. m320x200x64k = $10E;
  22. m640x400x256 = $100;
  23. m640x480x256 = $101;
  24. m640x480x32k = $110;
  25. m640x480x64k = $111;
  26. m800x600x16 = $102;
  27. m800x600x256 = $103;
  28. m800x600x32k = $113;
  29. m800x600x64k = $114;
  30. m1024x768x16 = $104;
  31. m1024x768x256 = $105;
  32. m1024x768x32k = $116;
  33. m1024x768x64k = $117;
  34. m1280x1024x16 = $106;
  35. m1280x1024x256 = $107;
  36. m1280x1024x32k = $119;
  37. m1280x1024x64k = $11A;
  38. const
  39. UseLFB : boolean = false;
  40. UseNoSelector : boolean = false;
  41. LFBPointer : pointer = nil;
  42. { Helpful variable to get save/restore support in IDE PM }
  43. const
  44. DontClearGraphMemory : boolean = false;
  45. implementation
  46. uses
  47. go32,ports;
  48. const
  49. InternalDriverName = 'DOSGX';
  50. {$i graph.inc}
  51. Type
  52. TDPMIRegisters = go32.registers;
  53. {$asmmode intel}
  54. { How to access real mode memory }
  55. { using 32-bit DPMI memory }
  56. { 1. Allocate a descriptor }
  57. { 2. Set segment limit }
  58. { 3. Set base linear address }
  59. const
  60. {$ifdef fpc}
  61. VideoOfs : longint = 0; { Segment to draw to }
  62. {$else fpc}
  63. VideoOfs : word = 0; { Segment to draw to }
  64. {$endif fpc}
  65. FirstPlane = $0102; (* 02 = Index to Color plane Select, *)
  66. (* 01 = Enable color plane 1 *)
  67. { ; ===== VGA Register Values ===== }
  68. SCREEN_WIDTH = 80 ; { MODE-X 320 SCREEN WIDTH }
  69. { CHANGE THE VALUE IF OTHER MODES }
  70. { OTHER THEN 320 ARE USED. }
  71. ATTRIB_Ctrl = $03C0 ; { VGA Attribute Controller }
  72. GC_Index = $03CE ; { VGA Graphics Controller }
  73. SC_Index = $03C4 ; { VGA Sequencer Controller }
  74. SC_Data = $03C5 ; { VGA Sequencer Data Port }
  75. CRTC_Index = $03D4 ; { VGA CRT Controller }
  76. CRTC_Data = $03D5 ; { VGA CRT Controller Data }
  77. MISC_OUTPUT = $03C2 ; { VGA Misc Register }
  78. INPUT_1 = $03DA ; { Input Status #1 Register }
  79. DAC_WRITE_ADDR = $03C8 ; { VGA DAC Write Addr Register }
  80. DAC_READ_ADDR = $03C7 ; { VGA DAC Read Addr Register }
  81. PEL_DATA_REG = $03C9 ; { VGA DAC/PEL data Register R/W }
  82. PIXEL_PAN_REG = $033 ; { Attrib Index: Pixel Pan Reg }
  83. MAP_MASK = $002 ; { S= $Index: Write Map Mask reg }
  84. READ_MAP = $004 ; { GC Index: Read Map Register }
  85. START_DISP_HI = $00C ; { CRTC Index: Display Start Hi }
  86. START_DISP_LO = $00D ; { CRTC Index: Display Start Lo }
  87. MAP_MASK_PLANE1 = $00102 ; { Map Register + Plane 1 }
  88. MAP_MASK_PLANE2 = $01102 ; { Map Register + Plane 1 }
  89. ALL_PLANES_ON = $00F02 ; { Map Register + All Bit Planes }
  90. CHAIN4_OFF = $00604 ; { Chain 4 mode Off }
  91. ASYNC_RESET = $00100 ; { (A)synchronous Reset }
  92. SEQU_RESTART = $00300 ; { Sequencer Restart }
  93. LATCHES_ON = $00008 ; { Bit Mask + Data from Latches }
  94. LATCHES_OFF = $0FF08 ; { Bit Mask + Data from CPU }
  95. VERT_RETRACE = $08 ; { INPUT_1: Vertical Retrace Bit }
  96. PLANE_BITS = $03 ; { Bits 0-1 of Xpos = Plane # }
  97. ALL_PLANES = $0F ; { All Bit Planes Selected }
  98. CHAR_BITS = $0F ; { Bits 0-3 of Character Data }
  99. GET_CHAR_PTR = $01130 ; { VGA BIOS Func: Get Char Set }
  100. ROM_8x8_Lo = $03 ; { ROM 8x8 Char Set Lo Pointer }
  101. ROM_8x8_Hi = $04 ; { ROM 8x8 Char Set Hi Pointer }
  102. { Constants Specific for these routines }
  103. NUM_MODES = $8 ; { # of Mode X Variations }
  104. { in 16 color modes, the actual colors used are not 0..15, but: }
  105. ToRealCols16: Array[0..15] of word =
  106. (0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63);
  107. var
  108. ScrWidth : word absolute $40:$4a;
  109. inWindows: boolean;
  110. {$ifndef tp}
  111. Procedure seg_bytemove(sseg : word;source : longint;dseg : word;dest : longint;count : longint); assembler;
  112. asm
  113. push edi
  114. push esi
  115. push es
  116. push ds
  117. cld
  118. mov ecx,count
  119. mov esi,source
  120. mov edi,dest
  121. mov ax,dseg
  122. mov es,ax
  123. mov ax,sseg
  124. mov ds,ax
  125. rep movsb
  126. pop ds
  127. pop es
  128. pop esi
  129. pop edi
  130. end ['ECX','EAX'];
  131. {$endif tp}
  132. Procedure CallInt10(val_ax : word); assembler;
  133. asm
  134. {$IFNDEF REGCALL}
  135. mov ax,val_ax
  136. {$ENDIF REGCALL}
  137. {$ifdef fpc}
  138. push ebp
  139. push esi
  140. push edi
  141. push ebx
  142. {$endif fpc}
  143. int 10h
  144. {$ifdef fpc}
  145. pop ebx
  146. pop edi
  147. pop esi
  148. pop ebp
  149. {$endif fpc}
  150. end ['EAX'];
  151. {************************************************************************}
  152. {* 4-bit planar VGA mode routines *}
  153. {************************************************************************}
  154. Procedure Init640x200x16; {$ifndef fpc}far;{$endif fpc}
  155. begin
  156. if DontClearGraphMemory then
  157. CallInt10($8e)
  158. else
  159. CallInt10($e);
  160. end;
  161. Procedure Init640x350x16; {$ifndef fpc}far;{$endif fpc}
  162. begin
  163. if DontClearGraphMemory then
  164. CallInt10($90)
  165. else
  166. CallInt10($10);
  167. end;
  168. Procedure Init640x480x16; {$ifndef fpc}far;{$endif fpc}
  169. begin
  170. if DontClearGraphMemory then
  171. CallInt10($92)
  172. else
  173. CallInt10($12);
  174. end;
  175. Procedure PutPixel16(X,Y : smallint; Pixel: Word); {$ifndef fpc}far;{$endif fpc}
  176. {$ifndef asmgraph}
  177. var offset: word;
  178. dummy: byte;
  179. {$endif asmgraph}
  180. Begin
  181. X:= X + StartXViewPort;
  182. Y:= Y + StartYViewPort;
  183. { convert to absolute coordinates and then verify clipping...}
  184. if ClipPixels then
  185. Begin
  186. if (X < StartXViewPort) or (X > (StartXViewPort + ViewWidth)) then
  187. exit;
  188. if (Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight)) then
  189. exit;
  190. end;
  191. {$ifndef asmgraph}
  192. offset := y * 80 + (x shr 3) + VideoOfs;
  193. PortW[$3ce] := $0f01; { Index 01 : Enable ops on all 4 planes }
  194. PortW[$3ce] := (Pixel and $ff) shl 8; { Index 00 : Enable correct plane and write color }
  195. Port[$3ce] := 8;
  196. Port[$3cf] := $80 shr (x and $7); { Select correct bits to modify }
  197. dummy := Mem[SegA000: offset]; { Latch the data into host space. }
  198. Mem[Sega000: offset] := dummy; { Write the data into video memory }
  199. PortW[$3ce] := $ff08; { Enable all bit planes. }
  200. PortW[$3ce] := $0001; { Index 01 : Disable ops on all four planes. }
  201. {$else asmgraph}
  202. asm
  203. {$ifndef fpc}
  204. mov es, [SegA000]
  205. { enable the set / reset function and load the color }
  206. mov dx, 3ceh
  207. mov ax, 0f01h
  208. out dx, ax
  209. { setup set/reset register }
  210. mov ax, [Pixel]
  211. shl ax, 8
  212. out dx, ax
  213. { setup the bit mask register }
  214. mov al, 8
  215. out dx, al
  216. inc dx
  217. { load the bitmask register }
  218. mov cx, [X]
  219. and cx, 0007h
  220. mov al, 80h
  221. shr al, cl
  222. out dx, ax
  223. { get the x index and divide by 8 for 16-color }
  224. mov ax,[X]
  225. shr ax,3
  226. push ax
  227. { determine the address }
  228. mov ax,80
  229. mov bx,[Y]
  230. mul bx
  231. pop cx
  232. add ax,cx
  233. mov di,ax
  234. add di, [VideoOfs]
  235. { send the data through the display memory through set/reset }
  236. mov bl,es:[di]
  237. mov es:[di],bl
  238. { reset for formal vga operation }
  239. mov dx,3ceh
  240. mov ax,0ff08h
  241. out dx,ax
  242. { restore enable set/reset register }
  243. mov ax,0001h
  244. out dx,ax
  245. {$else fpc}
  246. push eax
  247. push ebx
  248. push ecx
  249. push edx
  250. push edi
  251. { enable the set / reset function and load the color }
  252. mov dx, 3ceh
  253. mov ax, 0f01h
  254. out dx, ax
  255. { setup set/reset register }
  256. mov ax, [Pixel]
  257. shl ax, 8
  258. out dx, ax
  259. { setup the bit mask register }
  260. mov al, 8
  261. out dx, al
  262. inc dx
  263. { load the bitmask register }
  264. mov cx, [X]
  265. and cx, 0007h
  266. mov al, 80h
  267. shr al, cl
  268. out dx, ax
  269. { get the x index and divide by 8 for 16-color }
  270. movzx eax,[X]
  271. shr eax,3
  272. push eax
  273. { determine the address }
  274. mov eax,80
  275. mov bx,[Y]
  276. mul bx
  277. pop ecx
  278. add eax,ecx
  279. mov edi,eax
  280. add edi, [VideoOfs]
  281. { send the data through the display memory through set/reset }
  282. mov bl,fs:[edi+$a0000]
  283. mov fs:[edi+$a0000],bl
  284. { reset for formal vga operation }
  285. mov dx,3ceh
  286. mov ax,0ff08h
  287. out dx,ax
  288. { restore enable set/reset register }
  289. mov ax,0001h
  290. out dx,ax
  291. pop edi
  292. pop edx
  293. pop ecx
  294. pop ebx
  295. pop eax
  296. {$endif fpc}
  297. end;
  298. {$endif asmgraph}
  299. end;
  300. Function GetPixel16(X,Y: smallint):word; {$ifndef fpc}far;{$endif fpc}
  301. {$ifndef asmgraph}
  302. Var dummy, offset: Word;
  303. shift: byte;
  304. {$endif asmgraph}
  305. Begin
  306. X:= X + StartXViewPort;
  307. Y:= Y + StartYViewPort;
  308. {$ifndef asmgraph}
  309. offset := Y * 80 + (x shr 3) + VideoOfs;
  310. Port[$3ce] := 4;
  311. shift := 7 - (X and 7);
  312. Port[$3cf] := 0;
  313. dummy := (Mem[Sega000:offset] shr shift) and 1;
  314. Port[$3cf] := 1;
  315. dummy := dummy or (((Mem[Sega000:offset] shr shift) and 1) shl 1);
  316. Port[$3cf] := 2;
  317. dummy := dummy or (((Mem[Sega000:offset] shr shift) and 1) shl 2);
  318. Port[$3cf] := 3;
  319. dummy := dummy or (((Mem[Sega000:offset] shr shift) and 1) shl 3);
  320. GetPixel16 := dummy;
  321. {$else asmgraph}
  322. asm
  323. {$ifndef fpc}
  324. mov ax, [X] { Get X address }
  325. push ax
  326. shr ax, 3
  327. push ax
  328. mov ax,80
  329. mov bx,[Y]
  330. mul bx
  331. pop cx
  332. add ax,cx
  333. mov si,ax { SI = correct offset into video segment }
  334. mov es,[SegA000]
  335. add si,[VideoOfs] { Point to correct page offset... }
  336. mov dx,03ceh
  337. mov ax,4
  338. out dx,al
  339. inc dx
  340. pop ax
  341. and ax,0007h
  342. mov cl,07
  343. sub cl,al
  344. mov bl,cl
  345. { read plane 0 }
  346. mov al,0 { Select plane to read }
  347. out dx,al
  348. mov al,es:[si] { read display memory }
  349. shr al,cl
  350. and al,01h
  351. mov ah,al { save bit in AH }
  352. { read plane 1 }
  353. mov al,1 { Select plane to read }
  354. out dx,al
  355. mov al,es:[si]
  356. shr al,cl
  357. and al,01h
  358. shl al,1
  359. or ah,al { save bit in AH }
  360. { read plane 2 }
  361. mov al,2 { Select plane to read }
  362. out dx,al
  363. mov al,es:[si]
  364. shr al,cl
  365. and al,01h
  366. shl al,2
  367. or ah,al { save bit in AH }
  368. { read plane 3 }
  369. mov al,3 { Select plane to read }
  370. out dx,al
  371. mov al,es:[si]
  372. shr al,cl
  373. and al,01h
  374. shl al,3
  375. or ah,al { save bit in AH }
  376. mov al,ah { 16-bit pixel in AX }
  377. xor ah,ah
  378. mov @Result, ax
  379. {$else fpc}
  380. push eax
  381. push ebx
  382. push ecx
  383. push edx
  384. push esi
  385. movzx eax, [X] { Get X address }
  386. push eax
  387. shr eax, 3
  388. push eax
  389. mov eax,80
  390. mov bx,[Y]
  391. mul bx
  392. pop ecx
  393. add eax,ecx
  394. mov esi,eax { SI = correct offset into video segment }
  395. add esi,[VideoOfs] { Point to correct page offset... }
  396. mov dx,03ceh
  397. mov ax,4
  398. out dx,al
  399. inc dx
  400. pop eax
  401. and eax,0007h
  402. mov cl,07
  403. sub cl,al
  404. mov bl,cl
  405. { read plane 0 }
  406. mov al,0 { Select plane to read }
  407. out dx,al
  408. mov al,fs:[esi+$a0000] { read display memory }
  409. shr al,cl
  410. and al,01h
  411. mov ah,al { save bit in AH }
  412. { read plane 1 }
  413. mov al,1 { Select plane to read }
  414. out dx,al
  415. mov al,fs:[esi+$a0000]
  416. shr al,cl
  417. and al,01h
  418. shl al,1
  419. or ah,al { save bit in AH }
  420. { read plane 2 }
  421. mov al,2 { Select plane to read }
  422. out dx,al
  423. mov al,fs:[esi+$a0000]
  424. shr al,cl
  425. and al,01h
  426. shl al,2
  427. or ah,al { save bit in AH }
  428. { read plane 3 }
  429. mov al,3 { Select plane to read }
  430. out dx,al
  431. mov al,fs:[esi+$a0000]
  432. shr al,cl
  433. and al,01h
  434. shl al,3
  435. or ah,al { save bit in AH }
  436. mov al,ah { 16-bit pixel in AX }
  437. xor ah,ah
  438. mov @Result, ax
  439. pop esi
  440. pop edx
  441. pop ecx
  442. pop ebx
  443. pop eax
  444. {$endif fpc}
  445. end;
  446. {$endif asmgraph}
  447. end;
  448. Procedure GetScanLine16(x1, x2, y: smallint; var data);
  449. var dummylong: longint;
  450. Offset, count, count2, amount, index: word;
  451. plane: byte;
  452. Begin
  453. inc(x1,StartXViewPort);
  454. inc(x2,StartXViewPort);
  455. {$ifdef logging}
  456. LogLn('GetScanLine16 start, length to get: '+strf(x2-x1+1)+' at y = '+strf(y));
  457. {$Endif logging}
  458. offset := (Y + StartYViewPort) * 80 + (x1 shr 3) + VideoOfs;
  459. {$ifdef logging}
  460. LogLn('Offset: '+HexStr(offset,4)+' - ' + strf(offset));
  461. {$Endif logging}
  462. { first get enough pixels so offset is 32bit aligned }
  463. amount := 0;
  464. index := 0;
  465. If ((x1 and 31) <> 0) Or
  466. ((x2-x1+1) < 32) Then
  467. Begin
  468. If ((x2-x1+1) >= 32+32-(x1 and 31)) Then
  469. amount := 32-(x1 and 31)
  470. Else amount := x2-x1+1;
  471. {$ifdef logging}
  472. LogLn('amount to align to 32bits or to get all: ' + strf(amount));
  473. {$Endif logging}
  474. For count := 0 to amount-1 do
  475. WordArray(Data)[Count] := getpixel16(x1-StartXViewPort+Count,y);
  476. index := amount;
  477. Inc(Offset,(amount+7) shr 3);
  478. {$ifdef logging}
  479. LogLn('offset now: '+HexStr(offset,4)+' - ' + strf(offset));
  480. LogLn('index now: '+strf(index));
  481. {$Endif logging}
  482. End;
  483. amount := x2-x1+1 - amount;
  484. {$ifdef logging}
  485. LogLn('amount left: ' + strf(amount));
  486. {$Endif logging}
  487. If amount = 0 Then Exit;
  488. Port[$3ce] := 4;
  489. { first get everything from plane 3 (4th plane) }
  490. Port[$3cf] := 3;
  491. Count := 0;
  492. For Count := 1 to (amount shr 5) Do
  493. Begin
  494. dummylong := MemL[SegA000:offset+(Count-1)*4];
  495. dummylong :=
  496. ((dummylong and $ff) shl 24) or
  497. ((dummylong and $ff00) shl 8) or
  498. ((dummylong and $ff0000) shr 8) or
  499. ((dummylong and $ff000000) shr 24);
  500. For Count2 := 31 downto 0 Do
  501. Begin
  502. WordArray(Data)[index+Count2] := DummyLong and 1;
  503. DummyLong := DummyLong shr 1;
  504. End;
  505. Inc(Index, 32);
  506. End;
  507. { Now get the data from the 3 other planes }
  508. plane := 3;
  509. Repeat
  510. Dec(Index,Count*32);
  511. Dec(plane);
  512. Port[$3cf] := plane;
  513. Count := 0;
  514. For Count := 1 to (amount shr 5) Do
  515. Begin
  516. dummylong := MemL[SegA000:offset+(Count-1)*4];
  517. dummylong :=
  518. ((dummylong and $ff) shl 24) or
  519. ((dummylong and $ff00) shl 8) or
  520. ((dummylong and $ff0000) shr 8) or
  521. ((dummylong and $ff000000) shr 24);
  522. For Count2 := 31 downto 0 Do
  523. Begin
  524. WordArray(Data)[index+Count2] :=
  525. (WordArray(Data)[index+Count2] shl 1) or (DummyLong and 1);
  526. DummyLong := DummyLong shr 1;
  527. End;
  528. Inc(Index, 32);
  529. End;
  530. Until plane = 0;
  531. amount := amount and 31;
  532. Dec(index);
  533. {$ifdef Logging}
  534. LogLn('Last array index written to: '+strf(index));
  535. LogLn('amount left: '+strf(amount)+' starting at x = '+strf(index+1));
  536. {$Endif logging}
  537. dec(x1,startXViewPort);
  538. For Count := 1 to amount Do
  539. WordArray(Data)[index+Count] := getpixel16(x1+index+Count,y);
  540. {$ifdef logging}
  541. inc(x1,startXViewPort);
  542. LogLn('First 32 bytes gotten with getscanline16: ');
  543. If x2-x1+1 >= 32 Then
  544. Count2 := 32
  545. Else Count2 := x2-x1+1;
  546. For Count := 0 to Count2-1 Do
  547. Log(strf(WordArray(Data)[Count])+' ');
  548. LogLn('');
  549. If x2-x1+1 >= 32 Then
  550. Begin
  551. LogLn('Last 32 bytes gotten with getscanline16: ');
  552. For Count := 31 downto 0 Do
  553. Log(strf(WordArray(Data)[x2-x1-Count])+' ');
  554. End;
  555. LogLn('');
  556. GetScanLineDefault(x1-StartXViewPort,x2-StartXViewPort,y,Data);
  557. LogLn('First 32 bytes gotten with getscanlinedef: ');
  558. If x2-x1+1 >= 32 Then
  559. Count2 := 32
  560. Else Count2 := x2-x1+1;
  561. For Count := 0 to Count2-1 Do
  562. Log(strf(WordArray(Data)[Count])+' ');
  563. LogLn('');
  564. If x2-x1+1 >= 32 Then
  565. Begin
  566. LogLn('Last 32 bytes gotten with getscanlinedef: ');
  567. For Count := 31 downto 0 Do
  568. Log(strf(WordArray(Data)[x2-x1-Count])+' ');
  569. End;
  570. LogLn('');
  571. LogLn('GetScanLine16 end');
  572. {$Endif logging}
  573. End;
  574. Procedure DirectPutPixel16(X,Y : smallint); {$ifndef fpc}far;{$endif fpc}
  575. { x,y -> must be in global coordinates. No clipping. }
  576. var
  577. color: word;
  578. {$ifndef asmgraph}
  579. offset: word;
  580. dummy: byte;
  581. {$endif asmgraph}
  582. begin
  583. case CurrentWriteMode of
  584. XORPut:
  585. begin
  586. { getpixel wants local/relative coordinates }
  587. Color := GetPixel(x-StartXViewPort,y-StartYViewPort);
  588. Color := CurrentColor Xor Color;
  589. end;
  590. OrPut:
  591. begin
  592. { getpixel wants local/relative coordinates }
  593. Color := GetPixel(x-StartXViewPort,y-StartYViewPort);
  594. Color := CurrentColor Or Color;
  595. end;
  596. AndPut:
  597. begin
  598. { getpixel wants local/relative coordinates }
  599. Color := GetPixel(x-StartXViewPort,y-StartYViewPort);
  600. Color := CurrentColor And Color;
  601. end;
  602. NotPut:
  603. begin
  604. Color := (Not CurrentColor) and 15;
  605. end
  606. else
  607. Color := CurrentColor;
  608. end;
  609. {$ifndef asmgraph}
  610. offset := Y * 80 + (X shr 3) + VideoOfs;
  611. PortW[$3ce] := $f01;
  612. PortW[$3ce] := Color shl 8;
  613. Port[$3ce] := 8;
  614. Port[$3cf] := $80 shr (X and 7);
  615. dummy := Mem[SegA000: offset];
  616. Mem[Sega000: offset] := dummy;
  617. PortW[$3ce] := $ff08;
  618. PortW[$3ce] := $0001;
  619. {$else asmgraph}
  620. { note: still needs xor/or/and/notput support !!!!! (JM) }
  621. asm
  622. {$ifndef fpc}
  623. mov es, [SegA000]
  624. { enable the set / reset function and load the color }
  625. mov dx, 3ceh
  626. mov ax, 0f01h
  627. out dx, ax
  628. { setup set/reset register }
  629. mov ax, [Color]
  630. shl ax, 8
  631. out dx, ax
  632. { setup the bit mask register }
  633. mov al, 8
  634. out dx, al
  635. inc dx
  636. { load the bitmask register }
  637. mov cx, [X]
  638. and cx, 0007h
  639. mov al, 80h
  640. shr al, cl
  641. out dx, ax
  642. { get the x index and divide by 8 for 16-color }
  643. mov ax,[X]
  644. shr ax,3
  645. push ax
  646. { determine the address }
  647. mov ax,80
  648. mov bx,[Y]
  649. mul bx
  650. pop cx
  651. add ax,cx
  652. mov di,ax
  653. { send the data through the display memory through set/reset }
  654. add di,[VideoOfs] { add correct page }
  655. mov bl,es:[di]
  656. mov es:[di],bl
  657. { reset for formal vga operation }
  658. mov dx,3ceh
  659. mov ax,0ff08h
  660. out dx,ax
  661. { restore enable set/reset register }
  662. mov ax,0001h
  663. out dx,ax
  664. {$else fpc}
  665. push eax
  666. push ebx
  667. push ecx
  668. push edx
  669. push edi
  670. { enable the set / reset function and load the color }
  671. mov dx, 3ceh
  672. mov ax, 0f01h
  673. out dx, ax
  674. { setup set/reset register }
  675. mov ax, [Color]
  676. shl ax, 8
  677. out dx, ax
  678. { setup the bit mask register }
  679. mov al, 8
  680. out dx, al
  681. inc dx
  682. { load the bitmask register }
  683. mov cx, [X]
  684. and cx, 0007h
  685. mov al, 80h
  686. shr al, cl
  687. out dx, ax
  688. { get the x index and divide by 8 for 16-color }
  689. movzx eax,[X]
  690. shr eax,3
  691. push eax
  692. { determine the address }
  693. mov eax,80
  694. mov bx,[Y]
  695. mul bx
  696. pop ecx
  697. add eax,ecx
  698. mov edi,eax
  699. { send the data through the display memory through set/reset }
  700. add edi,[VideoOfs] { add correct page }
  701. mov bl,fs:[edi+$a0000]
  702. mov fs:[edi+$a0000],bl
  703. { reset for formal vga operation }
  704. mov dx,3ceh
  705. mov ax,0ff08h
  706. out dx,ax
  707. { restore enable set/reset register }
  708. mov ax,0001h
  709. out dx,ax
  710. pop edi
  711. pop edx
  712. pop ecx
  713. pop ebx
  714. pop eax
  715. {$endif fpc}
  716. end;
  717. {$endif asmgraph}
  718. end;
  719. procedure HLine16(x,x2,y: smallint); {$ifndef fpc}far;{$endif fpc}
  720. var
  721. xtmp: smallint;
  722. ScrOfs,HLength : word;
  723. LMask,RMask : byte;
  724. Begin
  725. { must we swap the values? }
  726. if x > x2 then
  727. Begin
  728. xtmp := x2;
  729. x2 := x;
  730. x:= xtmp;
  731. end;
  732. { First convert to global coordinates }
  733. X := X + StartXViewPort;
  734. X2 := X2 + StartXViewPort;
  735. Y := Y + StartYViewPort;
  736. if ClipPixels then
  737. Begin
  738. if LineClipped(x,y,x2,y,StartXViewPort,StartYViewPort,
  739. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  740. exit;
  741. end;
  742. ScrOfs:=y*ScrWidth+x div 8;
  743. HLength:=x2 div 8-x div 8;
  744. LMask:=$ff shr (x and 7);
  745. {$ifopt r+}
  746. {$define rangeOn}
  747. {$r-}
  748. {$endif}
  749. {$ifopt q+}
  750. {$define overflowOn}
  751. {$q-}
  752. {$endif}
  753. RMask:=$ff shl (7-(x2 and 7));
  754. {$ifdef rangeOn}
  755. {$undef rangeOn}
  756. {$r+}
  757. {$endif}
  758. {$ifdef overflowOn}
  759. {$undef overflowOn}
  760. {$q+}
  761. {$endif}
  762. if HLength=0 then
  763. LMask:=LMask and RMask;
  764. Port[$3ce]:=0;
  765. If CurrentWriteMode <> NotPut Then
  766. Port[$3cf]:= CurrentColor
  767. else Port[$3cf]:= not CurrentColor;
  768. Port[$3ce]:=1;
  769. Port[$3cf]:=$f;
  770. Port[$3ce]:=3;
  771. case CurrentWriteMode of
  772. XORPut:
  773. Port[$3cf]:=3 shl 3;
  774. ANDPut:
  775. Port[$3cf]:=1 shl 3;
  776. ORPut:
  777. Port[$3cf]:=2 shl 3;
  778. NormalPut, NotPut:
  779. Port[$3cf]:=0
  780. else
  781. Port[$3cf]:=0
  782. end;
  783. Port[$3ce]:=8;
  784. Port[$3cf]:=LMask;
  785. {$ifopt r+}
  786. {$define rangeOn}
  787. {$r-}
  788. {$endif}
  789. {$ifopt q+}
  790. {$define overflowOn}
  791. {$q-}
  792. {$endif}
  793. Mem[SegA000:ScrOfs]:=Mem[SegA000:ScrOfs]+1;
  794. {$ifdef rangeOn}
  795. {$undef rangeOn}
  796. {$r+}
  797. {$endif}
  798. {$ifdef overflowOn}
  799. {$undef overflowOn}
  800. {$q+}
  801. {$endif}
  802. Port[$3ce]:=8;
  803. if HLength>0 then
  804. begin
  805. dec(HLength);
  806. inc(ScrOfs);
  807. if HLength>0 then
  808. begin
  809. Port[$3cf]:=$ff;
  810. {$ifndef tp}
  811. seg_bytemove(dosmemselector,$a0000+ScrOfs,dosmemselector,$a0000+ScrOfs,HLength);
  812. {$else}
  813. move(Ptr(SegA000,ScrOfs)^, Ptr(SegA000,ScrOfs)^, HLength);
  814. {$endif}
  815. ScrOfs:=ScrOfs+HLength;
  816. end;
  817. Port[$3cf]:=RMask;
  818. {$ifopt r+}
  819. {$define rangeOn}
  820. {$r-}
  821. {$endif}
  822. {$ifopt q+}
  823. {$define overflowOn}
  824. {$q-}
  825. {$endif}
  826. Mem[Sega000:ScrOfs]:=Mem[SegA000:ScrOfs]+1;
  827. {$ifdef rangeOn}
  828. {$undef rangeOn}
  829. {$r+}
  830. {$endif}
  831. {$ifdef overflowOn}
  832. {$undef overflowOn}
  833. {$q+}
  834. {$endif}
  835. end;
  836. { clean up }
  837. Port[$3cf]:=0;
  838. Port[$3ce]:=8;
  839. Port[$3cf]:=$ff;
  840. Port[$3ce]:=1;
  841. Port[$3cf]:=0;
  842. Port[$3ce]:=3;
  843. Port[$3cf]:=0;
  844. end;
  845. procedure VLine16(x,y,y2: smallint); {$ifndef fpc}far;{$endif fpc}
  846. var
  847. ytmp: smallint;
  848. ScrOfs,i : longint;
  849. BitMask : byte;
  850. Begin
  851. { must we swap the values? }
  852. if y > y2 then
  853. Begin
  854. ytmp := y2;
  855. y2 := y;
  856. y:= ytmp;
  857. end;
  858. { First convert to global coordinates }
  859. X := X + StartXViewPort;
  860. Y2 := Y2 + StartYViewPort;
  861. Y := Y + StartYViewPort;
  862. if ClipPixels then
  863. Begin
  864. if LineClipped(x,y,x,y2,StartXViewPort,StartYViewPort,
  865. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  866. exit;
  867. end;
  868. ScrOfs:=y*ScrWidth+x div 8;
  869. BitMask:=$80 shr (x and 7);
  870. Port[$3ce]:=0;
  871. If CurrentWriteMode <> NotPut Then
  872. Port[$3cf]:= CurrentColor
  873. else Port[$3cf]:= not CurrentColor;
  874. Port[$3ce]:=1;
  875. Port[$3cf]:=$f;
  876. Port[$3ce]:=8;
  877. Port[$3cf]:=BitMask;
  878. Port[$3ce]:=3;
  879. case CurrentWriteMode of
  880. XORPut:
  881. Port[$3cf]:=3 shl 3;
  882. ANDPut:
  883. Port[$3cf]:=1 shl 3;
  884. ORPut:
  885. Port[$3cf]:=2 shl 3;
  886. NormalPut, NotPut:
  887. Port[$3cf]:=0
  888. else
  889. Port[$3cf]:=0
  890. end;
  891. for i:=y to y2 do
  892. begin
  893. {$ifopt r+}
  894. {$define rangeOn}
  895. {$r-}
  896. {$endif}
  897. {$ifopt q+}
  898. {$define overflowOn}
  899. {$q-}
  900. {$endif}
  901. Mem[SegA000:ScrOfs]:=Mem[Sega000:ScrOfs]+1;
  902. {$ifdef rangeOn}
  903. {$undef rangeOn}
  904. {$r+}
  905. {$endif}
  906. {$ifdef overflowOn}
  907. {$undef overflowOn}
  908. {$q+}
  909. {$endif}
  910. ScrOfs:=ScrOfs+ScrWidth;
  911. end;
  912. { clean up }
  913. Port[$3cf]:=0;
  914. Port[$3ce]:=8;
  915. Port[$3cf]:=$ff;
  916. Port[$3ce]:=1;
  917. Port[$3cf]:=0;
  918. Port[$3ce]:=3;
  919. Port[$3cf]:=0;
  920. End;
  921. procedure SetVisual480(page: word); {$ifndef fpc}far;{$endif fpc}
  922. { no page flipping supPort in 640x480 mode }
  923. begin
  924. VideoOfs := 0;
  925. end;
  926. procedure SetActive480(page: word); {$ifndef fpc}far;{$endif fpc}
  927. { no page flipping supPort in 640x480 mode }
  928. begin
  929. VideoOfs := 0;
  930. end;
  931. procedure SetVisual200(page: word); {$ifndef fpc}far;{$endif fpc}
  932. { two page supPort... }
  933. begin
  934. if page > HardwarePages then exit;
  935. asm
  936. mov ax,[page] { only lower byte is supPorted. }
  937. mov ah,05h
  938. {$ifdef fpc}
  939. push ebp
  940. push esi
  941. push edi
  942. push ebx
  943. {$endif fpc}
  944. int 10h
  945. {$ifdef fpc}
  946. pop ebx
  947. pop edi
  948. pop esi
  949. pop ebp
  950. {$endif fpc}
  951. { read start address }
  952. mov dx,3d4h
  953. mov al,0ch
  954. out dx,al
  955. inc dx
  956. in al,dx
  957. mov ah,al
  958. dec dx
  959. mov al,0dh
  960. out dx,al
  961. in al,dx
  962. end ['EDX','EAX'];
  963. end;
  964. procedure SetActive200(page: word); {$ifndef fpc}far;{$endif fpc}
  965. { two page supPort... }
  966. begin
  967. case page of
  968. 0 : VideoOfs := 0;
  969. 1 : VideoOfs := 16384;
  970. 2 : VideoOfs := 32768;
  971. else
  972. VideoOfs := 0;
  973. end;
  974. end;
  975. procedure SetVisual350(page: word); {$ifndef fpc}far;{$endif fpc}
  976. { one page supPort... }
  977. begin
  978. if page > HardwarePages then exit;
  979. asm
  980. mov ax,[page] { only lower byte is supPorted. }
  981. mov ah,05h
  982. {$ifdef fpc}
  983. push ebp
  984. push esi
  985. push edi
  986. push ebx
  987. {$endif fpc}
  988. int 10h
  989. {$ifdef fpc}
  990. pop ebx
  991. pop edi
  992. pop esi
  993. pop ebp
  994. {$endif fpc}
  995. end ['EAX'];
  996. end;
  997. procedure SetActive350(page: word); {$ifndef fpc}far;{$endif fpc}
  998. { one page supPort... }
  999. begin
  1000. case page of
  1001. 0 : VideoOfs := 0;
  1002. 1 : VideoOfs := 32768;
  1003. else
  1004. VideoOfs := 0;
  1005. end;
  1006. end;
  1007. {************************************************************************}
  1008. {* 320x200x256c Routines *}
  1009. {************************************************************************}
  1010. Procedure Init320; {$ifndef fpc}far;{$endif fpc}
  1011. begin
  1012. if DontClearGraphMemory then
  1013. CallInt10($93)
  1014. else
  1015. CallInt10($13);
  1016. end;
  1017. Procedure PutPixel320(X,Y : smallint; Pixel: Word); {$ifndef fpc}far;{$endif fpc}
  1018. { x,y -> must be in local coordinates. Clipping if required. }
  1019. {$ifndef fpc}
  1020. Begin
  1021. X:= X + StartXViewPort;
  1022. Y:= Y + StartYViewPort;
  1023. { convert to absolute coordinates and then verify clipping...}
  1024. if ClipPixels then
  1025. Begin
  1026. if (X < StartXViewPort) or (X > (StartXViewPort + ViewWidth)) then
  1027. exit;
  1028. if (Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight)) then
  1029. exit;
  1030. end;
  1031. asm
  1032. mov es, [SegA000]
  1033. mov ax, [Y]
  1034. mov di, [X]
  1035. xchg ah, al { The value of Y must be in AH }
  1036. add di, ax
  1037. shr ax, 2
  1038. add di, ax
  1039. add di, [VideoOfs] { point to correct page.. }
  1040. mov ax, [Pixel]
  1041. mov es:[di], al
  1042. end;
  1043. {$else fpc}
  1044. assembler;
  1045. asm
  1046. push eax
  1047. push ebx
  1048. push ecx
  1049. push edi
  1050. {$IFDEF REGCALL}
  1051. movsx edi, ax
  1052. movsx ebx, dx
  1053. mov al, cl
  1054. {$ELSE REGCALL}
  1055. movsx edi, x
  1056. movsx ebx, y
  1057. {$ENDIF REGCALL}
  1058. cmp clippixels, 0
  1059. je @putpix320noclip
  1060. test edi, edi
  1061. jl @putpix320done
  1062. test ebx, ebx
  1063. jl @putpix320done
  1064. cmp di, ViewWidth
  1065. jg @putpix320done
  1066. cmp bx, ViewHeight
  1067. jg @putpix320done
  1068. @putpix320noclip:
  1069. movsx ecx, StartYViewPort
  1070. movsx edx, StartXViewPort
  1071. add ebx, ecx
  1072. add edi, edx
  1073. { add edi, [VideoOfs] no multiple pages in 320*200*256 }
  1074. {$IFNDEF REGCALL}
  1075. mov ax, [pixel]
  1076. {$ENDIF REGCALL}
  1077. shl ebx, 6
  1078. add edi, ebx
  1079. mov fs:[edi+ebx*4+$a0000], al
  1080. @putpix320done:
  1081. pop edi
  1082. pop ecx
  1083. pop ebx
  1084. pop eax
  1085. {$endif fpc}
  1086. end;
  1087. Function GetPixel320(X,Y: smallint):word; {$ifndef fpc}far;{$endif fpc}
  1088. {$ifndef fpc}
  1089. Begin
  1090. X:= X + StartXViewPort;
  1091. Y:= Y + StartYViewPort;
  1092. asm
  1093. mov es, [SegA000]
  1094. mov ax, [Y]
  1095. mov di, [X]
  1096. xchg ah, al { The value of Y must be in AH }
  1097. add di, ax
  1098. shr ax, 2
  1099. add di, ax
  1100. xor ax, ax
  1101. add di, [VideoOfs] { point to correct gfx page ... }
  1102. mov al,es:[di]
  1103. mov @Result,ax
  1104. end;
  1105. {$else fpc}
  1106. assembler;
  1107. asm
  1108. push eax
  1109. push ebx
  1110. push ecx
  1111. push edx
  1112. push edi
  1113. {$IFDEF REGCALL}
  1114. movsx edi, ax
  1115. movsx ebx, dx
  1116. {$ELSE REGCALL}
  1117. movsx edi, x
  1118. movsx ebx, y
  1119. {$ENDIF REGCALL}
  1120. movsx ecx, StartYViewPort
  1121. movsx edx, StartXViewPort
  1122. add ebx, ecx
  1123. add edi, edx
  1124. { add edi, [VideoOfs] no multiple pages in 320*200*256 }
  1125. shl ebx, 6
  1126. add edi, ebx
  1127. movzx ax, byte ptr fs:[edi+ebx*4+$a0000]
  1128. pop edi
  1129. pop edx
  1130. pop ecx
  1131. pop ebx
  1132. pop eax
  1133. {$endif fpc}
  1134. end;
  1135. Procedure DirectPutPixel320(X,Y : smallint); {$ifndef fpc}far;{$endif fpc}
  1136. { x,y -> must be in global coordinates. No clipping. }
  1137. {$ifndef asmgraph}
  1138. var offset: word;
  1139. dummy: Byte;
  1140. begin
  1141. dummy := CurrentColor;
  1142. offset := y * 320 + x + VideoOfs;
  1143. case CurrentWriteMode of
  1144. XorPut: dummy := dummy xor Mem[Sega000:offset];
  1145. OrPut: dummy := dummy or Mem[Sega000:offset];
  1146. AndPut: dummy := dummy and Mem[SegA000:offset];
  1147. NotPut: dummy := Not dummy;
  1148. end;
  1149. Mem[SegA000:offset] := dummy;
  1150. end;
  1151. {$else asmgraph}
  1152. { note: still needs or/and/notput support !!!!! (JM) }
  1153. assembler;
  1154. asm
  1155. {$ifndef fpc}
  1156. mov es, [SegA000]
  1157. mov ax, [Y]
  1158. mov di, [X]
  1159. xchg ah, al { The value of Y must be in AH }
  1160. add di, ax
  1161. shr ax, 2
  1162. add di, ax
  1163. { add di, [VideoOfs] no multiple pages support in 320*200*256 }
  1164. mov ax, [CurrentColor]
  1165. cmp [CurrentWriteMode],XORPut { check write mode }
  1166. jne @MOVMode
  1167. mov ah,es:[di] { read the byte... }
  1168. xor al,ah { xor it and return value into AL }
  1169. @MovMode:
  1170. mov es:[di], al
  1171. {$else fpc}
  1172. push eax
  1173. push ebx
  1174. push edi
  1175. {$IFDEF REGCALL}
  1176. movzx edi, ax
  1177. movzx ebx, dx
  1178. {$ELSE REGCALL}
  1179. movzx edi, x
  1180. movzx ebx, y
  1181. {$ENDIF REGCALL}
  1182. { add edi, [VideoOfs] no multiple pages in 320*200*256 }
  1183. shl ebx, 6
  1184. add edi, ebx
  1185. mov ax, [CurrentColor]
  1186. cmp [CurrentWriteMode],XORPut { check write mode }
  1187. jne @MOVMode
  1188. xor al, fs:[edi+ebx*4+$a0000]
  1189. @MovMode:
  1190. mov fs:[edi+ebx*4+$a0000], al
  1191. pop edi
  1192. pop ebx
  1193. pop eax
  1194. {$endif fpc}
  1195. end;
  1196. {$endif asmgraph}
  1197. procedure SetVisual320(page: word); {$ifndef fpc}far;{$endif fpc}
  1198. { no page supPort... }
  1199. begin
  1200. VideoOfs := 0;
  1201. end;
  1202. procedure SetActive320(page: word); {$ifndef fpc}far;{$endif fpc}
  1203. { no page supPort... }
  1204. begin
  1205. VideoOfs := 0;
  1206. end;
  1207. {************************************************************************}
  1208. {* Mode-X related routines *}
  1209. {************************************************************************}
  1210. const CrtAddress: word = 0;
  1211. procedure InitModeX; {$ifndef fpc}far;{$endif fpc}
  1212. begin
  1213. asm
  1214. {see if we are using color-/monochorme display}
  1215. MOV DX,3CCh {use output register: }
  1216. IN AL,DX
  1217. TEST AL,1 {is it a color display? }
  1218. MOV DX,3D4h
  1219. JNZ @L1 {yes }
  1220. MOV DX,3B4h {no }
  1221. @L1: {DX = 3B4h / 3D4h = CRTAddress-register for monochrome/color}
  1222. MOV CRTAddress,DX
  1223. MOV AX, 0013h
  1224. MOV BL, DontClearGraphMemory
  1225. OR BL,BL
  1226. JZ @L2
  1227. OR AX, 080h
  1228. @L2:
  1229. {$ifdef fpc}
  1230. push ebp
  1231. push esi
  1232. push edi
  1233. push ebx
  1234. {$EndIf fpc}
  1235. INT 10h
  1236. {$ifdef fpc}
  1237. pop ebx
  1238. pop edi
  1239. pop esi
  1240. pop ebp
  1241. {$EndIf fpc}
  1242. MOV DX,03C4h {select memory-mode-register at sequencer Port }
  1243. MOV AL,04
  1244. OUT DX,AL
  1245. INC DX {read in data via the according data register }
  1246. IN AL,DX
  1247. AND AL,0F7h {bit 3 := 0: don't chain the 4 planes}
  1248. OR AL,04 {bit 2 := 1: no odd/even mechanism }
  1249. OUT DX,AL {activate new settings }
  1250. MOV DX,03C4h {s.a.: address sequencer reg. 2 (=map-mask),... }
  1251. MOV AL,02
  1252. OUT DX,AL
  1253. INC DX
  1254. MOV AL,0Fh {...and allow access to all 4 bit maps }
  1255. OUT DX,AL
  1256. {$ifndef fpc}
  1257. MOV AX,[SegA000] {starting with segment A000h, set 8000h logical }
  1258. MOV ES,AX {words = 4*8000h physical words (because of 4 }
  1259. XOR DI,DI {bitplanes) to 0 }
  1260. XOR AX,AX
  1261. MOV CX,8000h
  1262. CLD
  1263. REP STOSW
  1264. {$else fpc}
  1265. push eax
  1266. push ecx
  1267. push es
  1268. push edi
  1269. push fs
  1270. mov edi, $a0000
  1271. pop es
  1272. xor eax, eax
  1273. mov ecx, 4000h
  1274. cld
  1275. rep stosd
  1276. pop edi
  1277. pop es
  1278. pop ecx
  1279. pop eax
  1280. {$EndIf fpc}
  1281. MOV DX,CRTAddress {address the underline-location-register at }
  1282. MOV AL,14h {the CRT-controller Port, read out the according }
  1283. OUT DX,AL {data register: }
  1284. INC DX
  1285. IN AL,DX
  1286. AND AL,0BFh {bit 6:=0: no double word addressing scheme in}
  1287. OUT DX,AL {video RAM }
  1288. DEC DX
  1289. MOV AL,17h {select mode control register }
  1290. OUT DX,AL
  1291. INC DX
  1292. IN AL,DX
  1293. OR AL,40h {bit 6 := 1: memory access scheme=linear bit array }
  1294. OUT DX,AL
  1295. end ['EDX','EBX','EAX'];
  1296. end;
  1297. Function GetPixelX(X,Y: smallint): word; {$ifndef fpc}far;{$endif fpc}
  1298. {$ifndef asmgraph}
  1299. var offset: word;
  1300. {$endif asmgraph}
  1301. begin
  1302. X:= X + StartXViewPort;
  1303. Y:= Y + StartYViewPort;
  1304. {$ifndef asmgraph}
  1305. offset := y * 80 + x shr 2 + VideoOfs;
  1306. PortW[$3ce] := ((x and 3) shl 8) + 4;
  1307. GetPixelX := Mem[SegA000:offset];
  1308. {$else asmgraph}
  1309. asm
  1310. {$ifndef fpc}
  1311. mov di,[Y] ; (* DI = Y coordinate *)
  1312. (* Multiply by 80 start *)
  1313. mov bx, di
  1314. shl di, 6 ; (* Faster on 286/386/486 machines *)
  1315. shl bx, 4
  1316. add di, bx ; (* Multiply Value by 80 *)
  1317. (* End multiply by 80 *)
  1318. mov cx, [X]
  1319. mov ax, cx
  1320. {DI = Y * LINESIZE, BX = X, coordinates admissible}
  1321. shr ax, 1 ; (* Faster on 286/86 machines *)
  1322. shr ax, 1
  1323. add di, ax ; {DI = Y * LINESIZE + (X SHR 2) }
  1324. add di, [VideoOfs] ; (* Pointing at start of Active page *)
  1325. (* Select plane to use *)
  1326. mov dx, 03c4h
  1327. mov ax, FirstPlane ; (* Map Mask & Plane Select Register *)
  1328. and cl, 03h ; (* Get Plane Bits *)
  1329. shl ah, cl ; (* Get Plane Select Value *)
  1330. out dx, ax
  1331. (* End selection of plane *)
  1332. mov es,[SegA000]
  1333. mov al, ES:[DI]
  1334. xor ah, ah
  1335. mov @Result, ax
  1336. {$else fpc}
  1337. push eax
  1338. push ebx
  1339. push ecx
  1340. push edx
  1341. push edi
  1342. movzx edi,[Y] ; (* DI = Y coordinate *)
  1343. (* Multiply by 80 start *)
  1344. mov ebx, edi
  1345. shl edi, 6 ; (* Faster on 286/386/486 machines *)
  1346. shl ebx, 4
  1347. add edi, ebx ; (* Multiply Value by 80 *)
  1348. (* End multiply by 80 *)
  1349. movzx ecx, [X]
  1350. movzx eax, [Y]
  1351. {DI = Y * LINESIZE, BX = X, coordinates admissible}
  1352. shr eax, 2
  1353. add edi, eax ; {DI = Y * LINESIZE + (X SHR 2) }
  1354. add edi, [VideoOfs] ; (* Pointing at start of Active page *)
  1355. (* Select plane to use *)
  1356. mov dx, 03c4h
  1357. mov ax, FirstPlane ; (* Map Mask & Plane Select Register *)
  1358. and cl, 03h ; (* Get Plane Bits *)
  1359. shl ah, cl ; (* Get Plane Select Value *)
  1360. out dx, ax
  1361. (* End selection of plane *)
  1362. mov ax, fs:[edi+$a0000]
  1363. mov @Result, ax
  1364. pop edi
  1365. pop edx
  1366. pop ecx
  1367. pop ebx
  1368. pop eax
  1369. {$endif fpc}
  1370. end;
  1371. {$endif asmgraph}
  1372. end;
  1373. procedure SetVisualX(page: word); {$ifndef fpc}far;{$endif fpc}
  1374. { 4 page supPort... }
  1375. Procedure SetVisibleStart(AOffset: word); Assembler;
  1376. (* Select where the left corner of the screen will be *)
  1377. { By Matt Pritchard }
  1378. asm
  1379. push ax
  1380. push cx
  1381. push dx
  1382. {$IFDEF REGCALL}
  1383. mov cx, ax
  1384. {$ENDIF REGCALL}
  1385. { Wait if we are currently in a Vertical Retrace }
  1386. MOV DX, INPUT_1 { Input Status #1 Register }
  1387. @DP_WAIT0:
  1388. IN AL, DX { Get VGA status }
  1389. AND AL, VERT_RETRACE { In Display mode yet? }
  1390. JNZ @DP_WAIT0 { If Not, wait for it }
  1391. { Set the Start Display Address to the new page }
  1392. MOV DX, CRTC_Index { We Change the VGA Sequencer }
  1393. MOV AL, START_DISP_LO { Display Start Low Register }
  1394. {$ifndef fpc}
  1395. MOV AH, BYTE PTR [AOffset] { Low 8 Bits of Start Addr }
  1396. OUT DX, AX { Set Display Addr Low }
  1397. MOV AL, START_DISP_HI { Display Start High Register }
  1398. MOV AH, BYTE PTR [AOffset+1] { High 8 Bits of Start Addr }
  1399. {$else fpc}
  1400. {$IFDEF REGCALL}
  1401. mov ah, cl
  1402. {$ELSE REGCALL}
  1403. mov ah, byte [AOffset]
  1404. {$ENDIF REGCALL}
  1405. out dx, ax
  1406. mov AL, START_DISP_HI
  1407. {$IFDEF REGCALL}
  1408. mov ah, ch
  1409. {$ELSE REGCALL}
  1410. mov ah, byte [AOffset+1]
  1411. {$ENDIF REGCALL}
  1412. {$endif fpc}
  1413. OUT DX, AX { Set Display Addr High }
  1414. { Wait for a Vertical Retrace to smooth out things }
  1415. MOV DX, INPUT_1 { Input Status #1 Register }
  1416. @DP_WAIT1:
  1417. IN AL, DX { Get VGA status }
  1418. AND AL, VERT_RETRACE { Vertical Retrace Start? }
  1419. JZ @DP_WAIT1 { If Not, wait for it }
  1420. { Now Set Display Starting Address }
  1421. pop dx
  1422. pop cx
  1423. pop ax
  1424. end;
  1425. {$ifdef fpc}
  1426. {$undef asmgraph}
  1427. {$endif fpc}
  1428. begin
  1429. Case page of
  1430. 0: SetVisibleStart(0);
  1431. 1: SetVisibleStart(16000);
  1432. 2: SetVisibleStart(32000);
  1433. 3: SetVisibleStart(48000);
  1434. else
  1435. SetVisibleStart(0);
  1436. end;
  1437. end;
  1438. procedure SetActiveX(page: word); {$ifndef fpc}far;{$endif fpc}
  1439. { 4 page supPort... }
  1440. begin
  1441. case page of
  1442. 0: VideoOfs := 0;
  1443. 1: VideoOfs := 16000;
  1444. 2: VideoOfs := 32000;
  1445. 3: VideoOfs := 48000;
  1446. else
  1447. VideoOfs:=0;
  1448. end;
  1449. end;
  1450. Procedure PutPixelX(X,Y: smallint; color:word); {$ifndef fpc}far;{$endif fpc}
  1451. {$ifndef asmgraph}
  1452. var offset: word;
  1453. {$endif asmgraph}
  1454. begin
  1455. X:= X + StartXViewPort;
  1456. Y:= Y + StartYViewPort;
  1457. { convert to absolute coordinates and then verify clipping...}
  1458. if ClipPixels then
  1459. Begin
  1460. if (X < StartXViewPort) or (X > (StartXViewPort + ViewWidth)) then
  1461. exit;
  1462. if (Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight)) then
  1463. exit;
  1464. end;
  1465. {$ifndef asmgraph}
  1466. offset := y * 80 + x shr 2 + VideoOfs;
  1467. PortW[$3c4] := (hi(word(FirstPlane)) shl 8) shl (x and 3)+ lo(word(FirstPlane));
  1468. Mem[SegA000:offset] := color;
  1469. {$else asmgraph}
  1470. asm
  1471. push ax
  1472. push bx
  1473. push cx
  1474. push dx
  1475. push es
  1476. push di
  1477. mov di,[Y] ; (* DI = Y coordinate *)
  1478. (* Multiply by 80 start *)
  1479. mov bx, di
  1480. shl di, 6 ; (* Faster on 286/386/486 machines *)
  1481. shl bx, 4
  1482. add di, bx ; (* Multiply Value by 80 *)
  1483. (* End multiply by 80 *)
  1484. mov cx, [X]
  1485. mov ax, cx
  1486. {DI = Y * LINESIZE, BX = X, coordinates admissible}
  1487. shr ax, 2
  1488. add di, ax ; {DI = Y * LINESIZE + (X SHR 2) }
  1489. add di, [VideoOfs] ; (* Pointing at start of Active page *)
  1490. (* Select plane to use *)
  1491. mov dx, 03c4h
  1492. mov ax, FirstPlane ; (* Map Mask & Plane Select Register *)
  1493. and cl, 03h ; (* Get Plane Bits *)
  1494. shl ah, cl ; (* Get Plane Select Value *)
  1495. out dx, ax
  1496. (* End selection of plane *)
  1497. mov es,[SegA000]
  1498. mov ax,[Color] ; { only lower byte is used. }
  1499. cmp [CurrentWriteMode],XORPut { check write mode }
  1500. jne @MOVMode
  1501. mov ah,es:[di] { read the byte... }
  1502. xor al,ah { xor it and return value into AL }
  1503. @MovMode:
  1504. mov es:[di], al
  1505. pop di
  1506. pop es
  1507. pop dx
  1508. pop cx
  1509. pop bx
  1510. pop ax
  1511. end;
  1512. {$endif asmgraph}
  1513. end;
  1514. Procedure DirectPutPixelX(X,Y: smallint); {$ifndef fpc}far;{$endif fpc}
  1515. { x,y -> must be in global coordinates. No clipping. }
  1516. {$ifndef asmgraph}
  1517. Var offset: Word;
  1518. dummy: Byte;
  1519. begin
  1520. offset := y * 80 + x shr 2 + VideoOfs;
  1521. case CurrentWriteMode of
  1522. XorPut:
  1523. begin
  1524. PortW[$3ce] := ((x and 3) shl 8) + 4;
  1525. dummy := CurrentColor xor Mem[Sega000: offset];
  1526. end;
  1527. OrPut:
  1528. begin
  1529. PortW[$3ce] := ((x and 3) shl 8) + 4;
  1530. dummy := CurrentColor or Mem[Sega000: offset];
  1531. end;
  1532. AndPut:
  1533. begin
  1534. PortW[$3ce] := ((x and 3) shl 8) + 4;
  1535. dummy := CurrentColor and Mem[Sega000: offset];
  1536. end;
  1537. NotPut: dummy := Not CurrentColor;
  1538. else dummy := CurrentColor;
  1539. end;
  1540. PortW[$3c4] := (hi(word(FirstPlane)) shl 8) shl (x and 3)+ lo(word(FirstPlane));
  1541. Mem[Sega000: offset] := Dummy;
  1542. end;
  1543. {$else asmgraph}
  1544. { note: still needs or/and/notput support !!!!! (JM) }
  1545. Assembler;
  1546. asm
  1547. push ax
  1548. push bx
  1549. push cx
  1550. push dx
  1551. push es
  1552. push di
  1553. {$IFDEF REGCALL}
  1554. mov cl, al
  1555. mov di, dx
  1556. {$ELSE REGCALL}
  1557. mov cx, [X]
  1558. mov ax, cx
  1559. mov di, [Y] ; (* DI = Y coordinate *)
  1560. {$ENDIF REGCALL}
  1561. (* Multiply by 80 start *)
  1562. mov bx, di
  1563. shl di, 6 ; (* Faster on 286/386/486 machines *)
  1564. shl bx, 4
  1565. add di, bx ; (* Multiply Value by 80 *)
  1566. (* End multiply by 80 *)
  1567. {DI = Y * LINESIZE, BX = X, coordinates admissible}
  1568. shr ax, 2
  1569. add di, ax ; {DI = Y * LINESIZE + (X SHR 2) }
  1570. add di, [VideoOfs] ; (* Pointing at start of Active page *)
  1571. (* Select plane to use *)
  1572. mov dx, 03c4h
  1573. mov ax, FirstPlane ; (* Map Mask & Plane Select Register *)
  1574. and cl, 03h ; (* Get Plane Bits *)
  1575. shl ah, cl ; (* Get Plane Select Value *)
  1576. out dx, ax
  1577. (* End selection of plane *)
  1578. mov es,[SegA000]
  1579. mov ax,[CurrentColor] ; { only lower byte is used. }
  1580. cmp [CurrentWriteMode],XORPut { check write mode }
  1581. jne @MOVMode
  1582. mov ah,es:[di] { read the byte... }
  1583. xor al,ah { xor it and return value into AL }
  1584. @MovMode:
  1585. mov es:[di], al
  1586. pop di
  1587. pop es
  1588. pop dx
  1589. pop cx
  1590. pop bx
  1591. pop ax
  1592. end;
  1593. {$endif asmgraph}
  1594. {************************************************************************}
  1595. {* General routines *}
  1596. {************************************************************************}
  1597. var
  1598. SavePtr : pointer; { pointer to video state }
  1599. { CrtSavePtr: pointer;} { pointer to video state when CrtMode gets called }
  1600. StateSize: word; { size in 64 byte blocks for video state }
  1601. VideoMode: byte; { old video mode before graph mode }
  1602. SaveSupPorted : Boolean; { Save/Restore video state supPorted? }
  1603. {**************************************************************}
  1604. {* DPMI Routines *}
  1605. {**************************************************************}
  1606. {$IFDEF DPMI}
  1607. RealStateSeg: word; { Real segment of saved video state }
  1608. Procedure SaveStateVGA; {$ifndef fpc}far;{$endif fpc}
  1609. var
  1610. PtrLong: longint;
  1611. regs: TDPMIRegisters;
  1612. begin
  1613. SaveSupPorted := FALSE;
  1614. SavePtr := nil;
  1615. { Get the video mode }
  1616. asm
  1617. mov ah,0fh
  1618. {$ifdef fpc}
  1619. push ebp
  1620. push esi
  1621. push edi
  1622. push ebx
  1623. {$endif fpc}
  1624. int 10h
  1625. {$ifdef fpc}
  1626. pop ebx
  1627. pop edi
  1628. pop esi
  1629. pop ebp
  1630. {$endif fpc}
  1631. mov [VideoMode], al
  1632. end ['EAX'];
  1633. { saving/restoring video state screws up Windows (JM) }
  1634. if inWindows then
  1635. exit;
  1636. { Prepare to save video state...}
  1637. asm
  1638. mov ax, 1C00h { get buffer size to save state }
  1639. mov cx, 00000111b { Save DAC / Data areas / Hardware states }
  1640. {$ifdef fpc}
  1641. push ebx
  1642. push ebp
  1643. push esi
  1644. push edi
  1645. {$endif fpc}
  1646. int 10h
  1647. {$ifdef fpc}
  1648. pop edi
  1649. pop esi
  1650. pop ebp
  1651. {$endif fpc}
  1652. mov [StateSize], bx
  1653. {$ifdef fpc}
  1654. pop ebx
  1655. {$endif fpc}
  1656. cmp al,01ch
  1657. jnz @notok
  1658. mov [SaveSupPorted],TRUE
  1659. @notok:
  1660. end ['ECX','EAX'];
  1661. if SaveSupPorted then
  1662. begin
  1663. {$ifndef fpc}
  1664. PtrLong:=GlobalDosAlloc(64*StateSize); { values returned in 64-byte blocks }
  1665. {$else fpc}
  1666. PtrLong:=Global_Dos_Alloc(64*StateSize); { values returned in 64-byte blocks }
  1667. {$endif fpc}
  1668. if PtrLong = 0 then
  1669. RunError(203);
  1670. SavePtr := pointer(longint(PtrLong and $0000ffff) shl 16);
  1671. {$ifndef fpc}
  1672. { In FPC mode, we can't do anything with this (no far pointers) }
  1673. { However, we still need to keep it to be able to free the }
  1674. { memory afterwards. Since this data is not accessed in PM code, }
  1675. { there's no need to save it in a seperate buffer (JM) }
  1676. if not assigned(SavePtr) then
  1677. RunError(203);
  1678. {$endif fpc}
  1679. RealStateSeg := word(PtrLong shr 16);
  1680. FillChar(regs, sizeof(regs), #0);
  1681. { call the real mode interrupt ... }
  1682. regs.eax := $1C01; { save the state buffer }
  1683. regs.ecx := $07; { Save DAC / Data areas / Hardware states }
  1684. regs.es := RealStateSeg;
  1685. regs.ebx := 0;
  1686. RealIntr($10,regs);
  1687. FillChar(regs, sizeof(regs), #0);
  1688. { restore state, according to Ralph Brown Interrupt list }
  1689. { some BIOS corrupt the hardware after a save... }
  1690. regs.eax := $1C02; { restore the state buffer }
  1691. regs.ecx := $07; { rest DAC / Data areas / Hardware states }
  1692. regs.es := RealStateSeg;
  1693. regs.ebx := 0;
  1694. RealIntr($10,regs);
  1695. end;
  1696. end;
  1697. procedure RestoreStateVGA; {$ifndef fpc}far;{$endif fpc}
  1698. var
  1699. regs:TDPMIRegisters;
  1700. begin
  1701. { go back to the old video mode...}
  1702. asm
  1703. mov ah,00
  1704. mov al,[VideoMode]
  1705. {$ifdef fpc}
  1706. push ebp
  1707. push esi
  1708. push edi
  1709. push ebx
  1710. {$endif fpc}
  1711. int 10h
  1712. {$ifdef fpc}
  1713. pop ebx
  1714. pop edi
  1715. pop esi
  1716. pop ebp
  1717. {$endif fpc}
  1718. end ['EAX'];
  1719. { then restore all state information }
  1720. {$ifndef fpc}
  1721. if assigned(SavePtr) and (SaveSupPorted=TRUE) then
  1722. {$else fpc}
  1723. { No far pointer supPort, so it's possible that that assigned(SavePtr) }
  1724. { would return false under FPC. Just check if it's different from nil. }
  1725. if (SavePtr <> nil) and (SaveSupPorted=TRUE) then
  1726. {$endif fpc}
  1727. begin
  1728. FillChar(regs, sizeof(regs), #0);
  1729. { restore state, according to Ralph Brown Interrupt list }
  1730. { some BIOS corrupt the hardware after a save... }
  1731. regs.eax := $1C02; { restore the state buffer }
  1732. regs.ecx := $07; { rest DAC / Data areas / Hardware states }
  1733. regs.es := RealStateSeg;
  1734. regs.ebx := 0;
  1735. RealIntr($10,regs);
  1736. (*
  1737. {$ifndef fpc}
  1738. if GlobalDosFree(longint(SavePtr) shr 16)<>0 then
  1739. {$else fpc}
  1740. if Not Global_Dos_Free(longint(SavePtr) shr 16) then
  1741. {$endif fpc}
  1742. RunError(216);
  1743. SavePtr := nil;
  1744. *)
  1745. end;
  1746. end;
  1747. {$ELSE}
  1748. {**************************************************************}
  1749. {* Real mode routines *}
  1750. {**************************************************************}
  1751. Procedure SaveStateVGA; far;
  1752. begin
  1753. SavePtr := nil;
  1754. SaveSupPorted := FALSE;
  1755. { Get the video mode }
  1756. asm
  1757. mov ah,0fh
  1758. int 10h
  1759. mov [VideoMode], al
  1760. end;
  1761. { Prepare to save video state...}
  1762. asm
  1763. mov ax, 1C00h { get buffer size to save state }
  1764. mov cx, 00000111b { Save DAC / Data areas / Hardware states }
  1765. int 10h
  1766. mov [StateSize], bx
  1767. cmp al,01ch
  1768. jnz @notok
  1769. mov [SaveSupPorted],TRUE
  1770. @notok:
  1771. end;
  1772. if SaveSupPorted then
  1773. Begin
  1774. GetMem(SavePtr, 64*StateSize); { values returned in 64-byte blocks }
  1775. if not assigned(SavePtr) then
  1776. RunError(203);
  1777. asm
  1778. mov ax, 1C01h { save the state buffer }
  1779. mov cx, 00000111b { Save DAC / Data areas / Hardware states }
  1780. mov es, WORD PTR [SavePtr+2]
  1781. mov bx, WORD PTR [SavePtr]
  1782. int 10h
  1783. end;
  1784. { restore state, according to Ralph Brown Interrupt list }
  1785. { some BIOS corrupt the hardware after a save... }
  1786. asm
  1787. mov ax, 1C02h { save the state buffer }
  1788. mov cx, 00000111b { Save DAC / Data areas / Hardware states }
  1789. mov es, WORD PTR [SavePtr+2]
  1790. mov bx, WORD PTR [SavePtr]
  1791. int 10h
  1792. end;
  1793. end;
  1794. end;
  1795. procedure RestoreStateVGA; far;
  1796. begin
  1797. { go back to the old video mode...}
  1798. asm
  1799. mov ah,00
  1800. mov al,[VideoMode]
  1801. int 10h
  1802. end;
  1803. { then restore all state information }
  1804. if assigned(SavePtr) and (SaveSupPorted=TRUE) then
  1805. begin
  1806. { restore state, according to Ralph Brown Interrupt list }
  1807. asm
  1808. mov ax, 1C02h { save the state buffer }
  1809. mov cx, 00000111b { Save DAC / Data areas / Hardware states }
  1810. mov es, WORD PTR [SavePtr+2]
  1811. mov bx, WORD PTR [SavePtr]
  1812. int 10h
  1813. end;
  1814. { done in exitproc (JM)
  1815. FreeMem(SavePtr, 64*StateSize);}
  1816. SavePtr := nil;
  1817. end;
  1818. end;
  1819. {$ENDIF DPMI}
  1820. Procedure SetVGARGBAllPalette(const Palette:PaletteType); {$ifndef fpc}far;{$endif fpc}
  1821. var
  1822. c: byte;
  1823. begin
  1824. { wait for vertical retrace start/end}
  1825. while (port[$3da] and $8) <> 0 do;
  1826. while (port[$3da] and $8) = 0 do;
  1827. If MaxColor = 16 Then
  1828. begin
  1829. for c := 0 to 15 do
  1830. begin
  1831. { translate the color number for 16 color mode }
  1832. portb[$3c8] := toRealCols16[c];
  1833. portb[$3c9] := palette.colors[c].red shr 2;
  1834. portb[$3c9] := palette.colors[c].green shr 2;
  1835. portb[$3c9] := palette.colors[c].blue shr 2;
  1836. end
  1837. end
  1838. else
  1839. begin
  1840. portb[$3c8] := 0;
  1841. for c := 0 to 255 do
  1842. begin
  1843. { no need to set port[$3c8] every time if you set the entries }
  1844. { for successive colornumbers (JM) }
  1845. portb[$3c9] := palette.colors[c].red shr 2;
  1846. portb[$3c9] := palette.colors[c].green shr 2;
  1847. portb[$3c9] := palette.colors[c].blue shr 2;
  1848. end
  1849. end;
  1850. End;
  1851. { VGA is never a direct color mode, so no need to check ... }
  1852. Procedure SetVGARGBPalette(ColorNum, RedValue, GreenValue,
  1853. BlueValue : smallint); {$ifndef fpc}far;{$endif fpc}
  1854. begin
  1855. { translate the color number for 16 color mode }
  1856. If MaxColor = 16 Then
  1857. ColorNum := ToRealCols16[ColorNum];
  1858. asm
  1859. { on some hardware - there is a snow like effect }
  1860. { when changing the palette register directly }
  1861. { so we wait for a vertical retrace start period. }
  1862. push ax
  1863. push dx
  1864. mov dx, $03da
  1865. @1:
  1866. in al, dx { Get input status register }
  1867. test al, $08 { check if in vertical retrace }
  1868. jnz @1 { yes, complete it }
  1869. { we have to wait for the next }
  1870. { retrace to assure ourselves }
  1871. { that we have time to complete }
  1872. { the DAC operation within }
  1873. { the vertical retrace period }
  1874. @2:
  1875. in al, dx
  1876. test al, $08
  1877. jz @2 { repeat until vertical retrace start }
  1878. mov dx, $03c8 { Set color register address to use }
  1879. mov ax, [ColorNum]
  1880. out dx, al
  1881. inc dx { Point to DAC registers }
  1882. mov ax, [RedValue] { Get RedValue }
  1883. shr ax, 2
  1884. out dx, al
  1885. mov ax, [GreenValue]{ Get RedValue }
  1886. shr ax, 2
  1887. out dx, al
  1888. mov ax, [BlueValue] { Get RedValue }
  1889. shr ax, 2
  1890. out dx, al
  1891. pop dx
  1892. pop ax
  1893. end
  1894. End;
  1895. { VGA is never a direct color mode, so no need to check ... }
  1896. Procedure GetVGARGBPalette(ColorNum: smallint; Var
  1897. RedValue, GreenValue, BlueValue : smallint); {$ifndef fpc}far;{$endif fpc}
  1898. begin
  1899. If MaxColor = 16 Then
  1900. ColorNum := ToRealCols16[ColorNum];
  1901. Port[$03C7] := ColorNum;
  1902. { we must convert to lsb values... because the vga uses the 6 msb bits }
  1903. { which is not compatible with anything. }
  1904. RedValue := smallint(Port[$3C9]) shl 2;
  1905. GreenValue := smallint(Port[$3C9]) shl 2;
  1906. BlueValue := smallint(Port[$3C9]) shl 2;
  1907. end;
  1908. {************************************************************************}
  1909. {* VESA related routines *}
  1910. {************************************************************************}
  1911. {$I vesa.inc}
  1912. {************************************************************************}
  1913. {* General routines *}
  1914. {************************************************************************}
  1915. procedure CloseGraph;
  1916. Begin
  1917. If not isgraphmode then
  1918. begin
  1919. _graphresult := grnoinitgraph;
  1920. exit
  1921. end;
  1922. if not assigned(RestoreVideoState) then
  1923. RunError(216);
  1924. RestoreVideoState;
  1925. isgraphmode := false;
  1926. end;
  1927. (*
  1928. procedure LoadFont8x8;
  1929. var
  1930. r : registers;
  1931. x,y,c : longint;
  1932. data : array[0..127,0..7] of byte;
  1933. begin
  1934. r.ah:=$11;
  1935. r.al:=$30;
  1936. r.bh:=1;
  1937. RealIntr($10,r);
  1938. dosmemget(r.es,r.bp,data,sizeof(data));
  1939. for c:=0 to 127 do
  1940. for y:=0 to 7 do
  1941. for x:=0 to 7 do
  1942. if (data[c,y] and ($80 shr x))<>0 then
  1943. DefaultFontData[chr(c),y,x]:=1
  1944. else
  1945. DefaultFontData[chr(c),y,x]:=0;
  1946. { second part }
  1947. r.ah:=$11;
  1948. r.al:=$30;
  1949. r.bh:=0;
  1950. RealIntr($10,r);
  1951. dosmemget(r.es,r.bp,data,sizeof(data));
  1952. for c:=0 to 127 do
  1953. for y:=0 to 7 do
  1954. for x:=0 to 7 do
  1955. if (data[c,y] and ($80 shr x))<>0 then
  1956. DefaultFontData[chr(c+128),y,x]:=1
  1957. else
  1958. DefaultFontData[chr(c+128),y,x]:=0;
  1959. end;
  1960. *)
  1961. function QueryAdapterInfo:PModeInfo;
  1962. { This routine returns the head pointer to the list }
  1963. { of supPorted graphics modes. }
  1964. { Returns nil if no graphics mode supported. }
  1965. { This list is READ ONLY! }
  1966. var
  1967. EGADetected : Boolean;
  1968. VGADetected : Boolean;
  1969. mode: TModeInfo;
  1970. begin
  1971. QueryAdapterInfo := ModeList;
  1972. { If the mode listing already exists... }
  1973. { simply return it, without changing }
  1974. { anything... }
  1975. if assigned(ModeList) then
  1976. exit;
  1977. EGADetected := FALSE;
  1978. VGADetected := FALSE;
  1979. { check if Hercules adapter supPorted ... }
  1980. { check if EGA adapter supPorted... }
  1981. asm
  1982. mov ah,12h
  1983. mov bx,0FF10h
  1984. {$ifdef fpc}
  1985. push ebx
  1986. push ebp
  1987. push esi
  1988. push edi
  1989. {$endif fpc}
  1990. int 10h { get EGA information }
  1991. {$ifdef fpc}
  1992. pop edi
  1993. pop esi
  1994. pop ebp
  1995. {$endif fpc}
  1996. cmp bh,0ffh
  1997. {$ifdef fpc}
  1998. pop ebx
  1999. {$endif fpc}
  2000. jz @noega
  2001. mov [EGADetected],TRUE
  2002. @noega:
  2003. end ['EBX','EAX'];
  2004. {$ifdef logging}
  2005. LogLn('EGA detected: '+strf(Longint(EGADetected)));
  2006. {$endif logging}
  2007. { check if VGA adapter supPorted... }
  2008. if EGADetected then
  2009. begin
  2010. asm
  2011. mov ax,1a00h
  2012. {$ifdef fpc}
  2013. push ebp
  2014. push esi
  2015. push edi
  2016. push ebx
  2017. {$endif fpc}
  2018. int 10h { get display combination code...}
  2019. {$ifdef fpc}
  2020. pop ebx
  2021. pop edi
  2022. pop esi
  2023. pop ebp
  2024. {$endif fpc}
  2025. cmp al,1ah { check if supPorted... }
  2026. jne @novga
  2027. { now check if this is the ATI EGA }
  2028. mov ax,1c00h { get state size for save... }
  2029. { ... all imPortant data }
  2030. mov cx,07h
  2031. {$ifdef fpc}
  2032. push ebp
  2033. push esi
  2034. push edi
  2035. push ebx
  2036. {$endif fpc}
  2037. int 10h
  2038. {$ifdef fpc}
  2039. pop ebx
  2040. pop edi
  2041. pop esi
  2042. pop ebp
  2043. {$endif fpc}
  2044. cmp al,1ch { success? }
  2045. jne @novga
  2046. mov [VGADetected],TRUE
  2047. @novga:
  2048. end ['ECX','EAX'];
  2049. end;
  2050. {$ifdef logging}
  2051. LogLn('VGA detected: '+strf(Longint(VGADetected)));
  2052. {$endif logging}
  2053. if VGADetected then
  2054. begin
  2055. SaveVideoState := @SaveStateVGA;
  2056. {$ifdef logging}
  2057. LogLn('Setting VGA SaveVideoState to '+strf(longint(SaveVideoState)));
  2058. {$endif logging}
  2059. RestoreVideoState := @RestoreStateVGA;
  2060. {$ifdef logging}
  2061. LogLn('Setting VGA RestoreVideoState to '+strf(longint(RestoreVideoState)));
  2062. {$endif logging}
  2063. InitMode(mode);
  2064. { now add all standard VGA modes... }
  2065. mode.DriverNumber:= LowRes;
  2066. mode.HardwarePages:= 0;
  2067. mode.ModeNumber:=0;
  2068. mode.ModeName:='320 x 200 VGA';
  2069. mode.MaxColor := 256;
  2070. mode.PaletteSize := mode.MaxColor;
  2071. mode.DirectColor := FALSE;
  2072. mode.MaxX := 319;
  2073. mode.MaxY := 199;
  2074. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel320;
  2075. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel320;
  2076. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel320;
  2077. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVGARGBPalette;
  2078. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVGARGBPalette;
  2079. mode.SetAllPalette := {$ifdef fpc}@{$endif}SetVGARGBAllPalette;
  2080. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisual320;
  2081. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActive320;
  2082. mode.InitMode := {$ifdef fpc}@{$endif}Init320;
  2083. mode.XAspect := 8333;
  2084. mode.YAspect := 10000;
  2085. AddMode(mode);
  2086. { now add all standard VGA modes... }
  2087. InitMode(mode);
  2088. mode.DriverNumber:= LowRes;
  2089. mode.ModeNumber:=1;
  2090. mode.HardwarePages := 3; { 0..3 }
  2091. mode.ModeName:='320 x 200 ModeX';
  2092. mode.MaxColor := 256;
  2093. mode.DirectColor := FALSE;
  2094. mode.PaletteSize := mode.MaxColor;
  2095. mode.MaxX := 319;
  2096. mode.MaxY := 199;
  2097. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixelX;
  2098. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixelX;
  2099. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixelX;
  2100. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVGARGBPalette;
  2101. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVGARGBPalette;
  2102. mode.SetAllPalette := {$ifdef fpc}@{$endif}SetVGARGBAllPalette;
  2103. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualX;
  2104. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveX;
  2105. mode.InitMode := {$ifdef fpc}@{$endif}InitModeX;
  2106. mode.XAspect := 8333;
  2107. mode.YAspect := 10000;
  2108. AddMode(mode);
  2109. InitMode(mode);
  2110. mode.ModeNumber:=VGALo;
  2111. mode.DriverNumber := VGA;
  2112. mode.ModeName:='640 x 200 VGA';
  2113. mode.MaxColor := 16;
  2114. mode.HardwarePages := 2;
  2115. mode.DirectColor := FALSE;
  2116. mode.PaletteSize := mode.MaxColor;
  2117. mode.MaxX := 639;
  2118. mode.MaxY := 199;
  2119. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16;
  2120. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16;
  2121. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16;
  2122. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVGARGBPalette;
  2123. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVGARGBPalette;
  2124. mode.SetAllPalette := {$ifdef fpc}@{$endif}SetVGARGBAllPalette;
  2125. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisual200;
  2126. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActive200;
  2127. mode.InitMode := {$ifdef fpc}@{$endif}Init640x200x16;
  2128. mode.HLine := {$ifdef fpc}@{$endif}HLine16;
  2129. mode.VLine := {$ifdef fpc}@{$endif}VLine16;
  2130. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLine16;
  2131. mode.XAspect := 4500;
  2132. mode.YAspect := 10000;
  2133. AddMode(mode);
  2134. InitMode(mode);
  2135. mode.ModeNumber:=VGAMed;
  2136. mode.DriverNumber := VGA;
  2137. mode.ModeName:='640 x 350 VGA';
  2138. mode.HardwarePages := 1;
  2139. mode.MaxColor := 16;
  2140. mode.DirectColor := FALSE;
  2141. mode.PaletteSize := mode.MaxColor;
  2142. mode.MaxX := 639;
  2143. mode.MaxY := 349;
  2144. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16;
  2145. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16;
  2146. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16;
  2147. mode.InitMode := {$ifdef fpc}@{$endif}Init640x350x16;
  2148. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVGARGBPalette;
  2149. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVGARGBPalette;
  2150. mode.SetAllPalette := {$ifdef fpc}@{$endif}SetVGARGBAllPalette;
  2151. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisual350;
  2152. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActive350;
  2153. mode.HLine := {$ifdef fpc}@{$endif}HLine16;
  2154. mode.VLine := {$ifdef fpc}@{$endif}VLine16;
  2155. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLine16;
  2156. mode.XAspect := 7750;
  2157. mode.YAspect := 10000;
  2158. AddMode(mode);
  2159. InitMode(mode);
  2160. mode.ModeNumber:=VGAHi;
  2161. mode.DriverNumber := VGA;
  2162. mode.HardwarePages := 0;
  2163. mode.ModeName:='640 x 480 VGA';
  2164. mode.MaxColor := 16;
  2165. mode.DirectColor := FALSE;
  2166. mode.PaletteSize := mode.MaxColor;
  2167. mode.MaxX := 639;
  2168. mode.MaxY := 479;
  2169. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16;
  2170. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16;
  2171. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16;
  2172. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVGARGBPalette;
  2173. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVGARGBPalette;
  2174. mode.SetAllPalette := {$ifdef fpc}@{$endif}SetVGARGBAllPalette;
  2175. mode.InitMode := {$ifdef fpc}@{$endif}Init640x480x16;
  2176. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisual480;
  2177. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActive480;
  2178. mode.HLine := {$ifdef fpc}@{$endif}HLine16;
  2179. mode.VLine := {$ifdef fpc}@{$endif}VLine16;
  2180. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLine16;
  2181. mode.XAspect := 10000;
  2182. mode.YAspect := 10000;
  2183. AddMode(mode);
  2184. end;
  2185. { check if VESA adapter supPorted... }
  2186. {$ifndef noSupPortVESA}
  2187. hasVesa := getVesaInfo(VESAInfo);
  2188. { VBE Version v1.00 is unstable, therefore }
  2189. { only VBE v1.1 and later are supported. }
  2190. if (hasVESA=TRUE) and (VESAInfo.Version <= $0100) then
  2191. hasVESA := False;
  2192. {$else noSupPortVESA}
  2193. hasVESA := false;
  2194. {$endif noSupPortVESA}
  2195. if hasVesa then
  2196. begin
  2197. { We have to set and restore the entire VESA state }
  2198. { otherwise, if we use the VGA BIOS only function }
  2199. { there might be a crash under DPMI, such as in the}
  2200. { ATI Mach64 }
  2201. SaveVideoState := @SaveStateVESA;
  2202. {$ifdef logging}
  2203. LogLn('Setting SaveVideoState to '+strf(longint(SaveVideoState)));
  2204. {$endif logging}
  2205. RestoreVideoState := @RestoreStateVESA;
  2206. {$ifdef logging}
  2207. LogLn('Setting RestoreVideoState to '+strf(longint(RestoreVideoState)));
  2208. {$endif logging}
  2209. { now check all supported modes...}
  2210. if SearchVESAModes(m320x200x32k) then
  2211. begin
  2212. InitMode(mode);
  2213. mode.ModeNumber:=m320x200x32k;
  2214. mode.DriverNumber := VESA;
  2215. mode.ModeName:='320 x 200 VESA';
  2216. mode.MaxColor := 32768;
  2217. { the ModeInfo is automatically set if the mode is supPorted }
  2218. { by the call to SearchVESAMode. }
  2219. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2220. mode.PaletteSize := mode.MaxColor;
  2221. mode.DirectColor := TRUE;
  2222. mode.MaxX := 319;
  2223. mode.MaxY := 199;
  2224. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2225. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2226. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2227. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2228. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2229. mode.InitMode := {$ifdef fpc}@{$endif}Init320x200x32k;
  2230. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2231. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2232. mode.XAspect := 8333;
  2233. mode.YAspect := 10000;
  2234. AddMode(mode);
  2235. end;
  2236. if SearchVESAModes(m320x200x64k) then
  2237. begin
  2238. InitMode(mode);
  2239. mode.ModeNumber:=m320x200x64k;
  2240. mode.DriverNumber := VESA;
  2241. mode.ModeName:='320 x 200 VESA';
  2242. mode.MaxColor := 65536;
  2243. { the ModeInfo is automatically set if the mode is supPorted }
  2244. { by the call to SearchVESAMode. }
  2245. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2246. mode.PaletteSize := mode.MaxColor;
  2247. mode.DirectColor := TRUE;
  2248. mode.MaxX := 319;
  2249. mode.MaxY := 199;
  2250. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2251. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2252. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2253. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2254. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2255. mode.InitMode := {$ifdef fpc}@{$endif}Init320x200x64k;
  2256. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2257. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2258. mode.XAspect := 8333;
  2259. mode.YAspect := 10000;
  2260. AddMode(mode);
  2261. end;
  2262. if SearchVESAModes(m640x400x256) then
  2263. begin
  2264. InitMode(mode);
  2265. mode.ModeNumber:=m640x400x256;
  2266. mode.DriverNumber := VESA;
  2267. mode.ModeName:='640 x 400 VESA';
  2268. mode.MaxColor := 256;
  2269. { the ModeInfo is automatically set if the mode is supPorted }
  2270. { by the call to SearchVESAMode. }
  2271. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2272. mode.PaletteSize := mode.MaxColor;
  2273. mode.DirectColor := FALSE;
  2274. mode.MaxX := 639;
  2275. mode.MaxY := 399;
  2276. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA256;
  2277. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA256;
  2278. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA256;
  2279. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2280. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2281. {$ifdef fpc}
  2282. mode.SetAllPalette := @SetVESARGBAllPalette;
  2283. {$endif fpc}
  2284. mode.InitMode := {$ifdef fpc}@{$endif}Init640x400x256;
  2285. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2286. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2287. mode.hline := {$ifdef fpc}@{$endif}HLineVESA256;
  2288. mode.vline := {$ifdef fpc}@{$endif}VLineVESA256;
  2289. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256;
  2290. mode.XAspect := 8333;
  2291. mode.YAspect := 10000;
  2292. AddMode(mode);
  2293. end;
  2294. if SearchVESAModes(m640x480x256) then
  2295. begin
  2296. InitMode(mode);
  2297. mode.ModeNumber:=m640x480x256;
  2298. mode.DriverNumber := VESA;
  2299. mode.ModeName:='640 x 480 VESA';
  2300. mode.MaxColor := 256;
  2301. { the ModeInfo is automatically set if the mode is supPorted }
  2302. { by the call to SearchVESAMode. }
  2303. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2304. mode.PaletteSize := mode.MaxColor;
  2305. mode.MaxX := 639;
  2306. mode.MaxY := 479;
  2307. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA256;
  2308. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA256;
  2309. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA256;
  2310. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2311. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2312. {$ifdef fpc}
  2313. mode.SetAllPalette := @SetVESARGBAllPalette;
  2314. {$endif fpc}
  2315. mode.InitMode := {$ifdef fpc}@{$endif}Init640x480x256;
  2316. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2317. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2318. mode.hline := {$ifdef fpc}@{$endif}HLineVESA256;
  2319. mode.vline := {$ifdef fpc}@{$endif}VLineVESA256;
  2320. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256;
  2321. mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256;
  2322. mode.XAspect := 10000;
  2323. mode.YAspect := 10000;
  2324. AddMode(mode);
  2325. end;
  2326. if SearchVESAModes(m640x480x32k) then
  2327. begin
  2328. InitMode(mode);
  2329. mode.ModeNumber:=m640x480x32k;
  2330. mode.DriverNumber := VESA;
  2331. mode.ModeName:='640 x 480 VESA';
  2332. mode.MaxColor := 32768;
  2333. { the ModeInfo is automatically set if the mode is supPorted }
  2334. { by the call to SearchVESAMode. }
  2335. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2336. mode.PaletteSize := mode.MaxColor;
  2337. mode.DirectColor := TRUE;
  2338. mode.MaxX := 639;
  2339. mode.MaxY := 479;
  2340. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2341. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2342. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2343. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2344. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2345. mode.InitMode := {$ifdef fpc}@{$endif}Init640x480x32k;
  2346. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2347. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2348. mode.XAspect := 10000;
  2349. mode.YAspect := 10000;
  2350. AddMode(mode);
  2351. end;
  2352. if SearchVESAModes(m640x480x64k) then
  2353. begin
  2354. InitMode(mode);
  2355. mode.ModeNumber:=m640x480x64k;
  2356. mode.DriverNumber := VESA;
  2357. mode.ModeName:='640 x 480 VESA';
  2358. mode.MaxColor := 65536;
  2359. { the ModeInfo is automatically set if the mode is supPorted }
  2360. { by the call to SearchVESAMode. }
  2361. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2362. mode.PaletteSize := mode.MaxColor;
  2363. mode.DirectColor := TRUE;
  2364. mode.MaxX := 639;
  2365. mode.MaxY := 479;
  2366. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2367. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2368. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2369. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2370. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2371. mode.InitMode := {$ifdef fpc}@{$endif}Init640x480x64k;
  2372. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2373. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2374. mode.XAspect := 10000;
  2375. mode.YAspect := 10000;
  2376. AddMode(mode);
  2377. end;
  2378. if SearchVESAModes(m800x600x16) then
  2379. begin
  2380. InitMode(mode);
  2381. mode.ModeNumber:=m800x600x16;
  2382. mode.DriverNumber := VESA;
  2383. mode.ModeName:='800 x 600 VESA';
  2384. mode.MaxColor := 16;
  2385. { the ModeInfo is automatically set if the mode is supPorted }
  2386. { by the call to SearchVESAMode. }
  2387. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2388. mode.DirectColor := FALSE;
  2389. mode.PaletteSize := mode.MaxColor;
  2390. mode.MaxX := 799;
  2391. mode.MaxY := 599;
  2392. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA16;
  2393. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2394. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2395. {$ifdef fpc}
  2396. mode.SetAllPalette := @SetVESARGBAllPalette;
  2397. {$endif fpc}
  2398. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA16;
  2399. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA16;
  2400. mode.InitMode := {$ifdef fpc}@{$endif}Init800x600x16;
  2401. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2402. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2403. mode.XAspect := 10000;
  2404. mode.YAspect := 10000;
  2405. AddMode(mode);
  2406. end;
  2407. if SearchVESAModes(m800x600x256) then
  2408. begin
  2409. InitMode(mode);
  2410. mode.ModeNumber:=m800x600x256;
  2411. mode.DriverNumber := VESA;
  2412. mode.ModeName:='800 x 600 VESA';
  2413. mode.MaxColor := 256;
  2414. { the ModeInfo is automatically set if the mode is supPorted }
  2415. { by the call to SearchVESAMode. }
  2416. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2417. mode.PaletteSize := mode.MaxColor;
  2418. mode.DirectColor := FALSE;
  2419. mode.MaxX := 799;
  2420. mode.MaxY := 599;
  2421. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA256;
  2422. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA256;
  2423. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA256;
  2424. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2425. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2426. {$ifdef fpc}
  2427. mode.SetAllPalette := @SetVESARGBAllPalette;
  2428. {$endif fpc}
  2429. mode.InitMode := {$ifdef fpc}@{$endif}Init800x600x256;
  2430. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2431. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2432. mode.hline := {$ifdef fpc}@{$endif}HLineVESA256;
  2433. mode.vline := {$ifdef fpc}@{$endif}VLineVESA256;
  2434. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256;
  2435. mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256;
  2436. mode.XAspect := 10000;
  2437. mode.YAspect := 10000;
  2438. AddMode(mode);
  2439. end;
  2440. if SearchVESAModes(m800x600x32k) then
  2441. begin
  2442. InitMode(mode);
  2443. mode.ModeNumber:=m800x600x32k;
  2444. mode.DriverNumber := VESA;
  2445. mode.ModeName:='800 x 600 VESA';
  2446. mode.MaxColor := 32768;
  2447. { the ModeInfo is automatically set if the mode is supPorted }
  2448. { by the call to SearchVESAMode. }
  2449. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2450. mode.PaletteSize := mode.MaxColor;
  2451. mode.DirectColor := TRUE;
  2452. mode.MaxX := 799;
  2453. mode.MaxY := 599;
  2454. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2455. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2456. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2457. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2458. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2459. mode.InitMode := {$ifdef fpc}@{$endif}Init800x600x32k;
  2460. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2461. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2462. mode.XAspect := 10000;
  2463. mode.YAspect := 10000;
  2464. AddMode(mode);
  2465. end;
  2466. if SearchVESAModes(m800x600x64k) then
  2467. begin
  2468. InitMode(mode);
  2469. mode.ModeNumber:=m800x600x64k;
  2470. mode.DriverNumber := VESA;
  2471. mode.ModeName:='800 x 600 VESA';
  2472. mode.MaxColor := 65536;
  2473. { the ModeInfo is automatically set if the mode is supPorted }
  2474. { by the call to SearchVESAMode. }
  2475. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2476. mode.PaletteSize := mode.MaxColor;
  2477. mode.DirectColor := TRUE;
  2478. mode.MaxX := 799;
  2479. mode.MaxY := 599;
  2480. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2481. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2482. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2483. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2484. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2485. mode.InitMode := {$ifdef fpc}@{$endif}Init800x600x64k;
  2486. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2487. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2488. mode.XAspect := 10000;
  2489. mode.YAspect := 10000;
  2490. AddMode(mode);
  2491. end;
  2492. if SearchVESAModes(m1024x768x16) then
  2493. begin
  2494. InitMode(mode);
  2495. mode.ModeNumber:=m1024x768x16;
  2496. mode.DriverNumber := VESA;
  2497. mode.ModeName:='1024 x 768 VESA';
  2498. mode.MaxColor := 16;
  2499. { the ModeInfo is automatically set if the mode is supPorted }
  2500. { by the call to SearchVESAMode. }
  2501. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2502. mode.PaletteSize := mode.MaxColor;
  2503. mode.DirectColor := FALSE;
  2504. mode.MaxX := 1023;
  2505. mode.MaxY := 767;
  2506. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA16;
  2507. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA16;
  2508. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2509. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2510. {$ifdef fpc}
  2511. mode.SetAllPalette := @SetVESARGBAllPalette;
  2512. {$endif fpc}
  2513. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA16;
  2514. mode.InitMode := {$ifdef fpc}@{$endif}Init1024x768x16;
  2515. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2516. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2517. mode.XAspect := 10000;
  2518. mode.YAspect := 10000;
  2519. AddMode(mode);
  2520. end;
  2521. if SearchVESAModes(m1024x768x256) then
  2522. begin
  2523. InitMode(mode);
  2524. mode.ModeNumber:=m1024x768x256;
  2525. mode.DriverNumber := VESA;
  2526. mode.ModeName:='1024 x 768 VESA';
  2527. mode.MaxColor := 256;
  2528. { the ModeInfo is automatically set if the mode is supPorted }
  2529. { by the call to SearchVESAMode. }
  2530. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2531. mode.PaletteSize := mode.MaxColor;
  2532. mode.DirectColor := FALSE;
  2533. mode.MaxX := 1023;
  2534. mode.MaxY := 767;
  2535. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA256;
  2536. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA256;
  2537. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA256;
  2538. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2539. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2540. {$ifdef fpc}
  2541. mode.SetAllPalette := @SetVESARGBAllPalette;
  2542. {$endif fpc}
  2543. mode.InitMode := {$ifdef fpc}@{$endif}Init1024x768x256;
  2544. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2545. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2546. mode.vline := {$ifdef fpc}@{$endif}VLineVESA256;
  2547. mode.hline := {$ifdef fpc}@{$endif}HLineVESA256;
  2548. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256;
  2549. mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256;
  2550. mode.XAspect := 10000;
  2551. mode.YAspect := 10000;
  2552. AddMode(mode);
  2553. end;
  2554. if SearchVESAModes(m1024x768x32k) then
  2555. begin
  2556. InitMode(mode);
  2557. mode.ModeNumber:=m1024x768x32k;
  2558. mode.DriverNumber := VESA;
  2559. mode.ModeName:='1024 x 768 VESA';
  2560. mode.MaxColor := 32768;
  2561. { the ModeInfo is automatically set if the mode is supPorted }
  2562. { by the call to SearchVESAMode. }
  2563. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2564. mode.PaletteSize := mode.MaxColor;
  2565. mode.DirectColor := TRUE;
  2566. mode.MaxX := 1023;
  2567. mode.MaxY := 767;
  2568. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2569. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2570. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2571. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2572. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2573. mode.InitMode := {$ifdef fpc}@{$endif}Init1024x768x32k;
  2574. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2575. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2576. mode.XAspect := 10000;
  2577. mode.YAspect := 10000;
  2578. AddMode(mode);
  2579. end;
  2580. if SearchVESAModes(m1024x768x64k) then
  2581. begin
  2582. InitMode(mode);
  2583. mode.ModeNumber:=m1024x768x64k;
  2584. mode.DriverNumber := VESA;
  2585. mode.ModeName:='1024 x 768 VESA';
  2586. mode.MaxColor := 65536;
  2587. mode.DirectColor := TRUE;
  2588. { the ModeInfo is automatically set if the mode is supPorted }
  2589. { by the call to SearchVESAMode. }
  2590. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2591. mode.PaletteSize := mode.MaxColor;
  2592. mode.MaxX := 1023;
  2593. mode.MaxY := 767;
  2594. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2595. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2596. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2597. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2598. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2599. mode.InitMode := {$ifdef fpc}@{$endif}Init1024x768x64k;
  2600. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2601. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2602. mode.XAspect := 10000;
  2603. mode.YAspect := 10000;
  2604. AddMode(mode);
  2605. end;
  2606. if SearchVESAModes(m1280x1024x16) then
  2607. begin
  2608. InitMode(mode);
  2609. mode.ModeNumber:=m1280x1024x16;
  2610. mode.DriverNumber := VESA;
  2611. mode.ModeName:='1280 x 1024 VESA';
  2612. mode.MaxColor := 16;
  2613. { the ModeInfo is automatically set if the mode is supPorted }
  2614. { by the call to SearchVESAMode. }
  2615. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2616. mode.DirectColor := FALSE;
  2617. mode.PaletteSize := mode.MaxColor;
  2618. mode.MaxX := 1279;
  2619. mode.MaxY := 1023;
  2620. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA16;
  2621. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2622. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2623. {$ifdef fpc}
  2624. mode.SetAllPalette := @SetVESARGBAllPalette;
  2625. {$endif fpc}
  2626. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA16;
  2627. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA16;
  2628. mode.InitMode := {$ifdef fpc}@{$endif}Init1280x1024x16;
  2629. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2630. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2631. mode.XAspect := 10000;
  2632. mode.YAspect := 10000;
  2633. AddMode(mode);
  2634. end;
  2635. if SearchVESAModes(m1280x1024x256) then
  2636. begin
  2637. InitMode(mode);
  2638. mode.ModeNumber:=m1280x1024x256;
  2639. mode.DriverNumber := VESA;
  2640. mode.ModeName:='1280 x 1024 VESA';
  2641. mode.MaxColor := 256;
  2642. { the ModeInfo is automatically set if the mode is supPorted }
  2643. { by the call to SearchVESAMode. }
  2644. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2645. mode.DirectColor := FALSE;
  2646. mode.PaletteSize := mode.MaxColor;
  2647. mode.MaxX := 1279;
  2648. mode.MaxY := 1023;
  2649. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA256;
  2650. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA256;
  2651. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA256;
  2652. mode.InitMode := {$ifdef fpc}@{$endif}Init1280x1024x256;
  2653. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2654. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2655. {$ifdef fpc}
  2656. mode.SetAllPalette := @SetVESARGBAllPalette;
  2657. {$endif fpc}
  2658. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2659. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2660. mode.vline := {$ifdef fpc}@{$endif}VLineVESA256;
  2661. mode.hline := {$ifdef fpc}@{$endif}HLineVESA256;
  2662. mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256;
  2663. mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256;
  2664. mode.XAspect := 10000;
  2665. mode.YAspect := 10000;
  2666. AddMode(mode);
  2667. end;
  2668. if SearchVESAModes(m1280x1024x32k) then
  2669. begin
  2670. InitMode(mode);
  2671. mode.ModeNumber:=m1280x1024x32k;
  2672. mode.DriverNumber := VESA;
  2673. mode.ModeName:='1280 x 1024 VESA';
  2674. mode.MaxColor := 32768;
  2675. { the ModeInfo is automatically set if the mode is supPorted }
  2676. { by the call to SearchVESAMode. }
  2677. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2678. mode.DirectColor := TRUE;
  2679. mode.PaletteSize := mode.MaxColor;
  2680. mode.MaxX := 1279;
  2681. mode.MaxY := 1023;
  2682. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2683. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2684. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2685. mode.InitMode := {$ifdef fpc}@{$endif}Init1280x1024x32k;
  2686. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2687. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2688. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2689. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2690. mode.XAspect := 10000;
  2691. mode.YAspect := 10000;
  2692. AddMode(mode);
  2693. end;
  2694. if SearchVESAModes(m1280x1024x64k) then
  2695. begin
  2696. InitMode(mode);
  2697. mode.ModeNumber:=m1280x1024x64k;
  2698. mode.DriverNumber := VESA;
  2699. mode.ModeName:='1280 x 1024 VESA';
  2700. mode.MaxColor := 65536;
  2701. { the ModeInfo is automatically set if the mode is supPorted }
  2702. { by the call to SearchVESAMode. }
  2703. mode.HardwarePages := VESAModeInfo.NumberOfPages;
  2704. mode.DirectColor := TRUE;
  2705. mode.PaletteSize := mode.MaxColor;
  2706. mode.MaxX := 1279;
  2707. mode.MaxY := 1023;
  2708. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixVESA32kOr64k;
  2709. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixVESA32kOr64k;
  2710. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixVESA32kOr64k;
  2711. mode.InitMode := {$ifdef fpc}@{$endif}Init1280x1024x64k;
  2712. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetVESARGBPalette;
  2713. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetVESARGBPalette;
  2714. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualVESA;
  2715. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveVESA;
  2716. mode.XAspect := 10000;
  2717. mode.YAspect := 10000;
  2718. AddMode(mode);
  2719. end;
  2720. end;
  2721. end;
  2722. var
  2723. go32exitsave: pointer;
  2724. procedure freeSaveStateBuffer; {$ifndef fpc}far; {$endif}
  2725. begin
  2726. if savePtr <> nil then
  2727. begin
  2728. {$ifdef dpmi}
  2729. {$ifndef fpc}
  2730. if GlobalDosFree(longint(SavePtr) shr 16)<>0 then;
  2731. {$else fpc}
  2732. if Not Global_Dos_Free(longint(SavePtr) shr 16) then;
  2733. {$endif fpc}
  2734. {$else dpmi}
  2735. FreeMem(SavePtr, 64*StateSize);
  2736. {$endif dpmi}
  2737. SavePtr := nil;
  2738. end;
  2739. exitproc := go32exitsave;
  2740. end;
  2741. begin
  2742. { must be done *before* initialize graph is called, because the save }
  2743. { buffer can be used in the normal exit_proc (which is hooked in }
  2744. { initializegraph and as such executed first) (JM) }
  2745. go32exitsave := exitproc;
  2746. exitproc := @freeSaveStateBuffer;
  2747. { windows screws up the display if the savestate/restore state }
  2748. { stuff is used (or uses an abnormal amount of cpu time after }
  2749. { such a problem has exited), so detect its presense and do not }
  2750. { use those functions if it's running. I'm really tired of }
  2751. { working around Windows bugs :( (JM) }
  2752. asm
  2753. mov ax,$160a
  2754. {$ifdef fpc}
  2755. push ebp
  2756. push esi
  2757. push edi
  2758. push ebx
  2759. {$endif fpc}
  2760. int $2f
  2761. {$ifdef fpc}
  2762. pop ebx
  2763. pop edi
  2764. pop esi
  2765. pop ebp
  2766. {$endif fpc}
  2767. test ax,ax
  2768. sete al
  2769. mov inWindows,al
  2770. end ['EAX'];
  2771. InitializeGraph;
  2772. end.