



; ----------------= VIEW MEMORY SUBROUTINE =---------------
; displays in 16-byte lines the contents of memory
; between two addresses.
; ---------------------------------------------------------
***
;view_mem_sub: "m_view.asm"
;	Entered from the command line as "> md <addr1> <addr2>"
;	Takes the command line arguments;
;			<addr1> lower address to look from
;			<addr2> upper address to look to
;	It displays the memory contents from the first address rounded down to
;	The second address rounded up. There is no default case.
;	Reg Input:
;		None
;	Reg Output:
;		None
***

* This is awful code to debug.  It's uncommented and hard to follow. (JS)

* Get arguments from command buffer using parse_address routine (JS)
* They end up X=high, Y=low (JS)
view_mem_sub:
	jsr		parse_address		; returns low address in X
	cmpb		#$ff			; error?
	lbeq		vms_error		; if there was an error, print it and leave
	stx		tempw			; store it for later	

	jsr		parse_address		; returns high addr in X
	cmpb		#$ff			; error?
	bne		vms_two_arg		; if there was an error, print it and leave

* reaching this means only one argument was received - so, set up regs to display only one line (JS)
* need to set up X = low pointer, tempw = high pointer for print routine (JS)
	ldx		tempw			; save low address into X
	ldd		tempw			; load low address for manipulation
	orab		#$0f			; force D to be XXXF
	addd		#$01			; move d to next line, for compatibility with existing routine
	std		tempw			; put max into tempw for print routine
* now find minimum address
	xgdx					; move low address into D for manipulation
	andb		#$f0			; lower limit word should be made XXX0
	xgdx					; move lower limit into X for print routine

	bra		vms_beg_prn		; skip the mess - end (JS) addition
* The existing code is a pile of dung- i bet this code is more efficient (JS)

vms_two_arg:
	ldy		tempw			; Y is now the low addr
	
						; at this point, the low address is in tempw
						; the low address is in Y
						; and the high address is in X

*						* he really does not need to store the low address
*						* in tempw again, he just loaded y from tempw

* This little routine leaves if 1st arg > 2nd arg (JS)
	sty		tempw			; put it into a temp var to compare it to X
	cpx		tempw			; compare X (high addr) to tempw (low addr)
	ble		vms_done		; if high addr < low addr then its an error!

	stx		tempw			; put X (high addr) in var for later

*						* he puts y into x here, can be done better
*						* this entire section is really weird. I think it
* 						* can be done in a MUCH better way.

* This mess of code makes x = high, D = low (JS)
	pshy
	pulx					; X is now the low addr

	pshx					; yes, I realize this is dumb but I have to do it

	ldx		tempw			; get high address
	puld					; D is low addr
		
						; so now, D is the low address
						; and X is the high address.
				

	;jsr		print_address		; DEBUG

* 
						; round down the lower address
* OK, round down the low addr - fair enough (JS)
	andb		#%11110000		; by making the lower nibble 0
	xgdx					; X <-> D
	pshd					; i cannot figure out why this disapeared (JS)
						; round up the upper address (in D right now) 	pshd					; stores the upper address on the stack
						; lower address is in X

*						* this part seems AWFUL. try to improve
*						*  REALLY need to take this horrid part out

* This is really dumb? I suppose it's rounding up the high address (JS)
	andb		#%00001111		; kills upper nibble of B
	ldaa		#$0f			; makes A into $0f
	sba					; subtracts the two, puts remainder in A
	adda 		#1			; adds one to A 

	psha					; such a damn hack
	pulb					; puts A into B

	clra					; clears A
	std		tempw2			; stores D
	puld					; gets back the old D address
	addd		tempw2			; adds the difference to D, rounding it up

	std		tempw			; store D -- the upper address
						; X is still the lower address
* At this point, tempw should contain the end point, and x has the current
* pointer (JS)

*						* not sure why this is here
	;xgdx					; D is now the lower and X the upper

vms_beg_prn:
	ldy		#newline		; loads new line string
	jsr		print_string		; prints new line string	pshd

	pshx
	ldy		#md_first_line
	jsr		print_string
	pulx

loop1:
	cpx		tempw			; if X is now equal to the high value,
	beq		vms_done		; exit out of the code.


	jsr		print_address		; print_address prints what is in the X address, which
						; will start off as the low address and then be incremented
						; see "serial.asm"
	ldaa		#':'			; loads a ':' character to be printed
	jsr		put_char		; prints the character. see "serial.asm"
	ldaa		#32			; loads a space to be printed
	jsr		put_char		; prints the space. see "serial.asm"

loop2:
	ldaa		0,x			; load the number at the location
	jsr		print_number		; prints the number in A. see "serial.asm"
	ldaa		#32			; loads a space character
	jsr		put_char		; prints the space

	pshx					; puts x onto d
	puld					;

	andb		#%00001111		; clips off the upper nibble of B
	cmpb		#$0F			; if B is now FF, needs to move to the next line
	beq		vms_newline		; so it prints a new line
	bra		vms_blah		; otherwise goes to the next number
vms_newline:
	ldy		#newline		; loads new line string
	jsr		print_string		; prints new line string
	
	inx					; increments x to the next number
	bra		loop1			; then goes to the next line
vms_blah:
	inx					; increments x to the next number
	bra		loop2			; goes to print the next number
vms_done:
	rts					; returns from routine
vms_error:
	ldy		#error_msg		; loads address of error message
	jsr		print_string		; prints error message
	rts					; returns from routine
