Q:

How is the Apple II text flash mode timed?

On the Apple II, there are three 40 column text modes: normal (white on black), inverse (black on white) and flash. A text screen can contain a mix of text in all three of these modes.
Flash mode is roughly a 0.5s delay between cycling text between a normal and inverse mode. However, unlike the console cursor, the rate of the flash does not appear to be influenced by the speed of the CPU - my personal experience is with a RocketChip 5MHz and while the cursor flash is proportionate to the CPU speed, flashing 40-column text remains the same.
Speaking of the cursor, on the II and II+ machines it is a flashing white block - if you backspace over a character, it appears to go between inverse and normal in this 0.5s cadence. On later machines, it was replaced by a matrix of dots. So the question is not only how is flashing text implemented on the II, but perhaps an extension would be is why is the cursor affected but not the flashing characters of the text display? Is flashing text CPU-timed or something else?

A:

How is the Apple II text flash mode timed?

It's a fixed timing signal generated by an NE555 timer (at position B3 on the original II+).

(From the Apple II Reference Manual / Red Book p.151)
Entering the values of C/R1/R2 into an online calculator for NE555s will give about 2.1 seconds cycle time (*1)
The II's video logic used bit 2^6 and 2^7 to control the level in text mode.
7  6
0  0  - Inverted
0  1  - Inverted depending on the timer
1  0  - Not inverted

This is as well visible in the (screen) character set:

This as well shows that the Apple II character generator only holds 64 different glyphs - using above logic to produce them in Normal/Inverted/Flash.
There is no hardware cursor. It's essentially done by setting the two top bits of the character were the cursor should be shown to 01 (*2).

For the second part:

an extension would be why is the cursor is affected but not the text display?

I'm not entirely clear what you describe/ask.

*1 - These are analogue parts with up to 10% or more variation.
*2 - this is also, why pressing Reset may result having the 'old' cursor still blinking while a new one is displayed.

A:

Regarding the cursor, the character under the cursor is replaced with flashing text by RDKEY:
fd0c: a4 24        RDKEY       ldy     CH
fd0e: b1 28                    lda     (BASL),y        ;set screen to flash
fd10: 48                       pha
fd11: 29 3f                    and     #$3f
fd13: 09 40                    ora     #$40
fd15: 91 28                    sta     (BASL),y
fd17: 68                       pla
fd18: 6c 38 00                 jmp     (KSWL)          ;go to user key-in

Note the character from the screen is still in the accumulator.  The default KSWL function is KEYIN at $fd1b.  After you hit a key, KEYIN writes the new character, or in the case of ESC key movement the previous character, onto the screen before continuing:
fd1b: e6 4e        KEYIN       inc     RNDL
fd1d: d0 02                    bne     KEYIN2          ;incr rnd number
fd1f: e6 4f                    inc     RNDH
fd21: 2c 00 c0     KEYIN2      bit     IOADR           ;key down?
fd24: 10 f5                    bpl     KEYIN           ;  loop
fd26: 91 28                    sta     (BASL),y        ;replace flashing screen

Replacing the flashing (or, for 80-column mode, inverse) text with an alternating checkerboard, as is done on the Apple //e, requires a bit more work in the ROM; KEYIN jumps to code in the 80-column firwmware.  The logic is the same though -- replace the on-screen char with something else -- it's just done repeatedly.  (The hardware handles flashing text, but does not handle replacement with a checkerboard.  If you hit the reset key at the right time, you'll see a checkerboard character left behind.)

