.PAGE ;--- ; ZERO PAGE MAPPING ; ; The following equates are for dividing RAM into logical areas; ; however, as the code grew, this convention was not strictly adhered ; to and therefore one will find both "LOCAL" and "GLOBAL" variables ; scattered throughout the RAM area ;+++ IOB .Equ 00 ; INPUT OUTPUT BLOCK This starts at $FCC000. All ofsets from here are WORD offsets!!!. For example, COMMAND is at FCC002 (offset of one word). Actually, only the low byte of the word has any significance. SHARERAM .Equ 10 ; READ/WRITE SHARED RAM, INITIALIZED BY 6504 ON BOOT Starts at $FCC020 STATUS .Equ 20 ; READ ONLY STATUS FROM THE 6504 $FCC040 IIOB .Equ 30 ; INTERNAL IOB $FCC060 This can be used to check the last command excuted GLOBALS .Equ 40 ; 6504 INTERNAL GLOBALS $FCC080 This is where the actual "ROM" is maintained. Of course these can be changed, but don't even think about it LOCALS .Equ 68 ; LOCAL VARIABLES $FCC0D0 Local storage mainly. Probably should not be changed ;; THESE APPEAR, FROM THE LISTING PROVIDED, TO BE HEX NUMBERS UNLESS FOLLOWED BY A DECIMAL ;; 1/6/89 ARS .PAGE ;--- ; ; IOB ; ; THE IOB IS ALWAYS COPIED INTO THE INTERNAL IOB (IIOB) AREA BEFORE USAGE ; SO THAT THE 68K CAN START TO BUILD A NEW COMMAND INTO THE IOB AS SOON AS ; POSSIBLE. ALL REFERENMCES TO THE IOB OF IIOB ARE DONE IN THE FOLLOWING ; FORMAT: ; IOB IIOB ; -------- -------- ; GOBYTE IOB+GOBYTE IIOB+GOBYTE ; DRIVE IOB+DRIVE IIOB+DRIVE ; ;+++ IOBSIZE .Equ 07 ; SIZE OF IOB BLOCK USED FOR PARAMETER PASSING GOBYTE .Equ 00 ; COMMAND BYTE FROM 68K $FCC000/060 ; 00 COMMAND ACCEPTED BY THE 6504, 68K MAY ISSUE A NEW COMMAND ; 80-89 COMMAND FROM 68K TO 6504 ; 80 NULL, TESTS HANDSHAKE ; 81 RWTS COMMAND, COMMAND CODE IN 'COMMAND' ; 83 SEEK ; 84 CALL ADDRESS IN 6504 ; 85 CLEAR STATUS ; 86 SET MASK ; 87 CLEAR MASK ; 88 WAIT IN ROM ; 89 Go jump to self forever (Their case change ARS) ; ; 01-7F,82,90-FF *** RESERVED *** COMMAND .Equ 01 ; RWTS COMMAND CODE $FCC002/062 ; 00 READ Read Read the Data @ Drive/Side/Track/Sector ; 01 WRITE Write Read the Data @ Drive/Side/Track/Sector ; 02 UNCLAMP Unclamp the disk in Drive ; 03 FORMAT Format the disk in Drive ; 04 VERIFY Verify the disk in Drive ; 05 FORMAT TRACK Format single Track on the disk in Drive ; 06 VERIFY TRACK Verify single Track on the disk in Drive ; 07 READBF Read w/o checksum verification ; 08 WRITEBF Write w/o checksum creation ; 09 CLAMP Clamp the disk in Drive ; 0A-FF *** RESERVED *** MASK .Equ COMMAND ; MASK FOR SETTING AND RESETTING IMSK & IST $FCC002/062 ; 08 SET OR CLEAR INTERRUPT MASK FOR UPPER DRIVE ; 80 SET OR CLEAR INTERRUPT MASK FOR LOWER DRIVE ; 01 CLEAR DISK INSERTED INTERRUPT FOR UPPER DRIVE ; 10 CLEAR DISK INSERTED INTERRUPT FOR LOWER DRIVE ; 02 CLEAR BUTTOM PRESSED INTERRUPT FOR UPPER DRIVE ; 20 CLEAR BUTTOM PRESSED INTERRUPT FOR LOWER DRIVE ; 04 CLEAR R/W COMMAND COMPLETED INTERRUPT FOR UPPER DRIVE ; 40 CLEAR R/W COMMAND COMPLETED INTERRUPT FOR LOWER DRIVE ADRL .Equ COMMAND ; LOW BYTE OF ADDRESS FOR 6504 CALL $FCC002/062 ADRH .Equ ADRL+1 ; HIGH BYTE OF ADDRESS FOR 6504 CALL $FCC004/064 ; A call to "1FFB" will reset the 65404 DRIVE .Equ 02 ; DRIVE NUMBER $FCC004/064 ; 00 DRIVE 0 UPPER DRIVE ; 80 DRIVE 80 LOWER DRIVE SIDE .Equ 03 ; SIDE NUMBER $FCC006/066 ; 00 SIDE 0 UPPER SIDE OF MEDIA ; 01 SIDE 1 LOWER SIDE OF MEDIA SECTOR .Equ 04 ; SECTOR NUMBER $FCC008/068 ; 00-15 MAXIMUM DEPENDES ON TRACK NUMBER TRACK .Equ 05 ; TRACK NUMBER $FCC00A/06A ; 00-2D 46 TRACKS TOTAL (twiggy, Sony has 80 -- 0-79) SPEED .Equ 06 ; SPEED OVERRIDE $FCC00C/06C ; 00 NOOVERRIDE, SPEED IN DEPENDING ON TRACK NUMBER ; 01-FF Modifier value added to nominal speed FMTCNFN .Equ 07 ; Format configuration byte $FCC00E/06E ; Used to ensure format is not executed by mistake ; FF FMTCNFM must be = FF for foramt/format track to work ERRSTAT .Equ 08 ; ERROR STATUS, RETURNED AFTER R/W COMMANDS $FCC010/070 ; See constants for current error code values This also seems to be used for address mark storage? DISKID .Equ 09 ; Current id of the disk last accessed $FCC012/072 ; 00 UIniFile/DuoFile disk ; 01 Lisa disk ; 02 Macintosh disk NoSides .Equ 0A ; Number of sides of disk drive mechanism $FCC014/074 DrvError .Equ 0B ; Hard errors get returned throught his byte $FCC016/076 HostSeek .Equ 0C ; When moving the head this location = 'FF' $FCC018/078 SeekErr .Equ 0D ; When seek does not handshake then = '0F' $FCC01A/07a .Page ;-- ; Shared RAM ; ; SHARED RAM COMES IN TWO FLAVOERS: 'READ/WRITE' AND 'READ ONLY'. THE 68K CAN, ; OF COURSE, READ AND WRITE TO ANY BYTE IN THE RAM AT ANY TIME BUT THIS IS NOT ; VERY WISE, (ONE MIGHT SAY VERY FOOLISH...), SO THE BY 'READ ONLY' WE MEAN ; MEMORY THAT NEVER SHOULD BE WRITTEN TO BY THE 68K BUT IS VALID TO READ AT ; ANY TIME. TYPICAL 'READ ONY' VARIABLES ARE THE STATUS FLAGS CLMED0 AND ; CLMPED80 THAT TELLS THE 68K THAT A DISK IS CLAMPED IN DRIVE 0 OR 80 ; ; 'READ/WRITE' SHARED MEMORY IS, FOR EXAMPLE, THE IOB BUT IN THIS CASE IT IS ; A FAMILY OF 'CONSTANTS' SET UP ON COLD START BY THE 6504 TO THEIR DEFAULT ; VALUES, BUT THEY CAN BE CHANGED AT ANY TIME BY THE 68K TO ANY VALUE. THERE ; IS NO CHECKING OF THE RANGE OF THESE VALUES O THE NEW ONE BETTER MAKE SENSE ; OR THE 6504 MIGHT GO OF TO NEVER, NEVER LAND... ; ; SHARED: READ/WRITE ;++ MSpdTbl .Equ ShareRam $FCC020 SCDLY .Equ SHARERAM+5. ; Speed change delay in 5 ms intervals $FCC02A HEADELAY .Equ SHARERAM+6. ; Head settling time in 5 ms intervals $FCC02C MAXDDLY .Equ SHARERAM+7. ; Timer value in 2/3 second before motor off $FCC02E ROMIDNUM .Equ SHARERAM+8. ; ROM identification number ( 0018/FCC031 ) $FCC030 MAXRETRY .Equ SHARERAM+9. ; Maximum number of retries during a read/rwite $FCC032 MAXRECAL .Equ SHARERAM+10. ; Maximum number of recalibrations during a r/w $FCC034 StpDly .Equ SHARERAM+11. ; Step dely time in 100 usec intervals $FCC036 MONDLY .Equ SHARERAM+12. ; Motor on delay time in 5 ms intervals $FCC038 .Page ;++ ; SHARED: READ ONLY ;-- Clamped .Equ Status ; Disk in Place (=0 EMPYT, =FF CLAMPED) $FCC040 MtrOn .Equ Clamped+1 ; DRIVE MOTOR SELECT (0=OFF, FF=ON) $FCC042 CurTrack .Equ Status+2 ; value of current track $FCC044 CurClass .Equ CurTrack+1 ; Current track class (0: 4) $FCC046 DrvConn .Equ Status+4 ; Will be 'FF' if a drive is physically there $FCC048 FmtType .Equ DrvConn+1 ; '2' for single, '22' for double sided mechanism connected $FCC04A RetryCnt .Equ Status+6 ; RETRY COUNT $FCC04C RecalCnt .Equ RetryCnt+1 ; RECALIBRATION COUNT $FCC04E ImAlive .Equ Status+8 ; THIS VARIABLE SPINNS AS LONG AS THE MAIN LOOP IS EXECUTING $FCC050 Counter .Equ Status+9. ; GENERAL COUNTER $FCC052 HoldInx .Equ Counter+1 ; Holds command index temporarily $FCC054 FmtGap .Equ Counter+2 ; Amt * 5 of 20 usec 'FF's to write as selfsync $FCC056 Imsk .Equ Status+12. ; Bits 7 & 3 are mask; if set the drive enabled $FCC058 DipIntr .Equ Imsk+1 ; Flag reflects DIP interrupt $FCC05A OkToGo .Equ Imsk+2 ; REFLECTS FDIR (=0, FDIRL; <>0, FDIRH) $FCC05C IST .Equ Imsk+3 ; INTERRUPT STATUS $FCC05E ; Bits of IST are numbered for LSb (0) to MSb (7) ; ; Bit Meaning ; --- ------- ; 0 Drive 0 disk inserted ; 1 Drive 0 button pressed ; 2 Drive 0 R/W completed ; 3 Logical OR of bit 0,1 & 2 ; 4 Drive 80 disk inserted ; 5 Drive 80 button pressed ; 6 Drive 80 R/W completed ; 7 Logical OR of bit 4,5 & 6 AdrMk1 .Equ IIob+8 ; 5 values that indicate start and end of address field $FCC050 AdrMk2 .Equ AdrMk1+1 These seem to be overlapping w/ some of the good stuff in $FCC052 the main IIob? Maybe the two purposes are mutualy exclusive. AdrMk3 .Equ AdrMk1+2 $FCC054 AdrMk4 .Equ AdrMk1+3 $FCC056 AdrMk5 .Equ AdrMk1+4 $FCC058 .Page ; Following 3 byte counter controls both testing ; for DIP and shutting off teh motors. When WtLow .Equ Globals ; the low 2 bytes = 0 then test for DIP. When WtMid .Equ WtLow+1 ; the third byte becomes 0 the heads are parked WtHih .Equ WTLow+2 ; and the motors are turned off $FCC080/082/084 ; For timing and space purposes during writing ; of data, an indexed by "y" through zero INXPTRL .Equ Globals+3 ; pge instruction is used. The two bytes INXPTRH .Equ INXPTRL+1 ; hold the base address for the index. $FCC086/088 ; Some constants for timing purposes K000 .Equ Globals+5 ; A constant '00' K0FF .Equ K000+1 ; A constant 'FF' $FCC08A/08C ; Following 8 locations hold error counters for ; various read errors. The first three are for ; error w/ reading data and the last five are ; for errors associated w/ the header. STSLP .Equ GLOBALS+8. ; Read Data Starting Bitslip $FCC090 BSCNT .Equ StSlp+1 ; Read Data ending Bitslip $FCC092 CSERROR .Equ StSlp+2 ; Read data Checksum error $FCC094 RASTRT .Equ StSlp+3 ; Read Address Starting Bitslip $FCC096 RAEND .Equ StSlp+4 ; Read Address Ending Bitslip $FCC098 RASCTR .Equ StSlp+5 ; Read Address wrong sector $FCC09A RATRK .Equ StSlp+6 ; Read Address wrong track $FCC09C RACSUM .Equ StSlp+7 ; Read Address Checksum error $FCC09E ERRLEN .Equ 7 ; 8 bytes, zero based CSMFND .Equ Globals+16. ; CHECKSUM read from disk $FCC0A0 VOLFND .Equ CsmFnd+1 ; 0 = UniFile/DuoFile, 1 = Lisa, 2 = Mac $FCC0A2 SDFND .Equ CsmFnd+2 ; SIDE FOUND $FCC0A4 SECFND .Equ CsmFnd+3 ; SECTOR FOUND $FCC0A6 TRKFND .Equ CsmFnd+4 ; TRACK FOUND $FCC0A8 CSUM .Equ CsmFnd+5 ; Checksum calculated from ADDRESS data $FCC0AA ADRSLEN .Equ 4 ; LENGTH OF ADDRESS HEADER - 1 TrkFlg .Equ Globals+22. $FCC0AC MtrFlg .Equ TrkFlg+1 $FCC0AE StpAmt .Equ TrkFlg+2 $FCC0B0 Direct .Equ TrkFlg+3 $FCC0B2 IndexL .Equ Globals+26. $FCC0B4 IndexH .Equ IndexL+1 $FCC0B6 RangeL .Equ IndexL+2 $FCC0B8 RangeH .Equ IndexL+3 $FCC0BA CPBY01 .Equ Globals+30. ; Composite byte formed from BUFFER[ 2FF:301 ] $FCC0BC CPBY02 .EQY CPBY01+1 ; [ 3FE:3FF ] $FCC0BE CPCKSUM .Equ Globals+32. ; Composite byte formed from 3 checksum bytes $FCC0C0 CKSUM1 .Equ CPCKSUM+1 ; First checksum byte $FCC0C2 CKSUM2 .Equ CPCKSUM+2 ; Second shecksum byte $FCC0C4 CKSUM3 .Equ CPCKSUM+3 ; Third checksum byte $FCC0C6 TCKSM1 .Equ Globals+36. ; During a read of data, the checksum is read $FCC0C8 TCKSM2 .Equ TCKSM1+1 ; into "CKSM1..3". A new checksum is created $FCC0CA TCKSM3 .Equ TCKSM1+2 ; and stored in these 3 bytes to verify matters $FCC0CC TEMPSEC .Equ Globals+39. ; TEMPRARY SECTOR COUNTER USED BY FORMAT $FCC0CE .Page ;-- ; LOCAL VARIABLES USED IN ONE OR SEVERAL ROUTINES ;++ RWCSMFLG .Equ LOCALS ; Flag fro usage of host supplied checksum DELAY .Equ LOCALS+1 ; COMPUTED DELAY FOR TOTAL SEEK Sv1 .Equ LOCALS+2 ; storage during Write16 Sv2 .Equ Sv1+1 Sv3 .Equ Sv1+2 Sv4 .Equ Sv1+3 TEMP1 .Equ Locals+6. ; 2 Locations for temporary by many routines TEMP2 .Equ TEMP1+1 DatMk1 .Equ Locals+8 ; 5 values that indicate start and end of Data field DatMk2 .Equ DatMk1+1 DatMk3 .Equ DatMk1+2 DatMk4 .Equ DatMk1+3 DatMk5 .Equ DatMk1+4 LOWCNT .Equ LOCALS+13. ; Holds value for physiacl interleave count HIHCNT .Equ LOWCNT+1. ; Same but opposite/complimentary value CNTPTR .Equ LOWCNT+2. ; Pointer to which cnt to use ( high or low ) TOTCNT .Equ LOWCNT+3. ; Total count of sectors written TEMP3 .Equ Locals+17. TEMP4 .Equ TEMP3+1 RtyFlg .Equ Locals+19. ; flag for use in BadAddr error handling Uu6 .Equ Locals+20. ; 2 unused locations Cmdx .Equ Locals+21. SaveL .Equ Locals+22. SaveH .Equ Locals+23. CmdLeng .Equ 3F ; 64 byte ring buffer of 8 byte IOB's SavIndex .Equ 80 ; *** NOTE -- Ram from 'C0' to 'FF' is used by the 68K as parameter memory *** LSTUSED .Equ 0BF ; last used location in the ZERO PARE RAM .Page ;-- ; ; CONSTANTS ; ;++ BUFR12SZ .Equ 0B ; LENGTH OF 12 BYTE BLOCK HEADER - 1 NIBLRETR .Equ 20 ; THE NUMBER OF NIBBLES READ SEARCHING FOR THE ; FIRST ADDRESS MARK DURING A READ MAXTRACK .Equ 4F ; MAXIMUM TRACK NUMBER: 79. MINTRACK .Equ 0 ; MIMIMUM TRACK NUMBER: 0 MAXCLASS .Equ 04 ; Maximum track class value -- range from 0..4 MINSECNT .Equ 08 ; Minimum sector count MAXSECNT .Equ 0C ; Maximum sector count MINSPEED .Equ 0D4 ; Minimum speed value MAXSPEED .Equ 038 ; Maximum speed value -- Low # = high speed OkDly .Equ 28. CNFMVAL .Equ 0FF ; Format configuration check byte LOW6 .Equ 3F ; mask for low 6 bit MaxCmd .Equ 09 ; 10 commands return FDirH ( -1 ) CmdNumb .Equ 07 ; Seven commands nao accessed through '81' NullCmd .Equ 080 ; Null/Handshake command RwtsCmd .Equ 091 ; Read/Write Track/Sector command value LwCmdNo .Equ 083 ; Lowest command number ( not including '81' ) ClStsCmd .Equ 085 ; Command to clear interrupt status WrtCmd .Equ 01 ; Value of command to write data to disk WrtBfCmd .Equ 08 ; Write data, brute force method FrmtDsk .Equ 03 ; Value of command host to to format disk VrfyDsk .Equ 04 ; Value of command host to to verify disk FrmtTrk .Equ 05 ; Value of command from host to format a track VrfyTrk .Equ 06 ; Value opf command from host to verify a track ADM1 .Equ 0D5 ; Address mark one ADM2 .Equ 0AA ; Address mark two ADM3 .Equ 096 ; Address mark three DDM3 .Equ 0AD ; Data mark three BitSlp1 .Equ 0DE ; Bit slip mark one BitSlp2 .Equ 0AA ; Bit slip mark two RclStep .Equ 4. ; # of steps to take away from Trk00 during recal OneScc .Equ 200. ; constant for a one second wait TmOutRcl .Equ 100. ; Timeout for recal wait RdAdrTmt .Equ 08. ; Tiomeout for looking for address header IWMMode .Equ 01F ; constant to setup IWM modes TurnRound .Equ 08. ; 5*8=40 msec turn around time for changing directions Lrge .Equ 05. Smal .Equ 01. TblJmp .Equ 09. WHih .Equ 17. ; '11' hex WLow .Equ 00. tLow .Equ 20. ; ERROR NUMBERS GErrCmd .Equ 01 ; Gobyte error: Invalid command GErrDrv .Equ 02 ; Gobyte error: Invalid drive number GErrSid .Equ 03 ; GoByte error: Invalid side number GErrSec .Equ 04 ; Gobyte error: Invalid Sector number GErrTrk .Equ 05 ; Gobyte error: Invalid Track number GErrMsk .Equ 06 ; Gobyte error: Invalid mask GErrClm .Equ 07 ; Gobyte error: No clamped disk in drive GErrEna .Equ 08 ; Gobyte error: Drive not enabled GErrIntr .Equ 09 ; Gobyte error: Pending interrupts not cleared GErrFmPr .Equ 10. ; Gobyte error: Invalid format parameter PErrROM .Equ 11. ; Program error: ROM test failed PErrInt .Equ 12. ; Program error: Random IRQ, NMI or BRK DErrCal .Equ 13. ; Drive error: time out while looking for track zero IWMError .Equ 14. ; Fatal error: IWM doesn't respond to commands StepErr .Equ 15. ; Handshake diod not occur when stepping DErrTk0 .Equ 16. ; Drive Error: Unable to leave track zero location SErrProt .Equ 20. ; Errstat error: Write protect error SErrFrmt .Equ 21. ; Errstat error: Can't verify disk SErrClmp .Equ 22. ; Errstat error: Unable to clamp disk SErrRd .Equ 23. ; Errstat error: Read error SErrWr .Equ 24. ; Errstat error: Write error SErrUclmp .Equ 25. ; Errstat error: Unable to unclamp diskette SErrNoA9 .Equ 26. ; Errstat error: Cannot find A9's during chkspd SErrTmt .Equ 27. ; Errstat error: Unable to adjust speed w/in timeout SErrM1Tk .Equ 28. ; Errstat error: Cannot write speed track ErrHdr .Equ 30. ; UnderRun while writing header ErrWrt .Equ 31. ; UnderRun while writing data fields .Page ;++ ; ; Data Buffer equates and Bad Block equates ; ;-- StackSt .Equ 0CF ; Init stack to "01CF" -- push down stack SctrCnt .Equ 01D0 ; During VERIFY, will no. of bad sectors TrkNumb .Equ SctrCnt+1 ; Track number where bad sector occurred SidNumb .Equ SctrCnt+2 ; Side number where bad sector occurred SctrSav .Equ SctrCnt+3 ; Start of buffer where sector numbers are saved Page01 .Equ 100 ; last 12 bytes of data are for read/write Bufr12 .Equ 1F4 ; last 12 bytes of data for raed/write Page02 .Equ 200 ; 256 bytes of data for read/write Page03 .Equ 300 ; " Pg2Len .Equ 0FF ; # of bytes to read during Wrbf02 loop Pg3Len .Equ 0FE ; # of bytes to read during Wrbf03 loop .Page ;-- ; I/O Space ;++ IOSpace .Equ 800 ; name for beginning of I/O space offsets Off .Equ 00 ; Offset to switch a phase off On .Equ 01 ; Offset to switch a phase on Zero .Equ 00 ; Offset to drive zero Eighty .Equ 01 ; Offset to drive eighty Low .Equ 00 ; PwmEna + Low enables output of PWMReg High .Equ 01 InWard .Equ 00 ; direction offsets OutWard .Equ 01 CA0 .Equ IOSpace ; Control signal 0 for MCI PAL in Sony drive CA1 .Equ IOSpace+2 ; signal 1 CA2 .Equ IOSpace+4 ; signal 2 LStrb .Equ IOSpace+6 ; Load strobe -- 0 to 1 to 0 will strobe PAL MtEna .Equ IOSpace+8 ; Enables output of DrvEna DrEna .Equ IOSpace+10. ; = 0 --> drive 0, = 1 ==> drive 80 Q6L .Equ IOSpace+12. ; Low = Read or Write Q6H .Equ Q6L+1 ; High = Sense or Write Load Q7L .Equ IOSpace+14. ; Low disables writing to disk Q7H .Equ Q7L+1 ; Enables /WrReq output of IWM CntEna .Equ IOSpace+16. ; low enables PWM counter/comparator PwmEna .Equ IOSpace+22. ; High enables pulses to Sony, else always low DisL .Equ IOSpace+24. ; Memory enable for the 68K DisH .Equ DisL+1 ; Memory disable for the 68K Side0Sel .Equ IOSpace+26. ; Selects side 0 Side1Sel .Equ Side0Sel+1 ; Selects side 1 BootL .Equ IOSpace+28. ; Disk Diag Line; when High then I'm listening BootH .Equ BootL+1 FDirL .Equ IOSpace+30. ; Deselects the interrupts to the 68K FDirH .Equ FDirL+1 ; Selects the interrupts to the 68K PWMReg .Equ IOSpace+32. ; Selects the PWM register for writing ;