	device pentagon1024

SCROLLING=0
COLOUR=1
COLOURSPRITES=1
DOTS=1
       ifdef DOAUTOMASK
AUTOMASK=1
       else
AUTOMASK=0
       endif

scrwid=30 ;30 for clipping and tiles 16x16 ;32 spoils tile numbers at line 8
emptyattr=7

tilegfxend=0x10000

SPRMEMSIZE=0x2000 ;+256 for CRC

       if SCROLLING
tilegfx=tilegfxend-(4*256*(8+COLOUR)) ;4 copies
       else
tilegfx=tilegfxend-(256*(8+COLOUR))
       endif

TILEMAPHGT=24 ;16/24 data size for tilemap
TILEMAPTOPSKIP=2 ;0..7 skip lines in top of screen
TILEMAPBOTTOMSKIP=2 ;0..7 skip lines in bottom of screen (for TILEMAPHGT=24)

scrbuf_xbase=1 ;xbase-2..-1 и xbase+30..+31 - для клипирования спрайтов слева и справа
scrbuf=tilegfx-(256*(8+COLOUR))+scrbuf_xbase;0xf001 ;,0x800
       if COLOUR
attrbuf=scrbuf+0x800
       endif
tilemap=scrbuf-(((TILEMAPHGT+7)/8)*0x200);0xea01 ;,0x600 (flags,tiles,flags,tiles,flags,tiles) +more for clipping? LSB=screen LSB addr
tilemaptop=tilemap+(TILEMAPTOPSKIP*32)

imvec=(tilemap&0xff00)-257;0xe8ff
imer=((imvec/256)+1)*0x0101;0xe9e9
intstack=imer
databottom=imvec-255

sprslices=scrbuf+34 ;6 segments
       if COLOUR
drawsprkernel=sprslices+0x800 ;no conflict with FLAGs
       else
drawsprkernel=sprslices+0x600 ;no conflict with FLAGs
       endif
drawdotkernel=drawsprkernel+192
FLAG_SKIPTILE=scrbuf/256 ;skipskip=1b, skipdraw=3b, skipshow=4b (при SCROLLING=1 не бывает)
FLAG_DRAWTILE=FLAG_SKIPTILE+4 ;drawskip=3b, drawdraw=3b, drawshow=3b
FLAG_SHOWTILEFROMMEM=FLAG_DRAWTILE+3 ;showskip=4b, showdraw=3b, showshow=4b
        if !SCROLLING
FLAG_RETILE=FLAG_SHOWTILEFROMMEM
        endif
;при !SCROLLING в show FLAG_DRAWTILE превращается FLAG_RETILE (при скроллинге тоже превращается в FLAG_SHOWTILEFROMMEM)
;при !SCROLLING FLAG_RETILE работает как FLAG_SHOWTILEFROMMEM, в show превращается в FLAG_SKIPTILE (а при скроллинге остаётся!)

; 123456789012345678901234567890  s                            r    j   rj
; 123456789012345678901234567890  s
; 123456789012345678901234567890  s
; 123456789012345678901234567890  s
; 123456789012345678901234567890  s                            j    j   j
; 123456789012345678901234567890  s
; 123456789012345678901234567890  j  j  j  j  j  j  j  j
; 123456789012345678901234567890                               rj   j   rj


;TODO часть процедур спрятать в scrbuf
        display "maximum sprslices=",FLAG_SKIPTILE-(sprslices&0xff)
        display "free scrbuf-scrbuf_xbase+0x000+FLAG_SHOWTILEFROMMEM+4..XXff =",256-(FLAG_SHOWTILEFROMMEM+4)
        display "free scrbuf-scrbuf_xbase+0x100+FLAG_SKIPTILE..XXff =",256-(FLAG_SKIPTILE)
        display "free scrbuf-scrbuf_xbase+0x200+FLAG_SKIPTILE..XXff =",256-(FLAG_SKIPTILE)
        display "free scrbuf-scrbuf_xbase+0x300+FLAG_SKIPTILE..XXff =",256-(FLAG_SKIPTILE)
        display "free scrbuf-scrbuf_xbase+0x400+FLAG_SHOWTILEFROMMEM+4..XXff =",256-(FLAG_SHOWTILEFROMMEM+4)
        display "free scrbuf-scrbuf_xbase+0x500+FLAG_SKIPTILE..XXff =",256-(FLAG_SKIPTILE)
        display "free drawsprkernel+192..XXff =",256-((drawsprkernel&0xff)+192)
        display "free scrbuf-scrbuf_xbase+0x700+(sprslices&0xff)..FLAGs-1 =",FLAG_SKIPTILE-(sprslices&0xff)
        display "free scrbuf-scrbuf_xbase+0x700+FLAG_SHOWTILEFROMMEM+4..XXff =",256-(FLAG_SHOWTILEFROMMEM+4)
        display "free imvec+2..imer-1 =",imer-(imvec+2)
        display "free imerend..XXfe (2b for stack before tilemap) =",255-(imerend&0xff)

	org #6100
