home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
debug
/
wadesrc.lbr
/
MONSYM.AZM
/
MONSYM.ASM
Wrap
Assembly Source File
|
1988-06-19
|
10KB
|
652 lines
title 'Symbol Handler for Monitor'
;
; Last Edited 84-07-03 Wagner
;
; Copyright (c) 1984 by
;
; Thomas Wagner
; Patschkauer Weg 31
; 1000 Berlin 33
; West Germany
;
; Released to the public domain 1987
;
public rdsymbol,rdsymname,defsymbol,killsymbol,dissymbols,wrsymbol
public syminit,wsymbols,rsvsym
public symstart,symtop
;
extrn cmderr,next
extrn wrchar,wrhex,space,space2,crlf,wrstr
extrn stestch,sgetch,isdigit,isletter
extrn regsp,maxval,topval
extrn puthexbyte,putfilch
extrn mul16,div16,wrdec
;
;
;
maclib z80
maclib monopt
;
;
symlen equ 8
;
;
;
; Symbol Storage:
;
; | debugger
; --------------------------- high mem
; symstart --> | Symbols: Top down
; | N }
; | A }
; | M }} "symlen" bytes per name
; | E }
; | addr hi
; | addr lo
; | ...
; | ...
; symtop --> | last symbol
; | ...
; | free space
; ----------------------------- low mem
; currsx --> | RSX-header (page aligned)
; -----------------------------
; | default stack
; | ...
; -----------------------------
; maxval --> | top of program
;
;
;------------------------------------------------------------------------------
;
; rdsymbol: read symbol value
;
; exit: HL = symbol value
; Carry set if not a symbol or if symbol is undefined
;
rdsymbol:
cpi '.'
stc
rnz ; ret if no symbol lead-in
pushix
call sgetch
call rdsymname
jrc rdsym10
jrnz rdsym20
stc
rdsym10:
popix
ret
;
rdsym20:
pop d
mov d,m
dcx h
mov e,m
xchg
ret
;
;
; rdsymname: read symbol name
;
; exit: HL = symbol table pointer
; carry set if no symbol name found
; A = 0 if new (undefined) symbol
;
rdsymname:
call stestch
call isdigit
cmc
rc ; no symbol if first is digit
call issymch
rc
;
lhld symtop
dcx h
dcx h
mvi b,symlen
;
rdsymn10:
call sgetch
dcr b
inr b
jrz rdsymn15
mov m,a
dcx h
dcr b
rdsymn15:
call stestch
call issymch
jrnc rdsymn10
;
inr b
rdsymn20:
mvi m,' '
dcx h
djnz rdsymn20
;
; symbol read, now search in table
;
lded symstart
symsrch:
lhld symtop
xra a
dsbc d
jrz symsrchfnd
dcx d
dcx d
lhld symtop
mvi b,symlen
dcx h
dcx h
symcmp:
ldax d
cmp m
jrnz symnomatch
dcx h
dcx d
djnz symcmp
mvi a,0ffh ; signal exists
;
lxi h,symlen+2
dad d
ora a
ret
;
symsrchfnd:
xchg
ret
;
symnomatch:
dcx d
djnz symnomatch
jr symsrch
;
;
issymch:
ora a
stc
rz
call isletter
rnc
call isdigit
rnc
push h
push b
lxi h,symchtab
lxi b,lsymchtab
ccir
pop b
pop h
stc
rnz
ora a
ret
;
symchtab db '?@$.'
lsymchtab equ $-symchtab
;
;
;------------------------------------------------------------------------------
;
; defsymbol: define symbol
;
; entry: HL = name pointer
; DE = address
;
defsymbol:
push d ; save address value
mov m,d
dcx h
mov m,e ; store value
inx h ; pointer again
push h
lbcd symtop
ora a
dsbc b ; already in the table ?
pop h
jrz defsym01 ; ok if not
;
push h
lded symtop
lxi b,symlen+2
lddr ; move to symtop
sded symtop ; temporarily set new symtop
pop h
call killsymbol ; delete at old place
lhld symtop
lxi d,symlen+2
dad d
shld symtop ; reset symtop to previous value
mov b,h
mov c,l
;
defsym01:
lxi d,3*(symlen+2)+26 ; safety margin
lhld currsx ; bottom of symbol memory
dad d ; + safety
ora a
dsbc b ; - symtop
cnc expand ; expand if (currsx + margin) >= symtop
;
pop h ; address value into HL
call findaddr ; find the value
xchg
lhld symtop
ora a
dsbc d
jrnz defsym10 ; branch if not at top
lxi h,-(symlen+2)
dad d
shld symtop ; set new top
ret
;
defsym10:
push d ; save elem addr
lhld symtop
lxi b,-(symlen+2)
dad b ; new symtop
shld symtop
xchg
ora a
dsbc d ; element addr - new top = length to move
mov b,h ; length into BC
mov c,l
lxi h,-(symlen+2)
dad d ; move destination = new top - symlen+2
xchg
inx b ; one byte more
ldir ; make space for new elem
pop d ; elem addr
lhld symtop ; new symtop contains new elem
lxi b,symlen+2
lddr ; move into place
ret
;
;
; findaddr: find symbol corresponding to "addr"
;
; entry: HL = address
;
; exit: HL = symbol pointer
; Carry set if not found
;
findaddr:
mov b,h
mov c,l
lhld symstart
findcmp:
xchg
lhld symtop
ora a
dsbc d
xchg
stc
rz ; ret if end of table
mov d,m
dcx h
mov e,m
inx h
ora a
xchg
dsbc b ; elem-addr - addr
xchg
jrc findcmp10
rz
stc
ret ; ret on match or elem-addr > addr
findcmp10:
lxi d,-(symlen+2)
dad d
jr findcmp
;
;
; killsymbol: delete symbol from the table
;
; entry: HL = symbol pointer
;
killsymbol:
push h
lded symtop
ora a
dsbc d ; symptr - top = remaining length
pop d
rz ; ret if at top
mov b,h
mov c,l
mov h,d
mov l,e
push d
lxi d,-(symlen+2)
dad d
pop d
lddr
lhld symtop
lxi d,symlen+2
dad d
shld symtop
ret
;
;
; wrsymbol: write symbol corresponding to "addr"
;
; entry: HL = address
; A = display code:
; 0 -> display spaces only
; '.' -> display '.name'
; '/' -> display '/name'
; ':' -> display 'name:'
;
wrsymbol:
ora a
jrz wrspaces
push psw
call findaddr
jrc wrspaces2
dcx h
dcx h
pop psw
cpi ':'
cnz wrchar ; display dot or slash
jmp writesym
;
;
wrspaces2:
pop psw
wrspaces:
mvi b,symlen+1
wrspa2:
call space
djnz wrspa2
ret
;
;
writesym:
mvi b,symlen
mov c,a
writesym2:
mov a,m
cpi ' '
jrz writesym3
call wrchar
dcx h
djnz writesym2
mov a,c
cpi ':'
rnz
jmp wrchar
;
writesym3:
mov a,c
cpi ':'
cz wrchar
writesym4:
call space
dcx h
djnz writesym4
ret
;
;
; dissymbols: display symbol table
;
;
dissymbols:
lxi h,defstr
call wrstr
lhld symstart
lded symtop
ora a
dsbc d ; used space
lxi d,symlen+2
call div16
mvi a,' '
call wrdec
call space2
lxi h,freestr
call wrstr
lhld symtop
lded currsx
ora a
dsbc d
lxi d,-(3*(symlen+2)+26)
dad d
lxi d,symlen+2
call div16
mvi a,' '
call wrdec
call crlf
call crlf
;
lhld symstart
dissymlin:
mvi b,80/(symlen+7)
dissymloop:
xchg
lhld symtop
ora a
dsbc d
xchg
jz crlf
push b
mov a,m
call wrhex
dcx h
mov a,m
call wrhex
dcx h
call space
call writesym
call space2
pop b
djnz dissymloop
call crlf
jr dissymlin
;
;
defstr db 'Defined: ',0
freestr db 'Free: ',0
;
;
; wsymbols: write symbol table to file
;
;
wsymbols:
lhld symstart
fwsymline:
mvi b,4
fwsymloop:
xchg
lhld symtop
ora a
dsbc d
xchg
jrz fwsymend
push b
push h
mov a,m
call puthexbyte
pop h
dcx h
mov a,m
push h
call puthexbyte
mvi a,' '
call putfilch
pop h
dcx h
mvi b,symlen
fwsym10:
mov a,m
cpi ' '
jrz fwsym20
push b
push h
call putfilch
pop h
pop b
dcx h
djnz fwsym10
jr fwsym30
;
fwsym20:
dcx h
djnz fwsym20
fwsym30:
pop b
dcr b
jrz fwsym40
push b
push h
mvi a,09h
call putfilch
pop h
pop b
jr fwsymloop
;
fwsym40:
push h
mvi a,0dh
call putfilch
mvi a,0ah
call putfilch
pop h
jr fwsymline
;
;
fwsymend:
mov a,b
cpi 4
rz
jr fwsym40
;
;
;
; expand: expand symbol table by default size
;
; entry: -
;
;
; rsvsym: reserve symbol table space
;
; entry: HL = number of symbols to reserve
;
rsvsym:
lxi d,symlen+2
call mul16 ; required symbol table space
lxi d,0ffh
dad d
mvi l,0 ; round to next page boundary
jr expand10
;
expand:
lxi h,512
;
expand10:
push h
lxi d,512
dad d
lded maxval ; max addr read until now
dad d ; max + sym-space + 512 bytes for safety
xchg
lhld currsx
ora a
dsbc d ; currsx - (max + n)
jc cmderr ; error if max > curr
;
pop d
lxi h,0
dsbc d ; complement symbol table space
push h
lded regsp ; current stack ptr
lhld currsx ; RSX base
ora a
dsbc d ; stack length
jrc setstack ; no stack copying if SP > RSX
jrz setstack ; no copying if equal
mov a,h
cpi 2
jrnc copyrsx ; no stack copying if difference >= 512
mov b,h
mov c,l ; save length
pop h
push h
dad d ; SP - space
xchg ; copy from SP to (SP-space)
ldir ; move down the stack
;
setstack:
lhld regsp
pop d
push d
dad d ; SP - space
shld regsp ; set new SP
;
copyrsx:
lded currsx ; current RSX header
pop h
dad d ; - space
shld currsx ; new RSX header
dcx h
shld topval
inx h
xchg ; move from old RSX to (RSX-space)
push d
lxi b,26
ldir ; move down the RSX header
pop h
lxi d,6
dad d ; new BDOS entry in RSX header
shld 6 ; set jump location
;
IF cpm3
xchg ; save new RSX entry address
lxi h,4
dad d ; next field
push d
mov e,m
inx h
mov d,m ; addr of next RSX
lxi h,6
dad d ; point to prev-field in next RSX
pop d
mov m,e ; set prev-field
inx h
mov m,d
sded mxtpa
lxi d,scbpb
mvi c,49 ; set scb
jmp next ; set new MXTPA field
;
scbpb db 62h ; MXTPA offset
db 0feh ; set word value
mxtpa dw 0
;
ELSE
;
ret
;
ENDIF
;
;
;
; syminit: initialise symbol space
;
; entry: HL = RSX base
;
syminit:
shld currsx
inx h
shld symtop
shld symstart
jmp expand
;
;
dseg
;
currsx ds 2
symtop ds 2
symstart ds 2
;
end