nesdev.com
http://forums.nesdev.com/

FDS Writing extension for TapeDump
http://forums.nesdev.com/viewtopic.php?f=2&t=9909
Page 1 of 3

Author:  ccovell [ Mon Mar 11, 2013 9:32 am ]
Post subject:  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:
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

Author:  lidnariq [ Mon Mar 11, 2013 12:21 pm ]
Post subject:  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.

Author:  ccovell [ Mon Mar 11, 2013 6:57 pm ]
Post subject:  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

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... :?

Author:  lidnariq [ Mon Mar 11, 2013 8:36 pm ]
Post subject:  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.

Author:  ccovell [ Mon Mar 11, 2013 8:51 pm ]
Post subject:  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.

Author:  lidnariq [ Mon Mar 11, 2013 9:16 pm ]
Post subject:  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.

Author:  tepples [ Mon Mar 11, 2013 9:30 pm ]
Post subject:  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.

Author:  byemu [ Tue Mar 12, 2013 4:21 am ]
Post subject:  Re: FDS Writing extension for TapeDump

can you make a rom dumper use a real famicom via rs232?

Author:  ccovell [ Tue Mar 12, 2013 5:07 am ]
Post subject:  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.)

Author:  ccovell [ Fri Mar 22, 2013 11:56 pm ]
Post subject:  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

Code:
;*****************************
;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
;-------------------------------------------------


Author:  ccovell [ Sun Apr 21, 2013 7:50 am ]
Post subject:  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

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.)

Author:  ccovell [ Wed May 01, 2013 4:51 pm ]
Post subject:  Re: FDS Writing extension for TapeDump

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

tumbleweeds ^^^


So, nobody has tried this out or got it working? Interest is at 0%? :(

Author:  infiniteneslives [ Wed May 01, 2013 10:23 pm ]
Post subject:  Re: FDS Writing extension for TapeDump

Not a large population of people on here with FDS and flash carts I'd imagine.

Author:  Bregalad [ Thu May 02, 2013 12:32 am ]
Post subject:  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.

Author:  Tomy [ Thu May 02, 2013 5:15 am ]
Post subject:  Re: FDS Writing extension for TapeDump

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 ?

Page 1 of 3 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/