10REM > IDEPatch 1.19 20REM Modified for BBC Plus and BBC Model B fitted with Acorn WD1770 controller 30REM Patch BBC Model B ADFS-1.31E00 ROM to access IDE devices:REM CHANGED 40REM v1.10 Trial version, incorporates context preservation on Ctrl-Break 50REM v1.11 Verified with real hardware 60REM v1.13 Stack params, do one sector at a time 70REM v1.14 IDE transfers done twice to avoid DRQ bug, Tube works 80REM v1.15 SetGeo uses correct drive, errors translated 90REM v1.16 Automatically finds Library directory 100REM v1.17 Two drives per device, no wait for spin-up on power-on 105REM v1.18 Removed pain-in-the-arse context preservation on Ctrl-Break 107REM v1.19 Adapted Acorn ADFS-1.31E00 ROM for models with =>16 KByte Sideways RAM 110: 120DIM mcode% &3FFF:ver$="1.32":REM CHANGED 130INPUT"ADFS-1.31E00 ROM image: "file$:REM CHANGED 140OSCLI"Load "+file$+" "+STR$~mcode% 150IF mcode%!&16<>&31332E31:PRINT"Not ADFS-1.31E00 ROM":END:REM CHANGED 160DEF FNorg(A%,B%):P%=A%:O%=A%-&8000+mcode%:=P*3+4 170: 180FOR P=0 TO 1 190[OPT FNorg(&8008,-1) 200EQUB EVAL("&"+MID$(ver$,3)) :\ New version byte 210] 220[OPT FNorg(&8016,-1) 230EQUS LEFT$(ver$,1)+MID$(ver$,2) :\ New version string :\ CHANGED 240] 242[OPT FNorg(&8033,-1) 243JSR &8F80:RTS :\ A Kludge to prevent the untraceable ???? NoRAM message. 244EQUB &7F:EQUS "NoRA":EQUB &CD 245] 250[OPT FNorg(&8085,-1) :\ &8057 CHANGED FROM &8070 260LDA &FC47:STA &CC:LDA &FC47 :\ Read IDE status byte 270] 280[OPT FNorg(&8093,-1) :\ &8065 CHANGED FROM &807E 290RTS:NOP:NOP:NOP :\ Remove SCSI code 300NOP 310.ReadBreak 320NOP:NOP:NOP:NOP:NOP:NOP :\ JSR &9A88 AND #&01 RTS :\ CHANGED :\ Power-on Reset? 330NOP:NOP 340.WaitForData 350LDA &FC47:AND #8:BEQ WaitForData:\ Loop until data ready :\ BIT #8 360RTS 370: 380.MountCheck 390JSR &9A1E:JMP &9569 :\ Do *MOUNT, reselect ADFS JSR &A15E\JMP &9B38 FROM &A19E\&9B4A 400: 410\ next=&8080 :\ Changed from &8099 420] 430[OPT FNorg(&8123,-1) :\ Access hard drive :\ &80F6 CHANGED FROM &811A 440LDY #0 450NOP 460] 470[OPT FNorg(&8129,&818A) :\ 8114 CHANGED FROM &8137,&81AD Loop Point 480LDY #5:JMP BYE 490.SetCommand1 500PHP:JMP SetCommand 510NOP 520NOP 530NOP 540NOP 550: 555.CommandSaveLp1 560LDA &B0:PHA:LDA &B1:PHA 570JSR UpdateDrive :\ Merge drive 580STA &B0:STY &B1 :\ Point to block in RAM 590PHP:JSR SetGeometry:PLP :\ Set shape to c*4*64 600.CommandLoop 610LDX #2:.Twice :\ First pass to seek sector 620BIT &CD:BVC CommandStart :\ Accessing I/O memory 630PHP:TXA:PHA:LDX #&27:LDY #&B2:LDA #0:\ Point to address block :\ CHANGED PHX 640ROL A:EOR #1:JSR SetTubeAction+1:PLA:TAX:PLP :\ Set Tube action :\ FROM &8213 PLX 650.CommandStart :\ C=R/W, &B0/1=>block 660JSR SetSector :\ Set sector, count, command 670.TransferLoop 680JSR WaitForData:AND #&21:BNE TransDone 690BIT &CD:BVS TransTube:BCC IORead 700.IOWrite :LDA (&80),Y:STA &FC40:JMP TransferByte :\ BRA TransferByte 710.IORead :LDA &FC40:STA (&80),Y:JMP TransferByte :\ BRA TransferByte 720.TransTube:BCC TubeRead 730.TubeWrite:LDA &FEE5:STA &FC40:JMP TransferByte :\ BRA TransferByte 740.TubeRead :LDA &FC40:STA &FEE5:JMP TransferByte :\ BRA TransferByte 750.CommandLoop1 755JMP CommandLoop 760\ next=&8197 &818A CHANGED FROM &81AD YES ENTRY POINT!!!!! 770] 780[OPT FNorg(&8197,&81EF) :\ Transfer completed :\ &818A CHANGED from &81AD 790.CommandDone 800JSR GetResult :\ Get IDE result 810.CommandExit 820PHA:JSR &8072:PLA :\ Release Tube :\ &8043 CHANGED from &803A 830LDX &B0:LDY &B1:AND #&7F :\ Restore registers 840RTS 850: 860.TransferByte 870INY:BNE TransferLoop :\ Loop for 256 bytes 880DEX:BNE Twice:INC &81 :\ Second pass to do real transfer 890LDA &FC47:AND #&21:BNE TransDone:\ Error occured 900INC &B228:BNE TubeAddr :\ Increment Tube address :\ CHANGED &1028 910INC &B229:BNE TubeAddr:INC &B22A :\ CHANGED &1029 &102A 920.TubeAddr 930INC &87:BNE TransCount :\ Increment sector 940INC &86:BNE TransCount:INC &85 950.TransCount 960DEC &88:BNE CommandLoop1 :\ Loop for all sectors 970 :\ Done, check for errors 980: 990.TransDone 1000PLA:STA &B1:PLA:STA &B0:INY :\ Restore pointer 1010.CommandRestore :\ Restore memory 1020PLA:STA &7F,Y:INY:CPY #10:BNE CommandRestore 1030BEQ CommandDone :\ Jump to get result BRA CommandDone 1040: 1050.SetGeometry 1060JSR WaitNotBusy 1070LDA #64:STA &FC42:STA &FC43 :\ 64 sectors per track 1080LDY #6:LDA (&B0),Y:LSR A:LSR A:ORA #3 :\ Get drive number 1090JSR SetDriveA:LDA #&91:BNE SetCmd :\ 4 heads per cylinder 1100.SetTubeAction 1110\ next=&81FC CHANGED 81EF from &8212 1120]:REM &8201=Entry Point 1130[OPT FNorg(&8205,&8282) :\ CHANGED &81FC from &821F 1140.SetSector 1150PHP:JSR WaitNotBusy :\ Save CC/CS Read/Write 1160LDY #8:LDA #1:STA &FC42 :\ One sector 1170CLC:LDA (&B0),Y:AND #63:ADC #1:STA &FC43:\ Set sector b0-b5 1180DEY:LDA (&B0),Y:ADC #0:STA &FC44 :\ Set sector b8-b15 1190DEY:LDA (&B0),Y:JSR SetCylinder :\ Set sector b16-b21 1200INY:INY:EOR (&B0),Y:AND #2:EOR (&B0),Y :\ Merge Drive and Head 1210JSR SetDrive:DEY:DEY:DEY:LDA (&B0),Y :\ Get command &08 or &0A 1220.SetCommand 1230AND #2:PHA:EOR #2:LSR A:LSR A :\ Copy ~b1 into Cy 1240PLA:ASL A:ASL A:ASL A:ORA #&20 :\ Translate CS->&20 or CC->&30 1250LDY #0:PLP:.SetCmd:STA &FC47:RTS :\ Set command &08 or &0A 1260: 1270.SetDrive 1280ROL A:ROL A:ROL A :\ Move into position 1290.SetDriveA 1300AND #&13:STA &FC46:RTS :\ Set device + sector b6-b7 1310: 1320.SetCylinder 1330PHA:AND #&3F:ADC #0:STA &FC45 :\ Set sector b16-b21 1340PLA:ROL A:ROL A:ROL A:ROL A:RTS :\ Get Drive 0-1/2-3 into b1 1350: 1360.SetRandom 1370JSR SetCylinder :\ Set sector b16-b21 1380EOR &B201,X:AND #&02:EOR &B201,X :\ Merge Drive and Head :\ CHANGED 1390JSR SetDrive:PLA:JMP SetCommand1 :\ Set device and command BRA SetCommand 1400: 1410.GetResult 1420LDA &FC47:AND #&21:BEQ GetResOk :\ Get IDE result 1430ORA &FC41:LDX #&FF :\ Get IDE error code 1440.GetResLp 1450INX:ROR A:BCC GetResLp:LDA ResultCodes,X :\ Translate result code 1460.GetResOk 1470RTS 1480NOP:NOP:NOP 1490\ next=&828C - Entry Point :\&8282 CHANGED from &82A5 - Entry Point 1500] 1510[OPT FNorg(&8304,-1) :\ &8305 CHANGED from &8328 1520LDA &CD:AND #&FE:STA &CD :\ Fake that ensuring has completed 1530RTS:NOP:NOP:NOP 1540]:REM next=&830E 1550[OPT FNorg(&830E,&831B) :\ &830F CHANGED from &8332 1560.WaitNotBusy 1570PHP 1573.IDEstatus 1576JSR &8084 :\ Get IDE status :\ &8056 CHANGED from &806F 1580AND #&C0:CMP #&40:BNE IDEstatus :\ Wait for IDE not busy and ready 1590PLP:RTS 1600\ next=&831A :\ 11 spare bytes 831B 1610] 1620[OPT FNorg(&897D,-1) :\ Load a partial sector :\ &8B72 CHANGED from &8B7F 1640TXA:PHA:JSR SetGeometry:JSR SetSector:\ Pass sector address to IDE PHX 1660PLA:TAX:NOP :\PLX 1670]:REM next=&8988 :\ next=&8B7f 1680[OPT FNorg(&8D6B,-1) :\ &8FEA CHANGED from 8FF3 1690RTS :\ Bodge 'Bad FS map' check 1700] 1710[OPT FNorg(&9483,&9A78) :\ Check if hard drive present :\9A63 CHANGED from &9A6C 1720LDA &FC47 :\ &FF - absent, <>&FF - present 1730CLC:ADC #1:BEQ DriveNotPresent :\ &00 - absent, <>&00 - present INC A 1740LDA #0:RTS :\ EQ - present 1750.DriveNotPresent 1760SEC:SBC #1:RTS :\ A=&FF - NE -> absent DEC A 1770NOP:NOP:NOP:NOP:NOP:NOP 1780\ next=&9498 :\9A78 CHANGED FROM &9A7F 1790] 1800[OPT FNorg(&9AF6,-1) :\ CHANGED from &9B0B 1810\\JSR ReadBreak :\ Preserve context on Ctrl-Break :\ CHANGED 1820] 1830[OPT FNorg(&9B7C,-1) :\ Not Changed from &9B7C Can't find it !! 1840\\JSR ReadBreak :\ Preserve context on Ctrl-Break :\ CHANGED 1850] 1860[OPT FNorg(&960C,-1) :\9C29 CHANGED from &9C2F 1865\\JSR &A898 1870LDA &B31B:CLC:ADC #1:BNE &9654 :\9C74 Lib not unset, jump ahead :\ CHANGED INC A 1880LDA &CD:AND #32:BEQ &9654:BNE &9621 :\9C74, 9C3B If HD, look for $.Library :\ CHANGED 1890RTS:RTS 1895\ next=&9C3B 1900] 1910[OPT FNorg(&9DB8,-1) :\ CHANGED from &9E07 1920\\EQUS ver$ :\ New version string 1930] 1940[OPT FNorg(&989B,-1) :\9F6E CHANGED from &9F9B 1950EQUB (MountCheck-1) DIV 256 :\ Ensure *MOUNT checks for LIB 1960EQUB (MountCheck-1) AND 255 1970] 1971[OPT FNorg(&99A6,-1) :\Changed from &A0C3 1972RTS 1973.BYE 1974LDA (&B0),Y:CMP #&09 :\ Get command, CC=Read, CS=Write 1975AND #&FD:EOR #&08:BEQ CommandOk :\ Jump if Read (&08) or Write (&0A) 1976LDA #&60:JMP CommandExit :\ Return 'bad command' otherwise BRA CommandExit 1977.CommandOk 1978LDY #9 1979.CommandSaveLp 1980LDA &7F,Y:PHA:LDA (&B0),Y:STA &7F,Y 1981DEY:BNE CommandSaveLp :\ Save &80-&89 and copy block 1982JMP CommandSaveLp1 :\ Memory FULL 1988] 1989[OPT FNorg(&A07E,&AAF0) :\ Select sector for BGET/BPUT :\AACA CHANGED from &AADD 1990JSR WaitNotBusy:LDA #1:STA &FC42:CLC :\ one sector 2000LDA &B201,X:AND #63:ADC #1:STA &FC43 :\ Set sector b0-b5 2010LDA &B202,X:ADC #0:STA &FC44 :\ Set sector b8-b15 2020LDA &B203,X:STA &B333:JMP SetRandom :\ Set sector b16-b21 2030NOP:NOP 2040\ next=&A0A4 :\AAF0 CHANGED from &AB03 2050] 2060[OPT FNorg(&A10B,-1) :\ BPUT to hard drive :\AB57 CHANGED from &AB6A 2070NOP:JMP &A117 :\ Always jump to write :\ CHANGED BRA &AB63 2080: 2090.ResultCodes 2100EQUB &FF:EQUB &FF:EQUB &60:EQUB &FF 2110EQUB &50:EQUB &65:EQUB &48:EQUB &FF 2115\ next=&A117 :\ Changed from &AB63 2120] 2130[OPT FNorg(&A125,-1) :\AB72 CHANGED from &AB83 2140NOP:NOP:NOP :\ Don't trample on IDE register 2150] 2160[OPT FNorg(&A12B,&AB87) :\AB78 CHANGED from &AB89 2170RTS :\ Remove IRQ routine 2180: 2190.UpdateDrive 2200LDA &85:ORA &B317:STA &85 :\ Merge with current drive :\ CHANGED 2210STA &B333:LDA #&7F:RTS :\ Store for any error :\ CHANGED 2220NOP 2230\ next=&A13A :\AB87 CHANGED from &AB97 2240] 2250[OPT FNorg(&A25B,-1) :\ BGET from hard drive :\ACBA CHANGED from &ACC9 2260NOP:NOP :\ Always continue into read 2270] 2280NEXT 2290IF RIGHT$(file$,2)="31":file$=LEFT$(file$,LEN file$-2)+MID$(ver$,3):REM :\ CHANGED 2300PRINT"Save filename (";file$;:INPUT"): "A$:IF A$<>"":file$=A$ 2310OSCLI"Save "+file$+" "+STR$~mcode%+"+4000 FFFF0000 FFFF0000"