;----- ;The following code and data form the body of ;the 8086/88 cpu software Monitor program. Through ;the Monitor software the user may perform all ;necessary steps needed to load, edit and execute ;an 8086/88 machine language program. ; ;C1993, 1997 James L. Antonakos code segment para 'code' main proc far assume cs:code,ds:data,es:data2 ;segment usage is as follows: ; CS for machine code ; DS for rom-based data tables ; ES for user ram operations ; SS for ram-stack operations org 100h ; ;this is the starting address of the ;reserved system-ram area. rtop equ 1f80h ;----- ;This is where the re-start (int 95h) and ;breakpoint (int 03h) return vectors are ;generated. lea bx,re_strt mov cx,0e00h mov ax,0 mov si,0 mov ds,ax mov [si+254h],bx mov [si+256h],cx lea bx,br_entr mov [si+0ch],bx mov [si+0eh],cx ;----- ;Initialize all segment registers and create ;the system stack. Also initialize all system ;i/o devices, then greet the user with the ;sign-on message and go get a command! mov ax,cs add ax,data mov ds,ax sub ax,ax mov es,ax mov ss,ax mov sp,2000h call in_it lea si,hello call s_end jmp get_com ;----- ;BR_ENTR ;This is where we re-enter the monitor via ;the occurance of a breakpoint interrupt (int 03h) ;in the user program. The stack is cleaned up ;and the CS and IP from the caller stored for later ;use. All registers and flags are saved and ;printed out along with a message showing the ;memory location where the breakpoint was ;encountered. In addition, the opcode that was ;previously replaced by the int 03h byte (0cch) ;is replaced, thus restoring the original user ;program. ; ;save and display current environment br_entr:call envir ; ;print breakpoint message and CS:IP lea si,br_bak call s_end pop ax mov es:[br_ip+rtop],ax pop ax mov es:[br_cs+rtop],ax pop ax mov dx,es:[br_cs+rtop] call h_out mov al,':' call c_out mov dx,es:[br_ip+rtop] dec dx call h_out mov al,']' call c_out ; ;restore user code mov si,es:[b_mma+rtop] mov al,es:[op_kode+rtop] mov es:[si],al ; ;clear breakpoint status mov es:[br_stat+rtop],0 jmp get_com ;----- ;RE_STRT ;This is where the monitor is re-entered by ;the occurance of an 'int 95h' in the user ;program. All registers and flags are saved ;and printed along with a message saying from ;what CS:IP the user program interrupted. ; ;This routine falls into GET_COM. re_strt:call envir lea si,renter call s_end pop ax mov es:[br_ip+rtop],ax pop ax mov es:[br_cs+rtop],ax pop ax mov dx,es:[br_cs+rtop] call h_out mov al,':' call c_out mov dx,es:[br_ip+rtop] sub dx,2 call h_out mov al,']' call c_out ;----- ;GET_COM ;This is where we get a command from the ;user and decide what routine address to jump ;to for execution. Two tables are used. One ;contains a list of all valid command letters. ;The second contains a respective list of the ;addresses of the command routines. A sequential ;comparison search is made of the first table, ;comparing each element with the command letter ;just entered by the user. When a match is ;found, si points to the memory locations ;where the address for the command routine is ;saved. The command routines are always jumped ;to, never called. ; ;output prompt, get a command letter, ;echo it and convert into upper-case. get_com:mov sp,2000h call crlf mov al,'>' call c_out call c_in call c_out call ch_case ; ;ignore if CR cmp al,13 jz get_com ; ;look for command match mov cx,num_com mov si,0 c_test: cmp al,coms[si] jz chk_sn add si,2 loop c_test ; ;command not found, oops call error jmp get_com ; ;only CR and SP are valid after the ;command letter. chk_sn: call c_in cmp al,13 jz do_jmp call c_out cmp al,20h jz do_jmp call error jmp get_com ; ;jump to command routine do_jmp: jmp j_umps[si] ;----- ;L_OAD ;This routine takes care of loading ;a standard Intel-hex file. It recog- ;nizes 4 record types: ;(00) data record ;(01) end-of-file record ;(02) extended address record ;(03) start address record ; ;init values and wait for record start l_oad: call crlf mov bp,400h nxt_rec:mov es:[c_sum+rtop],0 kolon: call c_in call c_out cmp al,':' jnz kolon ; ;get record length call get_byt mov cl,al mov ch,0 ; ;get offset call get_wrd mov di,ax ; ;get and decode record type call get_byt cmp al,0 jz d_rec cmp al,1 jz eof_rec cmp al,2 jz ea_rec cmp al,3 jz sa_rec ; ;oops, unidentified record type lea si,urt call s_end jmp get_com ; ;read bytes into memory d_rec: call get_byt mov es:[bp][di],al inc di loop d_rec ; ;and check sum call get_byt call chk_sum jmp nxt_rec ; ;check sum and return to command level eof_rec:call get_byt call chk_sum jmp get_com ; ;load new segment address ea_rec: call get_wrd shl ax,1 shl ax,1 shl ax,1 shl ax,1 mov bp,ax ; ;check sum and get next record call get_byt call chk_sum jmp nxt_rec ; ;load starting address even though ;we don't use it sa_rec: call get_wrd ;CS value call get_wrd ;IP value call get_byt call chk_sum jmp nxt_rec ;----- ;B_RKP ;This routine is used to get a breakpoint ;address from the user. The opcode byte at ;the selected location is saved and replaced ;with the byte for int 03h (0cch). If a ;breakpoint is already saved the user is ;informed and no changes are made to the ;current breakpoint. ; ;get the breakpoint address b_rkp: call get_num ; ;check breakpoint status mov al,es:[br_stat+rtop] cmp al,0 jz do_bp ; ;sorry, breakpoint already saved lea si,bp_as call s_end jmp get_com ; ;save breakpoint address and user opcode do_bp: mov es:[b_mma+rtop],dx mov si,dx mov al,es:[si] mov es:[op_kode+rtop],al ; ;insert breakpoint code mov al,0cch mov es:[si],al ; ;adjust status and inform user that ;the breakpoint is saved mov es:[br_stat+rtop],1 lea si,bp_sa call s_end jmp get_com ;----- ;C_BRP ;This routine determines if a breakpoint is ;currently in effect by checking the status ;byte and if so, replaces the original user ;code and clears the breakpoint status. ; ;check breakpoint status c_brp: mov al,es:[br_stat+rtop] cmp al,1 jz op_ld ; ;breakpoint not active, sorry lea si,br_alc call s_end jmp get_com ; ;output breakpoint cleared message, restore ;user code and clear status byte. op_ld: lea si,br_clr call s_end mov si,es:[b_mma+rtop] mov al,es:[op_kode+rtop] mov es:[si],al mov es:[br_stat+rtop],0 jmp get_com ;----- ;T_EST ;This routine is used to test the analog ;i/o circuitry. There are two routines. ;The first repeatedly outputs sine-wave ;data from a rom-table to the 1408 DAC. ;The second routine echo's data read into ;the ADC back out to the 1408. ; ;offer a choice t_est: lea si,tst_msg call s_end get_rp: call c_in call c_out cmp al,'1' jz waver cmp al,'2' jz ek_o ; ;must choose 1 or 2 call error jmp get_rp ; ;'sine' is a rom-table containing 256 ;values that sequentially make up a ;normalized sine wave. There is no exit ;from the loop except for a system reset. waver: mov cx,256 mov si,0 p_ie: mov al,sine[si] out d_ac,al add si,1 loop p_ie jmp waver ; ;check ADC status. If active, read ADC data, ;complement it (a necessary conversion if the ;1408 is to track the ADC) and send it out to ;the 1408. This routine loops forever and ever. ek_o: in al,ad_stat and al,01h jnz ek_o mov al,ad_rd out ad_stat,al in al,a_dc not al out d_ac,al mov al,ad_wr out ad_stat,al mov al,ad_nom out ad_stat,al jmp ek_o ;----- ;I_NIT ;This routine is used to fill selected ;registers with custom data for use in ;a user program. The data for the 11 ;registers is stored in memory as 2-byte ;words starting at address r_data. When ;the 'go' command executes, it loads ;ax, bx, cx, dx, bp, si and di with ;their values and branches to the user ;program. The other registers sp, ss, ;es and ds are not changed because this ;may have an adverse effect on the operation ;of the monitor. ; ;prepare for 11 passes i_nit: mov si,0 mov cx,11 ; ;output register name i_nex: call crlf mov al,r_lets[si] call c_out mov al,r_lets[si+1] call c_out call blank mov al,'-' call c_out call blank ; ;output saved register value mov dx,es:r_data[rtop+si] call h_out ; ;ask use for new value mov al,'?' call c_out call get_num ; ;no change? cmp bh,'0' jz nun ; ;load new value into register storage mov es:r_data[rtop+si],dx ; ;prepare for next pass nun: add si,2 loop i_nex jmp get_com ;----- ;H_ELP ;Send the system help message to the user. ;It is simply a very long data string that ;terminates with a '$'. h_elp: lea si,h_msg call s_end jmp get_com ;----- ;A_UTH ;Displays the Author message. I have to ;get some recognition, don't I? a_uth: lea si,wr_by call s_end jmp get_com ;----- ;S_TOP ;This routine puts the 8088 into the HALT ;state, a useful place to examine signals. s_top: lea si,s_msg call s_end hlt ;----- ;M_OVE ;This routine is used to move a block ;of ram around in memory. The data of ;the ram block pointed to by si is moved ;into memory pointed to by di. ; ;get starting address m_ove: call get_num mov si,dx ; ;get ending address call get_num ; ;compute length of block sub dx,si mov cx,dx inc cx ; ;get transfer address call get_num mov di,dx ; ;do the data move mvit: mov al,es:[si] mov es:[di],al inc si inc di loop mvit jmp get_com ;----- ;D_REG ;This routine eventually jumps to ;D_ENV within the ENVIR routine and ;displays the saved contents of the ;11 system registers. d_reg: call dpr jmp get_com ;----- ;E_XEC ;This routine is used to transfer execution ;from the monitor to the user program stored ;somewhere in the first segment of memory ;(where CS=0). The stored data for registers ;ax, bx, cx, dx, bp, si and di is loaded into ;its respective register. The actual jump to ;the user code is actually a return accompliched ;by pushing the starting address specified by ;the user onto the stack as a 'return' address. e_xec: call get_num sub ax,ax push ax ;CS=0 push dx ;IP=user # call crlf mov ax,es:r_data[rtop+0] mov bx,es:r_data[rtop+2] mov cx,es:r_data[rtop+4] mov dx,es:r_data[rtop+6] mov bp,es:r_data[rtop+8] mov si,es:r_data[rtop+10] mov di,es:r_data[rtop+12] ret ;jump to routine ;----- ;E_XAM ;This routine is used to enter/change ;data in the system ram. The user enters ;the starting ram address. The routine ;prints the address, the data stored in the ;location and then gives the option to change ;the data byte stored there. The routine ;exits when only a CR is entered as data. ; ;get starting address e_xam: call get_num mov si,dx ; ;output the address do_lyn: call crlf mov dx,si call h_out call blank call blank ; ;output the data mov al,es:[si] call htoa ; ;ask for new data mov al,'?' call c_out call get_num ; ;no change? cmp bh,'0' jz e_mip ; ;replace data mov es:[si],dl ex_gna: inc si jmp do_lyn ; ;keep going or quit? e_mip: cmp al,20h jz ex_gna jmp get_com ;----- ;D_UMP ;This routine displays the contents of a selected ;range of memory locations. ; ;get starting address d_ump: call get_num push dx call blank ; ;get ending address call get_num pop si ; ;compute length of block sub dx,si mov cx,dx inc cx ; ;go start dump mov dx,si jmp do_dmp ; ;check for address wrap-around (is the ;least-significant digit a '0'?) chk_adr:mov dx,si mov al,dl and al,0fh jnz no_adr ; ;output address of next paragraph do_dmp: call crlf call h_out call blank no_adr: call blank ; ;output data byte mov al,es:[si] call htoa ; ;next location inc si loop chk_adr jmp get_com ;----- ;P_IN ;This is the port-input routine. Data from ;the port address specified by the user is ;displayed in []'s ; ;get port address p_in: call get_num call crlf mov al,'[' call c_out ; ;read port and output data in al,dx call htoa mov al,']' call c_out jmp get_com ;----- ;P_OUT ;This is the port-output routine. The user ;enters the port address and the byte of ;data to be output. ; ;get port address p_out: call get_num push dx mov al,' ' call c_out ; ;get data byte call get_num mov al,dl pop dx ; ;output data to port out dx,al jmp get_com main endp ;----- ;The remaining routines are all of a support nature. ;They are called by the main command routines, thus ;making the job of writing a 'command' a simple task ;aided by judicious calls to the following subroutines: ; ;----- ;IN_IT ;This routine initializes all system i/o devices and ;some status-type ram locations. ;Destroyed: al in_it proc near mov al,m8251 out s_ctrl,al mov al,c8251 out s_ctrl,al mov al,c8255 out ad_ctrl,al mov al,80h out d_ac,al mov al,ad_wr out ad_stat,al mov al,ad_nom out ad_stat,al mov es:[br_stat+rtop],0 in al,s_data ret in_it endp ;----- ;BLANK ;Output a blank (ASCII SP) to the display. ;Destroyed: al blank proc near mov al,20h call c_out ret blank endp ;----- ;CRLF ;Output a newline sequence to the display ;(ASCII CR, LF). ;Destroyed: al crlf proc near mov al,13 call c_out mov al,10 call c_out ret crlf endp ;----- ;HTOA ;This routine performs hex-to-ASCII conversion. ;The data in register al is converted into a 2 ;character sequence of ASCII characters representing ;the hex pair in al. For example, if al equals 3FH ;then an ASCII '3' and an ASCII 'F' are output to the ;display. ;Input: al ;Destroyed: al htoa proc near push ax shr al,1 shr al,1 shr al,1 shr al,1 call a_bias pop ax call a_bias ret htoa endp ;----- ;A_BIAS ;This routine converts the lower nybble of ;al into a printable ASCII equivalent ;character '0-9' or 'A-F'. ;Input: al ;Destroyed: al a_bias proc near and al,0fh add al,30h cmp al,3ah jc no_7 add al,7 no_7: call c_out ret a_bias endp ;----- ;H_OUT ;This routine prints the 4 character ASCII ;equivalent of the 16-bit value in dx. ;Input: dx ;Destroyed: al h_out proc near mov al,dh call htoa mov al,dl call htoa ret h_out endp ;----- ;C_OUT ;This routine interrogates the 8251 transmitter ;ready flag and sends the character in al to the ;display. ;Input: al c_out proc near push ax mov ah,al co_s: in al,s_ctrl and al,trdy jz co_s mov al,ah out s_data,al pop ax ret c_out endp ;----- ;CH_CASE ;This routine converts lower case 'a-z' ;characters in al to upper case characters. ;Input: al ;Destroyed: al ;Output: al ch_case proc near cmp al,'A' jc un_alph and al,0dfh un_alph:ret ch_case endp ;----- ;ERROR ;This routine prints out the standard ;monitor error message, a '?' followed ;by a terminal beep. ;Destroyed: al error proc near mov al,'?' call c_out mov al,7 call c_out ret error endp ;----- ;C_IN ;This routine interrogates the 8251 ;receiver ready flag and when active ;loads register al with the received ;character. The most-significant bit ;is cleared. ;Destroyed: al ;Output: al c_in proc near ci_s: in al,s_ctrl and al,rrdy jz ci_s in al,s_data and al,7fh ret c_in endp ;----- ;CHK_SUM ;This routine checks the C_SUM location ;and returns an error message if it is not 0. ;Destroyed: si chk_sum proc near cmp es:[c_sum+rtop],0 jz gd_ld lea si,cse call s_end jmp get_com gd_ld: ret chk_sum endp ;----- ;GET_BYT ;This routine is used to read two successive ;bytes from the serial port and convert them ;back into their hex-pair equivalent. ;Destroyed: al,bl ;Output: al get_byt proc near call c_in call c_out call con_v shl al,1 shl al,1 shl al,1 shl al,1 mov bl,al call c_in call c_out call con_v or al,bl add es:[c_sum+rtop],al ret get_byt endp ;----- ;GET_WRD ;This routine calls GET_BYT twice to read ;a word from the serial port. ;Destroyed: ax, bh get_wrd proc near call get_byt mov bh,al call get_byt mov ah,bh ret get_wrd endp ;----- ;CON_V ;This routine converts an ASCII character ;into its equivalent hex nybble. ;Input: al ;Destroyed: al ;Output: al con_v proc near sub al,'0' cmp al,10 jc no_sub7 sub al,7 no_sub7:ret con_v endp ;----- ;GET_NUM ;This routine accepts a multi-digit hex ;number from the user and converts them into ;a 16-bit equivalent result in dx. If more ;than 4 characters are entered, only the last ;4 are used as the value. A CR or a SP will ;properly terminate the input request. If no ;data is entered at all, bh will contain '0' ;and otherwise will contain '1'. ;Destroyed: al, bh, dx ;Output: bh, dx get_num proc near top_n: mov bh,'0' mov dx,0 gt_nm: call c_in cmp al,13 jz gt_bye call c_out cmp al,20h jz gt_bye mov bh,'1' call ch_case cmp al,'0' jc bad_nm cmp al,'9'+1 jc ok_sub cmp al,'A' jc bad_nm cmp al,'F'+1 jnc bad_nm sub al,7 ok_sub: sub al,30h shl dx,1 shl dx,1 shl dx,1 shl dx,1 add dl,al jmp gt_nm gt_bye: clc ret bad_nm: call error jmp top_n get_num endp ;----- ;S_END ;This routine sends ASCII characters stored in ;memory locations pointed to by si to the ;display. The message must end with a '$'. ;Input: si ;Destroyed: al, si s_end proc near s_nxt: mov al,[si] cmp al,'$' jz s_qwt call c_out inc si jmp s_nxt s_qwt: ret s_end endp ;----- ;ENVIR ;This routine takes care of saving the system ;environment (all registers and flags) when ;the monitor is re-entered from an external ;source. ENVIR also re-establishes the monitor ;segment registers, which may have been altered ;by the external software. All registers are ;stored in memory as 2-byte words (lo-byte first) ;beginning at location r_data[rtop+0] (address ;1F80 in system ram) in this order: ax, bx, cx ;dx, bp, si, di, sp, ds, ss, es. The flags are ;stored in memory locations 1FA1-1FA2. ; ;This routine falls into D_ENV. ;Input: everything ;Destroyed: ax, bx, ds, es envir proc near pushf push ax mov ax,ds push ax mov ax,data add ax,0e00h mov ds,ax mov ax,es push ax mov ax,0 mov es,ax pop ax mov es:r_data[rtop+20],ax pop ax mov es:r_data[rtop+16],ax pop ax mov es:r_data[rtop+0],ax mov es:r_data[rtop+2],bx mov es:r_data[rtop+4],cx mov es:r_data[rtop+6],dx mov es:r_data[rtop+8],bp mov es:r_data[rtop+10],si mov es:r_data[rtop+12],di pop ax pop bx mov es:r_data[rtop+14],sp push bx push ax mov es:r_data[rtop+18],ss pop ax mov es:[f_lags+rtop],ax ;----- ;D_ENV ;This routine displays the contents of all ;cpu registers. ; ;This routine falls into the next one. ;Destroyed: ax, cx, dx, si d_env: mov si,0 mov cx,11 call crlf t_dr: mov al,r_lets[si] call c_out mov al,r_lets[si+1] call c_out mov al,':' call c_out mov dx,es:r_data[rtop+si] call h_out call blank call blank add si,2 mov ax,si and al,7 jnz adjst call crlf adjst: loop t_dr ;----- ;D_FLG ;This routine displays the 5 most important ;system flags, zero, sign, parity, carry ;and aux-carry. ;Destroyed: al, cx, si d_flg: lea si,fl_msg call s_end mov si,0 mov cx,5 n_flg: mov al,f_sym[si] call c_out mov al,'=' call c_out mov ax,es:[f_lags+rtop] and al,f_mask[si] mov al,'0' jz not_1 inc al not_1: call c_out call blank call blank inc si loop n_flg ret envir endp ;----- ;DPR ;This routine displays the processor ;registers with having had to save them ;first (like ENVIR does...). dpr proc near jmp d_env dpr endp code ends ;----- ;This data segment contains all the rom-based data ;needed for proper monitor execution. All monitor ;messages are saved here, along with various other ;interesting tidbits that I won't fully explain in ;order to preserve the 'mystery' of education!!!!! data segment para 'data' hello db 13,10,'8088 Monitor, Ver:3.0$' wr_by db 13,10,'C1997 James L. Antonakos$' s_msg db 13,10,'Placing 8088 in HALT state...',13,10,'$' renter db 13,10,'Re-entry by external program at [$' tst_msg db 13,10,'1) Send sinewave to D/A converter, or' db 13,10,'2) Echo A/D to D/A' db 13,10,'Choice ?$' br_clr db 13,10,'Breakpoint cleared.$' bp_as db 13,10,'Breakpoint already saved...$' bp_sa db 13,10,'Breakpoint saved.$' br_bak db 13,10,'Breakpoint encountered at [$' br_alc db 13,10,'Breakpoint already cleared.$' urt db '<-Unidentified record type->$' cse db '<-Checksum error->$' r_lets db 'AXBXCXDXBPSIDISPDSSSES' fl_msg db 13,10,'Flags: $' f_sym db 'SZAPC' f_mask db 80h,40h,10h,4,1 coms db 'A B C D E G H I L M O R S T X ' num_com dw 15 j_umps dw a_uth dw b_rkp dw c_brp dw d_ump dw i_nit dw e_xec dw h_elp dw p_in dw l_oad dw m_ove dw p_out dw d_reg dw s_top dw t_est dw e_xam sine db 82h,85h,88h,8bh,8eh,91h,94h,97h db 9bh,9eh,0a1h,0a4h,0a7h,0aah,0adh,0afh db 0b2h,0b5h,0b8h,0bbh,0beh,0c0h,0c3h,0c6h db 0c8h,0cbh,0cdh,0d0h,0d2h,0d4h,0d7h,0d9h db 0dbh,0ddh,0dfh,0e1h,0e3h,0e5h,0e7h,0e9h db 0ebh,0ech,0eeh,0efh,0f1h,0f2h,0f4h,0f5h db 0f6h,0f7h,0f8h,0f9h,0fah,0fbh,0fbh,0fch db 0fdh,0fdh,0feh,0feh,0feh,0feh,0feh,0ffh db 0feh,0feh,0feh,0feh,0feh,0fdh,0fdh,0fch db 0fbh,0fbh,0fah,0f9h,0f8h,0f7h,0f6h,0f5h db 0f4h,0f2h,0f1h,0efh,0eeh,0ech,0ebh,0e9h db 0e7h,0e5h,0e3h,0e1h,0dfh,0ddh,0dbh,0d9h db 0d7h,0d4h,0d2h,0d0h,0cdh,0cbh,0c8h,0c6h db 0c3h,0c0h,0beh,0bbh,0b8h,0b5h,0b2h,0afh db 0adh,0aah,0a7h,0a4h,0a1h,9eh,9bh,97h db 94h,91h,8eh,8bh,88h,85h,82h,7eh db 7bh,78h,75h,72h,6fh,6ch,69h,66h db 62h,5fh,5ch,59h,56h,53h,50h,4eh db 4bh,48h,45h,42h,3fh,3dh,3ah,37h db 35h,32h,30h,2dh,2bh,29h,26h,24h db 22h,20h,1eh,1ch,1ah,18h,16h,14h db 12h,11h,0fh,0eh,0ch,0bh,9,8 db 7,6,5,4,3,2,2,1,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,1,2,2,3,4,5,6,7,8 db 9,0bh,0ch,0eh,0fh,11h,12h,14h db 16h,18h,1ah,1ch,1eh,20h,22h,24h db 26h,29h,2bh,2dh,30h,32h,35h,37h db 3ah,3dh,3fh,42h,45h,48h,4bh,4eh db 50h,53h,56h,59h,5ch,5fh,62h,66h db 69h,6ch,6fh,72h,75h,78h,7bh,7fh d_ac equ 0 a_dc equ 1 ad_stat equ 2 ad_ctrl equ 3 ad_rd equ 20h ad_wr equ 10h ad_nom equ 30h c8255 equ 83h ;Aout, Bin, CLin, CHout s_data equ 40h s_stat equ 41h s_ctrl equ 41h m8251 equ 0ceh ;2 stop, no parity, 8 data, *16 clock c8251 equ 05h ;R and T enable only trdy equ 01h rrdy equ 02h h_msg db 13,10,'8088 Monitor Command Summary' db 13,10 db 13,10,'Command Result' db 13,10 db 13,10,'A Author identification' db 13,10,'B #1 set Breakpoint to #1' db 13,10,'C clear Breakpoint' db 13,10,'D #1 #2 Dump memory from #1 to #2' db 13,10,'E Enter register data' db 13,10,'G #1 Execute program at #1' db 13,10,'H Display this message' db 13,10,'I #1 Input data from port #1' db 13,10,'L Load program into memory' db 13,10,'M #1 #2 #3 Move data to #3 from range #1 to #2' db 13,10,'O #1 #2 Output data #2 to port #1' db 13,10,'R Display registers' db 13,10,'S Stop (HALT) processor' db 13,10,'T Test Analog i/o' db 13,10,'X #1 eXamine memory starting at #1' db 13,10,' to exit, no change' db 13,10 db 13,10,'where #1, #2 and #3 are hex addresses' db 13,10,'$' data ends ;----- ;This data segment is used to generate the required ;ram-based addresses for temporary storage. data2 segment para 'data' r_data dw 11 dup(?) go_adr dw ? br_stat db ? b_mma dw ? ;breakpoint main-memory address op_kode db ? ;opcode byte br_cs dw ? ;breakpoint code-segment br_ip dw ? ;breakpoint instruction-pointer f_lags dw ? ;system flags c_sum db ? ;checksum storage data2 ends end