GW-BASIC (which was included prior to DOS 5.x) had the MOTOR command to control the cassette motor. I don't know if it actually worked though. In Microsoft's released GW-BASIC 1.0 source, it is a no-op and just prints an error message – https://github.com/microsoft/GW-BASIC/blob/master/GIOCAS.ASM [EDIT: I just disassembled GWBASIC.EXE version 3.23, I can see the calls to the BIOS INT 15h cassette API, so it isn't just a no-op in the binary.]
If it worked at all, it would have worked by calling INT 15h functions 0-1, which was part of the BIOS cassette API. I believe in ROM BASIC on the original IBM PC and PCjr, the MOTOR command was actually implemented to call those BIOS routines, and the BIOS actually had code to talk to the cassette port. I think, on subsequent machines, the BIOS routines were stubbed out and just returned an error.
GW-BASIC was the only part of MS-DOS which had any reference to the cassette tape. The more core parts of MS-DOS (IO.SYS, MSDOS.SYS, COMMAND.COM) knew absolutely nothing about it.
If it worked at all, it would have worked by calling INT 15h functions 0-1, which was part of the BIOS cassette API. I believe in ROM BASIC on the original IBM PC and PCjr, the MOTOR command was actually implemented to call those BIOS routines, and the BIOS actually had code to talk to the cassette port. I think, on subsequent machines, the BIOS routines were stubbed out and just returned an error.
GW-BASIC was the only part of MS-DOS which had any reference to the cassette tape. The more core parts of MS-DOS (IO.SYS, MSDOS.SYS, COMMAND.COM) knew absolutely nothing about it.