Subversion Repositories NedoOS

Rev

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

  1. TRUE=0xff
  2. FALSE=0x00
  3.  
  4. SECINBLK=32;16 ;TR-DOS reserves 16 sectors per block
  5. ;FILENAMESZ=9;10 for multi-block files (block # in +9)
  6.  
  7. _fin
  8.         ;EXPORT _fin
  9.         DW 0
  10. _fout
  11.         ;EXPORT _fout
  12.         DW 0
  13. ;_waseof
  14.         ;EXPORT _waseof
  15.         ;DB 0
  16.  
  17. TRDOSFCB=0
  18.         ;db 0 ;0 = free, 'r' = read, 'w' = write
  19. TRDOSFCB=TRDOSFCB+1
  20. ;;;;;;;;;;;;;;; copy of TR-DOS descriptor ;;;;;;;;;;;;;;
  21. TRDOSFCB.fn=TRDOSFCB
  22.         ;db "12345678c" ;filename
  23. TRDOSFCB=TRDOSFCB+9
  24. TRDOSFCB.block=TRDOSFCB
  25.         ;db 0 ;cur block for write, next block for read
  26.         ;db 0x60 ;(padding for "start")
  27. TRDOSFCB=TRDOSFCB+2
  28. TRDOSFCB.lastlen=TRDOSFCB
  29.         ;dw 0 ;length of block
  30. TRDOSFCB=TRDOSFCB+2
  31. TRDOSFCB.secinblk=TRDOSFCB
  32.         ;db 0 ;sectors remained in block (for read), block size (for write)
  33. TRDOSFCB=TRDOSFCB+1
  34. TRDOSFCB.firstsector=TRDOSFCB
  35.         ;dw 0 ;first sector of block (for write)
  36. TRDOSFCB=TRDOSFCB+2
  37. ;;;;;;;;;;;;;;; end of TR-DOS descriptor ;;;;;;;;;;;;;;
  38. TRDOSFCB.cursector=TRDOSFCB
  39.         ;dw 0 ;cur sector for write, next sector for read
  40. TRDOSFCB=TRDOSFCB+2
  41. TRDOSFCB.remain=TRDOSFCB
  42.         ;db 0xff ;remaining bytes in buf (for read)
  43. TRDOSFCB=TRDOSFCB+1
  44. TRDOSFCB.secwritten=TRDOSFCB
  45.         ;db 0 ;sectors written (for write)
  46. TRDOSFCB=TRDOSFCB+1
  47. TRDOSFCB.descpos=TRDOSFCB
  48.         ;db 0 ;position of descriptor (for write) 0..127
  49. TRDOSFCB=TRDOSFCB+1
  50. TRDOSFCB.waseof=TRDOSFCB
  51.         ;db 0 ;-1 = waseof
  52. TRDOSFCB=TRDOSFCB+1
  53. TRDOSFCB.drive=TRDOSFCB
  54.         ;db 0 ;-1 = waseof
  55. TRDOSFCB.buf=256;$-TRDOSFCB
  56.         ;ds 256 ;buffer for last sector
  57.  
  58.         ;align 256
  59. TRDOSFCB1=trdos_fcbbuf
  60.         ;ds 0x200*trdos_MAXFILES ;max 8 files
  61. DOSBUF=trdos_sectorbuf
  62.         ;ds 0x100
  63. ;TRDOSFCB2.=0x4a00 ;aligned
  64. ;TRDOSFCB3.=0x4c00 ;aligned
  65. ;TRDOSFCB4.=0x4e00 ;aligned
  66. ;TRDOSFCB5.=0x5000 ;aligned
  67. ;DOSBUF=0xff00 ;aligned
  68.  
  69.         if 1==0
  70. ;hl = poi to filename in string
  71. findlastslash.
  72. nfopenfnslash.
  73.         ld d,h
  74.         ld e,l ;de = after last slash
  75. ;find last slash
  76. nfopenfnslash0.
  77.         ld a,[hl]
  78.         inc hl
  79.         or a
  80.         jr z,nfopenfnslashq.
  81.         cp '/'
  82.         jr nz,nfopenfnslash0.
  83.         jr nfopenfnslash.
  84. nfopenfnslashq.
  85. ;de = after last slash
  86.         ret
  87.         endif
  88.  
  89. nfdel
  90. ;de=FCB
  91. ;TODO mask
  92.         inc de ;filename
  93. nfdel_filename
  94.         ld lx,0 ;number of files just deleted
  95.         ld b,8 ;sectors
  96. nfdelsectors0.
  97.         ld hx,0
  98.         push bc
  99.         push de ;filename
  100.         push ix
  101.         ld d,0 ;track
  102.         ld a,8
  103.         sub b
  104.         ld e,a ;sector
  105.         call rdsecDOSBUF
  106.         pop ix
  107.         pop de ;filename
  108.         pop bc
  109. ;de=filename
  110. ;b=sectors
  111.         ld hl,DOSBUF
  112. nfdelcp0.
  113.         push bc
  114.         push de ;filename
  115.         push hl ;DOSBUF+
  116.         ld bc,0x900 ;b=bytes to compare, c=errors
  117. nfdelcp00.
  118.         ld a,[de]
  119.         sub [hl]
  120.         or c
  121.         ld c,a ;errors
  122.         inc hl
  123.         inc de
  124.         djnz nfdelcp00.
  125.         pop hl ;DOSBUF+
  126.         pop de ;filename
  127.         pop bc
  128.         jr nz,nfdelcp_notthatfile
  129.         inc lx ;number of files just deleted
  130.         inc hx ;number of files just deleted in this sector
  131.         ld (hl),1 ;deleted
  132. nfdelcp_notthatfile
  133.         ld a,l
  134.         add a,16
  135.         ld l,a
  136.         jr nz,nfdelcp0. ;next descriptor
  137. ;was sector changed?
  138.         ld a,hx ;number of files just deleted in this sector
  139.         or a
  140.         jr z,nfdelcp_nodeletedinthissector
  141.         push bc
  142.         push de
  143.         push ix
  144.         ld d,0 ;track
  145.         ld a,8
  146.         sub b
  147.         ld e,a ;sector
  148.         call wrsecDOSBUF
  149.         pop ix
  150.         pop de
  151.         pop bc
  152. nfdelcp_nodeletedinthissector
  153.         djnz nfdelsectors0. ;next sector
  154.         xor a
  155.         cp lx
  156.         jr nz,nfdel_correctsystemsector
  157. ;not found
  158.         ld a,0xff ;fail
  159.         ret
  160. nfdel_correctsystemsector
  161.         push ix
  162.         ld de,0x0008
  163.         push de
  164.         call rdsecDOSBUF
  165.         pop de
  166.         pop ix
  167.         ld hl,DOSBUF+0xf4 ;del files
  168.         ld a,(hl)
  169.         add a,lx
  170.         ld (hl),a
  171.         ;ld de,0x0008
  172.         call wrsecDOSBUF
  173.         xor a ;success
  174.         ret
  175.        
  176. openwrite
  177.         ld c,'w'
  178. nfopen
  179. ;de=filename
  180. ;c=mode
  181. ;a=drive 0..3
  182.         ;EXPORT nfopen
  183.         push af
  184.          push bc
  185.          push de
  186.          ld a,c
  187.          cp 'w'
  188.          call z,nfdel_filename
  189.          pop de
  190.          pop bc
  191.         xor a
  192.         ld hl,TRDOSFCB1-0x0200
  193.  
  194.         inc h
  195.         inc h
  196.         cp [hl]
  197.         jr nz,$-3
  198. ;TODO check trdos_MAXFILES
  199.  
  200.         ld [hl],c ;mode in TRDOSFCB
  201.        
  202.         pop af
  203.         ld l,TRDOSFCB.drive
  204.         ld (hl),a
  205.         call trdossetdrvfromtrdosfcb ;l=0
  206.        
  207.         inc hl;ld l,TRDOSFCB.fn ;poi to fn in TRDOSFCB
  208.        
  209.         if 1==1
  210. ;de=filename
  211.         ex de,hl
  212.         ld bc,11
  213.         ldir
  214.         ex de,hl
  215.         else
  216.        
  217.         push hl ;poi to fn in TRDOSFCB
  218.         ld d,h
  219.         ld e,l
  220.         inc de
  221.         ld [hl],' '
  222.         ld bc,8
  223.         ldir ;empty filename
  224. nfopen.A.=$+1
  225.         ;EXPORT nfopen.A.
  226.         ld hl,0 ;poi to filename in string
  227.         call findlastslash.
  228. ;de = after last slash
  229.         pop hl ;poi to fn in TRDOSFCB
  230.         ld b,9
  231. nfopenfn0.
  232.         ld a,[de]
  233.         or a
  234.         jr z,nfopenfnq. ;no extension in string
  235.         inc de
  236.         cp '.'
  237.         jr z,nfopenfndot.
  238.         ld [hl],a
  239.         inc hl
  240.         djnz nfopenfn0.
  241. ;9 bytes in filename, no dot (9th byte goes to extension)
  242.         jr nfopenfnq.
  243. nfopenfndot.
  244.         inc hl
  245.         djnz $-1 ;hl points to extension in TRDOSFCB
  246.         dec hl
  247.         ld a,[de] ;extension in string
  248.         ld [hl],a ;extension in TRDOSFCB
  249. nfopenfnq.
  250.         endif
  251.  
  252. nfopen_reopen
  253. ;h-TRDOSFCB/256
  254.         ;xor a
  255.         ;ld l,TRDOSFCB.block
  256.         ;ld [hl],a;0 ;cur block for write, next block for read ;TODO брать из имени (тупо закомментировать)
  257.         ;inc hl
  258.         ;ld [hl],0x60 ;(padding for "start") ;TODO брать из имени (тупо закомментировать)
  259.        
  260.         ld l,0
  261.         ld a,(hl)
  262.         cp 'w'
  263.         jr z,nfopen_nofindfile ;TODO удалить, если есть
  264. ;проверить, что файл существует, иначе вернуть ошибку и освободить FCB
  265.         ld c,9 ;FILENAMESZ
  266.          ld l,TRDOSFCB.fn ;poi to fn
  267.         call findfile
  268.         or a
  269.         jr nz,nfopen_fail
  270. ;hl,de = after filename
  271. ;open for read!
  272.         ld l,TRDOSFCB.block
  273.         ld a,(de)
  274.         inc de
  275.         ld [hl],a;0 ;cur block for write, next block for read
  276.         inc hl
  277.         ld a,(de)
  278.         inc de
  279.         ld [hl],a;0x60 ;(padding for "start")
  280.        ;ld a,FALSE
  281.        ;ld [_waseof],a
  282.        ld l,TRDOSFCB.waseof
  283.        ld [hl],FALSE
  284. nfopen_nofindfile
  285.  
  286.         xor a
  287.         ld l,TRDOSFCB.lastlen
  288.         ld [hl],a;0 ;lastlen LSB ;???
  289.         inc hl
  290.         ld [hl],a;0 ;lastlen HSB ;???
  291.         inc hl
  292.         ld [hl],a;0 ;sectors remained in block (for read), block size (for write)
  293.         ld l,TRDOSFCB.remain
  294.         ld [hl],0xff ;remain (0xff = no data) for read
  295.         inc hl
  296.         ld [hl],a;0 ;sectors written (for write)
  297.         ld l,a;0;TRDOSFCB.mode
  298.         ret ;hl = poi to TRDOSFCB ;a=0 (success)
  299.  
  300. nfopen_fail
  301.         ld l,0
  302.         ld (hl),l;0 ;empty FCB
  303.         ;ld a,0xff
  304.         ret
  305.        
  306. trdossetdrvfromtrdosfcb
  307.        ld l,TRDOSFCB.drive
  308.        ld a,(hl)
  309.        ld (trdoscurdrive),a
  310.        ld l,0
  311.        ret
  312.  
  313. ;closewrite
  314.         ;EXPORT closewrite
  315. fclose
  316. ;hl=poi to TRDOSFCB
  317.         ;EXPORT fclose
  318. ;closewrite.A.=$+1
  319.         ;EXPORT closewrite.A.
  320. ;fclose.A.=$+1
  321.         ;EXPORT fclose.A.
  322.         ;ld hl,0 ;poi to TRDOSFCB
  323.        call trdossetdrvfromtrdosfcb
  324.         ld a,[hl]
  325.         ld [hl],l;0
  326.         cp 'w'
  327.         ret nz ;hl!=0
  328. ;hl = poi to TRDOSFCB
  329.         call flush.
  330.         ;следующая проверка не годится, если будет ручной flush:
  331.         ld l,TRDOSFCB.secwritten
  332.         ld a,[hl]
  333.         or a
  334.         ret z ;no sectors written - descriptor already saved (??? TODO)
  335.         ;call flushdesc.
  336.         ;ld l,1 ;OK TODO
  337.         ;ret ;hl!=0
  338. ;write descriptor
  339. ;if created or finished
  340. flushdesc.
  341. ;hl = poi to TRDOSFCB
  342.         push hl ;poi to TRDOSFCB
  343.  
  344.         push hl ;poi to TRDOSFCB
  345.         ld l,TRDOSFCB.descpos
  346.         ld l,[hl]
  347.         ld d,0 ;track of descriptor
  348.         ld h,d;0
  349.         add hl,hl
  350.         add hl,hl
  351.         add hl,hl
  352.         add hl,hl
  353.         ld e,h ;sector of descriptor
  354.         ld h,DOSBUF>>8
  355.         push hl ;hl = poi to descriptor
  356.         push de ;track,sector of descriptor
  357.         call rdsecDOSBUF
  358.         pop bc ;track,sector of descriptor
  359.         pop de ;poi to descriptor
  360.         pop hl ;poi to TRDOSFCB
  361.         ld l,TRDOSFCB.fn
  362.         push bc ;track,sector of descriptor
  363.         ld bc,16
  364.         ldir
  365.         pop de ;track,sector of descriptor
  366.         call wrsecDOSBUF
  367.  
  368.         pop hl ;poi to TRDOSFCB
  369.         ret
  370.  
  371.         if 1==0
  372. ;FUNC BOOL comparedesc FORWARD(PCHAR filename, PBYTE desc);
  373. comparedesc
  374. comparedesc.A.=$+1 ;filename
  375.         ld hl,0
  376.         call findlastslash.
  377. ;de = after last slash
  378. comparedesc.B.=$+1 ;desc
  379.         ld hl,0
  380. ;compare until '.' or '\0' or 8 loops
  381.         ld b,8
  382. comparedesc0.
  383.         ld a,[de] ;filename
  384.         ;or a
  385.         ;jr z,comparedesctrue. ;filename ended without ext (descriptor not ended)
  386.         inc de
  387.         cp '.'
  388.         jr z,comparedescdot.
  389.         cp [hl] ;descriptor
  390.         jr nz,comparedescfalse.
  391.         inc hl
  392.         djnz comparedesc0.
  393.         ld a,[de] ;filename
  394.         inc de
  395.         cp '.'
  396.         jr z,comparedescdot8. ;filenam8.ext
  397.         ;filenam8 (without ext)
  398.         ld a,[hl]
  399.         cp ' '
  400.         jr nz,comparedescfalse.
  401. comparedesctrue.
  402.         ld a,0xff ;TRUE
  403.         ret
  404. comparedescdot.
  405.         inc hl
  406.         djnz $-1 ;hl = descriptor ext
  407. comparedescdot8.
  408.         ld a,[de] ;filename ext
  409.         cp [hl] ;descriptor ext
  410.         jr z,comparedesctrue.
  411. comparedescfalse.
  412.         xor a ;FALSE
  413.         ret
  414.         endif
  415.  
  416. findfile
  417. ;find new block if exists
  418. ;find Nth block of file with hl pointed filename (10 bytes: name, ext, block N)
  419. ;hl=filename
  420. ;c=FILENAMESZ
  421. ;out: z=found (carry = off, a = 0, hl,de = after filename)
  422.          ;ld l,TRDOSFCB.fn ;poi to fn
  423.         ld b,8 ;sectors
  424. findfile0.
  425.         push bc
  426.         push hl
  427.         ld d,0 ;track
  428.         ld a,8
  429.         sub b
  430.         ld e,a ;sector
  431.         call rdsecDOSBUF
  432.         pop hl
  433.         pop bc
  434. ;hl=filename
  435. ;b=sectors
  436.         ld de,DOSBUF
  437. findfilecp0.
  438.          ;ld l,TRDOSFCB.fn ;poi to fn
  439.         push bc
  440.         ld b,c ;FILENAMESZ
  441.         ld c,0 ;b=bytes to compare, c=errors
  442. findfilecp00.
  443.         ld a,[de]
  444.         sub [hl]
  445.         or c
  446.         ld c,a ;errors
  447.         inc hl
  448.         inc de
  449.         djnz findfilecp00.
  450.         pop bc
  451.         ret z ;found (carry = off, a = 0, hl,de = after filename)
  452. findfile_continue
  453.          ld a,l
  454.          sub c
  455.          ld l,a
  456.          sbc a,l
  457.          add a,h
  458.          ld h,a
  459.          ;ld b,a
  460.          ;sbc hl,bc
  461.         ld a,e
  462.         or 15;add a,16-FILENAMESZ;6
  463.         ld e,a
  464.         inc e
  465.         jr nz,findfilecp0. ;next descriptor
  466.         djnz findfile0. ;next sector
  467. ;not found
  468.         xor a
  469.         dec a ;nz=fail
  470.         ret
  471.  
  472. ;length 0 while reading means either absence of files or zero length file (any sector length)
  473.  
  474. ;readf
  475.         ;EXPORT readf
  476. ;readf.A.=$+1
  477.         ;EXPORT readf.A.
  478.         ;ld hl,0 ;poi to TRDOSFCB
  479.         ;jr fread1. ;a=data ;keeps bc
  480. ;readfin
  481. ;       ;EXPORT readfin
  482. ;       ld hl,[_fin] ;poi to TRDOSFCB
  483. fread1.
  484. ;a=data
  485.  ;;if ok then inc de?
  486. ;keeps bc
  487.         ld l,TRDOSFCB.remain ;0xff = no data, 0xfe = 1 byte, ... 0x00 = 255 bytes
  488.         ld e,[hl]
  489.         ld d,h
  490.         inc d
  491.         inc e
  492.         ld a,[de]
  493.         ld [hl],e ;inc [hl] ;remain
  494.         ret nz
  495. fread1noremain.
  496.         push bc
  497.          ;push de
  498. ;read new buf (if exists)
  499.         ld l,TRDOSFCB.secinblk
  500.         xor a
  501.         cp [hl] ;sectors remained in block (0 means none)
  502.         jr nz,fread1sec. ;a = 0
  503.         ld c,10 ;FILENAMESZ
  504.          ld l,TRDOSFCB.fn ;poi to fn
  505.         call findfile
  506.         jr z,fread1blkq. ;found (carry = off, a = 0, hl,de = after filename)
  507. ;not found
  508. ;EOF - next block doesn't exist
  509. fread1EOF.
  510.          ;pop de
  511.         pop bc
  512.        ;ld a,TRUE
  513.        ;ld [_waseof],a
  514.        ld l,TRDOSFCB.waseof
  515.        ld [hl],TRUE
  516.        ld a,0x0a;'\n' ;EOF returns '\n'
  517. ;set vars as they were (next time EOF again)
  518.         ld l,TRDOSFCB.remain
  519.         dec [hl] ;remain = 0xff
  520.         ret
  521. fread1blkq.
  522. ;de = poi to descriptor + 10
  523. ;hl = poi to fn + 10
  524. ;a = 0
  525.         ;ld l,TRDOSFCB.fn + 10
  526.         ex de,hl
  527. ;hl = poi to descriptor + 10
  528. ;de = poi to filename + 10
  529.         ld bc,16-10 ;padding, len(LSB), len(HSB), secinblk, sec, track
  530.         ldir
  531.         ex de,hl
  532.         ld l,TRDOSFCB.firstsector
  533.         ld e,[hl]
  534.         inc hl
  535.         ld d,[hl]
  536.         ld l,TRDOSFCB.cursector
  537.         ld [hl],e
  538.         inc hl
  539.         ld [hl],d
  540. ;secinblk = (lastlen+255)/256 = (lastlen-1)/256 + 1
  541. ;иначе нельзя будет выделять блоки навырост (как делает TR-DOS)
  542.         ld l,TRDOSFCB.lastlen
  543.         ld e,[hl]
  544.         inc hl
  545.         ld d,[hl]
  546.         dec de
  547.         inc d
  548.         inc hl ;ld l,TRDOSFCB.secinblk
  549.         ld [hl],d
  550.         jr z,fread1EOF. ;(secinblk == 0)
  551.         ld l,TRDOSFCB.block
  552.         inc [hl] ;cur block for write, next block for read
  553. fread1sec.
  554. ;read next sector
  555. ;a = 0
  556.         ld l,TRDOSFCB.cursector
  557.         push hl ;poi to cursector
  558.         ld e,[hl]
  559.         inc hl
  560.         ld d,[hl]
  561.         inc h
  562.         ld l,a;0 ;poi to buf
  563.         call rdsec.
  564.         ex de,hl ;ld de,[0x5cf4] ;de=next sector
  565.         pop hl ;poi to cursector
  566.         ld [hl],e
  567.         inc hl
  568.         ld [hl],d
  569. ;if last sector of block, then remain = -lastlen and shift data in buf to the end
  570. ;else remain = 0 (read + 255 bytes)
  571.         xor a
  572.         ld l,TRDOSFCB.secinblk
  573.         dec [hl] ;sectors remained in block
  574.         jr nz,fread1nlast.
  575. ;last sector in block: shift data to the end of buf
  576.         ld l,TRDOSFCB.lastlen
  577.         ld c,[hl] ;1..256
  578.         ld b,a;0
  579.         dec c ;0..255
  580.         ld l,c ;end of data
  581.         inc h
  582.         inc bc ;1..256
  583.         ld d,h
  584.         ld e,0xff
  585.         lddr
  586.         ;hl = poi to buf - 1
  587.         ;h = poi to TRDOSFCB
  588.         ld a,e ;0xfe (1 byte) ... -1 (256 bytes)
  589.         inc a ;remain = 0xff (read + no data) ... 0 (read + 255 bytes)
  590. fread1nlast.
  591.         ld l,TRDOSFCB.remain
  592.         ld [hl],a
  593.          ;pop de
  594.         pop bc
  595. fread1ok.
  596. ;hl = poi to remain
  597.         ld l,[hl]
  598.         inc h
  599.         ld a,[hl]
  600.          ;inc de
  601.         ret
  602.  
  603. fread
  604. ;hl=poi to data
  605. ;de=poi to TRDOSFCB
  606. ;bc=size
  607. ;out: hl=total processed bytes
  608.         ;EXPORT fread
  609. ;fread.A.=$+1
  610.         ;EXPORT fread.A.
  611.         ;ld hl,0 ;poi to data
  612.          ;ld de,0 ;total processed bytes
  613. ;fread.C.=$+1
  614.         ;EXPORT fread.C.
  615.         ;ld bc,0 ;count
  616. ;fread0.
  617.         ;push bc
  618. ;fread.B.=$+1
  619.         ;EXPORT fread.B.
  620.         ;ld bc,0 ;size
  621.        ex de,hl
  622.        call trdossetdrvfromtrdosfcb
  623.        ex de,hl
  624.         ;ld (fread00size),bc
  625.         ld (fread00addr),hl
  626.         if 1==1
  627. ;read by sectors:
  628.        ld e,TRDOSFCB.waseof
  629.        ld a,[de]
  630.        ;ld a,[_waseof]
  631.        or a ;FALSE
  632.        jr nz,fread00q;freadbysector0q
  633.         ld e,TRDOSFCB.remain ;0xff = no data, 0xfe = 1 byte, ... 0x00 = 255 bytes
  634.         ld a,[de]
  635.         inc a
  636.         jr nz,fread00. ;not at sector margin (TODO read the beginning by bytes)
  637.         ld a,b
  638.         or a
  639.         jr z,fread00. ;length < 256
  640.        dec bc
  641.        inc b ;b=number of loops
  642. freadbysector0.
  643.         push de
  644.         push hl
  645.         ld h,d
  646.         ld e,0
  647.         inc d ;de=TRDOSFCB+256 (i.e. sector buffer)
  648.         call fread1noremain.
  649.         pop hl
  650.         pop de
  651.        ld e,TRDOSFCB.waseof
  652.        ld a,[de]
  653.        ;ld a,[_waseof]
  654.        or a ;FALSE
  655.        jr nz,fread00q
  656.         push bc
  657.         push de
  658.         ex de,hl ;data is at the end of buf
  659.         ld l,TRDOSFCB.remain ;0xff = 1 byte, 0xfe = 2 bytes, ... 0x00 = 256 bytes (including the returned byte that we've ignored)
  660.         ld l,[hl]
  661.         inc h ;hl=buf with data
  662.         ld b,a;0
  663.         ld a,l ;0xff..0x00
  664.         cpl
  665.         ld c,a ;0..255
  666.         inc bc ;1..256
  667.         ldir
  668.         ex de,hl
  669.         pop de
  670.         pop bc
  671.        inc a
  672.        jr nz,EOFfread00q ;last (short) sector in file
  673.         djnz freadbysector0.
  674.        ld e,TRDOSFCB.remain ;0xff = no data, 0xfe = 1 byte, ... 0x00 = 255 bytes
  675.        ld a,0xff
  676.        ld [de],a
  677.         jr fread00q
  678. EOFfread00q
  679.        ld e,TRDOSFCB.waseof
  680.        ld a,TRUE
  681.        ld [de],a
  682.         jr fread00q
  683.         endif
  684. ;read by bytes:
  685. fread00.
  686.         push de
  687.         push hl
  688. ;fread.D.=$+1
  689.         ;EXPORT fread.D.
  690.         ex de,hl ;ld hl,0 ;hl=poi to TRDOSFCB
  691.         call fread1. ;a=data ;keeps bc
  692.         pop hl
  693.         pop de
  694.         ld [hl],a ;may be EOF!
  695.        ld e,TRDOSFCB.waseof
  696.        ld a,[de]
  697.        ld e,0
  698.        ;ld a,[_waseof]
  699.        or a ;FALSE
  700.        jr nz,fread00q ;jr nz,freadpopret.
  701.         ;cpi
  702.         db 0xed,0xa1
  703.         jp pe,fread00.
  704.         ;pop bc
  705.         ;dec hl
  706.         ;cpi
  707.         ;db 0xed,0xa1
  708.         ;jp pe,fread0.
  709.          ;ex de,hl ;hl = total processed bytes
  710. fread00q
  711. ;bc=size-processedbytes
  712. ;fread00size=$+1
  713. ;        ld hl,0
  714. ;        xor a ;a=0: no error
  715. ;        sbc hl,bc ;hl=processedbytes
  716. ;hl=addr+processedbytes
  717. fread00addr=$+1
  718.         ld bc,0
  719.         xor a ;a=0: no error
  720.         sbc hl,bc ;hl=processedbytes
  721.         ret
  722. ;freadpopret.
  723.         ;pop bc
  724.         ;ret
  725.  
  726.         if 1==0
  727. fwritebyte
  728.         ;EXPORT fwritebyte
  729. fwritebyte.A.=$+1
  730.         ;EXPORT writebyte.A.
  731.         ld hl,0 ;file
  732. fwritebyte.B.=$+1
  733.         ;EXPORT writebyte.B.
  734.         ld a,0
  735.         jp fwrite1.
  736.         endif
  737. ;writefout
  738.         ;EXPORT writefout
  739.         ;ld hl,[_fout]
  740. ;writefout.A.=$+1
  741.         ;EXPORT writefout.A.
  742.         ;ld a,0
  743. ;hl = poi to TRDOSFCB
  744. ;a=data
  745. ;keeps bc
  746. fwrite1.
  747.         ;jr $
  748.         ld l,TRDOSFCB.lastlen
  749.         ld e,[hl]
  750.         ld d,h
  751.         inc d
  752.         ld [de],a
  753.         inc [hl] ;lastlen (LSB)
  754.         ;Z = end of buf
  755.         ret nz
  756.         inc l
  757.         inc [hl] ;lastlen (HSB)
  758. flush.
  759. ;ручной flush пока невозможен!!!
  760. ;can create zero length file
  761. ;hl = poi to TRDOSFCB
  762.         push bc
  763.  
  764. ;if secwritten == 0 then reserve sectors, reserve descriptor
  765.         ld l,TRDOSFCB.secwritten
  766.         ld a,[hl]
  767.         or a
  768.         jr nz,flushnnew.
  769. ;глючит, если последний блок <256 TODO
  770. ;потому что fclose второй раз вызывает flush
  771.         ld l,TRDOSFCB.secinblk
  772.         ld [hl],SECINBLK;16 ;TR-DOS reserves 16 sectors per block
  773. ;update sec8
  774.         push hl ;poi to TRDOSFCB
  775.         ld de,0x0008
  776.         push de
  777.         call rdsecDOSBUF
  778.         pop de ;0x0008
  779.         ld hl,[DOSBUF+0xe5] ;free sectors
  780.         ld bc,-SECINBLK;16
  781.         add hl,bc
  782.          ;bit 7,h
  783.          ;jr nz,$ ;no free sectors
  784.         ld [DOSBUF+0xe5],hl ;free sectors
  785.         ;jr $
  786.         ld hl,DOSBUF+0xe4 ;files
  787.         ld a,[hl] ;descriptor position 0..127
  788.          ;or a
  789.          ;jp m,$ ;128 files, can't add
  790.         inc [hl] ;files
  791.  
  792.         ld l,0xe1 ;free sector
  793.         ld c,[hl]
  794.         inc hl
  795.         ld b,[hl]
  796.         ;inc [hl] ;add 16 sectors = add 1 track
  797.         push bc
  798.         ld lx,SECINBLK
  799.         call addsectors
  800.         ld (hl),b
  801.         dec hl
  802.         ld (hl),c
  803.         pop bc
  804.  
  805.         pop hl ;poi to TRDOSFCB
  806.         ld l,TRDOSFCB.descpos
  807.         ld [hl],a ;descriptor position 0..127
  808.         ld l,TRDOSFCB.firstsector
  809.         ld [hl],c
  810.         inc hl
  811.         ld [hl],b
  812.         ld l,TRDOSFCB.cursector
  813.         ld [hl],c
  814.         inc hl
  815.         ld [hl],b
  816.  
  817.         push hl ;poi to TRDOSFCB
  818.         ;ld de,0x0008
  819.         call wrsecDOSBUF ;write sec8
  820.         pop hl ;poi to TRDOSFCB
  821. flushnnew.
  822.  
  823. ;write buf
  824.         ld l,TRDOSFCB.cursector
  825.         push hl ;poi to cursector
  826.         ld e,[hl]
  827.         inc hl
  828.         ld d,[hl]
  829.         ld l,0
  830.         inc h ;poi to buf
  831.         call wrsec.
  832.         ex de,hl ;ld de,(0x5cf4) ;de=next sector
  833.         pop hl ;poi to cursector
  834.         ld [hl],e
  835.         inc hl
  836.         ld [hl],d
  837.  
  838. ;increase secwritten
  839. ;get new block if this block filled up
  840.         ld l,TRDOSFCB.secinblk
  841.         ld a,[hl]
  842.         ld l,TRDOSFCB.secwritten
  843.         inc [hl]
  844.         sub [hl]
  845.         jr nz,flushnblk. ;not filled up
  846. ;block is filled up
  847. ;zero secwritten
  848.         ;ld l,TRDOSFCB.secwritten
  849.         ld [hl],a;0 ;block not created
  850. ;write descriptor
  851.         call flushdesc.
  852. ;increase block number (after flushdesc!!!)
  853.         ld l,TRDOSFCB.block
  854.         inc [hl] ;cur block for write, next block for read
  855. ;теперь дескриптор невалидный, пока не создадим его в начале другого flush
  856. ;zero lastlen (after flushdesc!!!)
  857.         ld l,TRDOSFCB.lastlen+1 ;(HSB), LSB is already 0 if not fclose
  858.         ld [hl],0
  859. flushnblk.
  860.  
  861.         pop bc
  862.         ret
  863.  
  864. addsectors
  865. ;bc=trsec
  866. ;lx=number of sectors
  867. ;keeps a
  868.         inc lx
  869.         jr flush_addsectors_go
  870. flush_addsectors0
  871.         inc c
  872.         bit 4,c
  873.         jr z,$+2+3
  874.         ld c,0
  875.         inc b
  876. flush_addsectors_go
  877.         dec lx
  878.         jr nz,flush_addsectors0
  879.         ret
  880.  
  881. fwrite
  882. ;hl=poi to data
  883. ;de=poi to TRDOSFCB
  884. ;bc=size
  885.         ;EXPORT fwrite
  886. ;fwrite.A.=$+1
  887.         ;EXPORT fwrite.A.
  888.         ;ld hl,0 ;poi to data
  889.          ;ld de,0 ;total processed bytes TODO
  890. ;fwrite.C.=$+1
  891.         ;EXPORT fwrite.C.
  892.         ;ld bc,0 ;count
  893. ;fwrite0.
  894.         ;push bc
  895. ;fwrite.B.=$+1
  896.         ;EXPORT fwrite.B.
  897.         ;ld bc,0 ;size
  898.        ex de,hl
  899.        call trdossetdrvfromtrdosfcb
  900.        ex de,hl
  901.         ;ld (fread00size),bc
  902.         ld (fread00addr),hl
  903. fwrite00.
  904.         ld a,[hl]
  905.         push de
  906.         push hl
  907.          ;push de
  908. ;fwrite.D.=$+1
  909.         ex de,hl ;ld hl,0 ;poi to TRDOSFCB
  910.         call fwrite1. ;a=data ;keeps bc
  911.          ;pop de
  912.          ;inc de
  913.         pop hl
  914.         pop de
  915.         ;cpi
  916.         db 0xed,0xa1
  917.         jp pe,fwrite00.
  918.         ;pop bc
  919.         ;dec hl
  920.         ;cpi
  921.         ;db 0xed,0xa1
  922.         ;jp pe,fwrite0.
  923.          ;ex de,hl ;hl = total processed bytes
  924.         jp fread00q ;ret
  925.  
  926. ;FUNC UINT readsectors FORWARD(PBYTE buf, UINT trsec, BYTE count);
  927. readsectors
  928. readsectors.A.=$+1 ;buf
  929.         ld hl,0
  930. readsectors.B.=$+1 ;trsec
  931.         ld de,0
  932. readsectors.C.=$+1 ;count
  933.         ld b,0
  934.         jr rdsectors.
  935. rdsecDOSBUF
  936.         ld hl,DOSBUF
  937. rdsec.
  938.         ld b,1
  939. rdsectors.
  940.         ld c,0x05
  941.         ;push hl ;read address
  942.         ;ld hl,0x8000 ;pgkillable
  943.         ;push bc
  944.         ;push hl
  945.         jp iodos. ;hl=next sector
  946.         ;pop hl
  947.         ;pop bc
  948.         ;ld c,0
  949.         ;pop de ;read address
  950.         ;ldir
  951.         ;ld hl,(0x5cf4);(sysvars+0x00f4) ;next sector
  952.         ;ret
  953.  
  954. ;FUNC UINT writesectors FORWARD(PBYTE buf, UINT trsec, BYTE count);
  955. writesectors
  956. writesectors.A.=$+1 ;buf
  957.         ld hl,0
  958. writesectors.B.=$+1 ;trsec
  959.         ld de,0
  960. writesectors.C.=$+1 ;count
  961.         ld b,0
  962.         jr wrsectors.
  963. wrsecDOSBUF
  964.         ld hl,DOSBUF
  965. wrsec.
  966.         ld b,1
  967. wrsectors.
  968.         ;push bc
  969.         ;push de ;track,sector
  970.         ;ld c,0
  971.         ;ld de,0x8000 ;pgkillable
  972.         ;push de
  973.         ;ldir
  974.         ;pop hl
  975.         ;pop de ;track,sector
  976.         ;pop bc
  977.         ld c,0x06
  978. iodos.
  979. trdoscurdrive=$+1
  980.         ld a,0xff
  981.         call iodos_setdrive
  982.         ;ld iy,23610
  983.         call dos3d13.
  984.         ld hl,(0x5cf4);(sysvars+0x00f4) ;next sector
  985.         ret
  986.  
  987. iodos_setdrive_okq
  988.         xor a
  989.         ret
  990. iodos_setdrive
  991. trdosolddrive=$+1
  992.                 cp 0xff
  993.                 jr z,iodos_setdrive_okq
  994.                 ld (trdoscurdrive),a
  995.                 push bc
  996.                 push de
  997.                 push hl
  998.                 ld a,(trdoscurdrive)
  999.                 ld c,1
  1000.                 call dos3d13nopg.
  1001.                 ;call iodos_chd_cherr
  1002.                 ld c,0x18
  1003.                 call dos3d13nopg.
  1004.                 call iodos_chd_cherr
  1005.                 ;ld bc,0x0105
  1006.                 ;ld hl,trdos_sectorbuf
  1007.                 ;ld de,0x0008
  1008.                 ;call dos3d13nopg.
  1009.                 ;call iodos_chd_cherr
  1010.                 ld a,(trdoscurdrive)
  1011.                 ld (trdosolddrive),a
  1012.                 xor a
  1013.                 jr iodos_chd_noerr
  1014. iodos_chd_cherr
  1015.                 or a
  1016.                 ret z
  1017.                 ld a,0xff
  1018.                 ld (trdosolddrive),a
  1019.         dec a ;Alone Coder: чтобы были не равны в следующий заход, тогда опять будем пытаться включить драйв
  1020.         ld (trdoscurdrive),a
  1021.                 ld a,0xff
  1022.                 pop hl
  1023. iodos_chd_noerr
  1024.         pop hl
  1025.         pop de
  1026.         pop bc
  1027.                 ret