; <><><> Small-C V1.2 DOS--CP/M Cross Compiler <><><>
|
; <><><> Small-C V1.2 DOS--CP/M Cross Compiler <><><>
|
; <><><><><> CP/M Large String Space Version <><><><><>
|
; <><><><><> CP/M Large String Space Version <><><><><>
|
; <><><><><><><><><><> By Ron Cain <><><><><><><><><><>
|
; <><><><><><><><><><> By Ron Cain <><><><><><><><><><>
|
;
|
;
|
code
|
code
|
org #0000
|
org #0000
|
ld hl,3072
|
ld hl,3072
|
ld sp,hl
|
ld sp,hl
|
call __main
|
call __main
|
;//---------------------------------------------------------------------------------------
|
;//---------------------------------------------------------------------------------------
|
;// Project: light8080 SOC WiCores Solutions
|
;// Project: light8080 SOC WiCores Solutions
|
;//
|
;//
|
;// File name: hello.c (February 04, 2012)
|
;// File name: hello.c (February 04, 2012)
|
;//
|
;//
|
;// Writer: Moti Litochevski
|
;// Writer: Moti Litochevski
|
;//
|
;//
|
;// Description:
|
;// Description:
|
;// This file contains a simple program written in Small-C that sends a string to
|
;// This file contains a simple program written in Small-C that sends a string to
|
;// the UART and then switches to echo received bytes.
|
;// the UART and then switches to echo received bytes.
|
|
;// This example also include a simple interrupt example which will work with the
|
|
;// verilog testbench. the testbench
|
;//
|
;//
|
;// Revision History:
|
;// Revision History:
|
;//
|
;//
|
;// Rev
|
;// Rev
|
;//
|
;//
|
;//---------------------------------------------------------------------------------------
|
;//---------------------------------------------------------------------------------------
|
|
;// define interrupt vectors
|
|
;// note that this file must be edited to enable interrupt used
|
|
;#include intr_vec.h
|
|
;//---------------------------------------------------------------------------------------
|
|
;// Project: light8080 SOC WiCores Solutions
|
|
;//
|
|
;// File name: intr_vec.h (March 03, 2012)
|
|
;//
|
|
;// Writer: Moti Litochevski
|
|
;//
|
|
;// Description:
|
|
;// This file contains a simple example of calling interrupt service routine. this
|
|
;// file defines the interrupt vector for external interrupt 0 located at address
|
|
;// 0x0008. the interrupts vectors addresses are set in the verilog interrupt
|
|
;// controller "intr_ctrl.v" file.
|
|
;// Code is generated for all 4 supported external interrupts but non used interrupt
|
|
;// are not called.
|
|
;// On execution of an interrupt the CPU will automatically clear the interrupt
|
|
;// enable flag set by the EI instruction. the interrupt vectors in this example
|
|
;// enable the interrupts again after interrupt service routine execution. to enable
|
|
;// nested interrupts just move the EI instruction to the code executed before the
|
|
;// call instruction to the service routine (see comments below).
|
|
;// Note that this code is not optimized in any way. this is just an example to
|
|
;// verify the interrupt mechanism of the light8080 CPU and show a simple example.
|
|
;//
|
|
;// Revision History:
|
|
;//
|
|
;// Rev
|
|
;//
|
|
;//---------------------------------------------------------------------------------------
|
|
;// to support interrupt enable the respective interrupt vector is defined here at the
|
|
;// beginning of the output assembly file. only the interrupt vector for used interrupts
|
|
;// should call a valid interrupt service routine name defined in the C source file. the
|
|
;// C function name should be prefixed by "__".
|
|
;#asm
|
|
;Preserve space for interrupt routines
|
|
;interrupt 0 vector
|
|
org #0008
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
; ei ; to enable nested interrupts uncomment this instruction
|
|
call __int0_isr
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ei ; interrupt are not enabled during the execution os the isr
|
|
ret
|
|
;interrupt 1 vector
|
|
org #0018
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
; call __int1_isr ; interrupt not used
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ei
|
|
ret
|
|
;interrupt 2 vector
|
|
org #0028
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
; call __int2_isr ; interrupt not used
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ei
|
|
ret
|
|
;interrupt 3 vector
|
|
org #0038
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
; call __int3_isr ; interrupt not used
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ei
|
|
ret
|
|
;//---------------------------------------------------------------------------------------
|
|
;// Th.. Th.. Th.. Thats all folks !!!
|
|
;//---------------------------------------------------------------------------------------
|
|
;// insert c80 assmbly library to the output file
|
;#include ..\tools\c80\c80.lib
|
;#include ..\tools\c80\c80.lib
|
;#asm
|
;#asm
|
;
|
;
|
;------------------------------------------------------------------
|
;------------------------------------------------------------------
|
; Small-C Run-time Librray
|
; Small-C Run-time Librray
|
;
|
;
|
; V4d As of July 16, 1980 (gtf)
|
; V4d As of July 16, 1980 (gtf)
|
; Added EXIT() function
|
; Added EXIT() function
|
;------------------------------------------------------------------
|
;------------------------------------------------------------------
|
;
|
;
|
;Fetch a single byte from the address in HL and sign extend into HL
|
;Fetch a single byte from the address in HL and sign extend into HL
|
ccgchar:
|
ccgchar:
|
ld a,(hl)
|
ld a,(hl)
|
ccsxt:
|
ccsxt:
|
ld l,a
|
ld l,a
|
rlca
|
rlca
|
sbc a
|
sbc a
|
ld h,a
|
ld h,a
|
ret
|
ret
|
;Fetch a full 16-bit integer from the address in HL
|
;Fetch a full 16-bit integer from the address in HL
|
ccgint:
|
ccgint:
|
ld a,(hl)
|
ld a,(hl)
|
inc hl
|
inc hl
|
ld h,(hl)
|
ld h,(hl)
|
ld l,a
|
ld l,a
|
ret
|
ret
|
;Store a single byte from HL at the address in DE
|
;Store a single byte from HL at the address in DE
|
ccpchar:
|
ccpchar:
|
ld a,l
|
ld a,l
|
ld (de),a
|
ld (de),a
|
ret
|
ret
|
;Store a 16-bit integer in HL at the address in DE
|
;Store a 16-bit integer in HL at the address in DE
|
ccpint:
|
ccpint:
|
ld a,l
|
ld a,l
|
ld (de),a
|
ld (de),a
|
inc de
|
inc de
|
ld a,h
|
ld a,h
|
ld (de),a
|
ld (de),a
|
ret
|
ret
|
;Inclusive "or" HL and DE into HL
|
;Inclusive "or" HL and DE into HL
|
ccor:
|
ccor:
|
ld a,l
|
ld a,l
|
or e
|
or e
|
ld l,a
|
ld l,a
|
ld a,h
|
ld a,h
|
or d
|
or d
|
ld h,a
|
ld h,a
|
ret
|
ret
|
;Exclusive "or" HL and DE into HL
|
;Exclusive "or" HL and DE into HL
|
ccxor:
|
ccxor:
|
ld a,l
|
ld a,l
|
xor e
|
xor e
|
ld l,a
|
ld l,a
|
ld a,h
|
ld a,h
|
xor d
|
xor d
|
ld h,a
|
ld h,a
|
ret
|
ret
|
;"And" HL and DE into HL
|
;"And" HL and DE into HL
|
ccand:
|
ccand:
|
ld a,l
|
ld a,l
|
and e
|
and e
|
ld l,a
|
ld l,a
|
ld a,h
|
ld a,h
|
and d
|
and d
|
ld h,a
|
ld h,a
|
ret
|
ret
|
;Test if HL = DE and set HL = 1 if true else 0
|
;Test if HL = DE and set HL = 1 if true else 0
|
cceq:
|
cceq:
|
call cccmp
|
call cccmp
|
ret z
|
ret z
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE ~= HL
|
;Test if DE ~= HL
|
ccne:
|
ccne:
|
call cccmp
|
call cccmp
|
ret nz
|
ret nz
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE > HL (signed)
|
;Test if DE > HL (signed)
|
ccgt:
|
ccgt:
|
ex de,hl
|
ex de,hl
|
call cccmp
|
call cccmp
|
ret c
|
ret c
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE <= HL (signed)
|
;Test if DE <= HL (signed)
|
ccle:
|
ccle:
|
call cccmp
|
call cccmp
|
ret z
|
ret z
|
ret c
|
ret c
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE >= HL (signed)
|
;Test if DE >= HL (signed)
|
ccge:
|
ccge:
|
call cccmp
|
call cccmp
|
ret nc
|
ret nc
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE < HL (signed)
|
;Test if DE < HL (signed)
|
cclt:
|
cclt:
|
call cccmp
|
call cccmp
|
ret c
|
ret c
|
dec hl
|
dec hl
|
ret
|
ret
|
; Signed compare of DE and HL
|
; Signed compare of DE and HL
|
; Performs DE - HL and sets the conditions:
|
; Performs DE - HL and sets the conditions:
|
; Carry reflects sign of difference (set means DE < HL)
|
; Carry reflects sign of difference (set means DE < HL)
|
; Zero/non-zero set according to equality.
|
; Zero/non-zero set according to equality.
|
cccmp:
|
cccmp:
|
ld a,e
|
ld a,e
|
sub l
|
sub l
|
ld e,a
|
ld e,a
|
ld a,d
|
ld a,d
|
sbc h
|
sbc h
|
ld hl,1
|
ld hl,1
|
jp m,cccmp1
|
jp m,cccmp1
|
or e ;"OR" resets carry
|
or e ;"OR" resets carry
|
ret
|
ret
|
cccmp1:
|
cccmp1:
|
or e
|
or e
|
scf ;set carry to signal minus
|
scf ;set carry to signal minus
|
ret
|
ret
|
;Test if DE >= HL (unsigned)
|
;Test if DE >= HL (unsigned)
|
ccuge:
|
ccuge:
|
call ccucmp
|
call ccucmp
|
ret nc
|
ret nc
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE < HL (unsigned)
|
;Test if DE < HL (unsigned)
|
ccult:
|
ccult:
|
call ccucmp
|
call ccucmp
|
ret c
|
ret c
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE > HL (unsigned)
|
;Test if DE > HL (unsigned)
|
ccugt:
|
ccugt:
|
ex de,hl
|
ex de,hl
|
call ccucmp
|
call ccucmp
|
ret c
|
ret c
|
dec hl
|
dec hl
|
ret
|
ret
|
;Test if DE <= HL (unsigned)
|
;Test if DE <= HL (unsigned)
|
ccule:
|
ccule:
|
call ccucmp
|
call ccucmp
|
ret z
|
ret z
|
ret c
|
ret c
|
dec hl
|
dec hl
|
ret
|
ret
|
;Routine to perform unsigned compare
|
;Routine to perform unsigned compare
|
;carry set if DE < HL
|
;carry set if DE < HL
|
;zero/nonzero set accordingly
|
;zero/nonzero set accordingly
|
ccucmp:
|
ccucmp:
|
ld a,d
|
ld a,d
|
cp h
|
cp h
|
jp nz,$+5
|
jp nz,$+5
|
ld a,e
|
ld a,e
|
cp l
|
cp l
|
ld hl,1
|
ld hl,1
|
ret
|
ret
|
;Shift DE arithmetically right by HL and return in HL
|
;Shift DE arithmetically right by HL and return in HL
|
ccasr:
|
ccasr:
|
ex de,hl
|
ex de,hl
|
ld a,h
|
ld a,h
|
rla
|
rla
|
ld a,h
|
ld a,h
|
rra
|
rra
|
ld h,a
|
ld h,a
|
ld a,l
|
ld a,l
|
rra
|
rra
|
ld l,a
|
ld l,a
|
dec e
|
dec e
|
jp nz,ccasr+1
|
jp nz,ccasr+1
|
ret
|
ret
|
;Shift DE arithmetically left by HL and return in HL
|
;Shift DE arithmetically left by HL and return in HL
|
ccasl:
|
ccasl:
|
ex de,hl
|
ex de,hl
|
add hl,hl
|
add hl,hl
|
dec e
|
dec e
|
jp nz,ccasl+1
|
jp nz,ccasl+1
|
ret
|
ret
|
;Subtract HL from DE and return in HL
|
;Subtract HL from DE and return in HL
|
ccsub:
|
ccsub:
|
ld a,e
|
ld a,e
|
sub l
|
sub l
|
ld l,a
|
ld l,a
|
ld a,d
|
ld a,d
|
sbc h
|
sbc h
|
ld h,a
|
ld h,a
|
ret
|
ret
|
;Form the two's complement of HL
|
;Form the two's complement of HL
|
ccneg:
|
ccneg:
|
call cccom
|
call cccom
|
inc hl
|
inc hl
|
ret
|
ret
|
;Form the one's complement of HL
|
;Form the one's complement of HL
|
cccom:
|
cccom:
|
ld a,h
|
ld a,h
|
cpl
|
cpl
|
ld h,a
|
ld h,a
|
ld a,l
|
ld a,l
|
cpl
|
cpl
|
ld l,a
|
ld l,a
|
ret
|
ret
|
;Multiply DE by HL and return in HL
|
;Multiply DE by HL and return in HL
|
ccmult:
|
ccmult:
|
ld b,h
|
ld b,h
|
ld c,l
|
ld c,l
|
ld hl,0
|
ld hl,0
|
ccmult1:
|
ccmult1:
|
ld a,c
|
ld a,c
|
rrca
|
rrca
|
jp nc,$+4
|
jp nc,$+4
|
add hl,de
|
add hl,de
|
xor a
|
xor a
|
ld a,b
|
ld a,b
|
rra
|
rra
|
ld b,a
|
ld b,a
|
ld a,c
|
ld a,c
|
rra
|
rra
|
ld c,a
|
ld c,a
|
or b
|
or b
|
ret z
|
ret z
|
xor a
|
xor a
|
ld a,e
|
ld a,e
|
rla
|
rla
|
ld e,a
|
ld e,a
|
ld a,d
|
ld a,d
|
rla
|
rla
|
ld d,a
|
ld d,a
|
or e
|
or e
|
ret z
|
ret z
|
jp ccmult1
|
jp ccmult1
|
;Divide DE by HL and return quotient in HL, remainder in DE
|
;Divide DE by HL and return quotient in HL, remainder in DE
|
ccdiv:
|
ccdiv:
|
ld b,h
|
ld b,h
|
ld c,l
|
ld c,l
|
ld a,d
|
ld a,d
|
xor b
|
xor b
|
push af
|
push af
|
ld a,d
|
ld a,d
|
or a
|
or a
|
call m,ccdeneg
|
call m,ccdeneg
|
ld a,b
|
ld a,b
|
or a
|
or a
|
call m,ccbcneg
|
call m,ccbcneg
|
ld a,16
|
ld a,16
|
push af
|
push af
|
ex de,hl
|
ex de,hl
|
ld de,0
|
ld de,0
|
ccdiv1:
|
ccdiv1:
|
add hl,hl
|
add hl,hl
|
call ccrdel
|
call ccrdel
|
jp z,ccdiv2
|
jp z,ccdiv2
|
call cccmpbcde
|
call cccmpbcde
|
jp m,ccdiv2
|
jp m,ccdiv2
|
ld a,l
|
ld a,l
|
or 1
|
or 1
|
ld l,a
|
ld l,a
|
ld a,e
|
ld a,e
|
sub c
|
sub c
|
ld e,a
|
ld e,a
|
ld a,d
|
ld a,d
|
sbc b
|
sbc b
|
ld d,a
|
ld d,a
|
ccdiv2:
|
ccdiv2:
|
pop af
|
pop af
|
dec a
|
dec a
|
jp z,ccdiv3
|
jp z,ccdiv3
|
push af
|
push af
|
jp ccdiv1
|
jp ccdiv1
|
ccdiv3:
|
ccdiv3:
|
pop af
|
pop af
|
ret p
|
ret p
|
call ccdeneg
|
call ccdeneg
|
ex de,hl
|
ex de,hl
|
call ccdeneg
|
call ccdeneg
|
ex de,hl
|
ex de,hl
|
ret
|
ret
|
ccdeneg:
|
ccdeneg:
|
ld a,d
|
ld a,d
|
cpl
|
cpl
|
ld d,a
|
ld d,a
|
ld a,e
|
ld a,e
|
cpl
|
cpl
|
ld e,a
|
ld e,a
|
inc de
|
inc de
|
ret
|
ret
|
ccbcneg:
|
ccbcneg:
|
ld a,b
|
ld a,b
|
cpl
|
cpl
|
ld b,a
|
ld b,a
|
ld a,c
|
ld a,c
|
cpl
|
cpl
|
ld c,a
|
ld c,a
|
inc bc
|
inc bc
|
ret
|
ret
|
ccrdel:
|
ccrdel:
|
ld a,e
|
ld a,e
|
rla
|
rla
|
ld e,a
|
ld e,a
|
ld a,d
|
ld a,d
|
rla
|
rla
|
ld d,a
|
ld d,a
|
or e
|
or e
|
ret
|
ret
|
cccmpbcde:
|
cccmpbcde:
|
ld a,e
|
ld a,e
|
sub c
|
sub c
|
ld a,d
|
ld a,d
|
sbc b
|
sbc b
|
ret
|
ret
|
;// UART IO registers
|
;// UART IO registers
|
;port (128) UDATA; // uart data register used for both transmit and receive
|
;port (128) UDATA; // uart data register used for both transmit and receive
|
;port (129) UBAUDL; // low byte of baud rate register
|
;port (129) UBAUDL; // low byte of baud rate register
|
;port (130) UBAUDH; // low byte of baud rate register
|
;port (130) UBAUDH; // low byte of baud rate register
|
;port (131) USTAT; // uart status register
|
;port (131) USTAT; // uart status register
|
;// digital IO ports registers
|
;// digital IO ports registers
|
;port (132) P1REG; // output port1 - used as first attenuator control
|
;port (132) P1DATA; // port 1 data register
|
;port (133) P2REG; // output port2 - used as low digit LCD
|
;port (133) P1DIR; // port 1 direction register control
|
;port (134) P3REG; // output port3 - used as high digit LCD
|
;port (134) P2DATA; // port 2 data register
|
;port (135) P4REG; // output port4
|
;port (135) P2DIR; // port 2 direction register control
|
|
;// interrupt controller register
|
|
;port (136) INTRENA; // interrupts enable register
|
;// simulation end register
|
;// simulation end register
|
;// writing any value to this port will end the verilog simulation when using tb_l80soc
|
;// writing any value to this port will end the verilog simulation when using tb_l80soc
|
;// test bench.
|
;// test bench.
|
;port (255) SIMEND;
|
;port (255) SIMEND;
|
;// registers bit fields definition
|
;// registers bit fields definition
|
;// uart status register decoding
|
;// uart status register decoding
|
;#define UTXBUSY 1
|
;#define UTXBUSY 1
|
;#define URXFULL 16
|
;#define URXFULL 16
|
;// globals
|
;// globals
|
;char rxbyte; // byte received from the uart
|
;char rxbyte; // byte received from the uart
|
;int tstary[2] = {1234, 5678};
|
;int tstary[2] = {1234, 5678};
|
;//---------------------------------------------------------------------------------------
|
;//---------------------------------------------------------------------------------------
|
;// send a single byte to the UART
|
;// send a single byte to the UART
|
;sendbyte(by)
|
;sendbyte(by)
|
__sendbyte:
|
__sendbyte:
|
;char by;
|
;char by;
|
;{
|
;{
|
; while (USTAT & UTXBUSY);
|
; while (USTAT & UTXBUSY);
|
cc2:
|
cc2:
|
in a,(131)
|
in a,(131)
|
call ccsxt
|
call ccsxt
|
push hl
|
push hl
|
ld hl,1
|
ld hl,1
|
pop de
|
pop de
|
call ccand
|
call ccand
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc3
|
jp z,cc3
|
jp cc2
|
jp cc2
|
cc3:
|
cc3:
|
; UDATA = by;
|
; UDATA = by;
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
call ccgchar
|
call ccgchar
|
ld a,l
|
ld a,l
|
out (128),a
|
out (128),a
|
|
|
;}
|
;}
|
ret
|
ret
|
;// check if a byte was received by the uart
|
;// check if a byte was received by the uart
|
;getbyte()
|
;getbyte()
|
__getbyte:
|
__getbyte:
|
;{
|
;{
|
; if (USTAT & URXFULL) {
|
; if (USTAT & URXFULL) {
|
in a,(131)
|
in a,(131)
|
call ccsxt
|
call ccsxt
|
push hl
|
push hl
|
ld hl,16
|
ld hl,16
|
pop de
|
pop de
|
call ccand
|
call ccand
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc4
|
jp z,cc4
|
; rxbyte = UDATA;
|
; rxbyte = UDATA;
|
in a,(128)
|
in a,(128)
|
call ccsxt
|
call ccsxt
|
ld a,l
|
ld a,l
|
ld (__rxbyte),a
|
ld (__rxbyte),a
|
; return 1;
|
; return 1;
|
ld hl,1
|
ld hl,1
|
ret
|
ret
|
; }
|
; }
|
; else
|
; else
|
jp cc5
|
jp cc5
|
cc4:
|
cc4:
|
; return 0;
|
; return 0;
|
ld hl,0
|
ld hl,0
|
ret
|
ret
|
cc5:
|
cc5:
|
;}
|
;}
|
ret
|
ret
|
;// send new line to the UART
|
;// send new line to the UART
|
;nl()
|
;nl()
|
__nl:
|
__nl:
|
;{
|
;{
|
; sendbyte(13);
|
; sendbyte(13);
|
ld hl,13
|
ld hl,13
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
; sendbyte(10);
|
; sendbyte(10);
|
ld hl,10
|
ld hl,10
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
;}
|
;}
|
ret
|
ret
|
;// sends a string to the UART
|
;// sends a string to the UART
|
;printstr(sptr)
|
;printstr(sptr)
|
__printstr:
|
__printstr:
|
;char *sptr;
|
;char *sptr;
|
;{
|
;{
|
; while (*sptr != 0)
|
; while (*sptr != 0)
|
cc6:
|
cc6:
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
call ccgchar
|
call ccgchar
|
push hl
|
push hl
|
ld hl,0
|
ld hl,0
|
pop de
|
pop de
|
call ccne
|
call ccne
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc7
|
jp z,cc7
|
; sendbyte(*sptr++);
|
; sendbyte(*sptr++);
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
push hl
|
push hl
|
call ccgint
|
call ccgint
|
inc hl
|
inc hl
|
pop de
|
pop de
|
call ccpint
|
call ccpint
|
dec hl
|
dec hl
|
call ccgchar
|
call ccgchar
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
jp cc6
|
jp cc6
|
cc7:
|
cc7:
|
;}
|
;}
|
ret
|
ret
|
;// sends a decimal value to the UART
|
;// sends a decimal value to the UART
|
;printdec(dval)
|
;printdec(dval)
|
__printdec:
|
__printdec:
|
;int dval;
|
;int dval;
|
;{
|
;{
|
; if (dval<0) {
|
; if (dval<0) {
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,0
|
ld hl,0
|
pop de
|
pop de
|
call cclt
|
call cclt
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc8
|
jp z,cc8
|
; sendbyte('-');
|
; sendbyte('-');
|
ld hl,45
|
ld hl,45
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
; dval = -dval;
|
; dval = -dval;
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
push hl
|
push hl
|
ld hl,4
|
ld hl,4
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
call ccneg
|
call ccneg
|
pop de
|
pop de
|
call ccpint
|
call ccpint
|
; }
|
; }
|
; outint(dval);
|
; outint(dval);
|
cc8:
|
cc8:
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
call __outint
|
call __outint
|
pop bc
|
pop bc
|
;}
|
;}
|
ret
|
ret
|
;// function copied from c80dos.c
|
;// function copied from c80dos.c
|
;outint(n)
|
;outint(n)
|
__outint:
|
__outint:
|
;int n;
|
;int n;
|
;{
|
;{
|
;int q;
|
;int q;
|
push bc
|
push bc
|
; q = n/10;
|
; q = n/10;
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
push hl
|
push hl
|
ld hl,6
|
ld hl,6
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,10
|
ld hl,10
|
pop de
|
pop de
|
call ccdiv
|
call ccdiv
|
pop de
|
pop de
|
call ccpint
|
call ccpint
|
; if (q) outint(q);
|
; if (q) outint(q);
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc9
|
jp z,cc9
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
call __outint
|
call __outint
|
pop bc
|
pop bc
|
; sendbyte('0'+(n-q*10));
|
; sendbyte('0'+(n-q*10));
|
cc9:
|
cc9:
|
ld hl,48
|
ld hl,48
|
push hl
|
push hl
|
ld hl,6
|
ld hl,6
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,4
|
ld hl,4
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,10
|
ld hl,10
|
pop de
|
pop de
|
call ccmult
|
call ccmult
|
pop de
|
pop de
|
call ccsub
|
call ccsub
|
pop de
|
pop de
|
add hl,de
|
add hl,de
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
;}
|
;}
|
pop bc
|
pop bc
|
ret
|
ret
|
;// sends a hexadecimal value to the UART
|
;// sends a hexadecimal value to the UART
|
;printhex(hval)
|
;printhex(hval)
|
__printhex:
|
__printhex:
|
;int hval;
|
;int hval;
|
;{
|
;{
|
;int q;
|
;int q;
|
push bc
|
push bc
|
; q = hval/16;
|
; q = hval/16;
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
push hl
|
push hl
|
ld hl,6
|
ld hl,6
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,16
|
ld hl,16
|
pop de
|
pop de
|
call ccdiv
|
call ccdiv
|
pop de
|
pop de
|
call ccpint
|
call ccpint
|
; if (q) printhex(q);
|
; if (q) printhex(q);
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc10
|
jp z,cc10
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
call __printhex
|
call __printhex
|
pop bc
|
pop bc
|
; q = hval-q*16;
|
; q = hval-q*16;
|
cc10:
|
cc10:
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
push hl
|
push hl
|
ld hl,6
|
ld hl,6
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,4
|
ld hl,4
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,16
|
ld hl,16
|
pop de
|
pop de
|
call ccmult
|
call ccmult
|
pop de
|
pop de
|
call ccsub
|
call ccsub
|
pop de
|
pop de
|
call ccpint
|
call ccpint
|
; if (q > 9)
|
; if (q > 9)
|
ld hl,0
|
ld hl,0
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
ld hl,9
|
ld hl,9
|
pop de
|
pop de
|
call ccgt
|
call ccgt
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc11
|
jp z,cc11
|
; sendbyte('A'+q-10);
|
; sendbyte('A'+q-10);
|
ld hl,65
|
ld hl,65
|
push hl
|
push hl
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
pop de
|
pop de
|
add hl,de
|
add hl,de
|
push hl
|
push hl
|
ld hl,10
|
ld hl,10
|
pop de
|
pop de
|
call ccsub
|
call ccsub
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
; else
|
; else
|
jp cc12
|
jp cc12
|
cc11:
|
cc11:
|
; sendbyte('0'+q);
|
; sendbyte('0'+q);
|
ld hl,48
|
ld hl,48
|
push hl
|
push hl
|
ld hl,2
|
ld hl,2
|
add hl,sp
|
add hl,sp
|
call ccgint
|
call ccgint
|
pop de
|
pop de
|
add hl,de
|
add hl,de
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
cc12:
|
cc12:
|
;}
|
;}
|
pop bc
|
pop bc
|
ret
|
ret
|
|
;// external interrupt 0 service routine
|
|
;int0_isr()
|
|
__int0_isr:
|
|
;{
|
|
; printstr("Interrupt 0 was asserted."); nl();
|
|
ld hl,cc1+0
|
|
push hl
|
|
call __printstr
|
|
pop bc
|
|
call __nl
|
|
;}
|
|
ret
|
;// program main routine
|
;// program main routine
|
;main()
|
;main()
|
__main:
|
__main:
|
;{
|
;{
|
; // configure UART baud rate - set to 9600 for 30MHz clock
|
; // configure UART baud rate - set to 9600 for 30MHz clock
|
; // BAUD = round(//16) = round(30e6/9600/16) = 195
|
; // BAUD = round(//16) = round(30e6/9600/16) = 195
|
; UBAUDL = 195;
|
;//MOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTI
|
ld hl,195
|
;//MOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTI
|
|
;// UBAUDL = 195;
|
|
; UBAUDL = 1;
|
|
ld hl,1
|
ld a,l
|
ld a,l
|
out (129),a
|
out (129),a
|
|
|
|
;//MOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTI
|
|
;//MOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTIMOTI
|
; UBAUDH = 0;
|
; UBAUDH = 0;
|
ld hl,0
|
ld hl,0
|
ld a,l
|
ld a,l
|
out (130),a
|
out (130),a
|
|
|
|
; // configure both ports to output and digital outputs as zeros
|
|
; P1DATA = 0x00;
|
|
ld hl,0
|
|
ld a,l
|
|
out (132),a
|
|
|
|
; P1DIR = 0xff;
|
|
ld hl,255
|
|
ld a,l
|
|
out (133),a
|
|
|
|
; P2DATA = 0x00;
|
|
ld hl,0
|
|
ld a,l
|
|
out (134),a
|
|
|
|
; P2DIR = 0xff;
|
|
ld hl,255
|
|
ld a,l
|
|
out (135),a
|
|
|
|
; // enable interrupt 0 only
|
|
; INTRENA = 0x01;
|
|
ld hl,1
|
|
ld a,l
|
|
out (136),a
|
|
|
|
; // enable CPU interrupt
|
|
;#asm
|
|
ei
|
|
;
|
; // print message
|
; // print message
|
; printstr("Hello World!!!"); nl();
|
; printstr("Hello World!!!"); nl();
|
ld hl,cc1+0
|
ld hl,cc1+26
|
push hl
|
push hl
|
call __printstr
|
call __printstr
|
pop bc
|
pop bc
|
call __nl
|
call __nl
|
; printstr("Dec value: "); printdec(tstary[1]); nl();
|
; printstr("Dec value: "); printdec(tstary[1]); nl();
|
ld hl,cc1+15
|
ld hl,cc1+41
|
push hl
|
push hl
|
call __printstr
|
call __printstr
|
pop bc
|
pop bc
|
ld hl,__tstary
|
ld hl,__tstary
|
push hl
|
push hl
|
ld hl,1
|
ld hl,1
|
add hl,hl
|
add hl,hl
|
pop de
|
pop de
|
add hl,de
|
add hl,de
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
call __printdec
|
call __printdec
|
pop bc
|
pop bc
|
call __nl
|
call __nl
|
; printstr("Hex value: 0x"); printhex(tstary[0]); nl();
|
; printstr("Hex value: 0x"); printhex(tstary[0]); nl();
|
ld hl,cc1+27
|
ld hl,cc1+53
|
push hl
|
push hl
|
call __printstr
|
call __printstr
|
pop bc
|
pop bc
|
ld hl,__tstary
|
ld hl,__tstary
|
push hl
|
push hl
|
ld hl,0
|
ld hl,0
|
add hl,hl
|
add hl,hl
|
pop de
|
pop de
|
add hl,de
|
add hl,de
|
call ccgint
|
call ccgint
|
push hl
|
push hl
|
call __printhex
|
call __printhex
|
pop bc
|
pop bc
|
call __nl
|
call __nl
|
|
; // assert bit 0 of port 1 to test external interrupt 0
|
|
; P1DATA = 0x01;
|
|
ld hl,1
|
|
ld a,l
|
|
out (132),a
|
|
|
|
;
|
; printstr("Echoing received bytes: "); nl();
|
; printstr("Echoing received bytes: "); nl();
|
ld hl,cc1+41
|
ld hl,cc1+67
|
push hl
|
push hl
|
call __printstr
|
call __printstr
|
pop bc
|
pop bc
|
call __nl
|
call __nl
|
;
|
|
; // loop forever
|
; // loop forever
|
; while (1) {
|
; while (1) {
|
cc13:
|
cc13:
|
ld hl,1
|
ld hl,1
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc14
|
jp z,cc14
|
; // check if a new byte was received
|
; // check if a new byte was received
|
; if (getbyte())
|
; if (getbyte())
|
call __getbyte
|
call __getbyte
|
ld a,h
|
ld a,h
|
or l
|
or l
|
jp z,cc15
|
jp z,cc15
|
; // echo the received byte to the UART
|
; // echo the received byte to the UART
|
; sendbyte(rxbyte);
|
; sendbyte(rxbyte);
|
ld a,(__rxbyte)
|
ld a,(__rxbyte)
|
call ccsxt
|
call ccsxt
|
push hl
|
push hl
|
call __sendbyte
|
call __sendbyte
|
pop bc
|
pop bc
|
; }
|
; }
|
cc15:
|
cc15:
|
jp cc13
|
jp cc13
|
cc14:
|
cc14:
|
;}
|
;}
|
ret
|
ret
|
;//---------------------------------------------------------------------------------------
|
;//---------------------------------------------------------------------------------------
|
;// Th.. Th.. Th.. Thats all folks !!!
|
;// Th.. Th.. Th.. Thats all folks !!!
|
;//---------------------------------------------------------------------------------------
|
;//---------------------------------------------------------------------------------------
|
cc1:
|
cc1:
|
db 72,101,108,108,111,32,87,111,114,108
|
db 73,110,116,101,114,114,117,112,116,32
|
db 100,33,33,33,0,68,101,99,32,118
|
db 48,32,119,97,115,32,97,115,115,101
|
db 97,108,117,101,58,32,0,72,101,120
|
db 114,116,101,100,46,0,72,101,108,108
|
db 32,118,97,108,117,101,58,32,48,120
|
db 111,32,87,111,114,108,100,33,33,33
|
db 0,69,99,104,111,105,110,103,32,114
|
db 0,68,101,99,32,118,97,108,117,101
|
db 101,99,101,105,118,101,100,32,98,121
|
db 58,32,0,72,101,120,32,118,97,108
|
db 116,101,115,58,32,0
|
db 117,101,58,32,48,120,0,69,99,104
|
|
db 111,105,110,103,32,114,101,99,101,105
|
|
db 118,101,100,32,98,121,116,101,115,58
|
|
db 32,0
|
__rxbyte:
|
__rxbyte:
|
ds 1
|
ds 1
|
__tstary:
|
__tstary:
|
db -46,4,46,22
|
db -46,4,46,22
|
|
|
; --- End of Compilation ---
|
; --- End of Compilation ---
|
|
|