Login

Subversion Repositories NedoOS

Rev

Rev 1543 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

trdosgetdirfcb
        ld hl,fcb2+FCB_FNAME
        call dotname_to_cpmname ;de -> hl
        ld hl,mfilinfo+FILINFO_FSIZE
        ld de,fcb2+FCB_FSIZE
        ld bc,4
        ldir
        ld hl,(mfilinfo+FILINFO_FDATE)
        ld (fcb2+FCB_FDATE),hl
        ld hl,(mfilinfo+FILINFO_FTIME)
        ld (fcb2+FCB_FTIME),hl      
        ld a,(mfilinfo+FILINFO_FATTRIB)
        ;and 0x10
        ld (fcb2+FCB_FATTRIB),a
        ret

dos3d13.
;hl=addr
;de=track,sector
;b=size/256
;c=5 (read), 6 (write)
        ;push bc
        ;ex de,hl
        ;call BDOS_preparedepage
        ;call BDOS_setdepage ;TODO убрать в драйвер
        ;ex de,hl
        ;pop bc
dos3d13nopg.
;bc,de,hl,a (for c=1)
        push iy
        exx
        ld e,(iy+app.gfxmode)
        ld iy,23610
        push af
dos3d13_waitnospace0
        ld a,0x7f
        in a,(0xfe)
        rra
        jr nc,dos3d13_waitnospace0
        pop af
        call dos3d13_resident
        pop iy
        ret

trdos_fread
        ld hl,FCB_FFSFCB
        add hl,de
        ld a,(hl)
        inc hl
        ld h,(hl)
        ld l,a ;hl = poi to TRDOSFCB
       
        ;ld de,(dma_addr) ;de=poi to data
        call BDOS_getdta
        call BDOS_preparedepage
        call BDOS_setdepage ;TODO убрать в драйвер

        ex de,hl ;hl=poi to data, de=poi to TRDOSFCB
        ld bc,128 ;bc=size
         push bc ;blocksize
        call fread ;hl=total processed bytes
         pop bc ;blocksize
        call movedma_addr ;+bc
        ld a,l
        xor 0x80 ;!=, если прочитали не 128 байт
;a=0: OK (прочитали 128 байт)
;a=128: fail (прочитали 0 байт)
;a=???: OK (последний блок файла меньше 128 байт)
        ;ld a,(_waseof)
        ;and 128 ;EOF (чтобы было как в FatFS)
        ;xor a ;success
        ret
trdos_fread_b
;b=trdosfcb high
;de=poi to data
;hl=size
        push hl ;Number of bytes to read
        ld h,b
        ld l,0
        call BDOS_preparedepage
        call BDOS_setdepage ;TODO убрать в драйвер
        pop bc ;Number of bytes to read
        ex de,hl
;hl=poi to data
;de=poi to TRDOSFCB
;bc=size
        jp fread ;hl=total processed bytes, a=error

       
trdos_fwrite
        ld bc,128 ;bc=size
;trdos_fwrite_nbytes
        ld hl,FCB_FFSFCB
        add hl,de
        ld a,(hl)
        inc hl
        ld h,(hl)
        ld l,a ;hl = poi to TRDOSFCB

        push bc
        ;ld de,(dma_addr) ;de=poi to data
        call BDOS_getdta
        call BDOS_preparedepage
        call BDOS_setdepage ;TODO убрать в драйвер
        pop bc
        ex de,hl ;hl=poi to data, de=poi to TRDOSFCB
         push bc ;blocksize
        call fwrite
         pop bc ;blocksize
        call movedma_addr ;+bc
        xor a ;success
        ret
trdos_fwrite_b
;b=trdosfcb high
;de=poi to data
;hl=size
        ;jr $
        push hl ;Number of bytes to write
        ld h,b
        ld l,0
        call BDOS_preparedepage
        call BDOS_setdepage ;TODO убрать в драйвер
        pop bc ;Number of bytes to write
        ex de,hl
