Jump to content

jhugard

New Members
  • Content Count

    7
  • Joined

  • Last visited

Posts posted by jhugard


  1. 15 hours ago, phaeron said:

    I had forgotten that CMP doesn't set the V flag, so yes, that does check for an interrupt from the FDC. However, that then means that nothing is actually using the result of the compare against the sector buffer. Which works, as the CRC-16 verification by the FDC is good enough, but then the CMP (zp),Y / INY instructions might as well just be removed -- the routine just needs to drain the data bytes as they come in while waiting for error or completion.

    Sweet!  I may have trimmed the BNE & code to load an error return, but left the compare as a reminder to add it back (or just forgot about it and focused on other areas to save bytes instead).  You just saved another 3 bytes!  So, 9 available...

     

    16 hours ago, phaeron said:

    The receive routine takes the last byte out of the sector buffer and saves it off, backs up a byte, jumps back into the receive loop with a special flag set, receives and stores one more byte to finish the buffer again, sees the flag it set, then pulls the checksum byte out of the sector buffer and puts the last data byte back. Bit roundabout. Generally receive routines handle this by instead moving the buffer store to the beginning of the loop and jumping into the middle, so that the receive routine exits without storing its last byte into the sector buffer.

    Agree; that would be a better approach and should save a few more bytes.  Inexperience at play; didn't realize at first I needed to read the checksum byte, so had to retrofit the original code.

     

    16 hours ago, phaeron said:

    There are a couple of things I can't ascertain from the firmware that would be nice to figure out for completeness. One is which chip is providing $80-FF memory and whether RIOT memory is still mapped to $0180-01FF.

    IIRC, we didn't change the existing mappings, just dropped 4K static RAM in at $0800.

     

    16 hours ago, phaeron said:

    The second is whether the FDC is a 2791 or 2795, again since the firmware issues command compatible with both.

    I want to say it was a 2795, but bottom line is I can't recall.

     

    The 2795/7 have a side-select output, which is only interesting for double-sided drives.  OTOH, that pin is used for ENABLE MINI_FLOPPY on 2791/3 and must be open/high for 1 MHz clock.  Since it didn't matter in our application, either part could be used (2791 or 2795), as long as pin 25 is left to float/isn't connected.  If it's tied high, then it's probably a 2791.  If there's an inverter between 6507 and 279x (which we might have done to buffer to tie-down the signal lines), then it's 2793/7.

     

    16 hours ago, phaeron said:

    Also reminds me, I don't think I saw any code in the firmware to enable write precompensation in MFM mode.

    Positive that we never even considered changing write precomp for inner tracks; I didn't even realize adjusting it on the fly was a thing until just now (had to look it up on Wikipedia :P).

     

    The 279x data sheet made it seem like a set-and-forget value that didn't need to be adjusted at run-time.  Nor did our sales rep mention anything about it.  To me, looked like a one-shot hardware setting (especially since it is controlled by ~TEST on pin-22) and that was Chuck's department.  We probably just tied ~TEST to high (precomp off) and might have tied WPW (pin-33) either high or low, rather than adding a 10K pot.  IIRC, the on-board pot is probably a 50K and tied to RPW (pin 18), to adjust the internal data separator.  Again, that was a Chuck thing.

     

    Note that there is an unused RIOT pin on one of the two ports, which we decided to NOT use to bank switch either ROM or RAM.  Would take some surgery to wire things up, plus add well over a dozen bytes to detect crossing the middle track and flipping precomp on-or-off accordingly...

     

     

    • Like 3

  2. phaeron, excellent job on the disassembly!

     

    On 8/2/2019 at 2:01 AM, phaeron said:

    Not sure write verify works correctly. It is checking bytes with the V flag instead of the Z flag.

    On checking the V flag, that would be testing bit-6 of the RIOT Port A.  For the life of me, I cannot recall exactly what the bits were wired to.  Do you have definitions of bit-7 and bit-6 of that port (schematic of what they were wired to)?

     

    I'm suspecting they were hooked to the 279x DRQ (data request) on bit-7 and INTRQ (interrupt request/command complete) on bit-6.  That makes for loops checking bit-7 for data ready (BMI) and bit-6 for error (BVS).

     

    If so, then the code should look like the following (sorry for the tabs):

    ;===============================================================================
    ; Verify sector
    ;
    FB8D: A9 77		LFB8D	LDA		#$77		;inverted $88 (read sector)
    FB8F: 20 94 F8			JSR		LF894		;issue FDC command
    FB92: A2 06				LDX		#$06		;~1.5s total timeout
    FB94: A0 00				LDY		#$00
    FB96: A9 FF		LFB96	LDA		#$FF		;~260ms timeout
    FB98: 8D 9F 03			STA		$039F		;start timer
    FB9B: B8				CLV                 ;JH: clear error flag
    FB9C: 70 1D		LFB9C	BVS		LFBBB       ;JH: exit if error
    FB9E: 2C 80 03			BIT		$0380       ;JH: get ready/error
    FBA1: 30 11				BMI		LFBB4       ;JH: jump if byte ready
    FBA3: AD 85 03			LDA		$0385       ;JH: check for timeout
    FBA6: 10 F4				BPL		LFB9C       ;JH: jump if not expired
    FBA8: CA				DEX                 ;JH: dec timeout
    FBA9: D0 EB				BNE		LFB96       ;JH: loop if not timed out
    FBAB: F0 0E				BEQ		LFBBB       ;JH: exit on timeout
    
    FBAD: 70 0C		LFBAD	BVS		LFBBB       ;JH: exit on error
    FBAF: 2C 80 03	LFBAF	BIT		$0380       ;JH: get ready/error status
    FBB2: 10 F9				BPL		LFBAD       ;JH: loop if byte not ready
    
    FBB4: A5 03		LFBB4	LDA		$03			;read byte from FDC
    FBB6: D1 88				CMP		($88),Y		;JH: compare with expected byte
    FBB8: C8				INY                 ;JH: bump write buffer index
    FBB9: 50 F4				BVC		LFBAF       ;JH: loop if no error detected earlier
    
    FBBB: A5 00		LFBBB	LDA		$00			;read inverted FDC status
    FBBD: 85 8C				STA		$8C			;stash it
    FBBF: 49 FF				EOR		#$FF		;uninvert to return
    FBC1: 60				RTS
    


     

     

     


  3. On 6/18/2019 at 6:07 PM, ijor said:

    Very interesting. Seems you invested a lot of time and effort. Just out of curiosity, did you have any contact with the other people/companies involved in similar developments, like Happy, Spartan/ICD (The Chip/Archiver)?

    Pretty sure we had a phone conversation once with the Happy folks.  I was a HUGE Scott Adams fan and consumed everything he produced, so even speaking with his brother was kind of a big deal.  Can't remember details of the conversation, but we may have brainstormed on copy protection schemes.  They may also have expressed concern we had used some of their code.  Furthest thing from the truth - everything was clean room.  Well.  Ok.  Tom did manage to get a printout of the source code for the original 810 firmware when I was stumped on something (reliable track formatting, maybe?), but at best it pointed to an answer and at worst was unhelpful; in either case, the code was all mine.  Never disassembled the Happy code, but I did work damn hard to beat them on features, reliability, and performance.

     

    On 6/18/2019 at 6:07 PM, ijor said:

    Seems you invested a lot of time and effort.

    End to end, was over a year of effort.  I think it was about 3 months to get to working v1.0 firmware going after building the hardware prototype, but then spent 9 months or so on bug fixes, copy protection, timing utilities, high-speed I/O, and working with Stace on OS/A+ (though he wrote all the code for that).

     

    • Like 2

  4. On 6/18/2019 at 6:07 PM, ijor said:

    May be you tested a Synertek CMOS 6502 somehow, and assumed 6507 Synertek NMOS (not CMOS) would behave the same?

    Quite possible as this was a loooong time ago, lol.

     

    In any event, IIRC we had 100% failure on the Synertek 6507 for whatever reasons - hence, the compatibility note in the manual.


  5. 13 hours ago, ijor said:

    If the Synertek doesn't implement them then it would be incompatible with all that software and we surely would have known.

    Are you certain the 6507 from Synertek wasn't a cleanroom design?  My recollection is that every drive sent to us that wouldn't boot had a Synertek part.  It might have been speculation, but I believe I verified that the opcodes in question were being executed as NOPs.

     

    13 hours ago, ijor said:

    Both terms were sometimes used to refer to the same thing.

    Much to my annoyance, lol.

     

    13 hours ago, ijor said:

    Do you remember anything about the software to copy copy protected disks?

    Well, the program was written in Val/Forth and IIRC uploaded dup firmware to the drive at runtime.  My code handled arbitrary sector interleave (which gives different read timings), duplicated sectors (with different content), and specific track-to-track skewing (which also gives different read timings).  Fairly certain I also recreated intentionally bad sectors and omitted sectors.  Minor story around choosing Val/Forth, but will save that for the (amended) interview.

     

    Anything else you'd like to know?

    • Like 6

  6. Lemme see if I can clear up a few questions from above:

     

    • My recollection is we used the WD2791, but it is possible we inverted/buffered signals and actually used a 2793.
    • The Synertek 6507 didn't implement all the same instructions as the Rockwell and MOS versions.  I needed to reduce code by about 8 bytes to fit a 2K ROM when adding turbo-speed serial I/O and code-upload (for disk copy, etc), and it took me a couple of weeks of hard thought.  Had to reach for several undocumented opcodes, but as we found out after the fact, Synertek didn't implement those instructions, so was totally incompatible.  No way could I fit everything otherwise, and man I tried.  IIRC, a couple of people hit problems with 1MHz, but largely the issues were all Synertek.
    • No, with DD, 4K can't buffer an entire track at once.  IIRC, it was either 1/2 track at a time or I bank-switched RAM.  We had a spare PIO pin available & Charles  suggested bank-switching the ROM (making it 2x2K pages), but I wanted RAM not ROM!  Pretty sure we ended up with 2x2K SRAM, though, and pretty sure we didn't bank switch anything in the end.
    • Can't recall the exact transfer rate (thought it was 56.4KB/s), but I do remember figuring out how to eliminate one clock cycle from the loop.  Unlike the Happy, we were running 1MHz so it might have even been 64KB/s or 72KB/s.  I think I hit the max transfer rate supported by the 400/800 SIO, but will probably take someone disassembling my code or measuring the rate and my recollection might just be wishful thinking, lol.
    • On the sector interleave, someone will need to disassemble the code to check.  I think I formatted single density with something akin to Chicago interleave (but better?) after a lot of empirical testing.  (@Nezgar called this skew, which is IMHO incorrect).
    • In addition, best I could tell, factory format floppies used the physical disk timing hole to align sector 1, which means when stepping track-to-track, there was a delay waiting for sector 1 to rotate under the head.  My formatting code put sector 1 under the head with a small delay after a step, so was in general faster track-to-track (this is called track skew).
    • Interleave didn't matter, though, because IIRC my code would read the first track and record the sector interleave, then buffer the entire track in one revolution.  (Possible I just wanted to do that, but never implemented it - curious what the disassembly shows)
    • For double density, I think I went with sequential 1,2,3,4 because with buffering I could read data that fast (or, it was 1,3,5, etc.) .  I might have also used the interleave-storage trick above for DD.
    • Have not re-read the manual, but the Atari disks ran at 288 RPM.  We supplied a utility to read the rate and there might have been some performance gain to be had by tuning that upwards towards 300 RPM, but TBH don't remember the details... 300 RPM was too fast for the number of sectors we put on the disk though, so probably best to tune for 288 RPM. 
    • Like 15
    • Thanks 2
×
×
  • Create New...