Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

; Product      : Gfx9000 library
; Version      : 0.7
; Main code by : Marcel delorme
; Support code : BiFi
; Bitbust      : Arjan Bakker
        
                include "g9klib.inc"
                MODULE  G9k
                  
;----------------------------------------------------------------------------;
; Gfx9000 general functions                                                  ;
;----------------------------------------------------------------------------;
                
Reset:
; Function :    Resets v9990, Deletes Palette, Sprites off,stops current blit operation, puts V9990 in correct RAM config and disables display
; Input    :    None
; Output   :    None
; Notes    :    Doesn't change current adjust
; Modifies :    A,B

                G9kReadReg G9K_DISPLAY_ADJUST + G9K_DIS_INC_READ
                PUSH    AF      ; Save adjust value

                ; Set reset state
                LD      A,G9K_SYS_CTRL_SRS
                OUT     (G9K_SYS_CTRL),A
                ; Clear reset state
                XOR     A,A
                OUT     (G9K_SYS_CTRL),A

                POP     AF
                OUT     (G9K_REG_DATA),A                ; Restore adjust value

                G9kWriteReg G9K_OPCODE,G9K_OPCODE_STOP
                G9kWriteReg G9K_CTRL,G9K_CTRL_DIS_SPD+G9K_CTRL_VRAM512

                ; Clear current palette
                G9kWriteReg G9K_PALETTE_PTR,0       ; A becomes 0
                LD      B,64 * 3
                      OUT     (G9K_PALETTE),A
                      DJNZ    $-2
;                OUT (G9K_OUTPUT_CTRL),A           ; Set output GFX9000
                RET


SetScreenMode:
; A = Mode
; B = Bit per dot
; C = Image size
; D = Interlace
; E = Palette control register

                LD      L,A
                ADD     A,A
                ADD     A,L     ; A  = A * 3
                LD      HL,G9K_MODE_TABLE
                ADD_HL_A
                LD      A,G9K_SCREEN_MODE0
                OUT     (G9K_REG_SELECT),A
                LD      A,(HL)  ; Get fixed settings for mode reg 6
                INC     HL
                OR      A,B     ; Set bits per dot
                OR      A,C     ; Set image size
                OUT     (G9K_REG_DATA),A
                LD      A,(HL)  ; Get fixed settings for mode reg 7
                INC     HL
                DEC     D
                INC     D       ; Is d 0?
                JR      Z,$+4
                     OR    A,G9K_SCR1_EO+G9K_SCR1_IL
                OUT     (G9K_REG_DATA),A
                LD      A,(HL)
                OUT     (G9K_SYS_CTRL),A
                G9kWriteReg G9K_PALETTE_CTRL,e
                RET

G9K_MODE_TABLE
                ; Pattern mode 1      (P1)
                DB      G9K_SCR0_P1+G9K_SCR0_DTCLK4
                DB      0
                DB      G9K_SYS_CTRL_XTAL
                ; Pattern mode 2      (P2)
                DB      G9K_SCR0_P2+G9K_SCR0_DTCLK4
                DB      0
                DB      G9K_SYS_CTRL_XTAL
                ; Bitmap 256 * 212    (B1)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK4
                DB      0
                DB      G9K_SYS_CTRL_XTAL
                ; Bitmap 384 * 240    (B2)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK2
                DB      0
                DB      G9K_SYS_CTRL_MCKIN
                ; Bitmap 512 * 212    (B3)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK2
                DB      0
                DB      G9K_SYS_CTRL_XTAL
                ; Bitmap 768 * 212    (B4)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK
                DB      0
                DB      G9K_SYS_CTRL_MCKIN
                ; Bitmap 640 * 400    (B5)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK
                DB      G9K_SCR1_HSCN
                DB      G9K_SYS_CTRL_XTAL
                ; Bitmap 640 * 480    (B6)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK
                DB      G9K_SCR1_HSCN+G9K_SCR1_C25M
                DB      G9K_SYS_CTRL_XTAL
                ; Bitmap 1024 * 212   (B7) (undocumented mode)
                DB      G9K_SCR0_BITMAP+G9K_SCR0_DTCLK
                DB      0
                DB      G9K_SYS_CTRL_XTAL


SetAdjust:
; Function: Adjustment of Gfx9000 display 
;                                                   L/T   C   R/B
; Input   :      BC =>   B -> Horizontal adjustment (-7 -> 0 -> 8)
;                        C -> Vertical adjustment   (-7 -> 0 -> 8)
; Modifies:      AF, BC
;
                LD      A,B
                ADD     A,7
                CP      16
                CCF
                RET     C       ; ERROR IN HORIZONTAL ADJUST
                SUB     7
                NEG
                AND     15
                LD      B,A
                LD      A,C
                ADD     A,7
                CP      16
                CCF
                RET     C       ; ERROR IN VERTICAL ADJUST
                SUB     7
                NEG
                AND     15
                RLCA
                RLCA
                RLCA
                RLCA
                OR      B
                LD      B,A
                G9kWriteReg G9K_DISPLAY_ADJUST,B
                RET

SetVramWrite:
; Function :    Sets Vram write address
; Input    :    E:HL VRAM address
; Output   :    none
; Modifies :    A,C

                 LD      A,G9K_WRITE_ADDR
                 OUT     (G9K_REG_SELECT),A
                 LD      C,G9K_REG_DATA
                 OUT     (C),L
                 OUT     (C),H
                 OUT     (C),E
                 RET

SetVramRead:
; Function :    Sets Vram read address
; Input    :    E:HL VRAM address
; Output   :    none
; Modifies :    A,C

                 LD      A,G9K_READ_ADDR
                 OUT     (G9K_REG_SELECT),A
                 LD      C,G9K_REG_DATA
                 OUT     (C),L
                 OUT     (C),H
                 OUT     (C),E
                 RET

Detect:
; Input    :    none
; Output   :    Z=detected , NZ=not detected
; Modifies :  A,C,E,H,L,F
; Works but could be saver
                  LD      E,0
                  LD      H,E
                  LD      L,E
                  CALL    SetVramWrite
                  LD      A,0A2h
                  OUT     (G9K_VRAM),A
                  LD      E,0
                  LD      H,E
                  LD      L,E
                  CALL    SetVramRead
                  IN      A,(G9K_VRAM)
                  CP      A,0A2h
                  RET


