; ;************************************** ; ; THIS IS WHERE WE ENTER WHEN PROCESSOR ; IS RESET. ; PERIPHERAL DEVICES ARE INITIALIZED ; MEMORY IS CLEARED ; BACKGROUND PROCESSING, IF ANY IS ; STARTED ; ;************************************** ; ; START LDX #$FF TXS ;SET THE STACK POINTER TO ;TOP OF STACK JSR CLRMEM ;CLEAR MEMORY JSR CLRZER ;CLEAR PAGE ZERO ; LDA #$4C ;LOAD JUMP INSTRUCTION STA GET STA PUT LDA SGVEC ;SET UP SLOW GET VECTOR STA GET+1 LDA SGVEC+1 STA GET+2 LDA SPVEC ;SET UP SLOW PUT VECTOR STA PUT+1 LDA SPVEC+1 STA PUT+2 LDA #0 STA DCKFLG ;CHECK TRACK DENSITY STA CMDRT ;SET COMMAND RETRYS TO 0 LDA #$FF STA SSTAT ;SPEED STAT AT NORMAL ; LDA #$FF STA FDCFLG ;HAVE NOT FOUND FDC TYPE LDA #$82 ;READ SECTOR FOR 1793 STA RSECCM LDA #$A2 ;WRITE SECTOR FOR 1793 STA WSECCM LDA #$A3 ;WRITE SECTOR WITH DM 1793 STA WSDMCM ; LDA #108 ;INITIAL STEP RATE STA SRATE ; LDA #LOW CMDNAK ;INIT USER COMMAND STA CSELXX ;DECODE VECTOR TO COMAND LDA #HIGH CMDNAK ;NAK STA CSELXX+1 LDA #$FF STA TINB LDA #$10 ;MAX OF 16 SEC TIMEOUT STA STAT+2 LDA #$10 STA STAT ;TELL THE WORLD WE ARE HERE ; LDA #$3C ;SET PORT A FOR INPUT STA DDRA ;USER MAY IF HE/SHE CHOOSES LDA #$3D STA DDRB LDA #%00111101 STA STPPOS STA DRB LDA #$FF STA DRA LDA #$FF STA TFLAG ;PUT IN UNBUFFER MODE ; LDA #40 ;DRIVE CONFIG INITIAL (STDRD) STA CONFIG ;40 TRACKS PER SIDE LDA #18 STA CONFIG+3 ;18 SECTORS PER TRACK LDA #128 STA CONFIG+7 STA LENTH ;SECTOR LENGTH LDA #$40 STA CONFIG+8 ; LDA #10 STA TL ;INIT MOTOR HANGON TIME 1 SEC ; CLD ;CLEAR DECIMAL MODE JSR MCK ;TURN ON MOTOR JSR TRK0 ;SEEK TRACK 0 LDA #15 STA NTRK JSR SKTK ;SEEK TRACK 15 JSR TRK0 ;SEEK TRACK 0 ; ; CHECK TO SEE IF THERE IS A DISK IN ; THE DRIVE ; BIT STREG ;CHECK FDC STATUS BMI STRT01 ;DOOR OPEN JSR CSSK ;CHECK TO SEE WHAT FORMAT ; ; STRT01 JSR I5SEC ;INIT 5 SECOND TIMER ; BKGRND PROC ; :STATUS = $A0 ; LDA #2 ;BIT MASK BIT DRB ;TEST CMD LINE BPL BK001 ;CMD NOT HIGH BNE BK004 ;COMPUTER NOT ON JSR RCMDFRM ;GET COMMAND FRAME ; ;ON RETURN, DO A COMPLETE RE-INIT OF ;THE TIMER IF STATUS = 0 ; LDA :STATUS ;CHECK STATUS BNE BK003 JSR I5SEC ;RE INIT 5 SEC TIMER JMP BK001 BK003 LDA #97 ;.1 SEC INTERVAL JSR STMO ;SET TIMER JMP BK001 ; BK004 LDA SGVEC ;SET UP SLOW VECTOR STA GET+1 LDA SGVEC+1 STA GET+2 LDA SPVEC STA PUT+1 LDA SPVEC+1 STA PUT+2 ; ;CONTINUE COUNTDOWN ; BK001 JSR DRCHK ;CHECK DOOR STATUS LDA MFLAG BEQ BKGRND JSR CK5S ;CHECK 5 SECOND TIMER BCC BK002 JSR MOOFF ;TURN OFF MOTOT LDA WT64D LDA #$00 STA MFLAG BK002 JMP BKGRND ;JUMP TO BACKGROUND ;ROUTINE EPROC ; ; ;************************************** ; ; DRCHK: CHECK DOOR STATUS ; ; ENTRY: NONE ; EXIT: NONE ; REGISTERS USED: ACCUMULATOR ; ;************************************** DRCHK BIT STREG BPL DRCHK1 ;DOOR CLOSED BIT DRCLSD BPL DRCKXT ;STILL OPEN, EXIT LDA #0 ;JUST OPENED STA DRCLSD JMP DRCKXT DRCHK1 BIT DRCLSD BMI DRCKXT ;STILL CLOSED, EXIT LDA #$FF ;JUST CLOSED STA DRCLSD JSR MCK ;TURN ON MOTOR JSR CSSK ;CHECK THE FORMAT JSR I5SEC DRCKXT RTS ;************************************** ; ; DELAY: ABOUT 250USEC ; ;************************************** ; DELAY PHA ;SAVE ACCUMULATOR LDA #42 DEL01 SEC SBC #$01 ;DECREMANT ACC BNE DEL01 PLA RTS ; ;************************************** ; ; BTOG: BUAD RATE TOGGLE ; ; ENTRY:NONE ; EXIT:NONE ; BUAD RATE IS TOGGLED ; ;************************************** ; BTOG PROC ; LDA SSTAT ;LOAD SPEED STATUS BNE :BTG01 LDA SGVEC ;SET UP SLOW GET VECTOR STA GET+1 LDA SGVEC+1 STA GET+2 LDA SPVEC ;SET UP SLOW PUT VECTOR STA PUT+1 LDA SPVEC+1 STA PUT+2 LDA #$FF STA SSTAT ;SPEED STAT AT NORMAL BNE :BTGXT ; :BTG01 LDA FGVEC ;SET UP US GET VECTOR STA GET+1 LDA FGVEC+1 STA GET+2 LDA FPVEC ;SET UP US PUT VECTOR STA PUT+1 LDA FPVEC+1 STA PUT+2 LDA #$0 STA SSTAT ;SPEED STAT AT US :BTGXT RTS ; ; ;************************************** ; ; SGET: GET SLOW DATA FROM SERIAL BUS ; ; ENTRY:A-REG =# OF BYTES TO GET ; :BPNT CONTAIN ADDRESS OF BUFFER ; EXIT:DATA IN BUFFER ; :$A0 CONTAINS STAUTUS ; :$A1 CONTAINS CHECKSUM ; ; REGISTERS USED:ACCUMULATOR,X,Y ; :USES BPNT ;************************************** ; SGET PROC ; :STATUS = $A0 :CKSUM = $A1 ; STA GCNT ;SAVE BYTE COUNT LDY #$00 STY FLAG ;INIT CHECKSUM FLAG :GET01 BIT DRA ;CHECK FOR TIME OUT BVC DITOUT BIT DRB ;WAIT FOR START BIT BVC :GET01 ;LOOP IF NO OVERFLOW SEC ;SET CARRY LDA #$80 ;A := $80 LDX #$06 ; :GET02 DEX ; BNE :GET02 ;DELAY LOOP LB80 LDX #$06 ; :GET03 DEX ; BNE :GET03 ;DELAY LOOP NOP NOP NOP ;TIMING BIT DRB BVC :GET04 ;JMP AND SET CARRY CLC BCC :GET05 ;JMP WITH CARRY CLEAR :GET04 SEC NOP :GET05 ROR A BCC LB80 LDX FLAG BNE :GETXIT STA (BPNT),Y INY CPY GCNT ;DECREMENT BYTE COUNT BNE :GET01 ;KEEP GOING, MORE DATA LDX #$FF STX FLAG ;NOW WE GET THE CHECKSUM BNE :GET01 :GETXIT STA :CKSUM ;SAVE CHECKSUM LDA #0 STA :STATUS LDA WT64D :GETXT RTS ; ;DO THIS IF THERE IS A TIMEOUT ; DITOUT LDA #$01 STA :STATUS ;TIMEOUT STATUS RETURNED LDA WT64D JMP :GETXT EPROC; SGVEC DW SGET ; ; ;************************************** ; ; SPUT: ; SEND THE BYTE IN THE ACCUMULATOR ; TO THE ATARI COMPUTER SLOWLY ; ; ENTRY:A<-- BYTE TO SEND ; EXIT: NONE ; ; REGISTERS USED:ALL PRESERVED ; ; ;************************************** ; ; SPUT PROC ; :DATA = $A0 ;DATA TO TRANSMIT :SAVEX = $A1 ;SAVE AREA FOR X REG :SAVEY = $A2 ;SAVE AREA FOR Y REG ; STA :DATA STY :SAVEY STX :SAVEX LDY #$08 LDA #$FE AND DRB STA DRB INC :SAVEX PUT93 ROR :DATA BCC PUT90 LDA #$01 ORA DRB BNE PUT91 PUT90 LDA #$FE AND DRB NOP PUT91 LDX #$05 PUT92 DEX BNE PUT92 STA DRB DEY BNE PUT93 LDX #$06 PUT94 DEX BNE PUT94 NOP DEC :SAVEX LDA #$01 ORA DRB STA DRB LDX #$05 PUT95 DEX BNE PUT95 LDX :SAVEX LDA :DATA LDY :SAVEY RTS EPROC SPVEC DW SPUT ; ;************************************** ; ; SET TIME OUT: ; ;************************************** ; STMO STA WT64D STA WT24E RTS ; ;************************************** ; ; ACK: ; SEND ACKNOLEGDE BACK TO ATARI ; ; ENTRY:NONE ; EXIT:NONE ; ; REGISTERS USED: ; ACCUMULATOR ; ;************************************** ; ACK LDA #'A' ;LOAD ACK CODE JSR PUT ;SEND IT TO THE ATARI RTS ; ;************************************** ; ; NAK: ; SEND NOT ACKNOLEGED BACK TO ATARI ; ; ENTRY:NONE ; EXIT:NONE ; ; REGISTERS USED: ; ACCUMULATOR ; ;************************************** ; NAK LDA #'N' ;LOAD NAK CODE JSR PUT ;SEND IT TO THE ARARI RTS ; ;************************************** ; ; ERR: ; SEND ERROR BACK TO ATARI ; ; ENTRY:NONE ; EXIT:NONE ; ; REGISTERS USED:A ; ;************************************** ; ERR LDA #'E' ;LOAD ERROR CODE JSR PUT ;SEND IT TO THE ARARI RTS ; ;************************************** ; ; CMPLT: ; SEND PROCESS COMPLETE CODE ; ; ENTRY: NONE ; EXIT: NONE ; ; REGISTERS USED:A ; ;************************************** ; CMPLT LDA #'C' ;LOAD COMPLETE CODE JSR PUT ;SEND IT TO THE ATARI RTS ; ; ;************************************** ; ; CSUM: ; COMPUTE THE CHECKSUM ; ; ENTRY:A CONTAINS VALUE TO ADD TO CSUM ; EXIT:NONE ; ;************************************** ; CSUM PHA ;SAVE ACCUMULATOR CLC ;PREPARE TO ADD ADC CHKSUM ADC #$00 STA CHKSUM PLA ;RECOVER ORIGINAL VALUE RTS ; ;************************************** ; ; CKSM: ; ; COMPUTE THE CHECKSUM ATARI STYLE ; ; ENTRY:X REG NUMBER OF VALUES TO CHK ; :BPNT=ADDRESS OF STRING ; :CHKSUM IS IN REG A ; EXIT:CARRY SET IF BAD CHECKSUM ; ; REGISTERS USED:A,X,Y ; ; MEMORY USE: ; ONE BYTE ON PAGE ZERO ; CHKSUM ; ;************************************** ; CKSM PROC ; :CHKSM = $A0 ; STA :CHKSM ;SAVE CHECKSUM STX GCNT ;SET UP LOOP COUNTER LDY #$00 ;ZERO INDEX TYA ;ZERO ACCUMULATOR CKSM01 CLC ADC (BPNT),Y;SUM WITH CHECKSUM ADC #$00 ;ADD CARRY IF ANY INY CPY GCNT ;END OF STRING? BNE CKSM01 SEC SBC :CHKSM ;EQUAL TO CHECKSUM? STA :CHKSM ;RETURN 0 IF EQUAL BEQ :EXIT LDA #$02 STA :CHKSM ;BAD CHECKSUM :EXIT RTS EPROC ; ;************************************** ; ; CLRMEM: ; CLEAR MEMORY PAGES 2 TO $0F ; ; ENTRY:NONE ; EXIT:PAGES 2 TO 15 FILLED WITH $00 ; ; REGISTERS USED:A,X,Y ; ; MEMORY USED:2 BYTES PAGE ZERO ; ;************************************** ; CLRMEM LDA #HIGH BUFF ;ON PAGE ZERO TO POINT STA BPNT+1 ;TO MEMORY TO CLEAR LDA #LOW BUFF ;CLEAR ACCUM STA BPNT ;SET UP INDIRECT POINTER ; LDY #$00 ;INIT INDEX REGISTER CLMEM1 STA (BPNT),Y INY ;POINT TO NEXT BYTE BNE CLMEM1 INC BPNT+1 ;INC MEMORY POINTER LDX BPNT+1 CPX #$40 ;END OF MEMORY TO CLEAR (2K) BNE CLMEM1 ;CONTINUE UNTILL DONE RTS ; ;HIGH SPEED TRANSFER ROUTINES ; ;************************************** ; ; FGET: GET FAST DATA FROM SERIAL BUS ; ; ENTRY:A-REG =# OF BYTES TO GET ; :BPNT CONTAIN ADDRESS OF BUFFER ; EXIT:DATA IN BUFFER ; :$A0 CONTAINS STAUTUS ; :$A1 CONTAINS CHECKSUM ; ; REGISTERS USED:ACCUMULATOR,X,Y ; :USES BPNT ;************************************** ; FGET PROC ; :STATUS = $A0 :CKSUM = $A1 :DUMMY = $A8 ; STA GCNT ;SAVE BYTE COUNT TAX LDY #$00 :FGET1 BIT DRA ;4 CHECK FOR TIME OUT BVC :TOUT ;2 :FGET2 BIT DRB ;4 WAIT FOR START BIT BVC :FGET2 ;2 LOOP IF NO OVERFLOW SEC ;2 SET CARRY LDA #$80 ;2 A := $80 NOP ;2 NOP ;2 NOP ;2 NOP ;2 STX :DUMMY ;3 ; :LOOP STX :DUMMY ;3 BIT DRB ;4 BVC :FGET4 ;JMP AND SET CARRY CLC BCC :FGET5 ;JMP WITH CARRY CLEAR :FGET4 SEC NOP :FGET5 ROR A BCC :LOOP STA (BPNT),Y ;STORE RECIEVED DATA INY DEX BEQ :FGET9 ;END OF GET JMP :FGET2 ;KEEP GOING, MORE DATA ; ;GET CHECKSUM ; :FGET6 BIT DRA ;4 CHECK FOR TIME OUT BVC :TOUT ;2 :FGET9 BIT DRB ;4 WAIT FOR START BIT BVC :FGET9 ;2 LOOP IF NO OVERFLOW SEC ;2 SET CARRY LDA #$80 ;2 A := $80 NOP ;2 NOP ;2 NOP ;2 NOP ;2 STX :DUMMY ;3 ; :LOOP1 STX :DUMMY ;3 BIT DRB ;4 BVC :FGET7 ;JMP AND SET CARRY CLC BCC :FGET8 ;JMP WITH CARRY CLEAR :FGET7 SEC NOP :FGET8 ROR A BCC :LOOP1 ; STA :CKSUM ;SAVE CHECKSUM LDA #0 STA :STATUS LDA WT64D :GETXT RTS ; ;DO THIS IF THERE IS A TIMEOUT ; :TOUT LDA #$01 STA :STATUS ;TIMEOUT STATUS RETURNED LDA WT64D JMP :GETXT EPROC; FGVEC DW FGET ; ; ;************************************** ; ; FPUT: ; SEND THE BYTE IN THE ACCUMULATOR ; TO THE ATARI COMPUTER SLOWLY ; ; ENTRY:A<-- BYTE TO SEND ; EXIT: NONE ; ; REGISTERS USED:ALL PRESERVED ; ; ;************************************** ; ; FPUT PROC ; :DATA = $A0 ;DATA TO TRANSMIT :SAVEX = $A1 ;SAVE AREA FOR X REG :SAVEY = $A2 ;SAVE AREA FOR Y REG :DUMMY = $A8 :; STA :DATA ;STORE DATA STY :SAVEY LDY #$08 LDA #$FE AND DRB STA DRB ;SET DATA BIT LOW BIT :DUMMY NOP :FPUT3 LSR A LSR :DATA+$100 ROL A ;PUT DATA BIT INTO D0 POSITION STA DRB DEY BNE :FPUT3 ;LOOP UNTIL OUT OF DATA ; LSR A SEC ROL A ;MAKE DATA BIT =1 NOP BIT :DUMMY STA DRB LDY :SAVEY RTS EPROC FPVEC DW FPUT ; ; ;************************************** ; ; CLRZER: ; CLEAR PAGE ZERO ; ; ENTRY:NONE ; EXIT: PAGE ZERO FILLED WITH $00 ; ; REGISTERS USED :A,X ; ;************************************** ; CLRZER LDA #$00 ;SET UP TO CLEAR MEM TAX ;INIT INDEX REGISTER CLZER1 STA ZERO,X ;CLEAR MEMORY BYTE INX CPX #$80 BNE CLZER1 ;CONTINUE TILL DONE RTS ; ;************************************** ; ; SDSTAT: ; SEND STATUS TO THE ATARI COMPT ; ; ENTRY:NONE ; EXIT: STATUS SENT TO ATARI ; ; REGISTERS USED:A,X ; ; MEMORY USED:SENDS STATUS BLOCK FROM ; PAGE ZERO SEE ABOVE ; ; FORMAT OF STATUS ARRAY: ; BYTE 0:COMMAND STATUS ; BYTE 1:HARDWARE STATUS ; BYTE 2:TIMEOUT ; BYTE 3:UNUSED ; ; COMMAND STATUS: ; BIT0=1 INDICATES INVALID CMD FRM REC ; BIT1=1 IND. INVALID DATA FRAME REC. ; BIT2=1 IND. PUT WAS UNSUCCESSFUL ; BIT3=1 IND. DISKET IS WRITE PROTECTED ; BIT4=1 IND ACTIVE STANDBY ; BIT5=1 IND DOUBLE DENSITY ; ; BIT7=1 IND DUAL DENSITY ; ; HARWARE STATUS = STAT REG OF 1793 ; ; TIME OUT = MAX TIME HANDLER TO USE ; ; ;************************************** ; SDSTAT LDA #$00 ;INITIALIZE CHECKSUM STA CHKSUM TAX ;INIT INDEX REGISTER SSTAT1 LDA STAT,X ;LOAD BYTE FROM ;STATUS ARRAY JSR CSUM ;CALCULATE CHECKSUM FOR XMIT JSR PUT ;SEND IT TO ATARI INX CPX #$04 ;SENT ALL FOUR BYTES? BNE SSTAT1 ; LDA CHKSUM ;LOAD CHECK SUM JSR PUT ;SEND IT TO ATARI TOO RTS ;RETURN ; ; ;************************************** ; ; READ: ; FILLS BUFFER ON PAGE TWO WITH ; 256 BYTES OF DATA SENT BY ; ATARI ; ; ENTRY:ACC=LENTH (0=256 BYTES) ; :BPNT= BUFFER AREA TO PUT DATA ; EXIT: BUFFER FILLED WITH DATA ; : $A0 STATUS OF OPERATION ; : 0=OK ; : 1=TIMEOUT ; : 2=CHECKSUM ERROR ; ; REGISTERS USED:A,X,Y ; ; MEMORY USED:PAGE 2 ; ;************************************** ; READ PROC :CHKS = $A1 ;CHECKSUM RETURNED FROM GET :STATUS = $A0 ;STATUS RETURNED BY GET :LEN = $A2 ;LENTH OF BUFFER TO SEND ; STA :LEN JSR GET ;GET DATA FROM SIO BUS LDA :STATUS ;CHECK STATUS BNE :RDXIT LDA :CHKS LDX :LEN ;CHECK LEN BYTES JSR CKSM :RDXIT RTS EPROC ; ; ;************************************** ; ; SEND: ; SEND DATA IN PAGE 2 BUFFER BACK ; TO THE ATARI COMPUTER ; ; ENTRY:BPNT POINTS TO DATA TO SEND ; EXIT :DATA SENT TO ATARI ; ; REGISTERS USED:A,Y ; ; MEMORY USED:PAGE 2 AS MEMORY BUFFER ; :$A4 ;************************************** ; SEND PROC ; :LEN = $A4 STA :LEN LDA #$00 ;INITIALIZE CHECKSUM STA CHKSUM TAY ;INITIALIZE INDEX REGISTER :SEND1 LDA (BPNT),Y ;LOAD DAT FROM BUFF JSR CSUM ;CALCULATE CHECK SUM JSR PUT ;SEND DATA TO ATARI INY ;NEXT MEMORY LOCATION TO SEND CPY :LEN ;COMPARE TO LENTH TO SEND BNE :SEND1 ;SENT ALL 256 BYTES? ; LDA CHKSUM ;LOAD CHECKSUM JSR PUT ;AND SEND IT ON ITS WAY RTS ;DONE EPROC ; LINK D2:DD15M2.ASM