;***********************************************************************************
; LISTING NO.: 1
;
; FILE NAME: FPQTQY.ASM
; PURPOSE: To provide a FLASH erase, program and verify program
; TARGET DEVICE: HC908QT1/2/4/QY1/2/4
;
; MEMORY USAGE - RAM: 1A0H BYTES
;			ROM: 280H BYTES
;
; ASSEMBLER: CASM08
; VERSION: 1.02
;
; PROGRAM DESCRIPTION:
; This program loads a RAM routine with instructions/data
; located in FLASH memory that:
;	Receives data over the SCI or Port A, bit 0
;	Row-erases FLASH block if necessary
;	Programs FLASH with received data
;	Dumps specified row out comm port
;	Bulk erases device upon command
;
; The program has assembler directives to be able to program in
; both user and monitor modes. In monitor mode, the generated S-record
; file will contain all of the necessary programming routines in RAM. It
; will not have any code that would reside out of RAM. In user mode, load
; routines are incorporated so that it could be contained in a user's
; application. The load routines load the programming routines into RAM and
; from there it looks just like the RAM routine executed in monitor mode.
;
;
; AUTHOR: Grant Whitacre
; LOCATION: Austin, Texas
;
; UPDATE HISTORY:
; REV	AUTHOR		DATE		DESCRIPTION OF CHANGE
; ===	============	========	=====================
; 0.0	GRANT WHITACRE	03/04/98	INITIAL VERSION
; 0.1	GRANT WHITACRE	04/15/98	SECOND VERSION (FP2.ASM)-
;					LOADS ALL RTNS INTO RAM
;					SO RE-ENTRY INTO FLASH IS
;					NOT NECESSARY. ALLOWS
;					REPROGRAMMING OF ENTIRE
;					FLASH ARRAY.
; 0.2	GRANT WHITACRE	06/22/98	CONSOLIDATES PROGRAM TO
;					ALLOW BOTH USER MODE AND
;					MONITOR MODE PROGRAMMING
;					SELECTABLE BY ASSEMBLER
;					DIRECTIVES
;
;
; GENERAL CODING NOTES:
; Bit names are labeled with <port name><bit number> and are
; used in the commands that operate on individual bits, such
; as BSET and BCLR. A bit name followed by a dot indicates
; a label that will be used to form a bit mask.
;
; FOR TESTING, HAD TO ADD AN ASSEMBLER SWITCH (TESTMOD) TO
; KEEP FROM TRIPPING ON AN ILLEGAL MEMORY WRITE BREAK IN
; THE DEBUGGER. OTHER SWITCHES ARE INSTALLED FOR EASE OF
; TESTING.
;
;***********************************************************************************
; ASSEMBLER DIRECTIVES
; (INCLUDES, BASE, MACROS, SETS, CONDITIONS, RAM DEFS, ETC.)
;***********************************************************************************
	       .radix	D		;DEFAULT TO BASE 10 NUMBER DESIGNATION
						        ;Remember: ACTIVE LOW!!!!!!!!!!!!!!!!!!
MONPROG		=	0				;IF SET, ALL (NECESSARY) ROUTINES WILL
						        ;BE ADDRESSED IN RAM INITIALLY; THIS
						        ;VERSION WOULD BE USED AS THE S19 RECORD
						        ;FILE THAT IS DOWNLOADED INTO RAM IN
						        ;MONITOR MODE FOR FLASH PROGRAMMING
;Be sure to manually set addresses of GET_PUT and PUT_BYTE if TESTMOD set!!
TESTMOD		=	0				;SINCE WE GET AN ILLEGAL WRITE ERROR
						        ;USING THE MMDS WHEN WE TRY TO WRITE TO
						        ;EMULATED MEMORY, TESTMOD CAUSES A READ
						        ;FROM FLASH LOCATION INSTEAD OF A WRITE
						        ;TO IT. OF COURSE VERIFY NEVER WORKS
						        ;UNDER THESE CIRCUMSTANCES. TURN OFF
						        ;TEST MODE FOR REAL TARGET EXECUTION.
ERSDTST		=	0		    ;SET TO FORCE A GOOD VERIFICATION OF
						        ;ERASED STATE
