Subversion Repositories NedoOS

Rev

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

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