Compare commits
No commits in common. "52d5e67f44709c6dff315fcd7502886937cd6cd5" and "68d9e64f93e641a97540ac5c8469e1e7d3744a1a" have entirely different histories.
52d5e67f44
...
68d9e64f93
@ -3,16 +3,25 @@ _start:
|
||||
move.b #0x4, d0
|
||||
bsr.w find_first_card
|
||||
| Load the header sector for the kernel binary
|
||||
move.l #0x200, a1 | Set the destination address to 0x200
|
||||
move.l #0x1, d0 | Set the starting sector number to 1
|
||||
move.l #0x1, d1 | Set the sector count to 1
|
||||
bsr.w read_sectors
|
||||
move.l #0x1, (a0) | Set the sector number to 1
|
||||
| Transfer 0x100 (256) bytes from the storage card's data register to 0x100
|
||||
move.w #0x100, a1 | Load a1, the destination address register, with 0x100
|
||||
move.w #0xFF, d0 | Load d0 with the sector size - 1.
|
||||
hdr_sector_loop:
|
||||
move.b (4, a0), (a1)+ | Transfer a byte of sector data to the destination
|
||||
dbra d0, hdr_sector_loop | Loop back if there is more to transfer
|
||||
move.w (0x102), d0 | Load d0 with the number of sectors for the kernel - 1
|
||||
subq.w #0x1, d0
|
||||
| load the ELF kernel binary off the disk
|
||||
move.l #0xA000, a1 | Set the destination address to 0xA000
|
||||
move.l #0x2, d0 | Set the starting sector number to 2
|
||||
clr.l d1
|
||||
move.w (0x202), d1 | Set the sector count
|
||||
bsr.b read_sectors
|
||||
move.l #0x2, (a0) | Set the sector number to 2
|
||||
| Transfer 0x100 (256) * d0 bytes from the storage card's data register to 0xA000
|
||||
move.l #0xA000, a1 | Load a1, the destination address register, with 0xA000
|
||||
sectors_loop:
|
||||
move.w #0xFF, d1 | Load d0 with the sector size - 1.
|
||||
sector_loop:
|
||||
move.b (4, a0), (a1)+ | Transfer a byte of sector data to the destination
|
||||
dbra d1, sector_loop | Loop back if there is more to transfer
|
||||
dbra d0, sectors_loop | Loop back if there are more sectors to transfer
|
||||
move.l (0xA01C), d0 | Load the offset of the program headers in the file
|
||||
move.l #0xA000, a0 | Put the address of the program headers in a0
|
||||
adda.w d0, a0
|
||||
@ -63,32 +72,8 @@ ffc_done:
|
||||
rts
|
||||
|
||||
|
||||
| Reads sectors from a storage card
|
||||
| Card base in a0
|
||||
| Destination in a1
|
||||
| Start sector in d0.l
|
||||
| Sector count in d1.l
|
||||
| Clobbers a1, d1
|
||||
read_sectors:
|
||||
move.l d0, (a0) | Set the sector number
|
||||
move.l d1, (4, a0) | Set the sector count
|
||||
move.w #0x0, (8, a0) | Issue a read command
|
||||
| Transfer 0x200 (512) * sector_count bytes from the storage card's data register to (a1)
|
||||
lsl.l #8, d1 | d0 = d0 * 256 to compute the number of words to transfer
|
||||
subq.l #0x1, d1 | Subtract 1 from the word count to account for the extra loop done by dbra
|
||||
bra.b rs_loop
|
||||
rs_loop_swap:
|
||||
swap.w d1
|
||||
rs_loop:
|
||||
move.w (0xA, a0), (a1)+ | Transfer a word of sector data to the destination
|
||||
dbra.w d1, rs_loop
|
||||
swap.w d1
|
||||
dbra.w d1, rs_loop_swap
|
||||
rts
|
||||
|
||||
.if . != 512
|
||||
.org 511
|
||||
.if . != 256
|
||||
.org 255
|
||||
.byte 0
|
||||
.endif
|
||||
|
||||
|
||||
|
@ -5,8 +5,7 @@ use std::{
|
||||
path::Path,
|
||||
};
|
||||
|
||||
const BLOCK_SIZE: u16 = 512;
|
||||
const MAX_NAME_LEN: u16 = BLOCK_SIZE - 8;
|
||||
const BLOCK_SIZE: u16 = 256;
|
||||
|
||||
fn main() {
|
||||
let mut archive = File::create("initrd").expect("Could not open initrd");
|
||||
@ -14,38 +13,34 @@ fn main() {
|
||||
let file_path = Path::new(&file_path);
|
||||
let file_name = file_path.file_name().unwrap();
|
||||
let file_name_len =
|
||||
u16::try_from(file_name.len()).expect("File name length greater than 256 bytes");
|
||||
assert!(
|
||||
file_name_len <= MAX_NAME_LEN,
|
||||
"File {:?} has name longer than {} bytes",
|
||||
file_name,
|
||||
MAX_NAME_LEN
|
||||
);
|
||||
u8::try_from(file_name.len()).expect("File name length greater than 256 bytes");
|
||||
if file_name_len > 252 {
|
||||
panic!("File {:?} has name longer than 252 bytes", file_name);
|
||||
}
|
||||
let mut file = File::open(file_path).expect("File did not exist");
|
||||
let length = u16::try_from(file.metadata().expect("Could not get file metadata").len())
|
||||
.expect("File size greater than 64 KiB");
|
||||
let file_num_blocks = (length / BLOCK_SIZE) + if length % BLOCK_SIZE == 0 { 0 } else { 1 };
|
||||
let file_num_blocks = (length / BLOCK_SIZE) + if length % BLOCK_SIZE != 0 { 1 } else { 0 };
|
||||
let mut header_block = Vec::new();
|
||||
header_block.extend_from_slice(&length.to_be_bytes());
|
||||
header_block.extend_from_slice(&file_num_blocks.to_be_bytes());
|
||||
header_block.extend_from_slice(&file_name_len.to_be_bytes());
|
||||
header_block.push(file_name_len);
|
||||
header_block.extend_from_slice(file_name.to_str().unwrap().as_bytes());
|
||||
header_block.push(0);
|
||||
header_block.resize(BLOCK_SIZE as usize, 0);
|
||||
archive
|
||||
.write_all(&header_block)
|
||||
.expect("Could not write to initrd");
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let bytes_written = io::copy(&mut file, &mut archive)
|
||||
.expect("Could not read from file/write to initrd") as u16;
|
||||
if (bytes_written % BLOCK_SIZE) != 0 {
|
||||
let bytes_padding = (BLOCK_SIZE) - (bytes_written % BLOCK_SIZE);
|
||||
let bytes_written =
|
||||
io::copy(&mut file, &mut archive).expect("Could not read from file/write to initrd");
|
||||
if (bytes_written as u16 % BLOCK_SIZE) != 0 {
|
||||
let bytes_padding = (BLOCK_SIZE) - (bytes_written as u16 % BLOCK_SIZE);
|
||||
for _ in 0..bytes_padding {
|
||||
archive.write_all(&[0]).expect("Could not write to initrd");
|
||||
}
|
||||
}
|
||||
}
|
||||
archive
|
||||
.write_all(&[0; BLOCK_SIZE as usize])
|
||||
.write_all(&[0; 256])
|
||||
.expect("Could not write to initrd");
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
.global _start
|
||||
_start:
|
||||
move.b #'H', 0xFF0200
|
||||
move.b #'i', 0xFF0200
|
||||
move.b #0xA, 0xFF0200
|
||||
stop #0x2700
|
||||
|
Loading…
Reference in New Issue
Block a user