MZ-800 course Chapter 5 5. Pokes, Peeks, tricks, tips and things like that 5.2 INs and OUTs With the INP@ and OUT@ instructions you can read a particular port or send a value between 0 and 255 to it. Ports are amongst others used to interface with the tape recorder, with the joysticks, but also the sound control is done with a port. Of course there are a lot more ports and the most important ones will be discussed here. The two JOYSTICK ports. There are two joystick ports, these are the ports \$F0 and \$F1. Writing to these ports have no effect whatsoever, but they can be read and this goes as follows: ```10 INIT "CTR:M1" 20 INP@\$F0,A 30 PRINT A 40 GOTO 20``` If you connect a joystick to port 1 and move it, you will see the value of A change. This can also be done with port 2, but then you have to change line 20 to: `INP@\$F1,A` The tape recorder. With a certain port ( port \$D2 ) we can read the status of the buttons on the tape recorder ( with exception of the EJECT button ), this goes as follows: ```10 INIT "CRT:M1" 20 INP@\$D2,A:IF A=152 THEN PRINT "A BUTTON ON THE TAPE RECORDER IS PRESSED." :END ELSE RUN``` When you run this program and then press one of the buttons on the tape recorder, you will see the message on the screen. Random numbers. There is a port that produces random numbers, this port is port \$D5. Here is an example: ```10 INIT "CRT:M1" 20 INP@\$D5,A 30 WAIT 100 40 CURSOR A/255*39,24:PRINT "0":GOTO 20``` A wait loop is inserted because the sequence will be to ‘regular’. If you look closely, you will see that there is still a certain regularity in the so-called random sequence. 80 by 50. A resolution of 80 columns by 50 lines is possible, but the screen is divided in four pieces. How is this possible? It is because port \$CE is the port that regulates the resolution and the mode ( 700 or 800 mode ) of the screen. By controlling this port from BASIC, some nice effects arise. The 80 by 50 resolution can be obtained by typing the following: `OUT@\$CE,\$6` Read the status of CTRL/SHIFT. It is impossible to use the GET instruction or similar instructions to read the status of the SHIFT- or the CTRL-key. By reading a particular port ( port \$D1 ) we can see if one of both keys are pressed. This goes as follows: ```10 INIT "CRT:M1" 20 INP@\$D1,A 30 IF A=191 THEN PRINT "THE CTRL-KEY IS PRESSED.":END 40 IF A=254 THEN PRINT "THE SHIFT-KEY IS PRESSED.":END 50 RUN``` Sound. There also is a port ( port \$F2 ) that makes it possible to produce all sorts of sounds. We will not discuss this port here because it will be discussed in a separate chapter. Palette changes. Normally the colour of a certain PALETTE is changed with the PAL instruction, but we can also do this by controlling a certain port ( port \$F0 ), the first digit of the second number is the PALETTE and the second digit is the assigned colour. For example: OUT@\$F0,\$39 the number \$39 is important. The 3 means that PALETTE 3 will be changed and the 9 means that PALETTE 3 gets the colour 9 as its new colour. Here is a program: ```10 INIT "CRT:M1" 20 SYMBOL [1]100,0,"NEPTUNES",2,2 30 SYMBOL [2]100,20,"NEPTUNES",2,2 40 SYMBOL 100,40,"NEPTUNES",2,2 50 FOR D=\$3F TO \$0 STEP -1 60 OUT@\$F0,D 70 WAIT 100:NEXT D 80 PAL 0,0:PAL 1,1:PAL 2,2:PAL 3,15``` Crashing the computer. There is a port that crashes the computer when we read it. This is port \$E0. The reason for this has to do with bankswitching, which is discussed in chapter 4. We switch to another part of the memory and this makes the computer crash. Just try this: `INP@\$E0,A` Now the computer is frozen and BASIC must be reloaded. You can also press the reset button in combination with the CTRL-key. How to find your own INs and OUTs. Because there are only 255 ports, it is not very difficult to find useful INs and OUTs yourself. The presence of 255 ports means that there are not so many useful INs and OUTs. It is also possible that there are still a few undiscovered but useful INs and OUTs and maybe you can discover them. For finding useful INs and OUTs you need to know what you are looking for before you can start your search. You can do this as follows: Let us take the tape recorder as an example. We are looking for a port that checks if a button on the tape recorder is pressed. It is possible such a port does not even exist, then your search will be in vain, but you will see that after a while. Let us start by reading the highest port (port \$FF) as follows: ```10 INP@\$FF,A 20 PRINT A:GOTO 10``` While this program is running we should press the PLAY-button for example to see if a change in the number sequence occurs. If it does not, we check the port below that ( port \$FE ). After a while you will reach port \$D2 and then you will notice that a change occurs in the number sequence and behold: We have found the port responsible for checking which button of the tape recorder is pressed. You probably wonder why we start at port \$FF and not with port \$00. This has to do with the fact that most ports responsible for things like this have a high value. Just look at all INs and OUTs given so far, they all have high values. In a similar way we can find useful OUTs. You start with port \$FF and send all values between 0 and 255 to this port and watch what happens. By doing this you will for example find that by sending things to port \$F2 will make the SHARP produce sound. Controlling the ports with a program looks like this: ```10 FOR A=0 TO 255 20 OUT@\$F2,A:NEXT A```

last updated March 10, 2006
Arjan Habing, Mark de Rover, Jeroen F. J. Laros, sharpmz@sharpmz.org