Index: code/C/HxCHost/Makefile
===================================================================
--- code/C/HxCHost/Makefile	(revision 53c4be3b65af5a789c2b9443a9563c7f5f7e074f)
+++ code/C/HxCHost/Makefile	(revision 1b74fa22cd361b2a2ecfb37637d48622faaf1dcb)
@@ -27,13 +27,17 @@
 # Linking
 TEST.BIN: $(OBJECTS)
-	$(CC) -Os $(OBJECTS) -o TEST.BIN -Wl,--map -Wl,-Ttext,0x7100 -nostdlib -lgcc
+	$(CC) -Os $(OBJECTS) -o TEST.BIN -Wl,--map -Wl,-Ttext,0x6100 -nostdlib -lgcc
 
 #Compiling
-obj/$(TARGET)/%.o: %.c
+obj/$(TARGET)/%.o: %.c obj/$(TARGET)
 	$(CC) $(CFLAGS) -c $< -o $@
 
-obj/$(TARGET)/%.o: pff/%.c
+obj/$(TARGET)/%.o: pff/%.c obj/$(TARGET)
 	$(CC) $(CFLAGS) -c $< -o $@
 
-obj/$(TARGET)/%.o: %.s
+obj/$(TARGET)/%.o: %.s obj/$(TARGET)
 	$(AS) $< -o $@
+
+# init
+obj/$(TARGET):
+	mkdir -p obj/$(TARGET)
Index: code/C/HxCHost/main.c
===================================================================
--- code/C/HxCHost/main.c	(revision 53c4be3b65af5a789c2b9443a9563c7f5f7e074f)
+++ code/C/HxCHost/main.c	(revision 1b74fa22cd361b2a2ecfb37637d48622faaf1dcb)
@@ -18,4 +18,6 @@
 unsigned char mark[512 + 16] = "HxCFEDA";
 unsigned char* secbuf = mark+16;
+
+const char* HXCSDFECFG = "HXCTEST.CFG";
 
 void printhex(unsigned char n)
@@ -89,5 +91,112 @@
 }
 
-int main(void)
+struct opt
+{
+	char* name;
+	BYTE off;
+	BYTE type;
+};
+
+static const struct opt options[7] =
+{
+	{"\x1B\x50\x0CHxC floppy emulator setup\r\n"
+	"UP/DOWN move - +/- change\r\n"
+	"space save - left quit\r\n"
+		 "Step sound       ", 16, 0}, 
+	{"\r\nGUI sound        ", 17, 0}, 
+	{"\r\nBacklight delay  ", 18, 1}, 
+	{"\r\nStandby delay    ", 19, 1}, 
+	{"\r\nDrive selector   ", 20, 0}, 
+	{"\r\nLoad last floppy ", 26, 0}, 
+	{"\r\nLCD scroll speed ", 28, 1}, 
+};
+
+inline static void config()
+{
+	// If it's HXCSDFE.CFG, enter config mode
+	// Read the config part of the file
+	WORD byteCount = 29;
+	FRESULT r = pf_read(secbuf, byteCount, &byteCount);
+	if (r != 0 || byteCount != 29) 
+	{
+		my_puts("read error");
+		abort();
+	}
+
+	BYTE selected;
+	for(;;) {
+		for (int j = 0; j < 7; j++)
+		{
+			my_puts(options[j].name);
+			mon_putc(0x1B); // Select back color
+			mon_putc(selected == j ? 0x54: 0x50) // Blue
+			if(options[j].type)
+				printhex(*(secbuf+options[j].off));
+			else
+				my_puts(*(secbuf+options[j].off) ? "ON":"OFF");
+			mon_putc(0x1B); // Select back color
+			mon_putc(0x50); // Select back color
+		}
+
+		do {
+			asm("SWI \t    \t;\n"
+				".fcb \t0x0A\t;GETC\n");
+		} while(KEY == 0);
+
+		switch(KEY)
+		{
+			case 0x08: // UP
+				// select next file
+				if (selected != 0) --selected;
+				// TODO next page ?
+				break;
+
+			case 0x19: // SPACE
+				// save configuration
+				r = pf_open(HXCSDFECFG);
+				if (r) {
+					my_puts("can't open cfg");
+					printhex(r);
+				}
+				byteCount = 29;
+				r = pf_write(secbuf, byteCount, &byteCount);
+				if (r || byteCount != 29) {
+					my_puts("can't write cfg");
+					printhex(r);
+				}
+				r = pf_write(0, 0, &byteCount); // flush sector
+				if (r) {
+					my_puts("can't close cfg");
+					printhex(r);
+				}
+				// fall through
+			case 0x10: // LEFT
+				// Quit (without saving)
+				return;
+				break;
+
+			case 0x18: // DOWN
+				// select previous file
+				if (++selected > 7) selected = 7;
+				// TODO previous page ?
+				break;
+			case 0x13: // -
+				// decrease current option value
+				if(options[selected].type)
+					--*(secbuf+options[selected].off);
+				else
+					*(secbuf+options[selected].off) = 0;
+				break;
+			case 0x0B: // +
+				if(options[selected].type)
+					++*(secbuf+options[selected].off);
+				else
+					*(secbuf+options[selected].off) = 0xFF;
+				break;
+		}
+	}
+}
+
+int __attribute__((noreturn)) main(void)
 {
 	// Detect HxC and print version code
@@ -106,13 +215,18 @@
 	}
 
