/packages/pasjpeg/src/jmemdosa.pas

https://github.com/slibre/freepascal · Pascal · 365 lines · 306 code · 39 blank · 20 comment · 0 complexity · 71508fabaccd2d0c6b293db56b23a6d3 MD5 · raw file

  1. Unit jmemdosa;
  2. {$G+} {enable 286/287 instructions }
  3. { Original: jmemdosa.asm ; Copyright (C) 1992, Thomas G. Lane.
  4. Based on code contributed by Ge' Weijers. }
  5. { This file contains low-level interface routines to support the MS-DOS
  6. backing store manager (jmemdos.c). Routines are provided to access disk
  7. files through direct DOS calls, and to access XMS and EMS drivers. }
  8. interface
  9. uses
  10. jmorecfg;
  11. type
  12. XMSDRIVER = pointer; {far} { actually a pointer to code }
  13. type
  14. XMScontext = packed record { registers for calling XMS driver }
  15. ax, dx, bx : ushort;
  16. ds_si : pointer; {far}
  17. end;
  18. type
  19. EMScontext = packed record { registers for calling EMS driver }
  20. ax, dx, bx : ushort;
  21. ds_si : pointer; {far}
  22. end;
  23. { offset is a reserved word in BASM }
  24. function jdos_open (var handle : short {far}; const filename {: PChar}) : short;
  25. function jdos_close (handle : short) : short;
  26. function jdos_seek (handle : short; offs : long) : short;
  27. function jdos_read (handle : short; buffer : pointer; {FAR}
  28. count : ushort) : short;
  29. function jdos_write (handle : short; buffer : pointer; {FAR}
  30. count : ushort) : short;
  31. procedure jxms_getdriver (var driver : XMSDRIVER);
  32. procedure jxms_calldriver (driver : XMSDRIVER;
  33. var ctx : XMScontext);
  34. function jems_available : short;
  35. procedure jems_calldriver (var ctx : EMScontext);
  36. implementation
  37. function jdos_open (var handle : short {far};
  38. const filename {: PChar}) : short; assembler;
  39. { Create and open a temporary file }
  40. label
  41. open_err;
  42. asm
  43. push si { save all registers for safety }
  44. push di
  45. push bx
  46. push cx
  47. push dx
  48. push es
  49. push ds
  50. mov cx,0 { normal file attributes }
  51. lds dx, filename { get filename pointer }
  52. mov ah,3ch { create file }
  53. int 21h
  54. jc open_err { if failed, return error code }
  55. lds bx, handle { get handle pointer }
  56. mov word ptr [bx],ax { save the handle }
  57. xor ax,ax { return zero for OK }
  58. open_err:
  59. pop ds { restore registers and exit }
  60. pop es
  61. pop dx
  62. pop cx
  63. pop bx
  64. pop di
  65. pop si
  66. end; { jdos_open }
  67. function jdos_close (handle : short) : short; assembler;
  68. { Close the file handle }
  69. label
  70. close_err;
  71. asm
  72. push si { save all registers for safety }
  73. push di
  74. push bx
  75. push cx
  76. push dx
  77. push es
  78. push ds
  79. mov bx, handle { file handle }
  80. mov ah,3eh { close file }
  81. int 21h
  82. jc close_err { if failed, return error code }
  83. xor ax,ax { return zero for OK }
  84. close_err:
  85. pop ds { restore registers and exit }
  86. pop es
  87. pop dx
  88. pop cx
  89. pop bx
  90. pop di
  91. pop si
  92. end; { jdos_close }
  93. function jdos_seek (handle : short; offs : long) : short; assembler;
  94. { Set file position }
  95. label
  96. seek_err;
  97. asm
  98. push si { save all registers for safety }
  99. push di
  100. push bx
  101. push cx
  102. push dx
  103. push es
  104. push ds
  105. mov bx, handle { file handle }
  106. mov dx, offs.word { LS offset }
  107. mov cx, offs.word[2] { MS offset }
  108. mov ax,4200h { absolute seek }
  109. int 21h
  110. jc seek_err { if failed, return error code }
  111. xor ax,ax { return zero for OK }
  112. seek_err:
  113. pop ds { restore registers and exit }
  114. pop es
  115. pop dx
  116. pop cx
  117. pop bx
  118. pop di
  119. pop si
  120. end; { jdos_seek }
  121. function jdos_read (handle : short; buffer : pointer; {FAR}
  122. count : ushort) : short; assembler;
  123. { Read from file }
  124. label
  125. read_ok, read_err;
  126. asm
  127. push si { save all registers for safety }
  128. push di
  129. push bx
  130. push cx
  131. push dx
  132. push es
  133. push ds
  134. mov bx, handle { file handle }
  135. lds dx, buffer { buffer address }
  136. mov cx, count { number of bytes }
  137. mov ah,3fh { read file }
  138. int 21h
  139. jc read_err { if failed, return error code }
  140. cmp ax, count { make sure all bytes were read }
  141. je read_ok
  142. mov ax,1 { else return 1 for not OK }
  143. jmp read_err
  144. read_ok:
  145. xor ax,ax { return zero for OK }
  146. read_err:
  147. pop ds { restore registers and exit }
  148. pop es
  149. pop dx
  150. pop cx
  151. pop bx
  152. pop di
  153. pop si
  154. end; { jdos_read }
  155. function jdos_write (handle : short; buffer : pointer; {FAR}
  156. count : ushort) : short; assembler;
  157. { Write to file }
  158. label
  159. write_ok, write_err;
  160. asm
  161. push si { save all registers for safety }
  162. push di
  163. push bx
  164. push cx
  165. push dx
  166. push es
  167. push ds
  168. mov bx, handle { file handle }
  169. lds dx, buffer { buffer address }
  170. mov cx, count { number of bytes }
  171. mov ah,40h { write file }
  172. int 21h
  173. jc write_err { if failed, return error code }
  174. cmp ax, count { make sure all bytes written }
  175. je write_ok
  176. mov ax,1 { else return 1 for not OK }
  177. jmp write_err
  178. write_ok:
  179. xor ax,ax { return zero for OK }
  180. write_err:
  181. pop ds { restore registers and exit }
  182. pop es
  183. pop dx
  184. pop cx
  185. pop bx
  186. pop di
  187. pop si
  188. end; { jdos_write }
  189. procedure jxms_getdriver (var driver : XMSDRIVER); assembler;
  190. { Get the address of the XMS driver, or NIL if not available }
  191. label
  192. xmsavail, xmsavail_done;
  193. asm
  194. push si { save all registers for safety }
  195. push di
  196. push bx
  197. push cx
  198. push dx
  199. push es
  200. push ds
  201. mov ax,4300h { call multiplex interrupt with }
  202. int 2fh { a magic cookie, hex 4300 }
  203. cmp al,80h { AL should contain hex 80 }
  204. je xmsavail
  205. xor dx,dx { no XMS driver available }
  206. xor ax,ax { return a nil pointer }
  207. jmp xmsavail_done
  208. xmsavail:
  209. mov ax,4310h { fetch driver address with }
  210. int 2fh { another magic cookie }
  211. mov dx,es { copy address to dx:ax }
  212. mov ax,bx
  213. xmsavail_done:
  214. les bx,dword ptr [bp+6] { get pointer to return value }
  215. mov word ptr es:[bx],ax
  216. mov word ptr es:[bx+2],dx
  217. pop ds { restore registers and exit }
  218. pop es
  219. pop dx
  220. pop cx
  221. pop bx
  222. pop di
  223. pop si
  224. end; { jxms_getdriver }
  225. procedure jxms_calldriver (driver : XMSDRIVER;
  226. var ctx : XMScontext); assembler;
  227. { The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.}
  228. { These are loaded, the XMS call is performed, and the new values of the }
  229. { AX,DX,BX registers are written back to the context structure. }
  230. asm
  231. push si { save all registers for safety }
  232. push di
  233. push bx
  234. push cx
  235. push dx
  236. push es
  237. push ds
  238. les bx, ctx { get XMScontext pointer }
  239. mov ax,word ptr es:[bx] { load registers }
  240. mov dx,word ptr es:[bx+2]
  241. mov si,word ptr es:[bx+6]
  242. mov ds,word ptr es:[bx+8]
  243. mov bx,word ptr es:[bx+4]
  244. call dword ptr driver { call the driver }
  245. mov cx,bx { save returned BX for a sec }
  246. les bx, ctx { get XMScontext pointer }
  247. mov word ptr es:[bx],ax { put back ax,dx,bx }
  248. mov word ptr es:[bx+2],dx
  249. mov word ptr es:[bx+4],cx
  250. pop ds { restore registers and exit }
  251. pop es
  252. pop dx
  253. pop cx
  254. pop bx
  255. pop di
  256. pop si
  257. end; { jxms_calldriver }
  258. function jems_available : short; assembler;
  259. { Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)}
  260. label
  261. no_ems, avail_done;
  262. const
  263. ASCII_device_name : packed array[0..7] of char = 'EMMXXXX0';
  264. asm
  265. push si { save all registers for safety }
  266. push di
  267. push bx
  268. push cx
  269. push dx
  270. push es
  271. push ds
  272. mov ax,3567h { get interrupt vector 67h }
  273. int 21h
  274. push cs
  275. pop ds
  276. mov di,000ah { check offs 10 in returned seg }
  277. lea si, ASCII_device_name { against literal string }
  278. mov cx,8
  279. cld
  280. repe cmpsb
  281. jne no_ems
  282. mov ax,1 { match, it's there }
  283. jmp avail_done
  284. no_ems: xor ax,ax { it's not there }
  285. avail_done:
  286. pop ds { restore registers and exit }
  287. pop es
  288. pop dx
  289. pop cx
  290. pop bx
  291. pop di
  292. pop si
  293. end; { jems_available }
  294. procedure jems_calldriver (var ctx : EMScontext); assembler;
  295. { The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. }
  296. { These are loaded, the EMS trap is performed, and the new values of the }
  297. { AX,DX,BX registers are written back to the context structure. }
  298. asm
  299. push si { save all registers for safety }
  300. push di
  301. push bx
  302. push cx
  303. push dx
  304. push es
  305. push ds
  306. les bx, ctx { get EMScontext pointer }
  307. mov ax, es:[bx].EMScontext.&ax { load registers }
  308. mov dx, es:[bx].EMScontext.&dx
  309. mov si, es:[bx].EMScontext.&ds_si.word
  310. mov ds, es:[bx].EMScontext.&ds_si.word[2]
  311. mov bx, es:[bx].EMScontext.&bx
  312. int 67h { call the EMS driver }
  313. mov cx,bx { save returned BX for a sec }
  314. les bx, ctx { get EMScontext pointer }
  315. mov es:[bx].EMScontext.&ax, ax { put back ax,dx,bx }
  316. mov es:[bx].EMScontext.&dx, dx
  317. mov es:[bx].EMScontext.&bx, cx
  318. pop ds { restore registers and exit }
  319. pop es
  320. pop dx
  321. pop cx
  322. pop bx
  323. pop di
  324. pop si
  325. end; { jems_calldriver }
  326. end.