jmemdosa.asm 8.1 KB

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