IOCB'S

by Anthony Roberts

 

 

Issue 15

May/Jun 85

Next Article >>

<< Prev Article

 

 

When I first started using machine code one of the first problems I encountered was what program to write. To solve this problem I looked through some back issues of computer magazines to see what other people had written. One feature that seemed to crop up fairly often was the use of IOCB's and in particular the section of CIO's. As a result I learned all that I could and finally became proficient in their use.

The name IOCB stands for Input Output Control Block and CIO stands for Central Input Output utility. As the names suggest they also allow the user to control the input from and output to various devices. The devices that are normally controlled using CIO's are cassette recorders, disk drives, printers, the screen and a few others. By changing a few parameters it is possible to send any amount of any sort of data to a device.

So what? Well if you have ever tried to do graphics in machine code or access data files on a disk or cassette or dump a screen to the printer then you will appreciate just how difficult it can be.

Those of you who are familiar with the BASIC command OPEN #n will have a head start because CIO's are exactly the same thing. If you have never come across the OPEN command then look it up in a users manual.

There are certain differences in the way CIO's are used from machine code and the way they are used in BASIC but these will become apparent as you use them. The main thing to remember is that there is no automatic error checking in machine code so if you make an error and don't check for it, all sorts of problems will arise. The most common mistake is to try and access devices that are not open or to try and open devices that are already open.

DEVICE NAMES:

These are the names used when you open a device.

E: Screen editor (see Basic Manual)
S: Screen graphics for graphics modes 
P: Printer (output only)
K: Keyboard (input only)
C: Cassette recorder
D:*.* Disk directory
D:filename.ext   Disk files

OPENING AN IOCB

Before you can open an IOCB it must first be closed. This is to prevent errors occurring when you attempt to open an already open IOCB.

