Skip to content

Instantly share code, notes, and snippets.

@barbeque
Created March 28, 2024 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barbeque/4ea8167f55cb87e178d467604ad70d88 to your computer and use it in GitHub Desktop.
Save barbeque/4ea8167f55cb87e178d467604ad70d88 to your computer and use it in GitHub Desktop.
PC-6001 P6Tech #11 - CMT decoding - English translation

Original article at http://p6ers.net/mm/pc-6001/cas/p6tech_11.pdf (thank you)

Basic control of CMT is performed by the SUB CPU. From the Z80 side, through the SUB CPU You can only write 1Byte to tape or read 1Byte from tape. Z80 is first First, tell the SUB CPU whether the operation you are about to perform is to start writing a tape or You need to tell it whether to start reading the file or not. The way to convey this is to use the Z80 explained in the previous chapter. By sending 1 byte or 2 bytes of data consecutively, The SUB CPU goes into CMT control mode.

command code processing content
3DH,39H 600baud SAVE START
1DH,19H 600baud LOAD START
3EH,39H 1200baud SAVE START
1EH,19H 1200baud LOAD START
3AH SAVE STOP
1AH LOAD STOP

CMT-controlled commands are a combination of tape read/write, start, and end. for example If you start with a tape read (LOAD) of 1200baud, the end of tape read (LOAD) Commands must be sent from the Z80 to the SUB CPU. As you can see from this table, the PC-6001 allows you to specify two types of baud rates: 600 and 1200. You can set After starting BASIC, it is set to 1200baud. read/write speed I don't know the reason for the existence of the slow 600baud, but perhaps the PC-8001, which was released earlier, 600baud (or 300baud) and can read tapes saved on the PC-8001. It seems that there is. CMT write and read processing is performed on the SUB CPU, but Loading is handled very differently. Reading is an interrupt from the SUB CPU, but For writing, the Z80 constantly monitors the status of the SUB CPU pins and the SUB CPU can accept data. This method sends data from the Z80 to the SUB CPU when it is in a certain state.

writing to tape

Since the tape is managed by the SUB CPU, tape operations are mainly done through interaction with the SUB CPU. This will be a process. First, send a command to the SUB CPU to start writing tape. Masu. Then, monitor the status of the SUB CPU and check whether the SUB CPU is in the data accepting state. Masu. This monitoring process is written from 1AEDH in BASIC ROM, so use that routine. It is safe to use it. The processing details are as follows.

1AEDH:
 LD B,00H
 LD A,08H
 OUT (093H),A
 IN A,(093H)
 BIT 3,A
 JR Z,01AFFH
 IN A,(093H)
 RLCA
 JR NC,01AFFH
 ; CMT OK 状態
 DEC B
1AFFH:
 LD A,09H
 OUT (093H),A
 LD A,B
 OR A
 RET

The zero flag indicates whether the SUB CPU can accept data at the time this process is called. I'm returning it. When the zero flag is 1, the SUB CPU is ready to accept data to be written. It becomes. Conversely, when the zero flag is 0, it means that the SUB CPU is not ready to accept it. Then repeat this routine again. Of course, repeat the check within this routine There is no problem if you change the process to something like this. In BASIC ROM, the STOP key is pressed during CSAVE. It is designed to interrupt the save process when pressed. Therefore, this SUB The CPU check process and the process to check whether the STOP key has been pressed are called alternately. This is how it is implemented. Whether the STOP key was pressed is determined by the SUB CPU Since it is detected by a keyboard interrupt from Manages flags. When the SUB CPU has completed accepting write data, first send 38H to the SUB CPU. I will. After that, he continues writing to the tape and sends 1Byte of data to the SUB CPU. From then on, Repeat this SUB CPU acceptance check and write, and when there is no more data to write, The write process ends when the write process end command is sent to the SUB CPU. 38H The meaning is unclear, but it seems to be the rule to do so.

LD A,038H
CALL 0E8FH
; data to export
LD A,nnH
CALL 0E8FH

These series of 1Byte write processing are described starting from 1ACCH of BASIC ROM. A Les Prepare the data you want to write to the tape in the register and call 1ACCH.The contents of the A register is written to tape. When writing to tape, it is necessary to send a command to start writing in advance.

