root/sys/arch/acorn32/stand/nbfs/rmheader.S
/*      $NetBSD: rmheader.S,v 1.5 2021/02/06 21:45:38 joerg Exp $       */

/*-
 * Copyright (c) 2001, 2006 Ben Harris
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Relocatable module header for NBFS.
 */

#include <arm/armreg.h>
#include <riscoscalls.h>

#include "nbfs.h"

.syntax unified

rmbase:
        .word   0                       /* Start code */
        .word   rminit - rmbase         /* Initialisation code */
        .word   rmfinal - rmbase        /* Finalisation code */
        .word   rmservice - rmbase      /* Service call handler */
        .word   rmtitle - rmbase        /* Title string */
        .word   rmhelp - rmbase         /* Help string */
        .word   rmcmdtbl - rmbase       /* Help and command keyword table */
        .word   0                       /* SWI chunk base number */
        .word   0                       /* SWI handler code offset */
        .word   0                       /* SWI decoding table offset */
        .word   0                       /* SWI decoding code offset */
        .word   0                       /* Messages filename offset */
        .word   flags - rmbase          /* Module flags extension offset */

fsib:   /* Filing system information block */
        .word   rmtitle - rmbase        /* Filing system name */
        .word   rmtitle - rmbase        /* Filing system boot text */
        .word   fsentry_open - rmbase
        .word   fsentry_getbytes - rmbase
        .word   fsentry_putbytes - rmbase
        .word   fsentry_args - rmbase
        .word   fsentry_close - rmbase
        .word   fsentry_file - rmbase
        .word   fileswitch_SUPPORTS_SPECIAL | fileswitch_READ_ONLY | NBFS_FSNUM
        .word   fsentry_func - rmbase
        .word   0                       /* FSEntry_GBPB */
        .word   0                       /* Extra information word */

rmtitle:
        .asciz  "NBFS"
        .align
flags:
        .word   0                       /* not 32 bit compatible */

rminit:
        /*
         * Module initialisation code
         *
         * On entry:
         * r10 = pointer to environment string
         * r11 = I/O base or instantiation number
         * r12 = pointer to private word
         * r14 = return address
         */
        stmfd   r13!, {r14}
        ldr     r1, Loldbase            /* Get old base address */
        adr     r2, rmbase              /* Get new base address */
        str     r2, Loldbase            /* New is the new old */
        ldr     r0, L_DYNAMIC           /* Pointer to the dynamic table */
        add     r0, r0, r2              /* ... relocated appropriately */
        bl      relocate_self           /* Call the relocation code */
        cmp     r0, #0
        bne     Lerror
        bl      Laddfs
        ldmfd   r13!, {pc}

Laddfs:
        stmfd   r13!, {r14}
        mov     r0, #OSFSControl_AddFS
        adr     r1, rmbase
        ldr     r2, =(fsib - rmbase)
        mov     r3, #0
        swi     XOS_FSControl
        ldmfd   r13!, {pc}              /* If that failed, so do we */

rmfinal:
        stmfd   r13!, {r14}
        mov     r0, #OSFSControl_RemoveFS
        adr     r1, rmtitle
        swi     XOS_FSControl
        cmp     r0, r0                  /* Clear V flag */
        ldmfd   r13!, {pc}

rmservice:
        cmp     r1, #Service_FSRedeclare
        movne   pc, r14
        stmfd   r13!, {r0-r3, r14}
        bl      Laddfs
        ldmfd   r13!, {r0-r3, pc}
        
Lerror:
        teq     pc, pc                  /* In 26-bit mode? */
        ldmfdne r13!, {r14}             /* If so, load up return address */
        orrsne  pc, r14, #R15_FLAG_V    /* and return setting V flag */
        mrs     r14, cpsr               /* Otherwise get cpsr */
        orr     r14, r14, #PSR_V_bit    /* set V flag */
        msr     cpsr_c, r14             /* put it back */
        ldmfd   r13!, {pc}              /* and return */

Loldbase:
        .word   0
L_DYNAMIC:
        .word   _DYNAMIC - rmbase


fsentry_open:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_open

fsentry_getbytes:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_getbytes

fsentry_putbytes:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_putbytes

fsentry_args:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_args

fsentry_close:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_close

fsentry_file:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_file

fsentry_func:
        stmfd   r13!, {r0-r7, r14}
        mov     r0, r13
        adr     r14, fsentry_ret
        b       nbfs_func

fsentry_ret:
        cmp     r0, #0
        popeq   {r0-r7, pc}
        add     r13, r13, #4
        pop     {r1-r7}
        b       Lerror

rmcmdtbl:
        .asciz  "NBFS"                  /* Command text */
        .align
        .word   rmcmd_nbfs - rmbase     /* Command code */
        .byte   0x00                    /* Min 0 parameters */
        .byte   0x00                    /* No GSTransed parameters */
        .byte   0x00                    /* Max 0 parameters */
        .byte   0x00                    /* Normal command */
        .word   rmcmd_nbfs_syntax - rmbase /* Syntax message */
        .word   rmcmd_nbfs_help - rmbase /* Help message */

        .byte   0                       /* end of list */

rmcmd_nbfs_syntax:
        .asciz  "Syntax: NBFS"
rmcmd_nbfs_help:
        .asciz  "*NBFS selects NBFS as the current filing system."
        .align

rmcmd_nbfs:
        /* We're called with r0 -> command tail. */
        stmfd   r13!, {r14}
        mov     r0, #OSFSControl_SelectFS
        adr     r1, rmtitle
        swi     XOS_FSControl
        ldmfd   r13!, {pc}