DisplayEnable:
; Modifies A
                  G9kReadReg G9K_CTRL+G9K_DIS_INC_READ
                  OR      A,G9K_CTRL_DISP
                  OUT     (G9K_REG_DATA),A
                  RET

DisplayDisable:
; Modifies A
                  G9kReadReg G9K_CTRL+G9K_DIS_INC_READ
                  AND     A,255-G9K_CTRL_DISP
                  OUT     (G9K_REG_DATA),A
                  RET

SpritesEnable:
; Modifies A
                  G9kReadReg G9K_CTRL+G9K_DIS_INC_READ
                  AND     A,255-G9K_CTRL_DIS_SPD
                  OUT     (G9K_REG_DATA),A
                  RET

SpritesDisable:
; Modifies A
                  G9kReadReg G9K_CTRL+G9K_DIS_INC_READ
                  OR      A,G9K_CTRL_DIS_SPD
                  OUT     (G9K_REG_DATA),A
                  RET        

SetScrollX:
; Set Horizontal scroll
; In:         HL =>        Left X-position
; Uses:       AF, HL
                PUSH    HL
                LD      A,G9K_SCROLL_LOW_X
                OUT     (G9K_REG_SELECT),a
                LD      A,L
                AND     A,7
                OUT     (G9K_REG_DATA),A
                LD      A,L
                SRL     H
                RRA
                SRL     H
                RRA
                SRL     H
                RRA
                OUT     (G9K_REG_DATA),A
                POP     HL
                RET

SetScrollY:
; Function :    Sets Scroll Y 
; Input    :    HL = Y
; Output   :    none
; Modifies :    A
                G9kWriteReg G9K_SCROLL_LOW_Y,L
                LD      A,(SCROLL_MODE)
                OR      A,H
                OUT     (G9K_REG_DATA),A                
                RET

                IFNDEF G9K_DISABLE_PATTERN

SetScrollXB:
; Set Horizontal scroll
; In:         HL =>        Left X-position
; Uses:       AF, BC, HL
                LD      A,G9K_SCROLL_LOW_X_B
                OUT     (G9K_REG_SELECT),a
                LD      A,L
                AND     A,7
                OUT     (G9K_REG_DATA),A
                LD      A,L
                SRL     H
                RRA
                SRL     H
                RRA
                SRL     H
                RRA
                OUT     (G9K_REG_DATA),A
                RET

                
SetScrollYB:
; Function :    Sets Scroll Y Layer B
; Input    :    HL = Y
; Output   :    none
; Modifies :    A
                G9kWriteReg G9K_SCROLL_LOW_Y_B,L
                LD      A,H
                OUT     (G9K_REG_DATA),A                
                RET             
                
                ENDIF

SetScrollMode:
; Vertical Scroll mode of Gfx9000
;
; In:         AF =>   A -> 0 = Roll by image space size
;                          1 = Roll by 256 lines
;                          2 = Roll by 512 lines
; Uses:       AF, B
                AND     A,3
                RRCA
                RRCA
                LD      (SCROLL_MODE),A
                RET
                
SCROLL_MODE     DB      0
                
                

SetBackDropColor:
; Change back drop color on Gfx9000 
; In:         A =>   A -> Back drop color
; Uses:       AF
;
                PUSH    AF
                LD      A,G9K_BACK_DROP_COLOR
                OUT     (G9K_REG_SELECT),A
                POP     AF
                AND     A,63
                OUT     (G9K_REG_DATA),A
                RET
                  
;----------------------------------------------------------------------------;
; Gfx9000 palette functions                                                  ;
;----------------------------------------------------------------------------;
WritePalette:
 ;  HL=pointer to palette data
 ;   C=Palette pointer offset
 ;   B=Number of bytes to write
 ;  Modifies : AF,BC,HL
                G9kWriteReg G9K_PALETTE_PTR,C  
                LD      C,G9K_PALETTE     
                OTIR
                RET

ReadPalette:
 ;  HL=pointer to buffer wherin palette data is stored
 ;   C=Palette pointer offset
 ;   B=Number of bytes to read
 ;
                G9kWriteReg G9K_PALETTE_PTR,C    
                LD      C,G9K_PALETTE      
                INIR
                RET

;----------------------------------------------------------------------------;
; Gfx9000 blitter functions                                                  ;
;----------------------------------------------------------------------------;

DrawFilledBox:
; HL = pointer to parameters (format: left,top,width,height)
; DE = Color
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,8*256+G9K_REG_DATA
                G9kCmdWait
                OTIR
                LD      A,G9K_FC
                OUT     (G9K_REG_SELECT),A
                OUT     (C),E
                OUT     (C),D   ; Set color
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LMMV
                RET
                
DrawLine:       
; HL = pointer to parameters
; DE = Color    
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,8*256+G9K_REG_DATA
                G9kCmdWait
                OTIR
                LD      A,G9K_FC
                OUT     (G9K_REG_SELECT),A
                OUT     (C),E
                OUT     (C),D   ; Set color
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LINE  
                RET     
DrawBox:                
; HL = pointer to parameters (format: left,top,width,height)
                PUSH    HL
                LD      A,G9K_ARG
                OUT     (G9K_REG_SELECT),A
                LD      BC,6*256+G9K_REG_DATA
                G9kCmdWait
                XOR     A,A
                OUT     (G9K_REG_DATA),A  ; Clear argument register
                
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                OTIR    
                XOR     A,A
                OUT     (G9K_REG_DATA),A
                OUT     (G9K_REG_DATA),A  ; Write MI
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LINE  ; Draw upper line
                POP     HL
                                
                
                PUSH    HL
                LD      A,G9K_ARG
                OUT     (G9K_REG_SELECT),A
                LD      B,4     
                G9kCmdWait
                LD      A,G9K_ARG_MAJ
                OUT     (G9K_REG_DATA),A  

                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                OTIR
                
                INC     HL
                INC     HL
                OUTI
                OUTI
                ; MI stays the same
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LINE  ; Draw left line
                POP     HL
                
                
                PUSH    HL
                LD      A,G9K_ARG
                OUT     (G9K_REG_SELECT),A      
                G9kCmdWait
                
                XOR     A,A
                OUT     (G9K_REG_DATA),A  ; Clear argument register
                
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A  
                
                OUTI
                OUTI    ; Write left 
                                        
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                INC     HL      ; top
                
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                INC     HL      ; Width
                                
                LD      A,(HL)
                INC     HL
                LD      H,(HL)  ; Height
                LD      L,A     
                ADD     HL,BC   ; Calc top+height
                LD      C,G9K_REG_DATA
        
                OUT     (C),L
                OUT     (C),H   ; Write Y
                
                OUT     (C),E
                OUT     (C),D   ; Write MJ
                
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LINE  ; Draw bottom line
                POP     HL   
                
                LD      A,G9K_ARG
                OUT     (G9K_REG_SELECT),A              
                ;DE = width
                LD      A,(HL)
                INC     HL
                PUSH    HL
                LD      H,(HL)
                LD      L,A   ; Left
                ADD     HL,DE ; Left+width
                G9kCmdWait
        
                LD      A,G9K_ARG_MAJ
                OUT     (G9K_REG_DATA),A  
                
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                
                OUT     (C),L
                OUT     (C),H   ; Write X
                POP     HL
                INC     HL
                OUTI
                OUTI            ; Write Y
                INC     HL
                INC     HL      
                OUTI
                OUTI            ; Height (MJ)   
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LINE  ; Draw right line
                RET     
                
                
