Difference between revisions of "7800 Software Guide"
(→APPENDIX 3: DMA TIMING) |
|||
(29 intermediate revisions by 2 users not shown) | |||
Line 189: | Line 189: | ||
register called BACKGRND used to specify background color. All the palette and BACKGRND registers are write-only. | register called BACKGRND used to specify background color. All the palette and BACKGRND registers are write-only. | ||
− | =====OFFSET===== | + | =====OFFSET ($38)===== |
The OFFSET register is a 4 bit value which gets added, automatically , to the high address byte on any graphics data fetch, whether Direct or Indirect. This register is internal to MARIA, and is set by each Display List List entry. | The OFFSET register is a 4 bit value which gets added, automatically , to the high address byte on any graphics data fetch, whether Direct or Indirect. This register is internal to MARIA, and is set by each Display List List entry. | ||
− | =====CHARBASE===== | + | =====CHARBASE ($34)===== |
The CHARBASE register serves to specify the high address for any graphics data fetch in Character (Indirect) mode. As you recall, The Character Map (pointed to by the Header in the Display List) specifies the low address bytes of graphics data. Each of these low address bytes is concatenated with the sum of CHARBASE + OFFSET, to give the full 16 bit addresses of where the graphics data should be found. The CHARBASE register is WRITE ONLY. | The CHARBASE register serves to specify the high address for any graphics data fetch in Character (Indirect) mode. As you recall, The Character Map (pointed to by the Header in the Display List) specifies the low address bytes of graphics data. Each of these low address bytes is concatenated with the sum of CHARBASE + OFFSET, to give the full 16 bit addresses of where the graphics data should be found. The CHARBASE register is WRITE ONLY. | ||
− | =====DPPH===== | + | =====DPPH ($2C)===== |
DPPH stands for Display List Pointer Pointer High, and this is the register which contains the high address byte of the Display List List. This register is WRITE ONLY. The Display List List may cross one page boundary, in which case DPPH is internally incremented, then reset at the end of the visible screen, so it is valid for the next frame. This register (and DPPL) should be written to before DMA is turned on. Once DMA is on, DPPH and DPPL may be written at any time, as they are only read at thebeginning of the screen. | DPPH stands for Display List Pointer Pointer High, and this is the register which contains the high address byte of the Display List List. This register is WRITE ONLY. The Display List List may cross one page boundary, in which case DPPH is internally incremented, then reset at the end of the visible screen, so it is valid for the next frame. This register (and DPPL) should be written to before DMA is turned on. Once DMA is on, DPPH and DPPL may be written at any time, as they are only read at thebeginning of the screen. | ||
− | =====DPPL===== | + | =====DPPL ($30)===== |
This register is used to specify the low address byte of the Display List List. It too, is WRITE ONLY. | This register is used to specify the low address byte of the Display List List. It too, is WRITE ONLY. | ||
− | =====MSTAT===== | + | =====MSTAT ($28)===== |
MSTAT is a READ ONLY register which communicates the status of Vertical Blank via bit 7 (MSB). When this bit is 1 VBLANK is on. When VBLANK turns off, DMA will begin according to your Display List. This transition occurs at raster 16 of the frame. | MSTAT is a READ ONLY register which communicates the status of Vertical Blank via bit 7 (MSB). When this bit is 1 VBLANK is on. When VBLANK turns off, DMA will begin according to your Display List. This transition occurs at raster 16 of the frame. | ||
− | =====CTRL===== | + | =====CTRL ($3C)===== |
The CTRL register is a WRITE ONLY register used to control many of the modes of MARIA. Through this register one can control whether the background color extends off the edge of the TV (horizontally), beyond the area where graphics may be positioned; or whether the background color stops at the horizontal limits of graphics and this border area appears black. This border area is an area which appears undependably on various television sets. | The CTRL register is a WRITE ONLY register used to control many of the modes of MARIA. Through this register one can control whether the background color extends off the edge of the TV (horizontally), beyond the area where graphics may be positioned; or whether the background color stops at the horizontal limits of graphics and this border area appears black. This border area is an area which appears undependably on various television sets. | ||
Line 246: | Line 246: | ||
The CTRL register is arranged as follows: | The CTRL register is arranged as follows: | ||
− | {| class="wikitable" style="table-layout: fixed; width: | + | {| class="wikitable" style="table-layout: fixed; width: 90%; max-width: 640px;" |
|+'''Color Register Layout''' | |+'''Color Register Layout''' | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
Line 253: | Line 253: | ||
| Color Kill: 0=normal color, 1=no color burst signal | | Color Kill: 0=normal color, 1=no color burst signal | ||
| colspan="2" | DMA Control: 0,1=TEST DO NOT USE, as it could break the console. 2=normal DMA. 3=no DMA | | colspan="2" | DMA Control: 0,1=TEST DO NOT USE, as it could break the console. 2=normal DMA. 3=no DMA | ||
− | | Character Width: 0= | + | | Character Width: 0=single byte characters, 1=double byte characters |
− | | Border Control: 0= | + | | Border Control: 0=black screen border, 1=BACKGRND color border |
| Kangaroo Mode: 0=regular transparency, 1=kangaroo mode with no transparency | | Kangaroo Mode: 0=regular transparency, 1=kangaroo mode with no transparency | ||
| colspan="2" | Read Mode: 0=160A/160B 1=N/A 2=320B/320D 3=320A/320C | | colspan="2" | Read Mode: 0=160A/160B 1=N/A 2=320B/320D 3=320A/320C | ||
Line 393: | Line 393: | ||
</pre> | </pre> | ||
− | |||
==OVERVIEW OF TIA== | ==OVERVIEW OF TIA== | ||
Line 410: | Line 409: | ||
====Registers==== | ====Registers==== | ||
− | =====AUDF0/1===== | + | =====AUDF0/1 ($17/$18)===== |
These addresses write data into the audio frequency divider registers. | These addresses write data into the audio frequency divider registers. | ||
Line 433: | Line 432: | ||
|} | |} | ||
− | + | =====AUDC0/1 ($15/$16)===== | |
− | =====AUDC0/1===== | ||
These addresses write data into the audio control registers which control the noise content and additional division of the audio output. | These addresses write data into the audio control registers which control the noise content and additional division of the audio output. | ||
Line 475: | Line 473: | ||
|} | |} | ||
− | + | =====AUDV0/1 ($19/$1A)===== | |
− | =====AUDV0/1===== | ||
These addresses write data into the audio volume registers which set the pull down impedance driving the audio output pads. | These addresses write data into the audio volume registers which set the pull down impedance driving the audio output pads. | ||
Line 497: | Line 494: | ||
| 1 || 1 || 1 || 1 || highest output current | | 1 || 1 || 1 || 1 || highest output current | ||
|} | |} | ||
− | |||
=====Input Ports INPT0/1/2/3===== | =====Input Ports INPT0/1/2/3===== | ||
Line 507: | Line 503: | ||
The two ports (Port A and Port B) are 8 bits wide and can be set for either input or output. Port A is used to interface to various hand-held controllers but Port B is dedicated to reading the status of the console switches and joystick buttons. | The two ports (Port A and Port B) are 8 bits wide and can be set for either input or output. Port A is used to interface to various hand-held controllers but Port B is dedicated to reading the status of the console switches and joystick buttons. | ||
− | ====Port B - Console Switches and Joystick Buttons==== | + | ====Port B - Console Switches and Joystick Buttons - SWCHB ($282)==== |
Port B is read by addressing SWCHB (HEX 282) to determine the status of all the console switches according to the following table: | Port B is read by addressing SWCHB (HEX 282) to determine the status of all the console switches according to the following table: | ||
Line 528: | Line 524: | ||
Bits 2 and 4 are used to enable/disable the 2-button joystick mode. More details on this are in the Joystick Controllers section. | Bits 2 and 4 are used to enable/disable the 2-button joystick mode. More details on this are in the Joystick Controllers section. | ||
− | ====Port A – Hand Controllers==== | + | ====Port A – Hand Controllers - SWCHA ($281)==== |
Port A is under full software control to be configured as an input or an output port. It can then be used to read or control various hand-held controllers with the data bits defined differently depending on the type of controller used. | Port A is under full software control to be configured as an input or an output port. It can then be used to read or control various hand-held controllers with the data bits defined differently depending on the type of controller used. | ||
Line 534: | Line 530: | ||
=====Setting for Input or Output===== | =====Setting for Input or Output===== | ||
− | Port A has an 8 bit wide Data Direction Register (DDR) that is written to at | + | Port A has an 8 bit wide Data Direction Register (DDR) that is written to at CTLSWA (HEX 281) to set each individual pin of Port A to either input or output. The Port A pins are labeled PA0 thru PA7, and writing a "0" to a pins' DDR bit sets that pin as input, and a "1" sets it as an output. For example, |
− | writing all 0's to | + | writing all 0's to CTLSWA (the DDR for Port A) sets PA0 thru PA7 (all 8 pins of Port A) as inputs. If F0 (11110000) were written to CTLSWA then PA7, PA6, PA5 & PA4 would be outputs, and PA3, PA2, PA1 & PA0 would be inputs. |
=====Inputting and Outputting===== | =====Inputting and Outputting===== | ||
Line 597: | Line 593: | ||
| INPT2 || P1, right button || Bit 7=1 if the button is pushed | | INPT2 || P1, right button || Bit 7=1 if the button is pushed | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | INPT3 || | + | | INPT3 || P1, left button || Bit 7=1 if the button is pushed |
|} | |} | ||
Line 648: | Line 644: | ||
| $280 || SWCHA || Port A, input or output | | $280 || SWCHA || Port A, input or output | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | $281 || | + | | $281 || CTLSWA || Port A DDR, 0=input, 1=output |
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
| $282 || SWCHB || Port B, console switches (read only) | | $282 || SWCHB || Port B, console switches (read only) | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | $283 || | + | | $283 || CTLSWB || Port B DDR (hardwired as input) |
|} | |} | ||
− | ==INPTCTRL REGISTER== | + | ==INPTCTRL REGISTER ($01)== |
The INPTCTRL register is responsible for switching and locking the 7800 into either 2600 or 7800 mode. It's a write-only register mapped to $0000-$001F, and controlled by external circuitry. | The INPTCTRL register is responsible for switching and locking the 7800 into either 2600 or 7800 mode. It's a write-only register mapped to $0000-$001F, and controlled by external circuitry. | ||
Line 673: | Line 669: | ||
In addition to the functions controlled by the register bits, INPTCTRL also controls the HALT input to the 6502. When the 7800 is first powered up HALT is blocked from getting to the 6502, but after 2 writes to the control register (the data written doesn’t make a difference), the HALT input will be enabled. | In addition to the functions controlled by the register bits, INPTCTRL also controls the HALT input to the 6502. When the 7800 is first powered up HALT is blocked from getting to the 6502, but after 2 writes to the control register (the data written doesn’t make a difference), the HALT input will be enabled. | ||
− | |||
==APPENDIX 1: 7800 MEMORY MAP== | ==APPENDIX 1: 7800 MEMORY MAP== | ||
Line 687: | Line 682: | ||
| 2 || MARIA || 0000 00XX 0010 0000 || 0000 00XX 0011 1111 | | 2 || MARIA || 0000 00XX 0010 0000 || 0000 00XX 0011 1111 | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | 3 || 6532 Ports || 0000 | + | | 3 || 6532 Ports || 0000 001X 1XX0 0000 || 0000 001X 1XX1 1111 |
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
| 4 || 6532 RAM (don't use) || 0000 010X 1000 0000 || 0000 010X 1111 1111 | | 4 || 6532 RAM (don't use) || 0000 010X 1000 0000 || 0000 010X 1111 1111 | ||
Line 695: | Line 690: | ||
| 6 || RAM Shadow || 00X0 000A 0100 0000 || 00X0 000A 1111 1111 | | 6 || RAM Shadow || 00X0 000A 0100 0000 || 00X0 000A 1111 1111 | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | 7 || RAM Shadow || 0010 X000 0000 0000 || | + | | 7 || RAM Shadow || 0010 X000 0000 0000 || 0010 X111 1111 1111 |
|} | |} | ||
− | Where X means "Don't Care", and A means the bits may be 1 or 0, but are not ignored. Entries 5 and 6 indicate that pieces of RAM from x'1800' - x'27FF' appear in zero, and first pages. The last entry indicates that the last 2K block (x'2000' - x'27FF') is repeated at x'2800'. For encryption purposes, the | + | Where X means "Don't Care", and A means the bits may be 1 or 0, but are not ignored. Entries 5 and 6 indicate that pieces of RAM from x'1800' - x'27FF' appear in zero, and first pages. The last entry indicates that the last 2K block (x'2000' - x'27FF') is repeated at x'2800'. For encryption purposes, the 120 bytes from x'FF80' - x'FFF7' must be left free. Put FFs in this area until encrypted. |
− | until encrypted. | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 719: | Line 713: | ||
| 0280 to 02FF || 6532 Ports | | 0280 to 02FF || 6532 Ports | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | 0300 to 03FF || Shadowed | + | | 0300 to 037F || Shadowed |
+ | |- style="vertical-align:top;" | ||
+ | | 0380 to 03FF || Shadowed 6532 Ports | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
| 0400 to 047F || Available for mapping by external devices | | 0400 to 047F || Available for mapping by external devices | ||
Line 741: | Line 737: | ||
| 2200 to 27FF || RAM | | 2200 to 27FF || RAM | ||
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | 2800 to 2FFF || | + | | 2800 to 2FFF || Unavailable for mapping by external devices. (BIOS conflict) |
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | 3000 to | + | | 3000 to FF7F || Available for mapping by external devices |
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | | + | | FF80 to FFF7 || Reserved for cart encryption signature |
|- style="vertical-align:top;" | |- style="vertical-align:top;" | ||
− | | | + | | FFF8 to FFFF || Reserved for startup flags and 6502 vectors |
|} | |} | ||
Line 755: | Line 751: | ||
;****** 00-1F ********* TIA REGISTERS ****************** | ;****** 00-1F ********* TIA REGISTERS ****************** | ||
− | INPTCTRL = $01 ;Input control - | + | INPTCTRL = $01 ;Input control write-only |
− | INPT0 = $08 ;Paddle Control Input 0 | + | INPT0 = $08 ;Paddle Control Input 0 read-only |
− | INPT1 = $09 ;Paddle Control Input 1 | + | INPT1 = $09 ;Paddle Control Input 1 read-only |
− | INPT2 = $0A ;Paddle Control Input 2 | + | INPT2 = $0A ;Paddle Control Input 2 read-only |
− | INPT3 = $0B ;Paddle Control Input 3 | + | INPT3 = $0B ;Paddle Control Input 3 read-only |
; ** some common alternate names for INPT0/1/2/3 | ; ** some common alternate names for INPT0/1/2/3 | ||
− | INPT4B = $08 ;Joystick 0 Fire | + | INPT4B = $08 ;Joystick 0 Fire 0 read-only |
− | INPT4A = $09 ;Joystick 0 Fire 1 | + | INPT4A = $09 ;Joystick 0 Fire 1 read-only |
− | INPT5B = $0A ;Joystick 1 Fire 0 | + | INPT5B = $0A ;Joystick 1 Fire 0 read-only |
− | INPT5A = $0B ;Joystick 1 Fire 1 | + | INPT5A = $0B ;Joystick 1 Fire 1 read-only |
− | INPT4R = $08 ;Joystick 0 Fire | + | INPT4R = $08 ;Joystick 0 Fire 0 read-only |
− | INPT4L = $09 ;Joystick 0 Fire 1 | + | INPT4L = $09 ;Joystick 0 Fire 1 read-only |
− | INPT5R = $0A ;Joystick 1 Fire 0 | + | INPT5R = $0A ;Joystick 1 Fire 0 read-only |
− | INPT5L = $0B ;Joystick 1 Fire 1 | + | INPT5L = $0B ;Joystick 1 Fire 1 read-only |
+ | INPT4 = $0C ;Player 0 Fire Button Input read-only | ||
+ | INPT5 = $0D ;Player 1 Fire Button Input read-only | ||
− | + | AUDC0 = $15 ;Audio Control Channel 0 write-only | |
− | + | AUDC1 = $16 ;Audio Control Channel 1 write-only | |
− | + | AUDF0 = $17 ;Audio Frequency Channel 0 write-only | |
− | AUDC0 = $15 ;Audio Control Channel 0 | + | AUDF1 = $18 ;Audio Frequency Channel 1 write-only |
− | AUDC1 = $16 ;Audio Control Channel 1 | + | AUDV0 = $19 ;Audio Volume Channel 0 write-only |
− | AUDF0 = $17 ;Audio Frequency Channel 0 | + | AUDV1 = $1A ;Audio Volume Channel 1 write-only |
− | AUDF1 = $18 ;Audio Frequency Channel 1 | ||
− | AUDV0 = $19 ;Audio Volume Channel 0 | ||
− | AUDV1 = $1A ;Audio Volume Channel 1 | ||
;****** 20-3F ********* MARIA REGISTERS *************** | ;****** 20-3F ********* MARIA REGISTERS *************** | ||
− | BACKGRND = $20 ;Background Color | + | BACKGRND = $20 ;Background Color write-only |
− | P0C1 = $21 ;Palette 0 - Color 1 | + | P0C1 = $21 ;Palette 0 - Color 1 write-only |
− | P0C2 = $22 ;Palette 0 - Color 2 | + | P0C2 = $22 ;Palette 0 - Color 2 write-only |
− | P0C3 = $23 ;Palette 0 - Color 3 | + | P0C3 = $23 ;Palette 0 - Color 3 write-only |
− | WSYNC = $24 ;Wait For Sync | + | WSYNC = $24 ;Wait For Sync write-only |
− | P1C1 = $25 ;Palette 1 - Color 1 | + | P1C1 = $25 ;Palette 1 - Color 1 write-only |
− | P1C2 = $26 ;Palette 1 - Color 2 | + | P1C2 = $26 ;Palette 1 - Color 2 write-only |
− | P1C3 = $27 ;Palette 1 - Color 3 | + | P1C3 = $27 ;Palette 1 - Color 3 write-only |
− | MSTAT = $28 ;Maria Status | + | MSTAT = $28 ;Maria Status read-only |
− | P2C1 = $29 ;Palette 2 - Color 1 | + | P2C1 = $29 ;Palette 2 - Color 1 write-only |
− | P2C2 = $2A ;Palette 2 - Color 2 | + | P2C2 = $2A ;Palette 2 - Color 2 write-only |
− | P2C3 = $2B ;Palette 2 - Color 3 | + | P2C3 = $2B ;Palette 2 - Color 3 write-only |
− | DPPH = $2C ;Display List List Pointer High | + | DPPH = $2C ;Display List List Pointer High write-only |
− | P3C1 = $2D ;Palette 3 - Color 1 | + | P3C1 = $2D ;Palette 3 - Color 1 write-only |
− | P3C2 = $2E ;Palette 3 - Color 2 | + | P3C2 = $2E ;Palette 3 - Color 2 write-only |
− | P3C3 = $2F ;Palette 3 - Color 3 | + | P3C3 = $2F ;Palette 3 - Color 3 write-only |
− | DPPL = $30 ;Display List List Pointer Low | + | DPPL = $30 ;Display List List Pointer Low write-only |
− | P4C1 = $31 ;Palette 4 - Color 1 | + | P4C1 = $31 ;Palette 4 - Color 1 write-only |
− | P4C2 = $32 ;Palette 4 - Color 2 | + | P4C2 = $32 ;Palette 4 - Color 2 write-only |
− | P4C3 = $33 ;Palette 4 - Color 3 | + | P4C3 = $33 ;Palette 4 - Color 3 write-only |
− | CHARBASE = $34 ;Character Base Address | + | CHARBASE = $34 ;Character Base Address write-only |
− | P5C1 = $35 ;Palette 5 - Color 1 | + | P5C1 = $35 ;Palette 5 - Color 1 write-only |
− | P5C2 = $36 ;Palette 5 - Color 2 | + | P5C2 = $36 ;Palette 5 - Color 2 write-only |
− | P5C3 = $37 ;Palette 5 - Color 3 | + | P5C3 = $37 ;Palette 5 - Color 3 write-only |
− | OFFSET = $38 ;Unused - Store zero here | + | OFFSET = $38 ;Unused - Store zero here write-only |
− | P6C1 = $39 ;Palette 6 - Color 1 | + | P6C1 = $39 ;Palette 6 - Color 1 write-only |
− | P6C2 = $3A ;Palette 6 - Color 2 | + | P6C2 = $3A ;Palette 6 - Color 2 write-only |
− | P6C3 = $3B ;Palette 6 - Color 3 | + | P6C3 = $3B ;Palette 6 - Color 3 write-only |
− | CTRL = $3C ;Maria Control Register | + | CTRL = $3C ;Maria Control Register write-only |
− | P7C1 = $3D ;Palette 7 - Color 1 | + | P7C1 = $3D ;Palette 7 - Color 1 write-only |
− | P7C2 = $3E ;Palette 7 - Color 2 | + | P7C2 = $3E ;Palette 7 - Color 2 write-only |
− | P7C3 = $3F ;Palette 7 - Color 3 | + | P7C3 = $3F ;Palette 7 - Color 3 write-only |
+ | ;****** 280-2FF ******* PIA PORTS AND TIMERS ************ | ||
− | ; | + | SWCHA = $280 ;P0, P1 Joystick Directional Input read-write |
+ | SWCHB = $282 ;Console Switches read-write | ||
+ | CTLSWA = $281 ;I/O Control for SCHWA read-write | ||
+ | SWACNT = $281 ;VCS name for above read-write | ||
+ | CTLSWB = $283 ;I/O Control for SCHWB read-write | ||
+ | SWBCNT = $283 ;VCS name for above read-write | ||
− | + | INTIM = $284 ;Iterval Timer Read read-only | |
− | + | TIM1T = $294 ;Set 1 CLK Interval (838 nsec/interval) write-only | |
− | + | TIM8T = $295 ;Set 8 CLK Interval (6.7 usec/interval) write-only | |
− | + | TIM64T = $296 ;Set 64 CLK Interval (63.6 usec/interval) write-only | |
− | + | T1024T = $297 ;Set 1024 CLK Interval (858.2 usec/interval) write-only | |
− | + | TIM64TI = $29E ;Interrupt timer 64T write-only | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</pre> | </pre> | ||
− | |||
==APPENDIX 3: DMA TIMING== | ==APPENDIX 3: DMA TIMING== | ||
Line 845: | Line 839: | ||
All times listed below refer to 7.16 MHz cycles. | All times listed below refer to 7.16 MHz cycles. | ||
− | {| class="wikitable" | + | {| class="wikitable" style="width: 80%; max-width: 640px;" |
|+'''DMA Timing''' | |+'''DMA Timing''' | ||
! Event !! MARIA Cycle Cost !! Comments | ! Event !! MARIA Cycle Cost !! Comments | ||
|- | |- | ||
− | | DMA start-up and shutdown, last line in zone || 24 cycles || The DMA start-up may be delayed if the 6502 clock isn't at the end of a cycle. | + | | DMA start-up and shutdown, last line in zone || 24 cycles || rowspan="2" | The DMA start-up may be delayed if the 6502 clock isn't at the end of a cycle when DMA begins. Up to 3 additional cycles are lost for DMA if the 6502 is at normal speed, or up to 5 additional cycles are lost if the 6502 happens to be slowed down for TIA access. DMA start-up delay usually occurs every other scanline, since a scanline length is 113.5 6502 cycles long. |
|- | |- | ||
− | | DMA start-up and shutdown, other lines in zone || 16 cycles | + | | DMA start-up and shutdown, other lines in zone || 16 cycles |
|- | |- | ||
| process 4-byte DL header || 8 cycles | | process 4-byte DL header || 8 cycles | ||
Line 857: | Line 851: | ||
| process 5-byte DL header || 10 cycles | | process 5-byte DL header || 10 cycles | ||
|- | |- | ||
− | | direct graphics data read || 3 cycles | + | | direct graphics data read || 3 cycles || per byte of data read |
|- | |- | ||
| indirect 1-byte read || 6 cycles | | indirect 1-byte read || 6 cycles | ||
Line 864: | Line 858: | ||
|} | |} | ||
− | If holey DMA is enabled and graphics reads would reside in a DMA hole, | + | If holey DMA is enabled and graphics reads would reside in a DMA hole, only 3 cycles of penalty for the graphic read is incurred, whatever the sprite width is. |
The end of VBLANK is made up of a DMA startup plus a Long shutdown. | The end of VBLANK is made up of a DMA startup plus a Long shutdown. |
Latest revision as of 18:15, 19 August 2023
Contents
INTRODUCTION
The 7800 is a product which combines the ATARI 2600 hardware with a new graphics chip called MARIA. The entire 2600 library of cartridges will run on the 7800 as they do on the 2600, but new cartridges designed to access the improved hardware will be able to take advantage of a large number of improvements.
OVERVIEW OF THE 7800
Ignoring the 2600 environment, which is identical to the ATARI 2600, the 7800 environment is characterized by the following:
- (2) 6116's
- 4K bytes of RAM
- 6532
- I/O
- TIA
- sounds
- some input ports.
- Expanded cartridge slot
- SALLY (6502)
- microprocessor running at 1.79 MHz.
- MARIA
- all video
Additionally, there is a protection circuit which verifies that each cartridge has the correct encrypted data before enabling 7800 mode. Encryption will be covered in another document, but see Appendix 1, 7800 Memory Map, for information about reserving space for encryption.
6116's
There are two (2) 6116 2Kx8 RAM chips on the 7800 PC board. Together they occupy addresses x '1800' to x'27FF'. They are also partly accessible (shadowed) at addresses x '0040' – x '00ff' and x '0140' - x '00FF' to extend zero page (quick access) RAM and first page (stack) RAM. Refer to the memory map appendix for further information.
6532
This chip is used only for I/O in 7800 mode, whereas in 2600 mode it also supplies access to all RAM and timers. Its functions are more limited because its speed is not fast enough for normal operation. Any access to this chip (joystick and switch I/O) will cause the microprocessor to slow to 1.19 MHz. The ports and switches connected through the 6532 are: joysticks (directional), pause, game select, game reset, and difficulty switches. The 6532 can be used to generate output through the joystick ports as well. For address information on 6532 ports and switches, refer to Appendix 2, Standard 7800 Equates.
TIA
The TIA is only partly accessible in 7800 mode. While it occupies addresses x'0000' - x'003F' in 2600 mode, only the section at x'0000' - x'001F' is available in 7800 mode. The only significant (useable) registers of these are the sound related registers and the input ports (fire buttons, paddle controllers). Any access to the TIA will cause the processor to slow from 1.79 MHz to 1.19 MHz.
Cartridge Slot
The cartridge slot is larger for 7800 mode cartridges. The additional lines are: three (3) address lines (now all 16 address lines appear on the cartridge connector); the READ/WRITE line, so that RAM may be added to any cartridge very simply; the phase 2 clock line in order to add another microprocessor on the cartridge and have it synchronized with the existing Sally chip; an audio line so that one may mix in audio signals generated on the cartridge; a composite video line, so that external video signals may be included; and the HALT line, to enable the cartridge to distinguish MARIA ROM accesses from SALLY ROM accesses.
SALLY (6502)
This is the microprocessor, which is also used in the ATARI 5200. The only thing special about the Sally chip is that it has a HALT line, which allows the functionality described above.
MARIA
This is the custom chip which is the heart of the 7800. It handles all graphics and video including the VSYNC and VBLANK signals.
Overview of MARIA
Graphics
MARIA does not employ the concepts of players, missiles, and playfield, as do the 2600 and 5200. Instead MARIA uses an approach to graphics commonly used in coin-operated games. Each raster of the display may be thought of as a bit map. This map is contained in an area of the MARIA chip called the Line RAM. Information is first stored into the Line RAM, then later read from Line RAM and displayed on the screen.
Consider for a moment just one raster of display. One would compose this raster's graphics by storing data into Line RAM. This is done by specifying what data should be put at what horizontal location. Graphics may be specified in small pieces, and overlapped. The order in which pieces of a raster are specified determines object priority with the last object specified on top.
When graphics data is specified to be stored into Line RAM, it will reference any one of eight (8) color palettes. Each pixel of data will take on any one of three (3) colors from the specified palette, or may be turned off (transparent). Again, the Line RAM contains only one raster of graphics information. There are actually two Line RAM buffers. While one is being read (displayed), the other is being written for display in the next raster. This means that the construction of graphics for a raster may take as long as, but no longer than, one raster, and that graphics must be stored into Line RAM on a raster by raster basis.
The only limit to the number, and size of objects on one scan line is the amount of time it takes to load each into Line RAM, as all loading must occur during one scan line.
Display
For NTSC consoles, there are a total of 263 rasters per frame (~1/60th second). The "visible" screen (during which MARIA attempts display) starts on raster 16 and ends on raster 258. The area found visible on all television sets starts on raster 41 and ends on raster 233, 192 scan lines later. Any display outside this area may not appear on all televisions. See Appendix 4, Frame Timing, for more details. For PAL consoles, there are a total of 313 rasters per frame. (~1/50th per second). The “visible” screen starts on raster 16 and ends on raster 308. The area vound visible on television sets starts on raster 41 and ends on raster 281, 240 scan lines later. As with NTSC, any display outside this area my not appear on all televisions.
Display is accomplished automatically by MARIA and consists of two tasks: constructing the Line RAM, and displaying the graphics. These happen simultaneously in MARIA. Construction of Line RAM is automatically initiated every raster by MARIA, and is directed by a predefined list of instructions called the Display List. Line RAM construction occurs through a process called DMA (Direct Memory Access). This means that the 6502 (SALLY) processing is suspended while MARIA comes in and interrogates the RAM and ROM for Display List and graphics information. DMA will occur every "visible" scan line and lasts no longer than one scan line. Because the Line RAM being constructed is displayed on the following scan line, MARIA will read each Display List one line before it is actually displayed. All Line RAM is cleared on a line by line basis and BACKGRND color will be displayed if no data is written.
Display List
DMA is mainly concerned with reading the Display List. This is a list of instructions for where to find graphics data, where to put it on the screen, and other details for constructing a scan line. The Display List is made up of many "headers." Most headers are four (4) bytes long (the exeption is discussed later). If the second byte of a header is zero, it indicates the end of the Display List, and DMA will stop allowing the 6502 to continue processing. The format of the header is as follows:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | |
---|---|---|---|---|---|---|---|---|
byte 0 | Low address of graphics data. | |||||||
byte 1 | Color Palette (0-7) | Width (1-31) is the 2's complement of the object's width. Measured in bytes, not pixels. | ||||||
byte 2 | High address of graphics data. | |||||||
byte 3 | Horizontal Position: X location on the screen where left edge of graphics is to be placed. Values 0-159 cover the visible screen, while other values are off-screen. |
Each header is concerned with one graphics item, which can be any width. If ten objects should appear on a scan line, the Display List for that scan line would be ten (10) headers long, followed by two (2) bytes, the first of which is ignored, and the second of which should be zero to end DMA.
A Display List may cross only one page boundary, so it can be no more than 512 bytes long. Additionally, Display Lists must be in RAM, due to the required access time.
Display List List
MARIA locates the Display Lists by reading a Display List List (referred to as DLL from now on). This list is a series of 3 byte entries. Each entry points to a Display List. Included in each entry is a value called OFFSET, which indicates how many rasters should use the specified Display List. OFFSET is decremented at the end of each raster until it becomes negative, which indicates that the next DLL entry should now be read and used. Each time graphics data is to be fetched OFFSET is added to the specified High address byte, to determine the actual address where the data should be found. This allows one display list to specify many rasters of graphics. Without OFFSET the only approach to graphics is to have a Display List for each raster, and a DLL for each Display List. Not only would this use a lot of RAM, but it would also take quite a bit of processing time to manipulate these Display Lists when objects move. Because OFFSET is added to HIGH address byte, each raster of graphics for an object must be separated by x'100' bytes, or one page.
The group of rasters specified by one DLL entry is called a "zone." Again, the number of rasters in a zone equals OFFSET+1. Larger zones mean less RAM is needed for DLLs, Display Lists and Character Maps (see DMA MODES below). But upon consideration of how to use zones, you will realize that to achieve smooth vertical motion each stamp must be padded at top and bottom with zeros. For example, if the top raster of an object is to appear on the last line of a 16 high zone, it must have 15 lines of zeros above it. If that object is 8 pixels (2 bytes) wide, and its top line of data is located at x'CF04', then you will need two bytes of zeros at x'D004', x'D104', x'D304',..., and x'DE04' (remember that OFFSET decrements). As this can add up to many pages of zeros, you can specify that MARIA should interpret certain data as zeros, even if it isn't. This is called "Holey DMA" because DMA will see "holes" in the data that aren't really there. This can be enabled and disabled on a zone by zone basis via a DLL entry. Holey DMA has been aimed at 8 or 16 raster zones, but will have the same effect for other zone sizes. MARIA can be told to interpret odd 4K blocks as zeros, for 16 high zones, or odd 2K blocks as zeros for 8 high zones. This will only work for addresses above x '8000'. This means that these blocks can hold meaningful code, or tables, or graphics data used in a zone where Holey DMA is not on.
One of the bits of a DLL entry tells MARIA to generate a Display List Interrupt (DLI) for that zone. The interrupt will actually occur following DMA on the last line of the PREVIOUS zone. This interrupt is non-maskable, and causes the processor to go to the address specified by the NMI vector at x 'FFFA' and x 'FFFB'. This interrupt in no way affects DMA, so processing will still be suspended at the beginning of the next raster.
The format of a 3 byte DLL entry is as follows:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | |
---|---|---|---|---|---|---|---|---|
byte 0 | DLI: List Interrupt flag. 0=no DLI for this zone. 1=DLI after DMA on the last line of the previous zone. | H16: 16-line Holey DMA enable. 0=Holey DMA disabled. 1=Holey DMA enabled. | H8: 8-line Holey DMA enable. 0=Holey DMA disabled. 1=Holey DMA enabled. | 0 | Offset: The height of the zone, minus 1. | |||
byte 1 | High DL Address: A DLL can cross only one page boundary, so it can be no larger than 512 bytes long. A DLL must be stored in RAM, due to required access time. | |||||||
byte 2 | Low DL Address |
MODES
DMA Modes
There are two modes for specifying graphics data. The first, called Direct mode, is what has just been explained, where a Header (in the Display List) points directly to graphics data.
The other mode is called Indirect or Character/Tile mode, and is somewhat different in that the Header points to a Character Map, which in turn points to graphics data. Indirect mode is selected by every header that requires it via an extended (5 byte long) header. The format of this header is as follows:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | |
---|---|---|---|---|---|---|---|---|
byte 0 | Low Address of graphics data. | |||||||
byte 1 | Write Mode bit: 0=160x2 or 320x1, 1=160x4 or 320x2. | 1 | Indirect mode bit: 0=direct, 1=indirect mode. | 0 | 0 | 0 | 0 | 0 |
byte 2 | High Address of graphics data. | |||||||
byte 3 | Palette: | Width: | ||||||
byte 4 | Horizontal Position: X location on the screen where left edge of graphics is to be placed. Values 0-159 cover the visible screen, while other values are off-screen. |
There is an added bonus to five byte headers. Because the end of DMA is indicated by the presence of a zero in the second byte of a header, and in a five byte header the width byte is not the second but the fourth, a width of zero is valid in an extended header, and will be interpreted as a value of 32.
Indirect mode, when selected, only lasts as long as the corresponding header is being processed. MARIA will return to Direct mode before the next header is read.
In indirect mode, the width indicates how many Character Map references to make, where each Character Map entry points to one byte of graphics data (the Character Map can point to two (2) consecutive bytes of graphics; see CTRL under REGISTERS). The idea behind Character (Indirect) mode is to specify a great amount of graphics with only one Header. The graphics start at the horizontal location specified by the Header and each character (graphics referred to by one Character Map entry) is inserted to the right of the previous one. One Character may be changed without affecting the others by altering the Character Map entry corresponding to that character. This is ideally suited for backgrounds such as the maze and dots in Ms. Pacman.
The Character Map is composed by W entries, where W is the specified width and each entry is one byte long. Each entry is a Low address byte of a character, and the High address byte is specified by the Character Base register (see CHARBASE under REGISTERS). This means that each character on a scan line must have the same high address byte (sit on the same 256 byte page).
Display Modes
The normal display mode is 160 mode, where the screen is divided into 160 pixels horizontally. Typically graphics are done in 160x2 mode, where there are two color bits specified for each pixel, and these two color bits refer to one of the eight palettes. Alternately, one may specify graphics in 160x4 mode, where there are four color bits per pixel. In this mode, each byte of graphics data would specify only two (2) pixels of graphics. If higher resolution is preferred, 320x1 mode is the common choice, where the screen is divided into 320 pixels horizontally and each pixel has one color bit. A more colorful 320x2 mode is also available with two color bits per pixel.
Selection of a particular mode is accomplished through two separate operations: specification of WRITE MODE, and specification of READ MODE. WRITE MODE is specified via the extended (5 byte) header, as described above. READ MODE is specified via the CTRL register. Both of these specifications will remain in effect until respecified. WRITE MODE is not initialized by MARIA on power-up, and must be initialized by the cartridge before any display occurs.
The reason for specifying WRITE MODE via an extended header, is to allow the programmer to change from 160x2 to 160x4 (or from 320x2 to 320x1, or vice-versa) during the DMA for a particular scan line. For more information about modes see CTRL under REGISTERS.
Registers
The location of the MARIA registers which control the display is shown in Appendix 1, 7800 Memory Map.
Palettes
The palette registers are used to specify colors for the graphics. There are eight palettes, and each contains three colors. The colors themselves are specified in the form:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
Color/Chroma | Luminosity |
4 bits of color information and 4 bits of luminosity provide a total of 256 available hues.
The palette registers are labeled P0C1, P0C2, P0C3, P1C1, P1C2, P1C3, P2C1, P2C2, P2C3, ... P7C1, P7C2, P7C3. A pixel whose two color bits are "10" and which refers to palette three (3) would be colored based on the value in P3C2. Color zero of any palette is transparent. Additionally, there is a register called BACKGRND used to specify background color. All the palette and BACKGRND registers are write-only.
OFFSET ($38)
The OFFSET register is a 4 bit value which gets added, automatically , to the high address byte on any graphics data fetch, whether Direct or Indirect. This register is internal to MARIA, and is set by each Display List List entry.
CHARBASE ($34)
The CHARBASE register serves to specify the high address for any graphics data fetch in Character (Indirect) mode. As you recall, The Character Map (pointed to by the Header in the Display List) specifies the low address bytes of graphics data. Each of these low address bytes is concatenated with the sum of CHARBASE + OFFSET, to give the full 16 bit addresses of where the graphics data should be found. The CHARBASE register is WRITE ONLY.
DPPH ($2C)
DPPH stands for Display List Pointer Pointer High, and this is the register which contains the high address byte of the Display List List. This register is WRITE ONLY. The Display List List may cross one page boundary, in which case DPPH is internally incremented, then reset at the end of the visible screen, so it is valid for the next frame. This register (and DPPL) should be written to before DMA is turned on. Once DMA is on, DPPH and DPPL may be written at any time, as they are only read at thebeginning of the screen.
DPPL ($30)
This register is used to specify the low address byte of the Display List List. It too, is WRITE ONLY.
MSTAT ($28)
MSTAT is a READ ONLY register which communicates the status of Vertical Blank via bit 7 (MSB). When this bit is 1 VBLANK is on. When VBLANK turns off, DMA will begin according to your Display List. This transition occurs at raster 16 of the frame.
CTRL ($3C)
The CTRL register is a WRITE ONLY register used to control many of the modes of MARIA. Through this register one can control whether the background color extends off the edge of the TV (horizontally), beyond the area where graphics may be positioned; or whether the background color stops at the horizontal limits of graphics and this border area appears black. This border area is an area which appears undependably on various television sets.
CTRL also specifies whether characters (in Character mode) are one or two bytes wide. That is, in Character (Indirect) mode, whether one, or two bytes of graphics data should be fetched at the address pointed to by the Character Map entry and CHARBASE. The advantage of two byte characters is that the same number of pixels can be specified with half as many Character Map entries. The disadvantage is that when changing one character, twice as much of the screen is affected.
This register also controls whether the color burst signal is generated or not. If color burst is turned off, the graphics are, of course, displayed in black and white, but with a greater clarity than if the gray scale colors (x'00' - x'0F') were used.
Another bit of CTRL enables "Kangaroo" mode which eliminates transparency, so that any pixel of color "0" will be background color, rather than transparent. For the derivation of this name see the ATARI coin-op game Kangaroo.
DMA may be turned on or off via the CTRL register. At power-up DMA is off, and must be turned on by the cartridge. This should not be done until after DPPL and DPPH have been stored (so that DMA doesn't try to read a DLL from an undefined location). DMA should be turned on DURING VBLANK, and never during the screen (rasters 16-258). If DMA is off the screen will continue to display the background color.
Finally, CTRL is where the READ MODE portion of the graphics mode is selected (remember the WRITE MODE portion is selected via an extended header). WRITE mode controls the way data is written into Line RAM, and READ mode controls the way Line RAM is interpreted and translated to the screen. Because READ MODE affects the scan line being displayed, changes to READ MODE should happen at the beginning of the scan line to be affected.
The WRITE MODE selects between 160x2/160x4 or 320x1/320x2. The Read mode selects between 320A/320C, 320B/320D, or 160A/160B, as the following table illustrates:
MODE | Write Mode (in DL entry) | Read Mode (in CTRL) |
---|---|---|
160A | 0 | 00 |
160B | 1 | 00 |
320A | 0 | 11 |
320B | 1 | 10 |
320C | 1 | 11 |
320D | 0 | 10 |
320A mode is a true 320x1 mode. Pixels that are "on" refer to color two (2) of the specified palette. Pixels that are off are transparent (or background color if “Kangaroo" mode is on). In 320B mode, which is a 320x2 display mode, only the most significant palette bit is read. This means that either palette zero (0) of palette four (4) is used. If "Kangaroo" mode is off, transparency will work differently for modes. Consider a pair of 320-size pixels which make up one 160-size pixel. If either pixel of the pair is off, it will not be transparent, but will take on background color instead. If both pixels are off, they will be transparent. With "Kangaroo" mode on, things work as one would expect them to work in this mode. Another factor concerning 320 modes is that the horizontal positioning still happens like 160 mode. This means that in 320 modes, objects can only be positioned in 2 pixel increments.
320C and 320D are display modes somewhat similar to 320B and 320A, respectively. They are what you would get if you changed WRITE mode without changing READ mode (such as changing modes during a scan line). If you were in 320A mode, and wanted to include a character with more colors on the line, changing modes would give you 320C mode. Likewise, changing from 320B on the fly would give you 320D mode. The way data is interpreted for 320C and 320D will be explained later on.
In 160x4 mode, again only the most significant palette bit is read (note that 160x4 and 320B share the same WRITE mode sense). Because there are more color bits than each palette can handle, the palettes are combined in 160x4 mode so you may choose between the combinations of 0-3 and 4-7. The net result of 160x4 mode is twelve (12) colors, where color one (1) is P0C1 or P4C1, two (2) is P0C2 or P4C2, five (5) is P1C1 or P5C1, six (6) is P1C2 or P5C2, etc. and colors 0, 4, 8, and 12 are transparent.
The CTRL register is arranged as follows:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
Color Kill: 0=normal color, 1=no color burst signal | DMA Control: 0,1=TEST DO NOT USE, as it could break the console. 2=normal DMA. 3=no DMA | Character Width: 0=single byte characters, 1=double byte characters | Border Control: 0=black screen border, 1=BACKGRND color border | Kangaroo Mode: 0=regular transparency, 1=kangaroo mode with no transparency | Read Mode: 0=160A/160B 1=N/A 2=320B/320D 3=320A/320C |
The coding of graphics data is straightforward for most of these modes. In 160A mode, each pair of bits is arranged so that the leftmost pixel's color is specified by the most significant pair of bits, and the rightmost pixel by the least significant pair of bits.
bits 76 54 32 10 ___ ___ ___ ___ pixels | | | | | | | | |___| |___| |___| |___| | | | | | | | | | | | | 160x2 | | | | | | | | / \ / \ / \ / \ _|___|___|___|___|___|___|___|_ graphics | | | | | | | | | byte |___|___|___|___|___|___|___|___|
In 160B mode, the data is read as follows: the left pixel's color is specified by bits 3,2,7,6 (where 3 is MSB, 6 is LSB). The right pixel is specified by bits 1,0,5,4 (where 1 is MSB, 4 is LSB).
bits 3276 1054 ___ ___ pixels | | | | |___| |___| | | +---------------+ | | | | 160x4 | +---------------+ | | | | / \ / \ / \ / \ _|___|___|___|___|___|___|___|_ graphic | | | | | | | | | byte |___|___|___|___|___|___|___|___|
320A mode is a direct mapping like 160x2, except that each bit specifies the color of one pixel. Note that while the table illustrates the bit to pixel relationship with different colors for each pixel+bit pair, 320A is a monochrome mode.
bits 7 6 5 4 3 2 1 0 _______________________________ pixels | | | | | | | | | |___|___|___|___|___|___|___|___| | | | | | | | | | | | | | | | | | | | | | | | | 320A(x1) | | | | | | | | _|___|___|___|___|___|___|___|_ graphics | | | | | | | | | byte |___|___|___|___|___|___|___|___|
The 320 modes get more complicated as we go on. The 320B mode bit to pixel mapping works as follows:
bits 73 62 51 40 ___ ___ ___ ___ pixels | | | | | | | | |___| |___| |___| |___| |\ / \ / \ /| | \ / \ / \ / | | \ / \ / \ / | | \ / \ \ / | | / / \ \ | | | \ / \ / | | | | \ / \ / | | | | \ / \ / | | 320B(x2) | | / \ | | | | | \ / | | | | | | \ / | | | | | | \ / | | | | | | \ / | | | | | | / | | | | | | / \ | | | _|___|___|___|___|___|___|___|_ graphics | | | | | | | | | byte |___|___|___|___|___|___|___|___|
320C mode allows more colors than 320A, but cannot really be called 320x2. In this mode, some of the graphics data goes to specifying palettes, which is somewhat non-standard. If a pixel is on, it is color two (2), and if it is off, it is transparent, or background color (same as 320A and 320B). The palette is determined by combining the most significant palette. The palette for the leftmost pixel is specified by P2,D3, and D2 (where P means a palette bit, and D means graphics data bit), and the graphics are specified by D7. The next pixel right uses the same palette, and uses D6 for data. The next pixel right uses a palette specified by P2, D1, and D0, and uses D5 for data. The rightmost pixel uses the same palette, but D4 for data. The mapping for 320C mode is as follows:
palette bits <P2><D3><D2> <P2><D1><D0> \__________/ \__________/ color | / bits D7 D6 D5 D4 | / | / pixels _ _ _ _ | / | | | | | | | | | / |_| |_| |_| |_| | / | | | | | | | | | | | | 320C | | | | / \ / \ graphics _|___|___|___|___|___|___|___|_ byte | | | | | | | | | |___|___|___|___|___|___|___|___|
320D mode is a little confusing, too. Every pixel refers to the same palette but palette bits affect the color of the pixels. The only palette bit used for palette definition is the most significant bit (same as 320B), so only palettes zero (0) and four (4) will be referenced. For color selection there is really more than one bit per pixel. The graphics data bits are used as follows: each is the most significant bit for a two bit pair. But the least significant bit of this pair is either P0 or P1 (where P again means palette bit).
If the specified palette is 0 or 4 (where P1 and P0 are zero), this is a normal 320x1 mode, like 320A. But if the specified palette is 5, palette 4 will be used, and certain pixels will be either color 1 or 3, and others will be 0 or 2. A picture is worth a thousand words, so:
palette bits P2 P2 P2 P2 P2 P2 P2 P2 color DP DP DP DP DP DP DP DP bits 71 60 51 40 31 20 11 00 _______________________________ pixels | | | | | | | | | |___|___|___|___|___|___|___|___| | | | | | | | | | | | | | | | | | | | | | | | | 320D | | | | | | | | _|___|___|___|___|___|___|___|_ graphics | | | | | | | | | byte |___|___|___|___|___|___|___|___|
OVERVIEW OF TIA
Sound
In TIA there are two audio circuits for generating sound. They are identical but completely independent and can be operated simultaneously to produce sound effects through the TV speaker. Each audio circuit has three registers that control a noise-tone generator (what kind of sound), a frequency selection (high or low pitch of the sound), and a volume control.
Tone
The noise-tone generator is controlled by writing to the 4 bit audio control registers (AUDC0, AUDC1). The values written cause different kinds of sounds to be generated. Some are pure tones like a flute, others have various "noise" content like a rocket, motor, or explosion. Even though the TIA hardware manual lists the sounds created by each value, some experimentation will be necessary to find "your sound".
Frequency
Frequency selection is controlled by writing to a 5 bit audio frequency register (AUDF0, AUDF1). The value written is used to divide a 30KHz reference frequency creating a higher or lower pitch of whatever type of sound is created by the noise-tone generator. By combining the pure tones available from the noise-tone generator with frequency selection, a wide range of tones can be generated.
Volume
Volume is controlled by writing to a 4 bit audio volume register (AUDV0, AUDV1). Writing 0 to these registers turns sound off completely, and writing any value up to 15 increases the volume accordingly.
Registers
AUDF0/1 ($17/$18)
These addresses write data into the audio frequency divider registers.
bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | 30 KHz base frequency... |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | divided by 1 |
0 | 0 | 0 | 0 | 1 | divided by 2 |
0 | 0 | 0 | 1 | 0 | divided by 3 |
... | ... | ... | ... | ... | ... |
1 | 1 | 1 | 0 | 1 | divided by 30 |
1 | 1 | 1 | 1 | 0 | divided by 31 |
1 | 1 | 1 | 1 | 1 | divided by 32 |
AUDC0/1 ($15/$16)
These addresses write data into the audio control registers which control the noise content and additional division of the audio output.
bit 3 | bit 2 | bit 1 | bit 0 | sound basis (divisor size, polycounter size) |
---|---|---|---|---|
0 | 0 | 0 | 0 | divided by 1 |
0 | 0 | 0 | 1 | 4-bit poly |
0 | 0 | 1 | 0 | divided by 15, 4-bit poly |
0 | 0 | 1 | 1 | 5-bit poly to 4-bit poly |
0 | 1 | 0 | 0 | divided by 2. pure |
0 | 1 | 0 | 1 | divided by 2. pure |
0 | 1 | 1 | 0 | divided by 31. pure |
0 | 1 | 1 | 1 | 5-bit poly, div 2 |
1 | 0 | 0 | 0 | 9-bit poly |
1 | 0 | 0 | 1 | 5-bit poly |
1 | 0 | 1 | 0 | divided by 31. pure |
1 | 0 | 1 | 1 | last 4-bits high |
1 | 1 | 0 | 0 | divided by 6. pure |
1 | 1 | 0 | 1 | divided by 6. pure |
1 | 1 | 1 | 0 | divided by 93. pure |
1 | 1 | 1 | 1 | 5-bit poly, div 6 |
AUDV0/1 ($19/$1A)
These addresses write data into the audio volume registers which set the pull down impedance driving the audio output pads.
bit 3 | bit 2 | bit 1 | bit 0 | audio output current |
---|---|---|---|---|
0 | 0 | 0 | 0 | no output current |
0 | 0 | 0 | 1 | lowest output current |
0 | 0 | 1 | 0 | next to lowest output current |
... | ... | ... | ... | ... |
1 | 1 | 1 | 0 | next to highest output current |
1 | 1 | 1 | 1 | highest output current |
Input Ports INPT0/1/2/3
The TIA input ports are used for joystick fire buttons, reading paddle positions, and the keyboard controller. See the "Port A - Hand Controllers" section of the 6532 Overview for more detail.
OVERVIEW OF 6532
The I/O Ports
The two ports (Port A and Port B) are 8 bits wide and can be set for either input or output. Port A is used to interface to various hand-held controllers but Port B is dedicated to reading the status of the console switches and joystick buttons.
Port B - Console Switches and Joystick Buttons - SWCHB ($282)
Port B is read by addressing SWCHB (HEX 282) to determine the status of all the console switches according to the following table:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
P1 difficulty switch. 0=(B)asic, 1=(A)dvanced | P0 difficulty switch. 0=(B)asic, 1=(A)dvanced | none | none | Pause. 0=pressed, 1=released | none | Game Select. 0=pressed, 1=released | Game Start. 0=pressed, 1=released |
Bits 2 and 4 are used to enable/disable the 2-button joystick mode. More details on this are in the Joystick Controllers section.
Port A – Hand Controllers - SWCHA ($281)
Port A is under full software control to be configured as an input or an output port. It can then be used to read or control various hand-held controllers with the data bits defined differently depending on the type of controller used.
Setting for Input or Output
Port A has an 8 bit wide Data Direction Register (DDR) that is written to at CTLSWA (HEX 281) to set each individual pin of Port A to either input or output. The Port A pins are labeled PA0 thru PA7, and writing a "0" to a pins' DDR bit sets that pin as input, and a "1" sets it as an output. For example, writing all 0's to CTLSWA (the DDR for Port A) sets PA0 thru PA7 (all 8 pins of Port A) as inputs. If F0 (11110000) were written to CTLSWA then PA7, PA6, PA5 & PA4 would be outputs, and PA3, PA2, PA1 & PA0 would be inputs.
Inputting and Outputting
Once the DDR has set the pins of Port A for input or output they may be read or written to by addressing SWCHA (HEX 280).
Joystick Controllers
Two joysticks can be read by configuring the entire port as input and reading the data at SWCHA according to the following table:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
P0 right | P0 left | P0 down | P0 up | P1 right | P1 left | P1 down | P1 up |
A "0" in a data bit indicates the joystick has been moved to close that switch. All "1's" in a player's nibble indicates that the joystick is not moving.
You can read single-button joystick button state from these TIA registers:
Register | Button | Bit |
---|---|---|
INPT4 | P0 | Bit 7=0 if the button is pushed |
INPT5 | P1 | Bit 7=0 if the button is pushed |
If your game requires both joystick fire buttons, you need to turn on two-button mode by performing this initial setup:
LDA #$14 STA CTLSWB ; set bits 2 and 4 of PORT B for output LDA #0 STA SWCHB ; output 0 on bits 2 and 4 of PORT B
After which, the joystick button state can be read from these TIA registers:
Register | Button | Bit |
---|---|---|
INPT0 | P0, right button | Bit 7=1 if the button is pushed |
INPT1 | P0, left button | Bit 7=1 if the button is pushed |
INPT2 | P1, right button | Bit 7=1 if the button is pushed |
INPT3 | P1, left button | Bit 7=1 if the button is pushed |
Reading in two button mode when the console has a one button joystick plugged-in isn't recommended, and may be harmful to the console if done for an extended period. A two button game should check for one button presses via INPT4/5, and if detected the game should turn off two button support for that joystick by setting the appropriate SWCHB bits high. (bit 2=player 0 joystick, bit 4=player 1 joystick)
Paddle (pot) Controllers
Only the paddle triggers are read from the 6532. The paddles themselves are read at INPT0 thru INPT3 of the TIA. The paddle triggers can be read at SWCHA according to the following table:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
P0 button | P1 button | N/A | N/A | P2 button | P3 button | N/A | N/A |
Keyboard Controllers
The keyboard controller has 12 buttons arranged into 4 rows and 3 columns. A signal is sent to a row, then the columns are checked to see if a button is pushed, then the next row is signaled and all columns sensed, etc. until the entire keyboard is scanned and sensed. The 6532 sends the signals to the rows, and the columns are sensed by reading INPT0, INPT1, and INPT4 of the TIA. With Port A configured as an output port, the data bits will send a signal to the keyboard controller rows according to the following table:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
P0 fourth row | P0 third row | P0 second row | P0 first row | P1 fourth row | P1 third row | P1 second row | P1 first row |
Note: a delay of 400 microseconds is necessary between writing to this port and reading the TIA input ports.
Register Summary
Address | Mnemonic | Purpose |
---|---|---|
$280 | SWCHA | Port A, input or output |
$281 | CTLSWA | Port A DDR, 0=input, 1=output |
$282 | SWCHB | Port B, console switches (read only) |
$283 | CTLSWB | Port B DDR (hardwired as input) |
INPTCTRL REGISTER ($01)
The INPTCTRL register is responsible for switching and locking the 7800 into either 2600 or 7800 mode. It's a write-only register mapped to $0000-$001F, and controlled by external circuitry. INPTCTRL's address range overlaps TIA's address range. As a consequence, once this register is set you need to also set the lock bit (see below) before you can use the TIA.
There are 4 bits in the register:
bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|
TIA-EN: 1 = enable TIA video pull-ups (video output is TIA instead of MARIA) and also disables 2 button joystick mode, 0 = disable TIA video pull-ups (video output is MARIA instead of TIA). | EXT: 0 = enable BIOS at $8000-$FFFF, 1 = disable BIOS / enable cartridge | MARIA Enable: 1 = enable MARIA (also enables system RAM), 0 = disable MARIA | Lock Mode: When set to 1 this bit locks the control register so that no more writes will affect it. The only way to clear the lock is to power cycle the console. |
In addition to the functions controlled by the register bits, INPTCTRL also controls the HALT input to the 6502. When the 7800 is first powered up HALT is blocked from getting to the 6502, but after 2 writes to the control register (the data written doesn’t make a difference), the HALT input will be enabled.
APPENDIX 1: 7800 MEMORY MAP
The memory map of the 7800, graphically illustrated on the next page, is in many ways similar to that of the 2600, with the addition not only of MARIA, but also of 4K of RAM. This RAM is shadowed (responds to other addresses) in zero, first, second, and third pages, the first two of these being significant. You will notice the absence of the 128 bytes of 6532 RAM that make up zero page RAM in the 2600. This is because of a speed discrepancy with the 6532. It's RAM has moved to an area in page four (4) and may not exist in future versions of the MARIA chip, so it should not be used.
From | To | ||
---|---|---|---|
1 | TIA | 0000 00XX 0000 0000 | 0000 00XX 0001 1111 |
2 | MARIA | 0000 00XX 0010 0000 | 0000 00XX 0011 1111 |
3 | 6532 Ports | 0000 001X 1XX0 0000 | 0000 001X 1XX1 1111 |
4 | 6532 RAM (don't use) | 0000 010X 1000 0000 | 0000 010X 1111 1111 |
5 | RAM | 0001 1000 0000 0000 | 0010 0111 1111 1111 |
6 | RAM Shadow | 00X0 000A 0100 0000 | 00X0 000A 1111 1111 |
7 | RAM Shadow | 0010 X000 0000 0000 | 0010 X111 1111 1111 |
Where X means "Don't Care", and A means the bits may be 1 or 0, but are not ignored. Entries 5 and 6 indicate that pieces of RAM from x'1800' - x'27FF' appear in zero, and first pages. The last entry indicates that the last 2K block (x'2000' - x'27FF') is repeated at x'2800'. For encryption purposes, the 120 bytes from x'FF80' - x'FFF7' must be left free. Put FFs in this area until encrypted.
Locations | Device |
---|---|
0000 to 001F | TIA Registers |
0020 to 003F | MARIA Registers |
0040 to 00FF | RAM (6116 Block Zero) |
0100 to 013F | Shadow of Page 0 |
0140 to 01FF | RAM (6116 Block One) |
0200 to 027F | Shadowed |
0280 to 02FF | 6532 Ports |
0300 to 037F | Shadowed |
0380 to 03FF | Shadowed 6532 Ports |
0400 to 047F | Available for mapping by external devices |
0480 to 04FF | 6532 RAM. Don't Use |
0500 to 057F | Available for mapping by external devices |
0580 to 05FF | 6532 RAM Shadow. Don't Use |
0600 to 17FF | Available for mapping by external devices |
1800 to 203F | RAM |
2040 to 20FF | Block Zero Shadow |
2100 to 213F | RAM |
2140 to 21FF | Block One Shadow |
2200 to 27FF | RAM |
2800 to 2FFF | Unavailable for mapping by external devices. (BIOS conflict) |
3000 to FF7F | Available for mapping by external devices |
FF80 to FFF7 | Reserved for cart encryption signature |
FFF8 to FFFF | Reserved for startup flags and 6502 vectors |
APPENDIX 2: STANDARD 7800 EQUATES
;****** 00-1F ********* TIA REGISTERS ****************** INPTCTRL = $01 ;Input control write-only INPT0 = $08 ;Paddle Control Input 0 read-only INPT1 = $09 ;Paddle Control Input 1 read-only INPT2 = $0A ;Paddle Control Input 2 read-only INPT3 = $0B ;Paddle Control Input 3 read-only ; ** some common alternate names for INPT0/1/2/3 INPT4B = $08 ;Joystick 0 Fire 0 read-only INPT4A = $09 ;Joystick 0 Fire 1 read-only INPT5B = $0A ;Joystick 1 Fire 0 read-only INPT5A = $0B ;Joystick 1 Fire 1 read-only INPT4R = $08 ;Joystick 0 Fire 0 read-only INPT4L = $09 ;Joystick 0 Fire 1 read-only INPT5R = $0A ;Joystick 1 Fire 0 read-only INPT5L = $0B ;Joystick 1 Fire 1 read-only INPT4 = $0C ;Player 0 Fire Button Input read-only INPT5 = $0D ;Player 1 Fire Button Input read-only AUDC0 = $15 ;Audio Control Channel 0 write-only AUDC1 = $16 ;Audio Control Channel 1 write-only AUDF0 = $17 ;Audio Frequency Channel 0 write-only AUDF1 = $18 ;Audio Frequency Channel 1 write-only AUDV0 = $19 ;Audio Volume Channel 0 write-only AUDV1 = $1A ;Audio Volume Channel 1 write-only ;****** 20-3F ********* MARIA REGISTERS *************** BACKGRND = $20 ;Background Color write-only P0C1 = $21 ;Palette 0 - Color 1 write-only P0C2 = $22 ;Palette 0 - Color 2 write-only P0C3 = $23 ;Palette 0 - Color 3 write-only WSYNC = $24 ;Wait For Sync write-only P1C1 = $25 ;Palette 1 - Color 1 write-only P1C2 = $26 ;Palette 1 - Color 2 write-only P1C3 = $27 ;Palette 1 - Color 3 write-only MSTAT = $28 ;Maria Status read-only P2C1 = $29 ;Palette 2 - Color 1 write-only P2C2 = $2A ;Palette 2 - Color 2 write-only P2C3 = $2B ;Palette 2 - Color 3 write-only DPPH = $2C ;Display List List Pointer High write-only P3C1 = $2D ;Palette 3 - Color 1 write-only P3C2 = $2E ;Palette 3 - Color 2 write-only P3C3 = $2F ;Palette 3 - Color 3 write-only DPPL = $30 ;Display List List Pointer Low write-only P4C1 = $31 ;Palette 4 - Color 1 write-only P4C2 = $32 ;Palette 4 - Color 2 write-only P4C3 = $33 ;Palette 4 - Color 3 write-only CHARBASE = $34 ;Character Base Address write-only P5C1 = $35 ;Palette 5 - Color 1 write-only P5C2 = $36 ;Palette 5 - Color 2 write-only P5C3 = $37 ;Palette 5 - Color 3 write-only OFFSET = $38 ;Unused - Store zero here write-only P6C1 = $39 ;Palette 6 - Color 1 write-only P6C2 = $3A ;Palette 6 - Color 2 write-only P6C3 = $3B ;Palette 6 - Color 3 write-only CTRL = $3C ;Maria Control Register write-only P7C1 = $3D ;Palette 7 - Color 1 write-only P7C2 = $3E ;Palette 7 - Color 2 write-only P7C3 = $3F ;Palette 7 - Color 3 write-only ;****** 280-2FF ******* PIA PORTS AND TIMERS ************ SWCHA = $280 ;P0, P1 Joystick Directional Input read-write SWCHB = $282 ;Console Switches read-write CTLSWA = $281 ;I/O Control for SCHWA read-write SWACNT = $281 ;VCS name for above read-write CTLSWB = $283 ;I/O Control for SCHWB read-write SWBCNT = $283 ;VCS name for above read-write INTIM = $284 ;Iterval Timer Read read-only TIM1T = $294 ;Set 1 CLK Interval (838 nsec/interval) write-only TIM8T = $295 ;Set 8 CLK Interval (6.7 usec/interval) write-only TIM64T = $296 ;Set 64 CLK Interval (63.6 usec/interval) write-only T1024T = $297 ;Set 1024 CLK Interval (858.2 usec/interval) write-only TIM64TI = $29E ;Interrupt timer 64T write-only
APPENDIX 3: DMA TIMING
There is some uncertainty as to the number of cycles DMA will require, because the internal MARIA chip timing resolution is 7.16 MHz, while the 6502 runs at either 1.79 MHz or 1.19MHz. As a result, it is not known how many extra cycles will be needed in DMA startup/shutdown to make the 6502 happy.
It is even possible for the 6502 to be in the middle of a long (TIA or 6532) access when it is to be halted, so the uncertainty goes up to about 5 cycles.
All times listed below refer to 7.16 MHz cycles.
Event | MARIA Cycle Cost | Comments |
---|---|---|
DMA start-up and shutdown, last line in zone | 24 cycles | The DMA start-up may be delayed if the 6502 clock isn't at the end of a cycle when DMA begins. Up to 3 additional cycles are lost for DMA if the 6502 is at normal speed, or up to 5 additional cycles are lost if the 6502 happens to be slowed down for TIA access. DMA start-up delay usually occurs every other scanline, since a scanline length is 113.5 6502 cycles long. |
DMA start-up and shutdown, other lines in zone | 16 cycles | |
process 4-byte DL header | 8 cycles | |
process 5-byte DL header | 10 cycles | |
direct graphics data read | 3 cycles | per byte of data read |
indirect 1-byte read | 6 cycles | |
indirect 2-byte read | 9 cycles |
If holey DMA is enabled and graphics reads would reside in a DMA hole, only 3 cycles of penalty for the graphic read is incurred, whatever the sprite width is.
The end of VBLANK is made up of a DMA startup plus a Long shutdown.
DMA does not begin until 7 CPU (1.79 MHz) cycles into each scan line. The significance of this is that there is enough time to change a color, or change CTRL before DMA begins, and during HBLANK (before display begins). This figure should, however, be included in any DMA usage calculations.
Another timing consideration is there is one MPU (7.16 MHz) cycle between DMA shutdown and generation of a DLI.
APPENDIX 4: FRAME TIMING
33.5 cycles @1.79 MHz 80 cycles @1.79 MHz 134 cycles @7.16 MHz 320 cycles @7.16 MHz NTSC <--67 pixels--> <-----------160 pixels-------------> PAL ______|_______________|____________________________________|_____ ^ | | ^ | ^ | | | | | | 16 |<---HBLANK---->| VBLANK | 16 | | | | | | | | | | | | ______v____|_______________|__________________v_________________|___v______ ^ ^ | | ^ | ^ ^ | | | | | | | | | 25 | | | | 25 | | | | | | | | | | | | | | | | | | -v----|---------------|------------------|-----------------|---v- | | ^ | | | | ^ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 243 192 | | VISIBLE | 242 293 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -v----|---------------|------------------|-----------------|---v- | | ^ | | | | ^ | | | | | | | | | | 26 | | | | 26 | | | | | | | | | | | | | | | | | _v____v____|_______________|__________________v_________________|___v____v_ ^ | | ^ | ^ | | | | | | 4 | | VBLANK | 4 | | | | | | | | | | | | _v____|_______________|__________________v_________________|___v_ |<-------------------227 pixels--------------------->| | 454 cycles @7.16 Mhz | 113.5 cycles @1.79 MHz