Also, the remote terminal must be enabled and the tape must run stably. These series What you need to do before writing to tape is to write from 1AB8H in BASIC ROM. It is stated. In this way, writing to tape uses basic routines in BASIC ROM. It is convenient to use this. Conversely, it is also possible to finish writing to tape. The series of processing for termination is described starting from 1B06H of BASIC ROM.

The procedure for using BASIC ROM can be summarized as follows.

 ; SAVE processing initialization routine
 CALL 1AB8H
LOOP:
 ; prepare write data to A register
 LD A,xx
 ; sub-cpu status check and 1-byte transmission
 CALL 1ACCH
 ; to continue writing to tape, go to LOOP
 ; SAVE processing termination routine
 CALL 1B06H

This is a simple usage example, but it is a sample program that writes the contents of BASIC ROM to tape. BASIC ROM 16Kbyte is written to CMT.

LD HL,0000H LD BC,4000H
 CALL 1AB8H
$$loop1:
 LD A,(HL) INC HL
 CALL 1ACCH
 DEC BC
 LD A,B
 OR C JR NZ,$$loop1
 CALL 1B06H
 RET

The processing in BASIC ROM also checks whether the STOP key was pressed during writing. Therefore, when using this routine, please be aware of the STOP key interrupt when accessing CMT. must be taken into account. Also, BASIC ROM uses the BASIC ROM work area (RAM area) from FA00H. Therefore, care must be taken when creating programs that utilize this area. If the work area FA1FH is 00H, it will be 600Baud, and if it is other than 00H, it will be 1200Baud. Masu. In BASIC ROM, if the STOP key is pressed during CMT write processing, CMT access FA18H is rewritten by interrupt processing using the STOP key. FA27H has an I/O port. The value of bit B0H is recorded and rewritten at the start/end of reading from tape.

Reading from tape

The main processing method for writing to tape was to monitor the status of the SUB CPU, but for reading uses interrupts. When the SUB CPU reads 1Byte of data from the tape, it sends a message to the Z80. generates an interrupt. If 1Byte is read from the SUB CPU within the interrupt processing, The reception process for 1Byte is completed. After that, repeat this for the required number of bytes. reading The decision to end the process is made by the Z80. How to count the number of bytes you want to read, There is a way to judge based on the content of the read data. For example, in BASIC's CLOAD instruction, 00H is If there are 10 consecutive readings, reading will stop at that point. Commercially available sauce In software, it seems that there are many things that are judged by the number of bytes read. To read from a tape, first send a command to the SUB CPU to start reading the tape. send. After that, the SUB CPU performs tape reading processing and generates an interrupt to the Z80. Masu. While the Z80 is not processing interrupts, it does not matter if it is performing other processing. however, Since the SUB CPU is dedicated to tape reading processing, other processing related to the SUB CPU, e.g. It is not possible to read the keyboard. Also, due to the nature of CMT, it is difficult to read data. The Z80 reads the data sent from the SUB CPU at any time because it is not possible to temporarily stop the processing. Failure to do so may result in data loss or even a SUB CPU hang. You need to be careful. As an example of performing other processing in parallel with tape reading, has his EGGY from BOTTEC, which updates the screen while reading the tape. When tape reading is no longer required, the Z80 can read the tape from the SUB CPU. When the command to finish reading is sent, the SUB CPU finishes reading the tape. However, Depending on the timing, even if you send a command to finish tape reading from the Z80, the tape may not be read. An interrupt may occur, so in that case he must read 1Byte from the SUB CPU. Must be. A series of processes related to the start and end of tape reading are performed by BASIC ROM. There is a routine in , which can be used to simplify the process. Processing to start tape reading The logic is 1A61H. Interrupt processing occurs at any time after this routine is called. Split Call 1A70H to receive data received during the processing. In this routine, Waits until data is received from the SUB CPU during read processing, and then stores it in the A register after receiving the data. Store the received data. At this time, if a CMT loading error occurs, the The log flag is 1. To finish reading from CMT, call 1AAAH.

However, similar to writing to tape, BASIC ROM can be written to BASIC ROM from FA00H. area (RAM area), so create a program that uses this area independently. Care must be taken in this case. If the work area FA1FH is 00H, it will be 600Baud, and if it is other than 00H, it will be 1200Baud.

