opt cre ;NEEDED org $400 ;NEEDED start bsr init ;initialize values moveq #1,D0 ;T1 lea sizp,A1 ;T1 moveq #lsizp,D1 ;T1 trap #15 ;\T1: output "size?" moveq #4,D0 ;T4 trap #15 ;\T4: input dec->size move.w D1,D2 ;store size in D2 move.w D2,count ;store COUNT subq #1,D2 ;decrement D2 (fix) bsr newline ;crlf loopx moveq #1,D0 ;T1, begin loop lea nump,A1 ;T1 moveq #lnump,D1 ;T1 trap #15 ;\T1: output "num?" moveq #4,D0 ;T4 trap #15 ;\T4: input dec->num move.l D1,num ;store num move.l sum,D3 ;2 add.l num,D3 ;2 * err check --- bvc chk2 ;Overflow? bsr operr ;ERR: Too big. chk2 cmpi.l #highsl,D3 ;Too big? bgt operr ;ERR: Too big. * err check --- sumok move.l D3,sum ;2: sum += num bsr minval ;set min bsr maxval ;set max loopy dbra D2,loopx ;loop until D2 < 0 bsr newline ;crlf bsr opsum ;output SUM bsr opmin ;output MIN bsr opmax ;output MAX move.l sum,D0 ; bsr design ;convert SUM to Unsigned LONG move.w count,D1 ; ext.l D1 ;Make COUNT a LONG for division bsr udiv32 ;[Unsigned LONG division] btst.b #0,flags ;was it negative? beq ngskp ;if not, skip neg.l D0 ;negate quotient neg.l D1 ;negate remainder ngskp move.l D0,D2 ;DBG: save AVERAGE move.l D1,D3 ;DBG: save REMAINDER bsr opavg ;output AVERAGE move.l D2,D0 ;DBG: AVERAGE: D0 move.l D3,D1 ;DBG: REMAINDER: D1 move.l sum,D3 ;DBG: show SUM: D3 move.l min,D4 ;DBG: show MIN: D4 move.l max,D5 ;DBG: show MAX: D5 move.b flags,D6 ;DBG: FLAGS in: D6 endprg trap #0 ;Stop Execution bra start ;(loop to start) stop #$2000 ;NEEDED * ---------------------------------------------------- * * INITIALIZE init move.l #0,sum ;sum=0 move.l #highsl,min ;1, min = highest num move.l min,max ;1 neg.l max ;\1: max = lowest num (-min) addq #2,max ;lowest = #$-2147483648 move.b #0,flags ;clear flags rts ;RETURN * ---------------------------------------------------- * * DISPLAY NEW LINE newline moveq #0,D0 ;T0 moveq #0,D1 ;T0 trap #15 ;\T0: output cr+lf rts ;RETURN * ---------------------------------------------------- * * GET MINIMUM VALUE minval move.l num,D0 ; [Min Value] cmp.l min,D0 ; bge minjmp ;min > num? move.l D0,min ;min = num minjmp rts ;RETURN * ---------------------------------------------------- * * GET MAXIMUM VALUE maxval move.l num,D0 ; [Max Value] cmp.l max,D0 ; ble maxjmp ;max < num? move.l D0,max ;max = num maxjmp rts ;RETURN * ---------------------------------------------------- * * OUTPUT AVG (D0,D1) opavg move.l D0,D2 move.l D1,D3 moveq #1,D0 ;T1 lea avgo,A1 ;T1 moveq #lavgo,D1 ;T1 trap #15 ;\T1: output "avg:" moveq #3,D0 ;T3 move.l D2,D1 ;T3 [avg] trap #15 ;\T3: output avg bsr newline ;crlf moveq #1,D0 ;T1 lea remo,A1 ;T1 moveq #lremo,D1 ;T1 trap #15 ;\T1: output "rem:" moveq #3,D0 ;T3 move.l D3,D1 ;T3 [rem] trap #15 ;\T3: output rem bsr newline ;crlf rts ;RETURN * ---------------------------------------------------- * * OUTPUT SUM opsum moveq #1,D0 ;T1 lea sumo,A1 ;T1 moveq #lsumo,D1 ;T1 trap #15 ;\T1: output "sum:" moveq #3,D0 ;T3 move.l sum,D1 ;T3 [sum] trap #15 ;\T3: output sum bsr newline ;crlf rts ;RETURN * ---------------------------------------------------- * * OUTPUT MIN opmin moveq #1,D0 ;T1 lea mino,A1 ;T1 moveq #lmino,D1 ;T1 trap #15 ;\T1: output "min:" moveq #3,D0 ;T3 move.l min,D1 ;T3 [min] trap #15 ;\T3: output min bsr newline ;crlf rts ;RETURN * ---------------------------------------------------- * * OUTPUT MAX opmax moveq #1,D0 ;T1 lea maxo,A1 ;T1 moveq #lmaxo,D1 ;T1 trap #15 ;\T1: output "max:" moveq #3,D0 ;T3 move.l max,D1 ;T3 [max] trap #15 ;\T3: output max bsr newline ;crlf rts ;RETURN * ---------------------------------------------------- * * DE-SIGN A LONG * IN: (signed LONG in D0, bit location in flags in D1) * OUT: (unsigned lONG in D0, sign in flags) * design tst.l D0 ;test it bpl desjmp ;negative? bset.b D1,flags ;set NEG bit neg.l D0 ;negate desjmp rts ;RETURN * ---------------------------------------------------- * * UDIV32 * IN: (unsigned LONGs in D0, D1; D0/D1) * OUT: (D0:Quotient, D1:Remainder) * Notes: uses D2,D3,D4 * I took this from "Assembly Language and Systems * Programming for the M68000 Family", page 341. * Heavily shoe-horned. * has errors for numbers big or bigger than $40000000 udiv32 moveq #0,D3 ;clear D3 move.l D0,D2 ;wait, which one move.l D1,D0 ;is divisor? move.l D2,D1 ;duh? fixed. moveq #0,D2 ;clear D2 * trap #0 udiv1 cmp.l D0,D1 ; * trap #0 blt udiv5 ;D0 > D1? goto 5 move.l D0,D2 ;D2 = divisor moveq #0,D4 ;clear D4 move.w #$10,CCR ;sets X in CCR * trap #0 udiv2 cmp.l D2,D1 ; * trap #0 blt udiv3 ;D2 > D1? goto 3 roxl.l #1,D4 ;rotate D4 left tst.l D2 ; bmi udiv4 ;D2 neg? goto 4 lsl.l #1,D2 ;shift D2 left bra udiv2 ;goto 2 udiv3 lsr.l #1,D2 ;undo last shift udiv4 sub.l D2,D1 ;D1 = D1-D2 add.l D4,D3 ;D3 = D4+D3 bra udiv1 ;goto 1 udiv5 move.l D3,D0 ; rts ;RETURN * ---------------------------------------------------- * * ERRBIG * Note: the emulator checks for numbers too low from * the add function, but not for numbers too big. * This function outputs an error message. operr tst num bmi err1 ;negative? lea errbo,A1 ;T1 "too big" moveq #lerrbo,D1 ;T1 move.l #0,sum ;clear sum bra err2 ; err1 lea errso,A1 ;T1 "too small" moveq #lerrso,D1 ;T1 move.l #0,sum ;clear sum err2 moveq #1,D0 ;T1 trap #15 ;\T1: output "err:" bra endprg ;Quit program. * ---------------------------------------------------- * * DATA data sizp dc.b 'Enter Size: ' lsizp equ *-sizp nump dc.b 'Enter number: ' lnump equ *-nump sumo dc.b 'Total of all is: ' lsumo equ *-sumo mino dc.b 'Minimum value is: ' lmino equ *-mino maxo dc.b 'Maximum value is: ' lmaxo equ *-maxo avgo dc.b 'Average value is: ' lavgo equ *-avgo remo dc.b 'Remainder is: ' lremo equ *-remo errbo dc.b 'Error! Number too big. Forcing termination. ' lerrbo equ *-errbo errso dc.b 'Error! Number too low. Forcing termination. ' lerrso equ *-errso num ds.l 1 ;Current Number count ds.w 1 ;Count sum ds.l 1 ;Running Sum min ds.l 1 ;Running Minimum max ds.l 1 ;Running Maximum flags ds.b 1 ;Holds neg flags highsl equ $7FFFFFFE ;Highest for signed long lowsl equ $80000000 ;Lowest for signed long end start ;REQUIRED * ---------------------------------------------------- *