OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [test.S] - Diff between revs 2 and 13

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
; Filename:     test.S
; Filename:     test.S
;
;
; Project:      Zip CPU -- a small, lightweight, RISC CPU soft core
; Project:      Zip CPU -- a small, lightweight, RISC CPU soft core
;
;
; Purpose:      A disorganized test, just showing some initial operation of
; Purpose:      A disorganized test, just showing some initial operation of
;               the CPU.  As a disorganized test, it doesn't prove anything
;               the CPU.  As a disorganized test, it doesn't prove anything
;               beyond the generic operation of the CPU.
;               beyond the generic operation of the CPU.
;
;
; Status:       As of July, 2015, the assembler isn't sophisticated enough
; Status:       As of August, 2015, this file assembles, builds, and passes
;               to handle the address resolution needed to assemble this file.
;               all of its tests in the Verilator simulator.
;
;
; Creator:      Dan Gisselquist, Ph.D.
; Creator:      Dan Gisselquist, Ph.D.
;               Gisselquist Tecnology, LLC
;               Gisselquist Tecnology, LLC
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
; Copyright (C) 2015, Gisselquist Technology, LLC
; Copyright (C) 2015, Gisselquist Technology, LLC
;
;
; This program is free software (firmware): you can redistribute it and/or
; This program is free software (firmware): you can redistribute it and/or
; modify it under the terms of  the GNU General Public License as published
; modify it under the terms of  the GNU General Public License as published
; by the Free Software Foundation, either version 3 of the License, or (at
; by the Free Software Foundation, either version 3 of the License, or (at
; your option) any later version.
; your option) any later version.
;
;
; This program is distributed in the hope that it will be useful, but WITHOUT
; This program is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
; for more details.
; for more details.
;
;
; License:      GPL, v3, as defined and found on www.gnu.org,
; License:      GPL, v3, as defined and found on www.gnu.org,
;               http://www.gnu.org/licenses/gpl.html
;               http://www.gnu.org/licenses/gpl.html
;
;
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
 
        sys.bus         equ     0xc0000000
 
        sys.breaken     equ     0x080
 
        sys.step        equ     0x040
 
        sys.gie         equ     0x020
 
        sys.sleep       equ     0x010
 
        sys.ccv         equ     0x008
 
        sys.ccn         equ     0x004
 
        sys.ccc         equ     0x002
 
        sys.ccz         equ     0x001
 
        sys.bu.pic      equ     0x000
 
        sys.bus.wdt     equ     0x001
 
        sys.bus.cache   equ     0x002
 
        sys.bus.ctrpic  equ     0x003
 
        sys.bus.tma     equ     0x004
 
        sys.bus.tmb     equ     0x005
 
        sys.bus.tmc     equ     0x006
 
        sys.bus.jiffies equ     0x007
 
        sys.bus.mtask   equ     0x008
 
        sys.bus.mpstl   equ     0x009
 
        sys.bus.mastl   equ     0x00a
 
        sys.bus.mstl    equ     0x00b
 
        sys.bus.utask   equ     0x00c
 
        sys.bus.upstl   equ     0x00d
 
        sys.bus.uastl   equ     0x00e
 
        sys.bus.ustl    equ     0x00f
 
#define DO_TEST_ASSEMBLER
test:
test:
 
#ifdef  DO_TEST_ASSEMBLER
 
; We start out by testing our assembler.  We give it some instructions, which
 
; 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
 
; one.
 
        noop
 
        bra     continue_test_with_testable_instructions
 
        break
 
        wait
 
        busy
 
        rtu
 
continue_test_with_testable_instructions:
 
        ; Now, let's place the assembler into a known state
        clr     r0
        clr     r0
        mov     r0,r1
        clr     r1
 
        clr     r2
 
        clr     r3
 
        clr     r4
 
        clr     r5
 
        clr     r6
 
        clr     r7
 
        clr     r9
 
        clr     r10
 
        clr     r11
 
        clr     r12
 
        clr     r13
 
        ; Don't clear the CC register
 
        ; Don't clear the SP register
 
        ; And repeat for the user registers
 
        mov     R0,uR0
 
        mov     R0,uR1
 
        mov     R0,uR2
 
        mov     R0,uR3
 
        mov     R0,uR4
 
        mov     R0,uR5
 
        mov     R0,uR6
 
        mov     R0,uR7
 
        mov     R0,uR8
 
        mov     R0,uR9
 
        mov     R0,uR10
 
        mov     R0,uR11
 
        mov     R0,uR12
 
        mov     R0,uR13
 
        mov     R0,uCC
 
        ; Don't clear the user PC register
 
        ; Now, let's try loading some constants into registers
 
dead_beef       equ     0xdeadbeef
 
        ldi     0x0dead,r5
 
        ldi     0x0beef,r6
 
        ldi     0xdeadbeef,r7
 
        ldihi   0xdead, r8
 
        ldilo   0xbeef, r8
 
        ldi     dead_beef,r9
 
        cmp     r5,r6
 
        bz      test_failure
 
        cmp     r7,r8
 
        bnz     test_failure
 
        ldi     $deadbeefh,r7   ; Try loading with the $[HEX]h mneumonic
 
        cmp     r7,r8
 
        bnz     test_failure
 
        cmp     r7,r9
 
        bnz     test_failure
 
        bra     skip_dead_beef
 
