; A macro to do unsigned integer division. It takes four parameters, each of
; which should be a register name:
;
; $Div: The macro places the quotient of the division in this register -
;       ie $Div := $Top DIV $Bot.
;       $Div may be omitted if only the remainder is wanted.
; $Top: The macro expects the dividend in this register on entry and places
;       the remainder in it on exit - ie $Top := $Top MOD $Bot.
; $Bot: The macro expects the divisor in this register on entry. It does not
;       alter this register.
; $Temp:The macro uses this register to hold intermediate results. Its initial
;       value is ignored and its final value is not useful.
;
; $Top, $Bot, $Temp and (if present) $Div must all be distinct registers.
; The macro does not check for division by zero; if there is a risk of this
; happening, it should be checked for outside the macro.

        MACRO
$Label  DivMod  $Div,$Top,$Bot,$Temp
        ASSERT  $Top <> $Bot            ; Produce an error if the
        ASSERT  $Top <> $Temp           ; registers supplied are
        ASSERT  $Bot <> $Temp           ; not all different.
        [       "$Div" /= ""
        ASSERT  $Div <> $Top
        ASSERT  $Div <> $Bot
        ASSERT  $Div <> $Temp
        ]

$Label  MOV     $Temp,$Bot              ; Put the divisor in $Temp
        CMP     $Temp,$Top,LSR #1       ; Then double it until
90      MOVLS   $Temp,$Temp,LSL #1      ; 2 * $Temp > $Top.
        CMP     $Temp,$Top,LSR #1
        BLS     %b90
        [       "$Div" /=""
        MOV     $Div,#0                 ; Initialise the quotient.
        ]

91      CMP     $Top,$Temp              ; Can we subtract $Temp?
        SUBCS   $Top,$Top,$Temp         ; If we can, do so.
        [       "$Div /= ""
        ADC     $Div,$Div,$Div          ; Double $Div & add new bit
        ]
        MOV     $Temp,$Temp,LSR #1      ; Halve $Temp,
        CMP     $Temp,$Bot              ; and loop until we've gone
        BHS     %b91                    ; past the original divisor.
        MEND
