minor fixes

This commit is contained in:
Steven Hugg 2019-06-03 10:08:29 -04:00
parent b3861f3361
commit baa9ed7482
19 changed files with 380 additions and 176 deletions

View File

@ -46,7 +46,6 @@ TODO:
- debug bankswitching for funky formats
- spaces in filename don't parse code listing (DASM, maybe more)
- 'undefined' for bitmap replacer
- astrocade: run to cursor in hello world messes up emulation
- requestInterrupt needs to be disabled after breakpoint?
- C/asm formatter
- fix WebAudio (https://news.ycombinator.com/item?id=18066474)
@ -66,6 +65,7 @@ TODO:
- sdcc:
- can't link asm files before c files (e.g. acheader.s must be last)
- figure out area names ordering
- debug inline asm
- live coding URL
- resize memory browser when vertical div resize
- preroll the emulator so optimizer does its thing before loading rom
@ -146,7 +146,7 @@ TODO:
- don't have to include bootstrap-tourist each time?
- don't have to include firebase always?
- squelch error msgs?
- test offline?
- test offline? (if window.firebase)
- Github
- gh-pages branch with embedded
- handle overwrite logic

View File

@ -275,6 +275,18 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<span class="control-def"><span class="control-key">A W S D</span> Move</span>
<span class="control-def"><span class="control-key">&#x2190;&#x2191;&#x2193;&#x2192;</span> Fire</span>
</div>
<div class="emucontrols-astrocade text-center small control-insns" style="display:none">
<span class="control-def"><span class="control-key">&#x2190;&#x2191;&#x2193;&#x2192;</span> Joystick</span>
<span class="control-def"><span class="control-key small">Space</span> Trigger</span>
<span class="control-def"><span class="control-key small">Mouse X</span> Knob</span>
<span class="control-def"><span class="control-key small" style="display:inline-block;font-family:monospace">
C A Z P<br>
R S H /<br>
7 8 9 X<br>
4 5 6 -<br>
1 2 3 ,<br>
E 0 . =</span> Keypad</span>
</div>
<!-- -->
<div id="emuoverlay" class="emuoverlay" style="display:none">
</div>

View File

@ -71,12 +71,16 @@ word* USERTB; // user routine table (-128 bytes)
// from bmusic.c
extern void music_update(void);
// INTERRUPT HANDLERS
// must be in 0x200 page
void hw_interrupt() __naked {
__asm__("ei");
__asm__("exx");
// INTERRUPT HANDLER
//#define USE_ALT_REGS
void hw_interrupt()
#ifdef USE_ALT_REGS
__naked {
__asm__("ex af,af'");
__asm__("exx");
#else
__interrupt {
#endif
CT[0]++;
CT[1]++;
CT[2]++;
@ -97,9 +101,12 @@ void hw_interrupt() __naked {
music_update();
}
}
#ifdef USE_ALT_REGS
__asm__("exx");
__asm__("ex af,af'");
__asm__("ei");
__asm__("reti");
#endif
}
void add_counters(byte mask, byte delta) {
@ -134,11 +141,18 @@ void TIMEY() {
void TIMEX() {
}
void DECCTS(ContextBlock *ctx) {
add_counters(_C, -1);
}
// INTERPRETER
void INTPC(ContextBlock *ctx) {
while (ctx->params[0] != 2) { // 2 = exit
SYSCALL(ctx);
}
ctx->params++; // skip EXIT opcode
}
// never called, hopefully
@ -164,6 +178,10 @@ void MRET(ContextBlock *ctx) {
ctx; // TODO
}
void NOOP(ContextBlock *ctx) {
ctx;
}
// jump within MCALL
void MJUMP(ContextBlock *ctx) {
ctx->params = (byte*) _HL; // TODO?
@ -225,13 +243,7 @@ void SETOUT(ContextBlock *ctx) {
// set entire palette at once (8 bytes to port 0xb)
// bytes in array should be in reverse
void set_palette(byte palette[8]) __z88dk_fastcall {
palette;
__asm
ld bc,#0x80b ; B -> 8, C -> 0xb
otir ; write C bytes from HL to port[B]
__endasm;
}
void set_palette(byte palette[8]) __z88dk_fastcall;
// sets color palettes from (HL)
void COLSET(ContextBlock *ctx) {
@ -260,25 +272,10 @@ void PAWS(ContextBlock *ctx) {
// MATH
void MOVE(ContextBlock *ctx) {
byte* dest = (byte*) _DE;
const byte* src = (const byte*) _HL;
word nb = _BC;
memcpy(dest, src, nb);
memcpy((byte*)_DE, (const byte*)_HL, _BC);
}
word bcdadd8(byte a, byte b, byte c) {
a;b;c;
__asm
ld a,6(ix) ; carry
rrc a ; set carry bit
ld h,#0 ; carry goes here
ld a,4(ix) ; a -> A
adc a,5(ix) ; a + b -> A
daa ; BCD conversion
ld l,a ; result -> L
rl h ; carry -> H
__endasm;
}
word bcdadd8(byte a, byte b, byte c);
void BCDADD(ContextBlock *ctx) {
byte* dest = (byte*) _DE;
@ -308,12 +305,7 @@ void RANGED(ContextBlock *ctx) {
// input
const byte KCTASC_TABLE[25] = {
0x00,
0x43, 0x5e, 0x5c, 0x25, 0x52, 0x53, 0x3b, 0x2f,
0x37, 0x38, 0x39, 0x2a, 0x34, 0x35, 0x36, 0x2d,
0x31, 0x32, 0x33, 0x2b, 0x26, 0x30, 0x2e, 0x3d
};
extern const byte KCTASC_TABLE[25];
void KCTASC(ContextBlock *ctx) {
_A = KCTASC_TABLE[_B];
@ -360,7 +352,7 @@ const SysCallEntry SYSCALL_TABLE[64] = {
{ &MJUMP, REG_HL },
{ &SUCK, REG_B },
{ &ACTINT, 0 },
{ 0, 0 },
{ &DECCTS, REG_C },
{ &BMUSIC, REG_HL|REG_IX|REG_A },
/* 20 */
{ &EMUSIC, },
@ -369,64 +361,64 @@ const SysCallEntry SYSCALL_TABLE[64] = {
{ &FILL, REG_A|REG_BC|REG_DE },
{ &RECTAN, REG_A|REG_B|REG_C|REG_D|REG_E },
/* 30 */
{ /*&VWRITR*/0, 0 },
{ &NOOP, REG_HL|REG_IX }, // VWRITR
{ &WRITR, REG_E|REG_D|REG_A|REG_HL },
{ &WRITP, REG_E|REG_D|REG_A|REG_HL },
{ &WRIT, REG_E|REG_D|REG_C|REG_B|REG_A|REG_HL },
{ /*&WRITA*/0, 0 },
{ &NOOP, REG_E|REG_D|REG_C|REG_B|REG_A|REG_HL }, // WRITA
/* 40 */
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, REG_E|REG_D|REG_IX }, // VBLANK
{ &NOOP, REG_E|REG_D|REG_B|REG_HL }, // BLANK
{ &NOOP, REG_B|REG_C|REG_DE|REG_HL }, // SAVE
{ &NOOP, REG_DE|REG_HL }, // RESTORE
{ &NOOP, REG_B|REG_C|REG_DE|REG_HL }, // SCROLL
/* 50 */
{ &CHRDIS, REG_E|REG_D|REG_C|REG_A },
{ &STRDIS, REG_E|REG_D|REG_C|REG_HL },
{ &DISNUM, REG_E|REG_D|REG_C|REG_B|REG_HL },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, REG_DE|REG_A }, // RELABS
{ &NOOP, REG_E|REG_D|REG_A }, // RELAB1
/* 60 */
{ 0, 0 },
{ 0, 0 },
{ &NOOP, REG_IX|REG_HL|REG_C }, // VECTC
{ &NOOP, REG_IX|REG_HL }, // VECT
{ &KCTASC, 0 },
{ &SENTRY, REG_DE },
{ &DOIT, REG_HL },
/* 70 */
{ &DOITB, REG_HL },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, 0 }, // PIZBRK
{ &NOOP, REG_DE|REG_HL }, // MENU
{ &NOOP, REG_BC|REG_HL }, // GETPAR
{ &NOOP, REG_B|REG_C|REG_D|REG_E|REG_HL }, // GETNUM
/* 80 */
{ &PAWS, REG_B },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, REG_E|REG_D|REG_C }, // DISTIM
{ &NOOP, REG_HL }, // INCSCR
{ &NOOP, REG_C|REG_HL }, // INDEXN
{ &NOOP, REG_HL }, // STOREN
/* 90 */
{ 0, 0 },
{ 0, 0 },
{ &NOOP, REG_A|REG_HL }, // INDEXW
{ &NOOP, REG_A|REG_HL }, // INDEXB
{ &MOVE, REG_DE|REG_BC|REG_HL },
{ 0, 0 },
{ &NOOP, 0 }, // SHIFTU
{ &BCDADD, REG_DE|REG_B|REG_HL },
/* 100 */
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, 0 }, // BCDSUB
{ &NOOP, 0 }, // BCDMUL
{ &NOOP, 0 }, // BCDDIV
{ &NOOP, 0 }, // BCDCHS
{ &NOOP, 0 }, // BCDNEG
/* 110 */
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, 0 }, // DADD
{ &NOOP, 0 }, // DSMG
{ &NOOP, 0 }, // DABS
{ &NOOP, 0 }, // NEGT
{ &RANGED, REG_A },
/* 120 */
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ &NOOP, 0 }, // QUIT
{ &NOOP, REG_A|REG_HL }, // SETB
{ &NOOP, REG_DE|REG_HL }, // SETW
{ &NOOP, REG_C|REG_DE|REG_HL }, // MSKTD
};
void SYSCALL(ContextBlock *ctx) {
@ -447,22 +439,17 @@ void SYSCALL(ContextBlock *ctx) {
suckParams(ctx, argmask);
}
// call the routine
if (routine) {
routine(ctx);
}
routine(ctx);
}
void bios_init() {
ContextBlock ctx;
memset((void*)0x4fce, 0, 0x5000-0x4fce);
ACTINT(0);
hw_verbl = 96*2;
hw_horcb = 41;
hw_inmod = 0x8;
// clear shifter
hw_magic = 0;
*((byte*)0x4fce) = 0;
hw_magic = 0;
// call SENTRY once to set current values
// (context block doesn't matter)
SENTRY((ContextBlock*)0x4fce);
SENTRY(&ctx);
}

View File

@ -1,10 +1,8 @@
;#link "bioslib.c"
TEST = 1
.module biosasm
.globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT
.module biosasm
.globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT
BIOSStart:
di ; disable interrupts
@ -33,8 +31,9 @@ FoundSentinel:
ld H,(HL)
ld L,A
jp (HL) ; jump to cart start vector
.ds 0x38 - (. - BIOSStart) ; eat up space until 0x38
.globl SYSCALL38
.ds 0x38 - (. - BIOSStart) ; eat up space until 0x38
.globl SYSCALL38
SYSCALL38:
push hl
push af
@ -56,53 +55,44 @@ SYSCALL38:
ret
; out to port
.globl _portOut
.globl _portOut
_portOut:
ld c,h
out (c),l
ret
; TODO?
ReloadRegs:
ld c,(hl)
inc hl
ld b,(hl)
inc hl
push bc
pop iy
ld c,(hl)
inc hl
ld b,(hl)
inc hl
push bc
.globl _bcdadd8
_bcdadd8:
push ix
ld ix,#0
add ix,sp
ld a,6(ix) ; carry
rrc a ; set carry bit
ld h,#0 ; carry goes here
ld a,4(ix) ; a -> A
adc a,5(ix) ; a + b -> A
daa ; BCD conversion
ld l,a ; result -> L
rl h ; carry -> H
pop ix
ld c,(hl)
inc hl
ld b,(hl)
inc hl
push bc
pop de
ld c,(hl)
inc hl
ld b,(hl)
inc hl
push bc
ld c,(hl)
inc hl
ld b,(hl)
inc hl
push bc
pop af
ld c,(hl)
inc hl
ld b,(hl)
inc hl
push bc
pop hl
pop bc
ret
.ds 0x200 - (. - BIOSStart) ; eat up space until 0x200
ret
;void set_palette(byte palette[8]) __z88dk_fastcall;
.globl _set_palette
_set_palette:
ld bc,#0x80b ; B -> 8, C -> 0xb
otir ; write C bytes from HL to port[B]
ret
.globl _KCTASC_TABLE
_KCTASC_TABLE:
.db 0x00
.db 0x43, 0x5e, 0x5c, 0x25, 0x52, 0x53, 0x3b, 0x2f
.db 0x37, 0x38, 0x39, 0x2a, 0x34, 0x35, 0x36, 0x2d
.db 0x31, 0x32, 0x33, 0x2b, 0x26, 0x30, 0x2e, 0x3d
.ds 0x200 - (. - BIOSStart) ; eat up space until 0x200
DOPEVector:
JP _STIMER
JP _CTIMER
@ -110,5 +100,8 @@ DOPEVector:
.dw _BIGFONT
.db 0xa0, 4, 6, 1, 5 ; Font descriptor (small font)
.dw _SMLFONT
.db 0x3f ; all keys mask
.db 0x3f
.db 0x3f
.db 0x3f

View File

@ -147,7 +147,7 @@ void CHRDIS(ContextBlock *ctx) {
}
// BCD routine
const char BCDTAB[17] = "0123456789*+,-./";
const char BCDTAB[18] = "0123456789*+,-./ ";
// DISNUM - (E.D) x/y (C) options (B) ext (HL) BCD-addr
void DISNUM(ContextBlock *ctx) {
@ -170,6 +170,11 @@ void DISNUM(ContextBlock *ctx) {
val &= 15;
pbcd--;
}
if (val == 0 && noleadingzero) {
val = 16;
} else {
noleadingzero = 0;
}
x += draw_char(font, BCDTAB[val]+add, x, y, opt);
}
}

View File

@ -55,6 +55,7 @@ void SENTRY(ContextBlock *ctx) {
}
}
// key up?
// TODO: race condition with KEYSEX and interrupt
if (key && key != KEYSEX) {
B = KEYSEX = key;
A = SKYD;

View File

@ -19,7 +19,7 @@ _main:
pop ix
SYSTEM INTPC
DO SETOUT
.db 89*2, 23, 0x00
.db 102*2, 23, 0x00
DONT EMUSIC
DONT ACTINT
DO COLSET
@ -89,11 +89,12 @@ _main:
.dw 3
.dw _BCDNUM
DO BMUSIC
.dw 0x4000
.dw 0x4e80
.db 0b11111100
.dw ANTHEM
; exit interpreter
EXIT
nop
.loop:
SYSSUK DISNUM
.db 80
@ -149,7 +150,7 @@ keymask:
BCDNUM = 0x4ea0 ; RAM
_BCDNUM:
.db 0x97,0x34,0x12
.db 0x97,0x99,0x09
BCDINC:
.db 0x01,0x00,0x00
; Critter Pattern

View File

@ -15,8 +15,41 @@ typedef struct {
const byte* chartab;
} FontDescriptor;
const FontDescriptor __at(0x206) FNTSYS;
const FontDescriptor __at(0x20d) FNTSML;
const FontDescriptor __at(0x206) FNTSYS; // system font
const FontDescriptor __at(0x20d) FNTSML; // small font
const byte __at(0x214) ALKEYS[4]; // "all keys" keyboard mask
// SENTRY
typedef enum {
SNUL,
SCT0,SCT1,SCT2,SCT3,SCT4,SCT5,SCT6,SCT7,
SF0,SF1,SF2,SF3,SF4,SF5,SF6,SF7,
SSEC,
SKYU,SKYD,
ST0,SJ0,ST1,SJ1,ST2,SJ2,ST3,SJ3,
SP0,SP1,SP2,SP3
} SENTRYCode;
typedef struct {
byte code;
word address;
} DOITEntry;
#define DOIT_END 0xff
// PATTERNS
typedef struct {
sbyte xofs, yofs;
byte xsize, ysize;
byte pattern[0];
} RelativeBlock;
typedef struct {
byte xsize, ysize;
byte pattern[0];
} PatternBlock;
// FUNCTIONS
@ -47,8 +80,11 @@ void display_bcd_number(byte x, byte y, byte options, const byte* number, byte e
void bcdn_add(byte* dest, byte size, const byte* n);
void bcdn_sub(byte* dest, byte size, const byte* n);
byte ranged_random(byte n) __z88dk_fastcall;
byte keycode_to_ascii(byte n) __z88dk_fastcall;
word sense_transition(const byte* keypad_mask) __z88dk_fastcall;
word sense_transition(const byte keypad_mask[4]) __z88dk_fastcall;
void respond_to_input(const DOITEntry* doit_table, byte a);
void respond_to_input_b(const DOITEntry* doit_table, byte b);
void begin_music(const byte* stack, byte voices, const byte* musicdata);
void end_music(void);
@ -69,6 +105,13 @@ void end_music(void);
__asm__(".dw "#count);\
__asm__(".db "#val);\
#define SYS_MOVE(dest,src,count)\
__asm__("rst 0x38");\
__asm__(".db 0x5f");\
__asm__(".dw "#dest);\
__asm__(".dw "#count);\
__asm__(".dw "#src);\
#define RESET_TIMEOUT() \
__asm__("ld a,#0xff");\
__asm__("ld (0x4FEC),a");

View File

@ -3,7 +3,7 @@
;;; C functions
.area _LIB
.area _CODE_ACBIOS
; activate interrupts
.globl _activate_interrupts
@ -99,6 +99,13 @@ _ranged_random:
SYSTEM RANGED
ret
; KCTASC n
.globl _keycode_to_ascii
_keycode_to_ascii:
ld a,l
SYSTEM KCTASC
ret
; BLANK w h data video-addr
.globl _blank_area
_blank_area:
@ -116,6 +123,20 @@ _sense_transition:
ld h,b
ret
; DOIT table-addr
.globl _respond_to_input
_respond_to_input:
call load5_edca_hl
SYSTEM DOIT
ret
; DOITB table-addr
.globl _respond_to_input_b
_respond_to_input_b:
call load5_edca_hl
SYSTEM DOIT
ret
; BMUSIC stack-addr voices score-addr
.globl _begin_music
_begin_music:

View File

@ -4,6 +4,9 @@
#include "aclib.h"
// special case for draw_sprite()
#define M_ERASE 0x04
// font constants
#define LOCHAR 32
#define HICHAR 127

View File

@ -0,0 +1,34 @@
.area _CODE_ACFAST
;void fast_sprite_8(const byte* src, byte* dst) {
.globl _fast_sprite_8
_fast_sprite_8:
push ix
ld ix,#0
add ix,sp
ld l,4(ix) ; src (HL)
ld h,5(ix)
ld e,6(ix) ; dst (DE)
ld d,7(ix)
inc hl ; skip width
ld c,(hl) ; load height -> C
sla c ; C *= 2
ld b,#0 ; B always 0 (BC < 256)
inc hl ; move to pattern bytes
001$:
ldi
ldi ; copy 2 bytes src to dst
ld a,b ; 0 -> A, doesnt affect flags
ld (de),a ; copy 3rd 0 (for shifts)
jp po,002$ ; exit if BC == 0
ld a,e ; E -> A
add a,#38 ; next scanline (dest += 38)
ld e,a ; A -> E
jr nc,001$ ; loop unless lo byte overflow
inc d ; inc hi byte of dest. addr
jr 001$ ; loop to next line
002$:
pop ix
ret

View File

@ -52,14 +52,16 @@ __sfr __at(0x18) hw_sndbx;
#define M_SHIFT1 0x01
#define M_SHIFT2 0x02
#define M_SHIFT3 0x03
#define M_ROTATE 0x04
#define M_XPAND 0x08
#define M_MOVE 0x00
#define M_OR 0x10
#define M_XOR 0x20
#define M_FLOP 0x40
#define M_SHIFT(x) ((x)&3)
#define XPAND_COLORS(off,on) (((off)&3) | (((on)&3)<<2))
#define M_ERASE 0x04 // special case for draw_sprite()
#define VTOTAL 102 // number of total scanlines
#define VHEIGHT 89 // number of scanlines in use

View File

@ -0,0 +1,87 @@
//#resource "astrocade.inc"
#include "aclib.h"
//#link "aclib.c"
#include "acbios.h"
//#link "acbios.s"
//#link "acfast.s"
//#link "hdr_autostart.s"
#include <stdlib.h>
#include <string.h>
#pragma opt_code_speed
/*{pal:"astrocade",layout:"astrocade"}*/
const byte palette[8] = {
0x77, 0xBC, 0x35, 0x01,
0x07, 0xF2, 0x64, 0x01,
};
const byte SPRITE[] = {
2,8,
/*{w:8,h:8,bpp:2,brev:1}*/
0x01,0x40, 0x06,0x90, 0x15,0x54, 0x47,0x51,
0x45,0xD1, 0x05,0x50, 0x04,0x10, 0x3C,0x3C,
};
extern void fast_sprite_8(const byte* pattern, byte* dst);
#define MAX_SPRITES 8
typedef struct {
byte x; // x coordinate
byte y; // y coordinate
byte lastmagic; // last magic byte used
byte* lastdest; // last destination address
const byte* pattern; // pattern definition
byte _unused;
} Actor;
Actor actors[MAX_SPRITES];
void erase_actor(Actor* actor) {
hw_magic = actor->lastmagic;
fast_sprite_8(actor->pattern, actor->lastdest);
}
void draw_actor(Actor* actor) {
byte op = M_XOR;
byte x = actor->x;
byte y = actor->y;
actor->lastdest = &vmagic[y][x>>2];// destination address
actor->lastmagic = M_SHIFT(x) | op; // set magic register
erase_actor(actor);
}
void main(void) {
byte i;
// setup palette
set_palette(palette);
// set screen height
// set horizontal color split (position / 4)
// set interrupt status
SYS_SETOUT(89*2, 0, 0);
// clear screen
SYS_FILL(0x4000, 89*40, 0);
// infinite loop
activate_interrupts();
// fill array
for (i=0; i<MAX_SPRITES; i++) {
actors[i].x = rand() & 0x7f;
actors[i].y = (i*4);
actors[i].pattern = SPRITE;
draw_actor(&actors[i]);
}
while (1) {
fast_vsync();
hw_col0r = 0x2;
for (i=0; i<MAX_SPRITES; i++) {
Actor* a = &actors[i];
erase_actor(a);
draw_actor(a);
a->x++;
}
hw_col0r = 0x1;
}
}

View File

@ -27,28 +27,12 @@ const byte BALL[] = {
0b01111000,
};
const byte BALL2[] = {
0, 0, // x and y offset
1, 6, // width (bytes) and height (lines)
/*{w:16,h:6,brev:1}*/
0b1111000,
0b11011100,
0b10111000,
0b110100,
0b11100000,
0b1111000,
0b1000000,
0b11010100,
0b10111100,
0b10110100,
0b11111000,
0b1111000,
};
// BCD number
byte bcdnum[3] = {0x56,0x34,0x12};
const byte bcdinc[3] = {0x01,0x00,0x00};
const byte keypadMask[4] = { 0x3f,0x3f,0x3f,0x3f };
void _clear() {
}
void main(void) {
// setup palette
@ -58,7 +42,7 @@ void main(void) {
// set interrupt status
SYS_SETOUT(89*2, 23, 0);
// clear screen
SYS_FILL(0x4000, 89*2, 0);
SYS_FILL(0x4000, 89*40, 0);
// display standard characters
display_string(2, 2, OPT_ON(1), "HELLO, WORLD!\xb1\xb2\xb3\xb4\xb5");
// 2x2 must have X coordinate multiple of 2
@ -87,8 +71,20 @@ void main(void) {
// make sure screen doesn't black out
RESET_TIMEOUT();
while (1) {
display_bcd_number(80, 80, OPT_ON(2), bcdnum, 6|DISBCD_SML|DISBCD_NOZERO);
bcdn_add(bcdnum, 3, bcdinc);
while (sense_transition(keypadMask) == 0);
// wait for SENTRY result
word code;
do {
code = sense_transition(ALKEYS);
} while (code == 0);
// respond to SENTRY
switch (code & 0xff) {
case SSEC:
display_bcd_number(80, 80, OPT_ON(2), bcdnum, 6|DISBCD_SML|DISBCD_NOZERO);
bcdn_add(bcdnum, 3, bcdinc);
break;
case SP0:
hw_horcb = (code>>8)>>2;
break;
}
}
}

View File

@ -2,12 +2,26 @@
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
// include NESLIB header
#include "neslib.h"
// include CC65 NES Header (PPU)
#include <nes.h>
// link the pattern table into CHR ROM
//#link "chr_generic.s"
// BCD arithmetic support
#include "bcd.h"
//#link "bcd.c"
// VRAM update buffer
#include "vrambuf.h"
//#link "vrambuf.c"
/*{pal:"nes",layout:"nes"}*/
const char PALETTE[32] = {
0x03, // screen color

View File

@ -652,7 +652,7 @@ export abstract class BaseZ80Platform extends BaseDebugPlatform {
}
getToolForFilename = getToolForFilename_z80;
getDefaultExtension() { return ".c"; };
// TODO
// TODO: Z80 opcode metadata
//this.getOpcodeMetadata = function() { }
getDebugCategories() {

View File

@ -145,18 +145,17 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
// or/xor
if (magicop & 0x30) {
var oldv = ram.mem[a];
// collision detect
var icpt = 0;
if ((oldv & 0xc0) && (v & 0xc0)) icpt |= 0x1;
if ((oldv & 0x30) && (v & 0x30)) icpt |= 0x2;
if ((oldv & 0x0c) && (v & 0x0c)) icpt |= 0x4;
if ((oldv & 0x03) && (v & 0x03)) icpt |= 0x8;
// apply op
if (magicop & 0x10)
v |= oldv;
if (magicop & 0x20)
v ^= oldv; // TODO: what if both?
// collision detect
var icpt = 0;
for (var i=0; i<8; i+=2) {
icpt <<= 1;
// pixel changed from off to on?
if ( !((oldv>>i)&3) && ((v>>i)&3) )
icpt |= 1;
}
// upper 4 bits persist, lower are just since last write
inputs[8] = (inputs[8] & 0xf0) | icpt | (icpt<<4);
}
@ -202,9 +201,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
[0x0000, 0x3fff, 0xfff, magicwrite],
]),
// TODO: correct values?
// TODO: no contention on hblank
isContended: () => { return true; },
contend: () => { return vidactive ? 1 : 0; },
contend: (addr:number) => { return vidactive && addr >= 0x4000 ? 1 : 0; },
};
} else {
// arcade game
@ -220,7 +218,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
[0x0000, 0x3fff, 0x3fff, magicwrite],
]),
isContended: () => { return true; },
contend: () => { return vidactive ? 1 : 0; },
contend: (addr:number) => { return vidactive ? 1 : 0; },
};
}
iobus = {
@ -266,7 +264,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
break;
case 0xc: // magic register
magicop = val;
//shift2 = 0; // TODO?
shift2 = 0; // TODO?
xplower = false;
break;
case 0xd: // INFBK (interrupt feedback)

View File

@ -12,11 +12,11 @@ const JSNES_PRESETS = [
{id:'hello.c', name:'Hello World'},
{id:'attributes.c', name:'Attribute Table'},
{id:'scroll.c', name:'Scrolling'},
{id:'vrambuffer.c', name:'VRAM Buffer'},
{id:'sprites.c', name:'Sprites'},
{id:'metasprites.c', name:'Metasprites'},
{id:'flicker.c', name:'Flickering Sprites'},
{id:'metacursor.c', name:'Controllers'},
{id:'vrambuffer.c', name:'VRAM Buffer'},
{id:'tint.c', name:'Color Emphasis'},
{id:'rletitle.c', name:'Title Screen RLE'},
{id:'statusbar.c', name:'Split Status Bar'},

View File

@ -448,13 +448,15 @@ function importProjectFromGithub(githuburl:string, replaceURL:boolean) {
}).catch( (e) => {
setWaitDialog(false);
console.log(e);
alertError("Could not import " + githuburl + ": " + e);
alertError("<p>Could not import " + githuburl + ".</p>" + e);
});
}
function _loginToGithub(e) {
getGithubService().login().then(() => {
alertInfo("You are signed in to Github.");
}).catch( (e) => {
alertError("<p>Could not sign in.</p>" + e);
});
}
@ -1180,6 +1182,7 @@ function getDebugExprExamples() : string {
var s = '';
if (cpu.PC) s += "c.PC == 0x" + hex(cpu.PC) + "\n";
if (cpu.SP) s += "c.SP < 0x" + hex(cpu.SP) + "\n";
if (cpu['HL']) s += "c.HL == 0x4000\n";
if (platform.readAddress) s += "this.readAddress(0x1234) == 0x0\n";
if (platform.readVRAMAddress) s += "this.readVRAMAddress(0x1234) != 0x80\n";
if (platform['getRasterScanline']) s += "this.getRasterScanline() > 222\n";
@ -1641,7 +1644,9 @@ function installErrorHandler() {
setDebugButtonState("pause", "stopped"); // TODO?
} else {
// send exception msg to GA
var msg = msgevent + " (" + line + ":" + col + "): " + error + " - " + url;
var msg = msgstr;
if (typeof error == 'string') msg += ": " + error;
if (line) msg += " (" + line + ":" + col + ")";
if (msg.length > 256) { msg = msg.substring(0, 256); }
if (ga) ga('send', 'exception', {
'exDescription': msg,
@ -1910,6 +1915,8 @@ function convertLegacyVCS(store) {
}
}
// HTTPS REDIRECT
const useHTTPSCookieName = "__use_https";
function setHTTPSCookie(val : number) {