SetupCopyRamToXY:
; Input   : HL = pointer to parameters (format: left,top,width,height)
; Modifies: A,BC,HL
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,8*256+G9K_REG_DATA
                G9kCmdWait
                OTIR
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LMMC
                RET

CopyRamToXY:
; HL = Pointer to data
; BC = Bytes to copy
                LD      A,B
                LD      B,C
                INC     B
                DEC     B
                JR      Z,$+3
                      INC    A
                LD      C,G9K_CMD_DATA
                      OTIR
                      DEC     A
                      JP   NZ,$-3
                RET

SetupCopyXYToRam:
; HL = pointer to parameters (format: left,top,width,height)
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,4*256+G9K_REG_DATA
                G9kCmdWait
                OTIR
                LD      B,4
                LD      A,G9K_NX
                OUT     (G9K_REG_SELECT),A
                OTIR
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LMCM
                RET

CopyXYToRam:
; HL = Pointer to data
; BC = Bytes to copy
                LD      A,B
                LD      B,C
                INC     B
                DEC     B
                JR      Z,$+3
                  INC    A
                LD      C,G9K_CMD_DATA
                  INIR
                  DEC     A
                  JP   NZ,$-3
                RET

CopyXYToXY:
; HL = Pointer to data  (format: SourceX,SourceY,DestX,DestY,Width,height) struct G9K_COPY_XY_XY
                
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,12*256+G9K_REG_DATA
                G9kCmdWait
                OTIR
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LMMM
                RET

CopyXYToRegisterXY
; HL = Pointer to G9B_BOX struct
; IX = Dest X
; IY = Dest Y
                
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      C,G9K_REG_DATA
                G9kCmdWait
                
                OUTI
                OUTI    ; SourceX
                OUTI
                OUTI    ; SourceY
                LD      A,IXL
                OUT     (G9K_REG_DATA),A
                LD      A,IXH
                OUT     (G9K_REG_DATA),A; DestX
                LD      A,IYL
                OUT     (G9K_REG_DATA),A
                LD      A,IYH
                OUT     (G9K_REG_DATA),A; DestY
                OUTI
                OUTI    ; Width 
                OUTI
                OUTI    ; Height
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_LMMM
                RET

CopyVramToXY:
; HL = Pointer to data  (format: SourceAddress,DestX,DestY,Width,height)

                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,11*256+G9K_REG_DATA
                G9kCmdWait
                OUTI
                OUT     (G9K_REG_DATA),A    ; dummy write
                OTIR
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_BMXL
                RET

CopyXYToVram:
; HL = Pointer to data  (format: SourceX,SourceY,DestAddress,Width,height)
; Modifies AF,HL,BC
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      BC,5*256+G9K_REG_DATA
                G9kCmdWait
                OTIR
                OUT     (G9K_REG_DATA),A    ; dummy write
                LD      B,6
                OTIR
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_BMLX
                RET

CopyVramToVram:
; HL = Pointer to data  (format: SrcAddress,DestAddress,NrBytes) 
; Modifies AF,HL,BC
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      C,G9K_REG_DATA
                G9kCmdWait
                
                OUTI                        ; Source Low
                OUT     (G9K_REG_DATA),A    ; dummy write
                OUTI                        ; Source mid
                OUTI                        ; Source high
                
                OUTI                        ; Destination Low
                OUT     (G9K_REG_DATA),A    ; dummy write
                OUTI                        ; Destination mid
                OUTI                        ; Destination High
                                
                OUTI                        ; Number of bytes Low
                OUT     (G9K_REG_DATA),A    ; dummy write
                OUTI                        ; Number of bytes mid
                OUTI                        ; Number of bytes High

                G9kWriteReg G9K_OPCODE,G9K_OPCODE_BMLL
                RET

SetPoint:
; HL = X
; DE = Y
; Under Construction
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      C,G9K_REG_DATA
                OUT     (C),L
                OUT     (C),H
                OUT     (C),E
                OUT     (C),D
                
                G9kCmdWait
                RET


SetCmdWriteMask:
; HL = mask value
                G9kWriteReg G9K_WRITE_MASK,L
                LD      A,H
                OUT     (G9K_REG_DATA),A
                RET
SetCmdColor:
; HL = color value
                G9kWriteReg G9K_FC,L
                LD      A,H
                OUT     (G9K_REG_DATA),A
                RET
                
SetCmdBackColor:                
; HL = color value
                G9kWriteReg G9K_BC,L
                LD      A,H
                OUT     (G9K_REG_DATA),A
                RET
                

CopyRamToVram:
; Function :    Data transfer from CPU to VRAM 
; Input    :    HL = pointer to buffer, BC=number of bytes to send
; Output   :    none
; Modifies :    A,B,C,HL
                LD      A,B
                LD      B,C
                LD      C,G9K_VRAM
                INC     B
                DEC     B
                JR      Z,.a
                INC     A
.a
                OTIR
                DEC     A
                JP      NZ,.a            
                RET
                

;----------------------------------------------------------------------------;
; Gfx9000 font functions                                                     ;
;----------------------------------------------------------------------------;
                IFNDEF G9K_DISABLE_VFF
