/** * Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.codesourcery.jasm16.emulator.devices.impl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Random; import junit.framework.TestCase; import de.codesourcery.jasm16.utils.Misc; public class FileBasedFloppyDiskTest extends TestCase { private static final int BYTES_PER_SECTOR = FloppyDisk.WORDS_PER_SECTOR*2; private File tmpFile; private FileBasedFloppyDisk disk; private byte[] buffer = new byte[BYTES_PER_SECTOR]; @Override protected void setUp() throws Exception { tmpFile = File.createTempFile("test", "test"); if ( ! tmpFile.exists() ) { tmpFile.createNewFile(); } disk = new FileBasedFloppyDisk( tmpFile ); clearBuffer(); } protected void tearDown() throws Exception { if ( tmpFile != null ) { try { tmpFile.delete(); } finally { tmpFile = null; } } } private void clearBuffer() { buffer = new byte[BYTES_PER_SECTOR]; } private void assertBufferEmpty() { for ( int i = 0 ; i < buffer.length ; i++ ) { if ( buffer[i] != 0 ) { dumpBuffer(buffer,i); fail("Buffer not empty at index "+i+",value: "+buffer[i]); } } } private byte[] createRandomDisk(int sizeInBytes) throws IOException { final byte[] result = new byte[ sizeInBytes ]; final Random rnd = new Random(System.currentTimeMillis()); rnd.nextBytes( result ); final float sectorCount = sizeInBytes / (float) disk.getSectorSize().getSizeInBytes(); System.out.println("*** created random disk with "+sizeInBytes+" bytes ("+(sizeInBytes>>1)+" words , "+sectorCount+" sectors)"); final FileOutputStream out = new FileOutputStream( tmpFile ); out.write(result); out.close(); return result; } private static void dumpBuffer(byte[] buffer , long byteOffset) { final int bufferLength = buffer.length; final int wordsPerLine = 16; int wordAddress = (int) (byteOffset >> 1); final int bytesToDump = bufferLength - wordAddress*2; final int sector = (int) byteOffset / (FloppyDisk.WORDS_PER_SECTOR*2); System.out.println("---- Dump starting at "+Misc.toHexString( wordAddress )+" , sector "+sector+" ----"); System.out.println( Misc.toHexDumpWithAddresses( wordAddress*2 , buffer, bytesToDump , wordsPerLine , false ) ); } public void testReadStartOfEmptyFile() throws IOException { disk.read(buffer , 0 ); assertBufferEmpty(); } public void testReadEndOfEmptyFile() throws IOException { disk.read(buffer , (disk.getSectorCount()-1) * BYTES_PER_SECTOR ); assertBufferEmpty(); } public void testRead() throws IOException { final byte[] expected = createRandomDisk( disk.getSectorCount() * disk.getSectorSize().getSizeInBytes() ); final int byteOffset = (disk.getSectorCount()-1) * BYTES_PER_SECTOR; disk.read( buffer , byteOffset ); assertArraysEqual( expected , byteOffset , buffer , 0 , buffer.length ); } public void testPartialRead1() throws IOException { createRandomDisk( ( (disk.getSectorCount()-1) * disk.getSectorSize().getSizeInBytes() ) ); final int byteOffset = (disk.getSectorCount()-1) * BYTES_PER_SECTOR; disk.read( buffer , byteOffset ); assertBufferEmpty(); } public void testPartialRead2() throws IOException { final int bytesPerSector = disk.getSectorSize().getSizeInBytes(); final int halfSectorSize = bytesPerSector >> 1; final int lastSector = disk.getSectorCount()-1; final byte[] diskContents = createRandomDisk( ( disk.getSectorCount() * bytesPerSector ) - halfSectorSize ); final int offsetOfLastSector = lastSector * BYTES_PER_SECTOR; disk.read( buffer , offsetOfLastSector ); assertArraysEqual( diskContents , offsetOfLastSector , buffer , 0 , halfSectorSize ); } private void assertArraysEqual(byte[] expected,int expectedOffset, byte[] actual, int actualOffset , int length) { for ( int i = 0 ; i < length ; i++ ) { final byte val1 = expected[expectedOffset+i]; final byte val2 = actual[actualOffset+i]; if ( val1 != val2 ) { System.out.println("*** expected ***"); dumpBuffer(expected,expectedOffset+i); System.out.println("*** actual ***"); dumpBuffer(actual,actualOffset+i); final int adr1 = expectedOffset + i; final int adr2 = actualOffset + i; fail("Value mismatch at actual offset #"+i+" "+Misc.toHexString( adr2 )+ " / expected offset "+Misc.toHexString( adr1 )+ " , got: "+Misc.toHexString(val2) +" but expected "+Misc.toHexString(val1)); } } } }