Merge pull request #3006 from djupdal/geos-c-da
CBM GEOS desk accessory support
This commit is contained in:
13 files changed
+461
-33
No files matched your search
@@ -0,0 +1,49 @@
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $1000;
|
||||
}
|
||||
SYMBOLS {
|
||||
__BACKBUFSIZE__: type = weak, value = $2000;
|
||||
__STACKSIZE__: type = weak, value = $0400; # 1k stack
|
||||
__STACKADDR__: type = weak, value = __VLIR0_LAST__;
|
||||
__SAVEDZPADDR__: type = weak, value = __STACKADDR__ + __STACKSIZE__;
|
||||
__HIMEM__: type = weak, value = __SAVEDZPADDR__ + __ZP_SIZE__;
|
||||
__VLIR0_BLOCKS__: type = export, value = ((__VLIR0_LAST__ - __VLIR0_START__ - __BSS_SIZE__) + 253) / 254;
|
||||
}
|
||||
MEMORY {
|
||||
CVT: file = %O, start = $0, size = $40000;
|
||||
ZP: define = yes, start = $58, size = $1A + $06;
|
||||
|
||||
VLIR0: define = yes, start = %S, size = ($6000 - %S) - __STACKSIZE__ - __ZP_SIZE__;
|
||||
SAVEDZP: define = yes, start = __SAVEDZPADDR__, size = __ZP_SIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: type = zp, load = ZP;
|
||||
EXTZP: type = zp, load = ZP, optional = yes;
|
||||
DIRENTRY: type = ro, load = CVT, align = $FE;
|
||||
FILEINFO: type = ro, load = CVT, align = $FE;
|
||||
RECORDS: type = ro, load = CVT, align = $FE, optional = yes;
|
||||
STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $FE, define = yes;
|
||||
LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes;
|
||||
ONCE: type = ro, run = VLIR0, load = CVT, optional = yes;
|
||||
CODE: type = ro, run = VLIR0, load = CVT;
|
||||
RODATA: type = ro, run = VLIR0, load = CVT;
|
||||
DATA: type = rw, run = VLIR0, load = CVT;
|
||||
INIT: type = bss, load = VLIR0, optional = yes;
|
||||
BSS: type = bss, load = VLIR0, define = yes;
|
||||
SAVEDZP: type = bss, load = SAVEDZP;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
||||
+11
-3
@@ -24,8 +24,9 @@ Optional resources might be menu definitions, other headers (e.g., for data
|
||||
files of an app.), dialog definitions, etc. Without an application's header,
|
||||
GEOS is unable to load and start it.
|
||||
|
||||
Currently, <bf/grc65/ supports only menus and the required header definition,
|
||||
along with support for building applications with VLIR-structured overlays.
|
||||
Currently, <bf/grc65/ supports menus, the required header definition,
|
||||
driver/accessory headers (desk accessories), and building applications with
|
||||
VLIR-structured overlays.
|
||||
|
||||
<bf/grc65/ generates output in two formats: C header and <bf/ca65/ source (.s).
|
||||
That is because the application header data must be in assembly format, while
|
||||
@@ -115,7 +116,8 @@ HEADER <GEOS_TYPE> "dosname" "classname" "version" {
|
||||
}</verb></tscreen>
|
||||
The header definition describes the GEOS header sector which is unique to
|
||||
each file. The definition starts with the keyword <tt/HEADER/, then goes the
|
||||
GEOS file-type. You can use only <tt/APPLICATION/ here at the moment. Then,
|
||||
GEOS file-type. It can be <tt/APPLICATION/, <tt/AUTO_EXEC/, or <tt/DESK_ACC/.
|
||||
Then,
|
||||
there are (each one in quotes) the DOS file-name (up to 16 characters), the GEOS
|
||||
Class name (up to 12 characters), and the version info (up to 4 characters).
|
||||
The version should be written as &dquot;<tt/V/x.y&dquot;, where <em/x/ is the
|
||||
@@ -266,6 +268,12 @@ required for the correct process of GEOS sequential application building.
|
||||
|
||||
|
||||
|
||||
<sect>Building desk accessories<label id="building-da">
|
||||
<p>Desk accessories (<tt/DESK_ACC/) must be built using the following target: <tt/geos-c-da/
|
||||
|
||||
See <tt>samples/geos</tt> for a working example.
|
||||
|
||||
|
||||
<sect>Building a GEOS VLIR overlay application<label id="building-vlir">
|
||||
<p>Large GEOS applications typically don't fit in one piece in their designated
|
||||
memory area. They are therefore split into overlays which are loaded into memory
|
||||
|
||||
@@ -12,6 +12,7 @@ void InitForIO(void);
|
||||
void DoneWithIO(void);
|
||||
void MainLoop(void);
|
||||
void EnterDeskTop(void);
|
||||
void RstrAppl(void);
|
||||
void ToBASIC(void);
|
||||
void Panic(void);
|
||||
|
||||
|
||||
+9
-2
@@ -31,7 +31,8 @@ CBMS = c128 \
|
||||
vic20
|
||||
|
||||
GEOS = geos-apple \
|
||||
geos-cbm
|
||||
geos-cbm \
|
||||
geos-c-da
|
||||
|
||||
TARGETS = agat \
|
||||
apple2 \
|
||||
@@ -191,18 +192,24 @@ else ifeq ($(TARGET),atarixl)
|
||||
DRVPFX = atrx
|
||||
else ifeq ($(TARGET),sim65c02)
|
||||
SRCDIR = sim6502
|
||||
else ifeq ($(TARGET),geos-c-da)
|
||||
SRCDIR = geos-cbm
|
||||
else
|
||||
SRCDIR = $(TARGET)
|
||||
endif
|
||||
|
||||
SRCDIRS = $(SRCDIR)
|
||||
|
||||
ifeq ($(TARGET),geos-c-da)
|
||||
SRCDIRS := geos-c-da $(SRCDIRS)
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),$(filter $(TARGET),$(CBMS)))
|
||||
SRCDIRS += cbm
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),$(filter $(TARGET),$(GEOS)))
|
||||
SRCDIRS += $(addprefix $(TARGET)/, $(GEOSDIRS))
|
||||
SRCDIRS += $(addprefix $(SRCDIR)/, $(GEOSDIRS))
|
||||
SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS))
|
||||
endif
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
;
|
||||
; Startup code for a GEOS desk accessory (DESK_ACC), based on
|
||||
; libsrc/geos-common/system/crt0.s
|
||||
;
|
||||
|
||||
.export _exit
|
||||
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
||||
.export __GEOS_SAVED_ZP__
|
||||
.export _RstrAppl
|
||||
.import __STACKADDR__, __STACKSIZE__ ; Linker generated
|
||||
.import __ZP_START__, __ZP_SIZE__ ; Linker generated
|
||||
.import initlib, donelib
|
||||
.import callmain
|
||||
.import zerobss
|
||||
.importzp c_sp
|
||||
|
||||
.include "jumptab.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Somewhere to save cc65's own runtime zero page block while this
|
||||
; accessory is running.
|
||||
|
||||
.segment "SAVEDZP"
|
||||
|
||||
__GEOS_SAVED_ZP__:
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Place the startup code in a special segment.
|
||||
|
||||
.segment "STARTUP"
|
||||
|
||||
; Save zero page before anything below gets a chance to use it.
|
||||
|
||||
ldy #<(__ZP_SIZE__ - 1)
|
||||
SaveZP: lda __ZP_START__,y
|
||||
sta __GEOS_SAVED_ZP__,y
|
||||
dey
|
||||
bpl SaveZP
|
||||
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Set up the stack.
|
||||
|
||||
lda #<(__STACKADDR__ + __STACKSIZE__)
|
||||
ldx #>(__STACKADDR__ + __STACKSIZE__)
|
||||
sta c_sp
|
||||
stx c_sp+1
|
||||
|
||||
; Call the module constructors.
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Call the module destructors, then leave this DA and resume the
|
||||
; calling application, restoring cc65's own runtime zero page block
|
||||
; first. Whether main() just returned or RstrAppl() was called
|
||||
; explicitly, both need to happen the same way, so _exit and _RstrAppl
|
||||
; are the same code.
|
||||
|
||||
_exit:
|
||||
_RstrAppl:
|
||||
jsr donelib
|
||||
|
||||
ldy #<(__ZP_SIZE__ - 1)
|
||||
RestoreZP:
|
||||
lda __GEOS_SAVED_ZP__,y
|
||||
sta __ZP_START__,y
|
||||
dey
|
||||
bpl RestoreZP
|
||||
|
||||
jmp RstrAppl
|
||||
@@ -79,6 +79,7 @@ endef # SUBDIR_recipe
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
bitmap-demo.cvt \
|
||||
deskacc.cvt \
|
||||
filesel.cvt \
|
||||
geosver.cvt \
|
||||
getid.cvt \
|
||||
@@ -172,9 +173,14 @@ yesno.cvt: yesnores.grc yesno.c
|
||||
$(if $(QUIET),echo $(SYS):$@)
|
||||
$(CL) -t $(SYS) -O -o $@ -m yesno.map yesnores.grc yesno.c
|
||||
|
||||
deskacc.cvt: deskaccres.grc deskacc.c
|
||||
$(if $(QUIET),echo $(SYS):$@)
|
||||
$(CL) -t geos-c-da -O -o $@ -m deskacc.map deskaccres.grc deskacc.c
|
||||
|
||||
|
||||
clean:
|
||||
@$(DEL) overlay-demores.h 2>$(NULLDEV)
|
||||
@$(DEL) deskaccres.h 2>$(NULLDEV)
|
||||
@$(DEL) bitmap.c 2>$(NULLDEV)
|
||||
@$(DEL) *.cvt 2>$(NULLDEV)
|
||||
@$(DEL) *.map 2>$(NULLDEV)
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
** Desk accessory example, replicating the behaviour of the sample desk
|
||||
** accessory shipped with GeoProgrammer
|
||||
**
|
||||
** 2026, Asbjørn Djupdal (asbjoern@djupdal.org)
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <geos.h>
|
||||
|
||||
#include "deskaccres.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* defines */
|
||||
|
||||
/* screen region this accessory uses, in cards */
|
||||
#define DA_TOP 8
|
||||
#define DA_LEFT 10
|
||||
#define DA_HEIGHT 8
|
||||
#define DA_WIDTH 20
|
||||
|
||||
#define NUM_CARDS (DA_HEIGHT * DA_WIDTH)
|
||||
|
||||
#define COLOR_MATRIX_BASE ((char *) 0x8c00)
|
||||
|
||||
#define CARD_ADDR(base, cardRow, cardCol) \
|
||||
((base) + (unsigned) (cardRow) * (40 * 8) + (unsigned) (cardCol) * 8)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* variables */
|
||||
|
||||
static char recoverFlag;
|
||||
static char colorBuf[NUM_CARDS];
|
||||
static char foreBuf[NUM_CARDS * 8];
|
||||
static char backBuf[NUM_CARDS * 8];
|
||||
|
||||
/*****************************************************************************/
|
||||
/* icon */
|
||||
|
||||
static const unsigned char iconPicture[] = {
|
||||
0x06, 0xFF, 0x81, 0x80, 0x04, 0x00, 0x82, 0x01,
|
||||
0x80, 0x04, 0x00, 0x82, 0x01, 0x80, 0x04, 0x00,
|
||||
0x82, 0x01, 0x80, 0x04, 0x00, 0x82, 0x01, 0x80,
|
||||
0x04, 0x00, 0xBE, 0x01, 0x80, 0x0E, 0x00, 0x00,
|
||||
0x00, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0x01,
|
||||
0x80, 0x04, 0x00, 0x00, 0x00, 0x01, 0x80, 0x04,
|
||||
0x38, 0x63, 0x60, 0x01, 0x80, 0x04, 0x4C, 0x91,
|
||||
0x90, 0x01, 0x80, 0x04, 0x41, 0x09, 0x10, 0x01,
|
||||
0x80, 0x04, 0x41, 0x09, 0x10, 0x01, 0x80, 0x04,
|
||||
0x41, 0x09, 0x10, 0x01, 0x80, 0x04, 0x44, 0x91,
|
||||
0x10, 0x01, 0x80, 0x0E, 0x38, 0x63, 0xB8, 0x01,
|
||||
0x80, 0x04, 0x00, 0x82, 0x01, 0x80, 0x04, 0x00,
|
||||
0x82, 0x01, 0x80, 0x04, 0x00, 0x82, 0x01, 0x80,
|
||||
0x04, 0x00, 0x82, 0x01, 0x80, 0x04, 0x00, 0x82,
|
||||
0x01, 0x80, 0x04, 0x00, 0x81, 0x01, 0x06, 0xFF
|
||||
};
|
||||
|
||||
void DoIcon1 (void);
|
||||
|
||||
static const struct icontab icon = {
|
||||
1,
|
||||
{ DA_LEFT * 8, DA_TOP * 8 },
|
||||
{
|
||||
{ (char *) iconPicture, DA_LEFT + 3, DA_TOP * 8 + 24, 6, 23,
|
||||
(unsigned) DoIcon1 }
|
||||
}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* framed box */
|
||||
|
||||
static const graphicStr drawBox = {
|
||||
NEWPATTERN (0), /* white */
|
||||
MOVEPENTO (DA_LEFT * 8, DA_TOP * 8),
|
||||
RECTANGLETO ((DA_LEFT + DA_WIDTH) * 8 - 1, (DA_TOP + DA_HEIGHT) * 8 - 1),
|
||||
NEWPATTERN (1), /* black */
|
||||
FRAME_RECTO (DA_LEFT * 8, DA_TOP * 8),
|
||||
GSTR_END
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* functions */
|
||||
|
||||
/* copy this accessory's screen area, one card at a time, between the given
|
||||
** screen bitmap and the given RAM buffer.
|
||||
*/
|
||||
static void CopyBitmap (char *screen, char *buf, bool toBuf)
|
||||
{
|
||||
char row, col, i;
|
||||
char *card;
|
||||
|
||||
for (row = 0; row < DA_HEIGHT; ++row) {
|
||||
for (col = 0; col < DA_WIDTH; ++col) {
|
||||
card = CARD_ADDR (screen, DA_TOP + row, DA_LEFT + col);
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (toBuf) {
|
||||
*buf++ = card[i];
|
||||
} else {
|
||||
card[i] = *buf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* save screen buffers */
|
||||
static void SaveScreen (void)
|
||||
{
|
||||
CopyBitmap (BACK_SCR_BASE, backBuf, true);
|
||||
|
||||
if (recoverFlag & 0x80) {
|
||||
CopyBitmap (SCREEN_BASE, foreBuf, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore screen buffers */
|
||||
static void RestoreScreen (void)
|
||||
{
|
||||
CopyBitmap (BACK_SCR_BASE, backBuf, false);
|
||||
|
||||
if (recoverFlag & 0x80) {
|
||||
CopyBitmap (SCREEN_BASE, foreBuf, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* save color values */
|
||||
static void SaveColors (void)
|
||||
{
|
||||
char row, col, fillColor;
|
||||
|
||||
fillColor = COLOR_MATRIX_BASE[39];
|
||||
|
||||
for (row = 0; row < DA_HEIGHT; ++row) {
|
||||
for (col = 0; col < DA_WIDTH; ++col) {
|
||||
if (recoverFlag & 0x40) {
|
||||
colorBuf[row * DA_WIDTH + col] =
|
||||
COLOR_MATRIX_BASE[(DA_TOP + row) * 40 + DA_LEFT + col];
|
||||
}
|
||||
COLOR_MATRIX_BASE[(DA_TOP + row) * 40 + DA_LEFT + col] = fillColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore color values */
|
||||
static void RestoreColors (void)
|
||||
{
|
||||
char row, col;
|
||||
|
||||
for (row = 0; row < DA_HEIGHT; ++row) {
|
||||
for (col = 0; col < DA_WIDTH; ++col) {
|
||||
COLOR_MATRIX_BASE[(DA_TOP + row) * 40 + DA_LEFT + col] =
|
||||
colorBuf[row * DA_WIDTH + col];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* handlers */
|
||||
|
||||
void DoClose (void)
|
||||
{
|
||||
GotoFirstMenu ();
|
||||
}
|
||||
|
||||
void DoCut (void)
|
||||
{
|
||||
GotoFirstMenu ();
|
||||
}
|
||||
|
||||
void DoCopy (void)
|
||||
{
|
||||
GotoFirstMenu ();
|
||||
}
|
||||
|
||||
void DoPaste (void)
|
||||
{
|
||||
GotoFirstMenu ();
|
||||
}
|
||||
|
||||
void DoIcon1 (void)
|
||||
{
|
||||
}
|
||||
|
||||
void DoQuit (void)
|
||||
{
|
||||
GotoFirstMenu ();
|
||||
if (recoverFlag & 0x40) {
|
||||
RestoreColors ();
|
||||
}
|
||||
RestoreScreen ();
|
||||
RstrAppl ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void main (void)
|
||||
{
|
||||
recoverFlag = r10L;
|
||||
|
||||
SaveScreen ();
|
||||
SaveColors ();
|
||||
|
||||
dispBufferOn = ST_WR_FORE | ST_WR_BACK;
|
||||
|
||||
GraphicsString (&drawBox);
|
||||
DoMenu ((struct menu *) &mainMenu);
|
||||
DoIcons ((struct icontab *) &icon);
|
||||
|
||||
MainLoop ();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
MENU fileSubMenu 80,79 VERTICAL
|
||||
{
|
||||
"close" MENU_ACTION DoClose
|
||||
"quit" MENU_ACTION DoQuit
|
||||
}
|
||||
|
||||
MENU editSubMenu 100,79 VERTICAL
|
||||
{
|
||||
"cut" MENU_ACTION DoCut
|
||||
"copy" MENU_ACTION DoCopy
|
||||
"paste" MENU_ACTION DoPaste
|
||||
}
|
||||
|
||||
MENU mainMenu 80,64 HORIZONTAL
|
||||
{
|
||||
"file" SUB_MENU fileSubMenu
|
||||
"edit" SUB_MENU editSubMenu
|
||||
}
|
||||
|
||||
HEADER DESK_ACC "deskacc" "DeskAcc Demo" "V1.0" {
|
||||
dostype USR
|
||||
info "Sample desk accessory"
|
||||
mode 40only
|
||||
}
|
||||
@@ -333,6 +333,7 @@ static void SetSys (const char* Sys)
|
||||
NewSymbol ("__GAMATE__", 1);
|
||||
break;
|
||||
|
||||
case TGT_GEOS_CBM_DA:
|
||||
case TGT_GEOS_CBM:
|
||||
/* Do not handle as a CBM system */
|
||||
NewSymbol ("__GEOS__", 1);
|
||||
|
||||
@@ -243,6 +243,7 @@ static void SetSys (const char* Sys)
|
||||
DefineNumericMacro ("__GAMATE__", 1);
|
||||
break;
|
||||
|
||||
case TGT_GEOS_CBM_DA:
|
||||
case TGT_GEOS_CBM:
|
||||
/* Do not handle as a CBM system */
|
||||
DefineNumericMacro ("__GEOS__", 1);
|
||||
|
||||
@@ -185,6 +185,7 @@ static const TargetEntry TargetMap[] = {
|
||||
{ "gamate", TGT_GAMATE },
|
||||
{ "geos", TGT_GEOS_CBM },
|
||||
{ "geos-apple", TGT_GEOS_APPLE },
|
||||
{ "geos-c-da", TGT_GEOS_CBM_DA },
|
||||
{ "geos-cbm", TGT_GEOS_CBM },
|
||||
{ "kim1", TGT_KIM1 },
|
||||
{ "lunix", TGT_LUNIX },
|
||||
@@ -251,6 +252,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = {
|
||||
{ "kim1", CPU_6502, BINFMT_BINARY, CTNone },
|
||||
{ "rp6502", CPU_W65C02, BINFMT_BINARY, CTNone },
|
||||
{ "agat", CPU_6502, BINFMT_BINARY, CTAgat },
|
||||
{ "geos-c-da", CPU_6502, BINFMT_BINARY, CTNone },
|
||||
};
|
||||
|
||||
/* Target system */
|
||||
|
||||
@@ -93,6 +93,7 @@ typedef enum {
|
||||
TGT_KIM1,
|
||||
TGT_RP6502,
|
||||
TGT_AGAT,
|
||||
TGT_GEOS_CBM_DA,
|
||||
TGT_COUNT /* Number of target systems */
|
||||
} target_t;
|
||||
|
||||
|
||||
+70
-28
@@ -148,6 +148,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
{
|
||||
switch (FindTarget (Arg)) {
|
||||
|
||||
case TGT_GEOS_CBM_DA:
|
||||
case TGT_GEOS_CBM:
|
||||
apple = 0;
|
||||
break;
|
||||
@@ -462,6 +463,7 @@ static void DoHeader (void)
|
||||
char *token;
|
||||
char i1[9], i2[9], i3[9];
|
||||
int i;
|
||||
int isDeskAcc = 0;
|
||||
|
||||
openSFile ();
|
||||
|
||||
@@ -471,20 +473,28 @@ static void DoHeader (void)
|
||||
|
||||
if (apple == 1) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
case 0: /* APPLICATION */
|
||||
myHead.geostype = 0x82;
|
||||
break;
|
||||
case 2: /* DESK_ACC */
|
||||
myHead.geostype = 0x81;
|
||||
isDeskAcc = 1;
|
||||
break;
|
||||
default:
|
||||
AbEnd ("Filetype '%s' is not supported yet", token);
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 0:
|
||||
case 0: /* APPLICATION */
|
||||
myHead.geostype = 6;
|
||||
break;
|
||||
case 1:
|
||||
case 1: /* AUTO_EXEC */
|
||||
myHead.geostype = 14;
|
||||
break;
|
||||
case 2: /* DESK_ACC */
|
||||
myHead.geostype = 5;
|
||||
isDeskAcc = 1;
|
||||
break;
|
||||
default:
|
||||
AbEnd ("Filetype '%s' is not supported yet", token);
|
||||
}
|
||||
@@ -597,31 +607,46 @@ static void DoHeader (void)
|
||||
|
||||
/* OK, all information is gathered, do flushout */
|
||||
|
||||
if (isDeskAcc) {
|
||||
/* The end address for a desk accessory must cover the whole memory
|
||||
** range GEOS has to save and restore. __HIMEM__ is used for this
|
||||
*/
|
||||
fprintf (outputSFile,
|
||||
" .import __HIMEM__\n");
|
||||
}
|
||||
|
||||
fprintf (outputSFile,
|
||||
" .import __BSS_SIZE__, __STARTUP_RUN__\n"
|
||||
" .import __VLIR0_START__, __VLIR0_LAST__\n"
|
||||
" .import __VLIR0_BLOCKS__\n"
|
||||
" .import __VLIR1_BLOCKS__\n"
|
||||
" .import __VLIR2_BLOCKS__\n"
|
||||
" .import __VLIR3_BLOCKS__\n"
|
||||
" .import __VLIR4_BLOCKS__\n"
|
||||
" .import __VLIR5_BLOCKS__\n"
|
||||
" .import __VLIR6_BLOCKS__\n"
|
||||
" .import __VLIR7_BLOCKS__\n"
|
||||
" .import __VLIR8_BLOCKS__\n"
|
||||
" .import __VLIR9_BLOCKS__\n"
|
||||
" .import __VLIR10_BLOCKS__\n"
|
||||
" .import __VLIR11_BLOCKS__\n"
|
||||
" .import __VLIR12_BLOCKS__\n"
|
||||
" .import __VLIR13_BLOCKS__\n"
|
||||
" .import __VLIR14_BLOCKS__\n"
|
||||
" .import __VLIR15_BLOCKS__\n"
|
||||
" .import __VLIR16_BLOCKS__\n"
|
||||
" .import __VLIR17_BLOCKS__\n"
|
||||
" .import __VLIR18_BLOCKS__\n"
|
||||
" .import __VLIR19_BLOCKS__\n\n"
|
||||
);
|
||||
|
||||
if (myHead.structure == APPHEADER_STRUCTURE_VLIR) {
|
||||
fprintf (outputSFile,
|
||||
" .import __VLIR1_BLOCKS__\n"
|
||||
" .import __VLIR2_BLOCKS__\n"
|
||||
" .import __VLIR3_BLOCKS__\n"
|
||||
" .import __VLIR4_BLOCKS__\n"
|
||||
" .import __VLIR5_BLOCKS__\n"
|
||||
" .import __VLIR6_BLOCKS__\n"
|
||||
" .import __VLIR7_BLOCKS__\n"
|
||||
" .import __VLIR8_BLOCKS__\n"
|
||||
" .import __VLIR9_BLOCKS__\n"
|
||||
" .import __VLIR10_BLOCKS__\n"
|
||||
" .import __VLIR11_BLOCKS__\n"
|
||||
" .import __VLIR12_BLOCKS__\n"
|
||||
" .import __VLIR13_BLOCKS__\n"
|
||||
" .import __VLIR14_BLOCKS__\n"
|
||||
" .import __VLIR15_BLOCKS__\n"
|
||||
" .import __VLIR16_BLOCKS__\n"
|
||||
" .import __VLIR17_BLOCKS__\n"
|
||||
" .import __VLIR18_BLOCKS__\n"
|
||||
" .import __VLIR19_BLOCKS__\n"
|
||||
);
|
||||
}
|
||||
|
||||
fprintf (outputSFile, "\n");
|
||||
|
||||
fprintf (outputSFile,
|
||||
" .segment \"DIRENTRY\"\n\n");
|
||||
|
||||
@@ -674,12 +699,22 @@ static void DoHeader (void)
|
||||
* add size of each VLIR segment, plus 1 block for the info block (icon),
|
||||
* plus another block for the VLIR RECORDS table (VLIR structure only)
|
||||
*/
|
||||
" .word %d + __VLIR0_BLOCKS__ + __VLIR1_BLOCKS__ + __VLIR2_BLOCKS__ + __VLIR3_BLOCKS__ + __VLIR4_BLOCKS__ + __VLIR5_BLOCKS__ + __VLIR6_BLOCKS__ + __VLIR7_BLOCKS__ + __VLIR8_BLOCKS__ + __VLIR9_BLOCKS__ + __VLIR10_BLOCKS__ + __VLIR11_BLOCKS__ + __VLIR12_BLOCKS__ + __VLIR13_BLOCKS__ + __VLIR14_BLOCKS__ + __VLIR15_BLOCKS__ + __VLIR16_BLOCKS__ + __VLIR17_BLOCKS__ + __VLIR18_BLOCKS__ + __VLIR19_BLOCKS__\n"
|
||||
/* PRG formatted or SEQ formatted */
|
||||
" .byte \"%s formatted GEOS file V1.0\"\n\n",
|
||||
" .word %d + __VLIR0_BLOCKS__",
|
||||
myHead.structure, myHead.geostype,
|
||||
myHead.year, myHead.month, myHead.day, myHead.hour, myHead.min,
|
||||
(myHead.structure == APPHEADER_STRUCTURE_SEQ) ? 1 : 2,
|
||||
(myHead.structure == APPHEADER_STRUCTURE_SEQ) ? 1 : 2
|
||||
);
|
||||
|
||||
if (myHead.structure == APPHEADER_STRUCTURE_VLIR) {
|
||||
fprintf (outputSFile,
|
||||
" + __VLIR1_BLOCKS__ + __VLIR2_BLOCKS__ + __VLIR3_BLOCKS__ + __VLIR4_BLOCKS__ + __VLIR5_BLOCKS__ + __VLIR6_BLOCKS__ + __VLIR7_BLOCKS__ + __VLIR8_BLOCKS__ + __VLIR9_BLOCKS__ + __VLIR10_BLOCKS__ + __VLIR11_BLOCKS__ + __VLIR12_BLOCKS__ + __VLIR13_BLOCKS__ + __VLIR14_BLOCKS__ + __VLIR15_BLOCKS__ + __VLIR16_BLOCKS__ + __VLIR17_BLOCKS__ + __VLIR18_BLOCKS__ + __VLIR19_BLOCKS__"
|
||||
);
|
||||
}
|
||||
|
||||
fprintf (outputSFile,
|
||||
"\n"
|
||||
/* PRG formatted or SEQ formatted */
|
||||
" .byte \"%s formatted GEOS file V1.0\"\n\n",
|
||||
(myHead.structure == APPHEADER_STRUCTURE_SEQ) ? "SEQ" : "PRG"
|
||||
);
|
||||
}
|
||||
@@ -702,8 +737,15 @@ static void DoHeader (void)
|
||||
|
||||
fprintf (outputSFile,
|
||||
" .byte %i, %i, %i\n"
|
||||
" .word __VLIR0_START__, __VLIR0_START__ - 1, __STARTUP_RUN__\n\n",
|
||||
myHead.dostype, myHead.geostype, myHead.structure);
|
||||
" .word __VLIR0_START__, %s, __STARTUP_RUN__\n\n",
|
||||
myHead.dostype, myHead.geostype, myHead.structure,
|
||||
/* For desk accessories, GEOS computes the memory range to back up
|
||||
** and restore as (end address - start address), i.e. end address
|
||||
** is exclusive. Every other file type uses the documented
|
||||
** "start address - 1" dummy convention instead (this field isn't
|
||||
** meaningful for them).
|
||||
*/
|
||||
isDeskAcc ? "__HIMEM__" : "__VLIR0_START__ - 1");
|
||||
|
||||
fillOut (myHead.classname, 12, "$20");
|
||||
|
||||
|
||||
Reference in new issue
Block a user