graph.pp 88 KB

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