OpenVff:
; Input           A = ram or vram.  0 = load data in vram, 1 = load font data in ram
;                DE = Pointer to Font file name
;                IX = Pointer to VFF object
                
                LD      (IX+VFF_OBJECT.ramFont),A
                PUSH    IX
                XOR     A,A     
                CALL    File.FileOpen
                POP     IX
                RET     NZ              ; Error opening
                
                PUSH    IX
                LD      HL,3            ; ID
                LD      DE,VFF_DATA_ID
                CALL    File.FileRead     ; Load Id
                POP     IX
                RET     NZ              ; Error reading

                PUSH    IX              
                PUSH    BC              ; Save file handle
                LD      B,3
                LD      HL,VFF_DATA_ID
                LD      DE,VFF_ID
                CALL    String.StringCompare
                LD      A,_NOVFF
                POP     BC
                POP     IX
                RET     NZ              ; Not a VFF file
                LD      (IX),B          ; Save file handle
                LD      DE,IX
                INC     DE
                INC     DE
                LD      HL,21           ; Load header
                JP      File.FileRead
                
VFF_ID          DB      "VFF"
VFF_DATA_ID     DS      3,0
                
LoadFont:
; Function      : Loads VFF font data 
; Input         : IX = Pointer to VFF object
;               : IY = Pointer to font offset table, if it's zero it's not loaded
;               : HL = Pointer to buffer for loading, or if it's a ram font the destination address
;               : BC = Vram low word font data offset. If it's a ram font the pointer for buffer loading is used as font data offset  
; Output        : Z = succeded NZ= not succeded, A = error number
                
                LD      A,(IX+VFF_OBJECT.ramFont)       
                OR      A,A
                JR      Z,.noRamFont
                LD      BC,HL   
.noRamFont              
                PUSH    IX
                PUSH    HL
                LD      (IX+VFF_OBJECT.vramOffset),BC     ; Store Vram font offset
                LD      HL,512                            ; Font offset table size
                LD      B,(IX + VFF_OBJECT.fileHandle)    ; File hanlde
                LD      DE,IY                             ; Pointer to offset table
                LD      (IX+VFF_OBJECT.ptrOffsetTable),DE ; Store pointer to font character offset table
                CALL    File.FileRead                     ; Load font offset table
                POP     DE                                ; Pointer to buffer
                POP     IX
                RET     NZ                                ; Return if loading failed
                
                LD      HL,(IX+VFF_OBJECT.dataSize)
                PUSH    HL
                PUSH    DE           ; Pointer to buffer
                CALL    File.FileRead
                POP     DE
                POP     HL
                RET     NZ           ; Loading failed
                
                ; If it is ram font then copy to vram is skipped
                LD      A,(IX+VFF_OBJECT.ramFont)
                DEC     A
                RET     Z
                
                PUSH    DE           ; Pointer to buffer
                PUSH    HL           ; data size    
                LD      HL,(IX+VFF_OBJECT.vramOffset)
                LD      E,7          ; High byte font address always 7
                CALL    SetVramWrite
                POP     BC           ; data size
                POP     HL           ; Pointer to buffer
                CALL    CopyRamToVram
                XOR     A,A
                RET             

SetFont:
; Input IX = Pointer to VFF object
                PUSH    AF
                PUSH    HL
                PUSH    DE
                
                LD      A,(IX + VFF_OBJECT.width)
                LD      (currentFont.width),A
                LD      A,(IX + VFF_OBJECT.height)
                LD      (currentFont.height),A

                ; Copy pointer to font offset table in print functions
                LD      HL,(IX + VFF_OBJECT.ptrOffsetTable)
                IFNDEF G9K_DISABLE_VFF_VRAM
                LD      (PrintStringVram.fontTablePtr+1),HL
                LD      (PutCharVram.fontTablePtr+1),HL
                ENDIF
                
                IFNDEF G9K_DISABLE_VFF_RAM
                LD      (PrintStringRam.fontTablePtr+1),HL      
                LD      (PutCharRam.fontTablePtr+1),HL
                ENDIF
                
                INC     HL
                INC     HL
                LD      A,(HL)  ; offset to second char is also the character size
                LD      (currentFont.charSize),A
                        
                LD      A,(IX+VFF_OBJECT.vramOffset+0)
                IFNDEF G9K_DISABLE_VFF_VRAM
                LD      (PrintStringVram.fontVramOffset+1),A
                LD      (PutCharVram.fontVramOffset+1),A
                ENDIF
                
                IFNDEF G9K_DISABLE_VFF_RAM
                LD      (PrintStringRam.fontRamOffset+1),A      
                LD      (PutCharRam.fontRamOffset+1),A
                ENDIF
                
                LD      A,(IX+VFF_OBJECT.vramOffset+1)
                IFNDEF G9K_DISABLE_VFF_VRAM
                LD      (PrintStringVram.fontVramOffset+2),A
                LD      (PutCharVram.fontVramOffset+2),A
                ENDIF   
                
                IFNDEF G9K_DISABLE_VFF_RAM
                LD      (PrintStringRam.fontRamOffset+2),A
                LD      (PutCharRam.fontRamOffset+2),A
                ENDIF
                
                LD      A,(IX+VFF_OBJECT.ramFont)
                IFNDEF G9K_DISABLE_VFF_VRAM
                LD      HL,PrintStringVram
                LD      DE,PutCharVram
                ENDIF
                
                OR      A,A
                JR      Z,.end
                
                IFNDEF G9K_DISABLE_VFF_RAM
                LD      HL,PrintStringRam
                LD      DE,PutCharRam
                ENDIF
.end:                           
                LD      (PrintString+1),HL
                LD      (PutChar+1),DE
                
                POP     DE
                POP     HL
                POP     AF
                RET
                
PrintString:    
                JP      0
PutChar:        
                JP      0        
        
                IFNDEF G9K_DISABLE_VFF_VRAM
PrintStringVram:        
; Function      : Print ASCIIZ String
; Input         : IX = X
;               : IY = Y
;               ; DE = Pointer to txt
; Output        : DE = Pointer to byte after term char
;               : IX = modified to x after printed string
; Modifies      ; AF,BC,DE,HL,IX
                LD      (currentFont.x),IX
                LD      (currentFont.y),IY
                    
.loop
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      A,(DE)
                INC     DE
                OR      A,A     ; End of ASCIIZ string
                RET     Z       
                  
.fontTablePtr   LD      BC,0    ;VFF.FONT_TABLE
                LD      L,A
                LD      H,0
                ADD     HL,HL
                ADD     HL,BC

                LD      A,(currentFont.width)   ; Next Char
                LD      C,A
                LD      B,0
                ADD     IX,BC           ; Precalculation
                
                LD      C,(HL)
                INC     HL
                LD      B,(HL)  ; vram offset of character  
