?login_element?

Subversion Repositories NedoOS

Rev

Rev 749 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1.         macro MASKBYTE
  2.         ld a,(hl)
  3.         and e
  4.         or d
  5.         ld (hl),a
  6.         endm
  7.         macro DOWNBYTE
  8.         add hl,bc
  9.         endm
  10.  
  11. prspr
  12. ;в 4000,8000 уже включен экран (setpgsscr40008000)
  13. ;iy=sprite data+2 = spraddr+4
  14. ;e=x = -(sprmaxwid-1)..159 (кодируется как x+(sprmaxwid-1))
  15. ;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
  16. ;(iy-3)=sprhgt
  17. ;(iy-4)=sprwid
  18. ;по x,y, ширине, высоте найти адрес на экране, куда выводим видимую часть спрайта
  19. ;спрайт полной высоты и ширины должен работать максимально быстро!
  20.         ld a,scrwid+(sprmaxwid-1)
  21.         sub e ;x ;a=расстояние до правой границы экрана
  22.         ld hx,a
  23.         ;ld lx,0 ;по умолчанию нет фальшивого экрана, выход по правой границе экрана будет сразу ;для полной ширины не надо - выход будет по окончанию спрайта
  24.          ;ld lx,0 ;для спрайта полной высоты, клипированного справа - выход сразу на границе
  25.         ld a,e ;x
  26.         sub sprmaxwid-1
  27.         jr nc,prsprnocropleft
  28. ;[найти адрес начала видимой части спрайта:]
  29. ;[сначала столбец (прибавить hgt*2*число скрытых столбцов) можно в цикле, т.к. пропуск столбцов бывает редко]
  30. ;или включить фальшивый экран в 0x4000,0x8000 и заменить адреса выхода на переключалку страниц, так можно работать со спрайтами процедурой
  31. ;a=-число отрезанных слева столбцов
  32. ;посчитать hx для правильного выхода из фальшивого экрана
  33. ;посчитать lx для правильного выхода из спрайта в y-клипированной выводилке
  34.         ld l,a
  35.         add a,(iy-4)
  36.         ld lx,a ;sprwid-число отрезанных слева столбцов
  37. ;если <=0, то спрайта нет на экране!!! выходим!!!
  38.          ret m
  39.          ret z
  40.         xor a
  41.         sub l
  42.         ld hx,a ;число отрезанных слева столбцов
  43.         push bc
  44.         ld a,(pgfake)
  45.         ;ld (curpg4000),a
  46.         SETPG16K
  47.         ;ld (curpg8000),a
  48.         SETPG32KLOW
  49. ;hl будет вычислен с ошибкой +64
  50.         pop bc
  51.         ld a,l
  52.         or a
  53. prsprnocropleft
  54.         ld (prsprqsp),sp
  55. ;NC
  56.         ld b,0
  57.         ld l,c ;y
  58.         rra ;x bit 0
  59.         ;ld h,0x40/32/2
  60.         ;jr nc,$+4 ;x bit 0
  61.         ; ld h,0x80/32/2
  62.          ld h,b;0
  63.          rl h
  64.          inc h ;0x40/32/2 или 0x80/32/2
  65.         srl a ;x bit 1
  66.          rl h
  67.         add hl,hl
  68.         add hl,hl
  69.         add hl,bc
  70.         add hl,hl
  71.         add hl,hl
  72.         add hl,hl ;y*40+scrbase
  73.          if scrbase&0xff
  74.          add a,scrbase&0xff
  75.          endif
  76. ;a=x/4
  77.         add a,l
  78.         ld l,a
  79.         adc a,h
  80.         sub l
  81.         ld h,a ;hl=scr ;не может быть переполнения при отрицательных x? maxhl = 199*40 + 127 = 8087
  82.         ld a,c ;y
  83.         ;add a,sprmaxhgt-1
  84.         ;sub sprmaxhgt-1
  85.         ;jp c,prsprcroptop
  86.          cp scrhgt
  87.          jp nc,prsprcroptop
  88.         add a,(iy-3) ;sprhgt
  89.         cp scrhgt+1 ;200=OK, >200=crop
  90.         jp nc,prsprcropbottom        
  91. ;hx=расстояние до правой границы экрана (columns)
  92. ;x=156: hx=4
  93. ;x=157: hx=3
  94. ;x=158: hx=2
  95. ;x=159: hx=1
  96. ;если нет клипирования справа, то при нечётном x и чётном sprwid надо сделать строго hx>sprwid/2!
  97. ;lx важен только при клипировании слева
  98.          ld a,hx
  99.          inc a
  100.          srl a
  101.          ld hx,a ;lx не пересчитываем, он завышен в 2 раза, но тут в полном спрайте есть выход по ширине раньше
  102. ;hx=расстояние до правой границы экрана (double columns)
  103. ;x=156: hx=2
  104. ;x=157: hx=2
  105. ;x=158: hx=1
  106. ;x=159: hx=1
  107.         ld c,40 ;b=0
  108. ;iy=sprite data+2
  109.         ld e,(iy-2)
  110.         ld d,(iy-1)
  111.         ld sp,iy
  112. ;выбрать ветку в зависимости от sprhgt
  113.         ld a,(iy-3) ;sprhgt
  114.         cp 16
  115.         jr z,prspr16
  116.         jr nc,prspr24
  117. prspr8
  118.         ld a,prspr8column&0xff
  119.         ld (prsprcolumnpatch),a
  120.         ld (prsprcolumnpatch2),a
  121.         jp prspr8column+1
  122. prspr16
  123.         ld a,prspr16column&0xff
  124.         ld (prsprcolumnpatch),a
  125.         ld (prsprcolumnpatch2),a
  126.         jp prspr16column+1
  127. prspr24
  128.         cp 32
  129.         jr z,prspr32
  130.         ld a,prspr24column&0xff
  131.         ld (prsprcolumnpatch),a
  132.         ld (prsprcolumnpatch2),a
  133.         jp prspr24column+1
  134. prspr32
  135.         ld a,prspr32column&0xff
  136.         ld (prsprcolumnpatch),a
  137.         ld (prsprcolumnpatch2),a
  138.         jp prspr32column+1
  139.         align 256
  140. ;отдельная процедура для спрайта полной высоты, т.к. там не надо на каждом столбце переставлять sp
  141. prspr32column
  142.         dup 8
  143.         pop de
  144.         MASKBYTE
  145.         DOWNBYTE
  146.         edup
  147. prspr24column
  148.         dup 8
  149.         pop de
  150.         MASKBYTE
  151.         DOWNBYTE
  152.         edup
  153. prspr16column
  154.         dup 8
  155.         pop de
  156.         MASKBYTE
  157.         DOWNBYTE
  158.         edup
  159. prspr8column
  160.         display prspr32column," HSB equal to ",$
  161.         dup 7
  162.         pop de
  163.         MASKBYTE
  164.         DOWNBYTE
  165.         edup
  166.         pop de
  167.         MASKBYTE
  168. ;найти адрес следующего столбца на экране или выйти        
  169. ;4000,8000,[c000]6000,a000,[e001]4001... ;единственное расположение для такой логики (из-за константы 0xa0) (другой вариант - константа 0x60? тогда надо экран в 0000!!!)
  170. ;нельзя использовать строки, где h=0xa0, т.е. верхние 7 строк (остаётся 193 строки), иначе надо ld a,0x9f...inc a (+2t)
  171.         pop de ;годится только для спрайтов полной высоты (не прокатит даже если делать pop всех данных столбца, т.к. сдвиг hl разный - разве что и hl сдвигать при клипировании)
  172.         ld a,0x9f;0xa0
  173.         cp h
  174.         adc hl,de ;de = 0x4000 - ((sprhgt-1)*40)
  175.          ret c ;выход по ширине спрайта, там надо восстановить sp и константу в стеке
  176. prsprcolumnpatch=$+1
  177.         jp pe,prspr16column ;в половине случаев
  178. ;8000->с000 (надо 6000) или a000->e001 (надо 4001)
  179.          inc a
  180.         xor h
  181.         ld h,a
  182.          dec hx
  183. goprsprcolumn
  184.          jp nz,prspr16column
  185. prsprcolumnpatch2=$-2
  186.          ;выход по границе экрана
  187. ;10+11+15+14 = 40t (+5+9)
  188. ;это может быть граница фальшивого экрана! надо иметь возможность продолжить (с hl-64 из-за ошибки адреса при отрицательных x?)
  189. ;        ld a,(pgfake)
  190. ;curpg4000=$+1
  191.         ld a,(curpg16k) ;ok
  192. pgfake2=$+1
  193.         cp 0
  194.         jp nz,prsprqright ;действительно выход по правой границе
  195. ;был фальшивый экран для клипирования по левой границе, продолжаем на настоящем экране
  196.         ld hx,lx
  197.         ld bc,-64
  198.         add hl,bc ;из-за ошибки адреса при отрицательных x
  199.          dec c ;NZ!!!
  200. ;как не запороть стек? даже если инлайнить вызов, там внутри всё равно rst
  201.         ld (prsprmaybeqrightsp),sp
  202.         ld sp,tempsp
  203.         call setpgsscr40008000 ;выключаем фальшивый экран, включаем настоящий
  204. prsprmaybeqrightsp=$+1
  205.         ld sp,0
  206.         ld bc,40
  207.         ;ld lx,b;0 ;второй раз будет действительно выход
  208.         jp goprsprcolumn ;NZ!!!
  209. ;можно то же самое сделать при спрайте кодом (патчи не нужны, de присваивать только если меняется, 13-1 байт (36.5t) лишних на столбец, выход по dec hx:ret z и просто ret в конце)
  210. ;а как делать вход в середину, если спрайты кодом, а de присваивается только при изменении? сначала рисовать в фальшивый экран и переключать по call z?
  211. ;но клипирование по y уже надо делать с данными спрайта, а не с кодом (т.е. нужна копия спрайта в виде данных)
  212.  
  213. ;выход по ширине спрайта
  214. prsprqwid
  215. ;у нас de взят с прошлого раза, и обработчик прерываний может запороть стек
  216.         ld hl,$
  217.         push hl ;если теперь произойдёт прерывание, то de не запорет стек
  218. prsprqright
  219. prsprqsp=$+1
  220.         ld sp,0
  221.         ret
  222.  
  223.        
  224. ;для вывода спрайта неполной высоты:
  225.  
  226. ;клипирование снизу
  227. prsprcropbottom
  228. ;a=sprbottom
  229. ;e?1=x = -(sprmaxwid-1)..159 (кодируется как x+(sprmaxwid-1))
  230. ;c?2=y = -(sprmaxhgt-1)..199 (кодируется как есть)
  231. ;(iy-3)?3=sprhgt
  232. ;(iy-4)?4=sprwid
  233. ;hl=scr
  234.         sub scrhgt;200
  235.         ;sub (iy-3) ;sprhgt
  236.          ld d,(iy-3) ;sprhgt
  237.          sub d
  238.         ld c,a ;-sprvisiblehgt = sprbottom-200-sprhgt
  239. ;если клипировано слева, то сейчас lx = sprwid-число отрезанных слева столбцов
  240. ;иначе lx не задано
  241.        
  242.         ld a,(iy-4) ;sprwid
  243.         cp hx ;расстояние до правого края экрана
  244.         ;jr nc,$
  245.         jr nc,prsprcropygo;_cropx ;берём меньшее из sprwid и расстояния до правой границы экрана
  246.         ld hx,a
  247.         jp prsprcropygo
  248.  
  249. prsprcroptop
  250. ;a=sprtop
  251. ;e?1=x = -(sprmaxwid-1)..159 (кодируется как x+(sprmaxwid-1))
  252. ;c?2=y = -(sprmaxhgt-1)..199 (кодируется как есть)
  253. ;(iy-3)?3=sprhgt
  254. ;(iy-4)?4=sprwid
  255. ;hl=scr неверный (выше экрана)
  256.        
  257.         neg ;a=number of lines to crop
  258.          ld d,(iy-3) ;sprhgt
  259.          sub d
  260. ;a = -sprvisiblehgt = -(sprtop+sprhgt) = linestocrop-sprhgt
  261. ;если sprvisiblehgt<=0, то спрайта нет на экране!!! выходим!!!
  262.          ret p
  263.         ld c,a ;-sprvisiblehgt = -(sprtop+sprhgt) = linestocrop-sprhgt
  264.  
  265. ;если клипировано слева, то сейчас lx = sprwid-число отрезанных слева столбцов
  266. ;иначе lx не задано
  267.        
  268.         ld a,(iy-4) ;sprwid
  269.         cp hx ;расстояние до правого края экрана
  270.         jr nc,prsprcropygo_cropx ;берём меньшее из sprwid и расстояния до правой границы экрана
  271.         ld hx,a
  272. prsprcropygo_cropx
  273.  
  274.          ld a,c
  275.          add a,d ;a=number of lines to crop
  276.         add a,a
  277. ;прибавить 2*число скрытых строк к адресу
  278.         add a,ly
  279.         ld ly,a
  280.         jr nc,$+4
  281.         inc hy
  282.        
  283.         ld a,e ;x
  284.         sub sprmaxwid-1 ;NC для положительных x
  285.         srl a
  286.         ld h,0x40
  287.         jr nc,$+4 ;x bit 0
  288.          ld h,0x80
  289.         srl a
  290.         jr nc,$+4 ;x bit 1
  291.          set 5,h
  292.        if scrbase&0xff
  293.        add a,scrbase&0xff
  294.        endif
  295.         ld l,a
  296.        
  297. prsprcropygo
  298. ;d=(iy-3)?3=sprhgt
  299. ;(iy-4)?4=sprwid
  300.         ld a,d ;sprhgt
  301.         ;add a,c ;-sprvisiblehgt
  302.         ; add a,3 ;inc a
  303.         ;add a,a
  304.         ;ld (prsprNspraddpatch),a ;2*(sprhgt-sprvisiblehgt)+2 +4
  305.          inc a
  306.          add a,a
  307.         ld (prsprNspraddpatch),a ;2*sprhgt+2
  308.  
  309.         ld a,c ;-sprvisiblehgt
  310.         add a,a
  311.         add a,c
  312.         add a,a
  313.         ld (prsprNpatch),a ;PRSPR24 и т.п. (по 6 байт)        
  314.  
  315.         ex de,hl
  316.          ;ld b,-1 ;убрать за счёт перемещения ld h
  317.          ;ld h,0x40/32-1
  318.          inc c
  319.         ld l,c ;-sprvisiblehgt
  320.         add hl,hl
  321.         add hl,hl
  322.          ld h,0x40/8-1 -1
  323.          jr nz,$+4
  324.          ld h,0x40/8 ;для sprvisiblehgt-1 == 0
  325.         add hl,bc
  326.         add hl,hl
  327.         add hl,hl
  328.         add hl,hl
  329.         ld (prsprNscraddpatch),hl ;0x4000 - ((sprvisiblehgt-1)*40)
  330.         ex de,hl
  331.  
  332. ;hl=scr
  333.         ;ld c,40
  334.         jp prsprN
  335.  
  336. ;выравнивание на нужный младший байт адреса:
  337. _lowaddr=256-(sprmaxhgt*6)
  338.         ds (_lowaddr-$)&0xff
  339. ;младший байт адреса равен 256-(sprvisiblehgt*6)
  340. PRSPR32
  341.         dup 8
  342.         MASKBYTE
  343.         DOWNBYTE
  344.         pop de
  345.         edup
  346. PRSPR24
  347.         MASKBYTE
  348.         DOWNBYTE
  349.         pop de
  350. PRSPR23
  351.         MASKBYTE
  352.         DOWNBYTE
  353.         pop de
  354. PRSPR22
  355.         MASKBYTE
  356.         DOWNBYTE
  357.         pop de
  358. PRSPR21
  359.         MASKBYTE
  360.         DOWNBYTE
  361.         pop de
  362. PRSPR20
  363.         MASKBYTE
  364.         DOWNBYTE
  365.         pop de
  366. PRSPR19
  367.         MASKBYTE
  368.         DOWNBYTE
  369.         pop de
  370. PRSPR18
  371.         MASKBYTE
  372.         DOWNBYTE
  373.         pop de
  374. PRSPR17
  375.         MASKBYTE
  376.         DOWNBYTE
  377.         pop de
  378. PRSPR16
  379.         MASKBYTE
  380.         DOWNBYTE
  381.         pop de
  382. PRSPR15
  383.         MASKBYTE
  384.         DOWNBYTE
  385.         pop de
  386. PRSPR14
  387.         MASKBYTE
  388.         DOWNBYTE
  389.         pop de
  390. PRSPR13
  391.         MASKBYTE
  392.         DOWNBYTE
  393.         pop de
  394. PRSPR12
  395.         MASKBYTE
  396.         DOWNBYTE
  397.         pop de
  398. PRSPR11
  399.         MASKBYTE
  400.         DOWNBYTE
  401.         pop de
  402. PRSPR10
  403.         MASKBYTE
  404.         DOWNBYTE
  405.         pop de
  406. PRSPR9
  407.         MASKBYTE
  408.         DOWNBYTE
  409.         pop de
  410. PRSPR8
  411.         MASKBYTE
  412.         DOWNBYTE
  413.         pop de
  414. PRSPR7
  415.         MASKBYTE
  416.         DOWNBYTE
  417.         pop de
  418. PRSPR6
  419.         MASKBYTE
  420.         DOWNBYTE
  421.         pop de
  422. PRSPR5
  423.         MASKBYTE
  424.         DOWNBYTE
  425.         pop de
  426. PRSPR4
  427.         MASKBYTE
  428.         DOWNBYTE
  429.         pop de
  430. PRSPR3
  431.         MASKBYTE
  432.         DOWNBYTE
  433.         pop de
  434. PRSPR2
  435.         MASKBYTE
  436.         DOWNBYTE
  437.         pop de
  438. PRSPR1
  439.         display PRSPR32," HSB equal to ",$
  440.         MASKBYTE
  441.        
  442. ;найти адрес следующего столбца на экране или выйти        
  443. ;4000,8000,[c000]6000,a000,[e001]4001...
  444. ;восстановить начальный hl
  445. prsprNscraddpatch=$+1
  446.         ld bc,0 ;bc = 0x4000 - ((sprvisiblehgt-1)*40)
  447.         ld a,0x9f;0xa0
  448.         cp h
  449.         adc hl,bc
  450.         jp pe,prsprNcolumnq ;в половине случаев
  451. ;8000->с000 (надо 6000) или a000->e001 (надо 4001)
  452.          inc a
  453.         xor h
  454.         ld h,a
  455. prsprNcolumnq
  456.         dec hx
  457.         jp z,prsprNmaybeqright ;это может быть граница фальшивого экрана! надо иметь возможность продолжить (с hl-64 из-за ошибки адреса при отрицательных x?)
  458. prsprNcolumnqq
  459. ;найти адрес данных следующего столбца спрайта
  460. ;можно просто сделать много пустых pop de, т.к. пропуск строк бывает редко
  461. prsprNspraddpatch=$+1
  462.         ld bc,0 ;bc = 2*(sprhgt-sprvisiblehgt)+2
  463.         add iy,bc
  464. prsprN
  465. ;iy=sprite data
  466.         ld c,40
  467.         ld sp,tempsp ;чтобы не намусорить новым de в старых данных
  468.         ld e,(iy-2)
  469.         ld d,(iy-1)
  470.         ld sp,iy
  471. prsprNpatch=$+1
  472.         jp PRSPR24
  473.        
  474. prsprNmaybeqright
  475. ;curpg8000=$+1
  476. ;        ld a,0
  477.         ld a,(curpg32klow) ;ok
  478. pgfake=$+1
  479.         cp 0
  480.         jp nz,prsprqright ;действительно выход
  481.         ld hx,lx
  482.         ld bc,-64
  483.         add hl,bc ;из-за ошибки адреса при отрицательных x
  484.         ld sp,tempsp
  485.         call setpgsscr40008000 ;выключаем фальшивый экран, включаем настоящий
  486.         ;ld bc,40
  487.         ;ld lx,b;0 ;второй раз будет действительно выход
  488.         jp prsprNcolumnqq
  489.  
  490. copyboxscrtoscr
  491. ;iy=sprite data+2 = spraddr+4
  492. ;e=x = -(sprmaxwid-1)..159 (кодируется как x+(sprmaxwid-1))
  493. ;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
  494. ;(iy-3)=sprhgt
  495. ;(iy-4)=sprwid
  496.        ;ld e,1+(sprmaxwid-1)
  497.        ;ld c,0
  498.        
  499.         ld l,(iy-4) ;sprwid
  500.         ld a,e ;x
  501.         sub sprmaxwid-1
  502.         ld e,a
  503.         jr nc,copyboxscrtoscr_nocropleft
  504.         add a,l
  505.         ld l,a ;new sprwid
  506. ;если <=0, то спрайта нет на экране!!! выходим!!!
  507.          ret m
  508.          ret z
  509.         xor a
  510.         ld e,a ;new x        
  511. copyboxscrtoscr_nocropleft
  512.         add a,l
  513.         sub scrwid
  514.         jr c,copyboxscrtoscr_nocropright
  515. ;a=число столбцов, откушенных справа
  516.         neg
  517.         add a,l
  518.         ld l,a ;new sprwid
  519. ;если <=0, то спрайта нет на экране!!! выходим!!!
  520.          ret m
  521.          ret z
  522. copyboxscrtoscr_nocropright
  523.         ld h,(iy-3) ;sprhgt
  524.         ld a,c ;y
  525.         cp -(sprmaxhgt-1)
  526.         jr c,copyboxscrtoscr_nocroptop
  527.         add a,h
  528.         ld h,a ;new sprhgt
  529. ;если <=0, то спрайта нет на экране!!! выходим!!!
  530.          ret m
  531.          ret z
  532.         xor a
  533.         ld c,a ;new y
  534. copyboxscrtoscr_nocroptop
  535.         add a,h
  536.         sub scrhgt
  537.         jr c,copyboxscrtoscr_nocropbottom
  538. ;a=число столбцов, откушенных справа
  539.         neg
  540.         add a,h
  541.         ld h,a ;new sprhgt
  542. ;если <=0, то спрайта нет на экране!!! выходим!!!
  543.          ret m
  544.          ret z
  545. copyboxscrtoscr_nocropbottom
  546. ;h=hgt,l=wid (/2) != 0
  547.          ;ld l,32
  548.         ld a,c
  549.         add a,h
  550.         dec a
  551.         ld c,a
  552. ;c=y, e=xleft (/2)
  553.         ld lx,c ;lx=y
  554.        push hl ;h=hgt,l=wid (/2) != 0
  555.         ld a,e ;xleft (/2)
  556.         add a,l ;wid (/2)
  557.         dec a
  558.         ld e,a ;xright (/2)
  559.         ld b,0
  560.         ld l,c ;y
  561.         ;srl a ;CY=x bit 0
  562.         ;srl a ;CY=x bit 1
  563.          ld h,0xc0/32
  564.         add hl,hl
  565.         add hl,hl
  566.         add hl,bc
  567.         add hl,hl
  568.         add hl,hl
  569.         add hl,hl ;y*40+scrbase
  570.         ; if scrbase&0xff
  571.         ; add a,scrbase&0xff
  572.         ; endif
  573.         ;add a,l
  574.         ;ld l,a
  575.         ;adc a,h
  576.         ;sub l
  577.         ;ld h,a ;hl=scr
  578.        pop bc ;b=hgt,c=wid (/2) != 0
  579. ;c=wid (/2)
  580. ;b=hgt
  581. ;e=xright (/2)
  582. ;lx=y
  583.         push bc
  584.         push de
  585.         push hl
  586.         call copyboxscrtoscr_page ;rightmost layer
  587.         pop hl
  588.         pop de
  589.         pop bc
  590.         dec e ;xright (/2)
  591.         dec c ;wid (/2)
  592.        ret z
  593.         push bc
  594.         push de
  595.         push hl
  596.         call copyboxscrtoscr_page ;next layer
  597.         pop hl
  598.         pop de
  599.         pop bc
  600.         dec e ;xright (/2)
  601.         dec c ;wid (/2)
  602.        ret z
  603.         push bc
  604.         push de
  605.         push hl
  606.         call copyboxscrtoscr_page ;next layer
  607.         pop hl
  608.         pop de
  609.         pop bc
  610.         dec e ;xright (/2)
  611.         dec c ;wid (/2)
  612.        ret z
  613. copyboxscrtoscr_page
  614. ;lx=y
  615. ;e=xright (/2)
  616. ;c=wid (/2)
  617. ;b=hgt
  618. ;hl=scrright = 0xc000+
  619.         push bc
  620.         ld a,e ;xright (/2)
  621.         rra
  622.         call nc,getuser_scr_low
  623.         call c,getuser_scr_high
  624.         SETPG32KHIGH ;kills bc
  625.         ld a,e ;xright (/2)
  626.         rra
  627.         rra
  628.         jr nc,$+4
  629.          set 5,h
  630.         and 0x3f
  631.          if scrbase&0xff
  632.          add a,scrbase&0xff
  633.          endif
  634.         add a,l
  635.         ld l,a
  636.         adc a,h
  637.         sub l
  638.         ld h,a ;hl=scr
  639.         pop bc
  640. ;widbytes = 1 + (xright)/4 - (xright-wid+1+(3-layer))/4 (layer = xright&3)
  641.         ld a,e ;xright
  642.         cpl
  643.         and 3 ;3-layer
  644.         add a,e ;xright
  645.         sub c ;wid
  646.         inc a
  647.         srl a
  648.         srl a
  649.         ld c,e
  650.         srl c
  651.         srl c
  652.         sub c
  653.         dec a ;a=-widbytes
  654.        ret z
  655.         neg
  656.         ld c,a
  657. ;c=wid (bytes in this page)
  658. ;b=hgt
  659.  
  660.        push bc
  661.        push hl
  662.  
  663.         ;ld a,e ;xright
  664.         ;cpl
  665.         ld a,+(UVSCROLL_SCRWID/2)-1
  666.         sub e
  667. ;[a=layer 0..3]
  668.          ;add a,+(UVSCROLL_SCRNPUSHES-1)*8
  669.         ld hl,allscroll_lsb
  670.         add a,(hl)
  671. ;hlc = allscroll = yscroll*512+x2scroll
  672.         ld c,a
  673.           ld hl,(allscroll)
  674.           jr nc,$+3
  675.           inc hl ;hlc = allscroll = yscroll*512+x2scroll
  676.         ld a,UVSCROLL_SCRHGT-1
  677.         sub lx ;y
  678.         ld e,a
  679.         ld d,0
  680.         add hl,de
  681.         add hl,de
  682.         ld a,c
  683.          ld e,l ;yscroll*2
  684.         add hl,hl
  685.         if 1==1
  686.          rr e ;yscroll (corrected для зацикливания)
  687.          rra
  688.          ;or 3 ;a=0xff-(((x2scroll+layer[+4])/2)&0xfc)
  689.          set 0,a
  690.           bit 1,a
  691.          res 1,a
  692.          jr nz,$+3
  693.          inc a
  694.         else
  695.          rr e ;yscroll (corrected для зацикливания)
  696.          rra
  697.           ;ld b,a
  698.          and 0xfc ;a=0xfc-(((x2scroll+layer[+4]+((UVSCROLL_SCRNPUSHES-1)*8))/2)&0xfc)
  699.         endif
  700.          ld (copyboxscrtoscr_page_e),a
  701.          ld a,h
  702.          rla
  703.          rla ;a=(x2scroll+layer)&3 + ((yscroll/64)*4)
  704.          xor c
  705.          and 0xfc
  706.          xor c
  707.           xor 3
  708.  
  709.         ld hl,tpushpgs
  710.         add a,l
  711.         ld l,a
  712.         adc a,h
  713.         sub l
  714.         ld h,a
  715.         ld a,(hl) ;gfx pages
  716.         SETPG16K
  717.         inc hl
  718.         inc hl
  719.         inc hl
  720.         inc hl
  721.         ld a,(hl)
  722.         SETPG32KLOW
  723.  
  724.         ld a,e ;yscroll (corrected для зацикливания)
  725.         and 63
  726.         add a,0x40
  727.         ld d,a
  728. copyboxscrtoscr_page_e=$+1
  729.         ld e,0
  730.          ;ld de,0x4001 ;de=ldpush = 0x4000+
  731.          
  732.        pop hl
  733.        pop bc
  734. ;рисуем справа налево!
  735. copyboxscrtoscr0
  736.         push bc ;b = hgt
  737.         ld hx,b
  738.         push de
  739.         push hl
  740. ;hl=scr = 0xc000+
  741. ;de=ldpush = 0x4000+
  742. ;11 LL RR pp 11 LL RR pp
  743.         ld bc,-40
  744. copyboxscrtoscrcolumn0
  745.         ld a,(de)
  746.         inc d
  747.         ld (hl),a
  748.         add hl,bc
  749.         dec hx
  750.         jp nz,copyboxscrtoscrcolumn0
  751.         pop hl
  752.         dec hl
  753.         pop de
  754.         bit 1,e
  755.         dec de
  756.         jr nz,$+2+3+3
  757.          ld bc,6
  758.          ex de,hl
  759.          add hl,bc
  760.          ex de,hl
  761.         pop bc
  762.         dec c
  763.         jr nz,copyboxscrtoscr0
  764.         ret
  765.