fixed VCS macro/loadROM; download all files menu option; error on build exception fix; PAL preset; 262 for VCS presets

This commit is contained in:
Steven Hugg 2018-08-26 09:19:09 -04:00
parent 113fdd4099
commit 7cf56b55a8
26 changed files with 191 additions and 67 deletions

View File

@ -54,7 +54,8 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" id="item_download_file">Download Source File</a></li>
<li><a class="dropdown-item" href="#" id="item_download_rom">Download ROM Image</a></li>
<li><a class="dropdown-item" href="#" id="item_download_zip">Download ZIP Archive</a></li>
<li><a class="dropdown-item" href="#" id="item_download_zip">Download Project as ZIP</a></li>
<li><a class="dropdown-item" href="#" id="item_download_allzip">Download All Changes as ZIP</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu">
@ -274,7 +275,6 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<script src="codemirror/addon/dialog/dialog.js"></script>
<script src="codemirror/addon/selection/active-line.js"></script>
<link rel="stylesheet" href="codemirror/addon/dialog/dialog.css">
<script src="javatari.js/release/javatari/javatari.js"></script>
<!--
<script src="javatari.js/src/main/Javatari.js"></script>

View File

@ -75,7 +75,7 @@ BigLoop
TIMER_WAIT
TIMER_SETUP 30
TIMER_SETUP 29
TIMER_WAIT
jmp NextFrame

View File

@ -57,7 +57,7 @@ ScanLoop
sta PF1
sta PF2 ; clear playfield
TIMER_SETUP 29
TIMER_SETUP 28
TIMER_WAIT
jmp NextFrame

View File

@ -1,4 +1,4 @@
j
processor 6502
include "vcs.h"
include "macro.h"
@ -227,7 +227,7 @@ ScanLoop3b
sta Temp ; 'brickheight' scan lines for each row
cpy #NBrickRows ; done drawing all brick rows?
bcc ScanSkipSync ; no -- but don't have time to draw ball!
jmp DoneBrickDraw ; exit outer loop
bcs DoneBrickDraw ; exit outer loop
ScanLoop3a
; These instructions are skipped on lines after the brick row changes.
; We need the extra cycles.
@ -260,7 +260,7 @@ ScanSkipSync
bne ScanLoop3a ; branch always taken
; Clear playfield from bricks loop
DoneBrickDraw
SLEEP 6
sta WSYNC
lda #0
sta PF0
sta PF1
@ -310,7 +310,7 @@ ScanLoop5
lda #0
sta GRP0
inx
cpx #192
cpx #190
bne ScanLoop5
; Disable ball
@ -319,11 +319,11 @@ ScanLoop5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 30 lines of overscan needed, but we have lots of logic to do.
; 29 lines of overscan needed, but we have lots of logic to do.
; So we're going to use the PIA timer to let us know when
; almost 30 lines of overscan have passed.
; almost 29 lines of overscan have passed.
; This handy macro does a WSYNC and then sets up the timer.
TIMER_SETUP 30
TIMER_SETUP 29
; Check for collisions
lda #%01000000
@ -507,7 +507,7 @@ SkipMoveRight
NoAudio
; Wait until our timer expires and then WSYNC, so then we'll have
; passed 30 scanlines. This handy macro does this.
; passed 29 scanlines. This handy macro does this.
TIMER_WAIT
; Goto next frame
jmp NextFrame

View File

@ -199,11 +199,11 @@ ScanLoop5
lda #0
sta ENABL
; 30 lines of overscan needed, but we have lots of logic to do.
; 29 lines of overscan needed, but we have lots of logic to do.
; So we're going to use the PIA timer to let us know when
; almost 30 lines of overscan have passed.
; almost 29 lines of overscan have passed.
; This handy macro does a WSYNC and then sets up the timer.
TIMER_SETUP 30
TIMER_SETUP 29
; Check for collisions
lda #%01000000

View File

