diff --git a/LICENSE.txt b/LICENSE.txt index 99da2e51..84e20f04 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -6,6 +6,12 @@ GPLv2 --- +https://github.com/gasman/jsspeccy2 + +GPLv3 + +--- + https://github.com/sehugg/javatari.js GNU Affero General Public License v3.0 diff --git a/doc/notes.txt b/doc/notes.txt index 18cbf6f5..03ba8581 100644 --- a/doc/notes.txt +++ b/doc/notes.txt @@ -69,6 +69,7 @@ TODO: - C/asm formatter - fix WebAudio (https://news.ycombinator.com/item?id=18066474) - Safari: verilog scope doesn't work +- no errors for verilog inline asm WEB WORKER FORMAT diff --git a/presets/vcs/examples/adventure.a b/presets/vcs/examples/adventure.a index d7673074..28d3753a 100644 --- a/presets/vcs/examples/adventure.a +++ b/presets/vcs/examples/adventure.a @@ -5,6 +5,8 @@ org $f000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; Now, we'll finally put everything together and ; make a little person with a hat that can move ; back and forth and throw rocks. We'll use one player @@ -21,6 +23,8 @@ ; ; Note: the Y coordinate goes bottom-top, not top-bottom ; as in the next section. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; counter equ $81 ; increments each frame yplyr equ $82 ; player y pos diff --git a/presets/vcs/examples/bankswitching.a b/presets/vcs/examples/bankswitching.a index 14226532..96f6b090 100644 --- a/presets/vcs/examples/bankswitching.a +++ b/presets/vcs/examples/bankswitching.a @@ -1,9 +1,23 @@ - + processor 6502 include "vcs.h" include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The VCS only supports 4096 bytes of address space for +; cartridge ROMs, but you can use 8192 or more bytes by +; using a bank-switching scheme. This lets you map segments +; of address space to multiple ROM segments. +; +; This example demonstrates standard Atari bank-switching, +; which just lets you switch multiple segments into the main +; $1000 bytes of cartridge ROM. Because all bytes must be +; switched at once, this forces you to build a trampoline -- +; a segment of code that remains valid during the bank-switch +; process. +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; seg.u Variables diff --git a/presets/vcs/examples/bigsprite.a b/presets/vcs/examples/bigsprite.a index a78ffca7..c061cb39 100644 --- a/presets/vcs/examples/bigsprite.a +++ b/presets/vcs/examples/bigsprite.a @@ -4,6 +4,18 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example demonstrates 48-pixel sprites. +; We'll use a technique similar to the Asynchronous Playfields +; trick -- reprogramming the TIA registers on-the-fly, writing +; to each register multiple times during the scanline. If we +; time our writes carefully, we'll be able to draw six unique +; sprites per scanline, for example to draw a six-digit +; scoreboard, or one large 48-pixel sprite. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 @@ -12,8 +24,6 @@ LoopCount byte THREE_COPIES equ %011 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - seg Code org $f000 diff --git a/presets/vcs/examples/bitmap.a b/presets/vcs/examples/bitmap.a index ef45aa0c..10e4a0b7 100644 --- a/presets/vcs/examples/bitmap.a +++ b/presets/vcs/examples/bitmap.a @@ -4,11 +4,17 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example demonstrates an asymmetric playfield, which +; allows different patterns for the left and right sides of +; the playfield, giving you 40 unique playfied pixels per line. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - seg Code org $f000 diff --git a/presets/vcs/examples/brickgame.a b/presets/vcs/examples/brickgame.a index d876769f..f4df9887 100644 --- a/presets/vcs/examples/brickgame.a +++ b/presets/vcs/examples/brickgame.a @@ -1,22 +1,24 @@ -j + processor 6502 include "vcs.h" include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; We've got collisions working, but now we'd like some more ; interaction. We can make a little "breakout" style game ; where the ball knocks out rows of bricks. We'll need to ; draw several rows of bricks, any or all of which might be ; missing. - +; ; We'll use a technique called "asychronous playfields". ; Remember that the playfield is either symmetric (20 pixels ; followed by the same 20 pixels reversed) or repeated (20 pixels ; repeated twice). But if we change the playfield registers ; *during* the scanline, we can make the second half a ; different bitmap than the first half. - +; ; We're going to move away from the HMPx/HMOVE method of ; setting object position and use the SetHorizPos method, since ; we really need to know the X position of both player and ball @@ -24,13 +26,15 @@ j ; two scanlines per object. But we do it during the overscan ; period at the end of the frame, and we've got the cycles ; to spare. - +; ; Also, we're going to keep score and have a rudimentary ; scoreboard, which makes this sort of an actual game! - +; ; Fun fact: Messing with the HMOVE register causes a "comb" ; effect on the left 8 pixels of the screen, which can be seen ; at the bottom of the screen in the overscan region. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; seg.u Variables org $80 diff --git a/presets/vcs/examples/collisions.a b/presets/vcs/examples/collisions.a index 1886c87b..859f373c 100644 --- a/presets/vcs/examples/collisions.a +++ b/presets/vcs/examples/collisions.a @@ -7,6 +7,8 @@ seg.u Variables org $80 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; In this example, we're going to tackle collision detection, ; which is one thing in the VCS that's easier than expected. ; The TIA has 15 different collision flags that can detect a @@ -14,19 +16,21 @@ ; and playfield. You can check these flags at any time (at the ; end of the frame is pretty common). When you're done checking ; you clear them all at once by writing to CXCLR. - +; ; For this example we'll use the ball object, and detect collisions ; between it and the playfield and the player. We only know ; the Y position of the ball and player (the X position is in ; the TIA chip) so we'll base our bounce decisions on the Y position ; of the ball (for playfield bounces) or the relative Y position of ; ball and player (for player bounces). - +; ; Note: You can press the button to capture the ball. - +; ; We're going to also include sound, which is generated by writing ; a volume register, a frequency register, and a mode register for ; one of two channels. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; counter byte ; increments each frame yplyr byte ; player y pos diff --git a/presets/vcs/examples/complexscene.a b/presets/vcs/examples/complexscene.a index e8f3dc8e..4cd99cf4 100644 --- a/presets/vcs/examples/complexscene.a +++ b/presets/vcs/examples/complexscene.a @@ -4,6 +4,13 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example demonstrates a scene with a full-screen +; playfield, and a single sprite overlapping it. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/complexscene2.a b/presets/vcs/examples/complexscene2.a index 76defb66..18cc0fbc 100644 --- a/presets/vcs/examples/complexscene2.a +++ b/presets/vcs/examples/complexscene2.a @@ -4,6 +4,14 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example demonstrates a scene with a full-screen +; playfield, and two sprites overlapping it. This takes more +; CPU time, so our kernel operates in 4-line chunks. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/lines.a b/presets/vcs/examples/lines.a index c245faf8..31e8b145 100644 --- a/presets/vcs/examples/lines.a +++ b/presets/vcs/examples/lines.a @@ -4,6 +4,13 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example draws a moving line using 16-bit fixed-point +; math and a missile object. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/missiles.a b/presets/vcs/examples/missiles.a index 87fd8a28..fedcc195 100644 --- a/presets/vcs/examples/missiles.a +++ b/presets/vcs/examples/missiles.a @@ -3,8 +3,8 @@ include "vcs.h" include "macro.h" - org $f000 - +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; Besides the two 8x1 sprites ("players") the TIA has ; two "missiles" and one "ball", which are just variable-length ; dots or dashes. They have similar positioning and display @@ -12,6 +12,10 @@ ; set the horizontal position of any of them. ; But we can also use the HMPx/HMOVE registers directly to move the ; objects by small offsets without using this routine every time. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + org $f000 counter equ $81 diff --git a/presets/vcs/examples/multisprite2.a b/presets/vcs/examples/multisprite2.a index cdcbdbff..10a22725 100644 --- a/presets/vcs/examples/multisprite2.a +++ b/presets/vcs/examples/multisprite2.a @@ -4,13 +4,15 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; For lots of games, we'd like to display more than two sprites. ; There are lots of different ways to tackle this on the VCS, ; but we're going to try for a generalized approach that lets ; use have N different sprites at any X-Y coordinate, each with ; its own bitmap and color table. This is tricky because we can ; only do so much on each scanline. - +; ; Our approach is to separate the problem into three phases. ; In the sort phase, we sort all sprites by Y coordinate. ; We do one sort pass per frame, so it may take several frames @@ -20,7 +22,7 @@ ; coming up. We then allocate it to one of the two player ; objects in hardware and set its position using the SetHorizPos ; method. We can set one or both of the player objects this way. - +; ; In the display phase, we display the objects which we previously ; assigned and positioned. First we figure out how many scanlines are ; required. If only one object is scheduled, we just use its height. @@ -30,7 +32,7 @@ ; registers at the appropriate time. We don't have time to do much ; else, so we don't look for any new objects to schedule until ; we're done with this loop. - +; ; This scheme can only display up to two objects on a given ; scanline, so if the system tries to schedule a third, it will ; be ignored. Also, the positioning routine takes a few scanlines @@ -52,6 +54,8 @@ ; There are still some timing issues to fix as you'll see when you ; move the adventure person around with the joystick. These might ; add additional lines to the display. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; seg.u Variables org $80 diff --git a/presets/vcs/examples/multisprite3.a b/presets/vcs/examples/multisprite3.a index fff20c8d..efc5bfee 100644 --- a/presets/vcs/examples/multisprite3.a +++ b/presets/vcs/examples/multisprite3.a @@ -4,13 +4,15 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; For lots of games, we'd like to display more than two sprites. ; There are lots of different ways to tackle this on the VCS, ; but we're going to try for a generalized approach that lets ; use have N different sprites at any X-Y coordinate, each with ; its own bitmap and color table. This is tricky because we can ; only do so much on each scanline. - +; ; Our approach is to separate the problem into three phases. ; In the sort phase, we sort all sprites by Y coordinate. ; We do one sort pass per frame, so it may take several frames @@ -20,7 +22,7 @@ ; coming up. We then allocate it to one of the two player ; objects in hardware and set its position using the SetHorizPos ; method. We can set one or both of the player objects this way. - +; ; In the display phase, we display the objects which we previously ; assigned and positioned. First we figure out how many scanlines are ; required. If only one object is scheduled, we just use its height. @@ -30,7 +32,7 @@ ; registers at the appropriate time. We don't have time to do much ; else, so we don't look for any new objects to schedule until ; we're done with this loop. - +; ; This scheme can only display up to two objects on a given ; scanline, so if the system tries to schedule a third, it will ; be ignored. Also, the positioning routine takes a few scanlines @@ -41,6 +43,8 @@ ; sprite entry is missed. In the sort phase, we move those sprites ; ahead of lower priority sprites in the sort order. This makes ; overlapping sprites flicker instead of randomly disappear. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; seg.u Variables org $80 diff --git a/presets/vcs/examples/musicplayer.a b/presets/vcs/examples/musicplayer.a index 11de0e9d..aff5cd27 100644 --- a/presets/vcs/examples/musicplayer.a +++ b/presets/vcs/examples/musicplayer.a @@ -6,26 +6,30 @@ org $f000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; This program demonstrates a VCS music player based on tracks ; and patterns. A pattern is a list of variable-length notes, ; each of which is defined by a pitch and duration. ; There are two tracks, one for each audio channel. ; Each track consists of a list of patterns, each entry being ; a byte offset into the Patterns array. - +; ; The patterns in the tracks are played in-order until one ends, ; and then both tracks are restarted. It's up to the composer ; to make sure the durations in each track line up properly. - +; ; Patterns consist of NOTE or TONE commands. TONE sets the ; tone of the channel (the AUDCx register) and NOTE plays a note ; with a duration taken from a lookup table. ; TONE 0 ends a pattern. - +; ; Both channels share the same logical array for tracks and patterns, ; so both tracks can take up to 255 bytes total, and all patterns ; can use up to 255 bytes total. ; The music player uses 8 bytes of RAM (not counting stack). +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trk0idx equ $e0 ; offset into tracks for channel 0 Trk1idx equ $e1 ; offset into tracks for channel 1 diff --git a/presets/vcs/examples/pal.a b/presets/vcs/examples/pal.a index d682bb55..00676ab8 100644 --- a/presets/vcs/examples/pal.a +++ b/presets/vcs/examples/pal.a @@ -6,6 +6,8 @@ org $f000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; To output a PAL signal, you need the following: ; ; - 3 scanlines of VSYNC @@ -14,23 +16,25 @@ ; - 36 blank lines ; ; Total = 312 lines (vs 262 for NTSC) - +; ; PAL runs at 50 Hz (vs 60 Hz for NTSC) ; so your game will run more slowly. ; Since you have extra cycles to play with, you could just ; call your position update routine twice every five frames. - +; ; Note also that PAL has different colors than NTSC. ; (See http://www.randomterrain.com/atari-2600-memories-tia-color-charts.html) - +; ; The TIMER_SETUP macro only goes up to 215 lines, ; so for the PAL visible frame you would need to use ; multiple sections (say 215 + 13 = 228) or count manually ; like we do in this example. - +; ; Many VCS games use conditional defines ; (IFCONST and IFNCONST in DASM) ; to switch between NTSC and PAL constants. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; background color BGColor equ $81 diff --git a/presets/vcs/examples/playfield.a b/presets/vcs/examples/playfield.a index 71b9f5c8..fbbac0d3 100644 --- a/presets/vcs/examples/playfield.a +++ b/presets/vcs/examples/playfield.a @@ -4,11 +4,15 @@ include "macro.h" org $f000 - + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; We're going to mess with the playfield registers, PF0, PF1 and PF2. ; Between them, they represent 20 bits of bitmap information ; which are replicated over 40 wide pixels for each scanline. ; By changing the registers before each scanline, we can draw bitmaps. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Counter equ $81 diff --git a/presets/vcs/examples/procgen1.a b/presets/vcs/examples/procgen1.a index 26d08c2b..ba9fbf3e 100644 --- a/presets/vcs/examples/procgen1.a +++ b/presets/vcs/examples/procgen1.a @@ -4,6 +4,14 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example uses a linear-feedback shift register to +; procedurally generate random rooms for the player to walk +; through. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/retrigger.a b/presets/vcs/examples/retrigger.a index cf7549fa..d609a2bb 100644 --- a/presets/vcs/examples/retrigger.a +++ b/presets/vcs/examples/retrigger.a @@ -4,6 +4,18 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The sprite retrigger trick relies on a behavior when the +; NUSIZ register is set to display multiple copies of objects +; (usually two). Basically, if the RESPx register is strobed +; multiple times on a given scanline, the first (leftmost) copy +; of the object will be hidden, and the TIA will draw the other +; copy. You can keep strobing the register to output multiple +; copies on the same scanline. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + org $f000 CurRow equ $8f diff --git a/presets/vcs/examples/road.a b/presets/vcs/examples/road.a index b02e32fd..cddbcb7a 100644 --- a/presets/vcs/examples/road.a +++ b/presets/vcs/examples/road.a @@ -3,6 +3,30 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example draws a pseudo-3D road using the two missiles +; and ball objects. With these, we'll draw the two shoulders +; of the road, and also the dashed center line. +; +; Our plan is this: The two missiles and ball all start at the +; same position on the horizon. As we go down the screen, we'll +; move the three objects slightly based on the curve of the road. +; The left shoulder of the road will be biased a little more to +; the left, and the right shoulder will bias a little more right. +; We can use the HMOVE registers for movement, since each object +; will not need to move more than seven pixels on any given +; scanline. +; +; It'd be easier if the scanlines went from bottom to top, +; because we could just start at the horizontal center of the +; screen and follow the road curve to the horizon, ending up +; wherever the road takes us. But scanlines go top to bottom, +; so we have to also do some preprocessing before the frame begins +; to figure out where the road ends up. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/score6.a b/presets/vcs/examples/score6.a index 4595e0f4..f13dbf4e 100644 --- a/presets/vcs/examples/score6.a +++ b/presets/vcs/examples/score6.a @@ -4,6 +4,13 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example uses the 48-pixel retriggering method to display +; a six-digit scoreboard. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/scoreboard.a b/presets/vcs/examples/scoreboard.a index aa73dcd6..77e59ff5 100644 --- a/presets/vcs/examples/scoreboard.a +++ b/presets/vcs/examples/scoreboard.a @@ -4,6 +4,15 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example draws a scoreboard using the playfield +; and a 4x5 font. We encode the left and right digits in a +; single byte, so we just mask one side or the other, and +; combine them into a 8-bit byte to draw a digit. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 diff --git a/presets/vcs/examples/sprite.a b/presets/vcs/examples/sprite.a index 4c593f09..5bb5ad47 100644 --- a/presets/vcs/examples/sprite.a +++ b/presets/vcs/examples/sprite.a @@ -5,6 +5,8 @@ org $f000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; Sprites are a tricky beast on the 2600. ; You only have two of them. ; They are 8 bits wide and 1 bit high. @@ -14,6 +16,8 @@ ; To position Y, you simply wait until the desired scanline and ; set the bits of your sprite to a non-zero value. ; Having fun yet? :) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Counter equ $81 diff --git a/presets/vcs/examples/tigervision[3E].a b/presets/vcs/examples/tigervision[3E].a index 3aec45c7..10f92562 100644 --- a/presets/vcs/examples/tigervision[3E].a +++ b/presets/vcs/examples/tigervision[3E].a @@ -1,4 +1,4 @@ - + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 64K Tigervision bank-switching example diff --git a/presets/vcs/examples/timing1.a b/presets/vcs/examples/timing1.a index e4c14986..54821f33 100644 --- a/presets/vcs/examples/timing1.a +++ b/presets/vcs/examples/timing1.a @@ -5,12 +5,16 @@ org $f000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; We're going to try to animate sprites horizontally. ; Remember, we have to pause the CPU until the exact moment the ; scanline hits the desired horizontal position of the sprite. ; Since we can't hard-code the SLEEP macro we'll have to do it ; dynamically somehow. But since the TIA beam is racing so much ; faster than the CPU clock, we'll have to be clever. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; counter equ $81 diff --git a/presets/vcs/examples/timing2.a b/presets/vcs/examples/timing2.a index 86692236..b3be23b8 100644 --- a/presets/vcs/examples/timing2.a +++ b/presets/vcs/examples/timing2.a @@ -5,6 +5,8 @@ org $f000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; We're going to use a more clever way to position sprites ; ("players") which relies on additional TIA features. ; Because the CPU timing is 3 times as coarse as the TIA's, @@ -12,6 +14,8 @@ ; CPU delays alone. ; Additional TIA registers let us nudge the final position ; by discrete TIA clocks and thus target all 160 positions. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; counter equ $81 diff --git a/presets/vcs/examples/tinyfonts2.a b/presets/vcs/examples/tinyfonts2.a index fb80aae1..c50f8e7a 100644 --- a/presets/vcs/examples/tinyfonts2.a +++ b/presets/vcs/examples/tinyfonts2.a @@ -4,10 +4,30 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Now that we know how to draw extra-wide sprites, we can +; apply this technique to another type of object: text. +; +; We can draw scoreboards and other kinds of text using the +; playfield registers. However, these are pretty blocky, and +; limited to 40 pixels in width. But we can draw lines of text +; that are 48 pixels width by five pixels high using the +; sprite retriggering trick. +; +; Instead of fetching our bitmap data from ROM, we build a +; bitmap in RAM using lookup tables. Building the bitmap array +; efficiently is a challenge, because we've got to look up 60 +; bytes in memory and combine those into 30 bytes. If we did +; this without regard to performance, it might consume a few +; thousand CPU cycles, which would require 30 or 40 scanlines +; just to set up the sprite. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80 - Temp .byte WriteOfs .byte ; offset into dest. array FontBuf LoopCount .byte ; counts scanline when drawing diff --git a/presets/vcs/examples/wavetable.a b/presets/vcs/examples/wavetable.a index 2d29503a..54ceb06a 100644 --- a/presets/vcs/examples/wavetable.a +++ b/presets/vcs/examples/wavetable.a @@ -4,6 +4,14 @@ include "macro.h" include "xmacro.h" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This example drives the VCS audio DAC directly to generate +; 4-voice music. Unfortunately, the CPU is 100% utilized so +; we can't display anything. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + seg.u Variables org $80