Subversion Repositories NedoOS

Rev

Rev 630 | Rev 754 | 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
  988. trdosolddrive=$+1
  989.         cp 0xff
  990.         ret z
  991.         ld (trdoscurdrive),a
  992.         push bc
  993.         push de
  994.         push hl
  995.         if atm == 1
  996.                         ld bc,0xfd77
  997.                         ld a,0xa6
  998.                         out (c),a
  999.                         ld a,(trdoscurdrive)
  1000.                         or 0x04
  1001.                         out (0xff),a
  1002.                         ld bc,0xbd77
  1003.                         ld a,0xae
  1004.                         out (c),a
  1005.                         ld c,0x00
  1006.                         call dos3d13nopg.
  1007.         endif
  1008.                         ld a,(trdoscurdrive)
  1009.                         ld c,1
  1010.                         call dos3d13nopg.
  1011.                         ;call iodos_chd_cherr
  1012.                         ld c,0x18
  1013.                         call dos3d13nopg.
  1014.                         call iodos_chd_cherr
  1015.                         ;ld bc,0x0105
  1016.                         ;ld hl,trdos_sectorbuf
  1017.                         ;ld de,0x0008
  1018.                         ;call dos3d13nopg.
  1019.                         ;call iodos_chd_cherr
  1020.                 ld a,(trdoscurdrive)
  1021.                 ld (trdosolddrive),a
  1022.                 xor a
  1023.                 jr iodos_chd_noerr
  1024. iodos_chd_cherr
  1025.                 or a
  1026.                 ret z
  1027.                 ld a,0xff
  1028.                 ld (trdosolddrive),a
  1029.         dec a ;Alone Coder: чтобы были не равны в следующий заход, тогда опять будем пытаться включить драйв
  1030.         ld (trdoscurdrive),a
  1031.                 ld a,0xff
  1032.                 pop hl
  1033. iodos_chd_noerr
  1034.         pop hl
  1035.         pop de
  1036.         pop bc
  1037.                 ret