ecs: fixed indexregister offset, for now

This commit is contained in:
Steven Hugg 2022-02-16 14:50:48 -06:00
parent a425012b2b
commit 0451e8ea33
10 changed files with 4008 additions and 45 deletions

View File

@ -507,7 +507,6 @@ class EntitySet {
class IndexRegister {
lo: number | null;
hi: number | null;
offset = 0;
elo: number;
ehi: number;
eset: EntitySet | undefined;
@ -548,16 +547,19 @@ class IndexRegister {
if (this.lo === null || this.hi === null) {
this.lo = 0;
this.hi = newehi - newelo;
this.offset = 0;
this.elo = newelo;
this.ehi = newehi;
} else {
if (action) console.log((action as any).event, this.offset, newelo, this.elo);
this.offset += newelo - this.elo;
//if (action) console.log((action as any).event, this.elo, '-', this.ehi, '->', newelo, '..', newehi);
this.lo += newelo - this.elo;
this.hi += newehi - this.ehi;
}
this.elo = newelo;
this.ehi = newehi;
if (action) console.log((action as any).event, this.offset, this.elo, this.ehi, newelo, newehi);
return true;
}
// TODO: removegi
offset() {
return this.lo || 0;
}
}
// todo: generalize
@ -711,8 +713,8 @@ class ActionEval {
props['%ecount'] = entities.length.toString();
props['%efullcount'] = fullEntityCount.toString();
// TODO
props['%xofs'] = (this.scope.state.xreg?.offset || 0).toString();
props['%yofs'] = (this.scope.state.yreg?.offset || 0).toString();
props['%xofs'] = (this.scope.state.xreg?.offset() || 0).toString();
props['%yofs'] = (this.scope.state.yreg?.offset() || 0).toString();
}
// replace @labels
code = code.replace(label_re, (s: string, a: string) => `${label}__${a}`);
@ -772,10 +774,11 @@ class ActionEval {
__index(args: string[]) {
// TODO: check select type and if we actually have an index...
let ident = args[0];
let index = parseInt(args[1] || '0');
if (this.entities.length == 1) {
return this.dialect.absolute(ident);
} else {
return this.dialect.indexed_x(ident, 0); //TODO?
return this.dialect.indexed_x(ident, index); //TODO?
}
}
__use(args: string[]) {
@ -814,7 +817,7 @@ class ActionEval {
return s;
}
wrapCodeInFilter(code: string) {
// TODO: :-p
// TODO: :-p filters too often?
const ents = this.entities;
const ents2 = this.oldState.xreg?.eset?.entities;
if (ents && ents2) {
@ -892,29 +895,37 @@ class ActionEval {
if (!range) throw new ECSError(`couldn't find field for ${component.name}:${fieldName}, maybe no entities?`); // TODO
// TODO: dialect
// TODO: doesnt work for entity.field
let eidofs = qr.entities.length && qr.entities[0].id - range.elo; // TODO: negative?
if (entityLookup)
eidofs = entities[0].id - range.elo;
// TODO: array field baseoffset?
if (baseLookup) {
return this.dialect.absolute(ident);
} else if (entities.length == 1) {
let eidofs = qr.entities.length && qr.entities[0].id - range.elo; // TODO: negative?
if (entityLookup)
eidofs = entities[0].id - range.elo;
return this.dialect.absolute(ident, eidofs);
} else {
let ir;
let int;
let eidofs;
let xreg = this.scope.state.xreg;
let yreg = this.scope.state.yreg;
if (xreg && (int = xreg.eset?.intersection(qr))) {
//console.log('x',qr.entities[0].id,xreg.elo,int.entities[0].id,xreg.offset);
//console.log(eidofs,'x',qr.entities[0].id,xreg.elo,int.entities[0].id,xreg.offset(),range.elo);
ir = xreg.eset;
eidofs -= xreg.offset;
}
else if (yreg && (int = yreg.eset?.intersection(qr))) {
//eidofs -= xreg.offset();
//eidofs -= int.entities[0].id - xreg.elo;
eidofs = xreg.elo - range.elo;
} else if (yreg && (int = yreg.eset?.intersection(qr))) {
ir = yreg.eset;
eidofs -= yreg.offset;
//eidofs -= yreg.offset();
eidofs = yreg.elo - range.elo;
} else {
ir = null;
eidofs = 0;
}
if (!ir) {
throw new ECSError(`no intersection for index register`, action);
}
if (!ir) throw new ECSError(`no intersection for index register`, action);
if (ir.entities.length == 0) throw new ECSError(`no common entities for index register`, action);
if (!ir.isContiguous()) throw new ECSError(`entities in query are not contiguous`, action);
if (ir == this.scope.state.xreg?.eset)
@ -1292,7 +1303,7 @@ export class EntityScope implements SourceLocated {
this.bss.allocateBytes('TEMP', bssbin.extents.right);
for (let b of pack.boxes) {
let inst : SystemInstance = (b as any).inst;
console.log(inst.system.name, b.box?.left);
//console.log(inst.system.name, b.box?.left);
this.bss.equates[this.dialect.tempLabel(inst)] = `TEMP+${b.box?.left}`;
}
}

View File

@ -85,30 +85,32 @@ describe('Compiler', function() {
let testdir = './test/ecs/';
let files = readdirSync(testdir).filter(f => f.endsWith('.ecs'));
files.forEach((ecsfn) => {
let asmfn = ecsfn.replace('.ecs','.asm');
let goodfn = ecsfn.replace('.ecs','.txt');
let ecspath = testdir + ecsfn;
let goodpath = testdir + goodfn;
let dialect = new Dialect_CA65();
let em = new EntityManager(dialect);
em.mainPath = ecspath;
let compiler = new ECSCompiler(em);
compiler.getImportFile = (path: string) => {
return readFileSync(testdir + path, 'utf-8');
}
let code = readFileSync(ecspath, 'utf-8');
compiler.parseFile(code, ecspath);
// TODO: errors
let out = new SourceFileExport();
em.exportToFile(out);
let outtxt = out.toString();
let goodtxt = existsSync(goodpath) ? readFileSync(goodpath, 'utf-8') : '';
if (outtxt.trim() != goodtxt.trim()) {
let asmpath = '/tmp/' + asmfn;
writeFileSync(asmpath, outtxt, 'utf-8');
console.log(spawnSync('/usr/bin/diff', [goodpath, asmpath], {encoding:'utf-8'}).stdout);
throw new Error(`files different; to fix: cp ${asmpath} ${goodpath}`);
}
it('Should compile ' + ecsfn, function() {
let asmfn = ecsfn.replace('.ecs','.asm');
let goodfn = ecsfn.replace('.ecs','.txt');
let ecspath = testdir + ecsfn;
let goodpath = testdir + goodfn;
let dialect = new Dialect_CA65();
let em = new EntityManager(dialect);
em.mainPath = ecspath;
let compiler = new ECSCompiler(em);
compiler.getImportFile = (path: string) => {
return readFileSync(testdir + path, 'utf-8');
}
let code = readFileSync(ecspath, 'utf-8');
compiler.parseFile(code, ecspath);
// TODO: errors
let out = new SourceFileExport();
em.exportToFile(out);
let outtxt = out.toString();
let goodtxt = existsSync(goodpath) ? readFileSync(goodpath, 'utf-8') : '';
if (outtxt.trim() != goodtxt.trim()) {
let asmpath = '/tmp/' + asmfn;
writeFileSync(asmpath, outtxt, 'utf-8');
console.log(spawnSync('/usr/bin/diff', [goodpath, asmpath], {encoding:'utf-8'}).stdout);
throw new Error(`files different; to fix: cp ${asmpath} ${goodpath}`);
}
});
});
});

299
test/ecs/score.ecs Normal file
View File

@ -0,0 +1,299 @@
//#resource "vcs-ca65.h"
import "vcslib.ecs"
component BCDScore2
digits: 0..0xff
end
component BCDScore4
digits: 0..0xffff
end
component BCDScore6
digits: 0..0xffffff
end
system Kernel6Digit
locals 15
on preframe do with [BCDScore6]
---
Digit0 = {{$0}}
Digit1 = {{$2}}
Digit2 = {{$4}}
Digit3 = {{$6}}
Digit4 = {{$8}}
Digit5 = {{$10}}
@BCD0 = {{$12}}
@BCD1 = {{$13}}
@BCD2 = {{$14}}
lda {{get digits 0}}
sta @BCD0
lda {{get digits 8}}
sta @BCD1
lda {{get digits 16}}
sta @BCD2
ldx #0 ; leftmost bitmap
ldy #2 ; start from most-sigificant BCD value
@Loop:
lda @BCD0,y ; get BCD value
and #$f0 ; isolate high nibble (* 16)
lsr ; shift right 1 bit (* 8)
clc
adc #<{{^FontTable}}
sta Digit0,x ; store pointer lo byte
lda #>{{^FontTable}}
adc #0
sta Digit0+1,x ; store pointer hi byte
inx
inx ; next bitmap pointer
lda @BCD0,y ; get BCD value (again)
and #$f ; isolate low nibble
asl
asl
asl ; * 8
clc
adc #<{{^FontTable}}
sta Digit0,x ; store pointer lo byte
lda #>{{^FontTable}}
adc #0
sta Digit0+1,x ; store pointer hi byte
inx
inx ; next bitmap pointer
dey ; next BCD value
bpl @Loop ; repeat until < 0
---
on kernel do with [BCDScore6,PFColor]
---
lda {{<pfcolor}}
sta COLUP0
sta COLUP1
lda #3
sta NUSIZ0
sta NUSIZ1
; set horizontal position of player objects
sta WSYNC
sta HMCLR
SLEEPR 24
sta RESP0
sta RESP1
lda #$10
sta HMP1
sta WSYNC
sta HMOVE
SLEEPR 24 ; wait 24 cycles between write to HMOVE and HMxxx
sta HMCLR
lda #1
sta VDELP0
sta VDELP1
---
on kernel do with [BCDScore6,BGColor]
---
; Display the resulting 48x8 bitmap
; using the Digit0-5 pointers.
@LoopCount = {{$12}}
@Temp = {{$13}}
lda {{<bgcolor}}
sta WSYNC
sta COLUBK
lda #7
sta @LoopCount
SLEEPR 20 ; TODO?
@BigLoop:
ldy @LoopCount ; counts backwards
lda (Digit0),y ; load B0 (1st sprite byte)
sta GRP0 ; B0 -> [GRP0]
lda (Digit1),y ; load B1 -> A
sta GRP1 ; B1 -> [GRP1], B0 -> GRP0
sta WSYNC ; sync to next scanline
lda (Digit2),y ; load B2 -> A
sta GRP0 ; B2 -> [GRP0], B1 -> GRP1
lda (Digit5),y ; load B5 -> A
sta @Temp ; B5 -> temp
lda (Digit4),y ; load B4
tax ; -> X
lda (Digit3),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
lda #0 ; clear the sprite registers
sta WSYNC
sta GRP0
sta GRP1
sta GRP0
sta GRP1
sta COLUBK
---
end
resource FontTable ---
; Font table for digits 0-9 (8x8 pixels)
FontTable:
;;{w:8,h:8,count:10,brev:1,flip:1};;
.byte $00,$3c,$66,$66,$76,$6e,$66,$3c,$00,$7e,$18,$18,$18,$38,$18,$18
.byte $00,$7e,$60,$30,$0c,$06,$66,$3c,$00,$3c,$66,$06,$1c,$06,$66,$3c
.byte $00,$06,$06,$7f,$66,$1e,$0e,$06,$00,$3c,$66,$06,$06,$7c,$60,$7e
.byte $00,$3c,$66,$66,$7c,$60,$66,$3c,$00,$18,$18,$18,$18,$0c,$66,$7e
.byte $00,$3c,$66,$66,$3c,$66,$66,$3c,$00,$3c,$66,$06,$3e,$66,$66,$3c
---
system Kernel2Digit
locals 3
on kernel do select [BCDScore2,PFColor]
---
lda #$02
sta CTRLPF
; TODO: should be constants
; and it's wrong, too!
lda {{<PFColor:pfcolor}}+0
sta COLUP0
lda {{<PFColor:pfcolor}}+1
sta COLUP1
---
on kernel do select [BCDScore2]
---
lda #7
sta {{$0}}
@Loop:
ldx #0
sta WSYNC
{{!compute2digit 0}}
inx
{{!compute2digit 1}}
; playfield
dec {{$0}}
bpl @Loop
; dex
; stx PF1
---
on compute2digit do once
---
lda {{$1}} ; load 1st pf
sta PF1 ; store 1st pf
; first digit
lda {{<BCDScore2:digits}} + {{#0}}
pha
and #$0f
asl
asl
asl
{{!fetchdigit}}
and #$0f
ldy {{$2}} ; load 2nd pf
sta {{$1}} + {{#0}}
; second digit
pla
and #$f0
lsr
sty PF1 ; store 2nd pf
{{!fetchdigit}}
and #$f0
ora {{$1}} + {{#0}}
sta {{$1}} + {{#0}}
---
on fetchdigit do once
---
adc {{$0}}
tay
; TODO: select your own?
lda {{^FontTablePF}},y
---
end
resource FontTablePF ---
; Font table for digits 0-9 (4x8 pixels)
FontTablePF:
;;{w:8,h:8,count:10,brev:1,flip:1};;
.byte $00,$00,$EE,$AA,$AA,$AA,$EE,$00
.byte $00,$00,$22,$22,$22,$22,$22,$00
.byte $00,$00,$EE,$88,$EE,$22,$EE,$00
.byte $00,$00,$EE,$22,$66,$22,$EE,$00
.byte $00,$00,$22,$22,$EE,$AA,$AA,$00
.byte $00,$00,$EE,$22,$EE,$88,$EE,$00
.byte $00,$00,$EE,$AA,$EE,$88,$EE,$00
.byte $00,$00,$22,$22,$22,$22,$EE,$00
.byte $00,$00,$EE,$AA,$EE,$AA,$EE,$00
.byte $00,$00,$EE,$22,$EE,$AA,$EE,$00
;;
---
resource FontTablePFFancy ---
; Font table for digits 0-9 (4x8 pixels)
FontTablePFFancy:
;;{w:8,h:8,count:10,brev:1,flip:1};;
.byte $00,$44,$AA,$AA,$AA,$AA,$AA,$44
.byte $00,$EE,$44,$44,$44,$44,$CC,$44
.byte $00,$EE,$88,$88,$44,$22,$AA,$44
.byte $00,$CC,$22,$22,$66,$22,$22,$CC
.byte $00,$22,$22,$22,$EE,$AA,$AA,$88
.byte $00,$44,$AA,$22,$44,$88,$88,$EE
.byte $00,$44,$AA,$AA,$CC,$88,$AA,$44
.byte $00,$22,$22,$22,$22,$22,$AA,$EE
.byte $00,$44,$AA,$AA,$44,$AA,$AA,$44
.byte $00,$44,$AA,$22,$66,$AA,$AA,$44
;;
---
system BCDMath
locals 1
on AddBCD4 do with [BCDScore6]
---
.ifnblank {{arg 0}}
lda #<{{arg 0}}
ldy #>{{arg 0}}
.endif
; Adds value to 6-BCD-digit score.
; A = 1st BCD digit
; Y = 2nd BCD digit
sed ; enter BCD mode
clc ; clear carry
adc {{get digits}}
sta {{set digits}}
tya
adc {{get digits 8}}
sta {{set digits 8}}
lda {{get digits 16}}
adc #0
sta {{set digits 16}}
cld ; exit BCD mode
---
end
demo Main
using FrameLoop
using Kernel6Digit, FontTable
using Kernel2Digit, FontTablePF
using JoyButton, BCDMath
entity [Player,BCDScore6,PFColor,BGColor]
init digits = 0x123456
init pfcolor = $3c
init bgcolor = $02
end
entity [BCDScore2,PFColor]
init digits = 0x24
init pfcolor = $ce
end
entity [BCDScore2,PFColor]
init digits = 0x56
init pfcolor = $3e
end
system IncScore
on joybutton do with [Player,BCDScore6]
---
{{!AddBCD4 $0210}}
---
end
end

423
test/ecs/score.txt Normal file
View File

@ -0,0 +1,423 @@
.scope Main
.zeropage
BCDScore6_digits_b0:
.res 1
BCDScore6_digits_b8:
.res 1
BCDScore6_digits_b16:
.res 1
PFColor_pfcolor_b0:
.res 1
.res 1
.res 1
BGColor_bgcolor_b0:
.res 1
BCDScore2_digits_b0:
.res 1
.res 1
TEMP:
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
Kernel6Digit__2__tmp = TEMP+0
Kernel2Digit__4__tmp = TEMP+15
.code
Main__INITDATA:
.byte 86
.byte 52
.byte 18
.byte 60
.byte 206
.byte 62
.byte 2
.byte 36
.byte 86
__Start:
.code
;;; start action Init 9 main_init
.include "vcs-ca65.h"
.macpack longbranch
.define PAL 0
__NMI:
__Reset:
__BRK:
CLEAN_START
ldy #9
: lda Main__INITDATA-1,y
sta BCDScore6_digits_b0-1,y
dey
bne :-
; initialize data segment
.code
;;; start action FrameLoop 1 start
FrameLoop__start__2__NextFrame:
FRAME_START
.code
;;; start action Kernel6Digit 2 preframe
Digit0 = Kernel6Digit__2__tmp+0
Digit1 = Kernel6Digit__2__tmp+2
Digit2 = Kernel6Digit__2__tmp+4
Digit3 = Kernel6Digit__2__tmp+6
Digit4 = Kernel6Digit__2__tmp+8
Digit5 = Kernel6Digit__2__tmp+10
Kernel6Digit__preframe__3__BCD0 = Kernel6Digit__2__tmp+12
Kernel6Digit__preframe__3__BCD1 = Kernel6Digit__2__tmp+13
Kernel6Digit__preframe__3__BCD2 = Kernel6Digit__2__tmp+14
lda BCDScore6_digits_b0
sta Kernel6Digit__preframe__3__BCD0
lda BCDScore6_digits_b8
sta Kernel6Digit__preframe__3__BCD1
lda BCDScore6_digits_b16
sta Kernel6Digit__preframe__3__BCD2
ldx #0 ; leftmost bitmap
ldy #2 ; start from most-sigificant BCD value
Kernel6Digit__preframe__3__Loop:
lda Kernel6Digit__preframe__3__BCD0,y ; get BCD value
and #$f0 ; isolate high nibble (* 16)
lsr ; shift right 1 bit (* 8)
clc
adc #<FontTable
sta Digit0,x ; store pointer lo byte
lda #>FontTable
adc #0
sta Digit0+1,x ; store pointer hi byte
inx
inx ; next bitmap pointer
lda Kernel6Digit__preframe__3__BCD0,y ; get BCD value (again)
and #$f ; isolate low nibble
asl
asl
asl ; * 8
clc
adc #<FontTable
sta Digit0,x ; store pointer lo byte
lda #>FontTable
adc #0
sta Digit0+1,x ; store pointer hi byte
inx
inx ; next bitmap pointer
dey ; next BCD value
bpl Kernel6Digit__preframe__3__Loop ; repeat until < 0
;;; end action Kernel6Digit 2 preframe
KERNEL_START
.code
;;; start action Kernel6Digit 2 kernel
lda PFColor_pfcolor_b0
sta COLUP0
sta COLUP1
lda #3
sta NUSIZ0
sta NUSIZ1
; set horizontal position of player objects
sta WSYNC
sta HMCLR
SLEEPR 24
sta RESP0
sta RESP1
lda #$10
sta HMP1
sta WSYNC
sta HMOVE
SLEEPR 24 ; wait 24 cycles between write to HMOVE and HMxxx
sta HMCLR
lda #1
sta VDELP0
sta VDELP1
;;; end action Kernel6Digit 2 kernel
;;; start action Kernel6Digit 2 kernel
; Display the resulting 48x8 bitmap
; using the Digit0-5 pointers.
Kernel6Digit__kernel__5__LoopCount = Kernel6Digit__2__tmp+12
Kernel6Digit__kernel__5__Temp = Kernel6Digit__2__tmp+13
lda BGColor_bgcolor_b0
sta WSYNC
sta COLUBK
lda #7
sta Kernel6Digit__kernel__5__LoopCount
SLEEPR 20 ; TODO?
Kernel6Digit__kernel__5__BigLoop:
ldy Kernel6Digit__kernel__5__LoopCount ; counts backwards
lda (Digit0),y ; load B0 (1st sprite byte)
sta GRP0 ; B0 -> [GRP0]
lda (Digit1),y ; load B1 -> A
sta GRP1 ; B1 -> [GRP1], B0 -> GRP0
sta WSYNC ; sync to next scanline
lda (Digit2),y ; load B2 -> A
sta GRP0 ; B2 -> [GRP0], B1 -> GRP1
lda (Digit5),y ; load B5 -> A
sta Kernel6Digit__kernel__5__Temp ; B5 -> temp
lda (Digit4),y ; load B4
tax ; -> X
lda (Digit3),y ; load B3 -> A
ldy Kernel6Digit__kernel__5__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 Kernel6Digit__kernel__5__LoopCount ; go to next line
bpl Kernel6Digit__kernel__5__BigLoop ; repeat until < 0
lda #0 ; clear the sprite registers
sta WSYNC
sta GRP0
sta GRP1
sta GRP0
sta GRP1
sta COLUBK
;;; end action Kernel6Digit 2 kernel
;;; start action Kernel2Digit 4 kernel
lda #$02
sta CTRLPF
; TODO: should be constants
; and it's wrong, too!
lda PFColor_pfcolor_b0+0
sta COLUP0
lda PFColor_pfcolor_b0+1
sta COLUP1
;;; end action Kernel2Digit 4 kernel
;;; start action Kernel2Digit 4 kernel
lda #7
sta Kernel2Digit__4__tmp+0
Kernel2Digit__kernel__7__Loop:
ldx #0
sta WSYNC
.code
;;; start action Kernel2Digit 4 compute2digit
lda Kernel2Digit__4__tmp+1 ; load 1st pf
sta PF1 ; store 1st pf
; first digit
lda BCDScore2_digits_b0 + 0
pha
and #$0f
asl
asl
asl
.code
;;; start action Kernel2Digit 4 fetchdigit
adc Kernel2Digit__4__tmp+0
tay
; TODO: select your own?
lda FontTablePF,y
;;; end action Kernel2Digit 4 fetchdigit
and #$0f
ldy Kernel2Digit__4__tmp+2 ; load 2nd pf
sta Kernel2Digit__4__tmp+1 + 0
; second digit
pla
and #$f0
lsr
sty PF1 ; store 2nd pf
.code
;;; start action Kernel2Digit 4 fetchdigit
adc Kernel2Digit__4__tmp+0
tay
; TODO: select your own?
lda FontTablePF,y
;;; end action Kernel2Digit 4 fetchdigit
and #$f0
ora Kernel2Digit__4__tmp+1 + 0
sta Kernel2Digit__4__tmp+1 + 0
;;; end action Kernel2Digit 4 compute2digit
inx
.code
;;; start action Kernel2Digit 4 compute2digit
lda Kernel2Digit__4__tmp+1 ; load 1st pf
sta PF1 ; store 1st pf
; first digit
lda BCDScore2_digits_b0 + 1
pha
and #$0f
asl
asl
asl
.code
;;; start action Kernel2Digit 4 fetchdigit
adc Kernel2Digit__4__tmp+0
tay
; TODO: select your own?
lda FontTablePF,y
;;; end action Kernel2Digit 4 fetchdigit
and #$0f
ldy Kernel2Digit__4__tmp+2 ; load 2nd pf
sta Kernel2Digit__4__tmp+1 + 1
; second digit
pla
and #$f0
lsr
sty PF1 ; store 2nd pf
.code
;;; start action Kernel2Digit 4 fetchdigit
adc Kernel2Digit__4__tmp+0
tay
; TODO: select your own?
lda FontTablePF,y
;;; end action Kernel2Digit 4 fetchdigit
and #$f0
ora Kernel2Digit__4__tmp+1 + 1
sta Kernel2Digit__4__tmp+1 + 1
;;; end action Kernel2Digit 4 compute2digit
; playfield
dec Kernel2Digit__4__tmp+0
bpl Kernel2Digit__kernel__7__Loop
; dex
; stx PF1
;;; end action Kernel2Digit 4 kernel
KERNEL_END
.code
;;; start action JoyButton 6 postframe
lda INPT4 ;read button input
bmi JoyButton__postframe__14__NotPressed
.code
;;; start action IncScore 8 joybutton
.code
;;; start action BCDMath 7 AddBCD4
.ifnblank $0210
lda #<$0210
ldy #>$0210
.endif
; Adds value to 6-BCD-digit score.
; A = 1st BCD digit
; Y = 2nd BCD digit
sed ; enter BCD mode
clc ; clear carry
adc BCDScore6_digits_b0
sta BCDScore6_digits_b0
tya
adc BCDScore6_digits_b8
sta BCDScore6_digits_b8
lda BCDScore6_digits_b16
adc #0
sta BCDScore6_digits_b16
cld ; exit BCD mode
;;; end action BCDMath 7 AddBCD4
;;; end action IncScore 8 joybutton
JoyButton__postframe__14__NotPressed:
;;; end action JoyButton 6 postframe
FRAME_END
.code
jmp FrameLoop__start__2__NextFrame ; loop to next frame
;;; end action FrameLoop 1 start
; start main routine
.segment "VECTORS"
Return: .word $6060
VecNMI:
VecReset: .word Main::__Reset
VecBRK: .word Main::__BRK
;;; end action Init 9 main_init
.code
;;; start action FontTable 3 FontTable
; Font table for digits 0-9 (8x8 pixels)
FontTable:
;;{w:8,h:8,count:10,brev:1,flip:1};;
.byte $00,$3c,$66,$66,$76,$6e,$66,$3c,$00,$7e,$18,$18,$18,$38,$18,$18
.byte $00,$7e,$60,$30,$0c,$06,$66,$3c,$00,$3c,$66,$06,$1c,$06,$66,$3c
.byte $00,$06,$06,$7f,$66,$1e,$0e,$06,$00,$3c,$66,$06,$06,$7c,$60,$7e
.byte $00,$3c,$66,$66,$7c,$60,$66,$3c,$00,$18,$18,$18,$18,$0c,$66,$7e
.byte $00,$3c,$66,$66,$3c,$66,$66,$3c,$00,$3c,$66,$06,$3e,$66,$66,$3c
;;; end action FontTable 3 FontTable
.code
;;; start action FontTablePF 5 FontTablePF
; Font table for digits 0-9 (4x8 pixels)
FontTablePF:
;;{w:8,h:8,count:10,brev:1,flip:1};;
.byte $00,$00,$EE,$AA,$AA,$AA,$EE,$00
.byte $00,$00,$22,$22,$22,$22,$22,$00
.byte $00,$00,$EE,$88,$EE,$22,$EE,$00
.byte $00,$00,$EE,$22,$66,$22,$EE,$00
.byte $00,$00,$22,$22,$EE,$AA,$AA,$00
.byte $00,$00,$EE,$22,$EE,$88,$EE,$00
.byte $00,$00,$EE,$AA,$EE,$88,$EE,$00
.byte $00,$00,$22,$22,$22,$22,$EE,$00
.byte $00,$00,$EE,$AA,$EE,$AA,$EE,$00
.byte $00,$00,$EE,$22,$EE,$AA,$EE,$00
;;
;;; end action FontTablePF 5 FontTablePF
.endscope
Main__Start = Main::__Start

440
test/ecs/sprites.ecs Normal file
View File

@ -0,0 +1,440 @@
//#resource "vcs-ca65.h"
import "vcslib.ecs"
component Bitmap
bitmapdata: array of 0..255 baseoffset 31
height: 0..255
end
component HasBitmap
bitmap: [Bitmap]
end
component Colormap
colormapdata: array of 0..255 baseoffset 31
end
component HasColormap
colormap: [Colormap]
end
component Sprite
plyrflags: 0..63
end
component HasXpos
xpos: 0..255
end
component HasYpos
ypos: 0..255
end
component SpriteSlot
sprite: [Sprite,HasBitmap,HasColormap,HasYpos]
end
component Missile
end
system Kernel2Sprite
locals 13
on preframe do with [KernelSection]
---
.define KLINES {{<lines}}
.define KPAD 32
; set height to zero in case no sprites
lda #0
sta {{$8}}
sta {{$9}}
; set temp value so we don't read bitmap from h/w registers
lda #$F0
sta {{$2}}
sta {{$3}}
sta {{$6}}
sta {{$7}}
---
on preframe do join
[SpriteSlot] with
[Sprite,HasBitmap,HasColormap,HasYpos] limit 2
---
; flags set according to sprite slot value
; skip sprite if negative
jmi @nosprite
; set player object flags
lda {{<plyrflags}}
sta NUSIZ0,y
sta REFP0,y
; calculate screen height - ypos
lda KLINES+KPAD
sec
sbc {{<ypos}}
sta {{$11}}
; calculate bitmap pointer
stx {{$12}} ; save X (Sprite index)
lda {{<bitmap}} ; deref bitmap
tax
lda {{<Bitmap:bitmapdata}},x
sec
sbc {{$11}}
sta {{$0}},y ; Y = sprite slot index
lda {{>Bitmap:bitmapdata}},x
sbc #0
sta {{$2}},y
; get bitmap height
lda {{<Bitmap:height}},x
sta {{$8}},y
; calculate colormap pointer
ldx {{$12}} ; restore X
lda {{<colormap}} ; deref colormap
tax
lda {{<Colormap:colormapdata}},x
sec
sbc {{$11}}
sta {{$4}},y
lda {{>Colormap:colormapdata}},x
sbc #0
sta {{$6}},y
; save ypos
ldx {{$12}} ; restore X
lda {{<ypos}}
sta {{$10}},y
@nosprite:
---
on preframe do once
---
; shuffle pointers into (MSB, LSB) byte order
; L0 L1 H0 H1 -> L0 H0 L1 H1
lda {{$1}}
ldy {{$2}}
sty {{$1}}
sta {{$2}}
lda {{$5}}
ldy {{$6}}
sty {{$5}}
sta {{$6}}
---
on preframe do if [BGColor]
---
lda {{<bgcolor}}
sta COLUBK
---
on preframe do if [Missile,HasYpos]
---
lda KLINES
sec
sbc {{<ypos}}
sta {{$12}}
---
on kernel do with [KernelSection]
---
ldy #0
sty VDELP0
iny
sta VDELP1
---
on kernel do with [KernelSection]
---
ldy {{<lines}}
@LVScan:
{{!scanline 0}}
dey ; next scanline
{{!scanline 1}}
dey ; next scanline
bne @LVScan ; repeat until out of lines
---
on scanline do once
---
; draw player 0
lda {{$8}} ; height
dcp {{$10}} ; ypos
bcs @DoDraw1
lda #0
.byte $2C
@DoDraw1:
lda ({{$0}}),y
.if {{#0}} = 0
sta WSYNC
.endif
sta GRP0
lda ({{$4}}),y
sta COLUP0
; draw player 1
lda {{$9}} ; height
dcp {{$11}} ; ypos
bcs @DoDraw2
lda #0
.byte $2C
@DoDraw2:
lda ({{$2}}),y
sta GRP1
lda ({{$6}}),y
sta COLUP1
---
on kernel do once
---
lda #0
sta GRP0
sta GRP1
sta GRP0
sta GRP1
---
on scanline do if [Missile,HasYpos]
---
cpy {{$12}}
php
pla
sta ENAM0
---
end
system VersatilePlayfield
locals 2
on preframe do with [VersatilePlayfield]
---
lda {{<data}}
sta {{$0}}
lda {{>data}}
sta {{$1}}
---
on scanline do once
---
.if {{arg 0}} = 0
lda ({{local 0}}),y
tax
.endif
---
on scanline do once
---
.if {{arg 0}} = 1
lda ({{local 0}}),y
sta $00,x
.endif
---
on postframe do once
---
lda #0
sta PF0
sta PF1
sta PF2
---
end
system SetXPos
on preframe do once
---
sta HMCLR
---
on preframe do join [SpriteSlot] with [HasXpos]
limit 2
---
lda {{<xpos}}
{{!SetHorizPos}}
---
on preframe do if [Missile,HasXpos]
---
lda {{<xpos}}
ldx #2
{{!SetHorizPos}}
---
on preframe do once
---
sta WSYNC
sta HMOVE
---
end
system JoyFaceDirection
on joyleft do with [Sprite]
---
lda {{<plyrflags}}
ora #$08
sta {{<plyrflags}}
---
on joyright do with [Sprite]
---
lda {{<plyrflags}}
and #$f7
sta {{<plyrflags}}
---
end
system MoveJoyX
on joyleft do with [HasXpos]
---
lda {{<xpos}}
sec
sbc #1
bcc @nomove
sta {{<xpos}}
@nomove:
---
on joyright do with [HasXpos]
---
lda {{<xpos}}
clc
adc #1
cmp #152
bcs @nomove
sta {{<xpos}}
@nomove:
---
end
system MoveJoyY
on joyup do with [HasYpos]
---
lda {{<ypos}}
sec
sbc #1
bcc @nomove
sta {{<ypos}}
@nomove:
---
on joydown do with [HasYpos]
---
lda {{<ypos}}
clc
adc #1
cmp #220
bcs @nomove
sta {{<ypos}}
@nomove:
---
end
system SpriteShuffler
locals 2
on postframe do select [SpriteSlot]
---
; load two sprite slots at left side of array
lda {{<SpriteSlot:sprite}}
sta {{$0}}
lda {{<SpriteSlot:sprite}}+1
sta {{$1}}
; move two slots to the left
ldx #0
@loop:
lda {{<SpriteSlot:sprite}}+2,x
sta {{<SpriteSlot:sprite}},x
inx
cpx #{{%ecount}}-2
bne @loop
; store two sprite slots at right side of array
lda {{$0}}
sta {{<SpriteSlot:sprite}}+{{%ecount}}-2
lda {{$1}}
sta {{<SpriteSlot:sprite}}+{{%ecount}}-1
---
end
system SpriteHider
locals 1
on postframe do select [SpriteSlot]
---
lda #{{%efullcount}}-1
sta {{$0}}
---
on postframe do
join [SpriteSlot]
with [Sprite,HasYpos]
limit 2
---
lda {{<ypos}}
cmp #192
bcc @skip
; swap this sprite slot with slot at end of array
lda {{<SpriteSlot:sprite}},y
pha
ldx {{$0}} ; clobbers X, but no longer used
lda {{<SpriteSlot:sprite}},x
sta {{<SpriteSlot:sprite}},y
pla
sta {{<SpriteSlot:sprite}},x
dec {{$0}}
@skip:
---
end
///
demo Main
using FrameLoop, Kernel2Sprite
using Joystick, MoveJoyX, MoveJoyY
using SetXPos, SetHorizPos
using SpriteShuffler, SpriteHider
entity Kernel [KernelSection, BGColor]
const lines = 192
const bgcolor = 0xa2
end
entity Bitmap1 [Bitmap]
const bitmapdata = [1, 1, 3, 7, 15, 31, 63, 127]
const height = 8
end
entity Bitmap2 [Bitmap]
const bitmapdata = [$18,$3e,$ff,$ff,$ff,$ff,$3e,$18]
const height = 8
end
entity Colormap1 [Colormap]
const colormapdata = [6, 3, 6, 9, 12, 14, 31, 63]
end
entity Sprite0 [Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
init xpos = 50
init ypos = 150
init bitmap = #Bitmap2
init colormap = #Colormap1
const plyrflags = 0
end
entity Sprite1 [Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
init xpos = 100
init ypos = 60
init bitmap = #Bitmap1
init colormap = #Colormap1
const plyrflags = 3
end
entity Sprite2 [Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
init xpos = 80
init ypos = 90
init bitmap = #Bitmap2
init colormap = #Colormap1
const plyrflags = 2
end
entity Sprite3 [Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
init xpos = 40
init ypos = 150
init bitmap = #Bitmap1
init colormap = #Colormap1
const plyrflags = 0
end
/*
entity [Missile,HasXpos,HasYpos]
init xpos = 70
init ypos = 70
end
*/
entity Slot0 [SpriteSlot]
init sprite = #Sprite0
end
entity Slot1 [SpriteSlot]
init sprite = #Sprite1
end
entity Slot2 [SpriteSlot]
init sprite = #Sprite2
end
entity Slot3 [SpriteSlot]
init sprite = #Sprite3
end
end

565
test/ecs/sprites.txt Normal file
View File

@ -0,0 +1,565 @@
.scope Main
.zeropage
HasBitmap_bitmap_b0:
.res 1
.res 1
.res 1
.res 1
HasColormap_colormap_b0:
.res 1
.res 1
.res 1
.res 1
HasXpos_xpos_b0:
.res 1
.res 1
.res 1
.res 1
HasYpos_ypos_b0:
.res 1
.res 1
.res 1
.res 1
SpriteSlot_sprite_b0:
.res 1
.res 1
.res 1
.res 1
TEMP:
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
.res 1
Kernel2Sprite__2__tmp = TEMP+0
Joystick__3__tmp = TEMP+0
SpriteShuffler__8__tmp = TEMP+1
SpriteHider__9__tmp = TEMP+3
.code
KernelSection_lines_b0:
.byte 192
BGColor_bgcolor_b0:
.byte 162
Bitmap_bitmapdata_b0:
.byte <(Bitmap_bitmapdata_e1_b0+31)
.byte <(Bitmap_bitmapdata_e2_b0+31)
Bitmap_bitmapdata_b8:
.byte >(Bitmap_bitmapdata_e1_b0+31)
.byte >(Bitmap_bitmapdata_e2_b0+31)
Bitmap_bitmapdata_e1_b0:
.byte 1
.byte 1
.byte 3
.byte 7
.byte 15
.byte 31
.byte 63
.byte 127
Bitmap_height_b0:
.byte 8
.byte 8
Bitmap_bitmapdata_e2_b0:
.byte 24
.byte 62
.byte 255
.byte 255
.byte 255
.byte 255
.byte 62
.byte 24
Colormap_colormapdata_b0:
.byte <(Colormap_colormapdata_e3_b0+31)
Colormap_colormapdata_b8:
.byte >(Colormap_colormapdata_e3_b0+31)
Colormap_colormapdata_e3_b0:
.byte 6
.byte 3
.byte 6
.byte 9
.byte 12
.byte 14
.byte 31
.byte 63
Sprite_plyrflags_b0:
.byte 0
.byte 3
.byte 2
.byte 0
Main__INITDATA:
.byte 1
.byte 0
.byte 1
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 50
.byte 100
.byte 80
.byte 40
.byte 150
.byte 60
.byte 90
.byte 150
.byte 0
.byte 1
.byte 2
.byte 3
__Start:
.code
;;; start action Init 10 main_init
.include "vcs-ca65.h"
.macpack longbranch
.define PAL 0
__NMI:
__Reset:
__BRK:
CLEAN_START
ldy #20
: lda Main__INITDATA-1,y
sta HasBitmap_bitmap_b0-1,y
dey
bne :-
; initialize data segment
.code
;;; start action FrameLoop 1 start
FrameLoop__start__2__NextFrame:
FRAME_START
.code
;;; start action Kernel2Sprite 2 preframe
.define KLINES #192
.define KPAD 32
; set height to zero in case no sprites
lda #0
sta Kernel2Sprite__2__tmp+8
sta Kernel2Sprite__2__tmp+9
; set temp value so we don't read bitmap from h/w registers
lda #$F0
sta Kernel2Sprite__2__tmp+2
sta Kernel2Sprite__2__tmp+3
sta Kernel2Sprite__2__tmp+6
sta Kernel2Sprite__2__tmp+7
;;; end action Kernel2Sprite 2 preframe
;;; start action Kernel2Sprite 2 preframe
ldy #0
Kernel2Sprite__preframe__4____each:
ldx SpriteSlot_sprite_b0,y
; flags set according to sprite slot value
; skip sprite if negative
jmi Kernel2Sprite__preframe__4__nosprite
; set player object flags
lda Sprite_plyrflags_b0,x
sta NUSIZ0,y
sta REFP0,y
; calculate screen height - ypos
lda KLINES+KPAD
sec
sbc HasYpos_ypos_b0,x
sta Kernel2Sprite__2__tmp+11
; calculate bitmap pointer
stx Kernel2Sprite__2__tmp+12 ; save X (Sprite index)
lda HasBitmap_bitmap_b0,x ; deref bitmap
tax
lda Bitmap_bitmapdata_b0,x
sec
sbc Kernel2Sprite__2__tmp+11
sta Kernel2Sprite__2__tmp+0,y ; Y = sprite slot index
lda Bitmap_bitmapdata_b8,x
sbc #0
sta Kernel2Sprite__2__tmp+2,y
; get bitmap height
lda Bitmap_height_b0,x
sta Kernel2Sprite__2__tmp+8,y
; calculate colormap pointer
ldx Kernel2Sprite__2__tmp+12 ; restore X
lda HasColormap_colormap_b0,x ; deref colormap
tax
lda Colormap_colormapdata_b0,x
sec
sbc Kernel2Sprite__2__tmp+11
sta Kernel2Sprite__2__tmp+4,y
lda Colormap_colormapdata_b8,x
sbc #0
sta Kernel2Sprite__2__tmp+6,y
; save ypos
ldx Kernel2Sprite__2__tmp+12 ; restore X
lda HasYpos_ypos_b0,x
sta Kernel2Sprite__2__tmp+10,y
Kernel2Sprite__preframe__4__nosprite:
iny
cpy #2
jne Kernel2Sprite__preframe__4____each
Kernel2Sprite__preframe__4____exit:
;;; end action Kernel2Sprite 2 preframe
;;; start action Kernel2Sprite 2 preframe
; shuffle pointers into (MSB, LSB) byte order
; L0 L1 H0 H1 -> L0 H0 L1 H1
lda Kernel2Sprite__2__tmp+1
ldy Kernel2Sprite__2__tmp+2
sty Kernel2Sprite__2__tmp+1
sta Kernel2Sprite__2__tmp+2
lda Kernel2Sprite__2__tmp+5
ldy Kernel2Sprite__2__tmp+6
sty Kernel2Sprite__2__tmp+5
sta Kernel2Sprite__2__tmp+6
;;; end action Kernel2Sprite 2 preframe
;;; start action Kernel2Sprite 2 preframe
lda #162
sta COLUBK
;;; end action Kernel2Sprite 2 preframe
;;; start action Kernel2Sprite 2 preframe
;;; end action Kernel2Sprite 2 preframe
;;; start action SetXPos 6 preframe
sta HMCLR
;;; end action SetXPos 6 preframe
;;; start action SetXPos 6 preframe
ldy #0
SetXPos__preframe__8____each:
ldx SpriteSlot_sprite_b0,y
lda HasXpos_xpos_b0,x
.code
;;; start action SetHorizPos 7 SetHorizPos
; SetHorizPos routine
; A = X coordinate
; Y = player number (0 or 1)
sta WSYNC ; start a new line
sec ; set carry flag
nop
SetHorizPos__SetHorizPos__9__DivideLoop:
sbc #15 ; subtract 15
bcs SetHorizPos__SetHorizPos__9__DivideLoop ; branch until negative
eor #7 ; calculate fine offset
asl
asl
asl
asl
sta RESP0,y ; fix coarse position
sta HMP0,y ; set fine offset
;;; end action SetHorizPos 7 SetHorizPos
iny
cpy #2
jne SetXPos__preframe__8____each
SetXPos__preframe__8____exit:
;;; end action SetXPos 6 preframe
;;; start action SetXPos 6 preframe
;;; end action SetXPos 6 preframe
;;; start action SetXPos 6 preframe
sta WSYNC
sta HMOVE
;;; end action SetXPos 6 preframe
KERNEL_START
.code
;;; start action Kernel2Sprite 2 kernel
ldy #0
sty VDELP0
iny
sta VDELP1
;;; end action Kernel2Sprite 2 kernel
;;; start action Kernel2Sprite 2 kernel
ldy #192
Kernel2Sprite__kernel__12__LVScan:
.code
;;; start action Kernel2Sprite 2 scanline
; draw player 0
lda Kernel2Sprite__2__tmp+8 ; height
dcp Kernel2Sprite__2__tmp+10 ; ypos
bcs Kernel2Sprite__scanline__13__DoDraw1
lda #0
.byte $2C
Kernel2Sprite__scanline__13__DoDraw1:
lda (Kernel2Sprite__2__tmp+0),y
.if 0 = 0
sta WSYNC
.endif
sta GRP0
lda (Kernel2Sprite__2__tmp+4),y
sta COLUP0
; draw player 1
lda Kernel2Sprite__2__tmp+9 ; height
dcp Kernel2Sprite__2__tmp+11 ; ypos
bcs Kernel2Sprite__scanline__13__DoDraw2
lda #0
.byte $2C
Kernel2Sprite__scanline__13__DoDraw2:
lda (Kernel2Sprite__2__tmp+2),y
sta GRP1
lda (Kernel2Sprite__2__tmp+6),y
sta COLUP1
;;; end action Kernel2Sprite 2 scanline
;;; start action Kernel2Sprite 2 scanline
;;; end action Kernel2Sprite 2 scanline
dey ; next scanline
.code
;;; start action Kernel2Sprite 2 scanline
; draw player 0
lda Kernel2Sprite__2__tmp+8 ; height
dcp Kernel2Sprite__2__tmp+10 ; ypos
bcs Kernel2Sprite__scanline__14__DoDraw1
lda #0
.byte $2C
Kernel2Sprite__scanline__14__DoDraw1:
lda (Kernel2Sprite__2__tmp+0),y
.if 1 = 0
sta WSYNC
.endif
sta GRP0
lda (Kernel2Sprite__2__tmp+4),y
sta COLUP0
; draw player 1
lda Kernel2Sprite__2__tmp+9 ; height
dcp Kernel2Sprite__2__tmp+11 ; ypos
bcs Kernel2Sprite__scanline__14__DoDraw2
lda #0
.byte $2C
Kernel2Sprite__scanline__14__DoDraw2:
lda (Kernel2Sprite__2__tmp+2),y
sta GRP1
lda (Kernel2Sprite__2__tmp+6),y
sta COLUP1
;;; end action Kernel2Sprite 2 scanline
;;; start action Kernel2Sprite 2 scanline
;;; end action Kernel2Sprite 2 scanline
dey ; next scanline
bne Kernel2Sprite__kernel__12__LVScan ; repeat until out of lines
;;; end action Kernel2Sprite 2 kernel
;;; start action Kernel2Sprite 2 kernel
lda #0
sta GRP0
sta GRP1
sta GRP0
sta GRP1
;;; end action Kernel2Sprite 2 kernel
KERNEL_END
.code
;;; start action Joystick 3 postframe
; 2 control inputs share a single byte, 4 bits each
lda SWCHA
sta Joystick__3__tmp+0
;;; end action Joystick 3 postframe
;;; start action Joystick 3 postframe
ldx #0
Joystick__postframe__17____each:
asl Joystick__3__tmp+0
bcs Joystick__postframe__17__SkipMoveRight
.code
;;; start action MoveJoyX 4 joyright
lda HasXpos_xpos_b0,x
clc
adc #1
cmp #152
bcs MoveJoyX__joyright__18__nomove
sta HasXpos_xpos_b0,x
MoveJoyX__joyright__18__nomove:
;;; end action MoveJoyX 4 joyright
Joystick__postframe__17__SkipMoveRight:
asl Joystick__3__tmp+0
bcs Joystick__postframe__17__SkipMoveLeft
.code
;;; start action MoveJoyX 4 joyleft
lda HasXpos_xpos_b0,x
sec
sbc #1
bcc MoveJoyX__joyleft__19__nomove
sta HasXpos_xpos_b0,x
MoveJoyX__joyleft__19__nomove:
;;; end action MoveJoyX 4 joyleft
Joystick__postframe__17__SkipMoveLeft:
asl Joystick__3__tmp+0
bcs Joystick__postframe__17__SkipMoveDown
.code
;;; start action MoveJoyY 5 joydown
lda HasYpos_ypos_b0,x
clc
adc #1
cmp #220
bcs MoveJoyY__joydown__20__nomove
sta HasYpos_ypos_b0,x
MoveJoyY__joydown__20__nomove:
;;; end action MoveJoyY 5 joydown
Joystick__postframe__17__SkipMoveDown:
asl Joystick__3__tmp+0
bcs Joystick__postframe__17__SkipMoveUp
.code
;;; start action MoveJoyY 5 joyup
lda HasYpos_ypos_b0,x
sec
sbc #1
bcc MoveJoyY__joyup__21__nomove
sta HasYpos_ypos_b0,x
MoveJoyY__joyup__21__nomove:
;;; end action MoveJoyY 5 joyup
Joystick__postframe__17__SkipMoveUp:
inx
cpx #4
jne Joystick__postframe__17____each
Joystick__postframe__17____exit:
;;; end action Joystick 3 postframe
;;; start action SpriteShuffler 8 postframe
; load two sprite slots at left side of array
lda SpriteSlot_sprite_b0
sta SpriteShuffler__8__tmp+0
lda SpriteSlot_sprite_b0+1
sta SpriteShuffler__8__tmp+1
; move two slots to the left
ldx #0
SpriteShuffler__postframe__22__loop:
lda SpriteSlot_sprite_b0+2,x
sta SpriteSlot_sprite_b0,x
inx
cpx #4-2
bne SpriteShuffler__postframe__22__loop
; store two sprite slots at right side of array
lda SpriteShuffler__8__tmp+0
sta SpriteSlot_sprite_b0+4-2
lda SpriteShuffler__8__tmp+1
sta SpriteSlot_sprite_b0+4-1
;;; end action SpriteShuffler 8 postframe
;;; start action SpriteHider 9 postframe
lda #4-1
sta SpriteHider__9__tmp+0
;;; end action SpriteHider 9 postframe
;;; start action SpriteHider 9 postframe
ldy #0
SpriteHider__postframe__24____each:
ldx SpriteSlot_sprite_b0,y
lda HasYpos_ypos_b0,x
cmp #192
bcc SpriteHider__postframe__24__skip
; swap this sprite slot with slot at end of array
lda SpriteSlot_sprite_b0,y
pha
ldx SpriteHider__9__tmp+0 ; clobbers X, but no longer used
lda SpriteSlot_sprite_b0,x
sta SpriteSlot_sprite_b0,y
pla
sta SpriteSlot_sprite_b0,x
dec SpriteHider__9__tmp+0
SpriteHider__postframe__24__skip:
iny
cpy #2
jne SpriteHider__postframe__24____each
SpriteHider__postframe__24____exit:
;;; end action SpriteHider 9 postframe
FRAME_END
.code
jmp FrameLoop__start__2__NextFrame ; loop to next frame
;;; end action FrameLoop 1 start
; start main routine
.segment "VECTORS"
Return: .word $6060
VecNMI:
VecReset: .word Main::__Reset
VecBRK: .word Main::__BRK
;;; end action Init 10 main_init
.endscope
Main__Start = Main::__Start

524
test/ecs/superman.ecs Normal file
View File

@ -0,0 +1,524 @@
//#resource "vcs-ca65.h"
import "vcslib.ecs"
import "sprites.ecs"
// https://csanyk.com/2014/02/topology-metropolis-superman-atari-2600/
component RoomGraphics
graphics: array 0..8 of 0..255
end
component Room
fgcolor: 0..255
bgcolor: 0..255
gfx: [VersatilePlayfield]
north: [Room]
east: [Room]
south: [Room]
west: [Room]
end
component Location
room: [Room]
end
component Enemy
end
component Moving
speed: 1..15
end
system SuperFly
on gowest do with [Location]
---
ldy {{<room}}
lda {{<Room:west}},y
sta {{<room}}
---
on goeast do with [Location]
---
ldy {{<room}}
lda {{<Room:east}},y
sta {{<room}}
---
on gonorth do with [Location]
---
ldy {{<room}}
lda {{<Room:north}},y
sta {{<room}}
---
on gosouth do with [Location]
---
ldy {{<room}}
lda {{<Room:south}},y
sta {{<room}}
---
on joyleft do with [Location,HasXpos,Moving]
---
lda {{<xpos}}
sec
sbc {{<speed}}
jcs @nomove
{{!gowest}}
lda #142
@nomove:
sta {{<xpos}}
---
on joyright do with [Location,HasXpos,Moving]
---
lda {{<xpos}}
clc
adc {{<speed}}
cmp #142
jcc @nomove
{{!goeast}}
lda #2
@nomove:
sta {{<xpos}}
---
on joyup do with [Location,HasYpos,Moving]
---
lda {{<ypos}}
sec
sbc {{<speed}}
jcs @nomove
{{!gonorth}}
lda #200
@nomove:
sta {{<ypos}}
---
on joydown do with [Location,HasYpos,Moving]
---
lda {{<ypos}}
clc
adc {{<speed}}
cmp #220
jcc @nomove
{{!gosouth}}
lda #2
@nomove:
sta {{<ypos}}
---
end
system BadMove
on postframe do foreach [Enemy]
---
{{!joyright}}
---
end
system RoomShuffle
on postframe do select [Location,Sprite]
---
ldy {{%ecount}}
ldx {{<Slot1.sprite}}
bmi @empty ; empty slot, load 1st entry
@loop:
inx
cpx {{%ecount}}
bcc @norecycle
; TODO: need to get index of specific entity
@empty:
ldx #1 ; skip null sprite and super dude?
@norecycle:
lda {{<Location:room}},x
cmp {{<Superdude.room}}
beq @exit
dey
bne @loop
ldx #$ff
@exit:
stx {{<Slot1.sprite}}
---
end
scope Main
using FrameLoop, Kernel2Sprite
using Joystick, JoyFaceDirection
using SuperFly
using BadMove
using RoomShuffle
//using MoveJoyX, MoveJoyY
using SetXPos, SetHorizPos
//using SpriteShuffler, SpriteHider
entity Kernel [KernelSection, BGColor]
const lines = 192
const bgcolor = 0xa2
end
entity NullShape [Bitmap,Colormap]
decode vcs_sprite
---
---
end
entity Superdude1 [Bitmap,Colormap]
decode vcs_sprite
---
......xx 52
.....xx. 54
x....xx. 48
.x...xx. 48
..x..xxx 48
...x.xx. 48
....xx.. 46
...xxx.. 88
...xxx.. 86
..xxxx.x 86
..xxxxx. 86
.xxx.x.. 86
.xxx.... 88
xxx..... 86
xxx..... 86
xx...... 86
xx...... 46
x....... 46
---
end
entity BexButhor1 [Bitmap,Colormap]
decode vcs_sprite
---
x....... 04
.xx..... 04
..xx.... 04
..x.x... 04
..x..... 04
..x..xx. 46
..x.xxx. 48
..x.xxx. 48
..x.xxxx 48
..x.xxx. 48
..x.xxx. 48
..x.xx.. 46
..xxxxx. 2a
..xxxxx. 2a
..xxxxxx 28
..xxxxxx 28
..xxxxxx 28
...xxxxx 28
...xxxx. 28
....xxx. 26
....xx.. c8
....xx.. c8
....xx.. c8
....xx.. c6
....xx.. c6
....xx.. c6
....xxx. 04
....xxx. 04
---
end
entity NullRoom [Room,VersatilePlayfield]
const fgcolor = $0
const bgcolor = $0
const north = #NullRoom
const south = #NullRoom
const east = #NullRoom
const west = #NullRoom
const data = [0]
end
entity InsideDailyPlanet [Room,VersatilePlayfield]
const fgcolor = $0c
const bgcolor = $12
const north = #InsideDailyPlanet
const south = #InsideDailyPlanet
const east = #OutsideDailyPlanet
const west = #OutsideDailyPlanet
decode vcs_versatile
---
.................... .. c0 ..
.................... .. .. 01
.................... 08 .. ..
.................... .. .. ..
.................... .. .. ..
.................... .. .. ..
.................... .. .. ..
..................xx .. .. ..
.....xxxx.........xx .. .. ..
.....xxxx........xxx .. .. ..
.....xxxx.......xxxx .. .. ..
.....xxxx.......xxxx .. .. ..
.....xxxx.......xxxx .. .. ..
.....xxxx.......xxx. .. .. ..
.....xxxx.......xx.. .. .. ..
.....xxxx.......x... .. .. ..
.....xxxx.......x..x .. .. ..
.....xxxx.......x.xx .. .. ..
.....xxxx.......x.xx .. .. ..
.....xxxx.......x.xx .. 60 ..
.....xxxxxxx....x.xx .. .. ..
.xx..xxxxxxx....x.xx .. .. ..
.xx..xxxxxxx....x..x .. .. ..
.xx..xxxxxxx....x... .. .. ..
.xx..xxxxxxx....xx.. .. .. ..
.xx..xxxxxxx....xxx. .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xx.x .. 50 ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. 44 ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. 46 ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. 38 ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
xxxx.xxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. 00
xxxxxxxxxxxxxxxxxxxx .. c8 ..
xxxxxxxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxx...xxx .. .. ..
xxxxxxxxxxxxx.....xx .. .. ..
xxxxxxxxxxxxx.....xx .. .. ..
xxxxxxxxxxxx.......x .. .. ..
xxxxxxxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx 08 .. ..
xxxxxxxxxxxxxxxxxxxx 06 .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. 18 ..
xxxx.x.x.x.xxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
---
end
// xxxxxxx....xxxxxx...
// xxx...x.x...xxxx..xx
// xxx.x....x....xx....
entity OutsideDailyPlanet [Room,VersatilePlayfield]
const fgcolor = $0c
const bgcolor = $12
const north = #InsideDailyPlanet
const south = #InsideDailyPlanet
const east = #InsideDailyPlanet
const west = #InsideDailyPlanet
//9f9f 9f 0c fc 3e 38 46 44 506070a0000000
decode vcs_versatile
---
.................... .. 70 ..
.................... .. .. 01
.................... a8 .. ..
.................... .. .. ..
.................... .. .. ..
.................... .. .. ..
.................... .. .. ..
..................xx .. .. ..
.....xxxx.........xx .. .. ..
.....xxxx........xxx .. .. ..
.....xxxx.......xxxx .. .. ..
.....xxxx.......xxxx .. .. ..
.....xxxx.......xxxx .. .. ..
.....xxxx.......xxx. .. .. ..
.....xxxx.......xx.. .. .. ..
.....xxxx.......x... .. .. ..
.....xxxx.......x..x .. .. ..
.....xxxx.......x.xx .. .. ..
.....xxxx.......x.xx .. .. ..
.....xxxx.......x.xx .. 60 ..
.....xxxxxxx....x.xx .. .. ..
.xx..xxxxxxx....x.xx .. .. ..
.xx..xxxxxxx....x..x .. .. ..
.xx..xxxxxxx....x... .. .. ..
.xx..xxxxxxx....xx.. .. .. ..
.xx..xxxxxxx....xxx. .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xx.x .. 50 ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. 44 ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xx.x.xx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xx.x .. .. ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx....xxxx .. 46 ..
.xx..xxxxxxx....xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxx.xx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. 38 ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
.xx..xxxxxxxxxx.xxxx .. .. ..
xxxx.xxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxxx.xxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. 00
xxxxxxxxxxxxxxxxxxxx .. c8 ..
xxxxxxxx.xxxxxxxxxxx .. .. ..
xxxxxxxx.xxxxxxxxxxx .. .. ..
xxxxxxx...xxxxxxxxxx .. .. ..
xxxxxx.....xxxxxxxxx .. .. ..
xxxxxx.....xxxxxxxxx .. .. ..
xxxxx.......xxxxxxxx .. .. ..
xxxxxxxx.xxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx .. .. ..
xxxxxxxxxxxxxxxxxxxx 08 .. ..
xxxxxxxxxxxxxxxxxxxx 06 .. ..
xxxxxxxxxxxxxxxxxxxx .. 06 ..
x.x.xxxxxxxxxxxxxxxx .. .. ..
x.x.x.x.x.x.xxxxxxxx .. .. ..
x.x.x.x.x.x.x.x.x.x. .. .. ..
x.x.x.x.x.x.x.x.x.x. .. .. ..
x.x.x.x.x.x.x.x.x.x. .. 18 ..
x.x.x.x.x.x.x.x.x.x. .. 06 ..
3f 3f
3f 3f
3f 3f
3f 3f
3f 3f
3f 3f
3f 3f
3f 3f
---
end
/*
entity NullSprite [Location,Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
var ypos = 224
const bitmap = #BexButhor1
const colormap = #BexButhor1
const plyrflags = $00
end
*/
entity Superdude [Location,Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player,Moving]
var room = #OutsideDailyPlanet
var xpos = 40
var ypos = 30
const bitmap = #Superdude1
const colormap = #Superdude1
var plyrflags = $05
const speed = 2
end
entity BexButhor [Location,Sprite,HasXpos,HasYpos,HasBitmap,HasColormap,Enemy,Moving]
var room = #OutsideDailyPlanet
var xpos = 100
var ypos = 30
const bitmap = #BexButhor1
const colormap = #BexButhor1
var plyrflags = $00
const speed = 1
end
entity JBexButhor [Location,Sprite,HasXpos,HasYpos,HasBitmap,HasColormap,Enemy,Moving]
var room = #OutsideDailyPlanet
var xpos = 100
var ypos = 60
const bitmap = #BexButhor1
const colormap = #BexButhor1
var plyrflags = $00
const speed = 1
end
entity KBexButhor [Location,Sprite,HasXpos,HasYpos,HasBitmap,HasColormap,Enemy,Moving]
var room = #InsideDailyPlanet
var xpos = 50
var ypos = 90
const bitmap = #BexButhor1
const colormap = #BexButhor1
var plyrflags = $00
const speed = 1
end
entity Slot0 [SpriteSlot]
var sprite = #Superdude
end
entity Slot1 [SpriteSlot]
var sprite = $ff
end
using VersatilePlayfield with #Superdude.room
end
/*
InsideDailyPlanetDS
.word SubwayGraphics
.byte WHITE - 2
.byte BLUE + 10
.byte <GreenSubwayDS ; pointer to north room
.byte <BlueSubwayDS ; pointer to east room
.byte <YellowSubwayDS ; pointer to south room
.byte <PinkSubwayDS ; pointer to west room
*/

1199
test/ecs/superman.txt Normal file

File diff suppressed because it is too large Load Diff

131
test/ecs/titles.ecs Normal file
View File

@ -0,0 +1,131 @@
//#resource "vcs-ca65.h"
import "vcslib.ecs"
component Bitmap48
bitmap0: array of 0..0xff
bitmap1: array of 0..0xff
bitmap2: array of 0..0xff
bitmap3: array of 0..0xff
bitmap4: array of 0..0xff
bitmap5: array of 0..0xff
height: 0..255
end
system Kernel48Pixel
locals 2
on kernelsetup do if [Bitmap48] ---
lda {{<height}}
sta {{$0}} ; scanline counter
lda #$22
sta COLUP0 ; show how players alternate
lda #$12
sta COLUP1 ; by having different colors
lda #3
sta NUSIZ0
sta NUSIZ1 ; both players have 3 copies
sta WSYNC
SLEEPH 34
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
SLEEPH 24 ; sleep 24 cycles
sta HMCLR ; clear HMOVE registers
lda #1
sta VDELP0 ; we need the VDEL registers
sta VDELP1 ; so we can do our 4-store trick
---
/* already exists on StaticKernel
on kernelsetup do if [BGColor] ---
lda {{<bgcolor}}
sta COLUBK
---
*/
on kernelsetup do if [PFColor] ---
lda {{<pfcolor}}
sta COLUP0
sta COLUP1
---
on kerneldraw do if [Bitmap48] ---
txa
pha
@Loop:
ldy {{$0}} ; counts backwards
sta WSYNC ; sync to next scanline
lda {{data bitmap0}},y ; load B0 (1st sprite byte)
sta GRP0 ; B0 -> [GRP0]
lda {{data bitmap1}},y ; load B1 -> A
sta GRP1 ; B1 -> [GRP1], B0 -> GRP0
lda {{data bitmap2}},y ; load B2 -> A
sta GRP0 ; B2 -> [GRP0], B1 -> GRP1
lda {{data bitmap5}},y ; load B5 -> A
sta {{$1}} ; B5 -> temp
ldx {{data bitmap4}},y ; load B4 -> X
lda {{data bitmap3}},y ; load B3 -> A
ldy {{$1}} ; 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 {{$0}} ; go to next line
bpl @Loop ; repeat until < 0
pla
tax
---
end
demo Main
//using FrameLoop, StaticKernel, Kernel48Pixel
using FrameLoop, Kernel48Pixel, StaticKernel
// TODO
entity [KernelSection, BGColor]
const lines = 10
const bgcolor = $a0
end
entity [KernelSection, BGColor]
const lines = 10
const bgcolor = $a2
end
entity [KernelSection, BGColor, PFColor, Bitmap48]
const lines = 2
const bgcolor = 0xa4
const pfcolor = 0xfc
decode vcs_bitmap48 ---
x.............................................xx
xx.........................................xxx.x
xxxx....................................xxx....x
xx..xxxx..............................xx.......x
xx......xx...........................x.........x
xx...x....x............xx............x.........x
xx...x....x...........x..x.........xx..........x
xx...x..x..x....x......xx.....x...x............x
xx...xxxx...x...xxx...x..x..xxx..x.............x
xx...x..x..x......x....xx...x.....x............x
xx...x....x...........x..x.........xx..........x
xx......xx.............xx............x.........x
xx..xxxx..............................xx.......x
xxxx....................................xxxxxxxx
................................................
---
end
entity [KernelSection, BGColor]
const lines = 10
const bgcolor = $a2
end
entity [KernelSection, BGColor]
const lines = 10
const bgcolor = $a0
end
end

369
test/ecs/titles.txt Normal file
View File

@ -0,0 +1,369 @@
.scope Main
.zeropage
TEMP:
.res 1
.res 1
Kernel48Pixel__2__tmp = TEMP+0
.code
KernelSection_lines_b0:
.byte 10
.byte 10
.byte 2
.byte 10
.byte 10
BGColor_bgcolor_b0:
.byte 160
.byte 162
.byte 164
.byte 162
.byte 160
PFColor_pfcolor_b0:
.byte 252
Bitmap48_bitmap0_b0:
.byte <Bitmap48_bitmap0_e2_b0
Bitmap48_bitmap0_b8:
.byte >Bitmap48_bitmap0_e2_b0
Bitmap48_bitmap0_e2_b0:
.byte 0
.byte 240
.byte 207
.byte 192
.byte 196
.byte 196
.byte 199
.byte 196
.byte 196
.byte 196
.byte 192
.byte 207
.byte 240
.byte 192
.byte 128
Bitmap48_bitmap1_b0:
.byte <Bitmap48_bitmap1_e2_b0
Bitmap48_bitmap1_b8:
.byte >Bitmap48_bitmap1_e2_b0
Bitmap48_bitmap1_e2_b0:
.byte 0
.byte 0
.byte 0
.byte 192
.byte 32
.byte 144
.byte 136
.byte 144
.byte 32
.byte 32
.byte 192
.byte 0
.byte 0
.byte 0
.byte 0
Bitmap48_bitmap2_b0:
.byte <Bitmap48_bitmap2_e2_b0
Bitmap48_bitmap2_b8:
.byte >Bitmap48_bitmap2_e2_b0
Bitmap48_bitmap2_e2_b0:
.byte 0
.byte 0
.byte 0
.byte 1
.byte 2
.byte 33
.byte 226
.byte 129
.byte 2
.byte 1
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
Bitmap48_bitmap3_b0:
.byte <Bitmap48_bitmap3_e2_b0
Bitmap48_bitmap3_b8:
.byte >Bitmap48_bitmap3_e2_b0
Bitmap48_bitmap3_e2_b0:
.byte 0
.byte 0
.byte 0
.byte 128
.byte 64
.byte 136
.byte 78
.byte 130
.byte 64
.byte 128
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
Bitmap48_bitmap4_b0:
.byte <Bitmap48_bitmap4_e2_b0
Bitmap48_bitmap4_b8:
.byte >Bitmap48_bitmap4_e2_b0
Bitmap48_bitmap4_e2_b0:
.byte 0
.byte 0
.byte 3
.byte 4
.byte 24
.byte 32
.byte 64
.byte 32
.byte 24
.byte 4
.byte 4
.byte 3
.byte 0
.byte 0
.byte 0
Bitmap48_bitmap5_b0:
.byte <Bitmap48_bitmap5_e2_b0
Bitmap48_bitmap5_b8:
.byte >Bitmap48_bitmap5_e2_b0
Bitmap48_bitmap5_e2_b0:
.byte 0
.byte 255
.byte 1
.byte 1
.byte 1
.byte 1
.byte 1
.byte 1
.byte 1
.byte 1
.byte 1
.byte 1
.byte 225
.byte 29
.byte 3
Bitmap48_height_b0:
.byte 14
__Start:
.code
;;; start action Init 4 main_init
.include "vcs-ca65.h"
.macpack longbranch
.define PAL 0
__NMI:
__Reset:
__BRK:
CLEAN_START
; initialize data segment
.code
;;; start action FrameLoop 1 start
FrameLoop__start__2__NextFrame:
FRAME_START
.code
;;; start action StaticKernel 3 preframe
.code
;;; start action Kernel48Pixel 2 kernelsetup
;;; end action Kernel48Pixel 2 kernelsetup
;;; start action Kernel48Pixel 2 kernelsetup
;;; end action Kernel48Pixel 2 kernelsetup
;;; start action StaticKernel 3 kernelsetup
lda #160
sta COLUBK
;;; end action StaticKernel 3 kernelsetup
;;; start action StaticKernel 3 kernelsetup
;;; end action StaticKernel 3 kernelsetup
;;; start action StaticKernel 3 kernelsetup
;;; end action StaticKernel 3 kernelsetup
;;; end action StaticKernel 3 preframe
KERNEL_START
.code
;;; start action StaticKernel 3 kernel
ldx #0
StaticKernel__kernel__5____each:
sta WSYNC
.code
;;; start action Kernel48Pixel 2 kernelsetup
cpx #2+1
jcs Kernel48Pixel__kernelsetup__6____skipxhi
cpx #2
jcc Kernel48Pixel__kernelsetup__6____skipxlo
lda #14
sta Kernel48Pixel__2__tmp+0 ; scanline counter
lda #$22
sta COLUP0 ; show how players alternate
lda #$12
sta COLUP1 ; by having different colors
lda #3
sta NUSIZ0
sta NUSIZ1 ; both players have 3 copies
sta WSYNC
SLEEPH 34
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
SLEEPH 24 ; sleep 24 cycles
sta HMCLR ; clear HMOVE registers
lda #1
sta VDELP0 ; we need the VDEL registers
sta VDELP1 ; so we can do our 4-store trick
Kernel48Pixel__kernelsetup__6____skipxlo:
Kernel48Pixel__kernelsetup__6____skipxhi:
;;; end action Kernel48Pixel 2 kernelsetup
;;; start action Kernel48Pixel 2 kernelsetup
cpx #2+1
jcs Kernel48Pixel__kernelsetup__7____skipxhi
cpx #2
jcc Kernel48Pixel__kernelsetup__7____skipxlo
lda #252
sta COLUP0
sta COLUP1
Kernel48Pixel__kernelsetup__7____skipxlo:
Kernel48Pixel__kernelsetup__7____skipxhi:
;;; end action Kernel48Pixel 2 kernelsetup
;;; start action StaticKernel 3 kernelsetup
lda BGColor_bgcolor_b0,x
sta COLUBK
;;; end action StaticKernel 3 kernelsetup
;;; start action StaticKernel 3 kernelsetup
cpx #2+1
jcs StaticKernel__kernelsetup__9____skipxhi
cpx #2
jcc StaticKernel__kernelsetup__9____skipxlo
lda #252
sta COLUPF
StaticKernel__kernelsetup__9____skipxlo:
StaticKernel__kernelsetup__9____skipxhi:
;;; end action StaticKernel 3 kernelsetup
;;; start action StaticKernel 3 kernelsetup
;;; end action StaticKernel 3 kernelsetup
.code
;;; start action Kernel48Pixel 2 kerneldraw
cpx #2+1
jcs Kernel48Pixel__kerneldraw__10____skipxhi
cpx #2
jcc Kernel48Pixel__kerneldraw__10____skipxlo
txa
pha
Kernel48Pixel__kerneldraw__10__Loop:
ldy Kernel48Pixel__2__tmp+0 ; counts backwards
sta WSYNC ; sync to next scanline
lda Bitmap48_bitmap0_e2_b0,y ; load B0 (1st sprite byte)
sta GRP0 ; B0 -> [GRP0]
lda Bitmap48_bitmap1_e2_b0,y ; load B1 -> A
sta GRP1 ; B1 -> [GRP1], B0 -> GRP0
lda Bitmap48_bitmap2_e2_b0,y ; load B2 -> A
sta GRP0 ; B2 -> [GRP0], B1 -> GRP1
lda Bitmap48_bitmap5_e2_b0,y ; load B5 -> A
sta Kernel48Pixel__2__tmp+1 ; B5 -> temp
ldx Bitmap48_bitmap4_e2_b0,y ; load B4 -> X
lda Bitmap48_bitmap3_e2_b0,y ; load B3 -> A
ldy Kernel48Pixel__2__tmp+1 ; 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 Kernel48Pixel__2__tmp+0 ; go to next line
bpl Kernel48Pixel__kerneldraw__10__Loop ; repeat until < 0
pla
tax
Kernel48Pixel__kerneldraw__10____skipxlo:
Kernel48Pixel__kerneldraw__10____skipxhi:
;;; end action Kernel48Pixel 2 kerneldraw
;;; start action StaticKernel 3 kerneldraw
ldy KernelSection_lines_b0,x
StaticKernel__kerneldraw__11__loop:
sta WSYNC
dey
bne StaticKernel__kerneldraw__11__loop
;;; end action StaticKernel 3 kerneldraw
inx
cpx #5
jne StaticKernel__kernel__5____each
StaticKernel__kernel__5____exit:
;;; end action StaticKernel 3 kernel
KERNEL_END
.code
FRAME_END
.code
jmp FrameLoop__start__2__NextFrame ; loop to next frame
;;; end action FrameLoop 1 start
; start main routine
.segment "VECTORS"
Return: .word $6060
VecNMI:
VecReset: .word Main::__Reset
VecBRK: .word Main::__BRK
;;; end action Init 4 main_init
.endscope
Main__Start = Main::__Start