7

To switch from 80-column to 40-column display, what is the difference between the following two actions:

lda #$11
jsr COUT ; $FDED

and

sta $C00C ; 80coloff switch

In the first case, I do not encounter any problem in the rest of my program.

In the second case I notice significant display problems, in particular if the display was in 80 columns before, and if the COUT routine is used after.

  1. What is the explanation of these different behaviors?
  2. How to use properly 80coloff switch in assembly language ?
  3. What is the most reliable procedure to go from 80 to 40 columns (and vice versa) in assembly language ?

I use an Apple IIc and mainly ProDOS.

3 Answers 3

8

(It would be useful if you could describe what problems are encountered Without it's hard to give any help - beside citing the manual, and/or giving a friendly RTFM)

Usage works, as so often on two level, by using the 'OS' (well, firmware) or direct access.

Via OS

In general the 80 column firmware needs to be activated first

Keyboard

  • PR#3 to turn on the 80 column firmware
  • It will by default switch to 80 col mode.
  • ESC 4 to switch to 40 col
  • ESC 8 to switch to 80 col
  • PR#0 to turn off the 80 col firmware, or (*1)
  • ESC CTRL+Q to turn off 80 col firmware

BASIC

Essentially as above:

  • PRINT CHR$ (4);"PR#3" to turn on the 80 column firmware
  • It will by default switch to 80 col mode
  • PRINT CHR$ (17) to switch to 40 col
  • PRINT CHR$ (18) to switch to 80 col
  • PRINT CHR$ (4);"PR#0" to turn off the 80 col firmware, or (*1)
  • PRINT CHR$ (21) to turn off 80 col firmware

Assembler

Again, like above.

  • A PR#3 is done by loading 3 into A and calling OUTPORT at $FE95.
  • Control codes can be used as above, simply load them to A and call COUT at $FDED

Direct access

Simply flip 80COL the way you want it and write direct to the screen. Do not expect the firmware to help here. Do not call COUT or alike.


*1 - While this is the default way, 80 col is a bit different, as it can stay active while another slot is selected. Using a PR#0 might not always be a good idea, so the additional control codes were invented.

3
  • Very clear. The display problem is difficult to describe. Strange characters appear, the computer is blocked and must be restarted. This simple code kills: sta col80off ldx #$18 lda #$8D loop jsr cout dex bne loop Direct access is not a good idea I guess.
    – bruno185
    Apr 25, 2021 at 20:52
  • 1
    @bruno185 This sounds more like missing clearing etc. In addition, when doing direct access, using routines like COUT should not be used - direct access goes best with your own screen handking.
    – Raffzahn
    Apr 25, 2021 at 22:33
  • A difference between the //c and the //e is that, at least as I remember it, the default character output function of the //e was agnostic to the existence of 80-column hardware. If one switched hardware modes without doing anything with the 80-column firmware, half of the columns would show whatever was in aux ram, while the other half, interleaved with the first group, would show the "normal" text screen contents. On the //c, activating the 80-column hardware soft switch changes the text-output behavior so it tries to treat 80-column output sensibly.
    – supercat
    Apr 26, 2021 at 21:00
11

In the first case, I do not encounter any problem in the rest of my program.

That's because you are calling into ROM routines which set up everything for you.

In the second case I notice significant display problems, in particular if the display was in 80 columns before, and if the COUT routine is used after.

Well, you only switched the hardware. You didn't clear the screen, you didn't tell the COUT routine that it's now running in 80 column mode, etc.

What is the explanation of these different behaviors?

See above: you are executing a routine in ROM which does all the extra work for you, vs. you are switching the display mode without doing anything else.

How to use properly 80coloff switch in assembly language ?

"Properly" depends on the circumstances. If you use COUT, to do it "properly", you need to update the values in the zero-page COUT depends on. You also need to do housekeeping like clearing the screen. If you control the framebuffer directly, you don't have to do that.

What is the most reliable procedure to go from 80 to 40 columns (and vice versa) in assembly language ?

The most reliable is your variant one (as you've discovered yourself). Alternatively, call directly into the ROM routine that sets this up ($11 just is a special character which is detected and triggers a jump to this part). Alternatively, read the routine in the ROM disassembly, and do all the work yourself.

The first variant has the advantage that it doesn't depend on the ROM layout.

5

See the IIc Technical Reference Manual, pages 64-66.

$FDED jumps to the user output vector ($0036) which is generally COUT1 (the 40-column firmware) or C3COUT1 (after a PR#3/JSR $C300).

COUT1 is strictly 40-column and the only control codes it supports are LF, CR, BS, and BELL. C3COUT1 is (obviously) 80-column aware and supports 21 control codes, including ^Q and ^R to select 40 or 80 columns.

You can see exactly what those particular control codes do (starting on page 428) but aside from touching the softswitches, they also adjust existing text so it displays correctly in the new mode and adjusts zero-page variables pertaining to the window size and cursor position.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .