There is no need to TryToSend before getting the character. We
send bytes during SER_PUT, and if interrupted during sending, we
still try to do it at the beginning of the next SER_PUT.
There's no target with more than one serial driver (and I don't see that change anytime soon) so it's a no-brainer to apply the standard driver concept to serial drivers.
We basically cast a struct timespec pointer to a time_t pointer when we pass the clock_settime() paramter to localtime(). Explicitly express that in the source code.
The CIA TOD only stores the time but not the date. Therefore the date set by clock_settime() ist just stored inside the C library for retrieval via clock_gettime().
The "very special" handling of 12AM/PM is based on https://groups.google.com/d/msg/comp.sys.cbm/ysVYSX4AMbc/vHrXCWEhCOUJ saying:
==========
24hr: Wr => Rd => Nx
--------------------
0 : 92 => 12 => 01 <= Switch from 00 to 01 (24-hour notation)
1 : 01 => 01 => 02
2 : 02 => 02 => 03
11 : 11 => 11 => 92
12 : 12 => 92 => 81 <= Switch from 12 to 13 (24-hour notation)
13 : 81 => 81 => 82
14 : 82 => 82 => 83
23 : 91 => 91 => 12
1. column ("24hr"): hour to be tested (decimal)
2. column ("Wr"): hour written to TOD register (BCD)
3. column ("Rd"): hour read from TOD register (BCD) immediately after writing the value in column 2 to see the conversion between AM/PM, if any
4. column ("Nx"): next hour (BCD) after the hour switch
==========
Thanks Paul!
We want to add the capability to not only get the time but also set the time, but there's no "setter" for the "getter" time().
The first ones that come into mind are gettimeofday() and settimeofday(). However, they take a struct timezone argument that doesn't make sense - even the man pages says "The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL." And POSIX says "Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function."
The ...timeofday() functions work with microseconds while the clock_...time() functions work with nanoseconds. Given that we expect our targets to support only 1/10 of seconds the microseconds look preferable at first sight. However, already microseconds require the cc65 data type 'long' so it's not such a relevant difference to nanoseconds. Additionally clock_getres() seems useful.
In order to avoid code duplication clock_gettime() takes over the role of the actual time getter from _systime(). So time() now calls clock_gettime() instead of _systime().
For some reason beyond my understanding _systime() was mentioned in time.h. _systime() worked exactly like e.g. _sysremove() and those _sys...() functions are all considered internal. The only reason I could see would be a performance gain of bypassing the time() wrapper. However, all known _systime() implementations internally called mktime(). And mktime() is implemented in C using an iterative algorithm so I really can't see what would be left to gain here. From that perspective I decided to just remove _systime().
About all CONIO functions offering a <...>xy variant call
popa
_gotoxy
By providing an internal gotoxy variant that starts with a popa all those CONIO function can be shortened by 3 bytes. As soon as program calls more than one CONIO function this means an overall code size reduction.
The way we want to use the INITBSS segment - and especially the fact that it won't have the type bss on all ROM based targets - means that the name INITBSS is misleading. After all INIT is the best name from my perspective as it serves several purposes and therefore needs a rather generic name.
Unfortunately this means that the current INIT segment needs to be renamed too. Looking for a short (ideally 4 letter) name I came up with ONCE as it contains all code (and data) accessed only once during initialization.
So far the INIT segment was run from the later heap+stack. Now the INIT segment is run from the later BSS. The background is that so far the INIT segment was pretty small (from $80 to $180 bytes). But upcoming changes will increase the INIT segment in certain scenarios up to ~ $1000 bytes. So programs with very limited heap+stack might just not been able to move the INIT segment to its run location. But moving the INIT segment to the later BSS allows it to occupy the later BSS+heap+stack.
In order to allow that the constructors are _NOT_ allowed anymore to access the BSS. Rather they must use the DATA segment or the new INITBSS segment. The latter isn't cleared at any point so the constructors may use it to expose values to the main program. However they must make sure to always write the values as they are not pre-initialized.
Up to now static drivers were created via co65 from dynamic drivers. However there was an issue with that approach:
The dynamic drivers are "o65 simple files" which obligates that they start with the 'code' segment. However dynamic drivers need to start with the module header - which is written to. For dynamic drivers this isn't more than a conceptual issue because they are always contain a 'data' segment and may therefore only be loaded into writable memory.
However when dynamic drivers are converted to static drivers using co65 then that issue becomes a real problem as then the 'code' segment may end up in non-writable memory - and thus writing to the module header fails.
Instead of changing the way dynamic drivers work I opted to rather make static driver creation totally independent from dynamic drivers. This allows to place the module header in the 'data' segment (see 'module.mac').
This change was suppsed to fix the issue that the former JUMPTABLE is merked as 'ro' while it is actually written to in several scenarios. When drivers are converted using co65 and then compiled into ROMs the JUMPTABLE isn't copied to RAM and therefore the write operations in question fail.
However unfortunately I didn't succeed in changing that :-( Just setting the former JUMPTABLE to 'rw' broke the drivers. So I placed the DATA segment directly after the former JUMPTABLE segment. This made the drivers converted with co65 work again - obviously after changing libsrc/Makefile:235 from '--code-label' to '--data-label'. But the actual dynamic drivers still didn't work as the former JUMPTABLE wasn't placed as the beginning of the loaded file anymore. That effect could be changed by exchanging src/ld65/o65.c:1391 with src/ld65/o65.c:1394 but doing so broke the drivers again :-((
Occasionally dynamically drivers suffer from not being to refer to
content in the C library. Therefore I added a mechanism to allow
a C library for a certian target to define a symbol that will be
handed over to dynamic drivers for that target. Then the drivers
can use their refernce to that symbol to access content in the C
library.
- No complex shell logic.
- "Source file shadowing" for all targets via vpath.
- Dependency handling.
- True incremental build.
- Don't write into source directories.
- Easy cleanup by just removing 'wrk'.
machines, the program runs in a separate 64K bank, and zeropage variables need
to be copied from the system bank into the execution bank to read by a simple
load operation. The change is currently untested!
git-svn-id: svn://svn.cc65.org/cc65/trunk@4597 b7a2c559-68d2-44c3-8de9-860c34a00d81
named EXEHDR.
* Renamed BASICHDR to EXEHDR for the PET-II machines.
* Moved the call to CHRCH in front of the code that saves the zero page, since
open files are sometimes remembered in the zero page, so we need to close
them before we grab a copy.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4507 b7a2c559-68d2-44c3-8de9-860c34a00d81