initial commit
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*~
|
||||
node_modules
|
9
.gitmodules
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
[submodule "javatari.js"]
|
||||
path = javatari.js
|
||||
url = https://github.com/sehugg/javatari.js
|
||||
[submodule "dasm"]
|
||||
path = dasm
|
||||
url = https://github.com/sehugg/dasm
|
||||
[submodule "codemirror"]
|
||||
path = codemirror
|
||||
url = https://github.com/sehugg/codemirror
|
349
css/codemirror.css
Normal file
@ -0,0 +1,349 @@
|
||||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
border: 1px solid #eee;
|
||||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||
font-size: 0.8em;
|
||||
height: 96vh;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 5px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #99cc99 !important;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker { color: black; }
|
||||
.CodeMirror-guttermarker-subtle { color: #999; }
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0 !important;
|
||||
background: #7e7;
|
||||
}
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.cm-animate-fat-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
.CodeMirror-overwrite .CodeMirror-cursor {}
|
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: -50px; bottom: -20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0; bottom: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
||||
.cm-s-default .cm-header {color: blue;}
|
||||
.cm-s-default .cm-quote {color: #090;}
|
||||
.cm-negative {color: #d44;}
|
||||
.cm-positive {color: #292;}
|
||||
.cm-header, .cm-strong {font-weight: bold;}
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
.cm-strikethrough {text-decoration: line-through;}
|
||||
|
||||
.cm-s-default .cm-keyword {color: #708;}
|
||||
.cm-s-default .cm-atom {color: #219;}
|
||||
.cm-s-default .cm-number {color: #164;}
|
||||
.cm-s-default .cm-def {color: #00f;}
|
||||
.cm-s-default .cm-variable,
|
||||
.cm-s-default .cm-punctuation,
|
||||
.cm-s-default .cm-property,
|
||||
.cm-s-default .cm-operator {}
|
||||
.cm-s-default .cm-variable-2 {color: #05a;}
|
||||
.cm-s-default .cm-variable-3 {color: #085;}
|
||||
.cm-s-default .cm-comment {color: #a50;}
|
||||
.cm-s-default .cm-string {color: #a11;}
|
||||
.cm-s-default .cm-string-2 {color: #f50;}
|
||||
.cm-s-default .cm-meta {color: #555;}
|
||||
.cm-s-default .cm-qualifier {color: #555;}
|
||||
.cm-s-default .cm-builtin {color: #30a;}
|
||||
.cm-s-default .cm-bracket {color: #997;}
|
||||
.cm-s-default .cm-tag {color: #170;}
|
||||
.cm-s-default .cm-attribute {color: #00c;}
|
||||
.cm-s-default .cm-hr {color: #999;}
|
||||
.cm-s-default .cm-link {color: #00c;}
|
||||
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-invalidchar {color: #f00;}
|
||||
|
||||
.CodeMirror-composing { border-bottom: 2px solid; }
|
||||
|
||||
/* Default styles for common addons */
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
|
||||
.CodeMirror-activeline-background {background: #e8f2ff;}
|
||||
|
||||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: scroll !important; /* Things will break if this is overridden */
|
||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -30px; margin-right: -30px;
|
||||
padding-bottom: 30px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
border-right: 30px solid transparent;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
}
|
||||
.CodeMirror-gutter-filler {
|
||||
left: 0; bottom: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -30px;
|
||||
/* Hack to make IE7 behave */
|
||||
*zoom:1;
|
||||
*display:inline;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
color: #cccccc;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
min-height: 1px; /* prevents collapsing before first draw */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: none;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.CodeMirror-widget {}
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Force content-box sizing for the elements where we expect it */
|
||||
.CodeMirror-scroll,
|
||||
.CodeMirror-sizer,
|
||||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
.CodeMirror-crosshair { cursor: crosshair; }
|
||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
|
||||
.CodeMirror span { *vertical-align: text-bottom; }
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
.cm-force-border { padding-right: .1px; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* See issue #2901 */
|
||||
.cm-tab-wrap-hack:after { content: ''; }
|
||||
|
||||
/* Help users use markselection to safely style text background */
|
||||
span.CodeMirror-selectedtext { background: none; }
|
23
doc/notes.txt
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
TODO:
|
||||
|
||||
- download ROM file
|
||||
- NaN in cycle count for macros
|
||||
- debugging of scan line overflow
|
||||
- confuse code/data in listing
|
||||
- show memory locations hovering over lines
|
||||
- don't play sound when debugging
|
||||
- coalesce compile events
|
||||
- don't check against ROM signatures
|
||||
- better errors when ROM format wrong
|
||||
- debugging inside of bank switching??? relocated segs?
|
||||
- support 6502 test cases
|
||||
- DASM: macro forward refs
|
||||
- support narrow screens
|
||||
- show other TIA internal values
|
||||
- case sensisitvity looking for mismatch variables
|
||||
- remove pulldown when no preset?
|
||||
- some units test maybe
|
||||
- can't step after reset (or when funky frame; TIA frame is out of sync)
|
||||
- break on BRK/illegal opcode?
|
||||
|
BIN
images/pause.png
Normal file
After Width: | Height: | Size: 95 B |
BIN
images/play.png
Normal file
After Width: | Height: | Size: 123 B |
BIN
images/resetandrun.png
Normal file
After Width: | Height: | Size: 143 B |
BIN
images/runtoline.png
Normal file
After Width: | Height: | Size: 128 B |
BIN
images/share.png
Normal file
After Width: | Height: | Size: 193 B |
BIN
images/singlestep.png
Normal file
After Width: | Height: | Size: 160 B |
BIN
images/timing.png
Normal file
After Width: | Height: | Size: 165 B |
176
include/macro.h
Normal file
@ -0,0 +1,176 @@
|
||||
; MACRO.H
|
||||
; Version 1.06, 3/SEPTEMBER/2004
|
||||
|
||||
VERSION_MACRO = 106
|
||||
|
||||
;
|
||||
; THIS FILE IS EXPLICITLY SUPPORTED AS A DASM-PREFERRED COMPANION FILE
|
||||
; PLEASE DO *NOT* REDISTRIBUTE MODIFIED VERSIONS OF THIS FILE!
|
||||
;
|
||||
; This file defines DASM macros useful for development for the Atari 2600.
|
||||
; It is distributed as a companion machine-specific support package
|
||||
; for the DASM compiler. Updates to this file, DASM, and associated tools are
|
||||
; available at at http://www.atari2600.org/dasm
|
||||
;
|
||||
; Many thanks to the people who have contributed. If you take issue with the
|
||||
; contents, or would like to add something, please write to me
|
||||
; (atari2600@taswegian.com) with your contribution.
|
||||
;
|
||||
; Latest Revisions...
|
||||
;
|
||||
; 1.06 03/SEP/2004 - nice revision of VERTICAL_BLANK (Edwin Blink)
|
||||
; 1.05 14/NOV/2003 - Added VERSION_MACRO equate (which will reflect 100x version #)
|
||||
; This will allow conditional code to verify MACRO.H being
|
||||
; used for code assembly.
|
||||
; 1.04 13/NOV/2003 - SET_POINTER macro added (16-bit address load)
|
||||
;
|
||||
; 1.03 23/JUN/2003 - CLEAN_START macro added - clears TIA, RAM, registers
|
||||
;
|
||||
; 1.02 14/JUN/2003 - VERTICAL_SYNC macro added
|
||||
; (standardised macro for vertical synch code)
|
||||
; 1.01 22/MAR/2003 - SLEEP macro added.
|
||||
; - NO_ILLEGAL_OPCODES switch implemented
|
||||
; 1.0 22/MAR/2003 Initial release
|
||||
|
||||
; Note: These macros use illegal opcodes. To disable illegal opcode usage,
|
||||
; define the symbol NO_ILLEGAL_OPCODES (-DNO_ILLEGAL_OPCODES=1 on command-line).
|
||||
; If you do not allow illegal opcode usage, you must include this file
|
||||
; *after* including VCS.H (as the non-illegal opcodes access hardware
|
||||
; registers and require them to be defined first).
|
||||
|
||||
; Available macros...
|
||||
; SLEEP n - sleep for n cycles
|
||||
; VERTICAL_SYNC - correct 3 scanline vertical synch code
|
||||
; CLEAN_START - set machine to known state on startup
|
||||
; SET_POINTER - load a 16-bit absolute to a 16-bit variable
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; SLEEP duration
|
||||
; Original author: Thomas Jentzsch
|
||||
; Inserts code which takes the specified number of cycles to execute. This is
|
||||
; useful for code where precise timing is required.
|
||||
; ILLEGAL-OPCODE VERSION DOES NOT AFFECT FLAGS OR REGISTERS.
|
||||
; LEGAL OPCODE VERSION MAY AFFECT FLAGS
|
||||
; Uses illegal opcode (DASM 2.20.01 onwards).
|
||||
|
||||
MAC SLEEP ;usage: SLEEP n (n>1)
|
||||
.CYCLES SET {1}
|
||||
|
||||
IF .CYCLES < 2
|
||||
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 1"
|
||||
ERR
|
||||
ENDIF
|
||||
|
||||
IF .CYCLES & 1
|
||||
IFNCONST NO_ILLEGAL_OPCODES
|
||||
nop 0
|
||||
ELSE
|
||||
bit VSYNC
|
||||
ENDIF
|
||||
.CYCLES SET .CYCLES - 3
|
||||
ENDIF
|
||||
|
||||
REPEAT .CYCLES / 2
|
||||
nop
|
||||
REPEND
|
||||
ENDM
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; VERTICAL_SYNC
|
||||
; revised version by Edwin Blink -- saves bytes!
|
||||
; Inserts the code required for a proper 3 scanline vertical sync sequence
|
||||
; Note: Alters the accumulator
|
||||
|
||||
; OUT: A = 0
|
||||
|
||||
MAC VERTICAL_SYNC
|
||||
lda #%1110 ; each '1' bits generate a VSYNC ON line (bits 1..3)
|
||||
.VSLP1 sta WSYNC ; 1st '0' bit resets Vsync, 2nd '0' bit exit loop
|
||||
sta VSYNC
|
||||
lsr
|
||||
bne .VSLP1 ; branch until VYSNC has been reset
|
||||
ENDM
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; CLEAN_START
|
||||
; Original author: Andrew Davie
|
||||
; Standardised start-up code, clears stack, all TIA registers and RAM to 0
|
||||
; Sets stack pointer to $FF, and all registers to 0
|
||||
; Sets decimal mode off, sets interrupt flag (kind of un-necessary)
|
||||
; Use as very first section of code on boot (ie: at reset)
|
||||
; Code written to minimise total ROM usage - uses weird 6502 knowledge :)
|
||||
|
||||
MAC CLEAN_START
|
||||
sei
|
||||
cld
|
||||
|
||||
ldx #0
|
||||
txa
|
||||
tay
|
||||
.CLEAR_STACK dex
|
||||
txs
|
||||
pha
|
||||
bne .CLEAR_STACK ; SP=$FF, X = A = Y = 0
|
||||
|
||||
ENDM
|
||||
|
||||
;-------------------------------------------------------
|
||||
; SET_POINTER
|
||||
; Original author: Manuel Rotschkar
|
||||
;
|
||||
; Sets a 2 byte RAM pointer to an absolute address.
|
||||
;
|
||||
; Usage: SET_POINTER pointer, address
|
||||
; Example: SET_POINTER SpritePTR, SpriteData
|
||||
;
|
||||
; Note: Alters the accumulator, NZ flags
|
||||
; IN 1: 2 byte RAM location reserved for pointer
|
||||
; IN 2: absolute address
|
||||
|
||||
MAC SET_POINTER
|
||||
.POINTER SET {1}
|
||||
.ADDRESS SET {2}
|
||||
|
||||
LDA #<.ADDRESS ; Get Lowbyte of Address
|
||||
STA .POINTER ; Store in pointer
|
||||
LDA #>.ADDRESS ; Get Hibyte of Address
|
||||
STA .POINTER+1 ; Store in pointer+1
|
||||
|
||||
ENDM
|
||||
|
||||
;-------------------------------------------------------
|
||||
; BOUNDARY byte#
|
||||
; Original author: Denis Debro (borrowed from Bob Smith / Thomas)
|
||||
;
|
||||
; Push data to a certain position inside a page and keep count of how
|
||||
; many free bytes the programmer will have.
|
||||
;
|
||||
; eg: BOUNDARY 5 ; position at byte #5 in page
|
||||
|
||||
.FREE_BYTES SET 0
|
||||
MAC BOUNDARY
|
||||
REPEAT 256
|
||||
IF <. % {1} = 0
|
||||
MEXIT
|
||||
ELSE
|
||||
.FREE_BYTES SET .FREE_BYTES + 1
|
||||
.byte $00
|
||||
ENDIF
|
||||
REPEND
|
||||
ENDM
|
||||
|
||||
;-------------------------------------------------------
|
||||
; SKIP_SCANLINES #lines
|
||||
;
|
||||
; Skip a given # of scanlines.
|
||||
; Sets the X register to zero.
|
||||
|
||||
MAC SKIP_SCANLINES
|
||||
.LINES SET {1}
|
||||
ldx #.LINES
|
||||
.vblank sta WSYNC
|
||||
dex
|
||||
bne .vblank
|
||||
ENDM
|
||||
|
||||
; EOF
|
200
include/vcs.h
Normal file
@ -0,0 +1,200 @@
|
||||
; VCS.H
|
||||
; Version 1.05, 13/November/2003
|
||||
|
||||
VERSION_VCS = 105
|
||||
|
||||
; THIS IS A PRELIMINARY RELEASE OF *THE* "STANDARD" VCS.H
|
||||
; THIS FILE IS EXPLICITLY SUPPORTED AS A DASM-PREFERRED COMPANION FILE
|
||||
; PLEASE DO *NOT* REDISTRIBUTE THIS FILE!
|
||||
;
|
||||
; This file defines hardware registers and memory mapping for the
|
||||
; Atari 2600. It is distributed as a companion machine-specific support package
|
||||
; for the DASM compiler. Updates to this file, DASM, and associated tools are
|
||||
; available at at http://www.atari2600.org/dasm
|
||||
;
|
||||
; Many thanks to the original author(s) of this file, and to everyone who has
|
||||
; contributed to understanding the Atari 2600. If you take issue with the
|
||||
; contents, or naming of registers, please write to me (atari2600@taswegian.com)
|
||||
; with your views. Please contribute, if you think you can improve this
|
||||
; file!
|
||||
;
|
||||
; Latest Revisions...
|
||||
; 1.05 13/NOV/2003 - Correction to 1.04 - now functions as requested by MR.
|
||||
; - Added VERSION_VCS equate (which will reflect 100x version #)
|
||||
; This will allow conditional code to verify VCS.H being
|
||||
; used for code assembly.
|
||||
; 1.04 12/NOV/2003 Added TIA_BASE_WRITE_ADDRESS and TIA_BASE_READ_ADDRESS for
|
||||
; convenient disassembly/reassembly compatibility for hardware
|
||||
; mirrored reading/writing differences. This is more a
|
||||
; readability issue, and binary compatibility with disassembled
|
||||
; and reassembled sources. Per Manuel Rotschkar's suggestion.
|
||||
; 1.03 12/MAY/2003 Added SEG segment at end of file to fix old-code compatibility
|
||||
; which was broken by the use of segments in this file, as
|
||||
; reported by Manuel Polik on [stella] 11/MAY/2003
|
||||
; 1.02 22/MAR/2003 Added TIMINT($285)
|
||||
; 1.01 Constant offset added to allow use for 3F-style bankswitching
|
||||
; - define TIA_BASE_ADDRESS as $40 for Tigervision carts, otherwise
|
||||
; it is safe to leave it undefined, and the base address will
|
||||
; be set to 0. Thanks to Eckhard Stolberg for the suggestion.
|
||||
; Note, may use -DLABEL=EXPRESSION to define TIA_BASE_ADDRESS
|
||||
; - register definitions are now generated through assignment
|
||||
; in uninitialised segments. This allows a changeable base
|
||||
; address architecture.
|
||||
; 1.0 22/MAR/2003 Initial release
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; TIA_BASE_ADDRESS
|
||||
; The TIA_BASE_ADDRESS defines the base address of access to TIA registers.
|
||||
; Normally 0, the base address should (externally, before including this file)
|
||||
; be set to $40 when creating 3F-bankswitched (and other?) cartridges.
|
||||
; The reason is that this bankswitching scheme treats any access to locations
|
||||
; < $40 as a bankswitch.
|
||||
|
||||
IFNCONST TIA_BASE_ADDRESS
|
||||
TIA_BASE_ADDRESS = 0
|
||||
ENDIF
|
||||
|
||||
; Note: The address may be defined on the command-line using the -D switch, eg:
|
||||
; dasm.exe code.asm -DTIA_BASE_ADDRESS=$40 -f3 -v5 -ocode.bin
|
||||
; *OR* by declaring the label before including this file, eg:
|
||||
; TIA_BASE_ADDRESS = $40
|
||||
; include "vcs.h"
|
||||
|
||||
; Alternate read/write address capability - allows for some disassembly compatibility
|
||||
; usage ; to allow reassembly to binary perfect copies). This is essentially catering
|
||||
; for the mirrored ROM hardware registers.
|
||||
|
||||
; Usage: As per above, define the TIA_BASE_READ_ADDRESS and/or TIA_BASE_WRITE_ADDRESS
|
||||
; using the -D command-line switch, as required. If the addresses are not defined,
|
||||
; they defaut to the TIA_BASE_ADDRESS.
|
||||
|
||||
IFNCONST TIA_BASE_READ_ADDRESS
|
||||
TIA_BASE_READ_ADDRESS = TIA_BASE_ADDRESS
|
||||
ENDIF
|
||||
|
||||
IFNCONST TIA_BASE_WRITE_ADDRESS
|
||||
TIA_BASE_WRITE_ADDRESS = TIA_BASE_ADDRESS
|
||||
ENDIF
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
SEG.U TIA_REGISTERS_WRITE
|
||||
ORG TIA_BASE_WRITE_ADDRESS
|
||||
|
||||
; DO NOT CHANGE THE RELATIVE ORDERING OF REGISTERS!
|
||||
|
||||
VSYNC ds 1 ; $00 0000 00x0 Vertical Sync Set-Clear
|
||||
VBLANK ds 1 ; $01 xx00 00x0 Vertical Blank Set-Clear
|
||||
WSYNC ds 1 ; $02 ---- ---- Wait for Horizontal Blank
|
||||
RSYNC ds 1 ; $03 ---- ---- Reset Horizontal Sync Counter
|
||||
NUSIZ0 ds 1 ; $04 00xx 0xxx Number-Size player/missle 0
|
||||
NUSIZ1 ds 1 ; $05 00xx 0xxx Number-Size player/missle 1
|
||||
COLUP0 ds 1 ; $06 xxxx xxx0 Color-Luminance Player 0
|
||||
COLUP1 ds 1 ; $07 xxxx xxx0 Color-Luminance Player 1
|
||||
COLUPF ds 1 ; $08 xxxx xxx0 Color-Luminance Playfield
|
||||
COLUBK ds 1 ; $09 xxxx xxx0 Color-Luminance Background
|
||||
CTRLPF ds 1 ; $0A 00xx 0xxx Control Playfield, Ball, Collisions
|
||||
REFP0 ds 1 ; $0B 0000 x000 Reflection Player 0
|
||||
REFP1 ds 1 ; $0C 0000 x000 Reflection Player 1
|
||||
PF0 ds 1 ; $0D xxxx 0000 Playfield Register Byte 0
|
||||
PF1 ds 1 ; $0E xxxx xxxx Playfield Register Byte 1
|
||||
PF2 ds 1 ; $0F xxxx xxxx Playfield Register Byte 2
|
||||
RESP0 ds 1 ; $10 ---- ---- Reset Player 0
|
||||
RESP1 ds 1 ; $11 ---- ---- Reset Player 1
|
||||
RESM0 ds 1 ; $12 ---- ---- Reset Missle 0
|
||||
RESM1 ds 1 ; $13 ---- ---- Reset Missle 1
|
||||
RESBL ds 1 ; $14 ---- ---- Reset Ball
|
||||
AUDC0 ds 1 ; $15 0000 xxxx Audio Control 0
|
||||
AUDC1 ds 1 ; $16 0000 xxxx Audio Control 1
|
||||
AUDF0 ds 1 ; $17 000x xxxx Audio Frequency 0
|
||||
AUDF1 ds 1 ; $18 000x xxxx Audio Frequency 1
|
||||
AUDV0 ds 1 ; $19 0000 xxxx Audio Volume 0
|
||||
AUDV1 ds 1 ; $1A 0000 xxxx Audio Volume 1
|
||||
GRP0 ds 1 ; $1B xxxx xxxx Graphics Register Player 0
|
||||
GRP1 ds 1 ; $1C xxxx xxxx Graphics Register Player 1
|
||||
ENAM0 ds 1 ; $1D 0000 00x0 Graphics Enable Missle 0
|
||||
ENAM1 ds 1 ; $1E 0000 00x0 Graphics Enable Missle 1
|
||||
ENABL ds 1 ; $1F 0000 00x0 Graphics Enable Ball
|
||||
HMP0 ds 1 ; $20 xxxx 0000 Horizontal Motion Player 0
|
||||
HMP1 ds 1 ; $21 xxxx 0000 Horizontal Motion Player 1
|
||||
HMM0 ds 1 ; $22 xxxx 0000 Horizontal Motion Missle 0
|
||||
HMM1 ds 1 ; $23 xxxx 0000 Horizontal Motion Missle 1
|
||||
HMBL ds 1 ; $24 xxxx 0000 Horizontal Motion Ball
|
||||
VDELP0 ds 1 ; $25 0000 000x Vertical Delay Player 0
|
||||
VDELP1 ds 1 ; $26 0000 000x Vertical Delay Player 1
|
||||
VDELBL ds 1 ; $27 0000 000x Vertical Delay Ball
|
||||
RESMP0 ds 1 ; $28 0000 00x0 Reset Missle 0 to Player 0
|
||||
RESMP1 ds 1 ; $29 0000 00x0 Reset Missle 1 to Player 1
|
||||
HMOVE ds 1 ; $2A ---- ---- Apply Horizontal Motion
|
||||
HMCLR ds 1 ; $2B ---- ---- Clear Horizontal Move Registers
|
||||
CXCLR ds 1 ; $2C ---- ---- Clear Collision Latches
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
SEG.U TIA_REGISTERS_READ
|
||||
ORG TIA_BASE_READ_ADDRESS
|
||||
|
||||
; bit 7 bit 6
|
||||
CXM0P ds 1 ; $00 xx00 0000 Read Collision M0-P1 M0-P0
|
||||
CXM1P ds 1 ; $01 xx00 0000 M1-P0 M1-P1
|
||||
CXP0FB ds 1 ; $02 xx00 0000 P0-PF P0-BL
|
||||
CXP1FB ds 1 ; $03 xx00 0000 P1-PF P1-BL
|
||||
CXM0FB ds 1 ; $04 xx00 0000 M0-PF M0-BL
|
||||
CXM1FB ds 1 ; $05 xx00 0000 M1-PF M1-BL
|
||||
CXBLPF ds 1 ; $06 x000 0000 BL-PF -----
|
||||
CXPPMM ds 1 ; $07 xx00 0000 P0-P1 M0-M1
|
||||
INPT0 ds 1 ; $08 x000 0000 Read Pot Port 0
|
||||
INPT1 ds 1 ; $09 x000 0000 Read Pot Port 1
|
||||
INPT2 ds 1 ; $0A x000 0000 Read Pot Port 2
|
||||
INPT3 ds 1 ; $0B x000 0000 Read Pot Port 3
|
||||
INPT4 ds 1 ; $0C x000 0000 Read Input (Trigger) 0
|
||||
INPT5 ds 1 ; $0D x000 0000 Read Input (Trigger) 1
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
SEG.U RIOT
|
||||
ORG $280
|
||||
|
||||
; RIOT MEMORY MAP
|
||||
|
||||
SWCHA ds 1 ; $280 Port A data register for joysticks:
|
||||
; Bits 4-7 for player 1. Bits 0-3 for player 2.
|
||||
|
||||
SWACNT ds 1 ; $281 Port A data direction register (DDR)
|
||||
SWCHB ds 1 ; $282 Port B data (console switches)
|
||||
SWBCNT ds 1 ; $283 Port B DDR
|
||||
INTIM ds 1 ; $284 Timer output
|
||||
|
||||
TIMINT ds 1 ; $285
|
||||
|
||||
; Unused/undefined registers ($285-$294)
|
||||
|
||||
ds 1 ; $286
|
||||
ds 1 ; $287
|
||||
ds 1 ; $288
|
||||
ds 1 ; $289
|
||||
ds 1 ; $28A
|
||||
ds 1 ; $28B
|
||||
ds 1 ; $28C
|
||||
ds 1 ; $28D
|
||||
ds 1 ; $28E
|
||||
ds 1 ; $28F
|
||||
ds 1 ; $290
|
||||
ds 1 ; $291
|
||||
ds 1 ; $292
|
||||
ds 1 ; $293
|
||||
|
||||
TIM1T ds 1 ; $294 set 1 clock interval
|
||||
TIM8T ds 1 ; $295 set 8 clock interval
|
||||
TIM64T ds 1 ; $296 set 64 clock interval
|
||||
T1024T ds 1 ; $297 set 1024 clock interval
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; The following required for back-compatibility with code which does not use
|
||||
; segments.
|
||||
|
||||
SEG
|
||||
|
||||
; EOF
|
172
index.html
Normal file
@ -0,0 +1,172 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>8bitworkshop IDE</title>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
overflow: hidden;
|
||||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||
}
|
||||
.dbg_info {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
#controls_top {
|
||||
padding: 0.5em;
|
||||
}
|
||||
.gutter-offset {
|
||||
width: 3em;
|
||||
}
|
||||
.gutter-bytes {
|
||||
width: 6em;
|
||||
}
|
||||
.gutter-clock {
|
||||
width: 0.5em;
|
||||
}
|
||||
.gutter-info {
|
||||
width: 1em;
|
||||
}
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-bottom: 1px dotted black;
|
||||
}
|
||||
.tooltip .tooltiptext {
|
||||
visibility: hidden;
|
||||
width: 120px;
|
||||
background-color: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px 0;
|
||||
|
||||
/* Position the tooltip */
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
.tooltip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
#notebook {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
div.editor {
|
||||
position:absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
bottom:0;
|
||||
right:0;
|
||||
width:50%;
|
||||
height:100vh;
|
||||
background-color:#999;
|
||||
}
|
||||
div.emulator {
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:0;
|
||||
width:50%;
|
||||
height:100vh;
|
||||
overflow-y: scroll;
|
||||
background-color: #666;
|
||||
}
|
||||
div.mem_info {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
background-color: #333;
|
||||
color: #66ff66;
|
||||
left: 20px;
|
||||
white-space: pre;
|
||||
padding: 20px;
|
||||
z-index: 2;
|
||||
}
|
||||
span.hilite {
|
||||
color: #ff66ff;
|
||||
}
|
||||
div.has-errors {
|
||||
background-color: #ff6666 !important;
|
||||
}
|
||||
div.menu_div {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
}
|
||||
div.booklink {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 6px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a {
|
||||
color:#333399;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="notebook">
|
||||
<div id="editor" class="editor">
|
||||
<div id="controls_top">
|
||||
<!-- <a id="file_new" href="#" title="New File">+</a> -->
|
||||
<!-- <a id="preset_prev" href="#"><<</a> -->
|
||||
<button id="btn_share" title="Share File"><img src="images/share.png"></button>
|
||||
<select id="preset_select" name="">
|
||||
</select>
|
||||
<button id="dbg_pause" type="button" title="Pause"><img src="images/pause.png"></button>
|
||||
<button id="dbg_go" type="button" title="Run"><img src="images/play.png"></button>
|
||||
<button id="dbg_toline" type="submit" title="Run To Line"><img src="images/runtoline.png"></button>
|
||||
<button id="dbg_step" type="submit" title="Step"><img src="images/singlestep.png"></button>
|
||||
<button id="dbg_reset" type="submit" title="Reset and Run To Line"><img src="images/resetandrun.png"></button>
|
||||
<button id="dbg_timing" type="submit" title="See Timing"><img src="images/timing.png"></button>
|
||||
<span class="dbg_info" id="dbg_info"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 30px auto 0; min-height: 594px;" class="emulator">
|
||||
<div id="javatari-screen" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
|
||||
<div id="javatari-console-panel" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
|
||||
<div id="mem_info" class="mem_info" style="display:none">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="booklink">
|
||||
<!--
|
||||
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"
|
||||
src="http://ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ac&ref=tf_til&ad_type=product_link&tracking_id=pzp-20&marketplace=amazon®ion=US&placement=B01N4DSRIZ&asins=B01N4DSRIZ&linkId=67b114b83ce0b13ceaf715ee86833626&show_border=true&link_opens_in_new_window=false&price_color=333333&title_color=0066c0&bg_color=7d6d6d">
|
||||
</iframe>
|
||||
-->
|
||||
<img src="https://images-na.ssl-images-amazon.com/images/I/5153Bd8oWeL._AC_AC_SR98,95_.jpg" style="float:right"/>
|
||||
Want to learn more?<br>
|
||||
Get the new book<br>
|
||||
<a target="_new" href="https://www.amazon.com/gp/product/B01N4DSRIZ/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=pzp-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B01N4DSRIZ&linkId=04d39e274c06e6c93b93d20a9a977111">
|
||||
Making Games For The Atari 2600</a>
|
||||
</div>
|
||||
|
||||
<script src="jquery/jquery-2.2.3.min.js"></script>
|
||||
|
||||
<script src="codemirror/lib/codemirror.js"></script>
|
||||
<script src="codemirror/mode/6502/6502.js"></script>
|
||||
<link rel="stylesheet" href="css/codemirror.css">
|
||||
<link rel="stylesheet" href="codemirror/theme/mbo.css">
|
||||
<script src="codemirror/addon/search/search.js"></script>
|
||||
<script src="codemirror/addon/search/searchcursor.js"></script>
|
||||
<script src="codemirror/addon/search/jumpToLine.js"></script>
|
||||
<script src="codemirror/addon/dialog/dialog.js"></script>
|
||||
<link rel="stylesheet" href="codemirror/addon/dialog/dialog.css">
|
||||
|
||||
<script src="javatari.js/release/javatari/javatari.js"></script>
|
||||
|
||||
<script src="src/jsdiff.js"></script>
|
||||
<script src="src/ui.js"></script>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-54497476-9', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
</html>
|
4
jquery/jquery-2.2.3.min.js
vendored
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "RetroConsole",
|
||||
"version": "0.0.1",
|
||||
"author": "Steven Hugg",
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "^13.0.0"
|
||||
}
|
||||
}
|
247
presets/examples/adventure.a
Normal file
@ -0,0 +1,247 @@
|
||||
processor 6502
|
||||
include "vcs.h"
|
||||
include "macro.h"
|
||||
|
||||
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
|
||||
; to generate a 8x16 sprite and one missile.
|
||||
;
|
||||
; We have two tables for the sprite, a bitmap table and
|
||||
; a color table. We'll lookup from both of these tables on
|
||||
; each scanline.
|
||||
;
|
||||
; Because VCS programming is all about thrift, we'll
|
||||
; reuse the machine code for our program as the backdrop
|
||||
; for the playfield, just to show we can fit it all on
|
||||
; a scanline.
|
||||
;
|
||||
; 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
|
||||
yrock equ $83 ; rock y pos
|
||||
animofs equ $84 ; sprite data offset, used for animation
|
||||
|
||||
; Initialize and set initial offsets of objects.
|
||||
start CLEAN_START
|
||||
lda #5
|
||||
sta yplyr
|
||||
lda #70
|
||||
ldx #0
|
||||
jsr SetHorizPos ; set player 0 horiz. pos
|
||||
sta WSYNC
|
||||
sta HMOVE
|
||||
|
||||
; Next frame loop
|
||||
nextframe
|
||||
VERTICAL_SYNC
|
||||
|
||||
; in case the rock is on screen
|
||||
lda ColorFrame0 ; load 1st entry of color data
|
||||
sta COLUP0 ; set sprite 0 color
|
||||
|
||||
; 37 lines of VBLANK
|
||||
ldx #37
|
||||
lvblank sta WSYNC
|
||||
dex
|
||||
bne lvblank
|
||||
|
||||
; set some colors
|
||||
lda #$80
|
||||
sta COLUBK ; set the background color
|
||||
lda #1
|
||||
sta CTRLPF ; playfield reflection
|
||||
|
||||
; Draw 192 scanlines with our sprite/missile kernel
|
||||
ldx #192
|
||||
lvscan
|
||||
; Draw sprite?
|
||||
txa
|
||||
sec ; make sure carry is set (meaning no borrow for subtraction)
|
||||
sbc yplyr ; get offset into sprite for this line
|
||||
cmp #SpriteHeight ; sprite is 16 pixels high + padding on either side
|
||||
bcc insprite
|
||||
lda #SpriteHeight-1 ; draw the padding
|
||||
insprite
|
||||
tay
|
||||
lda ColorFrame0,y ; load color data
|
||||
pha ; push color data onto stack
|
||||
clc ; clear carry flag
|
||||
adc animofs ; add animation offset (not for color though)
|
||||
lda Frame0,y ; load bitmap data
|
||||
sta WSYNC ; wait for next scanline (as late as possible!)
|
||||
sta GRP0 ; set sprite 0 pixels
|
||||
pla ; pull bitmap data from stack
|
||||
sta COLUP0 ; set sprite 0 color
|
||||
lda start,x ; store some random garbage into the playfield
|
||||
sta PF0
|
||||
sta PF1
|
||||
sta PF2
|
||||
; Draw rock? Player 0 and missile 0 share a color register,
|
||||
; so they will have the same colors on the same scanline
|
||||
lda #%00000000
|
||||
cpx yrock
|
||||
bne norock
|
||||
lda #%00000010 ; for ENAM0 the 2nd bit is enable
|
||||
norock
|
||||
sta ENAM0 ; enable missile 0
|
||||
dex
|
||||
bne lvscan ; repeat next scanline until finished
|
||||
; End of scanline loop
|
||||
|
||||
; Clear all colors to black before overscan
|
||||
stx COLUBK
|
||||
stx COLUP0
|
||||
stx COLUP1
|
||||
stx COLUPF
|
||||
; 30 lines of overscan
|
||||
ldx #29
|
||||
lvover sta WSYNC
|
||||
dex
|
||||
bne lvover
|
||||
|
||||
; Joystick movement
|
||||
; For up and down, we INC or DEC the Y Position
|
||||
lda #%00010000 ;Up?
|
||||
bit SWCHA
|
||||
bne SkipMoveUp
|
||||
inc yplyr
|
||||
SkipMoveUp
|
||||
lda #%00100000 ;Down?
|
||||
bit SWCHA
|
||||
bne SkipMoveDown
|
||||
dec yplyr
|
||||
SkipMoveDown
|
||||
; Note that the horizontal position is not contained in RAM,
|
||||
; but inaccessibly inside the TIA's registers! Some games can
|
||||
; get away with this if they use the collision registers.
|
||||
ldx #0 ; assume speed is 0 if no movement
|
||||
lda #%01000000 ;Left?
|
||||
bit SWCHA
|
||||
bne SkipMoveLeft
|
||||
ldx #$10 ;a 1 in the left nibble means go left
|
||||
SkipMoveLeft
|
||||
lda #%10000000 ;Right?
|
||||
bit SWCHA
|
||||
bne SkipMoveRight
|
||||
ldx #$F0 ;a -1 in the left nibble means go right...
|
||||
SkipMoveRight
|
||||
stx HMP0 ;set the move for plyr 0
|
||||
sta WSYNC
|
||||
sta HMOVE
|
||||
; Throw a rock when fire button pressed
|
||||
lda #0
|
||||
sta animofs
|
||||
ldy #%00000000 ; use later to enable/disable missile lock on player
|
||||
lda INPT4 ;read button input
|
||||
bmi ButtonNotPressed ;skip if button not pressed
|
||||
lda yplyr
|
||||
sta yrock ; set rock vert pos to player's vert
|
||||
lda #SpriteHeight
|
||||
sta animofs ; while button pressed, use alternate player bitmap
|
||||
ldy #%00000010 ; for RESMP0 the 2nd bit is the enable bit
|
||||
ButtonNotPressed
|
||||
sty RESMP0 ; reset missile 0 to player 0's horiz position
|
||||
inc yrock ; rock moves no matter what (actually a boomerang)
|
||||
|
||||
; Goto next frame
|
||||
jmp nextframe
|
||||
|
||||
; SetHorizPos - Sets the horizontal position of an object.
|
||||
; The X register contains the index of the desired object:
|
||||
; X=0: player 0
|
||||
; X=1: player 1
|
||||
; X=2: missile 0
|
||||
; X=3: missile 1
|
||||
; X=4: ball
|
||||
; This routine does a WSYNC and HMOVE before executing,
|
||||
; so whatever you do here will not take effect until you
|
||||
; call the routine again or do your own WSYNC and HMOVE.
|
||||
SetHorizPos
|
||||
sta WSYNC ; start a new line
|
||||
sta HMOVE ; apply the previous fine position(s)
|
||||
sta HMCLR ; reset the old horizontal position(s)
|
||||
sec ; set carry flag
|
||||
DivideLoop
|
||||
sbc #15 ; subtract 15
|
||||
bcs DivideLoop ; branch until negative
|
||||
eor #7 ; calculate fine offset
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta RESP0,x ; fix coarse position
|
||||
sta HMP0,x ; set fine offset
|
||||
rts ; return to caller
|
||||
|
||||
; Height of our sprite in lines
|
||||
SpriteHeight equ 18
|
||||
|
||||
; Bitmap data "standing" position
|
||||
Frame0
|
||||
.byte #0
|
||||
.byte #%01101100;$F6
|
||||
.byte #%00101000;$86
|
||||
.byte #%00101000;$86
|
||||
.byte #%00111000;$86
|
||||
.byte #%10111010;$C2
|
||||
.byte #%10111010;$C2
|
||||
.byte #%01111100;$C2
|
||||
.byte #%00111000;$C2
|
||||
.byte #%00111000;$16
|
||||
.byte #%01000100;$16
|
||||
.byte #%01111100;$16
|
||||
.byte #%01111100;$18
|
||||
.byte #%01010100;$18
|
||||
.byte #%01111100;$18
|
||||
.byte #%11111110;$F2
|
||||
.byte #%00111000;$F4
|
||||
|
||||
; Bitmap data "throwing" position
|
||||
Frame1
|
||||
.byte #0
|
||||
.byte #%01101100;$F6
|
||||
.byte #%01000100;$86
|
||||
.byte #%00101000;$86
|
||||
.byte #%00111000;$86
|
||||
.byte #%10111010;$C2
|
||||
.byte #%10111101;$C2
|
||||
.byte #%01111101;$C2
|
||||
.byte #%00111001;$C2
|
||||
.byte #%00111000;$16
|
||||
.byte #%01101100;$16
|
||||
.byte #%01111100;$16
|
||||
.byte #%01111100;$18
|
||||
.byte #%01010100;$18
|
||||
.byte #%01111100;$18
|
||||
.byte #%11111110;$F2
|
||||
.byte #%00111000;$F4
|
||||
|
||||
; Color data for each line of sprite
|
||||
ColorFrame0
|
||||
.byte #$FF ; rock color if not sharing line with player sprite
|
||||
.byte #$F6;
|
||||
.byte #$86;
|
||||
.byte #$86;
|
||||
.byte #$86;
|
||||
.byte #$C2;
|
||||
.byte #$C2;
|
||||
.byte #$C2;
|
||||
.byte #$C2;
|
||||
.byte #$16;
|
||||
.byte #$16;
|
||||
.byte #$16;
|
||||
.byte #$18;
|
||||
.byte #$18;
|
||||
.byte #$18;
|
||||
.byte #$F2;
|
||||
.byte #$F4;
|
||||
|
||||
; Epilogue
|
||||
org $fffc
|
||||
.word start
|
||||
.word start
|
98
presets/examples/bankswitching.a
Normal file
@ -0,0 +1,98 @@
|
||||
processor 6502
|
||||
include "vcs.h"
|
||||
include "macro.h"
|
||||
include "xmacro.h"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
seg.u Variables
|
||||
org $80
|
||||
|
||||
Temp .byte
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Macro that implements Bank Switching trampoline
|
||||
; X = bank number
|
||||
; A = hi byte of destination PC
|
||||
; Y = lo byte of destination PC
|
||||
MAC BANK_SWITCH_TRAMPOLINE
|
||||
pha ; push hi byte
|
||||
tya ; Y -> A
|
||||
pha ; push lo byte
|
||||
lda $1FF8,x ; do the bank switch
|
||||
rts ; return to target
|
||||
ENDM
|
||||
|
||||
; Macro that performs bank switch
|
||||
MAC BANK_SWITCH
|
||||
.Bank SET {1}
|
||||
.Addr SET {2}
|
||||
lda #>(.Addr-1)
|
||||
ldy #<(.Addr-1)
|
||||
ldx #.Bank
|
||||
jmp BankSwitch
|
||||
ENDM
|
||||
|
||||
seg Code
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; BANK 0
|
||||
|
||||
org $1000
|
||||
rorg $F000
|
||||
;----The following code is the same on both banks----
|
||||
Start
|
||||
; Ensure that bank 0 is selected
|
||||
lda #>(Reset_0-1)
|
||||
ldy #<(Reset_0-1)
|
||||
ldx #0
|
||||
BankSwitch
|
||||
BANK_SWITCH_TRAMPOLINE
|
||||
;----End of bank-identical code----
|
||||
Reset_0
|
||||
CLEAN_START
|
||||
lda #$30
|
||||
sta COLUBK ; make the screen red
|
||||
bit INPT4 ; test button
|
||||
bmi Reset_0 ; button not pressed, repeat
|
||||
; Switch to Bank 2 routine
|
||||
lda #>(Main_1-1)
|
||||
ldy #<(Main_1-1)
|
||||
ldx #1
|
||||
jmp BankSwitch
|
||||
|
||||
; Bank 0 epilogue
|
||||
org $1FFA
|
||||
rorg $FFFA
|
||||
.word Start ; NMI
|
||||
.word Start ; RESET
|
||||
.word Start ; BRK
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; BANK 1
|
||||
|
||||
org $2000
|
||||
rorg $F000
|
||||
;----The following code is the same on both banks----
|
||||
Start
|
||||
; Ensure that bank 0 is selected
|
||||
lda #>(Reset_0-1)
|
||||
ldy #<(Reset_0-1)
|
||||
ldx #0
|
||||
BankSwitch
|
||||
BANK_SWITCH_TRAMPOLINE
|
||||
;----End of bank-identical code----
|
||||
Main_1
|
||||
inc Temp
|
||||
lda Temp
|
||||
sta COLUBK ; make rainbows
|
||||
bit INPT4 ; test button
|
||||
bpl Main_1 ; button is pressed, repeat
|
||||
BANK_SWITCH 0,Reset_0
|
||||
|
||||
; Bank 1 epilogue
|
||||
org $2FFA
|
||||
rorg $FFFA
|
||||
.word Start ; NMI
|
||||
.word Start ; RESET
|
||||
.word Start ; BRK
|
125
presets/examples/bigsprite.a
Normal file
@ -0,0 +1,125 @@
|
||||
processor 6502
|
||||
include "vcs.h"
|
||||
include "macro.h"
|
||||
include "xmacro.h"
|
||||
|
||||
seg.u Variables
|
||||
org $80
|
||||
|
||||
Temp byte
|
||||
LoopCount byte
|
||||
|
||||
THREE_COPIES equ %011
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
seg Code
|
||||
org $f000
|
||||
|
||||
Start
|
||||
CLEAN_START
|
||||
|
||||
NextFrame
|
||||
VERTICAL_SYNC
|
||||
|
||||
TIMER_SETUP 37
|
||||
lda #64
|
||||
sta LoopCount ; scanline counter
|
||||
lda #$ff
|
||||
sta COLUBK ; background color
|
||||
lda #$22
|
||||
sta COLUP0 ; show how players alternate
|
||||
lda #$12
|
||||
sta COLUP1 ; by having different colors
|
||||
lda #THREE_COPIES
|
||||
sta NUSIZ0
|
||||
sta NUSIZ1 ; both players have 3 copies
|
||||
sta WSYNC
|
||||
SLEEP 20
|
||||
sta RESP0 ; position 1st player
|
||||
sta RESP1 ; ...and 2nd player
|
||||
lda #$10
|
||||
sta HMP1 ; 1 pixel to the left
|
||||
sta WSYNC
|
||||
sta HMOVE ; apply HMOVE
|
||||
sta HMCLR
|
||||
lda #1
|
||||
sta VDELP0 ; we need the VDEL registers
|
||||
sta VDELP1 ; so we can do our 4-store trick
|
||||
TIMER_WAIT
|
||||
|
||||
TIMER_SETUP 192
|
||||
|
||||
SLEEP 40 ; start near end of scanline
|
||||
BigLoop
|
||||
ldy LoopCount ; counts backwards
|
||||
lda Bitmap0,y ; load B0 (1st sprite byte)
|
||||
sta GRP0 ; B0 -> [GRP0]
|
||||
lda Bitmap1,y ; load B1 -> A
|
||||
sta GRP1 ; B1 -> [GRP1], B0 -> GRP0
|
||||
sta WSYNC ; sync to next scanline
|
||||
lda Bitmap2,y ; load B2 -> A
|
||||
sta GRP0 ; B2 -> [GRP0], B1 -> GRP1
|
||||
lda Bitmap5,y ; load B5 -> A
|
||||
sta Temp ; B5 -> temp
|
||||
ldx Bitmap4,y ; load B4 -> X
|
||||
lda Bitmap3,y ; load B3 -> A
|
||||
ldy Temp ; load B5 -> Y
|
||||
sta GRP1 ; B3 -> [GRP1]; B2 -> GRP0
|
||||
stx GRP0 ; B4 -> [GRP0]; B3 -> GRP1
|
||||
sty GRP1 ; B5 -> [GRP1]; B4 -> GRP0
|
||||
sta GRP0 ; ?? -> [GRP0]; B5 -> GRP1
|
||||
dec LoopCount ; go to next line
|
||||
bpl BigLoop ; repeat until < 0
|
||||
|
||||
TIMER_WAIT
|
||||
|
||||
TIMER_SETUP 30
|
||||
TIMER_WAIT
|
||||
jmp NextFrame
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Bitmap data, six columns
|
||||
|
||||
align $100 ; ensure we start on a page boundary
|
||||
Bitmap0
|
||||
hex 00
|
||||
hex 00000000000000000000000000000000
|
||||
hex 00000000000000000000000000000001
|
||||
hex 01010205040402040404040404040404
|
||||
hex 040404060203000107df7f1f0f000000
|
||||
Bitmap1
|
||||
hex 00
|
||||
hex 0000073f1f0303000000000000010704
|
||||
hex 0808101010101412120a0a1e75c38000
|
||||
hex 0000076260e0e0e0c0c0e0e0c0c00000
|
||||
hex 00000000408170feffffffffc7030000
|
||||
Bitmap2
|
||||
hex 00
|
||||
hex 007ffffcf0e0c0404040404020bb7608
|
||||
hex 000402020809094f494949fa07010000
|
||||
hex 00000000006070f0f0f0c0e0e0e0e0e0
|
||||
hex 400000000010a06010e0e0f1ffff7f00
|
||||
Bitmap3
|
||||
hex 00
|
||||
hex 3effff07010000000000302159878184
|
||||
hex 848efeffffff9f0f0e9c7c0402c12010
|
||||
hex 08040207050000000002020104070f0f
|
||||
hex 0f070703030707070f1f7efcf8f0c000
|
||||
Bitmap4
|
||||
hex 00
|
||||
hex 00f0f0fffff0404040404080641e02c3
|
||||
hex 4242c3e2e2f4fcfc787838787cfa3131
|
||||
hex 6102021cf840c04042a022c14080c4c3
|
||||
hex c0c0c0c0808090900010180c04243800
|
||||
Bitmap5
|
||||
hex 00
|
||||
hex 000000fcfefc1c0c040402020202040c
|
||||
hex f800e01804040402020101010111e192
|
||||
hex dc700000000000000000000080808000
|
||||
hex 00000000000000000000000000000000
|
||||
|
||||
; Epilogue
|
||||
org $fffc
|
||||
.word Start
|
||||
.word Start
|
154
presets/examples/bitmap.a
Normal file
@ -0,0 +1,154 @@
|
||||
processor 6502
|
||||
include "vcs.h"
|
||||
include "macro.h"
|
||||
include "xmacro.h"
|
||||
|
||||
seg.u Variables
|
||||
org $80
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
seg Code
|
||||
org $f000
|
||||
|
||||
Start
|
||||
CLEAN_START
|
||||
|
||||
NextFrame
|
||||
VERTICAL_SYNC
|
||||
|
||||
TIMER_SETUP 37
|
||||
; Set playfield foreground and background
|
||||
lda #$FF
|
||||
sta COLUBK
|
||||
lda #$F0
|
||||
sta COLUPF
|
||||
TIMER_WAIT
|
||||
|
||||
ldy #192
|
||||
ScanLoop
|
||||
; WSYNC and store playfield registers
|
||||
sta WSYNC
|
||||
lda PFBitmap0,y
|
||||
sta PF0 ; store first playfield byte
|
||||
lda PFBitmap1,y
|
||||
sta PF1 ; store 2nd byte
|
||||
lda PFBitmap2,y
|
||||
sta PF2 ; store 3rd byte
|
||||
; Here's the asymmetric part -- by this time the TIA clock
|
||||
; is far enough that we can rewrite the same PF registers
|
||||
; and display new data on the right side of the screen
|
||||
nop
|
||||
nop
|
||||
nop ; pause to let playfield finish drawing
|
||||
lda PFBitmap3,y
|
||||
sta PF0 ; store 4th byte
|
||||
lda PFBitmap4,y
|
||||
sta PF1 ; store 5th byte
|
||||
lda PFBitmap5,y
|
||||
sta PF2 ; store 6th byte
|
||||
dey
|
||||
bne ScanLoop ; repeat until all scanlines drawn
|
||||
; Reset playfield
|
||||
SLEEP 14 ; give time to finish drawing scanline
|
||||
lda #0
|
||||
sta PF0
|
||||
sta PF1
|
||||