graph.pp 88 KB

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