Additionally, in BASIC ROM, if the STOP key is pressed during the CMT write process, the CMT FA18H is rewritten by interrupt processing using the STOP key during access. CMT loading When a special interrupt occurs, the contents of FA19H are rewritten within the interrupt handling and the data is sent from the SUB CPU. The received 1Byte data is saved to FA1DH. Routines from 1A70H use interrupts. By continuing to check the contents of FA19H until a problem occurs, 1Byte is sent from the SUB CPU. I'm watching what's coming. FA27H records the value of I/O port B0H and records the value of I/O port B0H. It is rewritten at the start/end of reading.

This is an example program that reads data from CMT using routines in BASIC ROM.

ORG $Df00
 ; CMT READ OPEN
 CALL $1A61
$$LOOP1: CALL $1A70
 CALL DISP_XX
 JR $$LOOP1

Although the code for DISP_XX is not listed, there is a subroutine that displays the A register as a 2-digit hexadecimal number. This is Chin. This is a program that simply receives 1Byte from CMT and displays it on the screen. Any tape can be read on the CMT side. View the contents of the tape We will display it. Next is an example program in which only the interrupt and data reception parts are implemented independently.

 ORG $DF00
 ; Interrupt settings
 di ld hl,VEC04
 ld ($fa08),hl
 ei
 ; CMT READ OPEN
 call $1a61
$$loop1:
 ld a,(wk00)
 or a
 jr z,$$loop1
 ld a,(wk01)
 call DISP_XX
 xor a
 ld (wk00),a
 jr $$loop1
wk00:
 db $00
wk01:
 db $00
 
 ; interrupt processing
 ; cmt read
VEC04:
 push af
 ; read sub-cpu
 call $0e78
 ld (wk01), a
 ld a, $ff
 ld (wk00), a
 pop af
 ei
 ret

In interrupt processing, 1Byte is received from the SUB CPU, the received data is saved, and the receive flag is set. I'm doing it. The main routine side monitors the receive flag and displays the received data. destination The processing results are the same as the method using BASIC ROM, but details such as error checking etc. I haven't done any science. There is no guarantee that the content of the 1Byte data sent from the SUB CPU is correct. yeah. Data may become corrupted depending on the condition of the tape. The recording method on magnetic tape is Byte data is not simply arranged in bits, but with markings that separate the data. If the format is corrupted, it will be detected by the SUB CPU. Since it is not possible to detect damage to the data itself, the Z80 must make the decision. Commercially available The software performs a data checksum after reading all the data from the tape. There are things. When the SUB CPU starts reading data from a tape, the read data recorded on the tape is Detecting the cutting start marker part. Therefore, even if you play from the middle of the tape, the SUB Although the CPU is working on reading the data, it is treated as inappropriate data and the Z80 Does not send data. This is true no matter what the contents of the tape are, from BASIC to This is true whether it is CSAVEd or written to tape in a proprietary format. Also, marker creation and detection are performed internally by the SUB CPU, and this process itself is rewritten. There is no need for the programmer to be aware of this, as it cannot be changed.

characteristics of CMT

CMT can be controlled by communicating between Z80 and SUB CPU, but in order to actually use CMT, must know about the characteristics of CMT.

The PC-6001 main unit and CMT are connected using three cables, but if none of the cables are connected, The PC-6001 can perform tape operations even without it. Of course, the loading cassette Data cannot be read if the cable is not connected, but if the write cable is not connected. Writing can be performed even if the tape is connected, and if CMT is stopped in the middle of writing or the tape ends. However, the PC-6001 side, that is, the Z80 or SUB CPU, cannot detect it.

Of the three CMT cables, the one with the black jacket is used for remote control signals; This is used to notify the CMT from the PC-6001 that it will read or write tape. signal is simply ON/OFF, and when this signal is OFF, CMT PLAY and REC are disabled by hardware. The CMT is designed to prevent the tape from running even when pressed. PC-6001 is When reading or writing from a tape, the remote control signal must be turned on. When finished, the signal must be turned OFF. Remote control is Z80 instead of SUB CPU is controlled through the I/O port. The remote control signal cable is not connected. The SUB CPU can still read and write data from the CMT. wife The SUB CPU then reads or writes from the tape's current position. This means that it is operating without considering the read/write position of .

