Atari Programmer's Clinic
MATHEW Lodge chairs this month's programmer's problem solving forum covering such diverse topics as queries about paddles, a fix enabling 0.5Mb and 1Mb SIMMs to be mixed in STEs. Other items include IMG file routines, a STOS tip, MIDI queries and a MINIX question.
Mixing SIMMs in the STE
One clear fact arose from the recent confusion over STE memory upgrades: You cannot mix 512K SIMMs with 1MB SIMMs. However, even this is not a fact any more, since David Hoggan of Southsea, Devon has provided a software patch that enables STE owners to mix the two types to give a 2.5Mb STE.
The reason that mixing the two types of SIMM normally doesn't work is that there is a bug in TOS 1.6 such that the Memory Management Unit (MMU) is incorrectly programmed during boot-up.
Memory in STEs (and STs too) is split into two banks. When the STE is booted, it starts by assuming there is 2Mb in each bank, and by writing a series of test patterns to various parts of memory it works out exactly how much memory is fitted.
Unfortunately, TOS 1.6 in the STE adds up the memory and gets the wrong answer - when 2.5Mb is fitted, it believes that 4Mb is present. This causes problems as programs (particularly GEM) attempt to write to memory that doesn't exist.
The following program should be assembled and placed in an AUTO folder. Make sure that it is run before any other AUTO folder programs by copying it into the folder before anything else is put there. Comments in the source indicate the order in which the SIMM cards should be fitted.
------------------------------------------------------------------------------
A:\LISTINGS\SIMM.S
------------------------------------------------------------------------------
* STE SIMM mixer by David Hoggan
* Lets STE configure 2.5 Megs properly
* MUST BE FIRST IN AUTO FOLDER!
* This program asssumes 2Mb in bank 0 and 0.5Mb in bank 1.
* It has been found that the other way around doesn't work
* - the MMU configures to a 1Mb machine.
* Install your SIMMs as follows:
*
* (back of STE)
*
* |-- 1meg SIMM --|
* |-- .5meg SIMM --|
* |-- 1meg SIMM --|
* |-- .5meg SIMM --|
*
* (front of STE)
clr.l -(sp)
move.w #32,-(sp) Switch to super mode
trap #1
addq.l #6,sp
cmp.l #$280000,$42E RAM <= 2.5 megs?
ble already If so, nothing to do
cmp.b #9,$424 Is it installed properly?
bne already If so, nothing to do
move.l #$280000,$42E Set phystop
move.l $4F2,a0 Find reset address
jmp (a0) Reset system
already: move.l d0,-(sp) Returned stack
move.w #32,-(sp) Switch back to user mode
trap #1
addq.l #6,sp
clr.w -(sp) Back to TOS
trap #1
------------------------------------------------------------------------------
David notes that: "While not the most elegant solution, I have had no problems with compatibility while running any software or hardware combination. Memory block zero must contain 1Mbit SIMM cards, otherwise the MMU will be configured for a 1MB machine".
STOS tip
Kevin Ware-Lane of High Wycombe, Buckinghamshire, has found an undocumented feature in STOS BASIC:
"Create any file, and save it in the root directory of your working copy of the STOS Basic disk. It must be saved under the file name AUTOEXEC.BAS. Now, whenever you boot your working copy of STOS, that BASIC program will be loaded and run."
GFA takes parameters
Many programmers know how to read the command line passed to a .TTP program, or the document name of an installed GEM application is when it double clicked on. However, few people know how to do it in GFA BASIC - this month, Leighton Cathcart from Bangor, Co. Down in Northern Ireland comes to the rescue.
"Accessing the command line is very easy as GFA BASIC contains a built-in variable called BASEPAGE, which holds the address of the basepage of your program. The command line string is stored 128 bytes further on from this address.
The length of the command line string is stored at BASEPAGE+128 and the string starts at BASEPAGE+129, terminated by a zero. The folowing program is an example in which the command line is placed in the string ARG$. You should compile it and give it a .TTP extension".
------------------------------------------------------------------------------
A:\LISTINGS\GFA_TTP.BAS
------------------------------------------------------------------------------
Rem Read command line in GFA
Rem By Leighton Cathcart
Length%=Peek(Basepage+128)
If Length%=0
Print"No command line"
End
Else
For Count%=129 To (129+Length%)
Char%=Peek(Basepage+Count%)
Arg$=Arg$+Chr$(Char%)
Next Count%
Endif
Print"Command line:";Arg$
Repeat
Until Inkey$=Chr$(13)
------------------------------------------------------------------------------
"This will work not only for .TTP programs, but also for GEM .PRG programs as well. When you select Install Application from the desktop, the name of the file you opened to run your application is also placed at this location in memory."
What a GFA dump!
Another GFA user is Giulio Marchesi from Bergamo in Italy. Giulio has provided a program in GFA BASIC V2 to produce better proportioned screen dumps for Degas Elite .PI3 pictures. The program was written for an Epson FX-800 9-pin printer, but it should work on all compatibles.
------------------------------------------------------------------------------
A:\LISTINGS\GFA_DUMP.BAS
------------------------------------------------------------------------------
Rem Degas PI3 screen dump
Rem By Giulio Marchesi
' print Degas .PI3
INPUT "Filename: ";file$
BLOAD file$,XBIOS(2)-34
GOSUB print_degas
'
PROCEDURE print_degas
a$=SPACE$(800) ! buffer for line data
g$=CHR$(27)+"*"+CHR$(1)+CHR$(800)+CHR$(800/256)
' FX 800 graphics mode, double density)
OPEN "",#99,"LST:" ! open printer channel
FOR s%=XBIOS(3) TO s%+79 ! reads screen data
x%=VARPTR(a$)
FOR q%=s%+399*80 TO s% STEP -80
FOR i%=0 TO 1 ! double data for double density
POKE x%,PEEK(q%)
INC x%
NEXT i%
NEXT q%
PRINT #99,g$;a$;CHR$(13); ! one line and CR
PRINT #99,CHR$(27);"J";CHR$(1); ! 1/216 line feed
PRINT #99,g$;a$;CHR$(13); ! print line again
PRINT #99,CHR$(27);"J";CHR$(23); ! 23/216 feed
NEXT s%
CLOSE #99
RETURN
------------------------------------------------------------------------------
Turn over a new leaf
On now to computer literature, and Mark T. White of Toronto, Canada has a plea for anyone recommending books for further reading: "May I make a plea to all contributors: If you quote a book, please include its ISBN number, in addition to the full name, author(s) and publisher.
"I found Katherine Peel's 'Concise Atari ST 68000 Programmer's Guide' (Glentop), ISBN 1 85181 172 9, through an advert in ST World. I have been unable to find Balmer and Fitler's 'Programmer's Guide To GEM' (Sybex) without knowing the ISBN. Does anyone know it, or where I can get the book?".
STE is a joy to use
Tony Goodhew writes from Birstall, Leicester on the subject of the new controller ports found on the STE:
"The STE addendum sheet supplied with the new machine gives pinout specifications, but no details about how to read the port. I am particularly interested in pins 5 and 15 - the paddle inputs, as these must be connected to a four channel analogue to digital converter chip. I would be most grateful for some help in using these inputs from either HiSoft Power BASIC, or GFA BASIC V2.
"A similar input on a BBC Micro has been put to good use in the past for simple data logging applications, and I forsee many educational uses if this port can be used in the same manner".
Atari's STE Developer Information Addendum provides the necessary technical data. Four new joystick ports were added for the STE, directly interfaced to the 68000 bus, rather than using another IKBD controller. The following table gives the locations of the hardware registers for the joysticks, paddles and light gun/pen inputs:
STE CONTROLLER PORTS
Address Usage Description
=================================================
FF9200 xxxx xxxx xxxx 3210 Fire buttons
FF9202 UDLR UDLR UDLR UDLR Joystick directions
Joy3 Joy2 Joy1 Joy0
FF9210 xxxx xxxx NNNN NNNN Paddle 0 X
FF9212 xxxx xxxx NNNN NNNN Paddle 0 Y
FF9214 xxxx xxxx NNNN NNNN Paddle 1 X
FF9216 xxxx xxxx NNNN NNNN Paddle 1 Y
FF9220 xxxx xxNN NNNN NNNN Light pen/gun X
FF9222 xxxx xxNN NNNN NNNN Light pen/gun Y
Note that the joystick registers are bi-directional and can therefore be written to as well as read. If the registers are written, then the outputs are driven until the registers are read again.
Two paddle controllers can be connected with eight bit resolution on each axis, and the current position of each of the four paddles are reported in the registers shown in the table. No information is given in the data sheets as to the voltage range that the A/D converters function in, but I would guess that it is 0-5V. The triggers on the paddles are bits zero and one of $FF9202 (joystick zero left and right.)
The light gun/pen position is reported in $FF9220 and $FF9222. The x-axis accuracy is four pixels in low resolution, eight pixels in medium and 16 pixels in monochrome. The y-axis position is accurate to within one pixel in all modes.
The x position only ranges from 0 to 319, and therefore must be left shifted for other screen modes. Again, no electrical information is provided on how to implement a light gun/pen.
The key to the problem
Lloyd Patton provides help for Paul Margetson, who wants to write his own keyboard interrupt handler in order to test for the depression of more than one key at once. The problem is that if a replacement interrupt handler is written, then the operating system does not receive the key press information, and typing commands into a debugger becomes impossible.
"Simply placing the keystroke data into the keyboard buffer will be sufficient. Each keystroke is stored in a circular-list buffer as a 32 bit integer, in the format returned by the Bconin routine. The low word contains the character, the high word has the scan code in the lowest 8 bits and the kbshift variable in the highest 8 bits. Also remember to update the Iorec structure and take care of rotation around the buffer".
Here is Lloyd's solution:
------------------------------------------------------------------------------
A:\LISTINGS\INSERT.C
------------------------------------------------------------------------------
/* Insert keypresses by Lloyd Patton */
#include <local.h>
#include <osbind.h>
main()
{
long UpperA = 0x001e0041; /* 'A' */
long Number0 = 0x000b0030; /* '0' */
long ch;
appl_init();
insert_char(UpperA);
ch = evnt_keybd(); /* test GEM call */
printf("\nkeystroke should be 0x1e41 and is 0x%lx\n",
ch);
insert_char(Number0);
ch = Bconin(2); /* test BIOS call */
printf("\nkeystroke should be 0x000b0030 and is
0x%08lx\n", ch);
evnt_keybd();
appl_exit();
}
insert_char(keycode)
long keycode;
{
iorec *keybuf;
long stack;
keybuf = Iorec(1); /* get Iorec address */
stack = Super(0L); /* supervisor mode to access Iorec
*/
/* loop around buffer */
if ((keybuf->ibuftl += 4) >= keybuf->ibufsiz)
keybuf->ibuftl = 0;
/* if room in buffer store keystroke */
if (keybuf->ibuftl != keybuf->ibufhd)
*(long *)&keybuf->ibuf[keybuf->ibuftl] = keycode;
Super(stack); /* back to user mode */
}
------------------------------------------------------------------------------
Speedy AUTO solution
Lloyd's also supplies a solution to Pete Ellis' problem of setting the double-click speed from the AUTO folder:
"The only call to set this is evnt_dclick() which can be used only after GEM initialisation and thus after the AUTO folder programs have run. If the Control Panel is a problem using up a valuable accessory slot then write a program that is run from the desktop then use the following listing, but if the problem is memory usage then use a smaller DA like ROCP:"
main()
{ /* the control panel's dialogue setting is unaffected.
However, the dclick value does come into effect. */
appl_init();
evnt_dclick(4, 1);
appl_exit();
}
MIDI clock
Finally this month, a query from Rolf Nilsson of Genarp, Sweden, who has been dabbling with MIDI in assembler and C. "Since I am a musician, my main interest in programming is about MIDI. I have managed to program some simple MIDI programs, like getting MIDI bytes in to the ST, then manipulating and sending them back out again. I've also written a simple sequencer, but I need help.
"Can anyone suggest how to implement the clock that is the heart of any sequencer? This is vital if MIDI replay is to be accurate. Is it done through interrupts?
"There are some good books on MIDI programming for IBMs and compatibles, but they don't deal with this problem because the MIDI interface (Roland MPU-401 or equivalent) takes care of the clock."
Winding down
Clinic is more yours than it is mine, so if you know the answer to a problem then write in. Keep the letters coming - especially the solutions and comments on other people's problems and ideas, but don't forget that the clinic depends on your problems too! Remember to include your full name and give your phone number if possible.
If you have a listing longer than about 25 lines then please include it on a disk. Putting the text of your letter on disk is helpful, too, 1st Word format if possible, but straight ASCII is fine.
If you are sending a complete program then I also like to see it running before putting it into the column, so please include a double-clickable version of your program if at all possible. If you want the disk returning include a stamped addressed envelope.
Mathew Lodge
"Programmer's Clinic"
"Maen Melin"
Holmes Chapel Road
Lach Dennis
Northwich
Cheshire
CW9 7SZ
JANET : SOCS18 @ uk.ac.york.vaxa