- CHAPTER 5 -
This chapter will cover those aspects of Atari software programming
that can only be accomplished by accessing hardware registers
directly. In most cases, Atari has provided OS calls to manipulate
the hardware. When an OS call exists to access hardware, it should
always be used to ensure upward and backward compatibility.
Keep in mind that access to hardware registers is limited to those
applications operating in supervisor mode only (except where noted
otherwise).
Besides those hardware registers discussed here, a complete list
of I/O registers, system variables, and interrupt vectors are
contained in Appendix B: Memory Map.
Atari computers use the Motorola MC68000 or MC68030. Third party
devices have also been created to allow the use of a MC68010,
MC68020, or MC68040 processor. The system cookie '_CPU' should
be used to determine the currently installed processor. The following
table lists the 680x0's interrupt priority assignments:
HARDWARE
Overview
The 680x0 Processor
| Assignment |
---|---|
| NMI |
| MK68901 MFP |
| SCC |
| VBLANK (Sync) |
| VME Interrupter |
| HBLANK (Sync) |
| Unused |
Interrupts may be disabled by setting the system interrupt mask
(bits 8-10 of the SR register) to a value higher than the interrupts
you wish to disable. Setting the mask to a value of 7 will effectively
disable all interrupts (except the level 7 non-maskable interrupt).
The Atari TT030 and Falcon030 contain onboard data and instruction
caches. These caches may be controlled by writing to the CACR register (in supervisor mode). The following table lists longword
values that may be written to the CACR to enable or disable the
caches:
The Data/Instruction Caches
| Effect |
---|---|
| Flush and disable both caches. |
| Enable both caches. |
| Flush and disable the data cache. |
| Enable the data cache. |
| Flush and disable the instruction cache. |
| Enable the instruction cache. |
A MC6888x math coprocessor may be installed in a Mega ST, Mega STe, or a Falcon030. The TT030 has one installed in its standard configuration. The 6888x is interfaced to the 68000 in peripheral mode and to the 68030 in coprocessor mode. Thus, the TT030 and Falcon030 computers access the 6888x in coprocessor mode while the Mega ST and MegaSTe computers access the 6888x in peripheral mode.
When the 6888x is interfaced in coprocessor mode, using it is as simple as placing floating-point instructions in the standard instruction stream (use a coprocessor ID of 1). The 68030 will properly dispatch the instruction and respond to exceptions through the following vectors:
| Assignment |
---|---|
| FTRAPcc Instruction |
| F-Line Emulator |
| Co-processor Protocol Violation |
| Branch or Set on Unordered Condition |
| Inexact Result |
| Floating-Point Divide by Zero |
| Underflow |
| Operand Error |
| Overflow |
| Signaling NAN |
To execute a floating point instruction, use the following protocol for communicating data with the 6888x:
1. Wait for the chip to be idle.
2. Write a valid 6888x command to FPCMD.
3. If necessary for the command, write an operand to FPOP.
4. Wait for the status port to indicate the command is complete.
5. Read any return data from FPOP.
Step one is achieved by waiting for a value of 0x0802 to appear in the status register (after ANDing with 0xBFFF) as follows:
while( ( FPCIR & 0xBFFF) != 0x0802 ) ;
Steps two and three involve writing the command word to FPCMD and any necessary operand data to FPOP. A primitive response code will be generated (and should be read) between each write to either FPCMD or FPOP. For a listing of primitive response codes returned by the 68881, consult the MC68881/68882 Floating-Point Coprocessor User's Manual (2nd edition), Motorola publication MC68881UM/AD rev. 2, ISBN 0-13-567-009-8.
After the operation is complete (step 4), data may be read from the 68881 in FPOP (step 5).
When sending or receiving data in FPOP, the following chart details the transfer ordering and alignment:
The following code demonstrates transferring two single precision floating-point numbers to the 68881, multiplying them, and returning the result.
/* Number of iterations before an error is triggered */ #define FPCOUNT 0x80 #define FPCIR ((WORD *)(0xFFFFFA40L)) #define FPCMD ((WORD *)(0xFFFFFA4AL)) #define FPOP ((float *)(0xFFFFFA50L)) WORD fpcount, dum; /* fperr() is user-defined */ #define FPwait() { fpcount = FPCOUNT; \ while((*FPCIR & 0xBFFF) != 0x0802) \ if(!(--fpcount)) fperr(); } #define FPsglset(r,v) { FPwait(); \ *FPCMD = (0x5400 | ((r) << 7)); \ while((*FPCIR & 0xFFF0) != 0x8C00) \ if(!(--fpcount)) fperr(); \ *FPOP = (v); } #define FPsglmul(r1,r2) { FPwait(); \ *FPCMD = (0x0027 | ((r2) << 10) | ((r1) << 7)); \ dum = *FPCIR + 1; } /* dum = FPCIR +1; forces the status register to be read (we assume the data's good) */ #define FPsglget(r,var) { FPwait(); \ *FPCMD = (0x6400 | ((r) << 7)); \ while(*FPCIR != 0xb104) \ if(!(--fpcount)) fperr(); \ var = *FPOP; } /* * void sglmul( float *f1, float *f2 ); * * Multiplies f1 by f2. Returns result in f1. * */ void sglmul( float &f1, float &f2 ) { FPsglset( 0, *f1 ); FPsglset( 1, *f2 ); FPsglmul( 0, 1 ); FPsglget( 0, *f1 ); }
All Atari computers support an external 128K ROM cartridge port. Cartridges may be created to support applications or diagnostic tools. The 128K of address space allocated to cartridges appears from address 0xFA0000 to 0xFBFFFF. Newer Atari computers support larger cartridges (this is because the address space would no longer overlap the OS). All program code must be compiled to be relative of this base address.
The LONG appearing at 0xFA0000 determines the type of cartridge installed as follows:
Cartridge |
|
---|---|
Application |
|
Diagnostic |
|
Diagnostic cartridges are executed almost immediately after a
system reset. The OS uses a 680x0 JMP instruction to begin execution
at address 0xFA0004 after having set the Interrupt Priority Level
(IPL) to 7, entering supervisor mode, and executing a RESET instruction
to reset external hardware devices.
Upon execution, register A6 will contain a return address which
should be JMP'd to if you wish to continue system initialization
at any point. The stack pointers will contain garbage. In addition,
keep in mind that no hardware has been initialized, particularly
the memory controller. All system memory sizing and initialization
must be performed by the diagnostic cartridge.
Application cartridges should contain one or more application
headers beginning at location 0xFA0004 as follows (one cartridge
may contain one or many applications):
Application Cartridges
Name |
| Meaning |
---|---|---|
CA_NEXT |
| Pointer to the next application header (or NULL if there are no more). |
CA_INIT |
| Pointer to the application's initialization code. The high eight bits of this pointer have a special meaning as follows: Bit Set Meaning
0 Execute prior to display memory and interrupt vector initialization. 1 Execute just before GEMDOS is initialized. 2 (unused) 3 Execute prior to boot disk. 4 (unused) 5 Application is a Desk Accessory. 6 Application is not a GEM application. 7 Application needs parameters. |
CA_RUN |
| Pointer to application's main entry point. |
CA_TIME |
| Standard GEMDOS time stamp. |
CA_DATE |
| Standard GEMDOS date stamp. |
CA_SIZE |
| Size of application in bytes. |
CA_NAME |
| NULL terminated ASCII filename in standard GEMDOS 8+3 format. |
When application cartridges are present, GEMDOS will allow a special 'c' (lowercase) drive to be accessed. Executable files appear on this drive as they would on any standard disk. This 'drive' may also be installed on the desktop.
The Atari 1040STe and Falcon030 support new enhanced joystick
controls as well as older style CX-40 controls. For the usage and polling of the older style controls, refer to the following
section which discusses the IKBD controller. This section will
focus specifically on the newer style of controllers.
Enhanced joysticks are read by a two-step process. The WORD
at address 0xFF9202 is written to using a mask which determines
which values may subsequently be read from the WORDs at
address 0xFF9200 and 0xFF9202. Valid mask values and the keys
that may be read follow:
Joysticks
| ||
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||||
---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||||
---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To read the joystick, write a mask value corresponding to the
row of keys/positions you wish to interrogate to 0xFF9202. Next,
read back a WORD from either 0xFF9200 or 0xFF9202. As indicated
in the table, cleared bits mean that a key is being pressed or
a joystick is moved in that direction.
Two paddles may be plugged into each joystick port. Each paddle
returns an 8-bit value indicating its position ( 0 = full counter-clockwise,
255 = full clockwise) at the addresses shown below. Unlike joysticks,
paddle positions are returned automatically with no need to write
to an address prior to a read. Paddle fire buttons, however, are
mapped and read in the same manner as the joysticks. See the discussion
of joysticks above for an explanation.
Paddles
|
|
---|---|
|
|
|
|
|
|
|
|
Joystick port 0 supports a light gun or pen. The position that
the gun is pointing to is returned in the WORD registers
at 0xFF9220 (X position) and 0xFF9222 (Y position). Only the lower
10 bits are significant giving a range of values from 0-1023.
Light Gun/Pen
The IKBD Controller
Keyboard keys generate both a 'make' and 'break' code for each
complete press and release respectively. The 'make' code is equivalent
to the high byte of the IKBD scan code. 'make' codes are not related
in any way to ASCII codes. They represent the physical position
of the key in the keyboard matrix and may vary in keyboards designed
for other countries. The XBIOS function Keytbl()
provides lookup values which make internationalization possible.
The key 'break' code is the 'make' code logically ORed with 0x80.
It should be noted that 'key repeats' are not generated by the
ACIA but by a coordination of the ikbdsys and system timer
handlers.
The mouse may be programmed to return position reports in either
absolute, relative, or keycode mode (it is by default programmed
to return relative position reports).
In relative reporting mode, the IKBD generates a mouse packet
each time a mouse button is pressed or released, and every time
the mouse is moved over a preset threshold distance (which is
configurable). A relative mouse report packet is headed by a byte
value between 0xF8 and 0xFB followed by the X and Y movement of
the mouse as signed bytes. If the movement is greater than can
be represented as signed bytes (-128 to 127), multiple packets
are sent.
The header byte determines the state of the mouse buttons as follows:
The Keyboard
The Mouse
| Mouse Button State |
---|---|
| No buttons depressed. |
| Left button depressed. |
| Right button depressed. |
| Both buttons depressed. |
In absolute reporting mode, the IKBD only generates a mouse packet when interrogated. Mouse packets in absolute mode are headed by a 0xF7 byte followed by the MSB and LSB of the X value and the MSB and LSB of the Y value respectively. The minimum and maximum X and Y values are user-definable.
Keycode reporting mode generates keyboard 'make' and 'break' codes
for mouse movements rather than sending standard mouse packets.
Mouse movement is translated into the arrow keys and the codes
0x74 and 0x75 represent the left and right mouse button respectively.
'break' codes are sent immediately after the corresponding 'make'
code is delivered.
The basic CX-40 style joystick controls are still present on every
Atari computer. Atari recommends that these ports should not be
supported when STe/Falcon030 enhanced joysticks are present unless
the option for four-player play is desired. While no direct TOS
support is available for reading these ports, it is possible using
the IKBD controller in one of several joystick reporting modes.
Joystick event reporting mode (the default) sends a joystick packet
each time the status of one of the joysticks changes. The joystick
packet header is 0xFE if the state of joystick 0 has changed or
0xFF if the status of joystick 1 has changed. This header byte
is followed by a BYTE containing the new state of the joystick
as follows:
The four bits corresponding to joystick position can be interpreted
as follows:
Joysticks may be interrogated at any time by sending an interrogate
command (as described later in this chapter). The packet response
to this command is 0xFD followed by the BYTE report of
joystick 0 and 1 (as shown above).
The joysticks may be placed into joystick monitoring or fire button
monitoring mode. In these modes, all other IKBD communication
is stopped and all processor time is devoted to the processing
of packets. Joystick monitoring mode cause the IKBD to send a
continuous stream of two-byte packets as follows: The first byte
contains the status of joystick buttons 0 and 1 in bits 1 and
0 respectively. The second byte contains the position state of
joystick 0 in the high nibble and joystick 1 in the lower nibble
(the position state can be interpreted as shown in the diagram
above).
Fire button monitoring mode constantly scans joystick button 1
and returns the results in BYTEs packed with 8 reports
each (one per bit). These modes may be paused or halted using
the appropriate commands.
Joystick keycode mode is similar to mouse keycode mode. This mode
translates all joystick position information into arrow keys.
A 'make' code of 0x74 is generated when joystick button 0 is depressed
and a 'make' code of 0x75 is generated when joystick button 1
is depressed. The rate at which the IKBD controller generates
these joystick events can be controlled using commands discussed
in the following section.
The IKBD controller maintains a separate time-of day clock that
is kept synchronized with GEMDOS time by OS calls. A time-of-day
packet may be requested using the method shown below under IKBD
commands.
The response packet from the IKBD is seven bytes in length identified
by its header byte of 0xFC and followed by six UBYTES containing
the year (last two digits), month, day, hours (0-24), minutes,
and seconds in BCD format (ex: a month byte in December would
be 0x12).
Commands may be sent to the IKBD using any of the TOS function
calls described above. Some commands may generate packets while
other commands change the operating state of the IKBD controller.
Unrecognized command codes are treated as NOPs. The following
lists valid IKBD command codes:
The Joystick
Time-of-Day
IKBD Commands
| Result |
---|---|
| Set mouse button action. This command BYTE should be followed by a BYTE which describes how the mouse buttons should be treated as follows: BYTE Meaning
0x00 Default mode. 0x01 Mouse button press triggers an absolute position report. 0x02 Mouse button release triggers an absolute position report. 0x03 Mouse button press and release triggers absolute position reports. 0x04 Mouse buttons report key presses. |
| Enable relative mouse position reporting (default). |
| Enable absolute mouse position reporting. This command is followed by the MSB and LSB of the X and Y coordinate maximum values for the mouse. |
| Enable mouse keycode mode. This command is followed by two BYTEs indicating the maximum number of mouse 'ticks' required to generate a keycode for the X and Y axis respectively. |
| Set mouse threshold. This command is followed by two BYTEs which determine the number of mouse 'ticks' required to generate a mouse position report in relative positioning mode. |
| Set mouse scale. This command is followed by two BYTEs which determine the number of mouse 'ticks' for each single coordinate on the X and Y axis respectively. |
| Interrogate mouse position. This command generates an absolute mouse position report. |
| Load mouse position. This command sets the mouse position based on the current coordinate system in absolute reporting mode. The command is followed by a filler BYTE of 0x00 and the MSB and LSB of the new X and Y axis for the mouse. |
| Set Y=0 to the bottom. This command changes the origin of the mouse coordinate system to the upper left of the screen. |
| Set Y=0 to the top. This command changes the origin of the mouse coordinate system to the lower left of the screen. |
| Resume sending data. This command (or for that matter any command) will cause the IKBD to resume sending packet data to the host. |
| Disable all mouse packet reporting. Any valid mouse command resets this state. If the mouse buttons have been programmed to act like keyboard keys, this command will have no effect on them. |
| Pause output. All output from the IKBD controller is halted until a 'Resume' or other command is received. |
| Set joystick event reporting mode. This command causes a joystick report to be generated whenever the state of either joystick changes. |
| Set joystick interrogation mode. This command causes the IKBD to generate joystick packets only when requested by the host. |
| Joystick interrogation. This command causes a joystick packet indicating the status of both joysticks to be generated. |
| Enables joystick monitoring mode. Besides serial communication and the maintenance of the time-of-day clock, this command causes only special joystick reports to be generated.
The command BYTE should be followed by a BYTE indicating how often the joystick should be polled in increments of 1/100ths of a second. |
| Enables fire button monitoring mode. As above, this mode limits the IKBD to serial communication, updating the time-of-day clock, and the reporting of the state of joystick button 1. |
| Set joystick keycode mode. This command is followed by six BYTEs as follows: BYTE Meaning
1 The length of time (in tenths of a second) before the horizontal breakpoint is reached. 2 Same as above for the vertical plane. 3 The length of time (in tenths of a second) between key repeats before the velocity breakpoint is reached. 4 Same as above for the vertical plane. 5 The length of time (in tenths of a second) between key repeats after the velocity breakpoint is reached. 6 Same as above for the vertical plane. |
| Disable joystick event reporting. |
| Set the time of day clock. This command is followed by six BYTEs used to set the IKBD clock. These BYTEs are in binary-coded decimal (BCD) format. Each BYTE contains two digits (0-9), one in each nibble. The format for these BYTEs is as follows: BYTE Meaning
1 Year (last two digits) 2 Month 3 Date 4 Hours (0-23) 5 Minutes (0-59) 6 Seconds (0-59) |
| Interrogate the time-of-day clock. This command returns a packet headed by the value 0xFC followed by six BYTEs as indicated above. |
| Load BYTEs into the IKBD memory. This command is followed by at least three BYTEs containing the MSB and LSB of the address into which to load the data, the number of BYTEs to load (0-127), and the data itself. |
| Read BYTEs from the IKBD controller. This command is followed by two BYTEs containing the MSB and LSB of the address to read from. This returns a packet headed by the BYTE values 0xF6 and 0x20 followed by the memory data. |
| Execute a subroutine on the IKBD controller. This command BYTE is followed by two BYTEs containing the MSB and LSB of the memory location of the subroutine to execute. |
| Reset the IKBD controller. This command is actually a two-BYTE command. The BYTE 0x80 must be followed by a BYTE of 0x01 or the command will be ignored. |
| Return a status message containing the current mouse action state. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 0x07 3 Current mouse action state (see command 0x07) 4-8 0 |
| Return a status message containing the current mouse mode. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 Current mode as follows: 0x08 = Relative mode 0x09 = Absolute mode 0x0A = Keycode mode 3 Absolute mode: MSB of maximum X position (units to current scale). Keycode mode: Horizontal distance threshold that must be passed prior to sending a keycode. Relative mode: 0 4 Absolute mode: LSB of maximum X position. Keycode mode: Vertical distance threshold that must be passed prior to sending a keycode. Relative mode: 0 5 Absolute mode: MSB of maximum Y position (units to current scale). Keycode mode: 0 Relative mode: 0 6 Absolute mode: LSB of maximum Y position. Keycode mode: 0 Relative mode: 0 7-8 0 |
| Same as 0x88. |
| Same as 0x88. |
| Return a status message containing the current mouse threshold state. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 0x0B 3 Number of horizontal mouse 'ticks' that must be traveled prior to sending a mouse packet. 4 Number of vertical mouse 'ticks' that must be traveled prior to sending a mouse packet. 5-8 0 |
| Return a status message containing the current mouse scaling factor. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 0x0C 3 Horizontal mouse 'ticks' between a change in mouse position on the X axis. 4 Vertical mouse 'ticks' between a change in mouse position on the Y axis. 5-8 0 |
| Return a status message containing the current origin point of the Y axis used for mouse position reporting. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 0x0F = Bottom is (Y=0) 0x10 = Top is (Y=0) 3-8 0 |
| Same as 0x8F. |
| Return a status message containing the current state of mouse reporting. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 0x00 = Mouse reporting enabled. 0x12 = Mouse reporting disabled. 3-8 0 |
| Return a status message containing the current joystick mode. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 Current mode as follows: 0x14 = Event reporting mode 0x15 = Interrogation mode 0x19 = Keycode mode 3 Keycode mode: This value represents the amount of time (in tenths of a second) that keycodes are returned to the host for horizontal position events at the initial velocity level (after this time expires, the secondary velocity level is used). Event recording mode: 0 Interrogation mode: 0 4 Keycode mode: Same as BYTE 3 for vertical events. Event recording mode: 0 Interrogation mode: 0 5 Keycode mode: This value represents the initial horizontal velocity level (in tenths of a second). This is the initial rate at which keycodes are generated. Event recording mode: 0 Interrogation mode: 0 6 Keycode mode: Same as byte 5 for vertical events. Event recording mode: 0 Interrogation mode: 0 7 Keycode mode: This value represents the secondary horizontal velocity level (in tenths of a second). This is the rate used after the amount of time specified in bytes 3-4 expires. Event recording mode: 0 Interrogation mode: 0 8 Keycode mode: Same as byte 7 for vertical events. Event recording mode: 0 Interrogation mode: 0 |
| Same as 0x94. |
| Same as 0x94. |
| Return a status message containing the current status of the joystick. After receiving this command the IKBD will respond by sending a status packet (which may be intercepted at statvec) as follows: BYTE Meaning
1 0xF6 2 0x00 = Joystick enabled 0x1A = Joystick disabled 3-8 0 |
The Atari STe, Mega STe, TT030, and Falcon030 are all equipped with the ability to playback stereo digital audio. Only the Falcon030, however, has supporting XBIOS calls which eliminate the need for the programmer to directly access the sound system hardware. Although the Falcon030 has a more sophisticated sound system than the earlier Atari machines, the hardware registers have been kept compatible so older applications should function as expected. Programmers designing Falcon030 applications which use digital audio should use the appropriate XBIOS calls.
The STe, MegaSTe, and TT030 support 8-bit monophonic or stereophonic sound samples. Samples should be signed ( -128 to 127) with alternating left and right channels (for stereo) beginning with the left channel. Samples may be played at 50 kHz, 25 kHz, 12.5 kHz, or 6.25 kHz (6.25 kHz is not supported on the Falcon030).
Several hardware registers control DMA sound output as follows:
Addresses placed in the three groups of address pointer registers must begin on an even address. In addition, only sounds within the first 4 megabytes of memory may be accessed (this limitation has been lifted on the Falcon030). Sounds may not be played from alternate RAM.
To begin sound playback, place the start address of the sound in the Frame Base Address registers. Place the address of the end of the sound in the Frame End Address registers. The address of the end of the sound should actually be the first byte in memory past the last byte of the sample.
Set the Sound Mode Control register to the proper value. Bit 7, notated as 'm' should be set to 1 for a monophonic sample or 0 for a stereophonic sample. Bits 0 and 1, notated as 'r', control the sample playback rate as follows:
| Playback Rate |
---|---|
| 6258 Hz |
| 12517 Hz |
| 25033 Hz |
| 50066 Hz |
To begin the sample playback, set bits 0 and 1 of the Sound DMA Control register, notated as 'c', as follows:
| Sound Control |
---|---|
| Sound Disabled (this will stop any sound currently being played) |
| Sound Enabled (play once) |
| Sound Enabled (repeat until stopped) |
Sound playback may be prematurely halted by writing a 0 to address 0x00FF8900.
Discontinuous sample frames may be linked together using the MFP Timer A interrupt. When a sound is played using repeat mode an interrupt is generated at the end of every frame. By configuring Timer A to 'event count' mode you can ensure the seamless linkage and variable repeating of frames.
For example, suppose you have three sample frames, A, B, and C, in memory and you want to play A five times, B five times, and C only once. Use the following steps to properly configure Timer A and achieve the desired result:
Use Xbtimer() to set Timer A to event count mode with a data value of 4 (the first data value should be one less than actually desired since the sound will play once before the interrupt occurs).
Configure the sound registers as desired and start sound playback in repeat mode.
When the interrupt fires, place the address of frame B in the sound playback registers (these values aren't actually used until the current frame finishes).
Reset Timer A's data register to 5 and exit your interrupt handler.
When the second interrupt fires, place the address of frame C in the sound playback registers.
Reset Timer A's data register to 1 and exit your interrupt handler.
When the final interrupt is triggered, write a 0x01 to the sound control register to cause sound playback to end at the end of the current frame.
Another method of generating interrupts at the end of sound frames is by using the MFP's General Purpose Interrupt Port (GPIP) 7. This interrupt does not support an event count mode so it will generate an interrupt at the end of every frame. In addition, the interrupt must be configured differently depending on the type on monitor connected to the system (this is because GPIP 7 serves double-duty as the monochrome detect signal).
To program GPIP 7 for interrupts, disable all DMA sound by placing a 0x00 in the sound control register. Next, check bit 7 of the GPIP port at location 0xFFFA01. If a monochrome monitor is connected the bit will be 0. The bit will be 1 if a color monitor is connected.
Bit 7 of the MFP's active edge register (at 0xFFFA03) should be set to the opposite of the GPIP port's bit 7. This will cause an interrupt to trigger at the end of every frame. Use Mfpint() to set the location of your interrupt handler and Jenabint() to enable interrupts. From this point, interrupts will be generated at the end of every frame playing in 'play once' mode or repeat mode until the interrupt is disabled.
The STe and TT030 computers use the MICROWIRE interface to control volume, mixing of the PSG and DMA output, and tone control. The original ST is limited to amplitude control through the use of the appropriate PSG register. The Falcon030 supports new XBIOS calls which allow volume and mixing control.
The MICROWIRE interface is a write-only device accessed using two hardware registers 0xFFFF8924 (mask) and 0xFFFF8922 (data). To write a command to the MICROWIRE you must first place the value 0x07FF into the mask register and then write the appropriate command to the data register. The format for the data WORD is shown below:
Bits labeled 'x' will be ignored. Bits 9 and 10 should always be %10 to correctly specify the device address which is a constant. Bits labeled 'c' specify the command and bits labeled 'd' contain the appropriate data for the command. The following table explains the valid MICROWIRE commands:
|
|
|
---|---|---|
Set Master Volume |
| Example Value Result
%000000 -80dB Attenuation %010100 -40dB Attenuation %101000 0dB Attenuation (Maximum) |
Set Left Channel Volume |
| Example Value Result
%000000 -40dB Attenuation %001010 -20dB Attenuation %010100 0dB Attenuation (Maximum) |
Set Right Channel Volume |
| Example Value Result
%000000 -40dB Attenuation %001010 -20dB Attenuation %010100 0dB Attenuation (Maximum) |
Set Treble |
| Example Value Result
%000000 -12dB Attenuation %000110 0dB Attenuation %001100 +12dB Attenuation (Maximum) |
Set Bass |
| Example Value Result
%000000 -12dB Attenuation %000110 0dB Attenuation %001100 +12dB Attenuation (Maximum) |
Set PSG/DMA Mix |
| Example Value Result
%000000 -12dB Attenuation %000001 Mix PSG sound output. %000010 Don't Mix PSG sound output. |
When configuring multiple settings at once, you should program a delay between writes since the MICROWIRE takes at least 16sec to completely read the data register. During a read the MICROWIRE rotates the mask register one bit at a time. You will know a read operation has completed when the mask register returns to 0x07FF. The following assembly segment illustrates this by setting the left and right channel volumes to their maximum values:
MWMASK EQU $FFFF8924 MWDATA EQU $FFFF8922 MASKVAL EQU $7FF HIGHLVOL EQU $554 HIGHRVOL EQU $514 .text maxvol: move.w MASKVAL,MWMASK ; First write the mask and data values move.w #HIGHLVOL,MWDATA mwwrite: cmp.w MASKVAL,MWMASK bne.s mwwrite ; loop until MWMASK reaches $7FF again move.w #HIGHRVOL,MWDATA ; ok, safe to write second value rts .end
Atari computers support a wide range of video resolutions as shown in the following tables:
Computer System |
|
|
---|---|---|
ST, Mega ST |
|
|
STe, Mega STe |
|
|
STacy |
|
|
TT030 |
|
|
Falcon030 |
|
|
The Falcon030 is equipped with a much more flexible video controller than earlier Atari computers. The display area may be output on a standard television, an Atari color or monochrome monitor, or a VGA monitor. Overscan is supported with all monitor configurations with the exception of VGA. Also, hardware support for NTSC and PAL monitors is software configurable.
The Falcon030 supports graphic modes of 40 or 80 columns (320 or 640 pixels across) containing 1, 2, 4, 8, or 16 bits per pixel resulting in 2, 4, 16, 256, or 262,144 colors respectively. All modes except the 16 bit per pixel mode supply the video shifter with palette indexes. The 16 bit per pixel mode is a 'true-color' mode where each 16 bit value determines the color rather than being an index into a palette. Each 16 bit WORD value is arranged as follows:
The 'R', 'G', and 'B', represent the red, green, and blue components of the color. Because red and blue are each allocated five bits, they can represent a color range of 0-31. The green component is allocated six bits so it can represent a color range of 0-63.
The Falcon030 also supports an overlay mode (see VsetMask()) where certain colors can be defined as transparent to a connected Genlock (or similar) device. In this mode, the least signifigant green bit (Bit #5) is treated as the transparent flag bit and the resolution of the green color component is slightly reduced. If the transparent flag bit of a pixel is set, that pixel will display video from the Falcon030's video shifter, otherwise the external video source will be responsible for its display.
Another feature of the Falcon030's video shifter is an optional
interlace/double-line mode. When operating on a VGA monitor, this
mode doubles the pixel height effectively reducing the vertical
screen resolution by half. On any other video display, this mode
engages interlacing which increases the video resolution.
The operating system calls VsetMode() or VsetScreen()
can be used to manipulate the operating mode of the Falcon030's
video shifter. These calls do not, however, do any checking to
ensure the selected video mode is actually attainable on the connected
monitor or that the mode is legal. In particular, you should not
attempt to set the video shifter to either 40 column mode with
only one bit per pixel or 80 column VGA mode with 16 bits per
pixel.
Most of the available video modes are palette-based. The number
of bits required per pixel depends on the number of palette entries
as shown in the table below. The Falcon030 also offers a true
color video mode which requires 16 bits per pixel.
Video Memory
|
|
---|---|
|
|
|
|
|
|
|
|
Directly accessing video memory is normally not recommended because it may create compatibility problems with future machines and wreak havoc with other system applications. The VDI provides a rich set of function calls which should be used when outputting to the screen. The function call vr_trnfm(), for instance, can be useful in transforming video images into a pattern compatible with the current video shifter. Certain software, however, does need exclusive access to video memory.
With the exception of the 16-bit true color mode of the Falcon030, all video images are stored in memory in WORD interleaved format. The video shifter grabs one at a time from each plane present as shown in the following diagram which represents a 16-color (four plane) screen layout:
The Falcon030's 16-bit true color mode is pixel-packed so that
WORD #0 in memory is the complete color WORD for
the pixel at ( 0, 0 ), WORD #1 is the complete color WORD
for the pixel at ( 1, 0 ), etc.
All Atari computers except the original ST and Mega ST support
both horizontal and vertical fine scrolling in hardware. To accomplish
this, an application must place a special handler in the vertical
blank vector (at 0x00000070) which resets the scroll registers
and video base address as needed.
The following registers are manipulated during the vertical-blank
period to shift the screen across any number of virtual 'screens':
Fine Scrolling
Register | Address | Contents |
---|---|---|
VBASEHI | 0xFFFF8200 | Low byte contains bits 23-16 of the video display base address. |
VBASEMID | 0xFFFF8202 | Low byte contains bits 15-8 of the video display base address. |
VBASELO | 0xFFFF820C | Low byte contains bits 7-0 of the video display base address. |
LINEWID | 0xFFFF820E | Number of extra WORDs per scanline (normally 0). |
HSCROLL | 0xFFFF8264 | Low four bits contain the bitwise offset (0-15) of the screen (normally 0 unless scrolling is in effect). |
VCOUNTHI | 0xFFFF8204 | Low byte contains bits 23-16 of the current video refresh address (use with care). |
VCOUNTMID | 0xFFFF8206 | Low byte contains bits 15-8 of the current video refresh address (use with care). |
VCOUNTLO | 0xFFFF8208 | Low byte contains bits 7-0 of the current video refresh address (use with care). |
To accommodate virtual screens wider than the display can show, set LINEWID to the number of extra WORDs per scanline. For instance, to create a virtual display two screens wide for a 320x200 16-color display, set LINEWID to 80.
To scroll vertically, simply alter the video base address by adding or subtracting the number of WORDs per scanline for each line you wish to scroll during the vertical blank.
To scroll horizontally, alter the video base address in WORD increments to move the physical screen left and right over the virtual screen. This by itself will cause the screen to skip in 16 pixel jumps. To scroll smoothly, use the HSCROLL register to shift the display accordingly. When HSCROLL is non-zero, subtract one from LINEWID for each plane.
To illustrate this more clearly, imagine a physical screen of 320x200 (16 colors) which is laid out over 4 virtual screens in a 2x2 grid. The following diagram and table shows example values to move the physical screen to the desired virtual coordinates:
| |||
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|