0100 ; ********************** 0110 ; * Black Rabbit 2.0 * 0120 ; ********************** 0130 ; 0140 ; Highspeed sector copier 0150 ; for single-drive systems 0160 ; 0170 ; by Brian Moriarty 0180 ; ANALOG Compendium Volume 1 0190 ; 0200 ; OS disk handler equates 0210 ; 0220 DEVNUM = $0301 0230 DCOMND = $0302 0240 DSTATS = $0303 0250 DBUFLO = $0304 0260 DBUFHI = $0305 0270 SECTLO = $030A 0280 SECTHI = $030B 0290 DVSTAT = $02EB 0300 DISKIO = $E453 0310 ; 0320 ; Disk handler commands 0330 ; 0340 READ = $52 0350 WRITE = $57 0360 FORMAT = $21 0370 ; 0380 ; Misc. system equates 0390 ; 0400 COLDST = $0244 0410 BOOT? = $09 0420 SAVMSC = $58 0430 COLOR2 = $02C6 0440 OLDADR = $5E 0450 CONSOL = $D01F 0460 RAMTOP = $6A 0470 AUDF1 = $D200 0480 AUDC1 = $D201 0490 RTCLOK = $14 0500 ATRACT = $4D 0510 COLDSV = $E477 0520 ; 0530 ; Internal program equates 0540 ; 0550 RTOTAL = $80 0560 WTOTAL = $82 0570 BPOINT = $84 0580 PPOINT = $86 0590 SCREEN = $88 0600 VTOC = $8A 0610 LINE = $8C 0620 SAVEY = $8E 0630 SBYTE = $8F 0640 FFLAG = $90 0650 ; 0660 ; Characters for "Visible VTOC" 0670 ; 0680 DOT = $0E 0690 DATA = $80 0700 BAD = $1F 0710 WRITTEN = $8E 0720 NOTHING = $10 0730 ; 0740 ; Memory usage 0750 ; 0760 DUMMY = $0400 ; Dummy buffer 0770 ORIGIN = $0480 ; Program start 0780 BUFFER = $0780 ; Data buffer 0790 ; 0800 *= ORIGIN 0810 ; 0820 ; 6 bytes to control boot-up 0830 ; 0840 .BYTE $00,$06 ; # boot sects 0850 .BYTE ORIGIN&255,ORIGIN/256 0860 .BYTE ENTRY&255,ENTRY/256 0870 ; 0880 ENTRY 0890 ; 0900 ; Init screen line pointer 0910 ; 0920 LDA #0 0930 TAY 0940 STA (OLDADR),Y ; Kill cursor 0950 JSR TOPLINE 0960 ; 0970 ; Check for 48K RAM 0980 ; 0990 LDA RAMTOP 1000 CMP #$C0 ; $C0 = 48K 1010 BCS RABBIT ; > OR = 48K 1020 ; 1030 ; Print RAM warning 1040 ; 1050 LDA #WARNING&255 1060 STA PPOINT 1070 LDA #WARNING/256 1080 JSR MESSAGE 1090 ; 1100 FREEZE 1110 JMP FREEZE ; Infinite loop 1120 ; 1130 ; ******************** 1140 ; * Initialize R/W * 1150 ; ******************** 1160 ; 1170 RABBIT 1180 ; 1190 ; Initialize important things 1200 ; 1210 LDX #0 ; Black 1220 STX COLOR2 ; Background 1230 STX RTOTAL+1 ; Clear MSB 1240 STX WTOTAL+1 ; Ditto 1250 STX COLDST ; Coldstart flag 1260 INX ; X = 1 1270 STX RTOTAL ; LSB 1280 STX WTOTAL ; Ditto 1290 STX BOOT? ; Boot flag 1300 STX DEVNUM ; Drive #1 1310 STX FFLAG ; Format enable 1320 ; 1330 ; Setup VTOC screen pointer 1340 ; 1350 CLC 1360 LDA SAVMSC ; Addr of screen 1370 ADC #239 ; 6 lines down 1380 STA SCREEN 1390 STA VTOC 1400 LDA SAVMSC+1 1410 ADC #0 1420 STA SCREEN+1 1430 STA VTOC+1 1440 ; 1450 ; Print title 1460 ; 1470 JSR TOPLINE 1480 LDA #TITLE&255 1490 STA PPOINT 1500 LDA #TITLE/256 1510 JSR MESSAGE 1520 ; 1530 ; Reset screen pointer 1540 ; 1550 CLC 1560 LDA SAVMSC 1570 ADC #122 ; X=2, Y=3 1580 STA LINE 1590 BCC DODOTS 1600 INC LINE+1 1610 ; 1620 ; Init VTOC display matrix 1630 ; 1640 DODOTS 1650 INC VTOC 1660 BNE MATRIX 1670 INC VTOC+1 1680 MATRIX 1690 LDX #2 1700 LOOP1 1710 LDY #0 1720 LDA #DOT 1730 LOOP2 1740 STA (VTOC),Y 1750 INY 1760 CPY #240 1770 BNE LOOP2 1780 CLC 1790 LDA VTOC 1800 ADC #240 1810 STA VTOC 1820 BCC MORE 1830 INC VTOC+1 1840 MORE 1850 DEX 1860 BPL LOOP1 1870 ; 1880 ; ****************** 1890 ; * READ Routine * 1900 ; ****************** 1910 ; 1920 READER 1930 ; 1940 ; Reset buffer addr pointers 1950 ; 1960 JSR REPOINT 1970 ; 1980 ; Update VTOC pointer 1990 ; 2000 CLC 2010 LDA SCREEN 2020 ADC RTOTAL 2030 STA VTOC 2040 LDA SCREEN+1 2050 ADC RTOTAL+1 2060 STA VTOC+1 2070 ; 2080 ; Print READ prompt 2090 ; 2100 LDA #RPROMPT&255 2110 STA PPOINT 2120 LDA #RPROMPT/256 2130 JSR MESSAGE 2140 ; 2150 JSR WAIT ; START key 2160 ; 2170 LDA #READ 2180 STA DCOMND ; Set READ mode 2190 ; 2200 ; ************************ 2210 ; * Start of READ loop * 2220 ; ************************ 2230 ; 2240 RLOOP 2250 ; 2260 ; Update sector # 2270 ; 2280 LDA RTOTAL 2290 STA SECTLO 2300 LDA RTOTAL+1 2310 STA SECTHI 2320 ; 2330 JSR DISKIO ; Fetch sector 2340 LDA DSTATS ; Check status 2350 BPL SECSTAT ; Branch if okay 2360 LDA #BAD 2370 BNE SHOWSTAT 2380 ; 2390 ; Check sector data for status 2400 ; 2410 SECSTAT 2420 LDY #$7F 2430 NEXTBYTE 2440 LDA (BPOINT),Y 2450 BNE DATAID 2460 DEY 2470 BPL NEXTBYTE 2480 LDA #NOTHING 2490 BNE SHOWSTAT 2500 DATAID 2510 LDA #DATA 2520 SHOWSTAT 2530 STA SBYTE 2540 LDY #0 2550 STY ATRACT ; Attract off 2560 STA (VTOC),Y 2570 ; 2580 ; Update VTOC addr pointer 2590 ; 2600 INC VTOC 2610 BNE UPCOUNT 2620 INC VTOC+1 2630 UPCOUNT 2640 INC RTOTAL 2650 BNE SECTMAX 2660 INC RTOTAL+1 2670 ; 2680 ; End of disk? 2690 ; 2700 SECTMAX 2710 LDA RTOTAL+1 2720 CMP #$02 2730 BNE DATACHECK 2740 LDA RTOTAL 2750 CMP #$D1 2760 BEQ WRITER 2770 ; 2780 ; Check for data sector 2790 ; 2800 DATACHECK 2810 LDA SBYTE 2820 CMP #DATA 2830 BNE RLOOP 2840 ; 2850 ; Add 128 to buffer pointers 2860 ; 2870 CLC 2880 LDA DBUFLO 2890 ADC #$80 2900 STA DBUFLO 2910 STA BPOINT 2920 LDA DBUFHI 2930 ADC #0 2940 STA DBUFHI 2950 STA BPOINT+1 2960 ; 2970 ; Check if buffer full 2980 ; 2990 CMP #$BC ; Top of buffer? 3000 BNE RLOOP ; No; keep going 3010 ; 3020 ; ******************* 3030 ; * WRITE Routine * 3040 ; ******************* 3050 ; 3060 WRITER 3070 ; 3080 ; Init VTOC pointer 3090 ; 3100 CLC 3110 LDA SCREEN 3120 ADC WTOTAL 3130 STA VTOC 3140 LDA SCREEN+1 3150 ADC WTOTAL+1 3160 STA VTOC+1 3170 ; 3180 ; Print WRITE prompt 3190 ; 3200 LDA #WPROMPT&255 3210 STA PPOINT 3220 LDA #WPROMPT/256 3230 JSR MESSAGE 3240 ; 3250 JSR WAIT ; START key 3260 ; 3270 DEC FFLAG 3280 BNE NOFORM ; Skip if Pass 2 3290 ; 3300 ; Format disk 3310 ; 3320 ERASE 3330 JSR DUMPOINT ; buffer addr 3340 LDA #FORMAT 3350 STA DCOMND ; format cmnd 3360 JSR DISKIO ; Do it! 3370 ; 3380 ; Check for okay format 3390 ; 3400 LDA DSTATS 3410 CMP #1 3420 BEQ NOFORM 3430 ; 3440 ; Print bad format warning 3450 ; 3460 LDA #BADFORM&255 3470 STA PPOINT 3480 LDA #BADFORM/256 3490 JSR MESSAGE 3500 JSR WAIT 3510 BEQ ERASE 3520 ; 3530 NOFORM 3540 ; 3550 JSR REPOINT ; Reset pntrs 3560 ; 3570 LDA #WRITE 3580 STA DCOMND ; WRITE command 3590 ; 3600 ; ************************* 3610 ; * Start of WRITE loop * 3620 ; ************************* 3630 ; 3640 WLOOP 3650 ; 3660 ; Update setor # 3670 ; 3680 LDA WTOTAL 3690 STA SECTLO 3700 LDA WTOTAL+1 3710 STA SECTHI 3720 ; 3730 ; Get status of next read 3740 ; 3750 LDY #0 3760 STY ATRACT 3770 LDA (VTOC),Y 3780 STA SBYTE 3790 ; 3800 ; Branch depending on status 3810 ; 3820 CMP #DATA 3830 BNE SKIPSECT ; If no data 3840 ; 3850 DWRITE 3860 JSR DISKIO ; Write sector 3870 BMI DWRITE 3880 ; 3890 ; Display write status 3900 ; 3910 SKIPSECT 3920 LDA #WRITTEN 3930 LDY #0 3940 STA (VTOC),Y 3950 ; 3960 ; Update VTOC, WTOTAL 3970 ; 3980 INC VTOC 3990 BNE WRUP 4000 INC VTOC+1 4010 WRUP 4020 INC WTOTAL 4030 BNE WSECTMAX 4040 INC WTOTAL+1 4050 WSECTMAX 4060 LDA WTOTAL+1 4070 CMP #$02 4080 BNE BUFLOOK 4090 LDA WTOTAL 4100 CMP #$D1 4110 BEQ FINISHED 4120 ; 4130 ; Should buffer addr be updated? 4140 ; 4150 BUFLOOK 4160 LDA SBYTE 4170 CMP #DATA ; Update bufadr? 4180 BNE WLOOP ; No; next sect 4190 ; 4200 ; Update buffer address 4210 ; 4220 CLC 4230 LDA DBUFLO 4240 ADC #$80 4250 STA DBUFLO 4260 LDA DBUFHI 4270 ADC #0 4280 STA DBUFHI 4290 ; 4300 ; Buffer full? 4310 ; 4320 FULBUF 4330 CMP #$BC 4340 BNE WLOOP 4350 JMP READER ; Next pass 4360 ; 4370 ; ***************** 4380 ; * End routine * 4390 ; ***************** 4400 ; 4410 FINISHED 4420 LDA #COMPLETE&255 4430 STA PPOINT 4440 LDA #COMPLETE/256 4450 JSR MESSAGE 4460 DECIDE 4470 LDA CONSOL 4480 CMP #6 ; START press? 4490 BEQ RERUN 4500 CMP #3 ; OPTION? 4510 BNE DECIDE 4520 JSR LETGO 4530 JMP COLDSV ; Cold boot 4540 RERUN 4550 JSR LETGO 4560 JMP RABBIT ; Re-run Rabbit 4570 ; 4580 ; ***************** 4590 ; * Subroutines * 4600 ; ***************** 4610 ; 4620 ; Point to dummy buffer 4630 ; 4640 DUMPOINT 4650 LDA #DUMMY&255 4660 STA DBUFLO 4670 LDA #DUMMY/256 4680 STA DBUFHI 4690 RTS 4700 ; 4710 ; Point to top screen line 4720 ; 4730 TOPLINE 4740 CLC 4750 LDA SAVMSC 4760 ADC #42 ; X=2, Y=1 4770 STA LINE 4780 LDA SAVMSC+1 4790 ADC #0 4800 STA LINE+1 4810 RTS 4820 ; 4830 ; Beep and wait for START key 4840 ; 4850 WAIT 4860 LDA #100 ; Freq = 100 4870 STA AUDF1 4880 LDA #$AA ; D & V = 10 4890 STA AUDC1 4900 LDA #0 4910 STA RTCLOK ; Clear count 4920 BEEP 4930 LDA RTCLOK 4940 CMP #15 ; 1/4 sec 4950 BNE BEEP 4960 LDA #0 4970 STA AUDC1 ; Silence! 4980 ; 4990 ; Check key 5000 ; 5010 HOLDIT 5020 LDA CONSOL 5030 CMP #6 5040 BNE HOLDIT ; Pressed? 5050 LETGO 5060 LDA CONSOL 5070 CMP #7 5080 BNE LETGO ; Till released 5090 RTS 5100 ; 5110 ; Print text messages 5120 ; 5130 MESSAGE 5140 STA PPOINT+1 5150 LDY #33 5160 NEXTPRINT 5170 LDA (PPOINT),Y 5180 STA (LINE),Y 5190 DEY 5200 BPL NEXTPRINT 5210 RTS 5220 ; 5230 ; Set buffer pointers 5240 ; 5250 REPOINT 5260 LDA #BUFFER&255 5270 STA BPOINT 5280 STA DBUFLO 5290 LDA #BUFFER/256 5300 STA BPOINT+1 5310 STA DBUFHI 5320 RTS 5330 ; 5340 ; ******************* 5350 ; * Message texts * 5360 ; ******************* 5370 ; 5380 WARNING 5390 .SBYTE "Remove cartridge; requires 48K RAM" 5400 ; 5410 TITLE 5420 .SBYTE "Black Rabbit 2.0 by Brian Moriarty" 5430 ; 5440 RPROMPT 5450 .SBYTE "Insert SOURCE disk, press START " 5460 ; 5470 WPROMPT 5480 .SBYTE "Insert COPY disk, press START " 5490 ; 5500 COMPLETE 5510 .SBYTE "START to re-run, OPTION to boot " 5520 ; 5530 BADFORM 5540 .SBYTE "Replace bad COPY disk, press START" 5550 ; 5560 .END