spo600:6502_math
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
spo600:6502_math [2025/01/21 20:39] – [Multiplication and Division] chris | spo600:6502_math [2025/01/23 22:27] (current) – [Multiplication and Division] chris | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== | ====== | ||
- | The 6502 processor is limited to very simple math operations, and various processor flags affect these operations. | + | The [[6502]] processor is limited to very simple math operations, and various |
==== Decimal Mode ==== | ==== Decimal Mode ==== | ||
Line 89: | Line 89: | ||
There are no multiplication or division instructions on the 6502; it is up to the programmer to provide the appropriate logic. Typical implementations use a combination of shifts and adds; for example, to multiply by 12, the original value shifted left three times (x8) can be added to the original value shifted left two times (x4). | There are no multiplication or division instructions on the 6502; it is up to the programmer to provide the appropriate logic. Typical implementations use a combination of shifts and adds; for example, to multiply by 12, the original value shifted left three times (x8) can be added to the original value shifted left two times (x4). | ||
+ | Here is a simple example subroutine which multiplies two 8-bit values, producing a 16-bit product as the result (this code can be tested on the [[6502 Emulator]]): | ||
+ | < | ||
+ | ; | ||
+ | ; Example of 8-bit x 8-bit multiply with | ||
+ | ; 16-bit result on a 6502 | ||
+ | ; | ||
+ | ; This code uses shift-and-add | ||
+ | ; | ||
+ | ; Chris Tyler 2025-01-23 for the SPO600 course | ||
+ | ; | ||
+ | ; Copyright (C)2025 Seneca Polytechnic | ||
+ | ; Licensed under the terms of the GPLv2+ | ||
+ | ; See the file LICENSE for details | ||
+ | |||
+ | ; ######### MACRO DEFINITIONS | ||
+ | ; === ZERO-PAGE MEMORY LOCATIONS | ||
+ | |||
+ | ; INPUT PARAMETERS AND RESULT | ||
+ | define M1 | ||
+ | |||
+ | define M2 | ||
+ | |||
+ | define RESULT | ||
+ | define RESULT_L $12 | ||
+ | define RESULT_H $13 | ||
+ | |||
+ | ; TEMPORARY COPIES OF M1, M2 | ||
+ | define T1 | ||
+ | |||
+ | define T2 | ||
+ | define T2_L $21 | ||
+ | define T2_H $22 | ||
+ | |||
+ | ; ######### TEST CODE | ||
+ | |||
+ | ; NOTE: THE NEXT TWO OPERANDS ARE IN DECIMAL! | ||
+ | ; THIS IS DUE TO THE LACK OF $ | ||
+ | |||
+ | LDA #7 ; FIRST MULTIPLICAND | ||
+ | STA M1 | ||
+ | |||
+ | LDA #9 ; SECOND MULTIPLICAND | ||
+ | STA M2 | ||
+ | |||
+ | JSR MULTIPLY ; MULTIPLY THE VALUES | ||
+ | |||
+ | BRK ; SEE 16 BIT RESULT AT ' | ||
+ | |||
+ | ; ######### MULTIPLY SUBROUTINE | ||
+ | ; MULTIPLY THE CONTENTS OF M1 BY THE CONTENTS | ||
+ | ; OF M2 AND STORE THE RESULT IN ' | ||
+ | ; | ||
+ | ; Operation: | ||
+ | ; 0. Multiplicand M1 is copied to temporary | ||
+ | ; variable T1. Multiplicand M2 is copied to | ||
+ | ; the 16-bit temporary variable T2. The | ||
+ | ; RESULT is zeroed out. | ||
+ | ; 1. If either multiplicand is zero, the | ||
+ | ; product is zero, so the routine returns | ||
+ | ; immediately with RESULT=0. | ||
+ | ; 2. T1 is shifted right. If the bit shifted | ||
+ | ; out (formerly bit 0) is a ' | ||
+ | ; value of T2 is added to the RESULT. | ||
+ | ; 4. If T1 is zero after the shift, the | ||
+ | ; multiplication is complete and the routine | ||
+ | ; returns. | ||
+ | ; 5. T2 is rotated left (multiplied by 2). | ||
+ | ; 6. Processing continues at step 2. | ||
+ | |||
+ | MULTIPLY: | ||
+ | LDA #$00 ; ZERO OUT THE RESULT AND Tn_H | ||
+ | STA RESULT_L | ||
+ | STA RESULT_H | ||
+ | STA T2_H | ||
+ | |||
+ | LDA M1 ; COPY M1 TO T1 | ||
+ | BEQ MULT_DONE | ||
+ | STA T1 | ||
+ | |||
+ | LDA M2 ; COPY M2 TO T2 | ||
+ | BEQ MULT_DONE | ||
+ | STA T2_L | ||
+ | |||
+ | JMP MULT_FIRST | ||
+ | |||
+ | MULT_NEXT: | ||
+ | ASL T2_L ; SHIFT T2 LEFT | ||
+ | ROL T2_H | ||
+ | |||
+ | MULT_FIRST: | ||
+ | LSR T1 ; SHIFT T1 RIGHT | ||
+ | BEQ MULT_LAST | ||
+ | BCC MULT_NEXT | ||
+ | |||
+ | LDA T2_L ; IF BIT0 WAS 1: | ||
+ | CLC ; T2 + RESULT-> RESULT | ||
+ | ADC RESULT_L | ||
+ | STA RESULT_L | ||
+ | LDA T2_H | ||
+ | ADC RESULT_H | ||
+ | STA RESULT_H | ||
+ | JMP MULT_NEXT | ||
+ | |||
+ | MULT_LAST: | ||
+ | LDA T2_L ; PRECEEDING BLOCK, BUT | ||
+ | CLC ; WE'VE AVOIDED A SECOND | ||
+ | ADC RESULT_L | ||
+ | STA RESULT_L | ||
+ | LDA T2_H ; PER LOOP ITERATION OR | ||
+ | ADC RESULT_H | ||
+ | STA RESULT_H | ||
+ | |||
+ | MULT_DONE: | ||
+ | RTS | ||
+ | </ | ||
+ | |||
+ | This code is available in the [[spo600: |
spo600/6502_math.1737491995.txt.gz · Last modified: 2025/01/21 20:39 by chris