;
botseg          segment at 0000H        ;bottom of memory
                org 413H                ;offset to memory words
memsize         dw ?                    ;1st word, what the system thinks
truemem         dw ?                    ;2nd word, what really is
botseg          ends
;
CSEG            SEGMENT PARA PUBLIC 'CODE'
;
XDV             PROC FAR
                ASSUME CS:CSEG,DS:CSEG,ES:CSEG
BEGIN:
START           EQU $
;  Header for DOS Device Drivers
NEXT_DEV        DW  -1         ; fake pointer to next device driver
                dw -1
ATTRIBUTE       DW  08000H     ;character device without capability
STRATEGY        DW  XDV_STRAT  ;pointer to function which queues request header
FUNC_CALL       DW  XDV_FUNC   ;pointer to operating functions switch
DEV_NAME        DB  '_SETMEM_' ;8-byte device name field
;
;  Pointer to function request from DOS
RH_OFF          DW  ?    
RH_SEG          DW  ?
;
;  Device Strategy - set pointer to request header from DOS
XDV_STRAT:      MOV  CS:RH_SEG,ES
                MOV  CS:RH_OFF,BX
                RET
;
;  Device Interrupt Handler 
XDV_FUNC:       ;preserve machine state
                PUSHF
                CLD
                PUSH  DS
                PUSH  ES
                PUSH  AX
                PUSH  BX
                PUSH  CX
                PUSH  DX
                PUSH  DI
                PUSH  SI
;      Set DS to CS value
                PUSH  CS
                POP   DS
;      Load ES and BX with RH_SEG and RH_OFF
                LES   BX,DWORD PTR CS:RH_OFF
;      Branch to correct function in FUNTAB based on function code from DOS
                MOV   AL,ES:[BX+2]      ; get function code byte
                OR    AL,AL             ;is this INIT
                jnz   noth2             ;no get out of here
;
;
;
;  Device Initialization
INIT:           push ds                 ;save ds
                xor ax,ax               ;clear ax
                push ax                 ;move ax...
                pop ds                  ; ... to ds
                assume ds:botseg        ;let the assembler know
                mov ax,truemem          ;get the true memory size
                cmp ax,memsize          ;compare to what system thinks
                jz nothin               ;same? do nothing
                mov memsize,ax          ;tell system the true memory
                int 19H                 ;reload DOS
nothin:         assume ds:cseg          ;tell the assembler we're back
                pop ds                  ;and restore ds
                MOV  DX,OFFSET LASTWORD      ;end offset of XDV
                MOV  ES:[BX+14],DX
                MOV  ES:[BX+16],CS         ; and segment into request hdr 
noth2:          MOV  WORD PTR ES:[BX+3],0100H ;set status word to DONE, NOERROR
;
;  Restore registers and exit
EXIT:           POP  SI
                POP  DI
                POP  DX
                POP  CX
                POP  BX
                POP  AX
                POP  ES                  
                POP  DS
                POPF
                RET
LASTWORD        EQU $         ;end of XDV - used for terminate & stay resident
;
XDV             ENDP
CSEG            ENDS
                END  BEGIN

