head 4.4; access ; symbols ; locks oasisa:4.4; strict; comment @# @; 4.4 date 2001.06.19.12.15.45; author oasisa; state Exp; branches ; next ; desc @New Repository; 6/19/2001 (klh) @ 4.4 log @New Repository; 6/19/2001 (klh) @ text @;**************************************************************************** ;* Copyright 1994 MBARI * ;**************************************************************************** ;* $Header: startup.s,v 1.1 2001/06/19 11:44:59 oasisa Exp $ * ;* Summary : Assembly language routines for OASIS Microcontroller * ;* Filename : startup.s * ;* Author : Robert Herlien * ;* Project : OASIS Mooring Controller * ;* $Revision: 1.1 $ * ;* Created : 02/06/91 * ;* * ;* MBARI provides this documentation and code "as is", with no warranty, * ;* express or implied, of its quality or consistency. It is provided without* ;* support and without obligation on the part of the Monterey Bay Aquarium * ;* Research Institute to assist in its use, correction, modification, or * ;* enhancement. This information should not be published or distributed to * ;* third parties without specific written permission from MBARI. * ;* * ;**************************************************************************** ; $TITLE("OASIS Microcontroller") ; STARTUP MODULE MAIN ; $INCLUDE(..\C196\INCLUDE\8096.INC) $INCLUDE(OASIS.INC) ; ;***************************************************************************** ; EXTRN _main:ENTRY ;The brain dead Intel Assembler treates MAIN ;as a reserved keyword so I cannot call the ;C main procedure MAIN! EXTRN MEMORY:WORD ;Linker symbol, start of free memory EXTRN ?MEMORY_SIZE:WORD ;Linker symbol, length of free memory EXTRN sys_init:WORD ;Global initialization flag EXTRN bank_port:BYTE ;Bank select port in OASIS hardware EXTRN progRamChksum:WORD ;Program RAM checksum PUBLIC free_mem ;Start of free memory PUBLIC mem_size ;Length of free memory PUBLIC SP ;Stack pointer PUBLIC STACK ;Bottom of stack ;**************************************************************** ; CHIP CONFIGURATION BYTE ;**************************************************************** ; CSEG at 2018H ccb: DCB 0d4H ;No pwrdown, 8 bit, ADV, 2 Wait states ;***************************************************************************** ; power up reset vector - software start location ; CSEG at 2080H di ;In case we got here from userif ld sp, #100h ;Load init stack pointer ld tmp0, #tmp0+2 clrRegs: ;Loop to clear register space st R0, [tmp0]+ cmp tmp0, 200h jlt clrRegs ld tmp0, sys_init cmp tmp0, #RAM_OK ;See if RAM initialized IF EXEC_FROM_RAM jne startColdInit ;If no, init RAM scall chkProgRam ;Check program RAM checksum cmp tmp0, progRamChksum ;If chksum bad, go to init code ENDIF je goMain startColdInit: scall initRam ;If failed, init data and prog RAM st tmp0, progRamChksum ;store checksum st R0, sys_init ;clear sys_init flag goMain: ld SP,#STACK ;Load real stack pointer ldb zeroBank, #RAMSELBIT ;Select RAM for RAM/ROM area stb zeroBank, bank_port lcall _main ;start C main procedure ;Returns after main() turns off power idlpd #2 ;To be safe, put CPU in pwrdown mode ld tmp0, #8000h pwrdown_wait: ;Loop to wait for CPU power down nop djnzw tmp0, pwrdown_wait rst ;if STILL here, restart ;***************************************************************************** ; Bank Switching and Copying code ; Placed here because it needs to be in low memory (< 0x6000) ; PUBLIC chkProgRam ;Calculate checksum on program RAM PUBLIC zeroBank ;Byte to select bank zero PUBLIC bankCopy ;Copy to/from bank switched memory PUBLIC bankZero ;Zero bytes in bank switched memory ;***************************************************************************** ; chkProgRam - Calculate checksum on RAM/ROM area ; ; Nat16 chkProgRam( Void ); ; chkProgRam: ldb dstBank, #RAMSELBIT ;Select RAM for RAM/ROM area stb dstBank, bank_port ld tmp0, R0 ;Init checksum to zero ld tmp2, #PROG_RAM ;Point to ROM/RAM area ld tmp4, #RAM_CHKSUM_LEN ;Get length to checksum over chkRam1: add tmp0, [tmp2]+ ;Add program word djnzw tmp4, chkRam1 ;Repeat until done ret ;***************************************************************************** ; initRam - Initialize program and data RAM ; ; Nat16 initRam( Void ); ; ; Zeroes data RAM, copies program ROM to RAM, and returns program RAM checksum ; initRam: stb R0, bank_port ;Start in bank zero, ROM selected ld tmp0, #INIT_RAM ;point tmp0 to init area ld tmp2, tmp0 st R0, [tmp2]+ ;zero first word ld tmp4, #(INIT_LEN - 1) ;set remaining amount to init bmov tmp0, tmp4 ;copy the zero to rest of RAM IF EXEC_FROM_RAM ldb dstBank, #RAMSELBIT ;Select RAM for RAM/ROM area ld tmp0, R0 ;Init checksum to zero ld tmp2, #PROG_RAM ;Point to ROM/RAM area ld tmp4, #RAM_CHKSUM_LEN ;Get length to checksum over initRam1: stb R0, bank_port ;select ROM ld tmp6, [tmp2] ;Get word from ROM stb dstBank, bank_port st tmp6, [tmp2]+ ;Copy word to RAM add tmp0, tmp6 ;Calc checksum djnzw tmp4, initRam1 ;Repeat until done ENDIF ret ;***************************************************************************** ; bankCopySub - Subroutine for bank copier ; ; Performs one copy "block" for bankCopy, turns on/off ints and bank switch ; Assumes calling routine has done test for tmp1b != 0 ; ; Inputs: tmp1b = bytes to copy ; tmp4 = src ptr ; tmp6 = dst ptr ; dstBank = destination bank ; ; tmp0b used as scratch ; tmp2 must be untouched ; bankCopySub: di ;Ints off while in "wrong" bank stb dstBank, bank_port ;Select destination bank bCpySub1: ldb tmp0b, [tmp4]+ ;Move bytes stb tmp0b, [tmp6]+ djnz tmp1b, bCpySub1 stb zeroBank, bank_port ;Go back to bank 0 ei ;Allow interrupt window while bank=0 ret ;***************************************************************************** ; bankCopy - Copy bytes to/from bank switched memory ; ; Void bankCopy( Nat16 bank, const Byte *src, Byte *dst, Nat16 len ) ; ; Comment: Assumes one of src or dst is in non-banked memory, and hence ; in context even when bank 0 is switched out. This is true since ; 0xe000 to 0xffff in bank 0 is used only for permanently malloced ; structs (driver headers, etc), and are not are not declared as ; available to the linker. ; ; Takes approx 6 usec/byte. 2 Kbytes -> 12 ms. ; Transfers 32 bytes/loop. Interrupts are off for approx 200 usec. ; ; Register usage: tmp0b = byte to copy ; tmp1b = inner loop counter ; tmp2 = outer loop counter ; tmp4 = src ptr ; tmp6 = dst ptr ; bankCopy: ldb dstBank, 2[SP] ;Get destination bank orb dstBank, zeroBank ld tmp4, 4[SP] ;Get source address ld tmp6, 6[SP] ;Get destination address ld tmp2, 8[SP] ;Get length to copy andb tmp1b, tmp2b, #1fh ;Get odd 0 - 31 bytes be bCpy1 ;Skip if 0 scall bankCopySub ;Copy first 0 - 31 bytes bCpy1: shr tmp2, #5 ;Do 32 bytes at a time be bCpyDone ;If zero, skip bCpy2: ldb tmp1b, #32 ;Do 32 bytes at a time scall bankCopySub ;Copy them djnzw tmp2, bCpy2 ;Repeat until done bCpyDone: ret ;***************************************************************************** ; bankZeroSub - Subroutine for bank zero function ; ; Zeroes one block of 1 - 32 bytes for bankZero, turns off ints and bank switch ; Assumes calling routine has done test for tmp1b != 0 ; ; Inputs: tmp1b = bytes to zero ; tmp4 = destination ptr ; tmp5b = bank to zero ; ; tmp2 must be untouched ; bankZeroSub: di ;Ints off while in "wrong" bank stb tmp5b, bank_port ;Select destination bank bZeroSub1: stb R0, [tmp4]+ ;Zero the bytes djnz tmp1b, bZeroSub1 stb zeroBank, bank_port ;Go back to bank 0 ei ;Allow interrupt window while bank=0 ret ;***************************************************************************** ; bankZero - Zero bytes in bank switched memory ; ; Void bankZero( Nat16 bank, Byte *dst, Nat16 len ) ; ; Takes approx 4 usec/byte. 8 Kbytes -> 33 ms. ; Zeroes 32 bytes/loop. Interrupts are off for approx 140 usec. ; ; Register usage: tmp0b = byte to copy ; tmp1b = inner loop counter ; tmp2 = outer loop counter ; tmp4 = destination ptr ; tmp5b = bank ; bankZero: ldb tmp5b, 2[SP] ;Get destination bank orb tmp5b, zeroBank ld tmp4, 4[SP] ;Get destination address ld tmp2, 6[SP] ;Get length to zero andb tmp1b, tmp2b, #1fh ;Get odd 0 - 31 bytes be bZero1 ;If zero, skip scall bankZeroSub ;Zero first 1 - 31 bytes bZero1: shr tmp2, #5 ;Do 32 bytes at a time be bZeroDone ;If zero, skip bZero2: ldb tmp1b, #32 ;Do 32 bytes at a time scall bankZeroSub ;Zero the bytes djnzw tmp2, bZero2 ;Repeat until done bZeroDone: ret ;***************************************************************************** KSEG ; Data Constants ; free_mem: dcw MEMORY ;Linker free memory address mem_size: dcw ?MEMORY_SIZE ;Linker free memory size ;***************************************************************************** ; Registers for bankCopy, etc ; RSEG ;Register segment zeroBank: dsb 1 ;How to select bank 0 dstBank: dsb 1 ;Bank to copy to END @