?login_element?

Subversion Repositories NedoOS

Rev

Rev 574 | Rev 598 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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