Subversion Repositories NedoOS

Rev

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

  1.  
  2. ;NVOLUMES=8
  3. MAXFILES=16;8
  4. vol_trdos=4 ;'A'..'D'
  5. vol_pipe=25 ;'Z'
  6.  
  7. TRDOSADD40=0x40
  8. PIPEADD80=0x80
  9.  
  10. MAXPIPES=8
  11. PIPEBUF_SZ=255
  12. PIPEDESC_SZ=PIPEBUF_SZ+1
  13.  
  14. ;предполагается, что юзер не имеет стек ниже 0x3b00, иначе он затрёт систему
  15.  
  16. ;FCB и имя можно передавать в любой области userspace
  17. ;DTA может быть в любой области userspace
  18. fatfs_org=0x4000
  19. ;CurrVol=0X4000+26
  20. ;CurrDir=CurrVol+1
  21.  
  22.         MACRO GETVOLUME
  23.         ;ld a,(CurrVol)
  24.         ;ld a,(iy+app.dir+DIR.ID)
  25.          ld a,(iy+app.vol)
  26.         ENDM
  27.         MACRO SETVOLUME
  28.         ;ld a,(CurrVol)
  29.         ;ld a,(iy+app.dir+DIR.ID)
  30.          ld (iy+app.vol),a
  31.         ENDM
  32.  
  33.         MACRO CHECKVOLUMETRDOS
  34.         GETVOLUME
  35.         cp vol_trdos
  36.         ENDM
  37.  
  38. BDOS_setpgtrdosfs
  39.         ld a,pgtrdosfs
  40.         jr sys_setpg4000
  41.         ;ld bc,memport4000
  42.         ;ld (sys_curpg4000),a
  43.         ;out (c),a
  44.         ;ret
  45.  
  46. BDOS_setpgfatfs
  47.         ld a,pgfatfs
  48. sys_setpg4000
  49.         ld bc,memport4000
  50.         ld (sys_curpg4000),a ;для sys_sysint
  51.         out (c),a
  52.         ret
  53.  
  54. blocksize=128 ;сколько байтов читать в CP/M операциях
  55.  
  56. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  57. BDOS_wiznetopen
  58.         BDOSSETPGW5300 ;портит bc
  59.         jp wiznet_open
  60.  
  61. BDOS_wiznetclose
  62.         BDOSSETPGW5300 ;портит bc
  63.         jp wiznet_close
  64.  
  65. BDOS_wiznetread
  66. ;de=pointer, hl=buffer size
  67. ;out: hl=size
  68.         call BDOS_preparedepage
  69.         call BDOS_setdepage
  70. ;DE = Pointer to physical data
  71.         BDOSSETPGW5300
  72.         jp wiznet_read
  73.  
  74. BDOS_wiznetwrite
  75. ;de=pointer, hl=size
  76.         call BDOS_preparedepage
  77.         call BDOS_setdepage
  78. ;DE = Pointer to physical data
  79.         BDOSSETPGW5300
  80.         jp wiznet_write
  81.  
  82. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  83.  
  84. BDOS_setmusic
  85. muzpid=$+1
  86.         ld a,0
  87.         or a
  88.         call z,killmuz
  89.         ex af,af'
  90.        ld (muzpg),a
  91.        ld (muzcall),hl
  92.        ld a,(iy+app.id)
  93.        ld (muzpid),a
  94. ;страницы для 8000, c000 берём из текущей юзерской карты памяти
  95.        ld a,(iy+app.mainpg)
  96.        call sys_setpg8000
  97.        ld a,(curpg32klow+0x8000)
  98.        ld (muzpg8000),a
  99.        ld a,(curpg32khigh+0x8000)
  100.        ld (muzpgc000),a
  101.        ret
  102.        
  103. killmuz
  104.        xor a
  105.        ld (muzpid),a
  106.        ld de,sys_reter
  107.        ld (muzcall),de
  108.        ld c,0xfd
  109.        ld de,0x0e00
  110. shutay0
  111.        dec d
  112.        ld b,0xff
  113.        out (c),d
  114.        ld b,0xbf
  115.        out (c),e
  116.        jr nz,shutay0
  117.        ret
  118.  
  119. BDOS_setmainpage
  120.        ;ld iy,(appaddr)
  121. ;e=page for 0x0000
  122.        ld (iy+app.mainpg),e
  123.        ret
  124.        
  125. BDOS_setborder
  126.        ;ld iy,(appaddr)
  127. ;e=border=0..15
  128.        ld (iy+app.border),e
  129.        ret
  130.        
  131. BDOS_setscreen
  132.        ;ld iy,(appaddr)
  133. ;e=screen=0..1
  134.        ld a,e
  135.        add a,a
  136.        add a,a
  137.        add a,a
  138.        ld d,a
  139.        or fd_user
  140.        ld (iy+app.screen),a
  141.        ;xor a ;success
  142.        ret;jr rest_exit
  143.  
  144. BDOS_getappmainpages
  145. ;e=id
  146. ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, a=error
  147.        call BDOS_findapp
  148.        jp nz,BDOS_fail
  149. BDOS_getmainpages
  150.        ;ld iy,(appaddr)
  151. ;out: dehl=номера страниц в 0000,4000,8000,c000, c=flags, b=id
  152. BDOS_getmainpages_iy
  153.        call setmainpg_c000
  154.        ld d,a
  155.        ld a,(curpg16k+0xc000)
  156.        ld e,a
  157.        ld a,(curpg32klow+0xc000)
  158.        ld hl,(curpg32khigh+0xc000)
  159.        ld h,a
  160.        ld c,(iy+app.flags)
  161.        ld b,(iy+app.id)
  162.        xor a
  163.        ret
  164.  
  165. BDOS_preparedepage
  166. ;de=userspace addr
  167. ;out: de>=0x8000, включены нужные страницы в 8000,c000
  168.        ;ld iy,(appaddr)
  169.        ld a,(iy+app.mainpg)
  170.        call sys_setpg8000
  171.        bit 7,d
  172.        jr nz,BDOS_preparedepage8000_c000
  173.        bit 6,d
  174.        jr nz,BDOS_preparedepage4000_8000
  175.        set 7,d
  176.         ld (depage8000),a
  177.        ld a,(curpg16k+0x8000)
  178.        ;ld bc,memportc000
  179.        ;out (c),a
  180.         ld (depagec000),a
  181.        ret
  182. BDOS_preparedepage4000_8000
  183.        ld a,d
  184.        add a,0x40
  185.        ld d,a
  186.        ld a,(curpg32klow+0x8000)
  187.        ;call sys_setpgc000
  188.         ld (depagec000),a
  189.        ld a,(curpg16k+0x8000)
  190.        ;call sys_setpg8000
  191.         ld (depage8000),a
  192.        ret
  193. BDOS_preparedepage8000_c000
  194.        ld a,(curpg32khigh+0x8000)
  195.        ;call sys_setpgc000
  196.         ld (depagec000),a
  197.        ld a,(curpg32klow+0x8000)
  198.        ;call sys_setpg8000
  199.         ld (depage8000),a
  200.        ret
  201.  
  202. BDOS_setdepage
  203. ;keep de,hl
  204. depagec000=$+1
  205.        ld a,0
  206.        call sys_setpgc000
  207. depage8000=$+1
  208.        ld a,0
  209. sys_setpg8000
  210.        ld (sys_curpg8000),a
  211.        ld bc,memport8000
  212.        out (c),a
  213.         ret
  214.  
  215. BDOS_setpal
  216.        call BDOS_preparedepage
  217.        call BDOS_setdepage
  218. ;de=палитра (выше 0xc000)
  219.        push iy
  220.        pop hl
  221.        ld bc,app.pal
  222.        add hl,bc
  223.        ex de,hl
  224.        ld bc,32
  225.        ldir
  226.        ;call setpalettechanged
  227.        ;xor a
  228.        ;ret
  229. setpalettechanged
  230.        ld a,55+128 ;"or a"
  231.        ld (palettechanged),a
  232.        ret
  233.        
  234. BDOS_scroll_prepare
  235.        ld a,l
  236.        srl a
  237.        ld (BDOS_scrollpagelinelayer_wid),a
  238.        ld b,h
  239.        dec b
  240. BDOS_countxy
  241. ;keeps bc
  242.        ld a,d ;y
  243.        sub -0x87&0xff ;0xe1c0*4=0x8700
  244.        rra
  245.        ld h,a
  246.         ld a,0;16
  247.        rra
  248.        sra h
  249.        rra
  250.        ld l,e ;x
  251.        srl l
  252.        jr c,$+4
  253.        res 5,h
  254.        add a,l
  255.        ld l,a
  256.        ret
  257.  
  258. BDOS_getxy
  259. ;out: de=yx ;GET CURSOR POSITION
  260.        ;ld hl,(pr_textmode_curaddr)
  261.        ld l,(iy+app.textcuraddr)
  262.        ld h,(iy+app.textcuraddr+1)
  263.        ld a,h
  264.        rla
  265.        rla
  266.        rla ;bit5
  267.        ld a,l
  268.        rla
  269.        and 0x7f
  270.        ld e,a ;x
  271.        add hl,hl
  272.        add hl,hl ;h=y*4 + const + n*0x80
  273.        ld a,h
  274.        sub 0x87 ;0xe1c0*4=0x8700
  275.        and 0x1f
  276.        ld d,a ;y
  277.        xor a ;success
  278.        ret
  279.  
  280. BDOS_countattraddr
  281.        BDOSSETPGSSCR
  282.        ;ld hl,(pr_textmode_curaddr)
  283.        ld l,(iy+app.textcuraddr)
  284.        ld h,(iy+app.textcuraddr+1)
  285.        ld a,h
  286.        xor 0x60 ;attr + 0x20
  287.        ld h,a
  288.         and 0x20
  289.        jr nz,$+3
  290.        inc l
  291.        ret
  292.        
  293. BDOS_prattr
  294. ;e=color byte
  295.         ld hl,(appaddr)
  296.         ld bc,(focusappaddr)
  297.         or a
  298.         sbc hl,bc
  299.         ret nz
  300.        call BDOS_countattraddr
  301.        ld (hl),e
  302.        ret
  303.  
  304. BDOS_getattr
  305. ;out: a=color byte
  306.        call BDOS_countattraddr
  307.        ld a,(hl)
  308.        ret
  309.  
  310. BDOS_setxy
  311. ;de=yx
  312.        call BDOS_countxy
  313. BDOS_settextcuraddr
  314.        ;ld (pr_textmode_curaddr),hl
  315.        ld (iy+app.textcuraddr),l
  316.        ld (iy+app.textcuraddr+1),h
  317.        xor a ;success
  318.        ret
  319.        
  320. BDOS_prchar_controlcode
  321.        cp 0x0a
  322.        jr z,BDOS_prchar_lf
  323.        cp 0x0d
  324.        jp nz,BDOS_prchar_nocontrolcode
  325.        ;jr z,BDOS_prchar_cr
  326. BDOS_prchar_cr
  327.        ld a,l
  328.        and 0xc0
  329.        ld l,a
  330.        res 5,h
  331.        jr BDOS_settextcuraddr
  332.        ;jp BDOS_prchar_q
  333.        
  334. BDOS_prchar_lf
  335.        ld a,l
  336.        add a,0x40
  337.        ld l,a
  338.        jr nc,BDOS_settextcuraddr ;BDOS_prchar_q ;ret nc
  339.        jr BDOS_prchar_lf_q
  340.  
  341. BDOS_prchar
  342. ;e=char
  343.        ld a,e
  344. BDOS_prchar_a
  345. ;портит только 0xc000+, но сама восстанавливает там pgkillable (для быстрого вызова через rst)
  346.         ld hl,(appaddr)
  347.         ld bc,(focusappaddr)
  348.         or a
  349.         sbc hl,bc
  350.         ret nz ;no focus - no print
  351.  
  352.         ld h,trecode/256
  353.         ld l,a
  354.         ld a,(hl)
  355. ;pr_textmode_curaddr=$+1
  356.        ;ld hl,0xc1c0
  357.        ld l,(iy+app.textcuraddr)
  358.        ld h,(iy+app.textcuraddr+1)
  359.        cp 0x0e
  360.        jr c,BDOS_prchar_controlcode
  361. BDOS_prchar_nocontrolcode
  362.         ;push hl
  363.         ;ld hl,(appaddr)
  364.         ;ld bc,(focusappaddr)
  365.         ;or a
  366.         ;sbc hl,bc
  367.         ;pop hl
  368.         ;jr nz,BDOS_prchar_skip
  369.        ;ld de,pgscr0_1*256+pgscr0_0
  370.        ;ld bc,memportc000
  371.        ;out (c),d ;text
  372.        ;ld (hl),a
  373.        ;out (c),e ;attr
  374.        ld e,a
  375.        ld a,pgscr0_1
  376.        call sys_setpgc000
  377.        ld (hl),e
  378.        ld a,pgscr0_0
  379.        call sys_setpgc000
  380. ;BDOS_prchar_skip        
  381.  
  382.        ;ld de,0x2000 + pgkillable
  383.        
  384.         ;push af
  385.  
  386.        ld a,h
  387.        xor 0x20;d;0x20 ;attr + 0x20
  388.        ld h,a
  389.        and 0x20;d;0x20
  390.        jr nz,$+3
  391.        inc l
  392.  
  393.         ;pop af
  394.         ;jr nz,BDOS_prchar_skipattr
  395. ;pr_textmode_curcolor=$+1
  396.        ;ld (hl),7
  397.        ld a,(iy+app.curcolor)
  398.        ld (hl),a
  399.        
  400.        ;set 6,h ;attr -> next char
  401.  
  402.        ;;ld e,pgkillable
  403.        ;out (c),e ;pgkillable
  404.        ld a,pgkillable
  405.        call sys_setpgc000
  406. ;BDOS_prchar_skipattr
  407.  
  408.        ld a,l
  409.        and 0x3f
  410.        cp 80/2
  411.        ;ld (pr_textmode_curaddr),hl
  412.        ld (iy+app.textcuraddr),l
  413.        ld (iy+app.textcuraddr+1),h
  414.        ret nz ;jr nz,BDOS_prchar_q ;ret nz ;нет переноса строки
  415.        ld a,l
  416.        and 0xc0
  417.        add a,0x40
  418.        ld l,a
  419.        jr nc,BDOS_settextcuraddr ;BDOS_prchar_q ;ret nc
  420. BDOS_prchar_lf_q
  421.        inc h
  422.        bit 3,h
  423.        jr z,BDOS_settextcuraddr ;BDOS_prchar_q ;нет выхода за последнюю строку
  424. BDOS_scrolllock0
  425.        ld a,0xfe
  426.        in a,(0xfe)
  427.        rra ;Caps Shift
  428.        jr nc,BDOS_scrolllock0
  429.        ld hl,(appaddr)
  430.        ld de,(focusappaddr)
  431.        or a
  432.        sbc hl,de
  433.        jr nz,BDOS_prchar_skipscroll
  434. ;scroll+clear bottom line
  435.        call BDOS_scrollpage ;attr
  436.        ld a,pgscr0_1 ;text
  437.        ;ld bc,memportc000
  438.        ;out (c),a
  439.        call sys_setpgc000
  440.        call BDOS_cllastline
  441.        ld a,pgscr0_0 ;attr
  442.        ;ld bc,memportc000
  443.        ;out (c),a
  444.        call sys_setpgc000
  445.        call BDOS_cllastline
  446.        ld a,pgkillable
  447.        ;ld bc,memportc000
  448.        ;out (c),a
  449.        call sys_setpgc000
  450. BDOS_prchar_skipscroll
  451.        ld hl,0xc7c0
  452. BDOS_prchar_q
  453.        jp BDOS_settextcuraddr
  454.        ;;ld (pr_textmode_curaddr),hl
  455.        ;ld (iy+app.textcuraddr),l
  456.        ;ld (iy+app.textcuraddr+1),h
  457.        ;ret
  458.        
  459. BDOS_scrollpage
  460.        ld a,40
  461.        ld (BDOS_scrollpagelinelayer_wid),a
  462.        ld hl,0xc1c0
  463.        ld b,24
  464. BDOS_scrollpage0
  465.        push bc
  466.        ld d,h
  467.        ld e,l
  468.        ld bc,64
  469.        add hl,bc
  470.        call BDOS_scrollpageline
  471.        pop bc
  472.        djnz BDOS_scrollpage0
  473.        ret
  474. BDOS_scrollpageline
  475.        ld a,pgscr0_1 ;text
  476.        or a
  477.        call BDOS_scrollpagelinelayers ;text
  478.        ld a,pgscr0_0 ;attr
  479.        scf
  480. BDOS_scrollpagelinelayers
  481.        ;ld bc,memportc000
  482.        ;out (c),a
  483.        call sys_setpgc000
  484.        push af
  485.        push de
  486.        push hl
  487.        set 5,h
  488.        set 5,d
  489.        or a
  490.        call BDOS_scrollpagelinelayer
  491.        pop hl
  492.        pop de
  493.        pop af
  494. BDOS_scrollpagelinelayer
  495.        push de
  496.        push hl
  497.        jr nc,$+4
  498.        inc hl
  499.        inc de
  500. BDOS_scrollpagelinelayer_wid=$+1
  501.        ld bc,39;40
  502.        ldir
  503.        pop hl
  504.        pop de
  505.        ret
  506.  
  507. BDOS_scrolldown
  508. ;de=topyx, hl=hgt,wid
  509. ;x, wid even
  510.         ;push hl
  511.         ;ld hl,(appaddr)
  512.         ;ld bc,(focusappaddr)
  513.         ;or a
  514.         ;sbc hl,bc
  515.         ;pop hl
  516.         ;ret nz
  517.        ld a,d
  518.        add a,h
  519.        dec a
  520.        ld d,a ;ybottom
  521.        call BDOS_scroll_prepare
  522. BDOS_scrolldown0
  523.        push bc
  524.        ld d,h
  525.        ld e,l
  526.        ld bc,-64
  527.        add hl,bc
  528.        call BDOS_scrollpageline
  529.        pop bc
  530.        djnz BDOS_scrolldown0
  531.        ret
  532.  
  533. BDOS_scrollup
  534. ;de=topyx, hl=hgt,wid
  535. ;x, wid even
  536.         ;push hl
  537.         ;ld hl,(appaddr)
  538.         ;ld bc,(focusappaddr)
  539.         ;or a
  540.         ;sbc hl,bc
  541.         ;pop hl
  542.         ;ret nz
  543.        call BDOS_scroll_prepare
  544.        jp BDOS_scrollpage0
  545.        
  546. BDOS_cllastline
  547.        ld hl,0xc7c0
  548.        call BDOS_scrollpage_clline
  549.        ;ld de,0xc7c1
  550.        ;ld bc,64-1
  551.        ;ld (hl),b
  552.        ;ldir
  553.        ld hl,0xe7c0
  554. BDOS_scrollpage_clline        
  555.        ld d,h
  556.        ld e,l
  557.        inc e
  558.        ld bc,64-1
  559.        ld (hl),b
  560.        ldir ;clear bottom line
  561.        ret
  562.        
  563. BDOS_setcolor
  564. ;e=color byte
  565.        ;ld a,e
  566.        ;ld (pr_textmode_curcolor),a
  567.        ld (iy+app.curcolor),e
  568.        ret
  569. ;BDOS_getcolor
  570. ;       ld e,(iy+app.curcolor)
  571. ;       ret
  572.        
  573. BDOS_cls
  574.         ld hl,(appaddr)
  575.         ld bc,(focusappaddr)
  576.         or a
  577.         sbc hl,bc
  578.         ret nz
  579.        ;ld iy,(appaddr)
  580. ;e=color byte
  581.        BDOSSETPGSSCR
  582.  
  583.        if 1==1
  584.        ld a,(iy+app.gfxmode)
  585.        and 7
  586.        ;jr z,BDOS_cls_EGA(0)
  587.         sub 3 ;MC hires(2)
  588.        ld a,e ;attr byte
  589.         jr c,BDOS_cls_EGA ;TODO отдельную очистку для MC hires
  590.         ;dec a ;6912(3)
  591. ;textmode (6)
  592.         ld hl,0xc000
  593.         ld bc,0x1aff
  594.         jr z,BDOS_cls_textmode_ldirbc ;6912(3)
  595.        ld h,0x81;c0
  596.        call BDOS_cls_textmode_ldir
  597.        ld h,0xa1;c0
  598.        call BDOS_cls_textmode_ldir
  599.        endif
  600.        
  601.        ;ld de,0
  602.        ld d,b
  603.        ld e,b ;0
  604.        call BDOS_setxy
  605.        
  606.        if 1==1
  607.        xor a
  608.        ld h,0xc1;c0
  609.        call BDOS_cls_textmode_ldir
  610.        ld h,0xe1;c0
  611. BDOS_cls_textmode_ldir
  612.        ld l,0xc0
  613.        ld bc,25*64-1
  614. BDOS_cls_textmode_ldirbc
  615.        ld d,h
  616.        ld e,l
  617.        inc de
  618.        ld (hl),a
  619.        ldir
  620.        ret
  621. BDOS_cls_EGA
  622.        endif
  623.      
  624.        ;ld a,e
  625. scrbase=0x8000
  626. ;чистим через стек, кроме первых байтов (иначе прерывание может запортить два байта перед экраном)
  627.        ld (clssp),sp
  628.        ld hl,scrbase+(200*40) ;чистим с конца, потому что прерывание портит стек
  629.        ld b,200-1
  630.        scf
  631. clsline0
  632.        ld d,a
  633.        ld e,a
  634.        
  635.        ;ld c,2
  636. clsline1  
  637.        ld sp,hl
  638.        dup 20
  639.        push de
  640.        edup
  641.        set 5,h
  642.        ld sp,hl
  643.        dup 20
  644.        push de
  645.        edup
  646.        res 5,h
  647.        
  648.        set 6,h
  649.        ;dec c
  650.        ;jp nz,clsline1
  651.        ccf
  652.        jp nc,clsline1
  653.        
  654.        ;ld sp,hl
  655.        ;dup 20
  656.        ;push de
  657.        ;edup
  658.        ;res 5,h
  659.        ;ld sp,hl
  660.        ;dup 20
  661.        ;push de
  662.        ;edup
  663.        ;res 6,h
  664.        ld de,-40-0x4000
  665.        add hl,de ;CY=1!!!
  666.        djnz clsline0
  667. clssp=$+1
  668.        ld sp,0
  669.        ld hl,0x0000 + scrbase
  670.        call clslayer2
  671.        ;ld hl,0x2000 + scrbase
  672.        ;call clslayer
  673. clslayer2
  674.        ;ld hl,0x4000 + scrbase
  675.        call clslayer
  676.        ;ld hl,0x6000 + scrbase
  677. clslayer
  678.        ld d,h
  679.        ld e,l
  680.        inc de
  681.        ld  c,40-1;8000-1
  682.        ld (hl),a
  683.        ldir
  684.        ld de,0x2000-(40-1)
  685.        add hl,de
  686.        ret
  687.  
  688. BDOS_playcovox
  689. ;hl=data (0xc000+), ends with 0x00
  690. ;de=pagetable (0x0000+)
  691. ;hx=delay
  692.        set 7,d ;de=pagetable (0x8000+)
  693.        ld a,(iy+app.mainpg)
  694.        call sys_setpg8000 ;pagetable in mainpg
  695.         di
  696.        ld a,(iy+app.gfxmode)
  697.        and 0xf7 ;noturbo
  698.         ld bc,0xbd77
  699.         out (c),a
  700.        push bc
  701. ;hx=delay
  702. ;hl=data
  703. ;de=pagetable (0x8000+)
  704.        ld bc,memportc000
  705.         ld a,(de)
  706.         out (c),a
  707. BDOS_playcovox0
  708.        xor a ;4
  709. BDOS_playcovox0_a0
  710.         or (hl) ;7
  711.         out (0xfb),a    ;11
  712.         jr z,BDOS_playcovoxdone ;7/12
  713.         inc hl          ;6
  714.         bit 6,h         ;8
  715.         jr z,BDOS_playcovoxpage ;7/12
  716. BDOS_playcovoxdelay
  717.         ld a,hx         ;4+4
  718.         dec a           ;4
  719.         jp nz,$-1       ;10
  720.         jp BDOS_playcovox0_a0           ;10=78t при d=1, шаг задержки 14 тактов
  721. BDOS_playcovoxpage
  722. ;тут и раньше была неточная задержка
  723.         ld h,0xc0
  724.        inc de
  725.         ld a,(de)
  726.         out (c),a
  727.         jp BDOS_playcovoxdelay
  728. BDOS_playcovoxdone
  729.        ld a,(iy+app.gfxmode) ;turbo
  730.        pop bc
  731.         out (c),a
  732.         ei
  733.        ret
  734.  
  735. BDOShandler
  736.        push hl
  737.        ld a,c
  738.        ld hl,tbdoscmds
  739.        push bc
  740.        ld bc,nbdoscmds
  741.        cpir
  742.        jp nz,BDOS_pop2fail
  743. ;bc=nbdoscmds-(cmdnumber+1) = 0..(nbdoscmds-1)
  744.        add hl,bc
  745. ;hl=tbdoscmds+nbdoscmds
  746.        add hl,bc
  747.        add hl,bc
  748. ;hl=tbdoscmds+nbdoscmds+ 2*(nbdoscmds-(cmdnumber+1))
  749.        pop bc
  750.        ld a,(hl)
  751.        inc hl
  752.        ld h,(hl)
  753.        ld l,a
  754.        ;hl=jump addr
  755.        ex (sp),hl
  756.        ret
  757.  
  758. tbdoscmds
  759.         db CMD_WRITEHANDLE
  760.         db CMD_WIZNETREAD
  761.         db CMD_YIELDKEEP
  762.         db CMD_YIELD
  763.         db CMD_READHANDLE
  764.          db CMD_GETKEYMATRIX
  765.          db CMD_GETTIMER
  766.          db CMD_WAITPID
  767.          db CMD_SETSCREEN
  768.         db CMD_PRATTR
  769.         db CMD_SETXY
  770.         db CMD_SETCOLOR
  771.         db CMD_PRCHAR
  772.         db CMD_GETATTR
  773.         db CMD_SETDTA;0x1a
  774.         db CMD_FOPEN;0x0f
  775.         db CMD_FREAD;0x14
  776.         db CMD_FCLOSE;0x10
  777.         db CMD_FDEL;0x13 ;DEPRECATED!!!!!
  778.         db CMD_FCREATE;0x16
  779.         db CMD_FWRITE;0x15
  780.        db CMD_FSEARCHFIRST;0x11
  781.        db CMD_FSEARCHNEXT;0x12
  782.        db CMD_OPENDIR
  783.        db CMD_READDIR
  784.        db CMD_SETDRV
  785.         db CMD_PARSEFNAME;0x5c
  786.        db CMD_CHDIR
  787.        db CMD_GETPATH
  788.        db CMD_RUNAPP
  789.        db CMD_NEWAPP
  790.        db CMD_CLS
  791.        db CMD_SETGFX
  792.        db CMD_SETPAL
  793.        db CMD_GETMAINPAGES
  794.        db CMD_NEWPAGE
  795.        db CMD_DELPAGE
  796.        db CMD_MOUNT
  797.        db CMD_FREEZEAPP
  798.        db CMD_MKDIR
  799.        db CMD_RENAME
  800.        db CMD_SETSYSDRV
  801.        ;db CMD_FWRITE_NBYTES
  802.        db CMD_SCROLLUP
  803.        db CMD_SCROLLDOWN
  804.        db CMD_OPENHANDLE
  805.        db CMD_CREATEHANDLE
  806.        db CMD_CLOSEHANDLE
  807.        db CMD_SEEKHANDLE
  808.        db CMD_TELLHANDLE
  809.        db CMD_SETFILETIME
  810.        db CMD_GETFILETIME
  811.        db CMD_GETTIME
  812.        db CMD_GETXY
  813.        db CMD_GETAPPMAINPAGES
  814.        db CMD_DROPAPP
  815.        db CMD_WIZNETOPEN
  816.        db CMD_WIZNETCLOSE
  817.        db CMD_WIZNETWRITE
  818.        db CMD_GETFILESIZE
  819.        db CMD_DELETE
  820.        db CMD_SETWAITING
  821.        db CMD_SETBORDER
  822.        db CMD_READSECTORS
  823.        db CMD_WRITESECTORS
  824.        db CMD_SETMAINPAGE
  825.        db CMD_SETMUSIC
  826.        db CMD_PLAYCOVOX
  827.        db CMD_GETSTDINOUT
  828.        db CMD_SETSTDINOUT
  829.        db CMD_HIDEFROMPARENT
  830.        db CMD_RNDRD
  831.        db CMD_RNDWR
  832. nbdoscmds=$-tbdoscmds
  833.        dw BDOS_rndwr
  834.        dw BDOS_rndrd
  835.        dw BDOS_hidefromparent
  836.        dw BDOS_setstdinout
  837.        dw BDOS_getstdinout
  838.        dw BDOS_playcovox
  839.        dw BDOS_setmusic
  840.        dw BDOS_setmainpage
  841.        dw BDOS_writesectors
  842.        dw BDOS_readsectors
  843.        dw BDOS_setborder
  844.        dw BDOS_setwaiting
  845.        dw BDOS_delete
  846.        dw BDOS_getfilesize
  847.        dw BDOS_wiznetwrite
  848.        dw BDOS_wiznetclose
  849.        dw BDOS_wiznetopen
  850.        dw BDOS_dropapp
  851.        dw BDOS_getappmainpages
  852.        dw BDOS_getxy
  853.        dw BDOS_gettime
  854.        dw BDOS_getfiletime
  855.        dw BDOS_setfiletime
  856.        dw BDOS_tellhandle
  857.        dw BDOS_seekhandle
  858.        dw BDOS_closehandle
  859.        dw BDOS_createhandle
  860.        dw BDOS_openhandle
  861.        dw BDOS_scrolldown
  862.        dw BDOS_scrollup
  863.        ;dw BDOS_fwrite_nbytes
  864.        dw BDOS_setsysdrv
  865.        dw BDOS_rename
  866.        dw BDOS_mkdir
  867.        dw BDOS_freezeapp
  868.        dw BDOS_mount
  869.        dw BDOS_delpage
  870.        dw BDOS_newpage
  871.        dw BDOS_getmainpages
  872.        dw BDOS_setpal
  873.        dw BDOS_setgfx
  874.        dw BDOS_cls
  875.        dw BDOS_newapp
  876.        dw BDOS_runapp
  877.        dw BDOS_getpath
  878.        dw BDOS_chdir
  879.        dw BDOS_parse_filename
  880.        dw BDOS_setdrv
  881.        dw BDOS_readdir
  882.        dw BDOS_opendir
  883.        dw BDOS_fsearchnext
  884.        dw BDOS_fsearchfirst
  885.         dw BDOS_fwrite
  886.         dw BDOS_fcreate
  887.         dw BDOS_fdel ;DEPRECATED!!!!!
  888.         dw BDOS_fclose
  889.         dw BDOS_fread
  890.         dw BDOS_fopen
  891.        dw BDOS_setdta
  892.         dw BDOS_getattr
  893.         dw BDOS_prchar
  894.         dw BDOS_setcolor
  895.         dw BDOS_setxy
  896.         dw BDOS_prattr
  897.          dw BDOS_setscreen
  898.          dw BDOS_waitpid
  899.          dw BDOS_gettimer
  900.          dw BDOS_getkeymatrix
  901.         dw BDOS_readhandle
  902.         dw BDOS_yield
  903.         dw BDOS_yieldkeep
  904.         dw BDOS_wiznetread
  905.         dw BDOS_writehandle
  906.  
  907. BDOS_hidefromparent
  908.        if 1==1
  909. ;просто разбудить родителя
  910. activateparent
  911.         ld e,(iy+app.parentid)
  912.         ld a,e
  913.         dec a
  914.         ret z ;idle
  915.         call BDOS_findapp ;iy=found app
  916.         set factive,(iy+app.flags)
  917.         ret
  918.        else
  919.        push iy
  920.        call sys_findfreeid ;портит iy        
  921.        pop iy
  922.        ld c,a
  923. ;перезахватить страницы
  924.        ld hl,tsys_pages
  925.        ld a,(iy+app.id)
  926.        ld (iy+app.id),c
  927.        ld b,sys_npages&0xff
  928. BDOS_hidefromparent0
  929.        cp (hl) ;id задачи, которой принадлежит страница
  930.        jr nz,$+4
  931.        ld (hl),c ;заменили страницу
  932.        inc hl
  933.        djnz BDOS_hidefromparent0
  934.        endif
  935.        ret
  936.  
  937. BDOS_setstdinout
  938. ;b=id, e=stdin, d=stdout, h=stderr
  939.        push de
  940.        ld e,b
  941.        call BDOS_findapp
  942.        pop de
  943.        ld (iy+app.stdin),e
  944.        ld (iy+app.stdout),d
  945.        ld (iy+app.stderr),h
  946.        ret
  947.  
  948. BDOS_getstdinout
  949. ;e=stdin, d=stdout, h=stderr
  950.        ld e,(iy+app.stdin)
  951.        ld d,(iy+app.stdout)
  952.        ld h,(iy+app.stderr)
  953.        ret
  954.  
  955. BDOS_getkeymatrix
  956. ;out: bcdehlix = полуряды cs...space
  957.        ld hl,(appaddr)
  958.        ld de,(focusappaddr)
  959.        or a
  960.        sbc hl,de
  961.        jr nz,BDOS_getkeymatrix_fail
  962.        ld bc,0x7ffe
  963.        in a,(c)
  964.        ld lx,a  ;lx=%???bnmS_
  965.        ld b,0xbf
  966.        in a,(c)
  967.        ld hx,a  ;hx=%???hjklE
  968.        ld b,0xdf
  969.        in l,(c)  ;l=%???yuiop
  970.        ld b,0xef
  971.        in h,(c)  ;h=%???67890
  972.        ld b,0xf7
  973.        in e,(c)  ;e=%???54321
  974.        ld b,0xfb
  975.        in d,(c)  ;d=%???trewq
  976.        ld a,0xfd
  977.        in a,(0xfe);c=%???gfdsa
  978.        ld b,c;0xfe
  979.        in b,(c)  ;b=%???vcxzC
  980.        ld c,a
  981.         xor a ;z
  982.        ret
  983. BDOS_getkeymatrix_fail
  984. ;nz
  985.        ld bc,0xffff
  986.        ld d,c
  987.        ld e,c
  988.        ld h,c
  989.        ld l,c
  990.        push bc
  991.        pop ix
  992.        ret
  993.  
  994. BDOS_gettimerX
  995. BDOS_gettimer
  996.        ld hl,(sys_timer+2) ;ok
  997.        ld de,(sys_timer) ;ok
  998.         ld a,(sys_timer+2) ;ok
  999.         sub l
  1000.         jr nz,BDOS_gettimerX ;для атомарности
  1001.        ret ;a=0
  1002.        
  1003. ;BDOS_yield
  1004. ;        ex af,af'
  1005. ;        or a
  1006. ;        jr z,BDOS_yieldnokeep
  1007. ;        ;dec (iy+app.lasttime)
  1008. BDOS_yieldkeep
  1009.          ld a,(sys_timer) ;ok
  1010.          dec a
  1011.          jr BDOS_yieldgo
  1012.          ;ld (iy+app.lasttime),a
  1013. ;BDOS_yieldnokeep
  1014. BDOS_yield
  1015.          ld a,(sys_timer) ;ok
  1016. BDOS_yieldgo
  1017.          ld (iy+app.lasttime),a
  1018. ;регистры не сохраняем, т.к. нам не важно, что на выходе из yield
  1019.         if 1==1
  1020. ;но надо:
  1021. ;взять адрес стека для выхода из CALLBDOS и записать его в ld sp на выходе из обработчика прерываний
  1022. ;взять адрес возврата из CALLBDOS и записать его в jp на выходе из обработчика прерываний
  1023. ;на выходе надо вручную выставить везде pgkillable!
  1024.         ;ld iy,(appaddr)
  1025.        
  1026.         if bdosstack_sz==0
  1027.         ld hl,(callbdos_sp)
  1028.         else
  1029.         ;ld l,(iy+app.callbdos_sp)
  1030.         ;ld h,(iy+app.callbdos_sp+1)
  1031.         exx
  1032.         endif
  1033.  
  1034.         ;call setmainpg_c000
  1035.          ;halt ;проверка на вшивость
  1036.         ;ld (intsp+0xc000),hl
  1037.  
  1038.         ;ex de,hl
  1039.         ld de,-6
  1040.         add hl,de ;место в стеке под 3 рег.пары (а потом адрес возврата из bdos)
  1041.         ld (iy-2),l
  1042.         ld (iy-1),h ;sp в описателе текущей задачи
  1043.         ;call BDOS_preparedepage
  1044.         ;call BDOS_setdepage ;включается сразу 2 страницы на случай sp на границе страниц
  1045.         ;ex de,hl
  1046.          ;halt ;проверка на вшивость        
  1047.         ;ld e,(hl)
  1048.         ;inc hl
  1049.         ;ld d,(hl) ;вместо адреса возврата из bdos
  1050.  
  1051.         ;call setmainpg_c000
  1052.          ;halt ;проверка на вшивость
  1053.         ;ld (intjp+0xc000),de ;TODO при многозадачности в кернале это надо делать атомарно вместе с записью sp!
  1054.         endif
  1055.        
  1056.         ;ld a,pgkillable
  1057.         ;call sys_setpgc000
  1058.         ;call sys_setpg8000
  1059.         ;call setpgs_killable
  1060.        
  1061.         if bdosstack_sz !=0
  1062.         ld a,0xc0
  1063.         ld (callbdos_mutex),a ;то же самое делают те функции BDOS, которые не собираются возвращаться
  1064.         endif
  1065.  
  1066. ;не выходим из CALLBDOS, взамен шедулим и выходим через конец обработчика прерываний
  1067.  
  1068. BDOS_yield_q
  1069.  
  1070. ;        push iy
  1071.         call schedule ;out: iy=app ;можно с включенными прерываниями, пока системный обработчик не умеет шедулить
  1072.         call setpgs_killable ;во всех случаях!
  1073.          ;halt ;проверка на вшивость
  1074. ;        pop de
  1075. ;        or a
  1076. ;        sbc hl,de
  1077. ;        jr nz,BDOS_yield_nosame
  1078. ;        ld iy,app1 ;idle (TODO вместо этого сделать полноценные приоритеты)
  1079. ;        ld (appaddr),iy
  1080. ;BDOS_yield_nosame
  1081.        
  1082.         ;di ;TODO critical section
  1083.        
  1084.         jp sys_int_popregs ;там ei
  1085.        
  1086. BDOS_newapp
  1087. ;пока структура не заполнена до конца, нельзя делать runapp
  1088. ;out: b=id, dehl=номера страниц в 0000,4000,8000,c000 нового приложения, a=error
  1089.         BDOSSETPGTRDOSFS
  1090.         jp sys_newapp_forBDOS
  1091.  
  1092. BDOS_findapp
  1093. ;nz=error
  1094.         ld iy,app1
  1095.         ld a,e
  1096.         ld de,app_sz
  1097.         ld b,MAXAPPS
  1098. BDOS_findapp0
  1099.         cp (iy+app.id)
  1100.         ret z
  1101.         add iy,de
  1102.         djnz BDOS_findapp0
  1103.         ret ;nz
  1104.        
  1105. BDOS_dropapp
  1106. ;e=id
  1107.         call BDOS_findapp
  1108.         jp nz,BDOS_fail ;BDOS_popfail
  1109.         push iy
  1110.         call BDOS_freezeapp_go
  1111.         pop iy
  1112. BDOS_delapppages
  1113.          push iy
  1114.          call activateparent
  1115.          pop iy
  1116.         ld hl,tsys_pages
  1117.         ld a,(iy+app.id)
  1118.         ld b,sys_npages&0xff
  1119. sys_quit_delpages0
  1120.         cp (hl) ;страница снимаемой задачи
  1121.         jr nz,$+4
  1122.         ld (hl),0 ;освободили страницу
  1123.         inc hl
  1124.         djnz sys_quit_delpages0
  1125.                 if INETDRV
  1126.                 BDOSSETPGW5300
  1127.                 call w53_drop_socs
  1128.                 endif
  1129.         if 1==1
  1130.         call BDOS_setpgstructs
  1131.         ld ix,ffilearray
  1132.         ld b,MAXFILES
  1133. BDOS_dropapp_closefiles0
  1134.         ld de,FIL_sz
  1135.         ld a,(ix+FIL.PAD1)
  1136.         cp (iy+app.id)
  1137.         jr nz,BDOS_dropapp_closefiles_skip
  1138.         push bc
  1139.         push ix
  1140.         pop de
  1141.         push de
  1142.         F_CLOS_CURDRV
  1143.         pop ix
  1144.         pop bc
  1145. BDOS_dropapp_closefiles_skip
  1146.         add ix,de
  1147.         djnz BDOS_dropapp_closefiles0
  1148.         endif
  1149.         ld a,(muzpid)
  1150.         cp (iy+app.id)
  1151.         call z,killmuz
  1152.         xor a ;ok
  1153.         ld (iy+app.id),a ;b;0 ;освободили место
  1154.         ret
  1155.        
  1156. open_keeppid
  1157.         push af
  1158.         push de
  1159.         inc de
  1160.         inc de
  1161.         inc de
  1162.         inc de
  1163.         inc de
  1164.     push bc
  1165.     call BDOS_setpgstructs
  1166.     pop bc
  1167.         ld a,(iy+app.id)
  1168.         ld (de),a
  1169.         pop de
  1170.         pop af
  1171.         ret
  1172.  
  1173. BDOS_runapp
  1174. ;e=id
  1175.         ;push iy
  1176.         call BDOS_findapp
  1177.         jp nz,BDOS_fail ;BDOS_popfail
  1178.         set factive,(iy+app.flags)
  1179.         ;pop iy
  1180.         xor a
  1181.         ret
  1182.  
  1183. BDOS_setwaiting
  1184.          ;set fwaiting,(iy+app.flags)
  1185.          res factive,(iy+app.flags)
  1186.         ret
  1187.  
  1188. ;TODO remove?
  1189. BDOS_waitpid
  1190. ;e=id
  1191. ;check for app close (a=0 and reset waiting, or else a!=0)
  1192.          push iy
  1193.          ;set fwaiting,(iy+app.flags)
  1194.         ld c,(iy+app.id) ;my (parent's) id ;caller is the parent
  1195.         push bc
  1196.         call BDOS_findapp ;iy=found app
  1197.         pop bc
  1198.         ld a,(iy+app.parentid)
  1199.          pop iy
  1200.         jr nz,BDOS_waitpid_OK ;app doesn't exist = OK
  1201.         cp c ;parent id
  1202.         jp z,BDOS_fail ;existing app = fail
  1203. BDOS_waitpid_OK
  1204.          ;res fwaiting,(iy+app.flags)
  1205.         xor a
  1206.         ret
  1207.  
  1208. BDOS_setgfx
  1209.         ;ld iy,(appaddr)
  1210. ;e=0:EGA, e=2:MC, e=3:6912, e=6:text
  1211. ;e=-1: disable gfx (out: e=old gfxmode)
  1212.         ld a,e
  1213.         cp -1
  1214.         jr z,BDOS_setgfx_gfxoff;BDOS_gfxoff_givefocus
  1215.                 IFDEF NOTURBO
  1216.         or 0xa0;%10100000
  1217.                 ELSE
  1218.         or 0xa8;%10101000
  1219.                 ENDIF
  1220.         ld (iy+app.gfxmode),a
  1221.  
  1222.         call enablescreeninapp_setc000
  1223.        
  1224. ;кладём фокус в стек, только если не два раза setgfx в одной задаче:
  1225.         ld hl,(focusappaddr)
  1226.         push iy
  1227.         pop de
  1228.         or a
  1229.         sbc hl,de
  1230.         jr z,BDOS_setgfx_nopushfocus
  1231.         ;jr $
  1232.         add hl,de
  1233.         push de;iy
  1234.         push hl
  1235.         pop iy
  1236.         call disablescrpgs_setc000 ;у старой focusapp отключить экран в переменных и в памяти
  1237.         pop iy
  1238.        
  1239.          ld hl,(oldfocusappaddr)
  1240.          ld (oldoldfocusappaddr),hl ;TODO стек фокусов (чтобы после закрытия задачи вернуть фокус вызвавшей)
  1241.         ld hl,(focusappaddr)
  1242.         ld (oldfocusappaddr),hl ;TODO стек фокусов (чтобы после закрытия задачи вернуть фокус вызвавшей)
  1243.         ld (focusappaddr),iy
  1244.         call setpalettechanged
  1245. BDOS_setgfx_nopushfocus        
  1246.         set fgfx,(iy+app.flags)
  1247.         ld e,(iy+app.gfxmode)
  1248.         ;xor a ;success
  1249.         ret
  1250. BDOS_setgfx_gfxoff
  1251.         call disablescrpgs_setc000 ;у старой focusapp отключить экран в переменных и в памяти
  1252.         ld e,(iy+app.gfxmode)
  1253.         push de
  1254.         call BDOS_gfxoff_givefocus ;spoils iy!
  1255.         pop de
  1256.         ret
  1257. disablescreeninapp_setc000
  1258.         call setmainpg_c000
  1259. disablescreeninapp
  1260.         ld a,pgkillable
  1261.         ld (0xc000+user_scr0_low),a
  1262.         ld (0xc000+user_scr0_high),a
  1263.         ld (0xc000+user_scr1_low),a
  1264.         ld (0xc000+user_scr1_high),a
  1265.         ret
  1266. enablescreeninapp_setc000
  1267.         call setmainpg_c000
  1268.         ld a,pgscr0_0
  1269.         ld (0xc000+user_scr0_low),a
  1270.         ld a,pgscr0_1
  1271.         ld (0xc000+user_scr0_high),a
  1272.         ld a,pgscr1_0
  1273.         ld (0xc000+user_scr1_low),a
  1274.         ld a,pgscr1_1
  1275.         ld (0xc000+user_scr1_high),a
  1276.         ret
  1277.        
  1278. BDOS_freezeapp
  1279. ;e=id
  1280.         ;push iy
  1281.         call BDOS_findapp
  1282.         jp nz,BDOS_fail ;BDOS_popfail
  1283. BDOS_freezeapp_go
  1284.         ;ld (iy+app.flags),0 ;пока тут 0, задачу никто не будет трогать
  1285.         res factive,(iy+app.flags)
  1286. BDOS_gfxoff_givefocus
  1287.         res fgfx,(iy+app.flags) ;если в конце, то по дороге могут вручную переключить фокус, а если в начале, то ...
  1288. ;если фокус у этой задачи, то дать фокус какой-нибудь графической задаче
  1289.         push iy
  1290.         pop hl
  1291.         ld de,(focusappaddr)
  1292.         xor a
  1293.         sbc hl,de
  1294.         ret nz ;jr nz,sys_quit_findgfxapp_fail ;фокус не у этой задачи
  1295.        
  1296.          ;jr $
  1297. oldfocusappaddr=$+1
  1298.         ld hl,app1
  1299. oldoldfocusappaddr=$+1
  1300.          ld de,app1
  1301.          ld (oldfocusappaddr),de
  1302.         bit fgfx,(hl)
  1303.         jr nz,sys_quit_findgfxappq ;TODO стек фокусов (чтобы после закрытия задачи вернуть фокус вызвавшей)
  1304.        
  1305.         ld hl,app1
  1306.         ld bc,-app_last;app_afterlast
  1307.         ld de,app_last+app_sz;app_sz
  1308. sys_quit_findgfxapp0
  1309.         add hl,bc
  1310.         jr c,sys_quit_findgfxapp_fail ;уже проверили app_last, у него нет фокуса - некому давать фокус
  1311.         add hl,de
  1312.         bit fgfx,(hl)
  1313.         jr z,sys_quit_findgfxapp0
  1314. sys_quit_findgfxappq
  1315.         ld (focusappaddr),hl
  1316.         call setpalettechanged
  1317.         push hl
  1318.         pop iy
  1319.         call enablescreeninapp_setc000 ;включить экран в переменные этой задачи
  1320.        
  1321.          ;ld a,key_redraw
  1322.          ;ld (curkey),a
  1323.          ;ld bc,key_redraw
  1324.          ; ld (keyqueueput_codenolang),bc
  1325.          ;call KEYQUEUEPUT
  1326.          call KEY_PUTREDRAW
  1327. sys_quit_findgfxapp_fail
  1328.         ;pop iy
  1329.         xor a
  1330.         ret
  1331.  
  1332. BDOS_newpage
  1333.         ;ld iy,(appaddr)
  1334. BDOS_newpage_iy
  1335. ;out: a=0 (OK)/0xff (fail), e=page
  1336.        if TOPDOWNMEM
  1337.         ld hl,tsys_pages +sys_npages-1
  1338.         ld bc,sys_npages
  1339.         xor a
  1340.         cpdr
  1341.         jr nz,BDOS_fail
  1342.         inc hl
  1343.         ld a,(iy+app.id)
  1344.         ld (hl),a
  1345.         ld a,pagexor;0x7f
  1346.         sub c ;c=0..sys_npages-1
  1347.        else
  1348.         ld hl,tsys_pages
  1349.         ;push hl
  1350.         ld bc,sys_npages
  1351.         xor a
  1352.         cpir
  1353.         ;pop de
  1354.         jr nz,BDOS_fail
  1355.         dec hl
  1356.         ld a,(iy+app.id)
  1357.         ld (hl),a
  1358.          ;or a
  1359.          ;sbc hl,de ;hl=(0..sys_npages-1)
  1360.         ;ld a,pagexor;0x7f
  1361.         ;sub l ;l=0..sys_npages-1
  1362.         ld a,0xff&(pagexor-(sys_npages-1))
  1363.         add a,c
  1364.        endif
  1365.         ld e,a ;page
  1366. BDOS_OK
  1367.         xor a
  1368.         ret ;a=0 (OK), e=page
  1369.  
  1370. BDOS_pop2fail
  1371.         pop af
  1372. BDOS_popfail
  1373.         pop af
  1374. BDOS_fail
  1375.         ld a,0xff
  1376.         ret
  1377.  
  1378. BDOS_delpage
  1379. ;e=page
  1380. ;не портит de
  1381.         ld a,e
  1382.         call addrpage
  1383.         ld (hl),b ;0
  1384.         ret ;a=0
  1385.  
  1386. addrpage
  1387.         xor pagexor;0x7f
  1388.         ld c,a
  1389.         ld hl,tsys_pages
  1390.         xor a
  1391.         ld b,a
  1392.         add hl,bc
  1393.         ret
  1394.  
  1395. ;DEPRECATED!!!!!
  1396. BDOS_fdel
  1397.         call BDOS_preparedepage
  1398.         call BDOS_setdepage ;TODO убрать в драйвер
  1399. ;DE = Pointer to unopened FCB
  1400.         CHECKVOLUMETRDOS
  1401.         jr c,BDOS_fdel_noFATFS
  1402.  
  1403.         call get_name
  1404.         ld de,mfil
  1405.         F_UNLINK_CURDRV
  1406.         ;or a:jp z,fexit
  1407.         ;ld a,0xff
  1408.         ret;jp fexit
  1409. BDOS_fdel_noFATFS
  1410.         BDOSSETPGTRDOSFS
  1411. ;DE = Pointer to unopened FCB
  1412.         jp nfdel
  1413.  
  1414. BDOS_rndrdwrseek
  1415. ;DE = Pointer to opened FCB
  1416.        push de
  1417.         ld hl,0x21 ;outsize FCB_sz!!!
  1418.         add hl,de
  1419.         ld c,(hl)
  1420.         inc hl
  1421.         ld b,(hl)
  1422.         push bc ;record number BC
  1423.         call getFILfromFCB ;hl=FIL
  1424.         ex de,hl ;de=fil (2 words in stack = shift)        
  1425.         push de
  1426.         call BDOS_getfilesize_filde
  1427.          ;jr $
  1428. ;dehl=filesize (no more than 8M in CP/M finction)
  1429. ;highest record number = dehl/128???
  1430.         add hl,hl
  1431.         rl e
  1432.         ld l,h
  1433.         ld h,e
  1434. ;highest record number = dehl/128-1??? wrong!
  1435.         ;add hl,hl
  1436.         ;rl e
  1437.         ;ld l,h
  1438.         ;ld h,e
  1439.         ; ld a,h
  1440.         ; or l
  1441.         ; jr z,$+3
  1442.         ; dec hl
  1443. ;highest record number = (dehl-1)/128??? wrong!
  1444.         ;ld a,h
  1445.         ;or l
  1446.         ;dec hl
  1447.         ;jr nz,$+3
  1448.         ;dec de
  1449.         ;add hl,hl
  1450.         ;rl e
  1451.         ;ld l,h
  1452.         ;ld h,e
  1453.         ; ld a,h
  1454.         ; and l
  1455.         ; inc a
  1456.         ; jr nz,$+3
  1457.         ; inc hl
  1458.         pop de
  1459.         pop bc ;record number BC
  1460.         call minhl_bc_tobc        
  1461.         ld l,b ;HSB from BC
  1462.         ld h,0
  1463.         srl l
  1464.         push hl ;HSW
  1465.         ld b,c
  1466.         ld c,h;0
  1467.         rr b
  1468.         rr c
  1469.         push bc ;LSW
  1470.         F_LSEEK_CURDRV        
  1471.         pop bc
  1472.         pop bc
  1473.        pop de
  1474.         ret
  1475.  
  1476. ;TODO TR-DOS???
  1477. BDOS_rndrd
  1478.         call BDOS_preparedepage
  1479.         call BDOS_setdepage
  1480. ;DE = Pointer to opened FCB
  1481.         call BDOS_rndrdwrseek
  1482.         jr BDOS_fread_gofatfs
  1483.  
  1484. ;TODO TR-DOS???
  1485. BDOS_rndwr
  1486.         call BDOS_preparedepage
  1487.         call BDOS_setdepage
  1488. ;DE = Pointer to opened FCB
  1489.         call BDOS_rndrdwrseek
  1490.         jr BDOS_fwrite_gofatfs
  1491.  
  1492. BDOS_fread
  1493.         call BDOS_preparedepage
  1494.         call BDOS_setdepage ;TODO убрать в драйвер
  1495. ;DE = Pointer to opened FCB
  1496.         ;CHECKVOLUMETRDOS
  1497.         ld a,(de)
  1498.         cp vol_trdos
  1499.         jr c,BDOS_fread_noFATFS
  1500. BDOS_fread_gofatfs
  1501. ;достать из него адрес ffile
  1502.         call getFILfromFCB ;hl=FIL
  1503.         call BDOS_getdta ;de = disk transfer address
  1504.        push de
  1505.         call BDOS_preparedepage
  1506.         call BDOS_setdepage ;TODO убрать в драйвер
  1507.         ld b,d
  1508.         ld c,e
  1509.         ld de,blocksize
  1510.          push de ;blocksize
  1511.         ld ix,fres
  1512.         push ix ;fres
  1513.         push de ;blocksize
  1514.         ex de,hl;ld de,ffile
  1515.         F_READ_CURDRV
  1516. BDOS_fread_fatfsq        
  1517.         pop bc
  1518.         pop bc
  1519.         ld a,(bc)
  1520.          pop bc ;blocksize
  1521.        pop de ;de = disk transfer address
  1522.         ;call movedma_addr ;+bc ;TODO remove!!!
  1523.         xor 0x80 ;!=, если прочитали не 128 байт ;TODO remove!!!
  1524. ;a=0: OK (прочитали 128 байт)
  1525. ;a=128: fail (прочитали 0 байт)
  1526. ;a=???: OK (последний блок файла меньше 128 байт)
  1527.         ret z
  1528.         cp 0x80
  1529.         ret z ;fail
  1530. ;for CP/M compatibility: fill unused part of sector with 0x1a
  1531.         push af
  1532.         ;call BDOS_getdta ;de = disk transfer address
  1533.         call BDOS_preparedepage
  1534.         call BDOS_setdepage ;нельзя надеяться на включение выше, если будет убрано в драйвер (т.к. это могло быть не последнее включение страницы)
  1535.         pop af
  1536.         push af
  1537. ;a=128+bytes loaded
  1538.         neg
  1539. ;a=128-bytes loaded
  1540.         ld b,a
  1541.         ld a,e
  1542.         add a,127
  1543.         ld e,a
  1544.         adc a,d
  1545.         sub e
  1546.         ld d,a ;de= Point to buffer end
  1547.         ld a,0x1a
  1548.         ld (de),a
  1549.         dec de
  1550.         djnz $-2
  1551.         pop af
  1552.         ret;jp fexit
  1553. BDOS_fread_noFATFS
  1554.         BDOSSETPGTRDOSFS
  1555. ;DE = Pointer to opened FCB (0x8000+/0xc000+)
  1556.         jp trdos_fread
  1557.  
  1558. BDOS_fwrite
  1559.         call BDOS_preparedepage
  1560.         call BDOS_setdepage ;TODO убрать в драйвер
  1561. ;DE = Pointer to opened FCB
  1562.         ;CHECKVOLUMETRDOS
  1563.         ld a,(de)
  1564.         cp vol_trdos
  1565.         jr c,BDOS_fwrite_noFATFS
  1566. BDOS_fwrite_gofatfs
  1567. ;достать из него адрес ffile
  1568.         call getFILfromFCB ;hl=FIL
  1569.         call BDOS_getdta ;de = disk transfer address
  1570.        push de
  1571.         call BDOS_preparedepage
  1572.         call BDOS_setdepage ;TODO убрать в драйвер
  1573.         ld b,d
  1574.         ld c,e
  1575.         ld de,blocksize
  1576.          push de ;blocksize
  1577.         ld ix,fres
  1578.         push ix ;fres
  1579.         push de ;blocksize
  1580.         ex de,hl;ld de,ffile
  1581.         F_WRITE_CURDRV
  1582.         jr BDOS_fread_fatfsq
  1583. BDOS_fwrite_noFATFS
  1584.         BDOSSETPGTRDOSFS
  1585. ;DE = Pointer to opened FCB
  1586.         jp trdos_fwrite
  1587.  
  1588.         if 1==0
  1589. BDOS_fwrite_nbytes
  1590.         call BDOS_preparedepage
  1591.         call BDOS_setdepage ;TODO убрать в драйвер
  1592. ;DE = Pointer to opened FCB
  1593. ;hl = bytes
  1594.         ;CHECKVOLUMETRDOS
  1595.         ld a,(de)
  1596.         cp vol_trdos
  1597.         jr c,BDOS_fwrite_nbytes_noFATFS
  1598. ;достать из него адрес ffile
  1599.          push hl ;bytes
  1600.         call getFILfromFCB ;hl=FIL
  1601.  
  1602.         call BDOS_getdta ;de = disk transfer address
  1603.         call BDOS_preparedepage
  1604.         call BDOS_setdepage ;TODO убрать в драйвер
  1605.         ld b,d
  1606.         ld c,e
  1607.         ;ld de,blocksize
  1608.          pop de ;bytes
  1609.          push de ;blocksize
  1610.         ld ix,fres
  1611.         push ix ;fres
  1612.         push de ;blocksize
  1613.         ex de,hl;ld de,ffile
  1614.         F_WRITE_CURDRV
  1615.         jr BDOS_fread_fatfsq
  1616. BDOS_fwrite_nbytes_noFATFS
  1617.         BDOSSETPGTRDOSFS
  1618. ;DE = Pointer to opened FCB
  1619. ;hl = bytes
  1620.         ld b,h
  1621.         ld c,l
  1622.         jp trdos_fwrite_nbytes
  1623.         endif
  1624.        
  1625. count_fdir
  1626.         push iy
  1627.         pop de
  1628.         ld hl,app.dir
  1629.         add hl,de
  1630.         ex de,hl
  1631.         ret
  1632.  
  1633. ;TODO TR-DOS
  1634. ;de=path
  1635. BDOS_opendir
  1636.         call BDOS_preparedepage
  1637.         call BDOS_setdepage
  1638.                 call countfiledrive
  1639.         jr c,BDOS_opendir_noFATFS
  1640.         ld b,d
  1641.         ld c,e
  1642.         ;CHECKVOLUMETRDOS
  1643. BDOS_opencurdir
  1644.         call count_fdir ;LD de,fdir
  1645.         F_OPDIR_CURDRV
  1646.         ret
  1647.  
  1648. BDOS_opendir_noFATFS
  1649.        push af
  1650.         BDOSSETPGTRDOSFS
  1651.        pop af
  1652.        ld (trdoscurdrive),a
  1653.         ld hl,trdos_catbuf
  1654.         call writedircluster_hl        
  1655.         ld de,0x0000 ;track,sector
  1656.         ld bc,0x0905 ;read 9 sectors
  1657.         call iodos.
  1658.         xor a ;no error
  1659.         ret
  1660.  
  1661. ;TODO TR-DOS
  1662. ;de=buf for FILINFO, 0x00 in FILINFO_FNAME = end dir
  1663. BDOS_readdir
  1664.         call BDOS_preparedepage
  1665.         call BDOS_setdepage
  1666.         ld b,d
  1667.         ld c,e
  1668.         CHECKVOLUMETRDOS
  1669.         jr c,BDOS_readdir_noFATFS
  1670.         call count_fdir ;LD de,fdir
  1671.         F_RDIR_CURDRV
  1672.         ret
  1673.        
  1674. BDOS_readdir_noFATFS
  1675. ;bc=addrto
  1676.         push bc
  1677.         BDOSSETPGTRDOSFS
  1678.         ld l,(iy+app.dircluster)
  1679.         ld h,(iy+app.dircluster+1)
  1680.         ld de,fcb2+FCB_FNAME
  1681.         call trdos_searchnext
  1682.         jp z,BDOS_popfail ;fsearchnext_nofile;BDOS_fsearch_loadloop_noFATFS_empty
  1683.         call writedircluster_hl
  1684.         pop de
  1685. ;de=addrto
  1686.         ld hl,fcb2+FCB_FSIZE
  1687.         ld bc,4
  1688.         ldir
  1689.         ld hl,fcb2+FCB_FDATE
  1690.         ld c,2
  1691.         ldir
  1692.         ld hl,fcb2+FCB_FTIME
  1693.         ld c,2
  1694.         ldir
  1695.         ld hl,fcb2+FCB_FATTRIB
  1696.         ldi
  1697.         ld hl,fcb2+FCB_FNAME
  1698.         call get_name_hltode
  1699.         ld h,d
  1700.         ld l,e
  1701.         ld bc,12
  1702.         xor a ;no error
  1703.         ld (hl),a
  1704.         ldir
  1705.         ret
  1706. ;FILINFO_FSIZE=0;               DWORD           ;/* FILE SIZE */
  1707. ;FILINFO_FDATE=4;               WORD            ;/* LAST MODIFIED DATE */
  1708. ;FILINFO_FTIME=6;               WORD            ;/* LAST MODIFIED TIME */
  1709. ;FILINFO_FATTRIB=8;             BYTE            ;/* ATTRIBUTE */
  1710. ;FILINFO_FNAME=9;               BLOCK 13,0      ;/* SHORT FILE NAME (8.3 FORMAT with dot and terminator) */
  1711. ;FILINFO_LNAME=22;              BLOCK DIRMAXFILENAME64,0        ;/* LONG FILE NAME (ASCIIZ) */
  1712. ;FILINFO_sz=FILINFO_LNAME+DIRMAXFILENAME64
  1713.  
  1714.  
  1715. ;SEARCH FOR FIRST [FCB] (11H)
  1716. ;     Parameters:    C = 11H (_SFIRST)
  1717. ;                   DE = Pointer to unopened FCB
  1718. ;     Results:     L=A = 0FFH if file not found
  1719. ;                      =   0  if file found.
  1720. ;The filename may be ambiguous (containing "?" characters) in which case the first match will be found.
  1721. ;The low byte of the extent field will be used, and a file will only be found if it is big enough
  1722. ;to contain this extent number. Normally the extent field will be set to zero by the program before
  1723. ;calling this function. System file and sub-directory entries will not be found.
  1724. ;If a suitable match is found (A=0) then the directory entry will be copied to the DTA address,
  1725. ;preceded by the drive number. This can be used directly as an FCB for an OPEN function call if desired.
  1726. ;The extent number will be set to the low byte of the extent from the search FCB, and the record count
  1727. ;will be initialized appropriately (as for OPEN). The attributes byte from the directory entry will be
  1728. ;stored in the S1 byte position, since its normal position (immediately after the filename extension field)
  1729. ;is used for the extent byte.
  1730. BDOS_fsearchfirst
  1731.         call BDOS_preparedepage
  1732.         call BDOS_setdepage ;TODO убрать в драйвер
  1733.          push de ;DE = Pointer to unopened FCB (0x8000+/0xc000+)
  1734.         CHECKVOLUMETRDOS
  1735.         jr c,BDOS_fsearchfirst_noFATFS
  1736.                 ld bc,0 ; TCHAR *path   /* Pointer to the directory path */
  1737.         call BDOS_opencurdir
  1738.  
  1739.          pop de ;DE = Pointer to unopened FCB (0x8000+/0xc000+)
  1740.         or a
  1741.         ret nz;jp nz,fexit
  1742.         jr BDOS_fsearch_goloadloop
  1743. BDOS_fsearchfirst_noFATFS
  1744. ;TR-DOS
  1745.        push af
  1746.         BDOSSETPGTRDOSFS
  1747.        pop af
  1748.        ld (trdoscurdrive),a
  1749.         ld hl,trdos_catbuf
  1750.         ;ld (BDOS_fsearch_loadloop_trdosaddr),hl ;TODO где хранить для многозадачности? возвращать в FCB_DIRPOS?
  1751.         call writedircluster_hl
  1752.        
  1753.         ld de,0x0000 ;track,sector
  1754.         ld bc,0x0905 ;read 9 sectors
  1755.         call iodos.
  1756.          pop de ;DE = Pointer to unopened FCB (0x8000+/0xc000+)
  1757.         jr BDOS_fsearch_goloadloop
  1758.        
  1759. ;SEARCH FOR NEXT [FCB] (12H)
  1760. ;     Parameters:    C = 12H (_SNEXT)
  1761. ;     Results:     L=A = 0FFH if file not found
  1762. ;                      =   0  if file found.
  1763. BDOS_fsearchnext
  1764. ;(not CP/M!!!) для многозадачности принимать тут de = Pointer to unopened FCB
  1765.         call BDOS_preparedepage
  1766.         call BDOS_setdepage ;TODO убрать в драйвер
  1767. BDOS_fsearch_goloadloop
  1768.         inc de
  1769.         ld (fsearchnext_filename),de
  1770. BDOS_fsearch_loadloop
  1771.         ld iy,(appaddr) ;т.к. ffs портит iy
  1772.         CHECKVOLUMETRDOS
  1773.         jr c,BDOS_fsearch_loadloop_noFATFS
  1774.  
  1775.         call count_fdir ;LD de,fdir
  1776.         LD bc,mfilinfo
  1777.         F_RDIR_CURDRV
  1778.         ;or a
  1779.         ;ret nz;jp nz,fexit
  1780.  
  1781. ;переделать структуру FILINFO (которую мы сейчас считали) в структуру FCB
  1782.         ld de,mfilinfo+FILINFO_FNAME
  1783.         ld a,(de)
  1784.         or a
  1785.         jp z,BDOS_fail ;fsearchnext_nofile
  1786.         BDOSSETPGTRDOSFS
  1787.         call trdosgetdirfcb
  1788.         jr BDOS_fsearch_loadloop_FATFSq
  1789. BDOS_fsearch_loadloop_noFATFS
  1790. ;TR-DOS
  1791.         BDOSSETPGTRDOSFS
  1792.         ld l,(iy+app.dircluster)
  1793.         ld h,(iy+app.dircluster+1)
  1794.         ld de,fcb2+FCB_FNAME
  1795.         call trdos_searchnext
  1796.         jp z,BDOS_fail ;fsearchnext_nofile;BDOS_fsearch_loadloop_noFATFS_empty
  1797.         call writedircluster_hl
  1798.         jr BDOS_fsearch_loadloop_FATFSq
  1799. BDOS_fsearch_loadloop_FATFSq
  1800.         ld hl,fcb2+FCB_FNAME ;прочитанное имя
  1801. fsearchnext_filename=$+1
  1802.         ld de,0 ;образец
  1803.        
  1804. ;проверить имя файла hl == de (игнорировать (de)=='?')
  1805.         ld bc,11*256;0x0a00 ;b=bytes to compare, c=errors
  1806. fsearchnext_cp00
  1807.         ld a,[de]
  1808.         cp '?'
  1809.         jr z,fsearchnext_cpskip
  1810.         sub [hl]
  1811.         or c
  1812.         ld c,a ;errors
  1813. fsearchnext_cpskip
  1814.         inc hl
  1815.         inc de
  1816.         djnz fsearchnext_cp00
  1817.        
  1818. ;если не совпало, зациклить
  1819.         ld a,c
  1820.         or a
  1821.         jp nz,BDOS_fsearch_loadloop
  1822. fsearchnext_nofileq
  1823. ;иначе записать в dma
  1824.         ld iy,(appaddr)
  1825.         ld hl,fcb2
  1826.         call BDOS_getdta ;de = disk transfer address
  1827.         call BDOS_preparedepage
  1828.         call BDOS_setdepage ;TODO убрать в драйвер
  1829.         ld bc,FCB_sz;32;16
  1830.          push bc
  1831.         ldir
  1832.          pop bc
  1833.         call movedma_addr ;+bc
  1834.         xor a ;success
  1835.         ret;jp rest_exit
  1836.  
  1837. BDOS_getfiletime
  1838. ;de=Drive/path/file ASCIIZ string
  1839. ;out: ix=date, hl=time
  1840.         call BDOS_preparedepage
  1841.         call BDOS_setdepage ;TODO убрать в драйвер
  1842.         call countfiledrive ;a=volume, de=path without drive, c=1: drive in path, CY=TR-DOS
  1843.         jr c,BDOS_getfiletime_zero
  1844.                 ;push af
  1845.                 ;pop af
  1846.         ld bc,fres
  1847. ;de=name
  1848. ;bc=pointer to time,date
  1849.                 F_GETUTIME
  1850.         ld hl,(fres)
  1851.         ld ix,(fres+2)
  1852.         ;xor a
  1853.         ret
  1854. BDOS_getfiletime_zero
  1855.         ;xor a
  1856.         ;ld l,a
  1857.         ;ld h,a
  1858.         ;push hl
  1859.         ;pop ix
  1860. BDOS_gettime
  1861. ;out: ix=date, hl=time
  1862.                 if atm==1
  1863.                         call readtime
  1864.                 endif
  1865.         ld hl,(sys_time_date) ;ok
  1866.         ld ix,(sys_time_date+2) ;ok
  1867.         ret
  1868.        
  1869.  
  1870. BDOS_setfiletime
  1871. ;de=Drive/path/file ASCIIZ string, ix=date, hl=time
  1872.         call BDOS_preparedepage
  1873.         call BDOS_setdepage ;TODO убрать в драйвер
  1874.         push hl ;time
  1875.         push ix ;date
  1876.         pop bc ;date
  1877. ;de=name
  1878. ;bc=date
  1879. ;stack=time
  1880.         F_UTIME_CURDRV
  1881.         pop bc
  1882.         ret
  1883.        
  1884. BDOS_seekhandle
  1885. ;                    B = File handle
  1886. ;                    [A = Method code: 0=begin,1=cur,2=end]
  1887. ;                DE:HL = Signed offset
  1888. ;     Results:       A = Error
  1889. ;                DE:HL = New file pointer
  1890.         bit 6,b
  1891.         jr nz,BDOS_seekhandle_noFATFS
  1892.         push de ;HSW
  1893.         push hl ;LSW
  1894.         call BDOS_number_to_fil ;de=fil
  1895.         F_LSEEK_CURDRV        
  1896.         pop bc
  1897.         pop bc
  1898.         ret
  1899. BDOS_seekhandle_noFATFS
  1900.         push bc
  1901.         BDOSSETPGTRDOSFS
  1902.         pop bc
  1903.         jp trdos_seekhandle
  1904.  
  1905. BDOS_getfilesize
  1906. ;b=handle
  1907. ;out: dehl=filesize
  1908.         bit 6,b
  1909.         jr nz,BDOS_getfilesize_noFATFS
  1910.         call BDOS_number_to_fil ;de=fil
  1911. BDOS_getfilesize_filde
  1912.         ld hl,FIL.FSIZE
  1913.         jr BDOS_tellhandleq
  1914.         ;add hl,de
  1915.         ;ld e,(hl)
  1916.         ;inc hl
  1917.         ;ld d,(hl)
  1918.         ;inc hl
  1919.         ;ld a,(hl)
  1920.         ;inc hl
  1921.         ;ld h,(hl)
  1922.         ;ld l,a
  1923.         ;ex de,hl
  1924.         ;xor a
  1925.         ;ret
  1926. BDOS_getfilesize_noFATFS
  1927.         push bc
  1928.         BDOSSETPGTRDOSFS
  1929.         pop bc
  1930.         jp trdos_getfilesize ;dehl=filesize
  1931.  
  1932. BDOS_tellhandle
  1933. ;b=file handle, out: dehl=offset
  1934. ;TODO TR-DOS
  1935.         call BDOS_number_to_fil ;de=fil
  1936.         ld hl,FIL.FPTR
  1937. BDOS_tellhandleq
  1938.         call BDOS_setpgstructs
  1939.         add hl,de
  1940.         ld c,(hl)
  1941.         inc hl
  1942.         ld b,(hl)
  1943.         inc hl
  1944.         ld e,(hl)
  1945.         inc hl
  1946.         ld d,(hl)
  1947.         ld h,b
  1948.         ld l,c
  1949.         xor a
  1950.         ret
  1951.        
  1952. BDOS_createhandle
  1953. ;DE = Drive/path/file ASCIIZ string
  1954. ;A = Open mode. b0 set => no write, b1 set => no read, b2 set => inheritable, b3..b7   -  must be clear
  1955. ;B = b0..b6 = Required attributes, b7 = Create new flag
  1956. ;out: B = new file handle, A=error
  1957.         ld c,a
  1958.         ld a,'w'
  1959.         LD HL,FA_READ|FA_WRITE|FA_CREATE_ALWAYS
  1960.         jr BDOS_openorcreatehandle
  1961.  
  1962. BDOS_openhandle
  1963. ;DE = Drive/path/file ASCIIZ string
  1964. ;[A = Open mode. b0 set => no write, b1 set => no read, b2 set => inheritable, b3..b7   -  must be clear]
  1965. ;out: B = new file handle, A=error
  1966.         ld c,a
  1967.         ld a,'r'
  1968.         ld hl,FA_READ|FA_WRITE
  1969. BDOS_openorcreatehandle
  1970.         ld (BDOS_openorcreatehandle_trdosmode),a
  1971.         ld (.mode),hl
  1972.         call BDOS_preparedepage
  1973.         call BDOS_setdepage ;TODO убрать в драйвер
  1974. ;DE = Drive/path/file ASCIIZ string
  1975.         call countfiledrive ;a=volume, de=path without drive, c=1: drive in path, CY=TR-DOS
  1976.         jr c,BDOS_openhandle_noFATFS
  1977.         cp vol_pipe
  1978.         jr z,BDOS_openhandle_pipe
  1979.                 ld (.store_a),a
  1980.         push de
  1981.          ;dec c ;was c=1: drive in path
  1982.          ;call z,BDOS_setvol_rootdir ;drive specified in path
  1983.         call findfreeffile
  1984.          jr nz,$ ;TODO error
  1985.         push bc
  1986.         call BDOS_setdepage ;TODO убрать в драйвер????
  1987.         pop bc
  1988.         ld a,b
  1989.         ex de,hl ;a=fil number, de=poi to FIL
  1990.         pop bc
  1991.         push af
  1992. .mode=$+1
  1993.         LD HL,FA_READ|FA_WRITE
  1994. .store_a=$+1
  1995.                 ld a,0
  1996.         F_OP
  1997.         pop bc ;b=fil number=new file handle
  1998.          ret
  1999.  
  2000. BDOS_openhandle_noFATFS
  2001. ;a=drive
  2002. ;recode file name
  2003.         ;pop af ;z=drive in path
  2004.        push af ;drive
  2005.         BDOSSETPGTRDOSFS
  2006.         ex de,hl ;hl=path
  2007.         call findlastslash. ;de=after last slash or beginning of path
  2008.         ld hl,BDOS_parse_filename_cpmnamebuf
  2009.         push hl
  2010.         call dotname_to_cpmname ;de -> hl ;out: de=pointer to termination character, hl=buffer filled in
  2011.         ;BDOSSETPGTRDOSFS
  2012.         pop de
  2013. BDOS_openorcreatehandle_trdosmode=$+1
  2014.         ld c,'r'
  2015.        pop af ;drive
  2016.         call nfopen ;hl=trdosfcb
  2017.         ld b,h ;new file handle
  2018.         ret
  2019.  
  2020. BDOS_openhandle_pipe
  2021. ;find free pipe
  2022.         ld hl,freepipes
  2023.         xor a
  2024.         ld bc,MAXPIPES
  2025.         cpir
  2026.         jp nz,BDOS_fail
  2027.         dec hl
  2028.          inc (hl)
  2029.         inc (hl) ;opened once, used as stdin and as stdout, closed twice
  2030.         ld a,l
  2031.         add a,0xff&(-freepipes+PIPEADD80)
  2032.         push af ;a=handle
  2033. ;a = PIPEADD80+pipeindex
  2034.         call findpipe_byhandle ;hl=pipe
  2035.         xor a
  2036.         ld (hl),a ;size=0
  2037.         pop bc ;b=handle
  2038. ;b=new pipe handle
  2039.         ret
  2040.  
  2041. BDOS_number_to_fil
  2042. ;b = file handle = 0..
  2043. ;out: de=fil
  2044.         inc b
  2045.         ld hl,ffilearray-FIL_sz
  2046.         ld de,FIL_sz
  2047. BDOS_number_to_fil0
  2048.         add hl,de
  2049.         djnz BDOS_number_to_fil0
  2050.         ex de,hl
  2051.         ret
  2052.        
  2053. BDOS_closehandle
  2054. ;B = file handle
  2055. ;out: A=error
  2056.         bit 7,b
  2057.         jr nz,BDOS_closehandle_pipe
  2058.         bit 6,b
  2059.         jr nz,BDOS_closehandle_noFATFS
  2060.         call BDOS_number_to_fil
  2061. ;de=fil
  2062.         F_CLOS_CURDRV
  2063.         ret
  2064. BDOS_closehandle_noFATFS
  2065.         ld h,b
  2066.         ld l,0
  2067.         BDOSSETPGTRDOSFS
  2068.         jp trdos_fclose_hl
  2069.  
  2070. BDOS_closehandle_pipe
  2071. ;B = file handle
  2072.         inc b
  2073.         ret z ;0xff=rnd
  2074.         ld hl,freepipes-1-PIPEADD80
  2075.         ld c,b
  2076.         xor a
  2077.         ld b,a
  2078.         add hl,bc
  2079.         dec (hl)
  2080.         ret p
  2081.         inc (hl) ;чтобы терминал не думал, а закрывал оба пайпа дважды
  2082.         ret
  2083. freepipes
  2084.         ds MAXPIPES
  2085.  
  2086.        
  2087. BDOS_readwritehandleprepare
  2088. ;b=handle, hl=number of bytes, de=addr
  2089. ;out: hl=fil, de=number of bytes, bc=addr(0x8000+)
  2090.         push hl ;Number of bytes to read
  2091.         push de ;Buffer address
  2092.         call BDOS_number_to_fil ;de=fil
  2093.         ex de,hl ;hl=FIL
  2094.         pop de ;Buffer address
  2095.         call BDOS_preparedepage
  2096.          call BDOS_setdepage ;TODO убрать в драйвер (или уже убрано?)
  2097.         ld b,d
  2098.         ld c,e
  2099.         pop de ;Number of bytes to read
  2100.         ret
  2101.        
  2102. BDOS_readhandle
  2103. ;B = file handle
  2104. ;DE = Buffer address
  2105. ;HL = Number of bytes to read
  2106. ;out: HL = Number of bytes actually read, A=error
  2107.         dec hl
  2108.          ld a,h
  2109.         inc hl
  2110.          cp 0x40
  2111.          jr c,BDOS_readhandlego
  2112.         push hl
  2113.         ld hl,BDOS_readhandlego
  2114. BDOS_readwritehandle
  2115.         ld (BDOS_readwritehandle_proc),hl
  2116.         pop hl
  2117.         ld (BDOS_readwritehandle_oldaddr),de
  2118. BDOS_readwritehandle0
  2119.         push bc
  2120.         push hl
  2121.         push de ;addr
  2122.          dec hl
  2123.          ld a,h
  2124.          inc hl
  2125.          cp 0x40
  2126.          jr c,$+5 ;<=0x4000
  2127.          ld hl,0x4000
  2128.          push hl ;bytes to process
  2129.         ;call BDOS_readwritehandlego ;hl=processed bytes
  2130. BDOS_readwritehandle_proc=$+1
  2131.         call BDOS_readhandlego
  2132. ;TODO что делать, если возвратилось hl==0 или a!=0?
  2133.         ;ex af,af' ;error
  2134.         ;jr $
  2135.          pop bc ;bytes to process
  2136.          or a
  2137.          sbc hl,bc
  2138.          ld a,h
  2139.          or l
  2140.          add hl,bc ;z=all bytes were processed
  2141.         ld b,h
  2142.         ld c,l
  2143.         pop hl ;addr
  2144.         add hl,bc ;+processed bytes
  2145.         ex de,hl ;de = new addr
  2146.         pop hl
  2147.         or a
  2148.         sbc hl,bc ;-processed bytes
  2149.         pop bc
  2150.         jr z,BDOS_readwritehandleq ;0 bytes remain
  2151.         jr c,BDOS_readwritehandleq ;less than 0 bytes remain
  2152.         ;jr nc,BDOS_readwritehandle0 ;no less than 0 bytes remain
  2153.          or a
  2154.         jr z,BDOS_readwritehandle0 ;all bytes were processed
  2155. BDOS_readwritehandleq
  2156. ;0 bytes remain
  2157. ;de=end address
  2158.         ld h,d
  2159.         ld l,e
  2160. BDOS_readwritehandle_oldaddr=$+1
  2161.         ld bc,0
  2162.         xor a ;no error
  2163.         sbc hl,bc ;hl=processed bytes
  2164.         ;ex af,af' ;error
  2165.         jr BDOS_readhandle_errorfromEOF ;ret
  2166. ;BDOS_readwritehandlego
  2167. ;BDOS_readwritehandle_proc=$+1
  2168. ;        jp BDOS_readhandlego
  2169. BDOS_readhandlego
  2170. ;b=handle
  2171.         bit 7,b
  2172.         jr nz,BDOS_readhandle_pipe
  2173.         bit 6,b
  2174.         jr nz,BDOS_readhandle_noFATFS
  2175.         call BDOS_readwritehandleprepare
  2176. ;hl=fil, de=number of bytes, bc=addr(0x8000+)
  2177.         ld ix,fres
  2178.         push ix ;fres
  2179.         push de ;blocksize
  2180.         ex de,hl;ld de,ffile
  2181.         F_READ_CURDRV
  2182.         pop bc
  2183.         pop bc ;fres
  2184.         ld hl,(fres) ;hl=total processed bytes
  2185. BDOS_readhandle_errorfromEOF
  2186.         ;xor a ;no error
  2187.          ld a,h
  2188.          or l
  2189.          ld a,0
  2190.          ret nz
  2191.          dec a
  2192.         ret
  2193. BDOS_readhandle_noFATFS
  2194.         push bc
  2195.         BDOSSETPGTRDOSFS
  2196.         pop bc
  2197.         jp trdos_fread_b ;hl=total processed bytes, A=error
  2198.  
  2199. BDOS_writehandle
  2200. ;B = file handle
  2201. ;DE = Buffer address
  2202. ;HL = Number of bytes to write
  2203. ;out: HL = Number of bytes actually written, A=error
  2204.          ld a,h
  2205.          cp 0x40
  2206.          jr c,BDOS_writehandlego
  2207.         push hl
  2208.         ld hl,BDOS_writehandlego
  2209.         jr BDOS_readwritehandle
  2210. BDOS_writehandlego
  2211. ;B = file handle
  2212. ;DE = Buffer address
  2213. ;HL = Number of bytes to write <= 0x4000
  2214. ;out: HL = Number of bytes actually written, A=error
  2215.         bit 7,b
  2216.         jp nz,BDOS_writehandle_pipe
  2217.         bit 6,b
  2218.         jr nz,BDOS_writehandle_noFATFS
  2219.         call BDOS_readwritehandleprepare
  2220.         ld ix,fres
  2221.         push ix ;fres
  2222.         push de ;blocksize
  2223.         ex de,hl;ld de,ffile
  2224.         F_WRITE_CURDRV
  2225.         pop bc
  2226.         pop bc ;fres
  2227.         ld hl,(fres) ;hl=total processed bytes
  2228.         xor a ;a=0: no error
  2229.         ret
  2230. BDOS_writehandle_noFATFS
  2231.         push bc
  2232.         BDOSSETPGTRDOSFS
  2233.         pop bc
  2234.         jp trdos_fwrite_b ;hl=total processed bytes, a=0: no error
  2235.  
  2236. BDOS_readhandle_pipe
  2237. ;B = file handle
  2238. ;DE = Buffer address
  2239. ;HL = Number of bytes to write <= 0x4000
  2240. ;out: HL = Number of bytes actually written, A=error
  2241. ;TODO check EOF (input closed)
  2242.         push bc
  2243.         call BDOS_preparedepage
  2244.         call BDOS_setdepage
  2245.         pop af ;a=handle
  2246.         cp 0xff
  2247.         jr nz,BDOS_readhandle_pipe_nrnd
  2248.         ld a,r
  2249.         ld (de),a
  2250.         ld hl,1
  2251.         xor a ;no error
  2252.         ret
  2253. BDOS_readhandle_pipe_nrnd
  2254. ;a = PIPEADD80+pipeindex
  2255.          ld (BDOS_readhandle_pipe_handle),a
  2256.         call findpipe_byhandle ;bc=number of bytes
  2257. ;читаем из текущей головы столько байт, сколько есть, но не больше number of bytes
  2258. ;пока делаем, что вся очередь лежит в начале (не атомарно)
  2259.          ld (BDOS_readhandle_pipe_addr),hl
  2260.         ld a,(hl) ;cur_size
  2261.         inc hl
  2262.        push hl ;buf start
  2263.         ld l,a
  2264.         ld h,0
  2265.         call minhl_bc_tobc ;to_user_size=bc<=hl
  2266.        pop hl ;buf start
  2267. ;
  2268.         ex af,af'
  2269.        ld a,b
  2270.        or c
  2271.        jr z,BDOS_readhandle_pipe_empty
  2272.        ex af,af'
  2273.        push bc ;to_user_size
  2274.         ldir ;to user
  2275.        pop bc ;to_user_size
  2276.         ex de,hl
  2277.         ld l,a
  2278.         xor a
  2279.         ld h,a
  2280.        push bc ;to_user_size
  2281. ;bc=cur_size-to_user_size
  2282.         sbc hl,bc
  2283.         ld b,h
  2284.         ld c,l
  2285.         ex de,hl
  2286. BDOS_readhandle_pipe_addr=$+1
  2287.         ld de,0
  2288.          ld a,c
  2289.          ld (de),a
  2290.          inc de
  2291.         jr z,$+4
  2292.         ldir ;на начало очереди
  2293.        pop hl ;to_user_size ;возвращаем, сколько реально прочитано
  2294.         xor a ;no error
  2295.         ret
  2296. BDOS_readhandle_pipe_empty
  2297. ;проверяем, что нет EOF (т.е. не закрыла пишущая сторона)
  2298.         ld hl,freepipes-PIPEADD80
  2299. BDOS_readhandle_pipe_handle=$+1
  2300.         ld bc,0 ;PIPEADD80+pipeindex
  2301.         add hl,bc
  2302.         ld a,(hl) ;2=both sides open, 1=one side closed
  2303.         sub 2 ;a=error
  2304.         ld h,b
  2305.         ld l,b ;0 ;возвращаем, сколько реально прочитано
  2306.         ret
  2307.        
  2308. findpipe_byhandle
  2309.         sub PIPEADD80-1
  2310.         ld b,a
  2311.         push hl ;number of bytes
  2312.         push de ;user space
  2313.         ld de,PIPEDESC_SZ
  2314.         ld hl,pipebufs-PIPEDESC_SZ
  2315.         add hl,de
  2316.         djnz $-1
  2317.         pop de ;user space
  2318.         pop bc ;bc=number of bytes
  2319.         ret
  2320.  
  2321. BDOS_writehandle_pipe
  2322. ;b=handle, hl=number of bytes, de=addr
  2323.         push bc
  2324.         call BDOS_preparedepage
  2325.         call BDOS_setdepage
  2326.         pop af ;a=handle
  2327.         cp 0xff
  2328.         ret z ;rnd - fail
  2329. ;a = PIPEADD80+pipeindex
  2330.          ld (BDOS_writehandle_pipe_handle),a
  2331.         call findpipe_byhandle ;bc=number of bytes
  2332. ;добавляем в текущий хвост столько байт, сколько есть, но чтобы не превысило размер буфера
  2333. ;пока делаем, что вся очередь лежит в начале (не атомарно)
  2334.          ld (BDOS_writehandle_pipe_addr),hl
  2335.         ld a,(hl) ;cur_size
  2336.         inc hl
  2337.         push af
  2338.         add a,l
  2339.         ld l,a
  2340.         jr nc,$+3
  2341.         inc h
  2342.         pop af
  2343.         push hl ;tail
  2344.         ld hl,PIPEBUF_SZ
  2345.         push bc ;bc=number of bytes
  2346.         ld c,a
  2347.         xor a
  2348.         ld b,a
  2349.         sbc hl,bc ;оставшееся место в буфере
  2350.         pop bc ;bc=number of bytes
  2351.         call minhl_bc_tobc ;from_user_size=bc<=hl
  2352. BDOS_writehandle_pipe_addr=$+1
  2353.          ld hl,0
  2354.          ld a,(hl) ;cur_size
  2355.          add a,c ;from_user_size
  2356.          ld (hl),a ;cur_size
  2357.         ex de,hl ;hl=user space
  2358.         pop de ;tail
  2359.         ld a,b
  2360.         or c
  2361.         jr z,BDOS_readhandle_pipe_full
  2362.         push bc ;from_user_size
  2363.         ldir ;from user
  2364.         pop hl ;from_user_size ;возвращаем, сколько реально записано
  2365.         xor a ;no error
  2366.         ret
  2367. BDOS_readhandle_pipe_full
  2368. ;проверяем, что не закрыла читающая сторона
  2369.         ld hl,freepipes-PIPEADD80
  2370. BDOS_writehandle_pipe_handle=$+1
  2371.         ld bc,0 ;PIPEADD80+pipeindex
  2372.         add hl,bc
  2373.         ld a,(hl) ;2=both sides open, 1=one side closed
  2374.         sub 2 ;a=error
  2375.         ld h,b
  2376.         ld l,b ;0 ;возвращаем, сколько реально записано
  2377.         ret
  2378.        
  2379. minhl_bc_tobc
  2380.         or a
  2381.         sbc hl,bc
  2382.         add hl,bc
  2383.         ret nc ;bc<=hl
  2384.         ld b,h
  2385.         ld c,l
  2386.         ret
  2387.  
  2388.  
  2389. BDOS_fopen_getname_fil
  2390. ;out: de=poi to FIL, bc=mfil
  2391.         push de
  2392.         call get_name ;->mfil
  2393.         pop de
  2394.         call findfreeffile
  2395.          jr nz,$ ;TODO error
  2396.         ex de,hl ;de=poi to FIL
  2397.         LD bc,mfil
  2398.         jp nz,BDOS_pop2fail ;снимаем адрес возврата и FCB
  2399.         ret
  2400.        
  2401. BDOS_fopen
  2402.         call BDOS_preparedepage
  2403.         call BDOS_setdepage ;TODO убрать в драйвер
  2404. ;de = pointer to unopened FCB
  2405.         GETVOLUME
  2406.         ld (de),a ;volume
  2407.         cp vol_trdos ;CHECKVOLUMETRDOS
  2408.         jr c,BDOS_fopen_noFATFS
  2409.         push de ;FCB
  2410.         call BDOS_fopen_getname_fil ;de=poi to FIL, bc=mfil
  2411.         LD HL,FA_READ|FA_WRITE
  2412.         jr BDOS_fopen_go
  2413. BDOS_fopen_noFATFS
  2414. ;a=drive
  2415.        push af
  2416.         BDOSSETPGTRDOSFS
  2417.        pop af
  2418.         jp trdos_fopen
  2419.  
  2420. BDOS_fcreate
  2421.         call BDOS_preparedepage
  2422.         call BDOS_setdepage ;TODO убрать в драйвер
  2423. ;DE = Pointer to unopened FCB
  2424.         GETVOLUME
  2425.         ld (de),a ;volume
  2426.         cp vol_trdos ;CHECKVOLUMETRDOS
  2427.         jr c,BDOS_fcreate_noFATFS
  2428.         push de ;FCB
  2429.         call BDOS_fopen_getname_fil ;de=poi to FIL, bc=mfil
  2430.         LD HL,FA_READ|FA_WRITE|FA_CREATE_ALWAYS
  2431. BDOS_fopen_go
  2432.         ;F_OPEN ffile,mfil,FA_READ|FA_WRITE|FA_CREATE_ALWAYS
  2433.         ;LD de,ffile
  2434.         push de ;FIL
  2435.         F_OPEN_CURDRV
  2436.         pop de ;FIL
  2437.         pop bc ;FCB
  2438.         or a
  2439.         ret nz ;error
  2440. ;BDOS_fopen_OK
  2441. ;de=ffile (FIL)
  2442. ;bc=FCB
  2443.         ;ld iy,(appaddr)
  2444.         ;GETVOLUME
  2445.         ;ld (bc),a ;volume
  2446.         ld hl,FCB_FFSFCB
  2447.         add hl,bc
  2448.         push af
  2449.         call BDOS_setdepage
  2450.         pop af
  2451.         ld (hl),e
  2452.         inc hl
  2453.         ld (hl),d
  2454.         ret
  2455. BDOS_fcreate_noFATFS
  2456.        push af
  2457.         BDOSSETPGTRDOSFS
  2458.        pop af
  2459.         jp trdos_fcreate
  2460.  
  2461. getFILfromFCB
  2462. ;de=FCB (страницы уже включены)
  2463. ;out: hl=FIL
  2464.         ld hl,FCB_FFSFCB
  2465.         add hl,de
  2466.         ld a,(hl)
  2467.         inc hl
  2468.         ld h,(hl)
  2469.         ld l,a ;hl = poi to FIL
  2470.         ret
  2471.        
  2472. BDOS_fclose
  2473.         call BDOS_preparedepage
  2474.         call BDOS_setdepage ;TODO убрать в драйвер
  2475. ;DE = Pointer to opened FCB (для FATFS придётся игнорировать, брать текущий ffile - TODO искать подходящий ffile)
  2476.         ;CHECKVOLUMETRDOS
  2477.         ld a,(de)
  2478.         cp vol_trdos
  2479.         jr c,BDOS_fclose_noFATFS
  2480.         ;F_CLOSE ffile ;сам освобождает FIL
  2481.         call getFILfromFCB
  2482.         ex de,hl
  2483.         F_CLOS_CURDRV
  2484. ;TODO убрать poi to FIL из FCB?
  2485.         ;or a:jp z,fexit
  2486.         ;ld a,0xff
  2487.         ret;jp fexit
  2488. BDOS_fclose_noFATFS
  2489.         BDOSSETPGTRDOSFS
  2490.         jp trdos_fclose
  2491.  
  2492.  
  2493. call_ffs_curvol
  2494.                 GETVOLUME
  2495. call_ffs        ;A=логический раздел, HL=функция
  2496. ;портит iy! но нельзя двигать стек! в нём параметры!
  2497.                 push hl
  2498.                 push bc
  2499.         ld hl,fatfsarray ;вычисляем указатель на структуру fatfs
  2500.                 sub vol_trdos
  2501.         ;or a
  2502.         jr z,.fix_vol_dir
  2503.         ld bc,FATFS_sz
  2504. .calcfatfs
  2505.         add hl,bc
  2506.         dec a
  2507.         jr nz,.calcfatfs
  2508. .fix_vol_dir    ;устанавливаем текущие fatfs и директорию
  2509.                 BDOSSETPGFATFS
  2510.         ld (fatfs_org+FFS_DRV.curr_fatfs),hl
  2511.          ld l,(iy+app.dircluster)
  2512.          ld h,(iy+app.dircluster+1)
  2513.         ld (fatfs_org+FFS_DRV.curr_dir0),hl
  2514.          ld l,(iy+app.dircluster+2)
  2515.          ld h,(iy+app.dircluster+3)
  2516.         ld (fatfs_org+FFS_DRV.curr_dir2),hl
  2517.                 call BDOS_setpgstructs 
  2518.                 pop bc
  2519.                 ret             ;уходим в фатфс
  2520.  
  2521.                
  2522. BDOS_mount
  2523. ;e=logical volume(char A-Z)
  2524. ;out: a!=0 => not mounted
  2525.                 ld a,e
  2526.                 and 0xdf
  2527.                 sub 'A'
  2528.                 ret c
  2529.                 cp 26
  2530.                 ret nc
  2531.                 sub vol_trdos
  2532.         jr c,.noFATFS
  2533.                 ld e,a
  2534.         BDOSSETPGFATFS
  2535.                 call BDOS_setpgstructs
  2536.         ld hl,fatfsarray ;вычисляем указатель на структуру fatfs
  2537.         ld a,e
  2538.                 or a
  2539.         jr z,.fix_ffs
  2540.         ld bc,FATFS_sz
  2541. .calcfatfs
  2542.         add hl,bc
  2543.         dec a
  2544.         jr nz,.calcfatfs
  2545. .fix_ffs
  2546.         ld (fatfs_org+FFS_DRV.curr_fatfs),hl ;l
  2547.                 inc hl
  2548.                 ld a,e
  2549.                 cp 8
  2550.                 jr c,.isHDD
  2551.                 sub 6
  2552.                 ld (hl),a       ;номер драйва
  2553.                 xor a
  2554.                 jr .f_mnt
  2555. .isHDD         
  2556.                 srl e
  2557.                 srl e
  2558.                 ld (hl),e       ;номер драйва
  2559.                 and %00000011
  2560. .f_mnt
  2561.                 inc hl
  2562.                 ld (hl),a       ;номер раздела
  2563.                 F_MNT
  2564.                 ret
  2565. .noFATFS
  2566.         xor a ;xor a ;NC:success, CY:fail
  2567.         ret;jr rest_exit
  2568.                         display "BDOS_setsysdrv ",BDOS_setsysdrv
  2569. BDOS_setsysdrv
  2570. SYSDRV_VAL=$+1
  2571.         ld e,SYSDRV
  2572.          call BDOS_setdrv
  2573.          ld de,syspath
  2574.          jp setpath
  2575.  
  2576. BDOS_preparereadwritesectors_FATFS
  2577.         sub vol_trdos ;получаем физический номер устройства (HDD master, HDD slave, SD...)
  2578.         push af
  2579.         BDOSSETPGFATFS
  2580.         call BDOS_setdepage
  2581.         pop af
  2582.         push ix
  2583.         pop bc
  2584.         ex de,hl ;bcde=sector number, hl=buffer
  2585. ;hl=buffer
  2586. ;a=drive
  2587. ;bcde=sector
  2588. ;a'=count
  2589.         ret
  2590.  
  2591. BDOS_preparereadwritesectors_TRDOSFS
  2592.          push af
  2593.         BDOSSETPGTRDOSFS
  2594.          pop af
  2595.         ld (trdoscurdrive),a
  2596.         ld a,l
  2597.         add hl,hl
  2598.         add hl,hl
  2599.         add hl,hl
  2600.         add hl,hl
  2601.         ex de,hl ;hl=buffer, d=track
  2602.         and 0x0f
  2603.         ld e,a ;e=sector
  2604.         ex af,af'
  2605.        ld b,a ;count
  2606. ;hl=buffer
  2607. ;d=track
  2608. ;e=sector
  2609. ;b=count
  2610.        ret
  2611.  
  2612. BDOS_readsectors
  2613. ;b=drive(0..), de=buffer, ixhl=sector number, a'=count
  2614. ;передавать логический volume (букву) и пересчитать в номер драйвера (в смещение раздела, наверно, бессмысленно)?
  2615.         push bc
  2616.         call BDOS_preparedepage
  2617.         pop af
  2618.         cp vol_trdos
  2619.         jr c,BDOS_readsectors_TRDOS
  2620.         call BDOS_preparereadwritesectors_FATFS
  2621.         jp devices_read_go_regs
  2622. BDOS_readsectors_TRDOS
  2623.         call BDOS_preparereadwritesectors_TRDOSFS
  2624.         jp wrsectors. ;out: a=error?
  2625.  
  2626. BDOS_writesectors
  2627. ;b=drive(0..), de=buffer, ixhl=sector number, a'=count
  2628. ;передавать логический volume (букву) и пересчитать в номер драйвера (в смещение раздела, наверно, бессмысленно)?
  2629.         push bc
  2630.         call BDOS_preparedepage
  2631.         pop af
  2632.         cp vol_trdos
  2633.         jr c,BDOS_writesectors_TRDOS
  2634.         call BDOS_preparereadwritesectors_FATFS
  2635.         jp devices_write_go_regs
  2636. BDOS_writesectors_TRDOS
  2637.         call BDOS_preparereadwritesectors_TRDOSFS
  2638.         jp rdsectors. ;out: a=error?
  2639.  
  2640. BDOS_setdrv
  2641. ;e=volume
  2642. ;out: a!=0 => not mounted (TODO), [l=number of volumes]
  2643. ;мы не должны монтировать, просто должны указать volume, текущий для данной задачи, и сбросить path, текущий для данной задачи
  2644.         ld a,e
  2645.         ;call BDOS_setvol_rootdir
  2646.         ;call BDOS_opencurdir ;эта операция нужна для определения смонтированности (F_MNT всегда возвращает 0)
  2647.         ;or a
  2648.         ;jr nc,BDOS_setdrvnfail
  2649.         ; ld (iy+app.vol),d
  2650. ;BDOS_setdrvnfail
  2651.          
  2652.         ;ld l,NVOLUMES ;доступно 8 драйвов???
  2653.         ;xor a ;success
  2654.         ;ret;jr rest_exit
  2655.        
  2656. ;BDOS_setvol_rootdir
  2657. ;установлена страница PGFATFS
  2658.           ld d,(iy+app.vol)
  2659.          ld (iy+app.vol),a
  2660. ;BDOS_setrootdir
  2661. ;не установлена страница PGFATFS
  2662. ;CY=error (при NC a=0) - TODO убрать?
  2663.          xor a
  2664.          ld h,a
  2665.          ld l,a
  2666.          call writedircluster_hl
  2667.          ;ld (iy+app.dircluster),a
  2668.          ;ld (iy+app.dircluster+1),a
  2669.          ld (iy+app.dircluster+2),a
  2670.          ld (iy+app.dircluster+3),a
  2671.         CHECKVOLUMETRDOS
  2672.         push de
  2673.         ;sbc a,a; ld a,0
  2674.         jr c,BDOS_setrootdir_trdos ;ret c ;NC=no error, A=0
  2675.                 ld bc,0 ; TCHAR *path   /* Pointer to the directory path */
  2676.         call BDOS_opencurdir ;эта операция нужна для определения смонтированности (F_MNT всегда возвращает 0)
  2677. BDOS_setrootdir_q
  2678.         pop de
  2679.         or a
  2680.         ret z ;NC=no error, A=0
  2681.          ld (iy+app.vol),d
  2682.          scf
  2683.         ret ;CY=error
  2684. BDOS_setrootdir_trdos
  2685.         push af
  2686.         BDOSSETPGTRDOSFS
  2687.         pop af
  2688.         call iodos_setdrive
  2689.         ;ld a,(eRR2) ;0=OK, 0xff=Abort
  2690.         jr BDOS_setrootdir_q
  2691.        
  2692. BDOS_delete
  2693. ;DE = Drive/path/file ASCIIZ string
  2694.         call BDOS_preparedepage
  2695.         call BDOS_setdepage ;TODO убрать в драйвер
  2696. ;DE = Pointer to ASCIIZ string
  2697.         call countfiledrive ;a=volume, de=path without drive, c=1: drive in path, CY=TR-DOS
  2698.         ;call eatdrive ;TODO keep and restore curdrv,curdir!!!
  2699.         jr c,BDOS_delete_nofatfs
  2700.         ;call keepvoldir
  2701.         ; dec c ;was c=1: drive in path
  2702.         ; push de
  2703.         ; call z,BDOS_setvol_rootdir ;drive specified in path
  2704.         ; pop de
  2705.         F_UNLINK
  2706.         ret        
  2707. BDOS_delete_nofatfs
  2708.         BDOSSETPGTRDOSFS
  2709.         jp trdos_delete
  2710.        
  2711. BDOS_rename
  2712. ;DE = Drive/path/file ASCIIZ string, HL = New filename ASCIIZ string (can contain drive/path! NOT MSXDOS)
  2713.         ex de,hl
  2714.         call BDOS_preparedepage ;TODO разные страницы hl,de (т.е. надо копировать отсюда в буфер)
  2715.         call BDOS_setdepage ;TODO убрать в драйвер
  2716.         ex de,hl
  2717.         call BDOS_preparedepage
  2718.         call BDOS_setdepage ;TODO убрать в драйвер
  2719.         CHECKVOLUMETRDOS
  2720.         jr c,BDOS_rename_nofatfs
  2721.         ld b,h
  2722.         ld c,l
  2723. ;DE = Drive/path/file ASCIIZ string, BC = New filename ASCIIZ string
  2724.         F_RENAME
  2725.         ret
  2726. BDOS_rename_nofatfs
  2727.         BDOSSETPGTRDOSFS
  2728.         jp trdos_rename
  2729.  
  2730. countfiledrive
  2731. ;DE = Drive/path/file ASCIIZ string
  2732. ;out: a=volume, de=path without drive, c=1: drive in path, CY=TR-DOS
  2733.         inc de
  2734.         ld a,(de)
  2735.         cp ':'
  2736.         dec de
  2737.          ld c,0
  2738.         ;push af ;z=drive in path
  2739.         GETVOLUME
  2740.         jr nz,BDOS_openhandle_nodriveinpath ;drive not specified in path
  2741.          ld a,(de)
  2742.          and 0xdf
  2743.          sub 'A'
  2744.          inc de
  2745.          inc de
  2746.         ;cp a ;z
  2747.          inc c
  2748. BDOS_openhandle_nodriveinpath
  2749. ;a=volume, de=path without drive, c=1: drive in path
  2750.         cp vol_trdos
  2751.         ret
  2752.        
  2753. BDOS_mkdir
  2754.         call BDOS_preparedepage
  2755.         call BDOS_setdepage ;TODO убрать в драйвер
  2756. ;DE = Pointer to ASCIIZ string
  2757.         call countfiledrive ;call eatdrive
  2758.         jp c,BDOS_fail
  2759. ;DE = Pointer to ASCIIZ string
  2760.         ;call keepvoldir
  2761.         ; dec c ;was c=1: drive in path
  2762.         ; push de
  2763.         ; call z,BDOS_setvol_rootdir ;drive specified in path
  2764.         ; pop de
  2765.         F_MKDIR
  2766.         ret
  2767.                
  2768. BDOS_chdir
  2769.         call BDOS_preparedepage
  2770.         call BDOS_setdepage ;TODO убрать в драйвер
  2771. ;DE = Pointer to ASCIIZ string
  2772.  
  2773. setpath
  2774. ;установлена страница PGFATFS
  2775. ;DE = Pointer to ASCIIZ string
  2776.         call countfiledrive ;call eatdrive
  2777.         jr c,BDOS_chdir_trdos
  2778.         push af
  2779.         ; dec c ;was c=1: drive in path
  2780.         ; call z,BDOS_setvol_rootdir ;drive specified in path
  2781.         F_CHDIR
  2782.         pop hl
  2783.         or a
  2784.         ret nz
  2785.                 ld (iy+app.vol),h
  2786.          ld hl,(fatfs_org+FFS_DRV.curr_dir2)
  2787.          ld (iy+app.dircluster+2),l
  2788.          ld (iy+app.dircluster+3),h
  2789.                  ;xor a
  2790.          ld hl,(fatfs_org+FFS_DRV.curr_dir0)
  2791.          ;ld (iy+app.dircluster),l
  2792.          ;ld (iy+app.dircluster+1),h
  2793.          ;ret
  2794. writedircluster_hl
  2795.         ld (iy+app.dircluster),l
  2796.         ld (iy+app.dircluster+1),h
  2797.         ret
  2798.        
  2799. BDOS_chdir_trdos
  2800.                 ld (iy+app.vol),a
  2801.                 xor a
  2802.         ;ld a,(de) ;путь пустой?
  2803.         ;or a
  2804.         ;jp nz,BDOS_fail ;непустой
  2805.         ret
  2806.  
  2807.         if 1==0
  2808. strlen
  2809. ;hl=str
  2810. ;out: hl=length
  2811.         xor a
  2812.         ld b,a
  2813.         ld c,a ;bc=0 ;чтобы точно найти терминатор
  2814.         cpir ;найдём обязательно, если длина=0, то bc=-1 и т.д.
  2815.         ld hl,-1
  2816.         ;or a
  2817.         sbc hl,bc
  2818.         ret
  2819.         endif
  2820.  
  2821. ;GET WHOLE PATH STRING (5EH)
  2822. ;     Parameters:    C = 5EH (_WPATH)
  2823. ;                   DE = Pointer to 64 byte (MAXPATH_sz!) buffer
  2824. ;     Results:       A = Error
  2825. ;                   DE = Filled in with whole path string
  2826. ;                   HL = Pointer to start of last item
  2827. ;This function simply copies an ASCIIZ path string from an internal buffer into the user's buffer. The string represents the whole path and filename, from the root ;directory, of a file or sub-directory located by a previous "find first entry" or "find new entry" function. [MSXDOS: The returned string will not include a drive, or an; ;initial "\" character.] Register HL will point at the first character of the last item on the string, exactly as for the "parse path" function (function 5Bh).
  2828. ;in NedoOS: DRIVE:/PATH/ !!!
  2829. BDOS_getpath
  2830.         push de ;нельзя после BDOS_preparedepage
  2831.         call BDOS_preparedepage
  2832.         call BDOS_setdepage ;TODO убрать в драйвер
  2833.         push de ;DE = Pointer to 64 byte (MAXPATH_sz!) buffer (0x8000+/0xc000+!)
  2834.  
  2835.         push de ;Pointer to 64 byte (MAXPATH_sz!) buffer (0x8000+/0xc000+!)
  2836.        
  2837.         GETVOLUME
  2838.         add a,'A'
  2839.         ex de,hl
  2840.         ld (hl),a
  2841.         inc hl
  2842.         ld (hl),':'
  2843.         inc hl
  2844.         ld (hl),'/'
  2845.         inc hl
  2846.         ld (hl),0
  2847.         cp vol_trdos+'A'
  2848.         jr c,BDOS_getpath_FATq
  2849.         ex de,hl
  2850. BDOS_getpath_FAT
  2851.         ;DE=TCHAR *path,        /* Pointer to the directory path */ буфер
  2852.         ld bc,MAXPATH_sz;64 ;BC=UINT sz_path    /* Size of path */) размер буфера
  2853.         F_GETCWD_CURDRV
  2854. BDOS_getpath_FATq
  2855.         pop hl ;Pointer to 64 byte (MAXPATH_sz!) buffer (0x8000+/0xc000+!)
  2856.         call findlastslash. ;NC!!!
  2857.         ex de,hl ;HL = Pointer to start of last item (0x8000+/0xc000+!)
  2858.        
  2859.         pop de ;DE = Pointer to 64 byte (MAXPATH_sz!) buffer (0x8000+/0xc000+!)
  2860.         ;or a
  2861.         sbc hl,de ;hl=расстояние до последнего слэша
  2862.         pop de ;DE = Pointer to 64 byte (MAXPATH_sz!) buffer
  2863.         add hl,de ;HL = Pointer to start of last item
  2864.         ret
  2865.  
  2866. ;hl = poi to filename in string
  2867. findlastslash.
  2868. ;hl=path string
  2869. ;out: de = after last slash (or start of path) ;NC!!!
  2870. nfopenfnslash.
  2871.         ld d,h
  2872.         ld e,l ;de = after last slash
  2873. ;find last slash
  2874. nfopenfnslash0.
  2875.         ld a,[hl]
  2876.         inc hl
  2877.         or a
  2878.         ret z;jr z,nfopenfnslashq. ;NC!!!
  2879.         cp '/'
  2880.         jr nz,nfopenfnslash0.
  2881.         jr nfopenfnslash.
  2882.  
  2883. ;PARSE FILENAME (5CH) - MSX-DOS
  2884. ;     Parameters:    C = 5CH (_PFILE)
  2885. ;                   DE = ASCIIZ string for parsing
  2886. ;                   HL = Pointer to 11 byte buffer
  2887. ;     Results:       A = Error (always zero)
  2888. ;                   DE = Pointer to termination character
  2889. ;                   HL = Preserved, buffer filled in
  2890. ;                    B = Parse flags (TODO)
  2891. ;b0 - set if any characters parsed other than drive name
  2892. ;b1 - set if any directory path specified
  2893. ;b2 - set if drive name specified
  2894. ;b3 - set if main filename specified in last item
  2895. ;b4 - set if filename extension specified in last item
  2896. ;b5 - set if last item is ambiguous
  2897. ;b6 - set if last item is "." or ".."
  2898. ;b7 - set if last item is ".."
  2899. BDOS_parse_filename
  2900.         BDOSSETPGTRDOSFS
  2901. ;делает из имени с точкой имя без точки (для CP/M)
  2902.         push hl ;Pointer to 11 byte buffer
  2903.  
  2904.         push de ;ASCIIZ string for parsing
  2905.         call BDOS_preparedepage
  2906.         call BDOS_setdepage ;TODO убрать в драйвер
  2907.         push de ;ASCIIZ string for parsing (0x8000+/0xc000+)
  2908.         ld hl,BDOS_parse_filename_cpmnamebuf
  2909.         call dotname_to_cpmname ;de -> hl
  2910.         ex de,hl ;de=Pointer to termination character (0x8000+/0xc000+)
  2911.         pop bc ;ASCIIZ string for parsing (0x8000+/0xc000+)
  2912.         or a
  2913.         sbc hl,bc ;hl=расстояние до терминатора
  2914.         pop bc ;ASCIIZ string for parsing
  2915.         add hl,bc ;Pointer to termination character
  2916.  
  2917.         pop de ;Pointer to 11 byte buffer
  2918.         push hl ;Pointer to termination character
  2919.  
  2920.         push de ;Pointer to 11 byte buffer
  2921.         call BDOS_preparedepage
  2922.         call BDOS_setdepage ;TODO убрать в драйвер
  2923.         ld hl,BDOS_parse_filename_cpmnamebuf
  2924.         ld bc,11
  2925.         ldir
  2926.         pop hl ;HL = Pointer to 11 byte buffer
  2927.  
  2928.         pop de ;DE = Pointer to termination character
  2929.         xor a
  2930.         ret
  2931.  
  2932. get_name
  2933. ;делает из имени без точки имя с точкой (для FATFS и для печати)
  2934. ;de(FCB)->hl
  2935.         inc de
  2936.         ex hl,de
  2937.         ld de,mfil
  2938. get_name_hltode
  2939.         ld b,7
  2940.         ld a,' '
  2941. get_name1
  2942.         ldi
  2943.         cp (hl)
  2944.         jr z,get_name_skipspaces
  2945.         djnz get_name1
  2946.         ldi
  2947.         jr get_name_findext ;скопировали 8 символов, пробел не нашли
  2948. get_name_skipspaces
  2949.         inc hl
  2950.         djnz $-1;1b ;пропускаем оставшиеся пробелы
  2951. get_name_findext
  2952.         cp (hl)
  2953.         jr z,get_name1f ;на месте расширения пробел - не ставим точку
  2954.         ex hl,de
  2955.         ld (hl),'.'
  2956.         inc hl
  2957.         ex hl,de
  2958.         ldi
  2959.         cp (hl)
  2960.         jr z,get_name1f
  2961.         ldi
  2962.         cp (hl)
  2963.         jr z,get_name1f
  2964.         ldi
  2965. get_name1f
  2966.         xor a
  2967.         ld (de),a
  2968.         ret
  2969.  
  2970. findfreeffile
  2971. ;out: nz=fail, hl=FIL, b=fil number
  2972.         call BDOS_setpgstructs
  2973.         ld hl,ffilearray
  2974.         ld de,FIL_sz
  2975.         ld b,0
  2976. findfreeffile0
  2977.         inc hl
  2978.         ld a,(hl) ;FS(HSB)
  2979.         dec hl
  2980.         or a
  2981.         ret z ;OK
  2982.         add hl,de
  2983.         inc b
  2984.         ;ld a,b
  2985.         ;cp MAXFILES
  2986.         ;jr nz,findfreeffile0
  2987.         ;or a ;nz
  2988.          ld a,MAXFILES-1
  2989.          cp b
  2990.          jr nc,findfreeffile0
  2991.          ;or a ;nz
  2992.         ret
  2993.        
  2994. movedma_addr
  2995.         ld iy,(appaddr)
  2996.         ;ld hl,(dma_addr) ;оригинальный, не пересчитанный адрес
  2997.         call BDOS_getdta
  2998.         ex de,hl
  2999.         add hl,bc
  3000.         ex de,hl
  3001.         ;ld (dma_addr),hl
  3002.         ;ret
  3003. BDOS_setdta
  3004.         ld (iy+app.dta),e
  3005.         ld (iy+app.dta+1),d
  3006.         ;ret
  3007. BDOS_getdta
  3008.         ld e,(iy+app.dta)
  3009.         ld d,(iy+app.dta+1)
  3010.         ret
  3011.  
  3012. ;***********************ЗАГЛУШКИ**************************     
  3013.  
  3014. ;копирование строки из\в юзерспейса в\из либу фатфс
  3015. strcpy_lib2usp  ;DE - dst, BC - src
  3016. strcpy_usp2lib
  3017.         push bc
  3018.         call BDOS_setdepage
  3019.         pop bc
  3020. strcpy_lib2usp0
  3021.         ld a,(bc)
  3022.         ld (de),a
  3023.         inc de
  3024.         inc bc
  3025.         or a
  3026.         jr nz,strcpy_lib2usp0
  3027.         ;BDOSSETPGFATFS
  3028.         ;jp BDOS_setpgstructs
  3029. BDOS_setpgstructs
  3030.         ld a,pgfatfs2
  3031.         jr sys_setpgc000
  3032.  
  3033. setmainpg_c000
  3034.         ld a,(iy+app.mainpg)
  3035.         jr sys_setpgc000
  3036.  
  3037. sys_setpgsscr
  3038.         ld a,(iy+app.screen)
  3039.         bit 3,a
  3040.         ld a,pgscr0_0
  3041.         jr z,$+4
  3042.         ld a,pgscr1_0
  3043.         ;ld bc,memport8000
  3044.         ;out (c),a
  3045.         call sys_setpg8000
  3046.         xor pgscr0_1^pgscr0_0 ;ld a,pgscr0_1
  3047.         ;ld b,memportc000_hi;0xff
  3048.         ;out (c),a
  3049.         jr sys_setpgc000
  3050.  
  3051. setpgs_killable
  3052.         ld a,pgkillable
  3053.         ld bc,memport4000
  3054.         ld (sys_curpg4000),a
  3055.         out (c),a
  3056.         ;ld b,memport8000_hi;0xbf
  3057.         ;out (c),a
  3058.         ;ld b,memportc000_hi;0xff
  3059.         ;out (c),a
  3060.         ;ret
  3061.         call sys_setpg8000
  3062. sys_setpgc000
  3063.         ld (sys_curpgc000),a
  3064.         ld bc,memportc000
  3065.         out (c),a
  3066.         ret
  3067.  
  3068. ;копирование в\из юзерспейса в\из структуру
  3069. memcpy_buf2usp  ;DE - dst, BC - src, на стеке count
  3070.         res 7,b ;src=buf
  3071.         jr memcpy_buf_go
  3072. memcpy_usp2buf
  3073.         res 7,d ;dst=buf
  3074. memcpy_buf_go
  3075.         push bc
  3076.         ld a,pgfatfs2;=pgstructs
  3077.         call sys_setpg4000
  3078.         pop bc
  3079.         jr memcpy_loop
  3080. ;копирование в\из юзерспейса в\из либу фатфс
  3081. memcpy_lib2usp  ;DE - dst, BC - src, на стеке count
  3082. memcpy_usp2lib
  3083. memcpy_loop
  3084.         push bc
  3085.         call BDOS_setdepage
  3086.         pop hl;bc
  3087.         ;ld h,b
  3088.         ;ld l,c
  3089.         pop af
  3090.         pop bc
  3091.         push bc
  3092.         push af
  3093.         ldir
  3094.         BDOSSETPGFATFS ;4000
  3095.         jp BDOS_setpgstructs
  3096.  
  3097. ;по числу драйвов FatFS (для TR-DOS не надо)
  3098. fatfsarray=0xc000
  3099.         ;display "fatfsarray=",fatfsarray
  3100.         ;ds 4*FATFS_sz
  3101.  
  3102. ffilearray=fatfsarray+(13*FATFS_sz)
  3103.         display "ffilearray_end=",ffilearray+(MAXFILES*FIL_sz)
  3104.         ;ds MAXFILES*FIL_sz
  3105.         ;dw 0x100 ;признак конца ffilearray
  3106.        
  3107. mfil    db "12345678.123",0 ;нужно только на время операции, которая принимает имя файла (может быть с путём?)
  3108.  
  3109. mfilinfo ds FILINFO_sz ;FILINFO ;нужно только на время findnext
  3110.  
  3111. fcb2    ds FCB_sz ;нужно только на время findnext
  3112.  
  3113. fres    dw 0 ;структура для возврата результата FatFS (число прочитанных/записанных байт)
  3114.         dw 0 ;для возврата даты
  3115.  
  3116. syspath
  3117.         db "bin",0
  3118.        
  3119. ;для TASiS: не используются страницы ОЗУ 0x00, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
  3120. ;для избежания гибернации: не используются страницы ОЗУ 128K
  3121. tsys_pages
  3122.         ds 8,0xff ;системные страницы
  3123.         if TOPDOWNMEM
  3124.         db 0,0,0,0
  3125.         else
  3126.         db 0xff,0xff,0xff,0xff
  3127.         endif
  3128.         db 0,0,0,0 ;0x08..0x0f
  3129.         db 0,0,0,0,0,0,0,0 ;0x10..0x17
  3130.         db 0,0,0,0xff,0xff,0xff,0xff,0xff ;0x18..0x1f
  3131.         ds sys_npages-32-4 ;0=empty, or else process number
  3132.         if TOPDOWNMEM
  3133.         db 0xff,0xff,0xff,0xff
  3134.         else
  3135.         db 0,0,0,0
  3136.         endif
  3137.  
  3138. pipebufs
  3139.         ds PIPEDESC_SZ*MAXPIPES
  3140.  
  3141.         display "$ before align=",$
  3142. ;TODO хранить прямо в текстовом экране? а если затрут, то восстанавливать? по какому событию?
  3143.         align 256
  3144. trecode
  3145.         incbin "../_sdk/codepage/866toatm"
  3146.