;**********************************************************************terug.gif
;*                           A T O M   X M S                          *
;**********************************************************************
;* XMS ondersteuning voor Atom-in-PC                                  *
;**********************************************************************
;* Auteur:   Roland Leurs                                             *
;* Datum:    06 juli 1997                                             *
;**********************************************************************
XMSPAGES  DB 0                   ;DEFAULT GEEN XMS GEHEUGEN GERESERVEERD
XMSCURPAG DB 0                   ;XMS CURRENT PAGE IN BUFFER
XMSHANDLE DW (?)                 ;HANDLE VOOR XMS GEHEUGENBLOK
XMSDRV    EQU THIS DWORD         ;STARTADRES XMS DRIVER (HIMEM.SYS)
XMSOFS    DW (?)                 ;OFFSETADRES XMS FUNCTIES
XMSSEG    DW (?)                 ;SEGMENTADRES XMS FUNCTIES
COPYTBL   DW 8 DUP (?)           ;DATA TABEL VOOR KOPIEERROUTINE
XMSFILE   DW 2 DUP (0)           ;XMS FILE POINTER
XMS:      CALL LEESBYTE          ;LEES XMS COMMANDO VAN ATOM
          MOV  FUN_CODE,AL       ;SLA COMMANDO OP IN WERKRUIMTE
          CMP  AL,10H            ;TEST OP GELDIG COMMANDO
          JAE  XMS_ERR           ;SPRING INDIEN ONGELDIG COMMANDO
          XOR  AH,AH             ;BEREKEN INDEX VOOR COMMANDO TABEL
          SHL  AX,1
          MOV  DI,AX             ;ZET OFFSET IN INDEX REGISTER
          JMP  WORD PTR COMTB[DI];SPRING NAAR COMMANDO
XMS_ERR:  JMP  ERROR             ;GEEF FOUTMELDING
;-----------------------------------------------------------------------
; COMMANDO TABEL
;-----------------------------------------------------------------------
                
COMTB:    DW   XMSINFO,XMSLDPG,XMSLDPG,XMSLDPG
          DW   XMS_ERR,XMS_ERR,XMS_ERR,XMS_ERR
          DW   XMS_ERR,XMS_ERR,XMS_ERR,XMS_ERR
          DW   XMS_ERR,XMS_ERR,XMS_ERR,XMS_ERR
;-----------------------------------------------------------------------
; SUBROUTINES VOOR COMMANDO'S
;-----------------------------------------------------------------------
GETPGNR   PROC NEAR               ;TEST OF OPGEGEVEN PAGINA NUMMER GELDIG IS
          CALL LEESBYTE           ;LEES PAGINANUMMER VAN ATOM
GETPGNR1: CMP  XMSPAGES,AL        ;VOER VERGELIJKING UIT
          JAE  VALPAGE            ;ALS GELDIG SPRINGEN
          STC                     ;ZET CARRY, PAGINA IS NIET GELDIG
          JMP  SHORT ENDTEST      ;SPRING ALTIJD
VALPAGE:  CLC                     ;WIS CARRY, PAGINA IS GELDIG
ENDTEST:  RET                     ;EINDE ROUTINE
GETPGNR   ENDP
ADRES     PROC NEAR               ;LEEST ADRES VAN ATOM IN BX REGISTER
          PUSH AX                 ;SAVE AX
          CALL LEESBYTE           ;LEES LAGE BYTE VAN ATOM
          MOV  BL,AL              ;ZET IN BL REGISTER
          CALL LEESBYTE           ;LEES HOGE BYTE VAN ATOM
          MOV  BH,AL              ;ZET IN BH REGISTER
          SUB  BX,4000H           ;OFFSET ALLEEN TUSSEN 0-3FFFH TOEGESTAAN
          CMP  BX,4000H
          JB   ADRES1             ;SPRING INDIEN OFFSET GELDIG IS
          STC                     ;ZET CARRY VOOR FOUT
          JMP  SHORT ADRES2
ADRES1:   CLC                     ;WIS CARRY
ADRES2:   POP  AX                 ;HAAL AX TERUG
          RET                     ;EINDE ROUTINE MET ATOM ADRES IN BX
