; ; $Header: C:\\ham\\evm/RCS/bios2.asm 1.26 1999/04/07 17:47:46 dbraun Exp $ ; ; $Log: bios2.asm $ ; Revision 1.26 1999/04/07 17:47:46 dbraun ; Restored usage of pertick subroutine. Trying to execute its ; code in-line caused stack overflow in some applications. ; Also: if an illegal interrupt occurs, the PTT lines are turned off ; before halting. ; ; Revision 1.25 1998/12/10 21:51:23 dbraun ; Changed Port B data direction initialization to be compatible ; with the TAPR interface design. ; ; Revision 1.24 1998/12/09 07:47:42 dbraun ; Changed the date. ; ; Revision 1.23 1998/12/09 07:44:41 dbraun ; Fixed CODEC reset delay loop in opencd (EVM version) to be ; long enough for up to 80 MHz clock speed. ; ; Revision 1.22 1998/11/20 12:49:48 dbraun ; When a fatal interrupt is received, all the LEDs will light up ; before halting (except the Tx ones, of course). ALso, ; the timer interrupt uses one less stack location, so it is ; less likely to cause stack overflow in complicated programs ; (which was the motivation for the thing with the LEDs). ; ; Revision 1.21 1998/03/30 09:59:54 dbraun ; Added Johan's 3/98 bug fix to (EVM) opencd routine. ; ; Revision 1.20 1997/10/23 13:29:12 dbraun ; Updated version date ; ; Revision 1.19 1997/10/23 13:25:56 dbraun ; Turned off watchdog blinking fo Organge LED. ; ; Revision 1.18 1997/01/23 09:55:55 dbraun ; Stopped using up/down LEDs during program download. ; ; Revision 1.17 1997/01/17 11:04:57 dbraun ; Fixed bug in previous version: M3 was not set in pertick... ; ; Revision 1.16 1997/01/16 20:02:51 dbraun ; Rewrote timer interrupt to keep a 24-bit counter so ; longer time delays could be tracked. ; ; Revision 1.15 1997/01/14 12:18:06 dbraun ; Registers r3/m3/n3 are no longer sacred. They are saved/restored ; by interrupt service routines. However, user-callable routines ; like getc, putc still modify them. ; ; Revision 1.14 1996/11/30 15:25:55 dbraun ; Moved fake hardware reset code cragment to leonid.asm, as a macro. ; ; Revision 1.13 1996/10/25 11:14:01 dbraun ; If a command is not received within 2 seconds after reset, ; the currently loaded program is started. Naturally, you ; have to put a default program in the PEROM... ; ; Revision 1.12 1996/10/15 06:39:37 dbraun ; Fix mistakes in previous revision ; ; Revision 1.11 1996/10/15 06:17:31 dbraun ; Reverted back to original "enter" and "leave" macros that do not save ; A2. Also reverted to original-sized scidata. (Didn't work...) ; ; Revision 1.10 1996/10/15 06:11:27 dbraun ; Fixed mistake in memory allocation for new, bigger scidata. ; ; Revision 1.9 1996/10/14 13:17:02 dbraun ; Moved serial buffers to high Y memory: $3800 to $3FFF. ; Also moved code to P:$3800 to $3FFF ; Now application can use everything from $0100 to $37FF in P/X and Y ; ; Revision 1.8 1996/10/11 14:22:36 dbraun ; Changed this and leonid.asm so that monitor code/buffers sit ; from $3000 to top of RAM ($3fff) instead of $2000 to $2fff. ; This, the actual programs get to use a single block of ; P/X space from $0100 to $2fff instead of two pieces from ; $0100 to $13ff and $2000 to $3fff. ; Also, enter and leave macros now save a2. ; ; Revision 1.7 1996/07/17 13:13:10 dbraun ; Port B bits 8 and 9 are now programmed as outputs. ; ; Revision 1.6 1996/06/21 07:11:35 dbraun ; Clarified comments about EVM codec initialization. ; No code change. ; ; Revision 1.5 1996/06/20 08:59:29 dbraun ; Got serial-data-controlled reset function to actually work. ; Also added himem and lomem statements. ; Also made fanicier LED blinking on reset, booting, etc. ; ; Revision 1.4 1996/06/19 20:45:24 dbraun ; Initalize many variables at load time instead of at runtime, ; to reduce program size. ; ; Revision 1.3 1996/06/19 18:53:55 dbraun ; Added the June 11,1996 Alefnull fix for initializing pertim. ; Also made the same fix to the EVM-specific code. ; ; Revision 1.2 1996/06/19 12:45:32 dbraun ; Added RCS headers ; ; page 132,79 opt rc opt mu title 'DSP CARD 4 Bootloader/EVM56K BIOS' ;**************************************************************************** ;* Copyright (C) 1992-1995 by Alef Null. All rights reserved. * ;* Author(s): Jarkko Vuori, OH2LNS * ;**************************************************************************** ;* Here are all DSP56001/2 interrupt vectors and space for * ;* interrupt contexts and basic interrupt service routines. * ;* Also included are initalization code, self checking and * ;* support routines for host communication, codec control, * ;* low level AX25 handling and transmit control. * ;* * ;* KISS protocol handling is based on article * ;* Chepponis, M., Karn, P.: * ;* "The KISS TNC: A simple Host-to-TNC communications * ;* protocol", * ;* Proc. of the sixth ARRL computer networking cnf., 1988 * ;* * ;* HDLC protocol handling is based on article * ;* Carlson, D., E.: * ;* "Bit-Oriented Data Link Control Procedures", * ;* IEEE Trans. on Comm., Vol. 28, No. 4, April 1980 * ;* * ;* CRC calculation/checking is based on article * ;* Morse, G.: * ;* "Calculating CRCs by bits and bytes", * ;* BYTE Vol. 11, No. 9, September 1986 * ;* * ;* Modification(s): * ;* * ;* 08.04.95 added version number printout after reset * ;* 03.08.95 added DWAIT control logic to the KISS * ;* transmit control * ;* 02.09.95 corrected and modified KISS parameter * ;* handling and TXDELAY=0,TXTAIL=0 bugs * ;* KISS buffer length increased to 2048 bytes * ;* -------------------------------------------------------------------------* ;* J.B. Forrer, KC7WW for Motorola EVM56K * ;* Thanks for suggestions and help from P. Jalocha, SP9VRC * * ;-------------------------------------------------------------------------- * ;* 17/08/95 fixed usage of 20 dB amp. and HPF in "opencd" * ;* 22/08/95 Initialize "cryconf" so BIOS can be rommed * ;* 11/10/95 Conditional assembly for either EVM or DSP4 * ;* 05/03/96 Conditional assembly for 66 and 80 MHz EVM's * ;-------------------------------------------------------------------------- * ; * ; NOTE: r7 is sacred!! - it is used by the SSI - DO NOT TOUCH! * ; ; N1OWU: r3/m3/n3 used to be sacred, but not any more... ; * ; EVM CODEC SETUP DIFFERENCES (cryconf): * ; 1) EVM uses the wrong crystal selection for the 24MHz xtal * ; (check control word 1/2). * ; 2) It appears that we need to use the MIC input - I also * ; disable the input pre-amp, (check control word 3/4). * ;===========================================================================* ; Version number (source code date) * ;===========================================================================* year equ 1999 month equ 04 day equ 07 ;===========================================================================* ;---------------------------------------------------------------------------- ; We include LEONID here because we need some addresses ; for the user program/data areas in one place only. nolist include 'leonid' list if (EVM56K>0) ;---------------------------------------------------------------------------- ; EVM CODEC usage definitions - these are only EQU's NO_PREAMP equ $100000 LO_OUT_DRV equ $080000 HI_PASS_FILT equ $008000 SAMP_RATE_9 equ $003800 ; 9600 SPS with 24.576MHz xtal SAMP_RATE_48 equ $003000 ; 48000 SPS SAMP_RATE_32 equ $001800 ; 32000 SPS SAMP_RATE_27 equ $001000 ; 27428.57 SPS SAMP_RATE_16 equ $000800 ; 16000 SPS SAMP_RATE_8 equ $000000 ; 8000 SPS STEREO equ $000400 DATA_8LIN equ $200300 DATA_8A equ $200200 DATA_8U equ $200100 DATA_16 equ $200000 IMMED_3STATE equ $800000 XTAL2_SELECT equ $200000 BITS_64 equ $000000 BITS_128 equ $040000 BITS_256 equ $080000 CODEC_MASTER equ $020000 CODEC_TX_OFF equ $010000 CTRL_WD_12 equ NO_PREAMP+HI_PASS_FILT+SAMP_RATE_48+STEREO+DATA_16 ;CLB=0 CTRL_WD_34 equ IMMED_3STATE+XTAL2_SELECT+BITS_64+CODEC_MASTER CTRL_WD_56 equ $000000 CTRL_WD_78 equ $000000 HEADPHONE_EN equ $800000 LINEOUT_EN equ $400000 LEFT_ATTN equ $010000 ;63*LEFT_ATTN = -94.5 dB, 1.5 dB steps SPEAKER_EN equ $004000 RIGHT_ATTN equ $000100 ;63*RIGHT_ATTN = -94.5 dB, 1.5 dB steps MIC_IN_SELECT equ $100000 LEFT_GAIN equ $010000 ;15*LEFT_GAIN = 22.5 dB, 1.5 dB steps MONITOR_ATTN equ $001000 ;15*MONITOR_ATTN = mute, 6 dB steps RIGHT_GAIN equ $000100 ;15*RIGHT_GAIN = 22.5 dB, 1.5 dB steps OUTPUT_SET equ HEADPHONE_EN+LINEOUT_EN+(LEFT_ATTN*4) INPUT_SET equ MIC_IN_SELECT+(15*MONITOR_ATTN)+(RIGHT_ATTN*4) ;----------------------------------------------------------------------------- ; Define the PLL multiplier ;----------------------------------------------------------------------------- if (xtal==32000000) ClockMult equ $7 ; set PLL 8x endif if (xtal==40000000) ClockMult equ $9 ; set PLL 10x endif if (xtal==66000000) ; NOT DIVISIBLE BY 4 !!! (16.5) ClockMult equ $0F ; set PLL 16x endif if (xtal==68000000) ClockMult equ $10 ; set PLL 17x endif if (xtal==80000000) ClockMult equ $12 ; set PLL 20x endif ;----------------------------------------------------------------------------- ; EVM specific parameters ;----------------------------------------------------------------------------- if (EVM56K==2) ; Expanded EVM ;----------------------------------------------------------------------------- ; On the expanded EVM56K, all memory is independant ;----------------------------------------------------------------------------- ramx equ $0100 ; external X RAM st address ramxlen equ $4000-$0100 ; external X RAM length ramy equ $0100 ; external Y RAM st address ramylen equ $4000-$0100 ; external Y RAM length ramp equ $0100 ; external P RAM st address ramplen equ $8000-$0100 ; external P RAM length else ; Standard EVM ;----------------------------------------------------------------------------- ; On the standard EVM56K, P and X shares the same space, so we arbitrarily ; let P use 0100 - 1FFF, X use 2000 - 3FFF, Y is separate 0 - 3FFF ;----------------------------------------------------------------------------- ramx equ $2000 ; external X RAM st address ramxlen equ $4000-$0100 ; external X RAM length ramy equ $0100 ; external Y RAM st address ramylen equ $4000-$0100 ; external Y RAM length ramp equ $0200 ; external P RAM st address ramplen equ $2000-$0200 ; external P RAM length endif ;----------------------------------------------------------------------------- endif if (EVM56K==0) ;----------------------------------------------------------------------------- ; Further DSP CARD 4 specific parameters ;----------------------------------------------------------------------------- topmem equ $0c00 ; top p memory locations where buffers and monitor routines are located rom equ $8000 ; starting address of the EPROM monhigh equ $c600 ; part of monitor to be placed on high memory romlen equ 32768 ; length of the EPROM (in bytes) ramx equ $0100 ; external X RAM st address ramxlen equ $2000-$0100 ; external X RAM length ramy equ $0100 ; external Y RAM st address ramylen equ $4000-$0100 ; external Y RAM length ramp equ $0200 ; external P RAM st address ramplen equ $2000-$0200 ; external P RAM length ;----------------------------------------------------------------------------- endif ; General parameters hbeat equ 72.0 ; heartbeat blinking rate (pulses/min) ; Protocol parameters pgm_flash equ 0 ; commands chg_pgm equ 1 read_flash equ 2 load_go equ 3 ack equ 4 ; responses bad_crc equ 5 no_flash equ 6 erase_err equ 7 pgm_err equ 8 no_pgm equ 9 dataorp equ 0 ; download space flags xory equ 1 magicw equ 271828 ; special magic word to detect first time reset ; KISS special characters fend equ $c0 fesc equ $db tfend equ $dc tfesc equ $dd ; HDLC equations flagmsk equ $ff ; left justified flag mask flag equ %01111110 ; HDLC bit flag abrtmsk equ $fe ; left justified abort mask abort equ %11111110 ; abort sequence fivemsk equ $fe ; left justified five bit mask five equ %01111100 ; left justified five bit sequence poly equ $8408 ; HDLC CRC polynomial (x^16 + x^12 + x^5 + 1) crcchk equ $f0b8 ; special CRC checkword ; flags rempty equ 0 ; SCI flags rfull equ 1 xempty equ 2 xfull equ 3 timer equ 4 ; timer flag scmode equ 5 ; serial communication mode xkissf equ 6 ; put KISS frame begin ztstflg equ 7 ; HDLC xmitter status flags zinsflg equ 8 hunt equ 9 ; HDLC receiver status flags firstb equ 10 scndb equ 11 pwrup equ 12 ; set if power-up reset carrier equ 13 ; carrier on/off givedat equ 14 ; data output gate ; macro for green (actually orange LED on N1OWU circuit) LED handling copled macro mode b\mode #14,x:m_pbd endm ; macro for red (actually green DCD on N1OWU circuit) LED handling cmdled macro mode b\mode #13,x:m_pbd endm ; macro for yellow general-purpose LED (fifth from the right) on N1OWU circuit yellowled macro mode b\mode #3,x:m_pbd endm ; macro for yellow "up" LED on N1OWU circuit ; LED only, not connected to radio. upled macro mode b\mode #1,x:m_pbd endm ; macro for yellow "down" LED on N1OWU circuit ; LED only, not connected to radio. downled macro mode b\mode #2,x:m_pbd endm ; macro for immediate move movi macro data,dest move data,a1 move a1,dest endm ; macro for entering interrupt service routine ; stores x0, x1, a, and r3/m3 registers enter macro contex move x,l:1,x0 and x0,a rem,x0 eor x0,a lsr a #>poly,x0 jcc _crc1 eor x0,a _crc1 move a1,rem endm ; byte CRC calculation routine ; byte in x0, result in x:$000001,x1 move #>poly,y1 do #8,_crc2 move b1,a1 ; first LSB to remainder and x1,a x:@cvi(@pow(2,8-1)),x1 mpy x0,x1,a y:@cvi(@pow(2,8-1)),x1 mpy x0,x1,a y:@cvi(@pow(2,16-1)),x1 mpy x0,x1,a y:magicw,x0 eor x0,a jeq crcchk,x0 ; check with special checkword move x:ack,x0 ; tell to host that we managed to get out from the reset jsr putc move #>(day<<3)|((month-1)>>1),x0 jsr putc move #>((month-1)<<7)|(year-1900),x0 ; Y2K problem? jsr putc move #>@cvi(1.0*baud),x0 ; set timer jsr stimer _wchr wait jsr getc ; wait for chr of timer jcc $00000f,x0 ; no, calculate next pgm slot number and x0,a #>1,x0 add x0,a #>16,x1 ; robin round if last pgm slot number cmp x1,a tge x0,a move a1,y:magicw<<4,b ; active pgm slot found, store slot number move a1,x0 or x0,b move b1,y:load_go,a cmp x0,a jeq lg jmp wakeup+4,x0 jeq scir1 move #wakeup,r3 jmp scir2 scir1 move r3,a1 eor x0,a jne scir2 ; wake-up sequence detected. ;jmp boot ;jmp scir2 ;ignore it for now... hardreset ;restart EVM (with macro defined in leonid.asm) ; no wake-up sequence detected, continue searching scir2 move r3,x:str1,x0 jne scire ; we didn't see FEND, keep looking move x0,x:str2,x0 jeq scire ; just another FEND, keep looking for cmd ; analyze command byte move #0,a1 eor x1,a x1,x:fesc,x1 jmp store ; we have seen TFEND after an FESC, write an FEND str3end move #str2,a1 move a1,x:fend,x1 ; store the character to the queue store move x:kisses,x0 cmp x0,a #>P,x0 jgt str4c cmp x0,a #>kissext,x0 ; local parameter, check if a time parameter jeq str4a cmp x0,a #>kisspar-1,x0 jle str4b str4a move #>kisspar-1,x0 add x0,a ; no, store it without any conversion move a,r3 nop move x1,p:(r3) jmp str4c str4b add x0,a #>baud/100,x0 ; yes, time scale parameter mpy x0,x1,a a,r3 asr a ; interger multiply correction move a0,p:(r3) ; product in low order word str4c move y:ack,x0 ; tell to host that command was accepted jsr putc lghunt move #$00ffff,a1 ; try to find beginning of the frame move a1,x:flag,a cmp x0,a jne lghunt jsr rdbyte ; packet id jcs xmtnak move x0,y:crcchk,x0 move x:@cvi(@pow(2,16-1)),x1 mpy x0,x1,a move a0,y:@cvi(@pow(2,8-1)),x1 mpy x0,x1,a y:crcchk,x0 move x:ack,x0 jsr putc ; crc ok, wait for the next jmp lghunt xmtnak move #>bad_crc,x0 ; crc bad, ignore frame and try again jsr putc jmp lghunt rdytogo move #>ack,x0 ; crc ok, if len=0 then jump to the user code jsr putc cmdled clr jmp @cvi(0.5*baud),x0 ; error condition, blink cmd led jsr stimer _sherro wait jset #timer,y: write ptr there are also free space left jne putc2 ; buffer full state reached (ignore given data) bset #xfull,y:fesc,x0 move x0,y:(r3)+ move b1,x0 putke1 move x0,y:(r3)+ move r3,x:fend,x0 move x0,y:(r3)+ move r3,x:$f80000,x0 and x0,a cmp x0,a a1,y:@pow(2,-15),x1 move a1,x:1,x1 ; shift to right 15 bits crc x:$ff,x0 and x0,a move a1,x0 jsr putc ; discard the previous bit putb2 rts ; flag detected putb3 bclr #hunt,y:@pow(2,-16),x1 ; shift to right 16 bits mpy x0,x1,a crc x:crcchk,x0 eor x0,a jne putb3b ; reject frame if CRC failed jsr endc rts putb3b jsr rejc rts ; abort detected putb4 bset #hunt,y:0) ;----------------------------------------------------------------------------- ;**************************************************************************** ;* Open codec driver for EVM * ; ; r7 - address of the modulo buffer (x: A/D, y: D/A) ; m7 - length of the modulo buffer ; x0 - samping rate: ; ;**************************************************************************** ; ; portc usage: ; bit8: SSI TX (from DSP to Codec) ; bit7: ; bit6: ; bit5: ; bit4: codec reset (from DSP to Codec) ; bit3: ; bit2: data/control bar ; 0=control ; 1=data ; ; BTW, Motorola's choice of bit 2 for C/D, instead of say bit 3 (SC0), ; prevents us from accessing the SCLK signal. ; ; PROGRAM OUTLINE: ; ;1 program fsync and sclk == output ;2 write pc2 = 0 (control mode) ;3 send 64 bit frame x times, with dcb bit = 0, keep doing until read back as 0 ;4 send 64 bit frame x times, with dcb bit = 1, keep doing until read back as 1 ;5 re-program fsync and sclk == input ;6 write pc2 = 1 (data mode) ;7 receive/send data (echo slots 1,2,3,4; slots 5,6,7,8 == DIP switched) ; ; initialize ssi -- fsync and sclk ==> outputs ; ; ;**************************************************************************** ; *****Sample rate is passed in x0 from macro call***** ;**************************************************************************** opencd movep #$0003,x:m_pcc ; turn off ssi port (keep SCI on) movep #$4F03,x:m_cra ; 40MHz/16 = 2.5MHz SCLK, WL=16 bits, 16W/F movep #$3B30,x:m_crb ; RIE,TIE,RE,TE, NTWK, SYN, FSR/RSR->bit bclr #4,x:m_pcd ; RESET~ .... bclr #2,x:m_pcd ; D/C~ ...... 0 ==> Control mode ;----reset delay for codec ---- ; Codec needs at least a 50 mS delay. do #4000,_delay_loop rep #500 ; 12.5 us delay @ 80 MHz clock nop ; Keep the inner REP loop short to reduce _delay_loop ; interrupt latency. bset #4,x:m_pcd ; RESET~ = 1 movep #$01E3,x:m_pcc ; Turn on ssi port (keep SCI on) ; send control blocks to the codec until we get valid responce from it ; add sampling rate and set CLB = 0 move #>%1110101101000111<<8,x1 ; add MICGAIN, HPF, ; sampling rate, ; set CLB = 0 move y: Data mode movep #$01E3,x:m_pcc ; turn on ssi port (keep SCI on) waitsyn jclr #m_tde,x:m_sr,waitsyn ; wait for the frame sync jset #m_tfs,x:m_sr,frmsync movep x:m_rx,x:m_tsr jmp waitsyn frmsync do #4-1,flshfrm ; then get rid of the remaining data _loop1 jclr #m_tde,x:m_sr,_loop1 movep y:(r7)+,x:m_tx movep x:m_rx,x:(r7) flshfrm do #192*4,waitcal ; wait for calibration _loop2 jclr #m_tde,x:m_sr,_loop2 movep y:(r7)+,x:m_tx movep x:m_rx,x:(r7) waitcal movep #$7b00,x:m_crb ; enable transmit interrupts rts ;**************************** ;* Close codec driver * ;**************************** ; close SSI interface and set codec to power down mode closecd movep #$0003,x:m_pcc ; TXD,RXD movep #$001c,x:m_pcddr ; SCLK,SC0,SC1 as output rts ;----------------------------------------------------------------------------- else ;----------------------------------------------------------------------------- ;***************************************** ;* Open codec driver for DSP CARD4 * ;***************************************** ; Start-up Crystal CS4215 Codec ; r7 - address of the modulo buffer (x: A/D, y: D/A) ; m7 - lenght of the modulo buffer ; x0 - samping rate and HPF enable/disable: ; 8 kHz $000000 ; 9.6 kHz $003800 ; 16 kHz $000800 ; 27.42857 kHz $001000 ; 32 kHz $001800 ; 48 kHz $003000 ; ; HPF enable $008000 ; ; program SSI to handle codec's initial communication mode opencd movep #$4f03,x:m_cra ; 27/16 MHz SCLK, WL=16 bit, 16 W/F movep #$3b3c,x:m_crb ; generate SCLK and FS movep #$01e3,x:m_pcc ; TXD,RXD,SC2,SCK,SRD,STD movep #$001c,x:m_pcddr ; SCLK,SC0,SC1 as output movep #$0000,x:m_pcd ; PDN & D/C down (wake up codec and put it to the control mode) ; send control blocks to the codec until we get valid responce from it move #>%1111101101000111<<8,x1 ; add sampling rate and HPF bit and set CLB = 0 move y:$0000ff,a1 and x0,a #>$ffff00,x0 move a1,x1 movep x:m_pbd,a and x0,a or x1,a movep a1,x:m_pbd andi #$fc,mr rts ; *** Persistence routines *** ; state bits xstart equ 0 ; starting up xmitter (xmit on, no data transmitting) xstop equ 1 ; putting xmitter off xon equ 2 ; xmitter currently transmitting data xoff equ 3 ; xmitter off xwait equ 4 ; waiting for carrier to be inactive xpersis equ 5 ; waiting for a new persistence algorithm slot ; macro for state setting nxstate macro state move #(1<$0000ff,x0 and x0,a move a1,a move p:kisspar+P-1,x0 ; then compare it with P cmp x0,a x:0,x0 move #-1,m3 eor x0,a a1,r3 jeq _pert1 move (r3)- ; check if timer elapsed move r3,a1 eor x0,a r3,y:@cvi(@pow(2,8-1)),x1 mpy x0,x1,a move a0,y:@cvi(1.0*baud),x0 ; set timer (1s) jsr stimer jsr waitchr jcs _rbe crcbyte ; calculate CRC of byte in x0, result in x:rom,x0 add x0,a move a1,r1 ; then fetch the load address jsr romrdw rts romhdlr romrdb,romrdw,romload ;----------------------------------------------------------------------------- endif if (EVM56K>0) ;----------------------------------------------------------------------------- ;**************************** ;* Startup code for EVM * ;**************************** boot movep #$261000+ClockMult,x:m_pll ; set PLL movep #$0000,x:m_bcr ; zero wait states for ext. memory ori #3,mr ; disable interrupts movec #0,sp movec #0,omr ; single chip mode ; initialize SCI movep #$2b02,x:m_scr ; 8,n,1 movep #(xtal+2*16*baud)/(2*2*16*baud)-1,x:m_sccr ; round baud ; initialize port B movep #$0000,x:m_pbc ; port B as general purpose port movep #$61ff,x:m_pbddr ; N1OWU: PB0-PB8,PB13 and PB14 as outputs movep #$0000,x:m_pbd ; initialize port C movep #$0003,x:m_pcc ; We are using TXD,RXD ; pc2 (D/C~), pc3 (DCD), movep #$1C,x:m_pcddr ; pc4 (C Reset) as outputs movep #0,x:m_pcd ; init PC4,PC3,PC2=0 ; start interrupts movep #$b000,x:m_ipr ; SSI=IPL2, SCI=IPL1 andi #$fc,mr ; unmask interrupts ; print welcome message cmdled set yellowled set move #>ack,x0 ; tell to host that we managed to get out from the reset jsr putc move #>(day<<3)|((month-1)>>1),x0 jsr putc move #>((month-1)<<7)|(year-1900),x0 jsr putc ; wait 2 seconds for the (possible) command wait_cmd move #>@cvi(2.0*baud),x0 ; set timer jsr stimer _wchr wait jsr getc ; wait for chr of timer jcc gotcmd jset #timer,y:load_go,a cmp x0,a jne wait_cmd ;************************** ;* LOAD FROM HOST AND GO * ;************************** move #>ack,x0 ; tell to host that command was accepted jsr putc lghunt yellowled clr move #$00ffff,a1 ; try to find beginning of the frame move a1,x:flag,a cmp x0,a jne lghunt jsr rdbyte ; packet id jcs xmtnak move x0,y:crcchk,x0 move x:@cvi(@pow(2,16-1)),x1 mpy x0,x1,a move a0,y:@cvi(@pow(2,8-1)),x1 mpy x0,x1,a y:crcchk,x0 move x:ack,x0 jsr putc ; crc ok, wait for the next jmp lghunt xmtnak yellowled clr ; turn off LED move #>bad_crc,x0 ; crc bad, ignore frame and try again jsr putc jmp lghunt rdytogo yellowled clr ; turn off LED move #>ack,x0 ; crc ok, if len=0 then jump to the user code jsr putc cmdled clr jmp