Path: utzoo!attcan!uunet!mcvax!enea!kth!draken!tut!santra!kampi!jmunkki
From: jmunkki@kampi.hut.fi (Juri Munkki)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Reading data directly from MacRecorder
Message-ID: <17699@santra.UUCP>
Date: 29 Nov 88 12:49:00 GMT
References: <145@bnr-di.UUCP> <3fccf691.12e8e@scottie.engin.umich.edu> <5411@mva.cs.liv.ac.uk> <3fe2023d.1285f@maize.engin.umich.edu>
Sender: news@santra.UUCP
Reply-To: jmunkki@kampi.UUCP (Juri Munkki)
Organization: Helsinki University of Technology, Finland
Lines: 330

In <3fe2023d.1285f@maize.engin.umich.edu> mystone@caen.engin.umich.edu Dean Yu:
>In article <5411@mva.cs.liv.ac.uk>, phil@mva.cs.liv.ac.uk writes:
>>In <6522@csli.STANFORD.EDU>, johnson@csli.STANFORD.EDU (Mark Johnson) writes:
>>> Does anyone know how to read data directly from the MacRecorder into
>>> a program?  LSC sources would be great!
>> I second that request - but my language of preference is Pascal.  One of
...
>>sound right with a visual comparison).  Anyway, I have MacRecorder, so all I
>>need now are primitives to get some sound data from it. Any help would be much
>>appreciated! 
>  Me three!  Me three!  (Can anyone from Farallon see this?)

I'm sorry to disappoint you guys, but all I have is MDS assembler source for
a program that reads from the MacNifty sound digitizer...

MacRecorder is somewhat more advanced that MacNifty/Impulse, but it is
compatible. You should be able to use this program for your purposes.

I don't think that it is possible/easy to use a high level language to
read the digitizer. Could one of you write a decent package to use the
digitizer. A code resource with an interface similar to a PACK would be
great. You could then use it with any language. I don't have the time to
do something like that right now. Please keep the code compatible with
all the different flavors of digitizers...

I hope the code works. I don't know where I got it, I have never tried to
compile it and I have planned to use it to write a similar, but more
advanced program in LS-C inline asm.

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

Since I couldn't find a copyright notice, source code follows:

; mod 12 30 85 tsh - fix for new digitizer
; written 5 27 85 Tom Hedges, Fractal Software

;	Example Oscilloscope Program

	XDEF	Start
	
; Bring in all the dirty constants
	INCLUDE	SysEquX.D

; Dirty System Constants
myRow	EQU	45			;row we start on screen
MotorOff EQU	$0DFF1FF		;Motor Off Control Base
trigC	EQU	350			;trigger count max


; Data
transTab DS.B	256			;translate table
oldVal	DS.W	512			;old screen bit


;Initialize All Managers
Start:	PEA	-4(A5)
	DC.W	$A86E	;_InitGraf
	DC.W	$A8FE	;_InitFonts
	DC.W	$A912	;_InitWindows
	DC.W	$A930	;_InitMenus
	CLR.L	-(SP)
	DC.W	$A97B	;_InitDialogs

; Setup Translate Table with bit-reversed indices
	LEA	transTab(A5),A0		;address translate table
	MOVEQ	#0,D4			;index
	MOVE.W	#255,D3			;outer loop count (256 entries)
sutrlp:	MOVEQ	#7,D2			;inner loop counter (8 bits in byte)
	MOVE.W	D4,D0			;get copy of index
brlp:	LSL.W	#1,D1			;shift index left one
	BTST.L	#0,D0			;test low bit of index
	BEQ.S	bitns			;not set
	ADDQ.W	#1,D1			;put bit into result
bitns:	LSR.W	#1,D0			;shift index right one
	DBF	D2,brlp
	MOVE.B	D1,(A0)+		;store new index
	ADDQ.W	#1,D4			;bump index
	DBF	D3,sutrlp

; Init oldVal Array to Zeroes
	LEA	oldVal(A5),A0
	MOVE.W	#511,D0
initOV	CLR.W	(A0)+
	DBF	D0,initOV

; Setup Scc
	MOVEM.L	SccRd,A0-A1		;get the base addresses for Scc
	MOVEQ	#2,D0			;fudge for Port A
	ADDA.W	D0,A0			;Scc Read Addr
	ADDA.W	D0,A1			;Scc Write Addr
; disable interrupts
	MOVE	SR,-(SP)		;setup for RTE
	ORI	#$300,SR		;Disable Interrupts
