SC_INDEX       = 03C4H
SC_MAP_MASK    = 2    
SC_MEM_MODE    = 4

GC_INDEX       = 03CEH
GC_READ_MAP    = 4 
GC_GRAPH_MODE  = 5  
GC_MISCELL     = 6   
GC_BIT_MASK    = 8    

CRTC_INDEX      = 03D4H  
CC_HOR_TOTAL    = 00
CC_HOR_DISPLAY  = 01H
CC_START_H_BLANK= 02H
CC_END_H_BLANK  = 03H
CC_START_H_RETRA= 04H
CC_END_H_RETRACE= 05H
CC_VERT_TOT_REG = 06H
CC_OVERFLOW     = 07H 
CC_V_PEL_PANNING= 08H
CC_MAX_SCAN     = 09H
CC_START_HI     = 0CH
CC_START_LO     = 0DH
CC_START_V_RETRA= 010H
CC_END_V_RETRACE= 011H
CC_END_V_DISPLAY= 012H
CC_OFFSET       = 013H 
CC_UNDERLINE    = 014H
CC_START_V_BLANK= 015H
CC_END_V_BLANK  = 016H
CC_MODE_CTRL    = 017H
CC_LINE_COMPARE = 018H

CA_INDEX_ECR    = 03C0H
CA_INDEX_LEC    = 03C1H
CA_OVERSCAN     = 011H
CA_MODE         = 010H 
CA_H_PELPAN     = 013H

DAC_WRITE_ADR  = 03C8H       
DAC_READ_ADR   = 03C7H        
DAC_DATA       = 03C9H         

VERT_RETRACE   = 03DAH          



PAGE1          = 0A000H
PAGE2          = 0A000H+1000
PAGE3          = 0A000H+2000
PAGE4          = 0A000H+3000
BIGPAGE1       = Page1
BIGPAGE2       = Page2





;************************************
;* Fixe le mode 320*200 256c 4pages *
;************************************

MODE_4P MACRO MODE

 MOV   AL,MODE
 MOV   AH,00H
 INT   10H

 MOV   DX,GC_INDEX
 MOV   AL,GC_GRAPH_MODE
 OUT   DX,AL
 INC   DX
 IN    AL,DX
 AND   AL,11101111b
 OUT   DX,AL
 DEC   DX

 MOV   AL,GC_MISCELL
 OUT   DX,AL
 INC   DX
 IN    AL,DX
 AND   AL,11111101b
 OUT   DX,AL
 MOV   DX,SC_INDEX
 MOV   AL,SC_MEM_MODE
 OUT   DX,AL
 INC   DX
 IN    AL,DX
 AND   AL,11110111b
 or    AL,4
 OUT   DX,AL
 MOV   AX,0A000h
 MOV   ES,AX
 XOR   DI,DI
 MOV   AX,DI
 MOV   CX,8000h
 REP   STOSW
 MOV   DX,CRTC_INDEX
 MOV   AL,CC_UNDERLINE
 OUT   DX,AL
 INC   DX
 IN    AL,DX
 AND   AL,10111111b
 OUT   DX,AL
 DEC   DX
 MOV   AL,CC_MODE_CTRL
 OUT   DX,AL
 INC   DX
 IN    AL,DX
 OR    AL,01000000b
 OUT   DX,AL
ENDM


;**************************************
;* Selectionne le plan de bit adress‚ *
;* entr‚: numero du plan de bit       *
;**************************************
PLAN_BIT MACRO NUMERO
 PUSH AX
 PUSH DX
 PUSH CX
 MOV CL,NUMERO
 MOV DX,SC_INDEX
 MOV AL,02
 OUT DX,AL
 MOV AL,1
 SHL AL,CL
 INC DX
 OUT DX,AL
 POP CX
 POP DX
 POP AX
ENDM

;*****************************
;* attend le retour faisceau *
;*****************************
WAIT_RETRACE MACRO
       MOV DX,VERT_RETRACE
 BOUC1: IN AL,DX
        TEST AL,8
        JNE BOUC1

 BOUC2: IN AL,DX
        TEST AL,8
        JE BOUC2
ENDM


