/* * 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; }