?login_element?

Subversion Repositories NedoOS

Rev

Rev 746 | Blame | Compare with Previous | Last modification | View Log | Download

  1. ;4000: 64 канала(H) * 64 позиции(L) = 4096 треков
  2. ;8000..ffff: dynamic memory
  3.  
  4. BIGENDIAN=0 ;0=LSB,HSB
  5.  
  6. setscrpg
  7.         ld a,(user_scr0_high) ;ok
  8.         SETPG16K
  9.         ret
  10. setpgroots
  11. pgroots=$+1
  12.         ld a,0
  13.         SETPG16K
  14.         ret
  15. setpgsamples
  16. pgsamples=$+1
  17.         ld a,0
  18.         SETPG16K
  19.         ret
  20.  
  21. pokecurtime_curtrack_c
  22. ;c=data
  23.         ld a,(curtrack)
  24. ;pokecurtime_tracka_c
  25. ;a=track
  26. ;c=data
  27.         ld hl,(curtime)
  28.         call tracktime_totrackpartindex
  29. poketrackpartindex_c
  30. ;hl=index
  31. ;ly=part
  32. ;a=track
  33. ;c=data
  34.         ex de,hl
  35.         call getroot ;out: hl=root
  36.         call writetopoi_c ;keeps de ;c<->mem
  37.         ex de,hl
  38. ;c<->mem
  39.         ret
  40.  
  41. peekplaytime_tracka
  42. ;a=track
  43.         ld hl,(playtime)
  44.         call tracktime_totrackpartindex
  45. peektrackpartindex
  46. ;hl=index
  47. ;ly=part
  48. ;a=track
  49. ;out: a=data
  50.         ex de,hl
  51.         call getroot ;out: hl=root
  52.         call readfrompoi ;keeps de
  53.         ex de,hl
  54.         ret
  55.  
  56. getroot
  57. ;ly=part
  58. ;a=track
  59.         add a,0x40
  60.         ld h,a ;номер трека
  61.         ;ld l,0*4
  62.         ld a,ly ;part
  63.         add a,a
  64.         add a,a
  65.         ld l,a
  66. ;hl=root
  67.         ret
  68.  
  69. getendaddr
  70. ;ly=part
  71. ;a=track
  72.         call getroot ;out: hl=root
  73.         ld de,0xffff
  74.         jp findleft ;out: de=nonempty index (or 0), a=data
  75. ;de=addr ;последний байт трека
  76.  
  77. tracktime_totrackpartindex
  78. ;a=track
  79. ;hl=time
  80. ;если канал подписан на ордер, то найти на месте или влево цифру ордера, index=(time-digittime)
  81. ;иначе index=time
  82.         push af
  83.         push hl
  84.         call gettrackorder ;номер ордера (0=нет)
  85.         pop hl
  86.         or a ;канал подписан на ордер?
  87.         jr z,tracktime_toindexpart_noorder ;part=a=0
  88.         ;push af
  89.          push de
  90.         push hl
  91.         ex de,hl
  92.         xor a ;TODO номер канала ордера
  93.         ld ly,0 ;у ордера всегда берём дефолтную часть (part=0), т.к. ордер не подчиняется ордерам
  94.         call getroot
  95.         call findleft ;out: de=nonempty index (or 0), a=data (1..62 or 0)
  96.         pop hl ;time
  97.         or a
  98.         sbc hl,de ;time-digittime
  99.          pop de
  100.         ;pop af
  101. tracktime_toindexpart_noorder
  102.         ld ly,a
  103.         pop af
  104. ;hl=index
  105. ;ly=part
  106. ;a=track
  107.         ret
  108.  
  109. ;пусть номер трека и смещение в треке - это функция от номера канала и времени (зависит от ордера, если канал привязан к ордеру). всего 64 канала * 64 позиции = 4096 треков (одна страница адресов)
  110. ;адрес в треке - функция номера трека и смещения в треке
  111. ;для этого каждый трек (длиной 64K) храним как бинарное дерево: адрес левой части, адрес правой части
  112. ;и так до минимального элемента (4 байта, которые смотрим непосредственно)
  113. ;адрес делится на 4, поэтому 2 байтами можно адресовать 256K (16 страниц)
  114. ;но так будет медленно, поэтому выделим 32K для каждого (канал & 7)
  115.  
  116.         macro BITINC_D nbit
  117.         bit nbit,d
  118.         jr z,$+4
  119.          inc l
  120.          inc l
  121.         endm
  122.         macro BITINC_E nbit
  123.         bit nbit,e
  124.         jr z,$+4
  125.          inc l
  126.          inc l
  127.         endm
  128.  
  129.         macro HLFROMHL
  130.         ld a,(hl)
  131.         inc l
  132.         ld h,(hl)
  133.         ld l,a
  134.         or h
  135.         endm
  136.  
  137. readfrompoi
  138. ;hl=track root (4 bytes: left poi, right poi)
  139. ;de=index (kept)
  140. ;out: a=data
  141.         BITINC_D 7
  142.         HLFROMHL
  143.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  144.         BITINC_D 6
  145.         HLFROMHL
  146.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  147.         BITINC_D 5
  148.         HLFROMHL
  149.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  150.         BITINC_D 4
  151.         HLFROMHL
  152.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  153.         BITINC_D 3
  154.         HLFROMHL
  155.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  156.         BITINC_D 2
  157.         HLFROMHL
  158.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  159.         BITINC_D 1
  160.         HLFROMHL
  161.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  162.         BITINC_D 0
  163.         HLFROMHL
  164.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  165.         BITINC_E 7
  166.         HLFROMHL
  167.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  168.         BITINC_E 6
  169.         HLFROMHL
  170.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  171.         BITINC_E 5
  172.         HLFROMHL
  173.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  174.         BITINC_E 4
  175.         HLFROMHL
  176.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  177.         BITINC_E 3
  178.         HLFROMHL
  179.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  180.         BITINC_E 2
  181.         HLFROMHL
  182.         ret z ;пусто, возвращает 0=NOTE_SPACE (только для чтения!!!)
  183.         ld a,e
  184.         rra
  185.         jr nc,$+3
  186.          inc l
  187.         rra
  188.         jr nc,$+4
  189.          inc l
  190.          inc l
  191.         ld a,(hl)
  192.         ret
  193.  
  194.         macro WRITETOPOI_D nbit,addr
  195.         BITINC_D nbit
  196.         inc l
  197.         ld a,(hl)
  198.         dec l
  199.         or (hl)
  200.         jp z,addr ;пусто
  201.         ld a,(hl)
  202.         inc l
  203.         ld h,(hl)
  204.         ld l,a
  205.         endm
  206.  
  207.         macro WRITETOPOI_E nbit,addr
  208.         BITINC_E nbit
  209.         inc l
  210.         ld a,(hl)
  211.         dec l
  212.         or (hl)
  213.         jp z,addr ;пусто
  214.         ld a,(hl)
  215.         inc l
  216.         ld h,(hl)
  217.         ld l,a
  218.         endm
  219.  
  220. writetopoi_c
  221. ;hl=track root (4 bytes: left poi, right poi)
  222. ;de=index (kept)
  223. ;c=data
  224. ;out: c<->mem
  225.         ld a,c
  226.         or a
  227.         jp z,writetopoi_space
  228.         WRITETOPOI_D 7,writetopoi_create15 ;если надо, создать узел из 32768 байт
  229.         WRITETOPOI_D 6,writetopoi_create14
  230.         WRITETOPOI_D 5,writetopoi_create13
  231.         WRITETOPOI_D 4,writetopoi_create12
  232.         WRITETOPOI_D 3,writetopoi_create11
  233.         WRITETOPOI_D 2,writetopoi_create10
  234.         WRITETOPOI_D 1,writetopoi_create9
  235.         WRITETOPOI_D 0,writetopoi_create8
  236.         WRITETOPOI_E 7,writetopoi_create7
  237.         WRITETOPOI_E 6,writetopoi_create6
  238.         WRITETOPOI_E 5,writetopoi_create5
  239.         WRITETOPOI_E 4,writetopoi_create4
  240.         WRITETOPOI_E 3,writetopoi_create3
  241.         WRITETOPOI_E 2,writetopoi_create2 ;если надо, создать узел из 4 байт
  242.         ld a,e
  243.         rra
  244.         jr nc,$+3
  245.          inc l
  246.         rra
  247.         jr nc,$+4
  248.          inc l
  249.          inc l
  250.         ld a,(hl)
  251.         ld (hl),c
  252.         ld c,a
  253.         ret
  254.  
  255.         macro WRITETOPOI_CREATE_D nbit
  256.         push de
  257.         ex de,hl
  258.         call newmem ;keep de
  259.         ex de,hl
  260.         ld (hl),e
  261.         inc l
  262.         ld (hl),d
  263.         ex de,hl
  264.         pop de
  265.         BITINC_D nbit
  266.         endm
  267.  
  268.         macro WRITETOPOI_CREATE_E nbit
  269.         push de
  270.         ex de,hl
  271.         call newmem ;keep de
  272.         ex de,hl
  273.         ld (hl),e
  274.         inc l
  275.         ld (hl),d
  276.         ex de,hl
  277.         pop de
  278.         BITINC_E nbit
  279.         endm
  280.  
  281. writetopoi_create15 ;создать узел из 32768 байт
  282.         WRITETOPOI_CREATE_D 6
  283. writetopoi_create14 ;создать узел из 16384 байт
  284.         WRITETOPOI_CREATE_D 5
  285. writetopoi_create13 ;создать узел из 8192 байт
  286.         WRITETOPOI_CREATE_D 4
  287. writetopoi_create12 ;создать узел из 4096 байт
  288.         WRITETOPOI_CREATE_D 3
  289. writetopoi_create11 ;создать узел из 2048 байт
  290.         WRITETOPOI_CREATE_D 2
  291. writetopoi_create10 ;создать узел из 1024 байт
  292.         WRITETOPOI_CREATE_D 1
  293. writetopoi_create9 ;создать узел из 512 байт
  294.         WRITETOPOI_CREATE_D 0
  295. writetopoi_create8 ;создать узел из 256 байт
  296.         WRITETOPOI_CREATE_E 7
  297. writetopoi_create7 ;создать узел из 128 байт
  298.         WRITETOPOI_CREATE_E 6
  299. writetopoi_create6 ;создать узел из 64 байт
  300.         WRITETOPOI_CREATE_E 5
  301. writetopoi_create5 ;создать узел из 32 байт
  302.         WRITETOPOI_CREATE_E 4
  303. writetopoi_create4 ;создать узел из 16 байт
  304.         WRITETOPOI_CREATE_E 3
  305. writetopoi_create3 ;создать узел из 8 байт
  306.         WRITETOPOI_CREATE_E 2
  307. writetopoi_create2 ;создать узел из 4 байт
  308.         push de
  309.         ex de,hl
  310.         call newmem ;keep de
  311.         ex de,hl
  312.         ld (hl),e
  313.         inc l
  314.         ld (hl),d
  315.         ex de,hl
  316.         pop de
  317.         ld a,e
  318.         rra
  319.         jr nc,$+3
  320.          inc l
  321.         rra
  322.         jr nc,$+4
  323.          inc l
  324.          inc l
  325.         ld a,(hl)
  326.         ld (hl),c
  327.         ld c,a
  328.         ret
  329.  
  330.         macro WRITETOPOI_SPACE_D nbit,addr
  331.         BITINC_D nbit
  332.         push hl ;класть в стек адрес указателя, который мы удаляем (всю цепочку)
  333.         HLFROMHL
  334.         jp z,addr ;уже пусто
  335.         endm
  336.        
  337.         macro WRITETOPOI_SPACE_E nbit,addr
  338.         BITINC_E nbit
  339.         push hl ;класть в стек адрес указателя, который мы удаляем (всю цепочку)
  340.         HLFROMHL
  341.         jp z,addr ;уже пусто
  342.         endm
  343.        
  344. writetopoi_space
  345. ;hl=track root (4 bytes: left poi, right poi)
  346. ;de=index
  347. ;умеет удалять пустое поддерево
  348.         WRITETOPOI_SPACE_D 7,writetopoi_space_nodel15
  349.         WRITETOPOI_SPACE_D 6,writetopoi_space_nodel14
  350.         WRITETOPOI_SPACE_D 5,writetopoi_space_nodel13
  351.         WRITETOPOI_SPACE_D 4,writetopoi_space_nodel12
  352.         WRITETOPOI_SPACE_D 3,writetopoi_space_nodel11
  353.         WRITETOPOI_SPACE_D 2,writetopoi_space_nodel10
  354.         WRITETOPOI_SPACE_D 1,writetopoi_space_nodel9
  355.         WRITETOPOI_SPACE_D 0,writetopoi_space_nodel8
  356.         WRITETOPOI_SPACE_E 7,writetopoi_space_nodel7
  357.         WRITETOPOI_SPACE_E 6,writetopoi_space_nodel6
  358.         WRITETOPOI_SPACE_E 5,writetopoi_space_nodel5
  359.         WRITETOPOI_SPACE_E 4,writetopoi_space_nodel4
  360.         WRITETOPOI_SPACE_E 3,writetopoi_space_nodel3
  361.         WRITETOPOI_SPACE_E 2,writetopoi_space_nodel2
  362.  
  363.         push hl
  364.         ld a,e
  365.         rra
  366.         jr nc,$+3
  367.          inc l
  368.         rra
  369.         jr nc,$+4
  370.          inc l
  371.          inc l
  372.         ld c,(hl)
  373.         ld (hl),0
  374.         pop hl
  375.         ld a,(hl)
  376.         inc l
  377.         or (hl)
  378.         inc l
  379.         or (hl)
  380.         inc l
  381.         or (hl)
  382.         jp nz,writetopoi_space_nodel2 ;непусто - не удаляем
  383.         push de
  384.         ld a,l
  385.         and 0xfc
  386.         ld e,a
  387.         ld d,h
  388.         call delmem
  389.         pop de
  390.  
  391. ;удалять пустое поддерево, пока в узле выше вторая ссылка NULL
  392.         macro WRITETOPOI_SPACE_DEL nodeladdr
  393.         pop hl ;адрес указателя на узел уровня N
  394.         ld (hl),a
  395.         inc l
  396.         ld (hl),a
  397.         ld a,l
  398.         xor 2
  399.         ld l,a ;его брат
  400.         ld a,(hl)
  401.         dec l
  402.         or (hl)
  403.         jp nz,nodeladdr
  404.         push de
  405.         ld a,l
  406.         and 0xfc
  407.         ld e,a
  408.         ld d,h
  409.         call delmem
  410.         pop de
  411.         endm
  412.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel3 ;удалили узел из 4 байт
  413.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel4 ;удалили узел из 8 байт
  414.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel5 ;удалили узел из 16 байт
  415.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel6 ;удалили узел из 32 байт
  416.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel7 ;удалили узел из 64 байт
  417.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel8 ;удалили узел из 128 байт
  418.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel9 ;удалили узел из 256 байт
  419.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel10 ;удалили узел из 512 байт
  420.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel11 ;удалили узел из 1024 байт
  421.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel12 ;удалили узел из 2048 байт
  422.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel13 ;удалили узел из 4096 байт
  423.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel14 ;удалили узел из 8192 байт
  424.         WRITETOPOI_SPACE_DEL writetopoi_space_nodel15 ;удалили узел из 16384 байт
  425.         pop hl ;адрес указателя на узел уровня 15 в корне
  426.         ld (hl),a
  427.         inc l
  428.         ld (hl),a ;удалили узел из 32768 байт
  429.         ret
  430.  
  431. ;снять со стека все уровни
  432. writetopoi_space_nodel2
  433.         pop hl
  434. writetopoi_space_nodel3
  435.         pop hl
  436. writetopoi_space_nodel4
  437.         pop hl
  438. writetopoi_space_nodel5
  439.         pop hl
  440. writetopoi_space_nodel6
  441.         pop hl
  442. writetopoi_space_nodel7
  443.         pop hl
  444. writetopoi_space_nodel8
  445.         pop hl
  446. writetopoi_space_nodel9
  447.         pop hl
  448. writetopoi_space_nodel10
  449.         pop hl
  450. writetopoi_space_nodel11
  451.         pop hl
  452. writetopoi_space_nodel12
  453.         pop hl
  454. writetopoi_space_nodel13
  455.         pop hl
  456. writetopoi_space_nodel14
  457.         pop hl
  458. writetopoi_space_nodel15
  459.         pop hl
  460.         ret
  461.  
  462. ;найти ближайший непустой байт на месте или слева (для ордера)
  463. findleft
  464. ;hl=track root (4 bytes: left poi, right poi)
  465. ;de=index
  466. ;out: de=nonempty index (or 0), a=data
  467. ;если на месте непустой байт, то выходим
  468. ;иначе (мы на пустом поддереве):
  469. ;если мы на правом поддереве, то проверить левое, иначе подняться выше (если мы уже на корне, вернуть 0)
  470.         BITINC_D 7
  471. findleft_findleft15 ;мы в нужном месте узла из 65536 байт ;найти de
  472.         push hl
  473.         HLFROMHL
  474.         jp z,findleft_noleft14 ;мы в пустом узле из 32768 байт, искать левее или выйти (а не выше)
  475.         BITINC_D 6
  476. findleft_findleft14 ;мы в нужном месте узла из 32768 байт ;найти de
  477.         push hl
  478.         HLFROMHL
  479.         jp z,findleft_noleft13 ;мы в пустом узле из 16384 байт, искать левее или выше
  480.         BITINC_D 5
  481. findleft_findleft13 ;мы в нужном месте узла из 16384 байт ;найти de
  482.         push hl
  483.         HLFROMHL
  484.         jp z,findleft_noleft12 ;мы в пустом узле из 8192 байт, искать левее или выше
  485.         BITINC_D 4
  486. findleft_findleft12 ;мы в нужном месте узла из 8192 байт ;найти de
  487.         push hl
  488.         HLFROMHL
  489.         jp z,findleft_noleft11 ;мы в пустом узле из 4096 байт, искать левее или выше
  490.         BITINC_D 3
  491. findleft_findleft11 ;мы в нужном месте узла из 4096 байт ;найти de
  492.         push hl
  493.         HLFROMHL
  494.         jp z,findleft_noleft10 ;мы в пустом узле из 2048 байт, искать левее или выше
  495.         BITINC_D 2
  496. findleft_findleft10 ;мы в нужном месте узла из 2048 байт ;найти de
  497.         push hl
  498.         HLFROMHL
  499.         jp z,findleft_noleft9 ;мы в пустом узле из 1024 байт, искать левее или выше
  500.         BITINC_D 1
  501. findleft_findleft9 ;мы в нужном месте узла из 1024 байт ;найти de
  502.         push hl
  503.         HLFROMHL
  504.         jp z,findleft_noleft8 ;мы в пустом узле из 512 байт, искать левее или выше
  505.         BITINC_D 0
  506. findleft_findleft8 ;мы в нужном месте узла из 512 байт ;найти de
  507.         push hl
  508.         HLFROMHL
  509.         jp z,findleft_noleft7 ;мы в пустом узле из 256 байт, искать левее или выше
  510.         BITINC_E 7
  511. findleft_findleft7 ;мы в нужном месте узла из 256 байт ;найти de
  512.         push hl
  513.         HLFROMHL
  514.         jp z,findleft_noleft6 ;мы в пустом узле из 128 байт, искать левее или выше
  515.         BITINC_E 6
  516. findleft_findleft6 ;мы в нужном месте узла из 128 байт ;найти de
  517.         push hl
  518.         HLFROMHL
  519.         jp z,findleft_noleft5 ;мы в пустом узле из 128 байт, искать левее или выше
  520.         BITINC_E 5
  521. findleft_findleft5 ;мы в нужном месте узла из 64 байт ;найти de
  522.         push hl
  523.         HLFROMHL
  524.         jp z,findleft_noleft4 ;мы в пустом узле из 128 байт, искать левее или выше
  525.         BITINC_E 4
  526. findleft_findleft4 ;мы в нужном месте узла из 32 байт ;найти de
  527.         push hl
  528.         HLFROMHL
  529.         jr z,findleft_noleft3 ;мы в пустом узле из 16 байт, искать левее или выше
  530.         BITINC_E 3
  531. findleft_findleft3 ;мы в нужном месте узла из 16 байт ;найти de
  532.         push hl
  533.         HLFROMHL
  534.         jr z,findleft_noleft2 ;мы в пустом узле из 8 байт, искать левее или выше
  535.         BITINC_E 2
  536. findleft_findleft2 ;мы в нужном месте узла из 8 байт ;найти de
  537.         push hl
  538.         HLFROMHL
  539.         jr z,findleft_noleft1 ;мы в пустом узле из 4 байт, искать левее или выше
  540. ;мы в узле из 4 байт ;найти de
  541.         ld a,e
  542.         rra
  543.         jr nc,$+3
  544.          inc l
  545.         rra
  546.         jr nc,$+4
  547.          inc l
  548.          inc l
  549. ;мы в нужном месте узла из 4 байт
  550.         ld a,(hl)
  551.         or a
  552.         jp nz,findleft_ret2 ;return de, a
  553.         bit 0,e
  554.         jr z,findleft_noleft0
  555. ;мы в правой половине узла из 2 байт
  556.         dec e ;res 0,e
  557.         dec l
  558.         or (hl)
  559.         jp nz,findleft_ret2 ;return de, a
  560. findleft_noleft0 ;мы уже в левой половине узла из 2 байт ;подняться выше
  561.         bit 1,e
  562.         jr z,findleft_noleft1
  563. ;мы в правой половине узла из 4 байт
  564.         dec e
  565.         dec l
  566.         or (hl)
  567.         jp nz,findleft_ret2 ;return de, a
  568.         dec e
  569.         dec l
  570.         or (hl)
  571.         jp nz,findleft_ret2 ;return de, a
  572.  
  573. ;на месте не найдено - поднимаемся и ищем левее и выше
  574.  
  575.         macro FINDLEFTDECE addr,nbit
  576. ;мы в правой половине узла из N байт
  577.         dec e
  578.         dec l
  579.         ld a,(hl)
  580.         dec l
  581.         or (hl)
  582.         jp nz,addr ;поиск de в узле из N байт (левой половине)
  583.         endm
  584.         macro FINDLEFTDECDE addr,nbit
  585. ;мы в правой половине узла из N байт
  586.         dec de
  587.         dec l
  588.         ld a,(hl)
  589.         dec l
  590.         or (hl)
  591.         jp nz,addr ;поиск de в узле из N байт (левой половине)
  592.         endm
  593.  
  594. findleft_noleft1 ;мы уже в левой половине узла из 4 байт ;подняться выше
  595.          ld a,e
  596.          and 0xfc
  597.          ld e,a
  598.         pop hl ;узел из 8 байт ;адрес указателя на пустой узел из 4 байт ;искать левее или выше
  599.         and 4 ;bit 2,e
  600.         jr z,findleft_noleft2
  601.         FINDLEFTDECE findleft_findleft2,2 ;мы в правой половине узла из 8 байт ;поиск de в левой половине, если она есть
  602. findleft_noleft2 ;мы уже в левой половине узла из 8 байт ;подняться выше
  603.          ld a,e
  604.          and 0xf8
  605.          ld e,a
  606.         pop hl ;узел из 16 байт ;адрес указателя на пустой узел из 8 байт ;искать левее или выше
  607.         and 8 ;bit 3,e
  608.         jr z,findleft_noleft3
  609.         FINDLEFTDECE findleft_findleft3,3 ;мы в правой половине узла из 16 байт ;поиск de в левой половине, если она есть
  610. findleft_noleft3 ;мы уже в левой половине узла из 16 байт ;подняться выше
  611.          ld a,e
  612.          and 0xf0
  613.          ld e,a
  614.         pop hl ;узел из 32 байт ;адрес указателя на пустой узел из 16 байт ;искать левее или выше
  615.         and 0x10 ;bit 4,e
  616.         jr z,findleft_noleft4
  617.         FINDLEFTDECE findleft_findleft4,4 ;мы в правой половине узла из 32 байт ;поиск de в левой половине, если она есть
  618. findleft_noleft4 ;мы уже в левой половине узла из 32 байт ;подняться выше
  619.          ld a,e
  620.          and 0xe0
  621.          ld e,a
  622.         pop hl ;узел из 64 байт ;адрес указателя на пустой узел из 32 байт ;искать левее или выше
  623.         and 0x20 ;bit 5,e
  624.         jr z,findleft_noleft5
  625.         FINDLEFTDECE findleft_findleft5,5 ;мы в правой половине узла из 64 байт ;поиск de в левой половине, если она есть
  626. findleft_noleft5 ;мы уже в левой половине узла из 64 байт ;подняться выше
  627.          ld a,e
  628.          and 0xc0
  629.          ld e,a
  630.         pop hl ;узел из 128 байт ;адрес указателя на пустой узел из 64 байт ;искать левее или выше
  631.         and 0x40 ;bit 6,e
  632.         jr z,findleft_noleft6
  633.         FINDLEFTDECE findleft_findleft6,6 ;мы в правой половине узла из 128 байт ;поиск de в левой половине, если она есть
  634. findleft_noleft6 ;мы уже в левой половине узла из 128 байт ;подняться выше
  635.          ld a,e
  636.          and 0x80
  637.          ld e,a
  638.         pop hl ;узел из 256 байт ;адрес указателя на пустой узел из 128 байт ;искать левее или выше
  639.         ;bit 7,e
  640.         jr z,findleft_noleft7
  641.         FINDLEFTDECE findleft_findleft7,7 ;мы в правой половине узла из 256 байт ;поиск de в левой половине, если она есть
  642. findleft_noleft7 ;мы уже в левой половине узла из 256 байт ;подняться выше
  643.          ld e,a;0
  644.         pop hl ;узел из 512 байт ;адрес указателя на пустой узел из 256 байт ;искать левее или выше
  645.         bit 0,d
  646.         jr z,findleft_noleft8
  647.         FINDLEFTDECDE findleft_findleft8,0 ;мы в правой половине узла из 512 байт ;поиск de в левой половине, если она есть
  648. findleft_noleft8 ;мы уже в левой половине узла из 512 байт ;подняться выше
  649.          ld e,a;0
  650.          res 0,d
  651.         pop hl ;узел из 1024 байт ;адрес указателя на пустой узел из 512 байт ;искать левее или выше
  652.         bit 1,d
  653.         jr z,findleft_noleft9
  654.         FINDLEFTDECDE findleft_findleft9,1 ;мы в правой половине узла из 1024 байт ;поиск de в левой половине, если она есть
  655. findleft_noleft9 ;мы уже в левой половине узла из 1024 байт ;подняться выше
  656.          ld e,a;0
  657.          ld a,d
  658.          and 0xfc
  659.          ld d,a
  660.         pop hl ;узел из 2048 байт ;адрес указателя на пустой узел из 1024 байт ;искать левее или выше
  661.         and 4 ;bit 2,d
  662.         jr z,findleft_noleft10
  663.         FINDLEFTDECDE findleft_findleft10,2 ;мы в правой половине узла из 2048 байт ;поиск de в левой половине, если она есть
  664. findleft_noleft10 ;мы уже в левой половине узла из 2048 байт ;подняться выше
  665.          ld e,a;0
  666.          ld a,d
  667.          and 0xf8
  668.          ld d,a
  669.         pop hl ;узел из 4096 байт ;адрес указателя на пустой узел из 2048 байт ;искать левее или выше
  670.         and 8 ;bit 3,d
  671.         jr z,findleft_noleft11
  672.         FINDLEFTDECDE findleft_findleft11,3 ;мы в правой половине узла из 4096 байт ;поиск de в левой половине, если она есть
  673. findleft_noleft11 ;мы уже в левой половине узла из 4096 байт ;подняться выше
  674.          ld e,a;0
  675.          ld a,d
  676.          and 0xf0
  677.          ld d,a
  678.         pop hl ;узел из 8192 байт ;адрес указателя на пустой узел из 4096 байт ;искать левее или выше
  679.         and 0x10 ;bit 4,d
  680.         jr z,findleft_noleft12
  681.         FINDLEFTDECDE findleft_findleft12,4 ;мы в правой половине узла из 8192 байт ;поиск de в левой половине, если она есть
  682. findleft_noleft12 ;мы уже в левой половине узла из 8192 байт ;подняться выше
  683.          ld e,a;0
  684.          ld a,d
  685.          and 0xe0
  686.          ld d,a
  687.         pop hl ;узел из 16384 байт ;адрес указателя на пустой узел из 8192 байт ;искать левее или выше
  688.         and 0x20 ;bit 5,d
  689.         jr z,findleft_noleft13
  690.         FINDLEFTDECDE findleft_findleft13,5 ;мы в правой половине узла из 16384 байт ;поиск de в левой половине, если она есть
  691. findleft_noleft13 ;мы уже в левой половине узла из 16384 байт ;подняться выше
  692.          ld e,a;0
  693.          ld a,d
  694.          and 0xc0
  695.          ld d,a
  696.         pop hl ;узел из 32768 байт ;адрес указателя на пустой узел из 16384 байт ;искать левее или выше
  697.         and 0x40 ;bit 6,d
  698.         jr z,findleft_noleft14
  699.         FINDLEFTDECDE findleft_findleft14,6 ;мы в правой половине узла из 32768 байт ;поиск de в левой половине, если она есть
  700. findleft_noleft14 ;мы уже в левой половине узла из 32768 байт ;подняться выше
  701.          ;ld e,a;0
  702.          ;ld a,d
  703.          ;and 0x80
  704.          ;ld d,a
  705.         pop hl ;узел из 65536 байт ;адрес указателя на пустой узел из 32768 байт ;искать левее или выйти (а не выше)
  706.         bit 7,d
  707.         jr z,findleft_0 ;ret z ;дальше некуда левее, de=0, a=0
  708. ;мы в правой половине узла из 65536 байт
  709.         ld de,0x7fff;dec de
  710.         dec l
  711.         ld a,(hl)
  712.         dec l
  713.         or (hl)
  714.         jp nz,findleft_findleft15 ;поиск de в узле из 65536 байт (левой половине)
  715. findleft_0
  716.         ld d,a
  717.         ld e,a
  718.         ret ;дальше некуда выше, de=0, a=0
  719.  
  720. findleft_ret2
  721.         ;pop hl ;адрес указателя на узел из 4 байт
  722.         ;pop hl ;адрес указателя на узел из 8 байт
  723.         ;pop hl ;адрес указателя на узел из 16 байт
  724.         ;pop hl ;адрес указателя на узел из 32 байт
  725.         ;pop hl ;адрес указателя на узел из 64 байт
  726.         ;pop hl ;адрес указателя на узел из 128 байт
  727.         ;pop hl ;адрес указателя на узел из 256 байт
  728.         ;pop hl ;адрес указателя на узел из 512 байт
  729.         ;pop hl ;адрес указателя на узел из 1024 байт
  730.         ;pop hl ;адрес указателя на узел из 2048 байт
  731.         ;pop hl ;адрес указателя на узел из 4096 байт
  732.         ;pop hl ;адрес указателя на узел из 8192 байт
  733.         ;pop hl ;адрес указателя на узел из 16384 байт
  734.         ;pop hl ;адрес указателя на узел из 32768 байт
  735.         ld hl,14*2
  736.         add hl,sp
  737.         ld sp,hl
  738.         ret
  739.  
  740. ;найти ближайший непустой байт на месте или справа (для громкости и т.п.)
  741. findright
  742. ;hl=track root (4 bytes: left poi, right poi)
  743. ;de=index
  744. ;out: de=nonempty index (or 0xffff), a=data
  745. ;если на месте непустой байт, то выходим
  746. ;иначе (мы на пустом поддереве):
  747. ;если мы на левом поддереве, то проверить правое, иначе подняться выше (если мы уже на корне, вернуть 0xffff)
  748.         BITINC_D 7
  749. findright_findright15 ;мы в нужном месте узла из 65536 байт ;найти de
  750.         push hl
  751.         HLFROMHL
  752.         jp z,findright_noright14 ;мы в пустом узле из 32768 байт, искать правее или выйти (а не выше)
  753.         BITINC_D 6
  754. findright_findright14 ;мы в нужном месте узла из 32768 байт ;найти de
  755.         push hl
  756.         HLFROMHL
  757.         jp z,findright_noright13 ;мы в пустом узле из 16384 байт, искать правее или выше
  758.         BITINC_D 5
  759. findright_findright13 ;мы в нужном месте узла из 16384 байт ;найти de
  760.         push hl
  761.         HLFROMHL
  762.         jp z,findright_noright12 ;мы в пустом узле из 8192 байт, искать правее или выше
  763.         BITINC_D 4
  764. findright_findright12 ;мы в нужном месте узла из 8192 байт ;найти de
  765.         push hl
  766.         HLFROMHL
  767.         jp z,findright_noright11 ;мы в пустом узле из 4096 байт, искать правее или выше
  768.         BITINC_D 3
  769. findright_findright11 ;мы в нужном месте узла из 4096 байт ;найти de
  770.         push hl
  771.         HLFROMHL
  772.         jp z,findright_noright10 ;мы в пустом узле из 2048 байт, искать правее или выше
  773.         BITINC_D 2
  774. findright_findright10 ;мы в нужном месте узла из 2048 байт ;найти de
  775.         push hl
  776.         HLFROMHL
  777.         jp z,findright_noright9 ;мы в пустом узле из 1024 байт, искать правее или выше
  778.         BITINC_D 1
  779. findright_findright9 ;мы в нужном месте узла из 1024 байт ;найти de
  780.         push hl
  781.         HLFROMHL
  782.         jp z,findright_noright8 ;мы в пустом узле из 512 байт, искать правее или выше
  783.         BITINC_D 0
  784. findright_findright8 ;мы в нужном месте узла из 512 байт ;найти de
  785.         push hl
  786.         HLFROMHL
  787.         jp z,findright_noright7 ;мы в пустом узле из 256 байт, искать правее или выше
  788.         BITINC_E 7
  789. findright_findright7 ;мы в нужном месте узла из 256 байт ;найти de
  790.         push hl
  791.         HLFROMHL
  792.         jp z,findright_noright6 ;мы в пустом узле из 128 байт, искать правее или выше
  793.         BITINC_E 6
  794. findright_findright6 ;мы в нужном месте узла из 128 байт ;найти de
  795.         push hl
  796.         HLFROMHL
  797.         jp z,findright_noright5 ;мы в пустом узле из 128 байт, искать правее или выше
  798.         BITINC_E 5
  799. findright_findright5 ;мы в нужном месте узла из 64 байт ;найти de
  800.         push hl
  801.         HLFROMHL
  802.         jp z,findright_noright4 ;мы в пустом узле из 128 байт, искать правее или выше
  803.         BITINC_E 4
  804. findright_findright4 ;мы в нужном месте узла из 32 байт ;найти de
  805.         push hl
  806.         HLFROMHL
  807.         jr z,findright_noright3 ;мы в пустом узле из 16 байт, искать правее или выше
  808.         BITINC_E 3
  809. findright_findright3 ;мы в нужном месте узла из 16 байт ;найти de
  810.         push hl
  811.         HLFROMHL
  812.         jr z,findright_noright2 ;мы в пустом узле из 8 байт, искать правее или выше
  813.         BITINC_E 2
  814. findright_findright2 ;мы в нужном месте узла из 8 байт ;найти de
  815.         push hl
  816.         HLFROMHL
  817.         jr z,findright_noright1 ;мы в пустом узле из 4 байт, искать правее или выше
  818. ;мы в узле из 4 байт ;найти de
  819.         ld a,e
  820.         rra
  821.         jr nc,$+3
  822.          inc l
  823.         rra
  824.         jr nc,$+4
  825.          inc l
  826.          inc l
  827. ;мы в нужном месте узла из 4 байт
  828.         ld a,(hl)
  829.         or a
  830.         jp nz,findright_ret2 ;return de, a
  831.         bit 0,e
  832.         jr nz,findright_noright0
  833. ;мы в левой половине узла из 2 байт
  834.         inc e ;set 0,e
  835.         inc l
  836.         or (hl)
  837.         jp nz,findright_ret2 ;return de, a
  838. findright_noright0 ;мы уже в правой половине узла из 2 байт ;подняться выше
  839.         bit 1,e
  840.         jr nz,findright_noright1
  841. ;мы в левой половине узла из 4 байт
  842.         inc e
  843.         inc l
  844.         or (hl)
  845.         jp nz,findright_ret2 ;return de, a
  846.         inc e
  847.         inc l
  848.         or (hl)
  849.         jp nz,findright_ret2 ;return de, a
  850.  
  851. ;на месте не найдено - поднимаемся и ищем правее и выше
  852.  
  853.         macro FINDRIGHTINCE addr,nbit
  854. ;мы в левой половине узла из N байт
  855.         inc e
  856.         inc l
  857.         inc l
  858.         inc l
  859.         ld a,(hl)
  860.         dec l
  861.         or (hl)
  862.         jp nz,addr ;поиск de в узле из N байт (правой половине)
  863.         endm
  864.         macro FINDRIGHTINCDE addr,nbit
  865. ;мы в левой половине узла из N байт
  866.         inc de
  867.         inc l
  868.         inc l
  869.         inc l
  870.         ld a,(hl)
  871.         dec l
  872.         or (hl)
  873.         jp nz,addr ;поиск de в узле из N байт (правой половине)
  874.         endm
  875.  
  876. findright_noright1 ;мы уже в правой половине узла из 4 байт ;подняться выше
  877.          ld a,e
  878.          or 0x03
  879.          ld e,a
  880.         pop hl ;узел из 8 байт ;адрес указателя на пустой узел из 4 байт ;искать правее или выше
  881.         and 4 ;bit 2,e
  882.         jr nz,findright_noright2
  883.         FINDRIGHTINCE findright_findright2,2 ;мы в левой половине узла из 8 байт ;поиск de в правой половине, если она есть
  884. findright_noright2 ;мы уже в правой половине узла из 8 байт ;подняться выше
  885.          ld a,e
  886.          or 0x07
  887.          ld e,a
  888.         pop hl ;узел из 16 байт ;адрес указателя на пустой узел из 8 байт ;искать правее или выше
  889.         and 8 ;bit 3,e
  890.         jr nz,findright_noright3
  891.         FINDRIGHTINCE findright_findright3,3 ;мы в левой половине узла из 16 байт ;поиск de в правой половине, если она есть
  892. findright_noright3 ;мы уже в правой половине узла из 16 байт ;подняться выше
  893.          ld a,e
  894.          or 0x0f
  895.          ld e,a
  896.         pop hl ;узел из 32 байт ;адрес указателя на пустой узел из 16 байт ;искать правее или выше
  897.         and 0x10 ;bit 4,e
  898.         jr nz,findright_noright4
  899.         FINDRIGHTINCE findright_findright4,4 ;мы в левой половине узла из 32 байт ;поиск de в правой половине, если она есть
  900. findright_noright4 ;мы уже в правой половине узла из 32 байт ;подняться выше
  901.          ld a,e
  902.          or 0x1f
  903.          ld e,a
  904.         pop hl ;узел из 64 байт ;адрес указателя на пустой узел из 32 байт ;искать правее или выше
  905.         and 0x20 ;bit 5,e
  906.         jr nz,findright_noright5
  907.         FINDRIGHTINCE findright_findright5,5 ;мы в левой половине узла из 64 байт ;поиск de в правой половине, если она есть
  908. findright_noright5 ;мы уже в правой половине узла из 64 байт ;подняться выше
  909.          ld a,e
  910.          or 0x3f
  911.          ld e,a
  912.         pop hl ;узел из 128 байт ;адрес указателя на пустой узел из 64 байт ;искать правее или выше
  913.         and 0x40 ;bit 6,e
  914.         jr nz,findright_noright6
  915.         FINDRIGHTINCE findright_findright6,6 ;мы в левой половине узла из 128 байт ;поиск de в правой половине, если она есть
  916. findright_noright6 ;мы уже в правой половине узла из 128 байт ;подняться выше
  917.          ld a,e
  918.          or 0x7f
  919.          ld e,a
  920.         pop hl ;узел из 256 байт ;адрес указателя на пустой узел из 128 байт ;искать правее или выше
  921.         ;bit 7,e
  922.         jp m,findright_noright7
  923.         FINDRIGHTINCE findright_findright7,7 ;мы в левой половине узла из 256 байт ;поиск de в правой половине, если она есть
  924. findright_noright7 ;мы уже в правой половине узла из 256 байт ;подняться выше
  925.          ld e,0xff
  926.         pop hl ;узел из 512 байт ;адрес указателя на пустой узел из 256 байт ;искать правее или выше
  927.         bit 0,d
  928.         jr nz,findright_noright8
  929.         FINDRIGHTINCDE findright_findright8,0 ;мы в левой половине узла из 512 байт ;поиск de в правой половине, если она есть
  930. findright_noright8 ;мы уже в правой половине узла из 512 байт ;подняться выше
  931.          ld e,0xff
  932.          set 0,d
  933.         pop hl ;узел из 1024 байт ;адрес указателя на пустой узел из 512 байт ;искать правее или выше
  934.         bit 1,d
  935.         jr nz,findright_noright9
  936.         FINDRIGHTINCDE findright_findright9,1 ;мы в левой половине узла из 1024 байт ;поиск de в правой половине, если она есть
  937. findright_noright9 ;мы уже в правой половине узла из 1024 байт ;подняться выше
  938.          ld e,0xff
  939.          ld a,d
  940.          or 0x03
  941.          ld d,a
  942.         pop hl ;узел из 2048 байт ;адрес указателя на пустой узел из 1024 байт ;искать правее или выше
  943.         and 4 ;bit 2,d
  944.         jr nz,findright_noright10
  945.         FINDRIGHTINCDE findright_findright10,2 ;мы в левой половине узла из 2048 байт ;поиск de в правой половине, если она есть
  946. findright_noright10 ;мы уже в правой половине узла из 2048 байт ;подняться выше
  947.          ld e,0xff
  948.          ld a,d
  949.          or 0x07
  950.          ld d,a
  951.         pop hl ;узел из 4096 байт ;адрес указателя на пустой узел из 2048 байт ;искать правее или выше
  952.         and 8 ;bit 3,d
  953.         jr nz,findright_noright11
  954.         FINDRIGHTINCDE findright_findright11,3 ;мы в левой половине узла из 4096 байт ;поиск de в правой половине, если она есть
  955. findright_noright11 ;мы уже в правой половине узла из 4096 байт ;подняться выше
  956.          ld e,0xff
  957.          ld a,d
  958.          or 0x0f
  959.          ld d,a
  960.         pop hl ;узел из 8192 байт ;адрес указателя на пустой узел из 4096 байт ;искать правее или выше
  961.         and 0x10 ;bit 4,d
  962.         jr nz,findright_noright12
  963.         FINDRIGHTINCDE findright_findright12,4 ;мы в левой половине узла из 8192 байт ;поиск de в правой половине, если она есть
  964. findright_noright12 ;мы уже в правой половине узла из 8192 байт ;подняться выше
  965.          ld e,0xff
  966.          ld a,d
  967.          or 0x1f
  968.          ld d,a
  969.         pop hl ;узел из 16384 байт ;адрес указателя на пустой узел из 8192 байт ;искать правее или выше
  970.         and 0x20 ;bit 5,d
  971.         jr nz,findright_noright13
  972.         FINDRIGHTINCDE findright_findright13,5 ;мы в левой половине узла из 16384 байт ;поиск de в правой половине, если она есть
  973. findright_noright13 ;мы уже в правой половине узла из 16384 байт ;подняться выше
  974.          ld e,0xff
  975.          ld a,d
  976.          or 0x3f
  977.          ld d,a
  978.         pop hl ;узел из 32768 байт ;адрес указателя на пустой узел из 16384 байт ;искать правее или выше
  979.         and 0x40 ;bit 6,d
  980.         jr nz,findright_noright14
  981.         FINDRIGHTINCDE findright_findright14,6 ;мы в левой половине узла из 32768 байт ;поиск de в правой половине, если она есть
  982. findright_noright14 ;мы уже в правой половине узла из 32768 байт ;подняться выше
  983.          ;ld e,0xff
  984.          ;ld a,d
  985.          ;or 0x7f
  986.          ;ld d,a
  987.         pop hl ;узел из 65536 байт ;адрес указателя на пустой узел из 32768 байт ;искать правее или выйти (а не выше)
  988.         bit 7,d
  989.         jr nz,findright_0 ;ret z ;дальше некуда правее, de=0xffff, a=0
  990. ;мы в правой половине узла из 65536 байт
  991.         ld de,0x8000;inc de
  992.         inc l
  993.         inc l
  994.         inc l
  995.         ld a,(hl)
  996.         dec l
  997.         or (hl)
  998.         jp nz,findright_findright15 ;поиск de в узле из 65536 байт (правой половине)
  999. findright_0
  1000.         ld de,0xffff
  1001.         ret ;дальше некуда выше, de=0xffff, a=0
  1002.  
  1003. findright_ret2
  1004.         ;pop hl ;адрес указателя на узел из 4 байт
  1005.         ;pop hl ;адрес указателя на узел из 8 байт
  1006.         ;pop hl ;адрес указателя на узел из 16 байт
  1007.         ;pop hl ;адрес указателя на узел из 32 байт
  1008.         ;pop hl ;адрес указателя на узел из 64 байт
  1009.         ;pop hl ;адрес указателя на узел из 128 байт
  1010.         ;pop hl ;адрес указателя на узел из 256 байт
  1011.         ;pop hl ;адрес указателя на узел из 512 байт
  1012.         ;pop hl ;адрес указателя на узел из 1024 байт
  1013.         ;pop hl ;адрес указателя на узел из 2048 байт
  1014.         ;pop hl ;адрес указателя на узел из 4096 байт
  1015.         ;pop hl ;адрес указателя на узел из 8192 байт
  1016.         ;pop hl ;адрес указателя на узел из 16384 байт
  1017.         ;pop hl ;адрес указателя на узел из 32768 байт
  1018.         ld hl,14*2
  1019.         add hl,sp
  1020.         ld sp,hl
  1021.         ret
  1022.  
  1023. newmem
  1024. ;взять первый элемент списка свободных
  1025. ;вернуть его в hl
  1026. ;сдвинуть указатель на первый элемент списка свободных (если NIL, то повиснуть)
  1027. ;out: hl=адрес 4 байт свободных
  1028. firstfree=$+1
  1029.         ld hl,freemem_start
  1030.         push hl
  1031.         inc l
  1032.         inc l
  1033.        if BIGENDIAN
  1034.         ld a,(hl)
  1035.         inc l
  1036.         ld l,(hl)
  1037.         ld h,a ;новый указатель на первый элемент списка свободных
  1038.          or l
  1039.          jr z,$ ;если NIL, то повиснуть (TODO заказать новый 256-байтный блок)
  1040.        else
  1041.         ld a,(hl)
  1042.         inc l
  1043.         ld h,(hl)
  1044.         ld l,a ;новый указатель на первый элемент списка свободных
  1045.          or h
  1046.          jr z,$ ;если NIL, то повиснуть (TODO заказать новый 256-байтный блок)
  1047.        endif
  1048.         ld (firstfree),hl
  1049. ;в value этого элемента записать NIL (чтобы был двусвязный список свободных - в будущем можно будет освобождать 256-байтные блоки)
  1050.          xor a
  1051.          ld (hl),a
  1052.          inc l
  1053.          ld (hl),a ;NIL
  1054.        if BIGENDIAN
  1055.         ld hl,FreeMem_value
  1056.         ld a,(hl)
  1057.         inc l
  1058.         ld l,(hl)
  1059.         ld h,a
  1060.        else
  1061.         ld hl,(FreeMem_value)
  1062.        endif
  1063.         dec hl
  1064.         dec hl
  1065.         dec hl
  1066.         dec hl
  1067.        if BIGENDIAN
  1068.         ld a,h
  1069.         ld h,l
  1070.         ld l,a
  1071.         ld (FreeMem_value),hl
  1072.        else
  1073.         ld (FreeMem_value),hl
  1074.        endif
  1075.         pop hl
  1076.         xor a
  1077.         ld (hl),a
  1078.         inc l
  1079.         ld (hl),a
  1080.         inc l
  1081.         ld (hl),a
  1082.         inc l
  1083.         ld (hl),a
  1084.         dec l
  1085.         dec l
  1086.         dec l
  1087.         ret
  1088.  
  1089. delmem
  1090. ;de=адрес 4 байт, которые освободить
  1091. ;добавить в список свободных (value бывшего первого элемента пусть указывает на него, а у него на NIL, чтобы был двусвязный список свободных - в будущем можно будет освобождать 256-байтные блоки)
  1092.         ld hl,(firstfree) ;TODO проверить, что это последний занятый в 256-байтном блоке и освободить блок
  1093.        if BIGENDIAN
  1094.          ld (hl),d
  1095.          inc l
  1096.          ld (hl),e ;value бывшего первого элемента
  1097.        else
  1098.          ld (hl),e
  1099.          inc l
  1100.          ld (hl),d ;value бывшего первого элемента
  1101.         endif
  1102.          dec l
  1103.         ex de,hl
  1104.         ld (firstfree),hl
  1105.          xor a
  1106.          ld (hl),a
  1107.         inc l
  1108.          ld (hl),a ;NIL
  1109.         inc l
  1110.        if BIGENDIAN
  1111.         ld (hl),d
  1112.         inc l
  1113.         ld (hl),e ;next = бывший первый элемент
  1114.        else
  1115.         ld (hl),e
  1116.         inc l
  1117.         ld (hl),d ;next = бывший первый элемент
  1118.        endif
  1119.        if BIGENDIAN
  1120.         ld hl,FreeMem_value
  1121.         ld a,(hl)
  1122.         inc l
  1123.         ld l,(hl)
  1124.         ld h,a
  1125.        else
  1126.         ld hl,(FreeMem_value)
  1127.        endif
  1128.         ld de,4
  1129.         add hl,de
  1130.        if BIGENDIAN
  1131.         ld a,h
  1132.         ld h,l
  1133.         ld l,a
  1134.         ld (FreeMem_value),hl
  1135.        else
  1136.         ld (FreeMem_value),hl
  1137.        endif
  1138.         ret
  1139.  
  1140. initmem
  1141. ;инит одного блока 32K
  1142. ;4-байтные блоки prev.next, у первого prev=0, у последнего next=0
  1143.         ld hl,freemem_start
  1144.         ld b,h
  1145.         ld c,l
  1146.         ld de,0
  1147. initmem0
  1148. ;de=prev
  1149.         inc bc
  1150.         inc bc
  1151.         inc bc
  1152.         inc bc
  1153. ;bc=next
  1154.         push hl
  1155.         ld (hl),e
  1156.         inc l
  1157.         ld (hl),d ;prev
  1158.         inc l
  1159.         ld (hl),c
  1160.         inc l
  1161.         ld (hl),b ;next
  1162.         inc hl
  1163.         pop de ;de=prev
  1164.         ld a,h
  1165.         or a
  1166.         jr nz,initmem0
  1167.         ld (0xfffe),hl ;у последнего next=0
  1168.  
  1169.         call newmem
  1170.         xor a
  1171.         ld (hl),a
  1172.         inc l
  1173.         ld (hl),a
  1174.         inc l
  1175.         ld (hl),a
  1176.         inc l
  1177.         ld (hl),a ;root
  1178.         ret
  1179.  
  1180. FreeMem_value
  1181.         dw 0-freemem_start;32768
  1182.