To close an IOCB, you must first choose which one you are going to work with. There are five possible choices here and they correspond to the numbers 1,2,3,4 and 5 in BASIC. In machine code, you choose the number by loading it into the `X' register. The number you load is '#$10' for IOCB 1, '#$20' for IOCB 2 etc. When you have decided, use Listing 1 to close that IOCB.

00010

LDX #$10

; IOCB #1

00020

LDA #$OC

; COMMAND FOR CLOSE

00030

STA $342,X

; COMMAND LOCATION

00040

JSR $E456

; CALL OS ROUTINE

00050

LDA #$03

; COMMAND FOR OPEN

00060

LDX#$10

; IOCB #1

00070

STA $342,X

00080

LDA #LAB

; LOW BYTE OF DEVICE NAME

00090

STA $344,X

; BUFFER ADDRESS (LOW)

00100

LDA /LAB

; HIGH BYTE OF DEVICE NAME

00110

STA $345,X

; BUFFER ADDRESS (HIGH)

00120

LDA #$08

; OPEN FOR OUTPUT

00130

STA $34A,X

00140

LDA #$00

; JUST TO BE SAFE BUT NOT NEEDED

00150

STA$34B,X

00160

JSR$E456

00170

LDA #$08

; GOING TO SEND STRING

00180

LDX #$10

; IOCB #1

00190

STA $342,X

00200

LDA #MES

; LOW BYTE OF MESSAGE ADDRESS

00210

STA#344,X

00220

LDA /MES

; HIGH BYTE OF MESSAGE ADDRESS

00230

STA $345,X

00240

LDA #$FF

; MUST BE MORE THAN MESSAGE LENGTH

00250

STA $348,X

; BUFFER LENGTH HELD HERE (LOW)

00260

LDA #$00

; JUST TO BE SAFE

00270

STA #349,X

; BUFFER LENGTH HELD HERE (HIGH)

00280

JSR $E456

00290

LDA #$0C

; CLOSE IOCB #1

00300

LDX#$10

00310

STA $342,X

00320

JSR $E456

00330

BRK

; END OF PROGRAM

00340 LAB

.AS "E:"

; DEVICE NAME

00350 MES

.AS "ATARI COMPUTERS ARE GREAT" 

00360

.HS 9B

; END OF LINE CHARACTER

Line 10 tells the computer which IOCB to close. Line 20 loads the accumulator with the number #$0C. This is the number which tells the routine you want to close the IOCB. Line 30 stores the number #$0C in location $342 offset by X. Because X has the value of $10 in it the number will be stored in $352. The reason we have to use the 'X' register is because the computer uses the value in the 'X' register to decide which one to close. Line 40 calls the operating system routine that actually performs the close operation.

Now that the IOCB is closed you want to open it for a device. When you do this you need to declare the device name, which is best done by storing it in an ASCII string. The conventions I will use are those used by the SYNASSEMBLER but there are conversions at the end of this article for the ATARI ASSEMBLER-EDITOR. Listing 2 will open an IOCB.

The program opens IOCB 1 for the screen editor (E:). Lines 50, 60 and 70 tell the computer you want to open up IOCB 1. Line 80 is loading the accumulator with the low byte value address of the label 'LAB'. For example, if the address of the label 'LAB' was $1234 then the low byte value of the address would be #$34. Line 90 stores this value in a location where the computer can find it for later use. Lines 100 and 110 do the same thing as the two previous lines except they are loading and storing the high byte value of the address (e.g. #$12). The reason for these four lines is so that when the computer comes to perform the open it can look in locations $348 and $349 to find the address where the name of the device is located (E: is the name of the device). Lines 120 and 130 put a #$08 into #34A,X. The contents of location #34A,X tell the computer which direction the data will be travelling (i.e. to or from the device). In this case the 8 means we will be sending data. Lines 140 and 150 are just to be tidy because the 0 in the location has no effect on this particular IOCB. Line 160 calls the routine to do the open.

LOCATION  USED FOR POSSIBLE VALUES RESULT
$E456  Calls the routine to act on IOCB None  Execution of IOCB
$342 Sets the way the IOCB will be  used 3 open the IOCB
12 Close the lOCB
7 Get binary record
11 Put binary record
4 Input string
8 Output string
$344

 

Low byte value of buffer address 0 - 255 Tells the computer the low byte address of where to get or put data
$345  High byte value of buffer address 0 - 255 Same as above only High
address byte
$348 Low byte value of buffer length 0 - 255  Sets the amount of data to be moved (low byte)
$349 High byte value of buffer length
0 - 255 Same as above only high
length byte
$34A Sets the direction of data 4 transfer 4 Read data
8 Write data
12 Read and Write data
6 Open for directory
$34B Used mainly for graphics 0 - 255 See graphics table

USING THE IOCB

Now that the IOCB is open you want to do something with it In this case because we put a #$08 into $34A,X we want to send data. To send data to the device we use the routine in Listing 1.

The routine will print the message on the screen. Lines 170 to 190 are putting a #$08 into command location ($342). The #$08 tells the computer to expect an undetermined amount of data. This is like printing a string in BASIC, because you don't need to know how long the string is to print it The computer will stop printing data when it reaches a #$9 B. Lines 200 to 230 are instructing the computer how much data to send. Because we have used a #$08 in $342,X the number in these two locations only has to be more than we want to send. If you are sending a known amount of data then these two locations should contain this number. $344,X is the low byte and $345 is the high byte. Line 280 executes the operation.

If you are not familiar with the low byte, high byte notation it simply means the storing of numbers greater than 255 in two consecutive locations. Because the maximum value in one location is 255 we have to store numbers greater than this in a special way. The high byte location contains the number of 256's in the number and the low byte location contains the number of 1's in the number. If you wanted to store the number 1027 you would place a 4 in the high byte (4*256=1024) and a 3 in the low byte (3* 1=3). The result is 1024+3=1027. The same principle is used when storing an address.

When you have finished writing the program you must close the IOCB by using the first part again.

Now the best thing to do is to practice sending or receiving data from other devices such as the printer. You can have more than one device open at a time so that you can read data from a disk using one IOCB and print it to the screen using another. Have fun!

Some conversions 

SYN-ASSEMBLER ATARI ASSEMBLER-EDITOR
#LAB LAB&255
/LAB LAB/256
.AS "ATARI etc." .BYTE "ATARI etc"
.HS 9B .BYTE #$9B

With the Atari Editor you will need a *=$4000 at the start of the program.

GRAPHICS TABLE:

The following program will open the screen for graphics mode 2 and print a message.

00010

; GRAPHICS MODE 2 PROGRAM

00020

;

00030

LDX #$10 

; CLOSE IOCB # 1

00040

LDA #$OC

00050

STA $342,X

00060

JSR $E456

00070

LDA "$03 

; PEN IOCB a1

00080

LDX #$10

00090

STA $342,X

00100

LDA #SNAME 

; DEVICE NAME (LOW)

00110

STA $344.X

00120

LDA/SNAME  

; DEVICE NAME (HIGH)

00130

STA $345,X

00140

LDA #$18 

; SPLIT SCREEN + OUTPUT

00150

STA $34A,X

00160

LDA #$02 

; GRAPHICS MODE

00170

STA $34B.X

00180

JSR $E456

00190

LDA #$11

; PUT BINARY RECORD

00200

LDX #$10

00210

STA $342,X

00220

LDA "$06 

; AMOUNT OF DATA TO SEND (LOW)

00230

STA $348,X

00240

LDA #$00 

; AMOUNT OF DATA TO SEND (HIGH)

00250

STA $349,X

00260

LDA # WORD;

; LOW BYTE ADDRESS OF MESSAGE

00270

STA #344,X

00280

LDA/ WORD

; HIGH BYTE ADDRESS OF MESSAGE

00290

STA #345,X

00300

JSR $E456

00310

BRK 

; END OF PROGRAM

00320SNAME

.AS "S:"

 ; DEVICE NAME

00330WORD

AS "MODE 2"*

When the graphics screen is opened the mode number goes into location $34B,X. Location $34A,X contains details of the type of screen you want i. e. split screen configuration. The diagram below shows how to obtain the different types of screen.

128 64 32 16 8 4 2 1
C S W R

If bit 'C' is set (i. e. equal to 1) then when the screen is opened the current display will not be cleared.

If bit 'S' is set then the screen will be set up for a split screen arrangement. This is the same as if you opened a screen in BASIC without putting the '+16' on the end.

If bit 'W' is set then this instructs the screen to expect data to be sent to it This is set when you want to do 'PLOTS' and 'DRAWTOs'.

If bit 'R' is set then the screen will be set up so that you can get data from the screen. This is used when you wish to do a 'LOCATE' statement.

top