From 0451e8ea33e8d6ff6e22060b64311ca92a01838d Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Wed, 16 Feb 2022 14:50:48 -0600 Subject: [PATCH] ecs: fixed indexregister offset, for now --- src/common/ecs/ecs.ts | 53 +- src/test/testecs.ts | 50 +- test/ecs/score.ecs | 299 ++++++++++ test/ecs/score.txt | 423 +++++++++++++++ test/ecs/sprites.ecs | 440 +++++++++++++++ test/ecs/sprites.txt | 565 +++++++++++++++++++ test/ecs/superman.ecs | 524 ++++++++++++++++++ test/ecs/superman.txt | 1199 +++++++++++++++++++++++++++++++++++++++++ test/ecs/titles.ecs | 131 +++++ test/ecs/titles.txt | 369 +++++++++++++ 10 files changed, 4008 insertions(+), 45 deletions(-) create mode 100644 test/ecs/score.ecs create mode 100644 test/ecs/score.txt create mode 100644 test/ecs/sprites.ecs create mode 100644 test/ecs/sprites.txt create mode 100644 test/ecs/superman.ecs create mode 100644 test/ecs/superman.txt create mode 100644 test/ecs/titles.ecs create mode 100644 test/ecs/titles.txt diff --git a/src/common/ecs/ecs.ts b/src/common/ecs/ecs.ts index eaae6441..2b50c45a 100644 --- a/src/common/ecs/ecs.ts +++ b/src/common/ecs/ecs.ts @@ -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}`; } } diff --git a/src/test/testecs.ts b/src/test/testecs.ts index eb4af3ed..3402813f 100644 --- a/src/test/testecs.ts +++ b/src/test/testecs.ts @@ -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}`); + } + }); }); }); diff --git a/test/ecs/score.ecs b/test/ecs/score.ecs new file mode 100644 index 00000000..b3ae2924 --- /dev/null +++ b/test/ecs/score.ecs @@ -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 {{ [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 {{{{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 diff --git a/test/ecs/score.txt b/test/ecs/score.txt new file mode 100644 index 00000000..173c7927 --- /dev/null +++ b/test/ecs/score.txt @@ -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 + 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 + 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 \ No newline at end of file diff --git a/test/ecs/sprites.ecs b/test/ecs/sprites.ecs new file mode 100644 index 00000000..aa28b6ab --- /dev/null +++ b/test/ecs/sprites.ecs @@ -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 {{Bitmap:bitmapdata}},x + sbc #0 + sta {{$2}},y +; get bitmap height + lda {{Colormap:colormapdata}},x + sbc #0 + sta {{$6}},y +; save ypos + ldx {{$12}} ; restore X + lda {{ 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 {{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 {{(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 \ No newline at end of file diff --git a/test/ecs/superman.ecs b/test/ecs/superman.ecs new file mode 100644 index 00000000..137bc1ba --- /dev/null +++ b/test/ecs/superman.ecs @@ -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 {{(Bitmap_bitmapdata_e1_b0+31) +.byte >(Bitmap_bitmapdata_e2_b0+31) +.byte >(Bitmap_bitmapdata_e3_b0+31) +Bitmap_bitmapdata_e1_b0: +Bitmap_height_b0: +.byte 255 +.byte 17 +.byte 27 +Colormap_colormapdata_b0: +.byte <(Colormap_colormapdata_e1_b0+31) +.byte <(Colormap_colormapdata_e2_b0+31) +.byte <(Colormap_colormapdata_e3_b0+31) +Colormap_colormapdata_b8: +.byte >(Colormap_colormapdata_e1_b0+31) +.byte >(Colormap_colormapdata_e2_b0+31) +.byte >(Colormap_colormapdata_e3_b0+31) +Colormap_colormapdata_e1_b0: +Bitmap_bitmapdata_e2_b0: +.byte 128 +.byte 192 +.byte 192 +.byte 224 +.byte 224 +.byte 112 +.byte 116 +.byte 62 +.byte 61 +.byte 28 +.byte 28 +.byte 12 +.byte 22 +.byte 39 +.byte 70 +.byte 134 +.byte 6 +.byte 3 +Colormap_colormapdata_e2_b0: +.byte 70 +.byte 70 +.byte 134 +.byte 134 +.byte 134 +.byte 136 +.byte 134 +.byte 134 +.byte 134 +.byte 134 +.byte 136 +.byte 70 +.byte 72 +.byte 72 +.byte 72 +.byte 72 +.byte 84 +.byte 82 +Bitmap_bitmapdata_e3_b0: +.byte 14 +.byte 14 +.byte 12 +.byte 12 +.byte 12 +.byte 12 +.byte 12 +.byte 12 +.byte 14 +.byte 30 +.byte 31 +.byte 63 +.byte 63 +.byte 63 +.byte 62 +.byte 62 +.byte 44 +.byte 46 +.byte 46 +.byte 47 +.byte 46 +.byte 46 +.byte 38 +.byte 32 +.byte 40 +.byte 48 +.byte 96 +.byte 128 +Colormap_colormapdata_e3_b0: +.byte 4 +.byte 4 +.byte 198 +.byte 198 +.byte 198 +.byte 200 +.byte 200 +.byte 200 +.byte 38 +.byte 40 +.byte 40 +.byte 40 +.byte 40 +.byte 40 +.byte 42 +.byte 42 +.byte 70 +.byte 72 +.byte 72 +.byte 72 +.byte 72 +.byte 72 +.byte 70 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +Room_fgcolor_b0: +.byte 0 +.byte 12 +.byte 12 +Room_bgcolor_b0: +.byte 0 +.byte 18 +.byte 18 +Room_north_b0: +.byte 0 +.byte 1 +.byte 1 +Room_east_b0: +.byte 0 +.byte 2 +.byte 1 +Room_south_b0: +.byte 0 +.byte 1 +.byte 1 +Room_west_b0: +.byte 0 +.byte 2 +.byte 1 +VersatilePlayfield_data_b0: +.byte <(VersatilePlayfield_data_e4_b0+-1) +.byte <(VersatilePlayfield_data_e5_b0+-1) +.byte <(VersatilePlayfield_data_e6_b0+-1) +VersatilePlayfield_data_b8: +.byte >(VersatilePlayfield_data_e4_b0+-1) +.byte >(VersatilePlayfield_data_e5_b0+-1) +.byte >(VersatilePlayfield_data_e6_b0+-1) +VersatilePlayfield_data_e4_b0: +.byte 0 +VersatilePlayfield_data_e5_b0: +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 255 +.byte 14 +.byte 85 +.byte 14 +.byte 24 +.byte 9 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 6 +.byte 8 +.byte 0 +.byte 63 +.byte 255 +.byte 15 +.byte 247 +.byte 15 +.byte 128 +.byte 15 +.byte 0 +.byte 63 +.byte 193 +.byte 15 +.byte 227 +.byte 15 +.byte 0 +.byte 63 +.byte 247 +.byte 15 +.byte 200 +.byte 9 +.byte 0 +.byte 10 +.byte 255 +.byte 15 +.byte 255 +.byte 14 +.byte 240 +.byte 13 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 56 +.byte 9 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 247 +.byte 15 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 246 +.byte 15 +.byte 0 +.byte 63 +.byte 70 +.byte 9 +.byte 240 +.byte 15 +.byte 0 +.byte 63 +.byte 176 +.byte 15 +.byte 127 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 107 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 68 +.byte 9 +.byte 240 +.byte 15 +.byte 0 +.byte 63 +.byte 176 +.byte 15 +.byte 127 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 107 +.byte 14 +.byte 240 +.byte 15 +.byte 80 +.byte 9 +.byte 176 +.byte 15 +.byte 127 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 107 +.byte 14 +.byte 240 +.byte 15 +.byte 112 +.byte 15 +.byte 48 +.byte 15 +.byte 16 +.byte 15 +.byte 144 +.byte 15 +.byte 96 +.byte 13 +.byte 127 +.byte 14 +.byte 96 +.byte 9 +.byte 0 +.byte 63 +.byte 208 +.byte 15 +.byte 144 +.byte 15 +.byte 16 +.byte 15 +.byte 48 +.byte 15 +.byte 112 +.byte 15 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 240 +.byte 15 +.byte 224 +.byte 15 +.byte 120 +.byte 14 +.byte 192 +.byte 15 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 8 +.byte 8 +.byte 1 +.byte 10 +.byte 192 +.byte 9 +VersatilePlayfield_data_e6_b0: +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 63 +.byte 6 +.byte 9 +.byte 24 +.byte 9 +.byte 0 +.byte 63 +.byte 85 +.byte 15 +.byte 170 +.byte 14 +.byte 80 +.byte 13 +.byte 6 +.byte 9 +.byte 6 +.byte 8 +.byte 8 +.byte 8 +.byte 255 +.byte 14 +.byte 247 +.byte 14 +.byte 128 +.byte 14 +.byte 0 +.byte 63 +.byte 193 +.byte 14 +.byte 227 +.byte 14 +.byte 0 +.byte 63 +.byte 247 +.byte 14 +.byte 200 +.byte 9 +.byte 0 +.byte 10 +.byte 255 +.byte 15 +.byte 255 +.byte 14 +.byte 240 +.byte 13 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 56 +.byte 9 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 247 +.byte 15 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 246 +.byte 15 +.byte 0 +.byte 63 +.byte 70 +.byte 9 +.byte 240 +.byte 15 +.byte 0 +.byte 63 +.byte 176 +.byte 15 +.byte 127 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 107 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 68 +.byte 9 +.byte 240 +.byte 15 +.byte 0 +.byte 63 +.byte 176 +.byte 15 +.byte 127 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 107 +.byte 14 +.byte 240 +.byte 15 +.byte 80 +.byte 9 +.byte 176 +.byte 15 +.byte 127 +.byte 14 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 107 +.byte 14 +.byte 240 +.byte 15 +.byte 112 +.byte 15 +.byte 48 +.byte 15 +.byte 16 +.byte 15 +.byte 144 +.byte 15 +.byte 96 +.byte 13 +.byte 127 +.byte 14 +.byte 96 +.byte 9 +.byte 0 +.byte 63 +.byte 208 +.byte 15 +.byte 144 +.byte 15 +.byte 16 +.byte 15 +.byte 48 +.byte 15 +.byte 112 +.byte 15 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 240 +.byte 15 +.byte 224 +.byte 15 +.byte 120 +.byte 14 +.byte 192 +.byte 15 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 0 +.byte 63 +.byte 168 +.byte 8 +.byte 1 +.byte 10 +.byte 112 +.byte 9 +HasBitmap_bitmap_b0: +.byte 1 +.byte 2 +.byte 2 +.byte 2 +HasColormap_colormap_b0: +.byte 1 +.byte 2 +.byte 2 +.byte 2 +Moving_speed_b0: +.byte 2 +.byte 1 +.byte 1 +.byte 1 +Main__INITDATA: +.byte 2 +.byte 2 +.byte 2 +.byte 1 +.byte 5 +.byte 0 +.byte 0 +.byte 0 +.byte 40 +.byte 100 +.byte 100 +.byte 50 +.byte 30 +.byte 30 +.byte 60 +.byte 90 +.byte 0 +.byte 255 +.byte 0 +.byte 0 +.byte 0 +__Start: +.code + +;;; start action Init 11 main_init + +.include "vcs-ca65.h" +.macpack longbranch +.define PAL 0 +__NMI: +__Reset: +__BRK: + CLEAN_START + + ldy #21 +: lda Main__INITDATA-1,y + sta Location_room_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 8 preframe + + sta HMCLR + +;;; end action SetXPos 8 preframe + +;;; start action SetXPos 8 preframe + + ldy #0 +SetXPos__preframe__8____each: + ldx SpriteSlot_sprite_b0,y + + lda HasXpos_xpos_b0,x + .code + +;;; start action SetHorizPos 9 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 9 SetHorizPos + + + iny + cpy #2 + jne SetXPos__preframe__8____each +SetXPos__preframe__8____exit: + +;;; end action SetXPos 8 preframe + +;;; start action SetXPos 8 preframe + +;;; end action SetXPos 8 preframe + +;;; start action SetXPos 8 preframe + + sta WSYNC + sta HMOVE + +;;; end action SetXPos 8 preframe + +;;; start action VersatilePlayfield 10 preframe + + ldx Location_room_b0+0 + + lda VersatilePlayfield_data_b0,x + sta VersatilePlayfield__10__tmp+0 + lda VersatilePlayfield_data_b8,x + sta VersatilePlayfield__10__tmp+1 + + +;;; end action VersatilePlayfield 10 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__13__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__14__DoDraw1 + lda #0 + .byte $2C +Kernel2Sprite__scanline__14__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__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 + +;;; start action VersatilePlayfield 10 scanline + +.if 0 = 0 + lda (VersatilePlayfield__10__tmp+0),y + tax +.endif + +;;; end action VersatilePlayfield 10 scanline + +;;; start action VersatilePlayfield 10 scanline + +.if 0 = 1 + lda (VersatilePlayfield__10__tmp+0),y + sta $00,x +.endif + +;;; end action VersatilePlayfield 10 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__17__DoDraw1 + lda #0 + .byte $2C +Kernel2Sprite__scanline__17__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__17__DoDraw2 + lda #0 + .byte $2C +Kernel2Sprite__scanline__17__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 + +;;; start action VersatilePlayfield 10 scanline + +.if 1 = 0 + lda (VersatilePlayfield__10__tmp+0),y + tax +.endif + +;;; end action VersatilePlayfield 10 scanline + +;;; start action VersatilePlayfield 10 scanline + +.if 1 = 1 + lda (VersatilePlayfield__10__tmp+0),y + sta $00,x +.endif + +;;; end action VersatilePlayfield 10 scanline + + dey ; next scanline + bne Kernel2Sprite__kernel__13__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 + + asl Joystick__3__tmp+0 + bcs Joystick__postframe__22__SkipMoveRight + .code + +;;; start action JoyFaceDirection 4 joyright + + lda Sprite_plyrflags_b0 + and #$f7 + sta Sprite_plyrflags_b0 + +;;; end action JoyFaceDirection 4 joyright + +;;; start action SuperFly 5 joyright + + lda HasXpos_xpos_b0 + clc + adc #2 + cmp #142 + jcc SuperFly__joyright__24__nomove + .code + +;;; start action SuperFly 5 goeast + + ldy Location_room_b0 + lda Room_east_b0,y + sta Location_room_b0 + +;;; end action SuperFly 5 goeast + + lda #2 +SuperFly__joyright__24__nomove: + sta HasXpos_xpos_b0 + +;;; end action SuperFly 5 joyright + +Joystick__postframe__22__SkipMoveRight: + asl Joystick__3__tmp+0 + bcs Joystick__postframe__22__SkipMoveLeft + .code + +;;; start action JoyFaceDirection 4 joyleft + + lda Sprite_plyrflags_b0 + ora #$08 + sta Sprite_plyrflags_b0 + +;;; end action JoyFaceDirection 4 joyleft + +;;; start action SuperFly 5 joyleft + + lda HasXpos_xpos_b0 + sec + sbc #2 + jcs SuperFly__joyleft__27__nomove + .code + +;;; start action SuperFly 5 gowest + + ldy Location_room_b0 + lda Room_west_b0,y + sta Location_room_b0 + +;;; end action SuperFly 5 gowest + + lda #142 +SuperFly__joyleft__27__nomove: + sta HasXpos_xpos_b0 + +;;; end action SuperFly 5 joyleft + +Joystick__postframe__22__SkipMoveLeft: + asl Joystick__3__tmp+0 + bcs Joystick__postframe__22__SkipMoveDown + .code + +;;; start action SuperFly 5 joydown + + lda HasYpos_ypos_b0 + clc + adc #2 + cmp #220 + jcc SuperFly__joydown__29__nomove + .code + +;;; start action SuperFly 5 gosouth + + ldy Location_room_b0 + lda Room_south_b0,y + sta Location_room_b0 + +;;; end action SuperFly 5 gosouth + + lda #2 +SuperFly__joydown__29__nomove: + sta HasYpos_ypos_b0 + +;;; end action SuperFly 5 joydown + +Joystick__postframe__22__SkipMoveDown: + asl Joystick__3__tmp+0 + bcs Joystick__postframe__22__SkipMoveUp + .code + +;;; start action SuperFly 5 joyup + + lda HasYpos_ypos_b0 + sec + sbc #2 + jcs SuperFly__joyup__31__nomove + .code + +;;; start action SuperFly 5 gonorth + + ldy Location_room_b0 + lda Room_north_b0,y + sta Location_room_b0 + +;;; end action SuperFly 5 gonorth + + lda #200 +SuperFly__joyup__31__nomove: + sta HasYpos_ypos_b0 + +;;; end action SuperFly 5 joyup + +Joystick__postframe__22__SkipMoveUp: + +;;; end action Joystick 3 postframe + +;;; start action BadMove 6 postframe + + ldx #0 +BadMove__postframe__33____each: + + .code + +;;; start action JoyFaceDirection 4 joyright + + lda Sprite_plyrflags_b0+1,x + and #$f7 + sta Sprite_plyrflags_b0+1,x + +;;; end action JoyFaceDirection 4 joyright + +;;; start action SuperFly 5 joyright + + lda HasXpos_xpos_b0+1,x + clc + adc #1 + cmp #142 + jcc SuperFly__joyright__35__nomove + .code + +;;; start action SuperFly 5 goeast + + ldy Location_room_b0+1,x + lda Room_east_b0,y + sta Location_room_b0+1,x + +;;; end action SuperFly 5 goeast + + lda #2 +SuperFly__joyright__35__nomove: + sta HasXpos_xpos_b0+1,x + +;;; end action SuperFly 5 joyright + + + inx + cpx #3 + jne BadMove__postframe__33____each +BadMove__postframe__33____exit: + +;;; end action BadMove 6 postframe + +;;; start action RoomShuffle 7 postframe + + ldy 4 + ldx SpriteSlot_sprite_b0+1 + bmi RoomShuffle__postframe__37__empty ; empty slot, load 1st entry +RoomShuffle__postframe__37__loop: + inx + cpx 4 + bcc RoomShuffle__postframe__37__norecycle +; TODO: need to get index of specific entity +RoomShuffle__postframe__37__empty: + ldx #1 ; skip null sprite and super dude? +RoomShuffle__postframe__37__norecycle: + lda Location_room_b0,x + cmp Location_room_b0 + beq RoomShuffle__postframe__37__exit + dey + bne RoomShuffle__postframe__37__loop + ldx #$ff +RoomShuffle__postframe__37__exit: + stx SpriteSlot_sprite_b0+1 + +;;; end action RoomShuffle 7 postframe + +;;; start action VersatilePlayfield 10 postframe + + lda #0 + sta PF0 + sta PF1 + sta PF2 + +;;; end action VersatilePlayfield 10 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 11 main_init + +.endscope +Main__Start = Main::__Start \ No newline at end of file diff --git a/test/ecs/titles.ecs b/test/ecs/titles.ecs new file mode 100644 index 00000000..b42f6389 --- /dev/null +++ b/test/ecs/titles.ecs @@ -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 {{ [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 diff --git a/test/ecs/titles.txt b/test/ecs/titles.txt new file mode 100644 index 00000000..7e030e86 --- /dev/null +++ b/test/ecs/titles.txt @@ -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_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_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_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_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_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_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 \ No newline at end of file