;hl=poi to data
;de=poi to TRDOSFCB
;bc=size
        jp fwrite ;hl=total processed bytes, a=0: no error
       
trdos_searchnext
;hl=адрес в директории
;de=FCB, куда класть описатель
;out: hl=следующий адрес в директории, z=error
         ld a,' '
         ld (de),a
        ld a,(hl)
        or a
        ret z ;jr z,BDOS_fsearch_loadloop_noFATFS_empty
        ld bc,8
        ldir
        ld a,(hl)
        ldi
        cp 'B'
        jr nz,trdos_searchnext_nobas
;basic, если start < 0x4100 (чтобы можно было .BAT)
         inc hl
         ld a,(hl)
         cp 0x41
         jr nc,trdos_searchnext_decnobas
         inc hl
        ld a,' '
        ld (de),a
        inc de
        ld (de),a
        inc de
        jr trdos_searchnext_basq
trdos_searchnext_decnobas
         dec hl
trdos_searchnext_nobas
        ldi
        ldi
trdos_searchnext_basq
        ld de,fcb2+FCB_FSIZE
        ldi
        ldi
        xor a
        ld (de),a
        inc de
        ld (de),a
        ld de,fcb2+FCB_FDATE
        ld (de),a
        inc de
        ld (de),a
        ld de,fcb2+FCB_FATTRIB
        ld (de),a
        ld de,fcb2+FCB_FTIME
       ld a,l ;file pos in sector
       and 0xf0
        ld (de),a
        inc de
       ld a,h
       sub trdos_catbuf/256 ;sector
        ld (de),a
        ld bc,16-11-2
        add hl,bc
        inc a ;nz
        ret

trdos_fopen
;a=drive 0..3
        push de ;FCB
        inc de ;filename
        ld c,'r'
trdos_fopen_go
;a=drive 0..3
        call nfopen ;out: a (0=success, 0xff=fail), hl=TRDOSFCB
        pop bc ;bc = pointer to opened FCB (TODO чем отличается от unopened?)
        or a
        ret nz ;error
        ex de,hl ;de=TRDOSFCB
        ld hl,FCB_FFSFCB
        add hl,bc
        ld (hl),e
        inc hl
        ld (hl),d
        ret

trdos_fcreate
;a=drive 0..3
        push de ;FCB
        inc de ;filename
        ld c,'w'
        jr trdos_fopen_go
        ;call nfopen
        ;pop bc ;bc = pointer to opened FCB (TODO чем отличается от unopened?)
        ;xor a ;success ;TODO ошибка создания
        ;ret

trdos_fclose
        ;ld hl,TRDOSFCB1
        ld hl,FCB_FFSFCB
        add hl,de
        ld a,(hl)
        inc hl
        ld h,(hl)
        ld l,a ;hl = poi to TRDOSFCB
trdos_fclose_hl
        call fclose
        xor a ;success
        ret

trdos_getfilesize
;b=handle
;out: dehl=filesize
        xor a
        ld h,a
        ld l,a
        ld (trdos_getfilesizeLSW),hl
        ld (trdos_getfilesizeHSB),a
       
        ld h,b
        ld l,1 ;TRDOSFCB filename
       
        ld c,9 ;c=FILENAMESZ
        call findfile
        jr nz,trdos_getfilesize_q
;hl,de=after filename
trdos_getfilesize_0
        ;push bc
        push de
        push hl
;de=after filename on disk
        ex de,hl
        inc hl
        inc hl
        ld e,(hl)
        inc hl
        ld d,(hl) ;length
trdos_getfilesizeLSW=$+1
        ld hl,0
        add hl,de
        ld (trdos_getfilesizeLSW),hl
        ld hl,trdos_getfilesizeHSB
        jr nc,$+3
        inc (hl)
        pop hl
        pop de
        ;pop bc
        call findfile_continue
        jr z,trdos_getfilesize_0
