While there have been numerous routines for filling, moving and comparing memory, I eventually integrated all of these into a single set of routines. I later added the programming of the Atmel EEPROM into this as well. Granted, it's not going to be as fast as some other dedicated routines, but one of the goals was to make it flexible and relatively small in memory size. The Copy/Fill/Move functions all enter at the CPMVFL label, while the Program EEPROM enters at the PROGEE label.
Code:
;[C] Compare routine: one memory range to another and display any addresses which do not match
;[M] Move routine: uses this section for parameter input, then branches to MOVER below
;[F] Fill routine: uses this section for parameter input but requires a fill byte value
;[CTRL-P] Program EEPROM: uses this section for parameter input and to write the EEPROM
;Uses source, target and length input parameters. errors in compare are shown in target space
FM_INPUT LDA #$05 ;Send "val: " to terminal
JSR HEX2 ;Use short cut version for print and input
TAX ;Xfer fill byte to X reg
JSR CONTINUE ;Handle continue prompt
;
;Memory fill routine: parameter gathered below with Move/Fill,
; then a jump to here Xreg contains fill byte value
FILL_LP LDA LENL ;Get length low byte
ORA LENH ;OR in length high byte
BEQ DONEFILL ;Exit if zero
TXA ;Get fill byte
STA (TGTL) ;Store in target location
JSR UPD_TL ;Update Target/Length pointers
BRA FILL_LP ;Loop back until done
;
;Compare/Move/Fill memory operations enter here, branches as required
CPMVFL STA TEMP2 ;Save command character
JSR B_CHROUT ;Print command character (C/M/F)
CMP #$46 ;Check for F - fill memory
BNE PRGE_E ;If not continue normal parameter input
LDA #$03 ;Get msg " addr:"
BRA F_INPUT ;Branch to handle parameter input
;
;EEPROM write operation enters here
PROGEE LDA #$21 ;Get PRG_EE msg
JSR PROMPT ;send to terminal
STZ TEMP2 ;Clear (Compare/Fill/Move) / error flag
;
PRGE_E LDA #$06 ;Send " src:" to terminal
JSR HEX4 ;Use short cut version for print and input
STA SRCL ;Else, store source address in variable SRCL,SRCH
STY SRCH ;Store high address
LDA #$07 ;Send " tgt:" to terminal
F_INPUT JSR HEX4 ;Use short cut version for print and input
STA TGTL ;Else, store target address in variable TGTL,TGTH
STY TGTH ;Store high address
LDA #$04 ;Send " len:" to terminal
JSR HEX4 ;Use short cut version for print and input
STA LENL ;ELSE, store length address in variable LENL,LENH
STY LENH ;Store high address
;
; All input parameters for Source, Target and Length entered
LDA TEMP2 ;Get Command character
CMP #$46 ;Check for fill memory
BEQ FM_INPUT ;Handle the remaining input
CMP #$43 ;Test for Compare
BEQ COMPLP ;Branch if yes
CMP #$4D ;Check for Move
BEQ MOVER ;Branch if yes
;
PROG_EE LDA #$22 ;Get warning msg
JSR PROMPT ;Send to console
JSR CONTINUE2 ;Prompt for y/n
;
;Programming of the EEPROM is now confirmed by user. This routine will copy the core move and test
; routine from ROM to RAM, then call COMPLP to write and compare. As I/O can generate interrupts
; which point to ROM routines, all interrupts must be disabled during the program sequence.
;
;Send message to console for writing EEPROM
LDA #$23 ;Get write message
JSR PROMPT ;Send to console
OC_LOOP LDA OCNT ;Check output buffer count
BNE OC_LOOP ;Loop back until buffer sent
;
;Xfer byte write code to RAM for execution
JSR XFER_BYTE_WRT ;Xfer byte write code to Page Zero
;
;Wait for 1/2 second for RAM/ROM access to settle
LDA #$32 ;Set milliseconds to 50(*10 ms)
JSR B_SET_DLY ;Set Delay parameters
JSR B_EXE_MSDLY ;Call delay for 1/2 second
;
PROG_EEP SMB7 TEMP2 ;Set EEPROM write active mask
JSR COMPLP ;Call routine to write/compare
BBR6 TEMP2,PRG_GOOD ;Skip down if no error
LDA #$25 ;Get Prog failed message
BRA BRA_PRMPT ;Branch to Prompt routine
;
PRG_GOOD LDA #$24 ;Get completed message
BRA_PRMPT JMP PROMPT ;Send to console and exit
;
COMPLP LDA LENL ;Get low byte of length
ORA LENH ;OR in High byte of length
BEQ QUITMV ;If zero, nothing to compare/write
BBR7 TEMP2,SKP_BURN ;Skip burn if bit 7 clear
JSR BURN_BYTE ;Else Burn a byte to EEPROM
SKP_BURN LDA (SRCL) ;Else load source
CMP (TGTL) ;Compare to source
BEQ CMP_OK ;If compare is good, continue
;
SMB6 TEMP2 ;Set bit 6 of TEMP2 flag (compare error)
JSR SPC2 ;Send 2 spaces
JSR DOLLAR ;Print $ sign
LDA TGTH ;Get high byte of address
LDY TGTL ;Get Low byte of address
JSR PRWORD ;Print word
JSR SPC ;Add 1 space for formatting
;
CMP_OK JSR UPD_STL ;Update pointers
BRA COMPLP ;Loop back until done
;
;Parameters for move memory entered and validated, now make decision on which direction
; to do the actual move, if overlapping, move from end to start, else from start to end.
MOVER JSR CONTINUE ;Prompt to continue move
SEC ;Set carry flag for subtract
LDA TGTL ;Get target lo byte
SBC SRCL ;Subtract source lo byte
TAX ;Move to X reg temporarily
LDA TGTH ;Get target hi byte
SBC SRCH ;Subtract source hi byte
TAY ;Move to Y reg temporarily
TXA ;Xfer lo byte difference to A reg
CMP LENL ;Compare to lo byte length
TYA ;Xfer hi byte difference to A reg
SBC LENH ;Subtract length lo byte
BCC RIGHT ;If carry is clear, overwrite condition exists
;Move memory block first byte to last byte, no overlap condition
MVNO_LP LDA LENL ;Get length low byte
ORA LENH ;OR in length high byte
BEQ QUITMV ;Exit if zero bytes to move
LDA (SRCL) ;Load source data
STA (TGTL) ;Store as target data
JSR UPD_STL ;Update Source/Target/Length variables
BRA MVNO_LP ;Branch back until length is zero
;
;Move memory block last byte to first byte avoids overwrite in source/target overlap
RIGHT LDX LENH ;Get the length hi byte count
CLC ;Clear carry flag for add
TXA ;Xfer High page to A reg
ADC SRCH ;Add in source hi byte
STA SRCH ;Store in source hi byte
CLC ;Clear carry for add
TXA ;Xfer High page to A reg
ADC TGTH ;Add to target hi byte
STA TGTH ;Store to target hi byte
INX ;Increment high page value for use below in loop
LDY LENL ;Get length lo byte
BEQ MVPG ;If zero no partial page to move
DEY ;Else, decrement page byte index
BEQ MVPAG ;If zero, no pages to move
MVPRT LDA (SRCL),Y ;Load source data
STA (TGTL),Y ;Store to target data
DEY ;Decrement index
BNE MVPRT ;Branch back until partial page moved
MVPAG LDA (SRCL),Y ;Load source data
STA (TGTL),Y ;Store to target data
MVPG DEY ;Decrement page count
DEC SRCH ;Decrement source hi page
DEC TGTH ;Decrement target hi page
DEX ;Decrement page count
BNE MVPRT ;Loop back until all pages moved
QUITMV RTS ;Return to caller
;
;Xfer byte write code to RAM for execution
XFER_BYTE_WRT LDX #BYTE_WRE-BYTE_WRS+1 ;Get length of byte write code
BYTE_XFER LDA BYTE_WRS-1,X ;Get code
STA BURN_BYTE-1,X ;Write code to RAM
DEX ;Decrement index
BNE BYTE_XFER ;Loop back until done
RTS ;Return to caller
;
BYTE_WRS SEI ;Disable interrupts
LDA (SRCL) ;Get source byte
STA (TGTL) ;Write to target byte
LDA (TGTL) ;Read target byte (EEPROM)
AND #%01000000 ;Mask off bit 6 - toggle bit
BYTE_WLP STA TEMP3 ;Store in Temp location
LDA (TGTL) ;Read target byte again (EEPROM)
AND #%01000000 ;Mask off bit 6 - toggle bit
CMP TEMP3 ;Compare to last read (toggles if write mode)
BNE BYTE_WLP ;Branch back if not done
CLI ;Re-enable interrupts
BYTE_WRE RTS ;Return to caller
;
The other support routines are here:
Code:
;Routines to update pointers for memory operations. UPD_STL subroutine: Increments Source
; and Target pointers. UPD_TL subroutine: Increments Target pointers only, then drops into
; decrement Length pointer. Used by multiple Memory operation commands.
UPD_STL INC SRCL ;Increment source low byte
BNE UPD_TL ;Check for rollover
INC SRCH ;Increment source high byte
UPD_TL INC TGTL ;Increment target low byte
BNE DECLEN ;Check for rollover
INC TGTH ;Increment target high byte
;
;DECLEN subroutine: decrement 16-bit variable LENL/LENH
DECLEN LDA LENL ;Get length low byte
BNE SKP_LENH ;Test for LENL = zero
DEC LENH ;Else decrement length high byte
SKP_LENH DEC LENL ;Decrement length low byte
RTS ;Return to caller
;
There's a few other routines for confirming the write (JSR CONTINUE, JSR HEX, JSR PROMPT, etc.) and for printing mismatched locations on Compare (JSR PRWORD) but overall, it's not too bad considering everything it does, 302 bytes for the above.