6803 Assembly Language Programming in TRS80 MC10
6803 Assembly Language Programming in TRS80 MC10
6803 Assembly Language Programming in TRS80 MC10
Video/Sound
$9000-$BFFF
Control
15 8 7 0
D
15 0
X
15 0
S
15 0
PC
7 0
CCR 1 1 H I N Z V C
Accumulator
A B
15 8 7 0
D
15 0
You can also add a constant positive 8-bit offset to it and compare it
with other 16-bit values.
6803 Registers
15 0
PC
CCR 1 1 H I N Z V C
65
66
67
255
0
Tutorial #3 and #4
Addition
aba beq bra daa jmp mul rol staa tst
abx bne brn dec jsr rola stab tsta
adca bcc deca neg rolb std tstb
adcb bcs cba decb ldaa nega ror sts
adda bhi clc des ldab negb rora stx wai
addb bhs cli dex ldd nop rorb suba
addd blo clr lds rti subb
anda bls clra eora ldx oraa rts subd
andb bge clrb eorb lsl orab swi
asr bgt clv lsla sba
asra ble cmpa inc lslb psha sbca tab
asrb blt cmpb inca lsld pshb sbcb tap
bmi cpx incb lsr pshx sec tba
bita bpl com ins lsra pula sei tpa
bitb bvc coma inx lsrb pulb sev tsx
bsr bvs comb lsrd pulx txs
Unsigned Addition
• Addition shares the same “rollover”
properties as incrementing.
• You may add values to the A, B, or D
accumulators (adda, addb, addd)
• You can add to the contents of the A
register by the contents of the B (aba).
• You can add the B register (unsigned) to
the contents of the X register (abx)
Tutorial #3 – unsigned addition
Tutorial #4 Signed Addition
• The “rollover” property can be used to
construct negative numbers.
• We will first discuss an odometer which
rolls over at 1000000 miles.
• We’ll then apply this to our 8-bit and 16-bit
accumulators which rollover at 256 and
65536.
Odometer Example
• Consider an old
fashioned odometer
that goes from
000000 to 999999.
• If you drive exactly
1000000, 2000000,
3000000 or any
multiple of 1000000
9 99 9 9 9
miles, the odometer 0 00 0 0 0
will go back to
000000.
Odometer Example
• If your odometer is at,
say, 83014 miles, and
you drive exactly
1000000 miles, then
the odometer will still
read 83014.
083014
+1000000 miles
083014
Odometer Example
• If your odometer is at, 083014
say, 83014 miles, and +999999
083013
you drive exactly
999999 miles, then
the odometer will read X
+999999
read 83013. X-1
• Note that adding
X
999999 is the same -1
X-1
as adding -1.
Odometer Example
• If your odometer is at, 083014
say, 83014 miles, and +999998
083012
you drive exactly
999998 miles, then
the odometer will read X
+999998
read 83012. X-2
• Note that adding
X
999998 is the same -2
X-2
as adding -2.
Odometer Example
• This suggests the following relationship:
– X = 1000000 – X
• Thus if your “odometer” only has positive
numbers, you can use the “rollover” property to
find the equivalent negative number.
Odometer Example
• Let’s say your odometer is 999998
at 999998 miles. If you + 5
000003
drive 5 miles, you’ll end up
with a reading of 000003
miles.
-2
• Note the equivalency again + 5
3
of 999998 = -2
8-bit Odometer
• A single byte roll-over occurs at 256.
• Thus,
-X = 256 – X (single-byte)
• By convention, numbers 0, 1, 2, …,127 are
considered “positive”
• Numbers 128, 129, 130, …, 253, 254, 255 are
considered “negative” and correspond to values
-128, -127, -126, …, -3, -2, -1.
• Note that +128 cannot be represented with this
convention, but -128 can.
8-bit Negation Instructions
• You can negate the value of either the A or
B register (nega, negb)
• You can negate an address
ldaa #10 ; A holds 10
nega ; A holds -10 (246 = 256-10)
neg 16384 ;negate first screen char
neg ,X ; negate what X points to
16-bit Odometer
• A double byte roll-over occurs at 65536.
• Thus,
-X = 65536 – X (double-byte)
• By convention, numbers 0, 1, 2, …, 32767 are
considered “positive”
• Numbers 32768, 32769, 32770, …, 65533, 65534,
65535 are considered “negative” and correspond to
values -32768, -32767, -32766, …, -3, -2, -1.
• Note that -32768 is in this set, but that +32768 cannot
be.
• Sadly, there is no 16-bit negation instruction
Signed arithmetic
Like driving the car, addition and
subtraction with rollover don’t really care if
you consider your numbers as signed or
unsigned. The computer will blindly
increment or decrement its “internal
odometer” the specified number of times,
and leave you with the result, which you
can use either as signed or unsigned
depending on your needs.
Negative Operands
• The TASM compiler will gladly accept
negative numbers to instructions that take
immediate operands.
• It will automatically convert them to their
‘unsigned’ equivalents depending on
whether the particular instruction expects
a 8-bit or 16-bit operand.
• ldaa #-1 -> ldaa #255
• addd #-3 -> addd #65533
Example #4 - Signed Addition
Tutorial #5
Subtraction
aba beq bra daa jmp mul rol staa tst
abx bne brn dec jsr rola stab tsta
adca bcc deca neg rolb std tstb
adcb bcs cba decb ldaa nega ror sts
adda bhi clc des ldab negb rora stx wai
addb bhs cli dex ldd nop rorb suba
addd blo clr lds rti subb
anda bls clra eora ldx oraa rts subd
andb bge clrb eorb lsl orab swi
asr bgt clv lsla sba
asra ble cmpa inc lslb psha sbca tab
asrb blt cmpb inca lsld pshb sbcb tap
bmi cpx incb lsr pshx sec tba
bita bpl com ins lsra pula sei tpa
bitb bvc coma inx lsrb pulb sev tsx
bsr bvs comb lsrd pulx txs
Subtraction
• Subtraction shares the same “rollover”
properties as decrementing.
• You may subtract
– values from the A, B, or D accumulators (suba, subb,
subd)
– the contents of the A register by the contents of the B.
(sba)
• Unfortunately, there is no corresponding sbx
instruction that subtracts the B register from the
X.
Example #5
Subtraction
Tutorial #6
Branch Instructions
aba beq bra daa jmp mul rol staa tst
abx bne brn dec jsr rola stab tsta
adca bcc deca neg rolb std tstb
adcb bcs cba decb ldaa nega ror sts
adda bhi clc des ldab negb rora stx wai
addb bhs cli dex ldd nop rorb suba
addd blo clr lds rti subb
anda bls clra eora ldx oraa rts subd
andb bge clrb eorb lsl orab swi
asr bgt clv lsla sba
asra ble cmpa inc lslb psha sbca tab
asrb blt cmpb inca lsld pshb sbcb tap
bmi cpx incb lsr pshx sec tba
bita bpl com ins lsra pula sei tpa
bitb bvc coma inx lsrb pulb sev tsx
bsr bvs comb lsrd pulx txs
Condition Codes
for Addition and Subtraction
• The “Z” bit is set when the result is zero
• The “N” bit is set when the result is
“negative”
• The “C” bit is set when the operation rolls
through zero.
• The “V” bit is set when the operation rolls
through 32768.
Comparison
• Comparison sets condition codes exactly like
subtraction, except that the result is discarded
and not stored back in the registers.
• You may compare
– the values from the A or B accumulators (cmpa,
cmpb)
– the contents of the A register to the contents of the B
(cba)
– The value of the X register (cpx)
• Unfortunately, you can’t compare the value of
the D register (but you may subtract it).
Branch Instructions
• Usually performed after subtraction or
comparing two numbers
• Branches can reach only a small distance
from the location of the next instruction (up
to 127 bytes ahead or 128 bytes behind)
• Larger branches require an explicit,
unconditional, jump to memory (jmp)
Generic Branch Opcodes
• bra – branch always
• brn – branch never*
• beq – branch if equal to zero (Z=1)
• bne – branch if not equal to zero (Z=0)
• bmi – branch if minus (N=1)
• bpl – branch if plus or zero (N=0)
• bcs – branch if carry set (C=1)
• bcc – branch if carry cleared (C=0)
• bvs – branch if overflow set (V=1)
• bvc – branch if overflow cleared (V=0)
5
Example: is “L” pressed?
bits to inspect (write to 2) 0 1 2 3 4 5 6 7
0
1
2
corresponding bit
3
(read from 49151)
4
5
lsl C 0 ´2
lsr 0 C ÷2
Arithmetic Shift Right
• A quick way of dividing a signed number by 2.
• You can shift the A or B accumulator or memory
right by 1 bit. (asra, asrb, asr)
• The “sign” bit is left unchanged, and the
remaining bit is shifted into the carry.
• Signed multiplication by 2 can be done using the
lsl instructions
asr C ÷2
Rotating through the carry
• You can shift the A or B accumulator or
memory left/right by 1 bit.
(rola, rolb, rol; rora, rorb, ror)
• The carry is shifted in, and the remaining
bit is shifted into the carry.
rol C
ror C
Keyboard
Strobe
Example
Video Modes
• The MC6847 is capable of two major
modes of execution
– Major Mode 1:
A fully-interchangeable 32x16 character
format
– Major mode 2:
A dedicated graphics mode
Video Control
49151 7 6 5 4 3 2 1 0
($BFFF)
Sound CSS A/G GM0 GM1 GM2 N/C N/C
• The MC6847 INT/EXT pin is physically tied to the GM2 pin. INT/EXT
$4000-$41FF $4000-$41FF
16384-16895 16384-16895
$BFFF←$00 $BFFF←$40
POKE 49151, 0 POKE 49151,64
$4000-$41FF $4000-$41FF
16384-16895 16384-16895
$BFFF←$0C $BFFF←$4C
POKE 49151,12 POKE 49151,74
Major Mode 2
• Since the CSS pin is globally settable only one palette at a time is displayed on-screen for
the graphics modes.
– Resolution graphics modes: green/dark green or buff/black
– Color graphics modes: green-yellow-blue-red or buff-cyan-magenta-orange
• The MC6847 would otherwise allow you to switch between these color schemes horizontally
every eight cells (resolution graphics) or four cells (color graphics)
Major Mode 2
• The on-board Video RAM
for the MC-10 is 4K in size
(12 bit address: $4000-
$4FFF).
• Thus only 12 of the 13
address lines were wired to
the MC6847. (DA12 is
unconnected)
• CG6 and RG6 will paint
data from $4000 - $47FF
instead of $5000 - $57FF.
Major Mode 2
store at $BFFF (49151)
RG1 128x64 RG2 128x96
$4000-$43FF $4000-$45FF
16384-17407 16384-17919
$BFFF←$30 $BFFF←$38
POKE 49151,48
POKE 49151,56
$4000-$4BFF $4000-$4FFF
16384-19455 16384-20479
$BFFF←$34 $BFFF←$3C
POKE 49151,52 POKE 49151,60
Major Mode 2
store at $BFFF (49151)
RG1 128x64 RG2 128x96
$4000-$43FF $4000-$45FF
16384-17407 16384-17919
$BFFF←$70 $BFFF←$78
POKE 49151,112
POKE 49151,120
$4000-$4BFF $4000-$4FFF
16384-19455 16384-20479
$BFFF←$74 $BFFF←$7C
POKE 49151,116 POKE 49151,124
Major Mode 2
store at $BFFF (49151)
CG1 64x64 49151 CG2 128x64
($BFFF)
$4000-$43FF $4000-$47FF
16384-17407 16384-18431
$BFFF←$20 $BFFF←$28
POKE 49151,32 POKE 49151,40
$4000-$4BFF $4000-$4FFF
16384-19455 16384-20479
$BFFF←$24 $BFFF←$2C
POKE 49151,36 POKE 49151,44
Major Mode 2
store at $BFFF (49151)
CG1 64x64 CG2 128x64
$4000-$43FF $4000-$47FF
16384-17407 16384-18431
$BFFF←$60 $BFFF←$68
POKE 49151,96 POKE 49151,104
$4000-$4BFF $4000-$4FFF
16384-19455 16384-20479
$BFFF←$64 $BFFF←$6C
POKE 49151,100 POKE 49151,108
Rotating the screen
Tutorial #9
Multi-byte math
aba beq bra daa jmp mul rol staa tst
abx bne brn dec jsr rola stab tsta
adca bcc deca neg rolb std tstb
adcb bcs cba decb ldaa nega ror sts
adda bhi clc des ldab negb rora stx wai
addb bhs cli dex ldd nop rorb suba
addd blo clr lds rti subb
anda bls clra eora ldx oraa rts subd
andb bge clrb eorb lsl orab swi
asr bgt clv lsla sba
asra ble cmpa inc lslb psha sbca tab
asrb blt cmpb inca lsld pshb sbcb tap
bmi cpx incb lsr pshx sec tba
bita bpl com ins lsra pula sei tpa
bitb bvc coma inx lsrb pulb sev tsx
bsr bvs comb lsrd pulx txs
Adding with Carry
• The add with carry instructions (adca,
adcb) will add the A or B register with the
carry bit.
• Since the carry is set when the result of an
addition instruction doesn’t fit in 8 or 16
bits, you can use the adc instructions to
continue adding the larger bytes.
Adding with Carry
Byte_a3 Byte_a2 Byte_a1 Byte_a0
Byte_b3 Byte_b2 Byte_b1 Byte_b0
S top
S top
byte2
S byte1 byte1
top
S top
byte2 S top
byte1 byte1 S
top
S
0,X Top (X)
1,X
2,X
3,X
4,X
…
There is no direct way to transfer
between the X and D registers
• You can push and pull the values of the X and D
registers on the stack to load between them:
Transfer X to D:
pshx ;put X on stack
pula ;load A with X’s high byte
pulb ;load B with X’s low byte
Transfer D to X:
pshb ;put low-byte on stack
psha ;put high-byte on stack
pulx ;load X from stack
Transferring D to X
pshb psha pulx
S top
S top
A
B B S
top
S top
X (high)
X (low)
S X (low) top S
top