;***********************************************************************************
; PORT AND I/O REGISTER EQUATES
;***********************************************************************************
PORTA		=	$$00			;I/O PORT A
PORTB		=	$$01			;I/O PORT B
PORTC		=	$$02			;I/O PORT C
PORTD		=	$$03			;I/O PORT D
PORTE		=	$$07			;I/O PORT E
;***** FLASH CONTROL REGISTER ******************************************************
FLCR		=	$$FE08		;FLASH CONTROL REGISTER
; FDIV1		=	7
; FDIV0		=	6
; BLK1		=	5
; BLK0		=	4
HVEN		=	3
; VERF		=	2			;FOR 908GP20 ONLY
; MARG		=	2			;FOR 908XL36 ONLY
MASS            =       2                       ;FOR 908GP32
ERASE		=	1
PGM		=	0
; FDIV1.          =	$$80
; FDIV0.          =	$$40
; BLK1.		=	$$20
; BLK0.		=	$$10
HVEN.		=	$$08
; VERF.		=	$$04
; MARG.		=	$$04
MASS.           =       $$04
ERASE.          =	$$02
PGM.		=	$$01
;***** BLOCK PROTECTION REGISTER ***************************************************
; FLBPR		=	$$FF80		;FLASH BLOCK PROTECTION REGISTER - This is for HC08HC908GP20
; FLBPR		=	$$FF7E		;FLASH BLOCK PROTECTION REGISTER - This is the right address for HC08HC908GP32
FLBPR   = $$FFBE    ;FLASH BLOCK PROTECTION REGISTER - This is the right address for QT1/2/4 - QY1/2/4
;***********************************************************************************
; APPLICATION-SPECIFIC MEMORY AND I/O EQUATES
;***********************************************************************************
; THE VALUE FOR CPUSPD DRIVES THE FDIV SETTING AND THE BAUD RATE
; PRESCALER FOR THE SCI.
; MAKE SURE THAT CPUSPD IS SET TO 2 IF THE PLL IS TO BE USED.
; IN MONITOR MODE THE BUS FREQUENCY IS 2.45 MHZ, SO USE 2
;;  CPUSPD          =	2			        ;2 = 2.45 MHZ OPER. FREQ.
;;						                    ;4 = 4.92 MHZ, 8 = 8.0 MHZ
; ABS. ADDRESS OF MONITOR ROUTINES COMMENTED OUT IN TEST VERSION
;GET_PUT         =	$$FE97		    ;MON RTN TO GET A BYTE ON - GP20/GP32
GET_PUT         = $$FE8E        ;MON RTN TO GET A BYTE ON - QT1/2/4 QY1/2/4
;						                    ;PTA0 AND ECHO BACK
GETBYTE         = $$2800        ;GETS A BYTE WITHOUT ECHO - QT/QY
; PUT_BYTE	=	$$FEAA		        ;SEND A BYTE OUT PTA0 - GP20/GP32
PUT_BYTE	=	$$FEA1		          ;SEND A BYTE OUT PTA0 - QT1/2/4 QY1/2/4 (non HLC)
RSTVLOC	        =	$$FFFE		    ;RESET VECTOR LOCATION
;
RDVRRNG         = $$2803        ;QT/QY RDVRRNG jump address
ERARNGE         = $$2806        ;QT/QY ERARNGE jump address
PRGRNGE         = $$2809        ;QY4 PRGRNGE jump address
;
; RAM		=	$$50			              ;FIRST ADDRESS OF RAM, ACTUALLY
; 						                    ;$$40 BUT WILL START AT $50 - GP20/32
RAMSTART		    =	$$80			      ;FIRST ADDRESS OF RAM - QT1/2/4 QT1/2/4
;***********************************************************************************
; VARIABLE DEFINITIONS & RAM SPACE USAGE
;***********************************************************************************
;
;           Table 5. Data Structure Location and Content
; Location          Variable Name            Size              Description
; RAM + $08            CTRLBYT              1 byte  Control byte setting erase size
;                                                  CPU speed passed as 4 × fop
; RAM + $09            CPUSPD               1 byte
; RAM + $0A             LADDR              2 bytes  Last address for read a range
; RAM + $0B                                         and program a range
; RAM + $0C              DATA              Variable Variable number of bytes of
;                                                  passed data for programming or
;                                                  verifying a block
; $$88		TRANSFER SIZE			( 1 BYTE)
; $$89-$8A	FIRST ADDRESS TO BE PROGRAMMED( 2 BYTES)
; $$8B		DATA SIZE (DATASIZ)		( 1 BYTE)
; $$8C-$AB	DATA ARRAY			( 32 BYTES)
; $$AC-$EF	RAM PROGRAM			( 72 BYTES)
; $$F0-$FF	STACK				( 16 BYTES)
;
; $$FA      STACK (QT/QY initial value)
; - Call DumpROW/PGM        2 byte (F8)
; - Call DELNUS (from pgm)  2 byte (F6)
          .area	      RAMPGM	(ABS)
		      .org	      RAMSTART
		      .blkb 6     ; Spare ...