begin
	xor a
	out (#fe),a
        ;ld (iy-48),1 ;REPPER for IM1 keyboard
	;ld (#5d10),a;0 ;for TR-DOS find file
	;ld (iy+1),#cc ;48K
	;ld sp,STACK

        ld hl,0
        ld de,tilegfx
        ld bc,0x800
        ldir
       ld hl,tilegfx
       ld de,tilegfx+1
       ld bc,0x7ff
       ld (hl),0
       ldir
       if COLOUR
        ld de,tilegfx+0x800
mktilegfxcolour0
        ld a,(hl)
        and 1;8
        or 6;0x30
        ld (de),a
        inc l
        inc e
        jr nz,mktilegfxcolour0
       endif
        ld hl,0x3fff
        ld e,96;255
mktilegfx0
        ld d,tilegfx/256+7
        ld b,8
mktilegfx1
        ld a,(hl)
       cpl
        dec hl
        ld (de),a
        dec d
        djnz mktilegfx1
        dec e
        jr nz,mktilegfx0

        call initint       
        call inittile
        call initspr

        jp mainloop

        include "initint.asm"
        include "inittile.asm"
        include "initspr.asm"

        ds 0x8000-$
;everything <0x8000 is used once
;stack=0x8000
;----------------------------------------------------------------

SPRSLICEPOINTERSHGT=32 ;for y clipping
        if (($+SPRSLICEPOINTERSHGT+1)&0xff00) != ($&0xff00)
        align 256
        endif
sprslicepointers
        ds SPRSLICEPOINTERSHGT ;pointer to first sprite slice in line

        include "tile.asm"
        include "sprite.asm"
        include "logic.asm"
        include "int.asm"

mainloop
        ld sp,sprslicepointers+TILEMAPHGT
        ld hl,0x0101 ;slice plus 1
;_=sprslicepointers
        dup (TILEMAPHGT+1)/2
;        ld (_),hl
;_=_+2
         push hl
        edup

;TODO y clipping (сейчас клипируется с допустимыми координатами 0..TILEMAPHGT*8-sprhgt, т.е. без выхода за tilemap)
;TODO x clipping (сейчас клипирование слева и справа только на 8 пикс)
        ld c,sprslices&0xff ;free slice

        ld ix,objects
        ld hy,16 ;hgt
        ld b,NOBJECTS
objpost0
        ld a,(ix+OBJ_Y)
        cp 192-16+1
        jr nc,objpost0skip
        exx
        ld l,a
        ld a,(ix+OBJ_X)
        cp 256-16+1
        jr nc,objpost0exxskip
        ld b,a
        ;ld de,tball
        ld e,(ix+OBJ_LSB)
        ld d,(ix+OBJ_HSB)
       if COLOURSPRITES
       ;ld a,lx
       ;and 3
       ;add a,a
       ;add a,a
       ;add a,a
       ;or 7;0x38
       ld a,(ix+OBJ_COLOUR)
       endif
;c'=free slice
;de=sprite gfx addr
;hy=hgt (kept)
;l=y
;b=x
;a=colour
        call postsprite
objpost0exxskip
        exx
objpost0skip
         inc ix
        djnz objpost0

       if DOTS
        ld ix,dots
        ld b,NDOTS
dotpost0
        ld a,(ix+DOT_Y)
        cp 192
        jr nc,dotpost0skip
        exx
        ld l,a
        ld b,(ix+DOT_X)
;c'=free slice
;l=y
;b=x
        call postdot
        exx
dotpost0skip
         inc ix
        djnz dotpost0
       endif ;DOTS

        INITEOL ;558t (eol spoiled by sprite prepare)
        ;halt
waittimer
        ld a,(timer)
        ld c,a
oldtimer=$+1
        sub 0
        jr z,waittimer
         if SCROLLING ;for constant time but no constant CRT lines
         cp 3
         jr c,waittimer
         endif
       push af
       ld a,c
       ld (oldtimer),a
curtilegfx=$+1
        ld a,tilegfx/256
;a=tilegfx/256
        call drawtiles ;every line: drawtilestobuf:drawspritestobuf:showtilesfrombuf
;update full screen no sprites = 168801t = 29.3t/b, из них 28/16=1.75t/b тратится на запись флагов (при скролле не будет)
;empty screen = 9321t
       pop af
        cp 4
        jr c,$+4
         ld a,4
        ld b,a
logicloop0
        push bc
        call logic
        pop bc
        djnz logicloop0
        
        jp mainloop

NOBJECTS=10
OBJ_X=0
OBJ_Y=NOBJECTS
OBJ_DX=2*NOBJECTS
OBJ_DY=3*NOBJECTS
OBJ_LSB=4*NOBJECTS
OBJ_HSB=5*NOBJECTS
OBJ_COLOUR=6*NOBJECTS
OBJ_SIZE=7
        macro do x,y,dx,dy,addr,colour
        db x
_=$
        org $-1+N
        db y
        org $-1+N
        db dx
        org $-1+N
        db dy
        org $-1+N
        db addr&0xff
        org $-1+N
        db addr/256
        org $-1+N
        db colour
        org _
        endm
N=NOBJECTS
objects
        do 0,0,1,1,tball,7
        do 55,7,2,1,human0,6
        do 111,45,1,2,human1,5
        do 11,145,1,-1,human2,4
        do 30,100,-1,1,human3,7
        do 80,10,1,0,human4,6
        do 20,15,-1,-1,human0,5
        do 130,111,-1,-1,human1,4
        do 200,160,-1,-1,human2,7
        do 38,80,-1,-1,human3,6
        org objects+(NOBJECTS*OBJ_SIZE)

       if DOTS
        macro dt x,y,dx,dy
        db x
_=$
        org $-1+N
        db y
        org $-1+N
        db dx
        org $-1+N
        db dy
        org _
        endm
NDOTS=20
DOT_X=0
DOT_Y=NDOTS
DOT_DX=2*NDOTS
DOT_DY=3*NDOTS
DOT_SIZE=4
N=NDOTS
dots
        dt 33,0,1,-10
        dt 44,7,2,-11
        dt 55,45,1,-12
        dt 66,145,1,-13
        dt 77,100,-1,-14
        dt 88,10,1,-15
        dt 99,15,-1,-16
        dt 111,111,-1,-17
        dt 122,160,-1,-19
        dt 133,80,-1,-18
        dt 33,80,1,-10
        dt 44,160,2,-11
        dt 55,111,1,-12
        dt 66,15,1,-13
        dt 77,10,-1,-14
        dt 88,100,1,-15
        dt 99,55,-1,-16
        dt 111,71,-1,-17
        dt 122,80,-1,-19
        dt 133,30,-1,-18
        org dots+(NDOTS*DOT_SIZE)
       endif ;DOTS

postsprite
;c'=free slice (updated)
;keep b'
;de=sprite gfx addr
;l=y
;b=x
;hy=hgt (kept)
;a=colour
       if COLOURSPRITES
       ex af,af' ;'
       endif
       ld a,l ;y 
        rra
        rra
        rra
        and 31 ;y/8
       exx
         ld d,a ;0b000TTYYY
        ld hl,sprslicepointers;+(_y/8)
        add a,l
        ld l,a
       exx
       ld a,l ;y
       and 7
       ld ly,a ;y&7
        ld a,b ;x
        and 7
        ld c,a ;x&7
        add a,a
        add a,c ;*3
        add a,a
        add a,a
        add a,a ;+(_x&7)*24
        add a,drawsprkernel&0xff
        ld c,a
        srl b
        srl b
        srl b ;x/8
       ld a,l ;0bTTYYYyyy
        and 0x38 ;0b00YYY000
        rlca
        rlca ;0bYYY00000
        add a,b ;x/8
       exx
        ld e,a ;0bYYYXXXXX
         ld a,d
         rra
         rra
         and 6 ;0b00000TT0
        add a,tilemap/256
        ld d,a
        ld a,c ;free slice
       exx
;c'=a=first free slice
;hl'=sprslicepointers+Y
;de'=tilemap
;de=sprite gfx addr
;c=+(_x&7)*24 + (drawsprkernel&0xff)
;b=+(_x/8)
;ly = y&7 = 8-_TOPHGT
        ld l,a ;this slice = free slice
        ld h,sprslices/256
        ld (hl),e
        inc h
        ld (hl),d ;spr gfx addr
        inc h
        ld (hl),b;+(_x/8)
        inc h
       ld a,ly ;y&7 = 8-_TOPHGT
       add a,a
       add a,ly
       add a,c ;c = +(_x&7)*24 + (drawsprkernel&0xff)
        ld (hl),a;+(_x&7)*24 + (8-_TOPHGT)*3 + (drawsprkernel&0xff)
        inc h
       if COLOURSPRITES
       ex af,af' ;'
       ld (hl),a ;COLOUR
       ex af,af' ;'
       inc h
       endif
       ld a,ly ;y&7 = 8-_TOPHGT
       add a,scrbuf/256
        ld (hl),a;scrbuf/256+(_y&7)
       cpl
       add a,8+1+(scrbuf/256)
       if AUTOMASK
       else
       add a,a
       endif
       add a,a ;_TOPHGT*4 (_TOPHGT*2 for AUTOMASK) ;_TOPHGT = 8-(_y&7)
        add a,e
        ld e,a ;sprite gfx addr
        jp nc,$+4
         inc d
        exx
         ld a,FLAG_DRAWTILE
         ld (de),a
         inc e
         ld (de),a
         inc e
         ld (de),a
         ld a,e
         dec a ;for right carry
         add a,32-1
         ld e,a
         jp nc,$+5
         inc d
         inc d
        ld a,(hl) ;sprslicepointers+Y
        inc c ;next free slice
        ld (hl),c ;this slice +1
        inc l ;next Y
        exx
        inc h
        ld (hl),a ;next slice = previous slice in this line
        inc l ;this slice = free slice
       ld a,ly ;y&7 = 8-_TOPHGT
       sub 8+8 ;a=-tophgt-8
       add a,hy
;a=hgt-8
       jp m,postsprite_skipmid ;for hgt = 8..15
postsprite_mid0
       if COLOURSPRITES
       ld ly,a ;hgt-8
       else
       ex af,af' ;'
       endif
        ld h,sprslices/256
        ld (hl),e
        inc h
        ld (hl),d
        inc h
        ld (hl),b;+(_x/8)
        inc h
        ld (hl),c;+(_x&7)*3 + (drawsprkernel&0xff)
        inc h
       if COLOURSPRITES
       ex af,af' ;'
       ld (hl),a ;COLOUR
       ex af,af' ;'
       inc h
       endif
        ld (hl),scrbuf/256;+_y
        inc h
        exx
         ld a,FLAG_DRAWTILE
         ld (de),a
         inc e
         ld (de),a
         inc e
         ld (de),a
         ld a,e
         dec a ;for right carry
         add a,32-1
         ld e,a
         jp nc,$+5
         inc d
         inc d
        ld a,(hl) ;sprslicepointers+Y
        inc c ;next free slice
        ld (hl),c ;this slice +1
        inc l ;next Y
        exx
        ld (hl),a ;next slice = previous slice in this line
        inc l ;this slice = free slice
        ld a,e
       if AUTOMASK
        add a,8*2
       else
        add a,8*4
       endif
        ld e,a ;sprite gfx addr
        jp nc,$+4
         inc d
       if COLOURSPRITES
       ld a,ly ;hgt-8
       else
       ex af,af' ;' ;hgt-8
       ;ret z
       endif
       sub 8
       jp nc,postsprite_mid0
postsprite_skipmid
;hgt=0..7
;a=hgt-8
       cp -8
       ret z
        ld h,sprslices/256
        ld (hl),e
        inc h
        ld (hl),d
        inc h
        ld (hl),b;+(_x/8)
        inc h
       neg ;8-hgt
       ld b,a
       add a,a
       add a,b
       add a,c
        ld (hl),a;+(_x&7)*24 + (8-hgt)*3 + (drawsprkernel&0xff)
        inc h
       if COLOURSPRITES
       ex af,af' ;'
       ld (hl),a ;COLOUR
       inc h
       endif
        ld (hl),scrbuf/256;+_y
        inc h
        exx
         ld a,FLAG_DRAWTILE
         ld (de),a
         inc e
         ld (de),a
         inc e
         ld (de),a
        ld a,(hl) ;sprslicepointers+Y
        inc c ;next free slice
        ld (hl),c ;this slice +1
        exx
        ld (hl),a ;next slice = previous slice in this line
        ret
        
       if DOTS
postdot
;c'=free slice (updated)
;keep b'
;l=y
;b=x
       ;ld l,16
       ;ld b,16
       ld a,l ;y 
        rra
        rra
        rra
        and 31 ;y/8
       exx
         ld d,a ;0b000TTYYY
        ld hl,sprslicepointers;+(_y/8)
        add a,l
        ld l,a
       exx
       ld a,l ;y
       and 7
       ld ly,a ;y&7
        ld a,b ;x
        and 7
        ld c,a ;x&7
        add a,a
        add a,c ;*3
        add a,drawdotkernel&0xff
        ld c,a
        srl b
        srl b
        srl b ;x/8
       ld a,l ;0bTTYYYyyy
        and 0x38 ;0b00YYY000
        rlca
        rlca ;0bYYY00000
        add a,b ;x/8
       exx
        ld e,a ;0bYYYXXXXX
         ld a,d
         rra
         rra
         and 6 ;0b00000TT0
        add a,tilemap/256
        ld d,a
        ld a,c ;free slice
       exx
;c'=a=first free slice
;hl'=sprslicepointers+Y
;de'=tilemap
;c=+(_x&7)*3 + (drawdotkernel)
;b=+(_x/8)
        ld l,a ;this slice = free slice
        ld h,sprslices/256+2
        ;ld (hl),e
        ;inc h
         ;ld (hl),sprites/256 ;spr gfx addr != 0 (will be in sp) ;fill all slices in init
         ;inc h
        ld (hl),b;+(_x/8)
        inc h
        ld (hl),c;+(_x&7)*3 + (drawdotkernel&0xff)
        inc h
       if COLOURSPRITES
       ;ld (hl),a ;COLOUR
       inc h
       endif
       ld a,ly ;y&7
       add a,scrbuf/256
        ld (hl),a;scrbuf/256+(_y&7)
        exx
         ld a,FLAG_DRAWTILE
         ld (de),a
        ld a,(hl) ;sprslicepointers+Y
        inc c ;next free slice
        ld (hl),c ;this slice +1
        exx
        inc h
        ld (hl),a ;next slice = previous slice in this line
        ret
       endif ;DOTS
        
endcode

        align 256
sprites
        display "sprites=",sprites,",",SPRMEMSIZE,"+256 for CRC"
        ds 2 ;for stack before sprites

        macro dg gfx,mask
       if AUTOMASK
        dw gfx^mask
       else
        dw gfx^mask,mask
       endif
        endm
tball
;gfxR,gfxL,maskR,maskL (or:xor)
        dg %0000000000000000,%0000011111100000
        dg %0000011111100000,%0001111111111000
        dg %0001100000011000,%0011111111111100
        dg %0010000000000100,%0111111111111110
        dg %0010000000000100,%0111111111111110
        dg %0100000000000010,%1111111111111111
        dg %0100000000000010,%1111111111111111
        dg %0100000000000010,%1111111111111111
        dg %0100000000000010,%1111111111111111
        dg %0100000000000010,%1111111111111111
        dg %0100000000000010,%1111111111111111
        dg %0010000000000100,%0111111111111110
        dg %0010000000000100,%0111111111111110
        dg %0001100000011000,%0011111111111100
        dg %0000011111100000,%0001111111111000
        dg %0000000000000000,%0000011111100000

        include "sprites.ast"
        
       if 1==0
        align 256
tmirror
        dup 256
        db (($&1)<<7) + (($&2)<<5) + (($&4)<<3) + (($&8)<<1) + (($&16)>>1) + (($&32)>>3) + (($&64)>>5) + (($&128)>>7)
        edup
font
        incbin "font.bin"
       endif
        
end

	display "endcode=",endcode
        display "databottom=",databottom
	display "Free before 0x8000=",0x8000-0x5b00
	display "Free after endcode=",databottom-endcode
	;display "Size ",/d,end-begin," bytes"
	
	savebin "code.c",begin,end-begin
	
	LABELSLIST "..\us\user.l"