dead_beef.base:
 
        word    0
 
        fill    5,dead_beef
 
        word    0
 
dead_beef.zero          equ     0
 
dead_beef.values        equ     1
 
skip_dead_beef:
 
        lod     dead_beef.base(pc),r10  ; Should load a zero here
 
        cmp     r10,r11                 ; r11 should still be zero from init abv
 
        bnz     test_failure
 
        mov     dead_beef.base(pc),r10  ; Now, let's get the address
 
        lod     dead_beef.values(r10),r10       ; r10 now equals 0xdeadbeef
 
        cmp     r10,r9
 
        bnz     test_failure
 
 
 
; Test whether or not we can properly decode OCTAL values
 
        clr     r0      ; Re-clear our register set first
 
        clr     r1
 
        clr     r2
 
        clr     r3
 
        clr     r4
 
        clr     r5
 
        clr     r6
 
        clr     r7
 
        clr     r9
 
        clr     r10
 
        clr     r11
 
        clr     r12
 
        clr     r13
 
        ;
 
        ldi     $024o,r0
 
        ldi     $20,r1
 
        cmp     r0,r1
 
        bnz     test_failure
 
        ldi     $024,r0
 
        cmp     r0,r1
 
        bnz     test_failure
 
        clr     r0
 
        clr     r1
        mov     $1+r0,r2
        mov     $1+r0,r2
        mov     $2+r0,r3
        mov     $2+r0,r3
        mov     $22h+r0,r4
        mov     $22h+r0,r4
        mov     $377h+r0,ur5
        mov     $377h+r0,ur5
        noop
        noop
        nop
        nop
        add     r2,r0
        add     r2,r0
        add     $32,r0
        add     $32,r0
        add     $-33,r0
        add     $-33,r0
 
        bnz     test_failure
        not.z   r0
        not.z   r0
 
        bge     test_failure
 
junk_address:
        clrf    r0
        clrf    r0
 
        bnz     test_failure
        ldi     $5,r1
        ldi     $5,r1
        cmp     $0+r0,r1
        cmp     $0+r0,r1
        not.lt  r0
        not.lt  r0
        not.ge  r1
        not.ge  r1
        lod     $-7+pc,r2
        mov     junk_address(pc),r2     ; Test pc-relative addressing
        ldihi   $deadh,r3
        mov     junk_address(pc),r3
        ldihi   $beefh,r3
        cmp     r2,r3
 
        bnz     test_failure
 
        lod     junk_address(pc),r5     ; Test loads with pc-relative addressing
 
        lod     junk_address(pc),r6
 
        cmp     r5,r6
 
        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
 
 
 
#ifdef  NOONE // Testing comments after ifdef
 
#else   ; After else
 
#endif /* and after endif */
testbench:
testbench:
        // Let's build a software test bench.
        // Let's build a software test bench.
        clr     r12     ; R12 will point to our peripherals
        ldi     $c0000000h,r12  ; Set R12 to point to our peripheral address
        ldihi   $c000h,r12
 
        mov     r12,ur12
        mov     r12,ur12
        mov     test_start,upc
        mov     test_start(pc),upc
        ldihi   $8001,r0
        ldi     0x8000ffff,r0   ; Clear interrupts, turn all vectors off
        ldilo   $-1,r0
        sto     r0,(r12)
        sto     r0,$1+r12
 
        rtu
        rtu
        lod     r12,r0
        mov     ucc,r0
        cmp     $0,r0
        tst     -256,r0
        bnz     $1
        bnz     test_failure
        halt
        halt
 
// Go into an infinite loop if the trap fails
 
// Permanent loop instruction -- a busy halt if you will
 
test_failure:
        busy
        busy
; Now for a series of tests.  If the test fails, call the trap
; Now for a series of tests.  If the test fails, call the trap
; interrupt with the test number that failed.  Upon completion,
; interrupt with the test number that failed.  Upon completion,
; call the trap with #0.
; call the trap with #0.
 
 
; Now for a series of tests.  If the test fails, call the trap
 
; interrupt with the test number that failed.  Upon completion,
 
; call the trap with #0.
 
 
 
; Test LDI to PC
; Test LDI to PC
; Some data registers
; Some data registers
        .dat    __here__+5
test_data:
 
        .dat    __here__+0x0100000+5
test_start:
test_start:
        ldi     $2,r11
        ldi     $0x0100,r11
        lod     $-3+pc,pc
        lod     test_data+pc,pc
        clr     r11
        clr     r11
        noop
        noop
        cmp     $0,r11
        cmp     $0,r11
        sto.z   r11,(r12)
        trap.z  r11
        add     $1,r0
        add     $1,r0
        add     $1,r0
        add     $1,r0
// Let's test whether overflow works
// Let's test whether overflow works
        ldi     $3,r11
        ldi     $0x0200,r11
        ldi     $-1,r0
        ldi     $-1,r0
        lsr     $1,r0
        lsr     $1,r0
        add     $1,r0
        add     $1,r0
        bv      $1
        bv      first_overflow_passes
        sto     r11,(r12)
        trap    r11
 