.fontVramOffset LD      HL,0    ; vram font base address offset low word
                ADD     HL,BC   
                
                LD      C,G9K_REG_DATA
                G9kCmdWait

                OUT     (C),L   ; Vram address Low byte  
                LD      A,0
                OUT     (C),A   ; Looks stuppid but else it doens't work on turbo r             
                OUT     (C),H   ; Vram addres Mid byte   
                LD      HL,currentFont.vramAddress
                OUTI            ; Vram high address
                OUTI            ; X low byte
                OUTI            ; X high byte
                OUTI            ; Y low byte
                OUTI            ; Y high byte
                OUTI            ; Width
                LD      A,0
                OUT     (C),A   ; Width High byte always 0
                OUTI            ; Height
                LD      A,0     ; Height High byte always 0
                OUT     (C),A   ; Looks stuppid but else it doens't work in turbo r  
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_CMMM
                LD      (currentFont.x),IX
                JP      .loop

PutCharVram:    
; Function      : Print a character
; Input         : E  = Character
; Output        ; IX = modified to x after printed character
; Modifies      ; AF,BC,DE,HL,IX
                                
                                  
.fontTablePtr   LD      BC,0    
                LD      L,A
                LD      H,0
                ADD     HL,HL
                ADD     HL,BC
                
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A 

                LD      A,(currentFont.width)   ; Next Char
                LD      C,A
                LD      B,0
                ADD     IX,BC           ; Precalculation
                
                LD      C,(HL)
                INC     HL
                LD      B,(HL)  ; vram offset of character  
.fontVramOffset LD      HL,0    ; vram font base address offset low word
                ADD     HL,BC   
                
                LD      C,G9K_REG_DATA
                G9kCmdWait

                OUT     (C),L    ; Vram address Low byte  
                LD      A,0
                OUT     (C),A   ; Looks stuppid but else it doens't work on turbo r             
                OUT     (C),H   ; Vram addres Mid byte   
                LD      HL,currentFont.vramAddress
                OUTI            ; Vram high address
                OUTI            ; X low byte
                OUTI            ; X high byte
                OUTI            ; Y low byte
                OUTI            ; Y high byte
                OUTI            ; Width
                LD      A,0
                OUT     (C),A   ; Width High byte always 0
                OUTI            ; Height
                LD      A,0     ; Height High byte always 0
                OUT     (C),A   ; Looks stuppid but else it doens't work in turbo r  
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_CMMM
                LD      (currentFont.x),IX
                RET
                ENDIF
                
                IFNDEF G9K_DISABLE_VFF_RAM
PrintStringRam:
; Function      : Print ASCIIZ String
; Input         : IX = X
;               : IY = Y
;               ; DE = Pointer to txt
; Output        : DE = Pointer to byte after term char
;               : IX = modified to x after printed string
; Modifies      ; AF,BC,DE,HL,IX

                LD      (currentFont.x),IX
                LD      (currentFont.y),IY

.loop
                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                LD      A,(DE)
                INC     DE
                OR      A,A     ; End of ASCIIZ string
                RET     Z       
                 
                ; Calculate the font data pointer address in ram
.fontTablePtr   LD      BC,0
                LD      L,A
                LD      H,0
                ADD     HL,HL
                ADD     HL,BC

                ; Precalculate next character offset
                ; This is done here to minimize wasted time on waiting for the v9990 to finish
                LD      A,(currentFont.width)   ; Next Char
                LD      C,A
                LD      B,0
                ADD     IX,BC           ; Precalculation

                ; Get the address of the character data in ram
                LD      C,(HL)
                INC     HL
                LD      B,(HL)  ; ram offset of character  
.fontRamOffset  LD      HL,0    ; ram font base address offset low word
                ADD     HL,BC   
                PUSH    HL      
                LD      C,G9K_REG_DATA
                G9kCmdWait
                LD      HL,currentFont.x
                OUTI            ; X low byte
                OUTI            ; X high byte
                OUTI            ; Y low byte
                OUTI            ; Y high byte
                OUTI            ; Width
                LD      A,0
                OUT     (C),A   ; Width High byte always 0
                OUTI            ; Height
                LD      A,0     ; Height High byte always 0
                OUT     (C),A   ; Looks stuppid but else it doens't work in turbo r  
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_CMMC
                ; Store addres of next X position
                LD      (currentFont.x),IX
                
                ; Wait for v9990 to recieve data
                G9kWaitComReady
                
                ; Send character data to vdp
                POP     HL      ; Pointer to font data in ram
                LD      A,(currentFont.charSize)
                LD      B,A
                LD      C,G9K_CMD_DATA
                OTIR
                JP      .loop
                
PutCharRam:
; Function      : Print a character
; Input         : A  = Character
; Output        ; IX = modified to x after printed character
; Modifies      ; AF,BC,DE,HL,IX                
                ; Calculate the font data pointer address in ram
.fontTablePtr   LD      BC,0
                LD      L,A
                LD      H,0
                ADD     HL,HL
                ADD     HL,BC

                LD      A,G9K_DS_X
                OUT     (G9K_REG_SELECT),A
                 
                ; Precalculate next character offset
                ; This is done here to minimize wasted time on waiting for the v9990 to finish
                LD      A,(currentFont.width)   ; Next Char
                LD      C,A
                LD      B,0
                ADD     IX,BC           ; Precalculation

                ; Get the address of the character data in ram
                LD      C,(HL)
                INC     HL
                LD      B,(HL)  ; ram offset of character  
.fontRamOffset  LD      HL,0    ; ram font base address offset low word
                ADD     HL,BC   
                PUSH    HL      
                LD      C,G9K_REG_DATA
                G9kCmdWait
                LD      HL,currentFont.x
                OUTI            ; X low byte
                OUTI            ; X high byte
                OUTI            ; Y low byte
                OUTI            ; Y high byte
                OUTI            ; Width
                LD      A,0
                OUT     (C),A   ; Width High byte always 0
                OUTI            ; Height
                LD      A,0     ; Height High byte always 0
                OUT     (C),A   ; Looks stuppid but else it doens't work in turbo r  
                G9kWriteReg G9K_OPCODE,G9K_OPCODE_CMMC
                ; Store addres of next X position
                LD      (currentFont.x),IX
                
                ; Wait for v9990 to recieve data
                G9kWaitComReady
                
                ; Send character data to vdp
                POP     HL      ; Pointer to font data in ram
                LD      A,(currentFont.charSize)
                LD      B,A
                LD      C,G9K_CMD_DATA
                OTIR
                RET
                ENDIF
                
