My article about CD-ROM programming has been published.
ZXNet echo conference «code.zx»
From Vlad Sotnikov → To All 21 May 2002
Hello All!
Subject At http://www.zx-news.narod.ru/zxn/cdromzx.htm
Comments/suggestions for soap.
Vega/ex-Style Group.
FIDO: 2:5030/885.34 ZXNET: 500:812/5.13 E-mail: vega56@mail.ru
From Kirill Frolov → To Nikolaj Amosov 23 May 2002
Press RESET immediately, Nikolaj!
22 May 02 21:06, Nikolaj Amosov wrote to Vlad Sotnikov:
VS>> Subject. At http://www.zx-news.narod.ru/zxn/cdromzx.htm
VS>> Comments/suggestions in advance.
NA> Like instead of ZX-NEWS or something? Can I do it in text soap, but in general
NA> you can go here too, because it’s in the topic.
(C) Vlad Sotnikov/Vega, 2002 (vega56@mail.ru)
(R) The ZX-News Site (www.zx-news.narod.ru)
FEATURES OF PROGRAMMING CD-ROM ON THE SPECTRUM
Contents
1. Introduction
2. A little about CD-ROM
3. CD formats
3.1. "Red Book"
3.2. "Yellow Book"
3.3. ISO-9660
4. Routines for SMUC
4.1. Routines for NEMO HDD controller
5. ATA commands
6. Determining the presence of a CD-ROM
7. CD-ROM identification table
8. Transfer of ATAPI packet
9. Description of commands
General commands
9.1. "Dummy"
9.2. Positioning
9.3. Tray management
Information commands
9.4. Reading manufacturer parameters
9.5. Getting general parameters
9.6. Setting General Settings
9.7. Operation error code
9.8. Determining disk size
9.9. Audio Information9.10. Sector information
9.11. Track information
Audio disk management commands
9.12. Playing audio in blocks
9.13. Playing audio in MSF
9.14. Stop/resume playback
9.15. Stop playing
Read Data Commands
9.16. Reading data in MFS
9.17. Reading data in sectors
10. Example of reading data on Spectrum
11. Disk file system structure
11.1. TOC (Disc Table of Contents)
11.2. Catalog. Description of files
12. Conclusion
1. INTRODUCTION
═В═
newspaper ZX-News #54 I published an article about
features of hard drive programming on the Spectrum.
Numerous letters that came to me after the publication of the article,
showed that interest in low-level programming
There is quite a lot of equipment among spektrumists. What,
in fact, prompted me to write a continuation of the article, where
I want to tell you about another IDE device that received
Now universally accepted - CD-ROM.
Its appearance on the Spectrum is not accidental - the prerequisite was
creation of IDE controllers. This is SMUC on Scorpion, and
HDD controller by Nemo. And although the main purpose of creating these
devices was the connection of the hard drive, however, a side effect
the result was the ability to work with CD-ROM. Metogether with Pavel Vasiliev (POL) a program has already been written,
allows you to read data from CDs. Program
supports both controllers (SMUC and NEMO). So that's it,
what is written here serves the sole purpose of making it easier for people
writing similar programs, but in no way can claim
for a documentary description of the device. So they can
encounter errors and inaccuracies. However,
The information provided here should make it a lot easier
people who decide to support CD-ROM in their
programs, this work.
Unlike my previous article, designed for
for beginners, here I decided not to explain too much
times of elementary things and concepts to limit the text to
volume. I assume that the reader has already read my article
in ZX-News #54 and has basic programming skills
in assembler and hard drive programming. Purpose
registers and many of the routines I use here, you
You can find it in my article on HDD programming.
2. A LITTLE ABOUT CD-ROM
In its features, CD-ROM is very different from
Winchester. Firstly, CD-ROM can be classified as
Read-only devices. Despite the fact that the practice of recording on
The compact disc has now spread quite widely, however
doing less is quite difficult, and is unlikely to be possibleon Spectrum. However, despite this, CD-ROM is
is now one of the most popular external storage media in
mainly due to the cheapness of CDs and the convenience
using it as an archive.
CD-ROM is an external storage medium. It consists of
A CD player into which CDs are inserted. Volume
disks range from 640 to 700 megabytes. You can also
highlight another important part of the CD-ROM - the tray. This
platform on which CDs are placed. She is
moving part of the device, and is also programmable
management.
Like a hard drive, a CD-ROM can be either a Master or a Slave
device. However, the principle of issuing commands is somewhat
different from the one used with the hard drive, and
was described by me in a previous article. For programming
the hard drive used a set of registers (or ports),
each of whom performed a specific role
(command register, status register, data register), and
commands were given through the command register, and the set of these
teams were limited. The situation is completely different with CD-ROM.
The command is given via a data packet, usually consisting of 12
byte. This standard is called ATAPI (ATA Packet
Interface - Packet ATA protocol). To Command Register
the command “write data” is given, and then through the RegistersA packet of 12 bytes is transferred to the CD-ROM. The reason for these
difficulties are that the ATA set of instructions and registers is not
suitable for some CD-ROM command structures. Therefore
ATAPI devices support only a minimum set
traditional ATA commands.
3. CD FORMATS
3.1. "Red Book"
Compact discs were originally created by Philips and Sony.
to reproduce audio information. Now this is -
regular audio discs that can be played on any
CD player. Data format defined as "Red
book" and looks like this: on the disk there is
a certain number of audio tracks (tracks). The track is
usually one song. The track, in turn, is divided into
sectors that are 1/75 of a second in length and contain
2352 bytes of data in audio form.
3.2. "Yellow Book"
Later, the same manufacturing companies introduced another
disk standard known as the "Yellow Book". It contained
provided the ability to save information on disk, not
being audio. The sector format has been revised: now
2352 bytes of the audio sector were perceived as follows
way:
12 bytes of synchronization.
4 bytes of head information.
2048 bytes of user data.
288 bytes of error correction.
This is the basic standard. There are also "Green" standardsbook", "Orange book", but they are all variations
these two main standards. In addition, there is
ISO-9660 standard, which was originally intended for
data storage and has its own file structure. B
It does not provide storage of audio information. At the same time
you need to keep in mind that modern CD-ROMs independently
determine the standard in which the disc is recorded and operate either
with audio or data. In the second case we need
read 2048 bytes of data. This is the length of the sector
CD and the minimum length of read data.
3.3. ISO-9660
The ISO-9660 standard defines the file storage structure on
disk. It will be described in detail by me in Chapter 11 -
"Disk file system structure." To PC for conversion
This structure in MS-DOS format is the file MSCDEX.EXE. On
in fact, it's a pretty easy to understand file
structure. The disk is divided into sectors of 2048 bytes. At 16
sector contains information about the disk and location
root directory. All directories follow
CD, and then come the files. Moreover, the information in
files are located sequentially, sector by sector.
This structure is very similar to TR-DOS.
4. SUBROUTINES FOR SMUC
Despite the fact that, as I wrote above, I will refer to
examples in my previous article, however, I decidedgive here the main routines used in
programming an IDE device (hard drive, CD-ROM) via
SMUC controller. This is done so that without text everything
the examples given here were assembled without errors and
were a fully functional driver for working
from CD-ROM.
Firstly, I will once again list SMUC's ports, which
correspond to the registers of the IDE device. I remind you once again,
that they are called from under TR-DOS.
Read from port || Write to port
#FFBE Command Register || Status Register
#FEBE Drive/Head Register
#FDBE Cylinder register (high part)
#FCBE Cylinder register (low part)
#FBBE Sector number register
#FABE Sector counter register
#F9BE Error register || Additional register opportunities
#F8BE Data register (low part)
#D8BE Data register (high part)
;Write a value to the port.
;IN: [BC] - port number
; [A] - value
OUT_A LD IX,#3FF0
PUSH IX
JP #3D2F
;Read value from port.
;IN: [BC] - port number
;OUT: [A] - value
IN_A LD IX,#3FF3
PUSH IX
JP #3D2F
;Waiting for the device to become free.
NO_BSY LD BC,#FFBE
CALL IN_A
RLCA: RET NC
JR NO_BSY
;Waiting for data transfer to be ready.
WAIT_DRQ LD BC,#FFBECALL IN_A
BIT 3,A
RET NZ
JR WAIT_DRQ
;Let's see if an error has occurred.
NO_ERROR LD BC,#FFBE
CALL IN_A
RLCA
RET
;Selecting a Slave device.
SEL_SLAVE LD A,#B0
LD BC,#FEBE
CALL OUT_A
LD BC,#FEBE
CALL IN_A
RLCA: RET
;Write a number to the Cylinder Register.
HL_TO_LEN LD BC,#FCBE
LD A,L
CALL OUT_A
LD BC,#FDBE
LD A,H
CALL OUT_A
RET
;Reading a number from the Cylinder Register.
LEN_TO_HL LD BC,#FCBE
CALL IN_A
LD L,A
LD BC,#FDBE
CALL IN_A
LD H,A
RET
4.1 Routines for the NEMO HDD controller
For those who use the NEMO hard drive controller (for
computer KAY), I will also give individual subroutines.
This controller is convenient because it does not require
separate Professional ROM, as for the SMUC controller on Scorpion.
This controller just needs to be inserted into the system connector
any Spectrum-compatible computer. In addition, for
accessing it does not need to call the TR-DOS ROM every time -
the ports here are open, which, in turn, increases
speed of work with CD-ROM. And the last thing is the controller circuit
so simple that it can be assembled
on your own.
Read from port || Write to port#F0 Command register || Status Register
#D0 Drive/Head Register
#B0 Cylinder register (high part)
#90 Cylinder register (low part)
#70 Sector number register
#50 Sector counter register
#30 Error Register || Additional register opportunities
#10 Data register (low part)
#11 Data register (high part)
;Write a value to the port.
;IN: [BC] - port number
; [A] - value
OUT_A OUT (C),A
RET
;Read value from port.
;IN: [BC] - port number
;OUT: [A] - value
IN_A IN (C),A
RET
;Waiting for the device to become free.
NO_BSY LD BC,#F0
CALL IN_A
RLCA: RET NC
JR NO_BSY
;Waiting for data transfer to be ready.
WAIT_DRQ LD BC,#F0
CALL IN_A
BIT 3,A
RET NZ
JR WAIT_DRQ
;Let's see if an error has occurred.
NO_ERROR LD BC,#F0
CALL IN_A
RLCA
RET
;Selecting a Slave device.
SEL_SLAVE LD A,#B0
LD BC,#D0
CALL OUT_A
LD BC,#D0
CALL IN_A
RLCA: RET
;Write a number to the Cylinder Register.
HL_TO_LEN LD BC,#90
LD A,L
CALL OUT_A
LD BC,#B0
LD A,H
CALL OUT_A
RET
;Reading a number from the Cylinder Register.
LEN_TO_HL LD BC,#90
CALL IN_ALD L,A
LD BC,#B0
CALL IN_A
LD H,A
RET
Further in the text (for subroutines for determining the availability
CD-ROM and data reading) to users of the NEMO HDD controller
you need to replace the registers (ports) of the SMUC controller
corresponding ports of the NEMO controller.
5. ATA COMMANDS
These are auxiliary commands that are transferred to the CD-ROM
through the Command Register, not through the package. There are only such teams
4:
1. #A0 - ATAPI packet transmission command. More details
usage will be discussed below.
2. #08 - Soft reset. Full initialization in progress
CD-ROM.
3. #A1 - CD-ROM identification. Similar to the #EC command for
Winchester.
4. #EC - Treated as an error, but in the Cylinder Register
the value #14EB is set - the ATAPI device sign.
6. DETERMINING THE PRESENCE OF A CD-ROM
To determine the presence of a CD-ROM, you must run
the following steps:
1. Select the Slave/Master device.
2. See the absence of the BSY signal. If it's busy, it means
no device. (Please note that before this CD-ROM
did not execute any of your commands, otherwise the BSY flag may also
be installed).
3. Issue a master reset command. Although you can do without
this.
4. Write a number different from #14EB into the Cylinder Register.
For simplicity, you can simply write 0.5. Enter the ATA command #EC into the Command Register and wait a couple
interrupts.
6. Read the Cylinder Register. It must contain a number
#14EB. If so, then the CD-ROM is connected. Otherwise
In this case it could be a simple hard drive. In this case it is necessary
Please note that the CD-ROM will report an error in the Error Register.
This is fine.
Here I will give a subroutine that determines the presence
CD-ROM.
;IN: A=#00 - Master.
; A=#B0 - Slave
CD_INI LD BC,#FEBE
CALL OUT_A
LD BC,#FFBE
CALL IN_A
RLCA
JP C,NO_CDROM
LD HL,0
CALL HL_TO_LEN
LD BC,#FFBE
LD A,#EC
CALL OUT_A
CALL NO_BSY
CALL LEN_TO_HL
LD BC,#EB14
OR A
SBC HL,BC
JP NZ,NO_CDROM
RET
NO_CDROM...
Now we have made sure that we have an ATAPI device connected.
However, to be completely sure, it would be a good idea to check
Is this really a CD-ROM? To do this you need to look at the 1st byte in
CD-ROM identification table (transmitted by command
#A1).
7. CD-ROM IDENTIFICATION TABLE
The identification table is one sector of data, in
which contains information about a specific CD-ROM. Sector
called by ATA command #A1. After sending the command to us
you need to accept 2048 bytes from the CD-ROM. Attention! Data inthis table, as well as in a similar table on the hard drive,
upside down! The high byte comes first, then the low byte. to you
It is necessary to swap every two adjacent bytes.
Below is an example of such a subroutine:
;IN: [HL] - address for receiving data.
; [BC] - number of bytes.
TRANS_IN
PUSH BC
CALL NO_BSY
CALL WAIT_DRQ
POP B.C.
OR A
RR B
RR C
JR NC,$+3
INC B.C.
TRANS_IN1
PUSH BC
LD BC,#F8BE
CALL IN_A
LD(HL),A
INC HL
LD BC,#D8BE
CALL IN_A
LD(HL),A
INC HL
POP B.C.
DEC B.C.
LD A,B
OR C
JR NZ,TRANS_IN1
RET
So, to read the identification table, we need
execute the following subroutine:
CD_INITAB
LD A,#A1
LD BC,#FFBE
CALL OUT_A
LD HL,MY_BUFF
LD BC,#0200
CALL TRANS_IN
RET
And we have an identification table in our memory. In it
contains the following information:
00, bit 0 - Packet length:
0 - 12 bytes,
1 - 16 bytes.
01, bit 0-4 - Device type:
5 - CD-ROM
20-39 - Serial number.
40-45 - Something from the manufacturer
46-53 - Firmware version
54-93 - Model name
94-95 - Something from the manufacturer
The remaining parameters are not so important for us. Soway to make sure that we are really connected
CD-ROM, and not another ATAPI device, we need to read in
accumulator byte from table at offset 1, execute
command AND #1F and see if it is equal to 5. Although
the probability of connecting an ATAPI device to the Spectrum is not
being a hard drive, it’s unlikely, but nevertheless I advise
carry out this check.
8. TRANSFER OF ATAPI PACKET
This is nothing more than direct programming
CD-ROM. The commands that he perceives are transmitted to him in
packet consisting of 12 bytes. The first byte of the packet is
command code, and the remaining 11 bytes are command parameters.
To begin with, I will give a subroutine that passes
12-byte package on CD-ROM. It does the following:
writes command #A0 to the ATA Command Register (ATAPI transfer
packet) and transmits 12 bytes through data registers, and
being an ATAPI package.
Attention! When transmitting a packet, you must always specify
the device we are working with (Master/Slave).
;Transfer ATAPI packet.
;IN: [HL] - packet address.
SEND_ATAPI
PUSH HL
CALL SEL_SLAVE
LD HL,#0800
CALL HL_TO_LEN
LD BC,#FFBE
LD A,#A0
CALL OUT_A
POP HL
LD BC,12
;data transfer.
;IN: [HL] - data address.
; [BC] - number of bytes.
TRANSFER_OUT PUSH BC
CALL NO_BSYCALL WAIT_DRQ
POP B.C.
OR A
RR B
RR C
JR NC,$+3
INC B.C.
TRANS_OUT1 PUSH BC
INC HL
LD A,(HL)
LD BC,#D8BE
CALL OUT_A
DEC HL
LD A,(HL)
LD BC,#F8BE
CALL OUT_A
INC HL
INC HL
POP B.C.
DEC B.C.
LD A,B
OR C
JR NZ,TRANS_OUT1
RET
And a few words about what this command should look like
package. In my description I will present it in this way
form:
#00 - "Dummy".
DB 0
DS 11
The first byte is the command code. The rest are parameters.
I describe unused bytes with the DS assembler command
(sequence of zeros). Although unused data is not
are analyzed, for compatibility it is better to set them to 0.
So, the package itself can be designed like this:
AP_00 DB 0
DS 11
And it will be called like this:
LD HL,AP_00
CALL SEND_ATAPI
...
9. DESCRIPTION OF CD-ROM COMMANDS
General commands
9.1. "Dummy"
This command was given as an example by me in
previous chapter. The packet consists of 12 zeros. This team is notperforms no action. However, it is extremely necessary -
the fact is that for unknown reasons the CD-ROM refuses
execute many commands and reports an error. In particular,
this happens immediately after changing the media (Master ->
Slave or vice versa). Therefore I strongly recommend you
Before each command, call a "dummy". That's exactly how I am
got my CD-Copier program working on
Spectrum. In other words, executing the command described
package AP_?? should look like this:
LD HL,AP_00 : CALL SEND_ATAPI
LD HL,AP_?? : CALL SEND_ATAPI
...
9.2. Positioning
;#01 - Positioning on track 0.
DB #01
DS 11
This command sets the media heads to track 0. B
I have never used this command in my program.
;#2B - Positioning in MSF format.
DB #2B
DS 2
DB minutes
DB seconds
DB fractions of a second
DS 6
MSF (Minute/Second/Frame) is one way
positioning on the disk. It is defined in
minutes/seconds/fractions of a second that would have passed when reading
from the beginning of the disk at speed 1. The format is convenient when working with
audio discs.
9.3. Tray management
;#1B - Tray management.
DB #1B
DS 3
DB Function
DS 7
Function:
0 - Enter Sleep mode.
1 - Stop playing/reading.2 - Pull out the tray.
3 - Push in the tray.
As you can see, the functions of this command are not limited to one
tray management. Sleep mode is a reduced mode
power consumption, the drive stops or slows down
rotation until the command to read data arrives. Function code 1
convenient to use to stop playing a melody.
Tray management is carried out only if it
not blocked.
;#1E - Tray lock.
DB#1E
DS 3
DB Function
DS 7
Function:
0 - unlock tray.
1 - block tray.
The command blocks the action of command #1B.
Information commands
9.4. Reading manufacturer parameters
It contains almost the same data as in
identification table called by ATA command #A0.
;#12 - Read the manufacturer parameters string.
DB #12
DS 3
DB string length.
DS 7
The string length is usually 36. The following data is returned:
+0 - device type (CD = 5)
+1 - bit 7: removable media supported
+2 - ISO, ECMA and ANSI versions.
+3 - 0, for SCSI-2 compatibility
+4 - length of the remaining block
+5 - reserve
+7 - 0, for SCSI-2 compatibility
+8 - manufacturer's string (there is 'ATAPI')
+16 - product name
+32 - revision
9.5. Getting general parametersI have not studied this command, so I quote it from the description
without changes or comments. You have to either study it
action yourself, or skip it, because she reports
specific information about the CD-ROM and for the Spectrum decisive
doesn't matter.
;#5A - Get general parameters.
DB #5A
DB 0
DB Page - defines the required parameters, consists
of two bit fields:
bits 1?5 - number of the required parameters page:
%00000001 - error correction parameters
%00001011 - general parameters
%00001110 - audio control
%00101010 - device parameters (read only)
%00111111 - all pages
bits 6?7 - bits of the required page type:
%00000000 - current values
%01000000 - changed values
%10000000 - default values
%11000000 - saved values
DS 4
DW Length; table length
DS 3
The command is informational, issues the corresponding
parameters page.
General title:
00-01 - Length of the entire block (without the first word)
02 - Drive status
03-07 - ?
Title of each page:
08 - Page number from the request
09 - Page length
Page #01 - bug fixes
10 - Error correction option
11 - Read repeat counter
Page #0D - general parameters
10 - ?
11 - Inactivity timer multiplier12-13 - Number of S units in M unit for MSF format (60)
14-15 - Number of F units in S unit for MSF format (75)
Page #0E - audio parameters
10 - Parameter not used, but can be changed
11-12 - ?
13 - =0 LBA is always equal to the sector number, high bit
indicates the following field is correct
14-15 - Number of logical blocks per second for playback.
(usually not used)
16 - ml. tetrad - bits of channel 0 output port
17 - channel volume 0
18 - ml. tetrad - bits of channel 1 output port
19 - volume of channel 1
20 - ml. tetrad - bits of channel 2 output port
21 - channel 2 volume
22 - ml. tetrad - bits of channel 3 output port
23 - channel 3 volume
Page #2A - device parameters (read only)
; function presence/absence bits
12 - bit 0 - audio playback
bit 1 - composite audio/video stream
bit 2 - Digital out to port 1
bit 3 - Digital out to port 2
bit 4 - read sectors Mode 2 Form 1
bit 5 - -----//-------- Mode 2 Form 2
bit 6 - Reading multi-session disks
bit 7 - ?
13 - bit 0 - Reading the "Red Book" via the Read-CD command
bit 1 - Reading the "Red Book""with accurate stream"
bit 2 - Read subchannel
bit 3 - Support for subchannel data deinterleaving
bit 4 - Support "C2 error pointers"bit 5 - ISRC read support
bit 6 - UPC reading support
bit 7 - ?
14 - bit 0 - media lock
bit 1 - read lock status
bit 2 - Disk prevent jumper present
bit 3 - media eject command
bit 4 - ?
bit 5?7 - Bootloader type:
0 - Caddy
1 - Tray
2 - Pop-Up
3 - Reserved
4 - Changer with individual
replaceable disks
5 - Cartridge
6 - Reserved
7 - Reserved
15 - bit 0 - Separate channel adjustment
bit 1 - Separate channel switch
bit 2- Information about disk availability
16-17 - Maximum transfer speed in kilobytes
18 - ?
19 - Number of volume adjustment levels
20-21 - Buffer size in kilobytes
22-23 - Current baud rate
;---------may sometimes be missing------------
24 - ?
25 - bit 0 - Digital out on rising/falling edge of BCKF signal
bit 1 - LRCK indicates left/right channel
bit 2 - data in LSB/MSB format
bit 3 - ?
bit 4 BCKs: 0 - 32
bit 5 | 1 - 16
bit 6 / 2 - 24
3 - 24 (I^2S)
bit 7 - ?
The length of each page may vary. Described hereonly those fields that are more or less standard. If
all pages are requested (bits 0...5), then on the weekend
the block will have one common header and
sequentially arranged pages with their
headings.
9.6. Setting General Settings
The action of the command is similar to the previous one, with the only difference being
that it does not return values, but writes them. Codes and
You can see the page format from the previous description
teams.
;#55 - Setting general parameters.
DB #55
DB?; bit 1 - save to NVRAM (?)
DB Page; required parameters page
DS 4
DW Length; table length
DS 3*
9.7. Operation error code
;#03 - Read drive status.
DB #03
DS 11
Then you need to read 18 bytes of data and the 2nd byte will be the code
operation errors. The CD-ROM returns the following errors:
0 - meaningless data
1 - repeated error
2 - no readiness
3 - environment error
4 - hardware error
5 - invalid request
6 - device maintenance
7 - data protection
11 - command interrupted
14 - incorrect comparison
Unfortunately, I cannot give a complete description here
the actions of each error, since I did not study them in detail.
More complete information about the error can be obtained by looking at
value 12 and 13 bytes. Description of these errors in EnglishI provide the language in the appendix at the end of the article.
However, error handling when programming a CD-ROM has
much more important than in programming
Winchester. The fact is that when working with a CD
CD-ROM returns an error quite often. But this is not always
means that an error has occurred in the literal sense of the word, and
may, for example, indicate that the CD-ROM is not ready
transmit data due to insufficient rotation speed
CD (that is, simply put, the disc is not yet
unwinded). I will give an example from my immediate
experience in writing a copier for CD-ROM: if some long
while there is no access to the disk, it goes to
low power consumption mode. Starts slower
rotate. And when accessing the disk, for example when trying
read data, it clears the BSY flag, but the speed
The disk rotation is not yet sufficient to perform the operation. And
The CD-ROM will return a "2 - not ready" error until
until the disk rotation speed allows you to read data
and transfer them to the computer.
Actions when reading data (sectors) must have the following
sequence:
1. We transmit a packet with a data read command (will be described
me below).
2. We are waiting for the BSY busy flag to be removed.
3. Look at the 0th bit of the Status Register (if there is an error)4. If there is no error, continue reading the data.
5. We transmit packet "03". We read 18 bytes. Let's look at the error code.
6. If the code is 0 - “meaningless data”, then it is necessary
Continue reading. Otherwise we go to the state
errors.
For more details, see Chapter 10 - "Example
Reading data on the Spectrum."
9.8. Determining disk size
;#25 - Disk size in sectors.
DB #25
DS 11
Then you need to read 8 bytes. The first four bytes are
number of sectors on the current disk, and the next ones - size
sectors (as a rule, does not depend on the disk and is equal to 2352).
Let me remind you that the disk size can also be found from the TOC sector
disk (chapter 11.1).
9.9. Audio information
The following command allows you to obtain information related to
to audio discs. The work of this team has not been studied by me,
Therefore, I present its description with virtually no comments.
Maybe you can get some useful information from here.
;#42 - mixed information (subchannel reading)
DB #42
DB ScMsf ; 0/2 - type of address issuance (number
sector or MSF)
DB FullInfo; request option (full/short -
6th bit)
DB Func ; subfunction (only for full
request)
DS 3
DW Length ; Table length
DS 3
The command produces a block of the following information:
+00 DW audio playback status:#00 - unknown or not supported
#11 - Audio plays
#12 - Audio costs
#13 - Audio stopped at the end
#14 - Door open or startup error
#15 - Other
+02 DW length of subsequent data (0 - none)
Attention! +04 and further present if bit 40h is present in
FullInfo and depend on Func.
Func is not equal to 2 or 3:
+04 DB 01 (subchannel data format = 1)
+05 DB Ctrl/Addr
+06 DB Track number.
+07 DB Point or Index
+08 DB 0
+09 DS 3 - MSF/SECTOR on disk
+12 DB 0
+13 DS 3 - MSF/SECTOR on track
--Subfunction 2-- (Get UPC code)
+04 DB 2 (subchannel data format = 2)
+05 DS 3
+08 DB #80 - UPC presence flag (if not, then UPC
missing)
+09 DS 12 - UPC code is stored here (6 digits in BCD code)
+23 DS 3 - The position of something on the disk in MSF format
--Subfunction 3-- (get ISRC code)
+04 DB 03h (subchannel data format = 2)
+05 DB Ctrl/Addr
+06 DB Track number - not always used.
+07 DB ?
+08 DB #80 - presence flag (same as function 2)
+09 DB further entry ISRC
9.10. Sector information
This command creates a compromise between the two types
addressing information on a CD: audio addressing
(MFS) and sector addressing. At the input commands are given
minutes/seconds/frames, and the output generates information aboutsector located in this location - its number and format.
#44 - information about real position marks (Read HEADER)
DB #44
DB SL - bit 2 - what to write to the output buffer
(original sector number or read)
DB 0
DS M,S,F - Sector number
DB 0
DW Len - length of information output
DS 3
The command returns a table of 8 bytes:
+00 Sector format type (data mode)
+01 0,0,0,0
+05 Sector address (M,F,S).
Information is returned only if the CD was able to
read a given sector and determine its type.
9.11. Track information
This command has also not been studied by me, so I present it
without comments or explanations. I used this command
solely to find out which CD is in
CD-ROM: audio or information. Subroutine
allowing me to do this will be given by me at the end
team descriptions.
#43 - track information (READ TOC)
DB #43h
DB ScMsf - 0/2 type of address issuance
(sector number or MSF)
DS 4
DB BegTrk - initial track
(from 1, 0 is replaced by 1)
DW Length - Table length
DB Func - information output options (0/40h/80h)
DS 2
The command is informational and displays a table of tracks. Maximum
table length = 8*#64+4 bytes or #64 (100) tracks.
Func = #00 - get regular track table= #40 - get the session table
= #80 - get a regular table in
expanded format
General table format:
DW Len - length of subsequent fields in bytes
DB BegTrk - first track
DB EndTrk - last track
D? - description of the tracks
Description of tracks m.b. three formats:
1) 5 bytes per track (internal format, not external from CD
issued):
DB Ctrl/Addr - track type and flags
DB Index - track index (number)
DB Start (3 bytes) - address of the beginning of the track
2) 8 bytes per track (Func=0/#40):
DB?
DB Ctrl/Addr - track type and flags
DB TrackNumber - track number
DB?
DB Start (4 bytes) - address of the beginning of the track
3) 11 bytes per track (Func = #80):
DB Res1
DB Ctrl/Addr - track type
DB Res2
DB Index - track index
DB Res3
DB Res4
DB Res5
DB Start (4 bytes) - address of the beginning of the track
The returned variables have the following values:
Ctrl/Addr - track type
Ctrl (low tetrad, single bits):
01 - there is pre-emphasis
02 - copying allowed
04 - data track
08 - 4 channels (not 2)
Addr (high notebook, codes):
0 - no subchannel
1 - position is encoded in the subchannel
2 - UPC encoded in the subchannel3 - ISRC encoded in the subchannel
other - reserved
The most common codes:
14h - ROM
10h - audio
Index - encoded in BCD and for a regular track is located in
interval 01-99. Codes #A0 and above have a special meaning,
they do not correspond to the physical tracks on the disc, but are
service character - inform about the number of tracks, the beginning
disk, end of disk, etc.
Start - depending on the request, can be either a number
sector, or sector address in MSF format.
Audio disk management commands
Since CD-ROMs were originally used for
sound reproduction, and only later were they adapted for
storage of information, therefore among the control commands
The CD-ROM contains a large number of commands that work
directly with audio disc format. These are the so-called
audio tracks, or tracks. Typically, a CD-ROM has
fairly independent management ability
audio tracks. So, on the front panel of the CD-ROM there is
audio output, where you can connect headphones or an amplifier, and
button to switch tracks. Sound can also be recorded in
digital form and read it by a computer (on an IBM PC this
is handled by the sound card), but on the Spectrum, unfortunately,
this cannot be done yet. Therefore, programmatically you canlimit yourself only to switching playback of the selected
track, but the sound must be recorded through an amplifier or
headphones only from the front panel of the CD-ROM or from
a similar audio output on the rear panel.
9.12. Playback in blocks
This command specifies the start of playback and the length of playback
in blocks. Moreover, the number of blocks played
16-bit (maximum - 65535).
#45 - play audio in blocks.
DB #45
DB 0
DB (4)StartBlock - playback start block
(-1 - from current position)
DB 0
DW Length - number of blocks
DS 3
This command differs from the previous one only in that
the number of blocks played is set by 32-bit
number.
#0A5 - play audio in blocks.
DB #A5
DB 0
DD StartBlock - playback start block
(-1 - from current position).
DD Length - number of blocks.
DS 2
9.13. Playing audio in MSF
This command specifies playback in MSF format. This way
allows you to set a very precise (down to a fraction of a second) location
start of playback and playback time. Table
Track locations in this format can be obtained using
commands "#43 - track information" (chapter 9.11).
#47 - play audio in MSF.
DB #47
DS 2
DB M,S,F - beginning of the segment (FF:FF:FF - current
position)DB M,S,F - end of segment
DS 3
9.14. Stop/resume playback
This command is used to stop/resume playback
music.
#4B - Start/stop audio.
DB #4B
DS 7
DB Func
DS 3
Func=0 - stop playing.
Func=1 - continue playing.
9.15. Stop playback
This command is very simple and serves only one purpose -
stop playing the audio track. Besides, she doesn't
requires additional parameters.
#4E - stop playing.
DB #4e
DS 11
Read Data Commands
There are two commands for reading data. One of them allows
read data in specific sectors, and another in parameters
MSF (described above). If reading in MSF is relevant for
audio discs, when we want to accurately read the audio track
to convert it, for example, into a file (.wav or .mp3,
The minimum size of such a file is several megabytes, for
Spectrum is irrelevant). Although you can write a program
playing back short areas from an audio disc for
then converting them into samples for General Sound.
Then it is convenient to read the data in MSF. Reading in
sectors are just convenient for reading files (since all
file parameters are indicated in sectors). Below I am
I will give a description of two reading options and an example for readingsectors on the Spectrum.
9.16. Reading data in MFS
#B9 - Reading data in MSF.
DB #B9
DB Fmt can be = 00h any format is suitable
08h regular CD (Yellow
book)
10h varieties
14h/ Green Book.
DB 0
DB M,S,F start reading
DB M,S,F end of reading
DB Flg flags of the readable part of the sector:
01h three
02h unused (?)
04h bit
08h EDC/Zero/ECC
10h main sector body (data)
20h sector address descriptor (head)
40h subchannel data (sub)
80h initial sync bytes (sync)
Only those parts of sectors are transmitted for
which
bits are set. Transferable parts
sectors must go
consecutively, without gaps.
DB 0 always d.b. =0, otherwise error
DB 0
If in this command the read start address matches the address
end of reading, then positioning occurs on the specified
position and reading is tested. No data is transferred.
9.17. Reading data in sectors
#BE - Read data in sectors.
DB #BE
DB Fmt - reading format (as in #B9).DB Sec - start reading - 4 bytes.
(uses 24 bits only)
DB 0
DW ScNum - Number of sectors
DB Flg - flags of the readable piece of the sector (as in #B9)
DB 0 - always d.b. =0, otherwise error.
DB 0
The command is completely similar to command #B9 - “Read data in
MFS", with the exception of setting the addresses of the reading area in
sectors.
10. EXAMPLE OF READING DATA ON THE SPECTRUM
Below I will give an example of a subroutine for reading sectors on
Spectrum. Before calling it, you need to set the values in
AP_BE package (reading data in sectors). An example of this
package you see in front of you.
SECTOR - reading sector.
SECTORS - number of sectors to read (unfortunately, according to
for unknown reasons when trying to count more than one sector
Errors occur in the received data. Therefore I advise you
read one sector at a time and do not change this variable).
AP_BE DB #BE,#00
SECTOR DB #00,#00,#00,#1F
DB 0
SECTORS DB #00,#01
DB #10
DB 0.0
And the reading subroutine itself:
;IN: [HL] - address to read.
LOAD_SECTOR PUSH HL
CALL NO_BSY
LD HL,AP_00
CALL SEND_ATAPI
LD HL,AP_BE
CALL SEND_ATAPI
LOAD_SECTOR_CALL NO_BSY
CALL NO_ERROR
JP C,ERROR
CALL WAIT_DRQ
POP HL LD B,8
LOAD_SECTOR1