lmkbd2
lmkbd2 copied to clipboard
beeper sound of the space cadet and knight keyboards
We do not have a recording of what the beeper on the Lisp Machines sounded like via %BEEP. @MMcM Do you think it would be possible to record it?
%BEEP
itself takes (half-)wavelength and duration arguments, so it can have a variety of simple tones. From the microcode (XBEEP
in LCADR;UCADR >
), it just reads Unibus 764110, which toggles the state.
TV:BEEP
used
(DEFVAR TV-BEEP-DURATION 400000)
(DEFVAR TV-BEEP-WAVELENGTH 1350)
Which I think works out to a 370Hz square wave for .4s.
Thank you. We would like to be able to reproduce the original sound to the extent possible, including artifacts introduced by hardware imperfections. If you at some point would have the opportunity to record the actual sound from the keyboard(s?), we would be very grateful.
I'm not sure about Knight keyboards? Some photos seem to indicate there was a speaker, some don't.
I don't have access to a Lisp Machine to drive it.
However, it does occur to me that it should be reasonably easy to reproduce the tail-end of the hardware chain to get more authentic waveforms from '70s TTL.
The Unibus decoder (74LS138 C22:11 in CADRIO;IOBCLK) triggers a flip-flop (74LS74 H13 in CADRIO;IOBCSR) which drives a NAND buffer (7437 C25 same drawing).
So, like wire up the flip-flop to an Arduino and the driver to the 8 Ohm(?) speaker. And run it at the chosen microsecond periods.
Looks like I don't have those chips lying around in parts drawers. While I see that Digi-Key is still operating as an essential service, I'm not sure how I feel about taking advantage of that. So maybe in a while.
I'll also try to take some photos of the inside of the TK keyboard.
Thank you @MMcM !
How did you come to 370 Hz? Neither feet nor meters make sense -- I'm sure I'm just missing the right unit in the right spot. I tripped .. 1350 is octal for 744. Now it all makes sense.
I'll see about adding some code to usim so that it can beep accordingly.
Oh, you're right. It is octal. I forgot to check.
It's the number of microseconds between triggers of the flip-flop. That is, half the wavelength. So the frequency is, I think, (/ 1e6 (* #o1350 2))
. So I guess 672Hz. And duration is only .13sec.
Here is the code, in case anyone wants to try to work out any additional timing details beyond the system clock.
;;; Sophisticated audio home entertainment center.
XBEEP (MISC-INST-ENTRY %BEEP)
;;; First argument is half-wavelength, second is duration. Both are in microseconds.
;;; M-1 contains most recent time check
;;; M-2 has 2nd argument (duration) which is added to initial time-check
;;; to compute quitting time
;;; M-C contains 1st argument, the wavelength
;;; M-4 contains the time at which the next click must be done.
;;; Note that the 32-bit clock wraps around once an hour, we have to be careful
;;; to compare clock values in the correct way, namely without overflow checking.
((VMA-START-READ) (A-CONSTANT 77772050)) ;Unibus 764120
(CHECK-PAGE-READ)
((M-1) READ-MEMORY-DATA)
((VMA-START-READ) (A-CONSTANT 77772051)) ;Unibus 764122
(CHECK-PAGE-READ)
((M-1) DPB READ-MEMORY-DATA (BYTE-FIELD 20 20) A-1)
((M-2) Q-POINTER C-PDL-BUFFER-POINTER-POP)
((M-2) M-2 ADD A-1)
((M-C) Q-POINTER C-PDL-BUFFER-POINTER-POP)
((M-4) M-1)
BEEP-NEXT-CLICK
((M-4) M-4 ADD A-C)
BEEP-WAIT
((VMA-START-READ) (A-CONSTANT 77772050))
(CHECK-PAGE-READ)
((M-1) READ-MEMORY-DATA)
((VMA-START-READ) (A-CONSTANT 77772051))
(CHECK-PAGE-READ)
((M-1) DPB READ-MEMORY-DATA (BYTE-FIELD 20 20) A-1)
((M-TEM) SUB M-1 A-2)
(JUMP-GREATER-OR-EQUAL M-TEM A-ZERO XFALSE)
((M-TEM) SUB M-1 A-4)
(JUMP-LESS-OR-EQUAL M-TEM A-ZERO BEEP-WAIT)
((VMA-START-WRITE) (A-CONSTANT 77772044)) ;Unibus 764110
(CHECK-PAGE-WRITE)
(JUMP BEEP-NEXT-CLICK)
That is the old version (UCADR LISP 694-ish), the newer microcode for XBEEP (UCADR LISP 841 through on to Lambda) looks like this:
;;; Sophisticated audio home entertainment center.
XBEEP (MISC-INST-ENTRY %BEEP)
;;; First argument is half-wavelength, second is duration. Both are in microseconds.
;;; M-1 has 2nd argument (duration) which is added to initial time-check
;;; M-2 contains most recent time check
;;; to compute quitting time
;;; M-C contains 1st argument, the wavelength
;;; M-4 contains the time at which the next click must be done.
;;; Note that the 32-bit clock wraps around once an hour, we have to be careful
;;; to compare clock values in the correct way, namely without overflow checking.
(CALL-XCT-NEXT READ-MICROSECOND-CLOCK)
((M-1) Q-POINTER C-PDL-BUFFER-POINTER-POP)
((M-1) M-1 ADD A-2)
((M-C) Q-POINTER C-PDL-BUFFER-POINTER-POP)
((M-4) M-2)
BEEP-NEXT-CLICK
((M-4) M-4 ADD A-C)
BEEP-WAIT
(CALL READ-MICROSECOND-CLOCK)
((M-TEM) SUB M-2 A-1)
(JUMP-GREATER-OR-EQUAL M-TEM A-ZERO XFALSE)
((M-TEM) SUB M-2 A-4)
(JUMP-LESS-OR-EQUAL M-TEM A-ZERO BEEP-WAIT)
((VMA-START-WRITE) (A-CONSTANT 77772044)) ;Unibus 764110
(CHECK-PAGE-WRITE)
(JUMP BEEP-NEXT-CLICK)
Admitably, they end up doing the exact same thing -- only that READ-MICROSECOND-CLOCK is introduced and hides some of the noise.