Locate:         
; Set X and Y position for putchar
; Value in IX is also needed for the putchar so don't overwrite it
                LD      (currentFont.x),IX
                LD      (currentFont.y),IY      
                RET
                
                
currentFont
.vramAddress    DB      7               ; High Byte
.x              DW      0
.y              DW      0
.width          DB      8               ; Font Size
.height         DB      8               ;       
.charSize       DB      0                ; Char size in bytes.

                ENDIF
        
;----------------------------------------------------------------------------;
; Gfx9000 bitmap functions                                                   ;
;----------------------------------------------------------------------------;
                IFNDEF G9K_DISABLE_G9B  
                        
OpenG9B:
; Input  : DE = Pointer to file name asciiz
; Output : HL = Pointer to G9B header data, NZ = error , Error code in A
; Modifies:             
                PUSH    HL
                XOR     A,A     
                CALL    File.FileOpen
                POP     HL
                RET     NZ              ; Error opening
                
                PUSH    HL
                LD      HL,5            ; ID + HEADER LENGTH
                LD      DE,G9B_DATA_ID
                CALL    File.FileRead
                POP     HL
                RET     NZ              ; Error reading
                
                PUSH    HL              
                PUSH    BC              ; Save file handle
                LD      B,3
                LD      HL,G9B_DATA_ID
                LD      DE,G9B_ID
                CALL    String.StringCompare
                LD      A,_NOG9B
                POP     BC
                POP     HL
                RET     NZ              ; Not a G9B file
                
                LD      (HL),B          ; Save handle in G9B struct
                INC     HL
                INC     HL
                EX      DE,HL
                LD      HL,(G9B_HEADER_SIZE)
                JP      File.FileRead

ReadG9B:
; IX = Pointer to G9B object struct
; DE = Pointer to load buffer
; BC = Size of load buffer
; HL = Destination X
; IY = Destination Y
;  A = Palette offset in bytes. Only valid with palette modes. If a = 255 palette not loaded    
                
                PUSH    AF      ; Palette pointer
                LD      (G9B_COPY_PARMS),HL     
                LD      (G9B_COPY_PARMS+2),IY   
                
                LD      A,(IX+G9B_OBJECT.width+0)
                LD      (G9B_COPY_PARMS+4),A
                LD      A,(IX+G9B_OBJECT.width+1)               
                LD      (G9B_COPY_PARMS+5),A            ; Copy X
                
                LD      A,(IX+G9B_OBJECT.height+0)
                LD      (G9B_COPY_PARMS+6),A
                LD      A,(IX+G9B_OBJECT.height+1)              
                LD      (G9B_COPY_PARMS+7),A            ; Copy Y        
                
                LD      HL,G9B_COPY_PARMS
                POP     AF    ; Palette pointer
                PUSH    BC
                PUSH    DE
                
                PUSH    AF     ; Palette pointer
                CALL    SetupCopyRamToXY        
                POP     BC
                                
                LD      C,B    ; C = palette pointer    
                CALL    NZ,ReadG9BPalette

                POP     DE              
                POP     BC
                RET     NZ            ; Error Loading palette
        
                LD      HL,CopyRamToXY
                LD      (ReadToG9K.copyMode+1),HL ; Set copy mode
                
                IFNDEF G9K_DISABLE_BITBUST
                  LD      A,(IX + G9B_OBJECT.compression)
                  AND     A,07FH
                  CP      A,G9B_COMPRESSION_BITBUST
                  JP      Z,G9kBitBustXY
                ENDIF
                
ReadG9B.Load            
                LD      A, (IX+G9B_OBJECT.dataSize+2)
                LD      HL,(IX+G9B_OBJECT.dataSize)
ReadG9B.0       
                PUSH    HL
                POP     IY             ; Save low word, because this is the last block 
                OR      A,A
                SBC     HL,BC
                SBC     A,0            ; Calculate block size
                JR      C,ReadG9B.1    ; Jumps when last block is reached
                PUSH    AF             ; Size still to read high byte 
                PUSH    HL             ; Size still to read low word    
                PUSH    BC             ; buffer size    
                LD      HL,BC          ; Block size is buffer size     
                LD      B,(IX + G9B_OBJECT.fileHandle) ; Get file handle
                CALL    ReadToG9K
                POP     BC             ; buffer size
                POP     HL             ; Size still to read low word 
                POP     AF             ; Size still to read high byte  
                JP      ReadG9B.0
                
ReadG9B.1       
                PUSH    IY
                POP     HL
                LD      B,(IX)  ; Get file handle       
                JP      ReadToG9K
                

CalcG9BVramSize:
; Input IX    = Pointer to G9B header data
; Output E:HL = data size
                        LD      DE,(IX + G9B_OBJECT.width)
                        LD      BC,(IX + G9B_OBJECT.height)
                        ; Calculate number of pixels
                        CALL    Math.BCMulDE32 ; Result BC:HL 
                        LD      E,C
                        LD      A,(IX + G9B_OBJECT.bitDepth)
                        JP      CalcDataSize

CalcDataSize
;input E:HL=number of pixels   
;       A=bits per dot  
                        CP      A,16
                        JR      Z,.calc16bit
                        CP      A,8
                        RET     Z
                        LD      B,1
                        CP      A,4
                        JR      Z,.shiftLoop
                        LD      B,2
.shiftLoop
                        SRL     E
                        RR      H
                        RR      L
                        DJNZ    .shiftLoop
                        RET
.calc16bit
                        ADD     HL,HL
                        RL      E       
                        RET