@ -74,7 +74,6 @@ NextFrame
sta HMOVE ; gotta apply HMOVE
; Wait for end of VBLANK
TIMER_WAIT
sta WSYNC
lda #0
sta VBLANK
@ -153,7 +152,7 @@ NoMoreSegs
TIMER_WAIT
; Set up overscan timer
TIMER_SETUP 30
TIMER_SETUP 29
lda #2
sta VBLANK
jsr MoveJoystick

View File

@ -42,7 +42,9 @@ SpriteHeight equ 16
Start
CLEAN_START
Data0
; set up pointers to playfield and sprites
lda #<Data0
sta PFPtr
lda #>Data0
@ -63,6 +65,7 @@ Data0
sta ColorPtr1
lda #>ColorFrame0
sta ColorPtr1+1
; set up initial positions
lda #242
sta YPos0
lda #200
@ -103,7 +106,6 @@ NextFrame
sta HMOVE ; gotta apply HMOVE
; Wait for end of VBLANK
TIMER_WAIT
sta WSYNC
lda #0
sta VBLANK
SLEEP 31 ; so timing analysis works out
@ -144,7 +146,7 @@ KernelLoop
NoMoreLines
; Set up overscan timer
TIMER_SETUP 30
TIMER_SETUP 27
lda #2
sta VBLANK
jsr MoveJoystick

View File

@ -51,20 +51,20 @@ BitmapY equ $f0 ; next line of bitmap
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAC PULSE
TIMER_SETUP 35
TIMER_SETUP 33
jsr DutyCycle ; cycle notes
jsr Pulse ; decrement duration timer
lda Chan0note
sta COLUBK
lda Chan1note
sta COLUPF
jsr DrawBitmap ; draw ~34 lines of bitmap
jsr DrawBitmap ; draw ~33 lines of bitmap
ENDM
MAC DUTYCYCLE
TIMER_SETUP 34
TIMER_SETUP 32
jsr DutyCycle ; cycle notes
jsr DrawBitmap ; draw ~33 lines of bitmap
jsr DrawBitmap ; draw ~32 lines of bitmap
ENDM
Start

View File

@ -43,11 +43,8 @@ NextFrame
jsr SetHorizPos
sta WSYNC
sta HMOVE
TIMER_WAIT
TIMER_SETUP 192
lda #$54
sta COLUP0
ldy #0
@ -87,7 +84,7 @@ NoLine
jmp NextScan
DoneLine
TIMER_SETUP 30
TIMER_SETUP 29
; Change slope of line
lda Slope

View File

@ -48,8 +48,8 @@ start CLEAN_START
nextframe
VERTICAL_SYNC
; 37 lines of VBLANK
ldx #37
; 36 lines of VBLANK
ldx #36
lvblank sta WSYNC
dex
bne lvblank

View File

@ -77,6 +77,15 @@ MinYDist equ 7 ; min. Y distance to consider sprite
.Ok
ENDM
; Set the timer value to $FF.
; Use this at the beginning of a region to start
; using timer table routines.
MAC TIMER_TABLE_SETUP
lda #$FF
sta WSYNC
sta TIM64T
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
seg Code
@ -115,7 +124,7 @@ InitLoop2
NextFrame
; VSYNC and VBLANK periods
VERTICAL_SYNC
TIMER_SETUP 24
TIMER_SETUP 27
; Do joystick movement
jsr MoveJoystick
; Do one iteration of bubble sort on sprite indices
@ -135,9 +144,9 @@ SortLoop
; end of VBLANK
; Scanline loop
TIMER_SETUP 216 ; timer <- #$ff
lda #$90
sta COLUBK
TIMER_TABLE_SETUP
NextFindSprite
; Try to schedule sprites to both players
jsr FindAnotherSprite
@ -163,8 +172,8 @@ NoMoreScanlines
stx COLUP0
stx COLUP1
stx COLUPF
; 30-2 lines of overscan
TIMER_SETUP 28
; 29 lines of overscan
TIMER_SETUP 29
TIMER_WAIT
; Go to next frame
jmp NextFrame
@ -381,7 +390,7 @@ MoveJoystick subroutine
lda #%00010000 ;Up?
bit SWCHA
bne .SkipMoveUp
cpx #8
cpx #10
bcc .SkipMoveUp
dex
.SkipMoveUp
@ -420,9 +429,7 @@ MoveJoystick subroutine
; X=2: missile 0
; X=3: missile 1
; X=4: ball
; NOTE: This version of the routine does a NEWLINE after executing
; because when the beam is at the far right side of the screen
; there is little time to do so before wrapping to the next line.
; NOTE: This version of the routine does a NEWLINE before executing.
; It does NOT do a HMOVE and HCLR.
SetHorizPos subroutine
sta WSYNC ; start a new line

