Line 46... |
Line 46... |
; http://www.gnu.org/licenses/gpl.html
|
; http://www.gnu.org/licenses/gpl.html
|
;
|
;
|
;
|
;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;
|
;
|
// #include "sys.i"
|
#include "sys.i"
|
sys.bus equ 0xc0000000
|
sys.bus equ 0xc0000000
|
sys.breaken equ 0x080
|
sys.breaken equ 0x080
|
sys.step equ 0x040
|
sys.step equ 0x040
|
sys.gie equ 0x020
|
sys.gie equ 0x020
|
sys.sleep equ 0x010
|
sys.sleep equ 0x010
|
sys.ccv equ 0x008
|
sys.ccv equ 0x008
|
sys.ccn equ 0x004
|
sys.ccn equ 0x004
|
sys.ccc equ 0x002
|
sys.ccc equ 0x002
|
sys.ccz equ 0x001
|
sys.ccz equ 0x001
|
|
sys.cctrap equ 0x200
|
sys.bu.pic equ 0x000
|
sys.bu.pic equ 0x000
|
sys.bus.wdt equ 0x001
|
sys.bus.wdt equ 0x001
|
sys.bus.cache equ 0x002
|
sys.bus.cache equ 0x002
|
sys.bus.ctrpic equ 0x003
|
sys.bus.ctrpic equ 0x003
|
sys.bus.tma equ 0x004
|
sys.bus.tma equ 0x004
|
Line 73... |
Line 74... |
sys.bus.utask equ 0x00c
|
sys.bus.utask equ 0x00c
|
sys.bus.upstl equ 0x00d
|
sys.bus.upstl equ 0x00d
|
sys.bus.uastl equ 0x00e
|
sys.bus.uastl equ 0x00e
|
sys.bus.ustl equ 0x00f
|
sys.bus.ustl equ 0x00f
|
#define DO_TEST_ASSEMBLER
|
#define DO_TEST_ASSEMBLER
|
|
#define BREAK_TEST
|
|
#define OVERFLOW_TEST
|
|
#define CARRY_TEST
|
|
#define LOOP_TEST
|
|
#define SHIFT_TEST
|
|
#define TRAP_TEST
|
|
#define MPY_TEST
|
|
// #define PUSH_TEST
|
test:
|
test:
|
#ifdef DO_TEST_ASSEMBLER
|
#ifdef DO_TEST_ASSEMBLER
|
; We start out by testing our assembler. We give it some instructions, which
|
; We start out by testing our assembler. We give it some instructions, which
|
; are then manually checked by disassembling/dumping the result and making
|
; are then manually checked by disassembling/dumping the result and making
|
; certain they match. This is not an automated test, but it is an important
|
; certain they match. This is not an automated test, but it is an important
|
; one.
|
; one.
|
noop
|
noop
|
bra continue_test_with_testable_instructions
|
bra continue_test_with_testable_instructions
|
break
|
break
|
wait
|
wait
|
|
break
|
busy
|
busy
|
rtu
|
rtu
|
continue_test_with_testable_instructions:
|
continue_test_with_testable_instructions:
|
; Now, let's place the assembler into a known state
|
; Now, let's place the assembler into a known state
|
clr r0
|
clr r0
|
Line 204... |
Line 214... |
bnz test_failure
|
bnz test_failure
|
lod junk_address(pc),r5 ; Test loads with pc-relative addressing
|
lod junk_address(pc),r5 ; Test loads with pc-relative addressing
|
lod junk_address(pc),r6
|
lod junk_address(pc),r6
|
cmp r5,r6
|
cmp r5,r6
|
bnz test_failure
|
bnz test_failure
|
; Now, let's test whether or not our LSR and carry flags work
|
|
ldi -1,r0 ; First test: shifting all the way should yield zero
|
|
lsr 32,r0
|
|
cmp 0,r0
|
|
bnz test_failure
|
|
ldi -1,r0 ; Second test: anything greater than zero should set
|
|
lsr 0,r0 ; the carry flag
|
|
bc test_failure
|
|
lsr 1,r0
|
|
tst sys.ccc,cc
|
|
bz test_failure
|
|
lsr 31,r0
|
|
tst sys.ccc,cc
|
|
bz test_failure
|
|
lsr 1,r0
|
|
bc test_failure
|
|
; Now repeat the above tests, looking to see whether or not ASR works
|
|
ldi -1,r0
|
|
asr 32,r0
|
|
cmp -1,r0
|
|
bnz test_failure
|
|
ldi -1,r0
|
|
asr 0,r0
|
|
bc test_failure
|
|
cmp -1,r0
|
|
bnz test_failure
|
|
asr 1,r0
|
|
tst sys.ccc,r14
|
|
bz test_failure
|
|
asr 30,r0
|
|
tst sys.ccc,r14
|
|
bz test_failure
|
|
#endif
|
#endif
|
|
|
#ifdef NOONE // Testing comments after ifdef
|
#ifdef NOONE // Testing comments after ifdef
|
#else ; After else
|
#else ; After else
|
#endif /* and after endif */
|
#endif /* and after endif */
|
|
|
|
#ifdef BREAK_TEST
|
|
breaktest:
|
|
bra breaksupervisor
|
|
breakuser:
|
|
clr r0
|
|
mov 1+r0,r1
|
|
mov 1+r1,r2
|
|
mov 1+r2,r3
|
|
break ; At address 0x0100097
|
|
mov 1+r4,r5
|
|
mov 1+r5,r6
|
|
clr cc
|
|
busy
|
|
breaksupervisor:
|
|
ldi -1,r0
|
|
mov breakuser(pc),upc
|
|
rtu ; Should just keep returning immediately
|
|
mov upc,r0
|
|
rtu
|
|
rtu
|
|
mov upc,r1
|
|
cmp r0,r1
|
|
bnz test_failure
|
|
#endif
|
|
|
|
#ifdef TRAP_TEST
|
|
traptest:
|
|
bra traptest_supervisor
|
|
busy
|
|
traptest_user:
|
|
trap 0
|
|
busy
|
|
traptest_supervisor:
|
|
mov traptest_user(pc),upc
|
|
rtu
|
|
mov cc,r0
|
|
tst sys.cctrap,r0
|
|
bz test_failure
|
|
#endif
|
|
|
testbench:
|
testbench:
|
// Let's build a software test bench.
|
// Let's build a software test bench.
|
ldi $c0000000h,r12 ; Set R12 to point to our peripheral address
|
ldi $c0000000h,r12 ; Set R12 to point to our peripheral address
|
mov r12,ur12
|
mov r12,ur12
|
mov test_start(pc),upc
|
mov test_start(pc),upc
|
ldi 0x8000ffff,r0 ; Clear interrupts, turn all vectors off
|
ldi 0x8000ffff,r0 ; Clear interrupts, turn all vectors off
|
sto r0,(r12)
|
sto r0,(r12)
|
rtu
|
rtu
|
mov ucc,r0
|
mov ucc,r0
|
tst -256,r0
|
cmp sys.cctrap,r0
|
bnz test_failure
|
bnz test_failure
|
halt
|
halt
|
// Go into an infinite loop if the trap fails
|
// Go into an infinite loop if the trap fails
|
// Permanent loop instruction -- a busy halt if you will
|
// Permanent loop instruction -- a busy halt if you will
|
test_failure:
|
test_failure:
|
Line 267... |
Line 286... |
; Test LDI to PC
|
; Test LDI to PC
|
; Some data registers
|
; Some data registers
|
test_data:
|
test_data:
|
.dat __here__+0x0100000+5
|
.dat __here__+0x0100000+5
|
test_start:
|
test_start:
|
ldi $0x0100,r11
|
ldi $0x01000,r11
|
lod test_data+pc,pc
|
lod test_data+pc,pc
|
clr r11
|
clr r11
|
noop
|
noop
|
cmp $0,r11
|
cmp $0,r11
|
trap.z r11
|
trap.z r11
|
add $1,r0
|
add $1,r0
|
add $1,r0
|
add $1,r0
|
|
|
|
#ifdef OVERFLOW_TEST
|
// Let's test whether overflow works
|
// Let's test whether overflow works
|
ldi $0x0200,r11
|
ldi $0x02000,r11
|
ldi $-1,r0
|
ldi $-1,r0
|
lsr $1,r0
|
lsr $1,r0
|
add $1,r0
|
add $1,r0
|
bv first_overflow_passes
|
bv first_overflow_passes
|
trap r11
|
trap r11
|
first_overflow_passes:
|
first_overflow_passes:
|
// Overflow set from subtraction
|
// Overflow set from subtraction
|
ldi $0x0300,r11
|
ldi $0x03000,r11
|
ldi $1,r0
|
ldi $1,r0
|
rol $31,r0 ; rol $31,r0
|
rol $31,r0 ; rol $31,r0
|
sub $1,r0
|
sub $1,r0
|
bv subtraction_overflow_passes
|
bv subtraction_overflow_passes
|
trap r11
|
trap r11
|
subtraction_overflow_passes:
|
subtraction_overflow_passes:
|
// Overflow set from LSR
|
// Overflow set from LSR
|
ldi $0x0400,r11
|
ldi $0x04000,r11
|
ldi $1,r0
|
ldi $1,r0
|
rol $31,r0 ; rol $31,r0
|
rol $31,r0 ; rol $31,r0
|
lsr $1,r0
|
lsr $1,r0
|
bv lsr_overflow_passes
|
bv lsr_overflow_passes
|
trap r11
|
trap r11
|
lsr_overflow_passes:
|
lsr_overflow_passes:
|
// Overflow set from LSL
|
// Overflow set from LSL
|
ldi $0x0500,r11
|
ldi $0x05000,r11
|
ldi $1,r0
|
ldi $1,r0
|
rol $30,r0
|
rol $30,r0
|
lsl $1,r0
|
lsl $1,r0
|
bv lsl_overflow_passes
|
bv lsl_overflow_passes
|
trap r11
|
trap r11
|
lsl_overflow_passes:
|
lsl_overflow_passes:
|
// Overflow set from LSL, negative to positive
|
// Overflow set from LSL, negative to positive
|
ldi $0x0600,r11
|
ldi $0x06000,r11
|
ldi $1,r0
|
ldi $1,r0
|
rol $31,r0
|
rol $31,r0
|
lsl $1,r0
|
lsl $1,r0
|
bv second_lsl_overflow_passes
|
bv second_lsl_overflow_passes
|
trap r11
|
trap r11
|
|
#endif // OVERFLOW_TEST
|
|
#ifdef CARRY_TEST
|
second_lsl_overflow_passes:
|
second_lsl_overflow_passes:
|
// Test carry
|
// Test carry
|
ldi $0x0700,r11
|
ldi $0x07000,r11
|
ldi $-1,r0
|
ldi $-1,r0
|
add $1,r0
|
add $1,r0
|
tst $2,cc
|
tst $2,cc
|
trap.z r11
|
trap.z r11
|
// and carry from subtraction
|
// and carry from subtraction
|
ldi $0x0800,r11
|
ldi $0x08000,r11
|
|
clr r0
|
sub $1,r0
|
sub $1,r0
|
tst $2,cc
|
tst $2,cc
|
trap.z r11
|
trap.z r11
|
|
#endif
|
|
|
|
#ifdef LOOP_TEST
|
|
|
// Let's try a loop: for i=0; i<5; i++)
|
// Let's try a loop: for i=0; i<5; i++)
|
// We'll use R0=i, Immediates for 5
|
// We'll use R0=i, Immediates for 5
|
ldi $0x0800,r11
|
ldi $0x09000,r11
|
clr r0
|
clr r0
|
for_loop:
|
for_loop:
|
noop
|
noop
|
add $1,r0
|
add $1,r0
|
cmp $5,r0
|
cmp $5,r0
|
Line 344... |
Line 370... |
// implement, and this one is no different: 2 loop instructions
|
// implement, and this one is no different: 2 loop instructions
|
// (minus setup instructions) vs 3 from before.
|
// (minus setup instructions) vs 3 from before.
|
// R0 = 5; (from before)
|
// R0 = 5; (from before)
|
// do {
|
// do {
|
// } while (R0 > 0);
|
// } while (R0 > 0);
|
ldi $0x0900,r11
|
ldi $0x0a000,r11
|
bgt_loop:
|
bgt_loop:
|
noop
|
noop
|
sub $1,r0
|
sub $1,r0
|
bgt bgt_loop
|
bgt bgt_loop
|
|
|
Line 366... |
Line 392... |
// Let's try the reverse loop again, only this time we'll store our
|
// Let's try the reverse loop again, only this time we'll store our
|
// loop variable in memory.
|
// loop variable in memory.
|
// R0 = 5; (from before)
|
// R0 = 5; (from before)
|
// do {
|
// do {
|
// } while (R0 > 0);
|
// } while (R0 > 0);
|
ldi $0x0a00,r11
|
ldi $0x0b000,r11
|
bra mem_loop_test
|
bra mem_loop_test
|
loop_var:
|
loop_var:
|
.dat 0
|
.dat 0
|
mem_loop_test:
|
mem_loop_test:
|
mov loop_var(pc),r1
|
mov loop_var(pc),r1
|
Line 384... |
Line 410... |
sub $1,r0
|
sub $1,r0
|
sto r0,(r1)
|
sto r0,(r1)
|
bgt mem_loop
|
bgt mem_loop
|
cmp $5,r2
|
cmp $5,r2
|
trap.ne r11
|
trap.ne r11
|
|
#endif
|
|
|
|
#ifdef SHIFT_TEST
|
|
; Now, let's test whether or not our LSR and carry flags work
|
|
ldi $0x0c000,r11
|
|
ldi -1,r0 ; First test: shifting all the way should yield zero
|
|
lsr 32,r0
|
|
cmp 0,r0
|
|
bnz test_failure
|
|
ldi -1,r0 ; Second test: anything greater than zero should set
|
|
lsr 0,r0 ; the carry flag
|
|
bc test_failure
|
|
lsr 1,r0
|
|
tst sys.ccc,cc ; FAILS HERE!!! @0x010007c
|
|
bz test_failure
|
|
lsr 31,r0
|
|
tst sys.ccc,cc
|
|
bz test_failure
|
|
lsr 1,r0
|
|
bc test_failure
|
|
; Now repeat the above tests, looking to see whether or not ASR works
|
|
ldi -1,r0
|
|
asr 32,r0
|
|
cmp -1,r0
|
|
bnz test_failure
|
|
ldi -1,r0
|
|
asr 0,r0
|
|
bc test_failure
|
|
cmp -1,r0
|
|
bnz test_failure
|
|
asr 1,r0
|
|
tst sys.ccc,r14
|
|
bz test_failure
|
|
asr 30,r0
|
|
tst sys.ccc,r14
|
|
bz test_failure
|
|
|
// Let's test whether LSL works
|
// Let's test whether LSL works
|
ldi $0x0b00,r11
|
|
ldi 0x035,r2
|
ldi 0x035,r2
|
lsl 8,r2
|
lsl 8,r2
|
ldi 0x03500,r1
|
ldi 0x03500,r1
|
cmp r2,r1
|
cmp r2,r1
|
trap.ne r11
|
trap.ne r11
|
ldi 0x074,r0
|
ldi 0x074,r0
|
and 0x0ff,r0
|
and 0x0ff,r0
|
or r0,r2
|
or r0,r2
|
cmp 0x03574,r2
|
cmp 0x03574,r2
|
trap.ne r11
|
trap.ne r11
|
|
#endif
|
|
|
|
#ifdef MPY_TEST
|
|
|
|
// We have two multiply instructions. Let's see if those work
|
|
ldi $0x0d000,r11 // Mark our test
|
|
ldi 23171,r0 // = sqrt(2)/2 * 32768
|
|
mpyu r0,r0 // Should = 2/4 * 2^30 = 2^29 or thereabouts
|
|
ldi 536895241,r2
|
|
cmp r0,r2
|
|
trap.ne r11
|
|
ldi 0x0ffff,r0
|
|
mpyu r0,r0
|
|
ldi 0xfffe0001,r1
|
|
cmp r1,r0
|
|
trap.ne r11
|
|
ldi 0x08001,r0
|
|
ldi 0x07fff,r1
|
|
mpys r0,r1 // FAILS: result is 0x008001 ??? (pipeline prob)
|
|
ldi 0x3fff0001,r2
|
|
neg r2
|
|
cmp r2,r1 // @0x010011c
|
|
trap.ne r11 //TRAP FAILS TO TRIGGER ????? (R2=0x0c000ffff,R1=0x0008001 -- did mpy even happen?)
|
|
mpys r0,r0 // FAILS: result is 0x40010001
|
|
ldi 0x3fff0001,r2
|
|
cmp r2,r0
|
|
trap.ne r11 // TRAP FAILS TO TRIGGER AGAIN
|
|
ldi 0x08000,r0
|
|
mpys r0,r0 // R0 now equals 0x40000000
|
|
ldi 0x40000000,r1
|
|
cmp r0,r1
|
|
trap.ne r11
|
|
#endif
|
|
|
// Return success / Test the trap interrupt
|
// Return success / Test the trap interrupt
|
clr r11
|
clr r11
|
trap r11
|
trap r11
|
noop
|
noop
|