graph.pp 89 KB

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