FDS Writing extension for TapeDump

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

FDS Writing extension for TapeDump

Post by ccovell »

Hi, everyone. The NES programming bug hit me again (or was it a wave of FDS nostalgia that did it?) and so I wanted to find a way to upload .FDS images and save them to disk using my program, TapeDump (version 1.0 here). I was wondering, continuing the "no extra hardware needed" idea, whether KCS audio files could be sent TO the NES, or Famicom, via the microphone, or something.

Anyway, I didn't try to get KCS decoding going on the Famicom just yet (anybody has any advice with tape decoding, let me know) because I thought the simpler first step would be to get general (fast) data uploading going on the Famicom with a dedicated cable. Last summer I in fact did make a special cable for my C-64 DTV using the schematic included with DTVTrans, the software that uploads data to the C-64 via the PC's parallel port at a good rate.

So here are the initial results of my experiment:

Here's how I connected the DTVTrans cable to the Famicom expansion port:
Image

I adapted this cable to the Famicom's expansion port, choosing wires that wouldn't conflict with the existing connected joypads, and got the wiring all right and software polling of the data lines working. Using the DTVTrans software on the PC, I can upload files to the Famicom at about 4.6Kbytes/sec.

I then got down to studying how to write to FDS disks, and eventually, using a disk drive that HAS NO COPY-PROTECTION CIRCUITRY, got my software to write full FDS disk images from the PC! Since my current PC can't run FDSLoader at all, this disk re-writing via parallel port is the next best thing.

A quick whipped-together ZIP file: http://www.chrismcovell.com/data/TapeDu ... Writer.zip
(my in-progress version skips the usual TapeDump title screen and goes directly to the FDS Writer code)

Pic of it writing:
Image

Loading of FDS files straight to the RAM adaptor for soft booting works well too, though some files can't be loaded properly, and several games read the FDS disk themselves right after booting, but it's a good way to load your own software onto the FDS RAM unit for quick testing.

Pic of RAM upload:
Image
---

Okay, so I'll keep working on this program since it still needs polishing and stuff. Does anybody have any comments about the cable and connection method?

The $4016/$4017 bit assignments are not set in stone for now, but there are some limitations. I can't use the same $4016/7 bit assignments for the Famicom and the NES, because the NES has a few too many of those bits going to its expansion port, not the joystick port. And the bits that ARE usable on NES Joy 2 can't be used on the Famicom without having to disconnect the usually hard-wired Joystick 2 on the Famicom. That's why I chose other available bits on the Fami expansion connector.

If anybody makes a cable to try this out on their Famicoms, let me know if it works. The DTVTrans cable calls for Schottky-barrier diodes but the requirement may not be that strict. I've included a "PortTest.NES" program for debugging and verifying correct cable operation. (Remember that, as I discovered to my surprise, lines being sent to the Famicom appear logically inverted, because the Fami uses pull-up resistors, or something like that...)

Port tester:
Image
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: FDS Writing extension for TapeDump

Post by lidnariq »

Back in the day of acoustic couplers for modems, I don't think they got above 300 baud... wikipedia tells me the last one got to 1200 baud, but only with very good seals.

The two KCS parsing circuits I've seen (Famicom Keyboard, something from How to Build Your Own Working Microcomputer) both had a ~hysteretic stage to fix up the derivative-taking nature of audio cassettes. Since the famicom microphone doesn't have any such stage... it's hard to advise without some real-world data as to just how 1200hz+ audio comes in on the microphone's 1 bit ADC.
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FDS Writing extension for TapeDump

Post by ccovell »

Here's a program I made up to test the Famicom mic:

http://www.chrismcovell.com/data/Waveform_Check.zip

Image

The microphone, when in the controller's case, is extremely insensitive... put earbud headphones up to the mic hole and it barely registers as a pulse on-screen.

So I removed the mic from the controller case and it got much more response on-screen.