FRSADDRT: .blkb 2     ; Temporary start address
RXBLOCK:              ; Address of received block (receive)
XFRSIZE:	       			;NUMBER OF BYTES TO BE TRANSFERRED (receive)
CTRLBYT:  .blkb 1     ; 88 - Control byte setting erase size
FRSTADR:	            ;FIRST ADDR TO BE PROGRAMMED (receive)
CPUSPD:   .blkb 1     ; 89 - CPU speed passed as 4 × fop
FRSTADRL:             ;FIRSR ADDR TO BE PROGRAMMED (LO)
LADDR:    .blkb 1     ; 8A Last address for read a range
                      ;    and program a range
LADDRLO:              ; 8B Last address (lo)                      
DATASIZ:	.blkb	1			;NUMBER OF BYTES TO PROGRAM (receive)
DATARAY:	            ;RESERVE 64 BYTES FOR DATA (receive)
DATA:     .blkb 32    ; 8C Variable Variable number of bytes of
                      ;    passed data for programming or
                      ;    verifying a block
;
;***********************************************************************************
;	Program Algorithm (User Mode Programming)
;	1.	Initialize all variables and ports, PLL (if selected) and
;		SCI.
;	2.	Monitor SCI port for input of block of data to be
;		programmed and the start address. Load RAM with the data
;		array (up to 64 bytes), the start address and length of
;		data array.
;	3.	Transfer the following subroutines to
;		RAM at address RAMPRG
;		A.	LDDATA
;		B.	MAINPRG
;		C.	ERABLK
;		D.	DELNUS
;		E.	PROGRAM
;	4.	Jump to first byte of main RAM program (RAMPRG).
;	5	Execute RAM program MAINPRG and then return to SCI
;		port monitoring loop in RAM.
;
;	Program Algorithm - Monitor Mode Programming
;	1.	Monitor PTA0 for input of block of data to be
;		programmed and the start address. Load RAM with the data
;		array (up to 64 bytes), the start address and length of
;		data array.
;	2.	Execute RAM program MAINPRG and then return to PTA0
;		monitoring loop in RAM.
;***********************************************************************************
;
; START OF PROGRAM
;***********************************************************************************
; START OF THE MONITOR PROGRAM WHICH WE'LL .org IN RAM
START:
;***********************************************************************************
; NAME: LDDATA
; PURPOSE: LOAD RAM WITH USER'S DATA AND START ADDRESS VIA THE SCI;
;          PROGRAMS AND THEN DUMPS DATA THAT IS DOWNLOADED; ONLY DUMPS DATA
;          IN ROW SPECIFIED IF NUMBER OF BYTES TO BE PROGRAMMED (DATASIZ) IS 0.
; ENTRY CONDITIONS:
; EXIT CONDITIONS:
; SUBROUTINES CALLED: PRGFLSH, DUMPROW
; EXTERNAL VARIABLES USED:
; DESCRIPTION: EXECUTED OUT OF RAM
; THE STRUCTURE OF THE DATA RECEIVED IS AS FOLLOWS:
;	LOCATION	DESCRIPTION				RAM LOC.
;	========	==================================	========
;	1		COUNT OF THE TOTAL NUMBER OF		$$40
;			BYTES TO BE SENT (INCL. THAT BYTE)
;	2-3		THE FIRST ADDRESS WHERE THE		$$41-$42
;			FOLLOWING DATA IS TO BE PROGRAMMED
;	4		NUMBER OF BYTES TO BE PROGRAMMED	$$43
;	5-68		ARRAY SPACE FOR DATA TO BE PROGRAMMED	$$44-$83
;
; IF A COUNT IS USED THAT IS GREATER THAN (PROGRAM LENGTH + 1)
; THEN THE ROUTINE WILL HANG AFTER THE LAST PROGRAM BYTE IS SENT.
; CONTINUOUSLY LOOPS LOOKING FOR NEW DATA ON THE SCI. MUST RESET
; AFTER THE LAST ROW DOWNLOAD.
; IF A DATA ARRAY IS RECEIVED WITH A NUMBER OF BYTES TO BE PROGRAMMED OF >= $$80
; THEN PROGRAM WILL CONSTRUE THIS AS A SIGNAL TO ERASE THE ENTIRE ARRAY. THIS
; WAS THE MOST CONVENIENT WAY TO IMPLEMENT BULK ERASE WITHOUT HAVING TO HAVE
; A COMMAND BYTE IN THE DATA STRUCTURE.
;***********************************************************************************
LDDATA:		CLRH
          CLRA
          LDX     #XFRSIZE      ;POINT TO START OF RAM
