STORAGE_SEC equ $0 STORAGE_CNT equ $4 STORAGE_CMD equ $8 STORAGE_DMADR equ $C include cards.i include memory.i include string.i section .text,text ; Initialize the initrd reader public initrd_init initrd_init: move.w #$4, d0 ; Get the pointer to the MMU card jsr find_first_card move.l a0, storage_card_base rts ; Get the start byte for a specific file in the initrd ; Pointer to name in a0 ; Number returned in d0, or 0 if not found public initrd_find_file initrd_find_file: movem.l d2/a2, -(a7) move.l a0, a2 move.l #512, d0 jsr malloc move.l a0, a1 move.l #1, d0 iff_loop: movem.l d0/a0/a1, -(a7) move.l storage_card_base, a0 move.l #1, d1 bsr.b read_sectors movem.l (a7)+, d0/a0/a1 move.l (a1), d2 bne.b .1 move.l #0, d0 bra.b iff_done .1: ; File name at (12, a1) ; Passed in name at a2 movem.l d0/a0/a1, -(a7) move.l a2, a0 adda.l #12, a1 jsr strcmp movem.l (a7)+, d0/a0/a1 bne.b .2 addi.l #1, d0 movem.l (a7)+, d2/a2 lsl.l #8, d0 lsl.l #1, d0 rts .2: addi.l #1, d0 move.l (4,a1), d2 add.l d2, d0 bra.b iff_loop iff_done: movem.l (a7)+, d2/a2 rts ; Reads bytes of a file from the initrd ; Start byte of file in d0 ; Offset in d1 ; Length in d2 ; Buffer in a0 public initrd_read_bytes initrd_read_bytes: add.l d1, d0 move.l d2, d1 move.l a0, a1 move.l storage_card_base, a0 bra.b read_bytes ; Reads sectors from a storage card ; Card base in a0 ; Destination in a1 ; Start sector in d0.l ; Sector count in d1.l read_sectors: cmpi.l #0, d1 beq.b read_sectors_done move.l d0, (STORAGE_SEC,a0) ; Set the sector number move.l d1, (STORAGE_CNT,a0) ; Set the sector count move.l a1, (STORAGE_DMADR,a0) ; Set the destination address move.w #$1, (STORAGE_CMD,a0) ; Issue a DMA read command read_sectors_done: rts ; Reads bytes off a storage card ; Card base in a0 ; Destination in a1 ; Start byte in d0.l ; Byte count in d1.l read_bytes: movem.l d2-d5/a2/a3,-(a7) ; Save callee preserved registers move.l d0, d4 ; Save start byte in d4 move.l d1, d5 ; Save byte count in d5 move.l a1, a3 ; Save destination in a6 lsr.l #8, d0 ; Divide start byte by 512 to compute starting sector lsr.l #1, d0 move.l d0, d3 ; Save the starting sector in d3 move.l #1, d1 ; Read the starting sector into the sector buffer move.l #sec_buf, a1 bsr.b read_sectors move.l a3, a2 ; Load the destination into a2 move.l d4, d0 ; Load the start byte into d0 andi.l #$1FF, d0 ; Modulus start byte by 512 to compute sector data offset adda.l d0, a1 ; Add the offset to the start of the sector buffer move.l #$200, d1 ; Compute the number of bytes to transfer by subtracting the offset from 512 sub.l d0, d1 cmp d5, d1 ; Compare the number of bytes to transfer with the byte count ble.b count_ok ; If it was less than the byte count, do not adjust the bytes to transfer move.l d5, d1 ; Otherwise, cap the transfer count to the total byte count count_ok: move.l d1, d4 ; Save the number of bytes in d4 subi.l #1, d1 ; Subtract 1 from the number of bytes to account for the extra loop done by dbra start_sec_loop: ; Transfer the required bytes from the start sector to the destination buffer move.b (a1)+, (a2)+ dbra d1, start_sec_loop move.l d3, d0 ; Load the starting sector into d0 addi #1, d0 ; Compute the start of the middle sectors by adding 1 to the starting sector move.l d4, d2 ; Load the number of bytes transferred into d2 move.l d5, d1 ; Load the byte count into d1 sub.l d2, d1 ; Compute the number of remaining bytes by subtracting the number of transferred bytes from the byte count cmpi.l #0, d1 ; If there are no more bytes to read, end early beq.b read_bytes_done move.l d1, d4 ; Save the number of remaining bytes in d4 lsr.l #8, d1 ; Divide remaining bytes by 512 to compute the number of middle sectors lsr.l #1, d1 move.l a2, a1 ; Transfer the sector data to the end of the start sector bytes bsr.b read_sectors ; Read the middle sectors move.l d1, d3 ; Save the number of middle sectors in d3 lsl.l #8, d1 ; Multiply the number of middle sectors by 512 to compute the number of bytes transferred lsl.l #1, d1 sub.l d1, d4 ; Subtract the number of transferred bytes from the number of remaining bytes cmpi.l #0, d4 ; If there are no more bytes to read, end early beq.b read_bytes_done adda.l d1, a2 ; Add the number of bytes transferred to a2 add.l d3, d0 ; Compute the end sector number by adding the start and count of the middle sectors move.l #1, d1 ; Set the number of sectors to read to 1 move.l #sec_buf, a1 ; Set the read address of the sector to the sector buffer bsr.w read_sectors ; Read the end sector move.l d4, d1 ; Load the number of remaining bytes into d1 end_sec_loop: ; Transfer the required bytes from the start sector to the destination buffer move.b (a1)+, (a2)+ dbra d1, end_sec_loop read_bytes_done: movem.l (a7)+, d2-d5/a2/a3 ; Restore callee preserved registers rts section .bss,bss storage_card_base: ds.b 4 sec_buf: ds.b 512