1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-12-13 00:29:25 +00:00

initial commit

This commit is contained in:
Steven Hugg 2016-12-15 20:21:51 -05:00
parent 0cc1de0cb2
commit e42ff3a56a
52 changed files with 36415 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*~
node_modules

9
.gitmodules vendored Normal file
View 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
View 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; }

26681
dasm.js Normal file

File diff suppressed because one or more lines are too long

23
doc/notes.txt Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

BIN
images/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

BIN
images/resetandrun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

BIN
images/runtoline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

BIN
images/share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

BIN
images/singlestep.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

BIN
images/timing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

176
include/macro.h Normal file
View 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
View 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
View 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="#">&lt;&lt;</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&region=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>

1
javatari Symbolic link
View File

@ -0,0 +1 @@
javatari.js/release/javatari

4
jquery/jquery-2.2.3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

10
package.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "RetroConsole",
"version": "0.0.1",
"author": "Steven Hugg",
"dependencies": {
},
"devDependencies": {
"browserify": "^13.0.0"
}
}

View 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

View 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

View 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
View 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