mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 19:31:02 +00:00
132 lines
3.6 KiB
Plaintext
132 lines
3.6 KiB
Plaintext
;
|
||
; File: CRCPatch.a
|
||
;
|
||
; Contains: This file does the CRC calculation.
|
||
;
|
||
; Written by: George Norman - 7/30/86
|
||
;
|
||
; Copyright: © 1986-1992 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM4> 11/5/92 SWC Changed SlotEqu.a->Slots.a.
|
||
; <SM3> 5/29/92 KW (jmp,H3) Made sure the crcCalc is not performed on zero-sized
|
||
; <SM2> 5/29/92 kc Fix CalcCRC to allow decldata larger than 64k.
|
||
; <1> 1/31/92 JSM first checked in
|
||
;
|
||
INCLUDE 'SysEQU.a'
|
||
INCLUDE 'ROMEqu.a' ;Declaration ROM EQU's
|
||
include 'Slots.a'
|
||
|
||
;=====================================================================
|
||
; _CalcCRC : Calculate CRC
|
||
;
|
||
; PROCEDURE _CalcCRC(SizeCode,DataPtr,crc);
|
||
;=====================================================================
|
||
_CalcCRC PROC EXPORT
|
||
|
||
;VAR
|
||
RetnAddr$a EQU A0
|
||
DataPtr$a EQU A1
|
||
crcAdrL$a EQU A2
|
||
crcAdrH$a EQU A3
|
||
Temp$a EQU A4
|
||
TopOfData$a EQU A5
|
||
|
||
SizeCode$d EQU D0
|
||
crcPos$d EQU D1
|
||
crc$d EQU D2
|
||
Temp$d EQU D3
|
||
Index$d EQU D4
|
||
|
||
; Define stack-frame
|
||
StackFrame RECORD {A6Link},DECR
|
||
SizeCode DS.L 1 ;size of code
|
||
DataPtr DS.L 1 ;pointer to data
|
||
crc@ DS.L 1 ;VAR crc:longint
|
||
Return DS.L 1 ;Return address
|
||
A6Link DS.L 1 ;Old A6
|
||
ENDR
|
||
|
||
; Other
|
||
dataPtr EQU $4 ; [handle] <SM3>
|
||
|
||
;----------------------------------------------------------------------
|
||
; _CalcCRC
|
||
;----------------------------------------------------------------------
|
||
;BEGIN
|
||
WITH FHeaderRec, StackFrame
|
||
|
||
; Allocate local vars
|
||
LINK A6,#0
|
||
MOVEM.L A2-A5/D3-D4,-(SP) ;Save registers
|
||
|
||
|
||
; Calculate the address of the crc value.
|
||
MOVE.L SizeCode(A6),TopOfData$a ;TopOfData$a := Top of data
|
||
ADD.L DataPtr(A6),TopOfData$a
|
||
|
||
MOVE.L TopOfData$a,crcAdrL$a ;crcAdrL$a := TopOfData$a - (fhBlockSize-FH_crc) {Addr of crc MSB}
|
||
SUB.L #fhBlockSize-fhCRC,crcAdrL$a
|
||
MOVE.L crcAdrL$a,crcAdrH$a
|
||
ADD.L #3,crcAdrH$a ;Addr of crc LSB
|
||
|
||
|
||
; Determine the size of the declaration data to be checked.
|
||
MOVE.L TopOfData$a,Temp$a ;Temp$a := TopOfData$a - (fhBlockSize-FH_Length) {Addr of Length field}
|
||
SUB.L #fhBlockSize-fhLength,Temp$a ;Index := length of crc data.
|
||
MOVE.L (Temp$a),Index$d ;If there’s nothing to do (i.e., Index == 0), <SM3>
|
||
BEQ.S theEnd ; then just leave. <SM3>
|
||
|
||
MOVEQ #0,crc$d ;crc$d := 0
|
||
MOVE.L DataPtr(A6),DataPtr$a ;DataPtr$a := pointer to data
|
||
|
||
MOVE.L SizeCode(A6),Temp$d ;Adjust DataPtr$a
|
||
SUB.L Index$d,Temp$d
|
||
ADD.L Temp$d,DataPtr$a
|
||
|
||
|
||
; Calc the crc value.
|
||
MOVEQ #0,Temp$d ;Temp$d := 0
|
||
|
||
;REPEAT
|
||
Repeat ROL.L #1,crc$d ; Rotate-left the crc value.
|
||
|
||
CMP.L crcAdrL$a,DataPtr$a ; IF DataPtr$a IN [crcAdrL$a..crcAdrH$a] THEN
|
||
BLT.S C10
|
||
CMP.L crcAdrH$a,DataPtr$a
|
||
BGT.S C10
|
||
|
||
ADDQ.L #1,DataPtr$a ; DataPtr$a := DataPtr$a + 1 {Do not include crc in calculation}
|
||
BRA.S Until
|
||
; ELSE
|
||
C10 MOVE.B (DataPtr$a)+,Temp$d ; Temp$d := DataPtr$a^; DataPtr$a := DataPtr$a + 1
|
||
ADD.L Temp$d,crc$d ; crc$d := crc$d + Temp$d
|
||
|
||
Until Subq.l #1,Index$d ; <SM3>
|
||
Bne.s Repeat ; <SM3>
|
||
;UNTIL Index$d < 0
|
||
|
||
|
||
; Patch in the crc result.
|
||
MOVE.L crc$d,(crcAdrL$a)
|
||
|
||
|
||
; Move crc result to calling routine.
|
||
MOVE.L crc@(A6),Temp$a
|
||
MOVE.L crc$d,(Temp$a)
|
||
|
||
|
||
; Restore globals, cleanup stack & return
|
||
theEnd MOVEM.L (SP)+,A2-A5/D3-D4 ;Restore registers <SM3>
|
||
UNLK A6 ;Clear stack frame of local vars
|
||
MOVE.L (SP)+,RetnAddr$a ;Remove return address
|
||
ADD.L #12,SP ;Clear stack-frame of parameters
|
||
JMP (RetnAddr$a) ;Return
|
||
|
||
ENDWITH
|
||
|
||
ENDP
|
||
|
||
END
|