added error alerts; fixed window list; fixed z80 stack; astrocade .c bios
This commit is contained in:
parent
51021b5a67
commit
3b4f933d20
|
@ -65,7 +65,7 @@ TODO:
|
||||||
- click to break on raster position
|
- click to break on raster position
|
||||||
- restructure folders
|
- restructure folders
|
||||||
- update memory browser window if view before 1st compile, update symbols
|
- update memory browser window if view before 1st compile, update symbols
|
||||||
- spinner disappears sometimes
|
- spinner disappears sometimes (and compiles even when not spinning...)
|
||||||
|
|
||||||
|
|
||||||
WEB WORKER FORMAT
|
WEB WORKER FORMAT
|
||||||
|
|
|
@ -195,6 +195,10 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<button id="replay_max" type="submit" title="End of replay"><span class="glyphicon glyphicon-fast-forward" aria-hidden="true"></span></button>
|
<button id="replay_max" type="submit" title="End of replay"><span class="glyphicon glyphicon-fast-forward" aria-hidden="true"></span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="error_alert" class="alert alert-danger alert-dismissable" style="position:absolute;right:0;top:0;display:none">
|
||||||
|
<!--<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>-->
|
||||||
|
<div id="error_alert_msg"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="twitbtn">
|
<div class="twitbtn">
|
||||||
|
|
|
@ -0,0 +1,452 @@
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef signed char sbyte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
typedef signed short sword;
|
||||||
|
|
||||||
|
/// HARDWARE
|
||||||
|
|
||||||
|
__sfr __at(0x00) hw_col0r; // palette 0
|
||||||
|
__sfr __at(0x01) hw_col1r;
|
||||||
|
__sfr __at(0x02) hw_col2r;
|
||||||
|
__sfr __at(0x03) hw_col3r;
|
||||||
|
__sfr __at(0x04) hw_col0l;
|
||||||
|
__sfr __at(0x05) hw_col1l;
|
||||||
|
__sfr __at(0x06) hw_col2l;
|
||||||
|
__sfr __at(0x07) hw_col3l; // palette 7
|
||||||
|
|
||||||
|
__sfr __at(0x09) hw_horcb; // horiz color boundary
|
||||||
|
__sfr __at(0x0a) hw_verbl; // vertical blanking line * 2
|
||||||
|
__sfr __at(0x0c) hw_magic; // magic register
|
||||||
|
__sfr __at(0x0e) hw_inmod; // interrupt enable
|
||||||
|
__sfr __at(0x19) hw_xpand; // expander register
|
||||||
|
|
||||||
|
__sfr __at(0x08) hw_intst; // intercept test feedback
|
||||||
|
|
||||||
|
__sfr __at(0x10) hw_p1ctrl; // player controls
|
||||||
|
__sfr __at(0x11) hw_p2ctrl; // player controls
|
||||||
|
__sfr __at(0x12) hw_p3ctrl; // player controls
|
||||||
|
__sfr __at(0x13) hw_p4ctrl; // player controls
|
||||||
|
|
||||||
|
#define M_SHIFT0 0x00
|
||||||
|
#define M_SHIFT1 0x01
|
||||||
|
#define M_SHIFT2 0x02
|
||||||
|
#define M_SHIFT3 0x03
|
||||||
|
#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))
|
||||||
|
|
||||||
|
/// GRAPHICS FUNCTIONS
|
||||||
|
|
||||||
|
#define VHEIGHT 89 // number of scanlines
|
||||||
|
#define VBWIDTH 40 // number of bytes per scanline
|
||||||
|
#define PIXWIDTH 160 // 4 pixels per byte
|
||||||
|
|
||||||
|
#define EXIT_CLIPDEST(addr) if ((((word)addr)&0xfff) >= 0xe10) return
|
||||||
|
|
||||||
|
byte __at (0x0000) vmagic[VHEIGHT][VBWIDTH];
|
||||||
|
byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
|
||||||
|
|
||||||
|
// Used by MUSIC PROCESSOR:
|
||||||
|
word MUZPC; // $4FCE // MUSic Program Counter
|
||||||
|
word MUZSP; // $4FD0 // MUSic Stack Pointer
|
||||||
|
byte PVOLAB; // $4FD2 // Preset VOLume for tones A and B
|
||||||
|
byte PVOLMC; // $4FD3 // Preset VOLuMe for tone C and Noise Mode
|
||||||
|
byte VOICES; // $4FD4 // music VOICES mask
|
||||||
|
// COUNTER TIMERS (used by DECCTS,ACTINT,CTIMER):
|
||||||
|
byte CT[8];
|
||||||
|
// Used by SENTRY to track controls:
|
||||||
|
byte CNT; // $4FDD // Counter update & Number Tracking
|
||||||
|
byte SEMI4S; // $4FDE // SEMAPHORE flag bitS
|
||||||
|
byte OPOT[4]; // $4FDF // Old POT 0 tracking byte
|
||||||
|
byte KEYSEX; // $4FE3 // KEYS-EX tracking byte
|
||||||
|
byte OSW[4]; // $4FE4 // Old SWitch 0 tracking byte
|
||||||
|
byte COLLST; // $4FE8 // COLset LaST address for P.B. A
|
||||||
|
// Used by STIMER:
|
||||||
|
byte DURAT; // $4FEA // note DURATion
|
||||||
|
byte TMR60; // $4FEB // TiMeR for SIXTY'ths of sec
|
||||||
|
byte TIMOUT; // $4FEC // TIMer for blackOUT
|
||||||
|
byte GTSECS; // $4FED // Game Time SECondS
|
||||||
|
byte GTMINS; // $4FEE // Game Time MINuteS
|
||||||
|
// Used by MENU:
|
||||||
|
long RANSHT; // $4FEF // RANdom number SHifT register
|
||||||
|
byte NUMPLY; // $4FF3 // NUMber of PLaYers
|
||||||
|
byte ENDSCR[3]; // $4FF4 // END SCoRe to 'play to'
|
||||||
|
byte MRLOCK; // $4FF7 // Magic Register LOCK out flag
|
||||||
|
byte GAMSTB; // $4FF8 // GAMe STatus Byte
|
||||||
|
byte PRIOR; // $4FF9 // PRIOR music protect flag
|
||||||
|
byte SENFLG; // $4FFA // SENtry control seizure FLaG
|
||||||
|
// User UPI Routines, even numbers from $80 to $FE ( + 1 for SUCK):
|
||||||
|
byte* UMARGT; // $4FFB // User Mask ARGument Table + (routine / 2)
|
||||||
|
word* USERTB; // $4FFD // USER Table Base + routine = JumP address
|
||||||
|
|
||||||
|
// start routine @ 0x0
|
||||||
|
void bios_start() __naked {
|
||||||
|
__asm
|
||||||
|
DI
|
||||||
|
LD SP,#0x4fce
|
||||||
|
CALL _bios_init
|
||||||
|
LD HL,#0x2005
|
||||||
|
LD A,(HL)
|
||||||
|
INC HL
|
||||||
|
#ifndef TEST
|
||||||
|
LD H,(HL)
|
||||||
|
LD L,A
|
||||||
|
JP (HL)
|
||||||
|
#else
|
||||||
|
jp _main
|
||||||
|
#endif
|
||||||
|
.ds 0x38 - 0xf ; skip to 0x38
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void interrupt_0x38() __naked {
|
||||||
|
__asm
|
||||||
|
push hl
|
||||||
|
push af
|
||||||
|
push bc
|
||||||
|
push de
|
||||||
|
push ix
|
||||||
|
push iy
|
||||||
|
ld hl,#0
|
||||||
|
add hl,sp
|
||||||
|
push hl
|
||||||
|
call _SYSCALL
|
||||||
|
pop hl
|
||||||
|
pop iy
|
||||||
|
pop ix
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
pop af
|
||||||
|
pop hl
|
||||||
|
ret
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _predope() __naked {
|
||||||
|
__asm
|
||||||
|
.ds 0x200-0x52 ; skip to 0x200
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOPE vector @ 0x200
|
||||||
|
void DOPE() __naked {
|
||||||
|
__asm
|
||||||
|
JP _STIMER
|
||||||
|
JP _CTIMER
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: font defs
|
||||||
|
|
||||||
|
void STIMER() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTIMER() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void bios_init() {
|
||||||
|
memset((void*)0x4fce, 0, 0x5000-0x4fce);
|
||||||
|
}
|
||||||
|
|
||||||
|
///// INTERPRETER
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
word iy,ix,de,bc,af,hl;
|
||||||
|
} w;
|
||||||
|
struct {
|
||||||
|
byte iyl,iyh,ixl,ixh,e,d,c,b,f,a,l,h;
|
||||||
|
} b;
|
||||||
|
} regs;
|
||||||
|
byte* params;
|
||||||
|
} ContextBlock;
|
||||||
|
|
||||||
|
#define REG_IY 0x1
|
||||||
|
#define REG_E 0x2
|
||||||
|
#define REG_D 0x4
|
||||||
|
#define REG_C 0x8
|
||||||
|
#define REG_B 0x10
|
||||||
|
#define REG_IX 0x20
|
||||||
|
#define REG_A 0x40
|
||||||
|
#define REG_HL 0x80
|
||||||
|
#define REG_DE (REG_D|REG_E)
|
||||||
|
#define REG_BC (REG_B|REG_C)
|
||||||
|
|
||||||
|
typedef void (Routine)();
|
||||||
|
typedef void (SysRoutine)(ContextBlock *ctx);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SysRoutine* routine;
|
||||||
|
byte argmask;
|
||||||
|
} SysCallEntry;
|
||||||
|
|
||||||
|
void SYSCALL(ContextBlock *ctx);
|
||||||
|
|
||||||
|
void INTPC(ContextBlock *ctx) {
|
||||||
|
while (ctx->params[0] != 2) { // 2 = exit
|
||||||
|
SYSCALL(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// never called, hopefully
|
||||||
|
void EXIT(ContextBlock *ctx) {
|
||||||
|
ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jumps to HL
|
||||||
|
void RCALL(ContextBlock *ctx) {
|
||||||
|
((Routine*)ctx->regs.w.hl)();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs D to port 0A, B to port 09, A to port 0E.
|
||||||
|
void SETOUT(ContextBlock *ctx) {
|
||||||
|
hw_verbl = ctx->regs.b.d;
|
||||||
|
hw_horcb = ctx->regs.b.b;
|
||||||
|
hw_inmod = ctx->regs.b.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets color palettes from (HL)
|
||||||
|
void COLSET(ContextBlock *ctx) {
|
||||||
|
byte* palette = (byte*) ctx->regs.w.hl;
|
||||||
|
hw_col0r = *palette++;
|
||||||
|
hw_col1r = *palette++;
|
||||||
|
hw_col2r = *palette++;
|
||||||
|
hw_col3r = *palette++;
|
||||||
|
hw_col0l = *palette++;
|
||||||
|
hw_col1l = *palette++;
|
||||||
|
hw_col2l = *palette++;
|
||||||
|
hw_col3l = *palette++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stores A in BC bytes starting at location DE.
|
||||||
|
void FILL(ContextBlock *ctx) {
|
||||||
|
byte* dest = (byte*) ctx->regs.w.de;
|
||||||
|
word count = ctx->regs.w.bc;
|
||||||
|
byte val = ctx->regs.b.a;
|
||||||
|
memset(dest, val, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCHAR 32
|
||||||
|
#define HICHAR 127
|
||||||
|
#define FONT_BWIDTH 1
|
||||||
|
#define FONT_HEIGHT 8
|
||||||
|
const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x20,0x20,0x20,0x00,0x20, },{ 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x50,0xF8,0x50,0xF8,0x50, },{ 0x00,0x00,0x00,0xF8,0xA0,0xF8,0x28,0xF8, },{ 0x00,0x00,0x00,0xC8,0xD0,0x20,0x58,0x98, },{ 0x00,0x00,0x00,0xE0,0xA8,0xF8,0x90,0xF8, },{ 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00, },{ 0x00,0x00,0x30,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x20,0xA8,0x70,0xA8,0x20, },{ 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60, },{ 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60, },{ 0x00,0x00,0x00,0x08,0x10,0x20,0x40,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xE8,0x88,0xF8, },{ 0x00,0x00,0x00,0x10,0x30,0x50,0x10,0x10, },{ 0x00,0x00,0x00,0xF8,0x08,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0x38,0x48,0x88,0xF8,0x08, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x08,0x10,0x20,0x40, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30, },{ 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30, },{ 0x00,0x00,0x08,0x10,0x20,0x40,0x20,0x10, },{ 0x00,0x00,0x00,0x00,0xF8,0x00,0xF8,0x00, },{ 0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20, },{ 0x00,0x00,0x00,0xF8,0x08,0x78,0x00,0x60, },{ 0x00,0x00,0x00,0xF8,0xA8,0xB8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0xF0,0x90,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0x80, },{ 0x00,0x00,0x00,0xF8,0x80,0xB8,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40, },{ 0x00,0x00,0x00,0x08,0x08,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x90,0xA0,0x90,0x88, },{ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0x92, },{ 0x00,0x00,0x00,0x88,0xC8,0xA8,0x98,0x88, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0xF8,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xA8,0xA8,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x90,0x88, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0x90,0xA0,0xC0, },{ 0x00,0x00,0x00,0x92,0x92,0x92,0x92,0xFE, },{ 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8, },{ 0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08, },{ 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10, },{ 0x00,0x00,0x00,0x20,0x50,0x88,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },{ 0x00,0x00,0x40,0x20,0x10,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0xF0,0x90,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0x80, },{ 0x00,0x00,0x00,0xF8,0x80,0xB8,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40, },{ 0x00,0x00,0x00,0x08,0x08,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x90,0xA0,0x90,0x88, },{ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0x92, },{ 0x00,0x00,0x00,0x88,0xC8,0xA8,0x98,0x88, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0xF8,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xA8,0xA8,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x90,0x88, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0x90,0xA0,0xC0, },{ 0x00,0x00,0x00,0x92,0x92,0x92,0x92,0xFE, },{ 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8, },{ 0x00,0x00,0x38,0x20,0x20,0xE0,0x20,0x20, },{ 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0xE0,0x20,0x20,0x38,0x20,0x20, },{ 0x00,0x00,0x00,0xE8,0xB8,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },};
|
||||||
|
|
||||||
|
// draw a letter
|
||||||
|
void draw_char(byte ch, byte x, byte y, byte op) {
|
||||||
|
const byte* src = &FONT[(ch-LOCHAR)][0];
|
||||||
|
byte xb = x>>2; // divide x by 4
|
||||||
|
byte* dest = &vmagic[y][xb]; // destination address
|
||||||
|
hw_magic = M_SHIFT(x) | M_XPAND | op;
|
||||||
|
for (byte i=0; i<8; i++) {
|
||||||
|
char b = *src++;
|
||||||
|
EXIT_CLIPDEST(dest);
|
||||||
|
*dest++ = b; // expand lower nibble -> 1st byte
|
||||||
|
*dest++ = b; // expand upper nibble -> 2nd byte
|
||||||
|
*dest++ = 0; // leftover -> 3rd byte
|
||||||
|
*dest = 0; // reset upper/lower flag
|
||||||
|
dest += VBWIDTH-3; // we incremented 3 bytes for this line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_string(const char* str, byte x, byte y, byte op) {
|
||||||
|
do {
|
||||||
|
byte ch = *str++;
|
||||||
|
if (!ch) break;
|
||||||
|
draw_char(ch, x, y, op);
|
||||||
|
x += 8;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// String display routine
|
||||||
|
void STRDIS(ContextBlock *ctx) {
|
||||||
|
byte opts = ctx->regs.b.c;
|
||||||
|
byte x = ctx->regs.b.e;
|
||||||
|
byte y = ctx->regs.b.d;
|
||||||
|
char* str = (char*) ctx->regs.w.hl;
|
||||||
|
void* fontdesc = (void*) ctx->regs.w.ix;
|
||||||
|
hw_xpand = opts & 0xf;
|
||||||
|
draw_string(str, x, y, 3&(opts>>4)); // TODO: opts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Character display routine
|
||||||
|
void CHRDIS(ContextBlock *ctx) {
|
||||||
|
char chstr[2];
|
||||||
|
chstr[0] = ctx->regs.b.a;
|
||||||
|
chstr[1] = 0;
|
||||||
|
ctx->regs.w.hl = (word) &chstr;
|
||||||
|
STRDIS(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SysCallEntry SYSCALL_TABLE[64] = {
|
||||||
|
/* 0 */
|
||||||
|
{ &INTPC, 0 },
|
||||||
|
{ &EXIT, 0 },
|
||||||
|
{ &RCALL, REG_HL },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 10 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 20 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ &SETOUT, REG_D|REG_B|REG_A },
|
||||||
|
{ &COLSET, REG_HL },
|
||||||
|
{ &FILL, REG_A|REG_BC|REG_DE },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 30 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 40 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 50 */
|
||||||
|
{ &CHRDIS, REG_E|REG_D|REG_C|REG_A },
|
||||||
|
{ &STRDIS, REG_E|REG_D|REG_C|REG_HL },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 60 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 70 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 80 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 90 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 100 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 110 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
/* 120 */
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
{ 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
void suckParams(ContextBlock *ctx, byte argmask) {
|
||||||
|
byte* dest = (byte*) ctx;
|
||||||
|
byte* src = ctx->params;
|
||||||
|
if (argmask & REG_IX) {
|
||||||
|
ctx->regs.b.ixl = *src++;
|
||||||
|
ctx->regs.b.ixh = *src++;
|
||||||
|
}
|
||||||
|
if (argmask & REG_E)
|
||||||
|
ctx->regs.b.e = *src++;
|
||||||
|
if (argmask & REG_D)
|
||||||
|
ctx->regs.b.d = *src++;
|
||||||
|
if (argmask & REG_C)
|
||||||
|
ctx->regs.b.c = *src++;
|
||||||
|
if (argmask & REG_B)
|
||||||
|
ctx->regs.b.b = *src++;
|
||||||
|
if (argmask & REG_A)
|
||||||
|
ctx->regs.b.a = *src++;
|
||||||
|
if (argmask & REG_HL) {
|
||||||
|
ctx->regs.b.l = *src++;
|
||||||
|
ctx->regs.b.h = *src++;
|
||||||
|
}
|
||||||
|
ctx->params = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SYSCALL(ContextBlock *ctx) {
|
||||||
|
byte op = *ctx->params++;
|
||||||
|
byte argmask;
|
||||||
|
SysRoutine* routine;
|
||||||
|
// user-defined?
|
||||||
|
if (op & 0x80) {
|
||||||
|
argmask = UMARGT[op & 0x7f];
|
||||||
|
routine = (SysRoutine*) USERTB[op & 0x7f];
|
||||||
|
} else {
|
||||||
|
const SysCallEntry* entry = &SYSCALL_TABLE[op>>1];
|
||||||
|
argmask = entry->argmask;
|
||||||
|
routine = entry->routine;
|
||||||
|
}
|
||||||
|
// suck params into context block?
|
||||||
|
if (op & 1) {
|
||||||
|
suckParams(ctx, argmask);
|
||||||
|
}
|
||||||
|
// call the routine
|
||||||
|
if (routine) {
|
||||||
|
routine(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
void main() {
|
||||||
|
__asm
|
||||||
|
RST 0x38
|
||||||
|
.db 0 ; INTPC
|
||||||
|
.db 22+1 ; SETOUT
|
||||||
|
.db 102*2, 0x1c, 0x08
|
||||||
|
.db 24+1 ; COLSET
|
||||||
|
.dw _main ; palette???
|
||||||
|
.db 26+1 ; FILL
|
||||||
|
.dw 0x4000
|
||||||
|
.dw 90*40
|
||||||
|
.db 0xaa
|
||||||
|
.db 52+1 ; draw string
|
||||||
|
.db 0
|
||||||
|
.db 32
|
||||||
|
.db 0x0c
|
||||||
|
.dw HelloString
|
||||||
|
.db 50+1 ; draw char
|
||||||
|
.db 0
|
||||||
|
.db 64
|
||||||
|
.db 0x0c
|
||||||
|
.db 65
|
||||||
|
.db 2 ; EXIT
|
||||||
|
jp .end
|
||||||
|
HelloString:
|
||||||
|
.ascii "HELLO WORLD!"
|
||||||
|
.db 0
|
||||||
|
.end:
|
||||||
|
__endasm;
|
||||||
|
while (1) CT[0]++;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -523,8 +523,8 @@ export abstract class BaseZ80Platform extends BaseDebugPlatform {
|
||||||
switch (category) {
|
switch (category) {
|
||||||
case 'CPU': return cpuStateToLongString_Z80(state.c);
|
case 'CPU': return cpuStateToLongString_Z80(state.c);
|
||||||
case 'Stack': {
|
case 'Stack': {
|
||||||
var sp = state.c.SP;
|
var sp = state.c.SP-1;
|
||||||
var start = ((sp-1) & 0xff00);
|
var start = sp & 0xff00;
|
||||||
var end = start + 0xff;
|
var end = start + 0xff;
|
||||||
if (sp == 0) sp = 0x10000;
|
if (sp == 0) sp = 0x10000;
|
||||||
return dumpStackToString(<Platform><any>this, [], start, end, sp, 0xcd);
|
return dumpStackToString(<Platform><any>this, [], start, end, sp, 0xcd);
|
||||||
|
@ -897,7 +897,7 @@ export function dumpStackToString(platform:Platform, mem:number[], start:number,
|
||||||
} else {
|
} else {
|
||||||
if (nraw == 0)
|
if (nraw == 0)
|
||||||
s += "\n$" + hex(sp) + ": ";
|
s += "\n$" + hex(sp) + ": ";
|
||||||
s += hex(read(sp+1)) + " ";
|
s += hex(read(sp)) + " ";
|
||||||
if (++nraw == 8) nraw = 0;
|
if (++nraw == 8) nraw = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
|
||||||
|
|
||||||
start = function() {
|
start = function() {
|
||||||
ram = new RAM(arcade ? 0x5000 : 0x1000);
|
ram = new RAM(arcade ? 0x5000 : 0x1000);
|
||||||
var lzgrom = window['ASTROCADE_LZGROM'];
|
var lzgrom = window['ASTROCADE_LZGROM'] || window['ASTROCADE_BIOS_LZG'];
|
||||||
if (lzgrom)
|
if (lzgrom)
|
||||||
bios = new lzgmini().decode(stringToByteArray(atob(lzgrom)));
|
bios = new lzgmini().decode(stringToByteArray(atob(lzgrom)));
|
||||||
else
|
else
|
||||||
|
@ -320,6 +320,11 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadBIOS(title, data) {
|
||||||
|
bios = padBytes(data, 0x2000);
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
|
||||||
loadState(state) {
|
loadState(state) {
|
||||||
cpu.loadState(state.c);
|
cpu.loadState(state.c);
|
||||||
ram.mem.set(state.b);
|
ram.mem.set(state.b);
|
||||||
|
@ -426,9 +431,16 @@ const _BallyArcadePlatform = function(mainElement) {
|
||||||
this.loadControlsState(_in);
|
this.loadControlsState(_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _BallyAstrocadeBIOSPlatform = function(mainElement) {
|
||||||
|
this.__proto__ = new (_BallyAstrocadePlatform as any)(mainElement);
|
||||||
|
|
||||||
|
this.loadROM = this.loadBIOS;
|
||||||
|
}
|
||||||
|
|
||||||
/////
|
/////
|
||||||
|
|
||||||
PLATFORMS['astrocade'] = _BallyAstrocadePlatform;
|
PLATFORMS['astrocade'] = _BallyAstrocadePlatform;
|
||||||
|
PLATFORMS['astrocade-bios'] = _BallyAstrocadeBIOSPlatform;
|
||||||
PLATFORMS['astrocade-arcade'] = _BallyArcadePlatform;
|
PLATFORMS['astrocade-arcade'] = _BallyArcadePlatform;
|
||||||
|
|
||||||
//http://glankonian.com/~lance/astrocade_palette.html
|
//http://glankonian.com/~lance/astrocade_palette.html
|
||||||
|
@ -439,3 +451,5 @@ for (var i=0; i<256; i++) {
|
||||||
x = ((x&0xff)<<16) | ((x>>16)&0xff) | (x&0x00ff00);
|
x = ((x&0xff)<<16) | ((x>>16)&0xff) | (x&0x00ff00);
|
||||||
ASTROCADE_PALETTE[i] = x | 0xff000000;
|
ASTROCADE_PALETTE[i] = x | 0xff000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//var ASTROCADE_BIOS_LZG = decodeURIComponent();
|
||||||
|
|
|
@ -258,8 +258,8 @@ export class CodeProject {
|
||||||
|
|
||||||
processBuildResult(data:WorkerResult) {
|
processBuildResult(data:WorkerResult) {
|
||||||
// TODO: link listings with source files
|
// TODO: link listings with source files
|
||||||
this.listings = data.listings;
|
if (data.listings) {
|
||||||
if (this.listings) {
|
this.listings = data.listings;
|
||||||
for (var lstname in this.listings) {
|
for (var lstname in this.listings) {
|
||||||
var lst = this.listings[lstname];
|
var lst = this.listings[lstname];
|
||||||
if (lst.lines)
|
if (lst.lines)
|
||||||
|
|
|
@ -13,6 +13,7 @@ var FONT_DEFAULT_PARAMS = {
|
||||||
wbytes:1,
|
wbytes:1,
|
||||||
width:8,
|
width:8,
|
||||||
height:8,
|
height:8,
|
||||||
|
yoffset:0,
|
||||||
lochar:32,
|
lochar:32,
|
||||||
hichar:127,
|
hichar:127,
|
||||||
rotate:false,
|
rotate:false,
|
||||||
|
@ -36,6 +37,7 @@ var FONT_PRESETS = {
|
||||||
vcs: { output:'dasm', msbfirst:true },
|
vcs: { output:'dasm', msbfirst:true },
|
||||||
mw8080bw: { rotate:true, flip:true, msbfirst:true },
|
mw8080bw: { rotate:true, flip:true, msbfirst:true },
|
||||||
nes: { np:2, msbfirst:true },
|
nes: { np:2, msbfirst:true },
|
||||||
|
astrocade: { output:'zmac', msbfirst:true },
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadPreset(preset_id) {
|
function loadPreset(preset_id) {
|
||||||
|
@ -58,6 +60,7 @@ function refreshToolbar(event?) {
|
||||||
case 'height':
|
case 'height':
|
||||||
case 'lochar':
|
case 'lochar':
|
||||||
case 'hichar':
|
case 'hichar':
|
||||||
|
case 'yoffset':
|
||||||
params[event.item.id] = parseInt(event.item.value);
|
params[event.item.id] = parseInt(event.item.value);
|
||||||
break;
|
break;
|
||||||
case 'rotate':
|
case 'rotate':
|
||||||
|
@ -78,6 +81,10 @@ function refreshToolbar(event?) {
|
||||||
if (event.subItem)
|
if (event.subItem)
|
||||||
loadCharSel(event.subItem.id);
|
loadCharSel(event.subItem.id);
|
||||||
break;
|
break;
|
||||||
|
case 'output':
|
||||||
|
if (event.subItem)
|
||||||
|
params[event.item.id] = event.subItem.id;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// set derived params
|
// set derived params
|
||||||
|
@ -172,19 +179,27 @@ function renderGlyph(glyph, putPixel) {
|
||||||
var h = glyph.bbx[1];
|
var h = glyph.bbx[1];
|
||||||
var dx = glyph.bbx[2];
|
var dx = glyph.bbx[2];
|
||||||
var dy = glyph.bbx[3];
|
var dy = glyph.bbx[3];
|
||||||
|
var error_logged = false;
|
||||||
for (var y=0; y<glyph.bytes.length; y++) {
|
for (var y=0; y<glyph.bytes.length; y++) {
|
||||||
for (var x=0; x<w; x++) {
|
for (var x=0; x<w; x++) {
|
||||||
if (glyph.bytes[glyph.bytes.length-y-1] & (0x800000 >> x)) {
|
if (glyph.bytes[glyph.bytes.length-y-1] & (0x800000 >> x)) {
|
||||||
var xx = x+dx;
|
var xx = x+dx;
|
||||||
var yy = y+dy;
|
var yy = y+dy;
|
||||||
|
yy += params.yoffset || 0;
|
||||||
/*
|
/*
|
||||||
font.pixbounds[0] = Math.min(font.pixbounds[0], xx);
|
font.pixbounds[0] = Math.min(font.pixbounds[0], xx);
|
||||||
font.pixbounds[1] = Math.min(font.pixbounds[1], yy);
|
font.pixbounds[1] = Math.min(font.pixbounds[1], yy);
|
||||||
font.pixbounds[2] = Math.max(font.pixbounds[2], xx);
|
font.pixbounds[2] = Math.max(font.pixbounds[2], xx);
|
||||||
font.pixbounds[3] = Math.max(font.pixbounds[3], yy);
|
font.pixbounds[3] = Math.max(font.pixbounds[3], yy);
|
||||||
*/
|
*/
|
||||||
if (xx >= 0 && yy >= 0 && xx < params.width && yy < params.height)
|
var xoutrange = xx < 0 || x >= params.width;
|
||||||
|
var youtrange = yy < 0 || y >= params.width;
|
||||||
|
if (!xoutrange && !youtrange) {
|
||||||
putPixel(xx, yy);
|
putPixel(xx, yy);
|
||||||
|
} else if (!error_logged) {
|
||||||
|
errors.push((xoutrange?"X":"Y") + " out of range on character " + String.fromCharCode(glyph.ord) + " " + x + "," + y);
|
||||||
|
error_logged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,12 +259,6 @@ function encodeGlyph(glyph, bytes) {
|
||||||
}
|
}
|
||||||
var xoutrange = (x < 0 || x >= params.width);
|
var xoutrange = (x < 0 || x >= params.width);
|
||||||
var youtrange = (y < 0 || y >= params.height);
|
var youtrange = (y < 0 || y >= params.height);
|
||||||
if (xoutrange || youtrange) {
|
|
||||||
if (!abort) {
|
|
||||||
errors.push((xoutrange?"X":"Y") + " out of range on character " + String.fromCharCode(glyph.ord) + " " + x + "," + y);
|
|
||||||
abort = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var bpb = 8 / (params.bpp||1);
|
var bpb = 8 / (params.bpp||1);
|
||||||
var ofs = Math.floor(x/bpb) + (params.height-1-y)*params.wbytes;
|
var ofs = Math.floor(x/bpb) + (params.height-1-y)*params.wbytes;
|
||||||
var bit = x % bpb;
|
var bit = x % bpb;
|
||||||
|
@ -260,7 +269,8 @@ function encodeGlyph(glyph, bytes) {
|
||||||
|
|
||||||
function encodeFont() {
|
function encodeFont() {
|
||||||
var s = '';
|
var s = '';
|
||||||
if (params.output.startsWith('c_')) {
|
var c_output = params.output.startsWith('c_');
|
||||||
|
if (c_output) {
|
||||||
//s += '/* ' + JSON.stringify(params) + JSON.stringify(font.bounds) + JSON.stringify(font.pixbounds) + ' */\n';
|
//s += '/* ' + JSON.stringify(params) + JSON.stringify(font.bounds) + JSON.stringify(font.pixbounds) + ' */\n';
|
||||||
s += "#define LOCHAR " + params.lochar + "\n";
|
s += "#define LOCHAR " + params.lochar + "\n";
|
||||||
s += "#define HICHAR " + params.hichar + "\n";
|
s += "#define HICHAR " + params.hichar + "\n";
|
||||||
|
@ -268,9 +278,9 @@ function encodeFont() {
|
||||||
s += "#define FONT_HEIGHT " + params.height + "\n";
|
s += "#define FONT_HEIGHT " + params.height + "\n";
|
||||||
s += "const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {\n";
|
s += "const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {\n";
|
||||||
} else {
|
} else {
|
||||||
s += "LOCHAR\t\t= " + params.lochar + "\n";
|
s += "LOCHAR\t\tequ " + params.lochar + "\n";
|
||||||
s += "HICHAR\t\t= " + params.hichar + "\n";
|
s += "HICHAR\t\tequ " + params.hichar + "\n";
|
||||||
s += "FONT_HEIGHT\t= " + params.height + "\n";
|
s += "FONT_HEIGHT\tequ " + params.height + "\n";
|
||||||
s += "FontData:\n";
|
s += "FontData:\n";
|
||||||
}
|
}
|
||||||
errors = [];
|
errors = [];
|
||||||
|
@ -281,19 +291,23 @@ function encodeFont() {
|
||||||
encodeGlyph(glyph, bytes);
|
encodeGlyph(glyph, bytes);
|
||||||
if (params.output=='c_nested') s += "{ ";
|
if (params.output=='c_nested') s += "{ ";
|
||||||
else if (params.output=='dasm') s += "\thex\t";
|
else if (params.output=='dasm') s += "\thex\t";
|
||||||
|
else if (params.output=='zmac') s += "\tdb\t";
|
||||||
for (var i=0; i<bytes.length; i++) {
|
for (var i=0; i<bytes.length; i++) {
|
||||||
if (params.output.startsWith('c_'))
|
if (params.output == 'dasm')
|
||||||
s += "0x" + hex(bytes[i]) + ",";
|
|
||||||
else if (params.output == 'dasm')
|
|
||||||
s += hex(bytes[i]);
|
s += hex(bytes[i]);
|
||||||
|
else
|
||||||
|
s += "0x" + hex(bytes[i]) + ((i<bytes.length-1)?",":"");
|
||||||
}
|
}
|
||||||
if (params.output=='c_nested') s += " },";
|
if (params.output=='c_nested') s += " },";
|
||||||
if (!params.output.startsWith('c_') || params.newline) s += "\n";
|
if (!c_output || params.newline) s += "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s += "};\n";
|
if (c_output) s += "};\n";
|
||||||
while (errors.length) {
|
while (errors.length) {
|
||||||
|
if (c_output)
|
||||||
s = "/* " + errors.pop() + " */\n" + s;
|
s = "/* " + errors.pop() + " */\n" + s;
|
||||||
|
else
|
||||||
|
s = ";; " + errors.pop() + "\n" + s;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -356,6 +370,7 @@ $().w2toolbar({
|
||||||
{ text: 'Midway 8080', id: 'mw8080bw' },
|
{ text: 'Midway 8080', id: 'mw8080bw' },
|
||||||
{ text: 'NES', id: 'nes' },
|
{ text: 'NES', id: 'nes' },
|
||||||
{ text: 'Apple ][', id: 'apple2' },
|
{ text: 'Apple ][', id: 'apple2' },
|
||||||
|
{ text: 'Astrocade', id: 'astrocade' },
|
||||||
]},
|
]},
|
||||||
{ type: 'check', id: 'rotate', caption: 'Rotate', img: 'fas fa-sync', tooltip: 'Rotate 90 degrees (swap X/Y)' },
|
{ type: 'check', id: 'rotate', caption: 'Rotate', img: 'fas fa-sync', tooltip: 'Rotate 90 degrees (swap X/Y)' },
|
||||||
{ type: 'check', id: 'xflip', caption: 'Mirror', img: 'fas fa-arrows-alt-h', tooltip: 'Flip X axis' },
|
{ type: 'check', id: 'xflip', caption: 'Mirror', img: 'fas fa-arrows-alt-h', tooltip: 'Flip X axis' },
|
||||||
|
@ -370,10 +385,19 @@ $().w2toolbar({
|
||||||
]},
|
]},
|
||||||
{ type: 'html', id: 'width', html: toolbarHTMLItem('width','Width:',2) },
|
{ type: 'html', id: 'width', html: toolbarHTMLItem('width','Width:',2) },
|
||||||
{ type: 'html', id: 'height', html: toolbarHTMLItem('height','Height:',2) },
|
{ type: 'html', id: 'height', html: toolbarHTMLItem('height','Height:',2) },
|
||||||
|
{ type: 'html', id: 'yoffset', html: toolbarHTMLItem('yoffset','Y Offset:',2) },
|
||||||
|
{ type: 'menu-radio', id: 'output', caption: 'Output', img: 'icon-folder',
|
||||||
|
tooltip: 'Output format',
|
||||||
|
items: [
|
||||||
|
{ text: 'C array (nested)', id: 'c_nested' },
|
||||||
|
{ text: 'C array (flat)', id: 'c_flat' },
|
||||||
|
{ text: 'Assembler (DASM)', id: 'dasm' },
|
||||||
|
{ text: 'Assembler (zmac)', id: 'zmac' },
|
||||||
|
]},
|
||||||
{ type: 'break', id: 'break1' },
|
{ type: 'break', id: 'break1' },
|
||||||
{ type: 'menu-radio', id: 'charsel', caption: 'Characters', img: 'icon-folder',
|
|
||||||
|
{ type: 'menu-radio', id: 'charsel', caption: 'Chars', img: 'icon-folder',
|
||||||
tooltip: 'Range of characters to encode, from first to last',
|
tooltip: 'Range of characters to encode, from first to last',
|
||||||
//text: function(item) { refreshCharSel(item); return item.caption; },
|
|
||||||
items: [
|
items: [
|
||||||
//{ text: 'ISO (256 chars)', value:'0-255' },
|
//{ text: 'ISO (256 chars)', value:'0-255' },
|
||||||
{ text: 'ASCII (upper only)', id:'32-95' },
|
{ text: 'ASCII (upper only)', id:'32-95' },
|
||||||
|
|
18
src/ui.ts
18
src/ui.ts
|
@ -5,7 +5,7 @@
|
||||||
import $ = require("jquery");
|
import $ = require("jquery");
|
||||||
import * as bootstrap from "bootstrap";
|
import * as bootstrap from "bootstrap";
|
||||||
import { CodeProject } from "./project";
|
import { CodeProject } from "./project";
|
||||||
import { WorkerResult, SourceFile } from "./workertypes";
|
import { WorkerResult, SourceFile, WorkerError } from "./workertypes";
|
||||||
import { ProjectWindows } from "./windows";
|
import { ProjectWindows } from "./windows";
|
||||||
import { Platform, Preset } from "./baseplatform";
|
import { Platform, Preset } from "./baseplatform";
|
||||||
import { PLATFORMS } from "./emu";
|
import { PLATFORMS } from "./emu";
|
||||||
|
@ -95,6 +95,7 @@ function initProject() {
|
||||||
toolbar.removeClass("is-busy");
|
toolbar.removeClass("is-busy");
|
||||||
toolbar.removeClass("has-errors"); // may be added in next callback
|
toolbar.removeClass("has-errors"); // may be added in next callback
|
||||||
projectWindows.setErrors(null);
|
projectWindows.setErrors(null);
|
||||||
|
$("#error_alert").hide();
|
||||||
}
|
}
|
||||||
$('#compile_spinner').css('visibility', busy ? 'visible' : 'hidden');
|
$('#compile_spinner').css('visibility', busy ? 'visible' : 'hidden');
|
||||||
};
|
};
|
||||||
|
@ -469,11 +470,24 @@ function updateSelector() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showErrorAlert(errors : WorkerError[]) {
|
||||||
|
var div = $("#error_alert_msg").empty();
|
||||||
|
for (var err of errors.slice(0,10)) {
|
||||||
|
var s = '';
|
||||||
|
if (err.path) s += err.path + ":";
|
||||||
|
if (err.line) s += err.line + ":";
|
||||||
|
s += err.msg;
|
||||||
|
div.append($("<p>").text(s));
|
||||||
|
}
|
||||||
|
$("#error_alert").show();
|
||||||
|
}
|
||||||
|
|
||||||
function setCompileOutput(data: WorkerResult) {
|
function setCompileOutput(data: WorkerResult) {
|
||||||
// errors? mark them in editor
|
// errors? mark them in editor
|
||||||
if (data.errors && data.errors.length > 0) {
|
if (data.errors && data.errors.length > 0) {
|
||||||
projectWindows.setErrors(data.errors);
|
|
||||||
toolbar.addClass("has-errors");
|
toolbar.addClass("has-errors");
|
||||||
|
projectWindows.setErrors(data.errors);
|
||||||
|
showErrorAlert(data.errors);
|
||||||
} else {
|
} else {
|
||||||
// process symbol map
|
// process symbol map
|
||||||
symbolmap = data.symbolmap;
|
symbolmap = data.symbolmap;
|
||||||
|
|
|
@ -496,7 +496,7 @@ export class DisassemblerView implements ProjectView {
|
||||||
getCursorPC() : number {
|
getCursorPC() : number {
|
||||||
var line = this.disasmview.getCursor().line;
|
var line = this.disasmview.getCursor().line;
|
||||||
if (line >= 0) {
|
if (line >= 0) {
|
||||||
var toks = this.disasmview.getLine(line).split(/\s+/);
|
var toks = this.disasmview.getLine(line).trim().split(/\s+/);
|
||||||
if (toks && toks.length >= 1) {
|
if (toks && toks.length >= 1) {
|
||||||
var pc = parseInt(toks[0], 16);
|
var pc = parseInt(toks[0], 16);
|
||||||
if (pc >= 0) return pc;
|
if (pc >= 0) return pc;
|
||||||
|
|
|
@ -165,6 +165,13 @@ var PLATFORM_PARAMS = {
|
||||||
data_size: 0x220,
|
data_size: 0x220,
|
||||||
stack_end: 0x8000,
|
stack_end: 0x8000,
|
||||||
},
|
},
|
||||||
|
'astrocade-bios': {
|
||||||
|
code_start: 0x0000,
|
||||||
|
rom_size: 0x2000,
|
||||||
|
data_start: 0x4fce,
|
||||||
|
data_size: 50,
|
||||||
|
stack_end: 0x4fce,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// shim out window and document objects for security
|
// shim out window and document objects for security
|
||||||
|
@ -598,7 +605,7 @@ function assembleDASM(step) {
|
||||||
unresolved[matches[1]] = 0;
|
unresolved[matches[1]] = 0;
|
||||||
}
|
}
|
||||||
} else if (s.startsWith("Warning:")) {
|
} else if (s.startsWith("Warning:")) {
|
||||||
errors.push({line:1, msg:s.substr(9)});
|
errors.push({line:0, msg:s.substr(9)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var Module = DASM({
|
var Module = DASM({
|
||||||
|
@ -918,7 +925,7 @@ function assembleSDASZ80(step) {
|
||||||
if (matches) {
|
if (matches) {
|
||||||
//var errline = parseInt(matches[2]);
|
//var errline = parseInt(matches[2]);
|
||||||
errors.push({
|
errors.push({
|
||||||
line:1, // TODO
|
line:0, // TODO
|
||||||
path:step.path,
|
path:step.path,
|
||||||
msg:matches[1]
|
msg:matches[1]
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,7 +35,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<li>Select a font below (check out the search and filter options.)</li>
|
<li>Select a font below (check out the search and filter options.)</li>
|
||||||
<li>Choose a platform from the Presets menu, or choose your own encoding options.</li>
|
<li>Choose a platform from the Presets menu, or choose your own encoding options.</li>
|
||||||
<li>Select a range of characters to encode.</li>
|
<li>Select a range of characters to encode.</li>
|
||||||
<li>Check out the preview bitmap to make sure none of your characters are visibly cut off, or increase your height/width (if your platform supports it.)</li>
|
<li>If you have out-of-range errors you want to fix, adjust the Y Offset value, or increase your height/width (if your platform supports it.)</li>
|
||||||
<li>Copy the output to the clipboard.</li>
|
<li>Copy the output to the clipboard.</li>
|
||||||
<li>Paste it into your code.</li>
|
<li>Paste it into your code.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
Loading…
Reference in New Issue