FDS Writing extension for TapeDump
Moderator: Moderators
FDS Writing extension for TapeDump
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:
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:
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:
---
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:
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:
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:
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:
---
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:
Re: FDS Writing extension for TapeDump
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.
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.
Re: FDS Writing extension for TapeDump
Here's a program I made up to test the Famicom mic:
http://www.chrismcovell.com/data/Waveform_Check.zip
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...
http://www.chrismcovell.com/data/Waveform_Check.zip
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...
Re: FDS Writing extension for TapeDump
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.
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.
Re: FDS Writing extension for TapeDump
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.
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.
Re: FDS Writing extension for TapeDump
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.
Re: FDS Writing extension for TapeDump
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.
Re: FDS Writing extension for TapeDump
can you make a rom dumper use a real famicom via rs232?
Re: FDS Writing extension for TapeDump
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.)
Re: FDS Writing extension for TapeDump
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
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
;-------------------------------------------------
Re: FDS Writing extension for TapeDump
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
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.)
http://www.chrismcovell.com/data/TapeDu ... r_Beta.zip
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.)
Re: FDS Writing extension for TapeDump
.... .. . . . @ * *... . ... ... .
tumbleweeds ^^^
So, nobody has tried this out or got it working? Interest is at 0%?
tumbleweeds ^^^
So, nobody has tried this out or got it working? Interest is at 0%?
- infiniteneslives
- Posts: 2104
- Joined: Mon Apr 04, 2011 11:49 am
- Location: WhereverIparkIt, USA
- Contact:
Re: FDS Writing extension for TapeDump
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
Re: FDS Writing extension for TapeDump
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.
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.
Re: FDS Writing extension for TapeDump
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.ccovell wrote: So, nobody has tried this out or got it working? Interest is at 0%?
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.