diff --git a/Source/Apps/Build.cmd b/Source/Apps/Build.cmd index ee85be71..95411144 100644 --- a/Source/Apps/Build.cmd +++ b/Source/Apps/Build.cmd @@ -34,6 +34,7 @@ setlocal & cd FDU && call Build || exit /b 1 & endlocal setlocal & cd Tune && call Build || exit /b 1 & endlocal setlocal & cd FAT && call Build || exit /b 1 & endlocal setlocal & cd I2C && call Build || exit /b 1 & endlocal +setlocal & cd ramtest && call Build || exit /b 1 & endlocal copy *.com %APPBIN%\ diff --git a/Source/Apps/Clean.cmd b/Source/Apps/Clean.cmd index 36424e12..04a056ee 100644 --- a/Source/Apps/Clean.cmd +++ b/Source/Apps/Clean.cmd @@ -12,3 +12,4 @@ setlocal & cd FDU && call Clean || exit /b 1 & endlocal setlocal & cd Tune && call Clean || exit /b 1 & endlocal setlocal & cd FAT && call Clean || exit /b 1 & endlocal setlocal & cd I2C && call Clean || exit /b 1 & endlocal +setlocal & cd ramtest && call Clean || exit /b 1 & endlocal diff --git a/Source/Apps/Makefile b/Source/Apps/Makefile index 322bb6cc..cbcd6675 100644 --- a/Source/Apps/Makefile +++ b/Source/Apps/Makefile @@ -2,7 +2,7 @@ OBJECTS = sysgen.com survey.com \ syscopy.com assign.com format.com talk.com mode.com rtc.com \ timer.com inttest.com rtchb.com ppidetst.com tstdskng.com OTHERS = *.hex *.com -SUBDIRS = XM FDU FAT Tune I2C +SUBDIRS = XM FDU FAT Tune I2C ramtest DEST = ../../Binary/Apps TOOLS =../../Tools diff --git a/Source/Apps/ramtest/Build.cmd b/Source/Apps/ramtest/Build.cmd new file mode 100644 index 00000000..f62f9c6f --- /dev/null +++ b/Source/Apps/ramtest/Build.cmd @@ -0,0 +1,15 @@ +@echo off +setlocal + +set TOOLS=../../../Tools +set PATH=%TOOLS%\tasm32;%PATH% +set TASMTABS=%TOOLS%\tasm32 + +tasm -t80 -b -fFF loader.asm loader.bin loader.lst +tasm -t80 -b -fFF dbgmon.asm dbgmon.bin dbgmon.lst + +copy /Y /b loader.bin+dbgmon.bin ramtest.com + +if errorlevel 1 goto :eof + +copy /Y ramtest.com ..\..\..\Binary\Apps\ diff --git a/Source/Apps/ramtest/Clean.cmd b/Source/Apps/ramtest/Clean.cmd new file mode 100644 index 00000000..60b882d0 --- /dev/null +++ b/Source/Apps/ramtest/Clean.cmd @@ -0,0 +1,6 @@ +@echo off +setlocal + +if exist *.com del *.com +if exist *.bin del *.bin +if exist *.lst del *.lst diff --git a/Source/Apps/ramtest/Makefile b/Source/Apps/ramtest/Makefile new file mode 100644 index 00000000..f99ee0bc --- /dev/null +++ b/Source/Apps/ramtest/Makefile @@ -0,0 +1,10 @@ +OBJECTS = ramtest.com +DEST = ../../../Binary/Apps +DOCDEST = ../../../Doc +TOOLS = ../../../Tools +OTHERS = loader.bin dbgmon.bin +include $(TOOLS)/Makefile.inc + +ramtest.com: loader.bin dbgmon.bin + cat loader.bin dbgmon.bin >ramtest.com + diff --git a/Source/Apps/ramtest/dbgmon.asm b/Source/Apps/ramtest/dbgmon.asm new file mode 100644 index 00000000..393fafd5 --- /dev/null +++ b/Source/Apps/ramtest/dbgmon.asm @@ -0,0 +1,1213 @@ +;___RAM_TEST_PROGRAM_____________________________________________________________________________________________________________ +; +; ORIGINAL CODE BY: ANDREW LYNCH (LYNCHAJ@YAHOO COM) 17 JUL 2021 +; +; HELP FROM WAYNE WARTHEN +; +;__REFERENCES________________________________________________________________________________________________________________________ +; THOMAS SCHERRER BASIC HARDWARE TEST ASSEMBLER SOURCES FROM THE Z80 INFO PAGE +; INCLUDING ORIGINAL SCHEMATIC CONCEPT +; HTTP://Z80 INFO/Z80SOURC.TXT +; CODE SAMPLES FROM BRUCE JONES PUBLIC DOMAIN ROM MONITOR FOR THE SBC-200C +; HTTP://WWW RETROTECHNOLOGY.COM/HERBS_STUFF/SD_BRUCE_CODE.ZIP +; INSPIRATION FROM JOEL OWENS "Z-80 SPACE-TIME PRODUCTIONS SINGLE BOARD COMPUTER" +; HTTP://WWW JOELOWENSORG/Z80/Z80INDEX.HTML +; GREAT HELP AND TECHNICAL ADVICE FROM ALLISON AT ALPACA_DESIGNERS +; HTTP://GROUPS YAHOO.COM/GROUP/ALPACA_DESIGNERS +; INTEL SDK-85 ROM DEBUG MONITOR +; +;__HARDWARE_INTERFACES________________________________________________________________________________________________________________ +; +; PIO 82C55 I/O IS DECODED TO PORT 60-67 +; +PORTA: .EQU 60H +PORTB: .EQU 61H +PORTC: .EQU 62H +PIOCONT: .EQU 63H +; +; UART 16C450 SERIAL IS DECODED TO 68-6F +; +UART0: .EQU 68H ; DATA IN/OUT +UART1: .EQU 69H ; CHECK RX +UART2: .EQU 6AH ; INTERRUPTS +UART3: .EQU 6BH ; LINE CONTROL +UART4: .EQU 6CH ; MODEM CONTROL +UART5: .EQU 6DH ; LINE STATUS +UART6: .EQU 6EH ; MODEM STATUS +UART7: .EQU 6FH ; SCRATCH REG. +; +; MEMORY PAGE CONFIGURATION LATCH IS DECODED TO 7CH +; +MPCL_ROM: .EQU 7CH ; CONTROL PORT, SHOULD ONLY BE CHANGED WHILE +; IN UPPER MEMORY PAGE 08000h-$FFFF OR LIKELY +; LOSS OF CPU MEMORY CONTEXT +; +; ROM MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3 ) INFORMATION +; +; 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE 00000h-$7FFF +; ^ ^ ^ ^ ^ ^ ^ ^ +; : : : : : : : :--0 = A15 ROM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : : : : :----0 = A16 ROM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : : : :------0 = A17 ROM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : : :--------0 = A18 ROM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : :-----------0 = A19 ROM ONLY ADDRESS LINE DEFAULT IS 0 +; : : :-------------0 = A20 ROM ONLY ADDRESS LINE DEFAULT IS 0 +; : :---------------0 = ROM BOOT OVERRIDE DEFAULT IS 0 +; :-----------------0 = LOWER PAGE ROM SELECT (0=ROM, 1=NOTHING) DEFAULT IS 0 +; +; MEMORY PAGE CONFIGURATION LATCH IS DECODED TO 78H +; +MPCL_RAM: .EQU 78H ; CONTROL PORT, SHOULD ONLY BE CHANGED WHILE +; IN UPPER MEMORY PAGE 08000h-$FFFF OR LIKELY +; LOSS OF CPU MEMORY CONTEXT +; +; MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y1 ) INFORMATION +; +; 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE 00000h-$7FFF +; ^ ^ ^ ^ ^ ^ ^ ^ +; : : : : : : : :--0 = A15 RAM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : : : : :----0 = A16 RAM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : : : :------0 = A17 RAM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : : :--------0 = A18 RAM ONLY ADDRESS LINE DEFAULT IS 0 +; : : : :-----------0 = A19 RAM ONLY ADDRESS LINE DEFAULT IS 0 +; : : :-------------0 = UNDEFINED DEFAULT IS 0 +; : :---------------0 = RAM BOOT OVERRIDE DEFAULT IS 0 +; :-----------------0 = LOWER PAGE RAM SELECT (0=NOTHING, 1=RAM) DEFAULT IS 0; +; +;; +; +;__CONSTANTS_________________________________________________________________________________________________________________________ +; +RAMTOP: .EQU 0FFFFh ; HIGHEST ADDRESSABLE MEMORY LOCATION +STACKSTART: .EQU 0CFFFh ; START OF STACK +RAMBOTTOM: .EQU 08000h ; START OF FIXED UPPER 32K PAGE OF 512KB X 8 RAM 8000H-FFFFH +MONSTARTCOLD: .EQU 08000h ; COLD START MONITOR IN HIGH RAM +ENDT: .EQU 0FFh ; MARK END OF TEXT +CR: .EQU 0DH ; ASCII CARRIAGE RETURN CHARACTER +LF: .EQU 0AH ; ASCII LINE FEED CHARACTER +ESC: .EQU 1BH ; ASCII ESCAPE CHARACTER +BS: .EQU 08H ; ASCII BACKSPACE CHARACTER +; + + + +; +; +;__MAIN_PROGRAM_____________________________________________________________________________________________________________________ +; + .ORG 8000H ; NORMAL OP + + + + +;__MONSTARTWARM___________________________________________________________________________________________________________________ +; +; SERIAL MONITOR STARTUP +;________________________________________________________________________________________________________________________________ +; + +MONSTARTWARM: ; CALL HERE FOR SERIAL MONITOR WARM START + LD SP,STACKSTART ; SET THE STACK POINTER TO STACKSTART + CALL INITIALIZE ; INITIALIZE SYSTEM + + XOR A ;ZERO OUT ACCUMULATOR (ADDED) + PUSH HL ;PROTECT HL FROM OVERWRITE + LD HL,TXT_READY ;POINT AT TEXT + CALL MSG ;SHOW WE'RE HERE + POP HL ;PROTECT HL FROM OVERWRITE + +; +;__SERIAL_MONITOR_COMMANDS_________________________________________________________________________________________________________ +; +; A RAM TEST LOWER 32KB RAM PAGE +; B XX BOOT CPM FROM DRIVE XX +; D XXXXH YYYYH DUMP MEMORY FROM XXXX TO YYYY +; F XXXXH YYYYH ZZH FILL MEMORY FROM XXXX TO YYYY WITH ZZ +; H LOAD INTEL HEX FORMAT DATA +; I INPUT FROM PORT AND SHOW HEX DATA +; K ECHO KEYBOARD INPUT +; M XXXXH YYYYH ZZZZH MOVE MEMORY BLOCK XXXX TO YYYY TO ZZZZ +; O OUTPUT TO PORT HEX DATA +; P XXXXH YYH PROGRAM RAM FROM XXXXH WITH VALUE IN YYH, WILL PROMPT FOR NEXT LINES FOLLOWING UNTIL CR +; R RUN A PROGRAM FROM CURRENT LOCATION + + + +;__COMMAND_PARSE_________________________________________________________________________________________________________________ +; +; PROMPT USER FOR COMMANDS, THEN PARSE THEM +;________________________________________________________________________________________________________________________________ +; + +SERIALCMDLOOP: + LD HL,TXT_MAIN_MENU ; POINT AT MAIN MENU TEXT + CALL MSG ; PRINT COMMAND LABEL + CALL CRLFA ; CR,LF,> + LD HL,KEYBUF ; SET POINTER TO KEYBUF AREA + CALL GETLN ; GET A LINE OF INPUT FROM THE USER + LD HL,KEYBUF ; RESET POINTER TO START OF KEYBUF + LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND) + INC HL ; INC POINTER + + CP 'A' ; IS IT "A" (Y/N) + JP Z,DORAMTEST ; IF YES DO RAM TEST + CP 'B' ; IS IT "B" (Y/N) + JP Z,DOBOOT ; IF YES DO BOOT + CP 'R' ; IS IT "R" (Y/N) + JP Z,RUN ; IF YES GO RUN ROUTINE + CP 'P' ; IS IT "P" (Y/N) + JP Z,PROGRM ; IF YES GO PROGRAM ROUTINE + CP 'O' ; IS IT AN "O" (Y/N) + JP Z,POUT ; PORT OUTPUT + CP 'H' ; IS IT A "H" (Y/N) + JP Z,HXLOAD ; INTEL HEX FORMAT LOAD DATA + CP 'I' ; IS IT AN "I" (Y/N) + JP Z,PIN ; PORT INPUT + CP 'D' ; IS IT A "D" (Y/N) + JP Z,DUMP ; DUMP MEMORY + CP 'K' + JP Z,KLOP ; LOOP ON KEYBOARD + CP 'M' ; IS IT A "M" (Y/N) + JP Z,MOVE ; MOVE MEMORY COMMAND + CP 'F' ; IS IT A "F" (Y/N) + JP Z,FILL ; FILL MEMORY COMMAND + LD HL,TXT_COMMAND ; POINT AT ERROR TEXT + CALL MSG ; PRINT COMMAND LABEL + + JR SERIALCMDLOOP + + + + + +;__KLOP__________________________________________________________________________________________________________________________ +; +; READ FROM THE SERIAL PORT AND ECHO, MONITOR COMMAND "K" +;________________________________________________________________________________________________________________________________ +; +KLOP: + CALL KIN ; GET A KEY + CALL COUT ; OUTPUT KEY TO SCREEN + CP ESC ; IS ? + JR NZ,KLOP ; NO, LOOP + JP SERIALCMDLOOP ; + +;__GETLN_________________________________________________________________________________________________________________________ +; +; READ A LINE(80) OF TEXT FROM THE SERIAL PORT, HANDLE , TERM ON +; EXIT IF TOO MANY CHARS STORE RESULT IN HL. CHAR COUNT IN C. +;________________________________________________________________________________________________________________________________ +; +GETLN: + LD C,00H ; ZERO CHAR COUNTER + PUSH DE ; STORE DE +GETLNLOP: + CALL KIN ; GET A KEY + CALL COUT ; OUTPUT KEY TO SCREEN + CP CR ; IS ? + JR Z,GETLNDONE ; YES, EXIT + CP BS ; IS ? + JR NZ,GETLNSTORE ; NO, STORE CHAR + LD A,C ; A=C + CP 0 ; + JR Z,GETLNLOP ; NOTHING TO BACKSPACE, IGNORE & GET NEXT KEY + DEC HL ; PERFORM BACKSPACE + DEC C ; LOWER CHAR COUNTER + LD A,0 ; + LD (HL),A ; STORE NULL IN BUFFER + LD A,20H ; BLANK OUT CHAR ON TERM + CALL COUT ; + LD A,BS ; + CALL COUT ; + JR GETLNLOP ; GET NEXT KEY +GETLNSTORE: + LD (HL),A ; STORE CHAR IN BUFFER + INC HL ; INC POINTER + INC C ; INC CHAR COUNTER + LD A,C ; A=C + CP 4DH ; OUT OF BUFFER SPACE? + JR NZ,GETLNLOP ; NOPE, GET NEXT CHAR +GETLNDONE: + LD (HL),00H ; STORE NULL IN BUFFER + POP DE ; RESTORE DE + RET ; + + +;__KIN___________________________________________________________________________________________________________________________ +; +; READ FROM THE SERIAL PORT AND ECHO & CONVERT INPUT TO UCASE +;________________________________________________________________________________________________________________________________ +; +KIN: + IN A,(UART5) ; READ LINE STATUS REGISTER + BIT 0,A ; TEST IF DATA IN RECEIVE BUFFER + JP Z,KIN ; LOOP UNTIL DATA IS READY + IN A,(UART0) ; THEN READ THE CHAR FROM THE UART + AND 7FH ; STRIP HI BIT + CP 'A' ; KEEP NUMBERS, CONTROLS + RET C ; AND UPPER CASE + CP 7BH ; SEE IF NOT LOWER CASE + RET NC ; + AND 5FH ; MAKE UPPER CASE + RET + + +;__COUT__________________________________________________________________________________________________________________________ +; +; WRITE THE VALUE IN "A" TO THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +COUT: + PUSH AF ; STORE AF +TX_BUSYLP: + IN A,(UART5) ; READ LINE STATUS REGISTER + BIT 5,A ; TEST IF UART IS READY TO SEND + JP Z,TX_BUSYLP ; IF NOT REPEAT + POP AF ; RESTORE AF + OUT (UART0),A ; THEN WRITE THE CHAR TO UART + RET ; DONE + + +;__CRLF__________________________________________________________________________________________________________________________ +; +; SEND CR & LF TO THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +CRLF: + PUSH HL ; PROTECT HL FROM OVERWRITE + LD HL,TCRLF ; LOAD MESSAGE POINTER + CALL MSG ; SEBD MESSAGE TO SERIAL PORT + POP HL ; PROTECT HL FROM OVERWRITE + RET ; + + +;__LDHL__________________________________________________________________________________________________________________________ +; +; GET ONE WORD OF HEX DATA FROM BUFFER POINTED TO BY HL SERIAL PORT, RETURN IN HL +;________________________________________________________________________________________________________________________________ +; +LDHL: + PUSH DE ; STORE DE + CALL HEXIN ; GET K B. AND MAKE HEX + LD D,A ; THATS THE HI BYTE + CALL HEXIN ; DO HEX AGAIN + LD L,A ; THATS THE LOW BYTE + LD H,D ; MOVE TO HL + POP DE ; RESTORE BC + RET ; GO BACK WITH ADDRESS + + +;__HEXIN__________________________________________________________________________________________________________________________ +; +; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A +;________________________________________________________________________________________________________________________________ +; +HEXIN: + PUSH BC ;SAVE BC REGS + CALL NIBL ;DO A NIBBLE + RLC A ;MOVE FIRST BYTE UPPER NIBBLE + RLC A ; + RLC A ; + RLC A ; + LD B,A ; SAVE ROTATED BYTE + CALL NIBL ; DO NEXT NIBBLE + ADD A,B ; COMBINE NIBBLES IN ACC + POP BC ; RESTORE BC + RET ; DONE +NIBL: + LD A,(HL) ; GET K B. DATA + INC HL ; INC KB POINTER + CP 40H ; TEST FOR ALPHA + JR NC,ALPH ; + AND 0FH ; GET THE BITS + RET ; +ALPH: + AND 0FH ; GET THE BITS + ADD A,09H ; MAKE IT HEX A-F + RET ; + + +;__HEXINS_________________________________________________________________________________________________________________________ +; +; GET ONE BYTE OF HEX DATA FROM SERIAL PORT, RETURN IN A +;________________________________________________________________________________________________________________________________ +; +HEXINS: + PUSH BC ;SAVE BC REGS + PUSH HL ;SAVE HL REGS + CALL NIBLS ;DO A NIBBLE + RLC A ;MOVE FIRST BYTE UPPER NIBBLE + RLC A ; + RLC A ; + RLC A ; + LD B,A ; SAVE ROTATED BYTE + CALL NIBLS ; DO NEXT NIBBLE + ADD A,B ; COMBINE NIBBLES IN ACC + POP HL ; RESTORE HL + POP BC ; RESTORE BC + RET ; DONE +NIBLS: + CALL KIN ; GET K B. DATA + INC HL ; INC KB POINTER + CP 40H ; TEST FOR ALPHA + JR NC,ALPH ; + AND 0FH ; GET THE BITS + RET ; + + +;__HXOUT_________________________________________________________________________________________________________________________ +; +; PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +HXOUT: + PUSH BC ; SAVE BC + LD B,A ; + RLC A ; DO HIGH NIBBLE FIRST + RLC A ; + RLC A ; + RLC A ; + AND 0FH ; ONLY THIS NOW + ADD A,30H ; TRY A NUMBER + CP 3AH ; TEST IT + JR C,OUT1 ; IF CY SET PRINT 'NUMBER' + ADD A,07H ; MAKE IT AN ALPHA +OUT1: + CALL COUT ; SCREEN IT + LD A,B ; NEXT NIBBLE + AND 0FH ; JUST THIS + ADD A,30H ; TRY A NUMBER + CP 3AH ; TEST IT + JR C,OUT2 ; PRINT 'NUMBER' + ADD A,07H ; MAKE IT ALPHA +OUT2: + CALL COUT ; SCREEN IT + POP BC ; RESTORE BC + RET ; + + +;__SPACE_________________________________________________________________________________________________________________________ +; +; PRINT A SPACE CHARACTER ON THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +SPACE: + PUSH AF ; STORE AF + LD A,20H ; LOAD A "SPACE" + CALL COUT ; SCREEN IT + POP AF ; RESTORE AF + RET ; DONE + +;__PHL_________________________________________________________________________________________________________________________ +; +; PRINT THE HL REG ON THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +PHL: + LD A,H ; GET HI BYTE + CALL HXOUT ; DO HEX OUT ROUTINE + LD A,L ; GET LOW BYTE + CALL HXOUT ; HEX IT + CALL SPACE ; + RET ; DONE + +;__POUT__________________________________________________________________________________________________________________________ +; +; OUTPUT TO AN I/O PORT, MONITOR COMMAND "O" +;________________________________________________________________________________________________________________________________ +; +POUT: +POUT1: + INC HL ; + CALL HEXIN ; GET PORT + LD C,A ; SAVE PORT POINTER + INC HL ; + CALL HEXIN ; GET DATA +OUTIT: + OUT (C),A ; + JP SERIALCMDLOOP ; + + +;__PIN___________________________________________________________________________________________________________________________ +; +; INPUT FROM AN I/O PORT, MONITOR COMMAND "I" +;________________________________________________________________________________________________________________________________ +; +PIN: + INC HL ; + CALL HEXIN ; GET PORT + LD C,A ; SAVE PORT POINTER + CALL CRLF ; + IN A,(C) ; GET DATA + CALL HXOUT ; SHOW IT + JP SERIALCMDLOOP ; + + + + + +;__CRLFA_________________________________________________________________________________________________________________________ +; +; PRINT COMMAND PROMPT TO THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +CRLFA: + PUSH HL ; PROTECT HL FROM OVERWRITE + LD HL,PROMPT ; + CALL MSG ; + POP HL ; PROTECT HL FROM OVERWRITE + RET ; DONE + + +;__MSG___________________________________________________________________________________________________________________________ +; +; PRINT A STRING TO THE SERIAL PORT +;________________________________________________________________________________________________________________________________ +; +MSG: + +TX_SERLP: + LD A,(HL) ; GET CHARACTER TO A + CP ENDT ; TEST FOR END BYTE + JP Z,TX_END ; JUMP IF END BYTE IS FOUND + CALL COUT ; + INC HL ; INC POINTER, TO NEXT CHAR + JP TX_SERLP ; TRANSMIT LOOP +TX_END: + RET ;ELSE DONE + +;__RUN___________________________________________________________________________________________________________________________ +; +; TRANSFER OUT OF MONITOR, USER OPTION "R" +;________________________________________________________________________________________________________________________________ +; +RUN: + INC HL ; SHOW READY + CALL LDHL ; GET START ADDRESS + JP (HL) ; + + +;__PROGRM________________________________________________________________________________________________________________________ +; +; PROGRAM RAM LOCATIONS, USER OPTION "P" +;________________________________________________________________________________________________________________________________ +; +PROGRM: + INC HL ; SHOW READY + PUSH HL ; STORE HL + CALL LDHL ; GET START ADDRESS + LD D,H ; + LD E,L ; DE POINTS TO ADDRESS TO PROGRAM + POP HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; +PROGRMLP: + CALL HEXIN ; GET NEXT HEX NUMBER + LD (DE),A ; STORE IT + INC DE ; NEXT ADDRESS; + CALL CRLFA ; CR,LF,> + LD A,'P' ; + CALL COUT ; + CALL SPACE ; + LD H,D ; + LD L,E ; + CALL PHL ; + LD HL,KEYBUF ; SET POINTER TO KEYBUF AREA + CALL GETLN ; GET A LINE OF INPUT FROM THE USER + LD HL,KEYBUF ; RESET POINTER TO START OF KEYBUF + LD A,(HL) ; LOAD FIRST CHAR INTO A + CP 00H ; END OF LINE? + JP Z,PROGRMEXIT ; YES, EXIT + JP PROGRMLP ; NO, LOOP +PROGRMEXIT: + JP SERIALCMDLOOP + + + + + + + +;__DUMP__________________________________________________________________________________________________________________________ +; +; PRINT A MEMORY DUMP, USER OPTION "D" +;________________________________________________________________________________________________________________________________ +; +DUMP: + INC HL ; SHOW READY + PUSH HL ; STORE HL + CALL LDHL ; GET START ADDRESS + LD D,H ; + LD E,L ; + POP HL ; + PUSH DE ; SAVE START + INC HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; + CALL LDHL ; GET END ADDRESS + INC HL ; ADD ONE MORE FOR LATER COMPARE + EX DE,HL ; PUT END ADDRESS IN DE + POP HL ; GET BACK START +GDATA: + CALL CRLF ; +BLKRD: + CALL PHL ; PRINT START LOCATION + LD C,16 ; SET FOR 16 LOCS + PUSH HL ; SAVE STARTING HL +NXTONE: + EXX ; + LD C,E ; + IN A,(C) ; + EXX ; + AND 7FH ; + CP ESC ; + JP Z,SERIALCMDLOOP ; + CP 19 ; + JR Z,NXTONE ; + LD A,(HL) ; GET BYTE + CALL HXOUT ; PRINT IT + CALL SPACE ; +UPDH: + INC HL ; POINT NEXT + DEC C ; DEC LOC COUNT + JR NZ,NXTONE ; IF LINE NOT DONE + ; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP +PCRLF: + CALL SPACE ; SPACE IT + LD C,16 ; SET FOR 16 CHARS + POP HL ; GET BACK START +PCRLF0: + LD A,(HL) ; GET BYTE + AND 060H ; SEE IF A 'DOT' + LD A,(HL) ; O K. TO GET + JR NZ,PDOT ; +DOT: + LD A,2EH ; LOAD A DOT +PDOT: + CALL COUT ; PRINT IT + INC HL ; + LD A,D ; + CP H ; + JR NZ,UPDH1 ; + LD A,E ; + CP L ; + JP Z,SERIALCMDLOOP ; +; +;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE +UPDH1: + DEC C ; DEC CHAR COUNT + JR NZ,PCRLF0 ; DO NEXT +CONTD: + CALL CRLF ; + JP BLKRD ; + + +;__HXLOAD__________________________________________________________________________________________________________________________ +; +; LOAD INTEL HEX FORMAT FILE FROM THE SERIAL PORT, USER OPTION "H" +; +; [INTEL HEX FORMAT IS: +; 1) COLON (FRAME 0) +; 2) RECORD LENGTH FIELD (FRAMES 1 AND 2) +; 3) LOAD ADDRESS FIELD (FRAMES 3,4,5,6) +; 4) RECORD TYPE FIELD (FRAMES 7 AND 8) +; 5) DATA FIELD (FRAMES 9 TO 9+2*(RECORD LENGTH)-1 +; 6) CHECKSUM FIELD - SUM OF ALL BYTE VALUES FROM RECORD LENGTH TO AND +; INCLUDING CHECKSUM FIELD = 0 ] +; +; EXAMPLE OF INTEL HEX FORMAT FILE +; EACH LINE CONTAINS A CARRIAGE RETURN AS THE LAST CHARACTER +; :18F900002048454C4C4F20574F524C4420FF0D0AFF0D0A3EFF0D0A54BF +; :18F918006573742050726F746F7479706520524F4D204D6F6E69746FF1 +; :18F9300072205265616479200D0AFF0D0A434F4D4D414E4420524543F2 +; :18F948004549564544203AFF0D0A434845434B53554D204552524F52CD +; :16F96000FF0A0D20202D454E442D4F462D46494C452D20200A0DA4 +; :00000001FF +;________________________________________________________________________________________________________________________________ +HXLOAD: + CALL CRLF ; SHOW READY +HXLOAD0: + CALL KIN ; GET THE FIRST CHARACTER, EXPECTING A ':' +HXLOAD1: + CP 03Ah ; IS IT COLON ':'? START OF LINE OF INTEL HEX FILE + JR NZ,HXLOADERR ; IF NOT, MUST BE ERROR, ABORT ROUTINE + LD E,0 ; FIRST TWO CHARACTERS IS THE RECORD LENGTH FIELD + CALL HEXINS ; GET US TWO CHARACTERS INTO BC, CONVERT IT TO A BYTE + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + LD D,A ; LOAD RECORD LENGTH COUNT INTO D + CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + LD H,A ; PUT VALUE IN H REGISTER + CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + LD L,A ; PUT VALUE IN L REGISTER + CALL HEXINS ; GET NEXT TWO CHARACTERS, RECORD FIELD TYPE + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + CP 001h ; RECORD FIELD TYPE 00 IS DATA, 01 IS END OF FILE + JR NZ,HXLOAD2 ; MUST BE THE END OF THAT FILE + CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO BYTE + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + LD A,E ; RECALL THE CHECKSUM BYTE + AND A ; IS IT ZERO? + JP Z,HXLOADEXIT ; MUST BE O K., GO BACK FOR SOME MORE, ELSE + JR HXLOADERR ; CHECKSUMS DON'T ADD UP, ERROR OUT +HXLOAD2: + LD A,D ; RETRIEVE LINE CHARACTER COUNTER + AND A ; ARE WE DONE WITH THIS LINE? + JR Z,HXLOAD3 ; GET TWO MORE ASCII CHARACTERS, BUILD A BYTE AND CHECKSUM + CALL HEXINS ; GET NEXT TWO CHARS, CONVERT TO BYTE IN A, CHECKSUM IT + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + LD (HL),A ; CHECKSUM OK, MOVE CONVERTED BYTE IN A TO MEMORY LOCATION + INC HL ; INCREMENT POINTER TO NEXT MEMORY LOCATION + DEC D ; DECREMENT LINE CHARACTER COUNTER + JR HXLOAD2 ; AND KEEP LOADING INTO MEMORY UNTIL LINE IS COMPLETE +HXLOAD3: + CALL HEXINS ; GET TWO CHARS, BUILD BYTE AND CHECKSUM + CALL HXCHKSUM ; UPDATE HEX CHECK SUM + LD A,E ; CHECK THE CHECKSUM VALUE + AND A ; IS IT ZERO? + JR Z,HXLOADAGAIN ; IF THE CHECKSUM IS STILL OK, CONTINUE ON, ELSE +HXLOADERR: + LD HL,TXT_CKSUMERR ; GET "CHECKSUM ERROR" MESSAGE + CALL MSG ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD + JP HXLOADEXIT ; RETURN TO PROMPT +HXCHKSUM: + LD C,A ; BUILD THE CHECKSUM + LD A,E ; + SUB C ; THE CHECKSUM SHOULD ALWAYS EQUAL ZERO WHEN CHECKED + LD E,A ; SAVE THE CHECKSUM BACK WHERE IT CAME FROM + LD A,C ; RETRIEVE THE BYTE AND GO BACK + RET ; BACK TO CALLER +HXLOADAGAIN: + CALL KIN ; CATCH THE TRAILING CARRIAGE RETURN + JP HXLOAD0 ; LOAD ANOTHER LINE OF DATA +HXLOADEXIT: + CALL KIN ; CATCH ANY STRAY TRAILING CHARACTERS + JP SERIALCMDLOOP ; RETURN TO PROMPT + + +;__MOVE__________________________________________________________________________________________________________________________ +; +; MOVE MEMORY, USER OPTION "M" +;________________________________________________________________________________________________________________________________ +; +MOVE: + LD C,03 + ; START GETNM REPLACEMENT + ; GET SOURCE STARTING MEMORY LOCATION + INC HL ; SHOW EXAMINE READY + PUSH HL ; + CALL LDHL ; LOAD IN HL REGS + LD D,H ; + LD E,L ; + POP HL ; + PUSH DE ; PUSH MEMORY ADDRESS ON STACK + INC HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; PRINT SPACE SEPARATOR + PUSH HL ; + CALL LDHL ; LOAD IN HL REGS + LD D,H ; + LD E,L ; + POP HL ; + PUSH DE ; PUSH MEMORY ADDRESS ON STACK + INC HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; PRINT SPACE SEPARATOR + CALL LDHL ; LOAD IN HL REGS + PUSH HL ; PUSH MEMORY ADDRESS ON STACK + ; END GETNM REPLACEMENT + POP DE ; DEST + POP BC ; SOURCE END + POP HL ; SOURCE + PUSH HL ; + LD A,L ; + CPL ; + LD L,A ; + LD A,H ; + CPL ; + LD H,A ; + INC HL ; + ADD HL,BC ; + LD C,L ; + LD B,H ; + POP HL ; + CALL MOVE_LOOP ; + JP SERIALCMDLOOP ; EXIT MOVE COMMAND ROUTINE +MOVE_LOOP: + LD A,(HL) ; FETCH + LD (DE),A ; DEPOSIT + INC HL ; BUMP SOURCE + INC DE ; BUMP DEST + DEC BC ; DEC COUNT + LD A,C ; + OR B ; + JP NZ,MOVE_LOOP ; TIL COUNT=0 + RET ; + +;__FILL__________________________________________________________________________________________________________________________ +; +; FILL MEMORY, USER OPTION "M" +;________________________________________________________________________________________________________________________________ +; +FILL: + LD C,03 ; + ; START GETNM REPLACEMENT + ; GET FILL STARTING MEMORY LOCATION + INC HL ; SHOW EXAMINE READY + PUSH HL ; + CALL LDHL ; LOAD IN HL REGS + LD D,H ; + LD E,L ; + POP HL ; + PUSH DE ; PUSH MEMORY ADDRESS ON STACK + INC HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; PRINT SPACE SEPARATOR + ; GET FILL ENDING MEMORY LOCATION + PUSH HL ; + CALL LDHL ; LOAD IN HL REGS + LD D,H ; + LD E,L ; + POP HL ; + PUSH DE ; PUSH MEMORY ADDRESS ON STACK + INC HL ; + INC HL ; + INC HL ; + INC HL ; + INC HL ; PRINT SPACE SEPARATOR + ; GET TARGET STARTING MEMORY LOCATION + CALL HEXIN ; GET K B. AND MAKE HEX + LD C,A ; PUT FILL VALUE IN F SO IT IS SAVED FOR LATER + PUSH BC ; PUSH FILL VALUE BYTE ON STACK + ; END GETNM REPLACEMENT + POP BC ; BYTE + POP DE ; END + POP HL ; START + LD (HL),C ; +FILL_LOOP: + LD (HL),C ; + INC HL ; + LD A,E ; + SUB L ; + LD B,A ; + LD A,D ; + SUB H ; + OR B ; + JP NZ,FILL_LOOP ; + JP SERIALCMDLOOP ; + + +;__DOBOOT________________________________________________________________________________________________________________________ +; +; PERFORM BOOT +;________________________________________________________________________________________________________________________________ +; +DOBOOT: +; LD A,0H ; LOAD VALUE TO SWITCH OUT ROM + LD A,80H ; LOAD VALUE TO SWITCH OUT ROM + OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE + ; + ; + OUT (MPCL_RAM),A ; +; JP 0000H ; GO TO CP/M + + + +;__GOCPM_________________________________________________________________________________________________________________________ +; +; BOOT CP/M FROM ROM DRIVE, USER OPTION "C" +;________________________________________________________________________________________________________________________________ +; +GOCPM: +;___________________________ +; REMOVE COMMENTS WHEN BURNED IN ROM +;___________________________ + +; LD A,000000000b ; RESET MPCL LATCH TO DEFAULT ROM +; OUT (MPCL),A ; +; LD HL,ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) +; LD DE,RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) +; LD BC,MOVSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM +; LDIR ; PERFORM BLOCK COPY OF CP/M TO UPPER RAM PAGE +; LD A,010000000b ; RESET MPCL LATCH TO DEFAULT CP/M WITH 64K SETTING +; OUT (MPCL),A ; + +; JP 0EA00h ; CP/M COLD BOOT ENTRY POINT + RET ; RETURN TO CP/M + +; +;__INIT_UART_____________________________________________________________________________________________________________________ +; +; INITIALIZE UART +; PARAMS: SER_BAUD NEEDS TO BE SET TO BAUD RATE +; 1200: 96 = 1,843,200 / ( 16 X 1200 ) +; 2400: 48 = 1,843,200 / ( 16 X 2400 ) +; 4800: 24 = 1,843,200 / ( 16 X 4800 ) +; 9600: 12 = 1,843,200 / ( 16 X 9600 ) +; 19K2: 06 = 1,843,200 / ( 16 X 19,200 ) +; 38K4: 03 +; 57K6: 02 +; 115K2: 01 +; +;_________________________________________________________________________________________________________________________________ +; +INIT_UART: + LD A,80H ; + OUT (UART3),A ; SET DLAB FLAG + LD A,(SER_BAUD) ; + OUT (UART0),A ; + LD A,00H ; + OUT (UART1),A ; + LD A,03H ; + OUT (UART3),A ; SET 8 BIT DATA, 1 STOPBIT + LD A,03H ; set DTR & RTS + OUT (UART4),A ; + RET + + +; +;__FILL_MEM_______________________________________________________________________________________________________________________ +; +; FUNCTION : FILL MEMORY WITH A VALUE +; INPUT : HL = START ADDRESS BLOCK +; : BC = LENGTH OF BLOCK +; : A = VALUE TO FILL WITH +; USES : DE, BC +; OUTPUT : +; CALLS : +; TESTED : 13 FEB 2007 +;_________________________________________________________________________________________________________________________________ +; +FILL_MEM: + LD E,L ; + LD D,H ; + INC DE ; + LD (HL),A ; INITIALISE FIRST BYTE OF BLOCK WITH DATA BYTE IN A + DEC BC ; + LDIR ; FILL MEMORY + RET ; RETURN TO CALLER +; +;__RAM_TEST________________________________________________________________________ +; +; TEST FUNCTIONALITY OF LOWER 32KB RAM PAGE, USER OPTION "A" +; SYNTAX: A +;_____________________________________________________________________________ +; + +DORAMTEST: + +MEMSIZELOOP: + LD HL,TXT_RAM_TEST_MAIN ; POINT AT RAM TEST MAIN MENU TEXT + CALL MSG ; PRINT MENU TEXT LABEL + CALL CRLFA ; CR,LF,> + LD HL,KEYBUF ; SET POINTER TO KEYBUF AREA + CALL GETLN ; GET A LINE OF INPUT FROM THE USER + LD HL,KEYBUF ; RESET POINTER TO START OF KEYBUF + LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE MEM SIZE FOR TEST) + INC HL ; INC POINTER + + CP 'A' ; IS IT "A" (Y/N) + JP Z,MEM32KB ; IF YES DO 32KB RAM TEST + CP 'B' ; IS IT "B" (Y/N) + JP Z,MEM64KB ; IF YES DO 64KB RAM TEST + CP 'C' ; IS IT "C" (Y/N) + JP Z,MEM128KB ; IF YES DO 128KB RAM TEST + CP 'D' ; IS IT "D" (Y/N) + JP Z,MEM256KB ; IF YES DO 256KB RAM TEST + CP 'E' ; IS IT "E" (Y/N) + JP Z,MEM512KB ; IF YES DO 512KB RAM TEST + CP 'F' ; IS IT "F" (Y/N) + JP Z,MEM1024KB ; IF YES DO 1024KB RAM TEST + LD HL,TXT_COMMAND ; POINT AT ERROR TEXT + CALL MSG ; PRINT COMMAND LABEL + + JR MEMSIZELOOP + +MEM32KB: + LD HL,TXT_RAM_TEST_32KB ; 1 PAGE, 32KB RAM TEST SELECTED + CALL MSG ; DISPLAY IT + + LD A,$80 ; ONE 32KB PAGE ONLY + LD (PAGE_NUM),A ; STORE WORKING PAGE NUMBER + JP RAMTEST + +MEM64KB: + LD HL,TXT_RAM_TEST_64KB ; 2 PAGE, 64KB RAM TEST SELECTED + CALL MSG ; DISPLAY IT + + LD A,$81 ; TWO 32KB PAGES + LD (PAGE_NUM),A ; STORE WORKING PAGE NUMBER + JP RAMTEST + +MEM128KB: + LD HL,TXT_RAM_TEST_128KB ; 4 PAGE, 12864KB RAM TEST SELECTED + CALL MSG ; DISPLAY IT + + LD A,$83 ; FOUR 32KB PAGES + LD (PAGE_NUM),A ; STORE WORKING PAGE NUMBER + JP RAMTEST + +MEM256KB: + LD HL,TXT_RAM_TEST_256KB ; 8 PAGE, 256KB RAM TEST SELECTED + CALL MSG ; DISPLAY IT + + LD A,$87 ; EIGHT 32KB PAGES + LD (PAGE_NUM),A ; STORE WORKING PAGE NUMBER + JP RAMTEST + +MEM512KB: + LD HL,TXT_RAM_TEST_512KB ; 16 PAGE, 512KB RAM TEST SELECTED + CALL MSG ; DISPLAY IT + + LD A,$8F ; SIXTEEN 32KB PAGES + LD (PAGE_NUM),A ; STORE WORKING PAGE NUMBER + JP RAMTEST + +MEM1024KB: + LD HL,TXT_RAM_TEST_1024KB ; 32 PAGE, 1024KB RAM TEST SELECTED + CALL MSG ; DISPLAY IT + + LD A,$9F ; THIRTY-TWO 32KB PAGES + LD (PAGE_NUM),A ; STORE WORKING PAGE NUMBER + JP RAMTEST + +RAMTEST: + LD A,(PAGE_NUM) ; GET WORKING PAGE NUMBER + CP $8F ; IS IT PAGE SIXTEEN? + JP NZ,NEXTPAGE ; NO? DO ANOTHER 32KB PAGE + SUB $01 ; YES? SKIP OVER PAGE SIXTEEN + ; (WHERE RAMTEST PROGRAM IS RUNNING) + LD (PAGE_NUM),A ; UPDATE WORKING PAGE NUMBER + + LD HL,TXT_SKIP_16 ; POINT AT SYNTAX SKIP PAGE SIXTEEN + CALL MSG ; DISPLAY IT + + JP RAMTEST ; TRY AGAIN WITH NEXT RAM PAGE + +NEXTPAGE: + OUT (MPCL_ROM),A ; SWITCH OUT LOWER 32KB ROM PAGE + OUT (MPCL_RAM),A ; SWITCH IN LOWER 32KB RAM PAGE + + LD HL,$7FFF ; INITIALIZE MEMORY ADDRESS COUNT + LD DE,$0001 ; DECREMENT VALUE + LD IX,TEST_VALUES ; MEMORY TEST VALUES + +START: + LD A,(IX+0) ; LOAD TEST VALUE + LD B,A ; STORE TEST VALUE IN B + CP '$' ; IS IT LAST ONE? + JP Z,RAM_PASS ; YES?, RAM PASSED TEST, EXIT RAM TEST + + LD (HL),A ; NO?, WRITE TO MEMORY ADDRESS + LD C,(HL) ; LOAD VALUE FROM MEMORY ADDRESS + CP C ; IS IT SAME AS WRITTEN? + JP NZ,RAM_FAIL ; NO?, JUMP TO ERROR HANDLER ROUTINE + + SBC HL,DE ; REDUCE MEMORY ADDRESS COUNT BY 1 + JP NZ,START ; LOOP THROUGH ALL MEMORY IN LOWER 32KB PAGE + + ; DO $0000 MEMORY ADDRESS + LD (HL),A ; NO?, WRITE TO MEMORY ADDRESS + LD C,(HL) ; LOAD VALUE FROM MEMORY ADDRESS + CP C ; IS IT SAME AS WRITTEN? + JP NZ,RAM_FAIL ; NO?, JUMP TO ERROR HANDLER ROUTINE + + INC IX ; POINT TO NEXT TEST VALUE + LD HL,$7FFF ; INITIALIZE MEMORY ADDRESS COUNT + JP START ; START AGAIN, TEST ALL MEMORY LOCATIONS WITH NEW TEST VALUE + +RAM_PASS: + LD HL,TXT_RAM_PASS ; POINT AT SYNTAX RAM PASS TEXT + CALL MSG ; DISPLAY IT + + LD A,(PAGE_NUM) ; GET WORKING PAGE NUMBER + SUB $80 ; CONVERT MPCL VALUE TO PAGE NUMBER + CALL HXOUT ; SHOW IT + + LD A,(PAGE_NUM) ; GET WORKING PAGE NUMBER + DEC A ; MARK PAGE COMPLETE, MOVE TO NEXT + LD (PAGE_NUM),A ; STORE UPDATED PAGE NUMBER + + CP $7F ; WAS THAT THE LAST PAGE? + JP NZ,RAMTEST ; NO? DO ANOTHER 32KB PAGE + + LD HL,TCRLF ; CR & LF + CALL MSG ; DISPLAY IT + JP SERIALCMDLOOP ; YES? BACK TO COMMAND LOOP + + +RAM_FAIL: + LD HL,TXT_RAM_FAIL ; POINT AT SYNTAX RAM FAIL TEXT + CALL MSG ; DISPLAY IT + LD A,(PAGE_NUM) ; GET CURRENT PAGE NUMBER + SUB $80 + CALL HXOUT ; SHOW IT + LD HL,TCRLF ; CR & LF + CALL MSG ; DISPLAY IT + JP SERIALCMDLOOP ; AND BACK TO COMMAND LOOP + + +; +;__INITIALIZE_____________________________________________________________________________________________________________________ +; +; INITIALIZE SYSTEM +;_________________________________________________________________________________________________________________________________ +; +INITIALIZE: +; LD A,12 ; SPECIFY BAUD RATE 9600 BPS (9600,8,NONE,1) + LD A,3 ; SPECIFY BAUD RATE 38400 BPS (9600,8,NONE,1) + LD (SER_BAUD),A ; + CALL INIT_UART ; INIT THE UART + RET ; +; + +;__MTERM_INIT________________________________________________________________________________________ +; +; SETUP 8255, MODE 0, PORT A=OUT, PORT B=IN, PORT C=OUT/OUT +; +;____________________________________________________________________________________________________ +MTERM_INIT: + LD A, 82H + OUT (PIOCONT),A + RET + +; +;__TEXT_STRINGS_________________________________________________________________________________________________________________ +; +; SYSTEM TEXT STRINGS +;_____________________________________________________________________________________________________________________________ +; +TCRLF: + .DB CR,LF,ENDT + +PROMPT: + .DB CR,LF,'>',ENDT + +TXT_READY: + .DB "RAM TEST PROGRAM",CR,LF + .DB CR,LF + .DB "MONITOR READY " + .DB CR,LF,ENDT + +TXT_COMMAND: + .DB CR,LF + .DB "UNKNOWN COMMAND." + .DB ENDT + +TXT_MAIN_MENU: + .DB CR,LF + .DB "MAIN MENU: " + .DB "A RAM TEST, " + .DB "B BOOT, " + .DB "D DUMP, " + .DB "F FILL, " + .DB "H LOAD, " + .DB CR,LF + .DB "I INPUT, " + .DB "K ECHO, " + .DB "M MOVE, " + .DB "O OUTPUT, " + .DB "P PROGRAM, " + .DB "R RUN" + .DB CR,LF + .DB ENDT + +TXT_CKSUMERR: + .DB CR,LF + .DB "CHECKSUM ERROR." + .DB ENDT + +TXT_RAM_PASS: + .DB CR,LF + .DB "RAM PASS, PAGE = " + .DB ENDT + +TXT_RAM_FAIL: + .DB CR,LF + .DB "RAM FAIL, 32KB PAGE NUMBER: " + .DB CR,LF,ENDT + +TXT_SKIP_16: + .DB CR,LF + .DB "SKIPPING PAGE 0F " + .DB ENDT + +TXT_RAM_TEST_MAIN: + .DB CR,LF + .DB "ENTER RAM SIZE: A=32KB, B=64KB," + .DB " C=128KB, D=256KB, E=512KB," + .DB " F=1024KB" + .DB CR,LF,ENDT + +TXT_RAM_TEST_32KB: + .DB CR,LF + .DB "ONE 32KB PAGE SELECTED" + .DB CR,LF,ENDT + +TXT_RAM_TEST_64KB: + .DB CR,LF + .DB "TWO 32KB PAGES SELECTED" + .DB CR,LF,ENDT + +TXT_RAM_TEST_128KB: + .DB CR,LF + .DB "FOUR 32KB PAGES SELECTED" + .DB CR,LF,ENDT + +TXT_RAM_TEST_256KB: + .DB CR,LF + .DB "EIGHT 32KB PAGES SELECTED" + .DB CR,LF,ENDT + +TXT_RAM_TEST_512KB: + .DB CR,LF + .DB "SIXTEEN 32KB PAGES SELECTED" + .DB CR,LF,ENDT + +TXT_RAM_TEST_1024KB: + .DB CR,LF + .DB "THIRTY-TWO 32KB PAGES SELECTED" + .DB CR,LF,ENDT + +; +;__RAM_TEST_VALUES____________________________________________________________ +; +; RAM TEST VALUES +;_____________________________________________________________________________ +; +TEST_VALUES .DB $00,$FF,$55,$AA,'$' + +; +;__WORK_AREA___________________________________________________________________________________________________________________ +; +; RESERVED RAM FOR MONITOR WORKING AREA +;_____________________________________________________________________________________________________________________________ +; +SER_BAUD: .FILL 1 ; SPECIFY DESIRED UART COM RATE IN BPS +PAGE_NUM .FILL 1 +KEYBUF: .DB " " + .DB " " + .DB " " + .DB " " + .DB " " + +;********************* END OF PROGRAM *********************************** + .FILL 08FFFh-$ + .ORG 08FFFh + .DB 000h + .END + + + diff --git a/Source/Apps/ramtest/loader.asm b/Source/Apps/ramtest/loader.asm new file mode 100644 index 00000000..f239a443 --- /dev/null +++ b/Source/Apps/ramtest/loader.asm @@ -0,0 +1,55 @@ +; Z80 +;*********************************** +;* Z80 TEST PROTOTYPE +;* LOAD MONITOR FROM ROM INTO RAM AND EXECUTE PROGRAM +;* ANDREW LYNCH +;* LYNCHAJ@YAHOO COM +;* 15 FEB 2007 +;*********************************** + + +;********************* CONSTANTS **************************************** + +RAMTOP: .EQU 0FFFFh ; HIGHEST ADDRESSABLE MEMORY LOCATION +MONSTART: .EQU 08000h ; START OF 6116 SRAM 2KB X 8 RAM F800H-FFFFH +RAMBOTTOM: .EQU 08000h ; BEGINNING OF UPPER 32K RAM PAGE +END: .EQU 0FFh ; MARK END OF TEXT +CR: .EQU 0DH ; ASCII CARRIAGE RETURN CHARACTER +LF: .EQU 0AH ; ASCII LINE FEED CHARACTER +ESC: .EQU 1BH ; ASCII ESCAPE CHARACTER + +ROMSTART_MON: .EQU 00200h ; WHERE THE DBGMON IS STORED IN ROM +RAMTARG_MON: .EQU 08000h ; WHERE THE DBGMON STARTS IN RAM (ENTRY POINT) +MOVSIZ_MON: .EQU 01000h ; DBGMON IS 4096 BYTES IN LENGTH + +MON_ENTRY: .EQU 08000h ; DBGMON ENTRY POINT (MAY CHANGE) + + + +;******************************************************************* +;* START AFTER RESET +;* FUNCTION : READY SYSTEM, LOAD MONITOR INTO RAM AND START +;******************************************************************* + + .ORG 00100h + +; DI ; DISABLE INTERRUPT + LD SP,RAMTOP ; SET STACK POINTER TO TOP OF RAM +; IM 1 ; SET INTERRUPT MODE 1 + + LD HL,ROMSTART_MON ; WHERE IN ROM DBGMON IS STORED (FIRST BYTE) + LD DE,RAMTARG_MON ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) + LD BC,MOVSIZ_MON ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM + LDIR ; PERFORM BLOCK COPY OF DBGMON TO UPPER RAM PAGE + +; EI ; ENABLE INTERRUPTS (ACCESS TO MONITOR WHILE CP/M RUNNING) + + JP MON_ENTRY ; JUMP TO START OF MONITOR + + .FILL 001FFh-$ + + .ORG 001FFh +FLAG: + .DB 0FFh + + .END diff --git a/Source/Apps/ramtest/ramtest.bat b/Source/Apps/ramtest/ramtest.bat new file mode 100644 index 00000000..8d78b069 --- /dev/null +++ b/Source/Apps/ramtest/ramtest.bat @@ -0,0 +1,8 @@ +set TOOLS=../../../Tools +set PATH=%TOOLS%\tasm32;%PATH% +set TASMTABS=%TOOLS%\tasm32 + +tasm -t80 -b -fFF loader.asm loader.bin loader.lst +tasm -t80 -b -fFF dbgmon.asm dbgmon.bin dbgmon.lst + +copy /Y /b loader.bin+dbgmon.bin ramtest.com diff --git a/Source/Apps/ramtest/ramtest.sh b/Source/Apps/ramtest/ramtest.sh new file mode 100644 index 00000000..adbb2055 --- /dev/null +++ b/Source/Apps/ramtest/ramtest.sh @@ -0,0 +1,3 @@ +../../../Tools/unix/uz80as/uz80as -t z80 loader.asm loader.bin +../../../Tools/unix/uz80as/uz80as -t z80 dbgmon.asm dbgmon.bin +cat loader.bin dbgmon.bin > ramtest.com diff --git a/Source/Apps/tstdskng.asm b/Source/Apps/tstdskng.asm index ef34f35d..2bc94322 100644 --- a/Source/Apps/tstdskng.asm +++ b/Source/Apps/tstdskng.asm @@ -19,9 +19,10 @@ TRUE: .EQU !FALSE DSKY_OSC: .EQU 3000000 ; OSCILLATOR FREQ IN HZ ; BDOS: .EQU TRUE ; BDOS OR DIRECT TO 8250ISH +DSKY_PROTO: .EQU FALSE ; SET FOR DSKYNG PROTOTYPE ; UART_BASE: .EQU $68 ; UART BASE IO ADDRESS -PPI_BASE: .EQU $60 ; PPI BASE IO PORT +PPI_BASE_DEF: .EQU $60 ; PPI BASE IO PORT ; ; LED SEGMENTS (BIT VALUES) ; @@ -56,10 +57,10 @@ PPI_BASE: .EQU $60 ; PPI BASE IO PORT ; 10 10 10 10 10 ; 20 20 20 20 20 ; -PPIA: .EQU PPI_BASE + 0 ; PORT A -PPIB: .EQU PPI_BASE + 1 ; PORT B -PPIC: .EQU PPI_BASE + 2 ; PORT C -PPIX: .EQU PPI_BASE + 3 ; PIO CONTROL PORT +PPIA: .EQU 0 ; PORT A OFFSET +PPIB: .EQU 1 ; PORT B OFFSET +PPIC: .EQU 2 ; PORT C OFFSET +PPIX: .EQU 3 ; PIO CONTROL PORT OFFSET ; DSKY_PPIX_RD: .EQU %10010010 ; PPIX VALUE FOR READS DSKY_PPIX_WR: .EQU %10000010 ; PPIX VALUE FOR WRITES @@ -72,8 +73,23 @@ DSKY_PPIX_WR: .EQU %10000010 ; PPIX VALUE FOR WRITES ; SETTING BITS 3 & 4 WILL ASSERT /CS ON 3279 ; CLEAR BITS 1 OR 2 TO ASSERT READ/WRITE ; +; +#IF (DSKY_PROTO) +; +DSKY_PPI_IDLE: .EQU %01100000 +; +DSKY_RDBIT .EQU 6 +DSKY_WRBIT .EQU 5 +; +#ELSE +; DSKY_PPI_IDLE: .EQU %00000110 ; +DSKY_RDBIT .EQU 2 +DSKY_WRBIT .EQU 1 +; +#ENDIF +; DSKY_CMD_CLR: .EQU %11011111 ; CLEAR (ALL OFF) DSKY_CMD_CLRX: .EQU %11010011 ; CLEAR (ALL ON) DSKY_CMD_WDSP: .EQU %10010000 ; WRITE DISPLAY RAM @@ -90,10 +106,22 @@ DSKY_PRESCL: .EQU DSKY_OSC / 100000 ; PRESCALER LD SP,STACK ; CALL PRTSTRD - .DB "\r\nNextGenDSKY Test Program, v1.3, 2021-07-15$" + .DB "\r\nNextGenDSKY$" +; +#IF (DSKY_PROTO) CALL PRTSTRD - .DB "\r\nPPI port 0x$" - LD A,PPI_BASE + .DB " Prototype$" +#ENDIF +; + CALL PRTSTRD + .DB " Test Program, v1.4a, 2021-07-18$" +; + CALL GET_BASE + JP NZ,EXIT +; + CALL PRTSTRD + .DB "\r\nDSKYng PPI base port: 0x$" + LD A,(PPI_BASE) CALL PRTHEXBYTE CALL NEWLINE ; @@ -295,27 +323,30 @@ EXIT: ; DSKY_PPIWR: PUSH AF + PUSH BC +; + LD A,(PPI_BASE) + ADD A,PPIX + LD C,A ; ; CHECK FOR WRITE MODE - LD A,(DSKY_PPIX_VAL) + LD A,(PPIX_VAL) CP DSKY_PPIX_WR JR Z,DSKY_PPIWR1 ; ; SET PPI TO WRITE MODE LD A,DSKY_PPIX_WR - OUT (PPIX),A - LD (DSKY_PPIX_VAL),A + OUT (C),A + LD (PPIX_VAL),A ; ; RESTORE PORT C (MAY NOT BE NEEDED) LD A,DSKY_PPI_IDLE - OUT (PPIC),A -; -; ; DIAGNOSTIC -; LD A,'W' -; CALL COUT + DEC C + OUT (C),A ; DSKY_PPIWR1: ; + POP BC POP AF RET ; @@ -324,22 +355,29 @@ DSKY_PPIWR1: ; DSKY_PPIRD: PUSH AF + PUSH BC +; + LD A,(PPI_BASE) + ADD A,PPIX + LD C,A ; ; CHECK FOR READ MODE - LD A,(DSKY_PPIX_VAL) + LD A,(PPIX_VAL) CP DSKY_PPIX_RD JR Z,DSKY_PPIRD1 ; ; SET PPI TO READ MODE LD A,DSKY_PPIX_RD - OUT (PPIX),A - LD (DSKY_PPIX_VAL),A + OUT (C),A + LD (PPIX_VAL),A ; -; ; DIAGNOSTIC -; LD A,'R' -; CALL COUT + ; RESTORE PORT C (MAY NOT BE NEEDED) + LD A,DSKY_PPI_IDLE + DEC C + OUT (C),A ; DSKY_PPIRD1: + POP BC POP AF RET ; @@ -365,18 +403,23 @@ DSKY_INIT: ; DSKY_RES: ; + PUSH BC + LD A,(PPI_BASE) + ADD A,PPIC + LD C,A ; SETUP PPI CALL DSKY_PPIRD ; INIT 8279 VALUES TO IDLE STATE LD A,DSKY_PPI_IDLE - OUT (PPIC),A + OUT (C),A ; PULSE RESET SIGNAL ON 8279 SET 7,A - OUT (PPIC),A + OUT (C),A RES 7,A - OUT (PPIC),A + OUT (C),A ; DONE CALL DSKY_PPIIDLE + POP BC RET ; ; COMMAND IN A @@ -401,7 +444,9 @@ DSKY_DOUT2: CALL DSKY_PPIWR ; ; SETUP - LD C,PPIC + LD A,(PPI_BASE) + ADD A,PPIC + LD C,A ; ; SET ADDRESS FIRST LD A,DSKY_PPI_IDLE @@ -417,14 +462,18 @@ DSKY_DOUT2: LD B,A ; ; ASSERT DATA BYTE VALUE + DEC C + DEC C POP AF - OUT (PPIA),A + OUT (C),A + INC C + INC C ; ; PULSE /WR - RES 1,B + RES DSKY_WRBIT,B OUT (C),B NOP ; MAY NOT BE NEEDED - SET 1,B + SET DSKY_WRBIT,B OUT (C),B ; ; DEASSERT /CS @@ -458,7 +507,9 @@ DSKY_DIN2: CALL DSKY_PPIRD ; ; SETUP - LD C,PPIC + LD A,(PPI_BASE) + ADD A,PPIC + LD C,A ; ; SET ADDRESS FIRST LD A,DSKY_PPI_IDLE @@ -474,14 +525,18 @@ DSKY_DIN2: LD B,A ; ; ASSERT /RD - RES 2,B + RES DSKY_RDBIT,B OUT (C),B ; ; GET VALUE - IN A,(PPIA) + DEC C + DEC C + IN A,(C) + INC C + INC C ; ; DEASSERT /RD - SET 2,B + SET DSKY_RDBIT,B OUT (C),B ; ; DEASSERT /CS @@ -643,6 +698,27 @@ DSKY_READ1: DJNZ DSKY_READ1 RET ; +; +; +GET_BASE: + CALL PRTSTRD + .DB "\r\nDSKYng PPI base port [0x$" + LD A,(PPI_BASE) + CALL PRTHEXBYTE + CALL PRTSTRD + .DB "]: $" + LD A,(PPI_BASE) + CALL GETHEXBYTE + JR C,GET_BASE1 + LD (PPI_BASE),A + XOR A + RET +; +GET_BASE1: + CALL PRTSTRD + .DB "\r\nInvalid DSKYng PPI base port value!$" + JR GET_BASE +; ; OUTPUT CHARACTER FROM A ; COUT: @@ -651,7 +727,7 @@ COUT: PUSH DE ; PUSH HL ; -#IF BDOS +#IF (BDOS) LD C,2 ; BDOS FUNC: CONSOLE OUTPUT LD E,A ; CHARACTER TO E CALL $0005 ; CALL BDOS @@ -732,35 +808,6 @@ WAITKEY: JP Z,EXIT POP AF RET -; -; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE -; -HEXASCII: - LD D,A - CALL HEXCONV - LD E,A - LD A,D - RLCA - RLCA - RLCA - RLCA - CALL HEXCONV - LD D,A - RET -; -; CONVERT LOW NIBBLE OF A TO ASCII HEX -; -HEXCONV: - AND 0FH ;LOW NIBBLE ONLY - ADD A,90H - DAA - ADC A,40H - DAA - RET - - - - ; ;================================================================================================== ; UTILITY FUNCTIONS @@ -957,6 +1004,119 @@ PRTHEXWORDHL: POP AF RET ; +; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE +; +HEXASCII: + LD D,A + CALL HEXCONV + LD E,A + LD A,D + RLCA + RLCA + RLCA + RLCA + CALL HEXCONV + LD D,A + RET +; +; CONVERT LOW NIBBLE OF A TO ASCII HEX +; +HEXCONV: + AND 0FH ;LOW NIBBLE ONLY + ADD A,90H + DAA + ADC A,40H + DAA + RET +; +; +; +GETHEXBYTE: + PUSH AF ; SAVE INCOMING VALUE + LD C,0AH ; BDOS READ CONSOLE BUFFER + LD DE,CONBUF + CALL 5 ; GET EDITED STRING + CALL NEWLINE + POP DE ; RESTORE INCOMING TO D + + ; OK WE SHOULD NOW HAVE A STRING WITH A HEX NUMBER + LD HL,CONBUF + INC HL + LD A,(HL) ; GET CHARACTER COUNT + INC HL + CP 3 + JR C,GHB0 ; OK IF <= 2 CHARS + SCF ; SIGNAL ERROR + RET ; AND RETURN + +GHB0: + OR A ; SET FLAGS + JR NZ,GHB1 ; GOT CHARS, GO AHEAD + LD A,D ; RESTORE INCOMING VALUE + OR A ; SIGNAL SUCCESS + RET ; AND DONE + +GHB1: + LD B,A ; COUNT TO B + LD C,0 ; INITIAL VALUE + +GHB2: + LD A,(HL) ; GET NEXT CHAR + INC HL + CALL ISHEX + RET C ; ABORT ON NON-HEX CHAR + + ; OK WE ARE HERE WHEN WE HAVE A VALID CHARACTER (0-9,A-F,A-F) NEED TO CONVERT TO BINARY + ; CHARACTER IS STILL IN A + + CP 3AH ; TEST FOR 0-9 + JP M,GHB2C + CP 47H ; TEST FOR A-F + JP M,GHB2B + CP 67H ; TEST FOR A-F + JP M,GHB2A +GHB2A: SUB 20H ; CHARACTER IS A-F +GHB2B: SUB 07H ; CHARACTER IS A-F +GHB2C: SUB 30H ; CHARACTER IS 0-9 + + RLC C ; MULTIPLY CUR VALUE BY 16 + RLC C + RLC C + RLC C + ADD A,C ; ADD TO ACCUM + LD C,A ; PUT BACK IN C + + DJNZ GHB2 ; LOOP THRU ALL CHARS + + LD A,C ; INTO A FOR RETURN + OR A ; SIGNAL SUCCESS + RET ; DONE + +ISHEX: + CP 30H ; CHECK IF LESS THAN CHARACTER 0 + JP M,NOTHEX + CP 3AH ; CHECK FOR > 9 + JP M,ISHX1 ; OK, CHARACTER IS 1-9 + + CP 41H ; CHECK FOR CHARACTER LESS THAN A + JP M,NOTHEX + CP 47H ; CHECK FOR CHARACTERS > F + JP M,ISHX1 + + CP 61H ; CHECK FOR CHARACTERS < A + JP M,NOTHEX + + CP 67H ; CHECK FOR CHARACTER > F + JP M,ISHX1 +NOTHEX: + SCF ; SET CARRY TO INDICATE FAIL + RET + +ISHX1: + SCF + CCF + RET +; ; SHORT DELAY FUNCTIONS. NO CLOCK SPEED COMPENSATION, SO THEY ; WILL RUN LONGER ON SLOWER SYSTEMS. THE NUMBER INDICATES THE ; NUMBER OF CALL/RET INVOCATIONS. A SINGLE CALL/RET IS @@ -982,16 +1142,16 @@ ADDHLA: RET NC INC H RET - - - - - - ; ; STORAGE ; -DSKY_PPIX_VAL: .DB 0 +PPI_BASE: .DB PPI_BASE_DEF +; +CONBUF: .DB 8 ; MAXIMUM CHARS + .DB 0 ; COUNT + .FILL 8 ; SIZE OF BUFFER +; +PPIX_VAL: .DB 0 ; DSPBUF: .FILL 16,0 ; diff --git a/Source/ver.inc b/Source/ver.inc index 15d243c4..edf1acf5 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1.1-pre.91" +#DEFINE BIOSVER "3.1.1-pre.93" diff --git a/Source/ver.lib b/Source/ver.lib index da79ddcc..ab473ecc 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 1 rtp equ 0 biosver macro - db "3.1.1-pre.91" + db "3.1.1-pre.93" endm