?login_element?

Subversion Repositories NedoOS

Rev

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

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