trdos_getfilesize_q
        ld hl,(trdos_getfilesizeLSW)
trdos_getfilesizeHSB=$+1
        ld de,0
        xor a
        ret

trdos_getfiletime
;de=path/file ASCIIZ string
;out: ix=date, hl=time (counted from file index)
        ld c,9 ;c=FILENAMESZ
        call findfile
;carry = off, a = 0, de = DOSBUF after filename, b = 8-sector
        ld a,e
       and 0xf0
        ld l,a
        ld a,8
        sub b
        ld h,a
        ld ix,0
        ret

trdos_seekhandle_bof
;b=file handle
        ld h,b
        call nfopen_reopen ;переоткрываем файл
        jr trdos_seekhandle_q
        ;pop hl
        ;pop de
        ;xor a
        ;ret
       
trdos_seekhandle
;                    B = File handle
;                    [A = Method code: 0=begin,1=cur,2=end]
;                DE:HL = Signed offset
;     Results:       A = Error
;                DE:HL = New file pointer
;только для чтения!!!
        push de
        push hl

        ld a,e
        or h
        or l
        jr z,trdos_seekhandle_bof ;если addr=0, то переоткрыть файл
;addrm1=addr-1, т.к. все указатели и номера в TRDOSFCB при чтении рассчитаны на предыдущий байт
        ld a,e
        ld de,1
        ;or a
        sbc hl,de
        sbc a,d;0
        ld (trdos_seekhandleaddrLSW),hl
        ld (trdos_seekhandleaddrHSB),a        
       
        xor a
        ld h,a
        ld l,a
        ld (trdos_seekhandlesizeLSW),hl
        ld (trdos_seekhandlesizeHSB),a
       
        ld h,b
        ld l,1 ;TRDOSFCB filename
       
        ld c,9 ;c=FILENAMESZ
        call findfile
        jr nz,trdos_seekhandle_q
;пройти блоки файла, суммировать totalsize+=blocksize и остановиться на том, где addrm1 < totalsize+blocksize ((addrm1-totalsize) < blocksize)
;hl,de=after filename
trdos_seekhandle_0
        push bc
        push de
        push hl
;de=after filename on disk
        ex de,hl
        ld a,(hl)
        ld (trdos_seekhandle_blocknumber),a
        inc hl
        inc hl
        ld e,(hl)
        inc hl
        ld d,(hl) ;length
        ld (trdos_seekhandle_length),de
        inc hl
        inc hl
        ld c,(hl)
        inc hl
        ld b,(hl) ;track,sector
        ld (trdos_seekhandle_trsec),bc
trdos_seekhandleaddrLSW=$+1
        ld hl,0
        ld c,l ;addrm1&0xff
trdos_seekhandleaddrHSB=$+1
        ld a,0
trdos_seekhandlesizeLSW=$+1
        ld de,0
        or a
        sbc hl,de
trdos_seekhandlesizeHSB=$+1
        sbc a,0
;ahl=addrm1-totalsize
;keep h
        ld (trdos_seekhandle_shiftinblock),hl
;остановиться на том блоке, где addrm1 < totalsize+blocksize ((addrm1-totalsize) < blocksize)
trdos_seekhandle_length=$+1
        ld de,0 ;blocksize = length блока
        or a
        sbc hl,de
        sbc a,0
        jp m,trdos_seekhandle_blockfound
       
        ld hl,(trdos_seekhandlesizeLSW)
        ld a,(trdos_seekhandlesizeHSB)
        add hl,de
        adc a,0 ;ahl=totalsize+blocksize
        ld (trdos_seekhandlesizeLSW),hl
        ld (trdos_seekhandlesizeHSB),a
        pop hl
        pop de
        pop bc
        call findfile_continue
        jr z,trdos_seekhandle_0
;TODO error
trdos_seekhandle_q
        pop hl
        pop de
        xor a
        ret