ReadG9BLinear:
; IX   = Pointer to G9B header data
; DE   = Pointer to load buffer
; BC   = Size of load buffer
; IYL:HL = Vram destination address
;    A = Palette offset in bytes. Only valid with in palette modes, A = 255 palette not loaded  
                
                PUSH    AF
                PUSH    BC
                PUSH    DE ; Pointer to buffer
                LD      E,IYL
                CALL    SetVramWrite
                POP     DE
                POP     BC
                POP     AF

                PUSH    DE
                PUSH    BC
                LD      C,A    ; C = palette pointer    
                CALL    NZ,ReadG9BPalette
                POP     BC
                POP     DE              
                RET     NZ            ; Error Loading palette
                        
                LD      HL,CopyRamToVram
                LD      (ReadToG9K.copyMode+1),HL
                
                IFNDEF G9K_DISABLE_BITBUST
                  LD      A,(IX + G9B_OBJECT.compression)
                  AND     A,07FH
                  CP      A,G9B_COMPRESSION_BITBUST
                  JP      Z,G9kBitBustLinear
                ENDIF
                JP      ReadG9B.Load    
                
ReadToG9K:      
; Input B = FileHandle  
;      DE = Pointer to buffer
;      HL = Bytes to read               
                
                PUSH    DE
                PUSH    IX
                
                PUSH    DE  ; Pointer to buffer
                PUSH    HL  ; Bytes to read
                CALL    File.FileRead
                POP     BC  ; Bytes to read
                POP     HL  ; Pointer to buffer
                
.copyMode       CALL    CopyRamToXY

                POP     IX
                POP     DE
                RET     
                
ReadG9BPalette:
; IX = Pointer to G9B object struct
;  C = Palette pointer  (max 192), if 255 skip loading palette
; DE = Pointer to buffer
                
                INC     C
                RET     Z       ; C = 255 skip loading
                DEC     C
                
                LD      A,(IX+G9B_OBJECT.nrColors) 
                OR      A,A                     
                RET     Z               ; Nothing to load       

                LD      B,A
                ADD     A,A
                ADD     A,B     ; Number of colors * 3 = size on disk
                LD      H,0
                LD      L,A
                PUSH    HL      ; Bytes to read
                PUSH    DE      ; Pointer to buffer
                LD      B,(IX + G9B_OBJECT.fileHandle)
                CALL    File.FileRead ; Saves BC
                POP     HL      ; Pointer to buffer 
                POP     DE      ; Bytes to read
                RET     NZ      ; Error reading palette 
                LD      B,E
                JP      WritePalette
                
                
G9B_ID          DB      "G9B"   
G9B_DATA_ID     DS      3,0
G9B_HEADER_SIZE DW      0        
G9B_COPY_PARMS  DW      0
                DW      0
                DW      0
                DW      0

                IFNDEF G9K_DISABLE_BITBUST

G9kBitBustXY:
                LD      HL,CopyRamToXY  
                JR      G9kBitBust
                        
G9kBitBustLinear:
                LD      HL,CopyRamToVram
                
G9kBitBust:             
                LD      (.copyFunction+1),HL
                
                PUSH    DE
                LD      B,(IX + G9B_OBJECT.fileHandle) ; Get file handle
                LD      DE,.BLOCKS
                LD      HL,1
                CALL    File.FileRead
                POP     DE
                RET     NZ      ; Read error            
.loop           
                PUSH    DE
                LD      DE,.BLOCK_SIZE
                LD      HL,2
                CALL    File.FileRead
                POP     DE      ; pointer to buffer
                RET     NZ      ; Read error
                
                PUSH    DE      ; pointer to buffer
                LD      HL,(.BLOCK_SIZE)
                CALL    File.FileRead   
                POP     DE      ; pointer to buffer
                RET     NZ      ; Read error
                                
                PUSH    BC
                LD      HL,(.BLOCK_SIZE) ; bytes
                ADD     HL,DE    ; Calculate Address to depack to
                PUSH    DE       ; pointer to buffer 
                
                PUSH    HL       ; Pointer to decompress to     
                EX      DE,HL    ; HL =  Address of packed data
                CALL    bitbuster.depack_raw
                ; DE = Address of first byte after decompressed data
                POP     HL       ; Pointer to decompressed data
                                
                PUSH    HL
                EX      DE,HL
                OR      A,A             
                SBC     HL,DE    ; Calculate bytes to send to the vdp
                LD      BC,HL    ; Bytes to send 
                POP     HL       ; Pointer to decompressed data
                
.copyFunction   CALL    CopyRamToVram
                POP     DE       ; pointer to buffer 
                POP     BC
                
                LD      A,(.BLOCKS)
                DEC     A
                LD      (.BLOCKS),A
                JP      NZ,.loop
                RET
        
                
.BLOCKS         DB      0
.BLOCK_SIZE     DW      0

                ENDIF

                ENDIF

Close:
; HL = Pointer to G9B/VFF header object
; Modifies: B
                LD      B,(IX)
                PUSH    IX
                CALL    File.FileClose
                POP     IX
                LD      (IX),0 ; clear handle
                RET
                
;----------------------------------------------------------------------------;
; Gfx9000 Mouse cursor functions                                             ;
;----------------------------------------------------------------------------;

                IFNDEF G9K_DISABLE_CURSOR

SetCursorXY:
; Both cursors are set at the same,because the data is 1 bit. So both cursors
; are needed to make a good cursor. 
; input    : HL=X
;          : DE=Y
; Modifies : A,C

                ; Set V9990 address = #7FE00
                XOR     A,A
                OUT     (G9K_REG_SELECT),A
                OUT     (G9K_REG_DATA),A
                LD      A,0FEh
                OUT     (G9K_REG_DATA),A
                LD      A,7
                OUT     (G9K_REG_DATA),A 
                
                ; "First" cursor
                LD      C,G9K_VRAM
                OUT     (C),E        ; Y cordinate low byte
                OUT     (C),E        ; Dummy                   
                OUT     (C),D        ; Y cordinate high byte
                OUT     (C),D        ; Dummy
                
                OUT     (C),L        ; X cordinate low byte
                OUT     (C),L        ; Dummy
                LD      A,(CURSOR0_ATTRIB)
                OR      A,H          ; Set color atributes
                OUT     (G9K_VRAM),A ; X cordinate High byte and color
                OUT     (G9K_VRAM),A ; Dummy    
                      
                ; "Second" cursor
                OUT     (C),E        ; Y cordinate low byte
                OUT     (C),E        ; Dummy
                OUT     (C),D        ; Y cordinate high byte 
                OUT     (C),D        ; Dummy
                OUT     (C),L        ; X cordinate low byte
                OUT     (C),L        ; Dummy
                LD      A,(CURSOR1_ATTRIB)
                OR      A,H
                OUT     (G9K_VRAM),A ; X cordinate High byte and color
                RET

SetCursorPattern:
                

                RET