first_overflow_passes:
// Overflow set from subtraction
// Overflow set from subtraction
        ldi     $4,r11
        ldi     $0x0300,r11
        ldi     $1,r0
        ldi     $1,r0
        .dat    0x5000001f              ; rol $31,r0
        rol     $31,r0                  ; rol $31,r0
        sub     $1,r0
        sub     $1,r0
        bv      $1
        bv      subtraction_overflow_passes
        sto     r11,(r12)
        trap    r11
 
subtraction_overflow_passes:
// Overflow set from LSR
// Overflow set from LSR
        ldi     $5,r11
        ldi     $0x0400,r11
        ldi     $1,r0
        ldi     $1,r0
        .dat    0x5000001f              ; rol $31,r0
        rol     $31,r0                  ; rol $31,r0
        lsr     $1,r0
        lsr     $1,r0
        bv      $1
        bv      lsr_overflow_passes
        sto     r11,(r12)
        trap    r11
 
lsr_overflow_passes:
// Overflow set from LSL
// Overflow set from LSL
        ldi     $6,r11
        ldi     $0x0500,r11
        ldi     $1,r0
        ldi     $1,r0
        .dat    0x5000001e
        rol     $30,r0
        lsl     $1,r0
        lsl     $1,r0
        bv      $1
        bv      lsl_overflow_passes
        sto     r11,(r12)
        trap    r11
 
lsl_overflow_passes:
// Overflow set from LSL, negative to positive
// Overflow set from LSL, negative to positive
        ldi     $7,r11
        ldi     $0x0600,r11
        ldi     $1,r0
        ldi     $1,r0
        .dat    0x5000001f; //  E: ROL $30,R0
        rol     $31,r0
        lsl     $1,r0
        lsl     $1,r0
        bv      $1
        bv      second_lsl_overflow_passes
        sto     r11,(r12)
        trap    r11
 
second_lsl_overflow_passes:
// Test carry
// Test carry
        ldi     $0x010,r11
        ldi     $0x0700,r11
        ldi     $-1,r0
        ldi     $-1,r0
        add     $1,r0
        add     $1,r0
        tst     $2,cc
        tst     $2,cc
        sto.z   r11,(r12)
        trap.z  r11
// and carry from subtraction
// and carry from subtraction
        ldi     $17,r11
        ldi     $0x0800,r11
        sub     $1,r0
        sub     $1,r0
        tst     $2,cc
        tst     $2,cc
        sto.z   r11,(r12)
        trap.z  r11
 
 
// 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
for_loop:
        ldi     $0x0800,r11
        ldi     $18,r11
 
        clr     r0
        clr     r0
 
for_loop:
        noop
        noop
        add     $1,r0
        add     $1,r0
        cmp     $5,r0
        cmp     $5,r0
        blt     for_loop
        blt     for_loop
//
//
// Let's try a reverse loop.  Such loops are usually cheaper to
// Let's try a reverse loop.  Such loops are usually cheaper to
// 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
bgt_loop:
bgt_loop:
        ldi     $19,r11
 
        noop
        noop
        sub     $1,r0
        sub     $1,r0
        bgt     bgt_loop
        bgt     bgt_loop
// How about the same thing with a >= comparison?
// How about the same thing with a >= comparison?
// R1 = 5; // Need to do this explicitly
// R1 = 5; // Need to do this explicitly
// do {
// do {
// } while(R1 >= 0);
// } while(R1 >= 0);
        ldi     $20,r00
        ldi     $20,r0
        ldi     $5,r1
        ldi     $5,r1
bge_loop:
bge_loop:
        noop
        noop
        sub     $1,r1
        sub     $1,r1
        bge     bge_loop
        bge     bge_loop
// 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     $21,r11
        ldi     $0x0a00,r11
        bra     $1
        bra     mem_loop_test
loop_var:
loop_var:
        .dat    0
        .dat    0
mem_loop:
mem_loop_test:
        mov     $-2+pc,r1
        mov     loop_var(pc),r1
        clr     r2
 
        ldi     $5,r0
        ldi     $5,r0
        sto     r1,(r0)
        clr     r2
 
        sto     r0,(r1)
 
mem_loop:
        add     $1,r2
        add     $1,r2
        add     $14,r0
        add     $14,r0
        lod     (r1),r0
        lod     (r1),r0
        sub     $1,r0
        sub     $1,r0
        bgt     $-6
        sto     r0,(r1)
 
        bgt     mem_loop
        cmp     $5,r2
        cmp     $5,r2
        sto.ne  r11,(r12)
        trap.ne r11
 
 
// Return success / Test the trap interrupt
// Return success / Test the trap interrupt
        clr     r11
        clr     r11
        sto     r11,(r12)
        trap    r11
        noop
        noop
        noop
        noop
 
 
// Go into an infinite loop if the trap fails
 
// Permanent loop instruction -- a busy halt if you will
 
        busy
        busy
// And, in case we miss a halt ...
// And, in case we miss a halt ...
        halt
        halt
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.