Release Notes:
1.00 June 6, 2012: Initial Release.
1.01 June 12, 2012: Added MCU keypad and dip-switches (convenience) registers.
1.02 June 14, 2012: Added + capability for label expressions.
1.03 June 19, 2012: Now movable to the sdcard.
1.04 June 26, 2012: Added a simple built-in text editor (Edit within Menu).
1.05 June 27, 2012: Fixed editor window scrolling.
1.06 Aug. 1st,2012: Cleaned up code and samples.
1.07 Sept. 27,2012: Added analog input (light sensor).
1.08 Jan. 13, 2013: Full screen support for all resolutions up to 1280x800.
1.09 Mar. 22, 2013: Adapted for all screen resolutions up to 1920x1080 (Full-HD).
Support:
Author: Harry Konstas
Web site: http://sites.google.com/site/hkonstas/andmcu
Email: hkonstas@gmail.com
INTRODUCTION:
Welcome and thank you for your interest on the Android MCU Simulator!
The MCU simulator for Android OS runs Assembly language code similar to the 68705 MCU on a simulated on-screen prototype board.
Great for embedded applications hobbyists, students, teachers or anyone who likes to experiment with electronic Micro-controller prototype boards.
It's fun for learning assembly language too!
I hope you will enjoy AndMCU and have many hours of fun trying out assembly code snippets on this virtual prototype MCU board.
Please take a few minutes to read this documentation that will help you get started quickly and get the most out of this application.
SIMULATED HARDWARE FEATURES:
AndMCU simulates both hardware and software. The simulated hardware consists of the following components:
8-Bit CPU with 3x 8-bit bi-directional ports.
6 Digit segment display
16-character LCD display
2x 8-bit DIP Switches
2x 8 LED Bargraph displays
12-key keypad
1 piezo buzzer
External interrupt.
Timer and SWI interrupts
1 Analog input (light sensor)
You can use the 6-digit segment or the bargraph LED arrays to display binary 8-bit information.
You can flip the position of the DIP switches with your finger on the screen or use the .dipsw1/2 directives to setup the selection
programmatically (usefull on small displays where it's hard to do it with the finger).
The keypad is usefull for entering information for your running code, and the LCD panel can be used to display up to 16 characters.
The speed of the simulation is controlled by the .speed directive.
The higher the value, the less hardware simulation (display refresh rate) but more CPU simulation. Increase the speed if your code
does more calculations then hardware access, and decrease it if you need more frequent display refresh.
Please note that the speed of the simulator is intended for examining the results of the simulation (educational purpose).
(In other words, do not expect AndMCU to run as fast as a CPU 'emulator'!)
ASSEMBLER FEATURES:
The AndMCU built-in assembler is using a subset of the 68705 MCU instruction set.
It runs in a special, one-pass interpreted mode.
Here are some of the built-in assembler features:
Auto-run code at startup.
Adjust the CPU speed at runtime.
Step-by-step trace mode.
Setup the Dip switches programmatically.
Numerical and string data arrays.
Decimal and Hex numerical values.
Dump memory contents to file, beep or display values on the LCD for debugging.
Standard assembly language, subset instruction set of the 68705 MCU.
Please have a look at the provided samples in the '/sdcard/AndMCU' directory and the Assembly reference page from the menu
to get an idea on the Assembly language used by AndMCU.
HARDWARE-REQUIREMENTS:
Current version is designed for all screen resolutions up to 1920 x 1080 (Full-HD).
An SDCARD (internal or external) is absolutely required as your ASM files will be stored there for editing.
USAGE:
The first time you will run AndMCU, a new directory will be created in your SDCARD named '/SDCARD/AndMCU' along with a few sample
ASM files to get you started.
By default, AndMCU will ask you which file you would like to load at startup.. You can set the AUTORUN option in the preference
screen from within the menu, so that AndMCU runs automatically the file 'code.asm'.
There is a convenient but very primitive built-in text editor that you can use to quickly do simple edits on the fly but I recommend
the excellent and free Jota Text editor available in the Android Market for creating new files or any serious typing :-)
http://play.google.com/store/apps/details?id=jp.sblo.pandora.jota&hl=en
* Please make sure to use the 'Menu-Save' to save your code when using the built-in text editor, or use the 'back' button on your
device to cancel / abort editing. You can also use it in landscape mode.
From within the menus of the application, you can access the PCB board schematic, MCU memory map and block diagram.
There is also a built-in Assembly language reference page with the complete list of the supported opcodes.
Please have a look on these 4 reference pages as well the provided sample code to familiarize your self with the hardware and software MCU architecture.
The simulator has 2 modes: free-running and step-by-step trace. The LED on the right side of the LCD screen indicates the running MCU mode:
RED: The MCU simulation is on Standby (not running code).
YELLOW: The MCU is on trace mode. Tap on the LCD screen to advance 1 instruction at a time.
GREEN: The MCU is running. It is actually running on a separate thread in Android OS. You can set the speed of the CPU from within your code.
* The blue button on the left of the LCD is the external interrupt push-button.
Through the menu you can START and STOP and RESET the MCU, or load a different ASM file.
You will need an external text editor to create new ASM files. I highly recommend the excellent and free 'Jota Text editor' from the Android Market.
The ASM files are located at: '/sdcard/AndMCU' directory.
Please study the sample files that are provided to learn how to properly setup the MCU ports to interface the hardware components.
In the reference section there is a schematic diagram of the MCU board that will give you a good idea how the MCU is connected to
the hardware components of the PC-board.
The MCU memory map:
The CPU control registers are located at address 0-15.
Addresses 0-5 are used for the ports control registers.
The AN0 and AN1 registers (0x6 & 0x7) hold a 16-bit value of your device's light-sensor which is connected to the PC5 pin of the MCU.
AN0 holds the LSB value, and AN1 holds MSB. See the sensor.asm sample for details.
The AN2 & AN3 registers are reserved for a future version.
The timer control register holds the value for the timer interrupt (interrupt every #n of instructions).
The control register has 2 control bits:
Bit 0 : Timer interrupt control (1=enable)
Bit 1: External interrupt control (1=enable)
There are also 3 hidden registers for convenience (to avoid writing extra asm code for handling):
0xC = Keypad register holds value of pressed keypad button (0xf = no button)
0xD = DipSwitch1 register holds value of Dip Switch 1.
0xE = DipSwitch2 register holds value of Dip Switch 2.
RAM starts at address 16 (0x10) up to address 127 (0x07F).
ROM starts at address 128, there is no need to use a .ORG directive - the assembler automatically creates the
required Reset and interrupt vectors.
The Assembler syntax:
The built-in assembler uses a subset of the 68705 MCU instruction set.
From within the reference menu, you will find a detailed ASM reference table for all the MCU opcodes.
Comments can be followed after a semicolon (;) character, either at the beginning of the line or after the ASM instructions:
; This is a comment line
start: lda #5 ; in-line comment rts
Labels should be followed by 2-colon character (:)
For example:
start: jmp init ; jump to the init label nop nop rts init: clrx lda data,x ; read from data location inca ... ... data: .db 12,34,56,0 .ds "hello"
Immediate values (#) can be decimal, hexadecimal or labels:
PORTA equ 0x00
TEST equ PORTA+1 ; add a value to the TEST label..
TEST2 equ 10
lda #10 ; decimal
lda #$ff ; hexadecimal
lda #0x0f ; also hexadecimal
lda #test2 ; loads 10...
lda #test2+2 ; loads 12...
Direct (Memory) values can be decimal, hex or labels:
start:
lda PORTA ; label
lda TEST+1 ; add a value to the TEST label...
lda PORT,x ; indexed
sta 10 ; address 10 in decimal
sta 0xa ; also 10in hex
sta $0a ; again 10 in hex
...
...
The ASM directives:
.autorun
Run the loaded code automatically at startup.
.speed nn
Set the CPU speed programmatically (1-255). The higher the value, the more instructions per second are executed however
with less screen refreshes. You can use this directive many times anywhere in your code, to slow down when information is
displayed, or increase the speed for lenghtly calculations.
.traceon
.traceoff
Enable/disable the step-by-step trace mode.
This directive can be used many times anywhere you need tracing in your code.
When enabled, AndMCU will run the ASM code one instruction at a time.
You will need to tap on the LCD module to advance to the next instruction.
The RUN LED will turn yellow and the current instruction will be shown on the LCD module.
.dump
When a STOP instruction is encounterd, the execution will stop and Dump all memory and registers to 'dump.html' file.
You can open that file using your HTML browser. If you do not use the .dump directive, the execution will stop and the values
of the Accumulator, X-Register and Status flags will be shown on the LCD screen.
.dipsw1 nn
.dipsw2 nn
Setup the Dip-Switches programmatically anywhere on your program.
It's easier then doing it by hand on the screen!
label equ nn (or label = nn)
Assign a decimal or hex value to a label (8 bit).
For example, to assign the value 0x01 to a label named PORTC:
PORTS equ 0x00
PORTB equ PORTS+1 ; assign address value
init:
lda PORTB ; read PORTB
lda PORTS+1 ; also reads PORTB
...
...
.db 123,23,$0f,0x0f...
Create a byte array of numerical values separated by commas. You can use decimal, or hexadecimal values.
Maximum byte value is 255. Must be used at the end of your code.
.ds "string of text"
Create a byte array from a string of text. The string must be enclosed in double quotes.
The assembler automatically inserts a zero value byte in memory at the end of the string.
Must be used at the end of your code.
.lcd "message"
Display a message on the LCD at runtime.
.beep
Beep sound at runtime. Usefull to track if code is executed.
Can be placed many times and anywhere in the code.
Software Interrupts (SWI):
You must define your SWI routine in your code for the SWI to work.
You can mask (disable) interrupts if you set the Interrupt flag using the SEI opcode and enable them again using CLI.
A special IRQ: label is required to point to the SWI routine. This will instruct the assembler to automatically create the required Interrupt vectors for the MCU.
* The Accumulator, X-Register and Status register are automatically saved and restored during an interrupt.
Example:
; Interrupt routine for SWI
IRQ:
LDA #56
...
...
RTI ; return from interrupt
External Interrupts (blue push-button):
You must enable the external interrupt bit in the control register of the MCU and define your external interrupt routine in your code for the external interrupt to work.
You can mask (disable) interrupts if you set the Interrupt flag using the SEI opcode and enable them again using CLI.
A special EXTIRQ: label is required to point to the interrupt routine. This will instruct the assembler to automatically create the required Interrupt vectors for the MCU.
* The Accumulator, X-Register and Status register are automatically saved and restored during an interrupt.
Example:
; Interrupt routine for external IRQ
OPTION equ 0xb
bset 1,OPTION ; enable external interrupts
...
...
EXTIRQ:
LDA #56
...
...
RTI ; return from interrupt
Timer Interrupts:
You must enable the timer interrupt bit in the control register of the MCU, set the timer value in the timer control register and define your timer interrupt routine in your code for the timer interrupt to work.
You can mask (disable) interrupts if you set the Interrupt flag using the SEI opcode and enable them again using CLI.
A special TIMERIRQ: label is required to point to the interrupt routine. This will instruct the assembler to automatically create the required Interrupt vectors for the MCU.
* The Accumulator, X-Register and Status register are automatically saved and restored during an interrupt.
Example:
; Interrupt routine for timer IRQ
OPTION equ 0xb
TIMER equ 0xa
lda #50
sta TIMER ; IRQ every 50 instructions
bset 0,OPTION ; enable external interrupts
...
...
TIMERIRQ:
LDA #56
...
...
RTI ; return from interrupt
Assembler error codes:
When a syntax error is detected at runtime, the MCU will stop and an error code with the line of code will be displayed on the LCD.
The possible error code values are:
0= MCU is stopped.
1= Opcode not found
2= Label not found
3= Immediate value error.
4= Direct value error
5= equ value error.
6= IRQ vector not found (missing IRQ routine)
7= Directive error
8= STACK-OVERFLOW
EXTIRQ?= External IRQ routine not found.
TIMERIRQ= Timer IRQ routine not found.
SOME THEORY OF OPERATION:
1) I/O Ports
The MCU has 3 I/O ports, and like a real MCU, the ports can be programmed individually for input or output.
If you look at the schematic it will make sense why PORTA and PORTC should be programmed for OUTPUT, and PORTB for input.
The DDRx registers of the MCU are used to program the I/O mode. Setting a DDRx bit to one will program that pin for OUTPUT, and setting it at zero,
will program it as an input.
2) Chip select 7442
On the schematic you will notice the 7442 TTL chip. It's a binary to BCD decoder chip, and it is connected to the PORTC of the MCU.
This chip selects which hardware part you want to communicate with. For example, if you set PORTC to 2, the first digit from the left will be selected.
Once a component has been selected, you can output the data you want to send to the selected component through the PORTA.
The data will be 'latched' in the component.
And finally, you can 'unselect' all the components by sending a value higher then 10 to the PORTC.
3) LCD module
The LCD module uses 2 control pins: E/RW and CMD.
To interface to the LCD, first you program the pin E/WR to low (0) and send the character code through PORTA. For the next character you must
program the pin E/WR to high (1) and then low again with the next character to PORTA (negative pulse).
Once your characters are set, program the CMD (command) pin to low and use either the commands 0 to erase, or 1 to show through PORTA.
For more detailed information,please have a look at LCD sample in the AndMCU directory of your SDCARD.
If you don't want to write your own LCD routine, you can display a message on the LCD by using the .lcd "message" directive..
4) LED Segments (6-digits)
Simply select the wanted digit you want to interface with through PORTC, and send the display data through PORTA.
5) Bargraph displays
You can select the bargraph through PORTC and put the value to be displayed on PORTA.
6) Dip Switches
Like the bargraphs, select the Dip Switch through PORTC but read the switch selection through PORTB (on input mode of course).
You can also program the Dip switches position programmatically by using the .dipsw1 and .dipsw2 directives.
If you don't want to bother with the MCU ports you can cheat by accessing directly the value of the dip-switches from the hidden MCU registers
DIPSW1 and DIPSW2, addresses 0xd and 0xe:
DIPSW1 equ 0xd
DIPSW2 equ 0xe
lda DIPSW1 ; read dipsw1 value
ldx DIPSW2 ; read dipsw2 value
...
...
7) keypad
The keypad is also using PORTB for reading, and you should select the key again through PORTC.
If you don't want to bother writing your own keyboard routine, you can read directly the keypad value (faster) from the hidden MCU keypad register at address 0xC:
KEYREG equ 0xc
lda KEYREG ; read keypad (15= no key pressed)
...
....
8) Buzzer
As for the buzzer output, setting pin #4 of PORTC to '1' will sound the buzzer.
8) Light sensor (analog input)
The AN0 and AN1 registers hold a 16-bit value of your device's light-sensor which is connected to the PC5 pin of the MCU.
AN0 holds the LSB value, and AN1 holds MSB. See the sensor.asm sample for details.
ANREG0 equ 0x6
ANREG1 equ 0x7
lda ANREG0 ; read LSB light sensor value
ldx ANREG1 ; read MSB light sensor value
* PORTC Bits 6, and 7 are reserved for a futur version of AndMCU.
ASM DIRECTIVES
INHERENT
DIRECT
ARITHMETIC
LOGICAL
BRANCH
BIT MANIPULATION
* LEGEND
Some sample ASM code syntax:
; comment line .dump ;dump directive
.dipsw1 0x55 ;set dipsw1 to 0x55
.speed 50 ; Set CPU speed
.trace on ;trace enable
PORTS equ 0x0
PORTA equ PORTS+0
PORTB equ PORTS+1
start: lda #123 ;inline comment lda #$FF ;hex value lda #0xFF ;also hex value lda label lda label,x jmp start ;goto start jsr test
loop: bset 1,PORTB ;set bit#1
LDA DATA,X ;ignores case lda data,x jmp loop
test: bclr 7,PORTA
rts
.data: .db 23,45,$0f,0x4e,0 ;data bytes .ds "Hello world" ;data string