***************************************************************** * * * MORROW 68K SYSTEM monitor REV 0. * * * * initial coding: 5/3/84 -bjg- * * * ***************************************************************** ioaddr = $ff0000 * compupro i/o address space * Compupro interfacer IV equates sio = ioaddr+$10 * interfacer base address siostat = sio+$1 * uart status siodat = sio * uart data select = sio+$7 * group select port console = 7 * interface left port * mult i/o equates base = ioaddr+$48 * standard base address grpctl = base+$7 * select port group0 = $08 group1 = $09 * serial port 1 group2 = $0A * serial port 2 group3 = $0B * serial port 3 dll = base * divisor latch lsb dlm = base+$1 * divisor latch msb ier = base+$1 * interrupt enable register lcr = base+$3 * line control register mcr = base+$4 * modem control register lsr = base+$5 * line status register rbr = base * receive buffer register thr = base * trasnmitter holding register dlab = $80 * divisor latch access bit thre = $20 * transmitter hold reg empty status dr = $1 * received data ready status wls0 = $1 * word length select bit 0 wls1 = $2 * word length select bit 1 (for 8 bit word) stb = $4 * stop bit count (2 stop bits) imask = $00 * non interupt mode loop = $10 * UART loop mode * miscellaneous equates alf = $a * ascii line feed acr = $d * ascii carriage return asp = $20 * ascii space acs = $1a * ascii clear for ADM31 Š * PIC equates init = $010 * bit high to initialize the PIC icw1 = base + 4 * PIC initialization control word 1 icw2 = base + 5 * PIC initialization control word 2 icw3 = base + 5 * PIC initialization control word 3 icw4 = base + 5 * PIC initialization control word 4 ocw1 = base + 5 * PIC interrupt mask register ocw2 = base + 4 * PIC EOI register picmask = $ff * mask to turn all interrupts off ltim = $8 * level triggered mode adi4 = $4 * call address intervals = 4 adi8 = 00 * call address intervals = 8 sngl = 02 * sole system PIC ic4 = 01 * icw4 access bit lovect = 0 * call vectors begin at 0 hivect = 0 * call vectors begin at 0 normal = 0 * Master/Reg. nest/unbuffered/no AEOI/8085 * -normal setting of OCW4 for Morrow Software eoi = $20 * non-specific EOI constant ivalu = init OR ltim OR adi4 OR sngl OR ic4 OR lovect **************************************************************** * * * DJ-DMA Equates * * * **************************************************************** djchan = $50 * initial channel address djattn = ioaddr+$ef * dj attention port **************************************************************** * * * DMA Winchester Controller Equates * * * **************************************************************** cyl = 306 * number cylinders for Seagate ST-506 heads = 4 * number heads for Seagate ST-506 stpdly = $1e * 15 msec for Seagate ST-506 hdsetl = 0 * 20 msec for Seagate ST-506 secsiz = 7 * 1024 byte sectors for CPM readat = 0 * DMA controller read sector opcode write = 1 * DMA controller write sector opcode rhead = 2 * DMA controller read header opcode format = 3 * DMA controller format track opcode const = 4 * load drive constants command sense = 5 * return drive status command noop = 6 * command used when seeking dmarst = $54 * DMA controller reset port attn = $55 * DMA controller Attention port stepout = $10 * Step direction to track 0 stepin = 0 * Step direction away from track 0 track0 = 1 * track 0 status wfault = 2 * write fault condition from drive dready = 4 * drive ready status sekcmp = 8 * seek complete status hdspt = 17 * number of sectors per track iopb = $50 * pointer to the channel chan = $80 * actual channel select = chan + 3 * select byte in channel Šdmaddr = chan + 4 * 24 bit dma address location arg = chan + 7 * beginning of four arguments to commands cmmd = chan + 11 * actual command location statis = chan + 12 * controller return status location link = chan + 13 * link field address for next command bootad = $100 * dma address for first sector from hddma good = $ff * good status result ******************************************************** * * * The following routines make up the debugging tool * * called MON68. * * * ******************************************************** monitor: call ucrlf start: ld sp,stack LD DE,START * monitor begins here PUSH DE CALL CRLF LD C,':' CALL cout1 STAR0: CALL TI OR A JR Z,STAR0 CP 'z'+1 JP NC,ERROR LD C,002H CP 'D' JR Z,disp cp 'd' jr nz,fill * * DISPLAY MEMORY XXXX TO XXXX * * DISP: CALL EXLF DI0: CALL CRLF CALL LADR LD B,010H DI1: CALL BLK LD A,(HL) CALL LBYTE CALL HILOX DJNZ DI1 JR DI0 * * * * FILL MEMORY XXXX TO XXXX WITH XX * * * FILL: CP 'F' JR z,fill0 cp 'f' jr nz,goto fill0: CALL EXPR3 FI0: LD (HL),C CALL HILO JR NC,FI0 POP DE Š JR START * * * GOTO (EXECUTE) XXXX * * GOTO: CP 'G' JR Z,goto0 cp 'g' jr nz,mtest goto0: CALL EXPR1 CALL CRLF POP HL JP (HL) * * * TEST MEMORY XXXX TO XXXX * * MTEST: CP 'T' JR Z,t10 cp 't' jr nz,move t10: CALL EXLF T1: LD A,(HL) LD B,A CPL LD (HL),A XOR (HL) JR Z,T2 PUSH DE LD E,A CALL HLSP CALL QI1 CALL CRLF POP DE T2: LD (HL),B CALL HILOX JR T1 * * * MOVE DATA FROM XXXX TO XXXX * * MOVE: CP 'M' JR Z,mvo0 cp 'm' jr nz,subs mvo0: CALL EXPR3 MV0: LD A,(HL) LD (BC),A INC BC CALL HILOX JR MV0 STORE: LD (IX+00H),A Š INC IX DEC E RET * * * EXAMINE AND/OR REPLACE MEMORY DATA * * SUBS: CP 'S' JR Z,suo0 cp 's' jp nz,hexn suo0: CALL EXPR1 CALL QCHK JP C,ERROR POP HL SU0: LD A,(HL) CALL LBYTE LD C,02DH CALL COPCK RET C JR Z,SU1 PUSH HL LD HL,0 LD C,001H CALL EX1 POP DE POP HL LD (HL),E LD A,B CP 00DH RET Z SU1: INC HL CALL CRLF PUSH HL CALL LADR CALL BLK POP HL JR SU0 * * EXLF: CALL EXPR POP DE POP HL * CR/LF OUTPUT * * CRLF: PUSH HL PUSH BC LD C,0DH CALL cout1 LD C,0AH CALL cout1 POP BC POP HL Š CALL CSTS OR A RET Z * * CHECK FOR CONTROL CHARACTER * * CCHK: CALL con1 AND 07FH CP 013H * CONTROL-S JR Z,CCHK CP 003H * CONTROL-C RET NZ ERROR: CALL MEMSIZ LD DE,ERROR PUSH DE LD C,'?' CALL cout1 JP START HLSP: CALL LADR * * PRINT SPACE CHARACTER * BLK: LD C,020H * ******************************************************** * * * * * Console I/O routines for the Wunderbus I/O. These * * * routines assume that the uart divisor latch has * * * previously set (either on power up or in routine * * * executed before a trap to this routine occurred. * * * The character to output should be in the 'C' reg- * * * ister, the character received is returned in the * * * 'A' register. UCSTS returns with zero flag set * * * when no character is waiting in the UART buffer, * * * or with A = FF if a character is waiting. * * * * * ******************************************************** cout1: call coninit cout2: in a,(lsr) * get uart status and thre jr z,cout2 * loop until tbe ld a,c out (thr),a * output the data to uart ret con1: call coninit con2: in a,(lsr) * get uart status and dr jr z,con2 * wait until receive data available in a,(rbr) * read the uart data register and 07fh * strip parity Š ret csts: call coninit in a,(lsr) * read uart status and dr ret z * return zero set if no character ld a,0ff ret * return a = ff if character waiting coninit: ld a,group1 out (grpctl),a * set up for UART 1 ld a,wls0+wls1+stb out (lcr),a * 8 bit word, 2 bit stop bits ret * CONVERT HEX TO ASCII CONV: AND 00f ADD A,090H DAA ADC A,040H DAA LD C,A RET * * GET PARAMETERS 1,2,OR 3 * EXPR3: INC C CALL EXPR CALL CRLF POP BC POP DE POP HL RET EXPR1: LD C,001H EXPR: LD HL,0 EX0: CALL TI EX1: LD B,A CALL NIBBLE JR C,EX2 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL OR L LD L,A JR EX0 EX2: EX (SP),HL PUSH HL LD A,B CALL QCHK JR NC,EX3 Š DEC C RET Z EX3: JP NZ,ERROR DEC C JR NZ,EXPR RET HILOX: CALL HILO RET NC POP DE RET HILO: INC HL LD A,H OR L SCF RET Z LD A,E SUB L LD A,D SBC A,H RET * * HEXADECIMAL ARITHMETIC * HEXN: CP 'H' JR Z,hexd cp 'h' jr nz,port hexd: CALL EXLF PUSH HL ADD HL,DE CALL HLSP POP HL OR A SBC HL,DE * * CONVERT HL REGISTER TO ASCII * LADR: LD A,H CALL LBYTE LD A,L * * CONVERT A REGISTER TO ASCII * LBYTE: PUSH AF RRCA RRCA RRCA RRCA CALL DBLC POP AF DBLC: CALL CONV JP cout1 * checked MEMSIZ: LD HL,(STACK) Š RET NIBBLE: cp 'a' * is it less than lower case 'a'? jr c,nibok * take jump if so cp 'z'+1 * less than a lower case 'z'? ccf * set carry and return if > 'z' ret c sub ' ' * convert to upper case nibok: SUB 030H RET C cp 017h ccf RET C CP 00AH CCF RET NC SUB 007H CP 00AH RET COPCK: CALL cout1 PCHK: CALL TI * * CHARACTER CHECK * QCHK: CP 020H RET Z CP 02CH RET Z CP 00DH SCF RET Z CCF RET * * ECHO CONSOLE * TI: CALL con1 INC A RET Z DEC A AND 07FH RET Z CP 000H RET Z CP 04EH RET Z CP 06EH RET Z PUSH BC LD C,A CALL ucout1 LD A,C POP BC RET Š * * READ/WRITE TO I/O PORT * PORT: CP 'O' JR Z,QOUT CP 'o' jr z,qout CP 'I' JR Z,in cp 'i' jr z,in JR VERIFY IN: CALL EXPR1 LD C,0AH CALL cout1 POP BC Q0: IN E,(C) QI1: LD B,008H CALL BLK QI2: SLA E LD A,018H ADC A,A LD C,A CALL cout1 DJNZ QI2 RET QOUT: CALL EXPR POP DE POP BC OUT (C),E RET * * * * * VERIFY MEMORY XXXX TO XXXX WITH XXXX * VERIFY: CP 'V' JR Z,ver0 cp 'v' jr nz,retrn ver0: call expr3 VERIO: LD A,(BC) CP (HL) JR Z,U..B PUSH BC CALL CERR POP BC U..B: INC BC CALL HILOX JR VERIO Š * Return to task which just trapped with old pc and registers restored retrn: cp 'C' jr z,retr1 cp 'c' jr nz,contr retr1: ld a,(ctask) call tskbase ld de,mskofst add hl,de ld a,(hl) or 08 ld (hl),a jp otask * Return to trapped task, execute next instruction and trap back contr: cp 'U' jr z,cont1 cp 'u' jr nz,boot cont1: ld a,(ctask) call tskbase ld de,mskofst add hl,de ld a,(hl) and 0f6 * force mask for stop and run enble low ld (hl),a jp otask * Jump to the cpu switch address into task specified by CTASK boot: cp 'B' jr z,boot1 cp 'b' jp nz,error boot1: ld a,(ctask) call tskbase push hl ld a,(switch) and 0f8 cp 0 * check for a HDCA hard disk boot jp z,boot2 cp 08 * check for DMA hard disk boot jp z,boot2 cp 010 * check for DJ-DMA jp z,boot2 ld de,pcofst add hl,de ld (hl),0 inc hl ld (hl),a boot2: ld a,(cmask) Š pop hl ld de,mskofst add hl,de ld (hl),a jp oldtask * MEMORY MISMATCH PRINTOUT * CERR: LD B,A CALL HLSP LD A,(HL) CALL LBYTE CALL BLK LD A,B CALL LBYTE JP CRLF .end