; Thumb translation Dr. Meier's DE10-Lite ARM test program
; Dr. Durant 2018-05-17 CE1921

; The 16-bit Thumb instructions generally set the status bits.
; We write the instructions as movs/subs/adds/ands etc., which allows the online
; shell-storm assembler to correctly assemble them. If we omit the S,
; the assembler creates 32b Thumb-2 instructions (which are neither ARM nor Thumb).
; The ARM7 TDMI documentation provided in class says that you can just write AND instead of ANDS,
; etc., but this applies to a pure Thumb or ARM+Thumb architecture assembler,
; such as ARMv4t, ARMv6-M, ARMv7-R, or ARMv7-M.
; It does not apply to (most or all?) Thumb-2-type (e.g., ARMv6T2) architecture assemblers.

.equ    SLIDE,0x000000f4
.equ    SEG7,0x000000fc
.equ    LED,0x000000f8

main:   MOVS R4,#4     ; R4 = memory address           2404
        MOVS R7,#0     ; temp = 0                      2700
        STR R7,[R4]    ; MEM[4] = 0 : init memory      6027
        MOVS R7,#SLIDE ; address of sliders            27f4 ; 8 LSB is 8b simmediate
        LDR R6,[R7]    ; i = n                         683e
        MOVS R5,#0     ; sum = 0                       2500
        CMP R6,#0      ; i=0?                          2e00
        BEQ print      ; if yes branch to print        d00a ; inst. count rel. to PC+4 (not +2)
loop:   ADDS R5,R6     ; sum = sum + i                 1975
        SUBS R6,#1     ; i = i - 1                     3e01
        CMP R6,#0      ;                               2e00
        BNE loop       ;                               d1fa
if:     MOVS R2,#0     ; creating FFFFFFE0             2200
        SUBS R2,#32    ; 0 - 32 = -32 = FFFFFFE0       3a20
        ANDS R2,R5     ;                               402a
        CMP R2,#0      ;                               2a00
        BEQ else       ; if (R5 > 32) MEM[4] = 1       d000
        MOVS R2,#1     ; set the 1                     2201
else:   STR R2,[R4]    ; memory[4] = either 1 or 0     6022
print:  MOVS R7,#SEG7  ; seg7 data reg address         27fc
        STR R5,[R7]    ; seg7 = sum                    603d
        MOVS R7,#LED   ; LED reg address               27f8
        LDR R3,[R4]    ; get stored memory value back  6823
        STR R3,[R7]    ; leds = mem[4]: LED0 on if >32 603b
done:   B done         ;                               e7fe

; Assessembly/disassembly examples for Thumb:
; MOVS R4,#4: 001 00 100 0000_0100 = 2404
; ADDS R5,R6: 00011 0 0 101 110 101 = 1975, format 2 allows 3 operands
;             00011 0 0 101 101 110 = 196e, ...other source order
;             010001 00 00 110 101 = 4435, format 5 also works
; Format 2 is 3-operand add/subtrack, format 5 is 2-operand more general ALU ops with high reg support.
; Formats 2 and 5 BOTH work for this ADDS instruction!
; Some assemblers will use MOV/ADD, but it is understood that these Thumb instructions set the flag bits!
; Thumb does not have versions of these instructions that do NOT set the flag bits.

; 3E01: format 3: 001 11(op=subs) 110(Rd) 00000001(offset) -> subs r6,#1
; D00A: format 16: conditional branch: 1101 0000(beq) 0x0A = offset (in int16[]) relative to PC+4

; http://shell-storm.org/online/Online-Assembler-and-Disassembler/

; shell-storm puts the machine code in the C language's (8-bit) character array format.
; To use it, you'll select big endian for ease of reading. It will give you results like:
; "\x24\x04\x27\x00" The \x indicates an 8-bit character specified in hexadecimal,
; so the instructions are 2404 2700.

; The shell-storm assembler actually gives "eb150506" for adds r5,r6.
; This is disassembled as the Thumb-2 instruction adds.w r5,r5,r6 by onlinedissassembler.
; This is NOT an ARM instruction, even though it looks similar (ARM add r5,r5,r6 is 0xE0855006).
; But onlinedissassembler does confirm that 0x1975 is just plain adds r5,r6.
; Shell-storm doesn't recognize the more efficient Thumb encoding in this case and instead uses Thumb-2.
