2017-12-06 20:36:14 +00:00
|
|
|
#ifndef _APPLE2_H_
|
|
|
|
#define _APPLE2_H_
|
|
|
|
|
2017-12-16 04:22:40 +00:00
|
|
|
#include "apple2.dd.h"
|
2017-12-21 02:45:26 +00:00
|
|
|
#include "mos6502.h"
|
2017-12-22 05:33:04 +00:00
|
|
|
#include "vm_bitfont.h"
|
2017-12-21 02:45:26 +00:00
|
|
|
#include "vm_screen.h"
|
2017-12-06 20:36:14 +00:00
|
|
|
|
2018-01-04 02:48:16 +00:00
|
|
|
/*
|
|
|
|
* This is the size of the bitmap font we use for the apple2
|
|
|
|
*/
|
|
|
|
#define APPLE2_SYSFONT_SIZE 21558
|
|
|
|
|
2018-01-10 22:47:45 +00:00
|
|
|
/*
|
|
|
|
* The reset vector is the address where the apple will consult to
|
|
|
|
* figure out where control should go after a reset. Think of this as
|
|
|
|
* something like a pointer to a main() function in C. That is: where's
|
|
|
|
* the main function? Let's ask the reset vector!
|
|
|
|
*/
|
|
|
|
#define APPLE2_RESET_VECTOR 0x03F2
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is the address of the validity-check byte, aka the power-up
|
|
|
|
* byte. The Apple II will use this to see if the reset vector is valid.
|
|
|
|
*/
|
|
|
|
#define APPLE2_POWERUP_BYTE 0x03F4
|
|
|
|
|
|
|
|
/*
|
|
|
|
* I'm not _exactly_ clear on where the applesoft interpreter lives in
|
|
|
|
* ROM, after spending possibly too-much time researching how this
|
|
|
|
* works. My guess is I'm missing something that's obvious to others.
|
|
|
|
* $E000 seems to be the original spot that Integer BASIC was contained,
|
|
|
|
* and I'm going to guess Applesoft BASIC is in the same spot. Here's
|
|
|
|
* hoping!
|
|
|
|
*/
|
|
|
|
#define APPLE2_APPLESOFT_MAIN 0xE000
|
|
|
|
|
2017-12-21 03:52:28 +00:00
|
|
|
enum video_modes {
|
2017-12-21 17:52:56 +00:00
|
|
|
VIDEO_40COL_TEXT,
|
2017-12-21 03:52:28 +00:00
|
|
|
VIDEO_LORES,
|
|
|
|
VIDEO_HIRES,
|
2017-12-21 17:52:56 +00:00
|
|
|
VIDEO_80COL_TEXT,
|
2017-12-21 03:52:28 +00:00
|
|
|
VIDEO_DOUBLE_LORES,
|
|
|
|
VIDEO_DOUBLE_HIRES,
|
|
|
|
};
|
|
|
|
|
2017-12-21 17:52:56 +00:00
|
|
|
enum color_modes {
|
|
|
|
COLOR_GREEN,
|
|
|
|
COLOR_AMBER,
|
|
|
|
COLOR_GRAY,
|
|
|
|
COLOR_FULL,
|
|
|
|
};
|
|
|
|
|
2017-12-24 21:07:24 +00:00
|
|
|
enum lores_colors {
|
|
|
|
LORES_BLACK,
|
|
|
|
LORES_MAGENTA,
|
|
|
|
LORES_DARKBLUE,
|
|
|
|
LORES_PURPLE,
|
|
|
|
LORES_DARKGREEN,
|
|
|
|
LORES_GRAY1,
|
|
|
|
LORES_MEDBLUE,
|
|
|
|
LORES_LIGHTBLUE,
|
|
|
|
LORES_BROWN,
|
|
|
|
LORES_ORANGE,
|
|
|
|
LORES_GRAY2,
|
|
|
|
LORES_PINK,
|
|
|
|
LORES_LIGHTGREEN,
|
|
|
|
LORES_YELLOW,
|
|
|
|
LORES_AQUAMARINE,
|
|
|
|
LORES_WHITE,
|
|
|
|
};
|
|
|
|
|
2018-01-11 01:59:33 +00:00
|
|
|
// Write-protect on/off.
|
|
|
|
// Read target = ROM or RAM.
|
|
|
|
// Write target = RAM.
|
|
|
|
// Set mode of $Dxxx hexapage bank1 or bank2 ram.
|
|
|
|
|
|
|
|
// 0 - 0=off 1=on
|
|
|
|
// 1 - 0=ROM 1=RAM
|
|
|
|
// 2 - 0=BANK1 1=BANK2
|
|
|
|
|
2018-01-02 22:24:51 +00:00
|
|
|
/*
|
2018-01-11 01:59:33 +00:00
|
|
|
* An Apple II has bank-switched memory beginning with $D000 extending
|
|
|
|
* through $FFFF. The enums below define bit flag names to determine
|
|
|
|
* what is accessible through those addresses.
|
|
|
|
*
|
|
|
|
* Note that it _is_ possible to write while reading ROM, but your
|
|
|
|
* writes will not go to ROM; they'll go to _RAM_. Any write to $E000 -
|
|
|
|
* $FFFF may only be sent to bank 1 RAM. Writes to $D000-$DFFF may
|
|
|
|
* either be sent to bank 1 RAM or bank 2 RAM based upon the RAM2 bit
|
|
|
|
* flag below.
|
2018-01-02 22:24:51 +00:00
|
|
|
*/
|
|
|
|
enum memory_mode {
|
2018-01-11 01:59:33 +00:00
|
|
|
MEMORY_ROM = 1, // on = read ROM; off = read RAM
|
|
|
|
MEMORY_WRITE = 2, // on = allow writes to RAM; off = disallow writes
|
|
|
|
MEMORY_RAM2 = 4, // on = use bank 2 for $D000-$DFFF; off = use bank 1
|
2018-01-12 01:52:13 +00:00
|
|
|
MEMORY_AUX = 8, // on = use auxiliary memory; off = use main memory
|
2018-01-02 22:24:51 +00:00
|
|
|
};
|
|
|
|
|
2017-12-06 20:36:14 +00:00
|
|
|
typedef struct {
|
|
|
|
/*
|
|
|
|
* The apple 2 hardware used an MOS-6502 processor.
|
|
|
|
*/
|
|
|
|
mos6502 *cpu;
|
2017-12-06 21:21:39 +00:00
|
|
|
|
|
|
|
/*
|
2018-01-11 03:28:05 +00:00
|
|
|
* This is the main memory bank of the computer. Conventionally, it
|
|
|
|
* contains not only the first contiguous 48k of RAM, but it also
|
|
|
|
* contains the last 12k of bank 1 RAM.
|
2017-12-06 21:21:39 +00:00
|
|
|
*/
|
2018-01-11 03:28:05 +00:00
|
|
|
vm_segment *main;
|
2017-12-16 04:22:40 +00:00
|
|
|
|
2018-01-02 22:24:51 +00:00
|
|
|
/*
|
|
|
|
* The Apple II used a system of bank-switched memory to enable
|
|
|
|
* software to address a separate block of ROM.
|
|
|
|
*/
|
|
|
|
vm_segment *rom;
|
|
|
|
|
2018-01-11 02:36:44 +00:00
|
|
|
/*
|
|
|
|
* The Apple II may have an auxiliary RAM bank; this was possible by
|
|
|
|
* installing a card there. If you had the 80-column text card (and
|
|
|
|
* you likely did), then you got an extra kilobyte of RAM to work
|
|
|
|
* with; it was either used for the extra columns or you could take
|
|
|
|
* advantage of it for extra storage otherwise.
|
|
|
|
*/
|
|
|
|
vm_segment *aux;
|
|
|
|
|
2017-12-21 02:45:26 +00:00
|
|
|
/*
|
|
|
|
* The screen wherein we shall render all of our graphics.
|
|
|
|
*/
|
|
|
|
vm_screen *screen;
|
|
|
|
|
2017-12-22 05:33:04 +00:00
|
|
|
/*
|
|
|
|
* This is the system font (the only font the Apple II knows about,
|
|
|
|
* really); anywhere we render text, we have to use this font.
|
|
|
|
*/
|
|
|
|
vm_bitfont *sysfont;
|
|
|
|
|
2017-12-21 03:52:28 +00:00
|
|
|
/*
|
|
|
|
* This is the mode in which we must interpret graphics. This will
|
|
|
|
* tell us not only if we're in lo- or hi-res, but also if we are in
|
|
|
|
* single or double view mode.
|
|
|
|
*/
|
|
|
|
int video_mode;
|
|
|
|
|
2017-12-21 17:52:56 +00:00
|
|
|
/*
|
|
|
|
* This is the color mode we want to emulate. You can have a few
|
|
|
|
* different styles of monochromatic displays: green, amber, and
|
|
|
|
* light gray on black; you can also emulate a full color display,
|
|
|
|
* in which text mode tends to look like light gray.
|
|
|
|
*/
|
|
|
|
int color_mode;
|
|
|
|
|
2018-01-02 22:24:51 +00:00
|
|
|
/*
|
|
|
|
* This describes the behavior of our bank-switching scheme. We need
|
|
|
|
* our read/write mappers to know where writes into the
|
|
|
|
* bank-switched area of memory should target.
|
|
|
|
*/
|
2018-01-11 01:59:33 +00:00
|
|
|
vm_8bit bank_switch;
|
2018-01-02 22:24:51 +00:00
|
|
|
|
2017-12-16 04:22:40 +00:00
|
|
|
/*
|
|
|
|
* Our two disk drives.
|
|
|
|
*/
|
|
|
|
apple2dd *drive1;
|
|
|
|
apple2dd *drive2;
|
2017-12-06 20:36:14 +00:00
|
|
|
} apple2;
|
|
|
|
|
2017-12-21 02:45:26 +00:00
|
|
|
extern apple2 *apple2_create(int, int);
|
2017-12-26 22:39:32 +00:00
|
|
|
extern bool apple2_is_double_video(apple2 *);
|
|
|
|
extern int apple2_boot(apple2 *);
|
|
|
|
extern void apple2_clear_strobe(apple2 *);
|
2017-12-06 21:21:39 +00:00
|
|
|
extern void apple2_free(apple2 *);
|
|
|
|
extern void apple2_press_key(apple2 *, vm_8bit);
|
|
|
|
extern void apple2_release_key(apple2 *);
|
2018-01-05 22:20:13 +00:00
|
|
|
extern void apple2_reset(apple2 *);
|
2017-12-21 02:45:26 +00:00
|
|
|
extern void apple2_run_loop(apple2 *);
|
2017-12-22 05:33:04 +00:00
|
|
|
extern void apple2_set_color(apple2 *, int);
|
2018-01-11 01:59:33 +00:00
|
|
|
extern void apple2_set_bank_switch(apple2 *, vm_8bit);
|
2017-12-21 03:52:28 +00:00
|
|
|
extern void apple2_set_video(apple2 *, int);
|
2017-12-06 20:36:14 +00:00
|
|
|
|
|
|
|
#endif
|