Improve ROM boot

This commit is contained in:
dschmenk 2014-02-15 19:53:09 -08:00
parent 14b8ff2e11
commit 6cc5e45424
3 changed files with 112 additions and 82 deletions

8
debian/changelog vendored
View File

@ -1,3 +1,9 @@
a2pi (0.1.8-5) unstable; urgency=low
* Stabilize request/pidrive interaction
-- David Schmenk <dschmenk@gmail.com> Sat, 15 Feb 2014 13:15:00 -0800
a2pi (0.1.8-4) unstable; urgency=low a2pi (0.1.8-4) unstable; urgency=low
* Fix FUSE create file function * Fix FUSE create file function
@ -5,7 +11,7 @@ a2pi (0.1.8-4) unstable; urgency=low
* Fix recursive call request (FUSE mount w/ pidrive active) * Fix recursive call request (FUSE mount w/ pidrive active)
* Fix symlinks for A2VDx.PO updating * Fix symlinks for A2VDx.PO updating
* Add UTILS.PO image for comms programs and file manipulation * Add UTILS.PO image for comms programs and file manipulation
* Run PIDRIVE from STARTUP:wq * Run PIDRIVE from STARTUP
-- David Schmenk <dschmenk@gmail.com> Tue, 13 Feb 2014 15:31:23 -0800 -- David Schmenk <dschmenk@gmail.com> Tue, 13 Feb 2014 15:31:23 -0800

View File

@ -78,16 +78,47 @@ PDWRPRT EQU $2B
;* ;*
;* INIT ACIA ;* INIT ACIA
;* ;*
STY PAD1 ; CLEAR SYNCED FLAG
STY ACIASR ; RESET STATUS REGISTER STY ACIASR ; RESET STATUS REGISTER
LDY #$0B LDA #$0B
STY ACIACR ; SET CONTROL REGISTER STA ACIACR ; SET CONTROL REGISTER
LDY #$10 LDA #$10
STY ACIAMR ; SET COMMAND REGISTER (115K BAUD) STA ACIAMR ; SET COMMAND REGISTER (115K BAUD)
;*
;* CREATE COMMAND BUFFER FOR BOOT BLOCK
;*
STY PDUNIT
STY PDBUFL
STY PDBLKL
STY PDBLKH
INY ; LDY #PDREAD
STY PDCMD
LDY #$08
STY PDBUFH
JSR DOCMD
BCC BOOT
LDA $00
BEQ CONT
RTS
CONT: JMP $FABA ; JUMP BACK TO AUTOSTART BOOT SCANNER ROM
BOOT: LDX #BOOTDEV
STX PDUNIT
JMP $801
;*
;* PRODOS INTELLIGENT DEVICE ENTRYPOINT
;*
DOCMD: PHP
SEI
LDA PAD1
CMP #$81
BEQ SNDCMD
;* ;*
;* SYNC WITH HOST ;* SYNC WITH HOST
;* ;*
SYNC: LDA #$80 SYNC: LDA #$80
STA ACIADR STA ACIADR
LDA INDCTR
PHA
INX INX
TXA TXA
AND #$07 AND #$07
@ -96,51 +127,27 @@ SYNC: LDA #$80
STA INDCTR STA INDCTR
LDA #$FF LDA #$FF
JSR WAIT JSR WAIT
LDA #$A0 PLA
STA INDCTR STA INDCTR
LDA KEYBD LDA KEYBD
BMI SKIPBOOT BPL CHKRSP
LDA ACIASR STA STROBE
BMI IOERR
SPIN: DB $A1, $AF, $AD, $DC, $A1, $AF, $AD, $DC
CHKRSP: LDA ACIASR
AND #$08 AND #$08
BEQ SYNC BEQ SYNC
LDY ACIADR LDA ACIADR
CPY #$81 CMP #$81
BNE SYNC BNE SYNC
BEQ BOOT STA PAD1
SPIN: DB $A1, $AF, $AD, $DC, $A1, $AF, $AD, $DC SNDCMD: LDA PDUNIT
SKIPBOOT: STA STROBE
LDA $00
BNE NOAUTO
JMP $FABA ; JUMP BACK TO AUTOSTART BOOT SCANNER ROM
NOAUTO: RTS
;*
;* CREATE COMMAND BUFFER FOR BOOT BLOCK
;*
BOOT: LDY #PDREAD
STY PDCMD
;LDA #$08
STA PDBUFH
LDX #BOOTDEV
STX PDUNIT
LDA #$00
STA PDBUFL
STA PDBLKL
STA PDBLKH
JSR DOCMD
LDX #BOOTDEV
JMP $801
;*
;* PRODOS INTELLIGENT DEVICE ENTRYPOINT
;*
DOCMD: LDA PDUNIT
ASL ASL
LDA PDCMD LDA PDCMD
ROL ROL
ASL ASL
ORA #$A0 ORA #$A0
PHP
STA PAD0 STA PAD0
SEI
JSR SENDACC JSR SENDACC
LDA PDBLKL LDA PDBLKL
JSR SENDACC JSR SENDACC
@ -201,12 +208,12 @@ RECVWT: LDA ACIASR
BEQ RECVWT BEQ RECVWT
LDA ACIADR LDA ACIADR
RTS RTS
ENDCMD: ENDCMD:
.REPEAT $C000+ROMSLOT*256+250-* .REPEAT $C000+ROMSLOT*256+250-*
DB $FF DB $FF
.ENDREP .ENDREP
DB "Pi" DB "Pi"
DW 0 DW 0
DB $A7 DB $97
DB <DOCMD DB <DOCMD
.ASSERT * = $C000+(ROMSLOT+1)*256, error, "Code not page size" .ASSERT * = $C000+(ROMSLOT+1)*256, error, "Code not page size"

