Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

2735 lines
148 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 1
title 'DDT86 1.1 10/2/81'
;
; modified 5/14/81 R. Silberstein
; modified 6/15/81 R. Silberstein
; modified 8/12/81 R. Silberstein
; modified 9/6/81 R. Silberstein
; modified 9/16/81 R. Silberstein
; modified 10/1/81 R. Silberstein
;
;
; *****************************************
; * *
; * D D T 8 0 8 6 - 8 0 8 8 *
; * *
; *****************************************
;
0000 debug equ 00h ;if set, use direct bios calls for console io
;
0100 ddt_org equ 100h ;origin of this module
1400 lasmorg equ ddt_org+1300h ;origin of disassembler
2300 asmorg equ ddt_org+2200h ;origin of assembler
;
cseg
;
org 005ch
005C fcb rb 10h
006C fcb2 rb 14h
0080 buff rb 80h
;
org lasmorg
1400 B80000 disem: mov ax,0
1403 C20400 ret 4 ;remove parameters from stack
;
org asmorg
2300 B80000 assem: mov ax,0
2303 C20400 ret 4 ;remove parameters from stack
;
org ddt_org
0100 E94A01 024D jmp ddt86 ;ccp transfers control here
0103 E9EB02 03F1 jmp conin
0106 E9BB02 03C4 jmp plmconout
0109 E9C502 03D1 jmp plmgetline
010C E94B0A 0B5A jmp asment ;get here on error in assem (pl/m)
010F E94508 0957 jmp plmset ;assembler link to ddt set/verify
;
0112 CDE0 bdosint: int bdosi ;this is only here for user to patch
;actual bdos link gets set from here
0112 bdosintloc equ offset bdosint
0113 bdosintnum equ offset bdosint+1
;
00E0 bdosi equ 224 ;bdos interrupt number
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 2
0060 stsize equ 96 ;stack size
0002 nbps equ 2 ;number of breakpoints
;
0200 ifmask16 equ 0200h ;16-bit IF mask
0002 ifmask8 equ 02h ;8-bit IF mask
;
000A lf equ 0ah ;line feed
000D cr equ 0dh ;carriage return
000D eol equ cr
0013 ctls equ 13h ;ascii ctl-s
;
; *******************************************
; * *
; * m e s s a g e s *
; * *
; *******************************************
;
0114 20434F505952 copyright db ' COPYRIGHT (C) 1981, DIGITAL RESEARCH '
494748542028
432920313938
312C20444947
4954414C2052
455345415243
4820
;
013A 444454383620 signon db 'DDT86 1.','1' or 80h
312EB1
;
0143 2031302F3032 DATE DB ' 10/02/81 '
2F383120
014D 41D8 regname db 'A','X' or 80h
014F 42D8 db 'B','X' or 80h
0151 43D8 db 'C','X' or 80h
0153 44D8 db 'D','X' or 80h
0155 53D0 db 'S','P' or 80h
0157 42D0 db 'B','P' or 80h
0159 53C9 db 'S','I' or 80h
015B 44C9 db 'D','I' or 80h
015D 43D3 segreg db 'C','S' or 80h
015F 44D3 db 'D','S' or 80h
0161 53D3 db 'S','S' or 80h
0163 45D3 db 'E','S' or 80h
0165 49D0 db 'I','P' or 80h
;
0167 4F444954535A flagname db 'ODITSZAPC'
415043
0170 05060708090A flagbits db 5,6,7,8,9,10,12,14,16
0C0E10
;
0179 43D3 segnames db 'C','S' or 80h
017B 44D3 db 'D','S' or 80h
017D 45D3 db 'E','S' or 80h
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 3
017F 53D3 db 'S','S' or 80h
0181 58B1 db 'X','1' or 80h
0183 58B2 db 'X','2' or 80h
0185 58B3 db 'X','3' or 80h
0187 58B4 db 'X','4' or 80h
;
0189 0D0A43414E4E closem db cr,lf,'CANNOT CLOS','E' or 80h
4F5420434C4F
53C5
0197 0D0A494E5355 loadm db cr,lf,'INSUFFICIENT MEMOR','Y' or 80h
464649434945
4E54204D454D
4F52D9
01AC 0D0A4E4F2053 makem db cr,lf,'NO SPAC','E' or 80h
504143C5
01B6 0D0A4D454D4F memm db cr,lf,'MEMORY REQUEST DENIE','D' or 80h
525920524551
554553542044
454E4945C4
01CD 0D0A4E4F2046 openm db cr,lf,'NO FIL','E' or 80h
494CC5
01D6 202053544152 readm db ' START EN','D' or 80h
542020202020
20454EC4
01E6 0D0A56455249 verm db cr,lf,'VERIFY ERROR AT',' ' or 80h
465920455252
4F52204154A0
01F8 0D0A4449534B writem db cr,lf,'DISK WRITE ERRO','R' or 80h
205752495445
204552524FD2
;
; ****************************************************
; * *
; * i n i t i a l i z a t i o n *
; * *
; ****************************************************
;
setbdosint: ;copy vector at 0:bdosi*4 to (bdosi+1)*4
020A A01301 mov al,byte ptr .bdosintnum ;get bdos interrupt #
020D FEC0 inc al
020F A21E03 mov byte ptr .ddtbdosintnum,al ;ddt uses the next interrupt internally
0212 2AE4 sub ah,ah
0214 D1E0 shl ax,1
0216 D1E0 shl ax,1 ;bdos int # * 4
0218 8BF8 mov di,ax ;[di] points to new bdos interrupt vector
021A 8BF0 mov si,ax
021C 83EE04 sub si,4 ;[si] points to actual bdos interrupt vector
021F 1E push ds ;save ds
0220 2BC0 sub ax,ax
0222 8EC0 mov es,ax ;set es and ds to 0 to move interrupt vectors
0224 8ED8 mov ds,ax
0226 B90400 mov cx,4
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 4
0229 F3A4 rep movs al,al ;copy bdos interrupt vector to next int vector
022B 1F pop ds ;restore ds
022C C3 ret
;
checkcmdtail: ;if command tail not empty, assume E command
022D BE8000 mov si,offset buff
0230 B400 mov ah,0
0232 AC lods al ;get count from command tail
0233 0AC0 or al,al
0235 7415 024C jz cctret ;nothing to do if tail empty
0237 3C40 cmp al,conbuffmax
0239 7602 023D jbe movcom
023B B040 mov al,conbuffmax ;truncate, if needed
movcom:
023D 8BC8 mov cx,ax ;count to [cx]
023F BFC311 mov di,offset conbuff
0242 1E push ds
0243 07 pop es ;point destination to ddt seg
0244 F3A4 rep movs al,al ;copy command tail into ddt command buff
0246 B00D mov al,eol
0248 AA stos al ;store terminator
0249 E84B0A 0C97 call execute ;command tail is assumed E command
cctret:
024C C3 ret
;
ddt86:
024D FC cld
024E 8C16BD11 MOV CCPSS,SS
0252 8926BF11 MOV CCPSP,SP ;SAVE CCP STACK POINTER
0256 2E8C16B011 MOV USERSS,SS
025B 2E8926A411 MOV USERSP,SP ;INITIALIZE USER'S MACHINE STATE TO CCP STACK
;
0260 9C pushf
0261 58 pop ax ;get flags
0262 250002 and ax,ifmask16 ;mask to IF bit
0265 88266B12 mov sysif,ah ;save system IF state
0269 2EA3B611 mov userfl,ax ;initialize user's flags to sysif
;
026D 8CC8 mov ax,cs
026F FA cli ;entering critical region
0270 8ED0 mov ss,ax ;set ss = cs
0272 BC1013 mov sp,offset stackp ;set up stack pointer
0275 F6066B1202 test sysif,ifmask8 ;see if interrupts were enabled
027A 7401 027D jz d0 ;don't turn them on if they were off
027C FB sti
d0: ;exiting critical region
;
027D E88AFF 020A call setbdosint ;copy vector since ddt uses bdosi+1 internally
;
0280 F6066F12FF test savevecflag,0ffh ;ddt interrupts saved on each g/t/u?
0285 7503 028A jnz d1 ;if so, don't initialize here
0287 E8DA04 0764 call bpvect ;if not, initialize them here
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 5
d1:
if debug
;
sub ax,ax
mov es,ax
mov si,bdosi * 4 + 2
mov ax,es:[si] ;get bdos segment
mov es,ax
mov biosentryseg,ax
mov di,biosentryoff
mov al,81h
stos al
mov al,0c3h
stos al
mov al,0h
stos al
mov al,25h
stos al
mov al,0ffh
stos al
mov al,0d3h
stos al
mov al,0cbh
stos al
;
endif
;
028A BE3A01 mov si,offset signon ;get sign on message
028D E8AD01 043D call printm ;and print it
;
0290 E8A700 033A CALL VERSION
0293 3C30 CMP AL,30H ;SEE IF WE ARE UNDER FILE SYSTEM III (MP/M)
0295 B700 MOV BH,0
0297 7207 02A0 JC D2 ;IF EARLIER VERSION, SKIP
0299 B2FE MOV DL,0FEH
029B E8EC00 038A CALL SETERRMODE ;SO BDOS RETURNS TO DDT ON FILE ERRORS
029E B701 MOV BH,1
D2:
02A0 883E7112 MOV ERRMODE,BH
;
02A4 E886FF 022D call checkcmdtail ;if non-blank, do E command
;
; *************************************************
; * *
; * w o r k i n g l o o p *
; * *
; *************************************************
;
02A7 FC start: cld ;direction flag points up
02A8 BC1013 mov sp,offset stackp ;make sure stack is right
02AB E86F01 041D call crlf ;print crlf
02AE B02D mov al,'-' ;and prompt
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 6
02B0 E87300 0326 call conout
02B3 E82101 03D7 call getline ;get command line
02B6 E83801 03F1 call conin ;read first char
02B9 3C0D cmp al,eol
02BB 74EA 02A7 jz start
02BD 3C3B CMP AL,';'
02BF 74E6 02A7 JZ START ;IGNORE COMMENT LINES
02C1 2C41 sub al,'A' ;check range for valid command
02C3 721A 02DF jb err
02C5 3C19 cmp al,'Z'-'A'
02C7 7716 02DF ja err
02C9 D0E0 shl al,1 ;* 2 (2 bytes per ctable entry)
02CB B400 mov ah,0
02CD 93 xchg ax,bx
02CE C6066C1201 mov numreq,1 ;most commands require an argument
02D3 C6066D1200 mov wmode,0 ;most commands are not word mode
02D8 2EFF97E902 call word ptr ctable [bx] ;immed call command routine
02DD EBC8 02A7 jmps start ;start over
;
err:
02DF E83B01 041D call crlf
02E2 B03F mov al,'?' ;error handler
02E4 E83F00 0326 call conout ;print error char
02E7 EBBE 02A7 jmps start ;stack maybe messed up, keep this jmp
;
; **************************************************
; * *
; * c o m m a n d j u m p t a b l e *
; * *
; **************************************************
;
02E9 2F0B ctable dw assm ;assemble mnemonics
02EB 600B DW BLOCKCOMPARE ;COMPARE MEMORY BLOCKS
02ED DF02 dw err
02EF D60B dw display ;display memory
02F1 970C dw execute ;load user program for execution
02F3 150D dw fill ;fill memory with constant
02F5 5B0D dw gouser ;go to user program
02F7 BF0D dw hexmath ;compute hex sum and difference
02F9 DE0D dw ifcb ;input file control block
02FB DF02 dw err
02FD DF02 dw err
02FF 2E0E dw lassm ;disassemble memory
0301 A40E dw move ;move block
0303 DF02 dw err
0305 DF02 dw err
0307 DF02 dw err
0309 DF02 dw err
030B F20E dw read ;read file
030D 4C0F dw setmem ;set memory
030F A10F dw trace ;trace program execution
0311 D70F dw untrace ;untraced program execution
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 7
0313 DE0F dw verify ;display file info
0315 3010 dw write ;write memory block to disk
0317 E410 dw xcom ;display/alter CPU state
0319 DF02 dw err
031B DF02 dw err
;
; *************************************************
; * *
; * b d o s i n t e r f a c e *
; * *
; *************************************************
;
bdos: ;this interrupt instruction is overwritten on initialization
;the actual int # used is the one at bdosint: + 1
031E ddtbdosintnum equ offset bdos + 1
;
031D CDE0 int bdosi
031F C3 ret
;
if debug
;
bios:
callf dword ptr biosentryoff
ret
;
endif
;
if debug
;
consin:
mov bx,9
call bios
push ax
call conout
pop ax
ret
;
endif
;
if not debug
;
consin:
0320 B101 mov cl,1
0322 E8F8FF 031D call bdos
0325 C3 ret
;
endif
;
if debug
;
conout:
mov bx,0ch
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 8
mov cl,al
jmp bios
;
endif
;
if not debug
;
conout:
0326 B102 mov cl,2
0328 8AD0 mov dl,al
032A E8F0FF 031D call bdos
032D C3 ret
;
endif
;
rdconbuff:
032E B10A mov cl,10
0330 E8EAFF 031D call bdos
0333 C3 ret
;
if debug
;
constat:
mov bx,6
jmp bios
;
endif
;
if not debug
;
constat:
0334 B10B mov cl,11
0336 E8E4FF 031D call bdos
0339 C3 ret
;
endif
;
VERSION:
033A B10C MOV CL,12
033C E9DEFF 031D JMP BDOS
;
open:
033F B10F mov cl,15
0341 E8D9FF 031D call bdos
0344 FEC0 inc al ;test for 0ffh returned
0346 7401 0349 jz openerr
0348 C3 ret
openerr:
0349 BECD01 mov si,offset openm
034C EB70 03BE jmps errm
;
close:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 9
034E B110 mov cl,16
0350 E8CAFF 031D call bdos
0353 FEC0 inc al
0355 7401 0358 jz closeerr
0357 C3 ret
closeerr:
0358 BE8901 mov si,offset closem
035B EB61 03BE jmps errm
;
delete:
035D B113 mov cl,19
035F E9BBFF 031D jmp bdos
;
readsec:
0362 B114 mov cl,20
0364 E9B6FF 031D jmp bdos
;
writesec:
0367 B115 mov cl,21
0369 E8B1FF 031D call bdos
036C 0AC0 or al,al
036E 7501 0371 jnz writeerr
0370 C3 ret
writeerr:
0371 BEF801 mov si,offset writem
0374 EB48 03BE jmps errm
;
make:
0376 B116 mov cl,22
0378 E8A2FF 031D call bdos
037B FEC0 inc al
037D 7401 0380 jz makeerr
037F C3 ret
makeerr:
0380 BEAC01 mov si,offset makem
0383 EB39 03BE jmps errm
;
setdma:
0385 B11A mov cl,26
0387 E993FF 031D jmp bdos
;
SETERRMODE:
038A B12D MOV CL,45
038C E98EFF 031D JMP BDOS
;
setdmab:
038F B133 mov cl,51
0391 E989FF 031D jmp bdos
;
getmaxmem:
0394 B135 mov cl,53
0396 E884FF 031D call bdos
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 10
0399 FEC0 inc al
039B 740B 03A8 jz memerr
039D C3 ret
;
allocabsmem:
039E B138 mov cl,56
03A0 E87AFF 031D call bdos
; inc al
; jz memerr
03A3 90 NOP
03A4 90 NOP
03A5 90 NOP
03A6 90 NOP ;REPLACE INC AL, JZ MEMERR
03A7 C3 ret
memerr:
03A8 BEB601 mov si,offset memm
03AB EB11 03BE jmps errm
;
freemem:
03AD B139 mov cl,57
03AF E96BFF 031D jmp bdos
;
load:
03B2 B13B mov cl,59
03B4 E866FF 031D call bdos
03B7 40 inc ax ;test for 0ffffh returned
03B8 7401 03BB jz loaderr
03BA C3 ret
loaderr:
03BB BE9701 mov si,offset loadm
;
errm:
03BE E87C00 043D call printm
03C1 E9E3FE 02A7 jmp start
;
plmconout:
03C4 55 push bp
03C5 8BEC mov bp,sp
03C7 8B4604 mov ax,4[bp]
03CA E859FF 0326 call conout
03CD 5D pop bp
03CE C20200 ret 2
;
plmgetline:
03D1 55 push bp
03D2 E80200 03D7 call getline
03D5 5D pop bp ;restore bp for pl/m
03D6 C3 ret
;
; ****************************************************
; * *
; * c o n s o l e i / o r o u t i n e s *
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 11
; * *
; ****************************************************
;
if debug
;
ctlx:
mov al,'#'
call conout
call crlf
getline:
mov conptr,0
get0:
call consin
cmp al,3
jz ctlc
cmp al,8
jz backsp
cmp al,24 ;ctl-x
jz ctlx
cmp al,cr
jz getlinedone
cmp conptr,conbuffmax
jnb getlinedone
mov di,offset conbuff ;normal character store
add di,conptr
mov [di],al
inc conptr
jmps get0
getlinedone:
mov di,offset conbuff
add di,conptr
mov byte ptr [di],eol
mov conptr,0
ret
backsp:
cmp conptr,0
jz get0
dec conptr
call blank
mov al,8
call conout
jmps get0
ctlc:
mov cl,0
mov dl,0
jmp bdos
;
endif
;
if not debug
;
getline:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 12
03D7 BAC111 mov dx,offset conbuffhdr
03DA E851FF 032E call rdconbuff
03DD 8A1EC211 mov bl,conbuffcnt
03E1 B700 mov bh,0
03E3 81C3C311 add bx,offset conbuff
03E7 C6070D mov byte ptr [bx], eol
03EA C70604120000 mov conptr,0
03F0 C3 ret
;
endif
;
conin:
03F1 BEC311 mov si,offset conbuff
03F4 03360412 add si,conptr
03F8 AC lods al
03F9 FF060412 inc conptr
;fall thru to upper
03FD 3C61 upper: cmp al,'a' ;less than 'a'
03FF 7206 0407 jb upret ;or
0401 3C7A cmp al,'z' ;greater than 'z'
0403 7702 0407 ja upret ;then no change
0405 245F and al,5fh ;else convert to uc
0407 C3 upret: ret
;
ctlchek: ;check for ctl-s, ctl-q and ctl-c
0408 E829FF 0334 call constat ;keypress?
040B 0AC0 or al,al ;zero?
040D 740D 041C jz ctlexit ;no keypress so return
040F E80EFF 0320 call consin ;if keypress then get the data
0412 3C13 cmp al,ctls ;check for ctl-s
0414 7403 0419 jz kwait
0416 E98EFE 02A7 jmp start ;any other key will restart
0419 E804FF 0320 kwait: call consin ;if ctl-s then wait for another keypress
ctlexit:
041C C3 ret
;
crlf:
041D B00D mov al,cr ;send cr and lf to console
041F E804FF 0326 call conout
0422 B00A mov al,lf
0424 E8FFFE 0326 call conout
0427 C3 ret
;
CRLFCHK: ;DO CRLF AND CHECK FOR ABORT
0428 E8F2FF 041D CALL CRLF
042B E8DAFF 0408 CALL CTLCHEK
042E C3 RET
;
blank: ;print a blank.
042F B020 mov al,' '
0431 E8F2FE 0326 call conout
0434 C3 ret
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 13
;
tabs: ;print # blanks in cx
0435 51 push cx
0436 E8F6FF 042F call blank
0439 59 pop cx
043A E2F9 0435 loop tabs
043C C3 ret
;
printm: ;print the message at [si] on console
;end of message indicated by parity set.
043D AC lods al ;get a byte
043E A880 test al,80h ;check for end of message
0440 7507 0449 jnz pquit ;quit if parity set
0442 56 push si
0443 E8E0FE 0326 call conout ;otherwise display byte
0446 5E pop si
0447 EBF4 043D jmps printm ;print more message
pquit:
0449 247F and al,7fh ;strip parity
044B E8D8FE 0326 call conout ;print last byte
044E C3 ret
;
ascout: ;output [al] in ascii
044F 3C20 cmp al,' '
0451 7204 0457 jb perout ;less than blank?
0453 3C7E cmp al,7eh
0455 7602 0459 jna ascend
perout:
0457 B02E mov al,'.' ;output '.'
ascend:
0459 E8CAFE 0326 call conout ;else output ascii
045C C3 ret
;
print8or16: ;print byte or word at es:[si] depending on wmode
045D 268B04 mov ax,es:[si]
0460 F6066D1201 test wmode,1
0465 7415 047C jz printbyte
0467 EB0C 0475 jmps printword
;
printdword: ;print double word as ssss:oooo
; called with:
; es = segment
; di = offset
0469 57 push di
046A 8CC0 mov ax,es
046C E80600 0475 call printword ;print segment
046F B03A mov al,':'
0471 E8B2FE 0326 call conout
0474 58 pop ax
;
printword: ;print value in [ax] as 4 hex digits
0475 50 push ax
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 14
0476 8AC4 mov al,ah
0478 E80100 047C call printbyte
047B 58 pop ax
;
printbyte: ;print value in [al] as 2 hex digits
047C 50 push ax
047D B104 mov cl,4
047F D2E8 shr al,cl ;shift al right 4 places
0481 E80100 0485 call printnibble ;output upper nibble
0484 58 pop ax ;restore al (now we do lower nibble)
;
printnibble: ;print value in low 4 bits of [al] as a hex digit
0485 240F and al,0fh ;mask upper 4 bits
0487 0490 add al,90h
0489 27 daa
048A 1440 adc al,40h
048C 27 daa
048D E896FE 0326 call conout
0490 C3 ret
;
; **************************************
; * *
; * file name parsing routines *
; * *
; **************************************
;
parse: ;parse into fcb whose offset is in [di]
0491 0E push cs
0492 07 pop es ;set es=cs
0493 57 push di ;save fcb address
0494 2AC0 sub al,al
0496 B92400 mov cx,36 ;fcblen
0499 F3AA rep stos al ;initialize fcb to 0
049B 5F pop di ;restore fcb address
;
parse2: ;enter here to parse without clearing
;assumes es = cs from parse:
049C 893EAE12 mov fcbadr,di ;save fcb address
04A0 47 inc di ;point to first byte of filename
04A1 E82200 04C6 call setupdisk ;check for d: and set drive byte
04A4 B90800 mov cx,8
04A7 E84B00 04F5 call fillfield ;first item was disk, now get filename
04AA B90300 mov cx,3 ;length of file type
04AD 803EAD122E cmp lastchar,'.'
04B2 7405 04B9 jz filltype
04B4 E86000 0517 call fillbl ;fill type with blanks if no '.'
04B7 EB03 04BC jmps parseret
filltype:
04B9 E83900 04F5 call fillfield ;if '.', fill field from console buff
parseret:
04BC E85F00 051E call scanq ;count '?'s in fcb
04BF A0AD12 mov al,lastchar
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 15
04C2 C3 ret ;with last char scanned in [al]
parseerr:
04C3 E919FE 02DF jmp err
;
setupdisk: ;set byte 0 of fcb according to char in fcb (1)
04C6 E828FF 03F1 call conin
04C9 A2AD12 mov lastchar,al
04CC 3C20 cmp al,' '
04CE 74F6 04C6 jz setupdisk ;deblank input
04D0 3C0D cmp al,eol
04D2 7413 04E7 jz s1 ;can't be drive, decrement conptr to rescan
04D4 E81AFF 03F1 call conin
04D7 3C3A cmp al,':'
04D9 7508 04E3 jnz s0 ;not a drive, subtract 2 from conptr to rescan
04DB A0AD12 mov al,lastchar ;get drive char
04DE 2C40 sub al,'A'-1
04E0 4F dec di ;point to fcb (0)
04E1 AA stos al ;store drive byte
04E2 C3 ret
s0:
04E3 FF0E0412 dec conptr
s1:
04E7 FF0E0412 dec conptr
04EB C3 ret
;
pdelim: ;check char in [al] for delimiter; return ZF if so.
04EC BFA212 mov di,offset delims
04EF B90B00 mov cx,ndelims
04F2 F2AE repnz scas al ;look in table
04F4 C3 ret
;
fillfield: ;count in [cx], dest ptr in [di]
04F5 E8F9FE 03F1 call conin
04F8 A2AD12 mov lastchar,al ;save last char scanned
04FB 3C2A cmp al,'*'
04FD 7505 0504 jnz notast
04FF E81100 0513 call fillq ;fill with '?'
0502 EBF1 04F5 jmps fillfield ;continue till delimiter
notast:
0504 57 push di
0505 51 push cx
0506 E8E3FF 04EC call pdelim
0509 59 pop cx
050A 5F pop di
050B 740A 0517 jz fillbl ;if delimiter, fill field with ' '
050D E3B4 04C3 jcxz parseerr ;error if count exceeded
050F AA stos al ;store char in fcb
0510 49 dec cx ;decrement count
0511 EBE2 04F5 jmps fillfield
fillq:
0513 B03F mov al,'?'
0515 EB02 0519 jmps fillx
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 16
fillbl:
0517 B020 mov al,' '
fillx:
0519 E302 051D jcxz filldone
051B F3AA rep stos al ;store '?' or ' '
filldone:
051D C3 ret
;
scanq: ;count '?'s in fcb, return ZF set if found
051E 8B3EAE12 mov di,fcbadr
0522 47 inc di ;point to first char of filename
0523 B90B00 mov cx,11 ;11 chars to check
0526 B03F mov al,'?'
0528 F2AE repnz scas al
052A C3 ret
;
; ***********************************
; * *
; * user CPU state routines *
; * *
; ***********************************
;
chkreg: ;if reg name in [ax] is valid, return with
;register number in regnum
;else go to error processor
052B B90E00 mov cx,totreg+1 ;number of names to check + 1
052E BF4D01 mov di,offset regname
0531 0E push cs
0532 07 pop es
0533 F2AF repnz scas ax
0535 E320 0557 jcxz checkerr ;not a valid reg name
0537 BA0D00 mov dx,totreg
053A 2BD1 sub dx,cx
053C 89165512 mov regnum,dx ;save reg number
0540 C3 ret
;
checkflag: ;check for valid flag name
0541 B90A00 mov cx,nflag+1 ;number of names to check + 1
0544 BF6701 mov di,offset flagname
0547 0E push cs
0548 07 pop es
0549 F2AE repnz scas al
054B E30A 0557 jcxz checkerr ;not a valid flag name
054D BA0900 mov dx,nflag
0550 2BD1 sub dx,cx
0552 89165512 mov regnum,dx ;save flag number
0556 C3 ret
;
checkerr:
0557 E985FD 02DF jmp err
;
setreg: ;set reg whose number is in [cx] to value in [ax]
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 17
055A BE9C11 mov si,offset userreg
055D 03F1 add si,cx
055F 03F1 add si,cx
0561 8904 mov [si],ax
0563 C3 ret
;
printflags: ;print values of flags
0564 B90000 mov cx,0
pf0:
0567 51 push cx ;save count
0568 E84B00 05B6 call printflag
056B 59 pop cx
056C 41 inc cx
056D 83F909 cmp cx,9
0570 72F5 0567 jb pf0
0572 C3 ret
;
setflag: ;set flag whose # is in [cx] to value in [bx]
0573 BE7001 mov si,offset flagbits
0576 03F1 add si,cx
0578 AC lods al
0579 8AC8 mov cl,al
057B B8FEFF mov ax,0fffeh
057E D3C8 ror ax,cl
0580 D3CB ror bx,cl
0582 2E2106B611 and userfl,ax
0587 2E091EB611 or userfl,bx
058C C3 ret
;
printflagname: ;print flag name whose # is in [cx]
058D BE6701 mov si,offset flagname
0590 03F1 add si,cx
0592 AC lods al ;get flag name
0593 E890FD 0326 call conout
0596 C3 ret
;
getflag: ;check flag whose # is in [cx]
;return with ZF set if flag is set
0597 B80100 mov ax,1
059A BE7001 mov si,offset flagbits
059D 03F1 add si,cx
059F 8A0C mov cl,[si] ;get flagbits (flagnum)
05A1 D3C8 ror ax,cl ;get mask into position
05A3 2E2306B611 and ax,userfl ;see if bit set in CPU state
05A8 C3 ret
;
printflagval: ;print value of flag (as 0 or 1) whose # is in [cx]
05A9 E8EBFF 0597 call getflag
05AC B030 mov al,'0'
05AE 7402 05B2 jz pf2 ;if flag not set, print '0'
05B0 B031 mov al,'1' ;else print '1'
pf2:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 18
05B2 E871FD 0326 call conout
05B5 C3 ret
;
printflag: ;print flag (as flagname of '-') whose # is in [cx]
05B6 BE6701 mov si,offset flagname
05B9 03F1 add si,cx ;point to flag name
05BB FF34 push word ptr [si] ;save flag char
05BD E8D7FF 0597 call getflag
05C0 58 pop ax ;get flag char
05C1 7502 05C5 jnz pname ;if flag set, use flag char
05C3 B02D mov al,'-' ;else print hyphen
pname:
05C5 E85EFD 0326 call conout
05C8 C3 ret
;
PREG1: ;PRINT FIRST 6 REGISTER NAMES (FOR 40 COLUMNS)
05C9 B90000 MOV CX,0
05CC C606531206 MOV NREG,6
05D1 EB0D 05E0 JMPS PR0
PREG2: ;PRINT NEXT 7 REGISTER NAMES (FOR 40 COLUMNS)
05D3 B90600 MOV CX,6
05D6 EB03 05DB JMPS PR00
printregs: ;print register values
05D8 B90000 mov cx,0
PR00:
05DB C60653120D MOV NREG,13
pr0:
05E0 E82900 060C call testregcl ;see if reg should be printed
05E3 7308 05ED jnb pr2 ;don't print if carry not set
05E5 51 push cx
05E6 E80C00 05F5 call printregval
05E9 E843FE 042F call blank
05EC 59 pop cx
pr2:
05ED 41 inc cx
05EE 3A0E5312 CMP CL,NREG
05F2 72EC 05E0 jb pr0
05F4 C3 ret
;
printregval: ;print value of reg whose # is in [cx]
05F5 BE9C11 mov si,offset userreg
05F8 03F1 add si,cx
05FA 03F1 add si,cx
05FC AD lods ax
05FD E875FE 0475 call printword
0600 C3 ret
;
printregname: ;print name of reg whose # is in [cx]
0601 BE4D01 mov si,offset regname
0604 03F1 add si,cx
0606 03F1 add si,cx
0608 E832FE 043D call printm
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 19
060B C3 ret
;
testregcl: ;see if reg whose # is in [cl] should be printed
;return with carry set if so
060C F6065412FF test segflag,0ffh
0611 7509 061C jnz printit ;print all reg's if segflag set
0613 80F90B cmp cl,11 ;otherwise, see if [cl] has seg reg #
0616 7704 061C ja printit
0618 80F908 cmp cl,8
061B C3 ret
printit:
061C F9 stc
061D C3 ret
;
SETUPHDR:
061E E8FCFD 041D call crlf
0621 B90B00 mov cx,11
0624 E80EFE 0435 call tabs ;leave space for flags
0627 B90000 mov cx,0
062A C3 RET
;
PREGHDR1: ;PRINT HEADER FOR FIRST 6 REGS (FOR 40 COL)
062B E8F0FF 061E CALL SETUPHDR
062E C606531206 MOV NREG,6
0633 EB10 0645 JMPS PRH0
PREGHDR2: ;PRINT HEADER FOR NEXT 7 REGISTERS
0635 E8F7FD 042F CALL BLANK
0638 B90600 MOV CX,6
063B EB03 0640 JMPS PRH00
printregheader: ;print header for registers
063D E8DEFF 061E CALL SETUPHDR
PRH00:
0640 C60653120D MOV NREG,13
prh0:
0645 E8C4FF 060C call testregcl ;see if reg should be printed
0648 730B 0655 jnb prh1 ;don't print if carry not set
064A 51 push cx
064B E8B3FF 0601 call printregname
064E B90300 mov cx,3
0651 E8E1FD 0435 call tabs
0654 59 pop cx
prh1:
0655 41 inc cx
0656 3A0E5312 CMP CL,NREG
065A 72E9 0645 jb prh0
065C C3 ret
;
printinstr: ;disassemble instruction at [cs:ip]
065D 2E8E06AC11 mov es,usercs
0662 2E8B36B411 mov si,userip
0667 F6063912FF test disempresent,0ffh
066C 7410 067E jz pi1
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 20
066E 06 push es
066F 56 push si
0670 F6065412FF test segflag,0ffh
0675 7403 067A jz pi0
0677 E8A3FD 041D call crlf
pi0:
067A E8830D 1400 call disem
067D C3 ret
pi1:
067E 268A04 mov al,es:[si]
0681 E8F8FD 047C call printbyte
0684 C3 ret
;
printseginfo: ;print name, start and end address of segment whose
;number is in [al] if length is non-zero.
0685 8AC8 mov cl,al ;save seg number
0687 B306 mov bl,6
0689 F6E3 mul bl ;6 bytes per segment in base page
068B 057212 add ax,offset basepagesave
068E 8BF0 mov si,ax ;si now points to entry in base page
0690 AD lods ax ;get low 16 bits of length
0691 8BD8 mov bx,ax ;save in bx
0693 AC lods al ;get high nibble of length
0694 8AD0 mov dl,al ;save it
0696 B400 mov ah,0
0698 0BC3 or ax,bx ;test for zero length
069A 7430 06CC jz psiret ;if zero, no display
069C AD lods ax ;get base
069D 53 push bx ;save low (length)
069E 52 push dx ;save high (length)
069F 50 push ax ;save base
06A0 B500 mov ch,0 ;zero high byte of segment #
06A2 D1E1 shl cx,1 ;* 2 (2 bytes per segment name)
06A4 81C17901 add cx,offset segnames ;cx now points to segment name
06A8 51 push cx ;save it
06A9 E871FD 041D call crlf
06AC 5E pop si
06AD E88DFD 043D call printm ;print segment name
06B0 E87CFD 042F call blank
06B3 07 pop es ;get base
06B4 06 push es ;save base
06B5 BF0000 mov di,0
06B8 E8AEFD 0469 call printdword ;print start address
06BB E871FD 042F call blank
06BE 5B pop bx ;get base
06BF 58 pop ax ;get high (len)
06C0 B10C mov cl,12
06C2 D3E0 shl ax,cl ;move ls nibble of al to ms nibble of ah
06C4 03C3 add ax,bx ;add ms nibble of length to base
06C6 8EC0 mov es,ax
06C8 5F pop di ;get low (len)
06C9 E89DFD 0469 call printdword ;print end address
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 21
psiret:
06CC C3 ret
;
setcpustate: ;set users regs after E command
06CD A1BD11 MOV AX,CCPSS
06D0 2EA3B011 MOV USERSS,AX
06D4 A1BF11 MOV AX,CCPSP
06D7 2EA3A411 MOV USERSP,AX ;RESET USER STACK POINTER TO CCP STACK
06DB 8BC3 mov ax,bx ;get ds base in [ax] (returned from bdos load)
06DD 2EA3AE11 mov userds,ax ;set user's ds
06E1 2EA3AC11 mov usercs,ax
06E5 2EA3B211 mov useres,ax
06E9 A35A12 mov type1seg,ax
06EC A35E12 mov type2seg,ax
06EF 8EC0 mov es,ax
06F1 26F606050001 test es:byte ptr .5, 1 ;test 8080 flag
06F7 7405 06FE jz not8080
06F9 B80001 mov ax,100h ;default for userip, lasloc, disloc
06FC EB2D 072B jmps setdone
not8080:
06FE 26A10300 mov ax,es:.3 ;get cs base
0702 2EA3AC11 mov usercs,ax
0706 A35A12 mov type1seg,ax
0709 26A10F00 mov ax,es:.15 ;get es base
070D 0BC0 or ax,ax
070F 7404 0715 jz sc1
0711 2EA3B211 mov useres,ax ;set it if there was one
sc1:
0715 26A11500 mov ax,es:.21 ;get ss base
0719 0BC0 or ax,ax
071B 740E 072B jz setdone
071D 2EA3B011 mov userss,ax ;set it if there was one
0721 26A11200 mov ax,es:.18 ;get stack length
0725 2EA3A411 mov usersp,ax ;set user's sp
0729 2BC0 sub ax,ax ;userip, lasloc, disloc = 0 for non-8080 model
setdone:
072B 2EA3B411 mov userip,ax
072F A33112 mov lasloc,ax
0732 C3 ret
;
; *********************************************
; * *
; * breakpoint/single step procedures *
; * *
; *********************************************
;
setbp: ;set breakpoint at address stored in dword at [di]
0733 C435 les si,[di] ;point [es]:[si] to breakpoint location
0735 B0CC mov al,0cch ;int 3 instruction
0737 268604 xchg al,es:[si] ;set breakpoint and fetch instruction
073A 884504 mov 4[di],al ;save user instruction in breakpoint table
073D FE062612 inc bpcnt ;increment breakpoint count
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 22
0741 C3 ret
;
bpclear: ;clear breakpoint table
0742 2BC9 sub cx,cx
0744 8A0E2612 mov cl,bpcnt ;get # of bp's to clear
0748 BE2712 mov si,offset brk1loc ;point to bp table
bpcloop:
074B E30F 075C jcxz bpend ;0..quit
074D AD lods ax ;get bp offset
074E 50 push ax ;save it
074F AD lods ax ;get bp segment
0750 8EC0 mov es,ax
0752 AC lods al ;get inst byte
0753 5F pop di ;get bp offset
0754 AA stos al ;store user instruction back
0755 E2F4 074B loop bpcloop
0757 C606261200 mov bpcnt,0 ;zero bp counter
075C C3 bpend: ret
;
BPV:
075D F6066F12FF TEST SAVEVECFLAG,0FFH
0762 741C 0780 JZ BPVECTRET
bpvect: ;set up breakpoint/single step vectors
0764 E81A00 0781 call savevect
0767 BA0000 mov dx,0
076A 8EC2 mov es,dx ;make sure dest is absolute 0
076C BF0400 mov di,4 ;set up single step vector
076F B8DF07 mov ax,offset ssentry ;single step entry point
0772 AB stos ax ;save at ss vector
0773 8CC8 mov ax,cs
0775 AB stos ax ;save cs
0776 BF0C00 mov di,12 ;set up breakpoint vector
0779 B8D707 mov ax,offset breakentry ;set up bp vector
077C AB stos ax ;save at bp vector
077D 8CC8 mov ax,cs
077F AB stos ax ;save cs
BPVECTRET:
0780 C3 ret
;
savevect: ;save previous contents of 0:4 thru 0:f
0781 BE0400 mov si,4
0784 BF1A12 mov di,offset vectorsave
0787 1E push ds
0788 07 pop es ;point to ddt segment
0789 B90C00 mov cx,12
078C 1E push ds
078D BA0000 mov dx,0
0790 8EDA mov ds,dx
0792 F3A4 rep movs al,al
0794 1F pop ds
svret:
0795 C3 ret
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 23
;
restorevect: ;restore previous contents of 0:4 thru 0:f
0796 F6066F12FF test savevecflag,0ffh
079B 7410 07AD jz rvret
079D BE1A12 mov si,offset vectorsave
07A0 BF0400 mov di,4
07A3 B90C00 mov cx,12
07A6 BA0000 mov dx,0
07A9 8EC2 mov es,dx
07AB F3A4 rep movs al,al
rvret:
07AD C3 ret
;
SETDEFSEG: ;SET DEFAULT TYPE1SEG, LASLOC
07AE 2E8B3EB411 mov di,userip
07B3 893E3112 mov lasloc,di ;set disassembler offset
07B7 2E8E06AC11 mov es,usercs
07BC 8C065A12 mov type1seg,es ;set type1seg segment
07C0 C3 RET
;
breakaddr: ;print address where break occurred
07C1 E859FC 041D call crlf
07C4 B02A mov al,'*'
07C6 E85DFB 0326 call conout
07C9 2EA1AE11 mov ax,userds
07CD A35E12 mov type2seg,ax ;set type2 segment to userds
07D0 E8DBFF 07AE CALL SETDEFSEG
07D3 E893FC 0469 call printdword ;print break address
07D6 C3 ret
;
breakentry: ;breakpoint entry
07D7 2EC606BC1101 mov breakfl,1
07DD EB06 07E5 jmps savecpu ;common code for break and single step
ssentry: ;single step entry
07DF 2EC606BC1100 mov breakfl,0
savecpu:
07E5 2EA39C11 mov userax,ax
07E9 2E891E9E11 mov userbx,bx
07EE 2E890EA011 mov usercx,cx
07F3 2E8916A211 mov userdx,dx
07F8 2E8936A811 mov usersi,si
07FD 2E893EAA11 mov userdi,di
0802 2E892EA611 mov userbp,bp
0807 2E8926A411 mov usersp,sp
080C 2E8C06B211 mov useres,es
0811 2E8C1EAE11 mov userds,ds
0816 2E8C16B011 mov userss,ss
081B 8BEC mov bp,sp
081D 8B4600 mov ax,[bp]
0820 2EA3B411 mov userip,ax
0824 8B4602 mov ax,2[bp]
0827 2EA3AC11 mov usercs,ax
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 24
082B 8B4604 mov ax,4[bp]
082E 2EA3B611 mov userfl,ax
;
0832 8CC8 mov ax,cs
0834 8ED8 mov ds,ax
0836 8ED0 mov ss,ax
0838 BC1013 mov sp,offset stackp
;
083B F6066B1202 test sysif,ifmask8 ;see whether interrupts should be enabled
0840 7401 0843 jz sav0
0842 FB sti
sav0:
0843 2E8306A41106 add usersp,6 ;to make up for stacked cs, ip, and fl
0849 FC cld
084A E849FF 0796 call restorevect
084D 2EF606BC11FF test breakfl,0ffh
0853 741A 086F jz sst0
;
break0: ;continuation of break processing
0855 2EFF0EB411 dec userip ;adjust user ip for breakpoint instr
085A E8E5FE 0742 call bpclear ;clear all breakpoints
085D F6064912FF test skipbdos,0ffh ;were we originally in trace mode?
0862 7506 086A jnz sst00 ;if so, continue tracing
;
tracedone:
0864 E85AFF 07C1 call breakaddr
0867 E93DFA 02A7 jmp start
;
sst00: ;get here on breakpoint on return from bdos
086A C606491200 mov skipbdos,0 ;no longer tracing thru bdos
sst0: ;continuation of single step processing
086F 2E8126B611FF and userfl,0feffh ;clear user trap flag
FE
0876 F6064A1201 TEST USERIFOFF,1
087B 740C 0889 JZ SST1
087D C6064A1200 MOV USERIFOFF,0
0882 2E810EB61100 OR USERFL,200H ;RESTORE USER IF
02
SST1:
0889 FF0E4612 dec tracecount
088D 74D5 0864 jz tracedone
088F E876FB 0408 CALL CTLCHEK ;CHECK FOR ABORT
0892 F6064812FF test traceprint,0ffh
0897 7403 089C jz tracerestore
0899 E80608 10A2 call xnohdr ;display regs without header
;
tracerestore: ;enter here when in trace mode
089C 2E8E06AC11 mov es,usercs
08A1 2E8B36B411 mov si,userip
08A6 A11201 mov ax,word ptr .bdosintloc ;get bdos interrupt instruction
08A9 263B04 cmp ax,es:[si] ;see if instruction to be traced is bdos int
08AC 7518 08C6 jnz tr00
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 25
08AE 8C062912 mov brk1seg,es
08B2 83C602 add si,2 ;point to instruction after bdos int
08B5 89362712 mov brk1loc,si
08B9 BF2712 mov di,offset brk1loc
08BC E874FE 0733 call setbp ;set breakpoint at return from bdos
08BF C606491201 mov skipbdos,1 ;so we know we were in trace mode when we hit bp
08C4 EB39 08FF jmps rstore ;without setting single step flag
tr00:
08C6 2EA1B611 MOV AX,USERFL
08CA 0D0001 OR AX,100H ;SET TRACE FLAG
08CD A90002 TEST AX,200H ;IS USER IF SET?
08D0 7429 08FB JZ TR01
08D2 25FFFD AND AX,NOT 200H ;CLEAR IT (SO WE DON'T END UP IN INT HANDLER)
08D5 2E8E06AC11 MOV ES,USERCS
08DA 2E8B36B411 MOV SI,USERIP
08DF 268A1C MOV BL,ES:[SI] ;GET INSTRUCTION TO EXECUTE
08E2 80FBFA CMP BL,0FAH ;IS IT CLI?
08E5 7414 08FB JZ TR01
08E7 80FBCF CMP BL,0CFH ;IRET?
08EA 740F 08FB JZ TR01
08EC 80FB9D CMP BL,09DH ;POPF?
08EF 740A 08FB JZ TR01
08F1 80FBCD CMP BL,0CDH ;INT?
08F4 7405 08FB JZ TR01
08F6 C6064A1201 MOV USERIFOFF,1 ;SET FLAG SO DDT86 WILL TURN IF BACK ON
TR01:
08FB 2EA3B611 MOV USERFL,AX
rstore: ;enter here when in G mode
08FF E85BFE 075D CALL BPV
0902 FA cli
0903 BC9C11 mov sp,offset userreg ;point to reg save area
0906 58 pop ax
0907 5B pop bx
0908 59 pop cx
0909 5A pop dx
090A 2E8F06BA11 pop savesp
090F 5D pop bp
0910 5E pop si
0911 5F pop di
0912 1F pop ds ;throw away cs
0913 1F pop ds
0914 2E8F06B811 pop savess
0919 07 pop es
091A 2E8E16B811 mov ss,savess ;restore stack
091F 2E8B26BA11 mov sp,savesp
0924 2EFF36B611 push userfl ;flags
0929 2EFF36AC11 push usercs ;cs
092E 2EFF36B411 push userip ;ip
0933 CF iret ;transfer to user program
;
; **********************************
; * *
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 26
; * miscellaneous routines *
; * *
; **********************************
;
delim:
0934 3C0D cmp al,eol
0936 740A 0942 jz delret
0938 3C2C cmp al,','
093A 7406 0942 jz delret
093C 3C20 cmp al,' '
093E 7402 0942 jz delret
0940 3C3A cmp al,':'
delret:
0942 C3 ret
;
hexcon:
0943 2C30 sub al,'0'
0945 3C0A cmp al,10
0947 720A 0953 jb hexret
0949 04F9 add al,('0' - 'A' + 10) and 0ffh
094B 3C10 cmp al,16
094D 7305 0954 jnb hexerr
094F 3C0A cmp al,10
0951 7201 0954 jb hexerr
hexret:
0953 C3 ret
hexerr:
0954 E988F9 02DF jmp err
;
plmset: ;get here when assembler wants to set memory
0957 8BEC mov bp,sp ;for parameter fetching
0959 8B4602 mov ax,2[bp] ;get value in [al]
095C 8E065A12 mov es,type1seg ;segment used in A command is in type1 seg
0960 8B7E04 mov di,4[bp] ;get offset from stack
0963 E81A00 0980 call setbyte ;set and verify
0966 47 inc di ;increment offset
0967 7503 096C jnz psret ;if incremented offset is non-zero, return
0969 E93BF9 02A7 jmp start ;otherwise exit A command, since wrap occurred
psret:
096C C20400 ret 4 ;remove 2 parameters
;
set8or16: ;set byte or word at es:[di] depending on wmode
096F F6066D1201 test wmode,1
0974 740A 0980 jz setbyte
;fall through to setword
;
setword: ;set word at es:[di] to [ax] and verify
;
; NOTE: THIS CODE COULD BE REPLACED BY THE FOLLOWING 4 INSTRUCTIONS
; FOR SYSTEMS IN WHICH MEMORY CAN ONLY BE ADDRESSED BY WORDS.
; HOWEVER, THIS WILL WRAP AROUND AND MODIFY LOCATIONS 0 IF
; [DI] CONTAINS 0FFFEH.
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 27
;
; MOV ES:[DI],AX
; CMP ES:[DI],AX
; JNZ BADVER
; RET
;
0976 50 push ax ;save hi byte
0977 E80600 0980 call setbyte ;set low byte
097A 58 pop ax
097B 8AC4 mov al,ah
097D 47 inc di ;point to next location
097E 7408 0988 jz sret ;don't set byte if wraparound occurred
;fall thru to setbyte
;
setbyte: ;set byte at es:[di] to [al] and verify
0980 268805 mov es:[di],al ;store byte
0983 263805 cmp es:[di],al ;see if it got stored
0986 7501 0989 jnz badver
sret:
0988 C3 ret
;
badver:
0989 57 push di
098A 06 push es
098B BEE601 mov si,offset verm
098E E8ACFA 043D call printm ;print verify error message
0991 07 pop es
0992 5F pop di
0993 E8D3FA 0469 call printdword
0996 E90EF9 02A7 jmp start
;
inc1or2: ;inc pointer at [si] by 1 or 2, depending on wmode
;return with carry flag set if wrap occurred
0999 A06D12 mov al,wmode
099C 250100 and ax,1 ;mask to 0 or 1
099F 40 inc ax ;increment value is now 1 or 2
09A0 0104 add [si],ax ;increment pointer
09A2 3904 cmp [si],ax ;test for wraparound
09A4 C3 ret
;
getnumber: ;get number from input buffer
;returns:
;bx = value of number from input
;al = last character scanned (delimiter)
;ah = blank flag (0 = blank, 1 = non-blank)
09A5 2BDB sub bx,bx ;initialize value to 0
09A7 8AE7 mov ah,bh ;initialize blank flag to blank
getn0:
09A9 E845FA 03F1 call conin
09AC E885FF 0934 call delim ;check for delimiter
09AF 740D 09BE jz getnret ;delimiter found, exit
09B1 B104 mov cl,4
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 28
09B3 D3E3 shl bx,cl ;make room for new nibble
09B5 E88BFF 0943 call hexcon ;convert ascii to binary
09B8 02D8 add bl,al ;add nibble
09BA B401 mov ah,1 ;blank flag = non-blank
09BC EBEB 09A9 jmps getn0
getnret:
09BE C3 ret
;
getoffset: ;get offset from input line
;offset is a non-blank number not followed by ':'
;returns:
;al = last char scanned (delimiter)
;bx = value
09BF E8E3FF 09A5 call getnumber ;get value to bx
09C2 0AE4 or ah,ah ;check for blank entry
09C4 740D 09D3 jz geterr ;don't allow blank entry
09C6 3C3A cmp al,':' ;check delimiter for ':'
09C8 7409 09D3 jz geterr ;don't allow ':' delimiter
09CA C3 ret
;
getlastoffset: ;same as getoffset but delimiter must be a cr
09CB E8F1FF 09BF call getoffset
09CE 3C0D cmp al,eol
09D0 7501 09D3 jnz geterr
09D2 C3 ret
geterr:
09D3 E909F9 02DF jmp err
;
checkword: ;check for 'W' following command letter
09D6 E818FA 03F1 call conin
09D9 3C57 cmp al,'W'
09DB 7506 09E3 jnz chret
09DD C6066D1201 mov wmode,1
09E2 C3 ret
09E3 FF0E0412 chret: dec conptr ;to rescan character
09E7 C3 ret
;
checkreg: ;check for valid segment register prefix - <sr>:
;called with:
;bl = first char
;bh = second char
;returns:
;si = offset to register, if found
;zf = found flag (1 = found, 0 = not found)
09E8 80CF80 or bh,80h ;since they are defined like that
09EB BD5D01 mov bp,offset segreg ;point to seg reg names
09EE 2BF6 sub si,si ;initialize index to 0
check0:
09F0 3B1A cmp bx,[bp+si] ;is it a seg reg name
09F2 740A 09FE jz checkret
09F4 83C602 add si,2 ;point to next name
09F7 83FE08 cmp si,8 ;check for done (4 seg reg names)
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 29
09FA 75F4 09F0 jnz check0
09FC 0BF6 or si,si ;unset zero flag
checkret:
09FE C3 ret
;
checksegreg: ;check for valid seg reg name
;if found, return contents of seg reg
;else reset input pointer for rescan
;returns:
;dx = seg reg value
;zf = valid seg reg (1 = valid, 0 = not valid)
09FF FF360412 push conptr ;save input pointer for possible rescan
0A03 E8EBF9 03F1 call conin
0A06 50 push ax
0A07 E8E7F9 03F1 call conin
0A0A 50 push ax
0A0B E8E3F9 03F1 call conin
0A0E 3C3A cmp al,':' ;valid seg reg must have colon
0A10 5B pop bx
0A11 59 pop cx
0A12 8AF9 mov bh,cl
0A14 86DF xchg bl,bh
0A16 750C 0A24 jnz notsr
0A18 E8CDFF 09E8 call checkreg ;see if it's a valid name
0A1B 7507 0A24 jnz notsr
0A1D BDAC11 mov bp,offset usercs ;point to saved user seg reg's
0A20 8B12 mov dx,[bp+si] ;get value of user seg reg
0A22 59 pop cx ;throw away saved input pointer
0A23 C3 ret
notsr:
0A24 8F060412 pop conptr ;reset for rescan
0A28 C3 ret
;
getsegandoff: ;get user location specification
;may be one of the following forms:
;<empty>
;nnnn
;sr:nnnn
;mmmm:nnnn
;if numreq set, <empty> is invalid
;called with:
;di = offset of 4 byte area containing <offset><segment>
;numreq must have been initialized by calling routine
0A29 E8D3FF 09FF call checksegreg ;see if there is a segment prefix
0A2C 740D 0A3B jz gets0
0A2E E874FF 09A5 call getnumber ;no segment prefix, check for number
0A31 0AE4 or ah,ah ;was there one?
0A33 7412 0A47 jz gets3
0A35 8BD3 mov dx,bx ;move number to dx
0A37 3C3A cmp al,':' ;was delimiter a ':'
0A39 7509 0A44 jnz gets2
gets0:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 30
0A3B E881FF 09BF call getoffset ;segment prefix present, must have number
0A3E 891D mov [di],bx ;number goes to <offset>
0A40 895502 mov 2[di],dx ;first number (or sr) goes to <segment>
0A43 C3 ret
gets2:
0A44 8915 mov [di],dx ;only one number, put it in <offset>
getsret:
0A46 C3 ret
gets3:
0A47 F6066C12FF test numreq,0ffh ;blank field, see if ok
0A4C 74F8 0A46 jz getsret ;ok, return with no change at [di]
0A4E E98EF8 02DF jmp err ;number was required
;
; *****************************
; * *
; * disk i/o routines *
; * *
; *****************************
;
readfile: ;read file in fcb into memory described in mcb
;when done, mcb will have base and length of block to free
0A51 A16612 mov ax,mcbbase
0A54 A33C12 mov startreadseg,ax
0A57 A34012 mov endreadseg,ax
0A5A A34412 mov dmaseg,ax
0A5D 2BC0 sub ax,ax
0A5F A33A12 mov startreadoff,ax
0A62 A33E12 mov endreadoff,ax
rf0:
0A65 8B164412 mov dx,dmaseg
0A69 E823F9 038F call setdmab ;set dma base
0A6C C70642120000 mov dmaoff,0
rf1:
0A72 8B164212 mov dx,dmaoff
0A76 E80CF9 0385 call setdma ;set dma offset
0A79 833E681208 cmp mcblen,8 ;8 paragraphs per sector
0A7E 7239 0AB9 jb readerr ;if less than 8 pp's left, not enough memory
0A80 BA5C00 mov dx,offset fcb
0A83 E8DCF8 0362 call readsec
0A86 0AC0 or al,al ;test value returned from bdos
0A88 7528 0AB2 jnz readdone
0A8A 8306661208 add mcbbase,8 ;point mcb to next available paragraph
0A8F 832E681208 sub mcblen,8 ;decrement # of available paragraphs
0A94 A14212 mov ax,dmaoff
0A97 047F add al,7fh ;add sector size - 1
0A99 A33E12 mov endreadoff,ax
0A9C A14412 MOV AX,DMASEG
0A9F A34012 MOV ENDREADSEG,AX
0AA2 810642128000 add dmaoff,80h ;increment dma offset
0AA8 75C8 0A72 jnz rf1 ;if no wrap occurred, simply continue
0AAA 810644120010 add dmaseg,1000h ;else increment dma segment
0AB0 EBB3 0A65 jmps rf0
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAG ret
asmerr:
0B57 E985F7 02DF jmp err
asment: ;arrive here on input error in pl/m
0B5A 8B260712 mov sp,asmspsav ;reset stack to where it was
0B5E EBE0 0B40 jmps asm0 ;go back for more input
;
; *****************************
; * *
4
0AC1 D3E8 shr ax,cl ;divide offset by 16 - truncate ls nibble
0AC3 03064D12 add ax,startwriteseg ;compute absolute paragraph number
0AC7 A36612 mov mcbbase,ax
0ACA A34412 mov dmaseg,ax
0ACD 8BD8 mov bx,ax ;store start paragraph # in [bx]
0ACF A14F12 mov ax,endwriteoff
0AD2 D3E8 shr ax,cl
0AD4 03065112 add ax,endwriteseg ;calculate absolute paragraph number of end
0AD8 2BC3 sub ax,bx ;compute # of paragraphs to write
0ADA 7250 0B2C jb wferr ;start can't be > end
0ADC A36812 mov mcblen,ax ;store # paragraphs to write
0ADF BA5C00 mov dx,offset fcb
0AE2 E878F8 035D call delete
0AE5 F6067112FF TEST ERRMODE,0FFH
0AEA 7408 0AF4 JZ WF00
0AEC FEC0 INC AL ;DID DELETE RETURN 0FFH?
0AEE 7504 0AF4 JNZ WF00 ;IF NOT, OK
0AF0 0AE4 OR AH,AH ;SEE IF EXTENDED OR PHYSICAL ERROR
0AF2 7538 0B2C JNZ WFERR ;IF SO, DON'T CONTINUE
WF00:
0AF4 BA5C00 mov dx,offset fcb
0AF7 E87CF8 0376 call make
wf0:
0AFA 8B164412 mov dx,dmaseg
0AFE E88EF8 038F call setdmab
0B01 C70642120000 mov dmaoff,0 ;clear dma offset
wf1:
0B07 8B164212 mov dx,dmaoff
0B0B E877F8 0385 call setdma
0B0E BA5C00 mov dx,offset fcb
0B11 E853F8 0367 call writesec
0B14 832E681208 sub mcblen,8 ;8 paragraphs per sector
0B19 7210 0B2B jb writedone
0B1B 810642128000 add dmaoff,80h ;increment dma pointer
0B21 75E4 0B07 jnz wf1 ;loop if no wrap occurred
0B23 810644120010 add dmaseg,1000h ;if wrap occurred, increment dma segment
0B29 EBCF 0AFA jmps wf0
writedone:
0B2B C3 ret
wferr:
0B2C E9B0F7 02DF jmp err
;
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 32
eject
;
; **********************************
; * *
; * a - assemble mnemonics *
; * *
; **********************************
;
assm:
0B2F F6060612FF test assempresent,0ffh
0B34 7421 0B57 jz asmerr
0B36 89260712 mov asmspsav,sp ;save in case of error in pl/m
0B3A BF5812 mov di,offset type1loc
0B3D E8E9FE 0A29 call getsegandoff ;get start address
asm0:
0B40 FF365A12 push type1seg ;for pl/m call
0B44 FF365812 push type1loc ;for pl/m call
0B48 E8B517 2300 call assem ;returns offset of next available byte
0B4B 3B065812 cmp ax,type1loc ;test for no input
0B4F 7605 0B56 jna asmret ;done unless greater than original type1loc
0B51 A35812 mov type1loc,ax ;update type1loc
0B54 EBEA 0B40 jmps asm0
asmret:
0B56 C3 ret
asmerr:
0B57 E985F7 02DF jmp err
asment: ;arrive here on input error in pl/m
0B5A 8B260712 mov sp,asmspsav ;reset stack to where it was
0B5E EBE0 0B40 jmps asm0 ;go back for more input
;
; *****************************
; * *
; * B - BLOCK COMPARE *
; * *
; *****************************
;
BLOCKCOMPARE:
0B60 BF5C12 mov di,offset type2loc
0B63 E8C3FE 0A29 call getsegandoff
0B66 E856FE 09BF call getoffset ;get end offset
0B69 891E6012 mov usermax,bx
0B6D 3C0D cmp al,eol
0B6F 7451 0BC2 jz cmperr ;need 3 arguments
0B71 2B1E5C12 sub bx,type2loc
0B75 724B 0BC2 jb cmperr ;error if start > end
0B77 A15E12 mov ax,type2seg
0B7A A36412 mov userseg2,ax ;default to same seg as source
0B7D BF6212 mov di,offset userloc2
0B80 E8A6FE 0A29 call getsegandoff ;get destination address
0B83 3C0D cmp al,eol
0B85 753B 0BC2 jnz cmperr ;error if more than 3 arguments
CMP0:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 33
0B87 C4365C12 LES SI,DWORD PTR TYPE2LOC
0B8B 268A04 MOV AL,ES:[SI]
0B8E C4366212 LES SI,DWORD PTR USERLOC2
0B92 263A04 CMP AL,ES:[SI]
0B95 7415 0BAC JZ CMPCONT
0B97 E88EF8 0428 CALL CRLFCHK
0B9A BF5C12 MOV DI,OFFSET TYPE2LOC
0B9D E82500 0BC5 CALL PRINTERROR
0BA0 E88CF8 042F CALL BLANK
0BA3 E889F8 042F CALL BLANK
0BA6 BF6212 MOV DI,OFFSET USERLOC2
0BA9 E81900 0BC5 CALL PRINTERROR
CMPCONT:
0BAC FF065C12 INC TYPE2LOC
0BB0 A15C12 MOV AX,TYPE2LOC
0BB3 39066012 CMP USERMAX,AX
0BB7 7208 0BC1 JC CMPDONE
0BB9 FF066212 INC USERLOC2
0BBD 7402 0BC1 JZ CMPDONE ;PREVENT WRAPAROUND
0BBF EBC6 0B87 JMPS CMP0
;
CMPDONE:
0BC1 C3 RET
CMPERR:
0BC2 E91AF7 02DF JMP ERR
;
PRINTERROR: ;PRINT DWORD AT [DI], BYTE POINTED TO BY DWORD
0BC5 C43D LES DI,[DI]
0BC7 268A05 MOV AL,ES:[DI]
0BCA 50 PUSH AX ;SAVE BYTE AT ES:DI
0BCB E89BF8 0469 CALL PRINTDWORD
0BCE E85EF8 042F CALL BLANK
0BD1 58 POP AX
0BD2 E8A7F8 047C CALL PRINTBYTE
0BD5 C3 RET
;
; ******************************
; * *
; * d - display memory *
; * *
; ******************************
;
display:
0BD6 C6066C1200 mov numreq,0 ;ok to have no entries
0BDB A15E12 mov ax,type2seg
0BDE A30B12 mov disseg,ax ;default to type2 seg
0BE1 E8F2FD 09D6 call checkword
0BE4 F6067012FF TEST COL40,0FFH
0BE9 7411 0BFC JZ DIS01
0BEB F6066D1201 TEST WMODE,1
0BF0 7505 0BF7 JNZ DIS00
0BF2 A01312 MOV AL,ND40
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 34
0BF5 EB08 0BFF JMPS DIS02
DIS00:
0BF7 A01412 MOV AL,NDW40 ;CHARS PER LINE FOR DW IN 40 COL MODE
0BFA EB03 0BFF JMPS DIS02
DIS01:
0BFC A01212 MOV AL,ND80 ;16 BYTES PER LINE IN NORMAL MODE
DIS02:
0BFF A21112 MOV LINEMAX,AL
0C02 BF0912 mov di,offset disloc
0C05 E821FE 0A29 call getsegandoff
0C08 3C2C cmp al, ','
0C0A A10B12 mov ax,disseg
0C0D A35E12 mov type2seg,ax ;update default type2 seg
0C10 7505 0C17 jnz dis0 ;must be cr, no dismax entered
0C12 E8B6FD 09CB call getlastoffset ;get dismax
0C15 EB1A 0C31 jmps dis1
dis0:
0C17 8B1E0912 mov bx,disloc ;no dismax entered, calculate default
0C1B A01112 MOV AL,LINEMAX
0C1E 8A0E1512 MOV CL,NLINES
0C22 F6E1 MUL CL
0C24 FEC8 DEC AL
0C26 03D8 ADD BX,AX
0C28 3B1E0912 cmp bx,disloc ;see if we went over ffff
0C2C 7303 0C31 jnb dis1
0C2E BBFFFF mov bx,0ffffh ;set dismax if we wrapped around
dis1:
0C31 891E0D12 mov dismax,bx
disp3:
0C35 E8F0F7 0428 CALL CRLFCHK
0C38 C43E0912 les di,dword ptr disloc
0C3C 893E0F12 mov tdisp,di
0C40 E826F8 0469 call printdword
disp4:
0C43 E8E9F7 042F call blank
0C46 C4360912 les si,dword ptr disloc
0C4A E810F8 045D call print8or16
0C4D BE0912 mov si,offset disloc
0C50 E846FD 0999 call inc1or2
0C53 7216 0C6B jb disp6 ;stop if wrap occurred
0C55 A10912 mov ax,disloc
0C58 2B060F12 sub ax,tdisp ;calculate # bytes printed on line
0C5C 3A061112 CMP AL,LINEMAX ;SEE IF LINE FULL
0C60 7409 0C6B jz disp6
0C62 A10912 mov ax,disloc
0C65 3B060D12 cmp ax,dismax ;check for done
0C69 76D8 0C43 jna disp4
disp6:
0C6B E8C1F7 042F call blank
disp7:
0C6E 8E060B12 mov es,disseg
0C72 8B360F12 mov si,tdisp
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 35
0C76 268A04 mov al,es:[si]
0C79 E8D3F7 044F call ascout
0C7C FF060F12 inc tdisp
0C80 7411 0C93 jz disp8 ;stop if wrap occurred
0C82 A10F12 mov ax,tdisp
0C85 3B060912 cmp ax,disloc
0C89 75E3 0C6E jnz disp7
0C8B 3B060D12 cmp ax,dismax
0C8F 7702 0C93 ja disp8
0C91 EBA2 0C35 jmps disp3
disp8:
0C93 C3 ret
;
; ******************************************
; * *
; * e - load program for execution *
; * *
; ******************************************
;
0C94 434D44 cmd db 'CMD'
;
execute:
0C97 E857F7 03F1 call conin
0C9A 3C0D cmp al,eol ;check for no filename
0C9C 7474 0D12 jz eerr ;don't allow no filename
0C9E FF0E0412 dec conptr ;to rescan character
0CA2 BF5C00 mov di,offset fcb
0CA5 E8E9F7 0491 call parse
0CA8 7468 0D12 jz eerr ;no '?' or '*' allowed
0CAA 3C0D cmp al,eol
0CAC 7564 0D12 jnz eerr ;eol must follow filename
0CAE 0E push cs
0CAF 07 pop es ;set es = cs
0CB0 26803E650020 cmp es:fcb+9, ' ' ;see if filetype blank
0CB6 750B 0CC3 jnz ex0
0CB8 BE940C mov si,offset cmd
0CBB BF6500 mov di,offset fcb+9
0CBE B90300 mov cx,3
0CC1 F3A4 rep movs al,al ;set filetype to 'CMD' if empty
ex0:
0CC3 BA5C00 mov dx,offset fcb
0CC6 E876F6 033F call open ;see if file exists
0CC9 C6066A12FF mov mcbext,0ffh ;free all allocations below DDT86
0CCE BA6612 mov dx,offset mcb
0CD1 E8D9F6 03AD call freemem ;free all memory previously allocated under DDT
0CD4 BA5C00 mov dx,offset fcb
0CD7 E8D8F6 03B2 call load ;load user program
0CDA 53 push bx ;save ds base
0CDB E8EFF9 06CD call setcpustate
0CDE 5A pop dx ;get ds base back
0CDF E8ADF6 038F call setdmab ;set dma base
0CE2 BA8000 mov dx,80h
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 36
0CE5 E89DF6 0385 call setdma ;default to 80h in user's DS
0CE8 BA5C00 MOV DX,OFFSET FCB
0CEB E860F6 034E CALL CLOSE
0CEE C6066E1245 mov mode,'E'
0CF3 BE0000 mov si,0
0CF6 BF7212 mov di,offset basepagesave
0CF9 1E push ds
0CFA 07 pop es ;set es to ddt's segment
0CFB 2EA1AE11 mov ax,userds
0CFF 1E push ds ;save it
0D00 8ED8 mov ds,ax
0D02 B93000 mov cx,48
0D05 F3A4 rep movs al,al ;copy user's base page into ddt save area
0D07 1F pop ds ;restore ds
0D08 E8D302 0FDE call verify ;display load info
0D0B FF0E0412 DEC CONPTR ;TO RESCAN CR
0D0F E9CC00 0DDE JMP IFCB ;TO CLEAR FCB
eerr:
0D12 E9CAF5 02DF jmp err
;
; ***************************
; * *
; * f - fill memory *
; * *
; ***************************
;
fill:
0D15 E8BEFC 09D6 call checkword ;check for 'FW'
0D18 BF5C12 mov di,offset type2loc
0D1B E80BFD 0A29 call getsegandoff
0D1E E89EFC 09BF call getoffset ;get end address
0D21 891E6012 mov usermax,bx ;save end address
0D25 E8A3FC 09CB call getlastoffset ;get fill constant
0D28 F6066D1201 test wmode,1
0D2D 7504 0D33 jnz fil0
0D2F 0AFF or bh,bh ;if not wmode, high byte must be 0
0D31 7525 0D58 jnz filerr
fil0:
0D33 8B0E6012 mov cx,usermax ;get end address
0D37 2B0E5C12 sub cx,type2loc ;compare for valid range
0D3B 721B 0D58 jb filerr ;error if start > end
fil1:
0D3D C43E5C12 les di,dword ptr type2loc
0D41 8BC3 mov ax,bx ;get fill constant
0D43 E829FC 096F call set8or16
0D46 BE5C12 mov si,offset type2loc
0D49 E84DFC 0999 call inc1or2
0D4C 7209 0D57 jb filret ;stop if wrap occurred
0D4E A15C12 mov ax,type2loc
0D51 3B066012 cmp ax,usermax
0D55 76E6 0D3D jbe fil1
filret:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 37
0D57 C3 ret
filerr:
0D58 E984F5 02DF jmp err
;
; **********************************
; * *
; * g - go to user program *
; * *
; **********************************
;
gouser:
0D5B 2EA1AC11 mov ax,usercs
0D5F A31812 mov goseg,ax ;default goseg = usercs
0D62 2EA1B411 mov ax,userip
0D66 A31612 mov goloc,ax ;default goloc = userip
0D69 C6066C1200 mov numreq,0 ;number not required in G command
0D6E BF1612 mov di,offset goloc
0D71 E8B5FC 0A29 call getsegandoff ;get start address
0D74 3C0D cmp al,eol
0D76 742B 0DA3 jz gorestore ;if eol, no breakpoints set
0D78 A11812 mov ax,goseg
0D7B A32912 mov brk1seg,ax
0D7E A32E12 mov brk2seg,ax ;defaults for breakpoint segments = goseg
0D81 BF2712 mov di,offset brk1loc
0D84 E8A2FC 0A29 call getsegandoff ;get first breakpoint
0D87 50 push ax ;save terminating char
0D88 BF2712 mov di,offset brk1loc
0D8B E8A5F9 0733 call setbp ;save breakpoint in table
0D8E 58 pop ax ;get char
0D8F 3C0D cmp al,eol
0D91 7410 0DA3 jz gorestore ;only one breakpoint
0D93 BF2C12 mov di,offset brk2loc
0D96 E890FC 0A29 call getsegandoff ;get second breakpoint
0D99 3C0D cmp al,eol
0D9B 751C 0DB9 jnz goerr ;only 2 breakpoints allowed
0D9D BF2C12 mov di,offset brk2loc
0DA0 E890F9 0733 call setbp ;set second breakpoint
gorestore:
0DA3 C606491200 mov skipbdos,0 ;make sure it's 0 since we aren't in T/U mode
0DA8 A11812 mov ax,goseg
0DAB 2EA3AC11 mov usercs,ax ;usercs = goseg
0DAF A11612 mov ax,goloc
0DB2 2EA3B411 mov userip,ax ;userip = goloc
0DB6 E946FB 08FF jmp rstore ;restore user CPU state
goerr:
0DB9 E886F9 0742 call bpclear ;in case any were set
0DBC E920F5 02DF jmp err
;
;
; ************************
; * *
; * h - hex math *
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 38
; * *
; ************************
;
hexmath:
0DBF E8FDFB 09BF call getoffset
0DC2 53 push bx ;save first value
0DC3 E805FC 09CB call getlastoffset
0DC6 58 pop ax ;get first value
0DC7 50 push ax ;save a copy
0DC8 03C3 add ax,bx
0DCA 53 push bx ;save second value
0DCB 50 push ax ;save sum
0DCC E84EF6 041D call crlf
0DCF 58 pop ax ;get sum
0DD0 E8A2F6 0475 call printword ;print sum
0DD3 E859F6 042F call blank
0DD6 5B pop bx ;get second value
0DD7 58 pop ax ;get first value
0DD8 2BC3 sub ax,bx
0DDA E898F6 0475 call printword ;print difference
0DDD C3 ret
;
; ****************************************
; * *
; * i - input file control block *
; * *
; ****************************************
;
ifcb:
0DDE FF360412 push conptr ;save input pointer
0DE2 BF5C00 mov di,offset fcb
0DE5 E8A9F6 0491 call parse
0DE8 3C0D cmp al,eol
0DEA 7504 0DF0 jnz i0 ;only one filename
0DEC FF0E0412 dec conptr ;to rescan eol and blank second filename in fcb
i0:
0DF0 BF6C00 mov di,offset fcb2
0DF3 E8A6F6 049C call parse2 ;parse second filename
0DF6 1E push ds
0DF7 07 pop es ;point to DDT's ds
0DF8 8F060412 pop conptr ;restore input pointer
0DFC BF8100 mov di,81h ;move command tail to [es]:[di]
0DFF 2BC9 sub cx,cx ;zero count
i1:
0E01 E8EDF5 03F1 call conin ;get char from command tail
0E04 3C0D cmp al,eol ;end of command tail?
0E06 7404 0E0C jz i2
0E08 AA stos al ;store in user's base page
0E09 41 inc cx ;increment count
0E0A EBF5 0E01 jmps i1 ;loop until eol
i2:
0E0C B000 mov al,0
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 39
0E0E AA stos al ;store 0 at end of string
0E0F 26880E8000 mov es:.80h,cl ;store count at start of buffer
0E14 803E6E1245 cmp mode,'E'
0E19 750F 0E2A jnz idone ;if no file loaded with E command, we're done
0E1B BE5C00 mov si,offset fcb
0E1E 8BFE mov di,si
0E20 2E8E06AE11 mov es,userds
0E25 83C126 add cx,38 ;total bytes to move = # in command + 36 (fcb)
; +2 (0 at end of command and count byte)
0E28 F3A4 rep movs al,al ;move fcb from ddt86 basepage to user's basepage
idone:
0E2A C3 ret
ierr:
0E2B E9B1F4 02DF jmp err
;
; **********************************
; * *
; * l - list assembly code *
; * *
; **********************************
;
lassm:
0E2E F6063912FF test disempresent,0ffh
0E33 746C 0EA1 jz laserr
0E35 C606371200 mov lascntsw,0 ;don't use count if end addr specified
0E3A C6066C1200 mov numreq,0 ;ok if no entries
0E3F A15A12 mov ax,type1seg
0E42 A33312 mov lasseg,ax ;default to type1 seg
0E45 BF3112 mov di,offset lasloc
0E48 E8DEFB 0A29 call getsegandoff
0E4B 3C0D cmp al,eol
0E4D A13312 mov ax,lasseg
0E50 A35A12 mov type1seg,ax ;update default type1 seg
0E53 7405 0E5A jz las0
0E55 E873FB 09CB call getlastoffset ;if ',', get end address
0E58 EB0E 0E68 jmps las1
las0:
0E5A C606371201 mov lascntsw,1 ;disassemble fixed # of instructions
0E5F A01512 MOV AL,NLINES
0E62 A23812 MOV LASCNT,AL
0E65 BBFFFF mov bx,0ffffh ;set lasmax to big number
las1:
0E68 891E3512 mov lasmax,bx
las2:
0E6C 8B3E3112 mov di,lasloc
0E70 3B3E3512 cmp di,lasmax
0E74 772A 0EA0 ja lasret
0E76 57 push di
0E77 E8AEF5 0428 CALL CRLFCHK
0E7A 5F pop di
0E7B 8E063312 mov es,lasseg
0E7F 06 push es
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 40
0E80 57 push di ;for disem call (PL/M)
0E81 E8E5F5 0469 call printdword
0E84 E8A8F5 042F call blank
0E87 E87605 1400 call disem
0E8A 3B063112 cmp ax,lasloc
0E8E 7210 0EA0 jb lasret ;stop if wrap occurred
0E90 A33112 mov lasloc, ax
0E93 F6063712FF test lascntsw,0ffh
0E98 74D2 0E6C jz las2
0E9A FE0E3812 dec lascnt
0E9E 75CC 0E6C jnz las2
lasret:
0EA0 C3 ret
laserr:
0EA1 E93BF4 02DF jmp err
;
; **************************
; * *
; * m - move block *
; * *
; **************************
;
move:
0EA4 BF5C12 mov di,offset type2loc
0EA7 E87FFB 0A29 call getsegandoff
0EAA E812FB 09BF call getoffset ;get end offset
0EAD 891E6012 mov usermax,bx
0EB1 3C0D cmp al,eol
0EB3 743A 0EEF jz moverr ;need 3 arguments
0EB5 2B1E5C12 sub bx,type2loc
0EB9 7234 0EEF jb moverr ;error if start > end
0EBB A15E12 mov ax,type2seg
0EBE A36412 mov userseg2,ax ;default to same seg as source
0EC1 BF6212 mov di,offset userloc2
0EC4 E862FB 0A29 call getsegandoff ;get destination address
0EC7 3C0D cmp al,eol
0EC9 7524 0EEF jnz moverr ;error if more than 3 arguments
mov0:
0ECB C4365C12 les si,dword ptr type2loc
0ECF 268A04 mov al,es:[si] ;get source byte
0ED2 C43E6212 les di,dword ptr userloc2
0ED6 E8A7FA 0980 call setbyte ;put destination byte
0ED9 FF065C12 inc type2loc
0EDD 740F 0EEE jz movret ;don't allow wraparound
0EDF FF066212 inc userloc2
0EE3 7409 0EEE jz movret ;don't allow wraparound in destination segment
0EE5 A15C12 mov ax,type2loc
0EE8 3B066012 cmp ax,usermax ;check for done
0EEC 76DD 0ECB jna mov0
movret:
0EEE C3 ret
moverr:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 41
0EEF E9EDF3 02DF jmp err
;
; *************************
; * *
; * r - read file *
; * *
; *************************
;
read:
0EF2 E8FCF4 03F1 call conin ;get first command char
0EF5 3C0D cmp al,eol ;check for no input
0EF7 7450 0F49 jz rerr ;filename must be included in command
0EF9 FF0E0412 dec conptr ;to rescan first char
0EFD BF5C00 mov di,offset fcb
0F00 E88EF5 0491 call parse
0F03 7444 0F49 jz rerr ;no '?' or '*' allowed
0F05 3C0D cmp al,eol
0F07 7540 0F49 jnz rerr ;no parameters after filename
0F09 BA5C00 mov dx,offset fcb
0F0C E830F4 033F call open
0F0F C7066812FFFF mov mcblen,0ffffh ;largest memory request
0F15 BA6612 mov dx,offset mcb
0F18 E879F4 0394 call getmaxmem ;get size of largest chuck of memory
0F1B BA6612 mov dx,offset mcb
0F1E E87DF4 039E call allocabsmem ;allocate block returned from getmaxmem
0F21 E82DFB 0A51 call readfile ;read file into memory block
0F24 C6066A1200 mov mcbext,0 ;only free memory at mbase
0F29 BA6612 mov dx,offset mcb
0F2C E87EF4 03AD call freemem ;free memory not used in read (read updated mcb)
0F2F A13C12 mov ax,startreadseg
0F32 A35E12 mov type2seg,ax ;set default type2 segment to file just read
0F35 A35A12 mov type1seg,ax ;also type1 segment
0F38 2BC0 sub ax,ax
0F3A A30912 mov disloc,ax ;display pointer offset = 0
0F3D A33112 mov lasloc,ax ;list pointer offset = 0
0F40 C6066E1252 mov mode,'R' ;last disk input was read (not execute)
0F45 E89600 0FDE call verify
0F48 C3 ret
rerr:
0F49 E993F3 02DF jmp err
;
; **************************
; * *
; * s - set memory *
; * *
; **************************
;
setmem:
0F4C E887FA 09D6 call checkword ;check for 'SW'
0F4F BF5C12 mov di,offset type2loc
0F52 E8D4FA 0A29 call getsegandoff
set0:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 42
0F55 E8C5F4 041D call crlf
0F58 C43E5C12 les di,dword ptr type2loc
0F5C E80AF5 0469 call printdword
0F5F E8CDF4 042F call blank
0F62 C4365C12 les si,dword ptr type2loc
0F66 E8F4F4 045D call print8or16
0F69 E8C3F4 042F call blank
0F6C E868F4 03D7 call getline
0F6F E87FF4 03F1 call conin
0F72 3C0D cmp al,eol
0F74 741F 0F95 jz set2
0F76 3C2E cmp al,'.'
0F78 7423 0F9D jz setret
0F7A FF0E0412 dec conptr ;to rescan first character
0F7E E84AFA 09CB call getlastoffset
0F81 8BC3 mov ax,bx ;get new value to ax
0F83 F6066D1201 test wmode,1
0F88 7504 0F8E jnz set1
0F8A 0AFF or bh,bh
0F8C 7510 0F9E jnz seterr ;must be < 256 if not SW
set1:
0F8E C43E5C12 les di,dword ptr type2loc
0F92 E8DAF9 096F call set8or16
set2:
0F95 BE5C12 mov si,offset type2loc
0F98 E8FEF9 0999 call inc1or2
0F9B 73B8 0F55 jnb set0
setret:
0F9D C3 ret
seterr:
0F9E E93EF3 02DF jmp err
;
; ***************************************
; * *
; * t - trace program execution *
; * *
; ***************************************
;
trace:
0FA1 C606481201 mov traceprint,1
trace0: ;untrace enters here with traceprint = 0
0FA6 E848F4 03F1 call conin
0FA9 3C53 cmp al,'S' ;check for TS
0FAB B401 mov ah,1
0FAD 7406 0FB5 jz tr0 ;if TS, set segflag to 1
0FAF FECC dec ah ;else set segflag to 0, and
0FB1 FF0E0412 dec conptr ;decrement pointer to rescan character
tr0:
0FB5 88265412 mov segflag,ah ;print segment registers or not
0FB9 C70646120100 mov tracecount,1 ;default to 1 instruction trace
0FBF E8E3F9 09A5 call getnumber
0FC2 3C0D cmp al,eol
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 43
0FC4 750E 0FD4 jnz traceerr ;only 1 parameter allowed
0FC6 0AE4 or ah,ah ;see if a number was entered
0FC8 7404 0FCE jz trace1 ;skip if no number typed
0FCA 891E4612 mov tracecount,bx ;store number of instructions to trace
trace1:
0FCE E8C400 1095 call xdisp ;display CPU state
0FD1 E9C8F8 089C jmp tracerestore ;restore user's CPU state and return
traceerr:
0FD4 E908F3 02DF jmp err
;
; ******************************************
; * *
; * u - untraced program execution *
; * *
; ******************************************
;
untrace:
0FD7 C606481200 mov traceprint,0
0FDC EBC8 0FA6 jmps trace0 ;common code with trace command
;
; *********************************
; * *
; * v - display file info *
; * *
; *********************************
;
verify:
0FDE A06E12 mov al,mode
0FE1 3C52 cmp al,'R'
0FE3 7407 0FEC jz verifyr
0FE5 3C45 cmp al,'E'
0FE7 7421 100A jz verifye
0FE9 E9F3F2 02DF jmp err ;neither R nor E command done
verifyr:
0FEC E82EF4 041D call crlf
0FEF BED601 mov si,offset readm
0FF2 E848F4 043D call printm
0FF5 E825F4 041D call crlf
0FF8 C43E3A12 les di,dword ptr startreadoff
0FFC E86AF4 0469 call printdword
0FFF E82DF4 042F call blank
1002 C43E3E12 les di,dword ptr endreadoff
1006 E860F4 0469 call printdword
1009 C3 ret
;
verifye:
100A E810F4 041D call crlf
100D B90300 mov cx,3
1010 E822F4 0435 call tabs
1013 BED601 mov si,offset readm
1016 E824F4 043D call printm ;print header
1019 B000 mov al,0 ;initialize count to 0
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 44
v0:
101B 50 push ax ;save it
101C 58 pop ax ;get count
101D 50 push ax ;save it
101E E864F6 0685 call printseginfo ;print name, start, end of segment if non-zero
1021 58 pop ax ;get count
1022 FEC0 inc al ;increment it
1024 803E771201 cmp byte ptr basepagesave+5,1 ;check for 8080 model
1029 7404 102F jz verret ;no more segments if 8080 model
102B 3C08 cmp al,8 ;max of 8 segments described in base page
102D 72EC 101B jb v0 ;done when count = 8
verret:
102F C3 ret
;
; ******************************************
; * *
; * w - write memory block to disk *
; * *
; ******************************************
;
write:
1030 A13C12 mov ax,startreadseg
1033 A34D12 mov startwriteseg,ax
1036 A13A12 mov ax,startreadoff
1039 A34B12 mov startwriteoff,ax
103C A14012 mov ax,endreadseg
103F A35112 mov endwriteseg,ax
1042 A13E12 mov ax,endreadoff
1045 A34F12 mov endwriteoff,ax
1048 E8A6F3 03F1 call conin
104B 3C0D cmp al,eol ;check for no parameters
104D 7443 1092 jz werr ;must have a filename
104F FF0E0412 dec conptr ;to rescan first char
1053 BF5C00 mov di,offset fcb
1056 E838F4 0491 call parse ;get filename
1059 7437 1092 jz werr ;don't allow '?' or '*'
105B 3C0D cmp al,eol
105D 7509 1068 jnz w0 ;not end of input - must be 2 parameters
105F 803E6E1252 cmp mode,'R' ;see if a file was read in
1064 752C 1092 jnz werr ;no file read - must have start, end addresses
1066 EB20 1088 jmps w1 ;continue with write
w0:
1068 A15A12 mov ax,type1seg
106B A34D12 mov startwriteseg,ax ;set default to userds
106E BF4B12 mov di,offset startwriteoff
1071 E8B5F9 0A29 call getsegandoff ;get start address
1074 3C0D cmp al,eol
1076 741A 1092 jz werr ;need 2 parameters
1078 A14D12 mov ax,startwriteseg
107B A35112 mov endwriteseg,ax ;end defaults to start
107E BF4F12 mov di,offset endwriteoff
1081 E8A5F9 0A29 call getsegandoff ;get end address
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 45
1084 3C0D cmp al,eol
1086 750A 1092 jnz werr ;no more than 2 parameters
w1:
1088 E831FA 0ABC call writefile
108B BA5C00 mov dx,offset fcb
108E E8BDF2 034E call close
1091 C3 ret
werr:
1092 E94AF2 02DF jmp err
;
; ***************************************
; * *
; * x - display/alter CPU state *
; * *
; ***************************************
;
xdisp: ;display CPU state
1095 E816F7 07AE CALL SETDEFSEG ;SET TYPE1SEG, LASLOC TO CS:IP
1098 F6067012FF TEST COL40,0FFH
109D 751A 10B9 JNZ XD40
109F E89BF5 063D call printregheader
xnohdr: ;entry point to display CPU state without header
10A2 F6067012FF TEST COL40,0FFH
10A7 7517 10C0 JNZ XNH40
10A9 E871F3 041D call crlf
10AC E8B5F4 0564 call printflags
10AF E87DF3 042F call blank
10B2 E823F5 05D8 call printregs
10B5 E8A5F5 065D call printinstr ;disassemble instruction at [cs:ip]
10B8 C3 ret
;
XD40:
10B9 E86FF5 062B CALL PREGHDR1
10BC B001 MOV AL,1
10BE EB02 10C2 JMPS XD0
XNH40:
10C0 B000 MOV AL,0
XD0:
10C2 50 PUSH AX ;SAVE HEADER/NO HEADER FLAG
10C3 E857F3 041D CALL CRLF
10C6 E89BF4 0564 CALL PRINTFLAGS
10C9 E863F3 042F CALL BLANK
10CC E8FAF4 05C9 CALL PREG1
10CF E84BF3 041D CALL CRLF
10D2 58 POP AX
10D3 FEC8 DEC AL
10D5 7506 10DD JNZ XD1
10D7 E85BF5 0635 CALL PREGHDR2
10DA E840F3 041D CALL CRLF
XD1:
10DD E8F3F4 05D3 CALL PREG2
10E0 E87AF5 065D CALL PRINTINSTR
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 46
10E3 C3 RET
xcom:
10E4 C606541201 mov segflag,1 ;display seg reg's in x command
10E9 E805F3 03F1 call conin
10EC 3C0D cmp al,eol ;check for command by itself
10EE 74A5 1095 jz xdisp ;if so, simply display CPU state
10F0 A25712 mov xtemp,al ;else save char
10F3 E8FBF2 03F1 call conin
10F6 3C0D cmp al,eol ;check for single character after X
10F8 746A 1164 jz xflag ;if so, must be a flag name
10FA 8A265712 mov ah,xtemp ;else it's a reg name
10FE 0C80 or al,80h ;since names are declared that way
1100 86C4 xchg al,ah ;since that's how it is in memory
1102 E826F4 052B call chkreg ;check for valid reg name + store number in regnum
1105 E8E9F2 03F1 call conin
1108 3C0D cmp al,eol
110A 7555 1161 jnz xerr ;eol must follow reg name
x0:
110C E80EF3 041D call crlf
110F 8B0E5512 mov cx,regnum
1113 E8EBF4 0601 call printregname
1116 E816F3 042F call blank
1119 8B0E5512 mov cx,regnum
111D E8D5F4 05F5 call printregval
1120 E80CF3 042F call blank
1123 E8B1F2 03D7 call getline
1126 E8C8F2 03F1 call conin
1129 3C2E cmp al,'.'
112B 746E 119B jz xret ;done when '.' entered
112D FF0E0412 dec conptr ;else rescan character
1131 E871F8 09A5 call getnumber
1134 3C0D cmp al,eol
1136 7529 1161 jnz xerr ;eol must follow number
1138 0AE4 or ah,ah ;see if non-blank entry
113A 7419 1155 jz xnext ;if blank, go to next reg
113C 8B0E5512 mov cx,regnum
1140 8BC3 mov ax,bx ;get new value
1142 80F908 cmp cl,8 ;are we updating cs?
1145 7503 114A jnz x1
1147 A35A12 mov type1seg,ax ;if so, update default type1 segment
x1:
114A 80F909 cmp cl,9 ;are we updating ds?
114D 7503 1152 jnz x2
114F A35E12 mov type2seg,ax ;if so, update default type2 segment
x2:
1152 E805F4 055A call setreg
xnext:
1155 FF065512 inc regnum
1159 833E55120D cmp regnum,totreg
115E 72AC 110C jb x0
1160 C3 ret
xerr:
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 47
1161 E97BF1 02DF jmp err
;
xflag:
1164 A05712 mov al,xtemp ;get flag name
1167 E8D7F3 0541 call checkflag ;check for valid flag name
116A E8B0F2 041D call crlf
116D 8B0E5512 mov cx,regnum ;restore flag number
1171 E819F4 058D call printflagname
1174 E8B8F2 042F call blank
1177 8B0E5512 mov cx,regnum
117B E82BF4 05A9 call printflagval
117E E8AEF2 042F call blank
1181 E853F2 03D7 call getline
1184 E81EF8 09A5 call getnumber
1187 3C0D cmp al,eol
1189 75D6 1161 jnz xerr ;eol must follow number
118B 0AE4 or ah,ah ;see if non-blank entry
118D 740C 119B jz xret ;if blank, done
118F 83FB01 cmp bx,1
1192 77CD 1161 ja xerr ;flag value must be 0 or 1
1194 8B0E5512 mov cx,regnum
1198 E8D8F3 0573 call setflag
xret:
119B C3 ret
;
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 48
eject
; *********************************
; * *
; * d a t a a r e a *
; * *
; *********************************
;
; user regs must be in cseg, others may be in dseg
;
119C 0000 userax dw 0
119E 0000 userbx dw 0
11A0 0000 usercx dw 0
11A2 0000 userdx dw 0
11A4 0000 usersp dw 0
11A6 0000 userbp dw 0
11A8 0000 usersi dw 0
11AA 0000 userdi dw 0
11AC 0000 usercs dw 0
11AE 0000 userds dw 0
11B0 0000 userss dw 0
11B2 0000 useres dw 0
11B4 0000 userip dw 0
11B6 0000 userfl dw 0
119C userreg equ userax
;
11B8 0000 savess dw 0 ;temp holder for sp
11BA 0000 savesp dw 0 ;temp holder for sp
;
11BC breakfl rs 1 ;break/single step flag (must be in CS)
;
11BD endcs equ $
;
dseg
org offset endcs
;
; CCP STACK LOCATION
;
11BD 0000 CCPSS DW 0
11BF 0000 CCPSP DW 0
;
; console buffer declarations
;
0040 conbuffmax equ 64
11C1 40 conbuffhdr db conbuffmax
11C2 00 conbuffcnt db 0
11C3 conbuff rs conbuffmax+1 ;leave room for eol
1204 0000 conptr dw 0
;
; a command declarations
;
1206 01 assempresent db 1 ;assembler in memory flag
1207 asmspsav rw 1 ;temporary save for stack pointer
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 49
;
; d command declarations
;
1209 0000 disloc dw 0 ;offset for display
120B 0000 disseg dw 0 ;segment for display
120D dismax rw 1 ;end offset of display
120F tdisp rw 1 ;temporary storage for disloc
1211 00 LINEMAX DB 0 ;# OF BYTES PER LINE
1212 10 ND80 DB 16 ;16 BYTES PER LINE IN 80 COL MODE
1213 06 ND40 DB 6 ;6 BYTES PER LINE IN 40 COL MODE
1214 08 NDW40 DB 8 ;8 BYTES (4 WORDS) FOR DW IN 40 COL MODE
1215 0C NLINES DB 12 ;DEFAULT NUMBER OF LINES FOR L, D COMMANDS
;
; g command declarations
;
1216 0000 goloc dw 0
1218 0000 goseg dw 0
121A vectorsave rs 12 ;save area for bytes at 0004h to 000fh
1226 00 bpcnt db 0 ;breakpoint count
1227 0000 brk1loc dw 0
1229 0000 brk1seg dw 0
122B 00 brk1byt db 0
122C 0000 brk2loc dw 0
122E 0000 brk2seg dw 0
1230 00 brk2byt db 0
;
; l command declarations
;
1231 0000 lasloc dw 0
1233 0000 lasseg dw 0
1235 0000 lasmax dw 0
1237 lascntsw rb 1 ;# instructions specified or not
1238 lascnt rb 1 ;number of instructions to disassemble
1239 01 disempresent db 1 ;disassembler in memory flag
;
; r command declarations
;
123A startreadoff rw 1 ;offset where file read starts
123C startreadseg rw 1 ;segment where file read starts
123E endreadoff rw 1 ;offset where file read ends
1240 endreadseg rw 1 ;segment where file read ends
1242 dmaoff rw 1 ;offset of 20-bit dma address
1244 dmaseg rw 1 ;segment of 20-bit dma address
;
; t/u command declarations
;
1246 tracecount rw 1 ;number of instructions to trace
1248 traceprint rb 1 ;display CPU state on each step flag
1249 00 skipbdos db 0 ;set when trace suspended during BDOS call
124A 00 USERIFOFF DB 0 ;SET WHEN DDT86 MUST REENABLE USER IF
;
; w command declarations
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 50
;
124B startwriteoff rw 1 ;offset where file write starts
124D startwriteseg rw 1 ;segment where file write starts
124F endwriteoff rw 1 ;offset where file write ends
1251 endwriteseg rw 1 ;segment where file write ends
;
; x command declarations
;
1253 00 NREG DB 0 ;CURRENT NUMBER OF REGISTER NAMES TO DISPLAY
;(MAY DIFFER FOR 40 COLUMN MODE)
000D TOTREG EQU 13 ;TOTAL NUMBER OF REGISTER NAMES
0009 nflag equ 9 ;number of flag names
1254 01 segflag db 1 ;print segment register flag
1255 regnum rw 1 ;temp for reg/flag number
1257 xtemp rb 1 ;temp for first char of reg name
;
1258 0000 type1loc dw 0 ;offset for type 1 commands
125A 0000 type1seg dw 0 ;segment for type 1 commands
125C 0000 type2loc dw 0 ;offset for type 2 commands
125E 0000 type2seg dw 0 ;segment for type 2 commands
1260 usermax rw 1
1262 userloc2 rw 1
1264 userseg2 rw 1
;
; memory control block declarations
;
1266 mcb rs 0 ;used in reading/writing file
1266 0000 mcbbase dw 0 ;segment of memory block
1268 0000 mcblen dw 0 ;length of memory block
126A 00 mcbext db 0 ;returned value from bdos memory functions
;
126B sysif rb 1 ;system interrupt flag
126C numreq rb 1 ;number required or optional
126D wmode rb 1 ;set for DW, FW and SW commands
126E 49 mode db 'I' ;last disk access with 'R' or 'E' command
126F 00 savevecflag db 0 ;save/restore bp and ss vectors, or not
1270 00 COL40 DB 0 ;PATCHED TO 1 FOR 40 COLUMN CONSOLE
1271 00 ERRMODE DB 0 ;SET IF BDOS RETURN ERR MODE SET (V3.0)
;
1272 basepagesave rb 48 ;copy of user's base page
;
; parsing declarations
;
12A2 203D2E2C3A3B delims db ' ', '=', '.', ',', ':', ';', '[', ']', '<', '>', eol
5B5D3C3E0D
000B ndelims equ offset $ - offset delims
12AD 00 lastchar db 0
12AE 0000 fcbadr dw 0 ;temp storage for fcb address
;
12B0 rs stsize ;stack size
1310 stackp rs 0 ;top of stack
;
CP/M ASM86 1.1 SOURCE: DDT86.A86 DDT86 1.1 10/2/81 PAGE 51
if debug
;
biosentryoff dw 0a00h ;empty part of ccp (hopefully)
biosentryseg dw 0 ;same as bdos segment
;
endif
;
end
END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 32%