?login_element?

Subversion Repositories NedoOS

Rev

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

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