; ;************************************** ; ; READ SECTOR FROM DISK ; ; ENTRY:ACC=SECTOR NUMBER ; :BUFFER POINTER POINTS TO SECTOR ; :BUFFER WHERE DATA IS TO BE PUT ; EXIT:CARRY SET IF ANY ERROR ; ;************************************** ; RSEC PROC ; :STATUS = $A0 ; STA SECREG ;STORE IN SECTOR REG LDA TRACK STA TRKREG ;SET UP TRACK REGISTER RSEC12 LDY #$00 ;SET UP INDEX POINTER LDA #$E6 STA WT24E ;SET TIME OUT LDA RSECCM ;READ SECTOR COMMAND STA CMDREG ;PUT INTO COMMAND REGISTER RSEC01 BIT DRA ;TEST STATUS BVC RSEC10 ;TIMEOUT BPL RSEC01 ;DATA NOT READY YET LDA DTAREG ;LOAD DATA REGISTER EOR #$FF ;COMPLEMENT DATA IF NEED BE STA (BPNT),Y ;STORE IN BUFFER ; LDA RTDE ;CLEAR TIMEOUT COUNTER INY CPY LENTH ;COMPARE LENTH OF SECTOR BNE RSEC01 ;NOT DONE KEEP GETTING DATA LDA #$01 ;MASK FOR FDC RSEC02 BIT STREG ;CHECK FDC STATUS BNE RSEC02 LDA STREG EOR #$FF STA STAT+1 EOR #$FF ;PUT IT BACK THE WAY IT WAS AND #%00101000 ;CHECK CRC AND ;DELETED DATA MARK BEQ :RS003 LDA #$01 ;SET BAD STATUS STA :STATUS SEC BCS RSECXT :RS003 LDA #0 ;OK NO PROBLEM STA :STATUS ;RETURN GOOD STATUS CLC RSECXT RTS RSEC10 LDA STREG AND #$01 BEQ RSEC11 LDA #$E6 JSR STMO ;SET TIMEOUT BNE RSEC01 RSEC11 LDA WT64D LDA STREG AND #$04 ;CHECK FOR LOST DATA BNE RSEC12 LDA #$01 STA :STATUS ;SET YUCKY STATUS LDA STREG EOR #$FF STA STAT+1 ;SAVE FDC STATUS SEC BCS RSECXT ;ERROR EXIT EPROC ; ; ;************************************** ; ; VERIFY SECTOR JUST READ ; ; ENTRY:ACC=SECTOR NUMBER ; :BUFFER POINTER POINTS TO SECTOR ; :BUFFER WHERE DATA IS TO BE PUT ; EXIT:CARRY SET IF ANY ERROR ; ;************************************** VSEC PROC ; :STATUS = $A0 ; STA SECREG ;STORE IN SECTOR REG LDA TRACK STA TRKREG ;SET UP TRACK REGISTER LDA #$00 STA :STATUS STA TEMP ;CLEAR FLAG :VSEC1 LDY #$00 ;SET UP INDEX POINTER LDX #$00 LDA #$F6 JSR STMO ;SET TIME OUT LDA RSECCM ;READ SECTOR COMMAND STA CMDREG ;PUT INTO COMMAND REGISTER :VSEC2 BIT DRA ;TEST STATUS BVC :VSEC6 ;TIMEOUT BPL :VSEC2 ;DATA NOT READY YET LDA DTAREG ;LOAD DATA REGISTER EOR #$FF ;COMPLEMENT DATA CMP (BPNT),Y ;COMPARE WITH BUFFER BEQ :VSEC3 ;DATA OK LDA #$FF STA TEMP ;SET FLAG :VSEC3 INY CPY LENTH ;COMPARE LENTH OF SECTOR BNE :VSEC2 ;NOT DONE KEEP GETTING DATA LDA #$01 ;MASK FOR FDC :VSEC4 BIT STREG ;CHECK FDC STATUS BNE :VSEC4 LDA STREG EOR #$FF STA STAT+1 EOR #$FF AND #%00111000 ;CHECK FOR ERRORS BNE :VSEC8 LDA #0 ;SET GOOD STATUS STA :STATUS CLC :VSEC5 LDA TEMP ;LOAD FLAG BPL :VSECXT ;DATA OK LDA #$01 STA :STATUS ;SET BAD STATUS SEC BCS :VSECXT ;BAD READ :VSEC6 INC :STATUS CMP #$02 ;TRY TWO TIMES BEQ :VSEC8 LDA STREG AND #$01 BEQ :VSEC7 LDA #$E6 JSR STMO ;SET TIMEOUT BNE :VSEC2 :VSEC7 LDA WT64D LDA STREG AND #$04 ;CHECK FOR LOST DATA BNE :VSEC1 :VSEC8 LDA #$01 STA :STATUS SEC :VSECXT RTS EPROC ; ; ;************************************** ; ; READ TRACK ROUTINE ; ; ENTRY:NONE ; EXIT:CARRY SET IF ERROR ; :$A0 = # OF BAD SECTORS ;************************************** RDTK PROC ; :STATUS = $A0 :COUNT = $A5 ;COUNT OF SECTORS ; JSR FINT JSR NTS LDA TINB CMP #$FF ;BUFFER EMPTY? BEQ :RTK02 ;YES READ TRACK ; CMP NTRK ;IS NEW TRACK DIFFERENT? BNE :RTK02 LDA #01 ;INDICATE MOTOR NOT TURNED ON STA :STATUS CLC ;CLEAR CARRY FOR OK BCC :RTKXT ; :RTK02 JSR MCK ;CHECK MOTOR THING JSR SKTK ;SEEK TRACK IF NESSESACARY BCC :RTK12 LDA #$01 ;MOTOR WAS ON STATUS STA :STATUS BCS :RTKXT ; :RTK12 LDX #0 TXA STA :COUNT ;INIT GOOD SECTOR COUNT ; :RTK05 STA TRKCH,X ;CLEAR SECTOR STATUS INX CPX CONFIG+3 ;ALL SECTOR STATS CLEAR? BNE :RTK05 :RTK01 LDX :COUNT ;LOAD INDEX TO SKTAB LDA SKTAB,X ;SECTOR NUMBER JSR CTS ;CHECK FOR SECTOR 1,2,3 ON ;TRACK ZERO JSR SBPNT ;SET BUFFER POINTER LDY DTAREG ;DUMMY READ JSR RSEC ;READ IN SECTOR LDX :COUNT LDA SKTAB,X ;SECTOR NUMBER TAX DEX LDA STAT+1 ;GET FDC STATUS STA TRKCH,X ;STORE IN SECTOR CHECK ; INC :COUNT LDA :COUNT CMP CONFIG+3 ;ALL SECTORS? BEQ :RTK03 ;YES, EXIT LDA SKTAB,X ;LOAD SECTOR JSR SBPNT JMP :RTK01 :RTK03 LDA NTRK STA TINB ;SET TRACK IN BUFFER IND. CLC LDA #$0 ;INDICATE THAT MOTOR WAS STA :STATUS ;TURNED ON :RTKXT RTS EPROC ; ; ;************************************** ; ; SET BUFFER POINTER TO MEMORY PAGE FOR ; SECTOR ; ENTRY:ACC=SECTOR NUMBER ; EXIT:BPNT=PAGE POINTER ; ; ALL REGISTERS PRESERVED ; ;************************************** ; SBPNT PROC ; :BFOFF = $82 ;BUFFER OFFSET ; STA :BFOFF+1 PHA ;SAVE SECTOR NUMBER TXA ;SAVE X REGISTER PHA ; DEC :BFOFF+1 ; LDA #$20 BIT STAT ;CHECK DENSITIES BMI :SB128 ;128 BYTE SECTORS BEQ :SB128 ;128 BYTE SECTORS CLC LDA :BFOFF+1 ;THESE ARE 256 BYTE BUFFERS ADC #HIGH BUFF STA BPNT+1 LDA #$00 STA BPNT BEQ :SBXIT ; :SB128 LDX #$00 ;DO A 7 BIT SHIFT LEFT STX :BFOFF LSR :BFOFF+1 ROR :BFOFF CLC LDA #LOW BUFF ADC :BFOFF STA BPNT LDA #HIGH BUFF ADC :BFOFF+1 STA BPNT+1 ; :SBXIT PLA TAX ;RECOVER X REG PLA ;RECOVER ACC RTS EPROC ; ;************************************** ; READ SECTOR ; ; ENTRY:NONE ; EXIT:CARRY SET IF ERROR ; ;************************************** ; RDSC LDA NSEC JSR SBPNT JSR CTS ;SET LENTH ACORDING TO TRACK 0 ;AND SECTOR 1,2,3 LDA LENTH ;LENTH OF SECTOR JSR SEND RTS ; ;************************************** ; ; TURN ON DRIVE MOTOR ; ; ENTRY:NONE ; EXIT:NONE ; ; PRESERVES ALL USED REGISTERS ; ;************************************** ; MOON PROC PHA LDA DRA ;LOAD DATA REGISTER AND #$F7 ;SET CONTROLL BIT LOW STA DRA ;FOR MOTOR LDA #$FF STA MFLAG ;SET MOTOR ON FLAG LDA STAT ORA #$10 STA STAT LDA STPPOS ORA #$01 STA DRB ;TURN ON STEPPER MOTOR PLA RTS EPROC ; ;************************************** ; ; TURN OFF DRIVE MOTOT ; ; ENTRY:NONE ; EXIT:NONT ; ; PRESERVES ALL REGISTERS ; ;************************************** ; MOOFF PROC PHA LDA DRA ;LOAD DATA REGISTER ORA #$08 ;SET MOTOR CONTROL BIT HIGH STA DRA LDA STAT AND #$EF STA STAT LDA DRB ;TURN OFF STEPPER MOTOR STA STPPOS ORA #%00111100 ;ALL BITS OFF STA DRB PLA RTS EPROC ; ;************************************** ; ; INIT 5 SECOND TIMER ; ; ENTRY:NONE ; EXIT:NONE ; ; PRESERVES ALL REGISTERS ; ;************************************** ; I5SEC PHA LDA TL ;LOAD TIME LIMIT STA TC LDA #$97 ;.1 SECOND INTERVAL JSR STMO ;START TIMER PLA RTS ; ;************************************** ; ; CHECK 5 SECOND TIMER ; ; ENTRY:NONE ; EXIT:CARRY SET IF TIMED OUT ; ; PRESERVES ALL REGISTERS ; ;************************************** ; CK5S PHA BIT DRA ;CHECK FOR TIMER TIMEOUT BVS CK5SXT DEC TC ;DECREMENT TIMER COUNT LDA TC BEQ CK5S01 ;COUNT ENDED LDA #97 JSR STMO ;RESET TIMER CLC BCC CK5XIT CK5S01 LDA RTDE ;DISABLE TIMER SEC BCS CK5XIT CK5SXT CLC CK5XIT PLA RTS ; ;************************************** ; ; WRITE SECTOR ; ; ENTRY:ACC=SECTOR TO WRITE ; :BUFFER POINTER POINTS TO DATA ; EXIT:CARRY SET IF ANY ERRORS ; ;************************************** ; WSEC PROC ; :STATUS = $A0 ; STA SECREG LDA TRACK STA TRKREG ;SET UP SECTOR TO WRITE TO WSEC01 LDY #$00 LDA #$E6 STA WT24E LDA WSECCM ;WRITE SECTOR COMMAND STA CMDREG WSEC02 LDA (BPNT),Y EOR #$FF ;LOAD AND COMPLEMENT DATA WSEC03 BIT DRA ;CHECK FOR WHEN FDC REDY BVC WSEC10 ;TIME OUT ERROR BPL WSEC03 ;LOOP UNTIL READY STA DTAREG ;SEND DATA TO FDC LDA WT64D INY CPY LENTH ;COMPARE WITH SECTOR LENTH BNE WSEC02 LDA #$01 WSEC04 BIT STREG BNE WSEC04 ;LOOP UNTIL DONE LDA STREG LDA #0 STA :STATUS ;SET STATUS OK! CLC RTS WSEC10 LDA STREG AND #$01 ;CHECK FOR BUSY BEQ WSEC20 LDA #$E6 JSR STMO BNE WSEC02 WSEC20 LDA WT64D LDA STREG AND #$04 ;CHECK FOR LOST DATA BNE WSEC01 LDA STREG LDA #$01 STA :STATUS ;SET STATUS YUCKY! SEC RTS EPROC ; ; ;************************************** ; ; ITRKS : INITIALIZE A SINGLE DENSITY ; TRACK BY SETTING UP A MODEL TRACK ; IN RAM AT LOCATION $2000 ; ; ENTRY : SECT IS SECTOR # ; TRCK IS TRACK # ; EXIT : MODEL TRACK AT $2000 ; ;************************************** ITRKS LDA #$00 STA BPNT LDA #$20 STA BPNT+1 ;COPY BASE POINTER LDY #0 ;INITIALIZE INDEX LDX #$AC ;# OF BYTES TO LOOP LDA #0 ;INIT BYTES TO $FF TKHDR1 DEX ;DECREMENT LOOP COUNT STA (BPNT),Y ;STORE DATA JSR IBPNT ;INC BASE CPX #0 ;STOP LOOP? BNE TKHDR1 LDA #$FC ;INIT BYTE TO $FC STA (BPNT),Y ;STORE DATA JSR IBPNT ;INC BASE ;UPDATE BASE INDEX LDX #16 LDA #0 TKHDR3 DEX STA (BPNT),Y JSR IBPNT ;INC BASE CPX #0 BNE TKHDR3 ;END OF TRACK HEADER? LDX #0 STX SECT ;SECT IS SECTOR # INDEX ; BEGIN SECTOR FORMAT MODEL SHDR1 LDX #6 ;6 BYTES LDA #0 ;LOAD 0 SHDR2 DEX STA (BPNT),Y JSR IBPNT ;INC BASE CPX #0 BNE SHDR2 LDA #$FE STA (BPNT),Y JSR IBPNT ;INC BASE LDA TRCK ;TRACK # STA (BPNT),Y JSR STKP ;SAVE TRACK POINTER IN SKTAB JSR IBPNT ;INC BASE LDA #0 ;SIDE # STA (BPNT),Y JSR IBPNT ;INC BASE LDX SECT ;SECTOR # LDA SKTAB,X ;GET SECTOR FROM SKEW STA (BPNT),Y JSR IBPNT ;INC BASE LDA #0 ;SECTOR LENGTH = 128 STA (BPNT),Y JSR IBPNT ;INC BASE LDA #$F7 ;FOR 2 BYTE CRC STA (BPNT),Y JSR IBPNT ;INC BASE LDX #17 ;11 BYTES LDA #0 ;LOAD $FF SHDR3 DEX STA (BPNT),Y JSR IBPNT ;INC BASE CPX #0 BNE SHDR3 LDA #$FB STA (BPNT),Y JSR IBPNT ;INC BASE LDX #128 LDA #$FF SDATA DEX STA (BPNT),Y JSR IBPNT ;INC BASE CPX #0 BNE SDATA LDA #$F7 STA (BPNT),Y JSR IBPNT ;INC BASE LDX #12 LDA #0 SECEND DEX STA (BPNT),Y JSR IBPNT ;INC BASE CPX #0 BNE SECEND INC SECT LDA SECT ;INCREMENT SECTOR INDEX CMP #18 ;DONE WITH ALL 18 SECTORS? BEQ ITRKXT ;YES, NOW PAD TRACK JMP SHDR1 ITRKXT RTS ;DONE WITH TRACK IMAGE! ; ;************************************** ; ; STKP: SAVE POINTER TO TRACK NUMBER ; ; ENTRY:SECT=CURRENT SECTOR INDEX ; EXIT:POINTER IN SKTAB ; ; SAVE X,Y AND A REGISTERS ; ;************************************** ; STKP PROC ; PHA ;SAVE ACC TXA ;SAVE X REG PHA LDA SECT ;GET SECTOR INDEX ASL A ;MULTIPLY BY 2 TAX ;MOVE TO INDEX REGISTER LDA BPNT STA TNPNT,X ;STORE IN TRACK NUMBER INX LDA BPNT+1 STA TNPNT,X ;POINTER AREA PLA ;GET X REG TAX PLA ;GET ACC RTS ; ;************************************** ; ; CTS: CHECK TRACK/SECTOR STATUS ; ; ENTRY:ACC = SECTOR ; :NTRK = TRACK ; EXIT:LENTH APROPRIATLY SET ; ; SAVE ACC,X,Y ; ;************************************** ; CTS PROC ; PHA ;SAVE ACCUMULATOR LDA CONFIG+7 ;SET LENTH STA LENTH LDA NTRK ;CHECK TRACK NUMBER BNE :EXIT ;NOT ZERO JUST EXIT PLA ;GET SECTOR NUMBER CMP #4 ;CHECK FOR LESS THAT 4 BCS :EXIT1 PHA ;SAVE SECTOR NUMBER AGAIN LDA #$80 ;SET LENTH TO 128 STA LENTH :EXIT PLA ;GET ACC BACK :EXIT1 RTS EPROC ; LINK D2:DD15M5.ASM