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:41] – [6502 Math] 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 [[spo600: | + | The [[6502]] processor is limited to very simple math operations, and various [[spo600: |
| ==== 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.1737492105.txt.gz · Last modified: 2025/01/21 20:41 by chris
