mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-05-28 23:41:32 +00:00
pixel editor: reindex for vcs playfields, fixed ca65 stuff
This commit is contained in:
parent
64fcbdc9d5
commit
c5ccd4ff48
|
@ -161,6 +161,7 @@ div.mem_info a.selected {
|
||||||
padding-bottom:2px;
|
padding-bottom:2px;
|
||||||
margin:1px;
|
margin:1px;
|
||||||
vertical-align:baseline;
|
vertical-align:baseline;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
.btn_label {
|
.btn_label {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
|
|
|
@ -94,6 +94,7 @@ BigLoop
|
||||||
; Bitmap data, six columns
|
; Bitmap data, six columns
|
||||||
|
|
||||||
align $100 ; ensure we start on a page boundary
|
align $100 ; ensure we start on a page boundary
|
||||||
|
;;{w:8,h:65,count:6,brev:1,flip:1};;
|
||||||
Bitmap0
|
Bitmap0
|
||||||
hex 00
|
hex 00
|
||||||
hex 00000000000000000000000000000000
|
hex 00000000000000000000000000000000
|
||||||
|
@ -130,6 +131,7 @@ Bitmap5
|
||||||
hex f800e01804040402020101010111e192
|
hex f800e01804040402020101010111e192
|
||||||
hex dc700000000000000000000080808000
|
hex dc700000000000000000000080808000
|
||||||
hex 00000000000000000000000000000000
|
hex 00000000000000000000000000000000
|
||||||
|
;;
|
||||||
|
|
||||||
; Epilogue
|
; Epilogue
|
||||||
org $fffc
|
org $fffc
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
.zeropage
|
.zeropage
|
||||||
Temp: .byte 0
|
Temp: .byte 0
|
||||||
|
|
||||||
|
|
||||||
.segment "CODE"
|
.segment "CODE"
|
||||||
|
|
||||||
Reset:
|
Reset:
|
||||||
|
@ -26,7 +25,6 @@ NextFrame:
|
||||||
|
|
||||||
|
|
||||||
.segment "VECTORS"
|
.segment "VECTORS"
|
||||||
.word Reset
|
VecNMI: .word Reset
|
||||||
.word Reset
|
VecReset: .word Reset
|
||||||
.word Reset
|
VecBRK: .word Reset
|
||||||
|
|
||||||
|
|
|
@ -89,8 +89,8 @@ TIM1024T := $0297
|
||||||
; Uses illegal opcode (DASM 2.20.01 onwards).
|
; Uses illegal opcode (DASM 2.20.01 onwards).
|
||||||
|
|
||||||
.macro SLEEP cycles
|
.macro SLEEP cycles
|
||||||
.if cycles < 2
|
.if cycles < 0 || cycles = 1
|
||||||
.error "MACRO ERROR: 'SLEEP': Duration must be > 1"
|
.error "MACRO ERROR: 'SLEEP': Duration must be >= 2"
|
||||||
.endif
|
.endif
|
||||||
.if cycles & 1
|
.if cycles & 1
|
||||||
.ifndef NO_ILLEGAL_OPCODES
|
.ifndef NO_ILLEGAL_OPCODES
|
||||||
|
@ -180,6 +180,26 @@ CLEAR_STACK: dex
|
||||||
bne CLEAR_STACK ; SP=$FF, X = A = Y = 0
|
bne CLEAR_STACK ; SP=$FF, X = A = Y = 0
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
;-------------------------------------------------------
|
||||||
|
; 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
|
||||||
|
.macro SET_POINTER ptr, addr
|
||||||
|
lda #<addr
|
||||||
|
sta ptr
|
||||||
|
lda #>addr
|
||||||
|
sta ptr+1
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
|
||||||
; assume NTSC unless PAL defined
|
; assume NTSC unless PAL defined
|
||||||
.ifndef PAL
|
.ifndef PAL
|
||||||
PAL = 0
|
PAL = 0
|
||||||
|
@ -188,8 +208,10 @@ PAL = 0
|
||||||
; 192 visible scanlines for NTSC, 228 for PAL
|
; 192 visible scanlines for NTSC, 228 for PAL
|
||||||
.if PAL
|
.if PAL
|
||||||
SCANLINES = 228
|
SCANLINES = 228
|
||||||
|
LINESD12 = 19
|
||||||
.else
|
.else
|
||||||
SCANLINES = 192
|
SCANLINES = 192
|
||||||
|
LINESD12 = 16
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
; start of frame -- vsync and set back porch timer
|
; start of frame -- vsync and set back porch timer
|
||||||
|
@ -230,3 +252,17 @@ SCANLINES = 192
|
||||||
.macro FRAME_END
|
.macro FRAME_END
|
||||||
TIMER_WAIT
|
TIMER_WAIT
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
; SLEEPR - sleep macro that uses JSR/RTS for 12 cycle delays
|
||||||
|
; Requires a lone RTS instruction with the label "Return"
|
||||||
|
; (note: may fool 8bitworkshop's Anaylze CPU Timing feature)
|
||||||
|
|
||||||
|
.macro SLEEPR cycles
|
||||||
|
.if cycles >= 14 || cycles = 12
|
||||||
|
jsr Return
|
||||||
|
SLEEPR (cycles-12)
|
||||||
|
.else
|
||||||
|
SLEEP cycles
|
||||||
|
.endif
|
||||||
|
.endmacro
|
||||||
|
|
|
@ -142,6 +142,7 @@ abstract class CodeAnalyzer6502 implements CodeAnalyzer {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x20: // JSR
|
case 0x20: // JSR
|
||||||
|
// TODO: handle bare RTS case
|
||||||
this.traceInstructions(addr, minclocks, maxclocks, addr, constraints);
|
this.traceInstructions(addr, minclocks, maxclocks, addr, constraints);
|
||||||
var result = this.jsrresult[addr];
|
var result = this.jsrresult[addr];
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ export type PixelEditorImageFormat = {
|
||||||
sl?:number
|
sl?:number
|
||||||
pofs?:number
|
pofs?:number
|
||||||
remap?:number[]
|
remap?:number[]
|
||||||
|
reindex?:number[]
|
||||||
brev?:boolean
|
brev?:boolean
|
||||||
flip?:boolean
|
flip?:boolean
|
||||||
destfmt?:PixelEditorImageFormat
|
destfmt?:PixelEditorImageFormat
|
||||||
|
@ -62,6 +63,7 @@ type PixelEditorMessage = {
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
|
|
||||||
// 0xabcd, #$abcd, 5'010101, 0b010101, etc
|
// 0xabcd, #$abcd, 5'010101, 0b010101, etc
|
||||||
var pixel_re = /([0#]?)([x$%]|\d'h)([0-9a-f]+)(?:[;].*)?|(\d'b|0b)([01]+)/gim;
|
var pixel_re = /([0#]?)([x$%]|\d'h)([0-9a-f]+)(?:[;].*)?|(\d'b|0b)([01]+)/gim;
|
||||||
|
|
||||||
|
@ -143,6 +145,13 @@ function remapBits(x:number, arr:number[]) : number {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for VCS playfields
|
||||||
|
// ;;{w:20,h:10,flip:1,reindex:[4,5,6,7,15,14,13,12,11,10,9,8,16,17,18,19]};;
|
||||||
|
function reindexMask(x:number, inds:number[]) : [number, number] {
|
||||||
|
var i = inds[x % inds.length];
|
||||||
|
return [i >> 3, i & 7];
|
||||||
|
}
|
||||||
|
|
||||||
function convertWordsToImages(words:UintArray, fmt:PixelEditorImageFormat) : Uint8Array[] {
|
function convertWordsToImages(words:UintArray, fmt:PixelEditorImageFormat) : Uint8Array[] {
|
||||||
var width = fmt.w;
|
var width = fmt.w;
|
||||||
var height = fmt.h;
|
var height = fmt.h;
|
||||||
|
@ -164,13 +173,14 @@ function convertWordsToImages(words:UintArray, fmt:PixelEditorImageFormat) : Uin
|
||||||
for (var x=0; x<width; x++) {
|
for (var x=0; x<width; x++) {
|
||||||
var color = 0;
|
var color = 0;
|
||||||
var ofs = remapBits(ofs0, fmt.remap);
|
var ofs = remapBits(ofs0, fmt.remap);
|
||||||
|
if (fmt.reindex) { [ofs, shift] = reindexMask(x, fmt.reindex); ofs += ofs0; }
|
||||||
for (var p=0; p<nplanes; p++) {
|
for (var p=0; p<nplanes; p++) {
|
||||||
var byte = words[ofs + p*pofs + skip];
|
var byte = words[ofs + p*pofs + skip];
|
||||||
color |= ((fmt.brev ? byte>>(bitsperword-shift-bpp) : byte>>shift) & mask) << (p*bpp);
|
color |= ((fmt.brev ? byte>>(bitsperword-shift-bpp) : byte>>shift) & mask) << (p*bpp);
|
||||||
}
|
}
|
||||||
imgdata.push(color);
|
imgdata.push(color);
|
||||||
shift += bpp;
|
shift += bpp;
|
||||||
if (shift >= bitsperword) {
|
if (shift >= bitsperword && !fmt.reindex) {
|
||||||
ofs0 += 1;
|
ofs0 += 1;
|
||||||
shift = 0;
|
shift = 0;
|
||||||
}
|
}
|
||||||
|
@ -210,12 +220,13 @@ function convertImagesToWords(images:Uint8Array[], fmt:PixelEditorImageFormat) :
|
||||||
for (var x=0; x<width; x++) {
|
for (var x=0; x<width; x++) {
|
||||||
var color = imgdata[i++];
|
var color = imgdata[i++];
|
||||||
var ofs = remapBits(ofs0, fmt.remap);
|
var ofs = remapBits(ofs0, fmt.remap);
|
||||||
|
if (fmt.reindex) { [ofs, shift] = reindexMask(x, fmt.reindex); ofs += ofs0; }
|
||||||
for (var p=0; p<nplanes; p++) {
|
for (var p=0; p<nplanes; p++) {
|
||||||
var c = (color >> (p*bpp)) & mask;
|
var c = (color >> (p*bpp)) & mask;
|
||||||
words[ofs + p*pofs + skip] |= (fmt.brev ? (c << (bitsperword-shift-bpp)) : (c << shift));
|
words[ofs + p*pofs + skip] |= (fmt.brev ? (c << (bitsperword-shift-bpp)) : (c << shift));
|
||||||
}
|
}
|
||||||
shift += bpp;
|
shift += bpp;
|
||||||
if (shift >= bitsperword) {
|
if (shift >= bitsperword && !fmt.reindex) {
|
||||||
ofs0 += 1;
|
ofs0 += 1;
|
||||||
shift = 0;
|
shift = 0;
|
||||||
}
|
}
|
||||||
|
@ -600,6 +611,7 @@ function dedupPalette(cols : UintArray) : Uint32Array {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PaletteFormatToRGB extends PixNode {
|
export class PaletteFormatToRGB extends PixNode {
|
||||||
|
|
||||||
words : UintArray;
|
words : UintArray;
|
||||||
|
@ -851,8 +863,13 @@ export class CharmapEditor extends PixNode {
|
||||||
var im = new PixEditor();
|
var im = new PixEditor();
|
||||||
im.createWith(viewer);
|
im.createWith(viewer);
|
||||||
im.updateImage();
|
im.updateImage();
|
||||||
im.canvas.style.width = (viewer.width*xscale)+'px'; // TODO
|
var w = viewer.width * xscale;
|
||||||
im.canvas.style.height = (viewer.height*yscale)+'px'; // TODO
|
var h = viewer.height * yscale;
|
||||||
|
while (w > 500 || h > 500) {
|
||||||
|
w /= 2; h /= 2;
|
||||||
|
}
|
||||||
|
im.canvas.style.width = w+'px'; // TODO
|
||||||
|
im.canvas.style.height = h+'px'; // TODO
|
||||||
im.makeEditable(this, aeditor, this.left.palette);
|
im.makeEditable(this, aeditor, this.left.palette);
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
@ -1103,3 +1120,57 @@ class PixEditor extends Viewer {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: not yet used
|
||||||
|
|
||||||
|
abstract class TwoWayPixelConverter {
|
||||||
|
|
||||||
|
w : number;
|
||||||
|
h : number;
|
||||||
|
words : Uint8Array;
|
||||||
|
bitoffsets : Uint32Array;
|
||||||
|
coloffsets : Uint32Array;
|
||||||
|
|
||||||
|
constructor(width: number, height: number, bpp: number, colpp: number) {
|
||||||
|
this.w = width;
|
||||||
|
this.h = height;
|
||||||
|
this.words = new Uint8Array(width * height);
|
||||||
|
this.bitoffsets = new Uint32Array(width * height);
|
||||||
|
this.coloffsets = new Uint32Array(width * height);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPixel(x:number, y:number, col:number, bitofs:number, colofs:number) {
|
||||||
|
var ofs = x + y * this.w;
|
||||||
|
this.words[ofs] = col;
|
||||||
|
this.bitoffsets[ofs] = bitofs;
|
||||||
|
this.coloffsets[ofs] = colofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract wordsToImage(words: UintArray) : Uint8Array[];
|
||||||
|
|
||||||
|
abstract imageToWords(image: Uint8Array) : UintArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TwoWayMapper extends PixNode {
|
||||||
|
|
||||||
|
pc: TwoWayPixelConverter;
|
||||||
|
|
||||||
|
constructor(pc: TwoWayPixelConverter) {
|
||||||
|
super();
|
||||||
|
this.pc = pc;
|
||||||
|
}
|
||||||
|
updateLeft() {
|
||||||
|
//if (equalNestedArrays(this.images, this.right.images)) return false;
|
||||||
|
this.images = this.right.images;
|
||||||
|
this.words = this.pc.imageToWords(this.images[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
updateRight() {
|
||||||
|
if (equalArrays(this.words, this.left.words)) return false;
|
||||||
|
// convert each word array to images
|
||||||
|
this.words = this.left.words;
|
||||||
|
this.images = this.pc.wordsToImage(this.words);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,7 @@ export class SourceEditor implements ProjectView {
|
||||||
} else if (platform.getOpcodeMetadata) {
|
} else if (platform.getOpcodeMetadata) {
|
||||||
var opcode = parseInt(info.insns.split(" ")[0], 16);
|
var opcode = parseInt(info.insns.split(" ")[0], 16);
|
||||||
var meta = platform.getOpcodeMetadata(opcode, info.offset);
|
var meta = platform.getOpcodeMetadata(opcode, info.offset);
|
||||||
if (meta) {
|
if (meta && meta.minCycles) {
|
||||||
var clockstr = meta.minCycles+"";
|
var clockstr = meta.minCycles+"";
|
||||||
this.setGutter("gutter-clock", info.line-1, clockstr);
|
this.setGutter("gutter-clock", info.line-1, clockstr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ MEMORY {
|
||||||
}
|
}
|
||||||
|
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
RODATA: load=ROM, type=ro, align = $100;
|
RODATA: load=ROM, type=ro, align=$100;
|
||||||
CODE: load=ROM, type=ro, define=yes;
|
CODE: load=ROM, type=ro, align=$100, define=yes;
|
||||||
DATA: load=ROM, run=RAM, type=rw, define=yes;
|
DATA: load=ROM, run=RAM, type=rw, define=yes;
|
||||||
BSS: load=RAM, type=bss, define=yes;
|
BSS: load=RAM, type=bss, define=yes;
|
||||||
VECTORS: load=ROM, type=ro, start=$FFFA;
|
VECTORS: load=ROM, type=ro, start=$FFFA;
|
||||||
|
|
|
@ -962,7 +962,8 @@ function parseCA65Listing(code, symbols, params, dbg) {
|
||||||
lines.push({
|
lines.push({
|
||||||
line:linenum,
|
line:linenum,
|
||||||
offset:offset + segofs,
|
offset:offset + segofs,
|
||||||
insns:insns
|
insns:insns,
|
||||||
|
iscode:true // TODO: can't really tell unless we parse it
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user