The Hobbit makes no sound. A 48K Spectrum has one bit of sound hardware, bit 4 of port $FE, and nothing in the game ever sets it: there is no beeper routine, no tune and no click. The pictures draw, the characters come and go and the fights are fought in silence. The only noise the machine makes while the game runs is SAVE's tape signal, and that is the ROM's.

What the game writes to port $FE

The listing has 10 OUT instructions. 6 write to port $FE, and each writes a border colour -- bits 0-2 -- with the MIC bit (3) and the speaker bit (4) clear:

OUTWritesWhat forSeen in the run
$6C66 in START$00Black, before the title screen waits for a key (every new game).1 × $00
$6FD8 in CLEAR_SCREEN$07White, as CLEAR_SCREEN wipes the screen to black on white.1 × $07
$821B in CLEAR_CANVASthe picture's first byte, or $00The picture's border colour, the first byte of its stream; 0 (black) when TOO_DARK says the player cannot see.7 × $07
$843C in DO_PAUSE$04Green, for PAUSE.1 × $04
$844C in DO_PAUSE$07White again, once PAUSE has had its key.1 × $07
$96A5 in WAIT_FOR_ANY_KEY$07White, after the key that follows every picture.7 × $07

The picture border bytes, read from the 22 streams in PICTURE_TABLE, are black (0), blue (1), red (2), green (4), cyan (5), yellow (6), white (7); TROLLS_TURN_TO_STONE writes 5 (cyan) over the trolls' clearing's when day dawns. None has bit 3 or 4 set, so no picture moves the speaker or the MIC line either.

The other 4 OUTs, $8B31, $8B54, $8B66 and $8B72 in LINE_TO_PRINTER, are to port $FB, the ZX Printer, which PRINT drives a pixel at a time. Bit 0 of that port number is set, and the ULA only answers even ports, so they do nothing to the speaker; the whirr of a real printer is the printer's own.

No key click either. The 48K ROM's click is made by its line editor (ED-LOOP), which calls BEEPER for every key; the game never goes near it. It reads the keyboard itself (SCAN_KEYBOARD and the waits that poll port $FE directly), with interrupts off -- START begins with DI -- and its only calls into the ROM are $04C2 and $0556 -- SA-BYTES and LD-BYTES, for SAVE, its verify and LOAD: $8498 in LOAD_BLOCK; $84EF, $84FB, $8507 and $8513 in DO_SAVE; $855A in VERIFY_BLOCK.

Checked by running it

The game run in SkoolKit's simulator from START: the title, the opening, the 32 commands of the build's walkthrough, then PAUSE and SAVE with its verify -- 9 minutes of emulated time, with every port write logged and every address run recorded. It wrote port $FE 124,413 times: 18 from the six OUTs above, with the values in the table, and 124,395 from the ROM. The speaker bit changed not once. The ZX Printer's port was never written (the walkthrough never turns PRINT on). The ROM wrote $01, $02, $07, $09, $0A, $0D, $0E, $0F, all during SAVE and its verify, every value with bit 4 clear. The ROM code that ran was the tape routines, $04C2-$0604, and $0038-$0052, $028E-$029B, $02AB-$02B2, $02BF-$02C8, $02D1-$02DB, $031E-$0324 -- the ROM's interrupt routine and the keyboard scan it calls. SA-BYTES ends, as every ROM tape routine does, with EI, and DO_SAVE does not DI again until TAPE_DONE, so interrupts are on from the end of the fourth block, through the "REWIND" prompt and its key, until the verify's LD-BYTES turns them off; the ROM's keyboard scan runs fifty times a second there. It only reads the keyboard; the click is the editor's. BEEPER ($03B5) never ran.

The one noise: SAVE

SAVE (DO_SAVE) writes four headerless blocks -- the variables, the objects, the timers and characters, the rooms -- through the ROM's SA-BYTES ($04C2) and then reads them back through LD-BYTES ($0556) in verify mode. SA-BYTES makes the tape signal by flipping bit 3 of port $FE, the MIC socket, with the border going red and cyan for the leader and blue and yellow for the data. It never touches bit 4, so this is the signal on the lead to the tape recorder, not the speaker; a real 48K plays it quietly through its speaker as well, because the MIC and speaker lines share a pin of the ULA (that is the hardware, not measured here). LOAD and the verify only read: LD-BYTES writes port $FE to flash the border with bit 3 set and bit 4 clear, so what is heard while loading is the tape itself.

The recording is SAVE's first block, the 29 bytes at $B6EB, from the first OUT of SA-BYTES to its return: the leader, the two sync pulses, the flag byte, the block and the parity byte. The other three blocks follow at once and sound the same, only longer (10.1 s, 3.0 s, 9.7 s).

SAVE's first block

Recorded: the walkthrough's game in the simulator, SAVE typed at the prompt and a key pressed for its "start TAPE" message; the T-state of every change of bit 3 of port $FE logged, and rendered as 16-bit mono at 44100 Hz. Nothing is synthesised.

2.14 s, 3,722 edges; the leader 807 Hz, the data 1023 Hz for a 1 and 2047 Hz for a 0, as measured.

Checked against the ROM's loops and the timings the TZX tape format documents for them. The leader loop (a DJNZ from $A4, 163 turns of 13 T-states and a last of 8, and 41 more around it: 2,168) made 3,224 OUTs, so 3,223 pulses, every one 2,168 T-states (documented: 3,223 of 2,168 for a data block). The first is at the level the line was already at, so the recording hears one fewer. The sync pulses were 667 and 735 T-states (documented 667 and 735). Then 248 bits, 496 half-waves, every one exactly 855 or 1,710 T-states except the first of each byte, which is out by a few while the ROM fetches the byte: +1 for the flag byte, -3 for each of the 29 bytes of the block, and -1 for the parity byte; then SA/LD-RET wrote $07 (the white border BORDCR holds, and the line low) 945 T-states on. Read back as LD-BYTES reads it, the signal carries the flag byte $FF, the 29 bytes that were at $B6EB when SAVE ran, and a parity byte $D1, the exclusive-or of all the others.

And the whole save, all four blocks (65,416 edges), played back into the EAR bit of port $FE half a second after the key for the verify: the ROM's own LD-BYTES accepted all four blocks and the game carried on, with no "TAPE ERROR".