I also connected a waveform generator directly to the Mic wires and took some measurements:

Sensitivity Range (waveform is solid with no noise): 10 Hz -> 15 KHz

At high frequencies, it triggers at around 1.25 Volts.
At low frequencies, it triggers at 0.125 V. Max voltage 2.71 V (then the capacitor in the controller starts to lift the DC voltage away from 0V.)

Duty Cycle: 7.8% <-> 97.5% at low frequencies
49% <-> 55% at high frequencies

Maybe someone else can do more accurate measurements. Anyway, I had fun playing with the Mic input, but I'm not sure if I want to go down the long path to getting FDS rewriting working through 300 baud mic transmission... :?
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: FDS Writing extension for TapeDump

Post by lidnariq »

I've looked in Castle Excellent, which can save games using the Famicom data recorder. Its code for parsing KCS is in the first 255 bytes of the ROM, so it's easy to find.

The way it worked is it made a "temporal comparator" to determine whether it's been closer to 746 or 1491 cycles since the last time the input toggled. It should be easy enough to look at the input on the microphone and see if it's suitable for such logic, or if there's too much noise. Or maybe you could even just borrow the code from Castle Excellent for the purposes of testing, dunno.

I do suspect that driving the microphone with a sine instead of a square wave is better.
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FDS Writing extension for TapeDump

Post by ccovell »

Does Castle Excellent actually use KCS?

I checked earlier into the data format for Wrecking Crew and it used an incompatible format (borrowed from the SHARP MZ series of computers) for transmitting data, which means decoding/encoding software is esoteric/nonexistent.

The same KCS08 program that I use for TapeDump decoding can be used for encoding as well, so the same standard will be preferable.

In my tests with the Mic, square waves triggered much better than sine or triangle waves.
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: FDS Writing extension for TapeDump

Post by lidnariq »

It looked like KCS? Definitely 1200/2400 Hz FSK at 1200 baud; marker tone of 5 seconds of 1200 Hz. I suppose it might have been some other very similar FSK.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: FDS Writing extension for TapeDump

Post by tepples »

Wikipedia says there's something called KCS and something called CUTS. I can't really tell the difference. KCS, as I understand it, is FSK at 300 baud, 0=1200 Hz, 1=2400 Hz, 110 between bytes. CUTS is pretty much the same except with the option to run at 1200 baud.
User avatar
byemu
Posts: 297
Joined: Mon Sep 05, 2011 5:56 pm
Contact:

Re: FDS Writing extension for TapeDump

Post by byemu »

can you make a rom dumper use a real famicom via rs232?
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FDS Writing extension for TapeDump

Post by ccovell »

Possible, but I'm not the one to do it. I don't have a working COM port on my computer (and USB solutions have failed me.)
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FDS Writing extension for TapeDump

Post by ccovell »

Here's a partial disassembly of Castle Excellent's KCS code. Yes, it uses KCS, but the bit ordering is backwards in the bytes it sends compared to KCS.

KCS: 0,b0 b1 b2 b3 b4 b5 b6 b7,1,1
Castle Excellent: 0,b7 b6 b5 b4 b3 b2 b1 b0,1,1

Code: Select all

;*****************************
;Disassembly of Castle Excellent KCS loader/saver
;*****************************
; Partial work by Chris Covell
;*****************************
;
;*****************************

;*****************************
; 8000: Long delay.
;*****************************
k_Long_Delay:	ldx #$91
-:		dex
		bne -
		rts

;*****************************
; 8006: Short delay.
;*****************************
k_Short_Delay:	ldx #$47
-:		dex
		bne -
		rts

;*****************************
; 800C: Wait for Audio Level transition
;*****************************
k_Wait_Transition: ldy #$00              ;Y will be a "loop" counter
-:		iny
		beq +                 ;256 loops = timeout
