;; crt0_asm.s - tlcs90
	
	.t90
	
	.module crt0

;	.globl _meminit
	.globl _main
	;; .globl _xxaddr
	;; .globl _xxby
	;; .globl _xxdata

;	.globl _ser_putchar_irq
;	.globl _ser_puts
	
	;; put as abs in dat at end of file..
	;.globl _ser_irq_flags
	;.globl _ser_char
	
;	.globl _xget_byte_asm
;	.globl _xset_byte_asm


	 ;; for interrupts the pc and af are pushed on the stack
	
;	.globl _irq_info_swi
;	.globl _irq_info_intwd
;	.globl _irq_info_intt0
;	.globl _irq_info_intt1
;	.globl _timer1_irq
;	.globl _irq_info_intt3
;	.globl _irq_info_intt4
;	.globl _irq_info_int1
;	.globl _irq_info_intt5

	.globl _ticks16
	.globl _xflag
	
	;; NOTE: header might get trashed by linker when code loc ist not used!?
	.area	_HEADER (ABS)
	
	.org 	0

	.include "t90regs.s"

	;; _ser_irq_flags
TX_ACTIVE	.equ 0
RX_READY        .equ 1
	
L0:
	;halt
	;jr    L0
	jp    _astart
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop
L10:	
	; SWI
				;jp    _swi_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop  

L18:	
	nop  ; NMI
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  

L20:
	; INTWD
				;jp    _intwd_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L28:	
	reti ; INT0
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
L30:	
	; INTT0
				;jp    _intt0_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L38:	
	; INTT1
				;jp    _intt1_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L40:
	; INTAD 
	reti 
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop
L48:	
	; INTT3
				;jp    _intt3_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L50:	
	; INTT4
				;jp    _intt4_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L58:	
	; INT1
				;jp    _int1_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L60:	
	; INTT5
				;jp    _intt5_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L68:	
	reti ; INT2
	nop  
	nop  
	nop  
	nop  
	nop  
	nop  
	nop
L70:	
				;jp _serial_rx_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L78:	
				;jp _serial_tx_irq
	nop
	nop
	nop
	
	nop  
	nop  
	nop  
	nop  
	nop
L80:	
	nop  

	.org 0x100
	
_astart:
	ld    sp, #0x0FFA0	; stack
	
	;halt
	;swi
	
;	or    (P01CR), #0x04	;
	
;	ld    (P3), #0xF7	
;	ld    (P3CR), #0xA5	; P30 = RXD, P31 = IN:PaperOut CN3, P32 = TXD, P33 = OUT:CN2.LF P34:IN, P37:IN
	
;	ld    (P4), #0x00
;	ld    (P4CR), #0x03	; address output
;	ld    (P7), #0x03
;	ld    (P67CR), #0xF0
;	ld    (SMMOD), #0xA0
;	ld    (SMCR), #0x00
;	ld    (T4MOD), #0x35
;	ld    (P8), #0x08
;	ld    (P8CR), #0x08
;	ld    (T4FFCR), #0x01
	
;	ld    (TMOD), #0x40
	
	;ld    (SCMOD), #0x03	; 9600
;	ld    (SCMOD), #0x01	; 19200
;	or    (SCMOD), #0x08	; 8-bit data
;	or    (SCMOD), #0x20	; receiver enable

;	ld    (SCCR), #0x00
	
;	ld    (WDMOD), #0xC0
;	ld    (TRUN), #0x20	; PRRUN, start prescaler
;	or    (TRUN), #0xE0	; BRATE, 19200 baud

	;; enable rx/tx irqs
;	set   0,(INTEL)		; tx
;	set   1,(INTEL)		; rx

	;call _boot1

	call  _wd_reset_asm

;	res   TX_ACTIVE,(_ser_irq_flags)
	
	;call _boot2
;	call _meminit
	
	call  _wd_reset_asm
	
        ;; Initialise global variables

	;call _boot3
	
        call gsinit

	;call _boot4
	
	call _main
	halt
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	.area _CODE
	
	;; get far byte using by
	
;; _xget_byte_asm:
;; 	push bc
;; 	ld	iy, (_xxaddr)
;; 	ld	b, (BY)
;; 	ld	a, (_xxby)
;; 	ld	(BY), a
;; 	ld	a,(iy)
;; 	ld	(BY), b
;; 	ld	(_xxdata), a
;; 	pop	bc
;; 	ret

