cc65 program w/ assembler & COUT routine: inverse mode only in 80 column mode?

16 posts / 0 new
Last post
Offline
Last seen: 2 months 2 weeks ago
Joined: Nov 12 2022 - 16:50
Posts: 202
cc65 program w/ assembler & COUT routine: inverse mode only in 80 column mode?

I just realized while debugging a text adventure that setting inverse mode for text only works in 80-column mode, because the program was printing garbage where it was supposed to print inverse text until I added "videomode (VIDEOMODE_80COL);" to the beginning of the main() function.  I prefer the game to be in 80-column mode, anyway.  I'm wondering why this is.

Offline
Last seen: 4 weeks 1 day ago
Joined: Jul 5 2018 - 09:44
Posts: 2587
Inverse should work in 40

Inverse should work in 40 colums.

 

Offline
Last seen: 4 weeks 1 day ago
Joined: Jul 5 2018 - 09:44
Posts: 2587
a2_inverse.png
Offline
Last seen: 5 hours 19 min ago
Joined: Jun 18 2010 - 13:54
Posts: 792
softwarejanitor wrote:Inverse
softwarejanitor wrote:

Inverse should work in 40 colums.

Unless you want lowercase characters...

 

Offline
Last seen: 2 months 2 weeks ago
Joined: Nov 12 2022 - 16:50
Posts: 202
Well, I [b]am[/b] using lower

Well, I [b]am[/b] using lower-case characters.  I'm also not using BASIC.

Offline
Last seen: 22 hours 1 min ago
Joined: Nov 29 2020 - 19:48
Posts: 135
And $80

Try setting the high bit by anding teh acculator with $80 before calling COUT.  You may get expected results that way.

Offline
Last seen: 4 weeks 1 day ago
Joined: Jul 5 2018 - 09:44
Posts: 2587
jeffmazur wrote
jeffmazur wrote:
softwarejanitor wrote:

Inverse should work in 40 colums.

Unless you want lowercase characters...

 

True enough.  He didn't mention lower case.  Inverse lower case does work fine in 80 columns.

 

 

Offline
Last seen: 2 months 2 weeks ago
Joined: Nov 12 2022 - 16:50
Posts: 202
8BitHeaven: I think you mean

8BitHeaven: I think you mean OR $80.  I am doing that.  It works in 80-column mode but not 40-column mode.  :(  

mmphosis's picture
Offline
Last seen: 4 months 4 hours ago
Joined: Aug 18 2005 - 16:26
Posts: 437
> I'm wondering why this is

Character sets and "modes" can vary wildly. Just like all the differing Commodore models of machines, there are many differing models of Apple II—all with their own idiosychrocies.

 

TEXT mode on the Apple II and Apple II plus only had 40 columns with 64 characters with with normal, inverse and flash modes, but no lower case. Lower case would appear as symbol characters and control characters, if you poked them onto the screen, would appear as alpha characters. 80 column cards came as add-in boards which all had their own pecularities.

The Apple IIe and later could display lower case on the TEXT screen, but introduced slight incompatabilities and bugs between models:Apple 80-column mode, MouseText, ...

 

Offline
Last seen: 2 months 2 weeks ago
Joined: Nov 12 2022 - 16:50
Posts: 202
Thank you.  :)  That's okay,

Thank you.  :)  That's okay, because I prefer 80 columns, as I get more characters on the screen.  :)

Offline
Last seen: 22 hours 1 min ago
Joined: Nov 29 2020 - 19:48
Posts: 135
Yep. OR $80...

Yep. OR $80...

Offline
Last seen: 7 months 2 weeks ago
Joined: Aug 15 2023 - 19:57
Posts: 9
clearing up confusion?

So, ORring a character with $80 just makes it appear as a normal ASCII character, all things being equal. The high bit is expected to be set for any normal printing of an Apple display character.

First off, you can get the exact same effect in 40-column mode that you're currently getting in 80-column mode. 80-column mode always forces "altchar" on; you can turn this on in 40-column mode by writing any value to the location $C00F. You will lose the ability to have flashing characters.

But that's not actually "kosher", and it probably doesn't work right with my recommendations below for the portable way to set inverse text. A more "correct" way to do it is to enable 80-column mode, then switch to 40-column mode (if desired) while leaving 80-column firmware active. You can do this by sending Control-Q ($91) through COUT after 80-column is activated. So that's what I recommend (or just leave it in 80-col mode since you're happy).

Writing to $C00F (the "set altcharset" soft-switch toggle) is enough to enable lower-case + upper-case inverted characters, but the trouble is that the right character values  to use after you've done that is not portable. Unenhanced Apple ][e needs different bytecodes than //c or enhanced //e. For this reason, attempting to manipulate the value of the accumulator directly before sending characters through COUT, is the wrong way to go if you want to produce inverted ext.