trdos_seekhandle_blockfound
        pop hl ;TRDOSFCB
        push hl
;установить TRDOSFCB.remain = addrm1&0xff
        ld l,TRDOSFCB.remain
        ld (hl),c
;установить TRDOSFCB.firstsector = первый сектор блока
trdos_seekhandle_trsec=$+1
        ld bc,0
        ld l,TRDOSFCB.firstsector
        ld (hl),c
        inc l
        ld (hl),b
;установить TRDOSFCB.lastlen = length блока
        ld l,TRDOSFCB.lastlen
        ld (hl),e
        inc l
        ld (hl),d
;установить TRDOSFCB.secinblk = число оставшихся секторов в блоке = размер блока - (addrm1-totalsize)/256 - 1 (может получиться 0, если последний сектор блока уже загружен)
        dec de
        inc d
        ld a,d
trdos_seekhandle_shiftinblock=$+1
        ld de,0
        sub d
        dec a
        ld l,TRDOSFCB.secinblk
        ld (hl),a
;установить TRDOSFCB.cursector = первый сектор блока + (addrm1-totalsize)/256, прочитать этот сектор и инкрементировать
        ld lx,d
        call addsectors
        ld d,b
        ld e,c
        inc h
        ld l,0 ;poi to buf
        call rdsec.
        ;hl=next sector
        ex de,hl
        pop hl
        ld l,TRDOSFCB.cursector
        ld (hl),e
        inc l
        ld (hl),d
;установить TRDOSFCB.block = номер блока + 1(!), т.е. всегда следующий блок
        ld l,TRDOSFCB.block
trdos_seekhandle_blocknumber=$+1
        ld (hl),0
        inc (hl)
        pop de
        pop bc
        jr trdos_seekhandle_q

trdos_delete
       ld (trdoscurdrive),a
;DE = Drive/path/file ASCIIZ string
        ex de,hl
        call findlastslash. ;de=last slash
        ld hl,trdos_tempfilename
        push hl
        call dotname_to_cpmname ;de -> hl
        pop de
        jp nfdel_filename
        ;xor a
        ;ret
       
trdos_rename
       ld (trdoscurdrive),a
;DE = Drive/path/file ASCIIZ string, HL = New filename ASCIIZ string
        push de
        call findlastslash. ;de=last slash
        ld hl,trdos_tempfilename2
        call dotname_to_cpmname ;de -> hl
       
        pop hl ;hl = poi to filename in string

        call findlastslash. ;de=last slash
        ld hl,trdos_tempfilename
        push hl
        call dotname_to_cpmname ;de -> hl
        pop hl ;hl=filename
        ld c,9 ;c=FILENAMESZ
        call findfile
        jr nz,trdos_rename_q
;hl,de=after filename
        push hl
        ld a,(de)
        ld hl,trdos_tempfilename2+9 ;&newext[1]
        sub (hl) ;ext[1] - newext[1]
        ld (trdos_rename_ext1diff),a
        pop hl
trdos_rename_0
        push bc
        push de
        push hl
         push bc
;de=after filename
        ld hl,trdos_tempfilename2
        ld a,e
        and 0xf0
        ld e,a
        ld bc,9
        ldir
       dec hl
       ld a,[hl]
       inc hl
       cp 'B'
       jr nz,trdos_rename_nobasic
       inc de
       inc de
       ld a,[de] ;length LSB
       inc de
       ex af,af' ;'
       ld a,[de] ;length HSB
       dec de
       dec de
       ld [de],a ;start HSB
       ex af,af' ;'
       dec de
       ld [de],a ;start LSB
       jr trdos_rename_basicq
trdos_rename_nobasic
        ld a,(de) ;block # + ext[1]
trdos_rename_ext1diff=$+1
        sub 0
        ld (de),a ;block # + newext[1]
        inc hl
        inc de
        ld a,(hl)
        ld (de),a ;newext[2]
