/*
* JR-IDE Project
* - (c) 2017 Alan Hightower
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Temporary program design to facilitate bootstrap on a broken system.
* It sends a static request to the Pi for 1 of several basic images
* and writes them to disk
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "rpc.h"
#include "jride.h"
#include "flash_api.h"
volatile uint16_t far *ide_sector;
volatile uint8_t far *ide_window;
volatile uint8_t far *bios_window;
uint16_t sector[63 * 256];
extern void _xfer_sector_in (uint16_t far *dst);
#pragma aux _xfer_sector_in = \
"push ds" \
"lds si, dword ptr ide_sector" \
"mov cx, 0x100" \
"cld" \
"rep movsw" \
"pop ds" \
parm [di es] \
modify [si es di cx];
extern uint16_t get_ds(void);
#pragma aux get_ds = \
"mov ax,ds" \
value [ax];
#define LOGERR(fmt, ...) fprintf(stderr, "\nERROR: " fmt "\n\n", ## __VA_ARGS__)
int main (int argc, char *argv[])
{
uint32_t words, count;
uint16_t far *ptr;
int mode = 1, fd;
char *path = NULL;
if (argc > 1)
mode = atoi (argv[1]);
bios_window = (volatile uint8_t far *) MK_FP(0xc000, 0x0000);
ide_sector = (uint16_t far *) &bios_window[JRIDE_IDE_DATA_WIN];
ide_window = (uint8_t far *) &bios_window[JRIDE_IDE_REG_BASE];
ide_window[IDE_REG_FEATURE] = mode;
ide_window[IDE_REG_COMMAND] = IDE_CMD_PULL_REQUEST;
while (ide_window[IDE_REG_STATUS] & 0x80); // busy
if (ide_window[IDE_REG_STATUS] & 1) // error bit
{
LOGERR("Error pulling file\n");
return -1;
}
count = words = (((uint32_t) ide_window[IDE_REG_ADDR_CYL_H]) << 16)
| (((uint32_t) ide_window[IDE_REG_ADDR_CYL_L]) << 8)
| ((uint32_t) ide_window[IDE_REG_ADDR_SEC]);
ptr = (uint16_t far *) MK_FP(get_ds(), sector);
while (count)
{
while (!(ide_window[IDE_REG_STATUS] & 0x08));
_xfer_sector_in (ptr);
ptr += 256;
if (count >= 256)
count -= 256;
else
break;
}
if (mode == 0)
{
int i;
volatile uint16_t far *dst = (volatile uint16_t far *) bios_window;
for (i = 0; i < words; i++, dst++)
*dst = sector[i];
printf ("Loaded %d bytes at 0xc0000\n", words << 1);
return 0;
}
switch (mode)
{
default:
case 1: path = "pimount.com"; break;
case 2: path = "picon.com"; break;
}
unlink (path);
fd = open (path, O_RDWR | O_CREAT | O_BINARY, 0644);
write (fd, sector, words << 1);
close (fd);
printf ("wrote %u bytes to %s\n", (unsigned) (words << 1), path);
return 0;
}