?login_element?

Subversion Repositories NedoOS

Rev

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