mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-01-17 17:30:47 +00:00
Merge branch 'master' of github.com:sehugg/8bitworkshop
This commit is contained in:
commit
1a7480ea65
@ -6,6 +6,12 @@ GPLv2
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
https://github.com/gasman/jsspeccy2
|
||||||
|
|
||||||
|
GPLv3
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
https://github.com/sehugg/javatari.js
|
https://github.com/sehugg/javatari.js
|
||||||
|
|
||||||
GNU Affero General Public License v3.0
|
GNU Affero General Public License v3.0
|
||||||
|
@ -69,8 +69,12 @@ TODO:
|
|||||||
- C/asm formatter
|
- C/asm formatter
|
||||||
- fix WebAudio (https://news.ycombinator.com/item?id=18066474)
|
- fix WebAudio (https://news.ycombinator.com/item?id=18066474)
|
||||||
- Safari: verilog scope doesn't work
|
- Safari: verilog scope doesn't work
|
||||||
|
<<<<<<< HEAD
|
||||||
- share playable link w/ verilog?
|
- share playable link w/ verilog?
|
||||||
- pixedit Sprite Rotation bitmap wrong (bpw?)
|
- pixedit Sprite Rotation bitmap wrong (bpw?)
|
||||||
|
=======
|
||||||
|
- no errors for verilog inline asm
|
||||||
|
>>>>>>> 951088dd3b2f4cea5bb8ef5dfc8ea728fee3bbd7
|
||||||
|
|
||||||
|
|
||||||
WEB WORKER FORMAT
|
WEB WORKER FORMAT
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; Now, we'll finally put everything together and
|
; Now, we'll finally put everything together and
|
||||||
; make a little person with a hat that can move
|
; make a little person with a hat that can move
|
||||||
; back and forth and throw rocks. We'll use one player
|
; 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
|
; Note: the Y coordinate goes bottom-top, not top-bottom
|
||||||
; as in the next section.
|
; as in the next section.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
counter equ $81 ; increments each frame
|
counter equ $81 ; increments each frame
|
||||||
yplyr equ $82 ; player y pos
|
yplyr equ $82 ; player y pos
|
||||||
|
@ -1,9 +1,23 @@
|
|||||||
|
|
||||||
processor 6502
|
processor 6502
|
||||||
include "vcs.h"
|
include "vcs.h"
|
||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
|
@ -4,6 +4,18 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
@ -12,8 +24,6 @@ LoopCount byte
|
|||||||
|
|
||||||
THREE_COPIES equ %011
|
THREE_COPIES equ %011
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
seg Code
|
seg Code
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
@ -4,11 +4,17 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
seg Code
|
seg Code
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
j
|
|
||||||
processor 6502
|
processor 6502
|
||||||
include "vcs.h"
|
include "vcs.h"
|
||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.h"
|
include "xmacro.h"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; We've got collisions working, but now we'd like some more
|
; We've got collisions working, but now we'd like some more
|
||||||
; interaction. We can make a little "breakout" style game
|
; interaction. We can make a little "breakout" style game
|
||||||
; where the ball knocks out rows of bricks. We'll need to
|
; where the ball knocks out rows of bricks. We'll need to
|
||||||
; draw several rows of bricks, any or all of which might be
|
; draw several rows of bricks, any or all of which might be
|
||||||
; missing.
|
; missing.
|
||||||
|
;
|
||||||
; We'll use a technique called "asychronous playfields".
|
; We'll use a technique called "asychronous playfields".
|
||||||
; Remember that the playfield is either symmetric (20 pixels
|
; Remember that the playfield is either symmetric (20 pixels
|
||||||
; followed by the same 20 pixels reversed) or repeated (20 pixels
|
; followed by the same 20 pixels reversed) or repeated (20 pixels
|
||||||
; repeated twice). But if we change the playfield registers
|
; repeated twice). But if we change the playfield registers
|
||||||
; *during* the scanline, we can make the second half a
|
; *during* the scanline, we can make the second half a
|
||||||
; different bitmap than the first half.
|
; different bitmap than the first half.
|
||||||
|
;
|
||||||
; We're going to move away from the HMPx/HMOVE method of
|
; We're going to move away from the HMPx/HMOVE method of
|
||||||
; setting object position and use the SetHorizPos method, since
|
; setting object position and use the SetHorizPos method, since
|
||||||
; we really need to know the X position of both player and ball
|
; 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
|
; two scanlines per object. But we do it during the overscan
|
||||||
; period at the end of the frame, and we've got the cycles
|
; period at the end of the frame, and we've got the cycles
|
||||||
; to spare.
|
; to spare.
|
||||||
|
;
|
||||||
; Also, we're going to keep score and have a rudimentary
|
; Also, we're going to keep score and have a rudimentary
|
||||||
; scoreboard, which makes this sort of an actual game!
|
; scoreboard, which makes this sort of an actual game!
|
||||||
|
;
|
||||||
; Fun fact: Messing with the HMOVE register causes a "comb"
|
; Fun fact: Messing with the HMOVE register causes a "comb"
|
||||||
; effect on the left 8 pixels of the screen, which can be seen
|
; effect on the left 8 pixels of the screen, which can be seen
|
||||||
; at the bottom of the screen in the overscan region.
|
; at the bottom of the screen in the overscan region.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; In this example, we're going to tackle collision detection,
|
; In this example, we're going to tackle collision detection,
|
||||||
; which is one thing in the VCS that's easier than expected.
|
; which is one thing in the VCS that's easier than expected.
|
||||||
; The TIA has 15 different collision flags that can detect a
|
; 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
|
; and playfield. You can check these flags at any time (at the
|
||||||
; end of the frame is pretty common). When you're done checking
|
; end of the frame is pretty common). When you're done checking
|
||||||
; you clear them all at once by writing to CXCLR.
|
; you clear them all at once by writing to CXCLR.
|
||||||
|
;
|
||||||
; For this example we'll use the ball object, and detect collisions
|
; For this example we'll use the ball object, and detect collisions
|
||||||
; between it and the playfield and the player. We only know
|
; 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 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
|
; 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
|
; of the ball (for playfield bounces) or the relative Y position of
|
||||||
; ball and player (for player bounces).
|
; ball and player (for player bounces).
|
||||||
|
;
|
||||||
; Note: You can press the button to capture the ball.
|
; Note: You can press the button to capture the ball.
|
||||||
|
;
|
||||||
; We're going to also include sound, which is generated by writing
|
; We're going to also include sound, which is generated by writing
|
||||||
; a volume register, a frequency register, and a mode register for
|
; a volume register, a frequency register, and a mode register for
|
||||||
; one of two channels.
|
; one of two channels.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
counter byte ; increments each frame
|
counter byte ; increments each frame
|
||||||
yplyr byte ; player y pos
|
yplyr byte ; player y pos
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.h"
|
include "xmacro.h"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
|
; This example demonstrates a scene with a full-screen
|
||||||
|
; playfield, and a single sprite overlapping it.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.h"
|
include "xmacro.h"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
|
; This example draws a moving line using 16-bit fixed-point
|
||||||
|
; math and a missile object.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
include "vcs.h"
|
include "vcs.h"
|
||||||
include "macro.h"
|
include "macro.h"
|
||||||
|
|
||||||
org $f000
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; Besides the two 8x1 sprites ("players") the TIA has
|
; Besides the two 8x1 sprites ("players") the TIA has
|
||||||
; two "missiles" and one "ball", which are just variable-length
|
; two "missiles" and one "ball", which are just variable-length
|
||||||
; dots or dashes. They have similar positioning and display
|
; dots or dashes. They have similar positioning and display
|
||||||
@ -12,6 +12,10 @@
|
|||||||
; set the horizontal position of any of them.
|
; set the horizontal position of any of them.
|
||||||
; But we can also use the HMPx/HMOVE registers directly to move the
|
; But we can also use the HMPx/HMOVE registers directly to move the
|
||||||
; objects by small offsets without using this routine every time.
|
; objects by small offsets without using this routine every time.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
org $f000
|
||||||
|
|
||||||
counter equ $81
|
counter equ $81
|
||||||
|
|
||||||
|
@ -4,13 +4,15 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.h"
|
include "xmacro.h"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; For lots of games, we'd like to display more than two sprites.
|
; 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,
|
; There are lots of different ways to tackle this on the VCS,
|
||||||
; but we're going to try for a generalized approach that lets
|
; but we're going to try for a generalized approach that lets
|
||||||
; use have N different sprites at any X-Y coordinate, each with
|
; use have N different sprites at any X-Y coordinate, each with
|
||||||
; its own bitmap and color table. This is tricky because we can
|
; its own bitmap and color table. This is tricky because we can
|
||||||
; only do so much on each scanline.
|
; only do so much on each scanline.
|
||||||
|
;
|
||||||
; Our approach is to separate the problem into three phases.
|
; Our approach is to separate the problem into three phases.
|
||||||
; In the sort phase, we sort all sprites by Y coordinate.
|
; In the sort phase, we sort all sprites by Y coordinate.
|
||||||
; We do one sort pass per frame, so it may take several frames
|
; 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
|
; coming up. We then allocate it to one of the two player
|
||||||
; objects in hardware and set its position using the SetHorizPos
|
; objects in hardware and set its position using the SetHorizPos
|
||||||
; method. We can set one or both of the player objects this way.
|
; method. We can set one or both of the player objects this way.
|
||||||
|
;
|
||||||
; In the display phase, we display the objects which we previously
|
; In the display phase, we display the objects which we previously
|
||||||
; assigned and positioned. First we figure out how many scanlines are
|
; assigned and positioned. First we figure out how many scanlines are
|
||||||
; required. If only one object is scheduled, we just use its height.
|
; 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
|
; 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
|
; else, so we don't look for any new objects to schedule until
|
||||||
; we're done with this loop.
|
; we're done with this loop.
|
||||||
|
;
|
||||||
; This scheme can only display up to two objects on a given
|
; This scheme can only display up to two objects on a given
|
||||||
; scanline, so if the system tries to schedule a third, it will
|
; scanline, so if the system tries to schedule a third, it will
|
||||||
; be ignored. Also, the positioning routine takes a few scanlines
|
; 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
|
; There are still some timing issues to fix as you'll see when you
|
||||||
; move the adventure person around with the joystick. These might
|
; move the adventure person around with the joystick. These might
|
||||||
; add additional lines to the display.
|
; add additional lines to the display.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
@ -4,13 +4,15 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.h"
|
include "xmacro.h"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; For lots of games, we'd like to display more than two sprites.
|
; 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,
|
; There are lots of different ways to tackle this on the VCS,
|
||||||
; but we're going to try for a generalized approach that lets
|
; but we're going to try for a generalized approach that lets
|
||||||
; use have N different sprites at any X-Y coordinate, each with
|
; use have N different sprites at any X-Y coordinate, each with
|
||||||
; its own bitmap and color table. This is tricky because we can
|
; its own bitmap and color table. This is tricky because we can
|
||||||
; only do so much on each scanline.
|
; only do so much on each scanline.
|
||||||
|
;
|
||||||
; Our approach is to separate the problem into three phases.
|
; Our approach is to separate the problem into three phases.
|
||||||
; In the sort phase, we sort all sprites by Y coordinate.
|
; In the sort phase, we sort all sprites by Y coordinate.
|
||||||
; We do one sort pass per frame, so it may take several frames
|
; 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
|
; coming up. We then allocate it to one of the two player
|
||||||
; objects in hardware and set its position using the SetHorizPos
|
; objects in hardware and set its position using the SetHorizPos
|
||||||
; method. We can set one or both of the player objects this way.
|
; method. We can set one or both of the player objects this way.
|
||||||
|
;
|
||||||
; In the display phase, we display the objects which we previously
|
; In the display phase, we display the objects which we previously
|
||||||
; assigned and positioned. First we figure out how many scanlines are
|
; assigned and positioned. First we figure out how many scanlines are
|
||||||
; required. If only one object is scheduled, we just use its height.
|
; 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
|
; 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
|
; else, so we don't look for any new objects to schedule until
|
||||||
; we're done with this loop.
|
; we're done with this loop.
|
||||||
|
;
|
||||||
; This scheme can only display up to two objects on a given
|
; This scheme can only display up to two objects on a given
|
||||||
; scanline, so if the system tries to schedule a third, it will
|
; scanline, so if the system tries to schedule a third, it will
|
||||||
; be ignored. Also, the positioning routine takes a few scanlines
|
; 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
|
; sprite entry is missed. In the sort phase, we move those sprites
|
||||||
; ahead of lower priority sprites in the sort order. This makes
|
; ahead of lower priority sprites in the sort order. This makes
|
||||||
; overlapping sprites flicker instead of randomly disappear.
|
; overlapping sprites flicker instead of randomly disappear.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
@ -6,26 +6,30 @@
|
|||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; This program demonstrates a VCS music player based on tracks
|
; This program demonstrates a VCS music player based on tracks
|
||||||
; and patterns. A pattern is a list of variable-length notes,
|
; and patterns. A pattern is a list of variable-length notes,
|
||||||
; each of which is defined by a pitch and duration.
|
; each of which is defined by a pitch and duration.
|
||||||
; There are two tracks, one for each audio channel.
|
; There are two tracks, one for each audio channel.
|
||||||
; Each track consists of a list of patterns, each entry being
|
; Each track consists of a list of patterns, each entry being
|
||||||
; a byte offset into the Patterns array.
|
; a byte offset into the Patterns array.
|
||||||
|
;
|
||||||
; The patterns in the tracks are played in-order until one ends,
|
; The patterns in the tracks are played in-order until one ends,
|
||||||
; and then both tracks are restarted. It's up to the composer
|
; and then both tracks are restarted. It's up to the composer
|
||||||
; to make sure the durations in each track line up properly.
|
; to make sure the durations in each track line up properly.
|
||||||
|
;
|
||||||
; Patterns consist of NOTE or TONE commands. TONE sets the
|
; Patterns consist of NOTE or TONE commands. TONE sets the
|
||||||
; tone of the channel (the AUDCx register) and NOTE plays a note
|
; tone of the channel (the AUDCx register) and NOTE plays a note
|
||||||
; with a duration taken from a lookup table.
|
; with a duration taken from a lookup table.
|
||||||
; TONE 0 ends a pattern.
|
; TONE 0 ends a pattern.
|
||||||
|
;
|
||||||
; Both channels share the same logical array for tracks and patterns,
|
; Both channels share the same logical array for tracks and patterns,
|
||||||
; so both tracks can take up to 255 bytes total, and all patterns
|
; so both tracks can take up to 255 bytes total, and all patterns
|
||||||
; can use up to 255 bytes total.
|
; can use up to 255 bytes total.
|
||||||
; The music player uses 8 bytes of RAM (not counting stack).
|
; The music player uses 8 bytes of RAM (not counting stack).
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
Trk0idx equ $e0 ; offset into tracks for channel 0
|
Trk0idx equ $e0 ; offset into tracks for channel 0
|
||||||
Trk1idx equ $e1 ; offset into tracks for channel 1
|
Trk1idx equ $e1 ; offset into tracks for channel 1
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; To output a PAL signal, you need the following:
|
; To output a PAL signal, you need the following:
|
||||||
;
|
;
|
||||||
; - 3 scanlines of VSYNC
|
; - 3 scanlines of VSYNC
|
||||||
@ -14,23 +16,25 @@
|
|||||||
; - 36 blank lines
|
; - 36 blank lines
|
||||||
;
|
;
|
||||||
; Total = 312 lines (vs 262 for NTSC)
|
; Total = 312 lines (vs 262 for NTSC)
|
||||||
|
;
|
||||||
; PAL runs at 50 Hz (vs 60 Hz for NTSC)
|
; PAL runs at 50 Hz (vs 60 Hz for NTSC)
|
||||||
; so your game will run more slowly.
|
; so your game will run more slowly.
|
||||||
; Since you have extra cycles to play with, you could just
|
; Since you have extra cycles to play with, you could just
|
||||||
; call your position update routine twice every five frames.
|
; call your position update routine twice every five frames.
|
||||||
|
;
|
||||||
; Note also that PAL has different colors than NTSC.
|
; Note also that PAL has different colors than NTSC.
|
||||||
; (See http://www.randomterrain.com/atari-2600-memories-tia-color-charts.html)
|
; (See http://www.randomterrain.com/atari-2600-memories-tia-color-charts.html)
|
||||||
|
;
|
||||||
; The TIMER_SETUP macro only goes up to 215 lines,
|
; The TIMER_SETUP macro only goes up to 215 lines,
|
||||||
; so for the PAL visible frame you would need to use
|
; so for the PAL visible frame you would need to use
|
||||||
; multiple sections (say 215 + 13 = 228) or count manually
|
; multiple sections (say 215 + 13 = 228) or count manually
|
||||||
; like we do in this example.
|
; like we do in this example.
|
||||||
|
;
|
||||||
; Many VCS games use conditional defines
|
; Many VCS games use conditional defines
|
||||||
; (IFCONST and IFNCONST in DASM)
|
; (IFCONST and IFNCONST in DASM)
|
||||||
; to switch between NTSC and PAL constants.
|
; to switch between NTSC and PAL constants.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
; background color
|
; background color
|
||||||
BGColor equ $81
|
BGColor equ $81
|
||||||
|
@ -4,11 +4,15 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; We're going to mess with the playfield registers, PF0, PF1 and PF2.
|
; We're going to mess with the playfield registers, PF0, PF1 and PF2.
|
||||||
; Between them, they represent 20 bits of bitmap information
|
; Between them, they represent 20 bits of bitmap information
|
||||||
; which are replicated over 40 wide pixels for each scanline.
|
; which are replicated over 40 wide pixels for each scanline.
|
||||||
; By changing the registers before each scanline, we can draw bitmaps.
|
; By changing the registers before each scanline, we can draw bitmaps.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
Counter equ $81
|
Counter equ $81
|
||||||
|
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -4,6 +4,18 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
org $f000
|
||||||
|
|
||||||
CurRow equ $8f
|
CurRow equ $8f
|
||||||
|
@ -3,6 +3,30 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.h"
|
include "xmacro.h"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
|
; This example uses the 48-pixel retriggering method to display
|
||||||
|
; a six-digit scoreboard.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
seg.u Variables
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -4,6 +4,15 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; Sprites are a tricky beast on the 2600.
|
; Sprites are a tricky beast on the 2600.
|
||||||
; You only have two of them.
|
; You only have two of them.
|
||||||
; They are 8 bits wide and 1 bit high.
|
; They are 8 bits wide and 1 bit high.
|
||||||
@ -14,6 +16,8 @@
|
|||||||
; To position Y, you simply wait until the desired scanline and
|
; To position Y, you simply wait until the desired scanline and
|
||||||
; set the bits of your sprite to a non-zero value.
|
; set the bits of your sprite to a non-zero value.
|
||||||
; Having fun yet? :)
|
; Having fun yet? :)
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
Counter equ $81
|
Counter equ $81
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; 64K Tigervision bank-switching example
|
;; 64K Tigervision bank-switching example
|
||||||
|
@ -5,12 +5,16 @@
|
|||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; We're going to try to animate sprites horizontally.
|
; We're going to try to animate sprites horizontally.
|
||||||
; Remember, we have to pause the CPU until the exact moment the
|
; Remember, we have to pause the CPU until the exact moment the
|
||||||
; scanline hits the desired horizontal position of the sprite.
|
; scanline hits the desired horizontal position of the sprite.
|
||||||
; Since we can't hard-code the SLEEP macro we'll have to do it
|
; 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
|
; dynamically somehow. But since the TIA beam is racing so much
|
||||||
; faster than the CPU clock, we'll have to be clever.
|
; faster than the CPU clock, we'll have to be clever.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
counter equ $81
|
counter equ $81
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
org $f000
|
org $f000
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;
|
||||||
; We're going to use a more clever way to position sprites
|
; We're going to use a more clever way to position sprites
|
||||||
; ("players") which relies on additional TIA features.
|
; ("players") which relies on additional TIA features.
|
||||||
; Because the CPU timing is 3 times as coarse as the TIA's,
|
; Because the CPU timing is 3 times as coarse as the TIA's,
|
||||||
@ -12,6 +14,8 @@
|
|||||||
; CPU delays alone.
|
; CPU delays alone.
|
||||||
; Additional TIA registers let us nudge the final position
|
; Additional TIA registers let us nudge the final position
|
||||||
; by discrete TIA clocks and thus target all 160 positions.
|
; by discrete TIA clocks and thus target all 160 positions.
|
||||||
|
;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
counter equ $81
|
counter equ $81
|
||||||
|
|
||||||
|
@ -4,10 +4,30 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
|
||||||
Temp .byte
|
Temp .byte
|
||||||
WriteOfs .byte ; offset into dest. array FontBuf
|
WriteOfs .byte ; offset into dest. array FontBuf
|
||||||
LoopCount .byte ; counts scanline when drawing
|
LoopCount .byte ; counts scanline when drawing
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
include "macro.h"
|
include "macro.h"
|
||||||
include "xmacro.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
|
seg.u Variables
|
||||||
org $80
|
org $80
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
seven_segment_decoder - Decodes a digit into 7 segments.
|
||||||
|
|
||||||
|
segments_to_bitmap - Encodes a 7-segment bitmask into
|
||||||
|
a 5x5 bitmap.
|
||||||
|
|
||||||
Segment bit indices:
|
Segment bit indices:
|
||||||
|
|
||||||
6666
|
6666
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A bouncing ball using absolute coordinates.
|
||||||
|
*/
|
||||||
|
|
||||||
module ball_absolute_top(clk, reset, hsync, vsync, rgb);
|
module ball_absolute_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
`include "digits10.v"
|
`include "digits10.v"
|
||||||
`include "scoreboard.v"
|
`include "scoreboard.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A brick-smashing ball-and-paddle game.
|
||||||
|
*/
|
||||||
|
|
||||||
module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A bouncing ball using the "slipping counter" method, as
|
||||||
|
used in Pong, Computer Space, and other early arcade games.
|
||||||
|
*/
|
||||||
|
|
||||||
module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
A clock divider in Verilog, using both the cascading
|
||||||
|
flip-flop method and the counter method.
|
||||||
|
*/
|
||||||
|
|
||||||
module clock_divider(
|
module clock_divider(
|
||||||
input clk,
|
input clk,
|
||||||
input reset,
|
input reset,
|
||||||
|
@ -8,6 +8,18 @@
|
|||||||
`include "sound_generator.v"
|
`include "sound_generator.v"
|
||||||
`include "cpu16.v"
|
`include "cpu16.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A full video game console, with the following components:
|
||||||
|
|
||||||
|
64 kilobytes (32,678 16-bit words) of RAM
|
||||||
|
16-bit CPU running at 4.857 MHz
|
||||||
|
32x30 tile graphics with 256 x 8 tile ROM
|
||||||
|
32 16x16 sprites per frame with sprite ROM
|
||||||
|
16 colors (two per tile, one per sprite)
|
||||||
|
Two game controllers (four direction switches, two buttons)
|
||||||
|
One paddle/analog stick controller
|
||||||
|
*/
|
||||||
|
|
||||||
module cpu_platform(clk, reset, hsync, vsync,
|
module cpu_platform(clk, reset, hsync, vsync,
|
||||||
hpaddle, vpaddle,
|
hpaddle, vpaddle,
|
||||||
switches_p1, switches_p2,
|
switches_p1, switches_p2,
|
||||||
|
@ -4,6 +4,15 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
ROM module with 5x5 bitmaps for the digits 0-9.
|
||||||
|
|
||||||
|
digits10_case - Uses the case statement.
|
||||||
|
digits10_array - Uses an array and initial block.
|
||||||
|
|
||||||
|
These two modules are functionally equivalent.
|
||||||
|
*/
|
||||||
|
|
||||||
// module for 10-digit bitmap ROM
|
// module for 10-digit bitmap ROM
|
||||||
module digits10_case(digit, yofs, bits);
|
module digits10_case(digit, yofs, bits);
|
||||||
|
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
`ifndef HVSYNC_GENERATOR_H
|
`ifndef HVSYNC_GENERATOR_H
|
||||||
`define HVSYNC_GENERATOR_H
|
`define HVSYNC_GENERATOR_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
Video sync generator, used to drive a simulated CRT.
|
||||||
|
To use:
|
||||||
|
- Wire the hsync and vsync signals to top level outputs
|
||||||
|
- Add a 3-bit (or more) "rgb" output to the top level
|
||||||
|
*/
|
||||||
|
|
||||||
module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
`ifndef LFSR_V
|
`ifndef LFSR_V
|
||||||
`define LFSR_V
|
`define LFSR_V
|
||||||
|
|
||||||
|
/*
|
||||||
|
Configurable Linear Feedback Shift Register.
|
||||||
|
*/
|
||||||
|
|
||||||
module LFSR(clk, reset, enable, lfsr);
|
module LFSR(clk, reset, enable, lfsr);
|
||||||
|
|
||||||
parameter TAPS = 8'b11101; // bitmask for taps
|
parameter TAPS = 8'b11101; // bitmask for taps
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Paddle demonstration.
|
||||||
|
*/
|
||||||
|
|
||||||
module paddles_top(clk, reset, hsync, vsync, hpaddle, vpaddle, rgb);
|
module paddles_top(clk, reset, hsync, vsync, hpaddle, vpaddle, rgb);
|
||||||
|
|
||||||
input clk, reset;
|
input clk, reset;
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
`include "sprite_bitmap.v"
|
`include "sprite_bitmap.v"
|
||||||
`include "sprite_renderer.v"
|
`include "sprite_renderer.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A simple racing game with two sprites and a scrolling playfield.
|
||||||
|
This version does not use a CPU; all logic is straight Verilog.
|
||||||
|
*/
|
||||||
|
|
||||||
module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
`include "sprite_renderer.v"
|
`include "sprite_renderer.v"
|
||||||
`include "cpu8.v"
|
`include "cpu8.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A simple racing game with two sprites and a scrolling playfield.
|
||||||
|
This version uses the 8-bit CPU.
|
||||||
|
*/
|
||||||
|
|
||||||
// uncomment to see scope view
|
// uncomment to see scope view
|
||||||
//`define DEBUG
|
//`define DEBUG
|
||||||
|
|
||||||
|
@ -2,6 +2,17 @@
|
|||||||
`ifndef RAM_H
|
`ifndef RAM_H
|
||||||
`define RAM_H
|
`define RAM_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
RAM_sync - Synchronous RAM module.
|
||||||
|
RAM_async - Asynchronous RAM module.
|
||||||
|
RAM_async_tristate - Async RAM module with bidirectional data bus.
|
||||||
|
|
||||||
|
Module parameters:
|
||||||
|
|
||||||
|
A - number of address bits (default = 10)
|
||||||
|
D - number of data bits (default = 8)
|
||||||
|
*/
|
||||||
|
|
||||||
module RAM_sync(clk, addr, din, dout, we);
|
module RAM_sync(clk, addr, din, dout, we);
|
||||||
|
|
||||||
parameter A = 10; // # of address bits
|
parameter A = 10; // # of address bits
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
`include "digits10.v"
|
`include "digits10.v"
|
||||||
`include "ram.v"
|
`include "ram.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Displays a grid of digits on the CRT using a RAM module.
|
||||||
|
*/
|
||||||
|
|
||||||
module test_ram1_top(clk, reset, hsync, vsync, rgb);
|
module test_ram1_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk, reset;
|
input clk, reset;
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
`include "digits10.v"
|
`include "digits10.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
player_stats - Holds two-digit score and one-digit lives counter.
|
||||||
|
scoreboard_generator - Outputs video signal with score/lives digits.
|
||||||
|
*/
|
||||||
|
|
||||||
module player_stats(reset, score0, score1, lives, incscore, declives);
|
module player_stats(reset, score0, score1, lives, incscore, declives);
|
||||||
|
|
||||||
input reset;
|
input reset;
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
`include "lfsr.v"
|
`include "lfsr.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sound generator module.
|
||||||
|
This module has a square-wave oscillator (VCO) which can
|
||||||
|
be modulated by a low-frequency oscillator (LFO) and also
|
||||||
|
mixed with a LFSR noise source.
|
||||||
|
*/
|
||||||
|
|
||||||
module sound_generator(clk, reset, spkr,
|
module sound_generator(clk, reset, spkr,
|
||||||
lfo_freq,noise_freq, vco_freq,
|
lfo_freq,noise_freq, vco_freq,
|
||||||
vco_select, noise_select, lfo_shift, mixer);
|
vco_select, noise_select, lfo_shift, mixer);
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Simple sprite renderer example.
|
||||||
|
|
||||||
|
car_bitmap - ROM for a car sprite.
|
||||||
|
sprite_bitmap_top - Example sprite rendering module.
|
||||||
|
*/
|
||||||
|
|
||||||
module car_bitmap(yofs, bits);
|
module car_bitmap(yofs, bits);
|
||||||
|
|
||||||
input [3:0] yofs;
|
input [3:0] yofs;
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
|
||||||
`ifndef SPRITE_RENDERER_H
|
`ifndef SPRITE_RENDERER_H
|
||||||
`define SPRITE_RENDERER_H
|
`define SPRITE_RENDERER_H
|
||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
`include "sprite_bitmap.v"
|
`include "sprite_bitmap.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Displays a 16x16 sprite (8 bits mirrored left/right).
|
||||||
|
*/
|
||||||
|
|
||||||
module sprite_renderer(clk, vstart, load, hstart, rom_addr, rom_bits,
|
module sprite_renderer(clk, vstart, load, hstart, rom_addr, rom_bits,
|
||||||
gfx, in_progress);
|
gfx, in_progress);
|
||||||
|
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
|
|
||||||
`ifndef SPRITE_ROTATION_H
|
`ifndef SPRITE_ROTATION_H
|
||||||
`define SPRITE_ROTATION_H
|
`define SPRITE_ROTATION_H
|
||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
// tank bitmap ROM module
|
/*
|
||||||
|
tank_bitmap - ROM for tank bitmaps (5 different rotations)
|
||||||
|
sprite_renderer2 - Displays a 16x16 sprite.
|
||||||
|
tank_controller - Handles display and movement for one tank.
|
||||||
|
*/
|
||||||
|
|
||||||
module tank_bitmap(addr, bits);
|
module tank_bitmap(addr, bits);
|
||||||
|
|
||||||
input [7:0] addr;
|
input [7:0] addr;
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
`include "ram.v"
|
`include "ram.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
sprite_scanline_renderer - Module that renders multiple
|
||||||
|
sprites whose attributes are fetched from shared RAM,
|
||||||
|
and whose bitmaps are stored in ROM. Made to be paired
|
||||||
|
with the FEMTO-16 CPU.
|
||||||
|
*/
|
||||||
|
|
||||||
module example_bitmap_rom(addr, data);
|
module example_bitmap_rom(addr, data);
|
||||||
|
|
||||||
input [15:0] addr;
|
input [15:0] addr;
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
`include "lfsr.v"
|
`include "lfsr.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Scrolling starfield generator using a period (2^16-1) LFSR.
|
||||||
|
*/
|
||||||
|
|
||||||
module starfield_top(clk, reset, hsync, vsync, rgb);
|
module starfield_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk, reset;
|
input clk, reset;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Switch test program.
|
||||||
|
|
||||||
Player 1 Keys: arrow keys + space + shift
|
Player 1 Keys: arrow keys + space + shift
|
||||||
Player 2 Keys: A/D/W/S + Z + X
|
Player 2 Keys: A/D/W/S + Z + X
|
||||||
*/
|
*/
|
||||||
|
@ -3,6 +3,15 @@
|
|||||||
`include "digits10.v"
|
`include "digits10.v"
|
||||||
`include "sprite_rotation.v"
|
`include "sprite_rotation.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tank game.
|
||||||
|
|
||||||
|
minefield - Displays the minefield.
|
||||||
|
playfield - Displays the playfield maze.
|
||||||
|
tank_game_top - Runs the tank game, using two tank_controller
|
||||||
|
modules.
|
||||||
|
*/
|
||||||
|
|
||||||
module minefield(hpos, vpos, mine_gfx);
|
module minefield(hpos, vpos, mine_gfx);
|
||||||
|
|
||||||
input [8:0] hpos;
|
input [8:0] hpos;
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A simple test pattern using the hvsync_generator module.
|
||||||
|
*/
|
||||||
|
|
||||||
module test_hvsync_top(clk, reset, hsync, vsync, rgb);
|
module test_hvsync_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk, reset;
|
input clk, reset;
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
`include "font_cp437_8x8.v"
|
`include "font_cp437_8x8.v"
|
||||||
`include "ram.v"
|
`include "ram.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Displays a 32x30 grid of 8x8 tiles, whose attributes are
|
||||||
|
fetched from RAM, and whose bitmap patterns are in ROM.
|
||||||
|
*/
|
||||||
|
|
||||||
module tile_renderer(clk, reset, hpos, vpos,
|
module tile_renderer(clk, reset, hpos, vpos,
|
||||||
rgb,
|
rgb,
|
||||||
ram_addr, ram_read, ram_busy,
|
ram_addr, ram_read, ram_busy,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user