;-----
		lda $4016             ;Joystick 1 + strobe
		and #$02              ;Get Tape data bit
		eor $30               ;Is it different from last read?
		beq -			;If not, keep looping, inc Y
		eor $30
		sta $30               ;$30 will contain Level after transition
		rts                   ; Y will contain # of loops until transition
;-----
+:		dey			;Y = FF = 256 reads with no change.
		rts

;*****************************
; 8021: Count Audio Level Transitions within 40 loops
;*****************************
k_Count_Transitions:	ldx #$28              ;Do 40 loops no matter what
		ldy #$00
-:		lda $4016             ;Joystick 1 + strobe
		and #$02
		eor $30               ;Transition?
		beq +
		eor $30               ;Store the change
		sta $30
		iny
		dex
		bne -
		rts                   ;Y will contain # of transitions
;--------
+:		lda $30                ;This just wastes cycles
		lda $30
		lda $30
		dex
		bne -
		rts

;*****************************
; 8041: Send Zero Bit - Single long cycle
;*****************************
k_Zero_Bit:	lda #$00
		sta $4016             ;Joystick 1 + strobe
		jsr k_Long_Delay
		lda #$01
		sta $4016             ;Joystick 1 + strobe
		jsr k_Long_Delay
		lda #$00
		sta $4016             ;Joystick 1 + strobe
		rts

;*****************************
; 8057: Send a bit currently stored in Carry
;*****************************
k_Send_Bit:	bcc k_Zero_Bit
;*****************************
; 8059: Send a "One" - A Pair of short cycles.
;*****************************
k_Ones_Bit:	lda #$00
		sta $4016             ;Joystick 1 + strobe
		jsr k_Short_Delay
		lda #$01
		sta $4016             ;Joystick 1 + strobe
		jsr k_Short_Delay
		lda #$00
		sta $4016             ;Joystick 1 + strobe
		jsr k_Short_Delay
		lda #$01
		sta $4016             ;Joystick 1 + strobe
		jsr k_Short_Delay
		lda #$00
		sta $4016             ;Joystick 1 + strobe
		rts

;*****************************
; 807F: Waits for stable Leader tone
;*****************************
k_Wait_for_Leader: lda #$04
		sta $4016             ;Joystick 1 + strobe
		ldx #$00
		stx $30
-:		jsr k_Wait_Transition	;Wait for a transition
		cpy #$12                ;And check it's between $12 and $19
		bcc k_Wait_for_Leader	;loops per transition
		cpy #$1A
		bcs k_Wait_for_Leader
		inx
		bne -                  ;256 transitions
		rts

;*****************************
; 8097: Send Leader tone for 7.04 seconds
;*****************************
k_Send_Leader:	lda #$21	;#$2100 / 2400Hz * 2
		sta $2F
		ldy #$00
-:		jsr k_Ones_Bit	;Send continuous "Ones" for duration
		dey
		bne -
		dec $2F
		bne -
		clc
		rts

;*****************************
; 80A9: Send a full byte as: 0,b,11
; CASTLE EXCELLENT SENDS THE BYTE OPPOSITE TO KCS FORMAT!!
;*****************************
k_Send_Byte:	jsr k_Zero_Bit		;a coded "0" is sent first
		ldy #$08
-:		asl $17                 ;MSB first!! Backwards from KCS format!
		jsr k_Send_Bit		;Then all 8 bits
		dey
		bne -
		jsr k_Ones_Bit          ;Then a "1"
		jmp k_Ones_Bit		;Finish with a "1"

;*****************************
; 80BC: Receive a byte
; CASTLE EXCELLENT RECEIVES THE BYTE OPPOSITE TO KCS FORMAT!!
;*****************************
k_Recv_Byte:	lda $4016             ;Joystick 1 + strobe
		and #$02
		beq k_Recv_Byte       ;Wait for rising edge
-:		lda $4016             ;Joystick 1 + strobe
		and #$02
		bne -             	;Wait for falling edge
		sta $30                 ;Save zero
		jsr k_Wait_Transition   ;Wait 0->1
