home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
SB180
/
RAMFIX.LBR
/
RAMFIX.1Z0
/
RAMFIX.180
Wrap
Text File
|
2000-06-30
|
8KB
|
389 lines
.comment ~
Program: FIXRAM
Purpose: The SB180FX Boot ROM destroys two bytes at the beginning
of each of the banks of memory. Since these could be in
the middle of a file, or a directory, ths is not a good
situation. FIXRAM will examine each RAM disk configured
on an XBIOS system. If this disk contains an area that
is susceptible to such corruption, it will create a file
named !!!!!RAM.BAD in user area 31. This file will have
allocated to it all of the allocation groups that are subject
to this corruption.
Use: The FIXRAM program should be run each time the MDINIT utility
is run. This will insure that the disk cannot contain
corruptible areas. If a group is flagged as allocated in
the FIXRAM report, it may mean that you have a directory
group in a corruptible area. Add 1 to the number of tracks
before directory for this disk to solve this problem.
Cautions: This program creates the file by putting groups in a file
control block, forcing a write to the FCB, and then closing
the file. This technique works with ZRDOS17, but may fail
with other DOSes. Check the operation of this technique on
your system by running it and then using DU3 to make sure
the allocated groups agree with the report from FIXRAM.
Error: This program will flag the first group in the upper memory
part of the RAM disk as being a candidate. It is not, but
this is a small price to pay for such safety.
~
cr equ 13
lf equ 10
wboot equ 0
bdos equ 5
bdos37 equ 37
llrec equ 128
;
; Disk Header Block
;
dhb_skew equ 0 ; Skew values
dhb_dirbufp equ 8 ; Directory buffer address
dhb_dpbp equ 10 ; Disk parameter block address
dhb_chkp equ 12 ; Check buffer pointer
dhb_allvp equ 14 ; Allocation vector address
dhb_length equ 16 ; Length of disk header block
ldirbuf equ 128 ; Length of directory buffer
;
; Disk Parameter Block
;
dpb_spt equ 0 ; Sectors per track
dpb_bs equ 2 ; Block shift
dpb_bm equ 3 ; Block mask
dpb_em equ 4 ; Extent mask
dpb_maxb equ 5 ; Maximum allocable block - 1
dpb_dire equ 7 ; Directory entries - 1
dpb_allblk equ 9 ; Bit map allocated blocks
dpb_chksiz equ 11 ; Length of check buffer
dpb_tbfdir equ 13 ; Tracks before directory
dpb_length equ 15 ; Length of disk parameter block
;
ftype equ 1
htype equ 2
mtype equ 3
;
extrn print,pa2hc,phl4hc,cout
extrn putud,getud,logud
extrn initfcb,f$delete,f$mopen,f$write,f$close
maclib xsys
start:
call test_xbios
jp nz,xbios_error
call putud
ld de,buffer
ld c,3
ld hl,(wboot+1)
ld l,b_config
call callhl ; Get disk data
disk_loop:
call find_dsk
or a,a ; Do we have one
jp nz,wrap ; No, all done
call print
db cr,lf,'Disk ',0
ld a,c
call cout
ld a,c
sub a,'A'
call sel_disk
call print
db ' Groups: ',0
ld de,fcb
call initfcb ; Clear FCB
ld de,fcb
call f$delete ; Get rid of file
ld de,fcb
call f$mopen ; Create and open file
ld hl,fcb+16 ; Point to group location
ld (grpptr),hl ; Save away
ld hl,0
ld (curtrk),hl ; Initialize our track
group_loop: .new
ld de,(curtrk)
ld hl,64
add hl,de
ex de,hl ; Save our track
ld hl,1024+1 ; Largest track number + 1
sbc hl,de
jr c,end_group
ex de,hl ; HL = current track to check
ld (curtrk),hl
call chk_track
or a,a
jr nz,group_loop ; Not in range of this disk
call print
db ' ',0
call phl4hc
; Process group number
push hl ; Save group number
ld b,3 ; Shift length (divide by 8)
xor a,a ; Set remainder to 0
1$:
srl h
rr l
rra
djnz 1$
rla
rl b
rla
rl b
rla
rl b ; Put remainder in B
ld a,80h ; Mask
jr z,3$ ; No shift needed
2$:
srl a
djnz 2$
3$:
ld de,(alvec) ; Get base
add hl,de ; Pointer to byte
and a,(hl) ; See if we are already allocated
pop de ; Get group number
jr z,4$ ; Not allocated, continue
call print
db ' Allocated',0
jp group_loop
4$:
ld hl,(grpptr) ; Get our current fcb ptr
ld a,(max_block+1)
or a,a ; Set flags on size of entry
ld (hl),e
inc hl
jr z,5$
ld (hl),d
inc hl
5$:
ld (grpptr),hl ; Save away
jr group_loop
end_group:
ld de,fcb
call f$write
ld de,fcb
call f$close
jp disk_loop
wrap:
call getud
ld de,(reset_vector)
ld c,bdos37
call bdos ; Reset our disks, rebuild alloc vector
jp wboot
; chk_track
; Entry:
; HL = Track number
; CURDSK structure set
; Return:
; A =0FFh if no match
; A = 0
; HL = Group number if match
chk_track:
ld a,(groups_trk)
ld e,a
call mlt16x8 ; Get groups from beginning
ld de,(group_off)
or a,0FFh ; Reset Carry, set for return status
sbc hl,de
ret c ; Before this disk
ex de,hl ; Put group number in DE
ld hl,(max_block)
or a,0FFh ; Reset carry, set for return status
sbc hl,de
ex de,hl
ret c ; Good group number
xor a,a
ret
; sel_disk
; Entry:
; A = Disk number (A = 0)
; Disk will be put in reset vector, and logged in (user 31)
; CURDSK structure set
;
sel_disk: .new
ld b,a
ld hl,1
or a,a
jr z,2$ ; A drive, not shift
1$:
sla l
rl h ; Shift
djnz 1$
2$:
ld b,a ; Save disk number
ld a,(reset_vector)
or a,l
ld (reset_vector),a
ld a,(reset_vector+1)
or a,h
ld (reset_vector+1),a
ld c,31
call logud
ret
; Get next RAM disk.
; Return:
; A = 0FFh if no more
;
; A = 0
; C = Disk name ('A', 'B', etc)
; IX -> Disk Header Block
; IY -> Disk Parameter Block
find_dsk: .new
ld hl,buffer
ld b,16
1$:
ld c,(hl)
inc hl
ld a,(hl)
cp a,mtype
jr nz,4$
xor a,a
ld (hl),a ; Zero for next pass
inc hl ; Bump to DPH
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push de
pop ix ; IX -> DPH
ld h,(ix+dhb_dpbp+1)
ld l,(ix+dhb_dpbp)
push hl
pop iy ; Into IY
ld a,(iy+dpb_bs) ; Get block shift
ld b,a
ld a,5
sub a,b
; jr c,find_dsk ; Can't use this, >4k group
ld b,a
ld a,1
jr z,3$ ; 4k allocation, use the 1
2$:
sla a
djnz 2$ ; calculate groups per track
3$:
ld (groups_trk),a ; And save
ld h,(iy+dpb_tbfdir+1)
ld l,(iy+dpb_tbfdir) ; Get tracks before directory
ld e,a
call mlt16x8 ; Get group offset
ld (group_off),hl ; And save
ld h,(iy+dpb_maxb+1)
ld l,(iy+dpb_maxb)
ld (max_block),hl
ld h,(ix+dhb_allvp+1)
ld l,(ix+dhb_allvp) ; Get allocation vector pointer
ld (alvec),hl ; And save
xor a,a ; Set indicators
ret
4$:
inc hl
inc hl
inc hl
djnz 1$ ; Try next entry
or a,0FFh ; Set indicators
ret
;
; Routine to multiply HL by E (16bit X 8bit)
; Return:
; A = MSB
; HL = lower two bytes
;
mlt16x8:
ld d,h ; Save upper byte
ld h,e ; Get multiplier
mlt hl ; First product
mlt de ; And second
ld a,d ; High byte of product
ld d,e ; Move middle byte into position for add
ld e,0 ; This product has zero lower byte
add hl,de ; Add for middle and lower byte
adc a,0 ; Adjust high byte
ret
callhl:
jp (hl)
; Routine to test if XBIOS system
; Return:
; A = 0 if XBIOS
; A <> 0 if not XBIOS
;
test_xbios:
ld hl,(wboot+1)
ld l,b_time
inc hl ; Increment past jump
ld e,(hl)
inc hl
ld d,(hl)
dec de
ld hl,test_string+4
ld b,5
loop:
ld a,(de)
cp a,(hl)
ld a,0FFh
ret nz
dec hl
dec de
djnz loop
xor a,a ; Set status
ret
test_string:
db 'XBIOS'
xbios_error:
call print
db cr,lf,'RAMFIX: Can only run on XBIOS system.',0
jp wboot
reset_vector:
dw 0 ; Disk reset vector
fcb:
db 0,'!!!!!BADRAM'
ds 24
curtrk ds 2 ; Current track number
alvec ds 2 ; Pointer to allocation vector
grpptr ds 2 ; Pointer to groups (in fcb)
; CURDSK structure
group_off:
ds 2 ; Groups before directory
max_block:
ds 2 ; Last track number
groups_trk:
ds 1 ; Groups per track
; end of CURDSK structure
buffer ds llrec