XdX; **********************nX; * Black Rabbit 2.0 *xX; **********************X;X; Highspeed sector copierX; for single-drive systemsX;X; by Brian Moriarty X; ANALOG Compendium Volume 1X;X; OS disk handler equatesX;DEVNUMDCOMNDDSTATSDBUFLODBUFHISECTLO SECTHI "DVSTAT,DISKIOS6X;@X; Disk handler commandsJX;T READR^ WRITEWh FORMAT!rX;|X; Misc. system equatesX;COLDSTD BOOT?  SAVMSCXCOLOR2 OLDADR^CONSOL RAMTOPj AUDF1 AUDC1 RTCLOK ATRACTMCOLDSVwX;X; Internal program equatesX;& RTOTAL0 WTOTAL: BPOINTD PPOINTN SCREENX VTOCb LINEl SAVEYv SBYTE FFLAGX;#X; Characters for "Visible VTOC"X; DOT DATA BADWRITTENNOTHINGX;X; Memory usageX;DUMMY;; Dummy bufferORIGIN;; Program start BUFFER;; Data bufferX;  ORIGIN*X;4 X; 6 bytes to control boot-up>X;H =;; # boot sectsR ORIGIN=ORIGIN\ ENTRY=ENTRYfX;p ENTRYzX;X; Init screen line pointerX;Q>?P@OLDADR7;; Kill cursor TOPLINEX;X; Check for 48K RAMX; QRAMTOPR>;; $C0 = 48KERABBIT;; > OR = 48KX;X; Print RAM warningX;Q>WARNING$ PPPOINT.Q>WARNING8 MESSAGEBX;L FREEZEV!FREEZE;; Infinite loop`X;jX; ********************tX; * Initialize R/W *~X; ********************X; RABBITX;!X; Initialize important thingsX;$>;; Black&COLOR2;; Background&RTOTAL;; Clear MSB&WTOTAL;; Ditto&COLDST;; Coldstart flag 2;; X = 1&RTOTAL;; LSB&WTOTAL;; Ditto &BOOT?;; Boot flag&DEVNUM;; Drive #1&FFLAG;; Format enable(X;2X; Setup VTOC screen pointer<X;F,PQSAVMSC;; Addr of screenZO>;; 6 lines downd PSCREENn PVTOCxQSAVMSCO>PSCREEN PVTOCX;X; Print titleX; TOPLINEQ>TITLE PPPOINTQ>TITLE MESSAGEX;X; Reset screen pointerX;, QSAVMSC"O>z;; X=2, Y=3, PLINE6 DDODOTS@ #LINEJX;TX; Init VTOC display matrix^X;h DODOTSr #VTOC| HMATRIX #VTOC MATRIX$> LOOP1%> Q>DOT LOOP2 P@VTOC73)> HLOOP2, QVTOCO> PVTOC DMORE& #VTOC0MORE:0D ILOOP1NX;XX; ******************bX; * READ Routine *lX; ******************vX; READERX; X; Reset buffer addr pointersX; REPOINTX;X; Update VTOC pointerX;, QSCREEN ORTOTAL PVTOCQSCREENORTOTAL  PVTOCX; X; Print READ prompt*X;4Q>RPROMPT> PPPOINTHQ>RPROMPTR MESSAGE\X;f WAIT;; START keypX;z Q>READPDCOMND;; Set READ modeX;X; ************************X; * Start of READ loop *X; ************************X; RLOOPX;X; Update sector #X; QRTOTAL PSECTLOQRTOTAL PSECTHI X;  DISKIO;; Fetch sector$ QDSTATS;; Check status. ISECSTAT;; Branch if okay8 Q>BADB HSHOWSTATL X;V "X; Check sector data for status` X;j SECSTATt %>~ NEXTBYTE Q@BPOINT7 HDATAID 1 INEXTBYTE Q>NOTHING HSHOWSTAT DATAID Q>DATA SHOWSTAT PSBYTE %> 'ATRACT;; Attract off P@VTOC7 X; X; Update VTOC addr pointer X;( #VTOC2 HUPCOUNT< #VTOCF UPCOUNTP #RTOTALZ HSECTMAXd #RTOTALn X;x X; End of disk? X; SECTMAX QRTOTAL R> HDATACHECK QRTOTAL R> FWRITER X; X; Check for data sector X; DATACHECK QSBYTE R>DATA HRLOOP X;" X; Add 128 to buffer pointers, X;6 ,@ QDBUFLOJ O>T PDBUFLO^ PBPOINTh QDBUFHIr O>| PDBUFHI PBPOINT X; X; Check if buffer full X; R>;; Top of buffer? HRLOOP;; No; keep going X; X; ******************* X; * WRITE Routine * X; ******************* X; WRITER X; X; Init VTOC pointer X; ,& QSCREEN0 OWTOTAL: PVTOCD QSCREENN OWTOTALX PVTOCb X;l X; Print WRITE promptv X; Q>WPROMPT PPPOINT Q>WPROMPT MESSAGE X;  WAIT;; START key X; "FFLAG HNOFORM;; Skip if Pass 2 X; X; Format disk X; ERASE  DUMPOINT;; buffer addr Q>FORMAT PDCOMND;; format cmnd  DISKIO;; Do it!* X;4 X; Check for okay format> X;H QDSTATSR R>\ FNOFORMf X;p X; Print bad format warningz X; Q>BADFORM PPPOINT Q>BADFORM MESSAGE WAIT FERASE X; NOFORM X;  REPOINT;; Reset pntrs X; Q>WRITE PDCOMND;; WRITE commandX;X; *************************X; * Start of WRITE loop *$X; *************************.X;8 WLOOPBX;LX; Update setor #VX;` QWTOTALj PSECTLOtQWTOTAL~ PSECTHIX;X; Get status of next readX;%> 'ATRACT Q@VTOC7 PSBYTEX; X; Branch depending on statusX; R>DATAHSKIPSECT;; If no dataX;  DWRITE DISKIO;; Write sector GDWRITE(X;2X; Display write status<X;F SKIPSECTP Q>WRITTENZ%>d P@VTOC7nX;xX; Update VTOC, WTOTALX; #VTOC HWRUP #VTOCWRUP #WTOTAL HWSECTMAX#WTOTAL WSECTMAXQWTOTALR> HBUFLOOK QWTOTALR> FFINISHEDX;"$X; Should buffer addr be updated?,X;6 BUFLOOK@ QSBYTEJR>DATA;; Update bufadr?THWLOOP;; No; next sect^X;hX; Update buffer addressrX;|, QDBUFLOO> PDBUFLO QDBUFHIO> PDBUFHIX;X; Buffer full?X; FULBUFR> HWLOOP!READER;; Next passX;X; *****************X; * End routine *&X; *****************0X;: FINISHEDDQ>COMPLETEN PPPOINTXQ>COMPLETEb MESSAGEl DECIDEv QCONSOLR>;; START press? FRERUNR>;; OPTION? HDECIDE LETGO!COLDSV;; Cold boot RERUN LETGO!RABBIT;; Re-run RabbitX;X; *****************X; * Subroutines *X; *****************X; X; Point to dummy bufferX;  DUMPOINT*Q>DUMMY4 PDBUFLO>Q>DUMMYH PDBUFHIR:\X;fX; Point to top screen linepX;z TOPLINE, QSAVMSCO>*;; X=2, Y=1 PLINEQSAVMSCO> PLINE:X;!X; Beep and wait for START keyX;WAITQ>d;; Freq = 100 PAUDF1Q>;; D & V = 10 PAUDC1$Q>.PRTCLOK;; Clear count8BEEPB QRTCLOKLR>;; 1/4 secV HBEEP`Q>jPAUDC1;; Silence!tX;~X; Check keyX; HOLDIT QCONSOLR>HHOLDIT;; Pressed? LETGO QCONSOLR>HLETGO;; Till released:X;X; Print text messagesX;  MESSAGEPPPOINT%>!( NEXTPRINT2 Q@PPOINT7< P@LINE7F1PINEXTPRINTZ:dX;nX; Set buffer pointersxX; REPOINTQ>BUFFER PBPOINT PDBUFLOQ>BUFFERPBPOINT PDBUFHI:X;X; *******************X; * Message texts *X; *******************X; WARNING) ARemove cartridge; requires 48K RAMAX;" TITLE,) A by Brian MoriartyA6X;@ RPROMPTJ) AInsert SOURCE disk, press ATX;^ WPROMPTh) AInsert COPY disk, press ArX;| COMPLETE) A to re-run, to boot AX; BADFORM) AReplace bad COPY disk, press AX;