-:		sty $2D                 ;Save timing result
		jsr k_Wait_Transition   ;Wait 1->0 (or 0->1)
		tya
		clc
		adc $2D                 ;Add both timings together
		bcs -                   ;If over $FF, read again.
		cmp #$50		;If $50 or less, read again
		bcc -
		lda #$08
		sta $2E			;Counter for 8 bits
-:		jsr k_Count_Transitions ;How many transitions in a span (1/2400th sec?)
		cpy #$04
		bcs +                   ;If more than 3 transitions... QUIT!  (Bad transmission)
		cpy #$02                ;Carry set if >=2, cleared if 0 or 1
		rol $17                 ;Carry rolled into ZP
		tya
		lsr a                   ;If odd number of transitions, even it out
		bcs ++
		jsr k_Wait_Transition   ;Skip 1 pulse
++:		jsr k_Wait_Transition
		dec $2E
		bne -
		lda $2D
		clc
+:		rts
;-------------------------------------------------

;-------------------------------------------------
$80FF: 	;Reads in Joystick 1 with NMIs off, stores in $20 and A
;-------------------------------------------------
$810B:	;Reads in Joystick 1, stores in $20 and A
;-------------------------------------------------
$8111:	;Read Joystick
;-------------------------------------------------
$8129:	;Reads in Joystick 2 with NMIs off, stores in $20 and A
;-------------------------------------------------
$8135:	;Reads in Joystick 2, stores in $20 and A
;-------------------------------------------------
$813B:	;Read Joystick 2
;-------------------------------------------------
$8158:	;NMIs OFF: clears $2000.7
;-------------------------------------------------
$815E:	;NMIs_on: sets $2000.7
;-------------------------------------------------
$8164:	;Screen_off: clears $2000
;-------------------------------------------------
$816A:	;Wait VBlank start, turn on screen
;-------------------------------------------------
$8175:	;Bankswitch CHR.
;-------------------------------------------------
Start_KB_or_Tape_Send:	;$8180: Starts Xmission to keyboard or tape
		bit $1F
		bpl +
		jmp k_Send_Leader
+:		jsr Keyb_Next_Row
		lda #$00
		sta $17
		jsr Keyb_Write_Data
		lda #$AA
		sta $17
		jsr Keyb_Write_Data
		lda #$55
		sta $17
		jmp Keyb_Write_Data

;-------------------------------------------------
Start_KB_or_Tape_Recv:	;$819F: Starts Xmission from keyboard or tape
		bit $1F
		bpl +
		jmp k_Wait_for_Leader
+: 		jsr Keyb_Next_Row
		jsr Keyb_Read_Data
		jsr Keyb_Read_Data
		lda $17
		cmp #$AA
		bne +
		jsr Keyb_Read_Data
		lda $17
		cmp #$55
		bne +
		clc
		rts
+:		sec
		rts

;-------------------------------------------------
Send_KB_or_Tape: ;$81C2: sends to KB or Tape depending on $1F.8
		sta $17
		stx $1A
		bit $1F
		bpl +
		jsr k_Send_Byte
		jmp ++
+:		jsr Keyb_Write_Data
++:		ldx $1A
		rts
;-------------------------------------------------
Recv_KB_or_Tape: ;$81D6: Receives byte from KB or Tape depending on $1F.8
		stx $1A
		bit $1F
		bmi +
		jsr Keyb_Read_Data
		jmp ++
+:		jsr k_Recv_Byte
++:		ldx $1A
		lda $17
		rts
;-------------------------------------------------
Keyb_Write_Data: ;$81EA: Writes a byte to Keyboard serially (?)
		ldy #$07		;8 loops
