mirror of
https://github.com/V2RetroComputing/analog.git
synced 2025-02-19 13:31:06 +00:00
Release 01-19-2023-131
This commit is contained in:
parent
d9be2ed9cd
commit
564ebb545a
@ -34,11 +34,10 @@ else
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_apple2 = \
|
||||
uploadfont
|
||||
EXELIST_apple2 = uploadfont/uploadfont uploadfont/flashfont configtool/configtool
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
all: $(EXELIST_$(SYS))
|
||||
all: disk $(EXELIST_$(SYS))
|
||||
else
|
||||
all: notavailable
|
||||
endif
|
||||
@ -52,15 +51,17 @@ else
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
disk: font.dsk
|
||||
disk: v2a525.po v2a35.po
|
||||
|
||||
font.dsk: uploadfont
|
||||
cp prodos/prodos.dsk $@
|
||||
java -jar $(AC) -n $@ FONTDISK
|
||||
java -jar $(AC) -p $@ BASIC.SYSTEM SYS 0x2000 <prodos/basic.system
|
||||
java -jar $(AC) -p $@ BITSY.BOOT SYS 0x2000 <prodos/bitsy.boot
|
||||
java -jar $(AC) -p $@ QUIT.SYSTEM SYS 0x2000 <prodos/quit.system
|
||||
java -jar $(AC) -as $@ UPLOADFONT <uploadfont
|
||||
v2a525.po: uploadfont/uploadfont uploadfont/uploadfonte uploadfont/flashfont uploadfont/flashfonte configtool/v2acfg configtool/v2acfge
|
||||
cp prodos/pd525.po $@
|
||||
java -jar $(AC) -n $@ V2ANALOG
|
||||
java -jar $(AC) -as $@ UPLOADFONT <uploadfont/uploadfont
|
||||
java -jar $(AC) -as $@ UPLOADFONTE <uploadfont/uploadfonte
|
||||
java -jar $(AC) -as $@ FLASHFONT <uploadfont/flashfont
|
||||
java -jar $(AC) -as $@ FLASHFONTE <uploadfont/flashfonte
|
||||
java -jar $(AC) -as $@ V2ACFG <configtool/v2acfg
|
||||
java -jar $(AC) -as $@ V2ACFGE <configtool/v2acfge
|
||||
java -jar $(AC) -p $@ IIC.FONT BIN 0x2000 <fonts/iicfont.bin
|
||||
java -jar $(AC) -p $@ IIPLUS.FONT BIN 0x2000 <fonts/iiplus.bin
|
||||
java -jar $(AC) -p $@ LOWERCASE.FONT BIN 0x2000 <fonts/lcase.bin
|
||||
@ -74,9 +75,45 @@ font.dsk: uploadfont
|
||||
java -jar $(AC) -bas $@ MOUSETEXT.BAS <prodos/mousetext.bas
|
||||
java -jar $(AC) -bas $@ REACTIVE.BAS <prodos/reactive.bas
|
||||
|
||||
uploadfont: uploadfont.c
|
||||
$(CL) -Oirs -t apple2 --start-addr 0x4000 -m uploadfont.map $^
|
||||
v2a35.po: uploadfont/uploadfont uploadfont/uploadfonte uploadfont/flashfont uploadfont/flashfonte configtool/v2acfg configtool/v2acfge
|
||||
cp prodos/pd35.po $@
|
||||
java -jar $(AC) -n $@ V2ANALOG
|
||||
java -jar $(AC) -as $@ UPLOADFONT <uploadfont/uploadfont
|
||||
java -jar $(AC) -as $@ UPLOADFONTE <uploadfont/uploadfonte
|
||||
java -jar $(AC) -as $@ FLASHFONT <uploadfont/flashfont
|
||||
java -jar $(AC) -as $@ FLASHFONTE <uploadfont/flashfonte
|
||||
java -jar $(AC) -as $@ V2ACFG <configtool/v2acfg
|
||||
java -jar $(AC) -as $@ V2ACFGE <configtool/v2acfge
|
||||
java -jar $(AC) -p $@ IIC.FONT BIN 0x2000 <fonts/iicfont.bin
|
||||
java -jar $(AC) -p $@ IIPLUS.FONT BIN 0x2000 <fonts/iiplus.bin
|
||||
java -jar $(AC) -p $@ LOWERCASE.FONT BIN 0x2000 <fonts/lcase.bin
|
||||
java -jar $(AC) -p $@ PIG.FONT BIN 0x2000 <fonts/pigfont.bin
|
||||
java -jar $(AC) -p $@ MOUSETEXT.FONT BIN 0x2000 <fonts/iiemouse.bin
|
||||
java -jar $(AC) -p $@ REACTIVE.FONT BIN 0x2000 <fonts/reactive.bin
|
||||
java -jar $(AC) -bas $@ IICFONT.BAS <prodos/iicfont.bas
|
||||
java -jar $(AC) -bas $@ IIPLUS.BAS <prodos/iiplus.bas
|
||||
java -jar $(AC) -bas $@ LOWERCASE.BAS <prodos/lowercase.bas
|
||||
java -jar $(AC) -bas $@ PIGFONT.BAS <prodos/pigfont.bas
|
||||
java -jar $(AC) -bas $@ MOUSETEXT.BAS <prodos/mousetext.bas
|
||||
java -jar $(AC) -bas $@ REACTIVE.BAS <prodos/reactive.bas
|
||||
|
||||
uploadfont/uploadfont: uploadfont/uploadfont.c
|
||||
$(MAKE) -C uploadfont uploadfont
|
||||
|
||||
uploadfont/uploadfonte: uploadfont/uploadfont.c
|
||||
$(MAKE) -C uploadfont uploadfonte
|
||||
|
||||
uploadfont/flashfont: uploadfont/flashfont.c
|
||||
$(MAKE) -C uploadfont flashfont
|
||||
|
||||
uploadfont/flashfonte: uploadfont/flashfont.c
|
||||
$(MAKE) -C uploadfont flashfonte
|
||||
|
||||
configtool/v2acfg: configtool/configtool.c
|
||||
$(MAKE) -C configtool v2acfg
|
||||
|
||||
configtool/v2acfge: configtool/configtool.c
|
||||
$(MAKE) -C configtool v2acfge
|
||||
|
||||
clean:
|
||||
@$(DEL) font.dsk 2>$(NULLDEV)
|
||||
@$(DEL) uploadfont uploadfont.map 2>$(NULLDEV)
|
||||
|
@ -1,8 +1,11 @@
|
||||
#ifndef PICOPAL_SLOT
|
||||
#define PICOPAL_SLOT 3
|
||||
#endif
|
||||
|
||||
#define PICOPAL_REGISTER(n) (*(volatile unsigned char *)(0xc080 | (n) | (PICOPAL_SLOT << 4)))
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
|
||||
#define PICOPAL_REGISTER(n) (*(volatile unsigned char *)(0xC080 | (n) | (cardslot << 4)))
|
||||
|
||||
#define PICOPAL_WRDATA PICOPAL_REGISTER(0x0)
|
||||
#define PICOPAL_ALSB PICOPAL_REGISTER(0x1)
|
||||
@ -13,3 +16,98 @@
|
||||
#define PICOPAL_RDDATA PICOPAL_REGISTER(0x7)
|
||||
#define PICOPAL_WRFONT PICOPAL_REGISTER(0x8)
|
||||
#define PICOPAL_RDFONT PICOPAL_REGISTER(0xf)
|
||||
|
||||
#define CFG_BUFFER ((volatile unsigned char *)(0xC0E0 | (cardslot << 8)))
|
||||
|
||||
typedef enum {
|
||||
MODE_REBOOT = 0,
|
||||
MODE_DIAG,
|
||||
MODE_FS,
|
||||
MODE_VGACARD,
|
||||
MODE_APPLICARD,
|
||||
MODE_SERIAL,
|
||||
MODE_PARALLEL,
|
||||
MODE_MIDI,
|
||||
MODE_SNESMAX,
|
||||
MODE_ETHERNET
|
||||
} v2mode_t;
|
||||
|
||||
typedef enum {
|
||||
SERIAL_LOOP = 0,
|
||||
SERIAL_USB,
|
||||
SERIAL_WIFI,
|
||||
SERIAL_PRINTER,
|
||||
} serialmux_t;
|
||||
|
||||
typedef enum {
|
||||
USB_HOST_CDC,
|
||||
USB_GUEST_CDC,
|
||||
USB_GUEST_MIDI,
|
||||
} usbmux_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_CLIENT = 0,
|
||||
WIFI_AP,
|
||||
} wifimode_t;
|
||||
|
||||
|
||||
#define FS_BUFFER ((volatile unsigned char *)(0xC800))
|
||||
|
||||
#define FS_COMMAND PICOPAL_REGISTER(0x0)
|
||||
#define FS_FILE PICOPAL_REGISTER(0x1)
|
||||
#define FS_FLAGS PICOPAL_REGISTER(0x1)
|
||||
#define FS_SIZELSB PICOPAL_REGISTER(0x2)
|
||||
#define FS_SIZEMSB PICOPAL_REGISTER(0x3)
|
||||
#define FS_OFFLSB PICOPAL_REGISTER(0x2)
|
||||
#define FS_OFFMSB PICOPAL_REGISTER(0x3)
|
||||
#define FS_WHENCE PICOPAL_REGISTER(0x4)
|
||||
#define FS_BUSY PICOPAL_REGISTER(0xD)
|
||||
#define FS_STATUS PICOPAL_REGISTER(0xE)
|
||||
#define FS_EXECUTE PICOPAL_REGISTER(0xF)
|
||||
|
||||
|
||||
#define FS_O_RD 1
|
||||
#define FS_O_WR 2
|
||||
#define FS_O_APPEND 4
|
||||
#define FS_O_EXISTING 8
|
||||
#define FS_O_CREATE 16
|
||||
#define FS_O_TRUNC 32
|
||||
|
||||
#define FS_SEEK_SET 0
|
||||
#define FS_SEEK_CUR 1
|
||||
#define FS_SEEK_END 2
|
||||
|
||||
typedef enum {
|
||||
FS_OPEN = 0x10,
|
||||
FS_CLOSE = 0x11,
|
||||
FS_READ = 0x12,
|
||||
FS_WRITE = 0x13,
|
||||
FS_SEEK = 0x14,
|
||||
FS_TELL = 0x15,
|
||||
} fscommand_t;
|
||||
|
||||
typedef enum {
|
||||
FS_ERR_OK = 0, // No error
|
||||
FS_ERR_IO = -1, // Error during device operation
|
||||
FS_ERR_CORRUPT = -2, // Corrupted
|
||||
FS_ERR_NOENT = -3, // No directory entry
|
||||
FS_ERR_EXIST = -4, // Entry already exists
|
||||
FS_ERR_NOTDIR = -5, // Entry is not a dir
|
||||
FS_ERR_ISDIR = -5, // Entry is a dir
|
||||
FS_ERR_NOTEMPTY = -7, // Dir is not empty
|
||||
FS_ERR_BADF = -8, // Bad file number
|
||||
FS_ERR_FBIG = -9, // File too large
|
||||
FS_ERR_INVAL = -10, // Invalid parameter
|
||||
FS_ERR_NOSPC = -11, // No space left on device
|
||||
FS_ERR_NOMEM = -12, // No more memory available
|
||||
FS_ERR_NOATTR = -13, // No data/attr available
|
||||
FS_ERR_NAMETOOLONG = -14 // File name too long
|
||||
} fserror_t;
|
||||
|
||||
typedef enum {
|
||||
MACHINE_AUTO = 0,
|
||||
MACHINE_APPLE_II = 1,
|
||||
MACHINE_APPLE_IIE = 2,
|
||||
MACHINE_APPLE_IIGS = 3,
|
||||
MACHINE_MAXVALUE = 4
|
||||
} compat_t;
|
||||
|
File diff suppressed because it is too large
Load Diff
56
utilities/modes/Makefile
Normal file
56
utilities/modes/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= apple2
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_apple2 = modeswitch
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
all: $(EXELIST_$(SYS))
|
||||
else
|
||||
all: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: modeswitch not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'all' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
modeswitch: modeswitch.c
|
||||
$(CL) -Oirs -t apple2 --start-addr 0x2000 -m $@.map -o $@ $^
|
||||
~/applesingle/applesingle -r < $@ > $@"#062000"
|
||||
|
||||
clean:
|
||||
@$(DEL) modeswitch modeswitch.map 2>$(NULLDEV)
|
299
utilities/modes/modeswitch.c
Normal file
299
utilities/modes/modeswitch.c
Normal file
@ -0,0 +1,299 @@
|
||||
// cl65 -t apple2 --start-addr 0x4000 uploadfont.c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../common/picopal.h"
|
||||
|
||||
uint16_t cardslot = 3;
|
||||
uint8_t *cfgbuf;
|
||||
|
||||
void paint_backdrop(char *str) {
|
||||
int w, i;
|
||||
|
||||
w = strlen(str);
|
||||
if(w > 20) {
|
||||
w = 20;
|
||||
}
|
||||
|
||||
clrscr();
|
||||
gotoy(0); gotox(1);
|
||||
cputs("V2 Analog");
|
||||
|
||||
gotoy(0); gotox(39 - w);
|
||||
|
||||
if((w == 19) && str[19])
|
||||
w = 16;
|
||||
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(str[i]);
|
||||
}
|
||||
if((i == 17) && str[i])
|
||||
cputs("...");
|
||||
|
||||
gotoy(1); gotox(0);
|
||||
cputs("----------------------------------------");
|
||||
|
||||
gotoy(22); gotox(0);
|
||||
cputs("----------------------------------------");
|
||||
|
||||
gotoy(23); gotox(4);
|
||||
cputs("https://www.v2retrocomputing.com");
|
||||
}
|
||||
|
||||
void message(char *str) {
|
||||
int w, x, i, c;
|
||||
|
||||
if(strlen(str) > 34) {
|
||||
w = 34;
|
||||
} else {
|
||||
w = strlen(str);
|
||||
}
|
||||
|
||||
x = 20 - ((w+6)/2);
|
||||
|
||||
gotoy(9); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < (w); i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
gotoy(10); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(11); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(c = 0; c < w; c++) {
|
||||
cputc(str[c]);
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(12); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(13); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < ((w-4)/2); i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs("[OK]");
|
||||
i += 4;
|
||||
for(; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(14); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(15); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
for(;;) {
|
||||
switch(cgetc()) {
|
||||
case 0x0A:
|
||||
case 0x0D:
|
||||
case 0x1B:
|
||||
case 'O':
|
||||
case 'o':
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int confirm(char *str) {
|
||||
int w, x, i, c;
|
||||
|
||||
if(strlen(str) > 34) {
|
||||
w = 34;
|
||||
} else {
|
||||
w = strlen(str);
|
||||
}
|
||||
|
||||
x = 20 - ((w+6)/2);
|
||||
|
||||
gotoy(9); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < (w); i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
gotoy(10); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(11); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(c = 0; c < w; c++) {
|
||||
cputc(str[c]);
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(12); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(13); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < ((w-12)/2); i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs("[YES] / [NO]");
|
||||
i += 12;
|
||||
for(; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(14); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(15); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
|
||||
for(;;) {
|
||||
switch(cgetc()) {
|
||||
case 0x0A:
|
||||
case 0x0D:
|
||||
case 'Y':
|
||||
case 'y':
|
||||
return 1;
|
||||
case 0x1B:
|
||||
case 'N':
|
||||
case 'n':
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cfg_cmd(char *cmd) {
|
||||
int i = 0;
|
||||
uint16_t delay;
|
||||
|
||||
while(i < 31) {
|
||||
if(*cmd) {
|
||||
cfgbuf[i++] = *cmd++;
|
||||
} else {
|
||||
cfgbuf[i++] = 0x00;
|
||||
}
|
||||
}
|
||||
cfgbuf[31] = 0x00;
|
||||
|
||||
delay = 0x1fff;
|
||||
while(delay > 0) delay--;
|
||||
}
|
||||
|
||||
|
||||
int prompt_slot(void) {
|
||||
int c;
|
||||
paint_backdrop("Mode Switch");
|
||||
|
||||
gotoy(11); gotox(2);
|
||||
cputs("Which slot is the card installed in?");
|
||||
gotoy(13); gotox(14);
|
||||
printf("Default = %i", cardslot);
|
||||
|
||||
for(;;) {
|
||||
c = cgetc();
|
||||
if((c >= '1') && (c <= '7')) {
|
||||
cardslot = c - '0';
|
||||
return 1;
|
||||
} else if((c == 0x0A) || (c == 0x0D)) {
|
||||
return 1;
|
||||
} else if(c == 0x1B) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main (void) {
|
||||
int paint_menu = 1;
|
||||
int c;
|
||||
|
||||
if(!prompt_slot()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cfgbuf = (uint8_t *)(0xC0E0 | (cardslot << 8));
|
||||
|
||||
paint_backdrop("Mode Switch");
|
||||
gotoy(11); gotox(4);
|
||||
cputs("1. VGA Card");
|
||||
gotoy(12); gotox(4);
|
||||
cputs("2. PCPI Applicard");
|
||||
gotoy(13); gotox(4);
|
||||
cputs("3. Serial");
|
||||
gotoy(14); gotox(4);
|
||||
cputs("4. Parallel");
|
||||
gotoy(15); gotox(4);
|
||||
cputs("5. Card Diagnostic");
|
||||
gotoy(18); gotox(4);
|
||||
cputs("8. Save Default");
|
||||
gotoy(19); gotox(4);
|
||||
cputs("9. Quit");
|
||||
|
||||
for(;;) {
|
||||
c = cgetc();
|
||||
switch(c) {
|
||||
case '1':
|
||||
cfg_cmd("MODE=VGA");
|
||||
break;
|
||||
case '2':
|
||||
cfg_cmd("MODE=Z80");
|
||||
break;
|
||||
case '3':
|
||||
cfg_cmd("MODE=SERIAL");
|
||||
break;
|
||||
case '4':
|
||||
cfg_cmd("MODE=PARALLEL");
|
||||
break;
|
||||
case '5':
|
||||
cfg_cmd("MODE=DIAG");
|
||||
break;
|
||||
case '8':
|
||||
cfg_cmd("WRITE_CONFIG");
|
||||
break;
|
||||
case '9':
|
||||
clrscr();
|
||||
puts("Done.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -31,8 +31,7 @@ else
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_apple2 = \
|
||||
uploadfont
|
||||
EXELIST_apple2 = uploadfont uploadfonte flashfont flashfonte
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
all: $(EXELIST_$(SYS))
|
||||
@ -50,7 +49,20 @@ else
|
||||
endif
|
||||
|
||||
uploadfont: uploadfont.c
|
||||
$(CL) -Oirs -t apple2 --start-addr 0x4000 -m uploadfont.map $^
|
||||
$(CL) -Oirs -t apple2 --start-addr 0x2800 -m $@.map -o $@ $^
|
||||
~/applesingle/applesingle -r < $@ > $@"#062800"
|
||||
|
||||
uploadfonte: uploadfont.c
|
||||
$(CL) -Oirs -t apple2enh --start-addr 0x2800 -m $@.map -o $@ $^
|
||||
~/applesingle/applesingle -r < $@ > $@"#062800"
|
||||
|
||||
flashfont: flashfont.c
|
||||
$(CL) -Oirs -t apple2 --start-addr 0x2800 -m $@.map -o $@ $^
|
||||
~/applesingle/applesingle -r < $@ > $@"#062800"
|
||||
|
||||
flashfonte: flashfont.c
|
||||
$(CL) -Oirs -t apple2enh --start-addr 0x2800 -m $@.map -o $@ $^
|
||||
~/applesingle/applesingle -r < $@ > $@"#062800"
|
||||
|
||||
clean:
|
||||
@$(DEL) uploadfont uploadfont.map 2>$(NULLDEV)
|
||||
@$(DEL) uploadfont uploadfont.map uploadfonte uploadfonte.map flashfont flashfont.map flashfonte flashfonte.map 2>$(NULLDEV)
|
||||
|
449
utilities/uploadfont/flashfont.c
Normal file
449
utilities/uploadfont/flashfont.c
Normal file
@ -0,0 +1,449 @@
|
||||
// cl65 -t apple2 --start-addr 0x4000 uploadfont.c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../common/picopal.h"
|
||||
|
||||
uint16_t cardslot = 3;
|
||||
uint8_t *cfgbuf;
|
||||
uint8_t *fsbuf;
|
||||
uint8_t *font = (uint8_t *)0x2000;
|
||||
|
||||
#define CARD_TIMEOUT 0xfff
|
||||
uint16_t timeout = CARD_TIMEOUT;
|
||||
|
||||
void paint_backdrop(char *str) {
|
||||
int w, i;
|
||||
|
||||
w = strlen(str);
|
||||
if(w > 20) {
|
||||
w = 20;
|
||||
}
|
||||
|
||||
clrscr();
|
||||
gotoy(0); gotox(1);
|
||||
cputs("V2 Analog");
|
||||
|
||||
gotoy(0); gotox(39 - w);
|
||||
|
||||
if((w == 19) && str[19])
|
||||
w = 16;
|
||||
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(str[i]);
|
||||
}
|
||||
if((i == 17) && str[i])
|
||||
cputs("...");
|
||||
|
||||
gotoy(1); gotox(0);
|
||||
cputs("----------------------------------------");
|
||||
|
||||
gotoy(22); gotox(0);
|
||||
cputs("----------------------------------------");
|
||||
|
||||
gotoy(23); gotox(4);
|
||||
cputs("https://www.v2retrocomputing.com");
|
||||
}
|
||||
|
||||
void message(char *str) {
|
||||
int w, x, i, c;
|
||||
|
||||
if(strlen(str) > 34) {
|
||||
w = 34;
|
||||
} else {
|
||||
w = strlen(str);
|
||||
}
|
||||
|
||||
x = 20 - ((w+6)/2);
|
||||
|
||||
gotoy(9); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < (w); i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
gotoy(10); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(11); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(c = 0; c < w; c++) {
|
||||
cputc(str[c]);
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(12); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(13); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < ((w-4)/2); i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs("[OK]");
|
||||
i += 4;
|
||||
for(; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(14); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(15); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
for(;;) {
|
||||
switch(cgetc()) {
|
||||
case 0x0A:
|
||||
case 0x0D:
|
||||
case 0x1B:
|
||||
case 'O':
|
||||
case 'o':
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int confirm(char *str) {
|
||||
int w, x, i, c;
|
||||
|
||||
if(strlen(str) > 34) {
|
||||
w = 34;
|
||||
} else {
|
||||
w = strlen(str);
|
||||
}
|
||||
|
||||
x = 20 - ((w+6)/2);
|
||||
|
||||
gotoy(9); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < (w); i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
gotoy(10); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(11); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(c = 0; c < w; c++) {
|
||||
cputc(str[c]);
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(12); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(13); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < ((w-12)/2); i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs("[YES] / [NO]");
|
||||
i += 12;
|
||||
for(; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(14); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(15); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
|
||||
for(;;) {
|
||||
switch(cgetc()) {
|
||||
case 0x0A:
|
||||
case 0x0D:
|
||||
case 'Y':
|
||||
case 'y':
|
||||
return 1;
|
||||
case 0x1B:
|
||||
case 'N':
|
||||
case 'n':
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cfg_cmd(char *cmd) {
|
||||
int i = 0;
|
||||
uint16_t delay;
|
||||
|
||||
while(i < 31) {
|
||||
if(*cmd) {
|
||||
cfgbuf[i++] = *cmd++;
|
||||
} else {
|
||||
cfgbuf[i++] = 0x00;
|
||||
}
|
||||
}
|
||||
cfgbuf[31] = 0x00;
|
||||
|
||||
delay = 0x1fff;
|
||||
while(delay > 0) delay--;
|
||||
}
|
||||
|
||||
|
||||
int prompt_slot(void) {
|
||||
int c;
|
||||
paint_backdrop("Font Upload");
|
||||
|
||||
gotoy(11); gotox(2);
|
||||
cputs("Which slot is the card installed in?");
|
||||
gotoy(13); gotox(14);
|
||||
printf("Default = %i", cardslot);
|
||||
|
||||
for(;;) {
|
||||
c = cgetc();
|
||||
if((c >= '1') && (c <= '7')) {
|
||||
cardslot = c - '0';
|
||||
return 1;
|
||||
} else if((c == 0x0A) || (c == 0x0D)) {
|
||||
return 1;
|
||||
} else if(c == 0x1B) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int file_open(char *path, uint8_t flags) {
|
||||
timeout = CARD_TIMEOUT;
|
||||
|
||||
strcpy((char *)fsbuf, path);
|
||||
FS_FLAGS = flags;
|
||||
FS_COMMAND = FS_OPEN;
|
||||
FS_BUSY = 0xFF;
|
||||
FS_EXECUTE = 0x00;
|
||||
|
||||
while(FS_BUSY && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if(FS_BUSY) {
|
||||
message("I/O Error");
|
||||
return FS_ERR_IO;
|
||||
}
|
||||
|
||||
if(FS_STATUS != FS_ERR_OK) {
|
||||
return FS_STATUS;
|
||||
}
|
||||
|
||||
return FS_FILE;
|
||||
}
|
||||
|
||||
int file_close(int file) {
|
||||
timeout = CARD_TIMEOUT;
|
||||
|
||||
FS_FILE = file;
|
||||
FS_COMMAND = FS_CLOSE;
|
||||
FS_BUSY = 0xFF;
|
||||
FS_EXECUTE = 0x00;
|
||||
|
||||
while(FS_BUSY && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if(FS_BUSY) {
|
||||
message("I/O Error");
|
||||
return FS_ERR_IO;
|
||||
}
|
||||
|
||||
return FS_STATUS;
|
||||
}
|
||||
|
||||
int file_read(int file, char *buffer, uint16_t size) {
|
||||
timeout = CARD_TIMEOUT;
|
||||
|
||||
FS_FILE = file;
|
||||
FS_COMMAND = FS_READ;
|
||||
FS_SIZELSB = size & 0xFF;
|
||||
FS_SIZEMSB = size >> 8;
|
||||
FS_BUSY = 0xFF;
|
||||
FS_EXECUTE = 0x00;
|
||||
|
||||
while(FS_BUSY && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if(FS_BUSY) {
|
||||
message("I/O Error");
|
||||
return FS_ERR_IO;
|
||||
}
|
||||
|
||||
if(FS_STATUS != FS_ERR_OK) {
|
||||
return FS_STATUS;
|
||||
}
|
||||
|
||||
size = (((uint16_t)FS_SIZEMSB) << 8) | (uint16_t)FS_SIZELSB;
|
||||
|
||||
memcpy(buffer, fsbuf, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int file_write(int file, char *buffer, uint16_t size) {
|
||||
timeout = CARD_TIMEOUT;
|
||||
|
||||
memcpy(fsbuf, buffer, size);
|
||||
FS_FILE = file;
|
||||
FS_COMMAND = FS_WRITE;
|
||||
FS_SIZELSB = size & 0xFF;
|
||||
FS_SIZEMSB = size >> 8;
|
||||
FS_BUSY = 0xFF;
|
||||
FS_EXECUTE = 0x00;
|
||||
|
||||
while(FS_BUSY && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if(FS_BUSY) {
|
||||
message("I/O Error");
|
||||
return FS_ERR_IO;
|
||||
}
|
||||
|
||||
if(FS_STATUS != FS_ERR_OK) {
|
||||
return FS_STATUS;
|
||||
}
|
||||
|
||||
size = (((uint16_t)FS_SIZEMSB) << 8) | (uint16_t)FS_SIZELSB;
|
||||
return size;
|
||||
}
|
||||
|
||||
int file_seek(int file, int16_t off, uint8_t whence) {
|
||||
timeout = CARD_TIMEOUT;
|
||||
|
||||
FS_FILE = file;
|
||||
FS_COMMAND = FS_SEEK;
|
||||
FS_OFFLSB = ((uint16_t)off) & 0xFF;
|
||||
FS_OFFMSB = ((uint16_t)off) >> 8;
|
||||
FS_WHENCE = whence;
|
||||
FS_BUSY = 0xFF;
|
||||
FS_EXECUTE = 0x00;
|
||||
|
||||
while(FS_BUSY && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if(FS_BUSY) {
|
||||
message("I/O Error");
|
||||
return FS_ERR_IO;
|
||||
}
|
||||
|
||||
if(FS_STATUS != FS_ERR_OK) {
|
||||
return FS_STATUS;
|
||||
}
|
||||
|
||||
off = (int16_t)(((uint16_t)FS_SIZEMSB) << 8) | (uint16_t)FS_SIZELSB;
|
||||
return off;
|
||||
}
|
||||
|
||||
int file_tell(int file) {
|
||||
uint16_t off;
|
||||
timeout = CARD_TIMEOUT;
|
||||
|
||||
FS_FILE = file;
|
||||
FS_COMMAND = FS_TELL;
|
||||
FS_BUSY = 0xFF;
|
||||
FS_EXECUTE = 0x00;
|
||||
|
||||
while(FS_BUSY && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if(FS_BUSY) {
|
||||
message("I/O Error");
|
||||
return FS_ERR_IO;
|
||||
}
|
||||
|
||||
if(FS_STATUS != FS_ERR_OK) {
|
||||
return FS_STATUS;
|
||||
}
|
||||
|
||||
off = (((uint16_t)FS_SIZEMSB) << 8) | (uint16_t)FS_SIZELSB;
|
||||
return off;
|
||||
}
|
||||
|
||||
void main (void) {
|
||||
int paint_menu = 1;
|
||||
int file;
|
||||
|
||||
if(!prompt_slot()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cfgbuf = (uint8_t *)CFG_BUFFER;
|
||||
fsbuf = (uint8_t *)FS_BUFFER;
|
||||
|
||||
paint_backdrop("Please Wait");
|
||||
gotoy(11); gotox(13);
|
||||
cputs("Uploading font,");
|
||||
gotoy(12); gotox(8);
|
||||
cputs("your screen may flicker.");
|
||||
|
||||
cfg_cmd("MODE=FS");
|
||||
while(memcmp(cfgbuf+24, "FSREADY.", 8) && (timeout > 0)) {
|
||||
timeout--;
|
||||
}
|
||||
if(timeout == 0) {
|
||||
message("Communication Timeout");
|
||||
clrscr();
|
||||
return;
|
||||
}
|
||||
|
||||
file = file_open("font", FS_O_WR | FS_O_CREATE);
|
||||
if(file >= 0) {
|
||||
file_write(file, (char *)font, 2048);
|
||||
file_close(file);
|
||||
}
|
||||
|
||||
paint_backdrop("Please Wait");
|
||||
gotoy(11); gotox(13);
|
||||
cputs("Rebooting card,");
|
||||
gotoy(12); gotox(8);
|
||||
cputs("your screen may flicker.");
|
||||
|
||||
cfg_cmd("REBOOT");
|
||||
clrscr();
|
||||
puts("Done.\n");
|
||||
}
|
@ -6,22 +6,280 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PICOPAL_SLOT 3
|
||||
#include "../common/picopal.h"
|
||||
|
||||
void main (void)
|
||||
{
|
||||
unsigned char *font = (unsigned char *)0x2000;
|
||||
int i;
|
||||
uint16_t cardslot = 3;
|
||||
uint8_t *cfgbuf;
|
||||
uint8_t *fsbuf;
|
||||
uint8_t *font = (uint8_t *)0x2000;
|
||||
|
||||
puts("Loading font to PicoPal in slot 3...");
|
||||
void paint_backdrop(char *str) {
|
||||
int w, i;
|
||||
|
||||
PICOPAL_ALSB = 0x00;
|
||||
PICOPAL_AMSB = 0x00;
|
||||
|
||||
for(i = 0; i < 0x800; i++) {
|
||||
PICOPAL_WRFONT = font[i];
|
||||
w = strlen(str);
|
||||
if(w > 20) {
|
||||
w = 20;
|
||||
}
|
||||
|
||||
clrscr();
|
||||
gotoy(0); gotox(1);
|
||||
cputs("V2 Analog");
|
||||
|
||||
gotoy(0); gotox(39 - w);
|
||||
|
||||
if((w == 19) && str[19])
|
||||
w = 16;
|
||||
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(str[i]);
|
||||
}
|
||||
if((i == 17) && str[i])
|
||||
cputs("...");
|
||||
|
||||
gotoy(1); gotox(0);
|
||||
cputs("----------------------------------------");
|
||||
|
||||
gotoy(22); gotox(0);
|
||||
cputs("----------------------------------------");
|
||||
|
||||
gotoy(23); gotox(4);
|
||||
cputs("https://www.v2retrocomputing.com");
|
||||
}
|
||||
|
||||
void message(char *str) {
|
||||
int w, x, i, c;
|
||||
|
||||
if(strlen(str) > 34) {
|
||||
w = 34;
|
||||
} else {
|
||||
w = strlen(str);
|
||||
}
|
||||
|
||||
x = 20 - ((w+6)/2);
|
||||
|
||||
gotoy(9); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < (w); i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
gotoy(10); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(11); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(c = 0; c < w; c++) {
|
||||
cputc(str[c]);
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(12); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(13); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < ((w-4)/2); i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs("[OK]");
|
||||
i += 4;
|
||||
for(; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(14); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(15); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
for(;;) {
|
||||
switch(cgetc()) {
|
||||
case 0x0A:
|
||||
case 0x0D:
|
||||
case 0x1B:
|
||||
case 'O':
|
||||
case 'o':
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int confirm(char *str) {
|
||||
int w, x, i, c;
|
||||
|
||||
if(strlen(str) > 34) {
|
||||
w = 34;
|
||||
} else {
|
||||
w = strlen(str);
|
||||
}
|
||||
|
||||
x = 20 - ((w+6)/2);
|
||||
|
||||
gotoy(9); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < (w); i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
gotoy(10); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(11); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(c = 0; c < w; c++) {
|
||||
cputc(str[c]);
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(12); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(13); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < ((w-12)/2); i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs("[YES] / [NO]");
|
||||
i += 12;
|
||||
for(; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(14); gotox(x);
|
||||
cputs(" ! ");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc(' ');
|
||||
}
|
||||
cputs(" ! ");
|
||||
|
||||
gotoy(15); gotox(x);
|
||||
cputs(" +-");
|
||||
for(i = 0; i < w; i++) {
|
||||
cputc('-');
|
||||
}
|
||||
cputs("-+ ");
|
||||
|
||||
|
||||
for(;;) {
|
||||
switch(cgetc()) {
|
||||
case 0x0A:
|
||||
case 0x0D:
|
||||
case 'Y':
|
||||
case 'y':
|
||||
return 1;
|
||||
case 0x1B:
|
||||
case 'N':
|
||||
case 'n':
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cfg_cmd(char *cmd) {
|
||||
int i = 0;
|
||||
uint16_t delay;
|
||||
|
||||
while(i < 31) {
|
||||
if(*cmd) {
|
||||
cfgbuf[i++] = *cmd++;
|
||||
} else {
|
||||
cfgbuf[i++] = 0x00;
|
||||
}
|
||||
}
|
||||
cfgbuf[31] = 0x00;
|
||||
|
||||
delay = 0x1fff;
|
||||
while(delay > 0) delay--;
|
||||
}
|
||||
|
||||
|
||||
int prompt_slot(void) {
|
||||
int c;
|
||||
paint_backdrop("Font Upload");
|
||||
|
||||
gotoy(11); gotox(2);
|
||||
cputs("Which slot is the card installed in?");
|
||||
gotoy(13); gotox(14);
|
||||
printf("Default = %i", cardslot);
|
||||
|
||||
for(;;) {
|
||||
c = cgetc();
|
||||
if((c >= '1') && (c <= '7')) {
|
||||
cardslot = c - '0';
|
||||
return 1;
|
||||
} else if((c == 0x0A) || (c == 0x0D)) {
|
||||
return 1;
|
||||
} else if(c == 0x1B) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main (void) {
|
||||
int paint_menu = 1;
|
||||
uint16_t i;
|
||||
|
||||
if(!prompt_slot()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cfgbuf = (uint8_t *)CFG_BUFFER;
|
||||
fsbuf = (uint8_t *)FS_BUFFER;
|
||||
|
||||
paint_backdrop("Please Wait");
|
||||
gotoy(11); gotox(13);
|
||||
cputs("Uploading font,");
|
||||
gotoy(12); gotox(8);
|
||||
cputs("your screen may flicker.");
|
||||
|
||||
cfg_cmd("BANK=SAVE");
|
||||
cfg_cmd("BANK=FONT0");
|
||||
for(i = 0; i < 0x200; i++) {
|
||||
FS_BUFFER[i] = font[i];
|
||||
}
|
||||
cfg_cmd("BANK=FONT1");
|
||||
for(i = 0; i < 0x200; i++) {
|
||||
FS_BUFFER[i] = font[i+512];
|
||||
}
|
||||
cfg_cmd("BANK=FONT2");
|
||||
for(i = 0; i < 0x200; i++) {
|
||||
FS_BUFFER[i] = font[i+1024];
|
||||
}
|
||||
cfg_cmd("BANK=FONT3");
|
||||
for(i = 0; i < 0x200; i++) {
|
||||
FS_BUFFER[i] = font[i+1536];
|
||||
}
|
||||
cfg_cmd("BANK=RESTORE");
|
||||
|
||||
clrscr();
|
||||
puts("Done.\n");
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
if(${CMAKE_CURRENT_BINARY_DIR} MATCHES "build-lc")
|
||||
set(PICO_BOARD pico)
|
||||
else()
|
||||
set(PICO_BOARD pico_w)
|
||||
endif()
|
||||
|
||||
set(PICO_TARGET_LINKER_SCRIPT memmap_ota.ld)
|
||||
|
||||
# Pull in SDK (must be before project)
|
||||
@ -23,7 +28,7 @@ pico_generate_pio_header(v2-analog-${PICO_BOARD}
|
||||
target_sources(v2-analog-${PICO_BOARD} PUBLIC
|
||||
common/ota.o
|
||||
common/buffers.c
|
||||
common/flash_upload.c
|
||||
common/flash.c
|
||||
common/abus.c
|
||||
common/config.c
|
||||
common/main.c
|
||||
|
@ -33,9 +33,9 @@ next_bus_cycle:
|
||||
write_cycle:
|
||||
; the current time is P0+88ns (P0 + 16ns + 2 clocks (input synchronizers) + 7 instructions)
|
||||
|
||||
set PINS, 0b110 [14] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+200ns)
|
||||
set PINS, 0b110 [15] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+200ns)
|
||||
in PINS, 10 ; read R/W, ~DEVSEL, and Data[7:0], then autopush
|
||||
wait 0 GPIO, PHI0_GPIO [6] ; wait for PHI0 to fall
|
||||
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall
|
||||
jmp next_bus_cycle
|
||||
|
||||
read_cycle:
|
||||
@ -45,7 +45,7 @@ read_cycle:
|
||||
in PINS, 10 ; read R/W, ~DEVSEL, and dontcare[7:0], then autopush
|
||||
|
||||
irq set READ_DATA_TRIGGER_IRQ ; trigger the data read state machine to put data on the data bus
|
||||
wait 0 GPIO, PHI0_GPIO [6] ; wait for PHI0 to fall
|
||||
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall
|
||||
wait 0 irq DATA_BUSY_IRQ ; wait for the data handling state machine to complete to avoid contention w/transceiver control
|
||||
.wrap
|
||||
|
||||
@ -79,8 +79,8 @@ wait_loop:
|
||||
pull noblock ; extra early pull to clear out any standing values from the FIFO
|
||||
|
||||
set PINS, 0b01 ; enable Data tranceiver with output direction
|
||||
mov OSR, ~NULL
|
||||
out PINDIRS, 8 [30] ; set data pins as outputs
|
||||
mov OSR, ~NULL [3]
|
||||
out PINDIRS, 8 [31] ; set data pins as outputs
|
||||
|
||||
pull noblock ; pull value from the FIFO as late as possible
|
||||
out PINS, 8
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "buffers.h"
|
||||
|
||||
volatile uint8_t cardslot = 0;
|
||||
volatile uint32_t busactive = 0;
|
||||
|
||||
volatile uint8_t apple_memory[64*1024];
|
||||
volatile uint8_t private_memory[64*1024];
|
||||
|
||||
|
@ -2,11 +2,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern volatile uint8_t config_memory[32];
|
||||
extern volatile uint8_t cardslot;
|
||||
extern volatile uint32_t busactive;
|
||||
|
||||
extern volatile uint8_t apple_memory[64*1024];
|
||||
extern volatile uint8_t private_memory[64*1024];
|
||||
|
||||
#define config_cmdbuf ((uint8_t*)(apple_memory+0xC0F0+(cardslot<<8)))
|
||||
#define config_errbuf ((uint8_t*)(apple_memory+0xC0F8+(cardslot<<8)))
|
||||
|
||||
extern volatile uint8_t *text_p1;
|
||||
extern volatile uint8_t *text_p2;
|
||||
extern volatile uint8_t *text_p3;
|
||||
|
@ -1,246 +1,333 @@
|
||||
#include "common/config.h"
|
||||
#include "common/buffers.h"
|
||||
#include "common/flash.h"
|
||||
#include "pico_hal.h"
|
||||
|
||||
volatile uint8_t config_memory[32];
|
||||
volatile v2mode_t cfg_mode = MODE_UNKNOWN;
|
||||
volatile v2mode_t current_mode = MODE_UNKNOWN;
|
||||
|
||||
v2mode_t v2mode;
|
||||
usbmux_t usbmux;
|
||||
serialmux_t serialmux;
|
||||
wifimode_t wifimode;
|
||||
compat_t machine;
|
||||
uint8_t wifi_ssid[32];
|
||||
uint8_t wifi_psk[32];
|
||||
volatile usbmux_t usbmux;
|
||||
volatile serialmux_t serialmux;
|
||||
volatile wifimode_t wifimode;
|
||||
|
||||
extern bool userfont;
|
||||
volatile compat_t cfg_machine = MACHINE_AUTO;
|
||||
volatile compat_t current_machine = MACHINE_AUTO;
|
||||
|
||||
volatile uint8_t wifi_ssid[32];
|
||||
volatile uint8_t wifi_psk[32];
|
||||
|
||||
extern volatile bool userfont;
|
||||
|
||||
char ERR_READY[8] = { 'R', 'E', 'A', 'D', 'Y', 0, 0, 0 };
|
||||
char ERR_EOF[8] = { 'E', 'O', 'F', 0, 0, 0, 0, 0 };
|
||||
char ERR_NOFILE[8] = { 'E', 'O', 'F', 0, 0, 0, 0, 0 };
|
||||
|
||||
void parse_config(uint8_t *buffer) {
|
||||
if(!memcmp("MODE=", buffer, 5)) {
|
||||
if(!strcmp("DIAG", buffer+5)) {
|
||||
v2mode = MODE_DIAG;
|
||||
} else if(!strcmp("FS", buffer+5)) {
|
||||
v2mode = MODE_FS;
|
||||
} else if(!strcmp("VGA", buffer+5)) {
|
||||
v2mode = MODE_VGACARD;
|
||||
} else if(!strcmp("Z80", buffer+5)) {
|
||||
v2mode = MODE_APPLICARD;
|
||||
} else if(!strcmp("SERIAL", buffer+5)) {
|
||||
v2mode = MODE_SERIAL;
|
||||
} else if(!strcmp("PARALLEL", buffer+5)) {
|
||||
v2mode = MODE_PARALLEL;
|
||||
} else if(!strcmp("SNESMAX", buffer+5)) {
|
||||
v2mode = MODE_SNESMAX;
|
||||
if(!memcmp("C=", buffer, 2)) {
|
||||
if(!strcmp("DIAG", buffer+2)) {
|
||||
cfg_mode = MODE_DIAG;
|
||||
} else if(!strcmp("FS", buffer+2)) {
|
||||
cfg_mode = MODE_FS;
|
||||
} else if(!strcmp("VGA", buffer+2)) {
|
||||
cfg_mode = MODE_VGACARD;
|
||||
} else if(!strcmp("Z80", buffer+2)) {
|
||||
cfg_mode = MODE_APPLICARD;
|
||||
} else if(!strcmp("SER", buffer+2)) {
|
||||
cfg_mode = MODE_SERIAL;
|
||||
} else if(!strcmp("PAR", buffer+2)) {
|
||||
cfg_mode = MODE_PARALLEL;
|
||||
} else if(!strcmp("SNES", buffer+2)) {
|
||||
cfg_mode = MODE_SNESMAX;
|
||||
}
|
||||
} else if(!memcmp("MACHINE=", buffer, 8)) {
|
||||
if(!strcmp("II", buffer+8)) {
|
||||
machine = APPLE_II;
|
||||
} else if(!memcmp("H=", buffer, 2)) {
|
||||
if(!strcmp("AUTO", buffer+2)) {
|
||||
cfg_machine = MACHINE_AUTO;
|
||||
} else if(!strcmp("II", buffer+2)) {
|
||||
cfg_machine = MACHINE_II;
|
||||
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
|
||||
} else if(!strcmp("IIE", buffer+8)) {
|
||||
machine = APPLE_IIE;
|
||||
} else if(!strcmp("IIE", buffer+2)) {
|
||||
cfg_machine = MACHINE_IIE;
|
||||
soft_switches &= ~SOFTSW_IIGS_REGS;
|
||||
soft_switches |= SOFTSW_IIE_REGS;
|
||||
} else if(!strcmp("IIGS", buffer+8)) {
|
||||
machine = APPLE_IIGS;
|
||||
} else if(!strcmp("IIGS", buffer+2)) {
|
||||
cfg_machine = MACHINE_IIGS;
|
||||
soft_switches |= SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS;
|
||||
}
|
||||
} else if(!memcmp("MUX=", buffer, 4)) {
|
||||
if(!strcmp("USB", buffer+4)) {
|
||||
} else if(!memcmp("S=", buffer, 2)) {
|
||||
if(!strcmp("USB", buffer+2)) {
|
||||
serialmux = SERIAL_USB;
|
||||
} else if(!strcmp("MODEM", buffer+4)) {
|
||||
} else if(!strcmp("WIFI", buffer+2)) {
|
||||
serialmux = SERIAL_WIFI;
|
||||
} else if(!strcmp("PRINTER", buffer+4)) {
|
||||
} else if(!strcmp("PRN", buffer+2)) {
|
||||
serialmux = SERIAL_PRINTER;
|
||||
} else if(!strcmp("LOOP", buffer+4)) {
|
||||
} else if(!strcmp("LOOP", buffer+2)) {
|
||||
serialmux = SERIAL_LOOP;
|
||||
}
|
||||
} else if(!memcmp("USB=", buffer, 4)) {
|
||||
if(!strcmp("CDC_GUEST", buffer+4)) {
|
||||
} else if(!memcmp("U=", buffer, 2)) {
|
||||
if(!strcmp("CG", buffer+2)) {
|
||||
usbmux = USB_GUEST_CDC;
|
||||
} else if(!strcmp("CDC_HOST", buffer+4)) {
|
||||
} else if(!strcmp("CH", buffer+2)) {
|
||||
usbmux = USB_HOST_CDC;
|
||||
}
|
||||
} else if(!memcmp("WIFI=", buffer, 5)) {
|
||||
if(!strcmp("CLIENT", buffer+5)) {
|
||||
} else if(!memcmp("W=", buffer, 2)) {
|
||||
if(!strcmp("C", buffer+2)) {
|
||||
wifimode = WIFI_CLIENT;
|
||||
} else if(!strcmp("AP", buffer+5)) {
|
||||
} else if(!strcmp("A", buffer+2)) {
|
||||
wifimode = WIFI_AP;
|
||||
}
|
||||
} else if(!memcmp("SSID=", buffer, 5)) {
|
||||
strncpy(wifi_ssid, buffer+5, 25);
|
||||
} else if(!memcmp("PSK=", buffer, 4)) {
|
||||
strncpy(wifi_psk, buffer+5, 26);
|
||||
} else if(!memcmp("WN=", buffer, 3)) {
|
||||
strncpy((char*)wifi_ssid, buffer+5, 24);
|
||||
} else if(!memcmp("WP=", buffer, 3)) {
|
||||
strncpy((char*)wifi_psk, buffer+5, 24);
|
||||
}
|
||||
}
|
||||
|
||||
void default_config() {
|
||||
v2mode = MODE_VGACARD;
|
||||
cfg_mode = MODE_VGACARD;
|
||||
serialmux = SERIAL_LOOP;
|
||||
usbmux = USB_GUEST_CDC;
|
||||
wifimode = WIFI_AP;
|
||||
strcpy(wifi_ssid, "V2RetroNet");
|
||||
strcpy(wifi_psk, "Analog");
|
||||
machine = COMPAT_AUTO;
|
||||
soft_switches = 0;
|
||||
strcpy((char*)wifi_ssid, "V2RetroNet");
|
||||
strcpy((char*)wifi_psk, "Analog");
|
||||
cfg_machine = MACHINE_AUTO;
|
||||
}
|
||||
|
||||
void write_config() {
|
||||
uint8_t config_temp[32];
|
||||
int make_config(uint8_t *buf, uint16_t len) {
|
||||
uint16_t ptr = 0;
|
||||
|
||||
if(v2mode == MODE_DIAG) return;
|
||||
if(v2mode == MODE_REBOOT) return;
|
||||
|
||||
int file = pico_open("config", LFS_O_WRONLY | LFS_O_CREAT);
|
||||
if(file < 0)
|
||||
return;
|
||||
|
||||
switch(v2mode) {
|
||||
case MODE_FS:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=FS");
|
||||
pico_write(file, config_temp, 32);
|
||||
break;
|
||||
memset(buf, 0, len);
|
||||
|
||||
switch(cfg_mode) {
|
||||
default:
|
||||
case MODE_VGACARD:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=VGA");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "C=VGA");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MODE_APPLICARD:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=Z80");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "C=Z80");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MODE_SERIAL:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=SERIAL");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "C=SER");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MODE_PARALLEL:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=PARALLEL");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "C=PAR");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MODE_SNESMAX:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=SNESMAX");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "C=SNES");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MODE_ETHERNET:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MODE=ETHERNET");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "C=NET");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MODE_FS:
|
||||
strcpy(buf+ptr, "C=FS");
|
||||
ptr += 32;
|
||||
break;
|
||||
}
|
||||
switch(machine) {
|
||||
case APPLE_II:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MACHINE=II");
|
||||
pico_write(file, config_temp, 32);
|
||||
switch(cfg_machine) {
|
||||
default:
|
||||
case MACHINE_AUTO:
|
||||
strcpy(buf+ptr, "H=AUTO");
|
||||
ptr += 32;
|
||||
break;
|
||||
case APPLE_IIE:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MACHINE=IIE");
|
||||
pico_write(file, config_temp, 32);
|
||||
case MACHINE_II:
|
||||
strcpy(buf+ptr, "H=II");
|
||||
ptr += 32;
|
||||
break;
|
||||
case APPLE_IIGS:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MACHINE=IIGS");
|
||||
pico_write(file, config_temp, 32);
|
||||
case MACHINE_IIE:
|
||||
strcpy(buf+ptr, "H=IIE");
|
||||
ptr += 32;
|
||||
break;
|
||||
case MACHINE_IIGS:
|
||||
strcpy(buf+ptr, "H=IIGS");
|
||||
ptr += 32;
|
||||
break;
|
||||
}
|
||||
switch(serialmux) {
|
||||
default:
|
||||
case SERIAL_LOOP:
|
||||
strcpy(buf+ptr, "M=LOOP");
|
||||
ptr += 32;
|
||||
break;
|
||||
case SERIAL_USB:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MUX=USB");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "M=USB");
|
||||
ptr += 32;
|
||||
break;
|
||||
case SERIAL_WIFI:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MUX=WIFI");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "M=WIFI");
|
||||
ptr += 32;
|
||||
break;
|
||||
case SERIAL_PRINTER:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MUX=PRINTER");
|
||||
pico_write(file, config_temp, 32);
|
||||
break;
|
||||
case SERIAL_LOOP:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "MUX=LOOP");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "M=PRN");
|
||||
ptr += 32;
|
||||
break;
|
||||
}
|
||||
switch(usbmux) {
|
||||
case USB_GUEST_CDC:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "USB=CDC_GUEST");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "U=CG");
|
||||
ptr += 32;
|
||||
break;
|
||||
case USB_HOST_CDC:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "USB=CDC_HOST");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "U=CH");
|
||||
ptr += 32;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(wifimode) {
|
||||
case WIFI_CLIENT:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "WIFI=CLIENT");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "W=C");
|
||||
ptr += 32;
|
||||
break;
|
||||
case WIFI_AP:
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "WIFI=AP");
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "W=A");
|
||||
ptr += 32;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "SSID=");
|
||||
strncat(config_temp, wifi_ssid, 25);
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "WS=");
|
||||
strncpy(buf+ptr+2, (char*)wifi_ssid, 24);
|
||||
ptr += 32;
|
||||
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
strcpy(config_temp, "PSK=");
|
||||
strncat(config_temp, wifi_psk, 25);
|
||||
pico_write(file, config_temp, 32);
|
||||
strcpy(buf+ptr, "WP=");
|
||||
strncpy(buf+ptr+2, (char*)wifi_psk, 24);
|
||||
ptr += 32;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void write_config() {
|
||||
uint8_t config_temp[1024];
|
||||
int config_len;
|
||||
config_len = make_config(config_temp, sizeof(config_temp));
|
||||
|
||||
int file = pico_open("config", LFS_O_WRONLY | LFS_O_CREAT);
|
||||
if(file < 0)
|
||||
return;
|
||||
|
||||
pico_write(file, config_temp, config_len);
|
||||
pico_close(file);
|
||||
}
|
||||
|
||||
void read_config() {
|
||||
uint8_t config_temp[32];
|
||||
uint8_t config_temp[1024];
|
||||
int file = pico_open("config", LFS_O_RDONLY);
|
||||
int br = 0;
|
||||
int config_len = 0;
|
||||
|
||||
if(file < 0)
|
||||
return;
|
||||
|
||||
do {
|
||||
br = pico_read(file, config_temp, 32);
|
||||
if(br > 0) {
|
||||
parse_config(config_temp);
|
||||
}
|
||||
} while(br > 0);
|
||||
|
||||
memset(config_temp, 0, sizeof(config_temp));
|
||||
config_len = pico_read(file, config_temp, sizeof(config_temp));
|
||||
pico_close(file);
|
||||
|
||||
if(config_len > 0) {
|
||||
for(int ptr = 0; ptr < config_len; ptr+=32) {
|
||||
parse_config(config_temp+ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volatile uint8_t *videx_page_tmp = (private_memory+0xF000);
|
||||
extern uint8_t character_rom[4096];
|
||||
extern uint8_t character_rom[2048];
|
||||
|
||||
void upload_config() {
|
||||
int file = pico_open("config", LFS_O_RDONLY);
|
||||
|
||||
memset((uint8_t*)(apple_memory + 0xC800), 0, 1024);
|
||||
if(file < 0) {
|
||||
make_config((uint8_t*)(apple_memory + 0xC800), 1024);
|
||||
} else {
|
||||
pico_read(file, (uint8_t*)(apple_memory + 0xC800), 1024);
|
||||
pico_close(file);
|
||||
}
|
||||
|
||||
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
|
||||
}
|
||||
|
||||
void download_config(uint16_t ptr) {
|
||||
int file = pico_open("config", LFS_O_WRONLY | LFS_O_CREAT);
|
||||
|
||||
if(file < 0) {
|
||||
memcpy(config_errbuf, ERR_NOFILE, sizeof(ERR_NOFILE));
|
||||
return;
|
||||
}
|
||||
|
||||
pico_write(file, (uint8_t*)(apple_memory + ptr), 1024);
|
||||
pico_close(file);
|
||||
|
||||
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
|
||||
}
|
||||
|
||||
|
||||
void upload_font(uint8_t page) {
|
||||
int file;
|
||||
if(page > 1) {
|
||||
memcpy(config_errbuf, ERR_EOF, sizeof(ERR_EOF));
|
||||
return;
|
||||
}
|
||||
|
||||
file = pico_open("font", LFS_O_RDONLY);
|
||||
if(file < 0) {
|
||||
memcpy((uint8_t*)(apple_memory + 0xC800), (character_rom + (1024*page)), 1024);
|
||||
} else {
|
||||
pico_lseek(file, 1024 * page, LFS_SEEK_SET);
|
||||
pico_read(file, (uint8_t*)(apple_memory + 0xC800), 1024);
|
||||
pico_close(file);
|
||||
}
|
||||
|
||||
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
|
||||
}
|
||||
|
||||
void download_font(uint16_t ptr) {
|
||||
int file = pico_open("font", LFS_O_WRONLY | LFS_O_CREAT);
|
||||
|
||||
memcpy(character_rom, (uint8_t*)(apple_memory + ptr), 2048);
|
||||
|
||||
if(file < 0) {
|
||||
memcpy(config_errbuf, ERR_NOFILE, sizeof(ERR_NOFILE));
|
||||
return;
|
||||
}
|
||||
|
||||
pico_write(file, (uint8_t*)(apple_memory + ptr), 2048);
|
||||
pico_close(file);
|
||||
|
||||
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
|
||||
}
|
||||
|
||||
void config_format() {
|
||||
pico_unmount();
|
||||
|
||||
if(pico_mount(1) != LFS_ERR_OK) {
|
||||
memcpy(config_errbuf, ERR_NOFILE, sizeof(ERR_NOFILE));
|
||||
} else {
|
||||
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
|
||||
}
|
||||
}
|
||||
|
||||
void config_handler() {
|
||||
if(config_memory[31] != 0) return;
|
||||
if(config_cmdbuf[7] != 0) return;
|
||||
|
||||
if(!strcmp("BANK=SAVE", (uint8_t*)config_memory)) {
|
||||
videx_page_tmp = videx_page;
|
||||
} else if(!strcmp("BANK=RESTORE", (uint8_t*)config_memory)) {
|
||||
videx_page = videx_page_tmp;
|
||||
} else if(!memcmp("BANK=FONT", (uint8_t*)config_memory, 9)) {
|
||||
videx_page = character_rom + (((config_memory[9] - '0') & 3) * 1024);
|
||||
} else if(!strcmp("WRITE_CONFIG", (uint8_t*)config_memory)) {
|
||||
write_config();
|
||||
} else if(!strcmp("REBOOT", (uint8_t*)config_memory)) {
|
||||
v2mode = MODE_REBOOT;
|
||||
} else parse_config((uint8_t*)config_memory);
|
||||
config_cmdbuf[7] = 0xff;
|
||||
|
||||
if(!memcmp("H=", (uint8_t*)config_cmdbuf, 2)) {
|
||||
parse_config((uint8_t*)config_cmdbuf);
|
||||
} else if(!memcmp("UF", (uint8_t*)config_cmdbuf, 2)) {
|
||||
upload_font(config_cmdbuf[2]);
|
||||
} else if(!memcmp("DF", (uint8_t*)config_cmdbuf, 2)) {
|
||||
download_font((config_cmdbuf[2] << 0) | (config_cmdbuf[3] << 8));
|
||||
flash_reboot();
|
||||
} else if(!memcmp("UC", (uint8_t*)config_cmdbuf, 2)) {
|
||||
upload_config();
|
||||
} else if(!memcmp("DC", (uint8_t*)config_cmdbuf, 2)) {
|
||||
download_config((config_cmdbuf[2] << 0) | (config_cmdbuf[3] << 8));
|
||||
flash_reboot();
|
||||
} else if(!memcmp("FORMAT", (uint8_t*)config_cmdbuf, 6)) {
|
||||
config_format();
|
||||
flash_reboot();
|
||||
}
|
||||
|
||||
memset(config_cmdbuf, 0x00, 7);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CONFIG_SYSCLOCK 126.0 /* MHz */
|
||||
|
||||
// Pin configuration
|
||||
@ -19,6 +21,7 @@
|
||||
|
||||
typedef enum {
|
||||
MODE_REBOOT = 0,
|
||||
MODE_UNKNOWN,
|
||||
MODE_DIAG,
|
||||
MODE_FS,
|
||||
MODE_VGACARD,
|
||||
@ -29,7 +32,8 @@ typedef enum {
|
||||
MODE_ETHERNET
|
||||
} v2mode_t;
|
||||
|
||||
extern v2mode_t v2mode;
|
||||
extern volatile v2mode_t cfg_mode;
|
||||
extern volatile v2mode_t current_mode;
|
||||
|
||||
typedef enum {
|
||||
SERIAL_LOOP = 0,
|
||||
@ -38,7 +42,7 @@ typedef enum {
|
||||
SERIAL_PRINTER,
|
||||
} serialmux_t;
|
||||
|
||||
extern serialmux_t serialmux;
|
||||
extern volatile serialmux_t serialmux;
|
||||
|
||||
typedef enum {
|
||||
USB_HOST_CDC,
|
||||
@ -46,23 +50,24 @@ typedef enum {
|
||||
USB_GUEST_MIDI,
|
||||
} usbmux_t;
|
||||
|
||||
extern usbmux_t usbmux;
|
||||
extern volatile usbmux_t usbmux;
|
||||
|
||||
typedef enum {
|
||||
WIFI_CLIENT = 0,
|
||||
WIFI_AP,
|
||||
} wifimode_t;
|
||||
|
||||
extern wifimode_t wifimode;
|
||||
extern volatile wifimode_t wifimode;
|
||||
|
||||
typedef enum {
|
||||
APPLE_II = 0,
|
||||
APPLE_IIE = 1,
|
||||
APPLE_IIGS = 2,
|
||||
COMPAT_AUTO = 0xff
|
||||
MACHINE_II = 0,
|
||||
MACHINE_IIE = 1,
|
||||
MACHINE_IIGS = 2,
|
||||
MACHINE_AUTO = 0xff
|
||||
} compat_t;
|
||||
|
||||
extern compat_t machine;
|
||||
extern volatile compat_t cfg_machine;
|
||||
extern volatile compat_t current_machine;
|
||||
|
||||
enum {
|
||||
ABUS_MAIN_SM = 0,
|
||||
@ -74,7 +79,9 @@ enum {
|
||||
#define CARD_IOSEL (((address & 0xcf00) >= 0xc100) && ((address & 0xcf00) < 0xc700))
|
||||
#define CARD_IOSTROBE ((address & 0xc800) == 0xc800)
|
||||
|
||||
int make_config(uint8_t *buf, uint16_t len);
|
||||
void read_config();
|
||||
void write_config();
|
||||
void config_handler();
|
||||
void default_config();
|
||||
|
||||
|
25
v2-analog-rev1/common/flash.c
Normal file
25
v2-analog-rev1/common/flash.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <pico/stdlib.h>
|
||||
#include <pico/multicore.h>
|
||||
#include <hardware/flash.h>
|
||||
#include <hardware/watchdog.h>
|
||||
#include <hardware/resets.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef RASPBERRYPI_PICO_W
|
||||
#include <pico/cyw43_arch.h>
|
||||
#endif
|
||||
|
||||
void __time_critical_func(flash_reboot)() __attribute__ ((noreturn));
|
||||
|
||||
// Reboot the Pico
|
||||
void __time_critical_func(flash_reboot)() {
|
||||
save_and_disable_interrupts();
|
||||
|
||||
multicore_reset_core1();
|
||||
|
||||
reset_block((1<<11) | (1<<10) | (1<<2));
|
||||
|
||||
watchdog_enable(2, 1);
|
||||
for(;;);
|
||||
}
|
||||
|
5
v2-analog-rev1/common/flash.h
Normal file
5
v2-analog-rev1/common/flash.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern void flash_reboot() __attribute__ ((noreturn));
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint8_t flash_control;
|
||||
extern uint8_t flash_status;
|
||||
extern uint8_t flash_data;
|
||||
extern uint32_t flash_address;
|
||||
|
||||
enum {
|
||||
FLASH_STATUS_READY = 0x00,
|
||||
FLASH_STATUS_BUSY = 0x01,
|
||||
FLASH_STATUS_ECMD = 0xE0, // ERROR: Unknown Command
|
||||
FLASH_STATUS_EPRM = 0xE2, // ERROR: Incorrect Parameter
|
||||
FLASH_STATUS_ECRC = 0xE4, // ERROR: Invalid Checksum
|
||||
|
||||
FLASH_CONTROL_IDLE = 0x00,
|
||||
FLASH_CONTROL_ERASE = 0x45,
|
||||
FLASH_CONTROL_UPLOAD = 0x55,
|
||||
FLASH_CONTROL_REBOOT = 0x52,
|
||||
};
|
@ -1,111 +0,0 @@
|
||||
#include <pico/stdlib.h>
|
||||
#include <pico/multicore.h>
|
||||
#include <hardware/flash.h>
|
||||
#include <hardware/watchdog.h>
|
||||
#include <hardware/resets.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef RASPBERRYPI_PICO_W
|
||||
#include <pico/cyw43_arch.h>
|
||||
#endif
|
||||
|
||||
void flash_reboot() __attribute__ ((noreturn));
|
||||
|
||||
// Reboot the Pico
|
||||
void flash_reboot() {
|
||||
multicore_reset_core1();
|
||||
|
||||
reset_block((1<<11) | (1<<10) | (1<<2));
|
||||
|
||||
watchdog_enable(1, 1);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static uint16_t crc16_tab[256];
|
||||
uint32_t crc16_initdone = 0;
|
||||
|
||||
static void flash_crc16_init() {
|
||||
for (uint i=0; i<256; i++) {
|
||||
uint16_t crc = 0;
|
||||
uint16_t c = i;
|
||||
|
||||
for (uint j=0; j<8; j++) {
|
||||
|
||||
if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ 0xA001;
|
||||
else crc = crc >> 1;
|
||||
|
||||
c = c >> 1;
|
||||
}
|
||||
crc16_tab[i] = crc;
|
||||
}
|
||||
crc16_initdone = 1;
|
||||
}
|
||||
|
||||
int flash_check_crc16(uint8_t *p, uint32_t size, uint8_t *c) {
|
||||
uint16_t crc = 0x0000;
|
||||
|
||||
if(!crc16_initdone) flash_crc16_init();
|
||||
|
||||
for(uint32_t i = 0; i < size; i++) {
|
||||
crc = (crc >> 8) ^ crc16_tab[ (crc ^ (uint16_t) *p++) & 0x00FF ];
|
||||
}
|
||||
|
||||
return (crc != ((uint16_t)c[0]) | (((uint16_t)c[1]) << 8));
|
||||
}
|
||||
|
||||
// Erase a flash sector under Apple II control
|
||||
void flash_doerase() {
|
||||
uint32_t erase_offset = ((uint32_t)terminal_address) << 12;
|
||||
|
||||
terminal_reg[0xE] = FLASH_STATUS_BUSY;
|
||||
|
||||
if((terminal_reg[0x9] == ~terminal_reg[0x1]) && (terminal_reg[0xA] == ~terminal_reg[0x2])) {
|
||||
flash_range_erase(erase_offset, FLASH_SECTOR_SIZE);
|
||||
terminal_reg[0xE] = FLASH_STATUS_READY;
|
||||
} else {
|
||||
terminal_reg[0xE] = FLASH_STATUS_EPRM;
|
||||
}
|
||||
}
|
||||
|
||||
// Write 4096 bytes from Apple II Memory $3000-$3FFF to flash
|
||||
void flash_dowrite() {
|
||||
uint32_t write_offset = ((uint32_t)terminal_address) << 12;
|
||||
|
||||
if((terminal_reg[0x9] == ~terminal_reg[0x1]) && (terminal_reg[0xA] == ~terminal_reg[0x2])) {
|
||||
if(flash_check_crc16((uint8_t*)hires_memory+0x1000, FLASH_SECTOR_SIZE, (uint8_t*)terminal_reg+0xC) != 0) {
|
||||
terminal_reg[0xE] = FLASH_STATUS_ECRC;
|
||||
} else {
|
||||
flash_range_program(write_offset, hires_memory+0x1000, FLASH_SECTOR_SIZE);
|
||||
terminal_reg[0xE] = FLASH_STATUS_READY;
|
||||
}
|
||||
} else {
|
||||
terminal_reg[0xE] = FLASH_STATUS_EPRM;
|
||||
}
|
||||
}
|
||||
|
||||
void flash_dowork() {
|
||||
uint32_t op = flash_control;
|
||||
flash_control = FLASH_CONTROL_IDLE;
|
||||
|
||||
switch(op) {
|
||||
case FLASH_CONTROL_REBOOT:
|
||||
flash_reboot();
|
||||
break;
|
||||
#if 0
|
||||
case FLASH_CONTROL_ERASE:
|
||||
flash_doerase();
|
||||
break;
|
||||
case FLASH_CONTROL_UPLOAD:
|
||||
flash_dowrite();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
terminal_reg[0xE] = FLASH_STATUS_ECMD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,49 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <pico/stdlib.h>
|
||||
#include <pico/multicore.h>
|
||||
#include <hardware/pio.h>
|
||||
#include "common/abus.h"
|
||||
#include "common/config.h"
|
||||
#include "common/modes.h"
|
||||
#include "common/buffers.h"
|
||||
#include "common/flash.h"
|
||||
#include "pico_hal.h"
|
||||
|
||||
#ifdef RASPBERRYPI_PICO_W
|
||||
#include <pico/cyw43_arch.h>
|
||||
#endif
|
||||
|
||||
volatile uint8_t core1_running = 0;
|
||||
|
||||
static void core1_loop() {
|
||||
static void __time_critical_func(core1_loop)() {
|
||||
for(;;) {
|
||||
switch(v2mode) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
// device read access
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, apple_memory[address]);
|
||||
}
|
||||
}
|
||||
|
||||
if(CARD_SELECT) {
|
||||
if(CARD_DEVSEL) {
|
||||
cardslot = (address >> 4) & 0x7;
|
||||
} else if(CARD_IOSEL) {
|
||||
cardslot = (address >> 8) & 0x7;
|
||||
|
||||
// Config memory in card slot-rom address space
|
||||
if(((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) && ((address & 0xF0) == 0xF0)) {
|
||||
apple_memory[address] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(current_mode) {
|
||||
case MODE_DIAG:
|
||||
core1_running = 1;
|
||||
diag_businterface();
|
||||
core1_running = 0;
|
||||
diag_businterface(address, value);
|
||||
break;
|
||||
case MODE_FS:
|
||||
core1_running = 1;
|
||||
fs_businterface();
|
||||
core1_running = 0;
|
||||
fs_businterface(address, value);
|
||||
break;
|
||||
case MODE_VGACARD:
|
||||
core1_running = 1;
|
||||
vga_businterface();
|
||||
core1_running = 0;
|
||||
vga_businterface(address, value);
|
||||
break;
|
||||
case MODE_APPLICARD:
|
||||
core1_running = 1;
|
||||
z80_businterface();
|
||||
core1_running = 0;
|
||||
z80_businterface(address, value);
|
||||
break;
|
||||
case MODE_SERIAL:
|
||||
core1_running = 1;
|
||||
serial_businterface();
|
||||
core1_running = 0;
|
||||
serial_businterface(address, value);
|
||||
break;
|
||||
case MODE_PARALLEL:
|
||||
core1_running = 1;
|
||||
parallel_businterface();
|
||||
core1_running = 0;
|
||||
parallel_businterface(address, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -51,16 +63,15 @@ static void core1_loop() {
|
||||
|
||||
static void core0_loop() {
|
||||
for(;;) {
|
||||
switch(v2mode) {
|
||||
case MODE_REBOOT:
|
||||
flash_reboot();
|
||||
break;
|
||||
switch(current_mode) {
|
||||
case MODE_DIAG:
|
||||
diagmain();
|
||||
break;
|
||||
case MODE_FS:
|
||||
fsmain();
|
||||
break;
|
||||
default:
|
||||
current_mode = MODE_VGACARD;
|
||||
case MODE_VGACARD:
|
||||
vgamain();
|
||||
break;
|
||||
@ -73,13 +84,7 @@ static void core0_loop() {
|
||||
case MODE_PARALLEL:
|
||||
parallelmain();
|
||||
break;
|
||||
default:
|
||||
v2mode = MODE_VGACARD;
|
||||
}
|
||||
|
||||
while(core1_running) {
|
||||
sleep_ms(5);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,19 +93,24 @@ int main() {
|
||||
set_sys_clock_khz(CONFIG_SYSCLOCK*1000, true);
|
||||
|
||||
abus_init();
|
||||
|
||||
memcpy(config_errbuf, "V2ANALOG", 8);
|
||||
memset(config_cmdbuf, 0xFF, 8);
|
||||
|
||||
multicore_launch_core1(core1_loop);
|
||||
|
||||
// Sensible defaults if there is no config / fs
|
||||
default_config();
|
||||
|
||||
multicore_launch_core1(core1_loop);
|
||||
|
||||
// Try mounting the LittleFS, or format if it isn't there.
|
||||
if(pico_mount(0) == LFS_ERR_OK) {
|
||||
read_config();
|
||||
} else if(pico_mount(1) == LFS_ERR_OK) {
|
||||
read_config();
|
||||
} else {
|
||||
pico_mount(1);
|
||||
}
|
||||
|
||||
current_mode = cfg_mode;
|
||||
|
||||
core0_loop();
|
||||
|
||||
return 0;
|
||||
|
@ -1,20 +1,20 @@
|
||||
|
||||
void vgamain();
|
||||
void vga_businterface();
|
||||
void vga_businterface(uint32_t address, uint32_t value);
|
||||
|
||||
void z80main();
|
||||
void z80_businterface();
|
||||
void z80_businterface(uint32_t address, uint32_t value);
|
||||
|
||||
void serialmain();
|
||||
void serial_businterface();
|
||||
void serial_businterface(uint32_t address, uint32_t value);
|
||||
|
||||
void parallelmain();
|
||||
void parallel_businterface();
|
||||
void parallel_businterface(uint32_t address, uint32_t value);
|
||||
|
||||
void diag_businterface();
|
||||
void diagmain();
|
||||
void diag_businterface(uint32_t address, uint32_t value);
|
||||
|
||||
void fs_businterface();
|
||||
void fsmain();
|
||||
void fs_businterface(uint32_t address, uint32_t value);
|
||||
|
||||
void flash_reboot() __attribute__ ((noreturn));
|
||||
|
@ -5,39 +5,9 @@
|
||||
#include "abus.pio.h"
|
||||
#include "diag/businterface.h"
|
||||
|
||||
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
||||
void __time_critical_func(diag_businterface)(uint32_t address, uint32_t value) {
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
if(CARD_SELECT) {
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
apple_memory[address] = value;
|
||||
}
|
||||
// Config memory in card slot-rom address space
|
||||
if(CARD_IOSEL) {
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
config_memory[address & 0x1F] = value;
|
||||
if((address & 0xFF) == 0xFF)
|
||||
config_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __time_critical_func(diag_businterface)() {
|
||||
while(v2mode == MODE_DIAG) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t dout;
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
dout = apple_memory[address];
|
||||
|
||||
// device read access
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
||||
}
|
||||
}
|
||||
|
||||
shadow_memory(address, value);
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
apple_memory[address] = value;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ void diagmain() {
|
||||
memset((uint8_t*)(apple_memory+0xC700), 0xC7, 0x100);
|
||||
memset((uint8_t*)(apple_memory+0xC800), 0xC8, 0x800);
|
||||
|
||||
while(v2mode == MODE_DIAG) {
|
||||
while(current_mode == MODE_DIAG) {
|
||||
sleep_ms(50);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@
|
||||
#include "fs/businterface.h"
|
||||
#include "fs/fs.h"
|
||||
|
||||
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
||||
volatile uint8_t fs_slot = 0;
|
||||
|
||||
void __time_critical_func(fs_businterface)(uint32_t address, uint32_t value) {
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
if(address < 0x200) {
|
||||
@ -28,23 +30,12 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
if(CARD_DEVSEL) {
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
apple_memory[address] = value;
|
||||
if((address & 0xCF8F) == 0xC08F)
|
||||
fs_handler((address & 0x70) >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
if(CARD_IOSTROBE) {
|
||||
apple_memory[address] = value;
|
||||
}
|
||||
|
||||
// Config memory in card slot-rom address space
|
||||
if(CARD_IOSEL) {
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
config_memory[address & 0x1F] = value;
|
||||
if((address & 0xFF) == 0xFF)
|
||||
config_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shadow the soft-switches by observing all read & write bus cycles
|
||||
@ -73,23 +64,3 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __time_critical_func(fs_businterface)() {
|
||||
while(v2mode == MODE_DIAG) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t dout;
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
dout = apple_memory[address];
|
||||
|
||||
// device read access
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
||||
}
|
||||
}
|
||||
|
||||
shadow_memory(address, value);
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ void fs_handler(uint8_t slot) {
|
||||
void fsmain() {
|
||||
int i;
|
||||
|
||||
memset((uint8_t*)(apple_memory+0xC000), 0x00, 0x1000);
|
||||
memset((uint8_t*)(apple_memory+0xC000), 0xFF, 0x1000);
|
||||
|
||||
for(i = 0; i < FS_MAXFILE; i++) {
|
||||
fs_file[i].handle = -1;
|
||||
@ -207,15 +207,12 @@ void fsmain() {
|
||||
fs_file[0].handle = pico_open("boot.dsk", LFS_O_RDONLY);
|
||||
fs_file[0].valid = (fs_file[0].handle >= 0);
|
||||
|
||||
strcpy((uint8_t*)(apple_memory+0xC1E0), "FSREADY.");
|
||||
strcpy((uint8_t*)(apple_memory+0xC2E0), "FSREADY.");
|
||||
strcpy((uint8_t*)(apple_memory+0xC3E0), "FSREADY.");
|
||||
strcpy((uint8_t*)(apple_memory+0xC4E0), "FSREADY.");
|
||||
strcpy((uint8_t*)(apple_memory+0xC5E0), "FSREADY.");
|
||||
strcpy((uint8_t*)(apple_memory+0xC6E0), "FSREADY.");
|
||||
strcpy((uint8_t*)(apple_memory+0xC7E0), "FSREADY.");
|
||||
strcpy((char*)(apple_memory+0xC0E0+(cardslot << 8)), "FSREADY.");
|
||||
|
||||
while(v2mode == MODE_FS) {
|
||||
while(current_mode == MODE_FS) {
|
||||
config_handler();
|
||||
if(cardslot != 0)
|
||||
fs_handler(cardslot);
|
||||
sleep_ms(50);
|
||||
}
|
||||
|
||||
|
@ -28,45 +28,9 @@ static inline void __time_critical_func(parallel_write)(uint32_t address, uint32
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
||||
void __time_critical_func(parallel_businterface)(uint32_t address, uint32_t value) {
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
if(CARD_SELECT) {
|
||||
if(CARD_DEVSEL) {
|
||||
parallel_write(address, value);
|
||||
} else if(address < 0xC000) {
|
||||
apple_memory[address] = value;
|
||||
}
|
||||
// Config memory in card slot-rom address space
|
||||
if(CARD_IOSEL) {
|
||||
config_memory[address & 0x1F] = value;
|
||||
if((address & 0xFF) == 0xFF)
|
||||
config_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __time_critical_func(parallel_businterface)() {
|
||||
while(v2mode == MODE_PARALLEL) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t dout;
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
if(CARD_DEVSEL) {
|
||||
dout = ((address & 0xf) == 0) ? parallel_status : 0xff;
|
||||
} else {
|
||||
dout = apple_memory[address];
|
||||
}
|
||||
|
||||
// device read access
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
||||
}
|
||||
}
|
||||
|
||||
shadow_memory(address, value);
|
||||
if((CARD_SELECT) && (CARD_DEVSEL) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
parallel_write(address, value);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ void parallelmain() {
|
||||
// Copy Grappler ROM to Extended ROM area
|
||||
memcpy((void*)(apple_memory + 0xC800), (void*)(grappler_rom), 0x800);
|
||||
|
||||
while(v2mode == MODE_PARALLEL) {
|
||||
while(current_mode == MODE_PARALLEL) {
|
||||
config_handler();
|
||||
sleep_ms(50);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ static inline void __time_critical_func(serial_write)(uint32_t address, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
||||
void __time_critical_func(serial_businterface)(uint32_t address, uint32_t value) {
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
if(CARD_SELECT) {
|
||||
if(CARD_DEVSEL) {
|
||||
@ -35,37 +35,5 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
serial_read(address);
|
||||
}
|
||||
}
|
||||
// Config memory in card slot-rom address space
|
||||
if(CARD_IOSEL) {
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
config_memory[address & 0x1F] = value;
|
||||
if((address & 0xFF) == 0xFF)
|
||||
config_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __time_critical_func(serial_businterface)() {
|
||||
while(v2mode == MODE_SERIAL) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t dout;
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
if(CARD_DEVSEL) {
|
||||
dout = serial_reg[address & 0xf];
|
||||
} else {
|
||||
dout = apple_memory[address & 0xffff];
|
||||
}
|
||||
|
||||
// device read access
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
||||
}
|
||||
}
|
||||
|
||||
shadow_memory(address, value);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ void serialmain() {
|
||||
memcpy((void*)(apple_memory + 0xC100), (void*)(ssc_rom + 0x700), 0x100);
|
||||
memcpy((void*)(apple_memory + 0xC200), (void*)(apple_memory + 0xC100), 0x600);
|
||||
|
||||
while(v2mode == MODE_SERIAL) {
|
||||
while(current_mode == MODE_SERIAL) {
|
||||
config_handler();
|
||||
switch(serialmux) {
|
||||
#if 0
|
||||
case SERIAL_USB:
|
||||
|
@ -17,7 +17,7 @@ static inline void __time_critical_func(videx_crtc_write)(uint32_t value) {
|
||||
}
|
||||
|
||||
|
||||
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
||||
void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
||||
// Shadow the soft-switches by observing all read & write bus cycles
|
||||
if((address & 0xff80) == 0xc000) {
|
||||
switch(address & 0x7f) {
|
||||
@ -25,141 +25,142 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches &= ~SOFTSW_80STORE;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x01:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches |= SOFTSW_80STORE;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x04:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches &= ~SOFTSW_AUX_WRITE;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x05:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches |= SOFTSW_AUX_WRITE;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x08:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches &= ~SOFTSW_AUXZP;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x09:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches |= SOFTSW_AUXZP;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x0c:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches &= ~SOFTSW_80COL;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x0d:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches |= SOFTSW_80COL;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x0e:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches &= ~SOFTSW_ALTCHAR;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x0f:
|
||||
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches |= SOFTSW_ALTCHAR;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x21:
|
||||
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
if((SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
if(value & 0x80) {
|
||||
soft_switches |= SOFTSW_MONOCHROME;
|
||||
} else {
|
||||
soft_switches &= ~SOFTSW_MONOCHROME;
|
||||
}
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x22:
|
||||
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
terminal_tbcolor = value & 0xff;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x29:
|
||||
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches = (soft_switches & ~(SOFTSW_NEWVID_MASK << SOFTSW_NEWVID_SHIFT)) | ((value & SOFTSW_NEWVID_MASK) << SOFTSW_NEWVID_SHIFT);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x34:
|
||||
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
terminal_border = value & 0x0f;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x35:
|
||||
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches = (soft_switches & ~(SOFTSW_SHADOW_MASK << SOFTSW_SHADOW_SHIFT)) | ((value & SOFTSW_SHADOW_MASK) << SOFTSW_SHADOW_SHIFT);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x50:
|
||||
soft_switches &= ~SOFTSW_TEXT_MODE;
|
||||
return;
|
||||
break;
|
||||
case 0x51:
|
||||
soft_switches |= SOFTSW_TEXT_MODE;
|
||||
return;
|
||||
break;
|
||||
case 0x52:
|
||||
soft_switches &= ~SOFTSW_MIX_MODE;
|
||||
return;
|
||||
break;
|
||||
case 0x53:
|
||||
soft_switches |= SOFTSW_MIX_MODE;
|
||||
return;
|
||||
break;
|
||||
case 0x54:
|
||||
soft_switches &= ~SOFTSW_PAGE_2;
|
||||
return;
|
||||
break;
|
||||
case 0x55:
|
||||
soft_switches |= SOFTSW_PAGE_2;
|
||||
return;
|
||||
break;
|
||||
case 0x56:
|
||||
soft_switches &= ~SOFTSW_HIRES_MODE;
|
||||
return;
|
||||
break;
|
||||
case 0x57:
|
||||
soft_switches |= SOFTSW_HIRES_MODE;
|
||||
return;
|
||||
break;
|
||||
case 0x5e:
|
||||
if(soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) {
|
||||
soft_switches |= SOFTSW_DGR;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x5f:
|
||||
if(soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) {
|
||||
soft_switches &= ~SOFTSW_DGR;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x7e:
|
||||
if((soft_switches & SOFTSW_IIE_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches |= SOFTSW_IOUDIS;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 0x7f:
|
||||
if((soft_switches & SOFTSW_IIE_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
soft_switches &= ~SOFTSW_IOUDIS;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
if((machine == COMPAT_AUTO) && (a2_first_write == 0)) {
|
||||
if(current_machine == MACHINE_AUTO) {
|
||||
a2_first_write = (address << 16) | (value & 0x3FF);
|
||||
if(a2_first_write == 0xC0330100) { // Apple IIgs ROM03 Clock Access
|
||||
machine = APPLE_IIGS;
|
||||
current_machine = MACHINE_IIGS;
|
||||
soft_switches &= ~SOFTSW_IIE_REGS;
|
||||
soft_switches |= SOFTSW_IIGS_REGS;
|
||||
} else if(a2_first_write == 0x01F901FB) { // Apple II Plus
|
||||
machine = APPLE_II;
|
||||
current_machine = MACHINE_II;
|
||||
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
|
||||
} else if(a2_first_write == 0x01F5018B) { // Apple IIe Platinum
|
||||
machine = APPLE_IIE;
|
||||
current_machine = MACHINE_IIE;
|
||||
soft_switches |= SOFTSW_IIE_REGS;
|
||||
soft_switches &= ~SOFTSW_IIGS_REGS;
|
||||
} else {
|
||||
@ -197,9 +198,10 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Videx 80 Column Card
|
||||
if(CARD_SELECT) {
|
||||
if((address >= 0xCC00) && (address < 0xD000)) {
|
||||
if((address >= 0xC800) && (address < 0xCC00)) {
|
||||
videx_page[(address & 0x3FF)] = value & 0xff;
|
||||
}
|
||||
|
||||
@ -213,47 +215,14 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Config memory in card slot-rom address space
|
||||
if(CARD_IOSEL) {
|
||||
config_memory[address & 0x1F] = value;
|
||||
if((address & 0xFF) == 0xFF)
|
||||
config_handler();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Any access to Videx I/O sets the VRAM page visible in 0xCC00-0xD000
|
||||
if(CARD_SELECT && CARD_DEVSEL) {
|
||||
videx_page = videx_memory + ((address & 0x0C) << 9);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __time_critical_func(vga_businterface)() {
|
||||
while(v2mode == MODE_VGACARD) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
uint32_t dout;
|
||||
switch(address >> 10) {
|
||||
case (0xC000 >> 10):
|
||||
dout = (address & 1) ? videx_crtc_reg : 0xff;
|
||||
break;
|
||||
case (0xCC00 >> 10):
|
||||
dout = videx_memory[address & 0x3FF];
|
||||
break;
|
||||
default:
|
||||
dout = apple_memory[address];
|
||||
}
|
||||
|
||||
// device read access
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
||||
}
|
||||
}
|
||||
|
||||
shadow_memory(address, value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -12,24 +12,24 @@ uint16_t text_fore;
|
||||
uint16_t text_back;
|
||||
uint16_t text_border;
|
||||
|
||||
compat_t machinefont = APPLE_II;
|
||||
compat_t machinefont = MACHINE_II;
|
||||
bool userfont = false;
|
||||
|
||||
// Initialize the character generator ROM
|
||||
void switch_font() {
|
||||
switch(machine) {
|
||||
switch(current_machine) {
|
||||
default:
|
||||
case APPLE_II:
|
||||
case MACHINE_II:
|
||||
memcpy(character_rom, default_character_rom, 2048);
|
||||
break;
|
||||
case APPLE_IIE:
|
||||
case MACHINE_IIE:
|
||||
memcpy(character_rom, appleiie_character_rom, 2048);
|
||||
break;
|
||||
case APPLE_IIGS:
|
||||
case MACHINE_IIGS:
|
||||
memcpy(character_rom, appleiigs_character_rom, 2048);
|
||||
break;
|
||||
}
|
||||
machinefont = machine;
|
||||
machinefont = current_machine;
|
||||
}
|
||||
|
||||
void load_font() {
|
||||
@ -66,67 +66,106 @@ void render_init() {
|
||||
render_test_init();
|
||||
}
|
||||
|
||||
uint32_t testdone=0;
|
||||
// Blank screen
|
||||
void __time_critical_func(render_blank)() {
|
||||
struct vga_scanline *sl = vga_prepare_scanline();
|
||||
uint sl_pos = 0;
|
||||
|
||||
while(sl_pos < VGA_WIDTH/16) {
|
||||
sl->data[sl_pos] = (text_border|THEN_EXTEND_7) | ((text_border|THEN_EXTEND_7) << 16); // 8 pixels per word
|
||||
sl_pos++;
|
||||
}
|
||||
|
||||
sl->length = sl_pos;
|
||||
sl->repeat_count = 479;
|
||||
vga_submit_scanline(sl);
|
||||
}
|
||||
|
||||
uint32_t screentimeout = 0;
|
||||
uint32_t testdone = 0;
|
||||
|
||||
void __noinline __time_critical_func(render_loop)() {
|
||||
while(v2mode == MODE_VGACARD) {
|
||||
if(!userfont && (machinefont != machine)) {
|
||||
switch_font();
|
||||
}
|
||||
|
||||
update_text_flasher();
|
||||
|
||||
text_fore = lores_palette[TERMINAL_FORE];
|
||||
text_back = lores_palette[TERMINAL_BACK];
|
||||
text_border = lores_palette[TERMINAL_BORDER];
|
||||
|
||||
if(soft_switches & SOFTSW_TEST) {
|
||||
while(current_mode == MODE_VGACARD) {
|
||||
config_handler();
|
||||
#if 0
|
||||
if((busactive == 0) && (screentimeout > (30 * 60))) {
|
||||
render_blank();
|
||||
} else if((busactive == 0) && (screentimeout > (15 * 60))) {
|
||||
render_testpattern();
|
||||
|
||||
// Automatically dismiss the test pattern when the Apple II initializes
|
||||
// soft switches during startup.
|
||||
if(((soft_switches & SOFTSW_MODE_MASK) != 0) && (testdone == 0)) {
|
||||
soft_switches &= ~SOFTSW_TEST;
|
||||
testdone = 1;
|
||||
render_about_init();
|
||||
}
|
||||
} else if(soft_switches & SOFTSW_VIDEX) {
|
||||
render_videx();
|
||||
} else if(soft_switches & SOFTSW_SHR) {
|
||||
render_shr();
|
||||
screentimeout++;
|
||||
} else if((busactive == 0) && (screentimeout == 15 * 60)) {
|
||||
render_test_sleep();
|
||||
render_testpattern();
|
||||
screentimeout++;
|
||||
} else {
|
||||
switch(soft_switches & SOFTSW_MODE_MASK) {
|
||||
case 0:
|
||||
if(soft_switches & SOFTSW_DGR) {
|
||||
render_dgr();
|
||||
} else {
|
||||
render_lores();
|
||||
}
|
||||
break;
|
||||
case SOFTSW_MIX_MODE:
|
||||
if((soft_switches & (SOFTSW_80COL | SOFTSW_DGR)) == (SOFTSW_80COL | SOFTSW_DGR)) {
|
||||
render_mixed_dgr();
|
||||
} else {
|
||||
render_mixed_lores();
|
||||
}
|
||||
break;
|
||||
case SOFTSW_HIRES_MODE:
|
||||
if(soft_switches & SOFTSW_DGR) {
|
||||
render_dhgr();
|
||||
} else {
|
||||
render_hires();
|
||||
}
|
||||
break;
|
||||
case SOFTSW_HIRES_MODE|SOFTSW_MIX_MODE:
|
||||
if((soft_switches & (SOFTSW_80COL | SOFTSW_DGR)) == (SOFTSW_80COL | SOFTSW_DGR)) {
|
||||
render_mixed_dhgr();
|
||||
} else {
|
||||
render_mixed_hires();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
render_text();
|
||||
break;
|
||||
if(busactive == 0) {
|
||||
screentimeout++;
|
||||
} else {
|
||||
screentimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
busactive = 0;
|
||||
#endif
|
||||
|
||||
if(!userfont && (machinefont != current_machine)) {
|
||||
switch_font();
|
||||
}
|
||||
|
||||
update_text_flasher();
|
||||
|
||||
text_fore = lores_palette[TERMINAL_FORE];
|
||||
text_back = lores_palette[TERMINAL_BACK];
|
||||
text_border = lores_palette[TERMINAL_BORDER];
|
||||
|
||||
if(soft_switches & SOFTSW_TEST) {
|
||||
render_testpattern();
|
||||
// Automatically dismiss the test pattern when the Apple II is seen.
|
||||
if(((soft_switches & SOFTSW_MODE_MASK) != 0) && (testdone == 0)) {
|
||||
soft_switches &= ~SOFTSW_TEST;
|
||||
testdone = 1;
|
||||
render_about_init();
|
||||
}
|
||||
#if 0
|
||||
} else if(soft_switches & SOFTSW_VIDEX) {
|
||||
render_videx();
|
||||
} else if(soft_switches & SOFTSW_SHR) {
|
||||
render_shr();
|
||||
#endif
|
||||
} else {
|
||||
switch(soft_switches & SOFTSW_MODE_MASK) {
|
||||
case 0:
|
||||
if(soft_switches & SOFTSW_DGR) {
|
||||
render_dgr();
|
||||
} else {
|
||||
render_lores();
|
||||
}
|
||||
break;
|
||||
case SOFTSW_MIX_MODE:
|
||||
if((soft_switches & (SOFTSW_80COL | SOFTSW_DGR)) == (SOFTSW_80COL | SOFTSW_DGR)) {
|
||||
render_mixed_dgr();
|
||||
} else {
|
||||
render_mixed_lores();
|
||||
}
|
||||
break;
|
||||
case SOFTSW_HIRES_MODE:
|
||||
if(soft_switches & SOFTSW_DGR) {
|
||||
render_dhgr();
|
||||
} else {
|
||||
render_hires();
|
||||
}
|
||||
break;
|
||||
case SOFTSW_HIRES_MODE|SOFTSW_MIX_MODE:
|
||||
if((soft_switches & (SOFTSW_80COL | SOFTSW_DGR)) == (SOFTSW_80COL | SOFTSW_DGR)) {
|
||||
render_mixed_dhgr();
|
||||
} else {
|
||||
render_mixed_hires();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
render_text();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ extern void render_loop();
|
||||
extern void render_testpattern();
|
||||
extern void render_test_init();
|
||||
extern void render_about_init();
|
||||
extern void render_test_sleep();
|
||||
|
||||
extern void update_text_flasher();
|
||||
extern void render_text();
|
||||
@ -43,3 +44,5 @@ extern uint_fast32_t text_flasher_mask;
|
||||
|
||||
extern void flash_dowork();
|
||||
|
||||
extern void vga_init();
|
||||
extern void vga_deinit();
|
||||
|
@ -100,11 +100,11 @@ static void __time_critical_func(render_hires_line)(bool p2, uint line) {
|
||||
|
||||
if(soft_switches & SOFTSW_MONOCHROME) {
|
||||
// Consume 14 dots
|
||||
for(j = 0; j < 14; j++) {
|
||||
uint32_t pixeldata = (dots & 0x2000) ? (0x1ff|THEN_EXTEND_1) : (0x000|THEN_EXTEND_1);
|
||||
pixeldata |= (dots & 0x1000) ?
|
||||
((uint32_t)0x1ff|THEN_EXTEND_1) << 16 :
|
||||
((uint32_t)0x000|THEN_EXTEND_1) << 16;
|
||||
for(j = 0; j < 7; j++) {
|
||||
uint32_t pixeldata = (dots & 0x80000000) ? (0x1ff) : (0x000);
|
||||
pixeldata |= (dots & 0x40000000) ?
|
||||
((uint32_t)0x1ff) << 16 :
|
||||
((uint32_t)0x000) << 16;
|
||||
dots <<= 2;
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
|
@ -14,10 +14,20 @@
|
||||
|
||||
char error_message[16*24+1];
|
||||
|
||||
void render_test_sleep() {
|
||||
memcpy(error_message + 208, " APPLE II BUS ", 16);
|
||||
memcpy(error_message + 224, " ACTIVITY ", 16);
|
||||
memcpy(error_message + 240, " NOT DETECTED ", 16);
|
||||
|
||||
memcpy(error_message + 272, "SCREEN BLANKING ", 16);
|
||||
memcpy(error_message + 288, " IN 15 SECONDS ", 16);
|
||||
memcpy(error_message + 304, " ", 16);
|
||||
}
|
||||
|
||||
void render_test_init() {
|
||||
memset(error_message, ' ', 16*24);
|
||||
memcpy(error_message + 0, "HW: ANALOG-REV-1", 16);
|
||||
memcpy(error_message + 16, "FW: 23-01-16-119", 16);
|
||||
memcpy(error_message + 16, "FW: 23-01-19-131", 16);
|
||||
|
||||
memcpy(error_message + 64, " COPYRIGHT (C) ", 16);
|
||||
memcpy(error_message + 80, " DAVID KUDER ", 16);
|
||||
|
@ -11,5 +11,5 @@ void __noinline __time_critical_func(vgamain)() {
|
||||
vga_init();
|
||||
render_init();
|
||||
render_loop();
|
||||
vga_deinit();
|
||||
// vga_deinit();
|
||||
}
|
||||
|
@ -179,8 +179,6 @@ void vga_init() {
|
||||
|
||||
// Enable all state machines in sync to ensure their instruction cycles line up
|
||||
pio_enable_sm_mask_in_sync(CONFIG_VGA_PIO, (1 << VGA_HSYNC_SM) | (1 << VGA_VSYNC_SM) | (1 << VGA_DATA_SM));
|
||||
|
||||
multicore_lockout_victim_init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,8 +32,6 @@ struct vga_scanline {
|
||||
};
|
||||
|
||||
|
||||
void vga_init();
|
||||
void vga_deinit();
|
||||
|
||||
void vga_prepare_frame();
|
||||
struct vga_scanline *vga_prepare_scanline();
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include <string.h>
|
||||
#include <hardware/pio.h>
|
||||
#include "common/config.h"
|
||||
#include "common/buffers.h"
|
||||
#include "abus.pio.h"
|
||||
#include "z80/businterface.h"
|
||||
#include "z80/z80buf.h"
|
||||
|
||||
volatile uint8_t *pcpi_reg = apple_memory + 0xC0C0;
|
||||
|
||||
static inline void __time_critical_func(pcpi_read)(uint32_t address) {
|
||||
switch(address & 0x7) {
|
||||
@ -43,8 +45,8 @@ static inline void __time_critical_func(pcpi_write)(uint32_t address, uint32_t v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
||||
void __time_critical_func(z80_businterface)(uint32_t address, uint32_t value) {
|
||||
pcpi_reg = apple_memory + (0xC080 | (cardslot << 4));
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
if(CARD_SELECT) {
|
||||
if(CARD_DEVSEL) {
|
||||
@ -54,33 +56,6 @@ static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_
|
||||
pcpi_read(address);
|
||||
}
|
||||
}
|
||||
// Config memory in card slot-rom address space
|
||||
if(CARD_IOSEL) {
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
||||
config_memory[address & 0x1F] = value;
|
||||
if((address & 0xFF) == 0xFF)
|
||||
config_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __time_critical_func(z80_businterface)() {
|
||||
while(v2mode == MODE_APPLICARD) {
|
||||
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
||||
uint32_t dout;
|
||||
uint32_t address = (value >> 10) & 0xffff;
|
||||
|
||||
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
||||
if(CARD_SELECT) {
|
||||
dout = pcpi_reg[address & 0x7];
|
||||
|
||||
// device read access
|
||||
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
||||
}
|
||||
}
|
||||
|
||||
shadow_memory(address, value);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ extern volatile uint8_t z80_nmi;
|
||||
extern volatile uint8_t z80_res;
|
||||
extern uint8_t z80_rom[2*1024];
|
||||
#define z80_ram private_memory
|
||||
#define pcpi_reg slot4io
|
||||
extern volatile uint8_t *pcpi_reg;
|
||||
|
||||
#define clr_z80_stat { pcpi_reg[2] &= ~0x80; }
|
||||
#define set_z80_stat { pcpi_reg[2] |= 0x80; }
|
||||
|
@ -9,7 +9,7 @@ volatile uint8_t rom_shadow = 1;
|
||||
volatile uint8_t ram_bank = 0;
|
||||
volatile uint8_t ram_common = 0;
|
||||
|
||||
#define Z80break (z80_res || (v2mode != MODE_APPLICARD))
|
||||
#define Z80break (z80_res || (current_mode != MODE_APPLICARD) || (config_cmdbuf[7] == 0))
|
||||
|
||||
uint8_t cpu_in(uint16_t address) {
|
||||
uint8_t rv = 0;
|
||||
@ -85,23 +85,31 @@ void _RamWrite(uint16_t address, uint8_t value) {
|
||||
#include "z80cpu.h"
|
||||
|
||||
void z80main() {
|
||||
while(v2mode == MODE_APPLICARD) {
|
||||
rom_shadow = 1;
|
||||
ram_bank = 0;
|
||||
ram_common = 0;
|
||||
z80_res = 1;
|
||||
|
||||
z80_nmi = 0;
|
||||
z80_irq = 0;
|
||||
z80_res = 0;
|
||||
while(current_mode == MODE_APPLICARD) {
|
||||
config_handler();
|
||||
if(cardslot != 0) {
|
||||
if(z80_res) {
|
||||
rom_shadow = 1;
|
||||
ram_bank = 0;
|
||||
ram_common = 0;
|
||||
|
||||
// 6502 -> Z80
|
||||
clr_z80_stat;
|
||||
z80_nmi = 0;
|
||||
z80_irq = 0;
|
||||
z80_res = 0;
|
||||
|
||||
// Z80 -> 6502
|
||||
clr_6502_stat;
|
||||
// 6502 -> Z80
|
||||
clr_z80_stat;
|
||||
|
||||
Z80reset();
|
||||
Z80run();
|
||||
// Z80 -> 6502
|
||||
clr_6502_stat;
|
||||
|
||||
Z80reset();
|
||||
}
|
||||
|
||||
Z80run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user