The portable way to go about it, is to send Control-O ($8F) through COUT (only works if 80-column firmware is active, via PR#3 (but again, you can be in 40-column mode by virtue of having sent Control-Q through, or from the user typing Esc 4)). Send Control-N ($8E) to go back to normal mode.

The correct way used to be to just directly invoke the firmware's "INVERSE" and "NORMAL" routines, which manipulated a flag that gets ANDed against every character before being emitted. This no longer works, because it's no longer as simple as ANDing to get the right character. Sending the appropriate control-characters is the easy and portable way, but it does require the 80-col firmware to be active. You can set the soft switch and then write more carefully-crafted characters through COUT, but as mentioned, "carefully-crafted" differs depending on your system, so you'd have to do additional detection to discover what system is in place.

When I say to use "PR#3" to activate 80-column firmware, obviously that's from a "user at the BASIC prompt" perspective. Your program can't do that. You need to tell the OS to do it for you, instead of issue raw commands or invoke the firmware's output-slotting routines, as otherwise the OS gets unhooked. The way I usually do it in DOS 3.3, is to JSR to $C300, which will set up the appropriate KSW and CSW values (but unhook the OS), and then tell the OS to "rehook" itself up by following up with JSR $3EA. In ProDOS, if I expect BASIC.SYSTEM is loaded, I'll save awaty the values currently at KSW and CSW (and the byte next to them of course, since they're words), run $C300, and then move the new CSW and KSW values to $BE30 and $BE32 (respectively), and restore the old ones for BASIC.SYSTEM. Or I'll send the "IN#A$C300" command via BASIC.SYSTEM's DOSCMD routine at $BE03, or arrange for it to be printed (with a Control-D prefix) from a start-up BASIC program.

If you're running ProDOS and BASIC.SYSTEM is not loaded, then you can just do the JSR to $C300 and not worry about the rest, as there is no system prompt interface to be "unhooked".

Offline
Last seen: 7 months 2 weeks ago
Joined: Aug 15 2023 - 19:57
Posts: 9
re-hooking the OS is maybe a bit silly

Hah, most of my work being integrated with BASIC has left me a bit silly. You don't have to worry about unhooking the OS as long as you're not going to be using any of the "send DOS commands through COUT, prefaced by Control-D", "DOS command" type of interfacing with the OS. You can just save away whatever CSW and KSW is, run $C300, and then restore CSW and KSW before program exit (if applicable.)

 

When I say to use "PR#3" to activate 80-column firmware, obviously that's from a "user at the BASIC prompt" perspective. Your program can't do that. You need to tell the OS to do it for you, instead of issue raw commands or invoke the firmware's output-slotting routines, as otherwise the OS gets unhooked. The way I usually do it in DOS 3.3, is to JSR to $C300, which will set up the appropriate KSW and CSW values (but unhook the OS), and then tell the OS to "rehook" itself up by following up with JSR $3EA. In ProDOS, if I expect BASIC.SYSTEM is loaded, I'll save awaty the values currently at KSW and CSW (and the byte next to them of course, since they're words), run $C300, and then move the new CSW and KSW values to $BE30 and $BE32 (respectively), and restore the old ones for BASIC.SYSTEM. Or I'll send the "IN#A$C300" command via BASIC.SYSTEM's DOSCMD routine at $BE03, or arrange for it to be printed (with a Control-D prefix) from a start-up BASIC program.

Offline
Last seen: 2 months 2 weeks ago
Joined: Nov 12 2022 - 16:50
Posts: 202
micahcowan, I thank you for

micahcowan, I thank you for all  your information.  I really want to create a text adventure code to work in 40-column mode on the Apple2+ or at least an unenhanced Apple2e with lower-case letters.  I don't need flashing.  Will writing to $C00F do this?  BTW, I don't actually need inverse on the low-end text adventure code.  I wanted this for my own text adventure, as, at the time, its text was formatted for 40 columns, but I find 80 columns to be better.   :)

Offline
Last seen: 5 hours 19 min ago
Joined: Jun 18 2010 - 13:54
Posts: 792
Harry Potter wrote:I really
Harry Potter wrote:

I really want to create a text adventure code to work in 40-column mode on the Apple2+ or at least an unenhanced Apple2e with lower-case letters.

 Getting lower case characters on the Apple II/II+ will require some additional hardware such as the Paymar LCA or a ROMX.

Offline
Last seen: 2 months 2 weeks ago
Joined: Nov 12 2022 - 16:50
Posts: 202
Oh.  Thank you.

Oh.  Thank you.

Log in or register to post comments