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