ADRES     ENDP
XMSADRES  PROC NEAR               ;BEREKEN ADRES IN XMS GEHEUGEN
          MOV  DX,4000H           ;LAADT DX MET CONSTANTE
          XOR  AH,AH              ;AX = PAGINA NUMMER
          MUL  DX                 ;DX:AX = 16K*PAGINANUMMER
          ADD  AX,BX              ;TEL DAAR DE OFFSET BIJ
          RET
XMSADRES  ENDP                    ;OFFSET ADRES STAAT NU IN DX:AX
XMS2BUF   PROC NEAR               ;KOPIEER PAGINA VAN XMS NAAR BUFFER
          PUSH AX                 ;SAVE GEBRUIKTE REGISTERS
          PUSH BX
          PUSH DX
          MOV  XMSCURPAG,AL       ;ZET NIEUW XMS PAGINANUMMER IN CURRENT PAGE
          MOV  COPYTBL[0],4000H   ;ZET BLOKLENGTE IN DATATABEL
          MOV  COPYTBL[2],0000H
          MOV  DX,XMSHANDLE       ;ZET HANDLE IN DATATABEL
          MOV  COPYTBL[4],DX
          XOR  BX,BX              ;CLEAR OFFSET
          CALL XMSADRES           ;BEREKEN ADRES IN DX:AX
          MOV  COPYTBL[6],AX      ;ZET ADRES IN DATATABEL
          MOV  COPYTBL[8],DX
          MOV  COPYTBL[10],0      ;COPY NAAR CONVENTIONEEL GEHEUGEN
          MOV  DX,OFFSET XMSBUFFER   ;ZET BUFFER ADRES IN TABEL
          MOV  COPYTBL[12],DX
          MOV  COPYTBL[14],DS
          MOV  AH,0BH             ;LAADT FUNCTIENUMMER
          LEA  SI,COPYTBL         ;LAADT POINTER NAAR TABEL
          CALL DWORD PTR [XMSDRV] ;VOER OPDRACHT UIT
X2BOK:    POP  DX                 ;GEBRUIKTE REGISTERS TERUGHALEN
          POP  BX
          POP  AX
          RET                     ;EINDE ROUTINE
XMS2BUF   ENDP
BUF2XMS   PROC NEAR               ;KOPIEER PAGINA VAN BUFFER NAAR XMS
          PUSH AX                 ;SAVE GEBRUIKTE REGISTERS
          PUSH BX
          PUSH DX
          MOV  COPYTBL[0],4000H   ;ZET BLOKLENGTE IN DATATABEL
          MOV  COPYTBL[2],0000H
          MOV  COPYTBL[4],0       ;COPY NAAR XMS GEHEUGEN
          MOV  DX,OFFSET XMSBUFFER ;ZET BUFFER ADRES IN TABEL
          MOV  COPYTBL[6],DX
          MOV  COPYTBL[8],DS
          MOV  DX,XMSHANDLE       ;ZET HANDLE IN DATATABEL
          MOV  COPYTBL[10],DX
          XOR  BX,BX              ;CLEAR OFFSET
          CALL XMSADRES           ;BEREKEN ADRES IN DX:AX
          MOV  COPYTBL[12],AX     ;ZET ADRES IN DATATABEL
          MOV  COPYTBL[14],DX
          MOV  AH,0BH             ;LAADT FUNCTIENUMMER
          LEA  SI,COPYTBL         ;LAADT POINTER NAAR TABEL
          CALL DWORD PTR [XMSDRV] ;VOER OPDRACHT UIT
B2XOK:    POP  DX                 ;GEBRUIKTE REGISTERS TERUGHALEN
          POP  BX
          POP  AX
          RET                     ;EINDE ROUTINE
BUF2XMS   ENDP
XMSAT2PC  PROC NEAR               ;LEEST XMS BUFFER VAN ATOM
          PUSH AX                 ;SAVE REGISTERS
          PUSH DI
          MOV  DI,0000H           ;RESET POINTER
XATOM2PC: CALL LEESBYTE           ;LEES BYTE
          MOV  XMSBUFFER[DI],AL   ;ZET DATA IN BUFFER
          INC  DI                 ;VERHOOG POINTER
          CMP  DI,4000H           ;ALLES GELEZEN
          JNE  XATOM2PC           ;NEE, DAN VOLGENDE BYTE
          POP  DI                 ;HERSTEL REGISTERS
          POP  AX
          RET                     ;EINDE ROUTINE