trdos_rename_basicq
         pop bc
        ld d,0 ;track
        ld a,8
        sub b
        ld e,a ;sector
        call wrsecDOSBUF
        pop hl
        pop de
        pop bc
        call findfile_continue
        jr z,trdos_rename_0
trdos_rename_q
        xor a
        ret

dotname_to_cpmname
;de -> hl
;out: de=pointer to termination character
        ;push hl ;buffer
       
        push de ;ASCIIZ string for parsing
        push hl ;Pointer to 11 byte buffer
        ld d,h
        ld e,l
        inc de
        ld [hl],' '
        ld bc,11-1
        ldir ;empty filename
        pop hl ;Pointer to 11 byte buffer
        pop de ;ASCIIZ string for parsing

;change dots to 1, except the last
        ld a,(de)
        cp '.'
        jr z,parse_filename_changedots
        push de
        jr parse_filename_changedots0getgo
parse_filename_changedots0get
         ld a,1
         ld (de),a
parse_filename_changedots0getgo
        ld b,d
        ld c,e
parse_filename_changedots0
        ld a,(de)
        cp '.'
        jr z,parse_filename_changedots0get
        inc de
        or a
        jr nz,parse_filename_changedots0
        ld a,(bc)
        cp 1
        jr nz,$+5
         ld a,'.'
         ld (bc),a
        pop de
parse_filename_changedots

        ld b,9
       
        ld a,(de)
        cp '.'
        jr nz,parse_filename0.
        ld (hl),a
        inc de
        ld a,(de)
        cp '.'
        jr nz,parse_filenameq_findterminator.
        inc hl
        ld (hl),a
        jr parse_filenameq_findterminator.
parse_filename0.
        ld a,[de]
        or a
        ret z ;jr z,parse_filenameq. ;no extension in string
        cp '.'
        jr z,parse_filenamedot. ;можем уже быть на терминаторе
         ;cp 0x80
         ;jr nc,$+4
         ;or 0x20
         cp 1
         jr nz,$+5
          ld a,'.'
          ld [de],a
        ld [hl],a
        inc de
        inc hl
        djnz parse_filename0.
;9 bytes in filename, no dot (9th byte goes to extension)
;возможно, длинное имя, надо найти, что раньше - точка или терминатор
;можем уже быть на терминаторе или на точке
        dec hl
        ld [hl],' '
parse_filenamelongname0.
        ld a,[de]
        or a
        ret z ;jr z,parse_filenameq. ;a=0
        inc de
        cp '.'
        jr z,parse_filenameLONGnamedot. ;можем уже быть на терминаторе
        jr parse_filenamelongname0.
parse_filenamedot.
        inc de
        inc hl
        djnz $-1 ;hl points to extension in FCB
        dec hl
parse_filenameLONGnamedot.
        ld a,[de] ;extension in string
        or a
        ret z ;jr z,parse_filenameq. ;a=0
         ;cp 0x80
         ;jr nc,$+4
         ;or 0x20
        ld [hl],a ;extension in FCB
        inc hl
        inc de
        ld a,[de] ;extension in string
        or a
        ret z ;jr z,parse_filenameq. ;a=0
         ;cp 0x80
         ;jr nc,$+4
         ;or 0x20
        ld [hl],a ;extension in FCB
        inc hl
        inc de
        ld a,[de] ;extension in string
        or a
        ret z ;jr z,parse_filenameq. ;a=0
         ;cp 0x80
         ;jr nc,$+4
         ;or 0x20
        ld [hl],a ;extension in FCB
parse_filenameq_findterminator.
        inc de
        ld a,[de]
        or a
        jr nz,parse_filenameq_findterminator.
;parse_filenameq. ;de на терминаторе
        ;pop hl ;buffer
        ret ;a=0
       
trdos_tempfilename
        ds 11
trdos_tempfilename2
        ds 11
BDOS_parse_filename_cpmnamebuf
        ds 11 ;TODO объединить с одним из tempfilename