?login_element?

Subversion Repositories NedoOS

Rev

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