           ttl     Physical Memory Examine and Change
*
.   physical extended memory examine routines
.
pemex      proc

ascii      loc     16     16 bytes     ascii data buffer
segment    loc     1       8 bits      active segment number
offset     loc     2      12 bits      active segment offset
limit      loc     3      20 bits      extended address limit
count      loc     1       1 byte      local count field
digit      loc     1       1 byte      temporary used by hex routines

*
.   allocate local variables and get address from keyboard
.
memory:    mark                        mark the input stack
           aloc                        allocate local variables
           bsr     getaddr             get an input address
           bcs     exit                if no word, just exit
           sta     segment             stuff the segment number
           stx     offset              then stuff the offset
*
.   active memory loop - display address
.
nextaddr   bsr     showaddr            display address
           bsr     paddr               point to the address
           beq     havedata            if data exists, we have byte
           bsr     outch               output a trailing whatever
*
.   we have data address -- do something with it
.
havedata   bsr     showbyte            display memory byte
           bsr     getbyte             get a replacement byte
           bcc     alter               if valid hex, go alter byte
*
.   decide what flavor of non-alter command we have
.
           cmpa    #"^"                back up address
           beq     altdec              if so, decrement active address
           cmpa    #cr                 see if carriage return
           bne     altinc              anything else, increment
exit       exit
*
.   alter memory byte
.
alter      sta     0,x                 store byte into memory
altinc     bsr     incaddr             increment active address
           bra     nextaddr            and continue
altdec     bsr     decaddr             decrement active address
           bra     nextaddr
*
.   generate a pointer to a byte of memory
.
paddr      lda     segment             get msp of active address
           sta     datbox+tfr_seg      and map into the transfer buffer
           sta     xbpage              also stuff transfer buffer page
           ldd     offset              get the segment offset value
           ora     #tfr_seg<<4         convert into an address
           pshs    d                   save this address on stack
*
.   see if the byte exists (or if we think it does)
.
           lda     segment             get msp of active address
           cmpa    #nomap>>8
           beq     pnope               black hole?
           ldb     corecnt             pick up the core count
           addb    #segadr             add in number of segments for sys
           ldx     #sysmap             point at the system map
*
.   search system and core maps for such a page
.
psrch      cmpa    0,x+                compare against the core map
           beq     pexit               if equal, memory exists
           decb                        decrement the core count
           bne     psrch               loop if not there
pnope      lda     #"*"                load a snowflake for exit
pexit      ret     x
*
.   increment the active address
.
incaddr    ldd     offset              get lower 12 bits of address
           addd    #1                  add one to generate new address
           cmpd    #segsize            compare against segment size limit
           blo     setaddr             if lower, go set the address
           inc     segment             and increment msp of address
           bra     setaddr             go set the address
*
.   decrement memory address
.
decaddr    ldd     offset              get address segment offset
           subd    #1                  decrement it by one
           bcc     setaddr             if no carry, go set the address
           dec     segment             decrement msp of address
setaddr    anda    #segsize-1>>8       mask the segment offset value
           std     offset              stuff back the active address
           rts
*
.   display the contents of a data byte
.
showbyte   lda     0,x                 pick up the data byte
           bsr     hexbyte             convert to hex format
           bra     outsp               and exit, with the byte
*
.   display an address and stuff
.
showaddr   ldx     #newaddr            point to line
           bsr     pdata               and get a neweth line
           lda     segment             get current active address
           bsr     hexbyte             convert first two digits to hex
           ldd     offset              get current offset address
           bsr     hexoff              display last three digits
           bra     outsp               follow with trailing space
*
.   examine function displays blocks of memory
.
examine:   mark                        mark the stack pointer
           aloc                        allocate local variables
           bsr     getaddr             get an address
           bcs     exit
           sta     segment             store the segment address
           stx     offset              and the offset address
           ldb     offset+1            get lowest order byte
           anda    #$F0                strip off the low order four bits
           stb     offset+1            stuff back into the offset
*
.   get the upper limit address
.
           ldx     #hyphen             output a separator
           bsr     pdata
           bsr     getaddr             get the limit address
           bcs     exit
           sta     limit               store the limit address
           stx     limit+1
*
.   display the object code, 16 bytes at a time
.
doline     bsr     showaddr            display the address
           bsr     sixteen             display sixteen bytes
           bsr     incheck             check for interrupt
           bne     exexit              if so, just exit now
*
.   if no interrupt, handle next piece of the fur pie
.
           lda     segment             pick up segment number
           cmpa    limit               compare against limit
           blo     doline              continue if not equal
           ldd     offset              pick up offset value
           cmpd    limit+1             compare to limit value
           bls     doline              if lower, also continue
exexit     exit
*
.   display sixteen bytes of memory in hex
.
sixteen    bsr     outspp              output spaces and set count
dobytes    bsr     paddr               search out the byte
           bsr     showbyte            display the byte in hex
           lda     0,x                 get back the destroyed byte
           sta     0,y+                then store into ascii string
           bsr     incaddr             increment the memory address
           dec     count               decrement the byte count
           bne     dobytes             loop until done
*
.   then convert the same data to ASCII
.
           bsr     outspp              output another two spaces
inascii    lda     0,y+                pick up the next byte
           cmpa    #" "                compare to the lower limit
           blo     notascii            nope, not ascii character
           cmpa    #"~"                check the upper limit
           bls     doascii             if so, valid ascii character
notascii   lda     #"."                substitute a period
*
.   display the data byte
.
doascii    bsr     outch               output to flex routine
           decb                        decrement the count
           bne     inascii             loop if not done
           rts
*
.   set up for ascii display of bytes
.
outspp     ldb     #16                 load the count field
           stb     count               stuff into a temporary
           leay    ascii               point to ascii data string
           bsr     outsp               output a single space
           bra     outsp               and then another one

newaddr    fcb     cr                  new address field
hyphen     fcb     " - ",etx           address separators

           end
