Columns


Q & A

Formatting Floppies with an Embedded Controller

Ken Pugh


Kenneth Pugh, a principal in Pugh-Killeen Associates, teaches C and C++ language courses for corporations. He is the author of C Language for Programmers and All On C, and was a member on the ANSI C committee. He also does custom C programming for communications, graphics, image databases, and hypertext. His address is 4201 University Dr., Suite 102, Durham, NC 27707. You may fax questions for Ken to (919) 489-5239. Ken also receives email at kpugh@dukemvs.ac.duke.edu (Internet).

Q

I program rather simple control routines in C on embedded 8086-family, single-board computers. The need has arisen to be able to write 512-byte blocks of data to a 3.5-inch floppy disk drive. This will allow the data logging of process parameters as the controller controls the process. I program with either QuickC or Turbo C. I have no problem reading data by sectors using INT86X on an MS-DOS system.

Since I do not have the support of MS-DOS, I cannot use fopen, INT86X, or fwrite. I would not need to use a directory of files as long as I can address specific sectors and tracks. Can you steer me in the right direction so that I can build some code to transfer a block of data?

Your help is appreciated.

Harold Kilts
Andover, MN

A

This is an interesting coincidence. I have just helped program a system to duplicate the MS-DOS directory and file structure on an embedded controller. There was a need for the system to be able to write files which were then readable on a regular MS-DOS machine using the normal file routines. The embedded system could even format MS-DOS disks.

That was rather an ambitious project. Yours sounds a bit easier, although on a different scale. You simply wish to create a custom-formatted disk (i.e., a disk with no MS-DOS file structure) on your embedded controller. It sounds like you already have the method (using INT86X, Interrupt 0X25 Absolute Disk Read) for reading it.

You should create a low-level write routine that will take a logical sector and an address as parameters. It will need to translate the logical sector to a track/sector. The next steps are to turn on the drive motor and command the controller to seek to the specified track. A set of values is then sent that specifies the bytes per sector, sector gap, sector number, and operation (read/write). If you have DMA (Direct Memory Access) in your system, you will also need to set that up. Otherwise, you can use programmed I/O to read the individual bytes. The actual commands to perform this are based on the controller chip in your system. The IBM Technical Reference Manual BIOS assembly listing gives a good explanation of how they interfaced with the diskette using a NEC controller chip. It runs to about six pages of assembly language. Alternatively, you could purchase a real-time executive that already includes write-to-DOS-disk functionality in it. If you are using one already, it's possible the vendor has an add-on that provides it.

Q

I would like to write a function that takes a variable number of arguments, passes them to the sprintf function for formatting, and then processes the resulting string one character at a time, such as sending each character to the printer using INT17H BIOS calls. I know how to write a routine using varargs.h, but I do not like the idea of duplicating the string-formatting code already available in the sprintf function. I assume that this is the approach that the printf and fprintf functions use. How do they do it? Your advice would be appreciated.

Brett Johnson
Columbia, SC

A

You can use vsprintf to format the values into the string you are passed. Your routine could look something like Listing 1. You simply replace the call to do_it_for_one by whatever you like. I can't say for sure how each compiler's fprintf and printf do it, but I assume they would basically look the same as this function. There is an "environmental limitation" in the ANSI standard that states that the "minimum number for the maximum number of characters produced by any single conversion shall be 509." A #define for that size does not appear to be anywhere in a header file. No information is given as to the consequences of exceeding that size.

Check Digits

As I was perusing my junk pile, I came across a couple of pages on algorithms for check digits. There was a question in last month's column regarding this. The algorithm is called Modulus 10 Double Add Double. To calculate the check digit, you add up the digits in the odd positions (first, third, fifth, etc) in a number. You multiply each even position digit by 2. If the product is two digits, you add them together. You add these products to the sum of the odd digits. Finally you take the 10's complement of the units digit in the total.

An example will clarify this. Suppose your number is 536,891. The digits in the odd positions are 5, 6, and 9. Their sum is 20. The digits in the even positions are 3, 8, and 1. Multiplying each by 2 gives 6, 16, and 1. The second of these (16) has two digits, so those digits are added together. This gives 6, 7, and 1. The sum of these is 14. Adding that to the 20 gives 34. The units digit is 4. The 10's complement of 4 is 6 and that is the check digit.

The final step was described in one set of notes as subtracting the total from the next higher multiple of 10. In this example that multiple would be 40 and 40 minus 34 yields the check digit of 6. I guess those notes were from pre-New Math days.

Reader's Feedback

++ Answer

Why didn't you suggest:

    for (i = 0; i < 10; i++)
        {
        array[i] = i;
        }
instead of (The C Users Journal, August 1992 - Page 131)

    for (i = 0; i < 10;)
        {
        array[i] = i;
        i++;
        }
P.S. I love your Q?A! column.

Peter Cole
Duncanville, TX

Mostly because I was trying to make the point about when the ++ operation is actually performed. The original code was

    for (i = 0; i < 10; )
      {
      array[i++] = i;
      }
The latter form is closer to this than your suggestion. However, I always write loop code in the form you suggest. (KP)

Liana

You read a review of Liana, the Windows prototyping package in this magazine a few months ago. Let me state that I have used the package and it is excellent for prototyping. (KP) c