'=========================================================================== ' Subject: DISK PLAY Date: 10-01-98 (09:58) ' Author: David Karlov Code: QB, PDS ' Origin: davidk@softway.com.au Packet: DISK.ABC '=========================================================================== ' ' Here is something truly bizarre: play music on your disk drive!!! ' That's right, make weird sound effects with a floppy disk while Num, Caps, ' & Scroll dance to the music... ' ' This program will only work if you have a fairly noisy floppy disk drive... ' Some of the newer FDDs are silent and when this program is run, it seems to ' do nothing.... ' Also, you need to have a disk in the drive while running. ' For QB users, start QB with the command line option /L QB to load the ' library necessary for interrupt calls. ' ' NOTE -- Default setup is for a 1.44 MB disk in drive a:, if this does not ' match your configuration then change the constants below..... ' ' David Karlov dkarlov@acs.its.uts.edu.au ' dkarlov@rocketmail.com ' ' If you haven't seen Starfire yet, then check it out now!!!! ' === >>>>> ftp.cdrom.com/pub/games/dos/arcade/starfire.zip <<<<< === ' DEFINT A-Z TYPE RegTypeX AX AS INTEGER bx AS INTEGER cx AS INTEGER DX AS INTEGER bp AS INTEGER si AS INTEGER di AS INTEGER flags AS INTEGER ds AS INTEGER es AS INTEGER END TYPE DECLARE SUB INTERRUPTX (intnum AS INTEGER, inreg AS RegTypeX, outreg AS RegTypeX) DECLARE SUB ReadSector (DriveNum AS INTEGER, TrackNum AS INTEGER, SectorNum AS INTEGER) DECLARE SUB ClearReg () DECLARE SUB IncTrack (inc AS INTEGER) DECLARE SUB LockSet (ln AS INTEGER, c AS INTEGER) DECLARE SUB Init () CONST Dr = 0 ' Use 0 for drive a:, 1 for drive b: CONST DiskType = 3 ' 0 = 5.25 inch 360 KB ' 1 = 5.25 inch 1.2 MB ' 2 = 3.5 inch 720 KB ' 3 = 3.5 inch 1.44 MB DIM SHARED Reg AS RegTypeX DIM SHARED Buffer AS STRING * 512 DIM SHARED Tr AS INTEGER DIM SHARED TrDir AS INTEGER DIM SHARED Pattern(15000) AS INTEGER DIM SHARED NumPat AS INTEGER DIM SHARED Speed AS INTEGER ' 0 = normal, 1 = fast DIM SHARED MaxSect AS INTEGER DIM SHARED MaxTracks AS INTEGER Init c = 0 DO c = (c MOD NumPat) + 1 IF Speed THEN Se = Se + MaxSect - 1 Se = (Se MOD MaxSect) + 1 IF Pattern(c) < 0 THEN DO ' change speed on the fly.... IF Speed = 0 THEN Se = Se + MaxSect - 1 Se = (Se MOD MaxSect) + 1 IF Pattern(c) = -1 THEN Speed = 0 ELSEIF Pattern(c) = -2 THEN Speed = 1 END IF c = (c MOD NumPat) + 1 LOOP UNTIL Pattern(c) >= 0 END IF tc = tc + 1 - (Pattern(c) >= 8) 'ie. if Pattern(c) >= 8 then tc = tc + 2 else tc = tc + 1 LockSet 3, 3 IF tc MOD 2 = 0 THEN LockSet 1, 3 IF tc MOD 4 = 0 THEN LockSet 2, 3 END IF IncTrack Pattern(c) * 4 ReadSector Dr, Tr, Se LOOP UNTIL INKEY$ <> "" ' clear all locks . . . LockSet 1, 0: LockSet 2, 0: LockSet 3, 0 END ' PATTERN DATA..... ' Each number represents one read operation on the disk... the bigger ' the number, the further the R/W heads will move and the louder and ' longer the sound. 0 is a rest, -1 changes speed to slow and -2 changes ' speed to fast. Numbers > 7 will take twice as long as others, since ' the disk will have to rotate twice for this (on my disk drive anyway....) ' Don't use numbers > 10. ' Don't use 6 or 7, they take a varying no. of disk revolutions for ' different speeds. Notes 1 -> 5 use 1 disk revolution with varying ' loudness, 8 -> 10 use 2 disk revolutions. DATA -2,1,2,2,3,3,4,4,5 DATA 3,0,0,0,0,0,0,1,3,0,0,0,0,0,0,1,3,0,0,0,0,0,0,1,3,0,0,0,0,0,0,1 DATA 2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,1,2,0,0,0,2,0,0,0,2,0,0,0,0,2,0,2 DATA 1,0,5,0,1,0,5,0,1,0,5,0,1,0,5,0,1,0,5,0,1,0,5,0,1,0,5,0,1,0,5,1 DATA 2,1,5,1,2,1,5,1,2,1,5,1,2,1,5,2,2,1,5,1,2,1,5,1,2,0,0,0,0,2,3,4 DATA 5,1,1,1,5,1,1,1,5,1,1,1,5,1,1,5,1,5,5,1,5,1,1,1,5,1,5,1,5,1,5,1 DATA 9, 0,9, 0,9, 0,9, 0,9, 9, 9, 0,9, 0,9, 0,9, 0,9, 9 DATA 5,1,1,5,1,1,5,1,1,5,1,1,5,1,5,1,5,1,1,5,1,1,5,1,1,5,1,1,5,1,5,1 DATA 5,1,5,1,5,1,5,1,9, 0,0,0,1,0,1,5,1,5,1,5,1,5,1,9, 0,1,1,4,4,4 DATA 5,0,1,0,5,0,1,0,5,0,1,0,5,0,1,0,5,1,1,0,5,0,1,1,5,1,0,1,5,1,1,1 DATA 5,2,1,5,2,1,3,3,5,2,1,5,1,5,5,5,5,0,5,0,5,0,5,5,0,5,0,2,5,1,4,4 DATA 2,0,5,1,2,0,5,0,2,0,5,0,2,0,5,0,2,2,5,0,2,1,5,0,2,2,5,2,2,5,5,5 DATA 9, 1,1,5,5,1,5,5,1,5,1,5,2,4,1,5,5,5,0,5,0,5,5,0,5,5,4,5,0,5,5 ' use 999 to mark the end of the data. DATA 999 SUB ClearReg Reg.AX = 0: Reg.bx = 0: Reg.cx = 0: Reg.DX = 0 Reg.bp = 0: Reg.si = 0: Reg.di = 0: Reg.flags = 0 Reg.ds = 0: Reg.es = 0 END SUB SUB IncTrack (inc AS INTEGER) ' move the R/W heads by (inc) tracks. IF TrDir = 1 THEN IF Tr + inc <= MaxTracks THEN Tr = Tr + inc IF Tr = MaxTracks THEN TrDir = -1 ELSE TrDir = -1 Tr = Tr - inc IF Tr < 0 THEN Tr = 0 END IF ELSE IF Tr - inc >= 0 THEN Tr = Tr - inc IF Tr = 0 THEN TrDir = 1 ELSE TrDir = 1 Tr = Tr + inc IF Tr > MaxTracks THEN Tr = MaxTracks END IF END IF END SUB SUB Init ' some boring stuff... SELECT CASE DiskType CASE 0 ' 5.25 inch 360 KB MaxSect = 9 MaxTracks = 39 CASE 1 ' 5.25 inch 1.2 MB MaxSect = 15 MaxTracks = 79 CASE 2 ' 3.5 inch 720 KB MaxSect = 9 MaxTracks = 79 CASE 3 ' 3.5 inch 1.44 MB MaxSect = 18 MaxTracks = 79 END SELECT c = 0 DO c = c + 1 READ Pattern(c) LOOP UNTIL Pattern(c) = 999 NumPat = c - 1 TrDir = 1: Tr = MaxTracks \ 2 RANDOMIZE TIMER ReadSector 0, Tr, 0 END SUB SUB LockSet (ln, c) ' turns Caps/Num/Scroll Lock on, off, or toggles DEF SEG = 0 IF ln = 1 THEN mask% = &H40 'Caps Lock IF ln = 2 THEN mask% = &H20 'Num Lock IF ln = 3 THEN mask% = &H10 'Scroll Lock cur% = PEEK(&H417) IF c = 1 THEN POKE &H417, cur% OR mask% 'on IF c = 2 OR c = 0 THEN POKE &H417, cur% AND (NOT mask%) 'off IF c = 3 THEN POKE &H417, cur% XOR mask% 'toggle DEF SEG END SUB SUB ReadSector (DriveNum AS INTEGER, TrackNum AS INTEGER, SectorNum AS INTEGER) ' Read a sector from drive DriveNum. ClearReg Reg.AX = CVI(CHR$(1) + CHR$(2)) Reg.cx = CVI(CHR$(SectorNum) + CHR$(TrackNum)) Reg.DX = CVI(CHR$(DriveNum) + CHR$(0)) Reg.es = VARSEG(Buffer) Reg.bx = VARPTR(Buffer) c = 0 DO DO CALL INTERRUPTX(&H13, Reg, Reg) c = c + 1 IF ((Reg.flags AND 2048) > 0 AND (Reg.flags AND 128) = 0) THEN PRINT "Disk not found in drive a:" LockSet 1, 0: LockSet 2, 0: LockSet 3, 0 END END IF LOOP UNTIL (Reg.flags AND 1) = 0 OR c MOD 4 = 0 IF c MOD 4 = 0 THEN SLEEP 1 LOOP UNTIL c MOD 4 <> 0 END SUB