10 .OPT NO LIST 20 .SET 2,120 30 .SET 4,80 0100 .TITLE "ATARI 1050 DISK DRIVE O.S." 0110 * ATARI 1050 DISK DRIVE OPERATING SYSTEM 0120 * 0130 * based on listings of Michael Pascher (Abbuc-Buch) 0140 * and W. Derks 0150 * 0160 * RAM $0000 - $00FF 0170 * TIMER,IO $0280 - $029F (6532) 0180 * memory used by ports: 0190 * PORT A ($0280) 0200 * bit 0 drive number read 0210 * 1 " read 0220 * 2 write 0230 * 3 motor off write 0240 * 4 > track 20 write 0250 * 5 single density write 0260 * 6 IRQ floppy ? read 0270 * 7 data request floppy NAK read 0280 * 0290 * PORT B ($0282) 0300 * bit 0 data out (to CPU) write 0310 * 1 read 0320 * 2 step motor phase 1 write 0330 * 3 step motor phase 2 write 0340 * 4 step motor phase 3 write 0350 * 5 step motor phase 4 write 0360 * 6 data in (from CPU) read 0370 * 7 command (from CPU) read 0380 * 0390 * memory usage 0400 * 0410 * sector buffer from $0000 to $007F 0420 * 0430 SEKBUF = $00 0440 * 0450 * buffer for address info after READ ADRESS 0460 * TRACK, SIDE, SEKTOR, LENGTH, CRC1, CRC2 0470 * 0480 ATRACK = $7A 0490 ASEK = $7C 0500 ALEN = $7D 0510 ACRC1 = $7E 0520 ACRC2 = $7F 0530 * 0540 * buffer for command and sector number 0550 * 0560 RDRIVE = $80 0570 RKOMND = $81 0580 RSEKL = $82 0590 RSEKH = $83 0600 * 0610 FDATA = $85 0620 FSNR = $87 0630 FTNR = $89 0640 * 0650 MOTIML = $8B timer for MOTOR ON 0660 MOTIMH = $8C 0670 TRACK = $8D track # 0680 SEKTOR = $8E sector # 0690 CSTAT = $8F controller status shadow 0700 STATUS = $90 floppy drive status 0710 ERROR = $91 error byte 0720 COUNT = $92 counter 0730 DIR = $93 step direction floppy 0740 FLAG = $94 0750 HZ95 = $95 aux byte for track/sector calculation 0760 SEEKERR = $96 0770 TRKERR = $97 0780 KOMND = $98 command 0 - 7 0790 JUMPL = $99 jump vector 0800 JUMPH = $9A 0810 DSTAT = $9B drive status, to detect change of diskette 0820 MUSTERNR = $9C 0830 HZ9D = $9D 0840 HZ9E = $9E 0850 PHASE = $9F actual phase of step motor 0860 FMERK = $A0 0870 ERRADR = $A3 error addr for floppy test 0880 HZA4 = $A4 0890 BUFFER = $A5 temp for floppy test 0900 STEPCNT = $AF step count 0910 STEPS = $B0 steps to do 0920 SBUF = $B1 write buffer and track count for floppy test 0930 DRA = $0280 data register PORT A 0940 DDRA = $0281 data direction register PORT A 0950 DRB = $0282 data register PORT B 0960 DDRB = $0283 data direction register PORT B 0970 TIM64 = $0296 timer : 64 0980 TIM1024 = $0297 timer : 1024 0990 T1024I = $029F timer : 1024 INTERRUPT ENABLE 1000 FCNTRL = $0400 control register floppy controller 1010 TRKREG = $0401 track register 1020 SEKREG = $0402 sector register 1030 DATREG = $0403 data register 1040 * 1050 *= $F000 1060 * 1070 * masks for phases of step motor 1080 * 1090 PHASE1 .BYTE $FB each time 1 phase on 0 1100 .BYTE $F7 1110 .BYTE $EF 1120 PHASE4 .BYTE $DF 1130 * 1140 .BYTE $57 1150 * 1160 * command table 1170 * 1180 READSEK .BYTE $52 read sector 1190 WRITSEK .BYTE $50 write sector without verify 1200 WRVESEK .BYTE $57 write sector with verify 1210 .BYTE $53 status request 1220 .BYTE $21 format single density 1230 .BYTE $22 format enhanced density 1240 SPEZIAL .BYTE $23 special 1250 * first byte in following data block 1260 * 0 or 1 second byte to FLAG for command $24 1270 * 2 second byte contains sector number 1280 * it will be tested if sector after sector 1 on 1290 * each track is less or equal to this sector # 1300 * 3 do 1 step, direction in second byte ($FF or 1) 1310 * 4 floppy test 1320 * the diskette is enhanced formatted, then 1330 * several tests are done. The test returns 1340 * a 'C' or 'E' (error) 1350 * 5 SEEK on track in second byte 1360 .BYTE $24 send time for one rotation in 1370 * first two bytes of block (if command $23 00 00) or send motor rpms (if command $23 00 01) 1380 * The time is stored in first 2 bytes of the sector 1390 * send after the test 1400 * 1410 DRVNR .BYTE $33 drive number 1420 .BYTE $32,$34,$31 1430 .BYTE $FF end of table 1440 .BYTE 0 1450 * 1460 * start of program after RESET 1470 * 1480 * port init & hardware test 1490 START CLD 1500 LDX #$FF reset stack 1510 TXS 1520 LDA #$3C PORT A bit 2 - 5 output 1530 STA DDRA 1540 LDA #$38 set bits 3-5 1550 STA DRA 1560 LDA DRA read register 1570 AND #$3C 1580 CMP #$38 check for written value 1590 BNE FAIL no, FATAL ERROR 1600 LDA #$3D PORT B bit 0, 2-5 output 1610 STA DDRB 1620 LDA #$3D set all bits 1630 STA DRB 1640 LDA DRB read register 1650 AND #$3D 1660 CMP #$3D check for written value 1670 BNE FAIL no, FATAL ERROR 1680 LDA #$D0 1690 STA FCNTRL force interrupt floppy controller 1700 LDX #$15 1710 DEL1 DEX wait a little while 1720 BNE DEL1 1730 LDA FCNTRL controller ready? 1740 AND #1 1750 BNE FAIL no, FATAL ERROR 1760 LDA #$55 test sector & track register 1770 STA TRKREG 1780 STA SEKREG 1790 LDX #$1E 1800 DEL2 DEX some respite 1810 BNE DEL2 1820 EOR TRKREG ok? 1830 BNE FAIL no, FATAL ERROR 1840 LDA #$55 1850 EOR SEKREG 1860 BNE FAIL also for track register 1870 LDA #$48 1880 STA FCNTRL HEAD LOAD & STEP IN 1890 LDX #$28 delay 1900 JSR DELAY1 wait X * 71 cycles (?) 1910 LDA FCNTRL busy? 1920 AND #1 1930 BEQ FAIL no, something is rotten 1940 LDX #$28 1950 JSR DELAY1 wait another time 1960 LDA FCNTRL 1970 AND #1 now it must by ok 1980 BNE FAIL otherwise it't wrong 1990 LDA #$F0 get checksum of PROM 2000 STA SEKBUF+1 start address 2010 LDA #0 2020 STA SEKBUF 2030 CLC 2040 TAY 2050 PCHECK ADC (SEKBUF),Y add PROM bytes 2060 INY 2070 BNE PCHECK 2080 INC SEKBUF+1 next page 2090 BNE PCHECK 2100 ORA #0 result must be zero 2110 STA SEKBUF 2120 BEQ TSTOK if so, everything is fine 2130 * 2140 * fatal error, break 2150 * 2160 FAIL BRK hardware defect 2170 * 2180 * hardware test ok, do RAM test 2190 * 2200 TSTOK LDX #0 write to RAM 2210 RAMTST TXA 2220 STA SEKBUF,X 2230 INX 2240 BNE RAMTST 2250 RAMTST1 TXA read it 2260 CMP SEKBUF,X and compare 2270 BNE FAIL 2280 DEX 2290 BNE RAMTST1 2300 TXA 2310 RAMCLR STA SEKBUF,X write another time 2320 INX to zero out 2330 BNE RAMCLR 2340 * 2350 * for now, init motor 2360 * 2370 LDX #3 step motor phase 3 2380 STX PHASE 2390 LDA PHASE4 bitpattern of phase 2400 AND DRB to PORT B 2410 STA DRB 2420 JSR TMOTON motor on?, otherwise start motor 2430 LDA #0 track 0 2440 STA TRACK 2450 JSR SIREST 10 steps in, then restore 2460 LDA FCNTRL controller status 2470 STA CSTAT to RAM 2480 AND #$80 drive ready? 2490 BNE DRDY yes 2500 JSR IDENT otherwise, init drive, density etc 2510 * 2520 * here loops the program if nothing else to do 2530 * wait for command or new diskette 2540 * 2550 DRDY JSR DSKCHG change of disk? 2560 JSR TKOMND command from CPU, if so -- do it 2570 LDA DRA motor on? 2580 AND #8 2590 BNE DRDY no 2600 LDX #8 yes, delay 2610 DEL3 DEX 2620 BNE DEL3 2630 INC MOTIML incr MOTOR ON timer 2640 BNE DRDY 2650 INC MOTIMH also msb 2660 BNE DRDY 2670 JSR MOTOFF if timer expires, stop motor 2680 JMP DRDY end of main loop 2690 * 2700 * look for change of diskette 2710 * 2720 DSKCHG LDA #$80 2730 AND FCNTRL controller bit ready 2740 TAX still the same? 2750 EOR DSTAT if not 2760 BNE NEWDSK it's a change 2770 RTS for motor is turned on each change 2780 NEWDSK STX DSTAT store new status 2790 TXA 2800 BPL DIDENT motor off? 2810 JSR MOTOFF no, turn it off 2820 JMP UPDATE update status 2830 * 2840 DIDENT JSR TMOTON identify new diskette 2850 JSR IDENT 2860 UPDATE LDA FCNTRL update status 2870 STA CSTAT 2880 RTS 2890 * 2900 * turn motor off 2910 * 2920 MOTOFF LDA DRA turn motor off 2930 ORA #8 via bit 3 of PORT A 2940 STA DRA 2950 LDA #$3C 2960 ORA DRB 2970 STA DRB all step motor phases off 2980 LDA STATUS 2990 AND #$EF indicate MOTOR OFF to STATUS 3000 STA STATUS 3010 RTS 3020 * 3030 * turn motor on 3040 * 3050 MOTON LDA DRA turn motor on 3060 AND #$F7 3070 STA DRA 3080 LDX PHASE step motor in 3090 LDA DRB right phase 3100 AND PHASE1,X 3110 STA DRB 3120 LDA #0 reset MOTOR ON timer 3130 STA MOTIMH 3140 STA MOTIML 3150 LDA STATUS indicate MOTOR ON to STATUS 3160 ORA #$10 3170 STA STATUS 3180 LDX #5 3190 JSR DELAY2 give motor some time to speed up 3200 RTS 3210 * 3220 * identify inserted diskette 3230 * single or enhanced density 3240 * 3250 IDENT JSR RESTORE 3260 LDA DRA 3270 AND #$DF try enhanced 3280 STA DRA 3290 JSR RDADR READ ADRESS command 3300 BEQ IDENT1 succesfull read? 3310 JSR RDADR no, try again 3320 BEQ IDENT1 ok 3330 LDA DRA otherwise, try single 3340 EOR #$20 3350 STA DRA 3360 LDA STATUS indicate single 3370 AND #$7F 3380 STA STATUS 3390 RTS 3400 IDENT1 LDA STATUS 3410 ORA #$80 indicate enhanced 3420 STA STATUS 3430 RTS 3440 * 3450 * turn motor on if not on 3460 * & reset MOTOR ON timer 3470 * 3480 TMOTON LDA DRA 3490 AND #8 already on? 3500 BEQ ZF18A 3510 JSR MOTON no, turn it on 3520 ZF18A LDA #0 3530 STA MOTIML 3540 STA MOTIMH reset timer 3550 RTS 3560 * 3570 * delay, (X) * 100 micro seconds 3580 * 3590 DELAY1 LDY #$12 3600 D11 DEY 3610 BNE D11 3620 DEX 3630 NOP 3640 NOP 3650 BNE DELAY1 3660 RTS 3670 * 3680 * delay, (X) * 10 milliseconds 3690 * 3700 DELAY2 STX SBUF SBUF used as counter 3710 D21 LDY #4 3720 STY SBUF+1 3730 D22 LDX #$FA 3740 JSR DELAY1 3750 DEC SBUF+1 3760 BNE D22 3770 DEC SBUF 3780 BNE D21 3790 RTS 3800 * 3810 * delay, (X) * 5 + 12 micro seconds 3820 * 3830 DELAY3 DEY 3840 BNE DELAY3 3850 RTS 3860 * 3870 * 10 steps to the middle, and restore 3880 * 3890 SIREST LDA #10 3900 JSR DOSTEPS make the steps 3910 * 3920 * restore on track 0 3930 * 3940 RESTORE JSR FORCE force IRQ 3950 JSR FORCE interrupt floppy command 3960 LDA #$FF direction: from the middle 3970 STA DIR 3980 LDA #0 3990 STA STEPCNT no steps 4000 STA STEPS 4010 RESTOR1 LDA FCNTRL on track 0? 4020 AND #4 4030 BEQ RESTOR2 br if so 4040 JSR HSTEP make half a step 4050 JMP RESTOR1 until on track 0 4060 RESTOR2 LDA PHASE in phase 4? 4070 CMP #3 4080 BEQ RESTOR3 br if so 4090 JSR HSTEP otherwise, go on 4100 JMP RESTOR2 until on track 0, phase 4 4110 RESTOR3 LDA #0 4120 STA TRKREG reset track register 4130 STA STEPCNT and step counter 4140 LDX #$C8 20 milli seconds delay 4150 JSR DELAY1 4160 RTS 4170 * 4180 * make half a step 4190 * the step motor runs a cyclus of 4 phases, equal to 2 tracks 4200 * 4210 HSTEP JSR DOHSTEP make half a step 4220 JSR FORCE interrupt floppy command 4230 LDX #$64 10 ms delay 4240 JMP DELAY1 4250 * 4260 * do half a step 4270 * 4280 DOHSTEP INC STEPCNT incr counter 4290 LDA STEPCNT 4300 CMP #$78 already 120 steps? 4310 BCS STEPERR if so, something wrong 4320 LDA DRA motor on? 4330 AND #8 4340 BEQ STEP is so, alright 4350 STEPERR BRK step error: motor off or too many steps 4360 STEP LDX PHASE 4370 LDA PHASE1,X get mask for phase 4380 EOR #$FF invert 4390 TAY 4400 BIT DIR get step direction 4410 BPL STEPM for following phase 4420 INX step forward 4430 CPX #4 cyclus done? 4440 BNE STEP1 4450 LDX #0 if so, do it again 4460 BEQ STEP1 4470 STEPM DEX step backward 4480 BPL STEP1 cyclus done? 4490 LDX #3 if so, do it again backward 4500 STEP1 STX PHASE save new phase 4510 TYA reset old phase 4520 ORA DRB 4530 AND PHASE1,X set new phase 4540 STA DRB 4550 RTS 4560 * 4570 * seek track number in 008D 4580 * 4590 SEEK JSR FORCE interrupt actual command 4600 LDA TRACK get destination track 4610 SEC 4620 SBC TRKREG subtract actual track 4630 BNE DOSTEPS already there? 4640 RTS yes, done 4650 * 4660 * make as many steps as value in accu 4670 * 4680 DOSTEPS BMI DOST1 step backward? 4690 LDX #1 no, forward 4700 BPL DOSTEP1 4710 DOST1 LDX #$FF backward 4720 EOR #$FF get two's complement 4730 CLC 4740 ADC #1 4750 DOSTEP1 ASL A two times (2 phases/step) 4760 BPL DOSTEP2 br if ok 4770 JSR RESTORE otherwise too many steps: restore 4780 LDA #$80 indicate error 4790 STA STATUS 4800 RTS 4810 DOSTEP2 STA STEPS number of steps 4820 STX DIR direction 4830 LDA #0 4840 STA STEPCNT reset count of error steps 4850 DOSTEP3 JSR HSTEP make half a step 4860 DEC STEPS all done? 4870 BNE DOSTEP3 no, continue 4880 BIT DIR backward step? 4890 BMI CHKTRK br if so 4900 LDA #$FF otherwise step backward 4910 STA STEPS but first one step too much 4920 LDA #0 forward, so track will always 4930 STA STEPCNT be encountered from the 4940 JSR HSTEP same direction 4950 LDA #$FF 4960 STA DIR 4970 JSR HSTEP step backward 4980 LDA #0 reset error count 4990 STA STEPS 5000 STA STEPCNT 5010 * 5020 * set bit 4 of PORT A for tracks > track 20 5030 * 5040 CHKTRK LDA TRACK 5050 STA TRKREG actual track in track register 5060 CMP #20 greater then 20? 5070 BCC KTR20 no 5080 LDA #$10 otherwise, set bit 4 of PORT A 5090 ORA DRA 5100 BNE GTR20 br always 5110 KTR20 LDA #$EF reset bit 4 of PORT A 5120 AND DRA for track less then 20 5130 GTR20 STA DRA 5140 LDX #$C8 5150 JSR DELAY1 20 ms delay after SEEK 5160 * 5170 * force IRQ, interrupt floppy command 5180 * 5190 DFORCE JSR FORCE two times force IRQ 5200 FORCE LDA #$D0 5210 STA FCNTRL command force IRQ 5220 LDX #7 short delay 5230 FORC1 DEX 5240 BNE FORC1 5250 LDA #0 5260 FORC2 BIT FCNTRL wait until 5270 BNE FORC2 controller ready 5280 RTS 5290 * 5300 * command from CPU? 5310 * 5320 TKOMND LDA #2 5330 BIT DRB test bit 1 of PORT B ??? 5340 BNE NOKOM 5350 BMI TKOM1 bit 7 of PORT B = 1? 5360 NOKOM RTS no command from CPU 5370 * 5380 * link other parts 5390 * 5400 .INCLUDE #D8:FLOPOS2.M65 5410 .OPT LIST 5420 .INCLUDE #D8:FLOPOS3.M65 5430 .INCLUDE #D8:FLOPOS4.M65 5440 .INCLUDE #D8:FLOPOS5.M65 5450 .OPT NO LIST