-	mon_putc('z');
+	// Enter "fixed timings" mode - make sure track 255 sends index pulses
+	// every 200ms. Makes everything a bit slower, but the CD90-640 ROM
+	// requires it.
+	int j = 8;
+	mark[j++] = 3;
+	mark[j++] = 0xFF;
+	for(; j <512; j++) mark[j] = 0;
+	write(255,0,mark);
 
 	// Open root directory
 	pf_opendir(&d, "");
-	mon_putc('y');
 
 	// List files
 	ls(DIRECTORY_BUFFER);
-	mon_putc('x');
 
 	int selected = 0;
@@ -183,7 +297,24 @@
 					ls(DIRECTORY_BUFFER);
 				} else {
-					// TODO file open
-					// If it's HXCSDFE.CFG, enter config mode
-					// If it's a file, load it in HxCSDFE.CFG, then reboot
+					const char* cmp = HXCSDFECFG;
+					FRESULT res = pf_open(cmp);
+					if (res) {
+						my_puts("Can't open CFG file: ");
+						printhex(res);
+						exit(0);
+					}
+					if (*(long*)(fp->fname) == *(long*)(cmp)
+						&& *(long*)(fp->fname + 4) == *(long*)(cmp+4)
+						&& *(long*)(fp->fname + 8) == *(long*)(cmp+8)
+					)
+					{
+						config();
+					} else {
+						my_puts("LOADING FILE");
+						// If it's an HFE file, load it in HxCSDFE.CFG, then reboot
+						
+						// reboot
+						exit(0);
+					}
 				}
 				break;
@@ -194,11 +325,3 @@
 		}
 	}
-
-	// Leave LBA mode
-	/*
-
-*/
-
-	// Reboot
-	exit(0);
-}
+}
Index: code/C/HxCHost/pff/diskio.c
===================================================================
--- code/C/HxCHost/pff/diskio.c	(revision 53c4be3b65af5a789c2b9443a9563c7f5f7e074f)
+++ code/C/HxCHost/pff/diskio.c	(revision 1b74fa22cd361b2a2ecfb37637d48622faaf1dcb)
@@ -12,4 +12,6 @@
 extern unsigned char* secbuf;
 extern unsigned char mark[];
+
+static DWORD prevsec = -1;
 /*******/
 
@@ -35,4 +37,23 @@
 
 
+void map_sector(DWORD sector, BYTE write)
+{
+	// Set LBA address
+	int j = 8;
+	mark[j++] = 1;
+	mark[j++] = sector;
+	mark[j++] = (sector>>8);
+	mark[j++] = (sector>>16);
+	mark[j++] = (sector>>24);
+	mark[j++] = write;
+	mark[j++] = 1; // Sector count
+		// BEWARE of changing this to something else than 1 !
+		// In write burst mode it could erase all the sectors you don't rewrite
+
+	// TODO extract a send_hxc_command function from this
+	for(; j <512; j++) mark[j] = 0;
+	write(255,0,mark);
+}
+
 
 /*-----------------------------------------------------------------------*/
@@ -47,29 +68,10 @@
 )
 {
-	static DWORD prevsec = -1;
 	// TODO implement caching system
 	//  * If sector is reachable with current LBA, don't change it
 
-	printhex(sector>>24);
-	printhex(sector>>16);
-	printhex(sector>>8);
-	printhex(sector);
-	mon_putc(' ');
-
 	if (prevsec != sector)
 	{
-
-		// Set LBA address
-		int j = 8;
-		mark[j++] = 1;
-		mark[j++] = sector;
-		mark[j++] = (sector>>8);
-		mark[j++] = (sector>>16);
-		mark[j++] = (sector>>24);
-		mark[j++] = 0; // Write disabled
-		mark[j++] = 6; // Sector count
-		for(; j <512; j++) mark[j] = 0;
-		write(255,0,mark);
-
+		map_sector(sector, 0);
 		prevsec = sector;
 		// Read sector
@@ -98,26 +100,43 @@
 )
 {
-	// TODO write it
-	// Beware of using the sector buffer, read is doing caching there...
-	DRESULT res = RES_ERROR;
-
+	static WORD ptr;
+	static char* wrbuf[256];
+		// Separate buffer because we need to use map_sector, and it kills secbuf
 
 	if (!buff) {
 		if (sc) {
+			mon_putc('A');
+			// Initiate write process
+			prevsec = sc;
+			ptr = 0;
+		} else {
+			mon_putc('C');
+			mon_putc(' ');
+			printhex(ptr);
+			// Called with both param = 0 - flush buffer to disk
+			// First make sure it's zero-filled
+			for(;ptr < 512; ++ptr)
+			{
+				*(wrbuf + ptr) = 0;
+			}
 
-			// Initiate write process
+			// map in the sector (no need to read from SD)
+			map_sector(prevsec, 0xA5);
 
-		} else {
+			for(int j = 0; j < 40; j++)
+				printhex(*(char*)(wrbuf + j));
 
-			// Finalize write process
-
+			write(255,1,wrbuf);
 		}
 	} else {
-
-		// Send data to the disk
-
+		mon_putc('B');
+		// Here SC is a bytecount. copy that much bytes to the buffer
+		for(int j = 0; j <sc;++j)
+		{
+	    	*(char*)(wrbuf+ptr) = *(char*)(ptr++ + buff);
+		}
 	}
 
-	return res;
+	return RES_OK;
 }
 