View File

@ -84,7 +84,7 @@ NextFrame
TIMER_WAIT
TIMER_SETUP 192
TIMER_WAIT
TIMER_SETUP 30
TIMER_SETUP 29
TIMER_WAIT
jmp NextFrame

View File

@ -0,0 +1,78 @@
processor 6502
include "vcs.h"
include "macro.h"
include "xmacro.h"
org $f000
; To output a PAL signal, you need the following:
;
; - 3 scanlines of VSYNC
; - 45 blank lines
; - 228 visible scanlines
; - 36 blank lines
;
; Total = 312 lines (vs 262 for NTSC)
; PAL runs at 50 Hz (vs 60 Hz for NTSC)
; so your game will run more slowly.
; Since you have extra cycles to play with, you could just
; call your position update routine twice every five frames.
; Note also that PAL has different colors than NTSC.
; (See http://www.randomterrain.com/atari-2600-memories-tia-color-charts.html)
; The TIMER_SETUP macro only goes up to 215 lines,
; so for the PAL visible frame you would need to use
; multiple sections (say 215 + 13 = 228) or count manually
; like we do in this example.
; Many VCS games use conditional defines
; (IFCONST and IFNCONST in DASM)
; to switch between NTSC and PAL constants.
; background color
BGColor equ $81
; Start of program, init registers and clear memory
Start CLEAN_START
NextFrame
; 01 + 3 lines of VSYNC
VERTICAL_SYNC
; Now we need 44 lines of VBLANK...
TIMER_SETUP 44
TIMER_WAIT
; Re-enable output (disable VBLANK)
lda #0
sta VBLANK
; 228 PAL scanlines are visible
; We'll draw some rainbows
ldx #228
lda BGColor ; load the background color out of RAM
ScanLoop
adc #1 ; add 1 to the current background color in A
sta COLUBK ; set the background color
sta WSYNC ; WSYNC doesn't care what value is stored
dex
bne ScanLoop
; 36 lines of overscan to complete the frame
TIMER_SETUP 36
; Enable VBLANK again
lda #2
sta VBLANK
TIMER_WAIT
; The next frame will start with current color value - 1
; to get a downwards scrolling effect
dec BGColor
; Go back and do another frame
jmp NextFrame
; 6502 vectors
org $fffc
.word Start
.word Start

View File

@ -15,11 +15,11 @@ Counter equ $81
Start CLEAN_START
NextFrame
; This macro efficiently gives us 3 lines of VSYNC
; This macro efficiently gives us 1 + 3 lines of VSYNC
VERTICAL_SYNC
; 37 lines of VBLANK
ldx #37
; 36 lines of VBLANK
ldx #36
LVBlank sta WSYNC
dex
bne LVBlank

View File

@ -79,7 +79,7 @@ NextFrame
; Set up VBLANK timer
; We'll do four fewer lines than usual, so we can
; load the playfield registers in the first four lines.
TIMER_SETUP 33
TIMER_SETUP 37-4
lda #$68
sta COLUP0 ; player color
lda #1
@ -102,7 +102,6 @@ NextFrame
sta CXCLR ; clear collisions
; Wait for end of VBLANK
TIMER_WAIT
sta WSYNC
KernelLoop
; Phase 0: Fetch PF0 byte
@ -133,7 +132,7 @@ NoMoreLines
; Set up overscan timer
; We'll take back those four lines we skipped earlier.
TIMER_SETUP 34
TIMER_SETUP 30+4
lda #0
sta PF0
sta PF1

View File

@ -80,7 +80,7 @@ NextFrame
sta ENABL
sta ENAM1 ; turn off missile and ball
; Overscan
TIMER_SETUP 30
TIMER_SETUP 29
TIMER_WAIT
lda #0
sta COLUBK ; clear ground color

View File

@ -1,4 +1,3 @@
processor 6502
include "vcs.h"
include "macro.h"
@ -74,9 +73,9 @@ NextFrame
lda #10 ; initial lookahead
sta TrackLookahead
; VSYNC+36+198+24 = 4+258 = 262 lines
; VSYNC+37+198+23 = 4+258 = 262 lines
TIMER_SETUP 36
TIMER_SETUP 37
; Initialize array with X road positions
jsr PreprocessCurve
@ -92,7 +91,7 @@ NextFrame
TIMER_WAIT
TIMER_SETUP 24
TIMER_SETUP 23
; Advance position on track
; TrackFrac += Speed
lda TrackFrac

View File

@ -64,7 +64,7 @@ NextFrame
TIMER_WAIT
TIMER_SETUP 30
TIMER_SETUP 29
lda #$01
ldx #$00
ldy #$00

View File

@ -74,7 +74,7 @@ ScanLoop1a
sta CTRLPF
TIMER_WAIT
TIMER_SETUP 30
TIMER_SETUP 29
TIMER_WAIT
jmp NextFrame

View File

@ -20,11 +20,11 @@ Counter equ $81
Start CLEAN_START
NextFrame
; This macro efficiently gives us 3 lines of VSYNC
; This macro efficiently gives us 1 + 3 lines of VSYNC
VERTICAL_SYNC
; 37 lines of VBLANK
ldx #37
; 36 lines of VBLANK
ldx #36
LVBlank sta WSYNC
dex
bne LVBlank

View File

@ -20,8 +20,8 @@ start CLEAN_START
nextframe
VERTICAL_SYNC
; 37 lines of VBLANK
ldx #35
; 34 lines of VBLANK
ldx #34
lvblank sta WSYNC
dex
bne lvblank
@ -36,7 +36,7 @@ lvblank sta WSYNC
; The easy way on the 6502 is to subtract in a loop.
; Note that this also conveniently adds 5 CPU cycles
; (15 TIA clocks) per iteration.
sta WSYNC ; 36th line
sta WSYNC ; 35th line
sta HMCLR ; reset the old horizontal position
DivideLoop
sbc #15 ; subtract 15
@ -56,7 +56,7 @@ DivideLoop
; previous instructions, position 0 won't be exactly on the left side.
sta RESP0
; Finally we'll do a WSYNC followed by HMOVE to apply the fine offset.
sta WSYNC ; 37th line
sta WSYNC ; 36th line
sta HMOVE ; apply offset
; We'll see this method again, and it can be made into a subroutine

View File

@ -76,7 +76,7 @@ NextFrame
TIMER_WAIT
TIMER_SETUP 30
TIMER_SETUP 29
TIMER_WAIT
jmp NextFrame

View File

@ -7,18 +7,26 @@
MAC TIMER_SETUP
.lines SET {1}
lda #(((.lines-1)*76-14)/64)
sta WSYNC
.cycles SET ((.lines * 76) - 13)
; special case for when we have two timer events in a line
; and our 2nd event straddles the WSYNC boundary
if (.cycles % 64) < 12
lda #(.cycles / 64) - 1
sta WSYNC
else
lda #(.cycles / 64)
sta WSYNC
endif
sta TIM64T
ENDM
;-------------------------------------------------------
; Use with TIMER_SETUP to wait for timer to complete.
; You may want to do a WSYNC afterwards, since the timer
; is not accurate to the beginning/end of a scanline.
; Performs a WSYNC afterwards.
MAC TIMER_WAIT
.waittimer
lda INTIM
bne .waittimer
sta WSYNC
ENDM

View File

@ -37,6 +37,7 @@ const VCS_PRESETS = [
{id:'examples/bankswitching', chapter:35, name:'Bankswitching'},
{id:'examples/wavetable', chapter:36, name:'Wavetable Sound'},
{id:'examples/fracpitch', name:'Fractional Pitch'},
{id:'examples/pal', name:'PAL Video Output'},
// {id:'examples/music2', name:'Pitch-Accurate Music'},
// {id:'examples/fullgame', name:'Thru Hike: The Game', title:'Thru Hike'},
];
@ -66,8 +67,12 @@ class VCSPlatform {
}
loadROM(title, data) {
if (data.length == 0 || ((data.length & 0x3ff) != 0))
throw Error("Invalid ROM length: " + data.length);
// TODO: parse Log messages from Javatari?
var wasrunning = this.isRunning();
Javatari.loadROM(title, data);
if (!this.isRunning()) throw Error("Could not load ROM");
if (!wasrunning) this.pause();
}

View File

@ -352,8 +352,14 @@ function _shareEmbedLink(e) {
return true;
}
function fixFilename(fn : string) : string {
if (platform_id.startsWith('vcs') && fn.indexOf('.') <= 0)
fn += ".a"; // legacy stuff
return fn;
}
function _revertFile(e) {
var fn = getCurrentEditorFilename();
var fn = fixFilename(projectWindows.getActiveID());
$.get( "presets/"+platform_id+"/"+fn, function(text) {
if (confirm("Reset '" + fn + "' to default?")) {
projectWindows.getActive().setText(text);
@ -394,6 +400,28 @@ function _downloadProjectZipFile(e) {
});
}
function _downloadAllFilesZipFile(e) {
loadScript('lib/jszip.min.js', () => {
var zip = new JSZip();
var count = 0;
store.keys( (err, keys : string[]) => {
if (err) throw err;
keys.forEach((path) => {
store.getItem(path, (err, text) => {
if (text) {
zip.file(fixFilename(getFilenameForPath(path)), text);
}
if (++count == keys.length) {
zip.generateAsync({type:"blob"}).then( (content) => {
saveAs(content, platform_id + "-all.zip");
});
}
});
});
});
});
}
function populateExamples(sel) {
// make sure to use callback so it follows other sections
store.length(function(err, len) {
@ -467,8 +495,9 @@ function setCompileOutput(data: WorkerResult) {
} catch (e) {
console.log(e);
toolbar.addClass("has-errors");
projectWindows.setErrors([{line:1,msg:e+""}]); // TODO: doesn't work
projectWindows.setErrors([{line:1,msg:e+""}]); // TODO: doesn't work (use alert?)
current_output = null;
return;
}
}
// update all windows (listings)
@ -816,6 +845,7 @@ function setupDebugControls(){
$("#item_download_rom").click(_downloadROMImage);
$("#item_download_file").click(_downloadSourceFile);
$("#item_download_zip").click(_downloadProjectZipFile);
$("#item_download_allzip").click(_downloadAllFilesZipFile);
$("#item_record_video").click(_recordVideo);
if (platform.setFrameRate && platform.getFrameRate) {
$("#speed_bar").show();

View File

@ -72,10 +72,10 @@ export class ProjectWindows {
this.refreshErrors();
}
refreshErrors(embedlines?:boolean) {
refreshErrors() {
if (this.activewnd && this.activewnd.markErrors) {
if (this.lasterrors && this.lasterrors.length)
this.activewnd.markErrors(this.lasterrors); // TODO?, embedlines);
this.activewnd.markErrors(this.lasterrors);
else
this.activewnd.clearErrors();
}