; ;************************************** ; ; SRT: SPECIAL READ TRACK ROUTINE ; ; USES SECTOR SKEW TABLE TO READ IN ; SECTORS FROM THE DISK. ; ALLOWS USER TO READ TRACKS THAT HAVE ; A DOUBLE SECTOR ON THEM. ; THE FIRST SECTOR IN THE TABLE SHOULD ; NOT BE A DOUBLE SECTOR ; ;************************************** ; SRT PROC ; :STATUS = $A0 :COUNT = $A1 :SERR = $3F00 ;SPECIAL ERROR AREA ; ;SET UP BUFFER POINTER ; LDA #$00 STA BPNT LDA #$20 STA BPNT+1 JSR FINT ;CLEAR OUT ANY OLD COMMANDS LDA #$FF STA TINB ;CLEAR BUFFER FLAG LDA CMDFRM+2 ;GET AUX 1 STA NTRK JSR SKTK ;GOTO THAT TRACK ; ;ZERO SPECIAL ERROR AREA ; LDA #$00 LDX #0 :SRT01 STA :SERR,X INX BNE :SRT01 ; LDA #128 STA LENTH ;SET LENTH TO 128 BYTES LDA #$00 STA :COUNT ;SECTOR COUNT :LOOP LDX :COUNT LDA SKTAB,X ;GET FIRST SECTOR BEQ :SRT02 ;EXIT LOOP IF SECTOR=0 LDY DTAREG ;DUMMY READ JSR RSEC LDX :COUNT LDA STAT+1 ;GET FDC STATUS STA :SERR,X LDA #$80 CLC ADC BPNT ;INCREMENT BUFFER POINTER STA BPNT LDA #0 ADC BPNT+1 STA BPNT+1 INC :COUNT INX CPX #26 ;TWENTY SIX SECTORS, NO WAY BNE :LOOP LDA #$01 STA :STATUS JMP :SRTXT :SRT02 LDA #0 STA :STATUS :SRTXT RTS ; EPROC ; ; ;************************************** ; ; SPWT: SPECIAL WRITE TRACK ROUTINE ; ;************************************** ; SPWT PROC ; :STATUS = $A0 :COUNT = $A1 :SERR = $3F00 ;SPECIAL ERROR AREA ; ;SET UP BUFFER POINTER ; LDA #$00 STA BPNT LDA #$20 STA BPNT+1 JSR FINT ;CLEAR OUT ANY OLD COMMANDS LDA #$FF STA TINB ;CLEAR BUFFER FLAG LDA CMDFRM+2 ;GET AUX 1 STA NTRK JSR SKTK ;GOTO THAT TRACK ; ; LDA #128 STA LENTH ;SET LENTH TO 128 BYTES LDA #$00 STA :COUNT ;SECTOR COUNT ; ;FIRST HALF OF TRACK WRITE ; :LOOP LDX :COUNT LDA :SERR,X ;CHECK THE TYPE OF ERROR EOR #$FF STA TEMP ;PUT STATUS IN TEMP PLACE AND #$08 ;CHECK FOR CRC ERROR BEQ :SWT05 ; LDA SKTAB,X BEQ :SWT02 ;END OF TABLE LDY DTAREG ;DUMMY READ JSR CRC ;WRITE CRC ERROR TO DISK JMP :SWT04 ; :SWT05 LDA TEMP AND #$20 ;CHECK FOR DELTED DATA MARK BEQ :SWT03 LDA SKTAB,X ;GET FIRST SECTOR BEQ :SWT02 ;EXIT LOOP IF SECTOR=0 LDY DTAREG ;DUMMY READ JSR SWS JMP :SWT04 ; :SWT03 LDA SKTAB,X ;GET FIRST SECTOR BEQ :SWT02 ;EXIT LOOP IF SECTOR=0 LDY DTAREG ;DUMMY READ JSR WSEC ; :SWT04 BCC :SWT14 ;STATUS OK LDA #$01 STA :STATUS JMP :SWTXT ;BARF ; :SWT14 CLC LDA #$01 ADC BPNT+1 STA BPNT+1 INC :COUNT INC :COUNT JSR DELAY ;MAKE SURE WE MISS NEXT LDX :COUNT CPX #26 ;TWENTY SIX SECTORS, NO WAY BNE :LOOP ; ;SECOND HALF OF TRACK WRITE ; :SWT02 LDA #$20 STA BPNT+1 LDA #$80 STA BPNT LDA #$01 STA :COUNT ;SECTOR COUNT ; :LOOP1 LDX :COUNT LDA :SERR,X ;CHECK THE TYPE OF ERROR EOR #$FF STA TEMP ;PUT STATUS IN TEMP PLACE AND #$08 ;CHECK FOR CRC ERROR BEQ :SWT06 ; LDA SKTAB,X BEQ :SWT09 ;END OF TABLE LDY DTAREG ;DUMMY READ JSR CRC ;WRITE CRC ERROR TO DISK JMP :SWT08 ; :SWT06 LDA TEMP AND #$20 ;CHECK FOR DELTED DATA MARK BEQ :SWT07 LDA SKTAB,X ;GET FIRST SECTOR BEQ :SWT09 ;EXIT LOOP1 IF SECTOR=0 LDY DTAREG ;DUMMY READ JSR SWS JMP :SWT08 ; :SWT07 LDA SKTAB,X ;GET FIRST SECTOR BEQ :SWT09 ;EXIT LOOP1 IF SECTOR=0 LDY DTAREG ;DUMMY READ JSR WSEC ; :SWT08 BCC :SWT18 ;STATUS OK LDA #$01 STA :STATUS JMP :SWTXT ;BARF ; :SWT18 CLC LDA #$01 ADC BPNT+1 STA BPNT+1 INC :COUNT INC :COUNT JSR DELAY ;MAKE SURE WE MISS NEXT LDX :COUNT CPX #26 ;TWENTY SIX SECTORS, NO WAY BNE :LOOP1 ; LDA #$01 STA :STATUS JMP :SWTXT :SWT09 LDA #0 STA :STATUS :SWTXT RTS ; EPROC RTS ; ;************************************** ; ; CRC: PUTS A CRC ERROR ON THE DISK ; : WHERE WE WANT IT WITH THE DATA ; : THAT WE WANT WE HOPE ; ENTRY:BPNT POINTS TO DATA TO WRITE ; :ACC HOLDS SECTOR NUMBER ; :X REG HOLD CURRENT BLOCK NUM ; EXIT:$A0 HOLDS STATUS ; ;************************************** ; CRC PROC ; :STATUS = $A0 :LEN = $A1 ; STA SECREG LDA TRACK STA TRKREG ;SET UP SECTOR TO WRITE TO :WCE01 LDY #$00 LDX #$00 LDA #$E6 JSR STMO LDA #$20 ;DELETED DATA MARK MASK AND TEMP BEQ :WCE12 LDA WSDMCM ;WRITE SECTOR COMMAND ;DELEATED DATA MARK BNE :WCE22 :WCE12 LDA WSECCM ;NORMAL WRITE SECTOR :WCE22 STA CMDREG :WCE02 LDA (BPNT),Y EOR #$FF ;LOAD AND COMPLEMENT DATA :WCE03 BIT DRA ;CHECK FOR WHEN FDC REDY BVC :WCE10 ;TIME OUT ERROR BPL :WCE03 ;LOOP UNTIL READY STA DTAREG ;SEND DATA TO FDC 4 LDA WT64D ;4 INY ;2 CPY LENTH ;COMPARE WITH SECTOR :LEN 3 BNE :WCE02 ;2 JSR FINT ;STOP WRITE NOW! LDA #$01 :WCE04 BIT STREG BNE :WCE04 ;LOOP UNTIL DONE LDA STREG LDA #0 STA :STATUS ;SET STATUS OK! CLC RTS :WCE10 LDA STREG AND #$01 ;CHECK FOR BUSY BEQ :WCE20 LDA #$E6 JSR STMO BNE :WCE02 :WCE20 LDA WT64D LDA STREG AND #$04 ;CHECK FOR LOST DATA BNE :WCE01 LDA STREG LDA #$01 STA :STATUS ;SET STATUS YUCKY! SEC RTS EPROC ; ;************************************** ; ; REVT:WAIT FOR ONE DISK REVOLUTION ; ;************************************** ; REVT PROC ; LDA #$C6 ;A LITTLE LESS THAN ONE REV JSR STMO :LOOP BIT DRA ;WAIT FOR INTERRUPT BVS :LOOP RTS EPROC ; ; ;************************************** ; ; CKBF: CHECK SECTOR BUFFER FOR GARBAGE ; ; ENTRY:ACC=TRACK ; :X=LSB OF POINTER TO BUFFER ; :Y=MSB OF POINTER TO BUFFER ; EXIT:$A0 NUMBER OF SECTORS FOUND ; ;************************************** ; CKBF PROC ; ;LOCAL VARIABLES ; :STATUS = $A0 :TRACK = $2800 :TDPNT = $2801 ;POINTER TO TRACK INFO ;2 BYTES :INDX = $2803 :ADAT = $2804 :JNDX = $2805 :COUNT = $2806 :SECTOR = $2807 :FSTAT = $2817 :K = $2818 ; STA :TRACK STX :TDPNT STY :TDPNT+1 LDY #0 STY :COUNT STY :INDX STY :K :LOOP0 LDA :TDPNT ;SET PNTER TO TDPNT STA BPNT1 LDA :TDPNT+1 STA BPNT1+1 LDY :INDX LDA (BPNT1),Y ;LOAD TRACK DATA STA :ADAT CLC LDA #2 ADC :INDX TAY LDA (BPNT1),Y STA :SECTOR LDA #6 ;FDC STATUS CLC ADC :INDX TAY LDA (BPNT1),Y AND #%00011000 STA :FSTAT ; LDA :ADAT CMP :TRACK ;ADAT<>TRACK? BNE :CK001 ; LDA :FSTAT BNE :CK001 ;BAD FDC STATUS ; LDA :SECTOR BEQ :CK001 ;SECTOR=0 CMP #19 ;SECTOR >= 19? BCC :CK002 ; :CK001 LDA :INDX LDX :TDPNT LDY :TDPNT+1 JSR DLNTRY ;DELETE BAD ENTRY INC :K ;INCREMENT MAX DELETE COUNT LDA :K CMP #32 BEQ :CK004 ;EXIT WHEN EQUAL JMP :CK003 ; :CK002 INC :COUNT ;COUNT==+1 INC :INDX ;INDX==+1 LDA #$00 STA :JNDX ; :LOOP1 LDY :INDX LDA :ADAT ORA (BPNT1),Y STA :ADAT INC :INDX INC :JNDX LDX :JNDX CPX #7 BNE :LOOP1 LDA :ADAT CMP #0 ;END OF SECTOR DATA? BEQ :CK004 ; :CK003 LDA :INDX CMP #240 BCS :CK004 JMP :LOOP0 :CK004 LDA :COUNT STA :STATUS RTS EPROC ; ;************************************* ; ; DLNTRY: DELETE ENTRY IN TRACK DATA ; ; ENTRY:ACC=INDEX OF ENTRY TO DELETE ; :X=LSB OF BUFFER ; :Y=MSB OF BUFFER ; EXIT:NONE ; ;************************************* ; DLNTRY PROC ; :INDX = $2808 :TDPNT = $2809 ;POINTER 2 BYTES :JNDX = $280B ; STA :INDX STX :TDPNT STY :TDPNT+1 ; CLC LDA :INDX ADC #$08 STA :JNDX LDA :TDPNT STA BPNT1 LDA :TDPNT+1 STA BPNT1+1 :LOOP0 LDY :JNDX LDA (BPNT1),Y LDY :INDX STA (BPNT1),Y INC :INDX INC :JNDX BNE :LOOP0 RTS EPROC ; ;************************************* ; ; RTAT: MOVES ENTRYS AROUND ; ; ENTRY:ACC=LSB OF BUFFER POINTER ; :X=MSB OF BUFFER POINTER ; :Y=NUMBER OF ENTRY TO MOVE ; EXIT:NONE ; ;************************************* ; RTAT PROC ; :DPNT = $A0 :ENT1 = $A2 :INDX = $A3 :JNDX = $A4 :CNT = $A5 ; STA :DPNT STX :DPNT+1 STY :ENT1 ; LDY #0 ;SAVE FIRST ENTRY ON STACK :LOOP LDA (:DPNT),Y PHA ;SAVE DATA INY CPY #8 BNE :LOOP ; LDA #0 STA :INDX ;DESTINATION INDEX LDA #8 STA :JNDX ;SOURCE INDEX LDA :ENT1 ASL A ASL A ASL A ;MULT TIME 8 STA :CNT ; :LOOP1 LDY :JNDX LDA (:DPNT),Y LDY :INDX STA (:DPNT),Y INC :INDX INC :JNDX LDA :JNDX CMP :CNT BNE :LOOP1 ; LDX #0 :LOOP2 DEC :JNDX LDY :JNDX PLA STA (:DPNT),Y INX CPX #8 BNE :LOOP2 RTS EPROC ; ;************************************** ; ; CMP: COMPARE TWO BUFFERS OF DATA FOR ; EQUIVELENT SECTOR DATA ; ; ENTRY:ACC=LSB OF POINTER TO BUFF1 ; :X = MSB OF POINTER TO BUFF1 ; :Y = LSB OF POINTER TO BUFF2 ; :$A3=MSB OF POINTER TO BUFF2 ; :$A4=NUMBER OF SECTORS ; EXIT:$A0=0 IF GOOD, 1 IF BAD ; ;************************************** ; CMP PROC ; ;LOCAL VARIABLES ; :STATUS = $A0 :PARM1 = $A3 :PARM2 = $A4 :PNT1 = $280E ;POINTER TO BUFF1 DATA :PNT2 = $2810 ;POINTER TO BUFF2 DATA :NUMS = $2812 ;NUMBER OF SECTORS :TRYS = $2813 ;NUMBER OF TIMES :INDX = $2814 :ADAT = $2815 :BDAT = $2816 ; :TPNT1 = $A0 ;TEMPORARY POINTER REGS :TPNT2 = $A2 ; ;MAKE THE FIRST SECTOR IN EACH BUFFER ;THE SAME ; ;SAVE PASSED PARAMETERS ; STA :PNT1 STX :PNT1+1 STY :PNT2 LDA :PARM1 STA :PNT2+1 LDA :PARM2 STA :NUMS ; LDY #0 ;TRYS := 0 STY :TRYS ; :LOOP LDA :PNT1 STA :TPNT1 LDA :PNT1+1 STA :TPNT1+1 LDY #2 ;POINT TO SECTOR ADDRESS LDA (:TPNT1),Y STA :ADAT LDA :PNT2 STA :TPNT2 LDA :PNT2+1 STA :TPNT2+1 LDA (:TPNT2),Y STA :BDAT ; CMP :ADAT BEQ :CMP01 ;ENTRIES = COMPARE ARRAY ; ;ROTATE BUFF1 ; LDA :PNT1 LDX :PNT1+1 LDY :NUMS JSR RTAT INC :TRYS LDA :TRYS CMP :NUMS ;EXHASTED ALL POSIBILITIES? BNE :LOOP :CMP02 LDA #$01 STA :STATUS ;SEND BAD STATUS BACK JMP :CMPXT ; ;COMPARE ENTIRE BUFFER ; :CMP01 LDA :PNT1 ;SET UP POINTERS STA :TPNT1 LDA :PNT1+1 STA :TPNT1+1 LDA :PNT2 STA :TPNT2 LDA :PNT2+1 STA :TPNT2+1 ; LDA #0 STA :TRYS ;INIT LOOP COUNT LDA #2 STA :INDX :LOOP1 LDY :INDX LDA (:TPNT1),Y CMP (:TPNT2),Y BNE :CMP02 ;BAD DATA, BREAK FROM LOOP LDA :INDX CLC ADC #8 ;INDX ==+8 STA :INDX INC :TRYS LDA :TRYS CMP :NUMS ;END OF SEARCH? BNE :LOOP1 ;NO LDA #0 STA :STATUS ;GOOD SEARCH :CMPXT RTS EPROC ; ; ;************************************* ; ; FDCCK: CHECK FLOPPY DISK CONTROLLER ; TYPE ; ; ENTRY:ACC=TRACK TO CHECK ; EXIT:$A0=0 IF FDC CHECKED ; :$A0=1 IF ERROR ; :IF ERROR, FDC COMMANDS SET TO ; :1793 TYPE, ELSE SET TO TYPE ; :FOUND AND FOUND FLAG IS SET ; :TO FDC FOUND STATUS ; :$00=FOUND ; :$FF=NOT FOUND ; ; KILLS: X-REG, A-REG ; SAVES: $A1 CONTENTS ; ;************************************** ; FDCCK PROC ; :STATUS = $A0 :TRACK = $A1 ; TAX ;SAVE ACC LDA :TRACK PHA ;SAVE FOR EXIT STX :TRACK LDA FDCFLG ;CHECK FDC FLAG BNE :FD001 ;NO FOUND, CHECK IT OUT ; LDA #$00 ;ALREADY FOUND, EXIT STA :STATUS JMP :FDCXT ; ;TRY 1793 COMMAND FIRST ; :FD001 LDA :TRACK STA NTRK JSR SKTK ;SEEK TRACK ; LDA :C2793 STA RSECCM LDA #0 STA BPNT LDA #$20 STA BPNT+1 LDA #$01 ;SECTOR 1 JSR RSEC BCS :FD002 ;NO GOOD, TRY 1797 COMMAND ; ;COMMAND GOOD, SET FDC COMMANDS TO 2793 ; LDX #$00 :LOOP1 LDA :C2793,X STA RSECCM,X INX CPX #$03 BNE :LOOP1 LDA #$0 STA FDCFLG STA :STATUS JMP :FDCXT ;EXIT ROUTINE ; :FD002 LDA :C2797 ;LOAD COMMAND 1797 STA RSECCM LDA #$01 ;SECTOR 1 JSR RSEC ;READ SECTOR BCS :FD003 ;NOT THIS EITHER, BAD DISK? ; LDX #$00 :LOOP2 LDA :C2797,X STA RSECCM,X INX CPX #$03 BNE :LOOP2 LDA #$00 STA FDCFLG STA :STATUS JMP :FDCXT ; ;FDC NOT FOUND, SET TO 1793 FOR NOW ; :FD003 LDX #$00 :LOOP3 LDA :C2793,X STA RSECCM,X INX CPX #$03 BNE :LOOP3 LDA #$01 STA :STATUS :FDCXT PLA STA :TRACK RTS :C2793 DB $82,$A2,$A3 :C2797 DB $88,$A8,$A9 EPROC ; DB '2793/2797 VERSION' DB 'REV 3.10 ' DB '2-21-87 DB 'COPYRIGHT (C) 1986 BY EMC' DB 'COPYRIGHT (C) 1986 BY DTI' ; ORG $5FFC LOC $FFFC DW START ;RESET VECTOR DW START ;IRQ VECTOR ; END ;