; WR 9
	MOVE.B	(A0),D0			;assure WR0 next
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#9,(A1)			;WR 9
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$02,(A1)		;NV only
; WR 4
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#4,(A1)			;WR 4
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$0C,(A1)		;2 stop bits, Asynch Mode
; WR 1
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#1,(A1)			;WR 1
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$01,(A1)		;No Rx/Tx Int, Ext Int ON (Mouse)
; WR 3
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#3,(A1)			;WR 3
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$C1,(A1)		;8 bits per Byte, Rx Enable
; WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#5,(A1)			;WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$7A,(A1)		;8 bits/char, send break, Tx enable
; WR 11
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#11,(A1)		;WR 11
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$30,(A1)		;TRxC-Bar is Rcv Clock (External)
					;BR Generator is Xmt Clock
; WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#14,(A1)		;WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$01,(A1)		;BR Enable, no weird modes
; WR 15
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#15,(A1)		;WR 15
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$08,(A1)		;Interrupt on CD Changes (Mouse)
; WR 0
	MOVE.L	(SP),(SP)
	MOVE.B	#$40,(A1)		;Reset Rx CRC to WR 0
	MOVE.L	(SP),(SP)
	MOVE.B	#$40,(A1)		;Reset Rx CRC to WR 0
; WR 9
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#9,(A1)			;WR 9
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$0A,(A1)		;MIE and NV

; turn off the motor
	LEA	MotorOff,A2		;address the motor off base
	TST.B	(A2)			;do a fetch

; init the sound output buffer to FF's for smallest clip
	MOVE.L	SoundBase,A2		;init the sound buffer addr
	MOVE.W	#SndBufWLen-1,D2	;size of sound buffer
@1	MOVE.B	#$FF,(A2)		;set to 255
	ADDQ.L	#2,A2			;skip two bytes
	DBF	D2,@1

; wait for clock from box to start
	MOVE.B	(A0),D0			;assure WR 0 next
	MOVEQ	#10,D1			;flush first 10 samples
	MOVE.L	(SP),(SP)		;(delay)
; loop until at least one character is there
@2	BTST.B	#0,(A0)			;test RR 0 for data available
	BEQ.S	@2			;inner loop until a char is there
	MOVE.B	4(A0),D0		;receive the character
	MOVEM.L	D0-D7,-(SP)		;kill time
	MOVEM.L	(SP)+,D0-D7
	DBF	D1,@2			;outer loop on characters read
	
; set Screen to Black
	MOVEA.L	ScrnBase,A2		; SCREEN ADDRESS
	MOVE.W	ScreenRow,D0		;get byte width of screen
	LSR.W	#2,D0			;divided by 4
	MULU	#MaxY,D0
	SUBQ.W	#1,D0			;loop count
@3	MOVE.L	#$FFFFFFFF,(A2)+	;set to ones 4 bytes
	DBF	D0,@3

; compute the place on screen to draw
	MOVE.W	#myRow,D0		; LOAD TOP SCAN OF SCOPE
	MULU	ScreenRow,D0		; times row length (clean)
	MOVEA.L	ScrnBase,A3		; SCREEN ADDRESS
	ADDA.W	D0,A3			; ADD ON OFFSET OF SCAN...

; now draw white lines above and below 'scope region
	MOVEA.L	A3,A2
	SUBA.W	ScreenRow,A2
	MOVE.W	ScreenRow,D0
	LSR.W	#2,D0
	SUBQ.W	#1,D0			;loop count
@4	CLR.L	(A2)+
	DBF	D0,@4
	MOVE.W	#257,D0
	MULU	ScreenRow,D0		; times row length (clean)
	MOVEA.L	A3,A2
	ADDA.W	D0,A2	
	MOVE.W	ScreenRow,D0
	LSR.W	#2,D0
	SUBQ.W	#1,D0			;loop count
@5	CLR.L	(A2)+
	DBF	D0,@5
	
; turn on the sound
	MOVE.L	VIA,A2			;get VIA device address
	BCLR	#VSndEnb,(A2)		;clear the sound disable bit

; receive characters and stuff them into the sound buffer
	MOVE.W	#-trigC,D3		;trigger count
	MOVEQ	#(512/8)-1,D6		;buffer byte count - 1
	MOVEQ	#7,D7			;complement bit
	LEA	transTab(A5),A4		;load translate table
	LEA	oldVal(A5),A6		;get start of old array