;**********************************
;* Montre l'une des quatre pages  *
;* video.                         *
;* entr‚: page a visualiser       *
;**********************************

MONTRE_PAGE MACRO PAGE
 MOV DX,CRTC_INDEX
 MOV SI,PAGE
 MOV CS:PAGEVIS,SI
 SHL SI,1
 MOV BX,CS:SI+PAGESV

 MOV AL,CC_START_HI
 MOV AH,BH
 OUT DX,AX
 MOV AL,CC_START_LO
 MOV AH,BL
 OUT DX,AX
ENDM

;**********************************
;* Montre une partie de la ram    *
;* entr‚:adresse dans la ram video*
;**********************************

MONTRE_VIDEO MACRO ADRESV
 MOV DX,CRTC_INDEX
 MOV BX,ADRESV

 MOV AL,CC_START_HI
 MOV AH,BH
 OUT DX,AX

 MOV AL,CC_START_LO
 MOV AH,BL
 OUT DX,AX
ENDM


;*******************************
;* Selectionne la page active  *
;* fixe la variable CS:ADDpage *
;*                  CS:PAGEact *
;* entr‚ :numero de la page.   *
;*******************************

SELECT_PAGE MACRO PAGE
 MOV SI,PAGE
 MOV CS:PAGEACT,SI
 SHL SI,1
 MOV AX,CS:PAGESA+SI
 MOV CS:ADDPAGE,AX
ENDM

;********************************
;* Variables necessaire au prog.*
;********************************
GRAPH_ROUTINES MACRO
 PAGESV DW 00000H
        DW 03E80H
        DW 07D00H
        DW 0BB80H

 PAGESA DW 0A000H
        DW 0A000H+1000
        DW 0A000H+2000
        DW 0A000H+3000

 ADDPAGE DW 0
 PAGEACT DW 0
 PAGEVIS DW 0

 PUT_M_RAM:
  PUSH CX
  PLAN_BIT 0
  XOR SI,SI
  XOR DI,DI
  MRAM0:
   MOVSB
   ADD SI,3
  LOOP MRAM0
  POP CX
  PUSH CX
  PLAN_BIT 1
  MOV SI,1
  XOR DI,DI
  MRAM1:
   MOVSB
   ADD SI,3
  LOOP MRAM1
  POP CX
  PUSH CX
  PLAN_BIT 2
  MOV SI,2
  XOR DI,DI
  MRAM2:
   MOVSB
   ADD SI,3
  LOOP MRAM2
  POP CX
  PLAN_BIT 3
  MOV SI,3
  XOR DI,DI
  MRAM3:
   MOVSB
   ADD SI,3
  LOOP MRAM3
 RET
ENDM

;**********************************
;** Divise l'ecran en deux partie *
;**  entr‚:ligne ou se fait la    *
;**         division.             *
;** La premiere partie depend des *
;** registre 0DH et 0CH.          *
;** La seconde partie est le      *
;** depart de la ram Video        *
;** "ligne reel=ligne*2"          *
;**********************************


LINE_COMPARE MACRO LIGNE 
 MOV DX,CRTC_INDEX
 MOV AL,CC_END_V_RETRACE             ;enleve la protection des 7 premiers 
 OUT DX,AL                           ;registres du CRTC.
 INC DX
 IN  AL,DX
 AND AL,01111111b
 OUT DX,AL
 DEC DX

 MOV AL,CC_LINE_COMPARE              ;Fixe la valeur du registre line compare.
 MOV BX,LIGNE
 MOV AH,BL
 OUT DX,AX

 MOV AL,CC_OVERFLOW                  ;Fixe le 8em bit qui se trouve dans
 OUT DX,AL                           ;le registre overflow.
 INC DX
 IN AL,DX
 TEST BH,1
 JNZ COMPB0
 AND AL,11101111b
 JMP COMPB1
 COMPB0:
 OR  AL,00010000b
 COMPB1:
 OUT DX,AL
 DEC DX

 MOV AL,CC_MAX_SCAN                    ;Fixe le 9em bit dans le registre,
 OUT DX,AL                             ;maximum scan line.
 INC DX
 IN  AL,DX
 TEST BH,2
 JNZ COMPB2
 AND AL,10111111b
 JMP COMPB3
 COMPB2:
 OR  AL,01000000b
 COMPB3:
 OUT DX,AL

