;*
; memmap.mac
;
; Copyright (c) 2002 by Megan Gentry
;
; Abstract:
; This program is designed to locate and report ranges
; of memory in the low 64kb which can be referenced on
; a PDP-11 and report them to the terminal.
;
; The program was designed to be used to map the memory
; on a proto desktop portable pdp-11 which only has a
; 4 line x 40 character LCD screen, which is why it
; displays 3 lines and waits for character input to
; proceed.
;-
.asect
. = 0
reset ;reset the world
br start ; and jump to the code
start: mov #m.head,r0 ;Announce us
call ttostr ; ...
clr r1 ;R1 = Location under test
mov #2,r4 ;R4 = Count of lines before wait
10$: mov r1,r2 ;R2 = Low limit of memory range
; Here we look for the end of region of memory which exists
; (we assume that location 0 works)
20$: clc ;Clear carry (NXM will set carry)
tstb @r1 ;Test the location
bcs 30$ ;If it is non-existant...
mov r1,r3 ;R3 = Hi limit of memory range
inc r1 ;Update location under test
bne 20$ ; !loop!
br 100$ ;When we wrap in 64kb, we're done
30$: call report ;Report the range (R2,R3)
; Here we start looking for the start of the next region of
; responding memory.
40$: clc ;Clear carry (NXM will set carry)
tstb @r1 ;Test the location
bcc 10$ ;We've found memory...
inc r1 ;Update location under test
bne 40$ ; !loop!
; br 100$ ;When we wrap in 64kb, we're done
100$: call report ;Report the range (R2,R3)
110$: halt ;Stop the world...
br 110$ ; and don't let it restart...
report: mov r2,r0 ;Print out region low address
call octout ; ...
mov #m.del,r0 ;Print a delimiter
call ttostr ; ...
mov r3,r0 ;Print out region hi address
call octout ; ...
movb #11,r0 ;Another delimiter
call ttochr ; ...
mov r3,r0 ;Determine number of words (octal)
sub r2,r0 ; ...
inc r0 ; ...
call octout ;Print it out
mov #m.crlf,r0 ;On to next line
call ttostr ; ...
dec r4 ;Should we delay a bit?
bgt 10$ ;Nope...
mov #m.pak,r0 ;Yes, print out a prompt
call ttostr ; ...
call ttichr ;Get any character (where is that
; found on a keyboard?)
mov #m.crlf,r0 ;On to next line
call ttostr ; ...
mov #3,r4 ;Reset the line count
10$: return
octout: mov r0,-(sp) ;Save value
bic #177770,@sp ;Isolate an octal digit
add #^O60,@sp ;Make it printable
ror r0 ;Shift right
asr r0 ; three bits
asr r0 ; for next digit
beq 10$ ;If done... print out
call octout ;Not yet, recurse !!
10$: mov (sp)+,r0 ;Print a digit
call ttochr ; ...
return ;Unwind the stack and return
ttostr: mov r1,-(sp) ;Save R1 for awhile
mov r0,r1 ;Save pointer to string
10$: movb (r1)+,r0 ;Get a character of string
beq 20$ ;If null, add a <CR><LF>
cmpb r0,#200 ;If a <200>, we're done
beq 30$ ; ...
call ttochr ;Print the character
br 10$ ; !loop!
20$: movb #15,r0 ;output a <CR><LF> on a <NUL>
call ttochr ; ...
movb #12,r0 ; ...
call ttochr ; ...
30$: mov (sp)+,r1 ;Restore previously saved R1
return
ttochr: tstb @#177564 ;Terminal ready for output?
bpl ttochr ;Nope...
movb r0,@#177566 ;Yes... output character
return
ttichr: tstb @#177560 ;Has a key been typed?
bpl ttichr ;Nope...
movb @#177562,r0 ;Yes... get it...
return
nxmtrp: bis #1,2(sp) ;Set PSW<C> for return
rti ; from interrupt
m.head: .asciz /Memory Map:/
m.del: .ascii / - /<200>
m.pak: .ascii /Press any key to continue.../<200>
m.crlf: .byte 0
.even