; 'outer' loop resets the sound buffer
riloop:	MOVE.L	SoundBase,A2		;init the sound buffer addr
	MOVE.W	#sndBufWLen-1,D4	;words in sound buffer - 1 for DBF

; D3 = 0: if scoping, <0: if waiting for TB clr, >0: if waiting for TB set
; D4 = sound buffer down ctr,
; D6 = buffer byte count - 1, D7 = bit in byte (complement)
; A0 = constant Scc Read Addr, A1 = constant Scc Write Addr,
; A2 = ptr into sound buffer, A3 = video byte ptr,
; A4 = constant transTab ptr, A5 = data region ptr,
; A6 = current ptr to oldVal array
loop:	MOVEQ	#25,D0			;clock off timeout
wcloop:	BTST.B	#0,(A0)			;test RR 0 for data available
	BNE.S	gotdata			;data is there!
; no data yet, count down and loop
	DBF	D0,wcloop
; time out: the box must have been turned off
	BRA.S	doneOsc			;exit

; we have a character!!!!!
; assume top byte of D0.W is zeroes!!!!
gotdata	MOVE.B	4(A0),D0		;receive the character
	MOVE.B	0(A4,D0.W),D0		;get translated value
	MOVE.B	D0,(A2)			;put translated byte to sound buf
	ADDQ.L	#2,A2			;bump sound buffer ptr
	TST.W	D3			;test 'scope mode
	BEQ.S	@1			;normal mode

; waiting to trigger 'scope
	BPL.S	@2			;branch if waiting for < 0
; <0: waiting for top bit clear
	TST.B	D0			;test top bit
	BPL.S	@3			;branch if clear
	ADDQ.W	#1,D3			;count down
	BRA.S	doloop
@3	MOVE.W	#trigC,D3		;wait for top bit set
	BRA.S	doloop
; >0: waiting for top bit set
@2	TST.B	D0			;test sign of D0
	BMI.S	@4			;branch if set
	SUBQ.W	#1,D3			;count up
	BRA.S	doloop
@4	MOVEQ	#0,D3			;we've triggered

; output oscilloscope-like display to screen
@1	LSL.W	#6,D0			;shift into vertical byte offset
	MOVE.W	(A6),D1			;get old value
	MOVE.W	D0,(A6)+		;and replace with new one
	BSET	D7,0(A3,D1.W)		;clear the old bit
	BCLR	D7,0(A3,D0.W)		;set the current bit
	SUBQ.W	#1,D7			;decrement bit, N set if -1
	BPL.S	doloop			;no, loop quick

	MOVEQ	#7,D7			;set bit to 7
	ADDQ.L	#1,A3			;bump to next horizontal byte
	DBF	D6,doloop

; test for aborted by mouse button down
	MOVE.L	VIA,A3			;get VIA device address
	BTST	#vSW,(A3)
	BNE.S	@9			; no, reset video buffer and loop
; Aborted::: wait for mouse to rise upon the abort
@8	BTST	#vSW,(A3)
	BEQ.S	@8			; loop until mouse is up
	BRA.S	doneOsc

; reset video buffer
@9	MOVE.W	#-trigC,D3		;reset trigger count
	MOVEQ	#(512/8)-1,D6		;buffer byte count - 1
; compute the place on screen to draw
	MOVE.W	#myRow,D0		; LOAD TOP SCAN OF SCOPE
	MULU	ScreenRow,D0		; times row length (clean)
	MOVEA.L	ScrnBase,A3		; SCREEN ADDRESS
	ADDA.W	D0,A3			; ADD ON OFFSET OF SCAN...
	LEA	oldVal(A5),A6		;get start of old array


doloop:	DBF	D4,loop			;count and test for Sound Buf empty
	BRA	riloop			;Reset Sound Buffer and Loop

; done - clean things up
; turn internal clock on, enable BR generator, 
doneOsc: MOVE.B	(A0),D0			;assure WR0 next
; WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#5,(A1)			;WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$6A,(A1)		;8 bits/char, Tx enable
; WR 11	
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#11,(A1)		;WR 11
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$50,(A1)		;baudrate generator clocking
; WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#14,(A1)		;WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$01,(A1)		;BR Enable, no weird modes

; turn off the sound
	MOVE.L	VIA,A2			;get VIA device address
	BSET	#VSndEnb,(A2)		;set the sound disable bit

; allow interrupts
	ANDI	#$CFF,SR

; return to shell
	DC.W	$A9F4	;_ExitToShell
	
	END
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~