Subversion Repositories NedoOS

Rev

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

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