/*
DiskLikeDirectoryInfo.java
(c) 2010-2013 Edward Swartz
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*/
package v9t9.common.files;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import v9t9.common.memory.ByteMemoryAccess;
public class DiskLikeDirectoryInfo extends DirectoryInfo {
static class DiskFileRange {
int fdrSector;
int start;
int len;
NativeFile file;
}
Map<File, DiskFileRange> sectorRanges = new LinkedHashMap<File, DiskFileRange>();
private String devname;
public int lastSector;
public DiskLikeDirectoryInfo(File dir, IFilesInDirectoryMapper mapper, String devname) {
super(dir, mapper);
this.devname = devname;
int sec = 2;
for (File entry : entries) {
if (sec >= 65536)
break;
DiskFileRange range = new DiskFileRange();
try {
range.file = NativeFileFactory.INSTANCE.createNativeFile(entry);
range.fdrSector = sec++;
range.start = sec;
range.len = range.file.getSectorsUsed();
sec += range.len;
sectorRanges.put(entry, range);
} catch (IOException e) {
}
}
this.lastSector = sec;
}
/**
* @return the lastSector
*/
public int getLastSector() {
return lastSector;
}
public void synthesizeFDRSector(ByteMemoryAccess access, DiskFileRange range) throws DsrException {
int offset = access.offset;
Arrays.fill(access.memory, offset, offset + 256, (byte) 0);
if (range == null) {
return;
}
String name = mapper.getDsrFileName(range.file.getFile().getName());
for (int i = 0; i < 10; i++) {
if (i < name.length())
access.memory[offset++] = (byte) name.charAt(i);
else
access.memory[offset++] = (byte) 0x20;
}
// reserved
access.memory[offset++] = (byte) 0x0;
access.memory[offset++] = (byte) 0x0;
// file type
access.memory[offset++] = (byte) range.file.getFlags();
access.memory[offset++] = (byte) range.file.getRecordsPerSector();
int numsecs = (int) range.file.getSectorsUsed();
access.memory[offset++] = (byte) (numsecs / 256);
access.memory[offset++] = (byte) (numsecs % 256);
access.memory[offset++] = (byte) range.file.getByteOffset();
access.memory[offset++] = (byte) range.file.getRecordLength();
int numrecs = range.file.getNumberRecords();
access.memory[offset++] = (byte) (numrecs % 256);
access.memory[offset++] = (byte) (numrecs / 256);
while (offset< 0x1C) {
access.memory[offset++] = (byte) 0;
}
// sectors per track
access.memory[offset++] = (byte) 18;
int left = range.len;
int ofs = range.start;
while (left > 0) {
// >UM >SN >OF == >NUM >OFS
int num = Math.min(0xfff, left);
access.memory[offset++] = (byte) (num & 0xff);
access.memory[offset++] = (byte) (((num >> 8) & 0x0f) | ((ofs & 0xf) << 4));
access.memory[offset++] = (byte) ((ofs >> 4) & 0xff);
left -= num;
}
}
public void synthesizeVolumeSector(ByteMemoryAccess access) throws DsrException {
int offset = access.offset;
File localFile = mapper.getLocalFile(devname, null);
if (localFile == null)
throw new DsrException(PabConstants.es_hardware, "No directory for " + devname);
String diskname = mapper.getDsrFileName(localFile.getName());
for (int i = 0; i < 10; i++) {
if (i < diskname.length())
access.memory[offset++] = (byte) diskname.charAt(i);
else
access.memory[offset++] = (byte) 0x20;
}
// # sectors
long numsecs = Math.min(65535, (localFile.getTotalSpace() / 256));
access.memory[offset++] = (byte) (numsecs / 256);
access.memory[offset++] = (byte) (numsecs % 256);
// sectors per track
access.memory[offset++] = (byte) 18;
// DSR mark
access.memory[offset++] = 'D';
access.memory[offset++] = 'S';
access.memory[offset++] = 'K';
// protection
access.memory[offset++] = ' ';
// # tracks/side
access.memory[offset++] = 40;
// # sides
access.memory[offset++] = 2;
// density
access.memory[offset++] = 2;
// reserved
while (offset < access.offset + 0x38) {
access.memory[offset++] = 0;
}
// bitmap
while (offset < access.offset + 0xec) {
access.memory[offset++] = (byte) 0xaa;
}
// reserved
while (offset < access.offset + 0x100) {
access.memory[offset++] = (byte) 0xff;
}
}
public void synthesizeIndexSector(ByteMemoryAccess access) {
int offset = access.offset;
int endOffset = offset + 256;
int cnt = 127;
for (Map.Entry<File, DiskFileRange> entry : sectorRanges.entrySet()) {
int fdrSector = entry.getValue().fdrSector;
access.memory[offset++] = (byte) (fdrSector / 256);
access.memory[offset++] = (byte) (fdrSector % 256);
if (--cnt == 0)
break;
}
while (offset < endOffset) {
access.memory[offset++] = (byte) 0;
access.memory[offset++] = (byte) 0;
}
}
public void synthesizeSector(ByteMemoryAccess access, int secnum) throws IOException {
for (Map.Entry<File, DiskFileRange> entry : sectorRanges.entrySet()) {
DiskFileRange range = entry.getValue();
if (secnum == range.fdrSector) {
synthesizeFDRSector(access, range);
return;
} else if (secnum >= range.start && secnum < range.start + range.len) {
range.file.readContents(access.memory, access.offset,
(secnum - range.start) * 256, 256);
return;
}
}
Arrays.fill(access.memory, access.offset, access.offset + 256, (byte) 0xe5);
}
}