📄 newfile 2ok.65s
字号:
;==============================================================================
; Coding Examples for the Students of AER201S
;==============================================================================
;
;<=== Note the semicolon is a comment indicator
;
.ORG $E000
SEI ; INITIALIZING THE STACK POINTER
LDX #$FF
TXS
;
LDX #$00 ; Initial delay to allow spurious Resets to
LDY #$00 ; to subside. At this point accept that this code
Delay DEX ; must appear at the beginning of every EPROM
BNE Delay ; that will ever be used for the 6502 project board.
DEY
BNE Delay
;
; We are now ready to try some simple examples
;
;
; 1) Add the numbers $65 and $27 and place the answer in the memory
; location 'ANSWER'.
;
; First we must assign the location to the label 'ANSWER'
;
ANSWER = $0000
;
; OK now we do the addition:
LDA #$65 ; Load the number (#) $65 into the accumulator.
CLC ; Clear the carry flag to prevent carries from a
; previous and unrelated computation.
ADC #$27 ; Add the number (#) $27, the result goes in the
; accumulator
STA ANSWER ; Store the result into the memory location ANSWER
;
; Remarks: Note that the # number sign preceded the numbers $65 and $27 to
; indicate that these were in fact CONSTANTS, NUMBERS. If the # sign were
; omitted, TASM would interpret LDA $65 to mean 'load the accumulator from
; the memory location $0065'.
; Looking back at the assignment of ANSWER, we could have said:
; ANSWER = $00. This, when used in the statement STA ANSWER would still
; be interpreted as referring to the memory location $0000 but it would
; allow the 6502 to use something called 'Zero Page' addressing, a faster
; method of accessing the memory locations between $0000-$00FF.
;
;
;
; 2) Subtract the number $27 from the number $65 and store the result in the
; memory location 'ANS2'.
;
ANS2 = $01 ; We will use zero page addressing to refer to ANS2
;
LDA #$65 ; Load the number (#) $65 into the accumulator
SEC ; Clear the C flag (used as the borrow flag in
; subtraction) to prevent borrows from a previous
; unrelated computation.
SBC #$27 ; Subtract the number (#) $27 from the accumulator
; the result will be in the accumulator.
STA ANS2 ; Store the result in the memory location 'ANS2'
;
; Remarks: Note that the carry or borrow flag has a inverse logic in the case
; of subtraction: You have to SEC set the carry flag to prevent a borrow.
;
;
;
; 3) Program a subroutine to turn on specific bits in on VIA 1, Port A which
; can be used to light LEDs to monitor program performance. We will
; assume that there are 8 LEDs connected to Port A.
;
; We must first initialize port A as an output port
;
; LDA #%11111111 ; All ones means all bits are outputs
STA $A003 ; $A003 is the address of VIA1 Port A, data
; direction register. This register determines
; whether a bit is input or output.
; LDA #%00000000 ;
STA $A001 ; $A001 is the address of VIA1 Port A I/O
; register. It is initialized to all zeros
; to mean all bits output 0 volts.
; Before we proceed with writing the subroutine we need to send the program
; to a point somewhere after the subroutine we are about to write. We will
; use a JuMP statement:
;
JMP Down_Past ; Down_Past is a program position label we will
; define later.
;
;
;
;
; ============================================================================
; It is a good idea to put these bars in to make subroutines obvious
; ============================================================================
;
; Ok know we need to have some Specifications for this subroutine:
;
; Subroutine Name: Show
; Input Registers: .A contains a '1' in the bit position that you want to
; have turned on
; Output Registers: None
;
Show ORA $A001 ; 'Show' against the margin indicates a program
; position label. ORA $A001 takes the bit pattern
; in .A and logically OR's it with the pattern of
; bits in memory location $A001, the VIA 1, Port A
; I/O register.
;
; Say $A001 contains the bits: %abcdefgh (a through h are unknown 0 or 1)
; and we or it with .A : OR %00001000
; -------------
; We will get: %abcd1fgh
;
; Because: 0 or 0 = 0, 1 or 0 = 1, 0 or 1 = 1, 1 or 1 = 1
; the following is true: u or 0 = u and u or 1 = 1
; where u is an unknown level.
;
STA $A001 ; Store the new bit levels back into the I/O Port
RTS ; Return from Subroutine
;
; Remarks: This subroutine can be called by setting specific bits in the .A
; register and calling the subroutine:
; LDA #%00000001 ; Set bit 0
; JSR Show ; Show this on the VIA port
;
; Subroutines can be nested IE one subroutine can call others. Care
; should be exercised when one subroutine calls itself because there are no
; 'local' variables in assembly language (unless you simulate them) since
; the memory in the 6502 is global to all programs or subroutines.
; Subroutines can significantly compact a program and can lend to readability
; of the code if properly documented.
;
;
;
Down_Past ; This is the program position label that marks where the
; JMP Down_Past goes to.
;
;
; 4) Now that we have done an output subroutine, lets do some comparisons and
; light leds to show the results. Check if ANSWER - ANS2 = 2*#$27.
;
RHS = $03 ; Stores the value of the right hand side of the equation
;
LDA ANSWER ; Calculate the RHS
SEC
SBC ANS2
STA RHS
;
LDA #$27 ; To calculate 2*#$27 you use #$27+#$27
CLC
ADC #$27 ; Got the LHS in the accumulator
;
CMP RHS
BNE Not_Equal ; Don't Show any LED's
;
; The equation is true, light LED connected to bit 0
; LDA #%00000001
JSR Show
;
Not_Equal
;
;
;
; 5) See if ANSWER and ANS2 have any bits in common; light LED 1 if they do.
;
LDA ANSWER
AND ANS2 ; AND Tests to see if a bit in both arguments is
; set. If it is the resulting bit is set, otherwise
; the resulting bit is cleared.
; If two arguments have no bits in common the result
; will have no bits set or will be zero. In this case
; the AND instruction will set the zero flag.
BEQ No_Bits ; The BEQ branches on result equal for comparisons
; or result zero for arithmetic and logical
; OpCodes.
; LDA #%00000010
JSR Show ; This turns on bit 1 if there were any bits in common
;
; There were no bits in common, the AND resulted in a Z=1, zero
No_Bits
;
;
;
; 6) See if ANSWER and ANS2 have bit #1 in common; light LED 2 if they do.
;
LDA ANSWER
; AND #%00000010 ; This picks off the value of bit 1. You can think
; of a 1 in a constant of an AND statement like a
; delta function that zeros picks off one value
; and zeros the rest of the domain. As a result
; ANDing with #%11111111 does not change a number.
AND ANS2 ; We know that the .A has all zeros except possibly
; bit 1. ANDing with ANS2 will result in zero
; unless bit 1 was set in both ANSWER and ANS2
BEQ Bit1_Not_Set ; If the result is Z=1, don't show LEDs
; LDA #%00000100 ; otherwise Show LED 2
JSR Show
;
Bit1_Not_Set
;
;
;
; 7) Do an endless loop to alternate the pattern of indicators now present
; on the LEDs with the binary representation of ANSWER.
;
Endless LDX $A001 ; Grab the present bit pattern
LDA ANSWER ; Grab the new bit pattern
STA $A001 ; Put the new pattern on the Port
STX ANSWER ; Put the old pattern into ANSWER
;
LDX #$00
LDY #$00
D1 DEX ; A double indexed wait loop to waste time
BNE D1
DEY
BNE D1
JMP Endless ; Next time the old bit pattern becomes the new
; by the way it was stored, rotating through
; the ANSWER==>.A==>Port==>.X==>ANSWER loop.
;
; The last entry in every program must set the reset vector to point
; to the beginning of the program. If there is an interrupt routine
; then the interrupt vector must be set as well. In this case there is
; only a main program.
;
.ORG $FFFC ; Set pointer to Reset Vector Location
.WORD $E000 ; Store $E000 as the reset vector
.END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -