
#include "msxlib.h"
#include <ioport.h>
#include <interrupt.h>

sfr at 0x98 vdp1;
sfr at 0x99 vdp2;

void waitVB(void)
{
    _asm
    halt
    _endasm;
}

unsigned char space(void)
{
    char    c;
    c=(in(0xaa)&0xf0)|8;
    out(0xaa,c);
    c=in(0xa9)&1;

    return(1-c);
}

void screen(char mode)
{
    mode;
    _asm
    push    ix
    ld      ix,#0
    add     ix,sp
    push    iy
    push    bc
    push    de
    push    hl

    ld      a,6(ix)
    ld      (0xfcaf),a
    ld      ix,#0x5f
    ld      iy,(0xfcc0)
    call    0x1c

    pop     hl
    pop     de
    pop     bc
    pop     iy
    pop     ix
    _endasm;
}

void vdp_address(unsigned addr)
{
    vdp2=addr&0xff;
    vdp2=(addr>>8)|0x40;
/*    out(0x99,addr&0xff);
    out(0x99,(addr>>8)|0x40);*/
}

void vdp_poke(unsigned addr,unsigned char c)
{
    vdp2=addr&0xff;
    vdp2=(addr>>8)|0x40;
    vdp1=c;

/*    out(0x99,addr&0xff);
    out(0x99,(addr>>8)|0x40);
    out(0x98,c);*/
}

void vdp_set(unsigned char c,unsigned bytes)
{
    c;bytes;
    _asm
    push    ix
    ld      ix,#0
    add     ix,sp
    push    de
    push    bc

    ld      d,6(ix) ; Parametrit
    ld      c,7(ix)
    ld      b,8(ix)
    push    bc

    srl     b   ; BC/8
    rr      c
    srl     b
    rr      c
    srl     b
    rr      c
    ld      a,b
    or      c
    jp      z,1$

0$:
    ld      a,d
    out     (0x98),a
    out     (0x98),a
    out     (0x98),a
    out     (0x98),a
    out     (0x98),a
    out     (0x98),a
    out     (0x98),a
    out     (0x98),a
    dec     bc
    ld      a,b
    or      c
    jp      nz,0$

1$:
    pop     bc      ; The modulo part
    ld      a,c
    and     #7
    jp      z,2$

    ld      c,a
    ld      a,d
3$:
    out     (0x98),a
    dec     c
    jp      nz,3$

2$:
    pop     bc
    pop     de
    pop     ix
    _endasm;
}

void vdp_slowset(unsigned char c,unsigned bytes)
{
    c;bytes;
    _asm
    push    ix
    ld      ix,#0
    add     ix,sp
    push    de
    push    bc

    ld      d,6(ix) ; Parametrit
    ld      c,7(ix)
    ld      b,8(ix)
    push    bc

    srl     b   ; BC/8
    rr      c
    srl     b
    rr      c
    srl     b
    rr      c
    ld      a,b
    or      c
    jp      z,1$

0$:
    ld      a,d
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    nop
    nop
    nop
    out     (0x98),a
    dec     bc
    ld      a,b
    or      c
    jp      nz,0$

1$:
    pop     bc      ; The modulo part
    ld      a,c
    and     #7
    jp      z,2$

    ld      c,a
    ld      a,d
3$:
    out     (0x98),a
    dec     c
    jp      nz,3$

2$:
    pop     bc
    pop     de
    pop     ix
    _endasm;
}

void vdp_copy(unsigned char *src,unsigned bytes)
{
    src;bytes;
    _asm
    push    ix
    ld      ix,#0
    add     ix,sp
    push    de
    push    hl
    push    bc

    ld      l,6(ix) ; Parametrit
    ld      h,7(ix)
    ld      e,8(ix)
    ld      d,9(ix)
    push    de
    ld      c,#0x98

    srl     d   ; DE/8
    rr      e
    srl     d
    rr      e
    srl     d
    rr      e
    ld      a,d
    or      e
    jp      z,1$

0$:
    outi
    outi
    outi
    outi
    outi
    outi
    outi
    outi
    dec     de
    ld      a,d
    or      e
    jp      nz,0$

1$:
    pop     de      ; The modulo part
    ld      a,e
    and     #7
    jp      z,2$
    
    ld      b,a
    otir

2$:
    pop     bc
    pop     hl
    pop     de
    pop     ix
    _endasm;
}

void vdp_slowcopy(unsigned char *src,unsigned bytes)
{
    src;bytes;
    _asm
    push    ix
    ld      ix,#0
    add     ix,sp
    push    de
    push    hl
    push    bc

    ld      l,6(ix) ; Parametrit
    ld      h,7(ix)
    ld      e,8(ix)
    ld      d,9(ix)
    push    de
    ld      c,#0x98

    srl     d   ; DE/8
    rr      e
    srl     d
    rr      e
    srl     d
    rr      e
    ld      a,d
    or      e
    jp      z,1$

0$:
    outi
    nop
    nop
    outi
    nop
    nop
    outi
    nop
    nop
    outi
    nop
    nop
    outi
    nop
    nop
    outi
    nop
    nop
    outi
    nop
    nop
    outi
    dec     de
    ld      a,d
    or      e
    jp      nz,0$

1$:
    pop     de      ; The modulo part
    ld      a,e
    and     #7
    jp      z,2$
    
    ld      b,a
    otir

2$:
    pop     bc
    pop     hl
    pop     de
    pop     ix
    _endasm;
}

void vdp_register(int reg,unsigned char c)
{
    vdp2=c;
    vdp2=reg|0x80;
    /*out(0x99,c);
    out(0x99,reg|0x80);*/
}

void sprite_col(int num,char col)
{
    vdp_poke(0x1b00+(num<<2)+3,col);
}

void sprite_pos(int num,unsigned char x,unsigned char y)
{
    int addr=0x1b00+(num<<2);

    vdp2=addr&0xff;
    vdp2=(addr>>8)|0x40;
    vdp1=y;
    vdp1=x;

/*    out(0x99,addr&0xff);
    out(0x99,(addr>>8)|0x40);
    out(0x98,y);
    out(0x98,x);*/
}

void sprite_pat(int num,unsigned char pat)
{
    vdp_poke(0x1b00+(num<<2)+2,pat);
}
