?login_element?

Subversion Repositories NedoOS

Rev

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

  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.  
  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. fread00.
  626.         push de
  627.         push hl
  628. ;fread.D.=$+1
  629.         ;EXPORT fread.D.
  630.         ex de,hl ;ld hl,0 ;hl=poi to TRDOSFCB
  631.         call fread1. ;a=data ;keeps bc
  632.         pop hl
  633.         pop de
  634.         ld [hl],a ;may be EOF!
  635.        ld e,TRDOSFCB.waseof
  636.        ld a,[de]
  637.        ld e,0
  638.        ;ld a,[_waseof]
  639.        or a ;FALSE
  640.        jr nz,fread00q ;jr nz,freadpopret.
  641.         ;cpi
  642.         db 0xed,0xa1
  643.         jp pe,fread00.
  644.         ;pop bc
  645.         ;dec hl
  646.         ;cpi
  647.         ;db 0xed,0xa1
  648.         ;jp pe,fread0.
  649.          ;ex de,hl ;hl = total processed bytes
  650. fread00q
  651. ;bc=size-processedbytes
  652. fread00size=$+1
  653.         ld hl,0
  654.         xor a ;a=0: no error
  655.         sbc hl,bc ;hl=processedbytes
  656.         ret
  657. ;freadpopret.
  658.         ;pop bc
  659.         ;ret
  660.  
  661.         if 1==0
  662. fwritebyte
  663.         ;EXPORT fwritebyte
  664. fwritebyte.A.=$+1
  665.         ;EXPORT writebyte.A.
  666.         ld hl,0 ;file
  667. fwritebyte.B.=$+1
  668.         ;EXPORT writebyte.B.
  669.         ld a,0
  670.         jp fwrite1.
  671.         endif
  672. ;writefout
  673.         ;EXPORT writefout
  674.         ;ld hl,[_fout]
  675. ;writefout.A.=$+1
  676.         ;EXPORT writefout.A.
  677.         ;ld a,0
  678. ;hl = poi to TRDOSFCB
  679. ;a=data
  680. ;keeps bc
  681. fwrite1.
  682.         ;jr $
  683.         ld l,TRDOSFCB.lastlen
  684.         ld e,[hl]
  685.         ld d,h
  686.         inc d
  687.         ld [de],a
  688.         inc [hl] ;lastlen (LSB)
  689.         ;Z = end of buf
  690.         ret nz
  691.         inc l
  692.         inc [hl] ;lastlen (HSB)
  693. flush.
  694. ;ручной flush пока невозможен!!!
  695. ;can create zero length file
  696. ;hl = poi to TRDOSFCB
  697.         push bc
  698.  
  699. ;if secwritten == 0 then reserve sectors, reserve descriptor
  700.         ld l,TRDOSFCB.secwritten
  701.         ld a,[hl]
  702.         or a
  703.         jr nz,flushnnew.
  704. ;глючит, если последний блок <256 TODO
  705. ;потому что fclose второй раз вызывает flush
  706.         ld l,TRDOSFCB.secinblk
  707.         ld [hl],SECINBLK;16 ;TR-DOS reserves 16 sectors per block
  708. ;update sec8
  709.         push hl ;poi to TRDOSFCB
  710.         ld de,0x0008
  711.         push de
  712.         call rdsecDOSBUF
  713.         pop de ;0x0008
  714.         ld hl,[DOSBUF+0xe5] ;free sectors
  715.         ld bc,-SECINBLK;16
  716.         add hl,bc
  717.          ;bit 7,h
  718.          ;jr nz,$ ;no free sectors
  719.         ld [DOSBUF+0xe5],hl ;free sectors
  720.         ;jr $
  721.         ld hl,DOSBUF+0xe4 ;files
  722.         ld a,[hl] ;descriptor position 0..127
  723.          ;or a
  724.          ;jp m,$ ;128 files, can't add
  725.         inc [hl] ;files
  726.  
  727.         ld l,0xe1 ;free sector
  728.         ld c,[hl]
  729.         inc hl
  730.         ld b,[hl]
  731.         ;inc [hl] ;add 16 sectors = add 1 track
  732.         push bc
  733.         ld lx,SECINBLK
  734.         call addsectors
  735.         ld (hl),b
  736.         dec hl
  737.         ld (hl),c
  738.         pop bc
  739.  
  740.         pop hl ;poi to TRDOSFCB
  741.         ld l,TRDOSFCB.descpos
  742.         ld [hl],a ;descriptor position 0..127
  743.         ld l,TRDOSFCB.firstsector
  744.         ld [hl],c
  745.         inc hl
  746.         ld [hl],b
  747.         ld l,TRDOSFCB.cursector
  748.         ld [hl],c
  749.         inc hl
  750.         ld [hl],b
  751.  
  752.         push hl ;poi to TRDOSFCB
  753.         ;ld de,0x0008
  754.         call wrsecDOSBUF ;write sec8
  755.         pop hl ;poi to TRDOSFCB
  756. flushnnew.
  757.  
  758. ;write buf
  759.         ld l,TRDOSFCB.cursector
  760.         push hl ;poi to cursector
  761.         ld e,[hl]
  762.         inc hl
  763.         ld d,[hl]
  764.         ld l,0
  765.         inc h ;poi to buf
  766.         call wrsec.
  767.         ex de,hl ;ld de,(0x5cf4) ;de=next sector
  768.         pop hl ;poi to cursector
  769.         ld [hl],e
  770.         inc hl
  771.         ld [hl],d
  772.  
  773. ;increase secwritten
  774. ;get new block if this block filled up
  775.         ld l,TRDOSFCB.secinblk
  776.         ld a,[hl]
  777.         ld l,TRDOSFCB.secwritten
  778.         inc [hl]
  779.         sub [hl]
  780.         jr nz,flushnblk. ;not filled up
  781. ;block is filled up
  782. ;zero secwritten
  783.         ;ld l,TRDOSFCB.secwritten
  784.         ld [hl],a;0 ;block not created
  785. ;write descriptor
  786.         call flushdesc.
  787. ;increase block number (after flushdesc!!!)
  788.         ld l,TRDOSFCB.block
  789.         inc [hl] ;cur block for write, next block for read
  790. ;теперь дескриптор невалидный, пока не создадим его в начале другого flush
  791. ;zero lastlen (after flushdesc!!!)
  792.         ld l,TRDOSFCB.lastlen+1 ;(HSB), LSB is already 0 if not fclose
  793.         ld [hl],0
  794. flushnblk.
  795.  
  796.         pop bc
  797.         ret
  798.  
  799. addsectors
  800. ;bc=trsec
  801. ;lx=number of sectors
  802. ;keeps a
  803.         inc lx
  804.         jr flush_addsectors_go
  805. flush_addsectors0
  806.         inc c
  807.         bit 4,c
  808.         jr z,$+2+3
  809.         ld c,0
  810.         inc b
  811. flush_addsectors_go
  812.         dec lx
  813.         jr nz,flush_addsectors0
  814.         ret
  815.  
  816. fwrite
  817. ;hl=poi to data
  818. ;de=poi to TRDOSFCB
  819. ;bc=size
  820.         ;EXPORT fwrite
  821. ;fwrite.A.=$+1
  822.         ;EXPORT fwrite.A.
  823.         ;ld hl,0 ;poi to data
  824.          ;ld de,0 ;total processed bytes TODO
  825. ;fwrite.C.=$+1
  826.         ;EXPORT fwrite.C.
  827.         ;ld bc,0 ;count
  828. ;fwrite0.
  829.         ;push bc
  830. ;fwrite.B.=$+1
  831.         ;EXPORT fwrite.B.
  832.         ;ld bc,0 ;size
  833.        ex de,hl
  834.        call trdossetdrvfromtrdosfcb
  835.        ex de,hl
  836.         ld (fread00size),bc
  837. fwrite00.
  838.         ld a,[hl]
  839.         push de
  840.         push hl
  841.          ;push de
  842. ;fwrite.D.=$+1
  843.         ex de,hl ;ld hl,0 ;poi to TRDOSFCB
  844.         call fwrite1. ;a=data ;keeps bc
  845.          ;pop de
  846.          ;inc de
  847.         pop hl
  848.         pop de
  849.         ;cpi
  850.         db 0xed,0xa1
  851.         jp pe,fwrite00.
  852.         ;pop bc
  853.         ;dec hl
  854.         ;cpi
  855.         ;db 0xed,0xa1
  856.         ;jp pe,fwrite0.
  857.          ;ex de,hl ;hl = total processed bytes
  858.         jp fread00q ;ret
  859.  
  860. ;FUNC UINT readsectors FORWARD(PBYTE buf, UINT trsec, BYTE count);
  861. readsectors
  862. readsectors.A.=$+1 ;buf
  863.         ld hl,0
  864. readsectors.B.=$+1 ;trsec
  865.         ld de,0
  866. readsectors.C.=$+1 ;count
  867.         ld b,0
  868.         jr rdsectors.
  869. rdsecDOSBUF
  870.         ld hl,DOSBUF
  871. rdsec.
  872.         ld b,1
  873. rdsectors.
  874.         ld c,0x05
  875.         ;push hl ;read address
  876.         ;ld hl,0x8000 ;pgkillable
  877.         ;push bc
  878.         ;push hl
  879.         jp iodos. ;hl=next sector
  880.         ;pop hl
  881.         ;pop bc
  882.         ;ld c,0
  883.         ;pop de ;read address
  884.         ;ldir
  885.         ;ld hl,(0x5cf4);(sysvars+0x00f4) ;next sector
  886.         ;ret
  887.  
  888. ;FUNC UINT writesectors FORWARD(PBYTE buf, UINT trsec, BYTE count);
  889. writesectors
  890. writesectors.A.=$+1 ;buf
  891.         ld hl,0
  892. writesectors.B.=$+1 ;trsec
  893.         ld de,0
  894. writesectors.C.=$+1 ;count
  895.         ld b,0
  896.         jr wrsectors.
  897. wrsecDOSBUF
  898.         ld hl,DOSBUF
  899. wrsec.
  900.         ld b,1
  901. wrsectors.
  902.         ;push bc
  903.         ;push de ;track,sector
  904.         ;ld c,0
  905.         ;ld de,0x8000 ;pgkillable
  906.         ;push de
  907.         ;ldir
  908.         ;pop hl
  909.         ;pop de ;track,sector
  910.         ;pop bc
  911.         ld c,0x06
  912. iodos.
  913. trdoscurdrive=$+1
  914.         ld a,0xff
  915.         call iodos_setdrive
  916.         ;ld iy,23610
  917.         call dos3d13.
  918.         ld hl,(0x5cf4);(sysvars+0x00f4) ;next sector
  919.         ret
  920.                
  921. iodos_setdrive
  922. trdosolddrive=$+1
  923.         cp 0xff
  924.         ret z
  925.         ld (trdoscurdrive),a
  926.         push bc
  927.         push de
  928.         push hl
  929.         if atm == 1
  930.                         ld bc,0xfd77
  931.                         ld a,0xa6
  932.                         out (c),a
  933.                         ld a,(trdoscurdrive)
  934.                         or 0x04
  935.                         out (0xff),a
  936.                         ld bc,0xbd77
  937.                         ld a,0xae
  938.                         out (c),a
  939.                         ld c,0x00
  940.                         call dos3d13nopg.
  941.         endif
  942.                         ld a,(trdoscurdrive)
  943.                         ld c,1
  944.                         call dos3d13nopg.
  945.                         ;call iodos_chd_cherr
  946.                         ld c,0x18
  947.                         call dos3d13nopg.
  948.                         call iodos_chd_cherr
  949.                         ;ld bc,0x0105
  950.                         ;ld hl,trdos_sectorbuf
  951.                         ;ld de,0x0008
  952.                         ;call dos3d13nopg.
  953.                         ;call iodos_chd_cherr
  954.                 ld a,(trdoscurdrive)
  955.                 ld (trdosolddrive),a
  956.                 xor a
  957.                 jr iodos_chd_noerr
  958. iodos_chd_cherr
  959.                 or a
  960.                 ret z
  961.                 ld a,0xff
  962.                 ld (trdosolddrive),a
  963.         dec a ;Alone Coder: чтобы были не равны в следующий заход, тогда опять будем пытаться включить драйв
  964.         ld (trdoscurdrive),a
  965.                 ld a,0xff
  966.                 pop hl
  967. iodos_chd_noerr
  968.         pop hl
  969.         pop de
  970.         pop bc
  971.                 ret