*********************************************************************** *** *** crc.aii Calculates a CRC on a buffer *** Copyright 1993 Morgan Davis Group *** *** Inspired by Jon C. Thomason's FInfo, *** with a CRC method by Jim Ferr. *** *** Command Syntax: *** *** &CRC NEW seed Inits CRC seed value *** &CRC (adr, len) Caculates CRC on length bytes at address *** &CRC GET numvar Returns last CRC value *** &CRC PEEK adr, len Returns address and length of a work buffer *** *** History: *** *** When Who Ver Description *** ------- --- --- --------------------------------------- *** 01mar93 jct 1.0 crc routines based on Jim Ferr's Warp 6 BBS code *** 28sep93 mwd 1.1 converted to MPW IIGS Assembler, 65C02-ized, *** accepts byte ranges from 0 to $FFFF, OMM ID is 'CR' *** machine M65C02 case on include 'handy.mac' include 'mega2.equ' include 'omm.equ' crc16 equ d0 ;W: crc gets calculated here length equ d2 ;W: length of byte range address equ d4 ;W: address of byte range holdcrc equ d6 ;B: temp storage BUFLEN equ 1024 ;number of bytes in file buffer *------------------------------* * Inspect Module Header * *------------------------------* crc proc hVERS dc.w $0000 ;W: driver loader version hID dc.w 'CR' ;W: driver's two-byte signature hSIZE dc.w END-START ;W: size of driver (not including header) hORG dc.w START ;W: org of driver pc phase hAMPC dc.w AMPERCT ;W: ampersand command lookup table address hKIND dc.w $0000 ;W: driver kind hRSRV1 dc.w $0000 ;W: reserved 1 hRSRV2 dc.w $0000 ;W: reserved 2 START cmp #MSG_AMPR ;ampersand service call? beq doampr ;yes cmp #MSG_INFO ;get info string? bne donothing move word,a_info,a1 donothing rts *------------------------------* * Ampersand Command Dispatcher * *------------------------------* doampr lda (txtptr) ;Look at current token to see what to do pha jsr chrget ;advance text pointer pla cmp #'(' ;&CRC (... beq crccmd cmp #$BF ;&CRC NEW seed, type beq crcnew cmp #$BE ;&CRC GET numvar beq crcget cmp #$E2 ;&CRC PEEK beq crcpeek jmp synerr ;bad ***=============================================== *** CRC GET numvar *** gets the CRC value *** crcget move word,crclast,a1 jmp putword ***=============================================== *** CRC NEW seed *** sets the CRC seed type *** crcnew jsr getword strs y,a,crclast rts ***=============================================== *** CRC PEEK addrvar, lenvar *** return the buffer address *** crcpeek move word,bufptr,a1 jsr putword jsr chkcom move word,#BUFLEN,a1 jmp putword ***=============================================== *** CRC (address, length) *** return the CRC of a specified memory range *** crccmd jsr getword ;get address of buffer strs y,a,address jsr comword ;get length of data strs y,a,length jsr chkcls move word,crclast,crc16 ldy #0 @loop testw length beq @done decw length lda (address),y jsr crccalc iny bne @loop inc address+1 bra @loop @done move word,crc16,crclast rts ***=============================================== *** MISC ROUTINES putword ldy #OMM_PUTWORD ;store value at a1 into numeric variable ldx #OMM_ID jmp OMMVEC comword jsr chkcom ;skip comma getword jsr frmnum ;get word at text pointer jmp getadr ;return in Y/A ***=============================================== * crccalc: calc crc on a byte at a time * CRCCALC: Call once per character. The CRC is saved * in crc16. * This section is Jim Ferr's code. * crccalc sta holdcrc lda #0 ldx #8 @calc1 asl holdcrc ror a and #$80 eor crc16 asl crc16+1 rol a bcc @next pha lda crc16+1 eor #$21 sta crc16+1 pla eor #$10 @next sta crc16 dex bne @calc1 rts *------------------------------* * Data Section * *------------------------------* dc.b 0 ;flag start of immed mode table IMMED *------------------------------* * Immediate Mode Addresses * *------------------------------* a_info dc.w info bufptr dc.w bufadr dc.w $0000 *------------------------------* * Main Program Data Section * *------------------------------* AMPERCT cstr 'CRC' dc.b -1 msb on info cstr '&SYSDATE CRC 3.0' msb off crclast dc.w $0000 pad START,256 bufadr ;ds BUFLEN ;page-aligned for speed END equ *+BUFLEN end