skiphansen / pano_z80

Retro Z80 computer for the Pano Logic Thin Client
45 stars 2 forks source link

RTC possible? #2

Open snhirsch opened 4 years ago

snhirsch commented 4 years ago

I use Z-System (NZCOM) with z80pack on my Linux machine and have come to rely on the z80pack RTC for timestamping support. Unfortunately, the pano_z80 BIOS doesn't seem to have implemented it and I get cascades of error messages about port access. Does the Panologic G1 hardware have anything that could be leveraged for this purpose? Maybe a timer-based clock that one sets on boot?

I'm also seeing Z80HALT and lockups from time to time. Is there any trace or debug functionality present that could be used to chase this down?

skiphansen commented 4 years ago

I'm afraid there isn't any hardware support for an RTC of any kind. If someone gets the Ethernet port up we could use NTP, but no one is working on it that I am aware of. A timer-based clock that one sets on boot is certainly doable. I don't know how accurate the clock is, but I would get it's fine for a day or two...

There isn't any debug capability currently.

snhirsch commented 4 years ago

Hi, Skip. Did you have any luck implementing an interrupt-driven clock? If you can define the hardware, I may be able to help with the RISCV coding. At this point, Verilog is like Greek to me :-).

skiphansen commented 4 years ago

No, I've been trying to fix the first USB port which is proving to be challenging.

You might be able to do it without hardware, the RISCV has a built in counter of the number of cycles since power on that you could use for a time reference. time() returns the number of cycles since power up, at 25 Mhz it wraps every 171 seconds.

All of the Z80's I/O that isn't handled are already in RTL is redirected to the RISCV (see https://github.com/skiphansen/pano_z80/blob/c073bdb3ec9e65bbc6b5dd5917b1be57563f2e95/fw/firmware/cpm_io.c#L137)

Have fun! I promise won't collide with you time time.

snhirsch commented 4 years ago

Ah, ok. So the idea would be to check it on each iteration of the main I/O loop, correct?

skiphansen commented 4 years ago

Yup, that's the idea. Read the current number of cycles, subtract the number of cycles last time it was read, add the delta to an accumulated time. When the z80 reads the clock convert to the appropriate format.

snhirsch commented 4 years ago

Great. Handling counter wraparound is simple, given that we're unlikely to have an I/O operation taking more than 171 seconds. Let me see what I can do.

snhirsch commented 4 years ago

I have the timekeeping logic nominally working, but it turns out the main loop blocks on HandleIoIn() so it's possible to lose track of counter wraparound during long idle periods. Is this expected? I moved the code into the IdlePoll() function and things now work properly.

skiphansen commented 4 years ago

Good point, I didn't think about that. Moving your code into IdlePoll() and should be good. HandleIoIn() should be calling IdlePoll() while waiting for console input.

The BIOS is a bit of an odd interface since it was written for the z80pack simulator. The way I read the code reading the console port blocks until keyboard data available.

Send me a pull request when you are happy with the changes and I'll merge it.

snhirsch commented 4 years ago

Ran into a problem: Since the firmware does not include libc there are no date parsing functions available. Is there a way to selectively link from the full libc without bloating things up? I searched for open source date functions and cannot find anything usable. Neither uClibc or MUSL are available for RISCV32.

skiphansen commented 4 years ago

So gmtime() /localtime() is what you need? If so the it looks like you could probably swipe gmtime_r.c from the library sources and just compile it along with the other sources. It doesn't look like it's dependent on other functions and looks like it should be fairly easy to get to compile (famous last words).

skip@Dell-7040:~/riscv-gnu-toolchain-rv32i$ find . -name gmtime_r.c
./riscv-newlib/newlib/libc/time/gmtime_r.c

There's plenty of RAM for the RISCV, the problem is the somewhat limited flash space. The basic program skeleton dates back to when everything needed to fit into the FPGA's on chip RAM before the DDR2 RAM was brought up.

snhirsch commented 4 years ago

Actually, I need strptime(), which has some nastier dependencies. I found a source file in 'newlib' and am in the midst of hacking it to suit. Sort of a pain, but I should be able to do it.

snhirsch commented 4 years ago

Update: I have all the date handling functions coded and working. Currently cooking up a line-oriented input routine for RISCV code. Should have this working by tomorrow.