SetCursorAttrib:
; Input A = Cursor Number ( 0 or 1)             
                LD      HL,CURSOR0_ATTRIB
                OR      A,A
                JR      Z,$+3
                 INC    HL 
                LD      (HL),A
                RET
                
CURSOR0_ATTRIB   DB     0
CURSOR1_ATTRIB   DB     0

                ENDIF

;----------------------------------------------------------------------------;
; Gfx9000 Pattern mode functions                                             ;
;----------------------------------------------------------------------------;

                IFNDEF G9K_DISABLE_PATTERN
SetPatternData:
; DE = Ptr to pattern data
; HL = Pattern number
;  A = Layer number (0=A,1=B)
; Modifies: A,BC,HL
                PUSH    DE
                ADD     A,A
                LD      (PAT.LAYER_SEL_SC),A
                LD      (PAT.LAYER_SEL_DS),A            
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                LD      A,L
                LD      (PAT.X),A 
                LD      A,H
                ADD     A,A
                ADD     A,A
                ADD     A,A
                LD      (PAT.Y),A 
                LD      HL,PAT.X                
                CALL    SetupCopyRamToXY
                POP     HL
                LD      BC,8*8
                JP      CopyRamToXY
                  
                 

GetPatternData:
; DE = Ptr to buffer to write pattern data in
; HL = Pattern number
;  A = Layer number (0=A,1=B)
; Modifies: A,BC,HL
                PUSH    DE
                ADD     A,A
                LD      (PAT.LAYER_SEL_SC),A
                LD      (PAT.LAYER_SEL_DS),A            
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                LD      A,L
                LD      (PAT.X),A 
                LD      A,H
                ADD     A,A
                ADD     A,A
                ADD     A,A
                LD      (PAT.Y),A 
                LD      HL,PAT.X                
                CALL    SetupCopyXYToRam
                POP     HL
                LD      BC,8*8
                JP      CopyXYToRam
                  
                 
PAT.X                   DB      0
PAT.LAYER_SEL_SC        DB      0
PAT.Y                   DB      0,0
PAT.WIDTH               DB      8
PAT.LAYER_SEL_DS        DB      0
PAT.HEIGHT              DB      8,0
        
SetPattern:
; HL = Pattern number in generator table (on screen patterns 0 to A=8159,B=7679)
; DE = Pattern number in name table (on screen patterns 0 to 4095)
;  A = Layer number (0=A,1=B)                   
                PUSH    DE
                ADD     HL,HL
                LD      DE,0C000h
                OR      A,A
                JR      Z,$+5
                  LD      DE,0E000h
                ADD     HL,DE
                LD      E,7             
                CALL    SetVramWrite
                POP     DE
                LD      A,E
                OUT     (G9K_VRAM),A
                LD      A,D
                OUT     (G9K_VRAM),A
                RET     
                
GetPattern:
; Input  DE = Pattern number in name table (on screen patterns 0 to 4095)
; Output HL = Pattern number in generator table (on screen patterns 0 to A=8159,B=7679)
;  A = Layer number (0=A,1=B)           
                PUSH    DE
                ADD     HL,HL
                LD      DE,0C000h
                OR      A,A
                JR      Z,$+5
                  LD      DE,0E000h
                ADD     HL,DE
                LD      E,7             
                CALL    SetVramRead
                POP     DE
                IN      A,(G9K_VRAM)
                LD      L,A
                IN      A,(G9K_VRAM)
                LD      H,A
                RET        
                
PCopyVramToVram:
; NOTE: Not finished yet
; HL = Pointer to data  (format: SrcAddress,DestAddress,NrBytes)
; Modifies AF,HL,BC
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                LD      C,G9K_REG_DATA
                G9kCmdWait
                ; DestAddress address <40000h layer A
                ; DestAddress address >40000h layer B
                ; Addresses need to be shifted to the left
                LD      A,(HL)             
                INC     HL
                ADD     A,A
                OUT     (G9K_REG_DATA),A     ; Source low       
                OUT     (G9K_REG_DATA),A     ; dummy write
                LD      A,(HL)
                INC     HL
                RLA    
                OUT     (G9K_REG_DATA),A     ; Source mid               
                LD      A,(HL)
                INC     HL
                RLA                     
                OUT     (G9K_REG_DATA),A     ; Source high                                         
 
 
                
                ;OUTI                       ; Destination Low
                ;OUT     (G9K_REG_DATA),A    ; dummy write
                ;OUTI                       ; Destination mid
                ;OUTI                       ; Destination High
                                
                ;OUTI                       ; Number of bytes Low
                ;OUT     (G9K_REG_DATA),A    ; dummy write
                ;OUTI                       ; Number of bytes mid
                ;OUTI                       ; Number of bytes High

                G9kWriteReg G9K_OPCODE,G9K_OPCODE_BMLL
                
                RET             


PCopyVramToVramARegister:
; NOTE: Not finished yet
; Function: Copy vram to vram where destination is in layer A
; address value 00000h to 7FFFFh

; IYL:HL = start address
; IYH:DE = destination address
; IXL:BC = nr of bytes
                LD      A,G9K_SC_X
                OUT     (G9K_REG_SELECT),A
                
                ; Prepare the addresses
                
        
        
                G9kCmdWait
        
                 
        
        
                 
                                    
                ENDIF


;----------------------------------------------------------------------------;
; Gfx9000 Pattern mode sprite functions                                      ;
;----------------------------------------------------------------------------;

                IFNDEF G9K_DISABLE_SPRITES
SetSprite:
; B = Sprite Number (0 to 124)
                ; Set V9990 address = base 03FE00h + sprite number*4
                XOR     A,A
                OUT     (G9K_REG_SELECT),A
                LD      A,B
                LD      B,0
                ADD     A,A
                ADD     A,A
                OUT     (G9K_REG_DATA),A  ; Low address
                RL      B
                LD      A,0FEh
                ADD     A,B               
                OUT     (G9K_REG_DATA),A  ; Mid
                LD      A,03h 
                OUT     (G9K_REG_DATA),A  ; High 
                RET
                     
                
                ENDIF
                
;----------------------------------------------------------------------------;
; Gfx9000 Interrupt functions                                                ;
;----------------------------------------------------------------------------;
       
SetIntLine:             
; HL = int line
                G9kWriteReg G9K_INT_V_LINE_LO,L
                LD      A,H
                OUT     (G9K_REG_DATA),A
                RET
                
                ENDMODULE