Subversion Repositories NedoOS

Rev

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