XMSAT2PC  ENDP
XMSPC2AT  PROC NEAR               ;SCHRIJFT XMS BUFFER NAAR ATOM
          PUSH AX                 ;SAVE REGISTERS
          PUSH SI
          MOV  SI,0000H           ;RESET POINTER
XPC2ATOM: MOV  AL,XMSBUFFER[SI]   ;ZET DATA IN BUFFER
          CALL ZENDBYTE           ;STUUR BYTE NAAR ATOM
          INC  SI                 ;VERHOOG POINTER
          CMP  SI,4000H           ;ALLES GELEZEN
          JNE  XPC2ATOM           ;NEE, DAN VOLGENDE BYTE
          POP  SI                 ;HERSTEL REGISTERS
          POP  AX
          RET                     ;EINDE ROUTINE
XMSPC2AT  ENDP
;-----------------------------------------------------------------------
; COMMANDO'S
;-----------------------------------------------------------------------
; functie 0: versie opvragen                                      xmsinfo
;   -invoer:  geen
;   -uitvoer: versienummer
;             releasenummer
;             aantal xms pagina's
;
; functie 1: pagina voorzetten                                    xmsldpg
;   -invoer:  nieuw paginanummer
;   -uitvoer: (direct na opgave van paginanummer) statuscode
;             16 kb data
; opmerking: bij dit commando wordt de huidige
;            pagina niet opgeslagen in xmsgeheugen
;
; functie 2: pagina voorzetten                                    xmsldpg
;   -invoer:  huidig paginanummer
;             16 kb data
;   -uitvoer: (direct na opgave van paginanummer) statuscode
; opmerking: bij dit commando wordt de nieuwe
;            pagina niet gelezen in het atomgeheugen
;
; functie 3: pagina voorzetten                                    xmsldpg
;   -invoer:  huidig paginanummer
;             16 kb data
;             nieuw paginanummer
;   -uitvoer: (direct na opgave van paginanummers) statuscode
;             16 kb data
; opmerking: de huidige pagina wordt opgeslagen in
;            het xms geheugen en de nieuwe pagina
;            wordt in het atomgeheugen gelezen
;
;-----------------------------------------------------------------------
XMSINFO:  MOV  AX,02H             ;AL=VERSIENUMMER
          CALL ZENDBYTE           ;STUUR NAAR ATOM
          MOV  AL,00H             ;AL=RELEASE NUMMER
          CALL ZENDBYTE
          MOV  AL,XMSPAGES        ;AL=HOOGSTE BESCHIKBARE PAGINANUMMER
          CALL ZENDBYTE
          JMP  LEESCOM            ;EINDE COMMANDO 0
XMSLDPG:  MOV  AL,FUN_CODE        ;LAADT COMMANDONUMMER
          TEST AL,00000001B       ;MOET PAGINA GESCHREVEN WORDEN?
          JZ   XMSLD1             ;NEE, DAN OVERSLAAN
          CALL GETPGNR            ;LEES PAGINANUMMER
          JC   PGERROR            ;SPRING ALS FOUT
          CALL XMSAT2PC           ;LEES PAGINA IN BUFFER
          CALL BUF2XMS            ;KOPIEER BUFFER NAAR XMS GEHEUGEN
XMSLD1:   MOV  AL,FUN_CODE        ;LAADT COMMANDONUMMER NOGMAALS
          TEST AL,00000010B       ;MOET PAGINA GELEZEN WORDEN?
          JZ   XMSLD2             ;NEE, DAN OVERSLAAN
          CALL GETPGNR            ;LEES PAGINANUMMER
          JC   PGERROR            ;SPRING ALS FOUT
          CALL XMS2BUF            ;KOPIEER XMS GEHEUGEN NAAR BUFFER
          CALL XMSPC2AT           ;STUUR BUFFER NAAR ATOM
XMSLD2:   JMP  LEESCOM            ;EINDE COMMANDO 1
PGERROR: ; MOV  AL,1               ;FOUTSTATUS 1: ONGELDIGE XMS PAGINA GEGEVEN
         ; CALL ZENDBYTE           ;STUUR NAAR ATOM
          JMP  LEESCOM            ;COMMANDO AFGEBROKEN
