# Algorithm for Apple IIe and Apple IIgs boot/start beep

What is algorithms use for boot/start sound (when turn on computer) in Apple IIe and Apple IIgs? I can't find information about Apple boot sound algorithms or where in computer ROM store either algorithm.

• What makes you think there's an algorithm for it? On most systems, a startup sound is just some kind of beep. Nov 3, 2020 at 8:59
• Semi-related: folklore.org/… Nov 3, 2020 at 15:54

What is algorithms use for boot/start sound (when turn on computer)

Algorithm? Well, yes, technically everything is an algorithm. In this case it's simply executing the beep subroutine during reset, which in turn toggles the speaker line 192 times over 0.1s resulting in a sound of roughly 1 kHz, which should be is close to b′′.

Lets have a look into the manual:

(All excerpts taken from the 1979 Apple I Reference Manual A2L0001A (030-0004-01) -*1)

(The Reset Cycle, p.36)

In the end the function BELL1 is called.

(Some Useful Monitor Subroutines, p.62)

So if you're looking or the algorithm produceing the 0.1 second beep, here it is.

I can't find information about Apple boot sound algorithms or where in computer ROM store either algorithm.

It's all in the reference manual, described in great detail, ready to be followed.

For an example how to read see below.

## An Exercise in Code Reading

So as usual everything starts at Reset. With a 6502 that's a vector at \$FFFC/FD:

(Monitor ROM Listing, p.171)

On The Apple II Autostart ROM this points to a routine called ... well .. RESET at \$FF59:

(Monitor ROM Listing, p.169)

As shown, RESET calls the BELL function, described in the manual as:

(Some Useful Monitor Subroutines, p.62)

BELL is a rather 'short' piece of code, as it simply loads the ASCI BEL character (\$07, \$87 in Apple keyboard encoding) and calls the standard output routine COUT.

(Monitor ROM Listing, p.163)

COUT is described as:

(Some Useful Monitor Subroutines, p.61)

COUT itself doesn't do anything but handling the redirection to whatever standard output is set by issuing an indirect jump via CSW.

(Monitor ROM Listing, p.167)

The vector was previous (via SETVID, see above) set to COUT1, handling the build in screen:

(Some Useful Monitor Subroutines, p.61)

Note that it mentions handling the control character of 'bell'.

(Monitor ROM Listing, p.167)

COUT1 essentially it only changes the display of control characters and saves A and Y, while forwarding all work to VIDOUT at \$FBFD.

(Monitor ROM Listing, p.163)

VIDOUT is, as one expects, a rather lengty routine, but luckly all decisions essential to see what happens with the BEL char (\$87) are in the first few lines. All non control characters get outputted right away, followed by a check for CR, LF and BS. If neither of these are detected, it must be BEL (*2), so the handling is forwarded to BELL1

(Monitor ROM Listing, p.163)

BELL1 simply waits for ~10 milliseconds, producing that amount of silence, followed by flipping the speaker driver every ~0.5 milliseconds for roughly 100 milliseconds (192 turns), which, easy to see, makes a 0.1 second beep of ~1 kHz.

That's it. Everything is described in great detail. No big or small secrets or 'algorithm' beside counting the right number of cycles before fliping the speaker.

So for completeness, here's how the manual describes WAIT:

(Some Useful Monitor Subroutines, p.63)

While the formula sounds complicated at first, it simply adds up the cycles wasted ... err ... waited within the function as seen clear when looking at the code (*2):

(Monitor ROM Listing, p.165)

*1 - The manual describes the Apple II+. Used because the original version most easy reveals all working - also it's a nice course in how to read. Low level speaker handling is the same for all models, while over all operations are the same for the IIe and similar for the IIc and IIgs.

*2 - Well, when looking really close, one might find some discrepancies, as fadden did with his inspection.

