?login_element?

Subversion Repositories NedoOS

Rev

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

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