ENDM


;*************************************
;* Definit l'offset des ligne        *
;* suivant le mode il faut le divise *
;* chaine4:divise  par 4             *
;* odd/even:divise par 2             *
;*************************************

OFFSET_CRTC MACRO OFF
 MOV DX,CRTC_INDEX
 MOV AL,CC_OFFSET
 MOV AH,OFF
 OUT DX,AX
ENDM

;*************************
;* Passe au mode 320*400 *
;*************************
GO_400 MACRO
 MOV DX,CRTC_INDEX
 MOV AL,CC_MAX_SCAN
 OUT DX,AL
 INC DX
 IN AL,DX
 AND AL,01100000b
 OUT DX,AL
ENDM

;*************************
;* Passe au mode 320*200 *
;*************************
GO_200 MACRO
 MOV DX,CRTC_INDEX
 MOV AL,CC_MAX_SCAN
 OUT DX,AL
 INC DX
 IN AL,DX
 OR  AL,10000000b
 OUT DX,AL
ENDM


;****************************
;* Enleve la protection en  *
;* ‚criture des 7 premiers  *
;* registres du CRTC.       *
;****************************

DEPROT_CRTC MACRO
 MOV DX,CRTC_INDEX
 MOV AL,CC_END_V_RETRACE
 OUT DX,AL
 INC DX
 IN  AL,DX
 AND AL,01111111b
 OUT DX,AL
ENDM

;***********************************************
;* Definit si le pel panning(smooth scrolling) *
;* doit s'effectuer sur les deux parties de    *
;* l'ecran dans le cas d'une division a l' aide*
;* de line compare                             *
;***********************************************
PEL_PANNING_DOUBLE MACRO
 CLI
 MOV DX,CA_INDEX_ECR
 MOV AL,CA_MODE
 OR  AL,32
 OUT DX,AL
 MOV AL,01100001b
 OUT DX,AL
 STI
ENDM

PEL_PANNING_SINGLE MACRO
 CLI
 MOV DX,CA_INDEX_ECR
 MOV AL,CA_MODE
 OR  AL,32
 OUT DX,AL
 MOV AL,01000001b
 OUT DX,AL
 STI

ENDM

;***************************
;* Effectue un pel panning *
;* entr‚:X,Y               *
;***************************
PEL_PANNING MACRO X,Y
 CLI
 MOV DX,CA_INDEX_ECR
 MOV AL,CA_H_PELPAN
 OR AL,32
 OUT DX,AL
 MOV AL,X
 AND AL,00001111b
 OUT DX,AL
 MOV DX,CRTC_INDEX
 MOV AL,CC_V_PEL_PANNING
 MOV AH,Y
 AND AH,00011111b
 OUT DX,AX
 STI
ENDM

;*******************************
;* Fixe la couleur de bordure  *
;*******************************
OVERSCAN MACRO COLOR
 MOV DX,CA_INDEX_ECR
 MOV AL,CA_OVERSCAN
 OR AL,32
 MOV AH,COLOR
 OUT DX,AL
 SHR AX,8
 OUT DX,AL
ENDM

;*********************************************
;* Copy un espace memoire dans la ram video. *
;*********************************************
PUT_MEM_RAM MACRO ADRD,ADRA,bytes
PUSH DS
 CLI
 CLD
 MOV CX,bytes
 SHR CX,2
 MOV AX,ADRA
 MOV ES,AX
 MOV AX,ADRD
 MOV DS,AX
 CALL PUT_M_RAM
POP DS
 STI
ENDM

;**********************
;* Fonction d'aide    *
;**********************

IF_PROTECT_BOOT MACRO
 MOV DX,CRTC_INDEX
 MOV AL,CC_END_V_RETRACE
 OUT DX,AL
 INC DX
 IN AL,DX
 TEST AL,10000000b
 JZ NOT_PROT
  INT 19H
 NOT_PROT:
ENDM



