• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

How does the upscaling work for the Apple TV Tuner Card?

joevt

Well-known member
"Power Mac 8500/8500 has a few options for video input", was this configurable in the Apple Video Player?
I don't remember. I made my own classic Mac OS driver by reverse engineering the original driver and then ported it to Mac OS X. The source code shows that the fields that get digitized is selectable but I don't know if there was a UI to select them.

vdUseAnyField can give up to 60 fps max. The rest are 30 fps max.
vdUseBothFieldsInterlaced is required if you want to do more than half height resolution.

C:
static void SetSAA7196FieldFormatAndSize( UInt32 fieldMode, Point dimensions, vdigSettingsPtr settings )
{
	DOLOG2( "[] SetSAA7196FieldFormatAndSize fieldMode:%ld h:%ld w:%ld\n", fieldMode,
			(long)dimensions.v, (long)dimensions.h );
	
	switch ( fieldMode )
	{
		case vdUseAnyField: // both non-interlaced
			WriteOneSAA7196RegisterBits( kFormatsAndSequence_outputFieldMode,
										kOutputFieldMode_bothNonInterlaced, kSAA7196Reg_FormatsAndSequence, settings );
			break;
		case vdUseOddField:
			WriteOneSAA7196RegisterBits( kFormatsAndSequence_outputFieldMode,
										kOutputFieldMode_oddFieldOnly, kSAA7196Reg_FormatsAndSequence, settings );
			break;
		case vdUseEvenField:
			WriteOneSAA7196RegisterBits( kFormatsAndSequence_outputFieldMode,
										kOutputFieldMode_evenFieldOnly, kSAA7196Reg_FormatsAndSequence, settings );
			break;
		case vdUseBothFieldsInterlaced:
		default:
			dimensions.v >>= 1;
			WriteOneSAA7196RegisterBits( kFormatsAndSequence_outputFieldMode,
										kOutputFieldMode_bothInterlaced, kSAA7196Reg_FormatsAndSequence, settings );
	} // switch
	
	WriteOneSAA7196Register( dimensions.v, kSAA7196Reg_OutputDataLinesPerFieldLo, settings );
	WriteOneSAA7196RegisterBits( kVerticalYProcessing_outputDataLinesPerFieldHi,
										dimensions.v >> 8, kSAA7196Reg_VerticalYProcessingAndAFS, settings );

	WriteOneSAA7196Register( dimensions.h, kSAA7196Reg_OutputDataPixelsPerLineLo, settings );
	WriteOneSAA7196RegisterBits( kHorizontalFilter_OutputDataPixelsPerLineHi,
										dimensions.h >> 8, kSAA7196Reg_HorizontalFilter, settings );
}

PlanbDBDMADescriptorTablePtr InitPlanbDBDMADescriptorTable(
								InterruptStuff**				whereToStoreKernelPtrToInterruptStuffPhysical,
								InterruptStuff*					interruptStuffKernel,
								long							locationHeight,
								UInt16							locationWidthBytes,
								UInt16							rowBytes,
								OSType							pixelFormat,
								MemoryDescriptor*				baseAddrMemDesc,
								UInt32*							dmaRunningPtr,
								PlanbRec*						planbAddr,
								PlanbRec*						planbAddrPhysical,
								long							fieldFlag,
								PlanbDBDMADescriptorTablePtr	dbdmaInfo )

...

		switch ( fieldFlag )
		{
			case vdUseAnyField: // both non-interlaced
				evenFieldHeight = locationHeight;
				break;
			case vdUseOddField:
				oddFieldHeight = locationHeight;
				break;
			case vdUseEvenField:
				evenFieldHeight = locationHeight;
				break;
			case vdUseBothFieldsInterlaced:
			default:
				evenFieldHeight = locationHeight >> 1;
				oddFieldHeight = locationHeight >> 1;
				oddFieldOffset = rowBytes;	// each odd field line comes after an even field line
				rowBytes <<= 1;				// multiply rowBytes by 2 because the lines are interlaced
		}

...

There's also Linux source code.
 

noglin

Active member
@joevt: reverse engineering it and making your own driver based on it, that's very cool. Kudos. Out of curiosity, if you don't mind me asking, how did you go about that? I suppose MacsBug and looking at the driver entries with some custom made macros for mapping records/structs and reading disasm?
 

Arbee

Well-known member
The SAA7196 is documented, and unlike the Apple ASICs not secretly. Chipmakers back in the day would send printed chip documentation to pretty much anyone for cheap or even free. I picked up the AMD version of the Z8530 SCC manual that way.
 

joevt

Well-known member
@joevt: reverse engineering it and making your own driver based on it, that's very cool. Kudos. Out of curiosity, if you don't mind me asking, how did you go about that? I suppose MacsBug and looking at the driver entries with some custom made macros for mapping records/structs and reading disasm?
I used Jasik's MacNosy disassembler on the planb 68K resource in the System file, then manually converted each proc into a C function, defined structs based on the C code, concatenated all the structs and C code together, and tried to compile it.

Used the SAA7196_1.pdf documentation for register names.
Referenced the Linux source code and also Apple xnu source code regarding DBDMA registers for planb and creating DBDMA programs.
Used SoftVdig and SoftVDigX sample source code and Apple QuickTime Components documentation to clean up the project to make it look like a proper QuickTime video digitizer component.

For OS X, created a kext and user client to handle interrupts, allocate buffers, and map hardware registers.

There's also an Open Firmware patch to fix a assigned-address conflict between control and planb devices.
 

Attachments

  • planb.zip
    4.7 MB · Views: 0
Top