WAITRX:
          JSR     GET_PUT
CHKCHK:	  CPX     #RXBLOCK      ;IF VALUE OF 1ST BYTE IS ZERO, THEN
          BNE     STORNOW       ;BAD START - KEEP LOOPING FOR NON-
          TSTA                  ;ZERO FIRST BYTE
          BEQ     WAITRX
STORNOW:  STA     ,X            ;STORE THE DATA IN RAM
          INCX                  ;MOVE TO NEXT RAM LOCATION
          DBNZ    *RXBLOCK,WAITRX ;DEC. PROG SIZE CNTR (1st BYTE)
						                    ;IF ENTIRE PROG NOT LODED, CONT.
          LDA     DATASIZ       ;IF SIZE OF DATA TO BE PROGRAMMED
          LDHX    FRSTADR
          STHX    FRSADDRT      ; copies received start in temporary location
          DEC     A             ; decrement count (to address last byte)
          ADD     *FRSTADRL     ; adds start address (lo)
          STA     LADDRLO       ; stores in routine's data struc
          LDA     #0
          ADC     *FRSTADR      ; hi byte sum
          STA     LADDR         ; stores in routine's data struc
          BSR     PROGRAM
DUMP:     BSR     DUMPROW
          BRA     LDDATA        ;Waits for other commands
;***********************************************************************************
; NAME: PROGRAM
; PURPOSE: PROGRAMS A PAGE (8 BYTES) OF FLASH
; ENTRY CONDITIONS: H-X REG. LOADED WITH FIRST ADDRESS TO BE
; PROGRAMMED; Programs data in DATARAY
; EXIT CONDITIONS: NONE
; SUBROUTINES CALLED: DELNUS
; EXTERNAL VARIABLES USED:
; DESCRIPTION: EXECUTED OUT OF RAM
;
;***********************************************************************************
PROGRAM:
           mov  #$0A,CPUSPD   ;fop = 2.4576 MHz in this example
           ldhx FRSADDRT      ;Load beginning address of the
                              ; row to H:X
           jmp  PRGRNGE       ;Call PRGRNGE routine



;            ldhx  FRSADDRT      ;Load beginning address of range
;            mov   #$$0A,CPUSPD   ;2.45 MHZ OPER. FREQ. * 4
;            mov   #$$40,CTRLBYT  ;Select Mass erase operation
;            jmp   ERARNGE       ;Call ERARNGE routine (jumps into)
;***********************************************************************************
; NAME: DUMPROW
; PURPOSE: DUMPS THE ENTIRE 64-BYTE ROW THAT THE START ADDR IS IN
; ENTRY CONDITIONS: H-X CONTAINS THE NEXT ADDR TO BE PROGRAMMED
; EXIT CONDITIONS: NONE
; SUBROUTINES CALLED: ERACHK
; EXTERNAL VARIABLES USED:
; DESCRIPTION: EXECUTED OUT OF RAM
;***********************************************************************************
DUMPROW:    bclr  #0,*PORTA  ;0,$PORTA   ; PTA     ;Initialize data bit to zero PTA0=0
            ldhx  FRSADDRT   ;Load beginning address of range
                            ; to H:X
            clra            ;A=0 to select send-out option
            jmp   RDVRRNG   ;Call RDVRRNG routine
                            ; A contains a checksum value


