*
*``````````````````````````````*
* ADIM162:       INIT 2D ARRAY *
*-                            -*
* THIS SIMPLY CREATES A 1D     *
* ARRAY WITH THE DIM OF        *
* [:AXSIZE] BY [:AYSIZE].      *
*-                            -*
* CLOBBERS:                    *
*                              *
* FLAGS:  ????----  REG: AXYM  *
*-                            -*
* CYCLES: ???                  *
* SIZE:                        *
*-                            -*
* USAGE:                       *
*                              *
*-                            -*
* ENTRY                        *
*                              *
* TOP OF STACK                 *
*                              *
* LOW BYTE OF RETURN ADDRESS   *
* HI BYTE OF RETURN ADDRESS    *
*-                            -*
* EXIT                         *
*                              *
* TOP OF STACK                 *
*                              *
* LOW BYTE OF RETURN ADDRESS   *
* HI BYTE OF RETURN ADDRESS    *
*                              *
* .Y = ARRAY ADDRESS LO BYTE   *
* .X = ARRAY ADDRESS HI BYTE   *
* .A = ELEMENT SIZE            *
*                              *
* [RETURN] = TOTAL BYTE SIZE   *
* OF ARRAY.                    *
*                              *
* [RETLEN] = LENGTH IN BYTES   *
* OF THE RETURN VALUE.         *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
ADIM162
*
** SAVE RETURN ADDRESS
*
         PLA
         STA   RETADR
         PLA
         STA   RETADR+1
*
** GET PARAMETERS
*
         PLA
         STA   :FILL
         PLA
         STA   :ELEN      ; ELEMENT LENGTH
         PLA
*ADC #2
         STA   :AYSIZE
         STA   :AYBAK
         STA   :MCAND
         PLA
         STA   :AYSIZE+1
         STA   :AYBAK+1
         STA   :MCAND+1
         PLA
*ADC #2
         STA   :AXSIZE
         STA   :AXBAK
         STA   :MLIER
         PLA
         STA   :AXSIZE+1
         STA   :AXBAK+1
         STA   :MLIER+1
         PLA
         STA   ADDR1
         STA   ADDR4
         PLA
         STA   ADDR1+1
         STA   ADDR4+1
*
** LOOP THROUGH Y, CLEARING MEMORY
** FOR X BYTES TIMES ELEMENT SIZE,
** MOVING TO END OF LAST CLEAR
** UNTIL FINISHED
*
** MULTIPLY X AND Y
*
         LDA   #0
         STA   :PROD+2
         STA   :PROD+3
         LDX   #$10
:SHIFT_R
         LSR   :MLIER+1
         ROR   :MLIER
         BCC   :ROT_R
         LDA   :PROD+2
         CLC
         ADC   :MCAND
         STA   :PROD+2
         LDA   :PROD+3
         ADC   :MCAND+1
:ROT_R
         ROR              ; ROTATE PARTIAL PRODUCT
         STA   :PROD+3
         ROR   :PROD+2
         ROR   :PROD+1
         ROR   :PROD
         DEX
         BNE   :SHIFT_R
*
         LDA   :ELEN
         STA   :MCAND
         LDA   #0
         STA   :MCAND+1
         LDA   :PROD
         STA   :MLIER
         LDA   :PROD+1
         STA   :MLIER+1
*
** NOW MULTIPLY BY LENGTH OF ELEMENTS
*
         LDA   #0
         STA   :PROD
         STA   :PROD+1
         STA   :PROD+2
         STA   :PROD+3
         LDX   #$10
:SHIFTR  LSR   :MLIER+1
         ROR   :MLIER
         BCC   :ROTR
         LDA   :PROD+2
         CLC
         ADC   :MCAND
         STA   :PROD+2
         LDA   :PROD+3
         ADC   :MCAND+1
:ROTR
         ROR
         STA   :PROD+3
         ROR   :PROD+2
         ROR   :PROD+1
         ROR   :PROD
         DEX
         BNE   :SHIFTR
