• TI-86 OBDing Revisited

    Eric Hertz03/11/2023 at 21:25 0 comments

    I started peeking back into my TI-86 OBD-reader yesterday... Van's acting-up again, a little. I was surprisingly far with it, already able to send-then-receive via the bitbanged UART, but it's a weird path I went down...

    Thing is, my van has two of the many possible OBD2 protocols... One allegedly invented by the manufacturer, the other allegedly never even used in vehicles by this manufacturer(?!). The former has data going constantly. But it's far too fast to be processed in realtime with my bitbanging. In fact, it's so fast the ons and offs are only registerable if I use the tightest loop possible, using the dedicated "sample input, store in memory, repeat" instruction. So, even though there's a complementary "write-output from memory, repeat" instruction, bitbanging output is basically not an option, because the protocol also requires monitoring the bus for collisions *while* transmitting.

    Weirdly, as far as I can tell, the system components are nearly exclusively wired directly, not via a serial bus of any sort. So, I don't understand why there's so much chatter on that serial bus. There's one weird exception, which frankly makes little sense. It seems the analog output of the oil-pressure sensor feeds directly into the dashboard circuitry, wherein there's a microcontroller used to drive the stepper-motor for the oil-pressure needle. LOL. Why not just use a standard analog gauge? I *think* it's to do with the sensor's not actually outputting analog at all, it seems to be merely off and on. So, then, I guess the microcontroller interprets pulses (caused by fluctuations in oil pressure? Where do those come from? Something to do with the movement of cams?) and tries to convert those pulses into an analog-ish reading. But information on the matter is weird. Some claim the gauge actually does nothing but show if there is no oil pressure, that it simply sits at some arbitrary position unless it's too low, then sits in the red and turns on the light. Weird. But why's this relevant? Because as far as I can tell, that microcontroller also talks via serial to the computer... but since all the other gauges are directly-wired, it seems to suggest the high-speed "bus" is only communicating oil-pressure readings to the computer! And that, it would seem, is the /only/ chatter on the bus(?!) and a lot of it!

    Anyhow, the other serial bus is silent. Which makes more sense for a "request-then-response" protocol like OBD...

    So, basically, I wrote my entire TI-86 assembly program and libraries (over nearly a year) based on the presumption that that bus was "the one", which it turns out is a bus nowhere-I've-seen documented as ever being used by my vehicle's manufacturer. Heh.

    So far I don't even know enough detail about the packet-protocol... And experimenting with that, in assembly, would be quite an ordeal. Especially if there's no No-Acknowledge if I get something wrong (like the "address" of the computer, or the CRC algorithm, or the header bytes).

    So, really, I put a HUGE effort, over nearly a year, into something that may give zero indication that it never would've worked in the first place (e.g. again, why would this bus even be implemented by this manufacturer? I mean, the pins and idle-voltage are there, which is weird-enough).

    And, then, the fact is that if it does work in this system, I could've saved myself (could still) a *ton* of effort by programming it in C on a fast computer, where data logging is an option.

    I really have no idea what I was thinking doing all that in assembly on a tiny screen with a tiny RAM and awkward "keyboard."

    But: After stepping away for a year or more, I was able to compile my old code without a hitch (I think I swapped the batteries once or twice in the meantime)... And, I guess, if my presumption that that bus is usable is actually true, then it's really only a tiny matter to actually try a request and see if there's a response. The request-response mechanism is already implemented, the UART...

    Read more »

  • TI-CBL

    Eric Hertz07/21/2022 at 06:25 0 comments

    Back in college physics I'da never thought owning a CBL would be in my future!

    Working on #Z80 Reverse-Engineering And Hacking Adventures, I had a weird epiphany... Ordering some chip sockets to solder in to the empty ROM and RAM slots, I came across ISA prototyping boards for a price I couldn't refuse. I'd had my eyes on them for years, always way out of my price range... and here their price-per-hole is highly competitive with regular ol' protoboards. It seemed wrong, but, lacking other protoboards, I started thinking about using the ISA board as just a regular-ol protoboard for a Z80 riser-board, where-on I could try out some of the crazy ideas I had in this TI-86ing project for things like memory paging, display refreshing, and such. But I really couldn't get over the nagging feeling about using that long-sought ISA protoboard for something completely unrelated to ISA.

    ...

    A few days later I woke to an epiphany. A huge part of the reason I did #Improbable AVR -> 8088 substitution for PC/XT was for the sake of using and making [especially: weird] ISA cards. Here I'm planning to stick a Z80 processor, and various weird hacks, on an ISA card... I mean, wire that thing up to the edge-connector [too], dummy!

    So then, I started thinking about it even more, and it occurred to me, I could quite-literally use the Z80, on that ISA card  to be the main CPU in the system, by basically putting the bus in permanent DMA mode. Now we have an "Improbable Z80->8088 substitution for PC/XT"... or, really, any PC with ISA slots. Or... backplanes... or... heck, apparently there are plenty of ISA riser-cards from various weird old servers and computers... wouldn't even need to halt the main CPU for DMA, just don't plug the riser into the motherboard.

    Z80 with VGA and a soundblaster, yo!

    But, again, I really dig *weird* stuff, I mean VGA is great, but there must be some weird old ISA cards that no one can even figure out what they are, nevermind find drivers for, for pretty cheap, right?

    So I started searching... and sure-enough I found some from what appear to be industrial systems, and others from test-equipment... And knowing a bit about what to look for, it's not too difficult to recognize whether some weird old card might be within my means to program without any documentation... Or, at the very least, have components I could be glad to scavenge.

    So I found one I couldn't pass up for $9... This one has four high quality 24-bit ADCs that can sample at up to nearly 400KS/s. No small shakes, and every chip on the board is *very* well documented. But "the seller doesn't ship to P.O. boxes." So, through a bit of aggravation, I'm sure, on the seller's part, we found an arrangement that'd work... For nine measly bucks, including shipping. I felt kinda bad putting them though all that. So, well, I figured I'd see about other things they were selling, to make the extra trip to their less-preferred shipping depot worth their while... And, well, there were many other things under ten bux that I was interested in, but one really caught my eye...

    A Texas Instruments "Calculator-Based Laboratory" to be interfaced to a TI-Calc... Which, as you may've gathered, I have learned a thing or two about.

    This thing, too, is *very* well-documented, down to pinouts and configuration,, and even instructions for teachers to run long-term logging on field-trips off lantern batteries! And, again, every chip inside is well-documented, too. The only hidden part being whatever the microcontroller's ROM contains (and who knows, it may be dumpable).

    But, before I even bothered to look up documentation, I just plopped in some batteries and turned it on... didn't even hook it up to a calculator... and... This blasted thing turns-on as a multimeter! No kidding... I had been debating investing in a couple more cheap multimeters, actually... For e.g. trying to monitor current and voltage simultaneously while charging/discharging old Li-Ions. I'd found...

    Read more »

  • More Z80 Hackery Goin' On...

    Eric Hertz06/20/2022 at 05:54 0 comments

    The poor TI-86 has gone from the number-one hacking-platform in my life for nearly a year to now doing little more than crunching numbers I should be able to do in my head...

    But, I owe it (and @ziggurat29) a debt of gratitude in sealing my interest in 8bit computers, and of course Z80's in particular.

    We've begun #Z80 Reverse-Engineering And Hacking Adventures anew, with what seems to be a one-off piece of lab equipment used for controlling motors in, we think, spectrum analysis.

    I'll let that project's page speak for itself...

    The TI-86... well... I was *so close* to actually finishing my project with it, and it would be a great tool for diagnosing some long-persistent technical troubles in my life, so I haven't exactly given up on coming back to this project... It's entirely plausible the new project will reinspire this one, after a half-year hiatus from the 8bit realm.

    We shall see.

    In the meantime, if you're here for Z80 goodness, maybe go see what we're doing on the other project.

  • Wait for it...

    Eric Hertz02/01/2022 at 19:55 0 comments

    Well, I got some new-shineys! So, this project has wound-up on hold...

    Briefly:

    In my life"style" power is a huge concern, as is space. Thus I've been fighting (for years, really) to figure out a decent and reliable solution to the problem of having a computer at-the-ready to return to my various coding and other projects, along with organizing photos, etc.

    ("Briefly" never seems to be so brief when I start writing)

    That's a huge reason I took on *this* project, because the only thing I need a regular-ol' computer for it is making backups and occasional serial debugging. All the actual coding has been via the TI-86 keyboard, and all the assembling has been done on the TI-86, too. (!) Which has given me a good excuse to learn and practice assembly, despite my preferring the portability of C.

    But, it is a much slower process than I expected, and I do have many other projects which need gcc and such. Nevermind the not-so-rare occasion I could *quickly* throw-together an AVR based circuit for a random need here and there.

    What was I wanting that for recently? Oh, the *far faster* comparator in an AVR than the linear ICs I've got would be handy for my boost circuit for driving LED "filament" strips for a TI-86 backlight. Oh, and a current-monitor to keep my USB battery-packs powered-up regardless of low-current... Both of which can likely be done with a 555, but it really isn't my realm, so instead of being a quick day/side-project, it turns into a multi-day project-derailing new project of its own. Again, an excuse to learn new techniques, but also not particularly ideal functionally, as these things are *really* slow compared to a 20MHz AVR... meaning larger inductors/components and higher currents, among other things. 

    OTOH, TBH, I don't really know what I'm going-for anymore... the learning-experience is "fun" in a way. Maybe "the fun?" But, it also feels like at this rate I'm never going to get to the things that motivate me. And I've *tons* of those just waiting to be tackled... Hobbled by so many limitations in this still "new" to me life"style" (half a decade, now), I feel like nearly all the things I am (or was) good at take *significantly* longer than before, if not just darn-near impossible. Imagine a carpenter without a table-saw! 

    So, for some semblance of the life I knew for so long, I keep striving to find solutions to these hurdles that didn't exist before...

     One of those was purchasing a butane soldering iron. A far cry from the industrial-grade iron I invested in back in highschool. Merely taking it out of the box and finding workspace is a chore compared to decades of just flipping a switch. Nevermind waiting for it to heat up, then having to do-so again after refilling, quite often. BUT: it's a significant improvement over the past several years! 

    So, the same goes for computing... I tried a couple laptops, but they drew so much power that it was barely suitable for an hour's use. And, frankly, they take up a lot of space in this environment when set-up. A buddy I met here thoughtfully hooked me up with an Atom-based system a couple years back which I was able to finnagle into a spacially-suitable form... which worked great for a year or so. But in trying to increase its ruggedness, I managed to damage the board. Heh. Out of desperation to keep project-momentum I threw a Pi Zero I had planned for another project in its place... And that has been my main system, aside from my phone, ever since. Frankly, *excruciating* to even do a quick web-search on. But, functional-enough for most my needs. My buddy since thoughtfully hooked me up with several assorted atom-based boards to potentially plop back into the system as a brain-transplant... But, therein lies another conundrum... I've managed to fry (and replace) various components of the Pi-based system since the initial setup. Apparently proper grounding is a huge concern in an All-DC environment. First to go was the HDMI port....

    Read more »

  • More Wild Speculation...

    Eric Hertz01/22/2022 at 21:07 0 comments

    Let's say my huge code is correct, that I didn't mis-count T-States, etc...

    If the huge code works *without* counting M1-waits, but does *not* work when counting them, then most-likely that means the T6A43 does *not* have M1-waits. Right?

     But, again, assuming my code and T-State counting is correct, then I should be getting the same results in measuring the T-States in a specific time duration via two different methods, which I don't.

    So, now, Here's an odd thing... Regardless of whether I count M1-waits, my two time-measurement methods are off by about 2%. However, what *does* change, depending on if I count the plausible M1-wait or don't, is which timer-function reports having counted more T-States during the same time duration.

    So, In the last log I did a lot of wild speculation...

    And, here I do some possibly even wilder...

    What if there is a half-cycle M1-wait?

    This doesn't work with the standard Z-80, since the /Wait input is only sampled on the falling-edge of the clock, *and*, even if it sampled on the next rising-edge (during the previously-requested wait), then all the clock levels/edges thereafter would be swapped.

    But... Why not?

    As @ziggurat29 pointed out in a comment, the T6A43 ASIC (not VLSI, as I always mix-up... AS != Average Scale, AS=Application Specific).... The T6A43 ASIC is, exactly that, Application-Specific, AND, Far Newer than the original Z80...

    So, what could that imply? 

    Well, first, 6MHz, as most claim the clock frequency to be, was well within the speeds of the era this was designed. 

    Second, it seems to have been designed for an RC clock... I dunno off-hand how it's implemented, but an easy-enough way would be simply to discharge the capacitor through a transistor, then allow it to recharge through a pull-up resistor, until it reaches some threshold voltage, then discharge it again. Creating a sawtooth wave... which doesn't really do too nicely for a digital circuit like the Z80 which does things on both edges of the clock. So, the simple solution would be to run the sawtooth at Twice the frequency, then use a Toggle-Flip-Flop to divide that in half for a nice 50% square wave.

    Now... If one happens to be designing an ASIC like this in some newish era where memories are *much* faster than the original Z80 was designed-for, BUT, there still remain vast quantities of those older slower memories, AND, in that same era tradeoffs were also being made for speed vs low-power... One *Might* consider speeding up the Z80-ASIC a bit for later end-product production-runs, but ALSO leave the option to use slower memories in present runs.

    OK... So we come to my weird thought... in a bit... So, maybe the T6A43 is really quite capable of much higher clock frequencies than 6MHz... Then maybe even those newer-faster memories would need wait states...

    Alright. Now, unlike a real Z80, we've got control of the Discharge transistor for the RC "oscillator"...

    When a /Wait is detected, we could simply discharge that capacitor a little bit early, either at a lower threshold voltage, or, frankly, even *immediately* when that clock-edge is detected alongside the low-active wait. until it is no longer. And thereafter our clock-periods return to normal. Now we can control our wait-state durations externally... Fractions of a typical clock cycle or multitudes.

    This, I think, should be a pretty simple thing to do, when you've got gate-level access to the z80-internals. And even those *extremely* fast clock-cycles merely sampling the /wait shouldn't be a problem, since I'm guessing the entire CPU basically halts, holding its state, through wait-cycles.

    The next thought, for me anyhow, is whether similar could be done with a real Z80... And, I think I've come up with external circuitry that could at least make for /half/ wait-states. The key, in this case, is whether the Z80 would freak-out if suddenly one clock pulse was missing or shifted slightly...? Why would it? There's no PLL generating...

    Read more »

  • M1 wait-state? Revisited

    Eric Hertz01/17/2022 at 20:53 3 comments

    I've several past logs regarding the possibility the T6A43 Z80-alike makes use of a wait-state on M1 machine cycles.

    These are my latest findings:

    First, the setup:

    I have a 41.667Kb/s serial signal, pulse-width-modulated (a 1 is a 16us high, 8us low, a zero is 8us high, 16us low) and a 4800bps UART serial signal to compare to.

    41.6K is too fast to process in realtime, so I first take 1024 samples then post-process. A packet usually consists of 49 pwm-bits, and I generally measure around 272 samples containing a frame. I use the INIR instruction to grab 256 samples at a time, and pad with a nop between INIRs. Thus, each sample should be 21T-States (unless there are added wait states).

    Yes, I disable LCD DMA and interrupts.

    272samples/49pbits×21T/sample×41667pbits/sec gives 4.857Million T-States per second.

    Then, in the same program I "autobaud" by measuring the number of T-States during a "?" received by the UART at 4800b/s. The use of "?" for autobaud makes it easy to see a distinct change between the start bit and the first data bit, and the last data-bit and the stop bit.

    I measure the number of loops between detection of the start of the first bit and detection of the end of the last bit. Each loop is 35T-States long, assuming no wait-states. Though, the loop looking for the first bit is 29T-States.

    The counting loops look like:

    inc hl ; 6T

    in a,(7) ;11T

    and b ; (rxMask) 4T

    cp d ; (rxOne) 4T

    jp z, loop ;10T

    If M1 waits were implemented everywhere, this loop would be 40T-States instead of 35, and the INIRs would be 23T instead of 21.

    The autobaud measurement determines 993T/bit at 4800b/s, which amounts to 4.766Million T-States per second vs. the other measurement's 4.857. That's an error of about 2% which is enough to begin being concerned about UART timing.

    So, I started looking into potential error sources and whether they could account for the difference. First and foremost, if an M1 wait-state went unaccounted-for those numbers wouldn't get *closer*, they'd in fact veer even further apart. 5.45MHz vs 5.32MHz, 102.4%, vs 4.77 vs 4.86, 101.8%. A minor difference, I suppose... I could've sworn it was further off than that.

    So then I tried to account for the error elsewhere. E.G. what if the edge of a UART bit occurred immediately after sampling, then there'd be nearly 35T of error. And if the edge of the last bit occurred immediately before sampling, then there could be an additional nearly 35T of error.

    But... at 993T/bit, or 7945T/8-bit frame, that measurement error is nowhere near enough to account for 2%.

    This is important, again, to my project because ultimately I won't have autobaud as an option and will have to generate my UART timing based on the 41.6Khz signal. I looked at it with a scope and measured darn-near exactly 41667Hz. So, it's plausible my 4800bps UART connected to my computer (via USB) is off by some UART-Acceptable percentage. And/Or it's possible M1-Waits are a thing...

    But I ran some numbers and found another plausibly-reasonable explanation...

    Note, I went through all this because: If I autobaud accounting for M1-waits, and also account for M1-waits in my UART code, it sends/receives garbage.

    The other plausible explanation I came up with for the 2% error between the 41.6k signal and the 4.8k signal is that I/O may have wait-states. If there is no M1 wait-state, but there is one wait-state for port reads, then the numbers drop from 2% error to 1%. If, plausibly, INIR has two wait-states (why?) then the measurements from the two sources align almost perfectly at 

    ... DAGNABBIT!

    I did these calcs yesterday, and they did add-up. Why The Heck aren't they now?!

    I thumb-typed this whole thing for no reason?!

    ...

    GAAAAHHHHH!!!

    This Is Really Frustrating.

    I spent *weeks* making all the code switchable between M1-waits and no M1-waits, had to recount every friggin T-State in every friggin function *several* times, because at first I was...

    Read more »

  • The "Blacklink" is handy!

    Eric Hertz01/07/2022 at 00:40 0 comments

    I keep finding uses for it in ways never intended. There's a previous log where I talked about it, some, and drew the schematic...

    I've used it in /many/ different ways, now... Note that, as I recall, the comparator runs down to 2V and can accept inputs up to 18V or so even when the supply is lower.

    The "bias" (more like "threshold") voltage is 1.65V, which is a pretty decent threshold for many different signals, including "today's RS-232", TTL, 3.6V USB-Serial, and even 12V signals in a car...

    My USB-3.6V serial converter has a 3.3V zener at its Rx input, so I considered just connecting the calculator's link port to Tx and Rx, directly. BUT, actually, the calculator could feed up to 6V back into the /Tx/ line, which I don't think is a good idea. So, I just threw the "blacklink" between, for good measure. Its DB-9-side input is not pulled-up, so no feeding 6V into the 3.6V output on my USB-Serial Converter. The pull-up at the graphlink's output is pulled to the voltage of the DB-9-side's largest voltage, which is 3.6V from Tx, so the zener's really not necessary.

    Anyhow, I'm not really wording well right now, but here's the current use-case, very different:

    PWM is (I think) open-collector to ground, pulled up to 12V. I need the calc (circuits on the right) to read that, not write. The graphlink circuitry inbetween not only converts that to TI-link's levels, but also supplies 12V to the graphlink's circuitry through the diode at the input. Since it does this, I'll probably wire up 12V directly to the graphlink's power capacitor, just in case that pull-up and the heavy data flow allows that voltage to sag. 

    But now there's 12V in the graphlink... what about connecting to my 3.6V-UART signals? (BTW, did you notice the blacklink /also/ adapts my 1-wire bidirectional UART (on the calculator's red wire) to Tx and Rx for my 3.6V UART? Handy!) 

    Tx is simple-enough. There's no pull-up on the DB-9-side inputs. Threshold voltage is 1.6V. Great! 

    Rx, well, I already have the 3.3V zener at its input, and since the blacklink doesn't /drive/ during high outputs, instead pulling up with a resistor (yes to 12V, weakly) the zener shouldn't have to sink much current to keep a high input at a 3.6V-logic-safe level.

    That's pretty much it! Now my calculator can interface its bitbanged 1-Wire bidir UART with a 3.6V 2-wire Tx/Rx UART AND read a 12V "clock" signal from my car. And all i had to do was reroute a few pins from the graphlink's DB-9.

    (OK, and make sure there's a zener on Rx, and I soldered in some wires to the blacklink's power capacitor a while back).

    ....

    Trying to parse this from TI's datasheet of the LM339 comparator used in the blacklink:

    "The upper end of the common-mode voltage range is VCC+ – 1.5 V; however, one input can exceed VCC, and the comparator will provide a proper output state as long as the other input remains in the common-mode range. Either or both inputs can go to 30 V without damage."

    ...

    This note seems in conflict with other specifications, especially "Recommended". OTOH, without taking this note into account, the blacklink's circuit is not within the Recommended specs. Because: It draws its power /from/ the input... through a diode. So the input voltage might be say 0.6V higher than VCC. The above quote seems to be saying that's OK. The recommended parameters don't.

    The alternative is to consider the second diode at the comparators' inputs. This is reverse-biased to ground. Initial guess was to protect the comparator input from /negative/ input voltages, which would likely be present on an RS-232 signal. Bringing a negative input to, say, -0.6V. This is out of range, too. -0.3 is the LM339's spec... So, maybe it's shotkey. But, then, unless it's zener, the input still exceeds VCC. Meaning the above note is important to its design.

    Currently, this is especially relevant to my hacked-use of the blacklink. 

    Usually its inputs are connected to RS-232 signals which actually...

    Read more »

  • Where Am I?

    Eric Hertz01/06/2022 at 04:55 0 comments

    So, in a recent past-log I finally explained what it is I plan to do with this calc-hackery...

    And that had been kinda side-lined due to other/new issues with the very thing /this/ thing was intended to diagnose. heh.

    Anyhow, Thank Goodness, it seems those have subsided, so I can return to this to help diagnose that's long-term ailments.

    ...

    I'm interfacing with a 1-wire bidirectional UART... It works on a request/response basis. And, frankly, I don't really have a whole lot of /reliable/ information to go on about the structure of a request. So, until I get that right-enough, the responder might very well stay completely silent.

    This, combined with the fact the z80 CPU is clocked by a somewhat variable RC-clock, makes for a bit of an issue when it comes to bitbanging a UART to communicate with it... If the responder sent out a message every so often, I could determine its bit-duration (with respect to the CPU frequency, NOT WRT seconds!) with some sort of autobaud system. But, since it only speaks when spoken to (correctly!), I can't autobaud from it.

    Thankfully there are /two/ serial communication busses in this system. The other, which I will otherwise not interact with, has chitter-chatter going on quite regularly. So, I can autobaud off that!

    Sorta. It communicates at a MUCH higher baudrate, so fast, in fact, that the calculator CPU can /barely/ read the port fast enough to catch every bit, and certainly too fast and too regularly for the calculator to actually process the data.

    But, it /can/, just barely, catch every bit. And the packets are also rather long, which is helpful because then I can get a good sense of the CPU's clock speed with respect to that baudrate... 41.6K. It's also quite handy that protocol is "PWM" rather than a typical UART, because that means Every Bit has both a high and a low, and thus an inherent bit-clock.

    So, if I create the fastest sampling loop possible on the z80, I can sample just fast enough to see every high and low. Then I can divide the number of samples by the number of bits, and a little bit of dimensional-analysis math to determine the actual CPU speed... in actual Hertz.

    From there, I think my references are pretty consistent that my UART needs to communicate at 10.4Kbps. So, now Ican figure out how many CPU clock cycles should occur between each UART bit.

    YAY!

    Since I'm going into this rather blindly, I've been developing quite a few tools, which are unnecessary in the final project, in order to test things as I go with an actual computer rather than with the most-likely silent end-goal device.

    That means e.g. in order to develop the UART bitbanging code I needed to interface it with RS-232 at a normal baudrate ("10.4 Good Buddy!" just ain't normal). And detecting the CPU frequency, in that case, had to come from the computer, too, rather than my 41.6Kbps serial bus. So, that meant developing a real "autobaud" function which will never be used in the final system. heh!

    Similarly, Bitbanging the receiver is very different than bitbanging the transmitter... So, those two systems are different "libraries" altogether... But they have to work together. Since RS-232 is /not/ one-wire, I started with the receiver and transmitter on separate pins on the calculator's link port. But, later they'll be on the same pin. Thus I continue to develop "iPort7," "iUAR," and "iUAT" such that switching pins is merely a matter of changing an ".equ." 

    But, that's further complicated by the fact that Port7 is /not/ Read-Modify-Writeable! So, every time one pin on the port is written or reconfigured (input, output, pulled-up, driven high, pulled low, Hi-Z, ...) the /other/ pin must be accounted-for, too. iPort7 now makes that quite a bit easier, such that e.g. I can work on developing iUAT without knowing or caring what the other pin is used for. 

    Also making that easier is the fact that these processes pretty much /can't/ be multitasked. There's really...

    Read more »

  • Shouldn't've used a 555... a crazy ramble

    Eric Hertz12/06/2021 at 08:27 0 comments

    https://hackaday.com/2021/12/01/the-555-timer-contest-returns

    There's a category for "Shouldn't've used a 555"...

    This dang calculator doesn't have a high-speed timer of any sort, it seems, at least accessible by the CPU instructions.

    That's why all these UART and other tasks have been really quite difficult, counting T-States.

    One of my earlier thoughts was maybe there's an R/C circuit used to create the 200Hz interrupt. In which case I could tack an ADC on to get say 200×256 40,000ish ticks per second. It was mostly a joke, but I might've done it just to say I did, and maybe even figured out goofy ways to deal with those ticks' having different durations due to the RC charging curve. I'd've done it IF those beautiful ceramic and gold Analog Devices DIPs in my collection all these years were ADCs. Alas, they're DACs. Anyhow, Actually, now I think that 200Hz 200Hz interrupt is generated by the LCD driver). 

    But, 555's apparently go up to 100khz, which is even more ticks! Obviously, feed that into a TTL counter/divider, and yer set! But... inspired by the "Shouldn't have"... I actually hadn't thought of the TTL counter until just now. Heh.

    Instead my brain went straight to trying to create the counter FROM 555's. And, actually, now that I think of it, even /that/ could probably be done... ripple-counter, each 555 has a latch. Probably, yep.

    Nono, that's not where my brain went first, it went to trying to set up say 8 555 oscillators each oscillating at half the frequency of the previous. Yahknow, darn-near impossible to achieve precisely.

    So, then it went to even weirder ideas, like vernier-scales and gray-code and beating... e.g. 8 slightly-detuned free-running oscillators (I'm choosing 8 because that's the bus width, not because I expect 256 values)... maybe even far slower than 100khz.

    I hadn't really gotten much further than that before becoming /pretty sure/ something along those lines would be plausible... though a beast to decode in software, eh? Just the sorta way *not* to do a timekeeper...

    OK, so, what, now?

    I dunno, say you had three analog wall clocks with dying batteries. The second-hands would tick at slighly different rates, close to but not a second. Sometimes they'd seem to be in sync, other times completely out of sync...

    No, shoot, this is exactly the opposite, right? Here's a fast pulsing, and a slow measurement from it.

    No, wait, that works with the ~100KHz idea.

    Right, so, the relative phases indicates the count of "seconds."

    Heck yeah.

    'cause, the whole point is there's ziltch liklihood I'd be able to read the port at 100khz to catch every tick. Especially when doing other calculations like bit-shifting serial data. But, we don't want to write that data bit to the port until 1/9600th of a second after the last one, so now when the bit is ready we can start polling our 100khz tick-counter to see when enough time has passed...

    OK, I think there's something to work with, there... But, in the clock example one has to sit and watch the relative times between the /changes/ of the various second-hands to determine their relative phases, and /those/ occur *faster* than one second...

    OK, now this is becoming a real challenge, the sort my brain won't be able to let go of.

    ... So, to recap: Analog wall clocks are a bad example. Just look at the position of the second-hand, or the friggin' minutes hand, if you want to know how much time passed since last you looked.

    OK three metronomes.

    This is a bad example, too, because allegedly they'll sync and stay synced(?!)

    Pretend that's /not/ the case (seems absurd, would rule-out "beating").

    OK, so, if they're all close to one second and they're all started at the same time... then for the first few toggles, they'll all pretty much be at the same positions at the same times...

    I should start with two.

    And I want....

    To look at their /end-positions/ in order to determine how much time has passed.

    So, if they're off by 0.25 seconds... then...

    Read more »

  • M1 Wait State??? + OBD

    Eric Hertz12/05/2021 at 16:18 0 comments

    I found a post over at Cemetech by [Zeroko] claiming the T6A43 (z80 VLSI) in the TI-86 and TI-81 must have a wait-state added to every M1 cycle to account for some assembly timing oddities...

    I came to a similar conclusion prior to finding that post... My autobaud function was measuring something like a 5.1MHz CPU clock, while my CPU frequency meter was measuring more like 4.7. So, on finding that forum post about an extra T-State for every instruction, I thought I must've been on the right track.

    Rewrote all my UART bitbanging code, autobaud, delay_TStates, CPUFreq, etc. to account for that (recounting T-States and revising math in *numerous* libraries)...

    And now it doesn't work.

    Heh.

    Did before!

    ...

    Weird thing is, now autobaud and CPUFreq are measuring nearly the same clock frequency.... about 5.2MHz

    So...

    What'd I do wrong...? Heh.

    ...

    FYI: adding a wait-state to M1 cycles is apparently common-enough z80 practice as to be documented in the z80 datasheet. It makes for equal memory-access timings for all cycles, which is probably unnecessary with today's (or even TI-81-era) fast SRAMs, but makes sense that an era-VLSI like the T6A43 designed around a z80 might include it, since /adding/ it later isn't an option due to the lack of WAIT and M1 pins.

    This document lists the T-State count for every z80 instruction, with and without an M1-wait.

    http://map.grauw.nl/resources/z80instr.php

    Basically it amounts to adding a single T-State to every CPU instruction. But, of course, some assembly "instructions" are actually *two* CPU instructions under one name: e.g. using IX/IY is done by an instruction that basically says "for the next instruction, replace HL with IX." Thus the single assembly instruction is two CPU instructions, thus having two M1 cycles, thus, likely, two wait-states.

    My thought is that there really is no reason to expect the T6A43 (or any other implementation) to deviate from this table, owing to the *purpose* behind adding an M1 wait. Though, I suppose it's /plausible/ the z80 core in the VLSI may differ in implementation slightly from the original z80 (e.g. maybe they figured out how to speed up an instruction, here or there, which they likely would NOT do on a z80 chip, for compatibiliy-sake, but might do-so in a z80 core intended for an embedded application... the Gameboy's slightly-different z80-alike comes to mind).

    ...

    FYI2: I can't seem to find any other sources  mentioning M1 wait states and TI calculators. I'd think, with so much assembly hacking done to them over the years, including /emulators/, there'd've been plenty of folk who've run into this. So, I'm a bit confused how it could've gone under the radar for so long.

    [Zeroko] (the same) has also recently put up a wealth of information over at: https://wikiti.brandonw.net/index.php?title=86:ASIC and other pages, there. Much of which I've seen nowhere else (including /CS2 and /CS3!!!! And an /IOREQ?!) There he also mentions the M1 wait-state, but I see no references...

    ...

    Unfortunately, I STILL haven't gotten to the FLASH-backup utility that, really, was planned to be my *first* project with the TI-86... yahknow... /exactly/ for moments like these. And the memory is full. So, reverting to the previous functional code is quite an ordeal at 0.1KB/s between the USB-Serial dongle connected to my blacklink...

    Kinda a recurring chicken-egg problem. So, among many other things going on right now, I can't really verify the M1 Wait State finding (nor, really, continue with this project until I can).

    ...

    Meanwhile... I've been vague, here, in the past, about the underlying goal of this bidir UART project... so here I'll explain:

    My van has had some ongoing weirdness for some time... misfires, etc. were reported last I went to the parts store for an OBD scan. Well, that's *sorta* helpful, but would be *way* more helpful if I could actually see *when* these sorts of things happen... under what conditions....

    Read more »