When accessing a cassette tape, read and write with consideration to the characteristics of the cassette tape. Must. The tape rotates at an unstable speed for a while after the motor starts rotating. Because of this, it takes time to achieve stable rotation. Especially when writing to tape. must be started with the tape running steadily. As I wrote earlier, PC-6001 can send data to his CMT even if the CMT is not running, so the tape is spinning. If you perform a write process when you have just started recording, the data on the tape may become unstable. I'll come. Write operations must be performed after the tape has stabilized, so Use the remote control signal to first turn on the remote terminal and then wait a while. Read or write (after the tape has run stably). There is no technical data on how long it takes for the tape rotation to stabilize. However, BASIC's CSAVE seems to idle the tape for about 3.4 seconds at the beginning. Also, since the tape continues to rotate at a constant speed, there is a delay in writing and reading on the Z80 side. should not do. Write processing on the Z80 side when writing to tape, that is, from Z80 to SUB If there is a delay in sending data to the CPU, it will not be possible to write to the tape in time, making it difficult to read the tape. At times he noticed that the Z80 was not reading the data from his SUB CPU and the tape was moving forward. This will result in reading failure (data loss). An example of a read failure is that the program is separated into parts A and B, and part A Suppose you have software that reads part B (part A functions as a loader). vinegar. The file name is embedded in the first number of bytes of part B, and part A reads that number of bytes. and display it on the screen. At this time, after reading that number of Bytes from the tape, The process of displaying the file name on the screen is executed, but the tape is still running during this time, so it is not displayed. If the display process takes a long time, the data following the file name may not be read in time, resulting in data being missed. It will cause trouble.

There are three cables that connect the PC-6001 main unit and the cassette deck: red, white, and black. theory first As explained above, the black one is the tape remote control terminal, and the cassette deck is connected from the PC-6001 side. This is a signal sent to the key, and is used to turn on/off the running of the deck. The signal is ON There are only two types, OFF, and detailed control signals cannot be made. You can use the tape without connecting the remote control terminal. You can write and read files. ON/OFF of the remote terminal is controlled by B0h of the I/O port. I will control you.

I/O Port B0h

Bit 7 6 5 4 3 2 1 0
I/O Out Out Out Out
Content Remote, 0 = off, 1 = on VRAM address 01: $e000, 00: $c000, 11: $a000, 10: $8000 Second byte VRAM address Timer interrupt 0 = on, 1 = off

STOP key interrupt during CMT control

Normal keyboard interrupts do not occur while the SUB CPU is controlling the CMT. just, The only exception is the STOP key, which causes an interrupt to occur when controlling the CMT. vinegar. If his STOP key is pressed while the SUB CPU is in CMT control, there will be a difference between reading and writing. An interrupt vector is issued from the SUB CPU. Interrupt vector 0EH, Interrupt vector 10H during reading, FA0E-0FH, FA10-11H in the initial state of BASIC ROM. 0EA8H is written to the , and CMT control is interrupted during the same process for both writing and reading. It is now possible to do so. Processing when CMT loading is interrupted by the STOP key Most of this is done on the SUB CPU side, so the Z80 only needs to detect interrupts. However, depending on the timing, his CMT reading data may be sent from the SUB CPU. If so, you must receive it. In the BASIC ROM routine, when the STOP key is pressed, the PSG sound generation process and the STOP key stop are executed. Since the BASIC ROM work area is referenced by hook processing etc., the errors after FA00H are Care must be taken when using the rear independently. Also, subsequent processing will return to BASIC. The sea urchin is turning.

Tape read error

Although the SUB CPU cannot detect data corruption recorded on tape, If there is a problem with the expression, the SUB CPU will generate a CMT error interrupt to the Z80. TR Error occurs when the tape is stopped in the middle of reading or writing (CLOAD/CSAVE) in BASIC. This is the recording method corruption detection. CMT error interrupt is at vector 12H, After BASIC starts up, it jumps to address 0FB7H written in FA12H. 0FB7H?

These processes now return to BASIC after rewriting work area FA19H of BASIC ROM.

About the CLOAD instruction

Although BASIC is not explained in this book, it is possible to read some program from tape using PC-6001. The only way to get it is to use the CLOAD command. ``Chapter 3: A little bit of BASIC'' We have explained the program storage format, but here we will further explain the BASIC Describes how programs are read from tape.

| WAIT | D3h x 10 | file name (6 bytes) | 0.05 sec WAIT | Program | 00h x 3 | ... | 00h x 9 |

