?login_element?

Subversion Repositories NedoOS

Rev

Rev 49 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. LINEGIF=0x8000 ;адрес для сборки строк
  2. LINEGIF_sz=0x1800 ;макс. ширина = 2048
  3. ;KEEPFRAMELINE=LINEGIF-0x4000
  4. PAL_GLOB=0x9a00 ;,0x300 ;глобальная таблица цветов
  5. PAL_LOCAL=0x9d00 ;,0x300 ;локальная таблица цветов
  6. ROL_TAB=0xa000 ;,0x1000 ;L0>>n (16 bit)
  7.  
  8. ;процедуры чтения на входе хотят NC, иначе могут насквозь вернуть C даже без ошибки
  9.         macro GIFINITCY
  10.         ;or a
  11.         endm
  12.  
  13.         macro GIFRETIFDISKERR
  14.         ;ret c
  15.         endm
  16.  
  17.         macro GIFJRIFDISKERR addr
  18.         ;jr c,addr
  19.         endm
  20.  
  21.         macro GIFGETBYTE
  22.         rdbyte
  23.         GIFRETIFDISKERR
  24.         endm
  25.  
  26.         macro GIFGETBYTE_noret
  27.         rdbyte
  28.         endm
  29.  
  30.         macro GIFGETWORD
  31.         call GIF_GETWORD
  32.         GIFRETIFDISKERR
  33.         endm
  34.  
  35. ;Производит поиск элемента с кодом в HL по таблице цепочек
  36. ;  1,x-начальный (корневоЙ) элемент таблицы (при LZW_SIZE=8 всего их будет 256)
  37. ;  0,0-элемента не существует
  38. ;  0,1-код очистки
  39. ;  0,2-код завершения данных EOI
  40. ;  остальные величины означают адрес, по которому сидит предыдущий элемент цепочки +256
  41. ;и третий байт - собственно сам символ
  42. ;out: HL=адрес элемента. Если элемент равен CC,EOI или отсутствует, то Z=1, А=0-нет элемента,1-CC,2-EOI
  43. ;==========================================
  44.         macro GIFRECODE ;out: HL=адрес элемента. Если элемент равен CC,EOI или отсутствует, то Z=1, А=0-нет элемента,1-CC,2-EOI
  45.         LD C,L
  46.         ;LD a,H
  47.          or 0xc0
  48.          ld b,a
  49.         ADD HL,HL
  50.         ADD HL,BC
  51.         LD A,(HL)
  52.          or a
  53.         endm
  54.  
  55.         macro GIFGETCHAR
  56.         ex af,af'
  57.        dec a
  58.        call z,GETCHRnewblock
  59.        ex af,af'
  60.         GIFGETBYTE_noret
  61.         GIFRETIFDISKERR
  62.         endm        
  63.  
  64.         macro GIFGETCODE
  65.         call GETCODE_
  66.         GIFRETIFDISKERR
  67.         endm
  68.  
  69. readgif
  70.         ld hl,LINEGIF
  71.         ld de,LINEGIF+1
  72.         ld (hl),BACKGROUNDCOLORLEVEL
  73.         ld bc,LINEGIF_sz-1
  74.         ldir ;чтобы справа в остатке знакоместа была чернота (потом можно убрать, когда readchr будет это делать)
  75.        
  76.         xor a
  77.         ld (gifdisposalmethod),a
  78.        
  79.         ld a,GIFTRANSP_off
  80.         ld (giftransparencyflag),a
  81.         CALL ROL_INSTALL
  82.         CALL GIFSEARCH
  83.         RET C
  84.         CALL GIF_LOGSCR ;обработка дескриптора картинки вместе с палитрой (PAL_GLOB) ;заказывает память под bmp
  85.         RET C
  86. GIF_newframe
  87. GIF_parsechunk
  88.         GIFINITCY
  89.         GIFGETBYTE
  90.         CP #2C
  91.         jr Z,GIF_IMG
  92.         CP #21
  93.         ;JR Z,GIF_SPEC
  94.         ;CP #3B ;???
  95.         ;ret z
  96.         ret nz ;неопознанный блок, выход по ошибке
  97. ;GIF_SPEC ;специальный блок
  98.         GIFINITCY
  99.         GIFGETBYTE
  100.         cp #f9 ;graphic control extension
  101.         jr z,GIF_GFXCTRLEXT
  102. ;       CP #FF
  103. ;       JR NZ,GIF_fail
  104. GIF_HELP
  105.         GIFGETBYTE
  106.         OR A
  107.         jr z,GIF_parsechunk;newframe
  108.         LD B,A
  109. GIF_HP0
  110.         GIFGETBYTE    ;Пропустить HELP...
  111.         DJNZ GIF_HP0
  112.         JR GIF_HELP
  113.  
  114. ;graphic control extension
  115. GIF_GFXCTRLEXT
  116.         GIFGETBYTE ;=4
  117. gifdisposalmethod=$+1
  118.          ld a,0
  119.          ld (gifwasdisposalmethod),a
  120.         GIFGETBYTE ;bit0 = transparent color present, bit4..2 = disposal method (0=not specified(?), 1=do not dispose(?), 2=overwrite with bg color, 3=overwrite with prev frame(?))
  121. ;6908fast.gif, 6914fast.gif, 6911sled.gif: a=5 (transparent color present, do not dispose), 5, 5...
  122. ;6906wrbg.gif: a=5, 5, 5, 9 (то есть указанный dispose надо делать после картинки?)
  123. ;5scroll.gif: a=4...
  124. ;sprites.gif: a=1 (transparent color present, disposal not specified)
  125. ;animatie.gif: a=9 (transparent color present, overwrite with bg color), 9, 9...
  126. ;zajchik.gif: a=5...
  127. ;voloki.gif: a=0
  128. ;ris4.gif: a=0
  129. ;optic_14.gif: a=0
  130. ;optic_15.gif: a=0
  131. ;multipal.gif, melnchud.gif, melnchil.gif (все из Photoshop) - нет graphic control extension - TODO не заказывать память под bmp и не делать putline?
  132.         ld (gifdisposalmethod),a
  133.          ;cp 9
  134.          ;ret z
  135.         ;jr $
  136.          rra;bit 0,a
  137.          ld a,GIFTRANSP_on
  138.          jr c,$+4;nz
  139.          ld a,GIFTRANSP_off
  140.          ld (giftransparencyflag),a
  141.         GIFGETBYTE ;delayLSB
  142.         ld l,a
  143.         GIFGETBYTE ;delayHSB
  144.         ld h,a
  145.          or l
  146.          jr nz,$+4
  147.          ld l,10 ;0 s => 0.1 s
  148.         ld (gifframetime),hl
  149.         GIFGETBYTE ;transparent color index
  150.          ld (giftransparentcolor),a
  151.         GIFGETBYTE ;=0
  152.         jp GIF_parsechunk
  153.  
  154. ;"""""""""""""""""""""""
  155. GIF_IMG ;Обработка блока изображения.
  156.         call initframe ;один раз на кадр после setpicwid, setpichgt и после установки gifframetime ;заказывает память под конверченный кадр
  157.          ld (gifconvertedframeaddr),hl
  158.          ld (gifconvertedframeaddrHSB),a
  159.  
  160.         GIFINITCY
  161.         GIFGETWORD
  162.         ex de,hl;ld (localx),hl ;локальное начало строки        
  163.         GIFGETWORD
  164.         ;ld (starty),hl ;локальная первая строка
  165.         ld b,h
  166.         ld c,l
  167.         GIFGETWORD
  168.         LD (DX_IMG),HL ;локальная ширина
  169.          LD (pixelcounter_back),HL
  170.         GIFRETIFDISKERR
  171.         GIFGETWORD
  172.         LD (DY_IMG),HL ;локальная высота
  173.         ld h,d
  174.         ld l,e ;локальное начало строки
  175.         add hl,hl
  176.         add hl,de
  177.         ex de,hl ;de=localx*3
  178.         ld hl,LINEGIF
  179.         add hl,de
  180.         ld (linebufstart_local),hl
  181.         ld (linebufpointer),hl
  182.  
  183. gifrasteraddr=$+1
  184.         ld hl,0;(putchar_hl)
  185. gifrasteraddrHSB=$+1
  186.         ld a,0;(putchar_a)
  187.         call setputlineaddr
  188.  
  189. ;пропустить строки до starty (скопировать из предыдущего кадра) TODO что если это первый кадр, а строк нет? так не бывает?
  190. ;starty=$+1
  191. ;        ld bc,0
  192. ;bc=локальная первая строка
  193.         call gifpreparepic_skiplines
  194.  
  195.         if 1==0
  196. ;ищем, в какое место bmp класть начальную строчку кадра:
  197.         ld bc,(cury);(Y_IMG)
  198.          srl b
  199.          rr c ;TODO с учётом зума
  200.         inc bc
  201.         jr gifrasterstart0loop
  202. gifrasterstart0
  203.         call nextscreenline
  204.         call nextputlineaddr
  205. gifrasterstart0loop
  206.         cpi
  207.         jp pe,gifrasterstart0
  208.         endif
  209.        
  210.         GIFINITCY
  211.         GIFGETBYTE
  212.         if 1==0
  213.         BIT 6,A ;необходимо проверить бит 6 на предмет наличия чередования строк
  214.         JR Z,GIF_IMG_NORM
  215. ;чередование строк. TODO поддержать чередование строк (0,2,1,3? - разницу будет видно только с зумом)
  216.          SCF
  217.          RET
  218.  
  219. GIF_IMG_NORM
  220.         endif
  221.         push af
  222.  
  223. ;for PUTCHAR:
  224.         call PUTCHARgetline_ifvisible ;устанавливает PUTCHARaddr, PUTCHARputaddr
  225.         CALL gifsetpgLZW
  226. linebufpointer=$+1
  227.         ld de,0 ;Адрес для вывода байта в LINEGIF
  228. pixelcounter_back=$+1
  229.         ld bc,0
  230.         exx
  231.  
  232.         pop af ;A bit 7: признак наличия палитры, 2..0: число цветов
  233.         LD HL,PAL_LOCAL
  234.         CALL GIF_PAL
  235.         RET C
  236.  
  237. ;начало разборки отдельного блока графики
  238.         XOR A
  239.         ld lx,a;LD (GETCOD0+1),A ;количество бит в наличии
  240.         LD (GIF_IMG_ENDcode),A
  241.  
  242.         inc a ;ld a,1
  243.         ex af,af'
  244.        GIFINITCY
  245.        GIFGETBYTE
  246.        LD (LZW_SIZE),A
  247.         push hl
  248. ;"""""""""""""""""""""""
  249. GIF_IMGclearLZW ;очистка LZW
  250.         pop hl
  251.        CALL LZW_INSTALL
  252.        GIFGETCODE
  253.        GIFRECODE ;out: HL=адрес элемента. Если элемент равен CC,EOI или отсутствует, то Z=1, А=0-нет элемента,1-CC,2-EOI
  254.        push hl ;запоминаем адрес элемента, чтобы после NEW_CODE присвоить его значение LZW_OLD'у
  255.         JR nz,GIF_IMGputstring
  256.          inc hl
  257.          ld a,(hl)
  258.         dec a;CP 1
  259.         JR Z,GIF_IMGclearLZW ;код очистки
  260.         dec a;CP 2
  261.         jr Z,GIF_IMG_END ;код конца данных...
  262. ;элемент отсутствует - ошибка
  263.          pop hl
  264.         SCF
  265.         RET
  266. GIF_IMGputstring
  267.         CALL PUTSTRING ;вывод цепочки из таблицы цепочек
  268.         jr GIF_IMGunpackloop
  269.  
  270. GIF_IMGputstring_newcode
  271.         ;nop ;4t = 0.04 s
  272.         CALL PUTSTRING ;вывод цепочки из таблицы цепочек
  273. GIF_IMGnewcode_unpackloop
  274. ;добавить в таблицу цепочек элемент, состоящий из ссылки на OLD и символа А
  275. NEW_COD0 LD HL,0
  276.         LD DE,(LZW_OLD)
  277.          inc d
  278.         LD (HL),d;E
  279.         INC HL
  280.         LD (HL),e;D
  281.         INC HL
  282.         LD (HL),A
  283.         INC HL
  284.         LD (NEW_COD0+1),HL
  285. NEW_COD1 LD HL,0        
  286.         INC HL
  287.         LD (NEW_COD1+1),HL
  288. NEW_CODmask=$+1
  289.         LD DE,0 ;маска+1
  290.         OR A
  291.         SBC HL,DE
  292.         call z,gif_inccodemask ;сначала одни 111, затем 000... - увеличить LZW_SIZW
  293. GIF_IMGunpackloop
  294. ;главный цикл распаковки
  295.         pop hl
  296.         LD (LZW_OLD),HL
  297.         GIFGETCODE
  298.         GIFRECODE ;out: HL=адрес элемента. Если элемент равен CC,EOI или отсутствует, то Z=1, А=0:нет элемента,1:CC,2:EOI
  299.         push hl ;запоминаем адрес элемента, чтобы после NEW_CODE присвоить его значение LZW_OLD'у
  300.         jp nz,GIF_IMGputstring_newcode
  301.          inc hl
  302.          ld a,(hl)
  303.         dec a;CP 1
  304.         JR Z,GIF_IMGclearLZW ;код очистки
  305.         dec a;CP 2
  306.         jr Z,GIF_IMG_END;конец блока
  307. ;элемент отсутствует
  308.         ;nop ;4t < 0.02 s
  309. LZW_OLD=$+1
  310.         LD HL,0
  311.         CALL PUTSTRING ;вывод цепочки из таблицы цепочек
  312. PUTCHARaddr2=$+1
  313.         CALL PUTCHAR ;если не патчить на невидимых строках, видно следы ;keeps de
  314.          ld a,(de) ;первый символ цепочки
  315.         jp GIF_IMGnewcode_unpackloop
  316.  
  317. GIF_IMG_END
  318.          pop hl
  319. GIF_IMG_END0
  320. ;найден код конца LZW-данных
  321. ;необходимо считать след. блок, и если его длина=0, то конец кадра
  322.         GIFINITCY
  323.         call GETCHAR_ ;чтобы была правильная глубина стека при нахождении блока с длиной 0 (он пропускает чтение следующего байта через снятие адреса со стека)
  324. ;установит переменную GIF_IMG_ENDcode, если пойдёт блок с длиной 0, а пока дочитываем текущий блок
  325.         GIFRETIFDISKERR
  326. GIF_IMG_ENDcode=$+1
  327.         LD A,0 ;/0xff, если встретился блок с длиной 0
  328.         OR A
  329.         jr z,GIF_IMG_END0 ;т.е. ещё не конец блока.
  330. ;встретился блок с длиной 0 - конец изображения
  331.  
  332.         ld bc,(curpichgt)
  333.         ;jr $
  334.         call gifpreparepic_skiplines
  335.        
  336.         ld hl,(nframes)
  337.         inc hl
  338.         ld (nframes),hl
  339.  
  340. gifconvertedframeaddr=$+1
  341.         ld hl,0
  342. gifconvertedframeaddrHSB=$+1
  343.         ld a,0
  344.         ld (gifoldconvertedframeaddr),hl
  345.         ld (gifoldconvertedframeaddrHSB),a
  346.          ;ld a,(nframes)
  347.          ;cp 2
  348.          ;ret z
  349.         JP GIF_newframe ;следующий кадр
  350.        
  351. ;bc=номер строки выхода
  352. gifpreparepic_skiplines0
  353. ;TODO копировать прямо из памяти (окна 1,2) в память (окно 3)
  354.          push bc
  355.         call islinevisible ;nz=invisible
  356.         jr nz,gifpreparepic_skiplines_invisible
  357.         ld hl,(gifoldconvertedframeaddr)
  358.         ld a,(gifoldconvertedframeaddrHSB)
  359.         ld de,LINEPIXELS
  360.         ld bc,(keepframe_linesize_bytes)
  361.         call getfrommem ;берём сконверченную строку из предыдущего кадра
  362.         call nextoldconvertedframeaddr ;смещаем адрес, откуда брать сконверченную строку из предыдущего кадра (gifoldconvertedframeaddr)
  363.         call keepconvertedline ;запоминаем сконверченную строку из LINEPIXELS, смещаем адрес, куда класть (keepframeaddr)
  364.          call nextscreenline
  365.          call nextputlineaddr
  366. gifpreparepic_skiplines_invisible
  367.         call inccury
  368.          pop bc
  369. gifpreparepic_skiplines
  370. ;вход тут
  371.         ld hl,(cury)
  372.         or a
  373.         sbc hl,bc
  374.         jr nz,gifpreparepic_skiplines0
  375.         ;call gifsetpgLZW
  376.         ret
  377.  
  378. nextoldconvertedframeaddr
  379. gifoldconvertedframeaddr=$+1
  380.         ld bc,0
  381. gifoldconvertedframeaddrHSB=$+1
  382.         ld a,0
  383.         ld hl,(keepframe_linesize_bytes)
  384.         add hl,bc
  385.         adc a,0
  386.         ld (gifoldconvertedframeaddr),hl
  387.         ld (gifoldconvertedframeaddrHSB),a
  388.         ret
  389.  
  390. DX_IMG  DEFW 0  ;размер отдельного изображения
  391. DY_IMG  DEFW 0
  392. ;===========================
  393. ;затычка для неиспользуемых строк (вызывается только в двух местах)
  394. PUTCHAR_DUMMY
  395.         exx
  396.         cpi
  397.         exx
  398.         ret pe
  399.         jp PUTCHARendline
  400.  
  401. PUTCHARtransparent
  402.         inc de
  403.         inc de
  404.         inc de
  405.         cpi
  406.         exx
  407.         ret pe
  408.         jp PUTCHARendline
  409.  
  410. PUTCHAR
  411. ;Вывод символа в поток (строку)...
  412. ;портит a
  413. ;de'=linebufpointer, bc'=counter
  414.         exx
  415. giftransparentcolor=$+1
  416.          cp 0
  417. giftransparencyflag=$
  418.          jr z,PUTCHARtransparent ;/ld l,
  419. GIFTRANSP_on=0x28 ;"jr z"
  420. GIFTRANSP_off=0x2e ;"ld l"
  421.          ;nop ;4t = 0.1 s
  422. putchar_palH=$+1
  423.         ld h,PAL_GLOB/256
  424.         ld l,a
  425.         ld a,(hl)
  426.         ld (de),a
  427.         inc de
  428.         inc h
  429.         ld a,(hl)
  430.         ld (de),a
  431.         inc de
  432.         inc h
  433.         ldi
  434.         exx
  435.         ret pe ;строка не кончилась
  436. PUTCHARendline
  437. ;end of line
  438.         push bc
  439.         push de
  440.         push hl
  441.         call inccury
  442. PUTCHARputaddr=$+1
  443.         jp 0 ;jr nz,PUTCHARskipline
  444. PUTCHARputline
  445.         ld bc,(curpicwidx3)
  446.         ld hl,LINEGIF
  447. ;hl=откуда копируем строку
  448. ;bc=сколько байт копируем
  449.         push hl
  450.         call putline ;TODO для анимированных ;кладёт в bmp
  451.         pop hl
  452.         call drawscreenline_frombuf ;конвертируем LINEGIF в LINEPIXELS и выводим её на экран
  453.         call keepconvertedline ;запоминаем сконверченную строку из LINEPIXELS
  454.          ;call setpgtemp8000 ;drawscreenline_frombuf сама восстанавливает
  455.          ;call setpgcode4000 ;drawscreenline_frombuf сама восстанавливает
  456.         call nextoldconvertedframeaddr ;смещаем адрес, откуда брать сконверченную строку из предыдущего кадра (gifoldconvertedframeaddr)
  457. PUTCHARskipline
  458.         call PUTCHARgetline_ifvisible ;берём строку из bmp, если она видимая и если надо рисовать поверх ;устанавливает PUTCHARaddr
  459.         call gifsetpgLZW
  460.         pop hl
  461.         pop de
  462.         pop bc
  463.         exx
  464.         ld bc,(DX_IMG) ;локальная ширина
  465. linebufstart_local=$+1
  466.         ld de,0 ;локальное начало строки
  467.         exx
  468.         ret
  469.  
  470. PUTCHARgetline_ifvisible
  471. ;устанавливает PUTCHARaddr, PUTCHARputaddr
  472.          ld hl,PUTCHAR_DUMMY
  473.          ld de,PUTCHARskipline
  474.         call islinevisible ;nz=invisible
  475.         jr nz,PUTCHARgetline_ifvisibleq
  476. ;getline, если DX_IMG!=curpicwid или если есть прозрачность ;TODO делать эту проверку один раз за кадр
  477.          ld hl,(DX_IMG)
  478.          ld de,(curpicwid)
  479.          or a
  480.          sbc hl,de
  481.         ld bc,(curpicwidx3)
  482.         ld de,LINEGIF
  483.         jr nz,PUTCHARgetline
  484. ;de=куда достаём строку
  485. ;bc=сколько байт достаём
  486.         ld a,(giftransparencyflag)
  487.         cp GIFTRANSP_off
  488. PUTCHARgetline
  489.         call nz,getline ;TODO для анимированных: если не первый кадр, прочитать строку из памяти в LINEGIF (чтобы рисовать поверх неё)
  490.          ld hl,PUTCHAR
  491.          ld de,PUTCHARputline
  492. PUTCHARgetline_ifvisibleq
  493.          ld (PUTCHARaddr),hl
  494.          ld (PUTCHARaddr2),hl
  495.          ld (PUTCHARputaddr),de
  496.         ret
  497.  
  498. ;__________________________________
  499. PUTSTRING
  500. ;выводит цепочку с нач. адресом в HL в поток символов
  501. ;out: А=первый символ этой цепочки
  502. ;портит bc,de,hl
  503. ;использует буфер по адресу -1..-4096
  504.         ld bc,0
  505. PUTSTR0 ;
  506.         dec bc
  507.         ld d,(hl);e
  508.         inc hl
  509.         ld e,(hl);d
  510.         inc hl
  511.         ld a,(hl)
  512.         ld (bc),a
  513.         ex de,hl
  514.          ;BIT 4,B
  515.          ;JR Z,PUTSTR_fail ;ошибка (длина 4096 элементов, больше нет места) ;но реально такого не может быть в составленной нами таблице
  516.          ;nop ;4t = 0.1 s
  517.          dec h
  518.         jp nz,PUTSTR0 ;пока не перейдём к корневой цепочке
  519. PUTSTR2 ld a,(bc)
  520. PUTCHARaddr=$+1
  521.         call PUTCHAR
  522.         inc c
  523.         jp nz,PUTSTR2
  524.         inc b
  525.         jp nz,PUTSTR2
  526.          ld a,(de) ;первый символ цепочки
  527.         ret
  528.  
  529. ;________________________________________________
  530. LZW_INSTALL
  531. ;Инсталляция таблицы цепочек в 0xc000
  532. ;Структура таблицы - трёхбайтные элементы:
  533. ;  1,x-начальный (корневоЙ) элемент таблицы (при LZW_SIZE=8 всего их будет 256)
  534. ;  0,0-элемента не существует
  535. ;  0,1-код очистки
  536. ;  0,2-код завершения данных EOI
  537. ;  остальные величины означают адрес, по которому сидит предыдущий элемент цепочки +256
  538. ;и третий байт - собственно сам символ
  539.         ld hl,0xc000
  540.         push hl
  541.         ld de,0xc001
  542.         ld bc,0x3fff
  543.         ld (hl),l;=0
  544.         ldir
  545. LZW_SIZE=$+1
  546.         ld b,0 ;начальный размер кода LZW (расширяться будет не здесь, а в LZW_SIZW)
  547.         ld hl,1
  548.         add hl,hl
  549.         djnz $-1
  550.         LD C,L
  551.         LD B,H
  552.         INC HL
  553.         INC HL
  554.         LD (NEW_COD1+1),HL
  555.         pop hl ;0xc000
  556.         xor a
  557.         ld e,a;0
  558. LZW_INS1
  559.         LD (HL),1;0
  560.         INC HL
  561.         LD (HL),a;0
  562.         INC HL
  563.         LD (HL),E
  564.         INC E
  565.         cpi
  566.         jp pe,LZW_INS1
  567.         LD (HL),a;=0;#FF
  568.         INC HL
  569.         LD (HL),1
  570.         INC HL
  571.         LD (HL),A;0
  572.         INC HL
  573.         LD (HL),a;=0;#FF
  574.         INC HL
  575.         LD (HL),2
  576.         INC HL
  577.         LD (HL),A;0
  578.         INC HL
  579.         LD (NEW_COD0+1),HL ;Адрес первого свободного Элемента в таблице цепоЧек.
  580.         LD A,(LZW_SIZE)
  581.         INC A
  582. gif_setcodemask
  583. ;a=codesize=1..12
  584. ;out: CY=0
  585.         ld b,a
  586.          add a,a
  587.          add a,ROL_TAB/256-2
  588.         LD (LZW_SIZW),A ;1..12 *2 +(ROL_TAB/256-2)
  589.         ld hl,0
  590.         add hl,hl
  591.         inc hl
  592.         djnz $-2
  593.         ld a,l
  594.         ld (GETCODmasklow),a
  595.         ld a,h
  596.         ld (GETCODmaskhigh),a
  597.          inc hl
  598.         ld (NEW_CODmask),hl ;маска+1
  599.         ret
  600. gif_inccodemask
  601.         ld a,(LZW_SIZW) ;1..12 *2 +(ROL_TAB/256-2)
  602.          sub ROL_TAB/256-2
  603.          rrca
  604.         cp 12
  605.         adc a,0
  606.         ;JR NC,$+3
  607.         ; INC A
  608. ;a=codesize=1..12
  609.         jp gif_setcodemask ;out: CY=0
  610. ;__________________________
  611. GETCHAR_
  612. ;для GIF_IMG_END
  613.         GIFGETCHAR ;может вывалиться с C (ошибка) или NC (найден блок с длиной 0)
  614.         ret
  615.        
  616. GETCHRnewblock
  617. ;текущий блок закончился
  618.         GIFGETBYTE_noret
  619.         GIFJRIFDISKERR GETCHRnewblock_fail
  620.         or a
  621.         ret nz ;установить длину блока и читать байт
  622. ;блок нулевой длины - определить конец данных
  623. ;нужно только в GIF_IMG_END
  624.          ex af,af'
  625.         pop af ;выход на уровень выше, чтобы не читать данное (ret будет эквивалентно ret nc из GIFGETCHAR)
  626.        LD A,#FF
  627.        LD (GIF_IMG_ENDcode),A
  628.        GIFINITCY
  629.        RET
  630. GETCHRnewblock_fail
  631.         ex af,af'
  632.         pop af ;выход на уровень выше (ret будет эквивалентно ret c в GIFGETCHAR)
  633.         scf
  634.         ret
  635.  
  636. ;__________________________
  637. GETCODE_ ;читает код в HL с заданным количеством бит (см. LZW_SIZW)
  638. GETCOD00 LD L,0 ;оставшиеся данные.
  639.         ld a,lx ;количество бит в наличии *2
  640.         or a;ADD A,A
  641.         JP NZ,GETCOD1
  642.         GIFGETCHAR
  643.         LD L,A
  644.         LD (GETCOD00+1),A
  645.         LD A,16;8
  646.          ld lx,a
  647.          ;add a,a
  648. GETCOD1
  649.         ADD A,ROL_TAB/256-2
  650.         LD H,A
  651.  
  652.        ;LD A,lx ;количество бит в наличии *2
  653.        SUB 0
  654. LZW_SIZW=$-1 ;текущий размер кода LZW *2 +1 +(ROL_TAB/256-2)
  655.         JR NC,GETCODneed0bytes ;имеем достаточно бит в наличии
  656.         ADD A,16;8
  657.         jr nc,GETCODneed2bytes ;надо взять дополнительно 2 байта
  658. ;GETCODneed1byte
  659. ;надо взять дополнительно 1 байт (самый частый случай)
  660.         LD lx,a;(GETCOD0+1),A ;количество бит в наличии
  661.         LD E,(HL) ;LSB (L>>n)
  662.         GIFINITCY
  663.         GIFGETCHAR
  664.         LD (GETCOD00+1),A
  665.         LD L,A
  666.         LD D,(HL) ;LSB (L>>n)
  667.         inc h
  668.         LD A,(HL) ;HSB (L>>n)
  669.         OR E
  670.         ;JP GETCODq
  671. GETCODq
  672. GETCODmasklow=$+1
  673.         and 0
  674.         LD L,A
  675. GETCODmaskhigh=$+1
  676.         LD A,0
  677.         AND d
  678.         LD H,A
  679.         RET ;NC=OK, HL=код
  680. GETCODneed2bytes
  681. ;надо взять дополнительно 2 байта
  682.         ADD A,16;8
  683.         LD lx,a;(GETCOD0+1),A ;количество бит в наличии
  684.         LD E,(HL) ;LSB (L>>n)
  685.         GIFINITCY
  686.         GIFGETCHAR
  687.         LD L,A
  688.         LD D,(HL) ;LSB (L>>n)
  689.         inc h
  690.         LD A,(HL) ;HSB (L>>n)
  691.         OR E
  692.         LD E,A
  693.         GIFGETCHAR
  694.         LD (GETCOD00+1),A
  695.         LD L,A
  696.         LD A,(HL) ;HSB (L>>n)
  697.         OR D
  698.         LD D,A
  699.         ld a,e
  700.         JP GETCODq
  701. GETCODneed0bytes
  702. ;имеем достаточно бит в наличии
  703.         LD lx,a;(GETCOD0+1),A ;количество бит в наличии
  704.         LD D,0
  705.         ld a,(hl)
  706.         JP GETCODq
  707. ;________________________________________
  708. GIF_LOGSCR
  709. ;обработка дескриптора картинки
  710.          ld a,PAL_GLOB/256
  711.          ld (putchar_palH),a
  712.         GIFINITCY
  713.         GIFGETWORD
  714.         call setpicwid
  715.         GIFGETWORD
  716.         call setpichgt
  717.        
  718.         ld hl,(freemem_hl)
  719.         ld (gifrasteraddr),hl
  720.         ld a,(freemem_a)
  721.         ld (gifrasteraddrHSB),a
  722.         call reserve_bmp_pages ;TODO для анимированных
  723.         call reservefirstframeaddr
  724.        
  725.         GIFINITCY
  726.         GIFGETBYTE ;d7=palette on, d6..d4=bits of color resolution(add 1), d3=0, d2..d0=bits/pixel in image(add 1)
  727.         LD C,A
  728.         GIFGETBYTE
  729.         LD (gifbgcolor),A
  730.         GIFGETBYTE ;aspect ratio? (0 in GIF87)
  731.         LD A,C
  732.         LD HL,PAL_GLOB
  733.         ;JP GIF_PAL
  734. ;_______________________________
  735. GIF_PAL
  736. ;чтение палитры
  737. ;HL=адрес, куда класть палитру (768 b), А=флаг палитры (7) и число цветов (2..0)
  738.         OR A
  739.         ret p ;нет палитры
  740.         AND 7
  741.         INC A
  742.         LD B,A ;число битов палитры 1..8
  743.         ld a,h
  744.         ld (putchar_palH),a
  745.         LD a,1
  746.         add a,a
  747.         djnz $-1
  748.         ld b,a ;B=длина палитры в триплетах RGB (min=2, max=256)
  749.         GIFINITCY
  750. GIF_PAL1
  751.         inc h
  752.         inc h
  753.         GIFGETBYTE
  754.         ld (hl),a
  755.         dec h
  756.         GIFGETBYTE
  757.         ld (hl),a
  758.         dec h
  759.         GIFGETBYTE
  760.         ld (hl),a
  761.         inc l
  762.         djnz GIF_PAL1
  763. ;zajchik.gif - в локальных палитрах последний цвет чёрный
  764.         XOR A
  765.         RET
  766.  
  767. GIF_GETWORD
  768.         GIFINITCY
  769.         GIFGETBYTE
  770.         LD L,A
  771.         GIFGETBYTE_noret
  772.         LD H,A
  773.         RET
  774. ;_______ _______________________
  775. GIF_HEAD0 db "IF87a"
  776. GIF_HEAD1 db "IF89a"
  777.  
  778. GIFSEARCH
  779.         GIFINITCY
  780.         LD HL,GIF_HEAD0
  781.         LD DE,GIF_HEAD1
  782.         LD B,6-1
  783. GIFSEARCH0
  784.         GIFGETBYTE
  785.         CP (HL)
  786.         JR Z,GIFSEARCH1
  787.         EX DE,HL
  788.         CP (HL)
  789.         EX DE,HL
  790.         scf
  791.         ret nz ;CY=fail
  792. GIFSEARCH1
  793.         INC HL
  794.         INC DE
  795.         DJNZ GIFSEARCH0
  796.         XOR A ;OK
  797.         RET
  798.  
  799. ;=============================
  800. ROL_INSTALL
  801. ;Инсталятор таблички для ускорения процедуры GETCODE
  802. ;L0>>n (16 bit)
  803.         LD HL,ROL_TAB+#0E00
  804.         ld de,0x08FF
  805. ROL_I00
  806. ROL_I01
  807.         ld b,d
  808.         ld a,l
  809.         rlca
  810.         djnz $-1
  811.         ld c,a
  812.         and e
  813.         LD (HL),A ;LSB
  814.         INC H
  815.         xor c
  816.         LD (HL),A ;HSB
  817.         DEC H
  818.         INC L
  819.         jr nz,ROL_I01
  820.         DEC H
  821.         DEC H
  822.         srl e ;0xff >> n
  823.         dec d
  824.         jr nz,ROL_I00
  825.         ret
  826.