Subversion Repositories NedoOS

Rev

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

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