-:		asl $17			;Feed byte stored in $17 out to Keyboard
		lda #$00
		rol a                 ;Bit 0 = Keyboard row reset
		ora #$06              ;Enable keyboard
		sta $4016             ;Joystick 1 + strobe
		and #$03              ;Disable keyboard matrix
		sta $4016             ;Joystick 1 + strobe
		dey
		bpl -
		rts
;-------------------------------------------------
Keyb_Read_Data:	;$81FF: Reads only column 2 (???) of the Family BASIC keyboard?
		ldy #$07		;Loop 8 times
-:		lda $4017             ;Joystick 2 + strobe
		lsr a
		lsr a
		and #$01		;Isolate Keyboard column 2??
		ora #$06              ;Enable keyboard matrix (usually resets it)
		sta $4016             ;Joystick 1 + strobe
		and #$03              ;Disable keyboard matrix
		sta $4016             ;Joystick 1 + strobe
		lsr a
		rol $17               ;Store column 2 data in $17.
		dey
		bpl -
		clc
		rts
;-------------------------------------------------
Keyb_Next_Row:	;$821A: Increases Keyboard Row
		lda #$00              ;This should increment row
		sta $4016             ;Joystick 1 + strobe
		lda #$02
		sta $4016             ;Joystick 1 + strobe
		rts
;-------------------------------------------------

ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FDS Writing extension for TapeDump

Post by ccovell »

Okay, I've got KCS file receiving/disk writing working pretty well now, so I'll release a Beta version:

http://www.chrismcovell.com/data/TapeDu ... r_Beta.zip

Image

Be sure to read the included Quick readme.

This KCS writer will receive FDS disk header files and file header+data files at 1200 baud over the Fami's microphone. I've set up some scripts and included DOS/Win programs and batch files to automate FDS -> WAV conversion.

Let me know if you get it working! Different PC+Fami combinations will yield better or worse results through the microphone, and I've discovered that the circuits (and volume/detection levels) are different for the microphones inside of my two Famicom systems: a Sharp Twin Famicom and a Sharp Famicom Titler. The Titler receives audio files loud and clear if you connect the audio out from your PC to GND and the mic's red wire inside the controller; however, the Twin Famicom is rather hard-of-hearing. I discovered that bridging a resistor inside the Twin Fami system boosts its microphone detection to within "normal" parameters (hysteresis is still evident meaning the duty cycle will appear narrower through the Mic test program.) If anybody wants more info about the Twin Fami fix, ask me and I'll post a pic.

also...

Did anybody try out the Parport DTVTrans writing with a cable yet? Let me know. I've also made a bootstrap (DTVTrans protocol) receiving program that can be run without need for a devcart at all. (All that is needed is Wrecking Crew, a single Game Genie code, and some time.)
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FDS Writing extension for TapeDump

Post by ccovell »

.... .. . . . @ * *... . ... ... .

tumbleweeds ^^^


So, nobody has tried this out or got it working? Interest is at 0%? :(
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: FDS Writing extension for TapeDump

Post by infiniteneslives »

Not a large population of people on here with FDS and flash carts I'd imagine.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: FDS Writing extension for TapeDump

Post by Bregalad »

I am interested, but I don't have any free time and won't have any until june.

That being said, thank you very much for using something else than a parallel port !

Is there a way to make the microphone work on an AV Famicom ? Because I don't have the original famicom currently.
Tomy
Posts: 56
Joined: Sat May 06, 2006 9:19 am
Contact:

Re: FDS Writing extension for TapeDump

Post by Tomy »

ccovell wrote: So, nobody has tried this out or got it working? Interest is at 0%? :(
I think many people interest in it. But they don't know how to build (soldering work), or don't have cable to make it.
I want to ask, I only need DTVTrans cable to the Famicom expansion port is enough to dump FDS ?
Look like it transfer data not use sound format.

About KCS, I need a Famicom keyboard ?
Last edited by Tomy on Thu May 02, 2013 4:25 pm, edited 1 time in total.
Post Reply