• Fun fact: the explanation of WAIT's duration is completely wrong in the listing, and slightly wrong in the various printed references. See 6502disassembly.com/a2-rom/#wait Nov 3, 2020 at 15:50
• @fadden You're right. AFAIR it's basically the use of a wrong unit, µs instead of MHz plus a little rounding. Essentially it ends up in the same area. Anyone needing really exact timing will do his own routine anyway. Nov 3, 2020 at 16:03

The Apple IIgs uses a different routine and has a completely different sound. The monitor entry point is the same as in the Apple //e, though the monitor is a bit tricky to trace because it jumps around a lot (it's trying to preserve the old entry points).

To see the code from the Apple IIgs monitor, you need to be in bank \$FF.

As in the earlier Apple IIs, at \$FBD9 you can see it check for \$87, and if it matches it loads Y-reg with \$9E and jumps to \$F89C, which switches to native mode and sets the speed register, then calls \$9F88. The Y-reg contents are negative so it branches to \$9FC5.

At \$9FC5 it doubles the Y-reg value (x2=\$3C, regs are still 8-bit) and uses it as an index into a jump table at \$A011/A012. \$A04D/A04E holds \$A05C, which gets pushed, so RTS takes us to \$A05D.

That calls through a vector at \$E1/006C, which jumps to \$FF/B5DE. Which just sets the carry and returns, causing the following BCS \$A064 to be taken.

\$A064 is where the actual sound code happens; it's a little difficult to trace in the monitor because the register width changes. It calls \$F882 to set the data bank register (B) to \$E1 so it can have some storage for counters. You can see it hitting the \$C030 speaker location at \$A0AF.

Here's a quick dump of the core part of the routine:

``````CYAREG          .eq   \$c036           ;RW Configure Your Apple
SPKR_GS         .eq   \$e1c030         ;RW toggle speaker
CYAREG_GS       .eq   \$e1c036         ;RW Configure Your Apple
SOUNDCTL_GS     .eq   \$e1c03c         ;RW sound settings (0-3=volume)

.org  \$ffa064
.rwid shortm,shortx
.dbank \$00
php
sei
lda   #\$b0
jsr   \$fca8
lda   CYAREG
pha
and   #\$7f
sta   CYAREG
phx
phb
jsr   \$f882
.dbank \$e1
lda   \$02df
eor   #\$0f
sta   \$016d
stz   \$016e
rep   #\$20
.rwid longm
lda   #\$8888
sta   \$0169
lda   #\$2000
sta   \$016b
sep   #\$30
.rwid shortm
lda:  \$00ca
sta   \$016f
pha
clc
rep   #\$30
.rwid longm,longx
ldy   \$016d
ldx   #\$0250
LFFA0A4         dey
bne   LFFA0B2
ldy   \$016d
rol   \$0169
bcc   LFFA0B2
lda   SPKR_GS
LFFA0B2         dex
bne   LFFA0CD
ldx   #\$0250
sep   #\$20
.rwid shortm
lda   \$016f
beq   LFFA0D8
dec   A
sta   \$016f
sta:  \$00ca
sta   SOUNDCTL_GS
rep   #\$20
.rwid longm
bra   LFFA0D3

LFFA0CD         lda   #\$0005
LFFA0D0         dec   A
bne   LFFA0D0
LFFA0D3         dec   \$016b
bne   LFFA0A4
.rwid shortm
LFFA0D8         sep   #\$30
.rwid shortx
pla
sta:  \$00ca
sta   SOUNDCTL_GS
plb
plx
ldy   #\$00
pla
sta   CYAREG_GS
plp
rts
``````
• Diverging rapidly from the topic into my own world of questions, is there an online disassembly of more of the IIgs ROM? Nov 3, 2020 at 16:51
• If you look hard enough, you can find a leaked copy of the system 6 source code which includes the IIgs firmware source (originally written in EdAsm then auto converted to MPW Asm IIgs) Nov 5, 2020 at 1:08

Look on Page 11, Adresses FBD9 to FBEF,