; Seattle Computer Products 8086 Monitor version 1.6 X-XX-8X. ; by Tim Paterson ; This software is not copyrighted. ; To select a disk boot, set one of the following equates ; to 1, the rest to 0. SCP: EQU 0 ;1 for SCP, 0 for others. CROMEMCO4FDC: EQU 0 ;Cromemco 4FDC? CROMEMCO16FDC: EQU 0 ;Cromemco 16FDC? NORTHSTARSD: EQU 0 ;North Star single density? TARBELLSD: EQU 0 ;Tarbell SD controller or DD controller SD only TARBELLDD: EQU 1 ;Tarbell DD controller SD or DD? OTHER: EQU 0 ;User-defined disk PUTBASE: EQU 100H LOAD: EQU 200H ORG 7F0H PUT PUTBASE+7F0H JMP 0,0FF80H ;Power-on jump to monitor ORG 100H ;RAM area base address ;System Equates BASE: EQU 0F0H ;CPU Support base port address STAT: EQU BASE+7 ;UART status port DATA: EQU BASE+6 ;UART data port DAV: EQU 2 ;UART data available bit TBMT: EQU 1 ;UART transmitter ready bit BUFLEN: EQU 80 ;Maximum length of line input buffer BPMAX: EQU 10 ;Maximum number of breakpoints BPLEN: EQU BPMAX+BPMAX ;Length of breakpoint table REGTABLEN: EQU 14 ;Number of registers SEGDIF: EQU 800H ;-0FF800H (ROM address) PROMPT: EQU ">" CAN: EQU "@" ;RAM area. BRKCNT: DS 2 ;Number of breakpoints TCOUNT: DS 2 ;Number of steps to trace BPTAB: DS BPLEN ;Breakpoint table LINEBUF: DS BUFLEN+1 ;Line input buffer ALIGN DS 50 ;Working stack area STACK: ;Register save area AXSAVE: DS 2 BXSAVE: DS 2 CXSAVE: DS 2 DXSAVE: DS 2 SPSAVE: DS 2 BPSAVE: DS 2 SISAVE: DS 2 DISAVE: DS 2 DSSAVE: DS 2 ESSAVE: DS 2 RSTACK: ;Stack set here so registers can be saved by pushing SSSAVE: DS 2 CSSAVE: DS 2 IPSAVE: DS 2 FSAVE: DS 2 ;Start of Monitor code ORG 0 PUT PUTBASE ;One-time initialization 926B:0000 start: 926B:0000 FC cld ; UP 926B:0001 33 C0 xor ax,ax ; Zero register 926B:0003 8E D0 mov ss,ax 926B:0005 8E D8 mov ds,ax 926B:0007 8E C0 mov es,ax 926B:0009 BC 019C mov sp,19Ch 926B:000C úBF 019C mov di,AXSAVE ; (0000:019C=0) 926B:000F B9 000D mov cx,0Dh 926B:0012 F3/ AB rep stosw ; Rep when cx >0 Store ax to es:[di] 926B:0014 B4 02 mov ah,2 926B:0016 AB stosw ; Store ax to es:[di] 926B:0017 C6 06 01A5 10 mov byte ptr ds:data_13e+1,10h ; (0000:01A5=1Bh) ; Prepare 9513 926B:001C B0 17 mov al,17h 926B:001E E6 F5 out BASE+5,al ; port 0F5h ??I/O Non-standard 926B:0020 B0 F3 mov al,0F3h 926B:0022 E6 F4 out BASE+4,al ; port 0F4h ??I/O Non-standard 926B:0024 B8 0584 mov ax,584h 926B:0027 E7 F4 out BASE+4,ax ; port 0F4h ??I/O Non-standard ;Master Mode now set to 84F3H: ; Scaler set to BCD division ; Enable data pointer increment ; 8-bit data bus ; FOUT=100Hz, dividing F5 by 4 (F5=4MHz/10000) ; Both alarm comparators disabled ; Time-of-day enabled ;Counter 5 selected ;Initialize loop. Ports BASE through BASE+7 are initialized ;from table. Each table entry has number of bytes followed by ;data. 926B:0029 úBE 074C mov si,offset INITTABLE ; (926B:074C=1) 926B:002C BA 00F0 mov dx,BASE 926B:002F INITPORT: ; xref 926B:003E 926B:002F 2E: AC lods byte ptr cs:[si] ; String [si] to al 926B:0031 8A C8 mov cl,al 926B:0033 E3 05 jcxz NEXTPORT ; Jump if cx=0 926B:0035 INITBYTE: ; xref 926B:0038 926B:0035 2E: AC lods byte ptr cs:[si] ; String [si] to al 926B:0037 EE out dx,al ; port 0F0h ??I/O Non-standard 926B:0038 E2 FB loop INITBYTE ; Loop if cx > 0 926B:003A NEXTPORT: ; xref 926B:0033 926B:003A 42 inc dx 926B:003B 80 FA F8 cmp dl,BASE+8 926B:003E 75 EF jne INITPORT ; Jump if not equal ; not 100% sure what this does yet 926B:0040 E4 FF in al,BASE+0Fh ; port 0FFh ??I/O Non-standard 926B:0042 24 18 and al,18h 926B:0044 74 18 jz loc_4 ; Jump if zero 926B:0046 3C 08 cmp al,8 926B:0048 74 41 je loc_7 ; Jump if equal 926B:004A E8 001F call sub_1 ; (006C) 926B:004D E4 FF in al,BASE+0Fh ; port 0FFh ??I/O Non-standard 926B:004F A8 08 test al,8 926B:0051 74 38 jz loc_7 ; Jump if zero 926B:0053 B8 01A0 mov ax,1A0h 926B:0056 E6 F4 out BASE+4,al ; port 0F4h ??I/O Non-standard 926B:0058 8A C4 mov al,ah 926B:005A E6 F4 out BASE+4,al ; port 0F4h ??I/O Non-standard 926B:005C EB 2D jmp short loc_7 ; (008B) ;Initialization complete except for determining baud rate. ;Both 8259As are ready to accept interrupts, the 9513 is ;providing 19.2k baud X 16 to the 8251A which is set for ;16X clock and one stop bit. 926B:005E loc_4: ; xref 926B:0044 926B:005E E8 0020 call CHECKB ; (0081) 926B:0061 E8 0008 call INITBAUD ; (006C) 926B:0064 loc_5: ; xref 926B:006A 926B:0064 úE8 001A call CHECKB ; (0081) 926B:0067 E8 000E call INITB ; (0078) 926B:006A EB F8 jmp short loc_5 ; (0064) ;CHECKB does not return if baud rate is correct ;Intial baud rate (19.2k) was wrong, so run auto-baud routine 926B:006C INITBAUD: 926B:006C úBE 07F5 mov si,offset BAUD ; (926B:07F5=0Dh) ;First set up 9513 for slower baud rates (<=9600). ;Counter 5 mode register has already been selected. 926B:006F B8 E823 mov ax,0E823h ;Output 23H to BASE+4 926B:0072 E7 F4 out BASE+4,ax ; port 0F4h ??I/O Non-standard ;23H to BASE+4 sets lower half of Counter 5 mode register. ;Reload from Load, count down repetively in binary, ;toggle output. ;0E8H to BASE+5 disables data pointer sequencing 926B:0074 B0 0D mov al,0Dh 926B:0076 E6 F5 out BASE+5,al ; port 0F5h ??I/O Non-standard 926B:0078 INITB: 926B:0078 2E: AD lods word ptr cs:[si] ; String [si] to ax 926B:007A E6 F4 out BASE+4,al ; port 0F4h ??I/O Non-standard 926B:007C 8A C4 mov al,ah 926B:007E E6 F4 out BASE+4,al ; port 0F4h ??I/O Non-standard 926B:0080 loc_ret_6: ; xref 926B:0089 926B:0080 C3 retn 926B:0081 CHECKB: 926B:0081 E8 0097 call IN ; (011B) 926B:0084 E8 0094 call IN ; (011B) 926B:0087 3C 0D cmp al,0Dh 926B:0089 75 F5 jne loc_ret_6 ; Jump if not equal ; Initialization complete, including baud rate. 926B:008B MONITOR: ; xref 926B:0048, 0051, 005C ; Do auto boot if sense switch 0 is on. 926B:008B BF 0118 mov di,LINEBUF ;118h 926B:008E C6 05 0D mov byte ptr [di],0Dh 926B:0091 E4 FF in al,BASE+0Fh ; port 0FFh ??I/O Non-standard 926B:0093 A8 01 test al,1 926B:0095 74 03 jz DOMON ; Jump if zero 926B:0097 E9 06F5 jmp BOOT ; (078F) 926B:009A DOMON: ; xref 926B:0095 926B:009A BE 076A mov si,HEADER ;76Ah 926B:009D E8 008B call PRINTMES ; (012B) 926B:00A0 COMMAND: ; xref 926B:00BF, 00D5, 0119, 0391 926B:00A0 úFC cld ; Clear direction 926B:00A1 33 C0 xor ax,ax ; Zero register 926B:00A3 8E D8 mov ds,ax 926B:00A5 8E C0 mov es,ax 926B:00A7 BC 019C mov sp,STACK 926B:00AA C7 06 0064 06D4 mov word ptr ds:[64H],INT ; (0000:0064=1755h) 926B:00B0 8C 0E 0066 mov ds:[66H],cs ; (0000:0066=4D9h) 926B:00B4 B0 3E mov al,PROMPT ; '>' 926B:00B6 E8 00C8 call OUT ; (0181) 926B:00B9 E8 001E call INBUF ; (00DA) ;From now and throughout command line processing, DI points ;to next character in command line to be processed. 926B:00BC E8 007F call SCANB ; (013E) 926B:00BF 74 DF jz COMMAND ; Jump if zero 926B:00C1 8A 05 mov al,[di] ;Prepare commend letter for table lookup 926B:00C3 2C 42 sub al,'B' ; 'B' 926B:00C5 72 10 jc ERR1 ; Jump if carry Set 926B:00C7 3C 13 cmp al,'T'+1-'B' ;13h 926B:00C9 73 0C jae ERR1 ; Jump if above or = 926B:00CB 47 inc di 926B:00CC D0 E0 shl al,1 ; Shift w/zeros fill 926B:00CE 98 cbw ; Convrt byte to word 926B:00CF 93 xchg bx,ax 926B:00D0 2E: FF 97 0196 call word ptr cs:COMTAB[bx] ;*(926B:0196=78Fh) 19 entries 926B:00D5 EB C9 jmp short COMMAND ; (00A0) 926B:00D7 ERR1: ; xref 926B:00C5, 00C9 926B:00D7 E9 02A8 jmp ERROR ; (0382) ;Get input line 926B:00DA INBUF: 926B:00DA BF 0118 mov di,LINEBUF 926B:00DD 33 C9 xor cx,cx ; Zero register 926B:00DF GETCH: ; xref 926B:00F6, 00F8, 00FF, 0107 926B:00DF úE8 0039 call IN ; (011B) 926B:00E2 3C 20 cmp al,20h ; ' ' 926B:00E4 72 1B jb CONTROL ; Jump if below 926B:00E6 3C 7F cmp al,7Fh 926B:00E8 74 0E je BACKSP ; Jump if equal 926B:00EA E8 0094 call OUT ; (0181) 926B:00ED 3C 40 cmp al,CAN ; '@' 926B:00EF 74 25 je KILL ; Jump if equal 926B:00F1 AA stosb ; Store al to es:[di] 926B:00F2 41 inc cx 926B:00F3 83 F9 50 cmp cx,BUFLEN 926B:00F6 76 E7 jbe GETCH ; Jump if below or = 926B:00F8 BACKSP: ; xref 926B:00E8, 0103 926B:00F8 E3 E5 jcxz GETCH ; Jump if cx=0 926B:00FA 4F dec di 926B:00FB 49 dec cx 926B:00FC E8 0029 call sub_7 ; (0128) 926B:00FF EB DE jmp short GETCH ; (00DF) 926B:0101 CONTROL: ; xref 926B:00E4 926B:0101 3C 08 cmp al,8 926B:0103 74 F3 je BACKSP ; Jump if equal 926B:0105 3C 0D cmp al,0Dh 926B:0107 75 D6 jne GETCH ; Jump if not equal 926B:0109 AA stosb ; Store al to es:[di] 926B:010A BF 0118 mov di,LINEBUF ;Output CR/LF sequence 926B:010D CRLF: ; xref 926B:0280, 042A, 04CA, 066F 926B:010D úB0 0D mov al,0Dh 926B:010F E8 006F call OUT ; (0181) 926B:0112 B0 0A mov al,0Ah 926B:0114 EB 6B jmp short OUT ; (0181) ;Cancel input line 926B:0116 KILL: ; xref 926B:00EF 926B:0116 E8 FFF4 call CRLF ; (010D) 926B:0119 EB 85 jmp short COMMAND ; (00A0) ;Character input routine 926B:011B IN: 926B:011B FA cli ; Disable interrupts 926B:011C E4 F7 in al,STAT ; port 0F7h ??I/O Non-standard 926B:011E A8 02 test al,DAV 926B:0120 74 F9 jz IN ; Jump if zero 926B:0122 E4 F6 in al,DATA ; port 0F6h ??I/O Non-standard 926B:0124 24 7F and al,7Fh 926B:0126 FB sti ; Enable interrupts 926B:0127 C3 retn ;Physical backspace - blank, backspace, blank 926B:0128 BACKUP: 926B:0128 úBE 078C mov si,offset BACMES ; (926B:078C=8) ;Print ASCII message. Last char has bit 7 set 926B:012B PRINTMES: 926B:012B 2E: AC lods byte ptr cs:[si] ; String [si] to al 926B:012D E8 0051 call OUT ; (0181) 926B:0130 D0 E0 shl al,1 ; Shift w/zeros fill 926B:0132 73 F7 jnc PRINTMES ; Jump if carry=0 926B:0134 C3 retn ;Scan for parameters of a command 926B:0135 SCANP: 926B:0135 E8 0006 call SCANB ; (013E) 926B:0138 82 3D 2C cmp byte ptr [di],2Ch ; ',' 926B:013B 75 0A jne EOLCHK ; Jump if not equal 926B:013D 47 inc di ;Scan command line for next non-blank character 26B:013E SCANB: 926B:013E B0 20 mov al,20h ; ' ' 926B:0140 51 push cx 926B:0141 B1 FF mov cl,0FFh 926B:0143 F3/ AE repe scasb ; Rep zf=1+cx >0 Scan es:[di] for al 926B:0145 4F dec di 926B:0146 59 pop cx 926B:0147 EOLCHK: ; xref 926B:013B 926B:0147 82 3D 0D cmp byte ptr [di],0Dh 926B:014A C3 retn ;Print 5-digit hex address of SI and DS 926B:014B OUTSI: 926B:014B 8C DA mov dx,ds 926B:014D B4 00 mov ah,0 926B:014F E8 0078 call SHIFT4 ; (01CA) 926B:0152 03 D6 add dx,si 926B:0154 EB 09 jmp short OUTADD ; (015F) ;Print 5-digit hex address of DI and ES ;Same as OUTSI above \26B:0156 OUTDI: 926B:0156 8C C2 mov dx,es 926B:0158 B4 00 mov ah,0 926B:015A E8 006D call SHIFT4 ; (01CA) 926B:015D 03 D7 add dx,di ;Finish OUTSI here too 926B:015F OUTADD: ; xref 926B:0154 926B:015F 82 D4 00 adc ah,0 926B:0162 E8 0012 call HIDIG ; (0177) ;Print out 16-bit value in DX in hex 26B:0165 OUT16: 926B:0165 8A C6 mov al,dh 926B:0167 E8 0002 call HEX ; (016C) 926B:016A 8A C2 mov al,dl ;Output byte in AL as two hex digits 926B:016C HEX: 926B:016C 8A E0 mov ah,al ;Shift high digit into low 4 bits 926B:016E 51 push cx 926B:016F B1 04 mov cl,4 926B:0171 D2 E8 shr al,cl ; Shift w/zeros fill 926B:0173 59 pop cx 926B:0174 E8 0002 call DIGIT ; (0179) 926B:0177 HIDIG: 926B:0177 8A C4 mov al,ah 926B:0179 DIGIT: 926B:0179 24 0F and al,0Fh ;Trick 6-byte hex conversion works on 8086 too. 926B:017B 04 90 add al,90h 926B:017D 27 daa ; Decimal adjust 926B:017E 14 40 adc al,40h ; '@' 926B:0180 27 daa ; Decimal adjust ;Console output of character in AL 926B:0181 OUT: ; xref 926B:0114, 018E 926B:0181 ú50 push ax 926B:0182 OUT1: ; xref 926B:0186 926B:0182 E4 F7 in al,STAT ; port 0F7h ??I/O Non-standard 926B:0184 24 01 and al,TBMT 926B:0186 74 FA jz OUT1 ; Jump if zero 926B:0188 58 pop ax 926B:0189 E6 F6 out DATA,al ; port 0F6h ??I/O Non-standard 926B:018B C3 retn ;Output one space 926B:018C BLANK: 926B:018C B0 20 mov al,20h ; ' ' 926B:018E EB F1 jmp short OUT ; (0181) ;Output the number of blanks in CX 926B:0190 TAB: 926B:0190 E8 FFF9 call BLANK ; (018C) 926B:0193 E2 FB loop TAB ; Loop if cx > 0 926B:0195 C3 retn ;Command Table. Command letter indexes into table to get ;address of command. PERR prints error for no such command. 926B:0196 078F COMTAB: dw offset BOOT ; B (078F) 926B:0198 0381 data_27 dw offset PERR ; C (0381) 926B:019A 0226 data_28 dw offset DUMP ; D (0226) 926B:019C 03A1 data_29 dw offset ENTER ; E (03A1) 926B:019E 02B0 data_30 dw offset FILL ; F (02B0) 926B:01A0 0683 data_31 dw offset GO ; G (0683) 926B:01A2 0381 data_32 dw offset PERR ; H (0381) 926B:01A4 0665 data_33 dw offset INPUT ; I (0665) 926B:01A6 0381 data_34 dw offset PERR ; J (0381) 926B:01A8 0381 data_35 dw offset PERR ; K (0381) 926B:01AA 0381 data_36 dw offset PERR ; L (0381) 926B:01AC 0283 data_37 dw offset MOVE ; M (0283) 926B:01AE 0381 data_38 dw offset PERR ; N (0381) 926B:01B0 0672 data_39 dw offset OUTPUT ; O (0672) 926B:01B2 0381 data_40 dw offset PERR ; P (0381) 926B:01B4 0381 data_41 dw offset PERR ; Q (0381) 926B:01B6 0448 data_42 dw offset REG ; R (0448) 926B:01B8 02D3 data_44 dw offset SEARCH ; S (02D3) 926B:01BA 0583 data_45 dw offset TRACE ; T (0583) ;Given 20-bit address in AH:DX, breaks it down to a segment ;number in AX and a displacement in DX. Displacement is ;always zero except for least significant 4 bits. 926B:01BC GETSEG: 926B:01BC 8A C2 mov al,dl 926B:01BE 24 0F and al,0Fh 926B:01C0 E8 0007 call SHIFT4 ; (01CA) 926B:01C3 8A D0 mov dl,al 926B:01C5 8A C6 mov al,dh 926B:01C7 32 F6 xor dh,dh ; Zero register 926B:01C9 C3 retn ;Shift AH:DX left 4 bits 926B:01CA SHIFT4: 926B:01CA D1 E2 shl dx,1 ; Shift w/zeros fill 926B:01CC D0 D4 rcl ah,1 ; Rotate thru carry 926B:01CE D1 E2 shl dx,1 ; Shift w/zeros fill 926B:01D0 D0 D4 rcl ah,1 ; Rotate thru carry 926B:01D2 D1 E2 shl dx,1 ; Shift w/zeros fill 926B:01D4 D0 D4 rcl ah,1 ; Rotate thru carry 926B:01D6 D1 E2 shl dx,1 ; Shift w/zeros fill 926B:01D8 D0 D4 rcl ah,1 ; Rotate thru carry 926B:01DA C3 RET2: retn ;RANGE - Looks for parameters defining an address range. ;The first parameter is a hex number of 5 or less digits ;which specifies the starting address. The second parameter ;may specify the ending address, or it may be preceded by ;"L" and specify a length (4 digits max), or it may be ;omitted and a length of 128 bytes is assumed. Returns with ;segment no. in AX and displacement (0-F) in DX. 926B:01DB RANGE: 926B:01DB B9 0005 mov cx,5 926B:01DE E8 0122 call GETHEX ; (0303) 926B:01E1 50 push ax 926B:01E2 52 push dx 926B:01E3 E8 FF4F call SCANP ; (0135) 926B:01E6 82 3D 4C cmp byte ptr [di],'L' 926B:01E9 74 1C je GETLEN ; Jump if equal 926B:01EB BA 0080 mov dx,80h 926B:01EE E8 0130 call HEXIN ; (0321) 926B:01F1 72 1B jc RNGRET ; Jump if carry Set 926B:01F3 B9 0005 mov cx,5 926B:01F6 E8 010A call GETHEX ; (0303) 926B:01F9 8B CA mov cx,dx 926B:01FB 5A pop dx 926B:01FC 5B pop bx 926B:01FD 2B CA sub cx,dx 926B:01FF 1A E7 sbb ah,bh 926B:0201 75 1D jnz loc_28 ; Jump if not zero 926B:0203 93 xchg bx,ax 926B:0204 41 inc cx 926B:0205 EB 0B jmp short RNGCHK ; (0212) 926B:0207 GETLEN: ; xref 926B:01E9 926B:0207 47 inc di 926B:0208 B9 0004 mov cx,4 926B:020B E8 00F5 call GETHEX ; (0303) 926B:020E RNGRET: ; xref 926B:01F1 926B:020E 8B CA mov cx,dx 926B:0210 5A pop dx 926B:0211 58 pop ax ;RNGCHK verifies that the range lies entirely within one segment. ;CX=0 means count=10000H. Range is within one segment only if ;adding the low 4 bits of the starting address to the count is ;<=10000H, because segments can start only on 16-byte boundaries. 926B:0212 RNGCHK: ; xref 926B:0205 926B:0212 8B DA mov bx,dx 926B:0214 81 E3 000F and bx,0Fh 926B:0218 E3 04 jcxz MAXRNG ; Jump if cx=0 926B:021A 03 D9 add bx,cx 926B:021C 73 9E jnc GETSEG ; Jump if carry=0 926B:021E MAXRNG: ; xref 926B:0218 ;If here because of JCXZ MAXRNG, we are testing if low 4 bits ;(in BX) are zero. If we dropped straight in, we are testing ;for BX+CX=10000H (=0). Either way, zero flag set means ;withing range. 926B:021E 74 9C jz GETSEG ; Jump if zero 926B:0220 loc_28: ; xref 926B:0201 926B:0220 B8 4752 mov ax,4700+'R' 926B:0223 E9 031F jmp ERR ; (0545) ;Dump area of memory in both hex and ASCII 926B:0226 DUMP: 926B:0226 E8 FFB2 call RANGE ; (01DB) 926B:0229 50 push ax 926B:022A E8 014E call GETEOL ; (037B) 926B:022D 1F pop ds 926B:022E 8B F2 mov si,dx 926B:0230 ROW: ; xref 926B:0254 926B:0230 úE8 FF18 call OUTSI ; (014B) 926B:0233 56 push si 926B:0234 BYTE: ; xref 926B:0248 926B:0234 E8 FF55 call BLANK ; (018C) 926B:0237 BYTE1: ; xref 926B:024F 926B:0237 úAC lodsb ; String [si] to al 926B:0238 E8 FF31 call HEX ; (016C) 926B:023B 5A pop dx 926B:023C 49 dec cx 926B:023D 74 17 jz ASCII ; Jump if zero 926B:023F 8B C6 mov ax,si 926B:0241 A8 0F test al,0Fh 926B:0243 74 0C jz ENDROW ; Jump if zero 926B:0245 52 push dx 926B:0246 A8 07 test al,7 926B:0248 75 EA jnz loc_30 ; Jump if not zero 926B:024A B0 2D mov al,'-' 926B:024C E8 FF32 call OUT ; (0181) 926B:024F EB E6 jmp short BYTE1 ; (0237) 926B:0251 ENDROW: ; xref 926B:0243 926B:0251 E8 0002 call ASCII ; (0256) 926B:0254 EB DA jmp short ROW ; (0230) 926B:0256 ASCII: 926B:0256 51 push cx 926B:0257 8B C6 mov ax,si 926B:0259 8B F2 mov si,dx 926B:025B 2B C2 sub ax,dx ;Compute tab length. ASCII dump always appears on right side ;screen regardless of how many bytes were dumped. Figure 3 ;characters for each byte dumped and subtract from 51, which ;allows a minimum of 3 blanks after the last byte dumped. 926B:025D 8B D8 mov bx,ax 926B:025F D1 E0 shl ax,1 ; Shift w/zeros fill 926B:0261 03 C3 add ax,bx 926B:0263 B9 0033 mov cx,33h 926B:0266 2B C8 sub cx,ax 926B:0268 E8 FF25 call TAB ; (0190) 926B:026B 8B CB mov cx,bx 926B:026D ASCDMP: ; xref 926B:027D 926B:026D AC lodsb ; String [si] to al 926B:026E 24 7F and al,7Fh 926B:0270 3C 7F cmp al,7Fh 926B:0272 74 04 je NOPRT ; Jump if equal 926B:0274 3C 20 cmp al,' ' 926B:0276 73 02 jae PRIN ; Jump if above or = 926B:0278 NOPRT: ; xref 926B:0272 926B:0278 B0 2E mov al,'.' 926B:027A PRIN: ; xref 926B:0276 926B:027A E8 FF04 call OUT ; (0181) 926B:027D E2 EE loop ASCDMP ; Loop if cx > 0 926B:027F 59 pop cx 926B:0280 E9 FE8A jmp CRLF ; (010D) ;Block move one area of memory to another. Overlapping moves ;are performed correctly, i.e., so that a source byte is not ;overwritten until after it has been moved. 926B:0283 MOVE: 926B:0283 E8 FF55 call RANGE ; (01DB) 926B:0286 51 push cx 926B:0287 50 push ax 926B:0288 8B F2 mov si,dx 926B:028A B9 0005 mov cx,5 926B:028D E8 0073 call GETHEX ; (0303) 926B:0290 E8 00E8 call GETEOL ; (037B) 926B:0293 E8 FF26 call GETSEG ; (01BC) 926B:0296 8B FA mov di,dx 926B:0298 5B pop bx 926B:0299 8E DB mov ds,bx 926B:029B 8E C0 mov es,ax 926B:029D 59 pop cx 926B:029E 3B FE cmp di,si 926B:02A0 1B C3 sbb ax,bx 926B:02A2 72 07 jc COPYLIST ; Jump if carry Set ;Otherwise, move backward. Figure end of source and destination ;areas and flip direction flag. 926B:02A4 49 dec cx 926B:02A5 03 F1 add si,cx 926B:02A7 03 F9 add di,cx 926B:02A9 FD std ; Set direction flag 926B:02AA 41 inc cx 926B:02AB COPYLIST: ; xref 926B:02A2, 02C3, 02D1 926B:02AB úA4 movsb ; Mov [si] to es:[di] 926B:02AC 49 dec cx 926B:02AD F3/ A4 rep movsb ; Rep when cx >0 Mov [si] to es:[di] 926B:02AF C3 retn ;Fill an area of memory with a list values. If the list ;is bigger than the area, don't use the whole list. If the ;list is smaller, repeat it as many times as necessary. 26B:02B0 FILL: 926B:02B0 E8 FF28 call RANGE ; (01DB) 926B:02B3 51 push cx 926B:02B4 50 push ax 926B:02B5 52 push dx 926B:02B6 E8 00B4 call LIST ; (036D) 926B:02B9 5F pop di 926B:02BA 07 pop es 926B:02BB 59 pop cx 926B:02BC 3B D9 cmp bx,cx 926B:02BE úBE 0118 mov si,LINEBUF ; (0000:0118=0D0h) 926B:02C1 E3 02 jcxz BIGRNG ; Jump if cx=0 926B:02C3 73 E6 jnc COPYLIST ; Jump if carry=0 926B:02C5 BIGRNG: ; xref 926B:02C1 926B:02C5 2B CB sub cx,bx 926B:02C7 87 D9 xchg bx,cx 926B:02C9 57 push di 926B:02CA F3/ A4 rep movsb ; Rep when cx >0 Mov [si] to es:[di] 926B:02CC 5E pop si ;The list has been copied into the beginning of the ;specified area of memory. SI is the first address ;of that area, DI is the end of the copy of the list ;plus one, which is where the list will begin to repeat. ;All we need to do now is copy [SI] to [DI] until the ;end of the memory area is reached. This will cause the ;list to repeat as many times as necessary. 926B:02CD 8B CB mov cx,bx 926B:02CF 06 push es 926B:02D0 1F pop ds 926B:02D1 EB D8 jmp short COPYLIST ; (02AB) ;Search a specified area of memory for given list of bytes. ;Print address of first byte of each match. 926B:02D3 SEARCH: 926B:02D3 E8 FF05 call RANGE ; (01DB) 926B:02D6 51 push cx 926B:02D7 50 push ax 926B:02D8 52 push dx 926B:02D9 E8 0091 call LIST ; (036D) 926B:02DC 4B dec bx 926B:02DD 5F pop di 926B:02DE 07 pop es 926B:02DF 59 pop cx 926B:02E0 2B CB sub cx,bx 926B:02E2 SCAN: ; xref 926B:0301 926B:02E2 úBE 0118 mov si,LINEBUF ; (0000:0118=0D0h) 926B:02E5 AC lodsb ; String [si] to al 926B:02E6 DOSCAN: ; xref 926B:02E7 926B:02E6 AE scasb ; Scan es:[di] for al 926B:02E7 E0 FD loopnz DOSCAN ; Loop if zf=0, cx>0 926B:02E9 75 C4 jnz RET ; Jump if not zero 926B:02EB 53 push bx 926B:02EC 87 CB xchg cx,bx 926B:02EE 57 push di 926B:02EF F3/ A6 repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] 926B:02F1 8B CB mov cx,bx 926B:02F3 5F pop di 926B:02F4 5B pop bx 926B:02F5 75 08 jnz TEST ; Jump if not zero 926B:02F7 4F dec di 926B:02F8 E8 FE5B call OUTDI ; (0156) 926B:02FB 47 inc di 926B:02FC E8 FE0E call CRLF ; (010D) 926B:02FF TEST: ; xref 926B:02F5 926B:02FF E3 AE jcxz RET ; Jump if cx=0 926B:0301 EB DF jmp short SCAN ; (02E2) ;Get the next parameter, which must be a hex number. ;CX is maximum number of digits the number may have. 926B:0303 GETHEX: 926B:0303 E8 FE2F call SCANP ; (0135) 926B:0306 GETHEX1: 926B:0306 33 D2 xor dx,dx ; Zero register 926B:0308 8A E6 mov ah,dh 926B:030A E8 0014 call HEXIN ; (0321) 926B:030D 72 73 jc ERROR ; Jump if carry Set 926B:030F 8A D0 mov dl,al 926B:0311 GETLP: ; xref 926B:031F 926B:0311 ú47 inc di 926B:0312 49 dec cx 926B:0313 E8 000B call HEXIN ; (0321) 926B:0316 72 97 jc RET ; Jump if carry Set 926B:0318 E3 68 jcxz ERROR ; Jump if cx=0 926B:031A E8 FEAD call SHIFT4 ; (01CA) 926B:031D 0A D0 or dl,al 926B:031F EB F0 jmp short GETLP ; (0311) ;Check if next character in the input buffer is a hex digit ;and convert it to binary if it is. Carry set if not. 926B:0321 HEXIN: 926B:0321 8A 05 mov al,[di] ;Check if AL has a hex digit and convert it to binary if it ;is. Carry set if not. 926B:0323 HEXCHK: 926B:0323 2C 30 sub al,'0' 926B:0325 72 88 jc RET ; Jump if carry Set 926B:0327 3C 0A cmp al,0Ah 926B:0329 F5 cmc ; Complement carry 926B:032A 73 83 jnc RET ; Jump if carry=0 926B:032C 2C 07 sub al,7 926B:032E 3C 0A cmp al,0Ah 926B:0330 72 03 jb RET ; Jump if below 926B:0332 3C 10 cmp al,10h 926B:0334 F5 cmc ; Complement carry 926B:0335 C3 RET: retn ;Process one parameter when a list of bytes is ;required. Carry set if parameter bad. Called by LIST LISTITEM: 926B:0336 E8 FDFC call SCANP ; (0135) 926B:0339 E8 FFE5 call HEXIN ; (0321) 926B:033C 72 0B jc STRINGCHK ; Jump if carry Set 926B:033E B9 0002 mov cx,2 926B:0341 E8 FFBF call GETHEX ; (0303) 926B:0344 88 17 mov [bx],dl 926B:0346 43 inc bx 926B:0347 F8 GRET: clc ; Clear carry flag 926B:0348 C3 retn 926B:0349 STRINGCHK: ; xref 926B:033C 926B:0349 8A 05 mov al,[di] 926B:034B 3C 27 cmp al,''' 926B:034D 74 06 je STRING ; Jump if equal 926B:034F 3C 22 cmp al,'"' 926B:0351 74 02 je STRING ; Jump if equal 926B:0353 F9 stc ; Set carry flag 926B:0354 C3 retn 926B:0355 STRING: ; xref 926B:034D, 0351 926B:0355 8A E0 mov ah,al 926B:0357 47 inc di 926B:0358 STRINGLP: ; xref 926B:036B 926B:0358 ú8A 05 mov al,[di] 926B:035A 47 inc di 926B:035B 3C 0D cmp al,0Dh 926B:035D 74 23 je ERROR ; Jump if equal 926B:035F 3A C4 cmp al,ah 926B:0361 75 05 jne STOSTRG ; Jump if not equal 926B:0363 3A 25 cmp ah,[di] 926B:0365 75 E0 jne loc_45 ; Jump if not equal 926B:0367 47 inc di 926B:0368 STOSTRG: ; xref 926B:0361 926B:0368 88 07 mov [bx],al 926B:036A 43 inc bx 926B:036B EB EB jmp short STRINGLP ; (0358) ;Get a byte list for ENTER, FILL or SEARCH. Accepts any number ;of 2-digit hex values or character strings in either single ;(') or double (") quotes. 926B:036D LIST: 926B:036D BB 0118 mov bx,LINEBUF 926B:0370 LISTLP: ; xref 926B:0373 926B:0370 E8 FFC3 call LISTITEM ; (0336) 926B:0373 73 FB jnc LISTLP ; Jump if carry=0 926B:0375 81 EB 0118 sub bx,LINEBUF 926B:0379 74 07 jz ERROR ; Jump if zero ;Make sure there is nothing more on the line except for ;blanks and carriage return. If there is, it is an ;unrecognized parameter and an error. 926B:037B GETEOL: 926B:037B E8 FDC0 call SCANB ; (013E) 926B:037E 75 02 jnz ERROR ; Jump if not zero 926B:0380 C3 retn ;Command error. DI has been incremented beyond the ;command letter so it must decremented for the ;error pointer to work. 926B:0381 PERR: 926B:0381 4F dec di ;Syntax error. DI points to character in the input buffer ;which caused error. By subtracting from start of buffer, ;we will know how far to tab over to appear directly below ;it on the terminal. Then print "^ Error". 926B:0382 ERROR: ; xref 926B:00D7, 030D, 0318, 035D ; 0379, 037E 926B:0382 81 EF 0117 sub di,LINEBUF-1 ; 117h 926B:0386 8B CF mov cx,di 926B:0388 E8 FE05 call TAB ; (0190) 926B:038B BE 0783 mov si,SYNERR ;Print error message and abort to command level 926B:038E PRINT: ; xref 926B:0550 926B:038E úE8 FD9A call PRINTMES ; (012B) 926B:0391 E9 FD0C jmp COMMAND ; (00A0) ;Short form of ENTER command. A list of values from the ;command line are put into memory without using normal ;ENTER mode. GETLIST: 926B:0394 E8 FFD6 call LIST ; (036D) 926B:0397 5F pop di 926B:0398 07 pop es 926B:0399 úBE 0118 mov si,LINEBUF ; (926B:0118=0FFh) 926B:039C 8B CB mov cx,bx 926B:039E F3/ A4 rep movsb ; Rep when cx >0 Mov [si] to es:[di] 926B:03A0 C3 retn ;Enter values into memory at a specified address. If the ;line contains nothing but the address we go into "enter ;mode", where the address and its current value are printed ;and the user may change it if desired. To change, type in ;new value in hex. Backspace works to correct errors. If ;an illegal hex digit or too many digits are typed, the ;bell is sounded but it is otherwise ignored. To go to the ;next byte (with or without change), hit space bar. To ;back up to a previous address, type "-". On ;every 8-byte boundary a new line is started and the address ;is printed. To terminate command, type carriage return. ; Alternatively, the list of bytes to be entered may be ;included on the original command line immediately following ;the address. This is in regular LIST format so any number ;of hex values or strings in quotes may be entered. 926B:03A1 ENTER: 926B:03A1 B9 0005 mov cx,5 926B:03A4 E8 FF5C call GETHEX ; (0303) 926B:03A7 E8 FE12 call GETSEG ; (01BC) ;Adjust segment and displacement so we are in the middle ;of the segment instead of the very bottom. This allows ;backing up a long way. 926B:03AA 82 EC 08 sub ah,8 926B:03AD 80 C6 80 add dh,80h 926B:03B0 50 push ax 926B:03B1 52 push dx 926B:03B2 E8 FD89 call SCANB ; (013E) 926B:03B5 75 DD jnz GETLIST ; Jump if not zero 926B:03B7 5F pop di 926B:03B8 07 pop es 926B:03B9 GETROW: ; xref 926B:043E 926B:03B9 úE8 FD9A call OUTDI ; (0156) 926B:03BC E8 FDCD call BLANK ; (018C) 926B:03BF GETBYTE: ; xref 926B:0439 926B:03BF 26: 8A 05 mov al,es:[di] 926B:03C2 E8 FDA7 call HEX ; (016C) 926B:03C5 B0 2E mov al,'.' 926B:03C7 E8 FDB7 call OUT ; (0181) 926B:03CA B9 0002 mov cx,2 926B:03CD BA 0000 mov dx,0 926B:03D0 GETDIG: ; xref 926B:03E3, 0403, 0408, 0413 926B:03D0 úE8 FD48 call IN ; (011B) 926B:03D3 8A E0 mov ah,al 926B:03D5 E8 FF4B call HEXCHK ; (0323) 926B:03D8 86 E0 xchg ah,al 926B:03DA 72 0C jc NONEX ; Jump if carry Set 926B:03DC E8 FDA2 call OUT ; (0181) 926B:03DF 8A F2 mov dh,dl 926B:03E1 8A D4 mov dl,ah 926B:03E3 E2 EB loop GETDIG ; Loop if cx > 0 ;We have two digits, so all we will accept now is a command. WAIT: 926B:03E5 E8 FD33 call IN ; (011B) 926B:03E8 NOHEX: ; xref 926B:03DA 926B:03E8 3C 08 cmp al,8 926B:03EA 74 19 je BS ; Jump if equal 926B:03EC 3C 7F cmp al,7Fh 926B:03EE 74 15 je BS ; Jump if equal 926B:03F0 3C 2D cmp al,'-' 926B:03F2 74 4D je PREV ; Jump if equal 926B:03F4 3C 0D cmp al,0Dh 926B:03F6 74 2F je EOL ; Jump if equal 926B:03F8 3C 20 cmp al,' ' 926B:03FA 74 31 je NEXT ; Jump if equal ;If we got here, character was invalid. Sound bell 926B:03FC B0 07 mov al,7 926B:03FE E8 FD80 call OUT ; (0181) 926B:0401 E3 E2 jcxz WAIT ; Jump if cx=0 926B:0403 EB CB jmp short GETDIG ; (03D0) 926B:0405 BS: ; xref 926B:03EA, 03EE 926B:0405 82 F9 02 cmp cl,2 926B:0408 74 C6 je GETDIG ; Jump if equal 926B:040A FE C1 inc cl 926B:040C 8A D6 mov dl,dh 926B:040E 8A F5 mov dh,ch 926B:0410 E8 FD15 call BACKUP ; (0128) 926B:0413 EB BB jmp short GETDIG ; (03D0) ;If new value has been entered, convert it to binary and ;put into memory. Always bump pointer to next location 926B:0415 STORE: 926B:0415 82 F9 02 cmp cl,2 926B:0418 74 0B je NOSTO ; Jump if equal ;Rotate DH left 4 bits to combine with DL and make a byte value 926B:041A 51 push cx 926B:041B B1 04 mov cl,4 926B:041D D2 E6 shl dh,cl ; Shift w/zeros fill 926B:041F 59 pop cx 926B:0420 0A D6 or dl,dh 926B:0422 26: 88 15 mov es:[di],dl 926B:0425 NOSTO: ; xref 926B:0418 926B:0425 47 inc di 926B:0426 C3 retn 926B:0427 EOL: ; xref 926B:03F6 926B:0427 E8 FFEB call STORE ; (0415) 926B:042A E9 FCE0 jmp CRLF ; (010D) 926B:042D NEXT: ; xref 926B:03FA 926B:042D E8 FFE5 call STORE ; (0415) 926B:0430 41 inc cx 926B:0431 41 inc cx 926B:0432 E8 FD5B call TAB ; (0190) 926B:0435 8B C7 mov ax,di 926B:0437 24 07 and al,7 926B:0439 75 84 jnz GETBYTE ; Jump if not zero 926B:043B NEWROW: ; xref 926B:0446 926B:043B úE8 FCCF call CRLF ; (010D) 926B:043E E9 FF78 jmp GETROW ; (03B9) 926B:0441 PREV: ; xref 926B:03F2 926B:0441 E8 FFD1 call STORE ; (0415) ;DI has been bumped to next byte. Drop it 2 to go to previous addr 926B:0444 4F dec di 926B:0445 4F dec di 926B:0446 EB F3 jmp short NEWROW ; (043B) ;Perform register dump if no parameters or set register if a ;register designation is a parameter. 926B:0448 REG: 926B:0448 E8 FCEA call SCANP ; (0135) 926B:044B 74 62 jz DISPREG ; Jump if zero 926B:044D 8A 15 mov dl,[di] 926B:044F 47 inc di 926B:0450 8A 35 mov dh,[di] 926B:0452 82 FE 0D cmp dh,0Dh 926B:0455 74 76 je FLAG ; Jump if equal 926B:0457 47 inc di 926B:0458 E8 FF20 call GETEOL ; (037B) 926B:045B 82 FE 20 cmp dh,20h ; ' ' 926B:045E 74 6D je FLAG ; Jump if equal 926B:0460 úBF 06F0 mov di,offset REGTAB ; (926B:06F0='AXBXCXDXSPBPSIDI') 926B:0463 92 xchg dx,ax 926B:0464 0E push cs 926B:0465 07 pop es 926B:0466 B9 000E mov cx,REGTABLEN ;0Eh 926B:0469 F2/ AF repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax 926B:046B 75 3C jnz BADREG ; Jump if not zero 926B:046D 0B C9 or cx,cx ; Zero ? 926B:046F 75 06 jnz NOTPC ; Jump if not zero 926B:0471 4F dec di 926B:0472 4F dec di 926B:0473 2E: 8B 45 FE mov ax,cs:[di-2] 926B:0477 NOTPC: ; xref 926B:046F 926B:0477 E8 FD07 call OUT ; (0181) 926B:047A 8A C4 mov al,ah 926B:047C E8 FD02 call OUT ; (0181) 926B:047F E8 FD0A call BLANK ; (018C) 926B:0482 1E push ds 926B:0483 07 pop es 926B:0484 ú8D 9D FAAA lea bx,ds:REGDIF-2[di] ; (0000:FAAA=3Bh) Load effective addr 926B:0488 8B 17 mov dx,[bx] 926B:048A E8 FCD8 call OUT16 ; (0165) 926B:048D E8 FC7D call CRLF ; (010D) 926B:0490 B0 3A mov al,':' 926B:0492 E8 FCEC call OUT ; (0181) 926B:0495 E8 FC42 call INBUF ; (00DA) 926B:0498 E8 FCA3 call SCANB ; (013E) 926B:049B 74 0B jz RET3 ; Jump if zero 926B:049D B9 0004 mov cx,4 926B:04A0 E8 FE63 call GETHEX1 ; (0306) 926B:04A3 E8 FED5 call GETEOL ; (037B) 926B:04A6 89 17 mov [bx],dx RET3: retn 926B:04A9 BADREG: ; xref 926B:046B, 04D0 926B:04A9 B8 5242 mov ax,5200+'B' 926B:04AC E9 0096 jmp ERR ; (0545) 926B:04AF DISPREG: ; xref 926B:044B 926B:04AF úBE 06F0 mov si,offset REGTAB ; (926B:06F0='AXBXCXDXSPBPSIDI') 926B:04B2 BB 019C mov bx,AXSAVE 926B:04B5 B9 0008 mov cx,8 926B:04B8 E8 0065 call DISPREGLINE ; (0520) 926B:04BB E8 FC4F call CRLF ; (010D) 926B:04BE B9 0005 mov cx,5 926B:04C1 E8 005C call DISPREGLINE ; (0520) 926B:04C4 E8 FCC5 call BLANK ; (018C) 926B:04C7 E8 0093 call DISPFLAGS ; (055D) 926B:04CA E9 FC40 jmp CRLF ; (010D) 926B:04CD FLAG: ; xref 926B:0455, 045E 926B:04CD 82 FA 46 cmp dl,'F' 926B:04D0 75 D7 jne BADREG ; Jump if not equal 926B:04D2 E8 0088 call DISPFLAGS ; (055D) 926B:04D5 B0 2D mov al,'-' 926B:04D7 E8 FCA7 call OUT ; (0181) 926B:04DA E8 FBFD call INBUF ; (00DA) 926B:04DD E8 FC5E call SCANB ; (013E) 926B:04E0 33 DB xor bx,bx ; Zero register 926B:04E2 8B 16 01B6 mov dx,word ptr FSAVE ; (926B:01B6=448h) 926B:04E6 GETFLG: ; xref 926B:051E 926B:04E6 ú8B F7 mov si,di 926B:04E8 AD lodsw ; String [si] to ax 926B:04E9 3C 0D cmp al,0Dh 926B:04EB 74 66 je SAVCHG ; Jump if equal 926B:04ED 82 FC 0D cmp ah,0Dh 926B:04F0 74 66 je FLGERR ; Jump if equal 926B:04F2 úBF 070C mov di,offset FLAGTAB ; (926B:070C=0) 926B:04F5 B9 0020 mov cx,20h 926B:04F8 0E push cs 926B:04F9 07 pop es 926B:04FA F2/ AF repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax 926B:04FC 75 5A jnz FLGERR ; Jump if not zero 926B:04FE 8A E9 mov ch,cl 926B:0500 80 E1 0F and cl,0Fh 926B:0503 B8 0001 mov ax,1 926B:0506 D3 C0 rol ax,cl ; Rotate 926B:0508 85 C3 test ax,bx 926B:050A 75 33 jnz REPFLG ; Jump if not zero 926B:050C 0B D8 or bx,ax 926B:050E 0B D0 or dx,ax 926B:0510 F6 C5 10 test ch,10h 926B:0513 75 02 jnz NEXTFLG ; Jump if not zero 926B:0515 33 D0 xor dx,ax 926B:0517 NEXTFLG: ; xref 926B:0513 926B:0517 8B FE mov di,si 926B:0519 1E push ds 926B:051A 07 pop es 926B:051B E8 FC17 call SCANP ; (0135) 926B:051E EB C6 jmp short GETFLG ; (04E6) 926B:0520 DISPREGLINE: 926B:0520 2E: AD lods word ptr cs:[si] ; String [si] to ax 926B:0522 E8 FC5C call OUT ; (0181) 926B:0525 8A C4 mov al,ah 926B:0527 E8 FC57 call OUT ; (0181) 926B:052A B0 3D mov al,'=' 926B:052C E8 FC52 call OUT ; (0181) 926B:052F 8B 17 mov dx,[bx] 926B:0531 43 inc bx 926B:0532 43 inc bx 926B:0533 E8 FC2F call OUT16 ; (0165) 926B:0536 E8 FC53 call BLANK ; (018C) 926B:0539 E8 FC50 call BLANK ; (018C) 926B:053C E2 E2 loop DISPREGLINE ; Loop if cx > 0 926B:053E C3 retn 926B:053F REPFLG: ; xref 926B:050A 926B:053F B8 4644 mov ax,4600+'D' ;44h 926B:0542 FERR: ; xref 926B:055B 926B:0542 úE8 000E call SAVCHG ; (0553) 926B:0545 ERR: ; xref 926B:0223, 04AC, 06A3 926B:0545 úE8 FC39 call OUT ; (0181) 926B:0548 8A C4 mov al,ah 926B:054A E8 FC34 call OUT ; (0181) 926B:054D BE 0784 mov si,ERRMES 926B:0550 E9 FE3B jmp PRINT ; (038E) 926B:0553 SAVCHG: 926B:0553 89 16 01B6 mov word ptr [FSAVE],dx ; (926B:01B6=448h) 926B:0557 C3 retn 926B:0558 FLGERR: ; xref 926B:04F0, 04FC 926B:0558 B8 4642 mov ax,4600+'B' 926B:055B EB E5 jmp short FERR ; (0542) 926B:055D DISPFLAGS: 926B:055D úBE 070C mov si,offset FLAGTAB ; (926B:070C=0) 926B:0560 B9 0010 mov cx,10h 926B:0563 8B 16 01B6 mov dx,word ptr [FSAVE] ; (926B:01B6=448h) 926B:0567 DFLAGS: ; xref 926B:0580 926B:0567 2E: AD lods word ptr cs:[si] ; String [si] to ax 926B:0569 D1 E2 shl dx,1 ; Shift w/zeros fill 926B:056B 72 04 jc FLAGSET ; Jump if carry Set 926B:056D 2E: 8B 44 1E mov ax,cs:[si+1Eh] 926B:0571 FLAGSET: ; xref 926B:056B 926B:0571 0B C0 or ax,ax ; Zero ? 926B:0573 74 0B jz NEXTFLG ; Jump if zero 926B:0575 E8 FC09 call OUT ; (0181) 926B:0578 8A C4 mov al,ah 926B:057A E8 FC04 call OUT ; (0181) 926B:057D E8 FC0C call BLANK ; (018C) 926B:0580 NEXTFLG: ; xref 926B:0573 926B:0580 E2 E5 loop DFLAGS ; Loop if cx > 0 926B:0582 C3 retn ;Trace 1 instruction or the number of instruction specified ;by the parameter using 8086 trace mode. Registers are all ;set according to values in save area 926B:0583 TRACE: 926B:0583 E8 FBAF call SCANP ; (0135) 926B:0586 E8 FD98 call HEXIN ; (0321) 926B:0589 BA 0001 mov dx,1 926B:058C 72 06 jc STOCNT ; Jump if carry Set 926B:058E B9 0004 mov cx,4 926B:0591 E8 FD6F call GETHEX ; (0303) 926B:0594 STOCNT: ; xref 926B:058C 926B:0594 89 16 0102 mov ds:[TCOUNT],dx ; (0000:0102=0F000h) 926B:0598 E8 FDE0 call GETEOL ; (037B) 926B:059B STEP: ; xref 926B:05E8 926B:059B úC7 06 0100 0000 mov word ptr ds:[BRKCNT],0 ; (926B:0100=3CDEh) 926B:05A1 80 0E 01B7 01 or byte ptr [FSAVE+1],1 ; (926B:01B7=4) 926B:05A6 EXIT: ; xref 926B:06D1 926B:05A6 úC7 06 000C 05EA mov word ptr ds:[12],BREAKFIX ; (0000:000C=6F4h) 926B:05AC 8C 0E 000E mov ds:[14],cs ; (0000:000E=70h) 926B:05B0 C7 06 0004 05F1 mov word ptr ds:[4],REENTER ; (0000:0004=6F4h) 926B:05B6 8C 0E 0006 mov ds:[6],cs ; (0000:0006=70h) 926B:05BA FA cli ; Disable interrupts 926B:05BB C7 06 0064 05F1 mov word ptr ds:[64],REENTER ; (0000:0064=1755h) 926B:05C1 8C 0E 0066 mov ds:[66],cs ; (0000:0066=4D9h) 926B:05C5 BC 019C mov sp,STACK 926B:05C8 58 pop ax 926B:05C9 5B pop bx 926B:05CA 59 pop cx 926B:05CB 5A pop dx 926B:05CC 5D pop bp 926B:05CD 5D pop bp 926B:05CE 5E pop si 926B:05CF 5F pop di 926B:05D0 07 pop es 926B:05D1 07 pop es 926B:05D2 17 pop ss 926B:05D3 8B 26 01A4 mov sp,ds:[SPSAVE] ; (0000:01A4=1BD0h) 926B:05D7 FF 36 01B6 push word ptr ds:[FSAVE] ; (0000:01B6=0C000h) 926B:05DB FF 36 01B2 push word ptr ds:[CSSAVE] ; (0000:01B2=0F000h) 926B:05DF FF 36 01B4 push word ptr ds:[IPSAVE] ; (0000:01B4=2607h) 926B:05E3 8E 1E 01AC mov ds,ds:[DSSAVE] ; (0000:01AC=1BD0h) 926B:05E7 CF iret ; Interrupt return 926B:05E8 STEP1: jmp short STEP ; (059B) 926B:05EA 87 EC xchg bp,sp 926B:05EC FF 4E 00 dec word ptr [bp] 926B:05EF 87 EC xchg bp,sp ;Re-entry point from trace mode or interrupt during ;execution. All registers are saved so they can be ;displayed or modified. REENTER: 926B:05F1 2E: 89 26 09A4 mov cs:[SPSAVE+SEGDIF],sp ; (926B:09A4=0) 926B:05F6 2E: 8C 16 09B0 mov cs:[SSSAVE+SEGDIF],ss ; (926B:09B0=0B76h) 926B:05FB 33 E4 xor sp,sp ; Zero register 926B:05FD 8E D4 mov ss,sp 926B:05FF BC 01B0 mov sp,RSTACK 926B:0602 06 push es 926B:0603 1E push ds 926B:0604 57 push di 926B:0605 56 push si 926B:0606 55 push bp 926B:0607 4C dec sp 926B:0608 4C dec sp 926B:0609 52 push dx 926B:060A 51 push cx 926B:060B 53 push bx 926B:060C 50 push ax 926B:060D 16 push ss 926B:060E 1F pop ds 926B:060F 8B 26 01A4 mov sp,word ptr [SPSAVE] ; (926B:01A4=665h) 926B:0613 8E 16 01B0 mov ss,word ptr [SSSAVE] ; (926B:01B0=672h) 926B:0617 8F 06 01B4 pop word ptr [IPSAVE] ; (926B:01B4=381h) 926B:061B 8F 06 01B2 pop word ptr [CSSAVE] ; (926B:01B2=381h) 926B:061F 58 pop ax 926B:0620 80 E4 FE and ah,0FEh 926B:0623 A3 01B6 mov word ptr [FSAVE],ax ; (926B:01B6=448h) 926B:0626 89 26 01A4 mov word ptr [SPSAVE],sp ; (926B:01A4=665h) 926B:062A 1E push ds 926B:062B 07 pop es 926B:062C 1E push ds 926B:062D 17 pop ss 926B:062E BC 019C mov sp,STACK 926B:0631 C7 06 0064 06D4 mov word ptr ds:[64h],INT ; (926B:0064=1AE8h) 926B:0637 B0 20 mov al,' ' 926B:0639 E6 F2 out BASE+2,al ; port 0F2h ??I/O Non-standard 926B:063B FB sti ; Enable interrupts 926B:063C FC cld ; Clear direction 926B:063D E8 FACD call CRLF ; (010D) 926B:0640 E8 FE6C call DISPREG ; (04AF) 926B:0643 FF 0E 0102 dec word ptr ds:[TCOUNT] ; (926B:0102=7408h) 926B:0647 75 9F jnz STEP1 ; Jump if not zero ENDGO: 926B:0649 úBE 0104 mov si,BPTAB ; (926B:0104=0F3h) 926B:064C 8B 0E 0100 mov cx,word ptr ds:[BRKCNT] ; (926B:0100=3CDEh) 926B:0650 E3 10 jcxz COMJMP ; Jump if cx=0 926B:0652 CLEARBP: ; xref 926B:0660 926B:0652 8B 54 14 mov dx,[si+BPLEN] 926B:0655 AD lodsw ; String [si] to ax 926B:0656 50 push ax 926B:0657 E8 FB62 call GETSEG ; (01BC) 926B:065A 8E C0 mov es,ax 926B:065C 8B FA mov di,dx 926B:065E 58 pop ax 926B:065F AA stosb ; Store al to es:[di] 926B:0660 E2 F0 loop CLEARBP ; Loop if cx > 0 926B:0662 COMJMP: jmp COMMAND ; (00A0) ;Input from the specified port and display result 926B:0665 INPUT: 926B:0665 B9 0004 mov cx,4 926B:0668 E8 FC98 call GETHEX ; (0303) 926B:066B EC in al,dx ; port 0F1h ??I/O Non-standard 926B:066C E8 FAFD call HEX ; (016C) 926B:066F E9 FA9B jmp CRLF ; (010D) ;Output a value to specified port. 926B:0672 OUTPUT: 926B:0672 B9 0004 mov cx,4 926B:0675 E8 FC8B call GETHEX ; (0303) 926B:0678 52 push dx 926B:0679 B9 0002 mov cx,2 926B:067C E8 FC84 call GETHEX ; (0303) 926B:067F 92 xchg dx,ax 926B:0680 5A pop dx 926B:0681 EE out dx,al ; port 0F1h ??I/O Non-standard 926B:0682 C3 retn ;Jump to a program, setting up registers according to the ;save area. Up to 10 breakpoint addresses may be specified. 926B:0683 GO: 926B:0683 BB 0118 mov bx,LINEBUF 926B:0686 33 F6 xor si,si ; Zero register 926B:0688 GO1: ; xref 926B:069E 926B:0688 E8 FAAA call SCANP ; (0135) 926B:068B 74 19 jz EXEC ; Jump if zero 926B:068D B9 0005 mov cx,5 926B:0690 E8 FC70 call GETHEX ; (0303) 926B:0693 89 17 mov [bx],dx 926B:0695 88 67 ED mov [bx-BPLEN+1],ah ; 13h 926B:0698 43 inc bx 926B:0699 43 inc bx 926B:069A 46 inc si 926B:069B 83 FE 0B cmp si,BPMAX+1 ; 0bh 926B:069E 75 E8 jne GO1 ; Jump if not equal 926B:06A0 B8 5042 mov ax,5000H+'B' 926B:06A3 E9 FE9F jmp ERR ; (0545) 926B:06A6 EXEC: ; xref 926B:068B 926B:06A6 89 36 0100 mov ds:[BRKCNT],si ; (0000:0100=0EC59h) 926B:06AA E8 FCCE call GETEOL ; (037B) 926B:06AD 8B CE mov cx,si 926B:06AF E3 1A jcxz NOBP ; Jump if cx=0 926B:06B1 úBE 0104 mov si,BPTAB ; (0000:0104=0D0h) 926B:06B4 SETBP: ; xref 926B:06C9 926B:06B4 8B 54 14 mov dx,[si+BPLEN] ; 14h 926B:06B7 AD lodsw ; String [si] to ax 926B:06B8 E8 FB01 call GETSEG ; (01BC) 926B:06BB 8E D8 mov ds,ax 926B:06BD 8B FA mov di,dx 926B:06BF 8A 05 mov al,[di] 926B:06C1 C6 05 CC mov byte ptr [di],0CCh 926B:06C4 06 push es 926B:06C5 1F pop ds 926B:06C6 88 44 FE mov [si-2],al 926B:06C9 E2 E9 loop SETBP ; Loop if cx > 0 926B:06CB NOBP: ; xref 926B:06AF 926B:06CB C7 06 0102 0001 mov word ptr ds:[TCOUNT],1 ; (0000:0102=0F000h) 926B:06D1 E9 FED2 jmp EXIT ; (05A6) ;Console input interrupt handler. Used to interrupt commands ;or programs under execution (if they have interrupts ;enabled). Control-S causes a loop which waits for any other ;character to be typed. Control-C causes abort to command ;mode. All other characters are ignored. INT: 926B:06D4 50 push ax 926B:06D5 B0 20 mov al,' ' 926B:06D7 E6 F2 out BASE+2,al ; port 0F2h ??I/O Non-standard 926B:06D9 E4 F6 in al,DATA ; port 0F6h ??I/O Non-standard 926B:06DB 24 7F and al,7Fh 926B:06DD 3C 13 cmp al,'S'-'@' ;13h 926B:06DF 75 03 jne NOSTOP ; Jump if not equal 926B:06E1 E8 FA37 call IN ; (011B) 926B:06E4 NOSTOP: ; xref 926B:06DF 926B:06E4 3C 03 cmp al,'C'-'@' ;3 926B:06E6 74 02 je BREAK ; Jump if equal ;Just ignore interrupt - restore AX and return 926B:06E8 58 pop ax 926B:06E9 CF iret ; Interrupt return 926B:06EA BREAK: ; xref 926B:06E6 926B:06EA E8 FA20 call CRLF ; (010D) 926B:06ED E9 F9B0 jmp COMMAND ; (00A0) 926B:06F0 41 58 42 58 43 58 REGTAB: db 'AXBXCXDXSPBPSIDIDSESSSCSIPPC' ; xref 926B:0460 REGDIF: EQU AXSAVE-REGTAB ;Flags are ordered to correspond with the bits of the flag ;register, most significant bit first, zero if bit is not ;a flag. First 16 entries are for bit set, second 16 for ;bit reset. FLAGTAB: DW 0 DW 0 DW 0 DW 0 DB "OV" DB "DN" DB "EI" DW 0 DB "NG" DB "ZR" DW 0 DB "AC" DW 0 DB "PE" DW 0 DB "CY" DW 0 DW 0 DW 0 DW 0 DB "NV" DB "UP" DB "DI" DW 0 DB "PL" DB "NZ" DW 0 DB "NA" DW 0 DB "PO" DW 0 DB "NC" ;Initialization table. First byte of each entry is no. ;of bytes to output to the corresponding port. That ;many initialization bytes follow. INITTABLE: ;Port BASE+0 - Master 8259A. Intialization Command Word (ICW) ;One sets level-triggered mode, multiple 8259As, require ;ICW4. DB 1 DB 19H ;Port BASE+1 - Master 8259A. ICW2 sets vector base to 10H ;ICW3 sets a slave on interrupt input 1; ICW4 sets buffered ;mode, as a master, with Automatic End of Interrupt, 8086 ;vector; Operation Command Word (OCW) One sets interrupt ;mask to enable line 1 (slave 8259A) only. DB 4 DB 10H,2,0FH,0FDH ;Port BASE+2 - Slave 8259A. ICW1 sets level-triggered mode, ;multiple 8259As, require ICW4. DB 1 DB 19H ;Port BASE+3 - Slave 8259A. ICW2 sets vector base to 18H ;ICW3 sets slave address as 1; ICW4 sets buffered mode, ;as slave, with Automatic End of Interrupt (which doesn't ;work in slaves), 8086 vector; OCW1 sets interrupt mask ;to enable line 1 (serial receive) only. DB 4 DB 18H,1,0BH,0FDH ;Port Base+4 - 9513 Data. 9513 has previously been set ;up for Counter 5 mode register with auto increment. Thus ;mode is set to 0B63H, which is no gating, count source is ;F1 (4 MHz), reload from load or hold, count down repetitively ;in binary, with output toggle. Load register is set to ;0007H, and Hold register is set to 0006H. Thus we ;alternately divide by 7 and 6, which is divided by 2 by ;the output toggle, thus providing a square wave of ;4 MHz/13 = 307.7 kHz, which divided by 16 in the 8251A ;provides 19,230 baud (0.16% high). DB 6 DB 63H,0BH,7,0,6,0 ;Port BASE+5 - 9513 Control. Load and arm counter 5, ;enabling baud rate generation. Then select counter ;5 mode register, in case baud rate wasn't right. DB 2 DB 70H,5 ;Port BASE+6 - 8251A Data. No initialization to this port. DB 0 ;Port BASE+7 - 8251A Control. Since it is not possible to ;know whether the 8251A next expects a Mode Instruction or ;a Command Instruction, a dummy byte is sent which could ;safely be interpreted as either but guarantees it is now ;expecting a Command. The command sent is Internal Reset ;which causes it to start expecting a mode. The mode sent ;is for 2 stop bits, no parity, 8 data bits, 16X clock. ;This is followed by the command to error reset, enable ;transmitter and receiver, set RTS and DTR to +12V. DB 4 DB 0B7H,77H,0CEH,37H HEADER: db 0Dh, 0Ah, 0Ah, 'SCP 8086 Monitor 1.6',0Dh,8Ah db 8Ah SYNERR: db '^' 926B:0783 5E 20 45 72 72 6F ERRMES: db 'Error',0Dh,8Ah 926B:078C 08 BACMES: db 8,32,8 ; xref 926B:0128 ;Disk boot. Select one of the following routines by ;setting the equates at the start of this program. 926B:078F BOOT: ; xref 926B:0097 926B:078F 57 push di DISK: equ 78H ; looks like this copies code below to low RAM 926B:0790 úBE 079F mov si,DCOM ; (0000:079F=0B8h) 926B:0793 úBF 0080 mov di,80H ; (0000:0080=94h) 926B:0796 B9 0024 mov cx,24h ; move 24h bytes 926B:0799 2E: F3/ A5 rep movs word ptr es:[di],word ptr cs:[si] ; Rep when cx >0 Mov [si] to es:[di] 926B:079C E9 00E1 jmp $+0E4h DCOM: 926B:079F 32 FF xor bh,bh ; drive select 926B:07A1 B0 D0 mov al,0D0h 926B:07A3 E6 78 out DISK,al ; port 78h ??I/O Non-standard HOLD: 926B:07A5 B9 0005 mov cx,5 926B:07A8 DCOM0: ; xref 926B:07AA 926B:07A8 D4 0A aam ; Ascii adjust 926B:07AA E2 FC loop DCOM0 ; Loop if cx > 0 926B:07AC READY: ; xref 926B:07D5 926B:07AC 80 F7 08 xor bh,8 926B:07AF 8A C7 mov al,bh 926B:07B1 E6 7C out DISK+4,al ; port 7Ch ??I/O Non-standard 926B:07B3 B0 08 mov al,8 926B:07B5 E6 78 out DISK,al ; port 78h ??I/O Non-standard 926B:07B7 E4 7C in al,DISK+4 ; port 7Ch ??I/O Non-standard 926B:07B9 úBF 0200 mov di,LOAD ; 200h (926B:0200=0E7h) 926B:07BC B0 01 mov al,1 926B:07BE E6 7A out DISK+2,al ; port 7Ah ??I/O Non-standard 926B:07C0 BA 007B mov dx,7Bh 926B:07C3 B0 8C mov al,8Ch 926B:07C5 E6 78 out DISK,al ; port 78h ??I/O Non-standard 926B:07C7 EB 01 jmp short READ ; (07CA) 926B:07C9 READLOOP: ; xref 926B:07CF 926B:07C9 AA stosb ; Store al to es:[di] 926B:07CA READ: ; xref 926B:07C7 926B:07CA E4 7C in al,DISK+4 ; port 7Ch ??I/O Non-standard 926B:07CC D0 D0 rcl al,1 ; Rotate thru carry 926B:07CE EC in al,dx ; port 7Bh ??I/O Non-standard 926B:07CF 72 F8 jc READLOOP ; Jump if carry Set 926B:07D1 E4 78 in al,DISK ; port 78h ??I/O Non-standard 926B:07D3 24 9C and al,9Ch 926B:07D5 75 D5 jnz READY ; Jump if not zero 926B:07D7 C7 06 01B2 0000 mov word ptr [CSSAVE],0 ; (926B:01B2=381h) 926B:07DD C7 06 01B4 0200 mov word ptr [IPSAVE],LOAD ; (926B:01B4=381h) 926B:07E3 5F pop di 926B:07E4 E9 FDBB jmp GO ;*(05A2) 926B:07E4 E9 BB FD db 0E9h,0BBh,0FDh 926B:07E7 0009[FF] db 9 dup (0FFh) ENTRY: 926B:07F0 EA 00 00 80 FF db 0EAh, 00h, 00h, 80h,0FFh ;FF80:0000 ;Baud Rate Table. The 9513 divides 2MHz by these values. ;They are for 9600, 1200, 300, 150, 110 baud ; dw 13,104,416,832,1144 926B:07F5 0D BAUD: db 0Dh ; xref 926B:006C 926B:07F6 00 68 00 A0 01 40 db 00h, 68h, 00h,0A0h, 01h, 40h 926B:07FC 03 78 04 FF db 03h, 78h, 04h db 0FFh