* Docs say that CLK_TCK is an obsolete alias of CLOCKS_PER_SEC so there's no point in individual definitions.
* All targets determining the clock rate at runtime can use a common handling.
Please refer to https://github.com/cc65/cc65/pull/532 for background info.
I wrote in https://sourceforge.net/p/cc65/mailman/message/35873183/
===
cputs() wraps to the next line if the strings is too long to fit in the current line. I don't know if it's worth the effort to allow cpeeks() to continue reading from the next line. I'd like to discuss this aspect with the actual implementers.
===
This is still as unclear today as it was when I wrote the above. Therefore this change just doesn't add cpeeks() at all.
Since f8c6c58373 the Apple II CONIO implementation doesn't "need" revers() anymore - meaning that (nearly) every possible value can be placed in VRAM with a straight cputc() (without the need for a previous revers(1)).
The implementation of cpeekc() leverages that cputc() ability by always returning the value that can be fed into cputc() without a previous revers(1). Accordingly, cpeekrevers() always returns 0.
So after the sequence revers(1); cputc(x); a cpeekc() will return a value different from x! However, I don't see this behavior braking the cpeekc() contract. I see the cpeekc() contract being defined by the sequence textcolor(cpeekcolor()); revers(cpeekrevers()); cputc(cpeekc()); placing the very same value in VRAM that there was before. And that contract is fulfilled.
The driver requires a special linker configuration: "vic20-tgi.cfg".
The VIC-20 computer needs at least 8K of expansion RAM!
"tgidemo.c" needed to be adjusted because the VIC-20's vertical (y) range is greater than its horizontal (x) range -- the opposite of most other platforms. Also, the circle demo would jam on the VIC-20.
The implementation is a bit tricky as it requires to take different code paths for the //e, the //c and the IIgs. Additionally the //c only provides a VBL IRQ flag supposed to be used by an IRQ handler to determine what triggered the IRQ. However, masking IRQs on the CPU, activating the VBL IRQ, clearing any pending VBL IRQs and then polling for the IRQ flag does the trick.
From "Mapping the Atari": "Size of player. POKE with zero or two for normal size (eight color clocks wide), POKE with one to double a player's width (sixteen color clocks wide), and POKE with three for quadruple width (32 color clocks wide). Each player can have its own width set."
The _textcolor() macro doesn't just turn on the macro optimization. It defines the return value of textcolor() - and that is supposed to be a COLOR_... value.
It can be used to undo what "cbm_screen_charmap.h" does. Together, those headers let you mix screen-code and PetSCII string and character literals in a C source file's Assembly output.
Changed the number literals from Assembly format to C format. Swapped the (upper-/lower-case) mappings of letters because the header converts from ASCII, not PetSCII.
Most documentation say that most of the bits are normally set to 1 or 0,
so just mentioning that in the comments.
A.N.A.L.O.G. issue 59 (April 1988) "Bits & Pieces" column, "Atari Zucchini"
(https://www.atarimagazines.com/analog/issue59/bits_pieces.php) implies
that they are used for specific things, but it's not clear enough to be
useful (or specifically states "Too complex and not pertinent").
This is probably sufficient for most purposes; if any PIA / PACTL/PBCTL
experts pop up, they can tell us exactly how those 4 bits can be utilized.
Use a C "union" to give both read (NMIST) and write (NMIRES) labels
to their shared register in ANTIC. (h/t @groessler).
Consolodate duplicated color definitions (HUE_..., COLOR_... and TGI_COLOR_...;
and the "_gtia_mkcolor()" macro), found in both "atari.h" and "atari5200.h",
moving it to "_gtia.h", which they both share (and which makes the most sense).
Cleaned up comments in Atari 8-bit headers.
Internal keycodes (POKEY's KBCODE) were already #defined in atari.h,
so didn't need a whole new set in _pokey.h.
Relocated register #define'd values outside of the structs,
improved comment format, expanded & corrected some things.
h/t Trevin Beattie (https://user.xmission.com/~trevin/) for the PIA
register descriptions.
Some register #defines for PIA.
(Some may be too Atari-centric -- I know PIA chip was used by PET &
perhaps other platforms supported by cc65. If so, perhaps we can
define them elsewhere. Not sure whether they'd be the same for 5200;
I admit I know zilch about that system except that it's _more or less_
an Atari 400)
Add #defines for certain registers' values.
Also add #defines for internal keyboard codes (unrelated to ATASCII;
e.g. [Q] = 47, [W] = 46, [Shift] adds 64, etc), as seen in KBCODE.
There aren't really standard color names (e.g., Compute!'s Mapping the Atari and First Book of Atari Graphics have different names), and exact colors shown depend on the system & device, anyway. Added a note.
* DMACTL - playfield size, DMA access, PMG resolution
* CHACTL - inverted text, inverse effects
* NMIEN
Also, added #define equivalents for Display List mode line instructions
based on Atari 8-bit OS (aka Atari BASIC "GRAPHICS" command) values
(e.g., "DL_GRAPHICS0" == "DL_CHR40x8x1").
Added some more documentation in the comments.
Added macros with assembly language for the start/end of Display List
Interrupt (DLI) functions.
Originally the Apple II had a 64 char set and used the upper two bits to control inverse and blinking. The Apple //e brought then an alternate char set without blinking but more individual chars. However, it does _not_ contain 128 chars and use the upper bit to control inverse as one would assume. Rather it contains more than 128 chars - the MouseText chars. And because Apple wanted to provide as much backward compatibility as possible with the original char set, the alternate char set has a rather weird layout for chars > 128 with the inverse lowercase chars _not_ at (normal lowercase char + 128).
So far the Apple II CONIO implementation mapped chars 128-255 to chars 0-127 (with the exception of \r and \n). It made use of alternate chars > 128 transparently for the user via reverse(1). The user didn't have direct access to the MouseText chars, they were only used interally for things like chline() and cvline().
Now the mapping of chars 128-255 to 0-127 is removed. Using chars > 128 gives the user direct access to the "raw" alternate chars > 128. This especially give the use direct access to the MouseText chars. But this clashes with the exsisting (and still desirable) revers(1) logic. Combining reverse(1) with chars > 128 just doesn't result in anything usable!
What motivated this change? When I worked on the VT100 line drawing support for Telnet65 on the Apple //e (not using CONIO at all) I finally understood how MouseText is intended to be used to draw arbitrary grids with just three chars: A special "L" type char, the underscore and a vertical bar at the left side of the char box. I notice that with those chars it is possible to follow the CONIO approach to boxes and grids: Combining chline()/cvline() with special CH_... char constants for edges and intersections.
But in order to actually do so I needed to be able to define CH_... constants that when fed into the ordinary cputc() pipeline end up as MouseText chars. The obvious approach was to allow chars > 128 to directly access MouseText chars :-)
Now that the native CONIO box/grid approach works I deleted the Apple //e proprietary textframe() function that I added as replacement quite some years ago.
Again: Please note that chline()/cvline() and the CH... constants don't work with reverse(1)!
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().
The change matches the way that I/O register structures are defined in other headers. The names are defined as "struct", instead of as "pointer to struct".
So far conio.h included the target header to get the CH_... and COLOR_... macros. However tgi.h never did the same to get the TGI_COLOR_... macros. And some time ago the JOY_..._MASK macros moved from joystick.h into the target header yet joystick.h didn't include the target header.
Why wasn't that issue detected so far? Because about every program using TGI and/or the joystick uses CONIO too and therefore includes the target header that way.
However, conceptually it's clean to factor out the target header inclusion and have tgi.h and joystick.h do it like conio.h.
Apart from that user code may make direct use of target.h too.