;-- START EN INITIALISERINGSROUTINE ------------------------------------
XMS_INIT  PROC NEAR
INSTALL:  PUSH BX                 ;BEWAAR BX (commandline pointer)
          MOV  AX,4300H           ;TEST OF HIMEM.SYS GELADEN IS
          INT  2FH
          POP  BX                 ;HAAL BX TERUG
          CMP  AL,80H             ;ALS HIMEM GELADEN IS
          JE   HIMEM              ;VERDER GAAN
NOHIMEM:  MOV  XMSPAGES,0         ;SIMPEL, GEEN XMS GEHEUGEN BESCHIKBAAR
          JMP  XMS_EXIT           ;EINDE INITIALISATIE VAN XMS GEHEUGEN
HIMEM:    PUSH BX
          MOV  AX,4310H           ;ADRES VOOR XMS FUNCTIES OPVRAGEN
          INT  2FH
          MOV  XMSOFS,BX          ;BERG ADRES XMS FUNCTIES OP
          MOV  XMSSEG,ES
          MOV  AH,00              ;XMS VERSIENUMMER OPVRAGEN
          CALL DWORD PTR [XMSDRV]
          POP  BX
          CMP  AH,2               ;TEST OP VERSIE 2 OF HOGER
          JB   NOHIMEM            ;LAGER MAG NIET, GEEN GEHEUGEN GERESERVEERD
SKIPSPC:  CALL LEESCMDLINE        ;LEES KARAKTER
          CMP  AL,' '             ;NEGEER SPATIE
          JE   SKIPSPC
          XOR  DX,DX              ;PARAMETER KOMT IN DX
          XOR  AH,AH
DIGIT:    CMP  AL,0DH             ;TEST OP EINDE INVOER
          JE   ASC2BIN            ;SPRING BIJ EINDE REGEL
          CMP  AL,' '             ;SPATIE IS OOK EINDE INVOER
          JE   ASC2BIN            ;DAN DUS OOK SPRINGEN
          CMP  AL,'0'             ;TEST OP GELDIG DIGIT
          JB   NOHIMEM            ;SPRING INDIEN ONGELDIG TEKEN
          CMP  AL,'9'
          JA   NOHIMEM
          SUB  AL,'0'             ;CONVERTEER AL NAAR BINAIRE WAARDE
          PUSH BX
          IMUL DX,10              ;DX=DX*10+AL
          POP  BX
          ADD  DX,AX
          CALL LEESCMDLINE        ;LEES VOLGENDE DIGIT
          JMP  SHORT DIGIT
ASC2BIN:  CMP  DX,1000H           ;TEST OP ONGELDIGE WAARDE
          JA   NOHIMEM            ;SPRING INDIEN TE GROOT
          SHR  DX,4               ;BEREKEN AANTAL PAGINA'S VAN 16 KB
          CMP  DX,0               ;TEST RESULTAAT
          JE   NOHIMEM            ;PARAMETER TE KLEIN, NIETS TE RESERVEREN
          DEC  DX                 ;BEPAAL HOOGSTE PAGINA NUMMER
          MOV  XMSPAGES,DL        ;BERG RESULTAAT OP
RESXMS:   PUSH BX
          MOV  DL,XMSPAGES        ;LAADT AANTAL GEWENSTE PAGINA'S
          INC  DX                 ;TEL ER 1 BIJ OP
          SHL  DX,4               ;MAAK ER HET AANTAL KB VAN
          MOV  AH,09H             ;LAADT XMS FUNCTIENUMMER
          CALL DWORD PTR [XMSDRV] ;PROBEER GEHEUGEN TE RESERVEREN
          POP  BX
          CMP  AX,0001H           ;TEST RESULTAAT
          JE   SUCCES             ;SPRING INDIEN HET GEHEUGEN GERESERVEERD IS
          DEC  XMSPAGES           ;GEHEUGEN NIET BESCHIKBAAR
          CMP  XMSPAGES,0FFH      ;PROBEER KLEINERE HOEVEELHEID
          JNE  RESXMS             ;MAAR OOIT HOUDT HET OP
          JMP  NOHIMEM            ;NIEKS BESCHIKBAAR DUS
SUCCES:   MOV  XMSHANDLE,DX       ;BERG HANDLE OP
XMS_EXIT: DEC  BX                 ;VERLAAG COMMANDLINE INDEX
          RET                     ;EINDE INITIALISATIE
XMS_INIT  ENDP
terug.gif