EEA index
FileStore ExecutableSD card
Intro |
Version notes are given in reverse chronological order. Until the emulator is operational, all versions will be 0.00 - use the date as a reference.
FileStore versions log 0.00 2010/08/08 Added initialise routine to FDC. CHANGED LICENCE TO (open source) EUPL. Please refer to the included eupl_v1-1_en.pdf. 0.00 2010/08/07 FDC em now does the type I commands, plus poll routines for follow-through. As far as I can see, the current log is: FDC change: Test=No, MRst=No, DDen=Yes; FDC1=Yes, FDC2=No, Side=0 FDC read : 0 <- 0 [Status/Command] FDC write : 80 -> 1 [Track] FDC read : 80 <- 1 [Track] FDC write : 0 -> 3 [Data] FDC read : 0 <- 0 [Status/Command] Network IRQs disabled [READ] FDC write : 8 -> 0 [Status/Command] [point **A**] FDC: Restore FDC command type I, params = 8 VIA read : <- 13 [IFR] VIA read : <- 14 [IER] Network IRQs disabled [READ] NET read : <- 0 [CR1/SR1] CanIRQ = No FDC read : 68 <- 0 [Status/Command] Network IRQs enabled [READ] FDC read : 68 <- 0 [Status/Command] Network IRQs disabled [READ] go to point [**A**] and repeat a bunch of times. It does this numerous times on the left drive, then the right, then it fast-blinks the red LED (error - no disc?). What I don't get - we write 80 to the track register, read it back, blank the data register, then "restore" to find track zero. Um... I'm sorry, shouldn't we like, read a sector or something? The return code is 68 which is WRITE PROTECT and TRACK ZERO. Isn't that a good return code? 0.00 2010/08/06 FDC emulator now recognises commands. 0.00 2010/08/03 Started work on FDC emulation. 0.00 2010/07/24 Minor corrections to ROL/ROR for values written back to Acc. Must remember - CByte() is NOT the same as a byte-wide cast! PLA flags corrected. BRK is now, correctly, treated as a two byte instruction. Bit operations test script written. Load and save operations test script written. Comparison operations test script written. Other-stuff test script written. All test scripts written. CPU core passes tests. [now I can start work on other stuff...] 0.00 2010/07/22 SBC now ought to be correct. Erm... I hope. :-/ Maths test script complete. 0.00 2010/07/20 Corrected ADC V flag, overflowing a byte sets C, not V. Made the script parser a little more bulletproof; plus it better reports where the assert whoopsee occurred. Corrections to SBC handling of C and V. Surprised? :-) [still not entirely correct] 0.00 2010/07/19 Fixed bug in ADC re. adding in 1 for Carry. 0.00 2010/07/18 [daytime] Fixed bug in resolution of [(ABS,X)] addresses. Fixed bug in BRK handler. Fixed bug in Carry Clear / Carry Set in CMP. 0.00 2010/07/18 [early hours] Validation script system created. I've only written one script to perform basic tests on flags and registers, and check all the opcodes are present. This picked up an error with PLP's opcode number (oops!) and one of the SBCs too. More test scripts to be created. My next lot, God help me, will be to verify the correct functioning of the addressing modes. The script command format is: <reg> = X Y A SP PC PS C Z I D B V N \-- flags --/ All numbers are given in hex, without a prefix. assert <reg>|m<addr> <cond> <value> Confirm that a register, or memory location (m prefix) is or is not a specific value. The condition codes are '=' (is) or '!' (is not). Flags are 'ff' if set. assert a = 7f ; check accumulator is 127 assert m0 = 0 ; check memory at &0000 is zero cont / exec As an alternative to using the "op" command, especially with tricky things like conditional branches, you can poke code directly into memory and then execute it. Execution starts at &0200. The difference between "exec" and "cont" is that "exec" sets up the environment before stepping once, while "cont" simply steps once. Thus, to execute three instructions, you could: exec cont cont It is possible to execute code at other locations by massaging PC before calling "cont". load <file> Loads a secondary script and begins executing it. The filename should be a plain name with no quotes and no path (the path is fixed). You can only have ONE secondary script at a time. When this script is complete, execution passed back to the main script. Note - you CANNOT chain one script from another. To implement this sort of behaviour, create a "wrapper" script that loads each of the desired scripts in turn (look at how I've implemented it). memclr [<addr>] Zero the address specified. If the address is not specified, all memory except page &FC will be cleared. memset <addr> [<value>] Set the memory at the address given to the value given, or zero if no value. msg <msg> Simply displays the rest of the line (so no quotes) to the user in a messagebox. Clicking OK is required, so don't overdo it. op <op> [<param> [<param>]] Writes all the values given into memory byte by byte, starting at &0200, then steps the processor to execute the code. A maximum of three bytes can be given. As values are given as bytes, take care with the order of bytes for word values. op ea ; NOP op 4c ad de ; JMP &DEAD regset <reg> [<value>] Referring to the list above, this allows you to set the specified register or flag to either the value given or zero if no value specified. NOTE: YOU CANNOT SET PS OR PC. reset Resets the CPU to sane defaults, then pokes the memory latch to disable the EPROM. Here is an example of testing carry flag bahaviour: regset a 21 op 0a ; = 42 assert c = 0 op 0a ; = 84 assert c = 0 op 0a ; = roll over, 108 but we only see 8 assert a = 8 assert c = ff [remember, flags that are set are 'ff' and not '1'; think of it as 'ff' being '-1' (which is exactly what it is!)] If you look in the source, you may or may not see other commands and/or options. These should be used with care, read through the source to understand their effects. Note that the script interpreter is simple and fairly easy to break. It is NOT intended as a user function, more a means to script up and perform repeatable tests. There's a button in the setup dialogue to invoke the script. [this will go once things are working, to be replaced with a command line option] Closing the setup dialogue now properly quits the emulator. 0.00 2009/11/05 Fixed bug where SBC set the flags the wrong way around. Now the code crashes with an undefined instruction at address &79 or somesuch. I'm looking to writing some validation scripts. I have caught a cold. I feel like crap. This is when I would "traditionally" put a fair amount of work into this project, but I have to fit feeling like this around work. Ugh. *Totally* untested, but if the server writes an error report to the NVRAM, it should stop at that point and ask if you wish to cease execution (so you can check out what the error is). 0.00 2009/08/03 In disassembly, highlights the current instruction in an inverted style. In disassembly, pressing F8 may cause the highlight to be 'lost' if you JSR, RTS or something that goes away from what is currently shown. No worries, pressing ^D will realign the disassembly to the current instruction. Note, by current instruction we mean the one that has JUST been executed... Disassembly now has a processor status 'popup'. ^S will toggle it visible/invisible. CPU status can now be used to muck with the processor. Note that changes take effect IMMEDIATELY if you click on a flag, or when you press [Enter] if changing a register. Memory dump 'Go' text entry dodah now accepts [Enter] key. Fixed bug in BIT instruction where it was setting the result back to front. 0.00 2009/08/02 Fixed bugette with the memory dump opening 'blank'. Added F7 as a keypress to mean "Halt". This was chosen as it is next to F8 (step) and not next to F5 (run). The VB IDE uses ^Break, but this is not really available for the technical reason that it'll interrupt the IDE instead! :-) Added disassembler. It is only part colourised in that comments are green. Everything else is plain black, with the instruction in bold type. I did consider a Zap-like colourisation, but felt it would be overkill. The disassembler will annotate disassembly from a list of 'known' locations created specifically for each version of the EPROM. The most detailed is for v1.31 thanks to Johan's disassembly. This information is read from the "locs####.dat" file, where the '####' is the EPROM ID in hex. If no such file exists, then "locsxxxx.dat" will be used, which is a generic file containing hardware locations. When in disassembly, you can use Up/Down to move around (up goes back a byte). PageUp/PageDown for bigger jumping (and as before PageUp goes back 32 bytes). You can also use F5, F7, and F8 as in the main window. All run/halt/singlestep calls indirect through a routine in frmMain - this saves lots of stupid code dupe. It is a routine in frmMain and not CPU65C102 because it is mostly UI stuff and twiddling one global variable... Added Halt/Run[^Step] to the CPU status window. Also made the mem dump and disassemble buttons work. 0.00 2009/07/30 The beginnings of a VIA. Added Run/Halt/Singe-step, plus a reset option. Added some hotkeys. The F5/F8 match those used in VB. Added a picture of me hard at work. :-) CPU reset now resets the hardware. Removed spurious unnecessary CPU reset prior to start of emulation. EPROM patches are now applied from the "rompatch.dat" file. The format of this is: FE41@ECA9>7:0452,EA,EA,EA,EA,EA,EA,EA which is [romid]@[addr]>[len][check][data] All values are given in hex. The ROM ID can be determined from the Development menu. The length is how many bytes to alter. The original (in-EPROM) contents of these bytes are summed to create the check value. If this value does not agree, the check won't be applied. Finally, the replacement byte values comma separated. The results are 'undefined' if the data supplied differs from the number given previously. The entire rompatch.dat file is read, so it is possible to hold multiple patches to the same EPROM image. Hacked in a compilation option "DEMON". When set to '1', it will remove the instruction/branch recording, the disassembly, and logging hardware accesses. In the start-up test, it only shaved off around half a second... on the other hand, no clutter from an oversized hardware trace. Obviously this option is incompatible with others, like the insane internal trace one. 0.00 2009/07/01 After getting the crappy memory dump looking as I wanted it, I ripped out half the code and rewrote it to be a lot more optimal (namely via a page buffer raw-reading from the RAM array instead of 512 memory accesses which aren't really necessary...). Moving the mouse over the hex data or the ASCII data will show the byte with a cyan box around it. Double-clicking a byte that is highlighted will allow you to change that byte. Added a 'catch' to the CPU status. If you are playing with memory and you replace code with an incorrect instruction (such as &028A (I think!?) to a NOP), there is a chance you will see endless "unknown instruction" messages and never get a chance to exit. So hold down SHIFT and CTRL when clicking "OK" and you'll be asked if you wish to abort emulation. 0.00 2009/06/30 Implemented crappy rough'n'ready memory dump display. Emulator will no longer about upon unknown instruction and/or addressing mode - instead it will report the problem and then open the CPU status window. The eventual aim is to be able to 'update' the CPU status, perhaps to fake the unknown opcode, but this bit hasn't been implemented yet. 0.00 2009/06/20 The special check for if running on Aiko (to redirect to the local server as I don't have Internet at home) has been extended to cater for Azumi as well in preparedness for the code/support being copied onto my eeePC901. Don't rely on this though, as I may rename the computer, I may decide to hold the live server on Aiko via ethernet... or I may just shoot myself in the foot with a water pistol. :-0 Better shutdown routine. FS error report now displays the SIN. I *think* I have the bytes in the right order. :-) If the cycle count passes &6FFFFFFF, it will revert back to zero. This is to prevent "Overflow" errors; this value being 15 minutes and 40 seconds of emulated time. You might ask why not &7FFFFFFF, the actual point of overflow. Well, this is to give space for things that schedule in advance (like the RTC saying "I'll bother you again in a sec" with "a sec" being 2,000,000 cycles...). We can support advance scheduling up to two minutes, this ought to be more than enough for the various possible timeouts. BBRx/BBSx/RMBx/SMBx will not be supported. These are Rockwell specific instructions and may well not be present in the E01(S) firmware. If they are, they'll be added, but... Fixed TRB/TSB not to screw up the Accumulator. [Tom Walker] Expanded the 'catch' range in the register contents display to remove the black-box "undefined character" symbols. The EPROM joiner should now be considerably more resiliant. 0.00 2009/05/31 Now updates CPU status window (every 32 instructions). This'll be more useful when single-stepping is implemented. In that case, updating an option in the status window will change the processor's internals (like setting X, Y, A and flags...). Implemented the basics of a disassembler, you can see this in the trace of the CPU status. Implemented TSB and TRB. I don't have information on how these actually work, other than in the processor datasheet (which doesn't say much!). So I have guessed. If you know, please give the TRB/TSB code a thumbs up (or down?)! Messages appear for the currently unsupported instructions (BBS anyone?)... Added an EPROM version report. This is so you can check which EPROM image is running, and also so you can see the ROMCHK without running the code in the IDE. This is because... well, look at the "locs31f0.dat" file. You can create another called "locsXXXX.dat" where the X's are the ID. It'll have a tad more significance in the disassembler, when I have written it. :-) 0.00 2009/04/30 Added ADLC status form. Not linked yet, but it's a start. Only had a few minutes (well, about half an hour) before "Evil Aliens" on Zone Horror. :-) In between films, added the FS error report lookup. This makes it easier than eyeballing the NVRAM file in a hex editor. 0.00 2009/04/26 Basic does-nothing-much implentation of the ADLC, so the server will believe an ADLC and valid Econet is connected... ...well, that's the idea! Doesn't quite get that far, I think we need the VIA next? 0.00 2009/04/22 Rejigged the emulator to operate with a single 64KiB EPROM image file. To make life easier if you have split files (as most BBC-based EPROM programmers could only read in 16KiB or 32KiB chunks), you can 'join' either 4×16KiB parts, or 2×32KiB parts. There's a new button (and associated window) for this. Those "..." buttons now open the "Open" dialog(ue) so we don't have to try to remember paths. Note that *ANY* instance of a reference into the FileStore's own folder will be replaced with "<AppPath>". This is going to be used throughout as it makes things much tidier in the writeable icons. 0.00 2009/04/20 Implemented 'dummy' routines for the ADLC, FDC, HDC, and VIA. Calls to the hardware will result in output to "hwlog.txt" so we can see which parts of the devices are being used... For what it is worth, this is the first version of the emulator capable of running the firmware until it reaches a state of sitting doing very little except blinking the Mode LED (i.e. a sort of 'panic'). The previous version probably was able, but I didn't let the code run long enough! [note: this does NOT occur with the v1.40 firmware as this behaves rather differently] 0.00 2009/04/19 Implemented the Miscellaneous Functions Latch. That was dead easy. The array is public scope so it can easily be seen by the FDC and NVRAM code. It handles the red LED by itself. Implemented a lot of the NVRAM; and the RTC is totally faked by reading the values from the host. Note that the first ten bytes are therefore not used in our implementation (and, furthermore, attempting to write a new time/date will silently fail...) so in the "nvram.dat" file, you should NOT attempt to make any assumptions whatsoever about these bytes. The ~10 second delay might make sense on a real FileStore, to allow discs to spin up (etc). In an emulation, it is just wasting our time; therefore the emulator will patch this delay loop out of the loaded EPROM image (the original file is NOT altered). We have built-in support for: E01 firmware "FileStore 1.31" (C)Acorn 1988 E01S firmware "FileStore 1.33" (C)Acorn 1988 E01S firmware "FileStore 1.40.00" (C)1989 Acorn For other versions, I'll need a complete EPROM dump. If your version is not recognised, then no patch will be applied and you won't be warned about it either... Fixed bug in PC adjustment of absolute indirect addressing. Added JMP/JSR to list of opcodes for which NOT to perform a 'hidden' memory read (not for safety as you won't be jumping to a read-sensitive location, but rather for efficiency as the read isn't needed). 0.00 2009/04/16 No read functional changes, just implemented messages for menu options, and the front flap open/close (purely an effect atm) for the initial public release. To be honest it is WAAAAAY too early to release, but I'm hoping to get somebody else on-board so at least somebody can laugh at my mistakes... before fixing them! :-) I think this one might still say it is the 2009/04/15 build? No matter... 0.00 2009/04/15 Patched in some normally-inactive code to load up Johan's E01 EPROM dumps (16KiB bits) and create the expected 32KiB dumps from them. You might ask why I want to run the E01 firmware on an E01S emulator. Good question - it's because Johan's partial disassembly is for his firmware, not the E01S code. It will help greatly to have the two match up when developing this emulation. NOTE: In the future, it is HIGHLY likely that FileStore will operate with a single 64KiB EPROM image, and there will be some sort of utility provided to 'join' smaller images into a full-sized dump. You might also notice that we are using the Wiki-recommended "Kikibyte" terminology. This is apparently because some dickhead decided that KILObyte should be used to refer to 1000 byte units (which is logically correct) DESPITE the fact that programmers have been using that phrase to refer to 1024 byte units since the dawn of Unixtime (or 1970). It all started when harddisc manufacturers AGES ago switched to using decimal maths for their products in order to make them seem larger. A test case in the US failed on account of it being the "industry standard" way of describing storage capacity, which is bollocks for numerous reasons, namely: 1. A 1Mb capacity floppy disc can hold 1Mb of data (which is usually anything between 640Kb and 800Kb depending on how much is lost to formatting and soft-sectoring). 2. Onto a 700Mb CD-R, I can actually fit 703Mb. If it was decimal Mb, you'd only be able to fit on ~668Mb. 3. Funny, using the various lookup schemes implemented on harddiscs for addressing, they are all quite well aware of non-decimal units. The default (PC-like) scheme is for a sector of 512 units of 8 bit bytes. Why does a harddisc not provide 500 units of 10 bit bytes if they are so hung up on being decimal? It's all sales and marketing cons, which is why my 250Gb harddisc actually holds around 235Gb, and a pack of DVD-Rs claiming 4.7Gb actually holds exactly 4488Mb (but in my own copy-over I aim for around 4.35 as anything more seems likely to spill over, housekeeping/filesystem must be somewhat inefficient). Anyway, a "KiB" is a "kibibyte" which is units of 1024 bytes; what us old-timers have been calling "Ks" and "kilobytes" for decades... 0.00 2009/04/14 Implemented EPROM/RAM selection so it can switch to execution from RAM after initial copy. Fixed BRx instructions, the method of creating a signed value was totally bogus so I simply recoded it all. Added in TRACE and TRACEMORE macros to permit the CPUcore to be traced in operation. It will, later, be converted into something to allow... well, just look in the CPU window! Fixed bug in SBC, when CARRY you don't subtract one but when no Carry you do? Surely this means you must SEC before every SBC? Why doesn't the 65C02 have a plain 'SUB' that does a plain normal subtract? Fixed stupid bug in INC/DEC where you can use accumulator addressing. This is new to the CMOS and I missed it. Sorry. Added code (or a kludge, if you prefer!) to the PreFetch. You see, the CPUcore works out the addressing mode and sets up two 'secret' registers with the effective address and/or the data to be acted upon. This is, I believe, a mite slower but a lot more code-optimal than having each opcode do its own work; it also means that we can group opcodes together (i.e. ALL of the LDAs do pretty much the same thing in the same way...). HOWEVER, if we are WRITING to &FC08 to poke on the red LED, we sure as hell don't want to do a 'hidden' READ on that address as doing so will flip the EPROM/RAM latch to RAM-only and then it all goes tits waving in the air and you're scratching your head trying to work out why it's all total gibberish. Added a manky kludge to turn on the red LED. We don't need the rest of our Misc. Func. Latch yet, and having the red LED light up means we've successfully executed THREE instructions. :-) Lots of GUI stuff added, inc. the cute main window. 0.00 2009/04/13 CPU core believed to be mostly correct except for undefined ops, some CMOS-specific ops, and BCD. I'll need to look up what/how BBRx/BBSx/TSBx (etc) actually operate. Emulator now capable of loading an EPROM image to begin to execute. 0.00 2009/04/11 Project coding started after a bunch of R&D. :-)
|