*
         CLC
         LDA   :PROD      ; INCREASE BY 5
         ADC   #5
         STA   :PROD
         BCC   :NOCAR
         INC   :PROD+1
:NOCAR
*
*
********************************
*
*  ERROR CONTROL
*
********************************
*
         LDA   ERRCTRL
         CMP   #1
         BEQ   :CHKERR
         JMP   :ERREND
:CHKERR
         LDA   :PROD+2    ; IF PROD > 16-BIT VALUE
         CMP   #0
         BNE   :EMAX
         LDA   :PROD+1
         CMP   #>ARRMAX   ; 81
         BCS   :CHKCONT
         BEQ   :CHKCONT
         JMP   :ERREND
:CHKCONT
         LDA   :PROD
         CMP   #<ARRMAX   ; 92
         BCS   :EMAX
         BEQ   :EMAX
         JMP   :ERREND
:EMAX
         _ERR  #:E_SID;#:E_MSG;#:E_DMP;#:PROD;#18
*
********************************
*
:ERREND
*
********************************
*
** NOW CLEAR MEMORY BLOCKS, WHOLE PAGES FIRST
*
         LDA   :FILL      ; FILL VALUE
         LDX   :PROD+1    ; NOTE THAT THIS WON'T
                          ; GO BEYOND A 16BIT VALUE;
                          ; ANYTHING HIGHER THAN
                          ; 16BITS IS MORE THAN
                          ; THERE IS MEMORY IN A
                          ; STANDARD APPLE ][
         BEQ   :PART
         LDY   #0
:FULL
         STA   (ADDR1),Y
         INY
         BNE   :FULL
         INC   ADDR1+1
         DEX
         BNE   :FULL      ; LOOP UNTIL PAGES DONE
*
** NOW DO REMAINING BYTES
*
:PART
         LDX   :PROD
         BEQ   :MFEXIT
         LDY   #0
:PARTLP
         STA   (ADDR1),Y
         INY
         DEX
         BNE   :PARTLP    ; LOOP UNTIL DONE
:MFEXIT
*
** NOW SET SIZES
*
         LDY   #0
         LDA   :AXBAK
         STA   (ADDR4),Y
         INY
         LDA   :AXBAK+1
         STA   (ADDR4),Y
         INY
         LDA   :AYBAK
         STA   (ADDR4),Y
         INY
         LDA   :AYBAK+1
         STA   (ADDR4),Y
         INY
         LDA   :ELEN
         STA   (ADDR4),Y
*
** RESTORE RETURN ADDRESS
*
         LDA   RETADR+1
         PHA
         LDA   RETADR
         PHA
*
** RETURN POINTER TO STARTING ADDRESS OF ARRAY
** AND STORE TOTAL BYTE SIZE IN RETURN MEM
*
         LDY   ADDR4
         LDX   ADDR4+1
         LDA   :PROD
         STA   RETURN
         LDA   :PROD+1
         STA   RETURN+1
         LDA   :PROD+2
         STA   RETURN+2
         LDA   :PROD+3
         STA   RETURN+3
         LDA   #4         ; SIZE OF RETURN
         STA   RETLEN
*
         RTS
*
** DATA
*
:PROD    DS    4
:AXSIZE  DS    2
:AYSIZE  DS    2
:AXBAK   DS    2
:AYBAK   DS    2
:MLIER   DS    2
:MCAND   DS    2
:FILL    DS    1
:ELEN    DS    1
*
:E_SID   ASC   "ADIM162 (DIM162 MACRO)",00
:E_DMP   ASC   ":PROD(4) :AXSIZE(2) :AYSIZE(2)"
         ASC   ":AXBAK(2) :AYBAK(2) :MLIER(2)"
         ASC   ":MCAND(2) :FILL(1) :ELEN(1)",00
:E_MSG   ASC   "ARRAY TOO LARGE!",00
*