View File

@ -124,10 +124,10 @@ unsigned char *prodos_time(void)
*/ */
time_t now = time(NULL); time_t now = time(NULL);
struct tm *tm = localtime(&now); struct tm *tm = localtime(&now);
int ptime = (tm->tm_mday & 0x1F) int ptime = (tm->tm_mday & 0x1F)
| (((tm->tm_mon + 1) & 0x0F) << 5) | (((tm->tm_mon + 1) & 0x0F) << 5)
| (((tm->tm_year - 100) & 0x7F) << 9) | (((tm->tm_year - 100) & 0x7F) << 9)
| ((tm->tm_min & 0x3F) << 16) | ((tm->tm_min & 0x3F) << 16)
| ((tm->tm_hour & 0x1F) << 24); | ((tm->tm_hour & 0x1F) << 24);
time_buff[0] = (unsigned char) ptime; time_buff[0] = (unsigned char) ptime;
time_buff[1] = (unsigned char) (ptime >> 8); time_buff[1] = (unsigned char) (ptime >> 8);
@ -225,7 +225,7 @@ void sendkeycodeup(int fd, int code)
{ {
evkey.code = KEY_LEFTCTRL; evkey.code = KEY_LEFTCTRL;
write(fd, &evkey, sizeof(evkey)); write(fd, &evkey, sizeof(evkey));
} }
if (code & MOD_ALT) if (code & MOD_ALT)
{ {
evkey.code = KEY_LEFTALT; evkey.code = KEY_LEFTALT;
@ -237,7 +237,7 @@ static int prevkeycode = -1;
void sendkey(int fd, int mod, int key) void sendkey(int fd, int mod, int key)
{ {
int code = keycode[(mod & MOD_FN) | (key & KEY_ASCII)] | ((mod << 8) & MOD_ALT); int code = keycode[(mod & MOD_FN) | (key & KEY_ASCII)] | ((mod << 8) & MOD_ALT);
if (prevkeycode >= 0) if (prevkeycode >= 0)
{ {
sendkeycodeup(fd, prevkeycode); sendkeycodeup(fd, prevkeycode);
@ -267,10 +267,10 @@ void sendkey(int fd, int mod, int key)
void sendbttn(int fd, int mod, int bttn) void sendbttn(int fd, int mod, int bttn)
{ {
static int lastbtn = 0; static int lastbtn = 0;
if (bttn) if (bttn)
{ {
lastbtn = evkey.code = (mod == 0) ? BTN_LEFT lastbtn = evkey.code = (mod == 0) ? BTN_LEFT
: (mod & 0x40) ? BTN_RIGHT : (mod & 0x40) ? BTN_RIGHT
: BTN_MIDDLE; : BTN_MIDDLE;
evkey.value = 1; evkey.value = 1;
@ -287,7 +287,7 @@ void sendrelxy(int fd, int x, int y)
{ {
#if 0 #if 0
static int accel[32] = { 0, 1, 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, static int accel[32] = { 0, 1, 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
-21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -4, -1}; -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -4, -1};
x = ((x > 4) || (x < -4)) ? x * 2 : accel[x & 0x1F]; x = ((x > 4) || (x < -4)) ? x * 2 : accel[x & 0x1F];
y = ((y > 4) || (y < -4)) ? y * 2 : accel[y & 0x1F]; y = ((y > 4) || (y < -4)) ? y * 2 : accel[y & 0x1F];
#else #else
@ -308,7 +308,7 @@ void sendrelxy(int fd, int x, int y)
int writeword(int fd, int word, char ack) int writeword(int fd, int word, char ack)
{ {
char rwchar; char rwchar;
rwchar = word; /* send low byte of word */ rwchar = word; /* send low byte of word */
write(fd, &rwchar, 1); write(fd, &rwchar, 1);
if ((read(fd, &rwchar, 1) == 1) && (rwchar == ack)) /* receive ack */ if ((read(fd, &rwchar, 1) == 1) && (rwchar == ack)) /* receive ack */
@ -456,7 +456,7 @@ void main(int argc, char **argv)
fd_set readset, openset; fd_set readset, openset;
char *devtty = "/dev/ttyAMA0"; /* default for Raspberry Pi */ char *devtty = "/dev/ttyAMA0"; /* default for Raspberry Pi */
char *vdrvdir = "/usr/share/a2pi/"; /* default vdrv image directory */ char *vdrvdir = "/usr/share/a2pi/"; /* default vdrv image directory */
/* /*
* Parse arguments * Parse arguments
*/ */
@ -504,7 +504,7 @@ void main(int argc, char **argv)
die("error: uinput ioctl EV_REP"); die("error: uinput ioctl EV_REP");
for (i = KEY_ESC; i <= KEY_F10; i++) for (i = KEY_ESC; i <= KEY_F10; i++)
if (ioctl(kbdfd, UI_SET_KEYBIT, i) < 0) if (ioctl(kbdfd, UI_SET_KEYBIT, i) < 0)
die("error: uinput ioctl SET_KEYBITs"); die("error: uinput ioctl SET_KEYBITs");
for (i = KEY_HOME; i <= KEY_DELETE; i++) for (i = KEY_HOME; i <= KEY_DELETE; i++)
if (ioctl(kbdfd, UI_SET_KEYBIT, i) < 0) if (ioctl(kbdfd, UI_SET_KEYBIT, i) < 0)
die("error: uinput ioctl SET_KEYBITs"); die("error: uinput ioctl SET_KEYBITs");
@ -589,21 +589,6 @@ void main(int argc, char **argv)
gpclk(271); /* divisor for ~1.8 MHz => (500/271) MHz */ gpclk(271); /* divisor for ~1.8 MHz => (500/271) MHz */
sleep(1); /* give clock chance to settle down */ sleep(1); /* give clock chance to settle down */
#endif #endif
/*
* Open socket.
*/
prlog("a2pid: Open server socket\n");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6551);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
srvfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (srvfd < 0)
die("error: socket create");
if (bind(srvfd,(struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
die("error: bind socket");
if (listen(srvfd, MAX_CLIENT - 1) < 0)
die("error: listen socket");
/* /*
* Open serial port. * Open serial port.
*/ */
@ -623,7 +608,7 @@ void main(int argc, char **argv)
tcsetattr(a2fd, TCSANOW, &newtio); tcsetattr(a2fd, TCSANOW, &newtio);
prlog("a2pid: Waiting to connect to Apple II...\n"); prlog("a2pid: Waiting to connect to Apple II...\n");
iopkt[0] = 0x80; /* request re-sync if Apple II already running */ iopkt[0] = 0x80; /* request re-sync if Apple II already running */
write(a2fd, iopkt, 1); write(a2fd, iopkt, 1);
if (read(a2fd, iopkt, 1) == 1) if (read(a2fd, iopkt, 1) == 1)
{ {
if (iopkt[0] == 0x80) /* receive sync */ if (iopkt[0] == 0x80) /* receive sync */
@ -645,6 +630,21 @@ void main(int argc, char **argv)
} }
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */ newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
tcsetattr(a2fd, TCSANOW, &newtio); tcsetattr(a2fd, TCSANOW, &newtio);
/*
* Open socket.
*/
prlog("a2pid: Open server socket\n");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6551);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
srvfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (srvfd < 0)
die("error: socket create");
if (bind(srvfd,(struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
die("error: bind socket");
if (listen(srvfd, MAX_CLIENT - 1) < 0)
die("error: listen socket");
/* /*
* Come basck here on RESET. * Come basck here on RESET.
*/ */
@ -691,7 +691,7 @@ reset:
write(a2fd, iopkt, 1); write(a2fd, iopkt, 1);
tcflush(a2fd, TCIFLUSH); tcflush(a2fd, TCIFLUSH);
flushreqs(a2fd, 0, -1, -1); flushreqs(a2fd, 0, -1, -1);
break; break;
case 0x82: /* keyboard event */ case 0x82: /* keyboard event */
// printf("Keyboard Event: 0x%02X:%c\n", iopkt[1], iopkt[2] & 0x7F); // printf("Keyboard Event: 0x%02X:%c\n", iopkt[1], iopkt[2] & 0x7F);
sendkey(kbdfd, iopkt[1], iopkt[2]); sendkey(kbdfd, iopkt[1], iopkt[2]);
@ -791,6 +791,7 @@ reset:
state = RESET; state = RESET;
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */ newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
tcsetattr(a2fd, TCSANOW, &newtio); tcsetattr(a2fd, TCSANOW, &newtio);
a2reqlist->type |= AWAIT_COMPLETE;
} }
else else
state = RESET; state = RESET;
@ -799,7 +800,7 @@ reset:
for (i = 0; i < MAX_CLIENT; i++) for (i = 0; i < MAX_CLIENT; i++)
if (a2client[i].flags & CLIENT_COUT) if (a2client[i].flags & CLIENT_COUT)
write(a2client[i].fd, iopkt, 2); write(a2client[i].fd, iopkt, 2);
break; break;
case 0x9E: /* request complete ok */ case 0x9E: /* request complete ok */
case 0x9F: /* request complete error */ case 0x9F: /* request complete error */
@ -820,17 +821,21 @@ reset:
} }
else else
state = RESET; state = RESET;
break; break;
case 0xA0: /* virtual drive 1 STATUS call */ case 0xA0: /* virtual drive 1 STATUS call */
case 0xA2: /* virtual drive 2 STATUS call */ case 0xA2: /* virtual drive 2 STATUS call */
//printf("vdrive: STATUS unit:%d\n", (iopkt[0] >> 1) & 0x01); //printf("vdrive: STATUS unit:%d\n", (iopkt[0] >> 1) & 0x01);
iopkt[3] = iopkt[0] + 1; /* ack */ iopkt[3] = iopkt[0] + 1; /* ack */
write(a2fd, &iopkt[3], 1); write(a2fd, &iopkt[3], 1);
iopkt[0] = vdrvstatus((iopkt[0] >> 1) & 0x01); iopkt[0] = vdrvstatus((iopkt[0] >> 1) & 0x01);
write(a2fd, iopkt, 1); write(a2fd, iopkt, 1);
if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */ if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */
write(a2fd, &(a2reqlist->type), 1); {
break; iopkt[0] = a2reqlist->type;
write(a2fd, iopkt, 1);
printf("vdrive: status resend request %04X\n", a2reqlist->type);
}
break;
case 0xA4: /* virtual drive 1 READ call */ case 0xA4: /* virtual drive 1 READ call */
case 0xA6: /* virtual drive 2 READ call */ case 0xA6: /* virtual drive 2 READ call */
//printf("vdrive: READ unit:%d block:%d\n", (iopkt[0] >> 1) & 0x01, iopkt[1] | (iopkt[2] << 8)); //printf("vdrive: READ unit:%d block:%d\n", (iopkt[0] >> 1) & 0x01, iopkt[1] | (iopkt[2] << 8));
@ -839,7 +844,11 @@ reset:
iopkt[0] = vdrvread(a2fd, (iopkt[0] >> 1) & 0x01, iopkt[1] | (iopkt[2] << 8)); iopkt[0] = vdrvread(a2fd, (iopkt[0] >> 1) & 0x01, iopkt[1] | (iopkt[2] << 8));
write(a2fd, iopkt, 1); write(a2fd, iopkt, 1);
if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */ if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */
write(a2fd, &(a2reqlist->type), 1); {
iopkt[0] = a2reqlist->type;
write(a2fd, iopkt, 1);
printf("vdrive: read resend request %04X\n", a2reqlist->type);
}
break; break;
case 0xA8: /* virtual drive 1 WRITE call */ case 0xA8: /* virtual drive 1 WRITE call */
case 0xAA: /* virtual drive 2 WRITE call */ case 0xAA: /* virtual drive 2 WRITE call */
@ -849,20 +858,28 @@ reset:
newtio.c_cc[VMIN] = 1; /* blocking read until command packet received */ newtio.c_cc[VMIN] = 1; /* blocking read until command packet received */
tcsetattr(a2fd, TCSANOW, &newtio); tcsetattr(a2fd, TCSANOW, &newtio);
iopkt[0] = vdrvwrite(a2fd, (iopkt[0] >> 1) & 0x01, iopkt[1] | (iopkt[2] << 8)); iopkt[0] = vdrvwrite(a2fd, (iopkt[0] >> 1) & 0x01, iopkt[1] | (iopkt[2] << 8));
write(a2fd, iopkt, 1); write(a2fd, iopkt, 1);
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */ newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
tcsetattr(a2fd, TCSANOW, &newtio); tcsetattr(a2fd, TCSANOW, &newtio);
if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */ if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */
write(a2fd, &(a2reqlist->type), 1); {
iopkt[0] = a2reqlist->type;
write(a2fd, iopkt, 1);
printf("vdrive: write resend request %04X\n", a2reqlist->type);
}
break; break;
case 0xAC: /* virtual clock TIME call */ case 0xAC: /* virtual clock TIME call */
//printf("vclock: TIME\n"); //printf("vclock: TIME\n");
iopkt[3] = 0xAD; /* ack */ iopkt[0] = 0xAD; /* ack */
write(a2fd, &iopkt[3], 1); write(a2fd, iopkt, 1);
write(a2fd, prodos_time(), 4); write(a2fd, prodos_time(), 4);
if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */ if (a2reqlist && !(a2reqlist->type & AWAIT_COMPLETE)) /* resend last request */
write(a2fd, &(a2reqlist->type), 1); {
break; iopkt[0] = a2reqlist->type;
write(a2fd, iopkt, 1);
printf("vclock: resend request %04X\n", a2reqlist->type);
}
break;
default: default:
prlog("a2pid: Unknown Event\n"); prlog("a2pid: Unknown Event\n");
tcflush(a2fd, TCIFLUSH); tcflush(a2fd, TCIFLUSH);