;; _xset_byte_asm:
;; 	push bc
;; 	ld	iy, (_xxaddr)
;; 	ld	b, (BY)
;; 	ld	a, (_xxby)
;; 	ld	(BY), a
;; 	ld 	a, (_xxdata)
;; 	ld	(iy), a
;; 	ld	(BY), b
;; 	pop	bc
;; 	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; _serial_rx_irq:
;; 	ld a, (SCBUF)
;; 	ld (_ser_char), a
;; 	set RX_READY, (_ser_irq_flags)
;; 	reti 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
;; _serial_tx_irq:
;; 	res TX_ACTIVE,(_ser_irq_flags)
;; 	ld (IRFH), #0x0F ; clear tx request flag (vector 0x78/8 = 0x0F)
;; 	reti 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; _swi_irq:
;; 	push hl
;; 	ld hl, 4(sp)
;; 	ld (_swi_pc), hl	; pc
;; 	ld hl, 2(sp)
;; 	ld (_swi_af), hl	; af
;; 	call _irq_info_swi
;; 	pop hl
;; 	reti
;; _intwd_irq:	
;; 	call _irq_info_intwd
;; 	reti
;; _intt0_irq:	
;; 	call _irq_info_intt0
;; 	reti
;; _intt1_irq:	
;; 	;call _irq_info_intt1
;; 	;exx

;; 	; hangs when exx is used?
;; 	incw (_ticks16) 

;; 	; hangs when exx is used?
;; 	;; ld hl, (_ticks16)
;; 	;; inc hl
;; 	;; ld (_ticks16), hl
	
;; 	ld (WDCR), #0x4E
;; 	ld (IRFL), #0x10;
;; 	;call _timer1_irq
;; 	;exx
;; 	reti
;; _intt3_irq:	
;; 	call _irq_info_intt3
;; 	reti
;; _intt4_irq:	
;; 	call _irq_info_intt4
;; 	reti
;; _int1_irq:	
;; 	call _irq_info_int1
;; 	reti
;; _intt5_irq:	
;; 	call _irq_info_intt5
;; 	reti

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
;; _ser_putchar_irq:
;; 	ld    a, 2(sp)

;; _ser_putchar_asm:
	
;; loop1:

;; 	;; check tx active flag
;; 	bit   TX_ACTIVE,(_ser_irq_flags)
;; 	jr    z, send1

;; 	di
;; 	bit   0,(IRFH) ; check irq
;; 	jr    nz, send1
;; 	ei
	
;; 	nop
;; 	nop
;; 	call  _wd_reset_asm
;; 	jr    loop1 ; loop, wait for irq

;; send1:	
;; 	di
;; 	ld    (IRFH),#0x0F ; clear tx request flag (vector 0x78/8 = 0x0F)
;; 	ld    (SCBUF),a ; send
;; 	set   TX_ACTIVE,(_ser_irq_flags) ; tx active..
;; 	ei
;; 	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
;; _ser_puts:
;; 	ld hl, 2(sp)
	
;; ser_puts1:
;; 	ld a,(hl)
;; 	or a, a
;; 	ret z
	
;; 	call _ser_putchar_asm
;; 	inc hl
;; 	jr ser_puts1
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_WatchDogDisable:
	ld    (WDMOD), #0x00 	; wd disable code
	ld    (WDCR), #0xB1 	; wd disable code
	ret
	
_wd_reset_asm:
	ld    (WDCR), #0x4E 	; wd clear code

.if 0
	; STAR ASIC? Not needed..
	push  bc
	push  iy
	
	ld    b,(BY)
	ld    (BY), #0x01
	ld    iy, #0x4001		
	set   1,(iy)
	nop  
	nop  
	res   1,(iy)
	ld    (BY),b
	
	pop   iy
	pop   bc

.endif
	
	ret
	
	;; Ordering of segments for the linker.
	.area	_HOME
	.area	_CODE
	.area	_INITIALIZER
	.area   _GSINIT
	.area   _GSFINAL

	.area	_DATA
	.area	_INITIALIZED
	.area	_BSEG
	.area   _BSS
	.area   _HEAP

	.area   _CODE

	.area   _GSINIT
gsinit::

	; Default-initialized global variables.
        ld      bc, #l__DATA
        ld      a, b
        or      a, c
        jr      Z, zeroed_data
        ld      hl, #s__DATA
        ld      (hl), #0x00
        dec     bc
        ld      a, b
        or      a, c
        jr      Z, zeroed_data
        ld      e, l
        ld      d, h
        inc     de
        ldir
zeroed_data:

	; Explicitly initialized global variables.
	ld	bc, #l__INITIALIZER
	ld	a, b
	or	a, c
	jr	Z, gsinit_next
	ld	de, #s__INITIALIZED
	ld	hl, #s__INITIALIZER
	ldir

gsinit_next:

	.area   _GSFINAL
	ret
	
	.area _DATA
; __sfr __at	
_ser_irq_flags	=	0xffbf
_ser_char	=	0xffbe
_swi_pc		=       0xffbc
_swi_af         =       0xffba
_ticks16	=	0xffb8
_xflag		=	0xffb7
	
