; master-luke.asm 2/17/2013 dwg - doug's version derived from david's version ; Now includes BTROMWBW.INC (code to boot RomWBW style) Cmd "R" ; ; master-yoda.asm 2/17/2013 dwg - david's version unchanged ; ; monitor.asm This is main monitor program for my system ; ; BELL .EQU 07H SPACE .EQU 20H TAB .EQU 09H CR .EQU 0DH LF .EQU 0AH FF .EQU 0CH ESC .EQU 1BH DELETE .EQU 7FH STARTCPM .EQU 100H ;LOCATION WHERE CPM WILL BE PLACED FOR COLD BOOT ;---------PORT(S) TO SWITCH MASTER/SLAVE(S) Z80PORT .EQU 0D0H ;4 PORTS ON Z80 BOARD FOR MEMORY MANAGEMENT. BCTL .EQU 0A0H ;CHANNEL B CONTROL PORT FOR SCC ACTL .EQU 0A1H ;CHANNEL A CONTROL BDTA .EQU 0A2H ;CHANNEL B DATA ADTA .EQU 0A3H ;CHANNEL A DATA ;-------------- S100Computers IDE HARD DISK CONTROLLER COMMANDS ETC. IDEAport .EQU 030H ;lower 8 bits of IDE interface IDEBport .EQU 031H ;upper 8 bits of IDE interface IDECport .EQU 032H ;control lines for IDE interface IDECtrl .EQU 033H ;8255 configuration port IDEDrivePort .EQU 034H ;To select the 1st or 2nd CF card/drive (Not used with this monitor) IDE_Reset_Delay .EQU 020H ;Time delay for reset/initilization (~60 uS, with 10MHz Z80, 2 I/O wait states) CPM_ADDRESS .EQU 100H ;Will place the CPMLDR.COM Loader here with ;CPMLDR.COM will ALWAYS be on TRK 0,SEC2, (LBA Mode) SEC_COUNT .EQU 12 ;CPMLDR.COM requires (currently) 10, 512 byte sectors ;Add extra just in case RDcfg8255 .EQU 10010010B ;Set 8255 IDECport out, IDEAport/B input WRcfg8255 .EQU 10000000B ;Set all three 8255 ports output ; IDEa0line .EQU 01H ;direct from 8255 to IDE interface IDEa1line .EQU 02H ;direct from 8255 to IDE interface IDEa2line .EQU 04H ;direct from 8255 to IDE interface IDEcs0line .EQU 08H ;inverter between 8255 and IDE interface IDEcs1line .EQU 10H ;inverter between 8255 and IDE interface IDEwrline .EQU 20H ;inverter between 8255 and IDE interface IDErdline .EQU 40H ;inverter between 8255 and IDE interface IDEreset .EQU 80H ;inverter between 8255 and IDE interface ; ;Symbolic constants for the IDE Drive registers, which makes the ;code more readable than always specifying the address pins ; REGdata .EQU 08H ;IDEcs0line REGerr .EQU 09H ;IDEcs0line + IDEa0line REGcnt .EQU 0AH ;IDEcs0line + IDEa1line REGsector .EQU 0BH ;IDEcs0line + IDEa1line + IDEa0line REGcyLSB .EQU 0CH ;IDEcs0line + IDEa2line REGcyMSB .EQU 0DH ;IDEcs0line + IDEa2line + IDEa0line REGshd .EQU 0EH ;IDEcs0line + IDEa2line + IDEa1line ;(0EH) REGCMD .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line ;(0FH) REGstatus .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line REGcontrol .EQU 16H ;IDEcs1line + IDEa2line + IDEa1line REGastatus .EQU 17H ;IDEcs1line + IDEa2line + IDEa1line + IDEa0line ;IDE CMD Constants. These should never change. CMDrecal .EQU 10H CMDread .EQU 20H CMDwrite .EQU 30H CMDinit .EQU 91H CMDid .EQU 0ECH CMDdownspin .EQU 0E0H CMDupspin .EQU 0E1H ; ; IDE Status Register: ; bit 7: Busy 1=busy, 0=not busy ; bit 6: Ready 1=ready for CMD, 0=not ready yet ; bit 5: DF 1=fault occured insIDE drive ; bit 4: DSC 1=seek complete ; bit 3: DRQ 1=data request ready, 0=not ready to xfer yet ; bit 2: CORR 1=correctable error occured ; bit 1: IDX vendor specific ; bit 0: ERR 1=error occured ; .ORG 0F000H JP BEGIN TBL: .DW NOTIMPL ; "@" .DW MEMMAP ; "A" DISPLAY A MAP OF MEMORY .DW NOTIMPL ; "B" .DW NOTIMPL ; "C" .DW DISP ; "D" DISPLAY MEMORY (IN HEX & ASCII) .DW NOTIMPL ; "E" ECHO CHAR IN TO CHAR OUT .DW FILL ; "F" FILL MEMORY WITH A CONSTANT .DW GOTO ; "G" GO TO [ADDRESS] .DW NOTIMPL ; "H" .DW NOTIMPL ; "I" .DW NOTIMPL ; "J" NON-DESTRUCTIVE MEMORY TEST .DW NOTIMPL ; "K" .DW NOTIMPL ; "L" .DW NOTIMPL ; "M" .DW XMEMMAP ; "N" DISPLAY EXTENDED MEMORY SEGEMENT:ADDRESS .DW NOTIMPL ; "O" .DW HBOOTCPM ; "P" BOOT IN CPM FROM IDE HARD DISK" .DW QUERY ; "Q" QUERY PORT (IN OR OUT) .DW HBOOTWBW ; "R" BOOT IN CPM FROM RomWBW HARD DISK .DW SUBS ; "S" SUBSTITUTE &/OR EXAMINE MEMORY .DW NOTIMPL ; "T" .DW NOTIMPL ; "U" .DW NOTIMPL ; "V" COMPARE MEMORY .DW NOTIMPL ; "X" .DW NOTIMPL ; "Y" .DW NOTIMPL ; "Z" SCCINIT: .DB 04H ;Point to WR4 .DB 44H ;X16 clock,1 Stop,NP ; .DB 03H ;Point to WR3 .DB 0C1H ;Enable reciever, Auto Enable, Recieve 8 bits ; .DB 0E1H ;Enable reciever, No Auto Enable, Recieve 8 bits (for CTS bit) ; .DB 05H ;Point to WR5 .DB 0EAH ;Enable, Transmit 8 bits ; ;Set RTS,DTR, Enable ; .DB 0BH ;Point to WR11 .DB 56H ;Recieve/transmit clock = BRG ; .DB 0CH ;Point to WR12 ; .DB 40H ;Low Byte 2400 Baud ; .DB 1EH ;Low Byte 4800 Baud ; .DB 0EH ;Low Byte 9600 Baud .DB 06H ;Low byte 19,200 Baud ; .DB 02H ;Low byte 38,400 Baud <<<<<<<<<<< ; .DB 00H ;Low byte 76,800 Baud ; .DB 0DH ;Point to WR13 .DB 00H ;High byte for Baud .DB 0EH ;Point to WR14 .DB 01H ;Use 4.9152 MHz Clock. Note SD Systems uses a 2.4576 MHz clock, enable BRG ; .DB 0FH ;Point to WR15 .DB 00H ;Generate Int with CTS going high .DB 00H .DB 00H .DB 00H .DB 00H .DB 00H ; ; BEGIN OF CODE ----------------------------------------------------------------------- BEGIN: LD A,0FFH XOR A OUT (Z80PORT+1),A LD A,0H OUT (Z80PORT+2),A LD A,04H OUT (Z80PORT+3),A LD A,ACTL LD C,A LD B,$0E LD HL,SCCINIT OTIR LD A,BCTL LD C,A LD B,$0E LD HL,SCCINIT OTIR ZAXXLE: LD SP,AHEAD-4 ;SETUP FAKE STACK FRAME JP MEMSZ1 ;RETURNS WITH TOP OF RAM IN [HL] .DW AHEAD ;RETURN WILL PICK UP THIS ADDRESS AHEAD: LD SP,HL ;[HL] CONTAINS TOP OF RAM PUSH HL POP IX ;SAVE STACK POINTER IN IX FOR FUTURE USE LD HL,MSG0 CALL ZPMSG LD HL,SP_MSG ;PRINT CURRENT STACK LOCATION CALL ZPMSG PUSH IX ;SP IS STORED HERE FROM ABOVE POP HL CALL HLSP ;PRINT HL/SP CALL CRLF ;THEN CRLF START: LD DE,START PUSH DE ;EXTRA UNBALANCED POP & [DE] WOULD END UP IN [PC] CALL CRLF LD C,BELL ;A BELL HERE WILL SIGNAL WHEN JOBS ARE DONE CALL CO LD C,'-' CALL CO LD C,'>' CALL CO STAR0: ;MAIN LOOP. MONITOR WILL STAY HERE UNTIL CMD. CALL TI AND 7FH JR Z,STAR0 SUB '@' ;COMMANDS @ TO Z ONLY RET M CP 1BH ;A-Z ONLY RET NC ADD A,A LD HL,TBL ADD A,L LD L,A LD A,(HL) INC HL LD H,(HL) LD L,A LD C,02H JP (HL) ;JUMP TO COMMAND TABLE MSG0: .DB "Z80 ROM MONITOR V1.0 (David Mehaffy 12/24/2011) $" SP_MSG .DB CR,LF,"SP=$" ZPMSG: LD A,(HL) ;A ROUTINE TO PRINT OUT A STRING @ [HL] INC HL ;UP TO THE FIRST '$' CP '$' RET Z LD C,A CALL CO JR ZPMSG ;THIS IS A CALLED ROUTINE USED TO CALCULATE TOP OF RAM IS USED BY ;THE ERROR TO RESET THE STACK. Returns top of RAM in [HL] MEMSIZ: PUSH BC ;SAVE [BC] MEMSZ1: LD HL,0FFFFH ;START FROM THE TOP DOWN MEMSZ2: LD A,(HL) CPL LD (HL),A CP (HL) CPL ;PUT BACK WHAT WAS THERE LD (HL),A JP Z,GOTTOP DEC H ;TRY 100H BYTES LOWER JR MEMSZ2 ;KEEP LOOKING FOR RAM GOTTOP: POP BC ;RESTORE [BC] RET ;ABORT IF ESC AT CONSOL, PAUSE IF ^S AT CONSOL CCHK: CALL CSTS ;FIRST IS THERE ANYTHING THERE RET Z CALL CI CP 'S'-40H JR NZ,CCHK1 CCHK2: CALL CSTS ;WAIT HERE UNTIL ANOTHER INPUT IS GIVEN JR Z,CCHK2 CCHK1: CP ESC RET NZ ;RETURN EXECPT IF ESC ;RESTORE SYSTEM AFTER ERROR ERROR: CALL MEMSIZ ;GET RAM AVAILABLE - WORKSPACE IN [HL] LD SP,HL ;SET STACK UP IN WORKSPACE AREA LD C,'*' CALL CO JP START ;PRINT HIGHEST MEMORY FROM BOTTOM SIZE: CALL MEMSIZ ;RETURNS WITH [HL]= RAM AVAILABLE-WORKSPACE LFADR: CALL CRLF ;PRINT [HL] AND A SPACE HLSP: PUSH HL PUSH BC CALL LADR LD C,SPACE CALL CO POP BC POP HL RET ;PRINT A SPACE SF488: LD C,SPACE JP CO ;CONVERT HEX TO ASCII CONV: AND 0FH ADD A,90H DAA ADC A,40H DAA LD C,A RET ;GET TWO PARAMETERS AND PUT THEM IN [HL] & [DE] THEN CRLF EXLF: CALL HEXSP POP DE POP HL CRLF: PUSH BC LD C,LF CALL CO LD C,CR CALL CO POP BC RET ;PUT THREE PARAMETERS IN [BC] [DE] [HL] THEN CR/LF EXPR3: INC C ;ALREADY HAD [C]=2 FROM START CALL HEXSP CALL CRLF POP BC POP DE POP HL RET ;GET ONE PARAMETER EXPR1: LD C,01H HEXSP: LD HL,0000 EX0: CALL TI EX1: LD B,A CALL NIBBLE JR C,EX2X ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL OR L LD L,A JR EX0 EX2X: EX (SP),HL PUSH HL LD A,B CALL QCHK JR NC,SF560 DEC C RET Z SF560: JP NZ,ERROR DEC C JR NZ,HEXSP RET EXF: LD C,01H LD HL,0000H JR EX1 ;RANGE TEST ROUTINE CARRY SET = RANGE EXCEEDED HILOX: CALL CCHK CALL HILO RET NC POP DE ;DROP ONE LEVEL BACK TO START RET HILO: INC HL ;RANGE CHECK SET CARRY IF [DE]=[HL] LD A,H OR L SCF RET Z LD A,E SUB L LD A,D SBC A,H RET ; PRINT [HL] ON CONSOLE LADR: LD A,H CALL LBYTE LD A,L LBYTE: PUSH AF RRCA RRCA RRCA RRCA CALL SF598 POP AF SF598: CALL CONV JP CO NIBBLE: SUB 30H RET C CP 17H CCF RET C CP LF CCF RET NC SUB 07H CP LF RET COPCK: LD C,'-' CALL CO PCHK: CALL TI ;TEST FOR DELIMITERS QCHK: CP SPACE RET Z CP ',' RET Z CP CR SCF RET Z CCF RET ;KEYBOARD HANDLING ROUTINTE (WILL NOT ECHO CR/LF) ;IT CONVERTS LOWER CASE TO UPPERCASE FOR LOOKUP COMMANDS ;ALSO ^C WILL FOR A JUMP TO BOOT TO CP/M ;ALL OTHER CHARACTERS ARE ECHOED ON CONSOLE TI: CALL CI CP CR RET Z CP 'C' - 40H ;^C TO BOOT TO CP/M JP Z,FBOOT PUSH BC LD C,A CALL CO LD A,C POP BC CP 40H ;LC-.UC RET C CP 7BH RET NC SF574: AND 5FH RET BITS1: PUSH DE ;DISPLAY 8 BITS OF [A] PUSH BC LD E,A CALL BITS POP BC POP DE RET BITS: LD B,08H ;DISPLAY 8 BITS OF [E] CALL SF488 SF76E: SLA E LD A,18H ADC A,A LD C,A CALL CO DJNZ SF76E RET ;<<<<<<<<<<<<<<<< MAIN CONSOLE ROUTINES <<<<<<<<<<<<< CO: IN A,(ACTL) AND 04H ;ARE WE READY FOR A CHARACTER JR Z,CO LD A,C OUT (ADTA),A RET CI: IN A,(ACTL) AND 01H JR Z,CI IN A,(ADTA) RET CSTS: IN A,(ACTL) AND 01H RET Z ;RETURN Z IF NOTHING LD A,0FFH XOR A ;RETURN FF / NZ IF SOMETHING RET ;-------------- BOOT UP CPM FROM HARD DISK ON S100COMPUTERS IDR BOARD ---------------- ;BOOT UP THE 8255/IDE Board HARD DISK/Flash Memory Card ;NOTE CODE IS ALL HERE IN CASE A 2716 IS USED HBOOTCPM: POP HL ;CLEAN UP STACK CALL INITILIZE_IDE_BOARD ;Initilze the 8255 and drive (again just in case) LD D,11100000B ;Data for IDE SDH reg (512bytes, LBA mode,single drive) LD E,REGshd ;00001110,(0EH) CS0,A2,A1, CALL IDEwr8D ;Write byte to select the MASTER device LD B,0FFH ;Delay time to allow a Hard Disk to get up to speed WaitInit: LD E,REGstatus ;Get status after initilization CALL IDErd8D ;Check Status (info in [D]) BIT 7,D JR Z,SECREAD ;Zero, so all is OK to write to drive ;Delay to allow drive to get up to speed PUSH BC LD BC,0FFFFH DXLAY2: LD D,2 ;May need to adjust delay time to allow cold drive to DXLAY1: DEC D ;to speed JR NZ,DXLAY1 DEC BC LD A,C OR B JR NZ,DXLAY2 POP BC DJNZ WaitInit ;If after 0FFH, 0FEH, 0FDH... 0, then drive initilization problem IDError: LD HL,DRIVE_NR_ERR ;Drive not ready JP ABORT_ERR_MSG SECREAD: ;Note CPMLDR will ALWAYS be on TRK 0,SEC 1,Head 0 CALL IDEwaitnotbusy ;Make sure drive is ready JR C,IDError ;NC if ready LD D,1 ;Load track 0,sec 1, head 0 LD E,REGsector ;Send info to drive CALL IDEwr8D LD D,0 ;Send Low TRK# LD E,REGcyLSB CALL IDEwr8D LD D,0 ;Send High TRK# LD E,REGcyMSB CALL IDEwr8D LD D,SEC_COUNT ;Count of CPM sectors we wish to read LD E,REGcnt CALL IDEwr8D LD D,CMDread ;Send read CMD LD E,REGCMD CALL IDEwr8D ;Send sec read CMD to drive. CALL IDEwdrq ;Wait until it's got the data LD HL,CPM_ADDRESS ;DMA address where the CPMLDR resides in RAM LD B,0 ;256X2 bytes LD C,SEC_COUNT ;Count of sectors X 512 MoreRD16: LD A,REGdata ;REG regsiter address OUT (IDECport),A OR IDErdline ;08H+40H, Pulse RD line OUT (IDECport),A IN A,(IDEAport) ;read the LOWER byte LD (HL),A INC HL IN A,(IDEBport) ;read the UPPER byte LD (HL),A INC HL LD A,REGdata ;Deassert RD line OUT (IDECport),A DJNZ MoreRD16 DEC C JR NZ,MoreRD16 LD E,REGstatus ;Check the R/W status when done CALL IDErd8D BIT 0,D JR NZ,IDEerr1 ;Z if no errors LD HL,STARTCPM LD A,(HL) CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H JP Z,STARTCPM ;AS THE FIRST INSTRUCTION. IF OK JP to 100H in RAM JP ERR_LD1 ;Boot Sector Data incorrect IDEerr1: LD HL,IDE_RW_ERROR ;Drive R/W Error JP ABORT_ERR_MSG ; ----- SUPPORT ROUTINES -------------- INITILIZE_IDE_BOARD: ;Drive Select in [A]. Note leaves selected drive as [A] LD A,RDcfg8255 ;Config 8255 chip (10010010B), read mode on return OUT (IDECtrl),A ;Config 8255 chip, READ mode ;Hard reset the disk drive ;For some reason some CF cards need to the RESET line ;pulsed very carefully. You may need to play around LD A,IDEreset ;with the pulse length. Symptoms are: incorrect data comming OUT (IDECport),A ;back from a sector read (often due to the wrong sector being read) ;I have a (negative)pulse of 60 uSec. (10Mz Z80, two IO wait states). LD C,IDE_Reset_Delay ;~60 uS seems to work for the 5 different CF cards I have ResetDelay: DEC C JP NZ,ResetDelay ;Delay (reset pulse width) XOR A OUT (IDECport),A ;No IDE control lines asserted (just bit 7 of port C) CALL DELAY_15 ;Need to delay a little before checking busy status IDEwaitnotbusy: ;Drive READY if 01000000 LD B,0FFH LD C,080H ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives MoreWait: LD E,REGstatus ;Wait for RDY bit to be set CALL IDErd8D LD A,D AND 11000000B XOR 01000000B JR Z,DoneNotBusy DJNZ MoreWait DEC C JR NZ,MoreWait SCF ;Set carry to indicate an error RET DoneNotBusy: OR A ;Clear carry it indicate no error RET ;Wait for the drive to be ready to transfer data. IDEwdrq: ;Returns the drive's status in Acc LD B,0FFH LD C,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives MoreDRQ: LD E,REGstatus ;wait for DRQ bit to be set CALL IDErd8D LD A,D AND 10001000B CP 00001000B JR Z,DoneDRQ DJNZ MoreDRQ DEC C JR NZ,MoreDRQ SCF ;Set carry to indicate error RET DoneDRQ: OR A ;Clear carry RET ; ;------------------------------------------------------------------ ; Low Level 8 bit R/W to the drive controller. These are the routines that talk ; directly to the drive controller registers, via the 8255 chip. ; Note the 16 bit I/O to the drive (which is only for SEC Read here) is done directly ; in the routine MoreRD16 for speed reasons. IDErd8D: ;READ 8 bits from IDE register in [E], return info in [D] LD A,E OUT (IDECport),A ;drive address onto control lines OR IDErdline ;RD pulse pin (40H) OUT (IDECport),A ;assert read pin IN A,(IDEAport) LD D,A ;return with data in [D] LD A,E ;<---Ken Robbins suggestion OUT (IDECport),A ;Deassert RD pin XOR A OUT (IDECport),A ;Zero all port C lines RET IDEwr8D: ;WRITE Data in [D] to IDE register in [E] LD A,WRcfg8255 ;Set 8255 to write mode OUT (IDECtrl),A LD A,D ;Get data put it in 8255 A port OUT (IDEAport),A LD A,E ;select IDE register OUT (IDECport),A OR IDEwrline ;lower WR line OUT (IDECport),A LD A,E ;<-- Kens Robbins suggestion, raise WR line OUT (IDECport),A XOR A ;Deselect all lines including WR line OUT (IDECport),A LD A,RDcfg8255 ;Config 8255 chip, read mode on return OUT (IDECtrl),A RET ERR_NR: LD HL,DRIVE_NR_ERR ;"DRIVE NOT READY JP ABORT_ERR_MSG ERR_LD: LD HL,BOOT_LD_ERR ;"ERROR READING BOOT/LOADER SECTORS" JP ABORT_ERR_MSG ERR_LD1:LD HL,BOOT_LD1_ERR ;"DATA ERROR IN BOOT SECTOR" ABORT_ERR_MSG: CALL ZPMSG JP BEGIN ;BACK TO START OF MONITOR. DELAY_15: ;DELAY ~15 MS LD A,40 DELAY1: LD B,0 M0: DJNZ M0 DEC A JR NZ,DELAY1 RET #INCLUDE "BTROMWBW.INC" ;--------------------------------------------------------------- ;MEMORY MAP PROGRAM CF.DR.DOBBS VOL 31 P40. ;IT WILL SHOW ON CONSOLE TOTAL MEMORY SUMMARY OF RAM, PROM, AND NO MEMORY MEMMAP: CALL CRLF LD HL,0 LD B,1 MAP1: LD E,'R' ;PRINT R FOR RAM LD A,(HL) CPL LD (HL),A CP (HL) CPL LD (HL),A JR NZ,MAP2 CP (HL) JR Z,PRINT MAP2: LD E,'p' MAP3: LD A,0FFH CP (HL) JR NZ,PRINT INC L XOR A CP L JR NZ,MAP3 LD E,'.' PRINT: LD L,0 DEC B JR NZ,NLINE LD B,16 CALL CRLF CALL HXOT4 NLINE: LD A,SPACE CALL OTA LD A,E CALL OTA INC H JR NZ,MAP1 CALL CRLF CALL CRLF JP START ;16 HEX OUTPUT ROUTINE HXOT4: LD C,H CALL HXO2 LD C,L HXO2: LD A,C RRA RRA RRA RRA CALL HXO3 LD A,C HXO3: AND 0FH CP 10 JR C,HADJ ADD A,7 HADJ: ADD A,30H OTA: PUSH BC LD C,A CALL CO POP BC RET ;DISPLAY MEMORY IN HEX DISP: CALL EXLF ;GET PARAMETERS IN [HL],[DE] LD A,L ;ROUND OFF ADDRESSES TO XX00H AND 0F0H LD L,A LD A,E ;FINAL ADDRESS LOWER HALF AND 0F0H ADD A,10H ;FINISH TO END 0F LINE SF172: CALL LFADR SF175: CALL BLANK LD A,(HL) CALL LBYTE CALL HILOX LD A,L AND 0FH JR NZ,SF175 LD C,TAB ;INSERT A TAB BETWEEN DATA CALL CO LD B,4H ;ALSO 4 SPACES TA11: LD C,SPACE CALL CO DJNZ TA11 LD B,16 ;NOW PRINT ASCII (16 CHARACTERS) PUSH DE ;TEMPORLY SAVE [DE] LD DE,0010H SBC HL,DE POP DE T11: LD A,(HL) AND 7FH CP ' ' ;FILTER OUT CONTROL CHARACTERS' JR NC,T33 T22: LD A,'.' T33: CP 07CH JR NC,T22 LD C,A ;SET UP TO SEND CALL CO INC HL DJNZ T11 ;REPEAT FOR WHOLE LINE JR SF172 BLANK: LD C,' ' JP CO ;INSPECT AND / OR MODIFY MEMORY SUBS: LD C,1 CALL HEXSP POP HL SF2E3: LD A,(HL) CALL LBYTE LD C,'-' CALL CO CALL PCHK RET C JR Z,SF2FC CP 5FH JR Z,SF305 PUSH HL CALL EXF POP DE POP HL LD (HL),E LD A,B CP CR RET Z SF2FC: INC HL SF2FD: LD A,L AND 07H CALL Z,LFADR JR SF2E3 SF305: DEC HL JR SF2FD ;FILL A BLOCK OF MEMORY WITH A VALUE FILL: CALL EXPR3 SF1A5: LD (HL),C CALL HILOX JR NC,SF1A5 POP DE JP START ;GO TO A RAM LOCATION GOTO: LD C,1 ;SIMPLE GOTO FIRST GET PARMS. CALL HEXSP CALL CRLF POP HL ;GET PARAMETER PUSHED BY EXF JP (HL) ; GET OR OUTPUT TO A PORT QUERY: CALL PCHK CP 'O' ;OUTPUT TO PORT JR Z,SF77A CP 'I' ;INPUT FROM PORT JP Z,QQQ1 LD C,'*' JP CO ;WILL ABORT IF NOT 'I' OR 'O' QQQ1: LD C,1 CALL HEXSP POP BC IN A,(C) JP BITS ; SF77A: CALL HEXSP POP DE POP BC OUT (C),E RET ;Display Extended memory map for 1MG RAM using IA-2 Z80 Board window registers XMEMMAP: LD HL,MSG17 ;Get segment (0-F) CALL ZPMSG LD C,1 CALL HEXSP ;Get 2 or 4 hex digits (count in C). POP HL LD A,L ;Get single byte value AND 0FH EXX LD D,A ;Store in D' for 000X:YYYY display below SLA A SLA A SLA A SLA A OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space LD E,A ;store shifted nibble in E' LD HL,0 ;Will store 0-FFFF for total RAM display (not actual access) EXX LD D,0 ;Total display line count (256 characters, 16lines X 16 characters) CALL CRLF LD HL,0 LD B,1 XMAP1: LD A,H AND 00111111B ;Wrap 16K window LD H,A LD E,'R' ;PRINT R FOR RAM LD A,(HL) CPL LD (HL),A CP (HL) CPL LD (HL),A ;Save it back JR NZ,XMAP2 CP (HL) JR Z,XPRINT XMAP2: LD E,'p' XMAP3: LD A,0FFH CP (HL) JR NZ,XPRINT INC L XOR A CP L JR NZ,XMAP3 LD E,'.' XPRINT: LD L,0 DEC B JR NZ,XNLINE LD B,16 CALL CRLF CALL SET_WINDOW LD A,SPACE JR XN11 XNLINE: LD A,SPACE CALL OTA LD A,E XN11: CALL OTA INC H INC D ;Are we done yet JR NZ,XMAP1 CALL CRLF XOR A OUT (Z80PORT+2),A ;Set RAM window back to the way it was JP START SET_WINDOW: ;Setup the unique IA-II Z80 board window to address > 64k EXX LD C,D ;Print seg value CALL HXO2 LD C,':' CALL CO CALL HXOT4 ;Print HL' (not origional HL) LD A,H ;get current H being displayed (Already pointed to first 16K window) NOTW0: CP 40H JR NZ,NOTW1 LD A,E ADD A,04H ;Window for 4,5,6,7, set to H from above JR DOWIN NOTW1: CP 80H JR NZ,NOTW2 LD A,E ADD A,08H ;Window for 8,9,A,B set to H from above JR DOWIN NOTW2: CP 0C0H JR NZ,NOTW3 ;Must be values in between LD A,E ADD A,0CH ;Window for 4,5,6,7, set to H from above DOWIN: OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space NOTW3: LD A,H ADD A,10H LD H,A EXX ;Get back normal register set RET NOTIMPL: RET FBOOT: RET DRIVE_NR_ERR: .DB BELL,CR,LF .DB "Drive not Ready.",CR,LF,LF,'$' RESTORE_ERR: .DB BELL,CR,LF .DB "Restore Failed.",CR,LF,LF,'$' BOOT_LD_ERR: .DB BELL,CR,LF .DB "Read Error.",CR,LF,LF,'$' SEEK_ERROR_MSG: .DB BELL,CR,LF .DB "Seek Error.",CR,LF,LF,'$' BOOT_LD1_ERR: .DB BELL,CR,LF .DB "BOOT error.",CR,LF,LF,'$' IDE_RW_ERROR: .DB CR,LF .DB "IDE Drive R/W Error" .DB CR,LF,'$' MSG17: .DB CR,LF .DB "Segement (0-F):$" .END