home *** CD-ROM | disk | FTP | other *** search
- ;===========================================================================
- ;
- ; VFSUBS1.Z80 - File Loading and Sorting and Ring Maintenance Routines
- ;
- ;===========================================================================
-
-
- ; FILELOAD loads the files into the buffer, setting up the ring
- ; Return: Z if load OK,
- ; NZ if no files loaded
-
- fileload:
- call getdpb ; Get dpb values for f, gf, s commands
- ld hl,(ring) ; Start --> current position of ring
- ld (ringpos),hl ; Initialize ring pointers
- ld (ringend),hl ; So ring is empty.
- ld (bufstart),hl ; Preset now in case ring is empty
- ld hl,0 ; No files found (so far)
- ld (ringcnt),hl
-
- ld a,1 ; 1 = get system mask.
- call filemask ; Get system file spec.
-
- ; Build ring with filename positioned in default FCB area
-
- xor a ; Clear search 'fcb'..
- ld (fcbext),a ; Extent byte..
- ld (fcbrno),a ; And record number.
- ld de,fcb ; Default fcb for search
- ld c,srchf ; Of first occurrence.
- call bdos
- inc a ; 0ffh --> 00h if no file found
- jr nz,setring ; If found, branch and build ring.
- noload:
- inc a ; Indicate no files loaded.
- ld (canflg),a ; Return non-zero for error.
- ret
-
-
- ;---------------------------------------------------------------------------
-
- ; RINGEMPT - Test ring empty, Return Zero if no files
-
- ringempt:
- push hl ; Save HL
- ld hl,(ringcnt) ; Get the count
- ld a,h
- or l
- pop hl ; Restore HL
- ret
-
- ;---------------------------------------------------------------------------
-
- ; SETRING - Establish ring (circular list) of filenames
- ; - put each found name in ring.
- ; - A = offset into 'TBUFF' name storage
-
- setring:
- dec a ; Un-do 'inr' from above and below
- rrca
- rrca
- rrca ; Effectively A*32
- add a,tbuff ; Add page offset and..
- ld l,a ; Put address into hl.
- ld h,0
-
- if remote
- call getwhl ; If wheel is off, never show SYS files
- jr z,noshow
- endif ;remote
-
- ld a,(nosysa) ; Show $SYS files?
- or a
- jr z,showsys
-
- noshow:
- push hl ; Save HL
- ld de,10
- add hl,de ; Point to $SYS attribute
- ld a,(hl) ; Get the byte
- pop hl ; Restore HL
- rla ; Rotate attribute into carry
- ld a,' '
- jr c,setring1 ; Skip $SYS files
-
- showsys:
- ld a,(fcb) ; Get drive/user designator and..
- ld (hl),a ; Put into 'fcb' buffer.
- ld de,(ringpos) ; Pointer to current load point in ring
- ld b,eltsiz-1 ; Move drive designator and name to ring
- call movec ; Move attributes as well
- ex de,hl ; De contains next load point address
- push hl
- dec hl
- dec hl
- dec hl ; Point to R/O attribute
- ld a,128
- cp (hl) ; Check if set
- pop hl
- ld a,' '
- jr nc,setring0 ; Not R/O
- ld a,'r'
- setring0:
- ld (hl),a ; Space for potential..
- inc hl ; Tagging of files for mass copy.
- ld (ringpos),hl ; Store and search..
-
- ld a,(maxpage) ; Get maximum page of memory allowed.
- cp h ; About to overflow zcpr3?
- jp c,b$size1 ; Br if above valid range.
-
- ld hl,(ringcnt) ; Another file found.
- inc hl
- ld (ringcnt),hl ; Update file count.
-
- setring1:
- ld c,srchn ; For next occurrence.
- ld de,fcb ; Filename address field
- call bdos
- inc a ; If all done, 0ffh --> 00h.
- jr nz,setring ; If not, put next name into ring.
- call ringempt
- jr z,noload
-
- ; All filenames in ring -- setup ring size and copy-buffer start point
-
- ld hl,(ringpos) ; Next load point of ring is start of buffer
- ld (ringend),hl ; Set ring end..
- ld (bufstart),hl ; And copy-buffer start.
-
- ;---------------------------------------------------------------------------
-
- ; Sort ring of file entries
- ; - Shell sort algoritm used
-
- sort:
-
- ; Bypass sort if only 1 element in ring
-
- ld hl,(ringcnt) ; Get number of files in ring
- dec hl ; Only 1 file?
- ld a,h
- or l
- jr z,tblinz ; Bypass sort if only one file in ring.
-
- ; Set GAP to (power of 2 nearest CNT) - 1
-
- ex de,hl ; De = cnt
- inc de
- ld hl,4 ; Set initial gap.
- jr sort02
- sort01:
- add hl,hl ; Double gap
- sort02:
- call cmpdehl ; Compare current gap to cnt
- jr nc,sort01 ; Br if gap < cnt
- dec hl ; Set gap = gap-1
- ld (ringgap),hl
-
- ; DO WHILE (GAP>1)
-
- jr sort07
- sort03:
- ld hl,(ringgap) ; Gap = gap / 2
- call shftrh
- ld (ringgap),hl
-
- ; DO J = 0 TO (CNT-GAP)
-
- ld hl,(ringcnt)
- ld de,(ringgap)
- ld a,l
- sub e
- ld l,a
- ld a,h
- sbc a,d
- ld h,a
- ld (ringdiff),hl ; Save (cnt-gap) for inner loop.
- ld hl,0 ; J = 0
- sort04:
- ld (ringj),hl
- ex de,hl ; De = j
- ld hl,(ringdiff) ; Hl = (cnt-gap)
- call cmpdehl ; J > (cnt-gap)?
- jr nc,sort07 ; Br if so.
-
- ; DO I = J TO 0 BY (-GAP) WHILE (ENTRY(I) > ENTRY(I+GAP))
-
- ld hl,(ringj) ; I = j
- sort05:
- ld (ringi),hl
- ld a,h ; Exit if i = -1
- and l
- inc a
- jr z,sort06
- ex de,hl ; De = i
- ld hl,(ringgap) ; Hl = gap
- add hl,de ; De = i, hl = i+gap
- call ringcmp ; Compare elements for potential swap.
- jr c,sort06
-
- ; Swap ENTRY(I) and ENTRY(I+GAP)
-
- call ringswap
-
- ; ENDDO (I = J TO 0)
-
- ld de,(ringgap) ; I = i - gap
- ld a,d
- cpl
- ld d,a
- ld a,e
- cpl
- ld e,a
- inc de
- ld hl,(ringi)
- add hl,de
- jr c,sort05
-
- ; ENDDO (DO J = 0 TO (CNT-GAP))
-
- sort06:
- ld hl,(ringj) ; J=j+1
- inc hl
- jr sort04
-
- ; ENDDO (DO WHILE (GAP>1))
-
- sort07:
- ld de,-2 ; Gap > 1?
- ld hl,(ringgap)
- add hl,de
- jr c,sort03
-
- ; Sort done -- initialize tables for fast CRC calculations
-
- tblinz:
- call initcrc
-
- ; Calculate buffer maximum available record capacity
-
- b$size:
- ld hl,(bdos+1) ; Get 'bdos' entry (fbase)
-
- if not warmboot
- ld de,-ccp_ln
- add hl,de
- endif ; Not warmboot
-
- dec hl
- ex de,hl ; De = highest buffer address
- ld hl,(bufstart) ; Hl = buffer start addr (end of ring list)
- ld a,e ; Hl = de - hl = buffer size (bytes)
- sub l
- ld l,a
- ld a,d
- sbc a,h
- ld h,a
- jr c,b$size1 ; Error if start addr > end addr
-
- ld b,7+1 ; Shift hl right 7 bits
- call shiftlp ; To divide by 128.
-
- ld a,h ; Memory available for copy?
- or l
- jr nz,b$size2 ; Yes, buffer memory space available.
-
- b$size1:
- xor a ; Error code
- inc a
- inc a ; Indicate no room for files selected.
- ld (canflg),a ; Return non-zero for error.
- ret
-
- b$size2:
- ld (rec$max),hl ; Store maximum record count.
- xor a ; Return z for ok
- ld (canflg),a
- ret
-
- ;------------------------------
-
- ; RINGCMP - Compare Ring Elements
- ; - DE - First element number
- ; - HL - Second element number
-
- ringcmp:
- call ringaddr ; Get address of element in hl
- ex de,hl
- call ringaddr ; Get address of element in de
- ex de,hl
- push hl ; Save position pointers..
- push de ; For potential swap.
- ld a,(defalfa) ; Check for type of alphabetization
- or a ; If zero, alpha by type and name
- jr z,sorttn
-
- ; sort by file name and type
-
- ld b,12 ; # of characters to compare
- call cmpstr ; Do comparison
- jr nocmp ; Final test
-
- ;------------------------------
-
- ; sort by file type and name
-
- sorttn:
- push hl ; Save ptrs
- push de
- ld bc,9 ; Pt to type
- add hl,bc
- ex de,hl
- add hl,bc
- ex de,hl
- ld b,3 ; 3 chars in file type
- call cmpstr ; Compare type
- pop de ; Get ptrs
- pop hl
- jr nz,nocmp ; Final test
- push hl
- push de
- ld b,8 ; 8 chars in file name
- inc hl ; Pt to first
- inc de
- call cmpstr ; Compare name
- pop de ; Get ptrs
- pop hl
- jr nz,nocmp ; Final test
- call cmpdh ; Ignore attribute
-
- ;------------------------------
-
- ; final test for swapping purposes
-
- nocmp:
- pop de
- pop hl
- ret
-
- ;------------------------------
-
- ; RINGADDR - Get address of Ring Element
- ; - HL = Element number
- ;
- ; Note - assumes ELTSIZ = 13
-
- ringaddr:
- push bc ; Save work regs
- push de
-
- ld b,h ; Bc = hl
- ld c,l
- add hl,hl ; Hl = hl * 2
- add hl,bc ; * 3
- add hl,hl ; * 6
- add hl,hl ; * 12
- add hl,bc ; * 13
- ld de,(ring) ; Get ring start address
- add hl,de ; Point to array element
-
- pop de ; Restore work regs
- pop bc
- ret
-
- ;------------------------------
-
- ; RINGSWAP - Swap ring elements
- ; - HL -> first element
- ; - DE -> second element
-
- ringswap:
- ld b,eltsiz ; Length of element to swap
- swap:
- ld c,(hl) ; Get character from one string..
- ld a,(de) ; And one from other string.
- ld (hl),a ; Second into first
- ld a,c ; First into second
- ld (de),a
- inc hl ; Bump swap pointers
- inc de
- djnz swap
- ret
-
- ;------------------------------
-
- ; CMPSTR- left to right compare of two strings
- ; DE -> to 'a' string,
- ; HL -> to 'b' string,
- ; B contains string length.)
-
- cmpstr:
- call cmpdh
- ret nz ; If not equal, set flag.
- inc hl ; Bump compare..
- inc de ; Pointers and do next character.
- djnz cmpstr ; If done compare, strings are equal
- ret
-
- ;------------------------------
-
- ; CMPDH - Make comparison without regard to the attribute bit
-
- cmpdh:
- push bc ; Save BC
- ld c,7fh ; Mask
- ld a,(hl) ; B character
- and c ; Strip attribute
- ld b,a ; Save it
- ld a,(de) ; A character
- and c ; Strip attribute
- cp b ; Set flags, carry if B > A
- pop bc ; Restore BC
- ret
-
- ;---------------------------------------------------------------------------
-
- ; FILELERR - Process File Load Error
-
- ; - No files in current DIR (or not enough Storage to hold them)
- ; Report it on the error line
-
- filelerr:
- ld a,(canflg) ; Get log-cancel flag
- or a
- jr nz,filerr2 ; Br if not from fileload
- call ermsg ; Due to movdone (canflag = 0)
- db 'List Empty',0
- ret
-
- filerr2:
- dec a ; Was canflg = 1?
- jr nz,filerr3 ; Br if not
- call ermsg ; Due to fileload (canflg = 1)
- db 'No File Found',0
- ret
-
- filerr3:
- call ermsg ; Due to fileload (canflg = 2)
- db 'No Room for file list',0
- ret
-
- ;---------------------------------------------------------------------------
-
- ; RINGFCB - Copy filename from RINGPOS to SFCB
- ; - Initialize FCB
-
- ringfcb:
- ld hl,(ringpos) ; Move name from ring to source 'fcb'
- ld de,s$fcb ; Place to move filename and..
- ld b,12 ; Amount to move (fall thru to move)
- call movec ; Set the file name, type and attributes
- ld de,s$fcb ; Get fcb address again
- jp initfcb ; Initialize fcb and return.
-