So both Widgets and ProFile hard drives use z8 microcontrollers, disassembled + commented sources for the firmware are available on bitsavers, and I've been spending the last week looking at these and mapping out their states vs my profile.c code vs the Aphid code in an attempt to see if I can overhaul profile.c in the future.
The source code for these seems to be Z80 like, but was wondering if anyone knows for sure whether or not they're compatible with a Z80 (outside of the memory banking and I/O + timers.) Perhaps I might leverage a bit of a GPL'ed Z80 emulator for some of that.
Currently profile.c is good enough for LOS 3.x, 2.x, MacWorks XL and partially UniPlus, but not Xenix and LOS 1.x. It is however getting a bit furry and ugly and needs a major cleanup.
But there's another path I might take.
I'm playing with the idea of eventually creating an external binary that attaches + communicates with LisaEm using two bytes (one for the PA and another for the PB VIA 6522 lines). This would be a 2.0 feature, and would allow a core emulation process that spawns external processes for other attachments, such as drives, printers, ethernet, etc. (I'd do a similar thing for the serial ports as well.)
Some devices will continue be built in to the core, but others can be external processes - built in things might be the serial-pty/telnetd code. External processes would be devices such as printers, and even the GUI itself. (This is more of an architectural design thing for the future to make the code cleaner and easier to deal with - this will not be part of 1.2.7.)
I was also considering that since Tom's Aphid is python code (mostly) perhaps a version of that code could be such as external program.
The idea is to only emulate the communications portions of Z8 firmware Widget code for a higher level of accuracy and the actual block reads/writes would be handled in usual way via fopen/fread/fwrite, etc. via libdc42.
There's some challenges here as profile.c in LisaEm uses a state machine, but neither Widget nor ProFile firmware use that, rather they just sit in various loops waiting for the next thing to happen. A minor issue is that since these are time sensitive for some OS's such as Xenix, if LisaEm runs at a higher speed than 5MHz, I'd need some way to tell the external program what relative speed to run at to prevent issues, so I'd need to communicate timing as well to these processes, through usual IPC methods.
I think in the end though, pen and paper and mapping of the disassembly of widget firmware might be better to build a state machine, but this would introduce errors and other bugs due to edge cases, where as a Z80 emulator would run a more faithful simulation.
Ideally a Z80 to C translator would be best, but no such beast exists except for a commercial one.
Sorry, thinking outloud for the most part.
Firmware for Profile 10 looks something like this:
201/ 197 : ;********************************************************************
202/ 197 : ; and here we go...
203/ 197 : ;******************************************************************** ;; here here here - this is the handshake/command read
204/ 197 : ;
205/ 197 : E6 35 FF WarmStart ld PwrFlg0,#0FFh ; set warm start flags
206/ 19A : E6 36 01 ld PwrFlg1,#001h
207/ 19D : 56 02 F7 WarmStart1a and P2,#0FFh-BSY ; set BSY
208/ 1A0 : B0 43 clr ReadWithHdr ; state machine checks headers
209/ 1A2 : B0 08 clr SkipSpared
210/ 1A4 : E6 FF 80 WarmStart1 ld SPL,#Stack_Top ; dump stack
211/ 1A7 : B0 40 WarmStart2 clr BlockIsBad
212/ 1A9 : EC 01 ld R14,#1 ; 01 means waiting for command
213/ 1AB : D6 03 AD call DoHandshake ; wait for host to assert /CMD
214/ 1AE : ;
215/ 1AE : ; *** we end up here after successful 01 - 55 handshake ***
216/ 1AE : 76 0B 20 tm Status2,#020h ; ***
217/ 1B1 : 6B 08 jr z,WarmStart3 ; ***
218/ 1B3 : B0 07 WarmStart2a clr SpareTblDirty ; ***
219/ 1B5 : 46 0A 20 or Status1,#Stat_SpTblUpd ; host data lost
220/ 1B8 : D6 0B D2 call GetSpareTable
221/ 1BB : 90 07 WarmStart3 rl SpareTblDirty ; does our spare table need to be updated?
222/ 1BD : 6B 58 jr z,GetHostCmd ; no --> skip
223/ 1BF : ; update spare table
224/ 1BF : 46 0A 20 or Status1,#Stat_SpTblUpd ; host data lost
225/ 1C2 : 46 02 80 or P2,#DRW_Read
226/ 1C5 : 46 02 30 or P2,#Msel0+Msel1 ; Z8 --> Mem
227/ 1C8 : E6 F8 16 ld P01M,#016h ; reconnect bus
228/ 1CB : D6 0C 58 call ReadSpareTrk
229/ 1CE : E6 07 FF ld SpareTblDirty,#0FFh ; now table *really* needs to be updated...
230/ 1D1 : ED 02 17 jp nz,GetHostCmd ; ***