home *** CD-ROM | disk | FTP | other *** search
- .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
-
-
-