The first WAIT part consists of silence + 2400Hz, and the SUB CPU starts reading the tape. Since it is used for initial detection, it cannot be managed from the Z80 side, and there is no need to do so. not. Without this marker, the SUB CPU will not start reading from the tape, so For example, if you play from the middle of the tape, SUB will read the data from the middle from the CMT. However, I do not send that data to the Z80 (generate an interrupt). The following D3h × 10 (Bytes) are determined by the CLOAD instruction to be a BASIC program. This is the data that can be used. In the CLOAD instruction, when 10 D3Hs are sent from the SUB CPU, they are It is determined that it is a BASIC program. The file name is a file name given by the CSAVE command and can be up to 6 bytes. The CLOAD instruction is The 6Byte following 10 D3Hs is regarded as a file name and displayed on the screen. The file name is If it is less than 6Bbyte, 00H is stored. Displaying the file name is a process on the Z80 side. However, this process may also involve scrolling the screen, making it a relatively heavy process. Also, After displaying the file name, he may be executing the NEW command internally, and these heavy processes When the SUB CPU sends a BASIC program following the file name, the Z80 side , the data will be lost, so there should be a WAIT period between the file name and the BASIC program. It has been set up. WAIT exists on the cassette tape, so it cannot be read by CLOAD. This is not the data you want. As for the WAIT part, according to PC-Technow, the WAIT time is approximately 0.05 seconds. is. This WAIT for him is generated on the Z80 side during CSAVE. This means that his CSAVE instruction is BASIC After sending the start marker and filename to his SUB CPU, I'm just running an empty loop, Z80 and SUB CPU don't do anything special. Since he is running CMT even during empty loop processing, This seems to be the WAIT period.

A BASIC program is based on the BASIC start address and end address explained in “Chapter 3: A little bit of BASIC.” The data between the end addresses is stored as is. In a BASIC program, the link pointer of the next line pointed to by the last line is 0000, and the end of that line itself is 00, so There is a 3-byte 00H at the end of the BASIC program section.

The BASIC end marker is nine 00Hs. 00H is 3 at the end of the BASIC program section. There are 12 00Hs in total. Actual data on CMT When I looked into it, it seems that more than 12 00Hs are recorded, but in BASIC's CLOAD, When 10 00Hs are detected, reading ends at that point. For example, some kind of problem If 00H appears 10 times in a row in the middle of a BASIC program, CLOAD exits gracefully at this point. Of course, the BASIC of PC-6001 has 10 00Hs. The design is such that they do not appear consecutively, so this will not happen. The condition for the CLOAD instruction to finish reading from the CMT is 10 00Hs. So 10 If there are no consecutive 00Hs, reading continues. If you use this, it will contain machine language. BASIC can be loaded. CMT and SUB CPU determine whether the data on the tape is BASIC or not. I haven't judged it. When the CLOAD instruction detects the start marker of BASIC, it The program is determined to be 00HCMT, but it continues until it is read from 10 consecutive All it does is write the data sent from the SUB CPU to RAM. So, na In some way, there is a machine language part after the BASIC program part, and then 10 words. If you create a CMT that records 00H, you can also load machine language with just the CLOAD command. It is possible to do so. With this method, the machine language part is written without BASIC after the BASIC marker and file name. Although it seems like it would be okay to record the In order to check and modify the link pointer of the BASIC program after completing the import, A minimum level of BASIC programming is required. Specifically, there are various ways to create a tape with a BASIC+ machine language structure like this. The CSAVE instruction writes a BASIC program from its storage start address to its end address on tape. Since it is written, if you rewrite the work area where the end address is stored, it will become a CSAVE instruction. Therefore, data in memory after the BASIC program can also be recorded on tape. This BASIC program The area following the program is usually the BASIC variable area, so execute the BASIC program. However, it does not change with the POKE instruction that does not use variables. Or prepare machine language parts in other areas with his POKE and DATA instructions in the BASIC program. After that, retype BASIC, and then rewrite the BASIC program itself, including its intermediate language, etc. Copy the file before the previous machine language area, and then use the CSAVE command's tape writing start and end functions. Change the address and execute the CSAVE instruction, or write a machine language program to control the CMT. Another option is to record to CMT. Please note that the CLOAD command is This means that reading from CMT ends at this point. 00H in machine language data section If there is a place where 10 are lined up, reading will stop at that point.

With the PC-6001 alone, it is difficult to create long BASIC+ machine language sections due to the lack of memory. It would be easier to create a tape with a two-stage structure, such as the one found in commercially available software, consisting of BASIC + machine language section, followed by a machine language section. In this case, the latter machine language data The data section can be created by rewriting the export area of CSAVE or by controlling CMT independently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment