;SAVE#D5:B>PARK.M65 ;ASM,,#d5:b>PARK.OBJ ;06/02/92 By: Robert Puff *= $5000 .OPT NO LIST RTS INIT JSR START LDA #$FF STA RAMPAGE JMP ($0A) ; DEVMSK = $0247 RAMPAGE = $D1BC PIAPORTB = $D1BE ;Zero-page equates ; SCSIID = $36 ZWTEMP1 = $32 ZPTMP1 = $31 ZPTMP2 = $34 ZPTMP3 = $35 SECH512 = $30 ; PRTTMP = $E4 ; ; PIA Equates: PORTA = $D171 PORTB = $D170 DDRA = $D173 DDRB = $D172 PPCR = $D17C ; PTEMP .DS 40 ; RETRYS .DS 1 BYTES .DS 1 CURSY .DS 1 CTRLS .DS 1 DRIVE .DS 1 HDRLOC .DS 2 DATLOC .DS 2 MAXSEC .DS 3 SECSTRK .DS 1 DECRET .DS 1 FIRSTINC .DS 1 ; ;Select controller ; A=scsi # <0=7> SEL_CTRL STA ZPTMP1 LDA PPCR ORA #$0F STA PPCR ;kill any handshake LDA #$0C STA DDRB BIT PORTB ;are we busy? BVS S_C1 LDX #$F7 ;do a RESET STX PORTB S_C5 DEX BNE S_C5 ;pause a little LDA #$FF ;maybe this will STA PORTB ;wake ctrlr up TAX TAY S_C4 NOP NOP ;waste cycles NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP DEX BNE S_C4 DEY BNE S_C4 BIT PORTB ;let's look again BVS S_C1 ;yep, all ok LDY #142 ;else bus RTS ;'overrun'.. S_C1 JSR SETOUT ;set data out LDX ZPTMP1 LDA BITTAB,X STA PORTA LDA #$FB ;lower /SEL STA PORTB LDX #0 LDY #$80 S_C2 BIT PORTB BVC S_C3 ;is it busy? INX BNE S_C2 ;nope, loop INY BNE S_C2 BUSERR LDA #$FF STA PORTB ;oh well, LDA PPCR ORA #$0F STA PPCR S_C8 LDX #$0D STX DDRB DEX STX PORTB JSR SETINP ;give up LDY #138 RTS S_C3 LDA #$FF STA PORTB TAY TAX S_C6 LDA PORTB ;wait for AND #$82 ;REQ and C/D BEQ S_C7 ;to assert DEX BNE S_C6 DEY BNE S_C6 BEQ S_C8 S_C7 LDY #1 ;y=0, success! RTS ; BITTAB .BYTE 1,2,4,8,$10,$20,$40,$80 ; SETINP PHA ;set direction LDA #0 ;of data bus BEQ SETINP1 SETOUT PHA LDA #$FF SETINP1 STA DDRA PLA RTS ; SND_CMD STX ZWTEMP1 ;send cmd STY ZWTEMP1+1 ;frame STA BYTES JSR SETOUT ; LDA PPCR ; AND #$F0 ;enable ; ORA #9 ;handshake ; STA PPCR JSR WAITREQ LDY #0 SN_C1 LDX #0 SN_C2 LDA PORTB BPL SN_C21 BIT PORTB BVS SN_C4 BVC SN_C2 ;branch SN_C21 AND #2 BNE SN_C22 ;oops, data mode LDA (ZWTEMP1),Y STA PORTA JSR FIXSCSI INY CPY BYTES BNE SN_C1 ;always loop SN_C22 LDY #1 RTS SN_C4 JMP BUSERR ; ; RWDATA STX ZWTEMP1 STY ZWTEMP1+1 JSR FIXALF TYA ORA ZWTEMP1 BNE RWD1 RTS ;no data RWD1 JSR WAITREQ LDA PORTB LSR A BCS RW_DD2 ;writes JSR SETINP BCC RW_DA1 ;branch to reads ; RW_DD2 LDY #0 ;put data code RW_CC2 LDA PORTB BPL RW_CC3 BIT PORTB BVS RW_CC4 BVC RW_CC2 ;branch RW_CC3 AND #2 ;command or data? BEQ RW_DD3 ;out of data LDA (ZWTEMP1),Y STA PORTA INY BNE RW_CC2 INC ZWTEMP1+1 BNE RW_CC2 ;branch ; RW_DD3 TYA LDY #1 RTS ; RW_CC4 JMP BUSERR ; RW_DA1 LDY #0 RW_DA2 LDX #0 RW_DA3 LDA PORTB ;get data code BPL RW_DA4 BIT PORTB BVS RW_CC4 INX BEQ RW_CC4 BNE RW_DA3 RW_DA4 AND #2 BEQ RW_DA5 LDA PORTA STA (ZWTEMP1),Y INY BNE RW_DA3 ;in place of DA2 INC ZWTEMP1+1 BNE RW_DA3 ;branch ; RW_DA5 JSR FIXALF TYA LDY #0 RTS ; GETSTAT JSR SETINP LDA PPCR ORA #$0F STA PPCR JSR WAITREQ LDA PORTA ;status byte STA ZPTMP2 JSR FIXSCSI JSR WAITREQ ; LDA PORTA ;toss 2nd stat JSR FIXSCSI JSR BUSERR ;release bus LDA ZPTMP2 AND #2 BEQ GE_ST1 LDY #144 RTS GE_ST1 LDY #1 RTS ; FIXSCSI LDA PPCR AND #$FD STA PPCR FIX1 BIT PORTB BPL FIX1 ORA #2 STA PPCR RTS ; WAITREQ LDA #0 TAX LDY #0 ;5 min timeout WA_R1 BIT PORTB ;wait for REQ BVS WA_R2 ;not busy BMI WA_R3 RTS ;got it! WA_R3 JMP WA_R1 ;LOOP FOREVER ADC #1 BNE WA_R1 INX BNE WA_R1 INY BNE WA_R1 WA_R2 PLA PLA JMP BUSERR ; FIXALF LDA #$EF STA PPCR LDA #$E9 STA PPCR ;FIX ACK PROBLEM RTS ; DOIT PLA STA PRTTMP PLA STA PRTTMP+1 LDY #1 LDA (PRTTMP),Y STA BYTES INY LDA (PRTTMP),Y STA RETRYS INY LDA (PRTTMP),Y STA HDRLOC INY LDA (PRTTMP),Y STA HDRLOC+1 INY LDA (PRTTMP),Y STA DATLOC INY LDA (PRTTMP),Y STA DATLOC+1 TYA CLC ADC PRTTMP TAY LDA PRTTMP+1 ADC #0 PHA TYA PHA JSR DATPAGE LDA HDRLOC STA PRTTMP LDA HDRLOC+1 STA PRTTMP+1 DOI3 LDY #1 LDA (PRTTMP),Y AND #$1F STA (PRTTMP),Y LDX DRIVE LDA $D6AB,X AND #$E0 ORA (PRTTMP),Y STA (PRTTMP),Y ;set LUN # LDA $D6AB,X AND #7 JSR SEL_CTRL BMI DOI1 LDX HDRLOC LDY HDRLOC+1 LDA BYTES JSR SND_CMD BMI DOI2 JSR WAITREQ LDX DATLOC LDY DATLOC+1 JSR RWDATA BMI DOI2 JSR GETSTAT BPL DOI1 DOI2 DEC RETRYS ;retry 2x BPL DOI3 DOI1 RTS ; DATPAGE PHA LDA #$F5 BNE DATPAGE1 PRPAGE PHA LDA #$F6 BNE DATPAGE1 JUNKPAGE PHA LDA #$FF DATPAGE1 STA RAMPAGE PLA RTS ; MAKE_CLINE STX CURSY LDA #$20 LDY #32 CSS1 STA PTEMP,Y DEY BPL CSS1 INY STY PTEMP+21 TXA CLC ADC #$41 STA PTEMP JSR DATPAGE TXA ASL A ASL A ASL A STA DRIVE TAX LDA $D6AB,X PHA AND #7 ORA #$30 STA PTEMP+4 PLA LSR A SEC ROR A SEC ROR A LSR A LSR A STA PTEMP+6 LDA #', STA PTEMP+5 LDA $D6AE,X LSR A LSR A LSR A LSR A LDY #11 ;heads JSR A2DIGIT LDA $D6AC,X STA 0 LDA $D6AD,X STA 1 ORA 0 BNE CSS01 LDX CURSY CLC ;not valid RTS CSS01 LDX #0 STX 2 JSR A3DIGIT LDX #0 CSS8 LDA NUMBUF,Y STA PTEMP+16,X INX INY CPY #8 BCC CSS8 LDX #PTEMP&255 LDY #PTEMP/256 JSR PRINT LDX CURSY SEC ;good RTS ; NUMBUF .BYTE " ",0 ; A2DIGIT CMP #10 BCC A2D1 SBC #10 A2D1 PHA LDA #$18 ROL A STA PTEMP,Y PLA ORA #$30 STA PTEMP+1,Y RTS ; COMLO .BYTE $80,$40,$A0,$10,$E8,100,10,1 COMHI .BYTE $96,$42,$86,$27,3,0,0,0 COMH2 .BYTE $98,$0F,1,0,0,0,0,0 ; A3DIGIT LDA #'0 LDX #0 LDY #7 A3D1 STA NUMBUF,Y DEY BPL A3D1 INY A3D2 LDA 2,X CMP COMH2,Y BNE A3D3 LDA 1,X CMP COMHI,Y BNE A3D3 LDA 0,X CMP COMLO,Y A3D3 BCC A3D4 LDA 0,X SBC COMLO,Y STA 0,X LDA 1,X SBC COMHI,Y STA 1,X LDA 2,X SBC COMH2,Y STA 2,X CLC LDA NUMBUF,Y ADC #1 STA NUMBUF,Y BCC A3D2 ;branch A3D4 INY CPY #8 BCC A3D2 LDY #0 A3D5 LDA NUMBUF,Y CMP #'0 BNE A3D6 INY CPY #7 BCC A3D5 A3D6 RTS ; A3DIGPRT JSR A3DIGIT TYA CLC ADC #NUMBUF&255 TAX LDA #NUMBUF/256 ADC #0 TAY LDA #0 STA NUMBUF+8 ; PRINT STX PRTTMP STY PRTTMP+1 PR1 LDY #0 LDA (PRTTMP),Y BEQ PR2 JSR EOUTCH INC PRTTMP BNE PR1 INC PRTTMP+1 BNE PR1 PR2 RTS EOUTCH TAY LDA $0347 PHA LDA $0346 PHA LDX #0 TYA RTS ; KGETCH LDX #$10 LDA #$0C STA $0342,X JSR $E456 LDA #3 STA $0342,X LDA #KCOL&255 STA $0344,X LDA #KCOL/256 STA $0345,X LDA #4 STA $034A,X JSR $E456 LDA #7 STA $0342,X LDA #0 STA $0348,X STA $0349,X JSR $E456 PHA LDA #$0C STA $0342,X JSR $E456 PLA RTS KCOL .BYTE "K:",$9B ; INITMSG .BYTE $7D,$7D .BYTE "Ôèå ÂÌÁÃË ÂÏØ Õôéìéôéå󠠨é ±¹¹² ÃÓÓ",$9B .BYTE " Hard Disk Parking Utility 1.5",$9B .BYTE "",$9B,$9B .BYTE " Configured Drives:",$9B,$9B .BYTE "ÈÄ Õ£¬Ìõî Èåáäó Ãùìó Ìáóô Óåã Óôáôõó",$9B,0 NOCTLM .BYTE $9B,$9B,"No Hard Disks Configured!",$9B,0 SELHDM .BYTE $9B,"Press any key to exit.",$9B,0 ; START LDA #$FF STA PORTB LDX #INITMSG&255 LDY #INITMSG/256 ;title JSR PRINT LDA #0 STA CTRLS TAX STRL1 JSR MAKE_CLINE PHP ROL CTRLS ;display drives PLP BCS STRL2 STRL3 LDX CURSY INX CPX #8 BCC STRL1 LDA CTRLS ;make sure there BNE STRL4 ;is at least 1 LDX #NOCTLM&255 LDY #NOCTLM/256 JSR PRINT STRL4 LDX #SELHDM&255 LDY #SELHDM/256 ;press a key JSR PRINT LDA #$FF STA $02FC JSR KGETCH ;THAT'S ALL! NOW LEAVE PORT ;CORRECTLY... LDA #4 SEI STA $D1FF LDX $D802 LDA #0 STA $D1FF CLI CPX #6 BCS QUITDOS LDA #$0C STA DDRB ; QUITDOS LDA #$9B JSR EOUTCH JMP EOUTCH ; STRL2 JSR DOIT .WORD $040A,RCAPCMD,DATA BPL STRL2A LDA #$80 STA FIRSTINC JMP ERRDCP1 STRL2A LDA DATA+3 LDX DATA+2 LDY DATA+1 STRL5 STA 0 STX 1 STY 2 STA REACMD+3 STX REACMD+2 STY REACMD+1 LDX DRIVE LDA $D6AB,X ;is it 512? AND #8 BEQ STRL5A ASL 0 ROL 1 ROL 2 ;multiply # by 2 STRL5A JSR A3DIGIT LDY #0 STRL5B LDA NUMBUF,Y CMP #'0 BNE STRL5C ;kill leading LDA #$20 ;0's in sec # STA NUMBUF,Y INY CPY #7 BCC STRL5B STRL5C LDX #NUMBUF&255 LDY #NUMBUF/256 JSR PRINT JSR SETLAST JSR DOIT .WORD $0106,REACMD,DATA BPL STRL6 LDX #NOPARK&255 LDY #NOPARK/256 JSR PRINT STRL7 JMP STRL3 STRL6 LDX #PARK&255 LDY #PARK/256 JSR PRINT LDA #8 STA $D01F LDA $D01F AND #1 BNE STRL7 ;DO WE SHUT DOWN? LDX DRIVE LDA $D6AB,X AND #$10 BNE STRL7 JSR DOIT .WORD $0106,TURNOFF,DATA JMP STRL3 ; TURNOFF .BYTE $1B,0,0,0,0,0 REACMD .BYTE 8,0,0,0,1,0 RCAPCMD .BYTE $25,0,0,0,0,0,0,0,0,0 NOPARK .BYTE " Åòòïò¡",$9B,0 PARK .BYTE " Parked",$9B,0 ; ERRDCP1 LDX DRIVE LDA $D6AB,X AND #8 BEQ SAS1 LDA #17 ;secs/trk .BYTE $2C SAS1 LDA #32 STA SECSTRK LDA $D6AD,X STA DATA LDA $D6AC,X STA DATA+1 ;set up LDA $D6AE,X ;define limits LSR A ;parm block LSR A LSR A LSR A STA DATA+2 LDA $D6B0,X STA DATA+3 LDA $D6AF,X STA DATA+4 LDA $D6B2,X STA DATA+5 LDA $D6B1,X STA DATA+6 LDA #11 STA DATA+7 ;ecc length JSR DOIT .WORD $0106,DEFLIMC,DATA JMP SAS3 ;ignore status ; DEFLIMC .BYTE $0C,0,0,0,0,0 ; SAS3 LDA #$FF ;set to -1 STA MAXSEC STA MAXSEC+1 STA MAXSEC+2 SEC LDA DATA+1 ;TAKE 7 cylinders away SBC #7 ;for bad sectors STA DATA+1 LDA DATA SBC #0 STA DATA SAS6 LDX DATA+2 ;# of heads SAS6A CLC LDA MAXSEC ADC SECSTRK STA MAXSEC BCC SAS6B INC MAXSEC+1 BNE SAS6B INC MAXSEC+2 SAS6B DEX BNE SAS6A LDA DATA+1 ;cylinders BNE SAS6C DEC DATA ;high byte SAS6C DEC DATA+1 LDA DATA ORA DATA+1 BNE SAS6 ;figure # of secs LDA #0 STA DECRET NOB5 LDA MAXSEC STA REACMD+3 LDA MAXSEC+1 STA REACMD+2 LDA MAXSEC+2 STA REACMD+1 JSR SETLAST JSR DOIT .WORD $06,REACMD,DATA BMI NOB1 LDA FIRSTINC BPL NOUP1 LDA MAXSEC ;go up till we CLC ;hit an error ADC SECSTRK STA MAXSEC BCC NOB5 INC MAXSEC+1 BNE NOB5 INC MAXSEC+2 BNE NOB5 ;branch NOUP1 LDA MAXSEC LDX MAXSEC+1 LDY MAXSEC+2 JMP STRL5 NOB1 CPY #138 BNE NOB2 NOB3 LDX #ERRM2&255 LDY #ERRM2/256 JSR PRINT JMP STRL3 NOB2 LDA #0 STA FIRSTINC DEC DECRET ;ONLY GO DOWN BEQ NOB3 ;256 TRACKS LDA MAXSEC SEC SBC SECSTRK STA MAXSEC LDA MAXSEC+1 SBC #0 STA MAXSEC+1 LDA MAXSEC+2 SBC #0 STA MAXSEC+2 JMP NOB5 ERRM2 .BYTE "Îï Äòéöå¯Ãôòìò¡",$9B,0 ; SETLAST LDX DRIVE LDA $D6AB,X AND #$10 ;do step rate BEQ SETL1 LDA $D6AE,X AND #$0F SETL1 STA REACMD+5 RTS ; .OPT LIST DATA .OPT NO LIST ; *= $02E0 .WORD INIT