-not a Macintosh disk- BLUV0.90 Twiggy Image LOވTF'O |||a2||a$&<tra |4(TB&raNJ(fNuJAgPBg/J8fBg`?<?/a:J_g(Glz|N |||pNSARB`NuNVH0. a |B( @ B AnB(| |݁g |B@("n2h_|a@A"n0<H"H "H"H" QLN^ _ NH2<S@o Ah:<` 2<A|:<6" @n2BDBB(`EB@nAJEk2<`BA4LNu Xc"A)-*S#e CNDISK READ ERROR BLANKs  SONYREAD.TEXT( 2 SONYHI2.TEXTs2^ MAC.BOOT.TEXTz^_ MOCPASLIB.OBJ5_`L1.OBJ*z`p SONYHI.OBJsp SONYTEST.RSRCs SONYTEST.TEXTs SONYTEST.OBJs SONYUTIL.OBJsSTL.TEXT*SMR.TEXT*c SONYMID.TEXTs=SONYFORMAT.TEXTs=i SONYUTIL.TEXTsis SONYMID.OBJssv SONYLOW.OBJsv SONYMID2.TEXTs SONYHI1.TEXTs NEWTEST.TEXTsT1.OBJt os SONYLOW.TEXTs; SONYMID1.TEXTs; SONYHI.TEXTs3. "6F^5D!$ǐ^   n>pAdrMks ".Byte $D5,$AA,$96,$DE,$AA,$FF DtaMks ".Byte $D5,$AA,$AD,$DE,$AA,$FF MarkTbl ".Byte $FF,$3F,$CF,$F3,$FC,$FF ;self-sync pattern ".Byte $D5,$AA ;actual header ($AD written separately) SetUpPoll ,LEA SCCRBase+AData,A6 ; SCC A-reg data ,LEA AVBufA,A5 ; 6522 A-reg has head sel, wait/req ,MOVE.L SP,PollStack ; init PollStack at current stack level ,ADD.L D0,PollStack ; compensate for 1 or 2 levels ,ORI #$0300,SR ,RTS RdAddrSetup MOVEQ #8,D0 ; init PollStack 8 bytes down ,BSR.S SetUpPoll ,MOVEQ #RdDtaAdr,D0 ,BSR AdrDisk RdAddr LEA AdrMks,A2 ,MOVE.L JRdAddr,-(SP) ,RTS RdData LEA DtaMks,A1 ,MOVE.L JRdData,-(SP) ,RTS WrData LEA MarkTbl,A2 ,MOVE.L JWrData,-(SP) ,RTS 3. "6F^5D!$ǐ^5AA; File: Work2:SonyHi2 ;___________________________________________________________________ ; ; Hi Hardware Control Routines ;___________________________________________________________________ SetRW ,LEA RWFlag,A0 ,MOVE.W D3,(A0) ; control value ,RTS SetErrStp LEA ErrStpFlag,A0 ,MOVE.W D3,(A0) ; control value ,RTS SetWrData LEA randomData,A0 ,MOVE.W D3,(A0) ; control value ,RTS SetSide LEA SideFlag,A0 ,MOVE.W d3,(A0) ; control value ,RTS LiteButton MOVE.L (A0),-(SP) ; highlight the button ourselves ,MOVE.W #inButton,-(SP) ,_HiLiteControl ,RTS DarkButton MOVE.L (A0),-(SP) ; unhighlight the button ,CLR.W -(SP) ,_HiLiteControl ,RTS WaitMBUp BTST #VSW,AVBufM ,BEQ.S WaitMBUp ,MOVE.W #600,D0 ; wait 60 ms debounce time ,JSR WakeUp ,BTST #VSW,AVBufM ,BEQ.S WaitMBUp ,RTS ToSetEnb MOVEQ #MtrOnAdr,D0 ; sense current dip state ,JSR AdrAndSense ; address it ,BMI.S TurnOn ; if high, turn it on TurnOff MOVEQ #MtrOffAdr,D0 ,MOVEQ #1,D1 ; control value will be 1 ,MOVEQ #0,D4 ; power off time ,BRA.S TurnOn1 TurnOn MOVEQ #MtrOnAdr,D0 ,MOVEQ #0,D1 ; control value will be 0 ,MOVE.W #4000,D4 ; power-on wait time TurnOn1 LEA DskEnbCtl,A2 ; make sure the control is right ,MOVE.L CRefCOS(A2),-(SP) ; theControl handle ,LEA EnbHiName,A0 ,TST.W D1 ,BNE.S @3 ,LEA EnbLoName,A0 @3 MOVE.L A0,-(SP) ,JSR AdrAndStrb ,_SetCTitle ,MOVE.W D4,D0 ; power wait time ,JSR WakeUp ,RTS NotReady LEA NtRdyNote,A6 ,LEA RWFlag,A0 ,TST.W (A0) ; do we want to write? ,BEQ.S @1 ; ok if not ,MOVEQ #WrProtAdr,D0 ; sense current wp state ,JSR AdrAndSense ; address it ,BMI.S @1 ; br if not write protected ,LEA WrProtNote,A6 @1 BSR DrawNote ,MOVEQ #-1,D0 ; note failure for those who care ,RTS ReadyCk MOVEQ #DIPAdr,D0 ; check for disk-in-place ,JSR AdrAndSense ,BPL.S @2 @1 MOVEQ #-1,D0 ; not ready ,RTS @2 MOVEQ #MtrOnAdr,D0 ,JSR AdrAndSense ,BMI.S @1 ; br if motor is off ,LEA RWFlag,A0 ,TST.W (A0) ; do we want to write? ,BEQ.S @3 ; ok if not ,MOVEQ #WrProtAdr,D0 ; sense current wp state ,JSR AdrAndSense ; address it ,BPL.S @1 ; error if write protected @3 MOVEQ #0,D0 ,RTS ClearCnts LEA Pass,A0 ,LEA AECount,A1 ,LEA DCount,A2 ,MOVE.W #320,D0 @1 CLR.W (A0)+ ,CLR.W (A1)+ ,CLR.W (A2)+ ,SUBQ.W #2,D0 ,BGT.S @1 ,LEA TrkCnts,A0 ,MOVEQ #-1,D0 @2 CLR.W (A0)+ ,DBRA D0,@2 ,LEA PassNote,A0 ; ,CLR.L NoteValOS(A0) ,LEA BadAdrNote,A0 ; ,CLR.L NoteValOS(A0) ,LEA BadDtaNote,A0 ,CLR.L NoteValOS(A0) ,PEA memClip ,_EraseRect ,BSR DrawBuf ,RTS ToFmtTrk ,BSR ReadyCk ; must have dip first ,BNE NotReady ; ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,MOVE.W SideFlag,D1 ;See which side to read ,beq @10 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @10 JSR ToAdrDisk ; set us looking at read data ; ,JSR TrkFormat ,BEQ.S @1 @0 LEA FmtBadNote,A6 ,NEG.L D0 ; make it a positive number ,MOVE.L D0,NoteValOS(A6) ; show error code ,BSR DrawNote ,BRA.S @2 @1 LEA TFmtOKNote,A6 ,BSR DrawNote @2 RTS ; ; ToFormat ,BSR ReadyCk ; must have dip first ,BNE NotReady ,LEA FmtDskCtl,A0 ,BSR LiteButton ,LEA FmtInPgNote,A6 ,BSR DrawNote ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,MOVE.W SideFlag,D1 ;See which side to read ,beq @10 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @10 JSR ToAdrDisk ; set us looking at read data ,JSR Format ,BEQ.S @1 @0 LEA FmtBadNote,A6 ,NEG.L D0 ; make it a positive number ,MOVE.L D0,NoteValOS(A6) ; show error code ,BSR DrawNote ,BRA.S @2 @1 LEA FmtVerNote,A6 ; note that we are now verifying ,BSR DrawNote ,JSR FmtVerify ,BNE.S @0 ,LEA FmtOKNote,A6 ,BSR DrawNote @2 LEA FmtDskCtl,A0 ,BSR DarkButton ,BSR UDTrack ,RTS ToEject MOVEM.L A0-A6/D1-D7,-(SP) ,JSR Eject ,MOVEM.L (SP)+,A0-A6/D1-D7 ,RTS ToRecal BSR ReadyCk ; must have dip first ,BNE NotReady @1 MOVEM.L A0-A6/D1-D7,-(SP) ,JSR Recal ,MOVEM.L (SP)+,A0-A6/D1-D7 ,BEQ.S @2 ; br if successful ,LEA CantStpNote,A6 ; note that we can't step ,BSR DrawNote ,BRA.S @3 @2 MOVEQ #0,D6 ; set speed for track 0 ,JSR SetSpeed @3 BSR UDTrack ; note the track we are on ,BSR DrawBuf ; and show speed table values, if needed ,RTS SetSeq1 MOVEQ #1,D4 ,BRA.S SetSeq SetSeq2 MOVEQ #2,D4 ,BRA.S SetSeq SetSeq3 MOVEQ #3,D4 ,BRA.S SetSeq SetSeq4 MOVEQ #4,D4 SetSeq ,MOVEM.L A3/D3-D4,-(SP) ,LEA Seq1Ctl,A3 ; first seq control ,MOVEQ #1,D3 ; loop counter ,LEA SeqType,A0 ,MOVE.W D4,(A0) ; save seq type @1 MOVE.L (A3),-(SP) ; track scroll control handle ,CLR.W -(SP) ; set to 0 ,CMP.W D3,D4 ,BNE.S @2 ,ADDQ.W #1,(SP) ; except button being set @2 _SetCtlValue ,ADD #CDtaSize,A3 ,ADDQ.W #1,D3 ,CMP.W #4,D3 ,BLE.S @1 ,MOVEM.L (SP)+,A3/D3-D4 ,RTS ContTest ,BSR ReadyCk ; must have dip first ,BNE NotReady ,LEA StTestCtl,A0 ,BSR LiteButton ,LEA PassNote,A6 ; ,BSR DrawNote ,LEA BadAdrNote,A6 ; ,BSR DrawNote ,LEA BadDtaNote,A6 ,BSR DrawNote ,ORI #$0100,SR ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA recalCount,A0 ,MOVE.W (A0)+,(A0) ; recal after this many errors TrkTstStrt LEA PwrCount,A0 ; power down after this many passes ,MOVE.W (A0)+,(A0) TrkTstLoop ; first, seek accordingly ,JSR GetDrv1 ; figure out the current track ,MOVE.W Track(A1,D1),D6 ,and.w #$00FF,d6 ,MOVE.W SeqType,D0 ; 1=rndm,2=stc,3=seq+,4=seq- ,SUBQ.W #1,D0 ,BNE.S @1 ,BSR Random80 ; returns a random number in D0 ,MOVE.W D0,D6 ,BRA.S @3 @1 SUBQ.W #1,D0 ,BEQ.S @3 ; for 2 it all stays the same ,SUBQ.W #1,D0 ,BNE.S @2 ,ADDQ.W #1,D6 ; 3=incremental ,CMP.W #80,D6 ; maxed? ,BLT.S @3 ,MOVEQ #0,D6 ; wrap to 0 ,BRA.S @3 @2 SUBQ.W #1,D6 ; 4=decremental ,BPL.S @3 ,MOVE.W #79,D6 @3 JSR Seek ; go to it ,MOVEM.L (SP),D3-D7/A2-A6 ; make sure A5 is ok ,BPL.S @4 ,LEA BadSeekNote,A6 ; exit test on bad seeks . . . ,MOVE.L D0,NoteValOS(A6) ,BSR DrawNote ,BRA TrkTstExit ; see if it's time to check for thermal drifting . . . @4 BSR UDTrack ; note the track ,JSR GetDrv1 ,MOVE.B BadSpdInit(A1),BadSpdCnt(A1) CkDrift JSR GetDrv1 ,MOVE.W Track(A1,D1),D6 ; theTrack LoadBuf BSR FillBuffer ; fill the write buffer ,LEA TrkCnts,A6 ,CLR.L RSectMap(A6) ; clear sector bit maps ,CLR.L WSectMap(A6) ,CLR.W DataErr(A6) ,CLR.W AdrErr(A6) ,LEA passCount,A0 ,MOVE.W (A0)+,(A0) ; init pass count TTLoop LEA TagData,A0 ; clear tag data for each write ,CLR.L (A0)+ ,CLR.L (A0)+ ,CLR.L (A0)+ ,CLR (A0) ,MOVE.W SideFlag,D6 ; Which side? ,BEQ.S @1 ; br if not ,JSR RdAddr1Setup ; use a different routine ,BRA.S @2 @1 JSR RdAddrSetup ; read an address mark @2 MOVE.L PollStack,SP ; get rid of any poll data ,MOVE.W D0,DskErr ; was it good? ,BMI BadAMark ; branch if it wasn't ,MOVE.W #SeekErr,DskErr ; anticipate bad track number ,MOVE.W D1,D0 ,JSR GetDrv1 ,and.w #$00FF,d0 ,CMP.W Track(A1,D1),D0 ,BNE BadAMark ; make sure track number was right ,CLR.B DskVerify ; ,MOVE.W RWFlag,D0 ; doing writes? ,BEQ.S RdThisOne ; if not, just read . . . ,ST DskVerify ; for reads, use read verify mode ; the address mark was good; now see if we've already written this sector ,LEA TrkCnts,A0 ,MOVE.L WSectMap(A0),D4 ; get bitmap of sectors written ,BSET D2,D4 ; set bit ,BNE.S RdThisOne ; if already set, just read it to verify ; we haven't seen this one yet, so write it ,MOVE.L D4,WSectMap(A0) ; save it ,MOVE.W D2,TagData ; and write correct sector number ,LEA rwBuffer,A0 ,JSR WrData ; go write the sector ,MOVE.L PollStack,SP ; get rid of any poll data ,LEA TrkCnts,A6 ,TST.W D0 ; underrun? ,BEQ.S @3 ; go on if ok ,.WORD $FF30 ; trap for now . . . @3 MOVEQ #20,D0 ; make sure we don't try to read again ,JSR WakeUp ; for 2.0 ms after a write ,BRA NextSect ; go on if ok ; we already wrote this sector, so read it back in to verify it . . . RdThisOne MOVE.W D2,DskErr ; save the sector number ,LEA rwBuffer,A0 ; get someplace to stick data ,JSR RdData ; read in a sector ,MOVE.L PollStack,SP ; reset stack ,MOVE DskErr,D2 ; retrieve sector number ,MOVE D0,DskErr ; is the checksum right? ,BNE BadDMark ; branch if there was an error ,LEA TrkCnts,A6 ,MOVE.L RSectMap(A6),D4 ,BSET D2,D4 ; note that we've seen the sector ,MOVE.L D4,RSectMap(A6) ; go on to next sector ; process the next sector until we've done all 128 NextSect BTST #VSW,AVBufM ; loop if mouse button is not pressed ,BEQ TrkTst1Xit ; ,LEA passCount+2,A0 ,SUBQ.W #1,(A0) ; decrement the sector counter ,BNE TTLoop ; loop if we're not ,JSR GetDrv1 ; figure out the current track ,MOVE.W Track(A1,D1),D1 ; ,LSR.W #4,D1 ; divide by 16 to get speed group ,ADD D1,D1 ; make it a word offset ,MOVE.W SectBtMp(D1),D0 ; get bit map we should get ,LEA TrkCnts,A6 ,MOVE.L RSectMap(A6),D1 ; get bit map we actually got ,CMP.W D1,D0 ; the same? ,BEQ.S NxtSect1 ; br if so ,ADDQ.L #1,SectNFTotal(A6) ; otherwise, increment error count ,ADDQ #1,AdrErr(A6) ,BRA.S NxtSect1 ; SectBtMp .Word $0FFF ; sector map: 12 sectors ,.Word $07FF ; sector map: 11 sectors ,.Word $03FF ; sector map: 10 sectors ,.Word $01FF ; sector map: 9 sectors ,.Word $00FF ; sector map: 8 sectors NxtSect1 MOVEM.L (SP),D3-D7/A2-A6 ,BSR ErrUpdate ; display errors this pass and totals ,BSR DrawBuf ,LEA PwrCount,A0 ,TST.W (A0)+ ; never power down? ,BEQ.S @3 ; br if so ,SUBQ.W #1,(A0) ; decrement power count ,BGT.S @3 ,BSR TurnOff ,MOVE.W PwrTime,D2 ; power off time in seconds ,BEQ.S @2 ; br if 0 @1 MOVE.W #5000,D0 ; wait 1/2 second ,JSR WakeUp ,BTST #VSW,AVBufM ; loop if mouse button is not pressed ,BEQ.S @2 ; ,SUBQ.W #1,D2 ,BGT.S @1 @2 BSR TurnOn ,BRA TrkTstStrt @3 BRA TrkTstLoop TrkTst1Xit BSR WaitMBUp ; then wait for it to go high again TrkTstExit ANDI #$F8FF,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ,LEA StTestCtl,A0 ,BSR DarkButton ,BSR ErrUpdate ; display errors this pass and totals ,BSR DrawBuf ,RTS ; we got a data mark error so count it by incrementing count BadDMark LEA TrkCnts,A6 ,ADDQ #1,DataErr(A6) ,CMP.W #NoDtaMkErr,D0 ,BNE.S @1 ,ADDQ.L #1,DMNoneTotal(A6) ,BRA.S @4 @1 CMP.W #BadDCkSum,D0 ,BNE.S @2 ,ADDQ.L #1,DM1Total(A6) ,BRA.S @4 @2 CMP.W #BadDBtSlp,D0 ,BNE.S @3 ,ADDQ.L #1,DM2Total(A6) ,BRA.S @4 @3 CMP.W #DataVerErr,D0 ,BNE.S @4 ,ADDQ.L #1,RdVerTotal(A6) @4 Ck4Recal MOVE.W ErrStpFlag,D0 ; stop on error? ,BNE.S TrkTstExit ; exit if so ,LEA recalCount,A0 ; recal on this error? ,TST.W (A0)+ ,BEQ.S @1 ; br if never recal ,SUBQ.W #1,(A0) ; recal error count reached? ,BGT.S @1 ; br if not ,MOVEM.L (SP),D3-D7/A2-A6 ,JSR GetDrv1 ; figure out the current track ,MOVE.W Track(A1,D1),D6 ; save it in D6 ,BSR ToRecal ; recal and refig speeds ,JSR GetDrv1 ; ,JSR Seek ; go to it ,MOVEM.L (SP),D3-D7/A2-A6 ; make sure A5 is ok ,LEA recalCount,A0 ; ,MOVE.W (A0)+,(A0) ; reinit recal count @1 BRA NextSect ; handle address mark error BadAMark LEA TrkCnts,A6 ,ADDQ #1,AdrErr(A6) ,MOVE.W DskErr,D0 ,CMP.W #NoNybErr,D0 ,BEQ.S @0 ,CMP.W #NoAdrMkErr,D0 ; let no nib, no adr mk errs be = ,BNE.S @1 @0 ADDQ.L #1,AMNoneTotal(A6) ,BRA.S @4 @1 CMP.W #BadCkSmErr,D0 ,BNE.S @2 ,ADDQ.L #1,AM1Total(A6) ,BRA.S @4 @2 CMP.W #BadBtSlp,D0 ,BNE.S @3 ,ADDQ.L #1,AM2Total(A6) ,BRA.S @4 @3 CMP.W #SeekErr,D0 ,BNE.S @4 ,ADDQ.L #1,AM3Total(A6) @4 BRA.S Ck4Recal ; see if it's time to recal ;_______________________________________________________________________ ; ; ErrUpdate update the error count tables and displays them. ; ;_______________________________________________________________________ ErrUpdate LEA TrkCnts,A6 ,JSR Getdrv1 ,MOVE.W Track(A1,D1),D6 ; get current track number ,clr.l d5 ,MOVEQ #0,D4 ,ADD D6,D6 ; double it since the tables are words ,LEA Pass,A1 ,ADD D5,A1 ; add side offset ,ADDQ #1,0(A1,D6.W) ; bump the pass count, this track ,ADDQ.L #1,PassTotal(A6,D4) ,LEA PassNote,A0 ; ,MOVE.L PassTotal(A6,D4),NoteValOS(A0) ,LEA DCount,A1 ,ADD D5,A1 ; add side offset ,MOVE DataErr(A6),D1 ,EXT.L D1 ,ADD D1,0(A1,D6.W) ; update the data error count ,ADD.L D1,DErrTotal(A6,D4) ; and total data errors ,LEA BadDtaNote,A0 ; ,MOVE.L DErrTotal(A6,D4),NoteValOS(A0) ,LEA AECount,A1 ,ADD D5,A1 ; add side offset ,MOVE AdrErr(A6),D1 ,EXT.L D1 ,ADD D1,0(A1,D6.W) ; update the address error count ,ADD.L D1,AErrTotal(A6,D4) ; and total address errors ,LEA BadAdrNote,A0 ; ,MOVE.L AErrTotal(A6,D4),NoteValOS(A0) ,LEA recalCount,A0 ,ADDQ.L #1,(A0) ; bump track count since last recal ,LEA OnlyNoteVal,A2 ; only change value ,ST (A2) ,LEA PassNote,A6 ; ,BSR DrawNote ,ST (A2) ,LEA BadAdrNote,A6 ; ,BSR DrawNote ,ST (A2) ,LEA BadDtaNote,A6 ,BSR DrawNote ,RTS ;_______________________________________________________________________ ; ; Random80 returns a pseudo-random number between 0 and 79. ; ; Algorithm is shift left and xor: ; new bit 0 := old bit 6 xor old bit 30 ; repeat shift and xor 7 times ;_______________________________________________________________________ Random80 MOVEQ #7,D1 ,LEA RndSeed,A0 ;get random seed ,MOVE.L (A0),D0 ,BNE.S RndLoop ,MOVE.L #$87654321,D0 ; init seed RndLoop LSL.L #1,D0 ,BMI.S MSBSet ,TST.B D0 ,BPL.S Next SetBit0 ADD #1,D0 ,BRA.S Next MSBSet TST.B D0 ,BPL SetBit0 Next SUB #1,D1 ,BNE RndLoop ,MOVE.L D0,(A0) ; update seed ,SWAP D0 ,CLR D0 ; clear non-random upper part ,SWAP D0 ,DIVU #80,D0 ; divide by 80 to get 0-79 remainder ,SWAP D0 ; put remainder into lower word ,RTS ;___________________________________________________________________ ; ; FillBuffer generates 512 bytes of data which it ; places in the write buffer, and 12 bytes which it places in TagData+1. ; ;___________________________________________________________________ FillBuffer LEA rwBuffer,A1 ; pointer to buffer ,LEA randomData,A0 ,TST.W (A0) ; use random data? ,BNE.S GenRandom ,MOVE #511,D2 ; set loop counter ,LEA theByte,A0 ,MOVE.W (A0),D0 ; current write nibble @1 MOVE.B D0,(A1)+ ; fill write buffer with spec'd data byte ,DBRA D2,@1 FillTag LEA TagData,A1 ; and tag data ,CLR.B (A1)+ ; clear sector number byte ,CLR.B (A1)+ ,MOVEQ #11,D2 @2 MOVE.B D0,(A1)+ ; set up rest of Tag Data buffer ,DBRA D2,@2 ,RTS GenRandom LEA RndSeed,A0 ; get random seed ,MOVE.L (A0),D0 ,MOVE.W #255,D2 ; loop count GenStart MOVEQ #7,D1 ,TST.L D0 ,BNE.S GenOne ,MOVE.L #$43218765,D0 GenOne LSL.L #1,D0 ,BMI.S @1 ,TST.B D0 ,BPL.S @2 @0 ADD #1,D0 ,BRA.S @2 @1 TST.B D0 ,BPL @0 @2 SUB #1,D1 ,BNE GenOne ,MOVE.W D0,(A1)+ ; store next value ,DBRA D2,GenStart ,MOVE.L D0,(A0) ; update seed ,BRA.S FillTag ; and fill Tag Buffer with last value . . . ; ; ; ToAdrDisk MOVEM.L A1-A2/D0-D1,-(SP) ; set A0 to VBase pointer also ,JSR AdrDisk ,MOVEM.L (SP)+,A1-A2/D0-D1 ,RTS ; 3. "6F^5P:H r^u,,; File: Mac.Boot.Text ;_______________________________________________________________________ ; ; MacIntosh Disk-Based Boot Code ; ; written by Larry Kenyon 9-Feb-83 ; ; This code goes into the two disk boot blocks and is loaded into RAM ; at location $10000 after ROM initialization is complete and a boot ; diskette is in place. ; ; When this code is entered, the interrupt system, memory manager, and ; ROM-based I/O drivers have been initialized. This code initializes ; the remainder of the system and determines the next file(s) to load in, ; using the file system: these are typically the debugger files (loaded ; above the application heap zone and stack) and the system finder program. ; A screen picture will be displayed if the appropriate file is on the ; boot diskette. ; ; Modification History: ; ; 08 Feb 83 LAK New Today. ; 07 Apr 83 AJH Complete rewrite of mainline; installed deep shit alerts ; 01 Apr 83 AJH Made it work on 512K system ; 27 May 83 AJH New Loader! ; 31 May 83 AJH MacSys.Code no longer necessary to boot ; 02 Jun 83 AJH cleared theScrap, set up vidPage launch param ; set up sysResName and put MacSys there ; 03 Jun 83 AJH KEYM -> KEYC; detached keyProcs and deep shit alerts ; 04 Jun 83 AJH implemented system heap sizing and page 2 reservation ; 05 Jun 83 AJH set up key repeat parms from parameter RAM ; 07 Jun 83 AJH set up master block start address, ext file system fields ; 08 Jun 83 AJH finderName is 12 long, not 16... ; 10 Jun 83 AJH added "Hello" fileName for initial launch ; 13 Jul 83 LAK changed CLR.L Keylast to CLR.W Keylast. ; 09 Aug 83 AJH fixed bug releasing bootAlerts; misc cleanup ; 17 Aug 83 LAK added init of EvtBufLen; FinderName var moved in lomem. ; 20 Aug 83 LAK Added event queue count in header. Added scrap name in ; header. Changed param. memory for key stuff. Added param. ; mem. for click and caret. Added DoDetach for saving code. ; 28 Aug 83 AJH added whichAlerts option for DS alerts ; 04 Sep 83 LAK added CLR.L ResErrProc for resources, ; 05 Sep 83 SC scrap vars point to name ; 07 Sep 83 LAK added call to _ZeroScrap. optimized IO to make it fit. ; 13 Oct 83 LAK movescreen now uses CopyBits for Lisa compatibility; scrounged ; bytes from various places. ; To Do: ;_______________________________________________________________________ -.NoList ,.INCLUDE tlasm:SYSEQU.TEXT ,.INCLUDE tlasm:SYSMACS.TEXT ,.INCLUDE tlasm:GRAFEQU.TEXT ,.INCLUDE tlasm:GRAFTYPES.TEXT ,.INCLUDE tlasm:TOOLEQU.TEXT ,.INCLUDE tlasm:QUICKMACS.TEXT ,.INCLUDE tlasm:TOOLMACS.TEXT ,.INCLUDE Mac:FSEQU.TEXT ,.INCLUDE tlasm:RESEQU.TEXT ,.List ,.PROC LTEST1,0 ,.DEF RAMBoot ; first, initialize the event manager and the file system RAMBoot .WORD $4C4B ; boot code identifier ,BRA.S BootStart ; kick off the boot code ; configurable parameter area BootVersion .WORD $0070 ; boot block version number PageFlags .WORD $0000 ; no page 2 usage SysHeapSize .LONG $00004000 ; size of system heap (16K) SystemName .BYTE 6 ,.ASCII 'System ' ; name of system resource/code file ShellName .BYTE 6 ,.ASCII 'Finder ' ; name of system shell MBugName .BYTE 7 ,.ASCII 'Macsbug ' ; name of debugger DisName .BYTE 12 ,.ASCII 'Disassembler ' ; name of disassembler BSName .BYTE 10 ,.ASCII 'BootScreen ' ; name of bootScreen HelloName .BYTE 6 ,.ASCII 'Finder ' ; name of first program to run FCBNum .WORD 12 ; number of FCBs to allocate EventCount .WORD 30 ; number of event queue elements ScrapID .BYTE 9 ,.ASCII 'DeskScrap ' ; name of "the $crap" WhichAlerts .WORD 1 ; developer deep shits ; start of actual boot code. First adjust the size of the system heap BootStart ,MOVE.L SysZone,A0 ; get base of system heap ,ADD.L SysHeapSize,A0 ,_SetAppBase ; set size of system heap ,MOVE.L SysZone,TheZone ; make sure theZone is the system one ; now initialize the event manager and the file system ,MOVEQ #7,D0 ; clear 8 longs at AppPacks ,LEA AppPacks,A0 @1 CLR.L (A0)+ ,DBRA D0,@1 ;_______________________________________________________________________ ; ; InitEvents initializes the event manager by requesting memory from ; the storage allocator for the event buffer and marking each element ; as free. It also initializes the event queue and key repeat thresholds. ; ;_______________________________________________________________________ InitEvents ,MOVE.W EventCount,D2 ,MOVEQ #EvtQBlkSize,D0 ,MULU D2,D0 ,MOVE.L D0,D1 ; save a copy of the size ,_NewPtr ,SYS,CLEAR ; get memory for storage allocator ,LEA EvtBufCnt,A1 ,SUBQ #1,D2 ; set up lo mem event buffer count (-1) ,MOVE.W D2,(A1) ; EvtBufCnt ,CLR.L -(A1) ; EventQueue QTail ,CLR.L -(A1) ; EventQueue QHead ,CLR.W -(A1) ; EventQueue QFlags ,MOVE.L A0,-(A1) ; SysEvtBuf H; fill buffer with all ones InitEvLoop NOT.W (A0)+ ; 0000 -> FFFF ,SUBQ #2,D1 ; more to do? ,BNE.S InitEvLoop ; size must have been divisible by 4 ,MOVE.W #$FFEF,-(A1) ; SysEvtMask - enb all events except key up ,CLR.W KeyLast ; initialize keyboard repeat stuff ; initialize the keyboard repeat parameters from system parameter memory ,MOVEQ #-4,D1 ; mask for below(drop lower bits) ,MOVEQ #$F,D0 ; clear out high part of D0 ,MOVE.B SPKbd,D2 ; get threshold,repeat rate byte ,AND.B D2,D0 ; get repeat rate nibble ,ADD D0,D0 ; convert from 2/60 to 1/60 sec ,SWAP D0 ,MOVE.B D2,D0 ; get threshold byte ,LSR #2,D0 ; get in low order ,AND D1,D0 ; convert 4/60 to 1/60 sec ,SWAP D0 ,MOVE.L D0,KeyThresh ; set up parameters ,MOVEQ #$F,D0 ; clear out high part of D0 ,MOVE.B SPClikCaret,D2 ; get click, caret times ,AND.B D2,D0 ; get caret time ,LSL #2,D0 ; convert 4/60 to 1/60 sec ,MOVE.L D0,CaretTime ; set up parameters ,MOVE.B D2,D0 ; get click time ,LSR #2,D0 ; ,AND D1,D0 ; convert 4/60 to 1/60 sec ,MOVE.L D0,doubletime ; set up parameters ;_______________________________________________________________________ ; ; Routine: FSInit ; ; Function: File system initialization. Should only be called at system ; startup. Initializes FCB area, the VCBs, and file system Queue. ; ;_______________________________________________________________________ FSInit ; first, zero the low-memory fs area ,LEA FileVars,A0 ; initialize our lomem vars to 0 ,MOVEQ #-1,D1 ; esp. VCB, FS queue hdrs, params, FSBusy @1 CLR.W (A0)+ ,DBRA D1,@1 ; get some memory for the FCBs ,MOVEQ #FCBEntLen,D0 ; allocate the File Control Blocks ,MULU FCBNum,D0 ; number of bytes needed for FCBs ,ADDQ.W #2,D0 ; and 2 for length prefix ,MOVE.W D0,D1 ; and save in D1 ,_NewPtr ,SYS,CLEAR ; get buffer with D0 bytes in it. ,MOVE.L A0,FCBSPtr ; set the FCB pointer ; zero out the FCBs ,MOVE.W D1,(A0)+ ; first word is FCB part length ,MOVE.W #StrtDir,DRMstrBlk ; set up master block address ; install the boot-time deep shit alert table ,LEA BootDSTab,A0 ; get the address of the table ,MOVE.L A0,DSAlertTab ; install it ; now mount some disks . . . ,SUB #IOQElSize,SP ; allocate space for the request ,MOVE.L SP,A0 ; point to param block ,MOVE BootDrive,IODrvNum(A0) ; set up drive number ,_MountVol ; mount internal drive ,BNE CantMount ; branch if there's an error ,ADD #IOQElSize,SP ; deallocate param block ; move in the name for system.rsrc ,LEA SysResName,A1 ; here's where is goes ,LEA SystemName,A0 ; here's where it comes from ,MOVEQ #16,D0 ; move 16 bytes worth ,_BlockMove ; move it in ; put up the boot screen if we can find one ,_HideCursor ,LEA BSName,A1 ; point to the name of the boot screen ,MOVEQ #1,D3 ; signal to load onto screen ,BSR LoadOne ; load it in if we can ,MOVE D0,-(SP) ; remember if we have a bootScreen ,BNE.S SkipMove ; if we didn't get one, skip ,BSR MoveInScreen ; move in the bootScreen ; now try to init resources so we can use text in our alerts SkipMove ,_ShowCursor ,SUBQ #2,SP ; make room for function result ,CLR.L ResErrProc ; no error proc to start . . . ,_InitResources ; read in system.rsrc ,TST.W (SP)+ ; did we get it ? ,BMI BadResource ; if not, give up ; now the resources are alive, we can load in the deep shit alert table ; stored in system.rsrc for the next level of booting. ,MOVE (SP)+,D7 ; get bootScreen result in D7 ,SUBQ #4,SP ; make room for the result ,MOVE.L #$44534154,-(SP) ; push "DSAT" type ,CLR.W -(SP) ; type 0 is for booting ,_GetResource ; get it ,MOVE.L (SP)+,D5 ; get handle to it ,BEQ.S @1 ; if none, skip ,MOVE.L D5,A0 ; get it in an address register ,MOVE.L (A0),DSAlertTab ; install it ; now we can initialize the font manager so alerts ; can use text. Then display the "welcome to Mac OS" alert (if no bootScreen) @1 ,_InitFonts ,MOVEQ #40,D0 ; get alert ID ,BSR BootAlert ; display it if we should ; adjust bufPtr based on the flags word to reserve memory for page 2 sound and video ,MOVE.L #$00000600,D0 ; assume sound page 2 ,MOVE.W PageFlags,D1 ; any page 2 usage? ,BEQ.S LoadMBug ; if none, skip ,BPL.S @2 ; if sound, go subtract ,MOVEQ #1,D0 ,ROR.W #1,D0 ; ($00008000) for video, reserve 32K @2 ,SUB.L D0,BufPtr ; reserve additional space ; now try to load Macsbug LoadMBug ,SUB.L #$400,BufPtr ; leave space for macsbug globals ,LEA MBugName,A1 ; point to fileName of debugger ,BSR LoadOnStack ; try loading it ,BNE NoMBug ; go on if there's no debugger ,JSR (A1) ; tell it to install itself ,MOVEQ #-10,D0 ; alert saying we got MacsBug ,BSR BootAlert ; display it if we should ; We got MACSBUG so try for the disassembler ,LEA DisName,A1 ; point to the fileName ,BSR LoadOnStack ; search for disassembler ,BNE.S LoadSystem ; go on if there's no disassembler ,JSR (A1) ; tell it to install itself ,MOVEQ #-11,D0 ; alert saying we got the disassembler ,BSR BootAlert ; display it if we should ; now load the RAM based OS into the system heap LoadSystem ,LEA SysResName,A1 ; point to fileName ,MOVEQ #-1,D3 ; signal its to be loaded on the heap ,BSR LoadOne ; try to load MacSys.Code ,BNE NoMacSys ; if there's no system RAM code, skip ,JSR (A1) ; tell it to install itself ,MOVEQ #-12,D0 ; alert saying we loaded it ,BSR BootAlert ; display it if we should ,BRA.S NoMacSys ; InstlKMap loads the keyMap resource specified by D1 InstlKMap SUBQ #4,SP ,MOVE.L #$4B455943,-(SP) ; KEYC is resType ,MOVE.W D1,-(SP) ,_GetResource ,MOVE.L (SP)+,D0 ; get handle to key map proc and set CC ,MOVE.L D0,A0 ,RTS ; Common detach routine. Entered with: ; Resource Handle to be detached is at (SP)+ ; A3 points to low memory address in which to stuff the handle DoDetach ,MOVE.L A0,D0 ; get ds alerts handle ,BEQ.S adios ; if none, skip ,MOVE.L (A0),(A3) ; set up pointer ,MOVE.L A0,-(SP) ,_DetachResource adios ,RTS ; now load in the post-boot deep shit alert table NoMacSys ,MOVE.L SysZone,RamBase ; base traps on system heap base ,MOVE.L D5,-(SP) ; push boot DS alerts handle ,_ReleaseResource ; free up their space ,SUBQ #4,SP ; make room for function result ,MOVE.L #$44534154,-(SP) ; push "DSAT" resource class ,MOVE WhichAlerts,-(SP) ; sysAlerts are ID 1 ,_GetResource ,MOVE.L (SP)+,A0 ,LEA DSAlertTab,A3 ; detach key 2 ,BSR DoDetach ; now load the keyboard mapping tables ,MOVEQ #1,D1 ; install the keyboard mapping procs ,BSR InstlKMap ,LEA Key1Trans,A3 ; detach key 2 ,BSR DoDetach ,MOVEQ #2,D1 ; install keyPad mapping proc ,BSR InstlKMap ,LEA Key2Trans,A3 ; detach key 2 ,BSR DoDetach ; well, now the world is in pretty good shape so go try to chain in the ; shell. First allocate the AppParmHandle. ,MOVEQ #12,D0 ;allocate a tiny handle ,_NewHandle ,SYS,CLEAR ;allocate it zeroed ,MOVE.L A0,AppParmHandle ;save it in low memory ,MOVE.L (A0),A0 ;deref it ChainInShell InitLoader ,CLR.W CurApRefNum ; and no opening app open ,_InitApplZone ,_RDrvrInstall ;fix up ram based drivers ; move in the name for system.rsrc ,LEA scrapTag,A1 ; here's where is goes ,MOVE.L A1,scrapName ; point scrapName to location ,LEA ScrapID,A0 ; here's where it comes from ,MOVEQ #16,D0 ; move 16 bytes worth ,_BlockMove ; move it in ,SUBQ #4,SP ,_ZeroScrap ; init the scrap ,ADDQ #4,SP ,LEA ShellName,A0 ,LEA FinderName,A1 ,MOVEQ #16,D0 ; move 16 bytes worth ,_BlockMove ,CLR.W -(SP) ; no page 2 used for shell ,CLR.L -(SP) ; nothing to pass ,PEA HelloName ; chain this in . . . ,MOVE.L SP,A0 ,_Launch ; launch the shell ; if it came back from the chain, there must be an error so post an alert ,MOVEQ #41,D0 ; get alert ID for "can't load shell" ,_SysError ; signal the alert ReBoot ,SUB #IOQElSize,SP ; make room for pBlock ,MOVE.L SP,A0 ,MOVE.W #DskRfN,IORefNum(A0); driver refnum ,MOVE.W #EjectCode,CSCode(A0) ,MOVE.W BootDrive,IODrvNum(A0) ,_Control ; eject the bad diskette ,ADD #IOQElSize,SP ; pop off the pBlock ,MOVE.L $400004,A0 ; get reboot address ,JMP (A0) ; BootAlert posts the boot alert in D0 only if we didn't have a boot screen BootAlert ,TST D7 ; did we get a boot screen? ,BEQ.S @1 ; if we did, skip ,_SysError ; post the alert @1 ,RTS ; all done ; NoMBug handles the case when we cant find MacsBug. Deallocate the space ; reserved for MacsBug globals and go try to load in MacSys.Code NoMBug ,ADD.L #$0400,BufPtr ; deallocate mbug globals ,BRA.S LoadSystem ; go load in the system ; CantMount handles the case of not being able to mount the boot volume. CantMount BadResource ,MOVEQ #42,D0 ; get alert ID SigErr ,_SysError ; signal it ,BRA.S ReBoot ; better reboot ; LoadOne is the routine used for loading files during boot LoadOnStack MOVEQ #0,D3 ; signal we should load on the load stack LoadOne ,SUB #IOQElSize,SP ; make room for a parameter block ,MOVE.L SP,A0 ; make A0 point to it ,MOVEQ #-1,D2 ; error code ,LEA IOFileName(A0),A2 ; point to params we use ,MOVE.L A1,(A2)+ ; IOFileName(A0) ,CLR.L (A2)+ ; IODrvNum(A0), IORefNum(A0) use default drive? ,CLR.W (A2)+ ; IOFileType(A0) type 0, ok permissions ,MOVE.L #$11000,(A2) ; IOOwnBuf(A0) dedicated buffer saves time ,_Open ,BNE.S NotAround ,_GetEOF ,BNE.S CloseUp ,MOVE.L (A2)+,D4 ; IOLEOF(A0) get physical length in bytes ,MOVEQ #2,D6 ,ASL #8,D6 ; D6 := 512 (assume position is 512) ,SUB.L D6,D4 ; skip first block ,TST D3 ; what are we loading? ,BMI.S LoadOnHeap ; if negative, allocate on heap ,BNE.S LoadOnScreen ; if non-zero, load on screen ,MOVE.L BufPtr,A1 ; get top of code stack ,SUB.L D4,A1 ; A1=mem loc to read into LoadCommon ,;LEA IOBuffer(A0),A2 ,MOVE.L A1,(A2)+ ; IOBuffer(A0) ,MOVE.L D4,(A2)+ ; IOReqCount(A0) ,ADDQ #4,A2 ,MOVE.W #1,(A2)+ ; IOPosMode(A0) absolute positioning ,MOVE.L D6,(A2) ; IOPosOffset(A0) start at 512 ,_Read ,BNE.S CloseUp ,MOVEQ #0,D2 ; no errors CloseUp _Close NotAround ,MOVE D2,D0 ; result code ,ADD #IOQElSize,SP ,RTS ; LoadOnScreen handles the case of loading onto the screen LoadOnScreen ,MOVE.W #$6000,A1 ; buffer to load into ,ADD.L D6,D4 ; bump the length ,MOVEQ #0,D6 ; screen starts at the beginning ,BRA.S LoadCommon ; use common code ; LoadOnHeap handles the case of loading onto the heap LoadOnHeap ,MOVE.L D4,D0 ; get the size to load ,_NewPtr ,Sys ; allocate room on the system heap ,MOVE.L A0,A1 ; get up pointer ,MOVE.L SP,A0 ; make sure A0 points to pBlock ,BRA.S LoadCommon ; use common code ;MoveInScreen ; MOVE.W #$6000,A0 ; MOVE.L #$0007A700,A1 ; MOVE.L #$5580,D0 ; _BlockMove ; RTS MoveInScreen ,MOVE.L #$01560200,-(SP) ; bounds+bottom, bounds+right ,CLR.L -(SP) ; bounds+top, bounds+left ,MOVE.L #$60000040,-(SP) ; low-word baseAddr, rowBytes ,CLR.W -(SP) ; high-word baseAddr ,LEA $FD90,A5 ; restore A5 pointer wiped during boot ,;LEA <$FE00+portBits>,A2 ,LEA <$0070+portBits>(A5),A2 ,MOVE.L SP,-(SP) ; src bitmap ,PEA (A2) ; dst bitmap ,PEA bounds+8(SP) ; src rect ,PEA bounds(A2) ; dst rect ,CLR.W -(SP) ; srcOR ,CLR.L -(SP) ; nil clipRgn ,_CopyBits ,ADD #14,SP ; fix up stack ,RTS ; and return BootDSTab ; bootStrap deep shit alert table /.WORD 3 ; number of entrys ; alert definitions /.WORD 42,10,0,0,30,50,0 ;cant mount boot volume ; ; icons -- bad diskette ; /.WORD 30,136 /.WORD 98,224,162,288 /.LONG $E00001F8 /.LONG $FFFFFFFC /.LONG $FC0003FE /.LONG $FC01C3FF /.LONG $FC03E3FF /.LONG $FC03E3FF /.LONG $FC03E3FF /.LONG $FC03E3FF /.LONG $FC03E3FF /.LONG $FC01C3FF /.LONG $FE0007FF /.LONG $FFFFFFFF /.LONG $FFFFFFFF /.LONG $FFFFFFFF /.LONG $FF0000FF /.LONG $FF0000FF /.LONG $FF1008FF /.LONG $F0381C0F /.LONG $EF1C38F7 /.LONG $EF0E70F7 /.LONG $EF07E0F7 /.LONG $EF03C0F7 /.LONG $EF03C0F7 /.LONG $EF07E0F7 /.LONG $EF0E70F7 /.LONG $EF1C38F7 /.LONG $EF381CF7 /.LONG $EF1008F7 /.LONG $EF0000F7 /.LONG $EF0000F7 /.LONG $EFFFFFF7 /.LONG $EFFFFFF7 ; proc to vector to eject 0.WORD 50,4 0BRA ReBoot /.END MOCKPASL %_BEGIN %_BEGIN %_INIT %_INIT %_END %_END MOCKPASLMOCKPASL%_TERM %_TERM BNu _NUN _N]NЁSYSPAS SYSPAS SYSPAS %_END %_END %_TERM %_TERM LTEST LTEST %_INIT %_INIT %_BEGIN %_BEGIN &NNUNNNN]NNuHITEST SIDEFLAGSIDEFLAGMAKEHIWIMAKEHIWI|HITEST HITEST EJECT EJECT RDADDRSERDADDRSE0GETDRV1 GETDRV1 |Z"4,DISKSYNCDISKSYNCRECAL RECAL ADRANDSTADRANDSTlADRANDSEADRANDSEBWRDATA WRDATA DRDDATA RDDATA hTRKFORMATRKFORMA"FORMAT FORMAT j,WAKEUP WAKEUP Xt0hJ( ʉFMTVERIFFMTVERIFSETSPEEDSETSPEEDԉADRDISK ADRDISK RDADDR1SRDADDR1SSEEK SEEK H>*g8a:E// NHk(M za0ajfMja"atL|Nua`z`zEP8/JEfW`XSDnNuNuH>/ iMPMTaXMhaPM&aHaHza4aPalaaaajNA>/?1caMBVL|Nu/P/P//NuH>Iz( / qUO// Md/l0gf @ g @ ga`T,E8g $SDn`>UO///8 h0g.UO/`6C/?cMBaMJCACNL|NuH>G&B/HzHz?<Bg/ ?</<&_C"7|D7| J7|HC'IC$'IC'IC&'IE,8va"$RCSDnE8aBRCSDnL|NuYO/ HjHj?<?* ?*?* j"fBW?*"/T$NuYO/ HjHzR?<?* ?*?*?</T$Nu&RError Rate TestP<,,$P,^@sF"x }Test Seq Ps"OxQU}Options,F1U 6Notes,,n 5eject `r 5recal `\9dM on `n9dclear `$P dd format trk `J7 Kd format disk`\ d start test `_n write/read `n}  wt rndm dta`} stop on err` Side 1 Sel `n#random `$#2static `#seq + `#2seq - `;tk0-79 `2;err tks `errors `offon P,<F` ` d,'` ` d'``  dO``i'``iP'``i'``"'``"`` d Hd Set: d Sec/Ps:  $d CurTrk: ii SpdChg: ii Pwr Ct: i$i Rcl Ct: " PwrTim: " WrData: P0Z 6A-6 6A-6No Header Found . . .6A-6Diskette is Write-Protected? 6A-6Not Ready: Disk In & Powered?6A-6Press Mouse Button To Exit Loop6A-6Write-Underrun Occurred! 6#6Pass Count : #62-6Adr Mark Errs : 26A<6Data Mark Errs : #62-6New RPM Value : 6#6Hi RPM Value : 26A<6Low RPM Value : 6A-6Unable To Step (Step = 0)6A-6 Seek Error : 6A-6Please Insert A Diskette!6A-6Disk Format In Progress6A-6Now Verifying Diskette 6A-6Disk Successfully Formatted! 6A-6Track Successfully Formatted!6A-6Disk Format Failure: U6d_@ AM-none : d6sn@ AM-ck sum : s6}@ AM-bitslp : 6@ AM-trknum : 6@ DM-none : 6@ DM-ck sum : 6@ DM-bitslp : 6@ Rd ver err: 6@ Sect miss : E8"g SDnNuA UO//BJk@ @n @A.h0UO/`8ANNu 8P0/"oH> @fNvp`F0/"oH> @f6vp`.0/"oH> @fvp`0/"oH> @fvpa L|x _\ON82JCjDDaA$PANNuUO/ / UO/ `Wc`8NuH8C"QBiHHzҨ{0: @IvM-\ ahQ`Zv A*AUO/`8/0: @g( @f00@AdJpfAJpf RD DPl`a,RDQHzV{A`/LxC "Q3|HNuHNVGBS aD<:a< a<da<ma<=aA00@ah< a<aa<ma<=aAn00@a<< a<pa<sax<=apA00@aHnN^L8NutH@B@H@ H@2QpHA0?Xa"0`tH@B@H@ H@2QpHAI0?Ha0@;rRNu0123456789ABCDEFx` x`x`xHGvA0/BgCfRWc$RC CoHzبaLNu0<NA0A8MpaNu0<NN3D4N8)4MaNu0<NAd0A^8MaNu0<NN3D6N8)6Ma^Nu0<NA(0A"8Ma@Nu0<NA0A8Ma"Nu0<NA0A8MaNu//PN/// GBS0j <-a0D@tH@B@H@ H@2QpHA0?XJgad0a^Hzh&_Nu0<N<HNLjM>aA00A"0N<1F0:*S@fa<`S@gS@f RF FPm |`SFj<<ONL|jM-@ a`natNi01N<1aMBJBFBVBnA0ABBBBP<:gN`N.x:1Bk1B0N@qfB8,0:hg8P,A~((Ff(!DF1AN.x:M^J@g0pN`,1BAN.x:48B1BfM.(.J-DJ9gASPf@N21IA0;M".JAgRBRn` L|a aAJXg,SPn(a^4:g0<N9gSBnaF`F`Ha |L|AaaaNuMxRV @fR2`" @fR6` @fR:` @fR>0:"fAJXg&SPn"L|N<1a,NNL|A0`M Rn08B @g @fR"`" @fR&` @fR*` @fR.`MN<1BxFCRq`R@A!v@ Cn2Hq`Ӷ@ A!v@ C2.Hq`Ӷ@At!v@ A:RERPM( C?<DHHmnpS@2apE CA$NCAN .CA`NABPN:jPaL`NuAzJgNuUO?AE// E08/Bgc$SDnL|NuH>AfN$aA 0fJj`Jka2L|NuF#AJ((J(F NuH>/ iaL|Nu/aAmp0Jjp1M/PN/Av PfrgS`/Hz.,_Nu/`H>IH( / qUO// M2/l0gv @ g @ g`hUOM//BSh0gTUO/`6C/?c,E8g $SDn`,A P0*MJCgMACNaL|NuUO/ / UO/ `Wc`8NuH>G&B/HzHz?<Bg/ ?</<&_C'IC'IC`'IC&'IEh8va$RCSDnL|NuYO/ HjHj ?<B?< j"fBW?*"/T$NuZd|Interface Test  <ca2J(NuJ( Nu Fxca1J(NuJ(Nu ca0JNuJ(Nu selNuNu( <<strJ( NuJ(Nu(F<xstr`4`,F Z</enJ(NuJ(Nu@F#J(J( Ns&<8 /Dirtn = /DiskInPl = /Step = /Wr Prot = /Mtr On = /Tk 0 = Eject = Tach = Rd Data = Rd Data = ?? = ?? = Sides = Sides = /Exists = /Exists = 0F< 0<N1Nu/PN/// GBS0 @g4tH@B@H@ H@2QpHA0?XJga0a Hz&_Nu?Ha0@;rRNu0123456789ABCDEFH>M&*ga8 <@g,`a* VE// NpN/Hk(L|Nuz`zE68/JEfW`XSDnNuH>M<I8YO$fz DfD`0:gJDkaF`"0. N/ j gJEjaB` fJEja,SFn8jpg N/(3L|NuA `A 0`A1///PN/TN/Hz਄,_NuH>/ iMPa0M$aDM8aIz( / qUO// Md/l0gf @ g @ ga`T,E8g $SDn`>UO///8 h0g.UO/`6C/?cMa MJCACNL|NuH>G&B/HzHz?<Bg/ ?</<&_C"7|D7| J7|HC'IC$'IC'ICv'IE8va"$RCSDnE8aBRCSDnL|NuYO/ HjHj?<?* ?*?* j"fBW?*"/T$NuYO/ HjHz?<?* ?*?*?</T$NuF DTrack-Level Test PP^U_dFi nOptionsF 6 NotesQ Pddeject `nid}recal `Xdon ` P dZ read loop ` li }Z write loop ` Z not used ` ~7 KZ write trk ` R 2Zread trk ` 6 Z track test `x( write/read ` (x7 stop on err` l7xF read w/fmt ` P x Side 1 sel ` 4on offP``P```xO`d``_to Data = Track =  P /Exist = P Dirtn = P  /DskIn = P  /Step = OR Sides = OR /W Prt = OR /MtrOn = OR /Trk 0 = 0Z A- A-No Header Found . . .A-Diskette is Write-Protected? A-Not Ready: Disk Inserted?A-Press Mouse Button To Exit LoopA-Write-Underrun Occurred! #Track Pass Count : #2-Bad Nibble Count : 2A<No Hdr Fnd Count : A-Unable To Step (Step = 0)E8"g SDnNuA UO//BJk@ @n @A.h0UO/`8ANNu 8P0/"oH> @fNvp`F0/"oH> @f6vp`.0/"oH> @fvp`0/"oH> @fvpa L|x _\ON82JCjDDaA$PANNuUO/ / UO/ `Wc`8NuH8C"QBiHHz{vA*AUO/`8I(TI@/a*QHz{A/LxCJ"Q3|HNuNVGBS A:/Ha> a8<:a@< a8< a0|a< a QHnN^Nu?Ha0@;rRNu0123456789ABCDEF0<N&~`~4N&Nu0<N&A0AD0ABMFaaNu//PN/// GPBS0 @g?XJgad0a^Hz0&_Nu//PN/// GBS0 @g4tH@B@H@ H@2QpHA0?XJga 0aHz֨&_Nu<HN$LjMaN$81kMa~NuM*//H6<8<E*Eg$a(6<8<E*gaHzHzL8NuH??|~HG><d2JFf |Bg?<` |Bg?<?<BgQHGQLNuBg?MF#AR pA2 AgpNaf"V4<A6 fRSBn<ްfD<f:AZ ( fa9faaF L|AaaNuADR ATJPg Bnf<` r f<E4$)))G& S?A\/?c0@@@A1@P@P@1@aa*F L|AdaVaHz訤NuAR `/MlaMaMa,_Nuanf^AjaMalF!pAt2 AgpNX9fA6aaMa4F NuafH>F#pA*2 AgpNAaMraC2p$|&|(|JJjfJ9EEBaAaBaFMaF L|NuA0NuA0NuA0NuA0Nu/?< ]Nu/Bg]Nu9g0<XN!9gNu?ժުaf pNk MpA2 AgpNA6A P0<@S@nAABaF#2<E4<CK&|(|J Jp.Jk@p JJjQQpJjQJjQpJjQfJ9F L|MaDpNuJ9F L|apNuafH>pA*2 AgpNAJPgaBg(Ma`M"V2<@IF#jSAnF L|a NupLNuF#HpM"V"ժI4<= 2<jSBk fjSBk fjSBk fjQpBQpLNuAV0pNkp r`prE/AJAfA/N_NuMhapNupNjpNupNkpNuH`NlLNuHNLNuHN2Lg M a` Cd/BgcaNuH>*g8a:E// N0Hk(M za0ajfMja"atL|Nua`z`zEP8/JEfW`XSDnNuNuH>/ iMPMTaXMhaPM&aHaHza4aPalaaaajNA>/?1caMBVL|Nu/P/P//NuH>Iz( / qUO// Md/l0gf @ g @ ga`T,E8g $SDn`>UO///8 h0g.UO/`6C/?cMBaMJCACNL|NuH>G&B/HzHz?<Bg/ ?</<&_C"7|D7| J7|HC'IC$'IC'IC&'IE,8va"$RCSDnE8aBRCSDnL|NuYO/ HjHj?<?* ?*?* j"fBW?*"/T$NuYO/ HjHzR?<?* ?*?*?</T$Nu&RError Rate TestP<,,$P,^@sF"x }Test Seq Ps"OxQU}Options,F1U 6Notes,,n 5eject `r 5recal `\9dM on `n9dclear `$P dd format trk `J7 Kd format disk`\ d start test `_n write/read `n}  wt rndm dta`} stop on err` Side 1 Sel `n#random `$#2static `#seq + `#2seq - `;tk0-79 `2;err tks `errors `offon P,<F` ` d,'` ` d'``  dO``i'``iP'``i'``"'``"`` d Hd Set: d Sec/Ps:  $d CurTrk: ii SpdChg: ii Pwr Ct: i$i Rcl Ct: " PwrTim: " WrData: P0Z 6A-6 6A-6No Header Found . . .6A-6Diskette is Write-Protected? 6A-6Not Ready: Disk In & Powered?6A-6Press Mouse Button To Exit Loop6A-6Write-Underrun Occurred! 6#6Pass Count : #62-6Adr Mark Errs : 26A<6Data Mark Errs : #62-6New RPM Value : 6#6Hi RPM Value : 26A<6Low RPM Value : 6A-6Unable To Step (Step = 0)6A-6 Seek Error : 6A-6Please Insert A Diskette!6A-6Disk Format In Progress6A-6Now Verifying Diskette 6A-6Disk Successfully Formatted! 6A-6Track Successfully Formatted!6A-6Disk Format Failure: U6d_@ AM-none : d6sn@ AM-ck sum : s6}@ AM-bitslp : 6@ AM-trknum : 6@ DM-none : 6@ DM-ck sum : 6@ DM-bitslp : 6@ Rd ver err: 6@ Sect miss : E8"g SDnNuA UO//BJk@ @n @A.h0UO/`8ANNu 8P0/"oH> @fNvp`F0/"oH> @f6vp`.0/"oH> @fvp`0/"oH> @fvpa L|x _\ON82JCjDDaA$PANNuUO/ / UO/ `Wc`8NuH8C"QBiHHzҨ{0: @IvM-\ ahQ`Zv A*AUO/`8/0: @g( @f00@AdJpfAJpf RD DPl`a,RDQHzV{A`/LxC "Q3|HNuHNVGBS aD<:a< a<da<ma<=aA00@ah< a<aa<ma<=aAn00@a<< a<pa<sax<=apA00@aHnN^L8NutH@B@H@ H@2QpHA0?Xa"0`tH@B@H@ H@2QpHAI0?Ha0@;rRNu0123456789ABCDEFx` x`x`xHGvA0/BgCfRWc$RC CoHzبaLNu0<N *A0A8MpaNu0<N N3D4N8)4MaNu0<N Ad0A^8MaNu0<N Nn3D6Nf8)6Ma^Nu0<N A(0A"8Ma@Nu0<N A0A8Ma"Nu0<N nA0A8MaNu//PN/// GBS0j <-a0D@tH@B@H@ H@2QpHA0?XJgad0a^Hzh&_Nu0<N<HNLjM>aA00A"0N@<1F0:*S@fa<`S@gS@f RF FPm |`SFj<<ONL|jM-@ a`natNi01N<1aMBJBFBVBnA0ABBBBP<:gN`N.x:1Bk1B0N@qfB8,0:hg8P,A~((Ff(!DF1AN.x:M^J@g0pN`,1BANr.x:48B1BfM.(.J-DJ9gASPf@N21IA0;M".JAgRBRn` L|a aAJXg,SPn(a^4:g0<N9gSBnaF`F`Ha |L|AaaaNuMxRV @fR2`" @fR6` @fR:` @fR>0:"fAJXg&SPn"L|N<1a,NN$L|A0`M Rn08B @g @fR"`" @fR&` @fR*` @fR.`MN<1BxFCRq`R@A!v@ Cn2Hq`Ӷ@ A!v@ C2.Hq`Ӷ@At!v@ A:RERPM1jaP>fHFgBpr4Fg&kprAa3AR4paBavk`a`a3p a*a^k0N*_a|rJ((J(g4tHBpSktJ(J((fg AJ(`J(a~Pp aj2paA4paak`ap aakpSGg`p aakp3Na0< AJg0<J0J(Nu(_p a^J(0<LaJ( 0<La B1N`H@ $x4jnBjE| N2H@AYA*gj|S@jLNu5(_B@J@N(_Hz/8>g"x4H Nua"L N.x:aNժުժު?ժMK!:Ѹ:|Nupapal` papa`E/8*NuC/8.NuE/82Nu0)84aBiapa`j av0fNu    HA0BBaP<1I<:4JJ8; aPfp a6; K8; adLNu    Hp aTI:|OGxv8#6#fLNuH?aLkafSFSf`H|A0K0A0gN`NjaZ`21BA0B8,a.x:J@fA048B0gSPfp`p|LJ@Nu    HA0BBafBFGxfLHNuH?a3F<)ak`L`La fRFSf`HA:AMR,0 @F?F =D=|"|A*afnA0gN`NaX1Bk|1BJfr"<@M1Bn k8Hg AgRn J`faJJ1jR``p|LJ@NuMSn n l08B`RAg`\MSn n lJ08B`?ުH,H V0.2.4.a2. UAC$I6<&|(|J..Jk@t`$ItJjQQ6$ItJjQQtJjQ4<JjQtJjQS@ntfp`pJ9LNu?ժު?ժHx6SCKRC:aRDS@g :a RCS@fLNuC|``QC@q ~qP qP<Nq` <Fq` qp NuNNUN N NN]NNuBNu _NUN _N]N>CODE 4NNUN N NN]NNuBNu _NUN _N]N3. "6F^5D!$ǐ^;;File: SonyTest.Text ;_______________________________________________________________________ ; ; Sony 3-1/2 Inch Drive Test Program ; ; written by Larry Kenyon, beginning 1-March-83 ; ; This is a low-level test program for use by hardware jocks to debug, ; explore, and evaluate the Sony-type 3-1/2 disk drive. ; ; Modification History: ; 03-Mar-83 LAK New today. Completed coding on lowest-level interface ; (CA1, CA2, CA3, etc. button window). ; ;_______________________________________________________________________ TwigVers .Equ 0 ; set to 1 to generate version N; which boots on int-twig system N; and tests externally-connected N; sony-type drive. ,.NOLIST ,.INCLUDE tlasm:SYSEQU.TEXT ; general system equates ,.INCLUDE tlasm:SYSERR.TEXT ; error equates ,.INCLUDE tlasm:GRAFEQU.TEXT ; graphics-related equates ,.INCLUDE tlasm:GRAFTYPES.TEXT ,.INCLUDE tlasm:TOOLEQU.TEXT ,.INCLUDE tlasm:RESEQU.TEXT ,.INCLUDE tlasm:SonyEqu.Text ,.INCLUDE tlasm:SYSMACS.TEXT ; system macros ,.INCLUDE tlasm:TOOLMACS.TEXT ,.INCLUDE tlasm:QUICKMACS.TEXT ,.LIST ; some twiggy driver equates . . . TPower .EQU Drive+2 ; 0=no, 1=int, 2=ext drive powered TTimeOut .EQU TPower+2 ; timeout pending flag TWait .EQU TTimeOut+2 ; extra wait time for speed changes TCurSpeed .EQU TWait+2 ; current speed (0-399) DrawOffset .EQU WindowSize ; offset in window data to draw proc MDOffset .EQU DrawOffset+4 ; offset to mouse down in content proc TaskOffset .EQU MDOffset+4 ; offset to task this guy does when on top ActivOffset .EQU TaskOffset+4 ; offset to activate event proc WndDtaSize .EQU ActivOffset+4 SysMenu .EQU 1 TstMenu .EQU 2 ; testmenu is menu 2 DrvMenu .EQU 3 ; drive menu is menu 3 OptMenu .EQU 4 ; menu for global options LCMenuItem .EQU 1 ; in test menu MCMenuItem .EQU 2 ; in test menu HCMenuItem .EQU 3 ; in test menu XitMenuItem .EQU 4 ; in test menu D1MenuItem .EQU 1 ; in drive menu, internal drive D2MenuItem .EQU 2 ; in drive menu, external drive O1MenuItem .EQU 1 ; in options menu O2MenuItem .EQU 2 ; in options menu ,.PROC LTEST,0 ,.ORG 0 ,.REF MakeLowWindow ; init entry for lowest window ,.REF MakeMidWindow ; init entry for track-level window ,.REF MakeHiWindow ; init entry for diskette-level window ,.REF DiskOpen ,.REF AdrAndStrb ,.REF AdrAndSense ,.REF AdrDisk ,.REF Sense ,.REF Pulse ,.DEF DiskSync ,.DEF SlowSeek ,.DEF SpdRecal TestMain MOVEM.L A5-A6,-(SP) ,PEA -4(A5) ; set up LisaGraf global area ,_InitGraf ; Initialize LisaGraf ,_InitFonts ; initialize the other toolbox managers ,MOVEQ #0,D0 ; never stop ,SUBQ.W #1,D0 ; flushing . . . ,_FlushEvents ; gets rid of any pending events ,_InitWindows ; except initial update events ,BSR SetUpMenu ; init menu bar . . . ,LEA MinusOne,A2 ; hi control is in front ,LEA GLinState,A1 ; global line state: ,LEA LowWndRec,A0 ; pass ptr to storage ,JSR MakeLowWindow ; low control window ,SUB.L A2,A2 ; mid control is behind ,LEA GLinState,A1 ; global line state: ,LEA MidWndRec,A0 ; pass ptr to storage ,JSR MakeMidWindow ; mid control window ,SUB.L A2,A2 ; low control is behind ,LEA GLinState,A1 ; global line state: ,LEA HiWndRec,A0 ; pass ptr to storage ,JSR MakeHiWindow ; hi control window ,LEA QuitFlag,A0 ,CLR.W (A0) ; don't quit! ,.If TwigVers ,BSR TwigSync ; sync with internal twiggy, alloc vars ,.EndC ,JSR DiskOpen ; set up some locals for sony util ; ,_InitCursor ; ,BSR MainLoop ; main program ,MOVEM.L (SP)+,A5-A6 ,RTS ; that's all, folks ; (add a cursor change - current window has that responsibility . . ) ; (so a current window pointer would be nice . . .) MainLoop ,LEA QuitFlag,A0 ,TST.B (A0) ; want to quit? ,BEQ.S @1 ; br if not ,RTS @1 _SystemTask ,SUBQ #2,SP ; make room for result ,MOVE.W #$FFFF,-(SP) ; every event ,PEA TheEvent ; push buffer address ,_GetNextEvent ; get it ,TST.W (SP)+ ; boolean result ,BNE.S Activat ; if anything, go check it ,BSR WndTask ; do current window's task ,BRA.S MainLoop ; then loop back . . . ; now case out on all types of event Activat LEA TheEvent,A2 ,CMP.W #ActivateEvt,EvtNum(A2) ,BNE MouseDown ; if not activate, check for mouse down ,MOVE.L EvtMessage(A2),A3 ; theWindow ,MOVE #ActivOffset,D0 ,BSR GetOurWindow ,BNE.S MainLoop ; br if not one of ours or null proc ,BSR PortSet ,JSR (A0) ; A2 points at the event record ,BRA.S MainLoop MouseDown CMP.W #MButDwnEvt,EvtNum(A2) ,BNE UpdateEvt ; if not mouse down, check for updates ,SUBQ #2,SP ; result is window code ,MOVE.L EvtMouse(A2),-(SP) ; figure out where it went down ,LEA theWindow,A3 ; ,MOVE.L A3,-(SP) ,_FindWindow ,MOVE.W (SP)+,D0 ; get result ,BEQ.S MainLoop ; br if inDesk ,MOVE.L (A3),A3 ; which window pointer ,CMP.W #inMenuBar,D0 ; in the menu bar? ,BNE.S @1 ; br if not ,BSR DownInMenu ; br if so ,BRA.S MainLoop @1 CMP.W #inSysWindow,D0 ; in a system window? ,BNE.S @2 ,MOVE.L A2,-(SP) ; theEvent ptr ,MOVE.L A3,-(SP) ; theWindow ,_SystemClick ,BRA.S MainLoop @2 CMP.W #inContent,D0 ,BNE.S @3 ,BSR DownInContent ,BRA.S MainLoop @3 CMP.W #inDrag,D0 ; is it in drag? ,BNE.S @4 ; br if not . . . ,MOVE.L A3,-(SP) ; theWindow ,MOVE.L EvtMouse(A2),-(SP) ; where it went down ,PEA DragRect ; let him drag it . . . ,_DragWindow ,BRA.S MainLoop @4 CMP.W #inGoAway,D0 ; in the go-away region? ,BNE.S MainLoop ; try again if not . . . ,SUBQ #2,SP ; boolean result ,MOVE.L A3,-(SP) ; theWindow ,MOVE.L EvtMouse(A2),-(SP) ; where it went down ,_TrackGoAway ,TST.W (SP)+ ; true? ,BEQ.S MainLoop ; br if not ,MOVE.L A3,-(SP) ; theWindow ,_HideWindow ; hide it to make it go away ,BRA.S MainLoop UpdateEvt ,CMP.W #UpDatEvt,EvtNum(A2) ; update event? ,BNE MainLoop ; if not mouse down, check for updates ,MOVE.L EvtMessage(A2),A3 ; theWindow ,MOVE.L A3,-(SP) ,_BeginUpdate ,MOVE #DrawOffset,D0 ,BSR.S GetOurWindow ; make sure it's one of ours ,BEQ.S @3 @2 MOVE.L A3,-(SP) ; theWindow ,_EndUpdate ,BRA MainLoop ; keep on looping @3 BSR.S PortSet ,MOVE.L A3,-(SP) ; save theWindow ,JSR (A0) ,MOVE.L (SP)+,A3 ,BRA.S @2 ;___________________________________________________________________ ; ; Routine: GetOurWindow ; Arguments: A3.L (input) -- theWindow ; D0.L (input) -- offset to proc we want ; D0.W (output) -- 0 if our window and dispatch non-zero, -1 if not ; A0.L (output) -- proc address ; Clobbers D1. ; Function: Utility proc to search our window queue and get a ; dispatch address. ;___________________________________________________________________ GetOurWindow ,LEA Windows,A0 ; point to all the windows ,MOVE.W (A0)+,D1 ; number of windows @1 CMP.L A3,A0 ; this window? ,BEQ.S @3 ; br if so ,ADD #WndDtaSize,A0 ; bump to next window ,SUBQ.W #1,D1 ; check all windows ,BGT.S @1 @2 MOVEQ #-1,D0 ; failure ,RTS @3 MOVE.L 0(A3,D0),D0 ; proc pointer ,BEQ.S @2 ; exit if null ,MOVE.L D0,A0 ,MOVEQ #0,D0 ,RTS ;___________________________________________________________________ ; ; Routine: PortSet, PortRest ; Arguments: A3.L (input) -- port to set ; Function: Utility procs to save, restore current port. ; ;___________________________________________________________________ PortSet MOVE.L A0,-(SP) ; preserve A0 ,;PEA SavePort ,;_GetPort ,MOVE.L A3,-(SP) ,_SetPort ,MOVE.L (SP)+,A0 ,RTS ;___________________________________________________________________ ; ; Routine: WndTask ; Arguments: ; Function: This routine calls the loop task for the current ; window, if any. ; ;___________________________________________________________________ WndTask SUBQ #4,SP ,_FrontWindow ,MOVE.L (SP)+,D0 ; get pointer to the front, active window ,BEQ.S WtExit ; br if none ,MOVE.L D0,A3 ,MOVE #TaskOffset,D0 ,BSR.S GetOurWindow ,BEQ.S WtCall WtExit RTS WtCall BSR.S PortSet ,JSR (A0) ,;BSR.S PortRest ; restore previous port ,BRA.S WtExit ;___________________________________________________________________ ; ; Routine: DownInContent ; Arguments: A2.L (input) -- ptr to TheEvent ; A3.L (input) -- ptr to window where mouse went down ; Function: This routine handles mouse down events which occur in the ; content region of a window. ; ;___________________________________________________________________ DownInContent ,SUBQ #4,SP ,_FrontWindow ,CMP.L (SP)+,A3 ; is it the front window? ,BEQ.S @1 ; br if so ,MOVE.L A3,-(SP) ; theWindow ,_SelectWindow ; make it the active window ,BRA.S @2 ; then exit @1 MOVE #MDOffset,D0 ,BSR GetOurWindow ,BNE.S @2 ,BSR.S PortSet ,JSR (A0) ; call the window's proc ,;BSR.S PortRest @2 RTS ;___________________________________________________________________ ; ; Routine: DownInMenu ; Arguments: TheEvent ; Function: This routine handles mouse down events which occur in the ; menu bar. ; ;___________________________________________________________________ DownInMenu ,SUBQ #4,SP ,MOVE.L EvtMouse(A2),-(SP) ; where it went down ,_MenuSelect ,MOVE.W (SP)+,D0 ; which menu ,MOVE.W (SP)+,D1 ; menu item ,BEQ.S DIMExit ; br if nothing was selected ,CMP.W #TstMenu,D0 ; in test menu? ,BNE.S Ck4DrvMenu ; br if not ,CMP.W #LCMenuItem,D1 ; Low Control? ,BNE.S @1 ,PEA LowWndRec ; low-control window record ,_ShowWindow ,PEA LowWndRec ; low-control window record ,_SelectWindow ,BRA.S DIMExit @1 CMP.W #MCMenuItem,D1 ; Mid Control? ,BNE.S @2 ,PEA MidWndRec ; mid-control window record ,_ShowWindow ,PEA MidWndRec ; mid-control window record ,_SelectWindow ,BRA.S DIMExit @2 CMP.W #HCMenuItem,D1 ; Mid Control? ,BNE.S @3 ,PEA HiWndRec ; hi-control window record ,_ShowWindow ,PEA HiWndRec ; hi-control window record ,_SelectWindow ,BRA.S DIMExit @3 CMP.W #XitMenuItem,D1 ; Quit? ,BNE.S DIMExit ,LEA QuitFlag,A0 ,ST (A0) ; quit! DIMExit CLR.W -(SP) ; leave menu unhilighted ,_HiLiteMenu ,RTS Ck4DrvMenu ,CMP.W #DRVMenu,D0 ; in drive menu? ,BNE.S Ck4OptMenu ; try next menu if not ,CMP.W #D1MenuItem,D1 ; internal drive? ,BNE.S @1 ,MOVEQ #1,D0 ; set to internal drive ,BRA.S @2 @1 CMP.W #D2MenuItem,D1 ; external drive? ,BNE.S DIMExit ; exit if not ,MOVEQ #2,D0 ; set to external drive @2 LEA DrvToTest,A0 ; point to drive variable ,MOVE.W D0,(A0) ; set drive var ,BSR DiskSync ; set interface ,SUBQ #4,SP ; who's on top? ,_FrontWindow ,MOVE.L (SP)+,D0 ; get pointer to the front, active window ,BEQ.S DIMExit ; br if none ,MOVE.L D0,A3 ,BSR PortSet ; set the port ,PEA PortRect(A3) ; push the boundRect of the window ,_InvalRect ; schedule it all for updating ,BRA.S DIMExit Ck4OptMenu ,CMP.W #OptMenu,D0 ; in option menu? ,BNE DIMExit ; exit if not ,CMP.W #O1MenuItem,D1 ; slow seek item? ,BNE.S @2 ; br if not ,MOVE.L OptMenuHnd,-(SP) ; option menu handle (saved at NewMenu) ,MOVE.W #O1MenuItem,-(SP) ; the first item ,MOVE.B #1,-(SP) ; assume true (check it) ,LEA SlowSeek,A2 ; currently slow? ,NOT.W (A2) ; flip the state ,BNE.S @1 ; br if it became true ,CLR.W (SP) ; otherwise, uncheck it @1 _CheckItem ,BRA DIMExit ; exit if not @2 CMP.W #O2MenuItem,D1 ; speed recal item? ,BNE DIMExit ; exit if not ,MOVE.L OptMenuHnd,-(SP) ; option menu handle (saved at NewMenu) ,MOVE.W #O2MenuItem,-(SP) ; the second item ,MOVE.B #1,-(SP) ; assume true (check it) ,LEA SpdRecal,A2 ; check current value ,NOT.W (A2) ; flip the state ,BNE.S @3 ; br if it became true ,CLR.W (SP) ; otherwise, uncheck it @3 _CheckItem ,BRA DIMExit ; exit if not ;___________________________________________________________________ ; ; Routine: SetUpMenu ; Arguments: ; Function: Initialize the menu bar. ; ; ;___________________________________________________________________ SetUpMenu ,_InitMenus ; we have a menu bar! ,SUBQ #4,SP ,MOVE.W #SysMenu,-(SP) ; first menu is 1 ,PEA SysMenuTitle ,_NewMenu ,MOVE.L (SP),-(SP) ; copy menu handle ,PEA SysMenuData ,_AppendMenu ; add some items ,CLR.W -(SP) ,_InsertMenu ; append to the end ,SUBQ #4,SP ,MOVE.W #TstMenu,-(SP) ; second menu is 2 ,PEA TstMenuTitle ,_NewMenu ,MOVE.L (SP),-(SP) ; copy menu handle ,PEA TstMenuData ,_AppendMenu ; add some items ,CLR.W -(SP) ,_InsertMenu ; append to the end ,SUBQ #4,SP ,MOVE.W #DrvMenu,-(SP) ; third menu is 3 ,PEA DrvMenuTitle ,_NewMenu ,MOVE.L (SP),-(SP) ; copy menu handle ,PEA DrvMenuData ,_AppendMenu ; add some items ,CLR.W -(SP) ,_InsertMenu ; append to the end ,SUBQ #4,SP ,MOVE.W #OptMenu,-(SP) ; fourth menu is for global options ,PEA OptMenuTitle ,_NewMenu ,MOVE.L (SP),-(SP) ; copy menu handle ,LEA OptMenuHnd,A0 ; and save it for 'checking' ,MOVE.L (SP),(A0) ,PEA OptMenuData ,_AppendMenu ; add some items ,CLR.W -(SP) ,_InsertMenu ; append to the end ,_DrawMenuBar ,RTS ;___________________________________________________________________ ; ; Routine: DiskSync ; Arguments: ; Function: This routine selects the appropriate interface and disables ; the disk VBL task by marking the driver active. ; ;___________________________________________________________________ DiskSync MOVE SR,-(SP) ,MOVEM.L D0-D2/A0-A2,-(SP) ,MOVE #$2300,SR ,LEA DrvToTest,A0 ,MOVE.W (A0),D0 ; get int/ext drive indication ,MOVE.L SonyVars,A0 ; get current vars ,MOVE.W D0,Drive(A0) ; internal is drive 1, external is drive 2 ,ST Active(A0) ; make VBL leave us alone ,MOVEQ #MtrOffAdr,D0 ; turn current drive's motor off ,JSR AdrAndStrb ,.If TwigVers ,TST.B ExtDrive(A0) ; enable external port ,.EndC ,.If <1-TwigVers> ,LEA DrvToTest,A1 ,CMP.W #1,(A1) ; enable appropriate interface ,BEQ.S @1 ,TST.B ExtDrive(A0) ; enable external port ,BRA.S @2 @1 TST.B IntDrive(A0) ; enable internal port ,.EndC @2 TST.B MtrOn(A0) ,MOVEQ #MtrOnAdr,D0 ; start with motor on, interface enabled ,JSR AdrAndStrb ,MOVEQ #DirLAdr,D0 ,JSR AdrDisk ; set interface lines low ,LEA GLinState,A1 ; global line state: ,CLR.W (A1) ; x x enb str ca2 ca1 ca0 sel ,MOVEM.L (SP)+,D0-D2/A0-A2 ,RTE ;___________________________________________________________________ ; ; This routine is temporary: it is used to keep the internal twiggy ; confused enough to leave us alone. ;___________________________________________________________________ ,.If TwigVers InitParams ,.Byte 8,0 ; max 8 soft errs per recal/track ,.Byte 2,0 ; max 2 recals per track ,.Byte 64,0 ; max 64 wrong sectors per sector ,.Byte 2,0 ; max 2 wrong speeds per track ,.Word 0 ; I/O command 0 ,.Word KHdSetTime ; deflt head settle time = 30 ms ,.Word KSpdChgTime ; deflt speed chg wait time = 150 ms ,.Word KPowerOn ; deflt pwr-on = .4 sec ,.Word KRWPOff ; deflt pwr-off = 2-2.5 sec ,.Word KSeekTime ; deflt seek wait time = 12 ms ,.Word KSectTime ; deflt sector time = 10 ms ,.Word KDskVBLTime ; deflt disk VBL time = .5 sec ,.Word KEjectTime ; deflt eject time = .6 seconds ,.Long KCkDelta ; deflt speed check time = 2 min InitWCnt .EQU 15 ; 15 words to init TwigSync MOVEM.L A0-A2,-(SP) ,MOVE SR,-(SP) ,MOVE #$2300,SR ,MOVE.W #$FFFF,PWMValue ; mark speeds invalid for both drivers ,MOVE.L TwiggyVars,A0 ; get current vars ,MOVE.W #$0002,Drive(A0) ; external is drive 2 ,MOVE.W #$0002,TPower(A0) ; make VBL leave us alone ,CLR.W TTimeOut(A0) ; no timeouts pending ,MOVE.W #$FFFF,TCurSpeed(A0); current speed is invalid ,LEA VBase,A1 ; set all lines to init value ,BCLR #VHeadSel,VBufD(A1) ; ,LEA DBase,A0 ,TST.B Ph0L(A0) ; ,TST.B Ph1L(A0) ; ,TST.B Ph2L(A0) ; ,TST.B Ph3L(A0) ; ,TST.B ExtDrive(A0) ; enable external port ,TST.B MtrOn(A0) ,MOVE (SP)+,SR ; Disk Driver Initialization routine ,MOVE.L #DiskVarLth,D0 ; get memory for driver variables ,_NewPtr ,SYS ,MOVE.L A0,SonyVars ; and keep pointer in low memory ,MOVE.L A0,A2 ; copy address of locals ,MOVE.L A1,(A0)+ ; DCE pointer ,MOVE.W #-3,D0 ; get # of words of locals @1 CLR.W (A0)+ ,DBRA D0,@1 ; clear out local area ,MOVE.L A2,A1 ; SonyVars ,SUBQ.B #1,OneToOne(A1) ; go 1 to 1 for now . . . ,LEA ReadErrInit(A1),A0 ,LEA InitParams,A2 ,MOVEQ #InitWCnt-1,D0 @2 MOVE.W (A2)+,(A0)+ ; load up our soft-configurable ,DBRA D0,@2 ; parameters . . . ,MOVEM.L (SP)+,A0-A2 ,RTS ,.EndC ;_______________________________________________________________________ ; ; Program Data Space ; ;_______________________________________________________________________ Windows .WORD 3 ; three windows LowWndRec .BLOCK WindowSize,0 ; low-control window record ,.LONG 0 ; pointer to draw proc ,.LONG 0 ; pointer to mouse down proc ,.LONG 0 ; pointer to task proc (current window) ,.LONG 0 ; pointer to activate proc MidWndRec .BLOCK WindowSize,0 ; mid-control window record ,.LONG 0 ; pointer to draw proc ,.LONG 0 ; pointer to mouse down proc ,.LONG 0 ; pointer to task proc (current window) ,.LONG 0 ; pointer to activate proc HiWndRec .BLOCK WindowSize,0 ; hi-control window record ,.LONG 0 ; pointer to draw proc ,.LONG 0 ; pointer to mouse down proc ,.LONG 0 ; pointer to task proc (current window) ,.LONG 0 ; pointer to activate proc DefltGPort .BLOCK PortRec,0 DragRect .WORD 20,2,340,510 ; rectangle we can drag windows within theEvent .BLOCK EvtBlkSize,0 ; event buffer theWindow .LONG 0 ; scratch window pointer SavePort .LONG 0 ; used to save current port QuitFlag .WORD 0 ; set to non-zero to quit GLinState .WORD 0 DrvToTest .WORD 1 ; default to internal drive test SlowSeek .WORD 0 ; default to regular seek SpdRecal .WORD $FFFF ; default to speed code refig on recal TstMenuTitle ,.BYTE 4 ,.ASCII 'Test ' TstMenuData ,.BYTE 52 ,.ASCII 'Interface Test;Track-Level Test;Error Rate Test;Exit ' DrvMenuTitle ,.BYTE 5 ,.ASCII 'Drive' DrvMenuData ,.BYTE 17 ,.ASCII 'Internal;External' OptMenuTitle ,.BYTE 7 ,.ASCII 'Options' OptMenuData ,.BYTE 17 ,.ASCII ' Seek Handshake;!' ,.ALIGN 2 OptMenuHnd .LONG 0 SysMenuTitle ,.BYTE 1 ,.BYTE $7F ; apple SysMenuData ,.BYTE 55 ,.ASCII '(Sony Disk;(Interface Test;(by;(Larry Kenyon;(23 Mar 84' ,.END LTEST SPDRECALSPDRECALނLTEST LTEST DISKSYNCDISKSYNCSLOWSEEKSLOWSEEK܉ADRANDSTADRANDST0MAKELOWWMAKELOWW&MAKEMIDWMAKEMIDW4DISKOPENDISKOPENLMAKEHIWIMAKEHIWIBADRDISK ADRDISK 6HHmnpS@2apE CA$NCANCA`NABPNPaL`NuAzJgNuUO?1jaP>fHFgBpr4Fg&kprAa3A4paBavk`a`a3p a*a^k0N*_a|rJ((J(g4tHBpSktJ(J((fg AJ(`J(a~Pp aj2paA4paak`ap aakpSGg`p aakp3Na0< AJg0<J0J(Nu(_p a^J(0<LaJ( 0<La B1N`H@ $x4jnBjE| N2H@AYA*gj|S@jLNu5(_B@J@N(_Hz/8>g"x4H Nua"L N.x:aNժުժު?ժMK!:Ѹ:|Nupapal` papa`E/8*NuC/8.NuE/82Nu0)84aBiapa`j av0fNu    HA0BBaP<1I:4JJ8; aPfp a6; K8; adLNu    Hp aTI:|OGxv8#6#fLNuH?aLkafSFSf`H|A0K0A0gN`NjaZ`21BA0B8,a.x:J@fA048B0gSPfp`p|LJ@Nu    HA0BBafBFGxfLHNuH?a3F<)ak`L`La fRFSf`HA:AMR,0 @F?F =D=|"|A*afnA0gN`NaX1Bk|1BJfr"<@M1Bn k8Hg AgRn J`faJJ1jR``p|LJ@NuMSn n l08B`RAg`\MSn n lJ08B`?ުH,H V0.2.4.a2. UAC$I6<&|(|J..Jk@t`$ItJjQQ6$ItJjQQtJjQ4<JjQtJjQS@ntfp`pJ9LNu?ժު?ժHx6SCKRC:aRDS@g :a RCS@fLNuC|``QC@q ~qP qP<Nq` <Fq` qp Nu .3. "6F^5D!$ǐ^hsonytest sonylow sonymid sonyhi sonyutil l1 mocpaslib t1 3. "6F^5P:H r8^  4* * Resource Definition File Source Code * * ROM 2.0 Release Feb 16, 1983 * sonytest.rsrc Type CODE "t1,0 3. "6F^5D!$ǐ^; File: SonyMid.Text ;_______________________________________________________________________ ; ; Sony 3-1/2 Inch Drive Test Program: Middle Control Window ; ; written by Larry Kenyon, beginning 6-March-83 ; ; This is a mid-level test program for use by hardware jocks to debug, ; explore, and evaluate the Sony-type 3-1/2 disk drive. It includes ; eject, recal, step in, step out, write nibbles on a track, and read ; nibbles from a track. ; ; Modification History: ; 06 Mar 83 LAK New today. Made from low-control outline. ; 08 Mar 83 LAK Added sense stuff, head load/unload radio buttons, ; read/write track's worth of nibbles. ; 12 May 83 LAK Added margin testing; includes dials for setting speed ; code increment and tracks to read per increment. ; 03/22/84 GRC, Added side selection, for use on 2 sided disk drive. ;_______________________________________________________________________ ,.NOLIST ,.INCLUDE tlasm:SYSEQU.TEXT ; general system equates ,.INCLUDE tlasm:SYSERR.TEXT ; error equates ,.INCLUDE tlasm:GRAFEQU.TEXT ; graphics-related equates ,.INCLUDE tlasm:GRAFTYPES.TEXT ,.INCLUDE tlasm:TOOLEQU.TEXT ,.INCLUDE tlasm:RESEQU.TEXT ,.INCLUDE tlasm:SonyEqu.Text ,.INCLUDE tlasm:SYSMACS.TEXT ; system macros ,.INCLUDE tlasm:TOOLMACS.TEXT ,.INCLUDE tlasm:QUICKMACS.TEXT ,.LIST DrawOffset .EQU WindowSize ; offset in window data to draw proc MDOffset .EQU DrawOffset+4 ; offset to mouse down in content proc TaskOffset .EQU MDOffset+4 ; offset to task this guy does when on top ActivOffset .EQU TaskOffset+4 ; offset to activate event proc WndDtaSize .EQU ActivOffset+4 CRefCOS .EQU 0 ; ctl handle offset within data structure CRectOS .EQU CRefCOS+4 ; control rectangle offset CInitOS .EQU CRectOS+8 ; initial value CMinOS .EQU CInitOS+2 ; min control value CMaxOS .EQU CMinOS+2 ; max control value CNameOS .EQU CMaxOS+2 ; control name offset CProcOS .EQU CNameOS+12 ; control proc to execute button CDefPrOS .EQU CProcOS+4 ; type of control CDtaSize .EQU CDefPrOS+2 ; scroll controls only . . . CSmallOS .EQU CMaxOS+2 ; small increment/decrement CPageOS .EQU CSmallOS+2 ; page increment/decrement CSProc1OS .EQU CPageOS+2 ; proc called during buttons after ctl chg CSProc2OS .EQU CSProc1OS+4 ; proc called on exit CSDtaSize .EQU CSProc2OS+4 selBit .EQU 0 ca0Bit .EQU 1 ca1Bit .EQU 2 ca2Bit .EQU 3 strBit .EQU 4 enbBit .EQU 5 DtaBufSize .EQU 4096+64 ; uses a 4K-byte data buffer + slop WrNybCnt .EQU 4096 ; only write 4K nybbles ,.PROC MidTest,0 ,.ORG 0 ,.DEF MakeMidWindow ; only entry needed ,.REF DiskSync ,.REF FigTrkSpeed ,.REF Recal ,.REF Eject ,.REF Seek1 ,.REF SetASpeed ,.REF WakeUp ,.REF GetDrive ,.REF GetDrv1 ,.REF Format ,.REF FmtVerify ,.REF AdrAndStrb ,.REF AdrAndSense ,.REF AdrDisk ,.REF Sense ,.REF Pulse ;___________________________________________________________________ ; ; Routine: MidCtlActivate ; Arguments: A2 = event pointer ; Function: This routine handles the activation/deactivation of ; the low-control window by calling the DiskSync routine, ; and then setting all control values to 0. ;___________________________________________________________________ MidCtlActivate ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA DataBufPtr,A6 ,BTST #0,EvtMeta+1(A2) ; activate or de-activate? ,BEQ.S @2 ; if deactivate, return memory ,BSR.S ShowScroll ; show scroll bars ,MOVE.L #DtaBufSize,D0 ; get pointer to a data buffer ,_NewPtr ,BEQ.S @1 ,.word $fccc @1 MOVE.L A0,(A6) ,BRA.S @3 @2 BSR.S HideScroll ,MOVE.L (A6),A0 ,_DisposPtr @3 LEA FontForce,A2 ,MOVE.L (A2)+,-(SP) ; draw a blank to force font in ,_MoveTo ; prepare to draw text ,MOVE.L A2,-(SP) ,_DrawString ,JSR DiskSync ; proc in main program ,MOVEQ #MtrOnAdr,D0 ; start with motor on, interface enabled ,JSR AdrAndStrb ,PEA PortRect(A3) ; push the boundRect of the window ,_InvalRect ; schedule it all for updating ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ; show scroll bars when we activate ShowScroll MOVEQ #0,D5 ; show flag ,BRA.S SHScrl1 HideScroll MOVEQ #-1,D5 ; hide flag SHScrl1 LEA CtlScroll,A2 ; scroll control data structures ,MOVE.W (A2)+,D4 ; number of scroll controls SHScrlLoop MOVE.L (A2),-(SP) ; control handle ,TST.W D5 ,BNE.S @1 ,_ShowControl ,BRA.S @2 @1 _HideControl @2 ADD #CSDtaSize,A2 ; point to next scroll control ,SUBQ.W #1,D4 ; do them all ,BGT.S SHScrlLoop ,RTS ;___________________________________________________________________ ; ; Routine: MidCtlTask ; Arguments: ; Function: This routine checks to see if any sense lines have changed. ; It is also called during an update. There are two ; pertinent conditions: ; ; A = this window is the front window ; B = we are being called for updating ; ; /A X : must be an update call - just print blanks ; A/B : task call - update only those which changed ; A B : update - sense and print all ;___________________________________________________________________ MidCtlTask ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA MidMsg,A6 ,MOVE.W (A6)+,D6 ; number of sense messages ,LEA SenseWord,A4 ; current sense info ,MOVE.W (A4),D4 ,BCLR #15,D4 ; assume we aren't the front window ,SUBQ #4,SP ,_FrontWindow ,CMP.L (SP)+,A3 ; the front, active window? ,BNE.S MCTLoop ; br if not ,BSET #15,D4 ; set current window bit ,MOVEQ #0,D5 ; assume not update time ,CMP.W #$FFFF,D4 ; changed a sensible bit? ,BNE.S @2 ; br if not ,AND.W #$8000,D4 ; start sense out 0 ,BRA.S @3 ; always update @2 MOVE.W UpDateTime,D0 ; update time? ,BEQ.S MCTLoop ; br if not @3 BSET #15,D5 ; bit 15 of D5=1 means update time MCTLoop TST.W D4 ; current window? ,BMI.S @1 ; br if so @0 BSR.S NoteSB ; print out sense and blank ,BRA.S @5 @1 MOVE.W 12(A6),D0 ; sense address ,MOVE.B D0,D5 ; save in D5 ,JSR AdrAndSense ,BPL.S @3 ,BSET D5,D4 ; new sense state ,BEQ.S @2 ; br if changed ,TST.W D5 ,BPL.S @5 ; br if unchanged and no update @2 BSR.S NoteS1 ,BRA.S @5 @3 BCLR D5,D4 ; new sense state ,BNE.S @4 ; br if changed ,TST.W D5 ,BPL.S @5 ; br if unchanged and no update @4 BSR.S NoteS0 @5 ADD #24,A6 ; point to next message ,SUBQ.W #1,D6 ; go through all messages ,BGT.S MCTLoop SetSense MOVE.W D4,(A4) ; update the word sense ,BPL.S MCTExit ; exit if just an update ,MOVEQ #DIPAdr,D0 ; check for dip ,BTST D0,D4 ; ,BEQ.S MCTExit ; br if so ,JSR GetDrv1 ; mark track invalid if not ,MOVE.W #$FFFF,Track(A1,D1) MCTExit MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS NoteSB LEA MidTxt+1,A0 ; fill in the current sense ,MOVE.B #$20,(A0) ; to a blank ,BRA.S NoteSense NoteS0 LEA MidTxt+1,A0 ; fill in the current sense ,MOVE.B #$30,(A0) ; to a 0 ,BRA.S NoteSense NoteS1 LEA MidTxt+1,A0 ; fill in the current sense ,MOVE.B #$31,(A0) ; to a 1 NoteSense MOVE.L A6,-(SP) ,MOVE.L A6,-(SP) ; rectangle pointer ,MOVE.L A6,-(SP) ,_EraseRect ; that we wish to erase ,_FrameRect ; and frame ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,ADDQ #2,A6 ; skip over sense address ,MOVE.L A6,-(SP) ,_DrawString ,PEA MidTxt ,_DrawString ,MOVE.L (SP)+,A6 ,RTS ;___________________________________________________________________ ; ; Routine: DrawMidCtl ; Arguments: ; Function: This routine handles update events in the Mid-control ; window. ; ;___________________________________________________________________ DrawMidCtl ,MOVEM.L D3-D7/A2-A6,-(SP) ,MOVE.L A3,-(SP) ; window ptr ,_DrawControls ; draw the controls ,LEA UpDateTime,A6 ,ST (A6) ; update time ,BSR MidCtlTask ; do the sense updates ,LEA optionRect,A6 ,BSR DrawCapBox ,LEA msgRect,A6 ,BSR DrawCapBox ,BSR DrawBuf ; and draw buffer 'window' ,LEA theNibble,A0 ,MOVE.W (A0),D4 ; control value ,BSR DrawNib ,BSR DrawTrk ,JSR GetDrv1 ,LEA CtlTrkScrl,A0 ,MOVE.L CRefCOS(A0),-(SP) ; control handle ,MOVE.W Track(A1,D1),-(SP) ; set track value dial appropriately ,_SetCtlValue ,BSR DrawErrs ,LEA EraseNote,A6 ,BSR DrawNote ,LEA UpDateTime,A6 ,CLR.W (A6) ; update time is over ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ; short routine to draw a captioned box DrawCapBox MOVE.L A6,-(SP) ; push pointer to option box rect ,_FrameRect ,ADDQ.L #8,A6 ; bump past rect ,MOVE.L A6,-(SP) ; now draw the text (captioned box) ,_EraseRect ,ADDQ.L #8,A6 ; bump past rect ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ,MOVE.L A6,-(SP) ; push pointer to string ,_DrawString ,RTS ;___________________________________________________________________ ; ; Routine: DoMidCtl ; Arguments: TheEvent ; Function: This routine handles mouse down events which occur in the ; menu bar. ; ;___________________________________________________________________ DoMidCtl ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA MyPt,A4 ,MOVE.L EvtMouse(A2),(A4) ,MOVE.L A4,-(SP) ,_GlobalToLocal ,SUBQ #2,SP ,MOVE.L (A4),-(SP) ; local mouse down point ,MOVE.L A3,-(SP) ; theWindow ,LEA theControl,A6 ,MOVE.L A6,-(SP) ; var: control handle ,_FindControl ; figure out which control ,MOVE.W (SP)+,D0 ,BEQ.S DoLCExit ,CMP.W #InCheckBox,D0 ,BEQ.S @2 ,CMP.W #InButton,D0 ,BEQ.S @2 ,BSR ScrollTrack ; handle scroll bars separately ,BRA.S DoLCExit @2 ; now map the control onto one of my data structures, and do the proc ,MOVE.L (A6),D6 ; control handle ,LEA MidCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls SrchLCtl CMP.L CRefCOS(A2),D6 ; this one? ,BEQ.S @1 ; br if so ,ADD #CDtaSize,A2 ; point to next control ,SUBQ.W #1,D4 ,BGT.S SrchLCtl ,BRA.S DoLCExit ; br if not in the structure @1 SUBQ #2,SP ,MOVE.L (A6),-(SP) ; theControl handle ,MOVE.L (A4),-(SP) ; local mouse down point ,MOVE.L MinusOne,-(SP) ; nil action proc ,_TrackControl ,MOVE.W (SP)+,D0 ,BEQ.S DoLCExit ,SUBQ #2,SP ,MOVE.L (A6),-(SP) ; theControl handle ,_GetCtlValue ,MOVE.W (SP)+,D3 ; current value ,BCHG #0,D3 ,MOVE.L (A6),-(SP) ; theControl handle ,MOVE.W D3,-(SP) ; set new value ,_SetCtlValue ; erase current note at this time . . . ,LEA EraseNote,A6 ,BSR DrawNote ; now do the proc we do at the end . . . ,LEA CProcOS(A2),A6 ; get proc ,TST.W D3 ; control value ,LEA DBase,A0 ; need to set up A0, A1 ,LEA VBase,A1 ,JSR (A6) ; do it DoLCExit MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ;___________________________________________________________________ ; ; Routine: MakeMidWindow ; Arguments: A0.L (input) -- pointer to window record storage ; Function: This routine creates the Mid-Control window and initializes ; the window data structure. ; ;___________________________________________________________________ MakeMidWindow ,;.word $ff01 ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA LineStPtr,A3 ,MOVE.L A1,(A3) ; save pointer to line state ,CLR.L -(SP) ; make room for function result ,MOVE.L A0,-(SP) ; Mid-control window record ,PEA MidWRect ; global start location ,PEA MidWndNam ; window name = 'Mid Control' ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W #DocumentProc,-(SP) ; regular window ,MOVE.L A2,-(SP) ; behind this window ,MOVE.W #$0100,-(SP) ; it has a go-away region ,MOVE.L #$10100001,-(SP) ; refCon ,_NewWindow ,MOVE.L (SP)+,A3 ; our window pointer bounces back to us ,LEA myWindow,A1 ,MOVE.L A3,(A1) ; save for changing text mode ,MOVE.W #4,TxFont(A3) ; use Gacha (fixed-width font) ,MOVE.W #9,TxSize(A3) ; size 9 ,MOVE.W #srcOr,TxMode(A3) ,LEA DrawMidCtl,A1 ; fill in our proc pointers ,MOVE.L A1,DrawOffset(A3) ; the draw proc ,LEA DoMidCtl,A1 ; handles mouse down in content region ,MOVE.L A1,MDOffset(A3) ,LEA MidCtlTask,A1 ; does any sense updates ,MOVE.L A1,TaskOffset(A3) ,LEA MidCtlActivate,A1 ; does activate stuff ,MOVE.L A1,ActivOffset(A3) ,LEA MidCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls ,MOVEQ #0,D3 ; first refcon is 0 ICtlLoop BSR.S InitCtl ,ADD #CDtaSize,A2 ; point to next control ,ADDQ #1,D3 ; incr refNum ,SUBQ.W #1,D4 ; do them all ,BGT.S ICtlLoop ,LEA CtlScroll,A2 ; scroll control data structures ,MOVE.W (A2)+,D4 ; number of scroll controls ISCtlLoop BSR.S InitSCtl ,ADD #CSDtaSize,A2 ; point to next scroll control ,ADDQ #1,D3 ; incr refNum ,SUBQ.W #1,D4 ; do them all ,BGT.S ISCtlLoop ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS InitCtl SUBQ #4,SP ,MOVE.L A3,-(SP) ; windowPtr ,PEA CRectOS(A2) ; boundsRect ,PEA CNameOS(A2) ; control name ptr ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W CInitOS(A2),-(SP) ; initial value ,MOVE.W CMinOS(A2),-(SP) ; min value ,MOVE.W CMaxOS(A2),-(SP) ; max value ,CMP.W #PushButProc,CDefPrOS(A2) ,BNE.S @1 ; except for push button procs ,CLR.W (SP) ; max is 0 @1 MOVE.W CDefPrOS(A2),-(SP) ; type of control ,MOVE.L D3,-(SP) ; refcon ,_NewControl ,MOVE.L (SP)+,CRefCOS(A2) ; store handle ,RTS InitSCtl SUBQ #4,SP ,MOVE.L A3,-(SP) ; windowPtr ,PEA CRectOS(A2) ; boundsRect ,PEA SCtlName ; control name ptr ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W CInitOS(A2),-(SP) ; initial value ,MOVE.W CMinOS(A2),-(SP) ; min value ,MOVE.W CMaxOS(A2),-(SP) ; max value ,MOVE.W #ScrollBarProc,-(SP) ,MOVE.L D3,-(SP) ; refcon ,_NewControl ,MOVE.L (SP)+,CRefCOS(A2) ; store handle ,RTS ;_______________________________________________________________________ ; ; Mid Control Window Data Space ;_______________________________________________________________________ LineStPtr .LONG 0 ; ptr to main pgm global line state theControl .LONG 0 ; scratch control pointer MyPt .WORD 0,0 ; scratch point MyWindow .LONG 0 ; pointer to our window MidWRect .WORD 70,11,324,501 ; start global rectangle for Mid-Control MidWndNam .BYTE 16 ,.ASCII 'Track-Level Test ' memClip .WORD 80,276,200,479 ; rect to draw into fullClip .WORD 0,0,254,490 bufRect .WORD 80,260,200,480 ; buffer rectangle DBufTxt .WORD 94,280 invNibRect .WORD 85,0,95,0 ; rectangle to invert g10width .EQU 6 ; gatcha 10 chars are 6 bits wide optionRect .WORD 5,100,70,250 ; rectangle for option checkboxes optionMsg .WORD 4,105,6,162 ; erase rect ,.WORD 10,110 ; V,H local point ,.BYTE 7 ,.ASCII 'Options' msgRect .WORD 5,260,70,480 ; rectangle for messages msgMsg .WORD 4,265,6,310 ; erase rect ,.WORD 10,270 ; V,H local point ,.BYTE 5 ,.ASCII 'Notes' line1Vstrt .EQU 210 line1Hstrt .EQU 273 line2Vstrt .EQU 230 line2Hstrt .EQU 273 timingRect .WORD 199,260,250,480 ; rectangle around timing information tim2Rect .WORD 200 ; rectangle inside timing information ,.WORD line1Hstrt+64 ,.WORD 249 ,.WORD line1Hstrt+129 sbv .EQU 80 ; small button block vertical start sbh .EQU 100 ; and horizontal start lbv .EQU 5 lbh .EQU 10 ; all windows share fixed-length records in the following data structure MidCtlDta .WORD 13 ; 13 regular controls ,.LONG 0 ; control handle ,.WORD sbv,sbh,sbv+20,sbh+50 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'eject ' ,BRA ToEject ,.WORD PushButProc ,.LONG 0 ; control handle ,.WORD sbv+25,sbh,sbv+45,sbh+50 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'recal ' ,BRA ToRecal ,.WORD PushButProc DskEnbCtl .LONG 0 ; control handle ,.WORD sbv+50,sbh,sbv+70,sbh+50 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 2 ,.ASCII 'on ' ,BRA ToSetEnb ,.WORD PushButProc Tst2Ctl .LONG 0 ; control handle ,.WORD 80,10,100,90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 9 ,.ASCII 'read loop ' ,BRA RdLoop ,.WORD PushButProc Tst3Ctl .LONG 0 ; control handle ,.WORD 105,10,125,90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 10 ,.ASCII 'write loop ' ,BRA WrLoop ,.WORD PushButProc Tst4Ctl .LONG 0 ; control handle ,.WORD 130,10,150,90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 9 ,.ASCII 'not used ' ,BRA RdTrack ,.WORD PushButProc ,.LONG 0 ; control handle ,.WORD 55,10,75,90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 9 ,.ASCII 'write trk ' ,BRA WrTrack ,.WORD PushButProc ,.LONG 0 ; control handle ,.WORD 30,10,50,90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 8 ,.ASCII 'read trk ' ,BRA RdTrack ,.WORD PushButProc Tst1Ctl .LONG 0 ; control handle ,.WORD 5,10,25,90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 10 ,.ASCII 'track test ' ,BRA RdTest ,.WORD PushButProc Opt1Ctl .LONG 0 ; control handle ,.WORD 25,120,40,220 ; bounds rect ,.WORD 1 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'write/read ' ,BRA SetRW ,.WORD CheckBoxProc Opt2Ctl .LONG 0 ; control handle ,.WORD 40,120,55,220 ; bounds rect ,.WORD 1 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'stop on err' ,BRA SetErrStp ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 55,120,70,220 ; bounds rect ,.WORD 1 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'read w/fmt ' ,BRA SetRdFormat ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 10,120,25,220 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'Side 1 sel ' ,BRA SetSideSel ,.WORD CheckBoxProc ; alternate button names EnbhiName .BYTE 2 ,.ASCII 'on ' EnbloName .BYTE 3 ,.ASCII 'off' scv .EQU 80 sch .EQU 160 CtlScroll .WORD 3 ; 3 scroll controls CtlDtaScrl .LONG 0 ; control handle ,.WORD 80,260,200,276 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 512 ; max value (7 below true max) ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrawBuf ; proc to display ,BRA DrawBuf ; proc at end CtlNibScrl .LONG 0 ; control handle ,.WORD scv,sch,scv+16,sch+90 ; bounds rect ,.WORD $0096 ; initial value ,.WORD $0000 ; min value ,.WORD $00FF ; max value (all nibs with high bit on) ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrWaitNib ; proc to display ,BRA DrWaitNib ; proc at end CtlTrkScrl .LONG 0 ; control handle ,.WORD scv+40,sch,scv+56,sch+90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 79 ; max value (79 tracks) ,.WORD 1 ; small increment/decrement ,.WORD 4 ; 'page' increment/decrement ,BRA GoToTrk ; proc to display ,BRA GoToTrk ; proc at end NibMsg .WORD scv+15,sch,scv+36,sch+90 ; erase rect ,.WORD scv+31,sch ; V,H local point ,.BYTE 9 ,.ASCII ' Data = ' TrkMsg .WORD scv+55,sch,scv+76,sch+90 ; erase rect ,.WORD scv+71,sch ; V,H local point ,.BYTE 9 ,.ASCII ' Track = ' HexBuf .LONG 0,0,0,0 theNibble .WORD $0096 ; default write nibble marTrks .WORD 30 ; number of 0-error tracks for margining theCtlDta .LONG 0 ; pointer to current control data DskReady .WORD $FFFF ; 0 if disk is ready SenseWord .WORD 0 ; bits correspond to address DataBufPtr .LONG 0 ; pointer to 4096+64 byte data buffer UpdateTime .WORD 0 ; boolean, 0 when NOT update time ErrStpFlag .WORD 1 ; stop on errors when non-zero RWFlag .WORD 1 ; write before read when non-zero RdFmtFlag .WORD 1 ; do formatted read when non-zero SideFlag .Word 0 ; Select side 0 goodData .LONG 0 ; data as written badData .LONG 0 ; data as read msgv .EQU 160 msgh .EQU 10 MidMsg .WORD 8 ,.WORD msgv-1,msgh,msgv+20,msgh+70 ; erase rect ,.WORD msgv+15,msgh+2 ; V,H local point ,.WORD DrvExstAdr ,.BYTE 9 ,.ASCII '/Exist = ' ,.WORD msgv+19,msgh,msgv+40,msgh+70 ; erase rect ,.WORD msgv+35,msgh+2 ; V,H local point ,.WORD DirLAdr ,.BYTE 9 ,.ASCII ' Dirtn = ' ,.WORD msgv+39,msgh,msgv+60,msgh+70 ; erase rect ,.WORD msgv+55,msgh+2 ; V,H local point ,.WORD DIPAdr ,.BYTE 9 ,.ASCII '/DskIn = ' ,.WORD msgv+59,msgh,msgv+80,msgh+70 ; erase rect ,.WORD msgv+75,msgh+2 ; V,H local point ,.WORD StepLAdr ,.BYTE 9 ,.ASCII '/Step = ' ,.WORD msgv-1,msgh+69,msgv+20,msgh+140 ; erase rect ,.WORD msgv+15,msgh+72 ; V,H local point ,.WORD SidesAdr ,.BYTE 9 ,.ASCII ' Sides = ' ,.WORD msgv+19,msgh+69,msgv+40,msgh+140 ; erase rect ,.WORD msgv+35,msgh+72 ; V,H local point ,.WORD WrProtAdr ,.BYTE 9 ,.ASCII '/W Prt = ' ,.WORD msgv+39,msgh+69,msgv+60,msgh+140 ; erase rect ,.WORD msgv+55,msgh+72 ; V,H local point ,.WORD MtrOnAdr ,.BYTE 9 ,.ASCII '/MtrOn = ' ,.WORD msgv+59,msgh+69,msgv+80,msgh+140 ; erase rect ,.WORD msgv+75,msgh+72 ; V,H local point ,.WORD Tk0Adr ,.BYTE 9 ,.ASCII '/Trk 0 = ' MidTxt .BYTE 1 ,.BYTE $30 ; starts as Ascii 0 FontForce .WORD 150,90 ; V,H local point SCtlName .BYTE 1 ; also scroll control name ,.ASCII ' ' NoteValOS .EQU 12 ; offset to note value EraseNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 1 ,.ASCII ' ' NoHdrNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 21 ,.ASCII 'No Header Found . . .' WrProtNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 28 ,.ASCII 'Diskette is Write-Protected? ' NtRdyNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 25 ,.ASCII 'Not Ready: Disk Inserted?' ToStopNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 31 ,.ASCII 'Press Mouse Button To Exit Loop' BadWrNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 24 ,.ASCII 'Write-Underrun Occurred! ' PassNote .WORD 20,270,35,470 ; erase rect ,.WORD 30,270 ; V,H local point ,.LONG 0 ; passes value ,.BYTE 19 ,.ASCII 'Track Pass Count : ' BadRdsNote .WORD 35,270,50,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG 0 ; bad nibbles value ,.BYTE 19 ,.ASCII 'Bad Nibble Count : ' NoHdrsNote .WORD 50,270,65,470 ; erase rect ,.WORD 60,270 ; V,H local point ,.LONG 0 ; no header found count value ,.BYTE 19 ,.ASCII 'No Hdr Fnd Count : ' CantStpNote .WORD 20,270,65,470 ; erase rect ,.WORD 45,270 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 25 ,.ASCII 'Unable To Step (Step = 0)' ,.INCLUDE SONYMID1.TEXT ,.INCLUDE SONYMID2.TEXT ,.END 3. "6F^5D!$ǐ^{; File: SonyFormat.Text ;_______________________________________________________________________ ; ; Routine: TrkFormat ; Arguments: D0.W (output) -- result code (0 if correctly formatted) ; Function: This routine formats and verifies a single track. ; diskette to verify correct format. ;_______________________________________________________________________ FmtByte .EQU 2 ; 2-1 interleave, single side Fmt2Byte .EQU $22 ; 2-1 interleave, double-sided FmtParam .LONG 0 ; buffer pointer (27*22 bytes long) ,.WORD 0 ; sector count ,.WORD 0 ; volume number ,.WORD 0 ; side, track ,.WORD 7 ; number of intersector gap sync groups bufptrOS .EQU 0 ; parameter block offsets sectcntOS .EQU 4 volnumOS .EQU 6 sidenumOS .EQU 8 trknumOS .EQU 9 hdrSyncOS .EQU 10 SctTrkTbl .Word $0FFF ; sector map: 12 sectors ,.Word 12 ,.Word $07FF ; sector map: 11 sectors ,.Word 11 ,.Word $03FF ; sector map: 10 sectors ,.Word 10 ,.Word $01FF ; sector map: 9 sectors ,.Word 9 ,.Word $00FF ; sector map: 8 sectors ,.Word 8 TrkFormat ,MOVEM.L A0-A6/D1-D7,-(SP) ; preserve all registers ,LEA hdrSyncOS+FmtParam,A0 ; set this to 7 each time ,MOVE.W #7,(A0) ,CLR.L TagData+2 ,CLR.L TagData+6 ; clear for good tagging ,BSR GetDrv1 ; figure out which track ,MOVE.W Track(A1,D1),D6 ; track number ,lea SideFlag,a4 ,MOVE.W (a4),D5 ; side ,MOVE D6,D2 ; figure sectors per track ,LSR.W #4,D2 ; get speed class ,LSL.W #2,D2 ; get double word offset ,MOVE.W SctTrkTbl+2(D2),D4 ; sectors on this track ,BSR FormatTrack ; format it ,BNE.S TrkFmtDone ; exit on format errors ,MOVEQ #12,D0 ; wait 1.2 ms after last write ,BSR WakeUp ,MOVE.W SctTrkTbl+2(D2),D3 ; sectors on this track ,LSL.W #8,D3 ; get it into high byte ,MOVE.W SctTrkTbl(D2),D4 ; sector map ,BSR VerTrack ; and verify the track TrkFmtDone MOVEM.L (SP)+,A0-A6/D1-D7 ; restore all registers ,RTS ;_______________________________________________________________________ ; ; Routine: FmtVerify ; Arguments: D0.W (output) -- result code (0 if correctly formatted) ; Function: This routine reads all sectors on the newly formatted ; diskette to verify correct format. ;_______________________________________________________________________ Fmt1Err .EQU -82 Fmt2Err .EQU -83 VerErr .EQU -84 ,.Byte 0,0,0,0 ,.Byte 12,16 ; speed class 1 ,.Word $0FFF ; sector map: 12 sectors ,.Byte 11,16 ; speed class 2 ,.Word $07FF ; sector map: 11 sectors ,.Byte 10,16 ; speed class 3 ,.Word $03FF ; sector map: 10 sectors ,.Byte 9,16 ; speed class 4 ,.Word $01FF ; sector map: 9 sectors ,.Byte 8,16 ; speed class 5 ,.Word $00FF ; sector map: 8 sectors SectClsTbl FmtVerify ,MOVEM.L A0-A6/D1-D7,-(SP) ; preserve all registers ,MOVEQ #12,D0 ; wait 1.2 ms after last write ,BSR WakeUp ,lea SideFlag,a4 ,MOVE.W (a4),D5 ; side ,MOVEQ #79,D6 ; and track number 79 ,LEA SectClsTbl,A3 ; table with trks/class, sector map ,MOVEQ #0,D4 ; clear high byte ,MOVEQ #0,D3 NxtVClass MOVE.W -(A3),D4 ; sectors map this track speed class ,MOVE.W -(A3),D3 ; sec/trk, tracks this speed class ,BNE.S VerTrk VerDone MOVEM.L (SP)+,A0-A6/D1-D7 ; restore all registers ,RTS VerTrk MOVEM.L D2-D7/A0-A6,-(SP) ,BSR Seek ; seek to desired track ,MOVEM.L (SP)+,D2-D7/A0-A6 ,BMI.S VerDone ,BSR.S VerTrack ; and verify it ,BNE.S VerDone ; exit on errors ,SUBQ.W #1,D6 ; next track ,SUBQ.B #1,D3 ; end of speed class? ,BNE.S VerTrk ,BRA.S NxtVClass ; move to next speed class SectMpSave .WORD 0,0 VerTrack MOVEM.L D1-D7/A0-A6,-(SP) ,ORI #$0300,SR ; no interrupts ,LEA SectMpSave,A0 ,MOVE.W D4,(A0)+ ; save sector map ,LSR.W #8,D3 ; sectors this track ,MOVE.W D3,(A0) VTLoop ,lea SideFlag,a0 ,MOVE.W (a0),D0 ; Which side? ,BEQ.S @1 ; br if not ,JSR RdAddr1Setup ; use a different routine ,BRA.S @2 @1 JSR RdAddrSetup ; read an address mark @2 BPL.S @3 ; br if ok ,BSR EmptyPD ,BRA.S VTExit @3 MOVE D2,DskErr ; save sector number ,LEA FBuffer,A0 ; get someplace to stick data ,CLR.B DskVerify ; never verify for this one ,BSR RdData ; read in a sector ,MOVE.L PollStack,SP ; reset stack ,TST.W D0 ; read ok? ,BNE.S VTExit ,LEA SectMpSave,A0 ,MOVE.W (A0),D0 ,MOVE.W DskErr,D2 ; retrieve sector number ,BCLR D2,D0 ; mark this sector gotten ,MOVE.W D0,(A0)+ ; stash it back ,BEQ.S VTExitOK ; exit if now zero ,SUBQ.W #1,(A0) ; decrement sector count ,BNE.S VTLoop ; loop until done ,MOVEQ #VerErr,D0 ; should get 1-1 ok reads ,BRA.S VTExit VTExitOK MOVEQ #0,D0 VTExit ANDI #$F8FF,SR ,MOVEM.L (SP)+,D1-D7/A0-A6 ,TST.W D0 ,RTS ;_______________________________________________________________________ ; ; Routine: Format ; Arguments: D0.W (output) -- result code (0 if correctly formatted) ; Function: This routine formats side 0 of the sony diskette ; in the current drive, evenly spreading sync bytes between ; all the intersector gaps, and attempting to get the ; 'spiral' on the diskette from one track to the next ; correct. ; ; To Do: ; add routine to init fs master directory block, so that this diskette ; looks like a 0-file, non-boot diskette. (how are boot blocks added?). ;_______________________________________________________________________ MustFindCt .EQU 1500 ; nybbles to search for address mark TrkClsTbl .BYTE 16,12 ; speed class 1: 16 tracks @ 12 sec/trk ,.BYTE 16,11 ; speed class 2 ,.BYTE 16,10 ; speed class 3 ,.BYTE 16,9 ; speed class 4 ,.BYTE 16,8 ; speed class 5 ,.BYTE 0,0 ; end of diskette side Format ,MOVEM.L A0-A6/D1-D7,-(SP) ; preserve all registers ,LEA hdrSyncOS+FmtParam,A0 ; set this to 7 each time ,MOVE.W #7,(A0) ,CLR.L TagData+2 ,CLR.L TagData+6 ; clear for good tagging ,BSR Recal ; ,BNE.S FmtDone ,MOVE.W #0,D6 ; side and track number 0 ,LEA TrkClsTbl,A3 ; table with trks/class, sectors/track ,MOVEQ #0,D4 ; clear high byte NxtClass MOVE.B (A3)+,D3 ; number of tracks this speed class ,MOVE.B (A3)+,D4 ; sectors/track this track speed class ,BNE.S FmtTrk FmtDone MOVEM.L (SP)+,A0-A6/D1-D7 ; restore all registers ,EXT.L D0 ; long result ,RTS FmtTrk MOVEM.L D2-D7/A0-A6,-(SP) ; save regs thru speed drift compensate ,BSR GetDrv1 ,MOVE.W D6,SideTrack(A1) ,MOVE.W SideTrack(A1),D6 ; seek . . . ,BSR Seek ; seek to desired track ,BMI.S toFmtDone ,bra GoFormat toFmtDone MOVEM.L (SP)+,D2-D7/A0-A6 ,bra FmtDone GoFormat MOVEM.L (SP)+,D2-D7/A0-A6 ,BSR.S FormatTrack ; and format it ,BNE.S FmtDone ; exit on errors ,ADDQ.W #1,D6 ; next track ,SUBQ.B #1,D3 ; end of speed class? ,BNE.S FmtTrk ,BRA.S NxtClass ; move to next speed class FormatTrack MOVEM.L D1-D7/A0-A6,-(SP) ,lea SideFlag,a0 ,MOVE.W (a0),D5 ; side FmtTrk0 LEA FBuffer,A0 ,LEA FmtParam,A6 ,MOVE.L A0,bufptrOS(A6) ; ,MOVE.W D6,D0 ; track number ,LSR.B #6,D0 ; get 2 high bits into bits 0-1 ,LSL.B #5,D5 ; side bit -> bit 5 ,OR.B D5,D0 ,MOVE.B D0,sidenumOS(A6) ; side + 2 hi bits of track number ,AND.W #$003F,D6 ; low 6 bits only ,MOVE.B D6,trknumOS(A6) ; track ,MOVE.W D4,sectcntOS(A6) ; sector count ,MOVE.W #Fmt2Byte,volnumOS(A6) ; volume FmtTrk1 ORI #$0300,SR ; no interrupts ,LEA FmtParam,A0 ; param block pointer ,BSR TrackFormat ; format the track ,BNE.S FTExit ; exit on write errors ; now we check the intersector gap ,lea SideFlag,a0 ,MOVE.W (a0),D0 ; Which side? ,BEQ.S @1 ; br if not ,JSR RdAddr1Setup ; use a different routine ,BRA.S @2 @1 JSR RdAddrSetup ; read an address mark @2 BSR EmptyPD ; get rid of poll data ,MOVE.W D0,DskErr ; save error code ,BMI.S DecrSn1 ; br on error (change amt of sync in case H; erase turn-off glitched us out) ,MOVE.W #Fmt1Err,DskErr ; "not sector 0" ,TST.B D2 ; check for sector 0 ,BNE.S DecrSn1 ; if not there, too much sync GapCk2 MOVE.L #MustFindCt+4,D1 ; nibble must find count, adjusted ,SUB.W D0,D1 ; nybble gap before sector 0 ,DIVU #5,D1 ; sync group count ,LEA FmtParam,A6 ,MOVE.W #Fmt2Err,DskErr ; "not enuf sync" ,SUB.W hdrSyncOS(A6),D1 ; groups more than the standard ,BMI.S DecrSync ; br if too little ,EXT.L D1 ,DIVU sectcntOS(A6),D1 ; groups per sector ,BEQ.S FTExitOK ; br if ok ,CMP.W #1,D1 ; don't increase if only by 1 ,BEQ.S FTExitOK ,ADDQ.W #1,hdrSyncOS(A6) ; increase intersector gap by 1 only FTExitOK TST.B D5 ; side 1? ,bra @1 ;******************************************* ,BNE.S @1 ; br if so ,BSR GetDrv1 ; do we have a two-sided drive? ,TST.B Sides(A1,D1) ,BPL.S @1 ; br if not (only 1-sided . . .) ,ADDQ.B #1,D5 ; set for side 1 ,BRA FmtTrk0 ; and format the other side @1 MOVEQ #0,D0 FTExit ANDI #$F8FF,SR ,MOVEM.L (SP)+,D1-D7/A0-A6 ,TST.W D0 ,RTS DecrSync ,LEA FmtParam,A6 ,SUBQ.W #1,hdrSyncOS(A6) ; decrement intersector gap sync ,CMP.W #4,hdrSyncOS(A6) ; not below the minimum tho ,BGE.S @1 ,MOVE.W DskErr,D0 ,BRA.S FTExit @1 ADDQ.W #1,D1 ; if only one, don't worry ,BEQ.S FTExitOK ,BRA.S FmtTrk1 ; otherwise, go again DecrSn1 ,LEA FmtParam,A6 ,SUBQ.W #1,hdrSyncOS(A6) ; decrement intersector gap sync ,CMP.W #3,hdrSyncOS(A6) ; not below the minimum tho ,BGE.S FmtTrk1 ; go again ,MOVE.W DskErr,D0 ,BRA.S FTExit ;_____________________________________________________________________ ; ; Routine: TrackFormat ; Arguments: A0.L (input) -- pointer to parameter buffer: ; 00: pointer to buffer of min size 27*num sects ; 04: number of sectors ; 06: volume ; 08: side ; 09: track ; 0A: number of sync groups in intersector gap ; all registers are preserved ; Function: Formats the current track; the disk is assumed to be up ; to speed and correctly positioned, and interrupts disabled. ; ; write 200 sync groups (get something on the disk) ; start with sector 0: do 2-1 soft interleave ; ; loop: intersector gap sync groups ; ; 10 $A9 nybbles (only before sector 0) ; 1 sync group (6) ; D5 AA 96 trk sec side vol cksum DE AA FF (11) ; 1 sync group (6) ; D5 AA AD sec (4) ; ; 703 96 nibbles ; DE AA FF ; loop for all sectors ; ; ; ;_____________________________________________________________________ SyncTbl ".BYTE $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern ".BYTE $DE,$AA,$FF,$FF ; data mark bit slip bytes adrBytCnt .EQU 27 ; bytes in buffer for a sector adr mark syncBytCnt .EQU 6 ; bytes in a sync group dataBytCnt .EQU 703 ; number of $96 nibbles in an address mk strtSync .EQU 200 ; number of sync groups to initially write TrackFormat ,MOVEM.L D1-D7/A0-A6,-(SP) ,MOVE.L A0,A6 ; preserve param blk pointer ,MOVE.L bufptrOS(A6),A0 ; get parameters into registers ,MOVE.W sectcntOS(A6),D0 ,MOVE.W volnumOS(A6),D1 ,MOVE.W sidenumOS(A6),D2 ,BSR FillAdrBuf ; set up address mark buffer ; set up ; A0 : pointer to address mark buffer D0 : sector count ; A1 : pointer to sync group, data mk slip D1 : sync group count ; A2 : working buffer pointer D2 : working buffer count ; A3 : Q6H D3 : scratch ; A4 : Q6L D4 : scratch ,MOVE.W hdrSyncOS(A6),D1 ,SUBQ.W #2,D1 ; adjust for DBRA and adr mk sync ,LEA SyncTbl,A1 ,MOVE.L A1,A2 ; write a sync group ,MOVE.W #strtSync-1,D3 ,MOVE.L #DiskQ6H,A3 ; set up Q6H pointer ,MOVE.L #DiskQ6L,A4 ; set up Q6L pointer ,TST.B (A3) ; first byte written is a bit wierd ,MOVE.B (A2)+,DiskQ7H ; write first bit slip mark ,MOVE.L (SP),(SP) ; delay a bit ,MOVE.L (SP),(SP) ; delay a bit ,TST.B (A4) ; should be ready for second one now ,BMI.S @1 ; so go write it ,.WORD $FF40 ; otherwise, trap for now (hardware prob) @1 MOVE.B (A2)+,(A3) ; write nibble ,MOVEQ #syncBytCnt-3,D2 ,BRA.S WSS1 WrStrtSync MOVE.L A1,A2 ; write a sync group ,MOVEQ #syncBytCnt-1,D2 WSS1 MOVE.B (A2)+,D4 ; prefetch @2 TST.B (A4) ; check write handshake ,BPL.S @2 ; ,MOVE.B D4,(A3) ; write out next header nibble ,DBRA D2,WSS1 ,DBRA D3,WrStrtSync WrNxtSect MOVE.W D1,D3 ; number of sync groups - 1 @1 MOVE.L A1,A2 ; write a sync group ,MOVEQ #syncBytCnt-1,D2 @2 TST.B (A4) ; check write handshake ,BPL.S @2 ; ,MOVE.B (A2)+,(A3) ; write out next gap nibble ,DBRA D2,@2 ,DBRA D3,@1 ,MOVEQ #adrBytCnt-1,D2 @3 TST.B (A4) ; check write handshake ,BPL.S @3 ; ,MOVE.B (A0)+,(A3) ; write out next adr mk nibble ,DBRA D2,@3 ,MOVE.W #dataBytCnt-1,D2 @4 TST.B (A4) ; check write handshake ,BPL.S @4 ; ,MOVE.B #$96,(A3) ; write out next data mk nibble ,DBRA D2,@4 ,MOVEQ #3,D2 @5 TST.B (A4) ; check write handshake ,BPL.S @5 ; ,MOVE.B (A2)+,(A3) ; write out next bit slip nibble ,DBRA D2,@5 ,SUBQ.W #1,D0 ,BGT.S WrNxtSect ; write all sectors ,MOVE.B (A4),D0 ; read write handshake reg for status ,MOVEQ #0,D2 ; assume no underrun ,BTST #6,D0 ; any errors? ,BNE.S @6 ; branch if no underrun was detected ,MOVEQ #WrUnderRun,D0 ; underrun error ,BRA.S @7 @6 MOVEQ #0,D0 ; no errors @7 TST.B DiskQ7L ; get out of write mode after half H; of garbage nibble is written ,MOVEM.L (SP)+,D1-D7/A0-A6 ,RTS ;_____________________________________________________________________ ; ; Routine: FillAdrBuf ; Arguments: A0.L (input) -- buffer pointer (must be 27*number of sectors) ; D0.W (input) -- number of sectors ; D1.B (input) -- volume ; D2.W (input) -- side - track ; all registers are preserved ; Function: Fills the buffer with the address mark and sync nibbles ; as follows: ; ; 1 sync group (6) ; D5 AA 96 vol sec side trk cksum DE AA FF (11) ; 1 sync group (6) ; D5 AA AD sec (4) ; ;_____________________________________________________________________ AdrMkTbl ".BYTE $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern ".BYTE $D5,$AA,$96,$00,$00,$00,$00 ; addr mk skeleton ".BYTE $00,$DE,$AA,$FF ".BYTE $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern ".BYTE $D5,$AA,$AD,$00,$00 ; data mark header VolOffset .EQU 12 SecOffset .EQU 10 SidOffset .EQU 11 TrkOffset .EQU 9 CkSumOffset .EQU 13 DSecOffset .EQU 26 FillAdrBuf ,MOVEM.L A0-A1/D0-D7,-(SP) ,MOVEQ #0,D4 ; first sector number ,MOVE.W D0,D3 ; number of sectors ,SUBQ.W #1,D3 ,LSR.W #1,D3 ,ADDQ.W #1,D3 ; second sector number @1 MOVE.W D4,D5 ; next even sector number ,BSR.S AddToBuf ,ADDQ.W #1,D4 ,SUBQ.W #1,D0 ,BEQ.S FABExit ,MOVE.W D3,D5 ; next odd sector number ,BSR.S AddToBuf ,ADDQ.W #1,D3 ,SUBQ.W #1,D0 ,BNE.S @1 FABExit MOVEM.L (SP)+,A0-A1/D0-D7 ,RTS AddToBuf LEA AdrMkTbl,A1 ; first fill in the skeleton ,MOVEQ #adrBytCnt-1,D6 ; number of bytes in the table - 1 @1 MOVE.B 0(A1,D6),0(A0,D6) ; move end to beginning ,DBRA D6,@1 ,LEA Nibl,A1 ,MOVE.B 0(A1,D1.W),VolOffset(A0) ; write volume nibble ,MOVEQ #0,D7 ; initialize checksum ,MOVE.B D1,D7 ,MOVE.B 0(A1,D5.W),SecOffset(A0) ; write sector nibble ,MOVE.B 0(A1,D5.W),DSecOffset(A0) ; write data mark sector nibble ,EOR.B D5,D7 ; update checksum ,MOVE.W D2,D6 ; side - track ,LSR.W #8,D6 ; side ,MOVE.B 0(A1,D6.W),SidOffset(A0) ; write side nibble ,EOR.B D6,D7 ; update checksum ,MOVE.W D2,D6 ; side - track ,AND.W #$00FF,D6 ; track ,MOVE.B 0(A1,D6.W),TrkOffset(A0) ; write track nibble ,EOR.B D6,D7 ; checksum ,MOVE.B 0(A1,D7.W),CkSumOffset(A0) ; write checksum nibble ,ADD.W #adrBytCnt,A0 ; bump buffer pointer ,RTS ; Normal Nibblizing Table -> convert 6 bits into 8-bit code word. Nibl ".Byte $96,$97,$9A,$9B,$9D,$9E,$9F,$A6 ".Byte $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3 ".Byte $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC ".Byte $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3 ".Byte $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE ".Byte $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC ".Byte $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 ".Byte $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF FBuffer .Block 512,0 ; used for format, verify data 3. "6F^5D!$ǐ^( 22; File: SonyUtil.Text ;_______________________________________________________________________ ; ; Sony 3-1/2 Inch Drive Test Program: Utility Routines ; ; written by Larry Kenyon, beginning 6-March-83 ; ; Register Conventions: ; A3,A4: used for return addresses, highest level (MakeSpdTbl) ; also use D3-D4 to keep values, may trash all other regs ; A5,A6: used for return addresses, lowest level (Seek, Recal) ; also use D5,D6,D7 to keep values, must preserve A3-A4/D3-D4. ; DskRtnAdr: used by RdAddr,RdData,WrData,WakeUp to store return address. ; Utility routines must preserve registers D3-D7/A3-A6 (though many ; preserve all regs except D0). ; ; Modification History: ; 05 APR 83 LAK Broke out from SonyMid to share with SonyHi. ; 20 Aug 83 LAK Updated with the latest; I try to be compatible with ; both 5$ and final ROMs. Uses seek handshaking to be ; compatible with slow seeking precision disks . . . ;_______________________________________________________________________ TwigVers .Equ 0 ,.NOLIST ,.INCLUDE tlasm:SysEqu.Text ; general system equates ,.INCLUDE tlasm:SysErr.Text ; error equates ,.INCLUDE tlasm:SonyEqu.Text ,.INCLUDE tlasm:SysMacs.Text ,.LIST ; note disk not installed when both DIP and Wr Prot = 1 ,.PROC SUtil,0 ,.ORG 0 ,.DEF Seek ,.DEF Seek1 ,.DEF Recal ,.DEF Eject ,.DEF SetASpeed ,.DEF SetSpeed ,.DEF WakeUp ,.DEF Format ,.DEF TrkFormat ,.DEF FmtVerify ,.DEF GetDrive ,.DEF GetDrv1 ,.DEF DiskOpen ,.DEF MakeSpdTbl ,.DEF AdrAndStrb ,.DEF AdrAndSense ,.DEF AdrDisk ,.DEF Sense ,.DEF Pulse ,.DEF RdAddrSetUp ,.DEF RdAddr1SetUp ,.DEF EmptyPD ,.DEF RdAddr ,.DEF RdData ,.DEF WrData ,.DEF RWPowerUp ,.DEF PowerUp ,.REF SlowSeek ,.REF SideFlag ; Disk Driver Initialization routine DiskOpen LEA TagData,A0 ; get address low-memory variables ,MOVEQ #6,D0 ; 7 words for TagData @2 CLR (A0)+ ,DBRA D0,@2 ; clear out local area ,MOVE.L SonyVars,A1 ,MOVE.W #KHdSetTime,HeadSettle(A1) ; deflt head settle time = 30 ms ,MOVE.W #KSpdChgTime,SpdChgTime(A1); deflt speed chg wait time = 150 ms ,RTS ;_______________________________________________________________________ ; ; Routine: AdrAndSense, AdrAndStrb, AdrDisk, Pulse, Sense ; Arguments: A1 (output) -- pointer to driver variables (input for GetOther) ; D1 (output) -- word offset of current drive's specific vars ; A0 (output) -- IWM base ptr ; A2 (output) -- VIA base ptr ; Function: Utility routines used in addressing and configuring disk. ;_______________________________________________________________________ AdrDisk BSR.S GetDrive ; setup A0,A1,A2,D1 ,TST.B Ph0H(A0) ; when changing SEL from 1 to 0, ,TST.B Ph1H(A0) ; CA0=CA1=1 must be true ,TST.B Ph2L(A0) ; assume low ,LSR.B #1,D0 ; CA2 state ,BCC.S @1 ,TST.B Ph2H(A0) @1 BCLR #VHeadSel,VBufD(A2) ; assume low ,LSR.B #1,D0 ; SEL state ,BCC.S @2 ,BSET #VHeadSel,VBufD(A2) @2 LSR.B #1,D0 ; CA0 state ,BCS.S @3 ,TST.B Ph0L(A0) @3 LSR.B #1,D0 ; CA1 state ,BCS.S @4 ,TST.B Ph1L(A0) @4 RTS AdrAndSense BSR.S AdrDisk Sense MOVE SR,-(SP) ,ORI #$0300,SR ,TST.B Q6H(A0) ; get into sense mode ,MOVE.B Q7L(A0),D0 ; sense it ,TST.B Q6L(A0) ; back to read mode ,MOVE (SP)+,SR ,TST.B D0 ,RTS AdrAndStrb BSR.S AdrDisk Pulse MOVE SR,-(SP) ,ORI #$0300,SR ,TST.B Ph3H(A0) ; pulse it high, then low ,TST.B Ph3L(A0) ,RTE ;_______________________________________________________________________ ; ; Routine: GetDrive ; Arguments: A1 (output) -- pointer to driver variables ; D1 (output) -- word offset of current drive's specific vars ; A0 (output) -- IWM base ptr (GetDrive only) ; A2 (output) -- VIA base ptr (GetDrive only) ; Function: Get much-used values into D1,A0,A1, and A2. ;_______________________________________________________________________ GetDrive MOVE.L #DBase,A0 ; set up pointers to hardware ,MOVE.L VIA,A2 ; (5$ doesn't have IWM loc set up) GetDrv1 MOVE.L SonyVars,A1 ; ptr to driver locals ,CMP.W #1,Drive(A1) ; drive 1 (internal drive)? ,BEQ.S @1 ; br if so ,MOVE.W #Drive2,D1 ; external drive's var offset ,RTS @1 MOVEQ #Drive1,D1 ; internal drive's var offset ,RTS ;_______________________________________________________________________ ; ; Routine: Seek,Seek1 ; Arguments: D6.W (input) -- track to seek to ; D5.W (input) -- side to seek to ; D0 (output) -- result code ; Disk speed is set appropriately for the track. ; A3-A4/D3-D4 are preserved. ; All other registers are clobbered ; This routine returns to one level above the caller during ; the seek (unless no seek is required). ; Seek1 is used when the speed table is not valid. ; Function: Seek to a track. ;_______________________________________________________________________ Seek BCLR #11,D6 ; clear side bit (for now . . .) Seek1 MOVE.L (SP)+,A6 ; save caller's address ; D6 holds the track sought . . ,BSR GetDrv1 ,MOVE.W Track(A1,D1),D7 ; current track ,BPL.S SeekLp ; br if curTrack is valid ,BSR ReCal ; recal to get into a known state ,MOVE.W D0,D7 ; current track ,BNE.S SeekExit ; don't seek if recal fails SeekLp CMP.W D6,D7 ; already there? ,BEQ.S SeekEnd1 ; then we need not wait head settle time SeekLp1 MOVEQ #DirLAdr,D0 ; assume step in ,MOVEQ #1,D1 ; (step into higher tracks) ,MOVE.W D7,D2 ; current track ,SUB.W D6,D2 ; delta steps ,BEQ.S SeekEnd ; br if there ,BMI.S @1 ; step in ,MOVEQ #DirHAdr,D0 ,MOVEQ #-1,D1 @1 ADD.W D1,D7 ; adjust current track ,BSR AdrAndStrb ; set stepper direction ,MOVE.W D7,Track(A1,D1) ; update current track ,LEA SlowSeek,A0 ,MOVE.W (A0),D2 ; remember slow/reg seek option ,MOVEQ #StepLAdr,D0 ; check that step is high ,BSR AdrDisk ; address it @2 BSR Sense ; keep sensing until it's ready ,BMI.S @3 ; br if ready ,bra @2 @3 BSR Pulse ; then set it low ,BRA.S SeekLp1 SeekEnd BSR GetDrv1 ,MOVE.W D7,Track(A1,D1) ; update current track ,moveq #ReadyAdr,d0 ;Wait until ready ,bsr AdrDisk @1 bsr Sense ,bmi @1 SeekEnd1 MOVE.W D7,D0 ; positive value = success SeekExit JMP (A6) ; A6 has return address ;_______________________________________________________________________ ; ; Routine: Recal ; Arguments: ; ; D0 (output) -- result code ; This routine returns to one level above the caller during ; the recal (unless no seek is required). ; Function: Recal to track 0. ;_______________________________________________________________________ Recal MOVE.L (SP)+,A5 ; save return address SetIWMMode ,BSR GetDrive ,MOVEQ #$1F,D1 ; mask and value (coincidence) ,TST.B Q6H(A0) ; set IWM to sense mode ,MOVE.B Q7L(A0),D0 ; sense the mode register ,TST.B Q6L(A0) ; and back to read mode ,AND.B D1,D0 ; see if it's correct ,CMP.B D1,D0 ,BEQ.S @3 ; br if so ,MOVEQ #2,D2 ; loop timeout count = $20000 ,SWAP D2 ; should be about a second @1 MOVEQ #initIWMErr,D0 ; assume timeout error ,SUBQ.L #1,D2 ; decrement timeout loop ,BMI.S RecalExit ; exit on error . . . ,TST.B MtrOff(A0) ; change the IWM mode now ,TST.B Q6H(A0) ; set IWM to sense state ,MOVE.B Q7L(A0),D0 ; sense the mode register ,BTST #5,D0 ; interface should be disabled ,BNE.S @1 ; keep waiting ,AND.B D1,D0 ; see if low bits match mode we want ,CMP.B D1,D0 ,BEQ.S @2 ; if so, we are done ,MOVE.B D1,Q7H(A0) ; set to sony mode ,TST.B Q7L(A0) ; set IWM back to sense state ,BRA.S @1 ; loop back just to check @2 TST.B Q6L(A0) ; and back to read mode ,BSR RWPowerUp ; reenable the interface and H; repower the drive . . . @3 MOVEQ #80,D7 ; maximum number of steps needed RecalLoop ,MOVEQ #Tk0Adr,D0 ,BSR AdrAndSense ,BPL.S ReCalled ; keep going until track 0 is true ,MOVEQ #DirHAdr,D0 ; set direction out ,BSR AdrAndStrb ,LEA SlowSeek,A0 ,MOVE.W (A0),D2 ; remember slow/reg seek option ,MOVEQ #StepLAdr,D0 ; check that step is high ,BSR AdrDisk ; address it @2 BSR Sense ; keep sensing until it's ready ,BMI.S @3 ,bra @2 @3 BSR Pulse ; then set it low ,moveq #ReadyAdr,d0 ,bsr AdrDisk ;Wait until ready, so TK0 is sensed OK @4 bsr Sense ,bmi @4 ,MOVEQ #tk0BadErr,D0 ; assume error ,SUBQ.W #1,D7 ; reached maximum step count? ,BEQ.S RecalExit ; exit if so ,BRA.S RecalLoop ; keep going until track 0 is true ReCalled ,moveq #ReadyAdr,d0 ,bsr AdrDisk ;Wait until ready, so TK0 is sensed OK @1 bsr Sense ,bmi @1 ,MOVEQ #0,D0 ; track 0 RecalExit MOVE.W D0,Track(A1,D1) ,JMP (A5) ;_______________________________________________________________________ ; ; Routine: DiskSelect ; Arguments: Drive -- drive to enable ; D1,A0,A1,A2 set up per GetDrive ; Clobbers D0. ; DiskSel1 is a quick entry for DiskSense ; Function: Assert the IWM enable to a drive. ; ;_______________________________________________________________________ DiskSelect BSR GetDrive DiskSel1 MOVE #IntDrive,D0 ,CMP.W #Drive1,D1 ,BEQ.S @1 ; if Drive = 1, it's internal ,MOVE #ExtDrive,D0 @1 TST.B 0(A0,D0.W) ; select one or the other ,TST.B MtrOn(A0) ; and enable the disk, IWM style ,RTS ;_______________________________________________________________________ ; ; Routine: Eject ; Arguments: ; ; D0 (output) -- result code ; This routine returns to one level above the caller during ; the Eject. ; Function: Eject the diskette in the currently selected drive. ;_______________________________________________________________________ Eject MOVE.L (SP)+,A4 ,MOVEQ #EjectHAdr,D0 ,BSR AdrDisk ; address eject-high bit ,TST.B Ph3H(A0) ; set strobe high ,MOVE.W #KEjectTime,D0 ; wait .75 seconds ,BSR WakeUp ,TST.B Ph3L(A0) ; set strobe low then ,MOVE.W #KEjectTime,D0 ; wait .75 seconds ,BSR WakeUp ,CLR.B DiskInPlace(A1,D1) ; set to no disk-in-place ,JMP (A4) ;_______________________________________________________________________ ; ; Routine: SetSpeed, SetASpeed ; Arguments: D6.W (input) -- track number speed should be set for ; Drive (input) -- current disk drive ; TrkSpeedTbl (in) -- speed code table for current drive ; Wait (output) -- 0, or SpdChgTime if CurSpeed changed ; registers other than A0-A2, D0-D2 are preserved ; Called By: (SetSpeed): Seek,RWPower ; (SetASpeed): MakeSpdTbl ; Function: This routine determines the correct speed value for Track ; and sets up the PWM memory buffer to produce the desired output. ; The value of Wait is set to SpdChgTime if the speed is ; changed, 0 otherwise. The TrkSpeedTbl for the current ; drive is used. The drive enable is not changed, just the ; PWM buffer in memory. ; ; SetASpeed is an alternate entry point which simply sets the ; pwm buffer according to a speed code in D2. ;_______________________________________________________________________ SetSpeed ; SetASpeed is an alternate entry point which simply sets up the speed code in D2 SetASpeed LoadPWMBuf SetSpdExit BRA GetDrv1 ;_______________________________________________________________________ ; ; Routine: WakeUp ; Arguments: D0 (input) -- number of 100 usec intervals to wait (<65536) ; registers A3-A5 and D3-D7 are preserved. ; Function: Saves the return address in DskRtnAdr; it will call this ; routine after the timer interrupt in which the count is ; exhausted. Since the timer ticks away at 780 KHz, ; there are 78 timer ticks in each 100 microsecond interval. ;_______________________________________________________________________ ;_______________________________________________________________________ ; ; WakeUp waits the number of 100 microsecond increments specified by D0. ; All regs are preserved. This routine is for test use only; normal ; diosk routines use a version which returns idle time to the user. ; ; 6522 timer T2 is used so that interrupts will not affect timings much. ; 6.4K msec maximum delay. ;_______________________________________________________________________ WakeUp MOVEM.L D1/A2,-(SP) ,MOVE.L SonyVars,A2 ,SUB.W D0,Wait(A2) ,BGT.S @1 ,CLR.W Wait(A2) @1 LEA VBase,A2 ,MOVE.B #$20,VIER(A2) ; disable interrupts from the timer ,;ANDI #$F8FF,SR ; reenable interrupts ,MULU #78,D0 ; 78 counts = 100 usec ,MOVE D0,D1 ,SWAP D0 ; get remainder MS84Loop MOVE.B D1,VT2C(A2) ; write low byte ,ROL.W #8,D1 ; get high byte ,MOVE.B D1,VT2CH(A2) ; start timer and clear flag MSWLoop BTST #5,VIFR(A2) ; wait for flag to go high ,BEQ.S MSWLoop ,MOVE.B VT2C(A2),VT2C(A2) ; low byte counter goes to latch ,MOVE.B #$FF,VT2CH(A2) ; stuff the high byte to keep going ,SUBQ #1,D0 ; any left to do? ,BPL.S MSWLoop ,MOVEM.L (SP)+,D1/A2 ,RTS ; and return ;_______________________________________________________________________ ; ; Routine: MakeSpdTbl ; Arguments: Drive (input) -- current drive ; D0 (output) -- error code (-1 = drive not installed) ; all registers are used. ; current drive is powered up and recal'ed. ; Called By: CheckDIP,DoRecal ; Function: Makes a speed table for the current drive. ; ; Note: Drive must spin at speed codes 128 and 256 for this routine ; to work. ; ; Note: Speed variation has three major factors, temperature drift, speed ; drift, and load variation. Temperature drift occurs as the drive gets ; warmer and generally? is a negative factor (drive slows) accounting for ; up tp 6%? of speed variation. Speed drift occurs during ; the first minute the drive is powered and is a negative factor accounting ; for less than 1/2 of 1% of speed variation. Load is a factor which ; varies between inside and outside tracks of a drive: the inner tracks ; present less loading to the head than the outer tracks; speed variation ; due to loading may be as much as 1%. ; ; The main read/write track logic adjusts for speed drift by periodically ; checking the disk speed and adjusting the speed code if the speed is off ; by more than 2% using a speed code delta figured out by this routine: this ; should also catch any speed drift problems, depending upon the period ; of the check. ; ; We ignore loading variation since it is only 1% max and we will recheck ; each speed class when we first seek to it. Temperature and speed drift ; are not as easy to compensate for, but since they are both negative factors, ; this routine rounds to higher speed values. ; ;_______________________________________________________________________ ; table of frequency counts for 15 tach pulses, each of the 5 speed classes TachFreqs .WORD 4585,4405 ; speed class 1: +2%,-2% (4495) ,.WORD 5002,4806 ; speed class 2: +2%,-2% (4904) ,.WORD 5503,5287 ; speed class 3: +2%,-2% (5395) ,.WORD 6114,5874 ; speed class 4: +2%,-2% (5994) ,.WORD 6878,6608 ; speed class 5: +2%,-2% (6743) TrkClassCnt .EQU 5 ; number of track speed classes MakeSpdTbl MOVE.L (SP)+,A4 ; save return address ,clr.w d0 FSRTS TST.W D0 ; result code ,JMP (A4) ; return via A4 ; routine to call polldata process procedure if there is one, ; or reset the stack if there isn't . . . EmptyPD MOVE.L (SP)+,A4 ; save return address ,PEA @2 ; this routine's return address ,MOVE.L PollProc,-(SP) ; is there a proc to process poll data? ,BEQ.S @1 ; br if not ,MOVE.L SonyVars,A1 ,MOVEM.L D0/D2-D3/A0/A4,SaveRegs(A1) ; save some regs ,RTS ; go to it! @2 BSR GetDrv1 ,MOVEM.L SaveRegs(A1),D0/D2-D3/A0/A4 ,JMP (A4) @1 MOVE.L PollStack,SP ; otherwise, throw away any data ,BSR GetDrv1 ,JMP (A4) AdrMks ".Byte $D5,$AA,$96,$DE,$AA,$FF DtaMks ".Byte $D5,$AA,$AD,$DE,$AA,$FF MarkTbl ".Byte $FF,$3F,$CF,$F3,$FC,$FF ;self-sync pattern ".Byte $D5,$AA ;actual header ($AD written separately) SetUpPoll ,LEA SCCRBase+AData,A6 ; SCC A-reg data ,LEA AVBufA,A5 ; 6522 A-reg has head sel, wait/req ,MOVE.L SP,PollStack ; init PollStack at current stack level ,ADD.L D0,PollStack ; compensate for 1 or 2 levels ,ORI #$0300,SR ,RTS RdAddr1Setup MOVEQ #8,D0 ; init PollStack 8 bytes down ,BSR.S SetUpPoll ,MOVEQ #RdDta1Adr,D0 ; set for side 1 (the jittery side) ,BSR AdrDisk ,BRA.S RdAddr RdAddrSetup MOVEQ #8,D0 ; init PollStack 8 bytes down ,BSR.S SetUpPoll ,MOVEQ #RdDtaAdr,D0 ,BSR AdrDisk RdAddr LEA AdrMks,A2 ,MOVE.L JRdAddr,-(SP) ,RTS RdData LEA DtaMks,A1 ,MOVE.L JRdData,-(SP) ,RTS WrData LEA MarkTbl,A2 ,MOVE.L JWrData,-(SP) ,RTS ;_______________________________________________________________________ ; ; Routine: RWPowerUp,PowerUp ; Arguments: D0 (input) -- power-up time ; Timeout, Power, Wait, Drive ; sets interrupt level 0 if powers up; uses A0-A2,D0-D2 (by wakeup) ; 'Active' should be true when this routine is called. ; Called By: (RWPowerUp): DiskPrime,RWPower,SetIWMMode ; (PowerUp): DiskControl(Eject call) ; Function: PowerUp is called to power up a disk drive. Waits out D0 time ; unless disk is already powered . . . ;_______________________________________________________________________ RWPowerUp MOVE.W PwrOnTime(A1),D0 PowerUp MOVE.W D0,D2 ; save wait time ,BSR GetDrv1 ,CLR.W Timeout(A1) ; always clear timeout flag ,BSR.S DiskSelect ; go enable the interface ,MOVEQ #MtrOnAdr,D0 ,BSR AdrAndSense ; is it already powered up? ,BPL.S @1 ; br if so ,BSR Pulse ; turn power on ,MOVE.W D2,D0 ; get back wait time ,BNE WakeUp ; don't return until time is over @1 RTS ; return, restoring interrupt state ,.INCLUDE SonyFormat.Text ,.END MIDTEST MIDTEST MIDTEST MAKEMIDWMAKEMIDW,EJECT EJECT @GETDRV1 GETDRV1 \bDISKSYNCDISKSYNC6SEEK1 SEEK1 JRECAL RECAL NADRANDSTADRANDST<SETASPEESETASPEE xADRANDSEADRANDSE$WAKEUP WAKEUP  lADRDISK ADRDISK 2xH>M&*ga8 <@g,`a* VE// NpNHk(L|Nuz`zE68/JEfW`XSDnNuH>M<I8YO$fz DfD`0:gJDkaF`"0. Nj gJEjaB` fJEja,SFn8jpg N3L|NuA `A 0`A1///PN/TN/Hz਄,_NuH>/ iMPa0M$aDM8aIz( / qUO// Md/l0gf @ g @ ga`T,E8g $SDn`>UO///8 h0g.UO/`6C/?cMa MJCACNL|NuH>G&B/HzHz?<Bg/ ?</<&_C"7|D7| J7|HC'IC$'IC'ICv'IE8va"$RCSDnE8aBRCSDnL|NuYO/ HjHj?<?* ?*?* j"fBW?*"/T$NuYO/ HjHz?<?* ?*?*?</T$NuF DTrack-Level Test PP^U_dFi nOptionsF 6 NotesQ Pddeject `nid}recal `Xdon ` P dZ read loop ` li }Z write loop ` Z not used ` ~7 KZ write trk ` R 2Zread trk ` 6 Z track test `x( write/read ` (x7 stop on err` l7xF read w/fmt ` P x Side 1 sel ` 4on offP``P```xO`d``_to Data = Track =  P /Exist = P Dirtn = P  /DskIn = P  /Step = OR Sides = OR /W Prt = OR /MtrOn = OR /Trk 0 = 0Z A- A-No Header Found . . .A-Diskette is Write-Protected? A-Not Ready: Disk Inserted?A-Press Mouse Button To Exit LoopA-Write-Underrun Occurred! #Track Pass Count : #2-Bad Nibble Count : 2A<No Hdr Fnd Count : A-Unable To Step (Step = 0)E8"g SDnNuA UO//BJk@ @n @A.h0UO/`8ANNu 8P0/"oH> @fNvp`F0/"oH> @f6vp`.0/"oH> @fvp`0/"oH> @fvpa L|x _\ON82JCjDDaA$PANNuUO/ / UO/ `Wc`8NuH8C"QBiHHz{vA*AUO/`8I(TI@/a*QHz{A/LxCJ"Q3|HNuNVGBS A:/Ha> a8<:a@< a8< a0|a< a QHnN^Nu?Ha0@;rRNu0123456789ABCDEF0<N~`~4NNu0<NA0AD0ABMFaaNu//PN/// GPBS0 @g?XJgad0a^Hz0&_Nu//PN/// GBS0 @g4tH@B@H@ H@2QpHA0?XJga 0aHz֨&_Nu<HNLjMaN81kMa~NuM*//H6<8<E*Eg$a(6<8<E*gaHzHzL8NuH??|~HG><d2JFf |Bg?<` |Bg?<?<BgQHGQLNuBg?MF#AR pA2 AgpNaf"V4<A6 fRSBn<ްfD<f:AZ ( fa9faaF L|AaaNuADR ATJPg Bnf<` r f<E4$)))G& S?A\/?c0@@@A1@P@P@1@aa*F L|AdaVaHz訤NuAR `/MlaMaMa,_Nuanf^AjaMalF!pAt2 AgpNX9fA6aaMa4F NuafH>F#pA*2 AgpNAaMraC2p$|&|(|JJjfJ9EEBaAaBaFMaF L|NuA0NuA0NuA0NuA0Nu/?< ]Nu/Bg]Nu9g0<XN9gNu?ժުaf pNk MpA2 AgpNA6A P0<@S@nAABaF#2<E4<CK&|(|J Jp.Jk@p JJjQQpJjQJjQpJjQfJ9F L|MaDpNuJ9F L|apNuafH>pA*2 AgpNAJPgaBg(Ma`M"V2<@IF#jSAnF L|a NupLNuF#HpM"V"ժI4<= 2<jSBk fjSBk fjSBk fjQpBQpLNuAV0pNkp r`prE/AJAfA/N_NuMhapNupNjpNupNkpNuH`NLNuHNLNuHNLg M a` Cd/BgcaNupLOWTEST LOWTEST LOWTEST MAKELOWWMAKELOWWDISKSYNCDISKSYNCBWAKEUP WAKEUP $H>AE// E08/Bgc$SDnL|NuH>AfNaA 0fJj`Jka2L|NuF#AJ((J(F NuH>/ iaL|Nu/aAmp0Jjp1M/PN/Av PfrgS`/Hz.,_Nu/`H>IH( / qUO// M2/l0gv @ g @ g`hUOM//BSh0gTUO/`6C/?c,E8g $SDn`,A P0*MJCgMACNaL|NuUO/ / UO/ `Wc`8NuH>G&B/HzHz?<Bg/ ?</<&_C'IC'IC`'IC&'IEh8va$RCSDnL|NuYO/ HjHj ?<B?< j"fBW?*"/T$NuZd|Interface Test  <ca2J(NuJ( Nu Fxca1J(NuJ(Nu ca0JNuJ(Nu selNuNu( <<strJ( NuJ(Nu(F<xstr`4`,F Z</enJ(NuJ(Nu@F#J(J( Ns&<8 /Dirtn = /DiskInPl = /Step = /Wr Prot = /Mtr On = /Tk 0 = Eject = Tach = Rd Data = Rd Data = ?? = ?? = Sides = Sides = /Exists = /Exists = 0F< 0<NNu/PN/// GBS0 @g4tH@B@H@ H@2QpHA0?XJga0a Hz&_Nu?Ha0@;rRNu0123456789ABCDEF3. "6F^5D!$ǐ^; File: Work2:SonyMid2 ;_______________________________________________________________________ ; ; Mid Hardware Control Routines ;_______________________________________________________________________ TestStats .LONG 0 ; ,.LONG 0 ; errors TSRdCnt .EQU 0 ; offset to block read count TSErrCnt .EQU 4 ; offset to error count RdTest BSR ReadyCk ; must have dip first ,BNE NotReady ,LEA RWFlag,A0 ,TST.W (A0) ; write before track test? ,BEQ.S @1 ; br if not ,BSR WrTrack ,BEQ.S @1 ; br if write ok ,RTS @1 LEA Tst1Ctl,A0 ,BSR LiteButton ,LEA PassNote,A0 ; zero stats ,CLR.L NoteValOS(A0) ,LEA BadRdsNote,A0 ,CLR.L NoteValOS(A0) ,LEA NoHdrsNote,A0 ,CLR.L NoteValOS(A0) ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA DataBufPtr,A6 ,MOVE #$2300,SR RdTstLoop LEA PassNote,A0 ; ,ADDQ.L #1,NoteValOS(A0) ; incr block read count ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,lea SideFlag,a0 ;See which side to read ,move.w (a0),d1 ,cmp.w #0,d1 ,beq @10 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @10 JSR ToAdrDisk ; set us looking at read data ,BSR RdFTrack ,BNE NoHdr ; br if no header was found CkRdDta MOVE.L (A6),A1 ; data buffer ,MOVE.W #WrNybCnt,D2 ; number of data bytes in block ,LEA theNibble,A0 ,MOVE.W (A0),D3 ; theNibble ,MOVE.L (A1)+,D0 ; first 4 bytes read are ok (header found) ; check for correct data block @1 ASL.L #8,D0 ; next data byte written is a data nibble ,MOVE.B D3,D0 ,CMP.B (A1)+,D0 ; does it match read data? ,BNE.S BadNib ; br if not ,SUBQ.W #1,D2 ,BGT.S @1 ; check for trail marks ,ASL.L #8,D0 ,MOVE.B #$DE,D0 ; first trail mark written ,CMP.B (A1)+,D0 ,BNE.S BadNib ,ASL.L #8,D0 ,MOVE.B #$AA,D0 ; 2nd trail mark written ,CMP.B (A1)+,D0 ,BNE.S BadNib ; we found 'em, so check for mouse down here . . . RdTstLpEnd ,LEA PassNote,A0 ; display stats ,MOVE.L NoteValOS(A0),D0 ; every 8 passes ,AND.B #$07,D0 ,BNE.S @1 ,BSR PassUpdate @1 BTST #VSW,AVBufM ; loop if mouse button is not pressed ,BNE.S RdTstLoop ,BSR WaitMBUp ; then wait for it to go high again RdTstExit BSR PassUpdate ; ,MOVE #$2000,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ,LEA Tst1Ctl,A0 ,BSR DarkButton ,BSR DrawBuf ,RTS BadNib ,LEA BadRdsNote,A0 ; ,ADDQ.L #1,NoteValOS(A0) ; incr block error count ,LEA ErrStpFlag,A0 ,TST.W (A0) ; stop on errors? ,BEQ RdTstLpEnd ; loop if not ; first figure out the next written for reporting by looking at D2 and D0 values ; nibx nibx+1 tm1 tm2 ; D2 value: 2 1 0 0 ,MOVE.B D3,D1 ; assume next is nibble ,CMP.W #1,D2 ,BGT.S @2 ,BNE.S @1 ,MOVE.B #$DE,D1 ; if D2=1, next written was trail mark 1 ,BRA.S @2 @1 MOVEQ #0,D1 ,CMP.B #$DE,D0 ; was last written tm1? ,BNE.S @2 ,MOVE.B #$AA,D1 @2 ASL.L #8,D0 ; make D0 = nib1 nib2 badnib3 nib4 ,MOVE.B D1,D0 ; as written ,LEA goodData,A2 ,MOVE.L D0,(A2) ,MOVE.B -3(A1),D0 ,ASL.L #8,D0 ,MOVE.B -2(A1),D0 ,ASL.L #8,D0 ,MOVE.B -1(A1),D0 ; failing nibble ,ASL.L #8,D0 ,MOVE.B (A1),D0 ; data as read ,LEA badData,A3 ,MOVE.L D0,(A3) ,MOVE.L A1,D0 ; current buffer address ,SUBQ.L #1,D0 ; ptr to failing nibble ,SUB.L (A6),D0 ; relative distance into the buffer ,MOVE.W D0,-(SP) ; save it for offset ,LEA CtlDtaScrl,A0 ,MOVE.L (A0),-(SP) ; theControl handle ,ASR.L #3,D0 ,MOVE.W D0,-(SP) ; scroll data buffer to the error ,_SetCtlValue ,MOVE.W (SP)+,D0 ,AND.W #$07,D0 ; nibble offset ,MULU #18,D0 ; figure out buffer nibble to invert ,ADD.W #320,D0 ; horizontal left ,LEA invNibRect,A0 ,MOVE.W D0,2(A0) ,ADDQ.W #8,D0 ,ADDQ.W #8,D0 ,MOVE.W D0,6(A0) ; horizontal right ,BSR DrawErrs ; display good/bad data as timing diagrams ,BSR PassUpdate ; ,MOVE #$2000,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ,LEA Tst1Ctl,A0 ,BSR DarkButton ,BSR DrawBuf ,PEA invNibRect ,_InverRect ; highlight the nibble ,RTS NoHdr LEA NoHdrsNote,A0 ; ,ADDQ.L #1,NoteValOS(A0) ; incr block error count ,BRA RdTstLpEnd ; don't stop on 'no header' errors PassUpdate MOVE.L A6,-(SP) ; preserve A6 ,LEA PassNote,A6 ; display stats ,BSR DrawNote ,LEA BadRdsNote,A6 ,BSR DrawNote ,LEA NoHdrsNote,A6 ,BSR DrawNote ,MOVE.L (SP)+,A6 ,RTS RdLoop ; we are called after the mouse is up ,BSR ReadyCk ; must be ready first ,BNE NotReady ,LEA Tst2Ctl,A0 ,BSR LiteButton ,LEA ToStopNote,A6 ,BSR DrawNote ,MOVE #$2100,SR ; (interrupts off to keep mouse ok) ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,lea SideFlag,a0 ;See which side to read ,move.w (a0),d1 ,cmp.w #0,d1 ,beq @10 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @10 JSR ToAdrDisk ; set us looking at read data @1 BTST #VSW,AVBufM ; wait until mouse button is pressed ,BNE.S @1 ,LEA Tst2Ctl,A0 ,BSR DarkButton ,BSR WaitMBUp ; then wait for it to go high again ,LEA EraseNote,A6 ,BSR DrawNote ; erase our exit note ,MOVE #$2000,SR ,RTS WrLoop ,BSR ReadyCk ; must be ready first ,BNE NotReady ,MOVEM.L D3-D7/A2-A6,-(SP) ,MOVE #$2300,SR ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,lea SideFlag,a0 ;See which side to read ,move.w (a0),d1 ,cmp.w #0,d1 ,beq @10 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @10 JSR ToAdrDisk ; set us looking at read data ,LEA Tst3Ctl,A0 ,BSR LiteButton ,LEA ToStopNote,A6 ,BSR DrawNote ,LEA theNibble,A1 ,MOVE.W (A1),D1 ; theNibble ,MOVEQ #VSW,D0 ; mouse button reg bit ,MOVE.L #AVBufM,A2 ; mouse button reg ptr ,MOVE.L #DiskQ6H,A3 ; set up Q6H pointer ,MOVE.L #DiskQ6L,A4 ; set up Q6L pointer ,TST.B (A3) ; first byte written is a bit weird ,MOVE.B D1,DiskQ7H ; write it WLoop TST.B (A4) ; check write handshake ,BPL.S WLoop ; ,MOVE.B D1,(A3) ; write when ok ,BTST D0,(A2) ; wait until mouse button is pressed ,BNE.S WLoop ,MOVE.B (A4),D0 ; read write handshake reg for status ,TST.B DiskQ7L ; get out of write mode ,LEA goodData,A2 ; write data ,MOVE.B D1,(A2)+ ,MOVE.B D1,(A2)+ ,MOVE.B D1,(A2)+ ,MOVE.B D1,(A2)+ ,LEA badData,A2 ; no read data ,CLR.L (A2) ,BSR DrawErrs ; display data as timing diagrams ,LEA Tst3Ctl,A0 ,BSR DarkButton ,BSR WaitMBUp ; then wait for it to go high again ,LEA EraseNote,A6 ,BSR DrawNote ; erase our exit note ,MOVE #$2000,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS SetRW LEA RWFlag,A0 ,MOVE.W D3,(A0) ; control value ,RTS SetErrStp LEA ErrStpFlag,A0 ,MOVE.W D3,(A0) ; control value ,RTS SetRdFormat LEA RdFmtFlag,A0 ,MOVE.W D3,(A0) ; control value ,RTS SetSideSel LEA SideFlag,A0 ,MOVE.W D3,(A0) ; control value ,RTS LiteButton MOVE.L (A0),-(SP) ; highlight the button ourselves ,MOVE.W #inButton,-(SP) ,_HiLiteControl ,RTS DarkButton MOVE.L (A0),-(SP) ; unhighlight the button ,CLR.W -(SP) ,_HiLiteControl ,RTS WaitMBUp BTST #VSW,AVBufM ,BEQ.S WaitMBUp ,MOVE.W #600,D0 ; wait 60 ms debounce time ,JSR WakeUp ,BTST #VSW,AVBufM ,BEQ.S WaitMBUp ,RTS SyncTbl ".Byte $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern DtaMkTbl ".Byte $D5,$AA,$AD,$FF ; data mark bytes BitSlpTbl ".Byte $DE,$AA,$FF,$FF ; data mark bit slip bytes SyncGpCnt .EQU 2000 ; write 2000 sync groups before data SyncSize .EQU 6 ; size of sync group DtaMkSize .EQU 3 BitSlpSize .EQU 4 WrTrack ,BSR ReadyCk ; must be ready first ,BNE NotReady ,; check for write-protected diskette! ,MOVEQ #WrProtAdr,D0 ; check for write-protected diskette! ,JSR AdrAndSense ; address it ,BMI.S @0 ; br if writable ,LEA WrProtNote,A6 ; note the problem ,BSR DrawNote ,MOVEQ #-1,D0 ; failure ,RTS @0 MOVEM.L D3-D7/A2-A6,-(SP) ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,lea SideFlag,a0 ;See which side to read ,move.w (a0),d1 ,cmp.w #0,d1 ,beq @10 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @10 JSR ToAdrDisk ; set us looking at read data ,LEA theNibble,A0 ,MOVE.W (A0),D3 ; theNibble ,LEA DataBufPtr,A0 ,MOVE.L (A0),A0 ; set write buffer to all theNibble ,MOVE.W #DtaBufSize,D0 @1 MOVE.B D3,(A0)+ ,SUBQ.W #1,D0 ,BGT.S @1 ,LEA goodData,A0 ; write data ,MOVE.B D3,(A0)+ ,MOVE.B D3,(A0)+ ,MOVE.B D3,(A0)+ ,MOVE.B D3,(A0)+ ,LEA badData,A0 ; no read data ,CLR.L (A0) ,BSR DrawErrs ; display data as timing diagrams ,MOVE #$2300,SR ,MOVE.W #WrNybCnt-1,D1 ; number of bytes - 1 ,LEA SyncTbl,A2 ; pointer to sync group ,MOVE.W #SyncGpCnt,D2 ; number of sync groups to write ,LEA DtaMkTbl,A1 ; pointer to data mark bytes ,LEA BitSlpTbl,A5 ; pointer to bit slip bytes ; first we write some self-sync bytes, and the data mark ,MOVE.L #DiskQ6H,A3 ; set up Q6H pointer ,MOVE.L #DiskQ6L,A4 ; set up Q6L pointer ,TST.B (A3) ; first byte written is a bit wierd ,MOVE.L A2,A0 ,MOVE.B (A0)+,DiskQ7H ; write first bit slip mark ,MOVEQ #SyncSize-3,D0 ; wrote 2 outside the loop ,MOVE.L (SP),(SP) ; delay a bit ,TST.B (A4) ; should be ready for second one now ,BMI.S @3 ; so go write it ,.WORD $FF40 ; otherwise, trap for now (hardware prob) @3 MOVE.B (A0)+,(A3) ; write nibble WSync MOVEQ #SyncSize-1,D0 ; size of sync group ,MOVE.L A2,A0 WSync1 TST.B (A4) ; check write handshake ,BPL.S WSync1 ; ,MOVE.B (A0)+,(A3) ; write out next sync nibble ,DBRA D0,WSync1 ,DBRA D2,WSync ; write sync on most of the track ,MOVEQ #DtaMkSize-1,D0 WHead TST.B (A4) ; check write handshake ,BPL.S WHead ; ,MOVE.B (A1)+,(A3) ; write out next header nibble ,DBRA D0,WHead WData TST.B (A4) ; check write handshake ,BPL.S WData ; ,MOVE.B D3,(A3) ; write out next data nibble ,DBRA D1,WData ,MOVEQ #BitSlpSize -1,D0 WTail TST.B (A4) ; check write handshake ,BPL.S WTail ; ,MOVE.B (A5)+,(A3) ; write out next header nibble ,DBRA D0,WTail ,MOVE.B (A4),D0 ; read write handshake reg for status ,BTST #6,D0 ; any errors? ,BNE.S @1 ; branch if no underrun was detected ,TST.B DiskQ7L ; get out of write mode ,MOVE #$2000,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ; restore A5 particularly ,LEA BadWrNote,A6 ,BSR DrawNote ,MOVEQ #-1,D0 ; failure ,RTS @1 TST.B DiskQ7L ; get out of write mode after half H; of garbage nibble is written @2 MOVE #$2000,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ; restore A5 particularly ,BSR DrawBuf ,MOVEQ #0,D0 ; success! ,RTS RdTrack BSR ReadyCk ; must be ready first ,BNE NotReady ,MOVEM.L D3-D7/A2-A6,-(SP) ,MOVEQ #RdDtaAdr,D0 ;Default to side 0 ,lea SideFlag,a0 ;See which side to read ,move.w (a0),d1 ,cmp.w #0,d1 ,beq @0 ,MOVEQ #RdDta1Adr,D0 ;Set to side 1 @0 JSR ToAdrDisk ; set us looking at read data ,LEA RdFmtFlag,A0 ,TST.W (A0) ; try to read formatted data? ,BEQ.S @1 ; br if not ,BSR RdFTrack ; do a formatted read ,;(add error messages here...'no header', 'no trailer') ,BEQ.S RdTrkExit ,LEA NoHdrNote,A6 ,BSR DrawNote ,BRA.S RdTrkExit @1 LEA DataBufPtr,A6 ,MOVE.L (A6),A1 ; data buffer ,MOVE.W #DtaBufSize,D1 ; number of bytes in buffer ,LEA DiskQ6L,A4 ,MOVE #$2300,SR ReadNib MOVE.B (A4),D3 ,BPL.S ReadNib ; loop until data comes ,MOVE.B D3,(A1)+ ,SUBQ.W #1,D1 ,BGT.S ReadNib ,; beep for success? RdTrkExit MOVE #$2000,SR ,MOVEM.L (SP)+,D3-D7/A2-A6 ,BSR DrawBuf ,RTS NoHdrFnd MOVEQ #-1,D0 ; no header was found ,MOVEM.L (SP)+,D1-D3/A0-A6 ; ,RTS RdFTrack MOVE #$2300,SR ; (make sure interrupts are off - ,MOVEM.L D1-D3/A0-A6,-(SP) ; note that we exit in this state) ,LEA DataBufPtr,A6 ,MOVE.L (A6),A1 ; data buffer ,MOVE.L #$FFD5AAAD,(A1)+ ; data header bytes we will read if ok ,LEA DiskQ6L,A4 ; at 240 rpm (slowest for sony?), = 4 rps, = 250 ms/rev, /16usec/byte, = ; 15625 bytes max on a track, so make this our MUST FIND count ,MOVE.W #15625,D2 ; must find count ,MOVE.W #WrNybCnt+1,D1 ; data byte plus bit slip byte count -1 FindD5 MOVE.B (A4),D3 ,BPL.S FindD5 ; look for a header ,SUBQ.W #1,D2 ,BMI.S NoHdrFnd ,CMP.B #$D5,D3 ,BNE.S FindD5 FindAA MOVE.B (A4),D3 ,BPL.S FindAA ; look for second header byte ,SUBQ.W #1,D2 ,BMI.S NoHdrFnd ,CMP.B #$AA,D3 ,BNE.S FindD5 FindAD MOVE.B (A4),D3 ,BPL.S FindAD ; look for third header byte ,SUBQ.W #1,D2 ,BMI.S NoHdrFnd ,CMP.B #$AD,D3 ,BNE.S FindD5 ; ok, we found the header so go for the data and two bit-slip bytes GetDataBlk MOVE.B (A4),D3 ,BPL.S GetDataBlk ; wait for next byte in ,MOVE.B D3,(A1)+ ; and put it in the buffer ,DBRA D1,GetDataBlk ,MOVEQ #15,D0 ; clear out some bytes for clarity @1 CLR.B (A1)+ ,DBRA D0,@1 ,MOVEQ #0,D0 ; success! ,MOVEM.L (SP)+,D1-D3/A0-A6 ; ,RTS ToSetEnb LEA SenseWord,A0 ; current sense info ,MOVE.W #$FFFF,(A0) ; set for update ,MOVEQ #MtrOnAdr,D0 ; sense current dip state ,JSR AdrAndSense ; address it ,BMI.S TurnOn ; if high, turn it on TurnOff MOVEQ #MtrOffAdr,D0 ,MOVEQ #1,D1 ; control value will be 1 ,BRA.S TurnOn1 TurnOn MOVEQ #MtrOnAdr,D0 ,MOVEQ #0,D1 ; control value will be 0 TurnOn1 LEA DskEnbCtl,A2 ; make sure the control is right ,MOVE.L CRefCOS(A2),-(SP) ; theControl handle ,LEA EnbLoName,A0 ,TST.W D1 ,BNE.S @3 ,LEA EnbHiName,A0 @3 MOVE.L A0,-(SP) ,JSR AdrAndStrb ,_SetCTitle ,RTS NotReady LEA NtRdyNote,A6 ,BSR DrawNote ,MOVEQ #-1,D0 ; note failure for those who care ,RTS ReadyCk MOVEQ #DIPAdr,D0 ; check for disk-in-place ,JSR AdrAndSense ,BPL.S @2 @1 MOVEQ #-1,D0 ; not ready ,RTS @2 MOVEQ #MtrOnAdr,D0 ,JSR AdrAndSense ,BMI.S @1 ; br if motor is off ,MOVEQ #0,D0 ,RTS ToAdrDisk MOVEM.L A1-A2/D0-D1,-(SP) ; set A0 to VBase pointer also ,JSR AdrDisk ,MOVEM.L (SP)+,A1-A2/D0-D1 ,RTS ToEject MOVEM.L A0-A6/D1-D7,-(SP) ,JSR Eject ,MOVEM.L (SP)+,A0-A6/D1-D7 ,RTS ToRecal MOVEM.L A0-A6/D1-D7,-(SP) ,JSR Recal ,MOVEM.L (SP)+,A0-A6/D1-D7 ,BEQ.S @1 ; br if successful ,LEA CantStpNote,A6 ; note that we can't step ,BSR DrawNote ,BRA.S @2 @1 LEA CtlTrkScrl,A1 ; track control ,MOVE.L (A1),-(SP) ; track scroll control handle ,CLR.W -(SP) ; set to track 0 ,_SetCtlValue @2 BSR DrawTrk ; note the track we are on ,RTS W^5P-H r H r^ V; File SonyHi1.Text ;_______________________________________________________________ ; ; Routines for displaying data buffer within the Hi-control ; window. ; ; Modification History: ; ;_______________________________________________________________ ; handle the mouseDown by calling FindControl and tracking the control ; if its in one ScrollTrack ,LEA CtlScroll,A2 ; scroll control data structures ,MOVE.W (A2)+,D4 ; number of scroll controls ,MOVE.L (A6),D1 ; theControl handle @1 CMP.L (A2),D1 ; this control? ,BEQ.S ScrlTrk1 ,ADD #CSDtaSize,A2 ; point to next scroll control ,SUBQ.W #1,D4 ; check them all ,BGT.S @1 ,RTS ScrlTrk1 LEA theCtlDta,A0 ; fill in the data pointer for later ,MOVE.L A2,(A0) ,SUBQ #2,SP ,MOVE.L D1,-(SP) ; theControl handle ,MOVE.L (A4),-(SP) ; local mouse down point ,CLR.L -(SP) ; nil action proc ,TST.B D0 ; examine part code - if not an ,BMI.S @1 ; indicator, it needs an action proc ,SUB.W #20,D0 ; normalize part index ,CMP.W #3,D0 ; should be 0-3 ,BGT.S @1 ; br if not ,ADD.W D0,D0 ; double it ,LEA ActionOffset,A0 ; get offset to actionProc ,ADD.W 0(A0,D0),A0 ; compute actionProc address ,MOVE.L A0,(SP) ; the actionProc @1 _TrackControl ,MOVE.W (SP)+,D0 ; ignore result ,SUBQ #2,SP ,MOVE.L (A2),-(SP) ; now call the end proc ,_GetCtlValue ,MOVE.W (SP)+,D4 ; pass it in D4 ,LEA CSProc2OS(A2),A0 ; get proc pointer ,JSR (A0) ,RTS ActionOffset ,.WORD GoUp-ActionOffset ,.WORD GoDown-ActionOffset ,.WORD PageUp-ActionOffset ,.WORD PageDown-ActionOffset GoUp MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inUpButton,D0 ; in the up button ,BNE.S DoneGoUp ; if not, don't do anything ,MOVEQ #-1,D3 ; move up ,MOVEQ #CSmallOS,D0 ; a small amount ,BRA.S GoDoScroll GoDown MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inDownButton,D0 ,BNE.S DoneGoUp ,MOVEQ #1,D3 ; move down ,MOVEQ #CSmallOS,D0 ; a small amount ,BRA.S GoDoScroll PageUp MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inPageUp,D0 ,BNE.S DoneGoUp ,MOVEQ #-1,D3 ; go up ,MOVEQ #CPageOS,D0 ; a page amount ,BRA.S GoDoScroll PageDown MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inPageDown,D0 ,BNE.S DoneGoUp ,MOVEQ #1,D3 ; go down ,MOVEQ #CPageOS,D0 ; a page amount GoDoScroll ,BSR.S ScrollIt DoneGoUp ,MOVEM.L (SP)+,A2-A6/D3-D6 ,MOVE.L (SP)+,A0 ,ADDQ #6,SP ,JMP (A0) ; return to caller ScrollIt MOVE.W 0(A2,D0),D4 ; absolute amount to move ,TST.W D3 ; negate? ,BPL.S @1 ; br if not ,NEG.W D4 @1 BSR.S SetGetCtl ; change control and read it back ,LEA theCtlDta,A0 ; ,MOVE.L (A0),A2 ; get pointer to data structure ,LEA CSProc1OS(A2),A0 ; get during proc ,JSR (A0) ,RTS ; SetGetCtl: A1=control handle, D4=delta in, value out SetGetCtl SUBQ #2,SP ; make room for result ,MOVE.L A1,-(SP) ; push control handle ,MOVE.L A1,-(SP) ; push control handle ,SUBQ #2,SP ; make room for result ,MOVE.L A1,-(SP) ; push control handle ,_GetCtlValue ,ADD.W D4,(SP) ; offset it ,_SetCtlValue ; set the value ,_GetCtlValue ,MOVE.W (SP)+,D4 ; current value ,RTS ;___________________________________________________________________ ; ; DrawBuf draws the current window into the buffer: ; both the during and after proc for the data block scroll bar. ; ; control value is passed in D4, but we figure it out anyways ;___________________________________________________________________ DrawBuf MOVEM.L D3-D6/A2-A4,-(SP) ; save work regs ,LEA myWindow,A1 ,MOVE.L (A1),A1 ; window pointer ,MOVE.W #srcCopy,TxMode(A1) ; need copy mode ,PEA memClip ,_ClipRect ,MOVE.W BufDisp,D0 ,CMP.W #3,D0 ; display only error info? ,LEA AMNoneTotal+TrkCnts,A4 ,MOVEQ #8,D3 ; nine totals . . . ,LEA Err1Note,A6 ; point to first note @1 MOVE.L (A4)+,NoteValOS(A6) ,BSR DrawCpyNote ,ADD #ErrNoteLen,A6 ; next note ,DBRA D3,@1 ,BRA DrawBufXit ; DispTrks MOVEQ #9,D3 ; draw 10 lines ,LEA DBufTxt,A0 ,MOVE.L (A0),D5 ; init textLoc ,LEA CtlDtaScrl,A0 ,SUBQ #2,SP ,MOVE.L (A0),-(SP) ,_GetCtlValue ,MOVE.W (SP)+,D4 ; start track number UMemLoop ,MOVE.L D5,-(SP) ; push the position ,_MoveTo ; move to it ,MOVE.W BufDisp,D0 ,CMP.W #1,D0 ; display all tracks? ,BEQ.S @4 ; then just do it . . . ,CMP.W #2,D0 ; just error tracks? ,BNE.S DrawBufXit ; just exit right now . . . ,MOVE.W D4,D0 ,ADD.W D0,D0 ; double for buffer index ,LEA DCount,A0 ; get number of data mark errors ,TST.W 0(A0,D0) ; data errors? ,BNE.S @4 ; br if so ,LEA AECount,A0 ; get number of address mark errors ,TST.W 0(A0,D0) ; address errors? ,BNE.S @4 ; br if so ,ADDQ.W #1,D4 ,CMP.W #80,D4 ; past the last track? ,BGE.S DrawBufXit ; exit if so ,BRA.S UMemLoop ; loop otherwise @4 BSR.S DrawHexLine ; draw one line ,ADD.L #$000E0000,D5 ; bump textLoc ,ADDQ.W #1,D4 ; and track number ,DBRA D3,UMemLoop ; loop till done DrawBufXit PEA FullClip ,_ClipRect ,LEA bufRect,A0 ,MOVE.L A0,-(SP) ; rectangle pointer ,_FrameRect ; to frame data buffer display ,MOVEM.L (SP)+,D3-D6/A2-A4 ; restore regs ,LEA myWindow,A1 ,MOVE.L (A1),A1 ; window pointer ,MOVE.W #srcOr,TxMode(A1) ; back to default mode ,RTS ; we're done ; DrawHexLine draws a track number and associated error information DrawHexLine ,MOVEM.L D3-D5,-(SP) ,LINK A6,#-80 ; make room for the string ,LEA -80(A6),A3 ; point A3 at the string ,CLR (A3) ; initially it's length 0 ,MOVE.L D4,D0 ; the track number ,BSR AddDecByte ,ADD.W D4,D4 ; multply by 2 to get offset in errbufs ,MOVE.B #$3A,D0 ; get a colon ,BSR AddByte ,MOVE.B #$20,D0 ; get a blank ,BSR AddByte ,MOVE.B #$64,D0 ; 'd' ,BSR AddByte ,MOVE.B #$6D,D0 ; 'm' ,BSR AddByte ,MOVE.B #$3D,D0 ; '=' ,BSR AddByte ,LEA DCount,A0 ; get number of data mark errors ,MOVE.W 0(A0,D4),D0 ,BSR AddDecWord ,MOVE.B #$20,D0 ; get a blank ,BSR AddByte ,MOVE.B #$61,D0 ; 'a' ,BSR AddByte ,MOVE.B #$6D,D0 ; 'm' ,BSR AddByte ,MOVE.B #$3D,D0 ; '=' ,BSR AddByte ,LEA AECount,A0 ; get number of address mark errors ,MOVE.W 0(A0,D4),D0 ,BSR AddDecWord ,MOVE.B #$20,D0 ; get a blank ,BSR AddByte ,MOVE.B #$70,D0 ; 'p' ,BSR AddByte ,MOVE.B #$73,D0 ; 's' ,BSR AddByte ,MOVE.B #$3D,D0 ; '=' ,BSR AddByte ,LEA Pass,A0 ; get number of passes ,MOVE.W 0(A0,D4),D0 ,BSR AddDecWord ,PEA -80(A6) ; push the string pointer ,_DrawString ; draw it ,UNLK A6 ,MOVEM.L (SP)+,D3-D5 ,RTS ; AddDecWord adds 4 decimal characters corresponding to the byte in D0 to ; the string AddDecWord MOVEQ #3,D2 ; convert to decimal ,SWAP D0 @0 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVEQ #0,D0 ,SWAP D1 ,MOVE.W D1,D0 ; decimal ,MOVE.W D0,-(SP) ,ROR.W #8,D0 ,BSR.S AddHexByte ,MOVE.W (SP)+,D0 ,BRA.S AddHexByte ; AddDecByte adds 2 decimal characters corresponding to the byte in D0 to ; the string AddDecByte MOVEQ #1,D2 ; convert to decimal ,SWAP D0 @0 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVEQ #0,D0 ,SWAP D1 ,LSR.W #8,D1 ,MOVE.W D1,D0 ; decimal AddHexByte ,MOVE.W D0,-(SP) ; save a copy of the byte ,LSR #4,D0 ; get the high nybble ,BSR.S MapIt ; output the hex digit ,MOVE.W (SP)+,D0 ; recover low nibble MapIt ,AND.W #$000F,D0 ; use only low 4 bits ,MOVE.B HexTab(D0),D0 ; get the character ; AddByte adds the byte in D0 to the string pointed to by A3 AddByte ,MOVEQ #0,D1 ; clear out high part for index ,MOVE.B (A3),D1 ; get the length ,MOVE.B D0,1(A3,D1) ; move in the new byte ,ADDQ.B #1,(A3) ; bump the length ,RTS HexTab ,.ASCII '0123456789ABCDEF' SetBuf1 MOVEQ #1,D4 ,BRA.S SetBuf SetBuf2 MOVEQ #2,D4 ,BRA.S SetBuf SetBuf3 MOVEQ #3,D4 ,BRA.S SetBuf SetBuf4 MOVEQ #4,D4 SetBuf ,MOVEM.L A3/D3-D4,-(SP) ,LEA Buf1Ctl,A3 ; first seq control ,MOVEQ #1,D3 ; loop counter ,LEA BufDisp,A0 ,MOVE.W D4,(A0) ; save seq type @1 MOVE.L (A3),-(SP) ; track scroll control handle ,CLR.W -(SP) ; set to 0 ,CMP.W D3,D4 ,BNE.S @2 ,ADDQ.W #1,(SP) ; except button being set @2 _SetCtlValue ,ADD #CDtaSize,A3 ,ADDQ.W #1,D3 ,CMP.W #4,D3 ,BLE.S @1 ,PEA memClip ,_EraseRect ,BSR DrawBuf ,MOVEM.L (SP)+,A3/D3-D4 ,RTS ;___________________________________________________________________ ; ; DrDataByte notes the current byte on the screen and puts ; it into theByte. ;___________________________________________________________________ DrDataByte MOVE #1000,D0 ; need some delay ,JSR WakeUp ,LEA theByte,A0 ,MOVE.W D4,(A0) ; update current write nibble UdDataByte LEA theByte,A0 ,MOVE.W (A0),D4 ; update current write nibble ,LEA DtaBytMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrHdSettle notes the current head settle time on the screen and puts ; it into SettleTime. ;___________________________________________________________________ DrHdSettle MOVE #1000,D0 ; need some delay ,JSR WakeUp ,JSR GetDrv1 ,MOVE.W D4,HeadSettle(A1) ; update current head settle time UdHdSettle JSR GetDrv1 ,MOVE.W HeadSettle(A1),D4 ,LEA HdStlMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrPassCnt notes the current sector pass count on the screen and puts ; it into PassCount. ;___________________________________________________________________ DrPassCnt MOVE #1000,D0 ; need some delay ,JSR WakeUp ,LEA PassCount,A0 ,MOVE.W D4,(A0) UdPassCnt LEA PassCount,A0 ,MOVE.W (A0),D4 ,LEA PassMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrSpdChg notes the current speed change time on the screen and puts ; it into spdChgStl. ;___________________________________________________________________ DrSpdChg MOVE #1000,D0 ; need some delay ,JSR WakeUp ,JSR GetDrv1 ,MOVE.W D4,SpdChgtime(A1) UdSpdChg JSR GetDrv1 ,MOVE.W SpdChgtime(A1),D4 ,LEA SpdChgMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrPwrCnt notes the current pass count before power cycle on the screen and puts ; it into PwrCount. ;___________________________________________________________________ DrPwrCnt MOVE #1000,D0 ; need some delay ,JSR WakeUp ,LEA PwrCount,A0 ,MOVE.W D4,(A0) UDPwrCnt LEA PwrCount,A0 ,MOVE.W (A0),D4 ,LEA PwrCntMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrPwrTim notes the current amount of time the drive is powered off ; when cycled, and puts it into PwrTime. ;___________________________________________________________________ DrPwrTim MOVE #1000,D0 ; need some delay ,JSR WakeUp ,LEA PwrTime,A0 ,MOVE.W D4,(A0) UDPwrTim LEA PwrTime,A0 ,MOVE.W (A0),D4 ,LEA PwrTimMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrRecalCnt notes the current pass recal count on the screen and puts ; it into recalCount. ;___________________________________________________________________ DrRecalCnt MOVE #1000,D0 ; need some delay ,JSR WakeUp ,LEA recalCount,A0 ,MOVE.W D4,(A0) ; update current write nibble UDRecalCnt LEA recalCount,A0 ,MOVE.W (A0),D4 ; update current write nibble ,LEA RecalMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrawMsg is a utility routine which clears and outlines the rectangle ; at (A6), draws the text pointed to by 12(A6) at 8(A6), and then appends ; the hex byte in the low-order byte of D4 (two bytes if high-order byte ; is non-zero). ;___________________________________________________________________ DrawMsg MOVE.L A6,-(SP) ; rectangle pointer ,MOVE.L A6,-(SP) ,_EraseRect ; that we wish to erase ,_FrameRect ; and frame ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L A6,-(SP) ,_DrawString DrawHByt MOVE.L A3,-(SP) ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.W D4,D0 ; the nibble ,BPL.S @3 ,MOVE.B #$2D,D0 ,BSR AddByte ; (put a '-' in front) ,MOVE.W D4,D0 ,NEG.W D0 @3 MOVEQ #3,D2 ; convert to decimal ,SWAP D0 @0 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVEQ #0,D0 ,SWAP D1 ,MOVE.W D1,D0 ; decimal ,MOVE.W D0,-(SP) ,ROR.W #8,D0 ; high-order byte zero? ,TST.B D0 ,BEQ.S @1 ,BSR AddHexByte @1 MOVE.W (SP)+,D0 ,BSR AddHexByte ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it @2 MOVE.L (SP)+,A3 ,RTS ;___________________________________________________________________ ; ; DrawTrk notes the current track on the screen. ; DrTrack seeks to the appropriate track and then falls into DrawTrk. ;___________________________________________________________________ DrTrack MOVE #1000,D0 ; need some delay ,JSR WakeUp ,MOVE.W D4,D6 ; track to seek to ,MOVEM.L A0-A6/D1-D7,-(SP) ,JSR Seek ; go to it ,MOVEM.L (SP)+,A0-A6/D1-D7 ,BPL.S UDTrack ; br if valid ,LEA CantStpNote,A6 ; note that we can't step ,BSR DrawNote UDTrack ,JSR GetDrv1 ; current drive variables ,MOVE.W Track(A1,D1),D4 ; ,BCLR #11,D4 ; (for 1-sided disks) ,LEA CtlTrkScrl,A0 ,MOVE.L CRefCOS(A0),-(SP) ; control handle ,MOVE.W D4,-(SP) ,_SetCtlValue ,LEA TrackMsg,A6 ,BSR DrawMsg ,RTS ;___________________________________________________________________ ; ; DrawNote is used to draw a message in the note area and note ; an optional number in decimal after it. A6 should point at the ; message block. ; ; All regs are preserved. ;___________________________________________________________________ DrawCpyNote ,MOVEM.L A0-A2/A6/D0-D4,-(SP) ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L (A6)+,D4 ; save hex for now ,MOVE.L A6,-(SP) ,_DrawString ,BSR DrawHLong ,MOVEM.L (SP)+,A0-A2/A6/D0-D4 ,RTS DrawNote ,MOVEM.L A0-A2/A6/D0-D4,-(SP) ,LEA OnlyNoteVal,A2 ; only change value? ,TST.W (A2) ,BEQ.S @0 ,_HidePen @0 MOVE.L A6,-(SP) ; erase rectangle pointer ,_EraseRect ; that we wish to erase ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L (A6)+,D4 ; save hex for now ,MOVE.L A6,-(SP) ,_DrawString ,TST.W (A2) ,BEQ.S @1 ,_ShowPen ,CLR.W (A2) @1 CMP.L #$FFFFFFFF,D4 ; don't display it if -1 ,BEQ.S @2 ,LEA myWindow,A2 ,MOVE.L (A2),A2 ; window pointer ,MOVE.W #srcCopy,TxMode(A2) ; need copy mode ,BSR DrawHLong ,MOVE.W #srcOr,TxMode(A2) ; back to default mode @2 MOVEM.L (SP)+,A0-A2/A6/D0-D4 ,RTS DrawHLong MOVE.L A3,-(SP) ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.L D4,D0 ,MOVEQ #4,D2 ; convert to decimal @0 DIVU #10,D0 ,SWAP D0 ; get remainder ,MOVE.W D0,D1 ,CLR.W D0 ,SWAP D0 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVE.L D1,D0 ; decimal (5 digits) ,LSR.L #8,D0 ,LSR.L #4,D0 ; shift down into the lower bits ,BSR.S @1 ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it ,MOVE.L (SP)+,A3 ,RTS @1 MOVE.L D0,-(SP) ,SWAP D0 ,TST.W D0 ; high-order non-zero? ,BEQ.S @2 ,BSR MapIt @2 MOVE.L (SP),D0 ,ROR.W #8,D0 ; high-order byte ,BSR AddHexByte ,MOVE.L (SP)+,D0 ,BSR AddHexByte ,RTS 3. "6F^5D!$ǐ^  % aSonyUtil  lAE// E08/Bgc$SDnL|NuH>AfN$aA 0fJj`Jka2L|NuF#AJ((J(F NuH>/ iaL|Nu/aAmp0Jjp1M/PN/Av PfrgS`/Hz.,_Nu/`H>IH( / qUO// M2/l0gv @ g @ g`hUOM//BSh0gTUO/`6C/?c,E8g $SDn`,A P0*MJCgMACNaL|NuUO/ / UO/ `Wc`8NuH>G&B/HzHz?<Bg/ ?</<&_C'IC'IC`'IC&'IEh8va$RCSDnL|NuYO/ HjHj ?<B?< j"fBW?*"/T$NuZd|Interface Test  <ca2J(NuJ( Nu Fxca1J(NuJ(Nu ca0JNuJ(Nu selNuNu( <<strJ( NuJ(Nu(F<xstr`4`,F Z</enJ(NuJ(Nu@F#J(J( Ns&<8 /Dirtn = /DiskInPl = /Step = /Wr Prot = /Mtr On = /Tk 0 = Eject = Tach = Rd Data = Rd Data = ?? = ?? = Sides = Sides = /Exists = /Exists = 0F< 0<N1Nu/PN/// GBS0 @g4tH@B@H@ H@2QpHA0?XJga0a Hz&_Nu?Ha0@;rRNu0123456789ABCDEFH>M&*ga8 <@g,`a* VE// NpN/Hk(L|Nuz`zE68/JEfW`XSDnNuH>M<I8YO$fz DfD`0:gJDkaF`"0. N/ j gJEjaB` fJEja,SFn8jpg N/(3L|NuA `A 0`A1///PN/TN/Hz਄,_NuH>/ iMPa0M$aDM8aIz( / qUO// Md/l0gf @ g @ ga`T,E8g $SDn`>UO///8 h0g.UO/`6C/?cMa MJCACNL|NuH>G&B/HzHz?<Bg/ ?</<&_C"7|D7| J7|HC'IC$'IC'ICv'IE8va"$RCSDnE8aBRCSDnL|NuYO/ HjHj?<?* ?*?* j"fBW?*"/T$NuYO/ HjHz?<?* ?*?*?</T$NuF DTrack-Level Test PP^U_dFi nOptionsF 6 NotesQ Pddeject `nid}recal `Xdon ` P dZ read loop ` li }Z write loop ` Z not used ` ~7 KZ write trk ` R 2Zread trk ` 6 Z track test `x( write/read ` (x7 stop on err` l7xF read w/fmt ` P x Side 1 sel ` 4on offP``P```xO`d``_to Data = Track =  P /Exist = P Dirtn = P  /DskIn = P  /Step = OR Sides = OR /W Prt = OR /MtrOn = OR /Trk 0 = 0Z A- A-No Header Found . . .A-Diskette is Write-Protected? A-Not Ready: Disk Inserted?A-Press Mouse Button To Exit LoopA-Write-Underrun Occurred! #Track Pass Count : #2-Bad Nibble Count : 2A<No Hdr Fnd Count : A-Unable To Step (Step = 0)E8"g SDnNuA UO//BJk@ @n @A.h0UO/`8ANNu 8P0/"oH> @fNvp`F0/"oH> @f6vp`.0/"oH> @fvp`0/"oH> @fvpa L|x _\ON82JCjDDaA$PANNuUO/ / UO/ `Wc`8NuH8C"QBiHHz{vA*AUO/`8I(TI@/a*QHz{A/LxCJ"Q3|HNuNVGBS A:/Ha> a8<:a@< a8< a0|a< a QHnN^Nu?Ha0@;rRNu0123456789ABCDEF0<N&~`~4N&Nu0<N&A0AD0ABMFaaNu//PN/// GPBS0 @g?XJgad0a^Hz0&_Nu//PN/// GBS0 @g4tH@B@H@ H@2QpHA0?XJga 0aHz֨&_Nu<HN$LjMaN$81kMa~NuM*//H6<8<E*Eg$a(6<8<E*gaHzHzL8NuH??|~HG><d2JFf |Bg?<` |Bg?<?<BgQHGQLNuBg?MF#AR pA2 AgpNaf"V4<A6 fRSBn<ްfD<f:AZ ( fa9faaF L|AaaNuADR ATJPg Bnf<` r f<E4$)))G& S?A\/?c0@@@A1@P@P@1@aa*F L|AdaVaHz訤NuAR `/MlaMaMa,_Nuanf^AjaMalF!pAt2 AgpNX9fA6aaMa4F NuafH>F#pA*2 AgpNAaMraC2p$|&|(|JJjfJ9EEBaAaBaFMaF L|NuA0NuA0NuA0NuA0Nu/?< ]Nu/Bg]Nu9g0<XN!9gNu?ժުaf pNk MpA2 AgpNA6A P0<@S@nAABaF#2<E4<CK&|(|J Jp.Jk@p JJjQQpJjQJjQpJjQfJ9F L|MaDpNuJ9F L|apNuafH>pA*2 AgpNAJPgaBg(Ma`M"V2<@IF#jSAnF L|a NupLNuF#HpM"V"ժI4<= 2<jSBk fjSBk fjSBk fjQpBQpLNuAV0pNkp r`prE/AJAfA/N_NuMhapNupNjpNupNkpNuH`NlLNuHNLNuHN2Lg M a` Cd/BgcaNuH>*g8a:E// N0Hk(M za0ajfMja"atL|Nua`z`zEP8/JEfW`XSDnNuNuH>/ iMPMTaXMhaPM&aHaHza4aPalaaaajNA>/?1caMBVL|Nu/P/P//NuH>Iz( / qUO// Md/l0gf @ g @ ga`T,E8g $SDn`>UO///8 h0g.UO/`6C/?cMBaMJCACNL|NuH>G&B/HzHz?<Bg/ ?</<&_C"7|D7| J7|HC'IC$'IC'IC&'IE,8va"$RCSDnE8aBRCSDnL|NuYO/ HjHj?<?* ?*?* j"fBW?*"/T$NuYO/ HjHzR?<?* ?*?*?</T$Nu&RError Rate TestP<,,$P,^@sF"x }Test Seq Ps"OxQU}Options,F1U 6Notes,,n 5eject `r 5recal `\9dM on `n9dclear `$P dd format trk `J7 Kd format disk`\ d start test `_n write/read `n}  wt rndm dta`} stop on err` Side 1 Sel `n#random `$#2static `#seq + `#2seq - `;tk0-79 `2;err tks `errors `offon P,<F` ` d,'` ` d'``  dO``i'``iP'``i'``"'``"`` d Hd Set: d Sec/Ps:  $d CurTrk: ii SpdChg: ii Pwr Ct: i$i Rcl Ct: " PwrTim: " WrData: P0Z 6A-6 6A-6No Header Found . . .6A-6Diskette is Write-Protected? 6A-6Not Ready: Disk In & Powered?6A-6Press Mouse Button To Exit Loop6A-6Write-Underrun Occurred! 6#6Pass Count : #62-6Adr Mark Errs : 26A<6Data Mark Errs : #62-6New RPM Value : 6#6Hi RPM Value : 26A<6Low RPM Value : 6A-6Unable To Step (Step = 0)6A-6 Seek Error : 6A-6Please Insert A Diskette!6A-6Disk Format In Progress6A-6Now Verifying Diskette 6A-6Disk Successfully Formatted! 6A-6Track Successfully Formatted!6A-6Disk Format Failure: U6d_@ AM-none : d6sn@ AM-ck sum : s6}@ AM-bitslp : 6@ AM-trknum : 6@ DM-none : 6@ DM-ck sum : 6@ DM-bitslp : 6@ Rd ver err: 6@ Sect miss : E8"g SDnNuA UO//BJk@ @n @A.h0UO/`8ANNu 8P0/"oH> @fNvp`F0/"oH> @f6vp`.0/"oH> @fvp`0/"oH> @fvpa L|x _\ON82JCjDDaA$PANNuUO/ / UO/ `Wc`8NuH8C"QBiHHzҨ{0: @IvM-\ ahQ`Zv A*AUO/`8/0: @g( @f00@AdJpfAJpf RD DPl`a,RDQHzV{A`/LxC "Q3|HNuHNVGBS aD<:a< a<da<ma<=aA00@ah< a<aa<ma<=aAn00@a<< a<pa<sax<=apA00@aHnN^L8NutH@B@H@ H@2QpHA0?Xa"0`tH@B@H@ H@2QpHAI0?Ha0@;rRNu0123456789ABCDEFx` x`x`xHGvA0/BgCfRWc$RC CoHzبaLNu0<N *A0A8MpaNu0<N N3D4N8)4MaNu0<N Ad0A^8MaNu0<N Nn3D6Nf8)6Ma^Nu0<N A(0A"8Ma@Nu0<N A0A8Ma"Nu0<N nA0A8MaNu//PN/// GBS0j <-a0D@tH@B@H@ H@2QpHA0?XJgad0a^Hzh&_Nu0<N<HNLjM>aA00A"0N@<1F0:*S@fa<`S@gS@f RF FPm |`SFj<<ONL|jM-@ a`natNi01N<1aMBJBFBVBnA0ABBBBP<:gN`N.x:1Bk1B0N@qfB8,0:hg8P,A~((Ff(!DF1AN.x:M^J@g0pN`,1BANr.x:48B1BfM.(.J-DJ9gASPf@N21IA0;M".JAgRBRn` L|a aAJXg,SPn(a^4:g0<N9gSBnaF`F`Ha |L|AaaaNuMxRV @fR2`" @fR6` @fR:` @fR>0:"fAJXg&SPn"L|N<1a,NN$L|A0`M Rn08B @g @fR"`" @fR&` @fR*` @fR.`MN<1BxFCRq`R@A!v@ Cn2Hq`Ӷ@ A!v@ C2.Hq`Ӷ@At!v@ A:RERPM1jaP>fHFgBpr4Fg&kprAa3AR4paBavk`a`a3p a*a^k0N*_a|rJ((J(g4tHBpSktJ(J((fg AJ(`J(a~Pp aj2paA4paak`ap aakpSGg`p aakp3Na0< AJg0<J0J(Nu(_p a^J(0<LaJ( 0<La B1N`H@ $x4jnBjE| N2H@AYA*gj|S@jLNu5(_B@J@N(_Hz/8>g"x4H Nua"L N.x:aNժުժު?ժMK!:Ѹ:|Nupapal` papa`E/8*NuC/8.NuE/82Nu0)84aBiapa`j av0fNu    HA0BBaP<1I<:4JJ8; aPfp a6; K8; adLNu    Hp aTI:|OGxv8#6#fLNuH?aLkafSFSf`H|A0K0A0gN`NjaZ`21BA0B8,a.x:J@fA048B0gSPfp`p|LJ@Nu    HA0BBafBFGxfLHNuH?a3F<)ak`L`La fRFSf`HA:AMR,0 @F?F =D=|"|A*afnA0gN`NaX1Bk|1BJfr"<@M1Bn k8Hg AgRn J`faJJ1jR``p|LJ@NuMSn n l08B`RAg`\MSn n lJ08B`?ުH,H V0.2.4.a2. UAC$I6<&|(|J..Jk@t`$ItJjQQ6$ItJjQQtJjQ4<JjQtJjQS@ntfp`pJ9LNu?ժު?ժHx6SCKRC:aRDS@g :a RCS@fLNuC|``QC@q ~qP qP<Nq` <Fq` qp NuNNUN N NN]NNuBNu _NUN _N]NЁDgBR gE$RBjHa5|HLGNu/ GBS t H@2B@H@Q a Hz𖨄&_Nu/H@J@ga~ Xan ahNuA0NuA0NuA0NuA0Nu/?< ]Nu/Bg]Nu9g0<XN9gNupN"kp rx`pr8<E/A:JAfA6/N_0NNuMA JPg pNkMHapNupNjpNupNkAJPgpNjpNu3. "6F^5D!$ǐ^[  ; File: SonyLow.Text ;_______________________________________________________________________ ; ; Sony 3-1/2 Inch Drive Test Program: Lowest Control Window ; ; written by Larry Kenyon, beginning 1-March-83 ; ; This is a low-level test program for use by hardware jocks to debug, ; explore, and evaluate the Sony-type 3-1/2 disk drive. ; ; Modification History: ; 03 Mar 83 LAK New today. Completed coding on lowest-level interface ; (CA1, CA2, CA3, etc. button window). ; 06 Mar 83 LAK Broke out from main program. ; 13 May 83 LAK Added disk-exist sense caption, PWM output control. ; ;_______________________________________________________________________ ,.NOLIST ,.INCLUDE tlasm:SYSEQU.TEXT ; general system equates ,.INCLUDE tlasm:SYSERR.TEXT ; error equates ,.INCLUDE tlasm:GRAFEQU.TEXT ; graphics-related equates ,.INCLUDE tlasm:GRAFTYPES.TEXT ,.INCLUDE tlasm:TOOLEQU.TEXT ,.INCLUDE tlasm:RESEQU.TEXT ,.INCLUDE tlasm:SonyEqu.Text ,.INCLUDE tlasm:SYSMACS.TEXT ; system macros ,.INCLUDE tlasm:TOOLMACS.TEXT ,.INCLUDE tlasm:QUICKMACS.TEXT ,.LIST DrawOffset .EQU WindowSize ; offset in window data to draw proc MDOffset .EQU DrawOffset+4 ; offset to mouse down in content proc TaskOffset .EQU MDOffset+4 ; offset to task this guy does when on top ActivOffset .EQU TaskOffset+4 ; offset to activate event proc WndDtaSize .EQU ActivOffset+4 CRefCOS .EQU 0 ; ctl handle offset within data structure CRectOS .EQU CRefCOS+4 ; control rectangle offset CNameOS .EQU CRectOS+8 ; control name offset CGlobitOS .EQU CNameOS+4 ; global bit C0ProcOS .EQU CGlobitOS+2 ; control proc to set to state 0 C1ProcOS .EQU C0ProcOS+8 ; control proc to set to state 1 CDefPrOS .EQU C1ProcOS+8 ; type of control CDtaSize .EQU CDefPrOS+2 ; scroll controls only . . . CInitOS .EQU CRectOS+8 ; initial value CMinOS .EQU CInitOS+2 ; min control value CMaxOS .EQU CMinOS+2 ; max control value CSmallOS .EQU CMaxOS+2 ; small increment/decrement CPageOS .EQU CSmallOS+2 ; page increment/decrement CSProc1OS .EQU CPageOS+2 ; proc called during buttons after ctl chg CSProc2OS .EQU CSProc1OS+4 ; proc called on exit CSDtaSize .EQU CSProc2OS+4 selBit .EQU 0 ca0Bit .EQU 1 ca1Bit .EQU 2 ca2Bit .EQU 3 strBit .EQU 4 enbBit .EQU 5 ,.PROC LowTest,0 ,.ORG 0 ,.DEF MakeLowWindow ; only entry needed ,.REF DiskSync ,.REF SetASpeed,WakeUp ;___________________________________________________________________ ; ; Routine: LowCtlActivate ; Arguments: ; Function: This routine handles the activation/deactivation of ; the low-control window by calling the DiskSync routine, ; and then setting all control values to 0. ;___________________________________________________________________ LowCtlActivate ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA syncTime,A0 ,BCLR #0,(A0) ; tell task to sync with disk @3 LEA FontForce,A2 ,MOVE.L (A2)+,-(SP) ; draw a blank to force font in ,_MoveTo ; prepare to draw text ,MOVE.L A2,-(SP) ,_DrawString ,LEA LowCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls @1 MOVE.L CRefCOS(A2),-(SP) ; control handle ,CLR.W -(SP) ; set all controls to 0 ,_SetCtlValue ,ADD #CDtaSize,A2 ; point to next control ,SUBQ.W #1,D4 ,BGT.S @1 ; do all controls ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ;___________________________________________________________________ ; ; Routine: LowCtlTask ; Arguments: ; Function: This routine checks to see if any sense lines have changed. ; ;___________________________________________________________________ LowCtlTask MOVEM.L D3-D7/A2-A6,-(SP) ,LEA syncTime,A0 ,BSET #0,(A0) ; sync with disk? ,BNE.S @0 ,JSR DiskSync @0 BSR.S Sense ; get latest sense data ,LEA LowTxt+1,A0 ; check against the current sense ,CMP.B #$30,(A0) ; currently zero? ,BNE.S @1 ; br if not ,TST.B D1 ; is it still low? ,BPL.S @3 ; exit if so ,BRA.S @2 ; otherwise, update it @1 TST.B D1 ; sense data is bit 7 ,BMI.S @3 ; br if still high @2 BSR.S LowSense ; and sense initial state @3 MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS Sense MOVE #$2300,SR ,LEA DBase,A0 ,TST.B Q6H(A0) ; get into sense mode ,MOVE.B Q7L(A0),D1 ; sense it ,TST.B Q6L(A0) ; back to read mode ,MOVE #$2000,SR ,RTS ;___________________________________________________________________ ; ; Routine: DrawLowCtl ; Arguments: ; Function: This routine handles update events in the low-control ; window. ; ;___________________________________________________________________ DrawLowCtl MOVEM.L D3-D7/A2-A6,-(SP) ,MOVE.L A3,-(SP) ; window ptr ,_DrawControls ; draw the controls ,BSR.S LowSense ; and sense initial state ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS LowSense MOVE.L A6,-(SP) ,BSR.S Sense ; get sense data in D1 ,LEA LowTxt+1,A0 ; fill in the current sense ,MOVEQ #$30,D0 ; assume it is low ,TST.B D1 ; sense data is bit 7 ,BPL.S @1 ; br if we were right ,MOVEQ #$31,D0 @1 MOVE.B D0,(A0) ,LEA LowMsg,A6 ; string to print ,MOVE.L A6,-(SP) ; rectangle pointer ,_EraseRect ; that we wish to erase ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,LEA LineStPtr,A0 ,MOVE.L (A0),A0 ; get current line state ,MOVE.B (A0),D0 ; low bits are [ ca2 ca1 ca0 sel ] ,BTST #enbBit,D0 ; is interface enabled? ,BNE.S @4 ; leave blank if not ,MOVEQ #0,D1 ; used to bump pointer ,AND.B #$000F,D0 @2 BEQ.S @3 ,MOVE.B (A6)+,D1 ; next phrase byte count ,ADD D1,A6 ,SUBQ.B #1,D0 ; check next phrase ,BRA.S @2 @3 MOVE.L A6,-(SP) ,_DrawString ,PEA LowTxt ,_DrawString @4 MOVE.L (SP)+,A6 ,RTS @5 MOVE.L A6,-(SP) ,_DrawString ,BRA.S @4 ;___________________________________________________________________ ; ; Routine: DoLowCtl ; Arguments: TheEvent ; Function: This routine handles mouse down events which occur in the ; menu bar. ; ;___________________________________________________________________ DoLowCtl MOVEM.L D3-D7/A2-A6,-(SP) ,LEA MyPt,A4 ,MOVE.L EvtMouse(A2),(A4) ,MOVE.L A4,-(SP) ,_GlobalToLocal ,SUBQ #2,SP ,MOVE.L (A4),-(SP) ; local mouse down point ,MOVE.L A3,-(SP) ; theWindow ,LEA theControl,A6 ,MOVE.L A6,-(SP) ; var: control handle ,_FindControl ; figure out which control ,MOVE.W (SP)+,D0 ,BEQ.S DoLCExit ,CMP.W #InCheckBox,D0 ,BEQ.S @2 ,CMP.W #InButton,D0 ,BEQ.S @2 ,BRA.S DoLCExit @2 SUBQ #2,SP ,LEA theControl,A6 ,MOVE.L (A6),-(SP) ; theControl handle ,MOVE.L (A4),-(SP) ; local mouse down point ,CLR.L -(SP) ; use default proc ,SUBQ.L #1,(SP) ,_TrackControl ,MOVE.W (SP)+,D0 ,BEQ.S DoLCExit ,SUBQ #2,SP ,MOVE.L (A6),-(SP) ; theControl handle ,_GetCtlValue ,MOVE.W (SP)+,D3 ; current value ,BCHG #0,D3 ,MOVE.L (A6),-(SP) ; theControl handle ,MOVE.W D3,-(SP) ; set new value ,_SetCtlValue ; now map the control onto one of my data structures, and do the proc ,MOVE.L (A6),D6 ; control handle ,LEA LowCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls SrchLCtl CMP.L CRefCOS(A2),D6 ; this one? ,BEQ.S @1 ; br if so ,ADD #CDtaSize,A2 ; point to next control ,SUBQ.W #1,D4 ,BGT.S SrchLCtl ,BRA.S DoLCExit ; br if not in the structure @1 LEA LineStPtr,A0 ,MOVE.L (A0),A0 ; get pointer to line state ,MOVE.W CGlobitOS(A2),D0 ; get global bit ,LEA C0ProcOS(A2),A6 ; assume 0 proc ,BCLR D0,(A0) ,TST.W D3 ; control value ,BEQ.S @2 ,LEA C1ProcOS(A2),A6 ; it's 1 proc ,BSET D0,(A0) @2 LEA DBase,A0 ; need to set up A0, A1 ,LEA VBase,A1 ,JSR (A6) ; do it ,BSR LowSense ; note the sense of it, too DoLCExit MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ; SetGetCtl: A1=control handle, D4=delta in, value out SetGetCtl SUBQ #2,SP ; make room for result ,MOVE.L A1,-(SP) ; push control handle ,MOVE.L A1,-(SP) ; push control handle ,SUBQ #2,SP ; make room for result ,MOVE.L A1,-(SP) ; push control handle ,_GetCtlValue ,ADD.W D4,(SP) ; offset it ,_SetCtlValue ; set the value ,_GetCtlValue ,MOVE.W (SP)+,D4 ; current value ,RTS ;___________________________________________________________________ ; ; Routine: MakeLowWindow ; Arguments: A0.L (input) -- pointer to window record storage ; Function: This routine creates the Low-Control window and initializes ; the window data structure. ; ;___________________________________________________________________ MakeLowWindow ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA LineStPtr,A3 ,MOVE.L A1,(A3) ; save pointer to line state ,CLR.L -(SP) ; make room for function result ,MOVE.L A0,-(SP) ; low-control window record ,PEA LowWRect ; global start location ,PEA LowWndNam ; window name = 'Low Control' ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W #DocumentProc,-(SP) ; regular window ,MOVE.L A2,-(SP) ; behind this window ,MOVE.W #$0100,-(SP) ; it has a go-away region ,MOVE.L #$10100001,-(SP) ; refCon ,_NewWindow ,MOVE.L (SP)+,A3 ; our window pointer bounces back to us ,LEA DrawLowCtl,A1 ; fill in our proc pointers ,MOVE.L A1,DrawOffset(A3) ; the draw proc ,LEA DoLowCtl,A1 ; handles mouse down in content region ,MOVE.L A1,MDOffset(A3) ,LEA LowCtlTask,A1 ; does any sense updates ,MOVE.L A1,TaskOffset(A3) ,LEA LowCtlActivate,A1 ; does activate stuff ,MOVE.L A1,ActivOffset(A3) ,LEA LowCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls ,MOVEQ #0,D3 ; first refcon is 0 ICtlLoop BSR.S InitCtl ,ADD #CDtaSize,A2 ; point to next control ,ADDQ #1,D3 ; incr refNum ,SUBQ.W #1,D4 ; do them all ,BGT.S ICtlLoop ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS InitCtl SUBQ #4,SP ,MOVE.L A3,-(SP) ; windowPtr ,PEA CRectOS(A2) ; boundsRect ,PEA CNameOS(A2) ; control name ptr ,MOVE.W #$0100,-(SP) ; visible ,CLR.L -(SP) ; initial value 0, minimum 0 ,MOVE.W #1,-(SP) ; max is 1 ,CMP.W #PushButProc,CDefPrOS(A2) ,BNE.S @1 ; except for push button procs ,CLR.W (SP) ; max is 0 @1 MOVE.W CDefPrOS(A2),-(SP) ; type of control ,MOVE.L D3,-(SP) ; refcon ,_NewControl ,MOVE.L (SP)+,CRefCOS(A2) ; store handle ,RTS ;_______________________________________________________________________ ; ; Low Control Window Data Space ;_______________________________________________________________________ LineStPtr .LONG 0 ; ptr to main pgm global line state theControl .LONG 0 ; scratch control pointer MyPt .WORD 0,0 ; scratch point LowWRect .WORD 90,100,190,380 ; start global rectangle for Low-Control LowWndNam .BYTE 14 ,.ASCII 'Interface Test ' ; all windows share fixed-length records in the following data structure LowCtlDta .WORD 7 ; 7 controls ,.LONG 0 ; control handle ,.WORD 10,10,30,60 ; bounds rect ,.BYTE 3 ,.ASCII 'ca2' ,.WORD 3 ; global bit ,TST.B Ph2L(A0) ; A0 must point to disk base address ,RTS ; 8 bytes total ,.WORD $FFFF ,TST.B Ph2H(A0) ; state 1 is phase high ,RTS ; 8 bytes total ,.WORD $FFFF ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 10,70,30,120 ; bounds rect ,.BYTE 3 ,.ASCII 'ca1' ,.WORD 2 ; global bit ,TST.B Ph1L(A0) ; A0 must point to disk base address ,RTS ; 8 bytes total ,.WORD $FFFF ,TST.B Ph1H(A0) ; state 1 is phase high ,RTS ; 8 bytes total ,.WORD $FFFF ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 10,130,30,180 ; bounds rect ,.BYTE 3 ,.ASCII 'ca0' ,.WORD 1 ; global bit ,TST.B Ph0L(A0) ; A0 must point to disk base address ,RTS ; 8 bytes total ,.WORD $FFFF,$FFFF ; Ph0L is 0 ,TST.B Ph0H(A0) ; state 1 is phase high ,RTS ; 8 bytes total ,.WORD $FFFF ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 10,190,30,240 ; bounds rect ,.BYTE 3 ,.ASCII 'sel' ,.WORD 0 ; global bit ,BCLR #VHeadSel,VBufD(A1) ; A0 must point to VIA base address ,RTS ; 8 bytes total ,BSET #VHeadSel,VBufD(A1) ; A0 must point to VIA base address ,RTS ; 8 bytes total ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 40,10,60,60 ; bounds rect ,.BYTE 3 ,.ASCII 'str' ,.WORD 4 ; global bit ,TST.B Ph3L(A0) ; A0 must point to disk base address ,RTS ; 8 bytes total ,.WORD $FFFF ,TST.B Ph3H(A0) ; state 1 is phase high ,RTS ; 8 bytes total ,.WORD $FFFF ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD 40,70,60,120 ; bounds rect ,.BYTE 3 ,.ASCII 'str' ,.WORD 7 ; global bit (not used?) - should clear ,BRA Pulse ; both procs the same (kludge) ,.WORD $FFFF ,.WORD $FFFF ,BRA Pulse ; both procs the same (kludge) ,.WORD $FFFF ,.WORD $FFFF ,.WORD PushButProc ; last one is a pushbutton ,.LONG 0 ; control handle ,.WORD 70,10,90,60 ; bounds rect ,.BYTE 3 ,.ASCII '/en' ,.WORD 5 ; global bit ,TST.B MtrOn(A0) ; A0 must point to disk base address ,RTS ; 8 bytes total ,.WORD $FFFF ,TST.B MtrOff(A0) ; A0 must point to disk base address ,RTS ; 8 bytes total ,.WORD $FFFF ,.WORD CheckBoxProc Pulse MOVE SR,-(SP) ; A0 must point to disk base address ,MOVE.W #$2300,SR ; 16 bytes total ,TST.B Ph3H(A0) ; pulse it high, then low ,TST.B Ph3L(A0) ,RTE ; 16 bytes total LowMsg .WORD 38,140,60,280 ; erase rect ,.WORD 56,140 ; V,H local point ,.BYTE 9 ,.ASCII '/Dirtn = ' ,.BYTE 12 ,.ASCII '/DiskInPl = ' ,.BYTE 8 ,.ASCII '/Step = ' ,.BYTE 11 ,.ASCII '/Wr Prot = ' ,.BYTE 10 ,.ASCII '/Mtr On = ' ,.BYTE 8 ,.ASCII '/Tk 0 = ' ,.BYTE 8 ,.ASCII 'Eject = ' ,.BYTE 7 ,.ASCII 'Tach = ' ,.BYTE 10 ,.ASCII 'Rd Data = ' ,.BYTE 10 ,.ASCII 'Rd Data = ' ,.BYTE 5 ,.ASCII '?? = ' ,.BYTE 5 ,.ASCII '?? = ' ,.BYTE 8 ,.ASCII 'Sides = ' ,.BYTE 8 ,.ASCII 'Sides = ' ,.BYTE 10 ,.ASCII '/Exists = ' ,.BYTE 10 ,.ASCII '/Exists = ' LowTxt .BYTE 1 ,.BYTE $30 ; starts as Ascii 0 FontForce .WORD 70,60 ; V,H local point SCtlName .BYTE 1 ; also scroll control name ,.ASCII ' ' HexBuf .LONG 0,0,0,0 theCtlDta .LONG 0 ; pointer to current control data syncTime .WORD 0 ; 0 when time for task to sync ;___________________________________________________________________ ; ; DrawSpd notes the current speed on the screen. D4 is current speed. ; The PWM buffer is set to this speed. ;___________________________________________________________________ SetSpd MOVE #1000,D0 ; need some delay ,JSR WakeUp ,RTS ;___________________________________________________________________ ; ; DrawMsg is a utility routine which clears and outlines the rectangle ; at (A6), draws the text pointed to by 12(A6) at 8(A6), and then appends ; the decimal byte in the low-order byte of D4 (two bytes if high-order byte ; is non-zero). ;___________________________________________________________________ DrawMsg MOVE.L A6,-(SP) ,_EraseRect ; that we wish to erase ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L A6,-(SP) ,_DrawString DrawHByt MOVE.L A3,-(SP) ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.W D4,D0 ; the nibble ,CMP.W #$FFFF,D0 ; if it's unknown, print nothing ,BEQ.S @2 ,MOVEQ #3,D2 ; convert to decimal ,SWAP D0 @0 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVEQ #0,D0 ,SWAP D1 ,MOVE.W D1,D0 ; decimal ,MOVE.W D0,-(SP) ,ROR.W #8,D0 ; high-order byte zero? ,TST.B D0 ,BEQ.S @1 ,BSR AddHexByte @1 MOVE.W (SP)+,D0 ,BSR AddHexByte ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it @2 MOVE.L (SP)+,A3 ,RTS ; AddHexByte adds 2 hex characters corresponding to the byte in D0 to ; the string AddHexByte ,MOVE.W D0,-(SP) ; save a copy of the byte ,LSR #4,D0 ; get the high nybble ,BSR.S MapIt ; output the hex digit ,MOVE.W (SP)+,D0 ; recover low nibble MapIt ,AND.W #$000F,D0 ; use only low 4 bits ,MOVE.B HexTab(D0),D0 ; get the character ; AddByte adds the byte in D0 to the string pointed to by A3 AddByte ,MOVEQ #0,D1 ; clear out high part for index ,MOVE.B (A3),D1 ; get the length ,MOVE.B D0,1(A3,D1) ; move in the new byte ,ADDQ.B #1,(A3) ; bump the length ,RTS HexTab ,.ASCII '0123456789ABCDEF' ,.END W^5P-H r H r^### ; File: SonyMid1.Text ;_______________________________________________________________ ; ; Routines for displaying data buffer within the mid-control ; window. ; ; Modification History: ; ;_______________________________________________________________ ; handle the mouseDown by calling FindControl and tracking the control ; if its in one ScrollTrack ,LEA CtlScroll,A2 ; scroll control data structures ,MOVE.W (A2)+,D4 ; number of scroll controls ,MOVE.L (A6),D1 ; theControl handle @1 CMP.L (A2),D1 ; this control? ,BEQ.S ScrlTrk1 ,ADD #CSDtaSize,A2 ; point to next scroll control ,SUBQ.W #1,D4 ; check them all ,BGT.S @1 ,RTS ScrlTrk1 LEA theCtlDta,A0 ; fill in the data pointer for later ,MOVE.L A2,(A0) ,SUBQ #2,SP ,MOVE.L D1,-(SP) ; theControl handle ,MOVE.L (A4),-(SP) ; local mouse down point ,CLR.L -(SP) ; nil action proc ,TST.B D0 ; examine part code - if not an ,BMI.S @1 ; indicator, it needs an action proc ,SUB.W #20,D0 ; normalize part index ,CMP.W #3,D0 ; should be 0-3 ,BGT.S @1 ; br if not ,ADD.W D0,D0 ; double it ,LEA ActionOffset,A0 ; get offset to actionProc ,ADD.W 0(A0,D0),A0 ; compute actionProc address ,MOVE.L A0,(SP) ; the actionProc @1 _TrackControl ,MOVE.W (SP)+,D0 ; ignore result ,SUBQ #2,SP ,MOVE.L (A2),-(SP) ; now call the end proc ,_GetCtlValue ,MOVE.W (SP)+,D4 ; pass it in D4 ,LEA CSProc2OS(A2),A0 ; get proc pointer ,JSR (A0) ,RTS ActionOffset ,.WORD GoUp-ActionOffset ,.WORD GoDown-ActionOffset ,.WORD PageUp-ActionOffset ,.WORD PageDown-ActionOffset GoUp MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inUpButton,D0 ; in the up button ,BNE.S DoneGoUp ; if not, don't do anything ,MOVEQ #-1,D3 ; move up ,MOVEQ #CSmallOS,D0 ; a small amount ,BRA.S GoDoScroll GoDown MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inDownButton,D0 ,BNE.S DoneGoUp ,MOVEQ #1,D3 ; move down ,MOVEQ #CSmallOS,D0 ; a small amount ,BRA.S GoDoScroll PageUp MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inPageUp,D0 ,BNE.S DoneGoUp ,MOVEQ #-1,D3 ; go up ,MOVEQ #CPageOS,D0 ; a page amount ,BRA.S GoDoScroll PageDown MOVE.W 4(SP),D0 ; part code ,MOVE.L 6(SP),A1 ; control handle ,MOVEM.L A2-A6/D3-D6,-(SP) ,CMP #inPageDown,D0 ,BNE.S DoneGoUp ,MOVEQ #1,D3 ; go down ,MOVEQ #CPageOS,D0 ; a page amount GoDoScroll ,BSR.S ScrollIt DoneGoUp ,MOVEM.L (SP)+,A2-A6/D3-D6 ,MOVE.L (SP)+,A0 ,ADDQ #6,SP ,JMP (A0) ; return to caller ScrollIt MOVE.W 0(A2,D0),D4 ; absolute amount to move ,TST.W D3 ; negate? ,BPL.S @1 ; br if not ,NEG.W D4 @1 BSR.S SetGetCtl ; change control and read it back ,LEA theCtlDta,A0 ; ,MOVE.L (A0),A2 ; get pointer to data structure ,LEA CSProc1OS(A2),A0 ; get during proc ,JSR (A0) ,RTS ; SetGetCtl: A1=control handle, D4=delta in, value out SetGetCtl SUBQ #2,SP ; make room for result ,MOVE.L A1,-(SP) ; push control handle ,MOVE.L A1,-(SP) ; push control handle ,SUBQ #2,SP ; make room for result ,MOVE.L A1,-(SP) ; push control handle ,_GetCtlValue ,ADD.W D4,(SP) ; offset it ,_SetCtlValue ; set the value ,_GetCtlValue ,MOVE.W (SP)+,D4 ; current value ,RTS ;___________________________________________________________________ ; ; DrawBuf draws the current window into the buffer: ; both the during and after proc for the data block scroll bar. ; ; control value is passed in D4, but we figure it out anyways ;___________________________________________________________________ DrawBuf MOVEM.L D3-D6/A2-A4,-(SP) ; save work regs ,LEA myWindow,A1 ,MOVE.L (A1),A1 ; window pointer ,MOVE.W #srcCopy,TxMode(A1) ; need copy mode ,PEA memClip ,_ClipRect ,MOVEQ #7,D3 ; draw 8 lines ,LEA DBufTxt,A0 ,MOVE.L (A0),D5 ; init textLoc ,LEA CtlDtaScrl,A0 ,SUBQ #2,SP ,MOVE.L (A0),-(SP) ,_GetCtlValue ,MOVE.W (SP)+,D4 ,ASL.L #3,D4 ; multiply by 8 to get address ,LEA DataBufPtr,A4 ,MOVE.L (A4),A4 ; buffer pointer ,LEA 0(A4,D4),A4 ; initialize start address UMemLoop ,MOVE.L D5,-(SP) ; push the position ,_MoveTo ; move to it ,BSR.S DrawHexLine ; draw one line ,ADD.L #$000E0000,D5 ; bump textLoc ,DBRA D3,UMemLoop ; loop till done ,PEA FullClip ,_ClipRect ,LEA bufRect,A0 ,MOVE.L A0,-(SP) ; rectangle pointer ,_FrameRect ; to frame data buffer display ,MOVEM.L (SP)+,D3-D6/A2-A4 ; restore regs ,LEA myWindow,A1 ,MOVE.L (A1),A1 ; window pointer ,MOVE.W #srcOr,TxMode(A1) ; back to default mode ,RTS ; we're done ; DrawHexLine draws an address and 16 bytes of data pointed to by A4 DrawHexLine ,LINK A6,#-80 ; make room for the string ,LEA -80(A6),A3 ; point A3 at the string ,CLR (A3) ; initially it's length 0 ,MOVE.L A4,D0 ; the address ,LEA DataBufPtr,A0 ,SUB.L (A0),D0 ; normalize it ,MOVE.L D0,-(SP) ; save it ,LSR #8,D0 ; high byte ,BSR AddHexByte ,MOVE.L (SP)+,D0 ; low byte ,BSR AddHexByte ,MOVE.B #$3A,D0 ; get a colon ,BSR AddByte ,MOVE.B #$20,D0 ; get a blank ,BSR AddByte ,MOVE.B #$20,D0 ; do it again ,BSR AddByte ,MOVEQ #7,D6 ; 8 bytes to print DHexLoop ,MOVE.B (A4)+,D0 ; get next byte ,BSR AddHexByte ,MOVE.B #$20,D0 ,BSR AddByte ,DBRA D6,DHexLoop ; loop for 16 bytes ,PEA -80(A6) ; push the string pointer ,_DrawString ; draw it ,UNLK A6 ,RTS ; AddHexByte adds 2 hex characters corresponding to the byte in D0 to ; the string AddHexByte ,MOVE.W D0,-(SP) ; save a copy of the byte ,LSR #4,D0 ; get the high nybble ,BSR.S MapIt ; output the hex digit ,MOVE.W (SP)+,D0 ; recover low nibble MapIt ,AND.W #$000F,D0 ; use only low 4 bits ,MOVE.B HexTab(D0),D0 ; get the character ; AddByte adds the byte in D0 to the string pointed to by A3 AddByte ,MOVEQ #0,D1 ; clear out high part for index ,MOVE.B (A3),D1 ; get the length ,MOVE.B D0,1(A3,D1) ; move in the new byte ,ADDQ.B #1,(A3) ; bump the length ,RTS HexTab ,.ASCII '0123456789ABCDEF' ;___________________________________________________________________ ; ; DrawSpd notes the current speed on the screen. D4 is current speed. ; The PWM buffer is set to this speed. ;___________________________________________________________________ SetSpdX MOVE #1000,D0 ; need some delay ,JSR WakeUp ,MOVEQ #0,D7 ; no speed around test during short moves ,BRA.S SetSpd1 SetSpd MOVEQ #-1,D7 SetSpd1 MOVE.W D4,D2 ; set up PWM buffer ,JSR SetASpeed ,RTS ;___________________________________________________________________ ; ; DrawNib notes the current nibble on the screen and puts ; it into theNibble. ;___________________________________________________________________ DrWaitNib MOVE #1000,D0 ; need some delay ,JSR WakeUp DrawNib LEA theNibble,A0 ,MOVE.W D4,(A0) ; update current write nibble ,LEA goodData,A0 ,MOVE.B D4,(A0) ; construct timing ,MOVE.B D4,1(A0) ,MOVE.W (A0)+,(A0) ,LEA badData,A0 ,CLR.L (A0) ,LEA NibMsg,A6 ,BSR DrawHMsg ,BSR DrawErrs ,RTS ;___________________________________________________________________ ; ; DrawHMsg is a utility routine which clears and outlines the rectangle ; at (A6), draws the text pointed to by 12(A6) at 8(A6), and then appends ; the decimal byte in the low-order byte of D4 (two bytes if high-order byte ; is non-zero). ;___________________________________________________________________ DrawHMsg MOVE.L A6,-(SP) ; rectangle pointer ,MOVE.L A6,-(SP) ,_EraseRect ; that we wish to erase ,_FrameRect ; and frame ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L A6,-(SP) ,_DrawString ,MOVE.L A3,-(SP) ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.W D4,D0 ; the nibble ,CMP.W #$FFFF,D0 ; if it's unknown, print nothing ,BEQ.S @2 ,MOVE.W D0,-(SP) ,ROR.W #8,D0 ; high-order byte zero? ,TST.B D0 ,BEQ.S @1 ,BSR AddHexByte @1 MOVE.W (SP)+,D0 ,BSR AddHexByte ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it @2 MOVE.L (SP)+,A3 ,RTS ;___________________________________________________________________ ; ; DrawMsg is a utility routine which clears and outlines the rectangle ; at (A6), draws the text pointed to by 12(A6) at 8(A6), and then appends ; the decimal byte in the low-order byte of D4 (two bytes if high-order byte ; is non-zero). ;___________________________________________________________________ DrawMsg MOVE.L A6,-(SP) ; rectangle pointer ,MOVE.L A6,-(SP) ,_EraseRect ; that we wish to erase ,_FrameRect ; and frame ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L A6,-(SP) ,_DrawString DrawHByt MOVE.L A3,-(SP) ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.W D4,D0 ; the nibble ,CMP.W #$FFFF,D0 ; if it's unknown, print nothing ,BEQ.S @2 ,MOVEQ #3,D2 ; convert to decimal ,SWAP D0 @0 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVEQ #0,D0 ,SWAP D1 ,MOVE.W D1,D0 ; decimal ,MOVE.W D0,-(SP) ,ROR.W #8,D0 ; high-order byte zero? ,TST.B D0 ,BEQ.S @1 ,BSR AddHexByte @1 MOVE.W (SP)+,D0 ,BSR AddHexByte ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it @2 MOVE.L (SP)+,A3 ,RTS ;___________________________________________________________________ ; ; DrawTrk notes the current track on the screen. ; GotoTrk seeks to the appropriate track and then falls into DrawTrk. ;___________________________________________________________________ GoToTrk MOVE.W D4,D6 ; track to seek to ,MOVEM.L A0-A6/D1-D7,-(SP) ,JSR Seek1 ; go to it (don't mess with speed) ,MOVEM.L (SP)+,A0-A6/D1-D7 ,BPL.S DrawTrk ; br if valid ,LEA CantStpNote,A6 ; note that we can't step ,BSR DrawNote DrawTrk JSR GetDrv1 ,MOVE.W Track(A1,D1),D4 ; ,BMI.S @1 ; br if track invalid ,LEA TrkMsg,A6 ,BSR DrawMsg @1 RTS ;___________________________________________________________________ ; ; DrawErrs draws 32 bits of the data pointed to by A2 and A3 as timing ; diagrams on the screen. ; DrawTiming is a subroutine which draws the 32 bits in D5 as a timing ; diagram with the low-order bit starting at D3,D4 (v,h). ;___________________________________________________________________ DrawErrs ,LEA timingRect,A6 ,MOVE.L A6,-(SP) ; rectangle pointer ,MOVE.L A6,-(SP) ,_EraseRect ; that we wish to erase ,_FrameRect ; and frame ,MOVEM.L D3-D5,-(SP) ,MOVE.W #line1Vstrt,D3 ; upper-left starting location ,MOVE.W #line1Hstrt,D4 ,LEA goodData,A2 ,MOVE.L (A2),D5 ; good data ,LEA badData,A2 ,CMP.L (A2),D5 ; don't display if good=bad ,BEQ.S @1 ,BSR DrawTiming ,MOVE.W #line2Vstrt,D3 ; upper-left starting location ,MOVE.W #line2Hstrt,D4 ,LEA badData,A2 ,MOVE.L (A2),D5 ; bad data ,BEQ.S @1 ; don't draw if all zero ,BSR DrawTiming ,PEA tim2Rect ; put in byte lines ,_InverRect ,PEA tim2Rect ; then frame it ,_FrameRect @1 MOVEM.L (SP)+,D3-D5 ,RTS DrawTiming ,MOVEM.L D3-D7,-(SP) ,_PenNormal ; just draw a thin black line ,MOVE.W D4,-(SP) ; start horizontal ,MOVE.W D3,-(SP) ,_MoveTo ,MOVEQ #1,D6 ; we start high ,MOVEQ #2,D7 ; 3 groups of 8 bits ,ASL.L #8,D5 ; just display low-order 3 bytes DTLoop SWAP D7 ,MOVE.W #7,D7 DTLoop1 ASL.L #1,D5 ; check next bit ,BCC.S @4 ; if 0, just move it ,TST.W D6 ; are we up already? ,BNE.S @1 ; then move it down ,MOVEQ #1,D6 ; mark it high and move it up ,CLR.W -(SP) ; no horizontal movement ,MOVE.W #-8,-(SP) ; go up ,_Line ,BRA.S @2 @1 MOVEQ #0,D6 ; mark it low ,CLR.W -(SP) ; no horizontal movement ,MOVE.W #8,-(SP) ; go down ,_Line @2 MOVE.W #8,-(SP) ; go right 8 ,CLR.W -(SP) ; no vertical movement ,_Line ,DBRA D7,DTLoop1 ; do 8 bits ,SWAP D7 ,DBRA D7,DTLoop ; 4 groups ,MOVEM.L (SP)+,D3-D7 ,RTS ; draw an upward blip to distinguish bits @4 CLR.W -(SP) ; no horizontal movement ,MOVE.W #-1,-(SP) ; go up 1 ,_Moov ,CLR.W -(SP) ; no horizontal movement ,MOVE.W #2,-(SP) ; go back down 2 ,_Line ,CLR.W -(SP) ; no horizontal movement ,MOVE.W #-1,-(SP) ; go up 1 ,_Moov ,BRA.S @2 ;___________________________________________________________________ ; ; DrawNote is used to draw a message in the note area and note ; an optional number in decimal after it. A6 should point at the ; message block. ; ; All regs are preserved. ;___________________________________________________________________ DrawNote ,MOVEM.L A0-A1/A6/D0-D4,-(SP) ,MOVE.L A6,-(SP) ; erase rectangle pointer ,_EraseRect ; that we wish to erase ,ADDQ #8,A6 ; bump past rectangle ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ; prepare to draw text ,MOVE.L (A6)+,D4 ; save hex for now ,MOVE.L A6,-(SP) ,_DrawString ,CMP.L #$FFFFFFFF,D4 ; don't display it if -1 ,BEQ.S @1 ,BSR DrawHLong @1 MOVEM.L (SP)+,A0-A1/A6/D0-D4 ,RTS DrawHLong MOVE.L A3,-(SP) ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.W D4,D0 ,MOVEQ #3,D2 ; convert to decimal ,SWAP D0 @0 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@0 ,MOVEQ #0,D0 ,SWAP D1 ,MOVE.W D1,D0 ; decimal ,BSR.S @1 ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it ,MOVE.L (SP)+,A3 ,RTS @1 MOVE.W D0,-(SP) ,ROR.W #8,D0 ; high-order byte ,BSR AddHexByte ,MOVE.W (SP)+,D0 ,BSR AddHexByte ,RTS notePercent ,MOVEM.L A0-A6/D0-D7,-(SP) ,EXG D0,D7 ,SUB.L D0,D7 ; get difference ,BPL.S @1 ,NEG.L D7 ; absolute difference @1 MULU #100,D7 ,MOVE.L D0,D1 ,LSR.L #1,D1 ; 1/2 D0 ,ADD.L D1,D7 ; for correct rounding ,DIVU D0,D7 ,LEA HexBuf,A3 ; point A3 at the hex buffer ,CLR.W (A3) ; initially it's length 0 ,MOVE.B #$20,D0 ,BSR AddByte ; start with a space ,MOVE.B #$28,D0 ,BSR AddByte ; left paren ,MOVE.W D7,D0 ; the percent ,MOVEQ #3,D2 ; convert to decimal ,SWAP D0 @2 CLR.W D0 ,SWAP D0 ,DIVU #10,D0 ,SWAP D0 ,MOVE.W D0,D1 ,ROR.L #4,D1 ,DBRA D2,@2 ,MOVEQ #0,D0 ,SWAP D1 ,MOVE.W D1,D0 ; decimal ,BSR AddHexByte ,MOVE.B #$25,D0 ,BSR AddByte ; percent sign ,MOVE.B #$29,D0 ,BSR AddByte ; right paren ,PEA HexBuf ; push the string pointer ,_DrawString ; draw it ,MOVEM.L (SP)+,A0-A6/D0-D7 ,RTS 3. "6F^5D!$ǐ^; File: SonyHi.Text ;_______________________________________________________________________ ; ; Sony 3-1/2 Inch Drive Test Program: Error-Rate Test Window ; ; written by Larry Kenyon, beginning 16-Apr-83 ; ; This is a hi-level test program for use by hardware jocks to debug, ; explore, and evaluate the Sony-type 3-1/2 disk drive. It includes ; eject, recal, format, sector read/write testing with seek and power ; on/off, and printing of results. ; ; Modification History: ; 16 Apr 83 LAK New today. Made from mid-control outline and twiggy ; error rate test. ; 20 Aug 83 LAK Updated; ; 03/22/84 GRC, Changed Add Jitter selection to select Side 1, vs Side 0 ;_______________________________________________________________________ ,.NOLIST ,.INCLUDE tlasm:SYSEQU.TEXT ; general system equates ,.INCLUDE tlasm:SYSERR.TEXT ; error equates ,.INCLUDE tlasm:GRAFEQU.TEXT ; graphics-related equates ,.INCLUDE tlasm:GRAFTYPES.TEXT ,.INCLUDE tlasm:TOOLEQU.TEXT ,.INCLUDE tlasm:RESEQU.TEXT ,.INCLUDE tlasm:SonyEqu.Text ,.INCLUDE tlasm:SYSMACS.TEXT ; system macros ,.INCLUDE tlasm:TOOLMACS.TEXT ,.INCLUDE tlasm:QUICKMACS.TEXT ,.LIST DrawOffset .EQU WindowSize ; offset in window data to draw proc MDOffset .EQU DrawOffset+4 ; offset to mouse down in content proc TaskOffset .EQU MDOffset+4 ; offset to task this guy does when on top ActivOffset .EQU TaskOffset+4 ; offset to activate event proc WndDtaSize .EQU ActivOffset+4 CRefCOS .EQU 0 ; ctl handle offset within data structure CRectOS .EQU CRefCOS+4 ; control rectangle offset CInitOS .EQU CRectOS+8 ; initial value CMinOS .EQU CInitOS+2 ; min control value CMaxOS .EQU CMinOS+2 ; max control value CNameOS .EQU CMaxOS+2 ; control name offset CProcOS .EQU CNameOS+12 ; control proc to execute button CDefPrOS .EQU CProcOS+4 ; type of control CDtaSize .EQU CDefPrOS+2 ; scroll controls only . . . CSmallOS .EQU CMaxOS+2 ; small increment/decrement CPageOS .EQU CSmallOS+2 ; page increment/decrement CSProc1OS .EQU CPageOS+2 ; proc called during buttons after ctl chg CSProc2OS .EQU CSProc1OS+4 ; proc called on exit CSDtaSize .EQU CSProc2OS+4 selBit .EQU 0 ca0Bit .EQU 1 ca1Bit .EQU 2 ca2Bit .EQU 3 strBit .EQU 4 enbBit .EQU 5 ,.PROC HiTest,0 ,.ORG 0 ,.DEF MakeHiWindow ; only entry needed ,.DEF SideFlag ;Variable for which side to format ,.REF DiskSync ,.REF FigTrkSpeed ,.REF MakeSpdTbl ,.REF GetFreq1 ,.REF Seek ,.REF Recal ,.REF Eject ,.REF SetASpeed ,.REF SetSpeed ,.REF WakeUp ,.REF Format ,.REF TrkFormat ,.REF FmtVerify ,.REF GetDrive ,.REF GetDrv1 ,.REF AdrAndStrb ,.REF AdrAndSense ,.REF AdrDisk ,.REF Sense ,.REF Pulse ,.REF RdAddrSetUp ,.REF RdAddr1SetUp ,.REF EmptyPD ,.REF RdAddr ,.REF RdData ,.REF WrData ,.REF SpdRecal ;___________________________________________________________________ ; ; Routine: HiCtlActivate ; Arguments: A2 = event pointer ; Function: This routine handles the activation/deactivation of ; the low-control window by calling the DiskSync routine, ; and then setting all control values to 0. ;___________________________________________________________________ HiCtlActivate ,MOVEM.L D3-D7/A2-A6,-(SP) ,BTST #0,EvtMeta+1(A2) ; activate or de-activate? ,BEQ.S HiCtlDeAct ; br if deactivate ,BSR.S ShowScroll ; show scroll bars ,LEA FontForce,A2 ,MOVE.L (A2)+,-(SP) ; draw a blank to force font in ,_MoveTo ; prepare to draw text ,MOVE.L A2,-(SP) ,_DrawString ,JSR DiskSync ; proc in main program ,PEA PortRect(A3) ; push the boundRect of the window ,_InvalRect ; schedule it all for updating Wait4One LEA NeedDskNote,A6 ,BSR DrawNote @1 BSR ReadyCk ,BNE.S @1 ,LEA EraseNote,A6 ,BSR DrawNote InitSpdTbl BSR ToRecal ; recal HiCtlAcXit MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS HiCtlDeAct BSR.S HideScroll ,BRA.S HiCtlAcXit ; show scroll bars when we activate ShowScroll MOVEQ #0,D5 ; show flag ,BRA.S SHScrl1 HideScroll MOVEQ #-1,D5 ; hide flag SHScrl1 LEA CtlScroll,A2 ; scroll control data structures ,MOVE.W (A2)+,D4 ; number of scroll controls SHScrlLoop MOVE.L (A2),-(SP) ; control handle ,TST.W D5 ,BNE.S @1 ,_ShowControl ,BRA.S @2 @1 _HideControl @2 ADD #CSDtaSize,A2 ; point to next scroll control ,SUBQ.W #1,D4 ; do them all ,BGT.S SHScrlLoop ,RTS ;___________________________________________________________________ ; ; Routine: HiCtlTask ; Arguments: ; Function: Currently, this routine does nothing. ;___________________________________________________________________ HiCtlTask ,RTS ;___________________________________________________________________ ; ; Routine: DrawHiCtl ; Arguments: ; Function: This routine handles update events in the Hi-control ; window. ; ;___________________________________________________________________ DrawHiCtl ,MOVEM.L D3-D7/A2-A6,-(SP) ,MOVE.L A3,-(SP) ; window ptr ,_DrawControls ; draw the controls ,LEA UpDateTime,A6 ,ST (A6) ; update time ,LEA optionRect,A6 ,BSR DrawCapBox ,LEA msgRect,A6 ,BSR DrawCapBox ,LEA seqRect,A6 ,BSR DrawCapBox ,BSR DrawBuf ; and draw buffer 'window' ,PEA ubufRect ; under the buffer rectangle ,_FrameRect ,BSR UdDataByte ,BSR UdHdSettle ,BSR UdPassCnt ,BSR UdSpdChg ,BSR UDPwrCnt ,BSR UDRecalCnt ,BSR UDTrack ,JSR GetDrv1 ,LEA CtlTrkScrl,A0 ,MOVE.L CRefCOS(A0),-(SP) ; control handle ,MOVE.W Track(A1,D1),-(SP) ; set track value dial appropriately ,_SetCtlValue ,BSR UDPwrTim ,LEA UpDateTime,A6 ,CLR.W (A6) ; update time is over ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ; short routine to draw a captioned box DrawCapBox MOVE.L A6,-(SP) ; push pointer to option box rect ,_FrameRect ,ADDQ.L #8,A6 ; bump past rect ,MOVE.L A6,-(SP) ; now draw the text (captioned box) ,_EraseRect ,ADDQ.L #8,A6 ; bump past rect ,MOVE.L (A6)+,-(SP) ; push horizontal, vertical ,_MoveTo ,MOVE.L A6,-(SP) ; push pointer to string ,_DrawString ,RTS ;___________________________________________________________________ ; ; Routine: DoHiCtl ; Arguments: TheEvent ; Function: This routine handles mouse down events which occur in the ; menu bar. ; ;___________________________________________________________________ DoHiCtl ,MOVEM.L D3-D7/A2-A6,-(SP) ,LEA MyPt,A4 ,MOVE.L EvtMouse(A2),(A4) ,MOVE.L A4,-(SP) ,_GlobalToLocal ,SUBQ #2,SP ,MOVE.L (A4),-(SP) ; local mouse down point ,MOVE.L A3,-(SP) ; theWindow ,LEA theControl,A6 ,MOVE.L A6,-(SP) ; var: control handle ,_FindControl ; figure out which control ,MOVE.W (SP)+,D0 ,BEQ.S DoLCExit ,CMP.W #InCheckBox,D0 ,BEQ.S @2 ,CMP.W #InButton,D0 ,BEQ.S @2 ,BSR ScrollTrack ; handle scroll bars separately ,BRA.S DoLCExit @2 ; now map the control onto one of my data structures, and do the proc ,MOVE.L (A6),D6 ; control handle ,LEA HiCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls SrchLCtl CMP.L CRefCOS(A2),D6 ; this one? ,BEQ.S @1 ; br if so ,ADD #CDtaSize,A2 ; point to next control ,SUBQ.W #1,D4 ,BGT.S SrchLCtl ,BRA.S DoLCExit ; br if not in the structure @1 SUBQ #2,SP ,MOVE.L (A6),-(SP) ; theControl handle ,MOVE.L (A4),-(SP) ; local mouse down point ,MOVE.L MinusOne,-(SP) ; nil action proc ,_TrackControl ,MOVE.W (SP)+,D0 ,BEQ.S DoLCExit ,SUBQ #2,SP ,MOVE.L (A6),-(SP) ; theControl handle ,_GetCtlValue ,MOVE.W (SP)+,D3 ; current value ,BCHG #0,D3 ,MOVE.L (A6),-(SP) ; theControl handle ,MOVE.W D3,-(SP) ; set new value ,_SetCtlValue ; erase current note at this time . . . ,LEA EraseNote,A6 ,BSR DrawNote ; now do the proc we do at the end . . . ,LEA CProcOS(A2),A6 ; get proc ,TST.W D3 ; control value ,LEA DBase,A0 ; need to set up A0, A1 ,LEA VBase,A1 ,JSR (A6) ; do it DoLCExit MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS ;___________________________________________________________________ ; ; Routine: MakeHiWindow ; Arguments: A0.L (input) -- pointer to window record storage ; Function: This routine creates the Hi-Control window and initializes ; the window data structure. ; ;___________________________________________________________________ MakeHiWindow ,;.word $ff01 ,MOVEM.L D3-D7/A2-A6,-(SP) ; ; ,LEA LineStPtr,A3 ,MOVE.L A1,(A3) ; save pointer to line state ,CLR.L -(SP) ; make room for function result ,MOVE.L A0,-(SP) ; Hi-control window record ,PEA HiWRect ; global start location ,PEA HiWndNam ; window name = 'Error Rate Test' ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W #DocumentProc,-(SP) ; regular type window ,MOVE.L A2,-(SP) ; behind this window ,MOVE.W #$0100,-(SP) ; it has a go-away region ,MOVE.L #$10100001,-(SP) ; refCon ,_NewWindow ,MOVE.L (SP)+,A3 ; our window pointer bounces back to us ,LEA myWindow,A1 ,MOVE.L A3,(A1) ; save for changing text mode ,MOVE.W #4,TxFont(A3) ; use Gacha (fixed-width font) ,MOVE.W #9,TxSize(A3) ; size 10 ,MOVE.W #srcOr,TxMode(A3) ,LEA DrawHiCtl,A1 ; fill in our proc pointers ,MOVE.L A1,DrawOffset(A3) ; the draw proc ,LEA DoHiCtl,A1 ; handles mouse down in content region ,MOVE.L A1,MDOffset(A3) ,LEA HiCtlTask,A1 ; does any sense updates ,MOVE.L A1,TaskOffset(A3) ,LEA HiCtlActivate,A1 ; does activate stuff ,MOVE.L A1,ActivOffset(A3) ,LEA HiCtlDta,A2 ; control data structures ,MOVE.W (A2)+,D4 ; number of controls ,MOVEQ #0,D3 ; first refcon is 0 ICtlLoop BSR.S InitCtl ,ADD #CDtaSize,A2 ; point to next control ,ADDQ #1,D3 ; incr refNum ,SUBQ.W #1,D4 ; do them all ,BGT.S ICtlLoop ,LEA CtlScroll,A2 ; scroll control data structures ,MOVE.W (A2)+,D4 ; number of scroll controls ISCtlLoop BSR.S InitSCtl ,ADD #CSDtaSize,A2 ; point to next scroll control ,ADDQ #1,D3 ; incr refNum ,SUBQ.W #1,D4 ; do them all ,BGT.S ISCtlLoop ,MOVEM.L (SP)+,D3-D7/A2-A6 ,RTS InitCtl SUBQ #4,SP ,MOVE.L A3,-(SP) ; windowPtr ,PEA CRectOS(A2) ; boundsRect ,PEA CNameOS(A2) ; control name ptr ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W CInitOS(A2),-(SP) ; initial value ,MOVE.W CMinOS(A2),-(SP) ; min value ,MOVE.W CMaxOS(A2),-(SP) ; max value ,CMP.W #PushButProc,CDefPrOS(A2) ,BNE.S @1 ; except for push button procs ,CLR.W (SP) ; max is 0 @1 MOVE.W CDefPrOS(A2),-(SP) ; type of control ,MOVE.L D3,-(SP) ; refcon ,_NewControl ,MOVE.L (SP)+,CRefCOS(A2) ; store handle ,RTS InitSCtl SUBQ #4,SP ,MOVE.L A3,-(SP) ; windowPtr ,PEA CRectOS(A2) ; boundsRect ,PEA SCtlName ; control name ptr ,MOVE.W #$0100,-(SP) ; visible ,MOVE.W CInitOS(A2),-(SP) ; initial value ,MOVE.W CMinOS(A2),-(SP) ; min value ,MOVE.W CMaxOS(A2),-(SP) ; max value ,MOVE.W #ScrollBarProc,-(SP) ,MOVE.L D3,-(SP) ; refcon ,_NewControl ,MOVE.L (SP)+,CRefCOS(A2) ; store handle ,RTS ;_______________________________________________________________________ ; ; Hi Control Window Data Space ;_______________________________________________________________________ LineStPtr .LONG 0 ; ptr to main pgm global line state theControl .LONG 0 ; scratch control pointer MyPt .WORD 0,0 ; scratch point MyWindow .LONG 0 ; pointer to our window HiWRect .WORD 38,5,338,505 ; start global rectangle for Hi-Control HiWndNam .BYTE 15 ,.ASCII 'Error Rate Test' H1 .EQU 10 ; some screen horizontal anchor points H2 .EQU 115 H3 .EQU 300 H4 .EQU 490 H21 .EQU 105 H31 .EQU 200 W1 .EQU 90 ; some screen object widths W12 .EQU 90 W2 .EQU 175 W3 .EQU 190 V1 .EQU 5 ; some screen vertical anchor points V2 .EQU 110 V3 .EQU 176 V4 .EQU 216 V5 .EQU 256 V21 .EQU 80 V22 .EQU 80 V32 .EQU 232 V42 .EQU 300 memClip .WORD V22,H3+16,V32,H4-1 ; rect to draw into fullClip .WORD 0,0,300,500 ubufRect .WORD V32-1,H3,V5+36,H4 ; under buffer rectangle bufRect .WORD V22,H3,V32,H4 ; buffer rectangle DBufTxt .WORD V22+14,H3+20 g10width .EQU 6 ; gatcha 10 chars are 6 bits wide seqRect .WORD V1,H2,V21-10,H2+W2 ; rectangle for sequence checkboxes seqMsg .WORD V1-1,H2+5,V1+1,H2+60 ; erase rect (12+6*chars) ,.WORD V1+5,H2+10 ; V,H local point ,.BYTE 8 ,.ASCII 'Test Seq ' optionRect .WORD V21,H2,V3-10,H2+W2 ; rectangle for option checkboxes optionMsg .WORD V21-1,H2+5,V21+1,H2+54 ; erase rect (12+6*chars) ,.WORD V21+5,H2+10 ; V,H local point ,.BYTE 7 ,.ASCII 'Options' msgRect .WORD V1,H3,70,H3+W3 ; rectangle for messages msgMsg .WORD V1-1,H3+5,V1+1,H3+41 ; erase rect (12+6*chars) ,.WORD V1+5,H3+10 ; V,H local point ,.BYTE 5 ,.ASCII 'Notes' inBufRect .WORD V32-1,H3,V42,H4 ; rect around buf select buttons ; all windows share fixed-length records in the following data structure HiCtlDta .WORD 18 ; 18 regular controls ,.LONG 0 ; control handle ,.WORD v2,h1,v2+25,h1+43 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'eject ' ,BRA ToEject ,.WORD PushButProc ,.LONG 0 ; control handle ,.WORD v2+30,h1,v2+55,h1+43 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'recal ' ,BRA ToRecal ,.WORD PushButProc DskEnbCtl .LONG 0 ; control handle ,.WORD v2+30,h1+47,v2+55,h1+90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 4 ,.ASCII 'M on ' ,BRA ToSetEnb ,.WORD PushButProc ,.LONG 0 ; control handle ,.WORD v2,h1+47,v2+25,h1+90 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'clear ' ,BRA ClearCnts ,.WORD PushButProc PrintCtl .LONG 0 ; control handle ,.WORD v1+75,h1,v1+95,h1+w1 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 10 ,.ASCII 'format trk ' ,BRA ToFmtTrk ,.WORD PushButProc FmtDskCtl .LONG 0 ; control handle ,.WORD v1+50,h1,v1+70,h1+w1 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'format disk' ,BRA ToFormat ,.WORD PushButProc StTestCtl .LONG 0 ; control handle ,.WORD v1,h1,v1+20,h1+w1 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 10 ,.ASCII 'start test ' ,BRA ContTest ,.WORD PushButProc Opt1Ctl .LONG 0 ; control handle ,.WORD v21+15,h2+15,v21+30,h2+120 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 10 ,.ASCII 'write/read ' ,BRA SetRW ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD v21+30,h2+15,v21+45,h2+150 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'wt rndm dta' ,BRA SetWrData ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD v21+45,h2+15,v21+60,h2+120 ; bounds rect ,.WORD 1 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'stop on err' ,BRA SetErrStp ,.WORD CheckBoxProc ,.LONG 0 ; control handle ,.WORD v21+60,h2+15,v21+75,h2+120 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 11 ,.ASCII 'Side 1 Sel ' ,BRA SetSide ,.WORD CheckBoxProc Seq1Ctl .LONG 0 ; control handle ,.WORD v1+15,h2+15,v1+30,h2+85 ; bounds rect ,.WORD 1 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 6 ,.ASCII 'random ' ,BRA SetSeq1 ,.WORD RadioButProc Seq2Ctl .LONG 0 ; control handle ,.WORD v1+30,h2+15,v1+45,h2+85 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 6 ,.ASCII 'static ' ,BRA SetSeq2 ,.WORD RadioButProc Seq3Ctl .LONG 0 ; control handle ,.WORD v1+15,h2+95,v1+30,h2+160 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'seq + ' ,BRA SetSeq3 ,.WORD RadioButProc Seq4Ctl .LONG 0 ; control handle ,.WORD v1+30,h2+95,v1+45,h2+160 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 5 ,.ASCII 'seq - ' ,BRA SetSeq4 ,.WORD RadioButProc Buf1Ctl .LONG 0 ; control handle ,.WORD v32+15,h3+15,v32+30,h3+85 ; bounds rect ,.WORD 1 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 6 ,.ASCII 'tk0-79 ' ,BRA SetBuf1 ,.WORD RadioButProc Buf2Ctl .LONG 0 ; control handle ,.WORD v32+30,h3+15,v32+45,h3+85 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 7 ,.ASCII 'err tks ' ,BRA SetBuf2 ,.WORD RadioButProc Buf3Ctl .LONG 0 ; control handle ,.WORD v32+15,h3+95,v32+30,h3+160 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 1 ; max value ,.BYTE 6 ,.ASCII 'errors ' ,BRA SetBuf3 ,.WORD RadioButProc ; alternate button names EnbhiName .BYTE 3 ,.ASCII 'off' EnbloName .BYTE 2 ,.ASCII 'on ' CtlScroll .WORD 9 ; 9 scroll controls CtlDtaScrl .LONG 0 ; control handle ,.WORD v22,h3,v32,h3+16 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 70 ; max value (9 below true max) ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrawBuf ; proc to display ,BRA DrawBuf ; proc at end CtlScr11 .LONG 0 ; control handle (head settle time) ,.WORD v3,h1,v3+16,h1+w12 ; bounds rect ,.WORD 300 ; initial value ,.WORD 0 ; min value ,.WORD 9999 ; max value (1 second) ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrHdSettle ; proc to display ,BRA DrHdSettle ; proc at end CtlScr21 .LONG 0 ; control handle (sectors/pass count) ,.WORD v4,h1,v4+16,h1+w12 ; bounds rect ,.WORD 170 ; initial value (170 sectors/pass) ,.WORD 1 ; min value ,.WORD 9999 ; max value ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrPassCnt ; proc to display ,BRA DrPassCnt ; proc at end CtlTrkScrl CtlScr31 .LONG 0 ; control handle (set current track) ,.WORD v5,h1,v5+16,h1+w12 ; bounds rect ,.WORD 0 ; initial value ,.WORD 0 ; min value ,.WORD 79 ; max value (79 tracks) ,.WORD 1 ; small increment/decrement ,.WORD 4 ; 'page' increment/decrement ,BRA DrTrack ; proc to display ,BRA DrTrack ; proc at end CtlScr12 .LONG 0 ; control handle (speed change wait time) ,.WORD v3,h21,v3+16,h21+w12 ; bounds rect ,.WORD $05DC ; initial value (1500 * 100 usec) ,.WORD $0000 ; min value (no speed change wait) ,.WORD 9999 ; max value (1 second) ,.WORD 1 ; small increment/decrement ,.WORD 16 ; 'page' increment/decrement ,BRA DrSpdChg ; proc to display ,BRA DrSpdChg ; proc at end CtlScr22 .LONG 0 ; control handle (power cycle pass count) ,.WORD v4,h21,v4+16,h21+w12 ; bounds rect ,.WORD 80 ; initial value (every 80 passes) ,.WORD $0000 ; min value ,.WORD 9999 ; max value (power cycle every 32k passes) ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrPwrCnt ; proc to display ,BRA DrPwrCnt ; proc at end CtlScr32 .LONG 0 ; control handle (recal pass count) ,.WORD v5,h21,v5+16,h21+w12 ; bounds rect ,.WORD 2 ; initial value ,.WORD 0 ; min value (never recal) ,.WORD 9999 ; max value ,.WORD 1 ; small increment/decrement ,.WORD 16 ; 'page' increment/decrement ,BRA DrRecalCnt ; proc to display ,BRA DrRecalCnt ; proc at end CtlScr13 .LONG 0 ; control handle (undefined) ,.WORD v3,h31,v3+16,h31+w12 ; bounds rect ,.WORD 2 ; initial value (2 sec) ,.WORD 0 ; min value ,.WORD 9999 ; max value (166 sec) ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrPwrTim ; proc to display ,BRA DrPwrTim ; proc at end CtlScr23 .LONG 0 ; control handle (set write data byte) ,.WORD v4,h31,v4+16,h31+w12 ; bounds rect ,.WORD $0000 ; initial value ,.WORD $0000 ; min value ,.WORD $00FF ; max value ,.WORD 1 ; small increment/decrement ,.WORD 8 ; 'page' increment/decrement ,BRA DrDataByt ; proc to display ,BRA DrDataByt ; proc at end HdStlMsg .WORD v3+15,h1,v3+36,h1+w12 ,.WORD v3+31,h1 ; V,H local point ,.BYTE 9 ,.ASCII ' Hd Set: ' PassMsg .WORD v4+15,h1,v4+36,h1+w12 ,.WORD v4+31,h1 ; V,H local point ,.BYTE 9 ,.ASCII ' Sec/Ps: ' TrackMsg .WORD v5+15,h1,v5+36,h1+w12 ,.WORD v5+31,h1 ; V,H local point ,.BYTE 9 ,.ASCII ' CurTrk: ' SpdChgMsg .WORD v3+15,h21,v3+36,h21+w12 ,.WORD v3+31,h21 ; V,H local point ,.BYTE 9 ,.ASCII ' SpdChg: ' PwrCntMsg .WORD v4+15,h21,v4+36,h21+w12 ,.WORD v4+31,h21 ; V,H local point ,.BYTE 9 ,.ASCII ' Pwr Ct: ' RecalMsg .WORD v5+15,h21,v5+36,h21+w12 ,.WORD v5+31,h21 ; V,H local point ,.BYTE 9 ,.ASCII ' Rcl Ct: ' PwrTimMsg .WORD v3+15,h31,v3+36,h31+w12 ,.WORD v3+31,h31 ; V,H local point ,.BYTE 9 ,.ASCII ' PwrTim: ' DtaBytMsg .WORD v4+15,h31,v4+36,h31+w12 ,.WORD v4+31,h31 ; V,H local point ,.BYTE 9 ,.ASCII ' WrData: ' HexBuf .LONG 0,0,0,0 theByte .WORD $0000 ; default write byte passCount .LONG $00AA0000 ; starts at 170 sectors/pass pwrCount .LONG $00500000 ; default = power cycle every 80 passes pwrTime .LONG $00020000 ; default = power down for 2 sec recalCount .LONG $00020000 ; default = recal every 2 errors theCtlDta .LONG 0 ; pointer to current control data UpdateTime .WORD 0 ; boolean, 0 when NOT update time ErrStpFlag .WORD 1 ; stop on errors when non-zero RWFlag .WORD 0 ; write before read when non-zero randomData .WORD 0 ; use random data when non-zero SideFlag .WORD 0 ; Side 0 or 1 selection SeqType .WORD 1 ; 1=rnd,2=stc,3=seq+,4=seq- BufDisp .WORD 1 ; 1=all,2=errtks,3=errors,4=config HiTxt .BYTE 1 ,.BYTE $30 ; starts as Ascii 0 FontForce .WORD 150,90 ; V,H local point SCtlName .BYTE 1 ; also scroll control name ,.ASCII ' ' NoteValOS .EQU 12 ; offset to note value OnlyNoteVal .WORD 0 ; only note value when non-zero EraseNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 1 ,.ASCII ' ' NoHdrNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 21 ,.ASCII 'No Header Found . . .' WrProtNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 28 ,.ASCII 'Diskette is Write-Protected? ' NtRdyNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 29 ,.ASCII 'Not Ready: Disk In & Powered?' ToStopNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 31 ,.ASCII 'Press Mouse Button To Exit Loop' BadWrNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 24 ,.ASCII 'Write-Underrun Occurred! ' PassNote .WORD 20,h3+10,35,h4-1 ; erase rect ,.WORD 30,h3+10 ; V,H local point ,.LONG 0 ; passes value ,.BYTE 17 ,.ASCII 'Pass Count : ' BadAdrNote .WORD 35,h3+10,50,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG 0 ; bad nibbles value ,.BYTE 17 ,.ASCII 'Adr Mark Errs : ' BadDtaNote .WORD 50,h3+10,65,h4-1 ; erase rect ,.WORD 60,h3+10 ; V,H local point ,.LONG 0 ; no header found count value ,.BYTE 17 ,.ASCII 'Data Mark Errs : ' RPMNote .WORD 35,h3+10,50,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG 0 ; rpm value ,.BYTE 16 ,.ASCII 'New RPM Value : ' RPMHiNote .WORD 20,h3+10,35,h4-1 ; erase rect ,.WORD 30,h3+10 ; V,H local point ,.LONG 0 ; bad nibbles value ,.BYTE 16 ,.ASCII 'Hi RPM Value : ' RPMLoNote .WORD 50,h3+10,65,h4-1 ; erase rect ,.WORD 60,h3+10 ; V,H local point ,.LONG 0 ; no header found count value ,.BYTE 16 ,.ASCII 'Low RPM Value : ' CantStpNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 25 ,.ASCII 'Unable To Step (Step = 0)' BadSeekNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG 0 ; no value ,.BYTE 13 ,.ASCII 'Seek Error : ' NeedDskNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 25 ,.ASCII 'Please Insert A Diskette!' FmtInPgNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 23 ,.ASCII 'Disk Format In Progress' FmtVerNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 23 ,.ASCII 'Now Verifying Diskette ' FmtOKNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 28 ,.ASCII 'Disk Successfully Formatted! ' TFmtOKNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG $FFFFFFFF ; no value ,.BYTE 29 ,.ASCII 'Track Successfully Formatted!' FmtBadNote .WORD 20,h3+10,65,h4-1 ; erase rect ,.WORD 45,h3+10 ; V,H local point ,.LONG 0 ; error code ,.BYTE 21 ,.ASCII 'Disk Format Failure: ' ; error totals information ErrNoteLen .EQU 30 ; each entry is 30 bytes long Err1Note .WORD V22+5,h3+10,V22+20,h4-10 ; erase rect ,.WORD V22+15,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'AM-none : ' ,.WORD V22+20,h3+10,V22+35,h4-10 ; erase rect ,.WORD V22+30,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'AM-ck sum : ' ,.WORD V22+35,h3+10,V22+50,h4-10 ; erase rect ,.WORD V22+45,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'AM-bitslp : ' ,.WORD V22+50,h3+10,V22+65,h4-10 ; erase rect ,.WORD V22+60,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'AM-trknum : ' ,.WORD V22+65,h3+10,V22+80,h4-10 ; erase rect ,.WORD V22+75,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'DM-none : ' ,.WORD V22+80,h3+10,V22+95,h4-10 ; erase rect ,.WORD V22+90,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'DM-ck sum : ' ,.WORD V22+95,h3+10,V22+110,h4-10 ; erase rect ,.WORD V22+105,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'DM-bitslp : ' ,.WORD V22+110,h3+10,V22+125,h4-10 ; erase rect ,.WORD V22+120,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'Rd ver err: ' ,.WORD V22+125,h3+10,V22+140,h4-10 ; erase rect ,.WORD V22+135,h3+20 ; V,H local point ,.LONG 0 ; ,.BYTE 12 ,.ASCII 'Sect miss : ' DataErr .EQU 0 AdrErr .EQU DataErr+2 PassTotal .EQU AdrErr+2 DErrTotal .EQU PassTotal+8 AErrTotal .EQU DErrTotal+8 RclCount .EQU AErrTotal+8 SideToTest .EQU RclCount+4 AMNoneTotal .EQU SideToTest+2 AM1Total .EQU AMNoneTotal+4 AM2Total .EQU AM1Total+4 AM3Total .EQU AM2Total+4 DMNoneTotal .EQU AM3Total+4 DM1Total .EQU DMNoneTotal+4 DM2Total .EQU DM1Total+4 RdVerTotal .EQU DM2Total+4 SectNFTotal .EQU RdVerTotal+4 WSectMap .EQU SectNFTotal+4 RSectMap .EQU WSectMap+4 TkCntLth .EQU RSectMap+4 TrkCnts .BLOCK TkCntLth,0 rwBuffer .BLOCK 512,0 ; buffer we use for r/w data Pass .BLOCK 320,0 ; number of passes per track AECount .BLOCK 320,0 ; number of address errors per track DCount .BLOCK 320,0 ; number of data mark errors per track ,.INCLUDE SONYHI1.TEXT ,.INCLUDE SONYHI2.TEXT ,.END