; PDP_MON.mac by John Monahan (S100Computers.com) ; ; Assembled with AsmPDP.exe (windows) assembler. ; Note code cannot contain BASIC names like "PRINT" (Because the compiler was written in basic). ; Best to use lower case labels. ; ; Remember most port I/O's are 8 bits wide. If you send a word to an odd port you will trigger a CPU error/exception. ; Use MOVB x,y and not MOV x,y ; ; >>> For this monitor ALL S100 bus ports range from E000H - FFFFH. (The "Normal" S100 bus address range + E000H) <<< ; ; V0.1 1/11/2017 ;Initial code ; V0.11 3/4/2017 ;Run on V0.8 prototype board ; V0.12 3/4/2017 ;Corrected byte span routines for M,V, F etc and speech synthesis. ; V0.13 3/14/2017 ;Added XModem file download capability ; V1.0 4/3/2017 ;Corrected Serial port initilization for speech synthesizer ; V1.1 6/22/2017 ;Jump table for main menu, (started on TU58 UART) ; V1.11 6/22/2017 ;For XModem, send initial NAK for Telnet Tera Term program ; V1.12 6/30/2017 ;Fill out Interrupt routines in low RAM ; V1.13 6/30/2017 ;Fixed MemMap routine (0FF RAM bytes were showing up as empty) ; V1.14 6/30/2017 ;Continous 5 second beep done using timer on PDP-11 Support board ; V1.15 7/4/2017 ;Started on TU58 UART Interrupts ; V1.15a 7/31/2017 ;More on TU58 UART Interrupts ; V1.2 8/19/2017 ;Startup direct to S100 bus Console IO ; V1.3 10/5/2017 ;Added UART interrupts,enlarged the "W" command ; V1.31 10/8/2017 ;Query Port Output/inputs with 8 or 16 bits ("B" & "O" commands) ; V1.31 10/12/2017 ;Updated Ports I/O Test routine ; V1.41 11/01/2017 ;More extensive ports tests. ; V1.42 11/01/2017 ;TU58 UART Interrupt tests ; V1.43 11/03/2017 ;CON UART Interrupt tests ; V1.5 11/15/2017 ;Added Serial Ports Test. XModem now working correctly with CPU Board UART (9600 baud, 2 stop bits) ; V2.0 11/23/2017 ;Split into High/LOW "Page", Add DEC TU58 Tape Boot Loader code ; V2.1 12/13/2017 ;Added printer routines ; V2.2 12/16/2017 ;Split into HIGH & LOW Page ; V2.3 1/25/2018 ;Added ODT Console UART on Support Board option ; V2.31 1/28/2018 ;Added Global RAM flag (CONSOLE_IO_FLAG) for Console I/O redirection ; V2.32 2/4/2018 ;Updated the Tu58 Tape boot routine to recognize BREAK* function ; V2.33 2/4/2018 ;Updated the Memory Map routine. Move Serial Port test to High Page ; V2.34 2/21/2018 ;Tape boot from Diane's (Neisius) PDP Web Page ; V2.35 5/9/2108 ;Add Display valid I/O ports to 'O' menu ; ; ; Since V2.0 this monitor is now duplicated into two similar but not identical ; copies. IF you have the V2 PDP11 CPU S100 Board, the 4K monitor can reside in duplicate in an ; 8K 28C64 EEPROM (or 27C64 UV-ROM). There is the "normal" lower 4K monitor where the LA13 ; address line is low. This is the "normal" state upon reset (pin 2 of U12 & U13 is low, thereby ; selecting the lower 4K half of the 8K ROM. If you are using the original S100Computers Z80 CPU board this ; this is the setup. ; If you have the newer V2 board, inputting (anything) from to port E0E4H will raise the LA13 line ; thereby selecting the top 4K of the EEPROM. Inputting from to port E0E5H will bring back ; the lower 4K section again. ; ; So, there will be two "versions" of the monitor; LOW & HIGH. The LOW version will reside ; from 0-FFFH in the 28C64 EEPROM. The HIGH version will reside from 1000H-1FFFFH in ; the same 28C64 EEPROM. Clearly there must be code common to both sections. ; The page switching code is near the start of the monitor. It is ; at the location "PAGE_CHANGE:" and uses the "X" menu command. ; ; Both versions of the monitor have most of the same menu options. The main difference (so far) is ; the "HIGH" page image has the XModem routine (Menu "C") to download files directly into RAM ; from another computer over the ODT serial port, and the ability to boot a TU58 tape OS. The "LOW" page image has ; teh ability to test IO ports and various UART IO tests. ; ; This is the same "X" menu command approach we used for our MASTER Z80 monitor. Unfortunately this trick ; leads to some confusion in the assembly code. Relative jumps can be out of range etc. To help clearify what ; sections are common and those that are unique to the HIGH/LOW pages I use different columns for each component. ;Programming a Wellon VP-290 with 28C64's EEPROMS for HIGH & LOW Pages is quite tricky. You have 4 files in all. ;Burn two ROMs Even & Odd.... ; ;For the LOW PAGE image:- ;Assemble and make a .bin file using "ROM_HIGH_PAGE: equ FALSE". ; ;Do a "normal" EEPROM burn ; ;For File Mode use "Even" and Clear Buffer Options = 0xFF ;For "Leave the "File Address(Hex) as 0000 and the "To Buffer Address (HEX) as 0000H) ;For "Auto Format Detect" use bin ;Set the File size for a 28C64 as 2000H ; ;Repeat for the Odd bytes ;For File Mode use "Odd" and Clear Buffer Options = 0xFF ;For "Leave the "File Address(Hex) as 0000 and the "To Buffer Address (HEX) as 0000H) ;For "Auto Format Detect" use bin ;Set the File size for a 28C64 as 2000H ; ;We now need to ADD to both EEPROMS code for the HIGH page starting at 1000H in the ROM. ;It must not overwrite the LOW page code above. ; ;For the HIGH PAGE image:- ;Assemble and make a .bin file using "ROM_HIGH_PAGE: equ TRUE" ; ;Insert the EVEN Byte ROM and read it. This will place the ROM bytes 0-FFFH in memory. ;Load your HIGH page .bin file with:- ;For File Mode use "Even", and Clear Buffer Options = DISABLED ;Set the "File Address(Hex) as 1000 and the "To Buffer Address (HEX) as 0000H) ;For "Auto Format Detect" use bin ;The File size for a 28C64 is 1000H ; ;Insert the ODD Byte ROM and read it. This will place the ROM bytes 0-FFFH in memory. ;Load your HIGH page .bin file with:- ;For File Mode use "Odd" and Clear Buffer Options = DISABLED ;Set the "File Address(Hex) as 1000 and the "To Buffer Address (HEX) as 0000H) ;For "Auto Format Detect" use bin ;The File size for a 28C64 is 1000H ; ; ; Note the assembler strips off the (3F)xxxx from the I/O addresses xxxx below ; ; so they edffectively become E000-FFFFH and on the S100 bus Ports 0000-1F00H ; ODT_CONIN_STAT: equ &FF70 ; &o17777560 Will be converted to 1F70H by the CPU board ODT_CONIN_DATA: equ &FF72 ; &o17777562 ODT_CONOUT_STAT: equ &FF74 ; &o17777564 ODT_CONOUT_DATA: equ &FF76 ; &o17777566 DEBUG_CONIN_STAT: equ &FF10 ; Will be converted to 1F10H by the CPU board if Support Board ODT UART is active DEBUG_CONIN_DATA: equ &FF12 ; DEBUG_CONOUT_STAT: equ &FF14 ; DEBUG_CONOUT_DATA: equ &FF16 ; TU58_IN_STAT: equ &FF40 ; &o17777500 Will be converted to 1F40H by the CPU board TU58_IN_DATA: equ &FF42 ; &o17777502 TU58_OUT_STAT: equ &FF44 ; &o17777504 TU58_OUT_DATA: equ &FF46 ; &o17777506 TIMER_ADDRESS: equ &3FFF66 ; &o17777546 Timer port address on Support board (FF66=1F66) PSW: equ &3FFFFE ; CPU Program status word CPU_STACK: equ &BF00 ; Will place stack below ROMs CONSOLE_IO_FLAG: equ &BFFE ; FFFF = ALL CONSOLE IO TO ODT UART. ANYTHING ELSE TO S100 CONSOLE CON_CHAR_BUFFER: equ &BF80 ; Buffer location to capture characters from CONSOLE UART Interrupt CON_XMT_Flag: equ &BF7E ; RAM location for XMT flag (Byte) TU58_CHAR_BUFFER: equ &BF00 ; Buffer location to capture characters from TU58 UART Interrupt TU58_XMT_Flag: equ &BE7E ; RAM location for XMT flag (Byte) S100_CONIN_STAT: equ &E000 ; S100Computers Console IO Board In Status (translated to 0000H by CPU board) S100_CONIN_DATA: equ &E001 ; S100Computers Console IO Board In Data S100_CONOUT_STAT: equ &E000 ; S100Computers Console IO Board Out Status S100_CONOUT_DATA: equ &E001 ; S100Computers Console IO Board Out Data ACTL: equ &E0A1 ; Serial port on S100Computers Serial Board (Zilog SCC Chip) ADTA: equ &E0A3 BCTL: equ &E0A0 ; S100Computers Serial board speaker B CTL port (Zilog SCC Chip) BDTA: equ &E0A2 ; S100Computers Speaker B data port ROM_HIGH_PORT: equ &E0E4 ; Port to shadow in ROM High Page in the PDP address space via Port E4H ROM_LOW_PORT: equ &E0E5 ; Port to shadow in ROM Low Page in the PDP address space via Port E5H SW86: equ &E0ED ; Input from this port switches the PDP back to the Z80 in hardware SW86_TM: equ &E0EE ; Output 00H switch the PDP back to Z80 Hardware (on SMB V2,V3 boards) IOBYTE: equ &E0EF ; S100Computers SMB IOBYTE Port #if ST8C4 ; If S100_Parallel_IO Board for PRINTER OUTPUT PRN_CTRL: equ &E0C2 ; ST8C4 Control Port PRN_STATUS: equ &E0C1 ; ST8C4 Status port PRN_OUT: equ &E0C0 ; ST8C4 Data port PRN_ST_LOW: equ &0D ; OUT STROBE LOW PRN_ST_HIGH: equ &0C ; OUT STROBE HIGH #else LP11_XMT_Flag: equ &BE7C ; RAM location for Printer ACK flag (Byte) LP11_DATA: equ &FF4E ; RAM location for Printer data port. #endif BP_SOH: EQU &0 ; XMODEM equates BP_BLK_NO: EQU &2 ; BP Offset for Recieved Sector Number for XModem BP_INV_BLK_NO: EQU &4 BP_SECT_NO: EQU &6 ; BP Offset for CURRENT SECTOR NUMBER BP_CKSUM: EQU &8 BP_TIMEOUT: EQU &A FiveSeconds: EQU &10 ; Try Modem input for a max of 5 seconds CR: equ &0D LF: equ &0A BELL: equ &07 ESC: equ &1B SPACE: equ &20 SCROLL: equ &01 ; Set scrool direction UP. BELL: equ &08 TAB: equ &09 ; TAB ACROSS (8 SPACES FOR SD-BOARD) FF: equ &0C DELETE_CHAR: equ &7F BACKS: equ &08 SOH: equ &1 ; For Modem etc. EOT: equ &4 ACK: equ &6 NAK: equ &15 BIT7: equ &80 ; &o200 BIT4: equ &10 BIT2: equ &04 BIT1: equ &02 BIT0: equ &01 ROMS: equ TRUE ; Set to FALSE for test program running at 1000H in RAM (10000 Octal) DETAILED_INTS: equ TRUE ; Set to TRUE for detailed UART Interrupt data display. (Note characters must be entered slowly) ST8C4: equ FALSE ; FALSE if LP11 Printer output. TRUE (only) if output is to the S100_Parallel_IO Board. S100_ONLY: equ FALSE ; <----- If TRUE will skip checking to see if console IO should go to the UART ; will always sent to Console IO board (Switch K10 is ignored on the CPU board). ODT_ONLY: equ FALSE ; <----- If TRUE will skip checking and always send console IO to the ODT UART DEBUG_FLAG: equ TRUE ; Display extra info #if ROMS ORG &C000 ; Location of default onboard ROMS (&o140000) #else ORG &1000 ; Locate at 1000H for testing (Above PDP11 traps etc) #endif ;_________________________________________________________________________________________________________________________________ Start: MOV #CPU_STACK,SP ; LOW ROM & HIGH PAGEs: Setup stack at BF00H (Below ROM ORG at C000H) MOV #&00E0,@#PSW ; Block ALL Interrupts (Clear bits 7-5) JMP NoLowPageError Align ACTIVATE_HIGH_PAGE: ; <---- ARRIVE HERE FROM LOW PAGE NOP NOP JMP HIGH_Loop Align ACTIVATE_LOW_PAGE: ; <----- JUMP BACK TO LOW PAGE MOVB @#ROM_LOW_PORT,R1 ; Switch the LA13 Address line input to the ROMs LOW. MUST be to an even byte JMP NoLowPageError ; Will arrive here only IF no address line LA13 switch. Must be inactive (Check JP K12) ;_________________________________THE ABOVE CODE MUST NOT BE CHANGED __________________________________ ; Align HIGH_Loop: #if DEBUG_FLAG MOV #HPMsg,R5 ; "In HIGH PAGE RAM" JSR PC,PrStr ; Print string MOVB R3,R5 JSR PC,PutByte_R5 ; Print HEX Byte value in R5 JSR PC,ConCRLF #endif CMPB #&0,R3 BNE HIGH_PAGE1 JMP HIGH_IO_Tests ; RUN VARIOUS PORT IO TESTS HIGH_PAGE1: CMPB #&1,R3 BNE HIGH_PAGE2 JMP HIGH_XModem ; RUN XMODEM FILE TRANSFER PROGRAM HIGH_PAGE2: CMPB #&2,R3 BNE HIGH_MenuError JMP HIGH_Test_Serial ; TEST SERIAL PORT HIGH_MenuError: MOV #HMenu_Error,R5 ; Point Error Message in HIGH ROM JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE NoLowPageError: MOV #NoLowPageMsg,R5 ; "No address line LA13 switch active" JSR PC,PrStr ; Print string HALT ; ----------------------------- PORTS Test Routines (HIGH PAGE) -------------------------- Align HIGH_IO_Tests: ; MOV #&FFFF,@#CONSOLE_IO_FLAG ; FFFF = ALL CONSOLE IO TO ODT UART. ANYTHING ELSE THEN SEND TO S100 CONSOLE ; MOV @#CONSOLE_IO_FLAG,R5 ; JSR PC,PutWord_R5 MOV #Ports_MenuString,R5 ; Point to Ports Menu JSR PC,PrStr ; Print string JSR PC,ConCRLF ; Show CR,LF MOV #&3E,R0 ; Print '>' JSR PC,CONSOLE_OUT JSR PC,CONSOLE_IN ; Get a menu character (WITH ECHO) to R0 JSR PC,ToUpper ; a-z to A-Z MOV R0,R1 CMPB #ESC,R0 BEQ Low_Loop1 ; Abort if ESC returned JSR PC,CONSOLE_OUT ; Echo CMP R1,#&2F ; Test ASCII 0-7 BLE IO_MenuError CMP R1,#&37 ; Currently 0-6 only BHI IO_MenuError SUB #&30,R1 ; 0-6 ROL R1 ; X2 MOV #PORTS_TABLE,R5 ADD R1,R5 MOV (R5),PC IO_MenuError: MOV #IO_Menu_Error,R5 ; "Not a valid IO Menu Option" JSR PC,PrStr ; Print string Low_Loop1: JMP ACTIVATE_LOW_PAGE ; Back to low page Align PORTS_TABLE: ; For main Menu commands equw PORTS_IN_ByteL_Port_Test ; "0", Read Low Byte from port equw PORTS_IN_ByteH_Port_Test ; "1", Read High Byte from port equw PORTS_IN_Word_Port_Test ; "2", Read Word from port equw PORTS_OUT_ByteL_Port_Test ; "3", Write Low Byte to port equw PORTS_OUT_ByteH_Port_Test ; "4", Write High Byte to port equw PORTS_OUT_Word_Port_Test ; "5", Write Word to port equw CRT_IO_Test ; "6" Send ascii characters to port 1 (S100 bus Console) equw Valid_Ports ; "7" Display PDP11 valid I/O Ports equw IO_MenuError ; "8" PORTS_IN_ByteL_Port_Test: ; Ports Tests Menu, Sub-Menu 0" Continously read low byte from port MOV #Port_Msg,R5 ; "Enter Port #" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Get Port# CMPB #ESC,R0 BEQ PORTS_In_Test_Done ; Abort if ESC returned MOV R5,R4 ; Store Port location in R4 MOV #PortOK_Msg,R5 ; "(Hit Reset to stop test) Test port = " JSR PC,PrStr ; Print string MOV R4,R5 JSR PC,PutWord_R5 ; Print HEX word value in R5 JSR PC,ConCRLF PORTS_IN_Byte1: MOVB (R4),R5 ; In Port to R4 reg (note, BYTE) JSR PC,PutBits_R5 JSR PC,ConCRLF BR PORTS_IN_Byte1 ; Note must hit RESET to stop PORTS_IN_ByteH_Port_Test: ; "Ports Tests Menu, Sub-Menu 1" Continously read high byte from port MOV #Port_Msg,R5 ; "Enter Port #" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Get Port# CMPB #ESC,R0 BEQ PORTS_In_Test_Done ; Abort if ESC returned MOV R5,R4 ; Store Port location in R4 MOV #PortOK_Msg,R5 ; "(Hit Reset to stop test) Test port = " JSR PC,PrStr ; Print string MOV R4,R5 JSR PC,PutWord_R5 ; Print HEX word value in R5 JSR PC,ConCRLF PORTS_IN_Byte2: MOVB (R4),R5 ; In Port to R4 reg (note, BYTE) JSR PC,PutBits_R5 JSR PC,ConCRLF BR PORTS_IN_Byte2 ; Note must hit RESET to stop PORTS_IN_Word_Port_Test: ; "Ports Tests Menu, Sub-Menu 2" Continously read Word from port MOV #Port_Msg,R5 ; "Enter Port #" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Get Port# CMPB #ESC,R0 BEQ PORTS_In_Test_Done ; Abort if ESC returned MOV R5,R4 ; Store Port location in R4 MOV #PortOK_Msg,R5 ; "(Hit Reset to stop test) Test port = " JSR PC,PrStr ; Print string MOV R4,R5 JSR PC,PutWord_R5 ; Print HEX word value in R5 JSR PC,ConCRLF PORTS_IN_Word1: MOV (R4),R3 ; In Port to R4 reg (note, WORD) MOV R3,R5 JSR PC,PutBits_R5 ; Show high Byte SWAB R3 ; Swap upper byte to lower 8 bits MOV R3,R5 MOVB #&2C,R0 ; Space with a ',' JSR PC,CONSOLE_OUT JSR PC,PutBits_R5 ; Show low Byte JSR PC,ConCRLF BR PORTS_IN_Word1 ; Note must hit RESET to stop PORTS_In_Test_Done: MOV #CMD_Done,R5 ; "Test Done" JSR PC,PrStr ; Print string JMP HIGH_IO_Tests PORTS_OUT_ByteL_Port_Test: ; "Ports Tests Menu, Sub-Menu 3" Continously write low byte to port MOV #Port_Msg,R5 ; "Enter Port #" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Get Port# CMPB #ESC,R0 BEQ PORTS_In_Test_Done ; Abort if ESC returned MOV R5,R4 ; Store Port location in R4 MOV #PortOK_Msg,R5 ; "(Hit Reset to stop test) Test port = " JSR PC,PrStr ; Print string MOV R4,R5 JSR PC,PutWord_R5 ; Print HEX word value in R5 JSR PC,ConCRLF PORTS_OUT_Byte1: MOVB #&33,(R4) ; Send to Port 3's (note, BYTE) JSR PC,PutBits_R5 JSR PC,ConCRLF BR PORTS_OUT_Byte1 ; Note must hit RESET to stop PORTS_OUT_ByteH_Port_Test: ; "Ports Tests Menu, Sub-Menu 4" Continously write high byte to port MOV #Port_Msg,R5 ; "Enter Port #" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Get Port# CMPB #ESC,R0 BEQ PORTS_In_Test_Done ; Abort if ESC returned MOV R5,R4 ; Store Port location in R4 MOV #PortOK_Msg,R5 ; "(Hit Reset to stop test) Test port = " JSR PC,PrStr ; Print string MOV R4,R5 JSR PC,PutWord_R5 ; Print HEX word value in R5 JSR PC,ConCRLF PORTS_OUT_Byte2: MOVB #&24,(R4) ; Send to Port '$' (note, BYTE) JSR PC,PutBits_R5 JSR PC,ConCRLF BR PORTS_OUT_Byte2 ; Note must hit RESET to stop PORTS_OUT_Word_Port_Test: ; "Ports Tests Menu, Sub-Menu 5" Continously read Word from port MOV #Port_Msg,R5 ; "Enter Port #" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Get Port# CMPB #ESC,R0 BEQ PORTS_In_Test_Done ; Abort if ESC returned MOV R5,R4 ; Store Port location in R4 MOV #PortOK_Msg,R5 ; "(Hit Reset to stop test) Test port = " JSR PC,PrStr ; Print string MOV R4,R5 JSR PC,PutWord_R5 ; Print HEX word value in R5 JSR PC,ConCRLF PORTS_OUT_Word1: MOV #&2425,(R4) ; Send to Port '$' and '%' (note,WORD) JSR PC,PutBits_R5 ; Show high Byte SWAB R5 ; Swap upper byte to lower 8 bits MOVB #&2C,R0 ; Space with a ',' JSR PC,CONSOLE_OUT JSR PC,PutBits_R5 ; Show low Byte JSR PC,ConCRLF BR PORTS_OUT_Word1 ; Note must hit RESET to stop CRT_IO_Test: ; "Ports Tests Menu, Sub-Menu 6" MOV #IOTestMsg,R5 ; "Send character test string to port 01H, 80 times" JSR PC,S100_PrStr ; Print string DIRECTLY on S100 console MOV #81,R4 ; Do 80 lines IO_Test1: DEC R4 BEQ IO_Test_Done MOV #TestStr,R5 ; Point to string IO_Test2: MOVB (R5)+,R0 TSTB R0 BEQ IO_Test1 JSR PC,S100_CONSOLE_OUT ; Send directly to S100 Propeller Console I/O board (character in R0) JMP IO_Test2 IO_Test_Done: MOV #CMD_Done,R5 ; "Test Done" JSR PC,PrStr ; Print string JMP HIGH_IO_Tests Valid_Ports: ; 7, Display PDP11 valid INPUT Ports MOV #IOPortsMsg,R5 ; Valid PDP11 IO ports on the S100 bus are at:- JSR PC,PrStr ; Print R5 string DIRECTLY on S100 console MOV #IO_Err_Routine,@#&04 ; CPU Error reoutine (whenever the CPU calls the "Red Flag Error vector" @ 04H in RAM) BICB #&80,@#PSW ; Allow ALL Interrupts (Clear bits 7-5) MOV #&E000,R3 ; E000H up to FFFFH in R3 VPorts1: MOV #0,R0 ; Set flag for Interrupt routine MOV R3,-(SP) ; Save R3 MOV #&200,R1 MOV (R3),R2 ; Note this is a Word <-- At this point there will be a interrupt if an invalid port NOP NOP VPorts3: DEC R1 ; Delay for Interrupt/Display TST R1 BNE VPorts3 NOP NOP CMP #&FFFF,R0 BEQ BadPort ; Was not 0H->FFFF, so go to invalid port MOV R3,R5 JSR PC,PutWord_R5 MOV #IOPortsMsg2,R5 ; "H --> " + CR JSR PC,PrStr ; Print string on console MOV R2,R5 JSR PC,PutWord_R5 ; Port value MOV #IOPortsMsg3,R5 ; "H Valid Input Port. " + CR,LF VPorts2: JSR PC,PrStr ; Print string on console MOV (SP)+,R3 ; Get back R3 INC R3 ; Next (Word) Port value INC R3 TST R3 ; Will Wrapp from FFFF -> 0000H BNE VPorts1 JMP HIGH_IO_Tests BadPort: MOV R3,R5 JSR PC,PutWord_R5 MOV #IOPortsMsg4,R5 ; "H" + CR (only) BR VPorts2 IO_Err_Routine: ; Typically the CPU would come here if the is an undefined I/O port MOV R5,-(SP) ; This is the "Abort" interrupt location MOV R4,-(SP) MOV #&FFFF,R0 ; 0->FFFFH is a flag for an invalid port MOV (SP)+,R4 MOV (SP)+,R5 RTI ;-------------------------------------------------- XMODEM ---------------------------------------------------------- ; Download a file (from a PC) to S100 bus RAM. Note the UART used here ; is the PDP-11 CPU board UART, NOT our Serial IO Board Zilog SSC. ; If you wish to download from that serial conenction do so from ; the Z80 monitor, then bring up this monitor with "O" command Align HIGH_XModem: ; Note this is the converted 8086 Monitor code MOV #XModemMsg,R5 ; "Load a File from a PC...." JSR PC,PrStr ; Print string MOV SP,R4 ; R4 will be the Base Pointer (BP of 8086 code) SUB #100,R4 ; Drop it well below the stack for now MOVB #1,BP_SECT_NO(R4) ; Current sector/Blk MOV #RAMStart,R5 ; "Enter destination in RAM for data (up to 4 digits):" JSR PC,PrStr ; Print string JSR PC,GetWord_R5 ; Put Start Address in R3 MOV R5,R3 ; Store in R3 CMPB #ESC,R0 BNE XModem1 ; Abort if ESC returned JMP ACTIVATE_LOW_PAGE ; Back to low page ShowBlkInfo: MOV #RMSGMsg,R5 ; "WAITING FOR SECTOR # JSR PC,PrStr ; Print string MOVB BP_SECT_NO(R4),R5 ; Current sector/Blk# JSR PC,PutByte_R5 MOV #RAMMsg,R5 ; "H. If OK will write to RAM location " JSR PC,PrStr ; Print string MOV R3,R5 JSR PC,PutWord_R5 ; Load Address in R3 RTS PC ; Return XModem1: JSR PC,ConCRLF JSR PC,ShowBlkInfo MOV #NAK,R0 JSR PC,XMODEM_SEND_CHARACTER ; Send Back NAK for Telnet Tera Term program XModemLoop: MOVB #0,BP_SOH(R4) ; SOH store MOVB #0,BP_BLK_NO(R4) ; Current Block store MOVB #0,BP_INV_BLK_NO(R4) ; Inverted Current Block store MOVB #0,BP_CKSUM(R4) MOVB #&80,R2 ; 128 Byte Blocks JSR PC,XMODEM_GET_CHARACTER BCS XModemTimeout CMPB #SOH,R0 BEQ GOT_SOH CMPB #EOT,R0 BNE BAD_SOH JMP GOT_EOT ;All Done get out of loop GOT_SOH: JSR PC,XMODEM_GET_CHARACTER MOVB R0,BP_BLK_NO(R4) ; Store BLK# JSR PC,XMODEM_GET_CHARACTER; MOVB R0,BP_INV_BLK_NO(R4) ; Store Inverted BLK# XBlock: JSR PC,XMODEM_GET_CHARACTER ; Get 128 byte Block MOVB R0,(R3)+ DECB R2 BNE XBlock JSR PC,XMODEM_GET_CHKSUM ; Get File Checksum CMPB R0,BP_CKSUM(R4) BNE BAD_CKSUM MOVB BP_INV_BLK_NO(R4),R0 MOVB BP_BLK_NO(R4),R1 ADD R1,R0 CMPB #&FF,R0 BNE BAD_BLK INCB BP_SECT_NO(R4) ; Point to next BLK# JSR PC,ShowBlkInfo ; Update Screen Info MOV #ACK,R0 JSR PC,XMODEM_SEND_CHARACTER ; Send Back Block OK Acknowledge JMP XModemLoop ; Get next block until EOT signal XModemTimeout: MOV #TimeOutMsg,R5 ; "Timeout" JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE ; Back to low page BAD_SOH: MOV #NOSOH,R5 ; "Did not get SOH" JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE ; Back to low page BAD_BLK: MOV #XERR2,R5 ; "Bad BLK # in Header" JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE ; Back to low page BAD_CKSUM: MOV #XERR3,R5 ; "Bad Checksum for Sector" JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE ; Back to low page GOT_EOT: MOV #ACK,R0 JSR PC,XMODEM_SEND_CHARACTER ; Send Back Block OK Acknowledge to close out sender MOV #TRANS_DONE,R5 ; "Data Transfer Is Complete",CR,LF,LF,0 JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE ; Back to low page XMODEM_GET_CHARACTER: ; XMODEM SERIAL PORT GET CHARACTER ROUTINE MOV #FiveSeconds,R1 MOV #0,R0 XMODEM_IN1: BITB #BIT7,@#ODT_CONIN_STAT ; Check bit-7/ready of xmt status reg BNE XMODEM_IN2 DEC R0 BNE XMODEM_IN1 DEC R4 BNE XMODEM_IN1 SEC ; Timeout Set Carry RTS PC ; Return XMODEM_IN2: MOVB @#ODT_CONIN_DATA,R0 ; ASCII to R0 reg ADD R0,BP_CKSUM(R4) ; Add in to checksum CLC ; Carry clear indicating all OK RTS PC XMODEM_GET_CHKSUM: MOV #FiveSeconds,R1 MOV #0,R0 XMODEM_IN3: BITB #BIT7,@#ODT_CONIN_STAT ; Check bit-7/ready of xmt status reg BNE XMODEM_IN4 DEC R0 BNE XMODEM_IN3 DEC R1 BNE XMODEM_IN3 SEC ; Timeout Set Carry RTS PC ; Return XMODEM_IN4: MOVB @#ODT_CONIN_DATA,R0 ; Checksuum in R0 reg CLC ; Carry clear indicating all OK RTS PC XMODEM_SEND_CHARACTER: ;Modem Send Character back to UART ADD R0,BP_CKSUM(R4) ;CALC CKSUM NO MATTER WHAT JSR PC,ODT_CONSOLE_OUT RTS PC ; ----------------------------- TEST S100Computers Serial Port UART ---------------------------------------------- HIGH_Test_Serial: MOV #SERIAL_TEST_MSG,R5 ; Will show mesage explaining the test JSR PC,PrStr ; Print string JSR PC,InitSerialA ; Initilize the S100Computers Zilog Serial Port TEST_SERIAL1: ; COMMAND LOOP JSR PC,SERIAL_IN BCS TEST_SERIAL1 CMPB #ESC,R0 ; If ESC return to main Menu loop BEQ TEST_SERIAL_DONE JSR PC,CONSOLE_OUT ; Display on Console also JSR PC,SERIAL_OUT BCS SER_OUT_ERR BR TEST_SERIAL1 TEST_SERIAL_DONE: JSR PC,ConCRLF JMP ACTIVATE_LOW_PAGE ; Back to low page SER_OUT_ERR: MOV #SERIAL_OUT_ERR,R5 ; Will show mesage explaining the test JSR PC,PrStr ; Print string JMP ACTIVATE_LOW_PAGE ; Back to low page ; <<<< INPUT FROM SERIAL PORT on the S100Ccomputers.COM Serial I/O Board (Zilog UART) ; <<<< DATA Returned in R1. Carry Set if an error SERIAL_IN: JSR PC,SERIAL_IN_STAT ; Are we ready, No, then Carry Set BCC SERIAL_IN3 RTS PC ; Return from subroutine, R1 unchanged, Carry Clear SERIAL_IN3: MOVB @#ADTA,R0 ; Point to data port of Zilog serial chip CLC ; Return with Clear Carry to indicate success RTS PC ; Return from subroutine, char in R1 SERIAL_IN_STAT: MOVB #&5,@#ACTL ; Point to Control port of Zilog UART MOVB #&EA,@#ACTL ; Lower RTS line NOP NOP SERIAL_IN2: BITB #BIT0,@#ACTL BNE SERIAL_OK ; Get serial data if bit0 = 1 SEC ; Return with Set Carry to indicate an error after trying 512 times RTS PC ; Return from subroutine, Carry set SERIAL_OK: CLC RTS PC ; Return from subroutine, Carry clear ; <<<< OUTPUT TO SERIAL PORT on the S100Ccomputers.COM Serial I/O Board (Zilog UART) ; <<<< DATA Sent in R1. Carry Set if an error SERIAL_OUT: ; BYTE DATA is in R1 MOV R3,-(SP) ; Save R3 MOV #512,R3 ; Will check status 512 times (only) SERIAL_OUT_STAT: BITB #BIT2,@#ACTL ; Point to Control port of Zilog serial chip, Check serial port is ready BNE SEND_SERIAL ; Ready to send DEC R3 ; Decrease loop count TST R3 BNE SERIAL_OUT_STAT SEC ; Return with Set Carry to indicate an error after trying 512 times SERIAL_DONE: MOV (SP)+,R3 ; Restore R3 RTS PC ; Return from subroutine, char in R1 SEND_SERIAL: MOVB R0,@#ADTA ; Point to data port of Zilog serial chip CLC ; Return with Clear Carry to indicate success BR SERIAL_DONE InitSerialA: ; Initilize the S100Computers Serial board Serial port MOVB #ACTL,R1 ; Serial board CTL port (Zilog SCC Chip) MOVB #&04,(R1) ; Point to WR4 MOVB #&44,(R1) ; X16 clock,1 Stop,NP MOVB #&03,(R1) ; Point to WR3 MOVB #&C1,(R1) ; Enable reciever, Auto Enable, Recieve 8 bits MOVB #&05,(R1) ; Point to WR5 MOVB #&EA,(R1) ; Enable, Transmit 8 bits MOVB #&0B,(R1) ; Set RTS,DTR, Enable. Point to WR11 MOVB #&56,(R1) ; Recieve/transmit clock = BRG MOVB #&0C,(R1) ; Point to WR12 MOVB #&02,(R1) ; Low byte 38,400 Baud <<<<<<<<<<< for XModem I/O (Port A) ; MOVB #&06,(R1) ; Low byte 19,200 MOVB #&0D,(R1) ; Point to WR13 MOVB #&00,(R1) ; High byte for Baud MOVB #&0E,(R1) ; Point to WR14 MOVB #&01,(R1) ; Use 4.9152 MHz Clock. MOVB #&0F,(R1) ; Point to WR15 MOVB #&00,(R1) ; Generate Int. with CTS going high RTS PC ; Return ;---------------------------------------- SUPPORT ROUTINES --------------------------------------------------- ; Remember we cannot access these equivalent routine in the LOW ROM ; page from here. We have to replecate them in this HIGH ROM page GetWord_R5: ; Get a WORD HEX value from Console to R5 CLR R0 CLR R5 GetWord1: JSR PC,GetNibble_R5 CMPB #CR,R0 BEQ GetWordDone CMPB #SPACE,R0 BEQ GetWordDone CMPB #ESC,R0 BEQ GetWordDone BR GetWord1 ; Note will return the last 4 valid hex characters GetWordDone: ; up to a CR, ',' or SPACE RTS PC ; 0 in R0 if all OK, ESC if invalid character GetByte_R5: ; Get a BYTE HEX value from Console to R5 CLR R0 CLR R5 JSR PC,GetNibble_R5 CMPB #CR,R0 BEQ GetByteDone CMPB #SPACE,R0 BEQ GetByteDone CMPB #ESC,R0 BEQ GetByteDone JSR PC,GetNibble_R5 CMPB #ESC,R0 BEQ GetByteDone ; Abort if ESC returned JSR PC,CONSOLE_IN ; Character to R0 GetByteDone: RTS PC ; N clear if all OK, N set if invalid character GetNibble_R5: ; Get a NIBBLE HEX CHARACTER from Console to R5 CLR R0 JSR PC,CONSOLE_IN CMPB #ESC,R0 ; Was an abort requested BEQ NibbleError CMPB #CR,R0 BEQ NibbleCR CMPB #SPACE,R0 BEQ NibbleSPACE CMPB #&2C,R0 ; Check for ',' BEQ NibbleCOMMA JSR PC,ToUpper JSR PC,CONSOLE_OUT ; Echo data SUB #&30,R0 ; '0' to 0, '1' to 1... BLT NibbleError CMPB #&09,R0 BGE NibbleDone SUB #&7,R0 CMPB #&0F,R0 ; Greater than 'F' in invalid BLT NibbleError NibbleDone: ASL R5 ; Shift R5 up a nibble ASL R5 ASL R5 ASL R5 BIS R0,R5 ; OR in the high nibble of what will be the high byte CLR R0 RTS PC ; Return with Nibble in R5, 0 in R0 NibbleCR: MOV #CR,R0 RTS PC ; Return with CR in R0 NibbleSPACE: JSR PC,CONSOLE_OUT ; Echo data MOV #SPACE,R0 RTS PC ; Return with SPACE in R0 NibbleCOMMA: JSR PC,CONSOLE_OUT ; Echo data MOV #CR,R0 RTS PC ; Return with CR in R0 NibbleError: MOV #&3F,R0 ; Send "?' JSR PC,CONSOLE_OUT MOV #ESC,R0 RTS PC ; Return with ESC in R0 PutWord_R5: ; Print HEX Word value in R5 SWAB R5 ; Value in R5 is retained JSR PC,PutByte_R5 ; Print HEX byte value in R5 SWAB R5 JSR PC,PutByte_R5 RTS PC PutByte_R5: ; Print HEX Byte value in R5 CLR R0 ; Clear R0 MOVB R5,R0 ; Origional number to R0 ROR R0 ; Shift upper byte to lower 4 bits ROR R0 ROR R0 ROR R0 ; Upper nibble is now lower nibble JSR PC,HexOut MOV R5,R0 JSR PC,HexOut RTS PC HexOut: ; Print Hex Byte value in R0 BICB #&F0,R0 ; Clear upper nibble ADD #&30,R0 ; CONVERT TO ASCII CMPB #&39,R0 ; See if > 9 BGE HexOK ADD #&07,R0 ; Add to make 10=A, 11=B... HexOK: JSR PC,CONSOLE_OUT RTS PC PutBits_R5: ; Print 8 bits in R5. MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOVB #8,R2 ; 8 bits across MOVB #&80,R3 ; test bit MOVB R5,R4 BitTst: BITB R3,R4 BEQ Bit8L MOVB #&31,R0 ; '1' BR Bits8 Bit8L: MOVB #&30,R0 ; '0' Bits8: JSR PC,CONSOLE_OUT CLC RORB R3 ; Shift test bit right one bit DECB R2 BNE BitTst MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 RTS PC ToUpper: ; >>> ;a-z to A-Z CMP #&61,R0 ; less than 'a' BGT SkipToU CMP #&7A,R0 ; Greater tha 'z' BLT SkipToU SUB #&20,R0 ; Adjust SkipToU: RTS PC And_R0_R1: ; Bitwise AND r0 and r1, result in R1 COM R0 COM R1 BIS R0,R1 COM R1 RTS PC ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ODT & S100 BUS CONSOLE I/O ROUTINES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< PrStr: MOVB (R5)+,R0 ; >>> Print String Routine to ODT (or S100 Console) BEQ PrStr1 JSR PC,CONSOLE_OUT BR PrStr ; Next character PrStr1: RTS PC ; return S100_PrStr: MOVB (R5)+,R0 ; >>> Print String Routine direct to S100 Console BEQ PrStr2 JSR PC,S100_CONSOLE_OUT BR S100_PrStr PrStr2: RTS PC ; return ConSPACE2: ; >>> Send SPACE+SPACE to ODT or S100 console MOVB #SPACE,R0 JSR PC,CONSOLE_OUT ConSPACE1: MOVB #SPACE,R0 JSR PC,CONSOLE_OUT RTS PC ; Note R0 contains ASCII ctaracter (as a Byte) HConCRLF: ; >>> Send 'H' to ODT or S100 console MOVB #&48,R0 ; then fall through to CR/LF JSR PC,CONSOLE_OUT ConCRLF: ; >>> Send CR+LF to ODT or S100 console MOVB #CR,R0 JSR PC,CONSOLE_OUT ConLF: ; >>> Send LF to ODT or S100 console MOVB #LF,R0 JSR PC,CONSOLE_OUT RTS PC ; Note R0 contains ASCII character (as a Byte) ;----------------------------------------------------------------------------------------------------------- CONIN_STATUS: ; Check if Character at Console, Set Carry if true #if S100_ONLY BR S100_CONIN_STATUS ; Force input from S100 bus always #endif #if ODT_ONLY BR ODT_CONIN_STATUS ; Force input from ODT UART always #endif CMP #&FFFF,@#CONSOLE_IO_FLAG ; FFFF = ALL CONSOLE IO TO ODT UART. ANYTHING ELSE THEN SEND TO S100 CONSOLE BEQ ODT_CONIN_STATUS BR S100_CONIN_STATUS ; If not go to the default ODT routine in the CPU S100_CONIN_STATUS: BITB #BIT1,@#S100_CONIN_STAT ; Check bit-1/ready of Propeller board Console In port (0H) ODT_STAT1: BEQ S100_Nothing ; Nothing there while bit-1 is 0 SEC ; Set Carry Flag if ESC RTS PC ; Return with Carry Set if a character is available S100_Nothing: CLC ; Return with Carry flag cleared RTS PC ; Return ODT_CONIN_STATUS: BITB #BIT7,@#ODT_CONIN_STAT ; Check bit-7/ready of xmt status reg BR ODT_STAT1 ;----------------------------------------------------------------------------------------------------------- ConCheckESC: ; Check if ESC key was pressed on console #if S100_ONLY BR S100_ConCheckESC ; Force input to S100 bus always #endif #if ODT_ONLY BR ODT_ConCheckESC ; Force input to ODT UART always #endif CMP #&FFFF,@#CONSOLE_IO_FLAG ; FFFF = ALL CONSOLE IO TO ODT UART. ANYTHING ELSE THEN SEND TO S100 CONSOLE BEQ ODT_ConCheckESC BR S100_ConCheckESC ; If not go to the default ODT routine in the CPU S100_ConCheckESC: BITB #BIT1,@#S100_CONIN_STAT ; Check bit-1/ready of Propeller board Console In port (0H) BEQ S100_NoESC ; Nothing there while bit-1 is 0 MOVB @#S100_CONIN_DATA,R0 ; ASCII to R0 reg CMPB #ESC,R0 BNE S100_NoESC SEC ; Set Carry Flag if ESC RTS PC ; Return with ESC in R0 S100_NoESC: CLC ; Return with Carry flag cleared RTS PC ; Return ODT_ConCheckESC: BITB #BIT7,@#ODT_CONIN_STAT ; Check bit-7/ready of xmt status reg BEQ ODT_NoESC ; busy-loop while bit-7 is 0 MOVB @#ODT_CONIN_DATA,R0 ; ASCII to R0 reg CMPB #ESC,R0 BNE ODT_NoESC SEC ; Set Carry Flag if ESC RTS PC ; Return with ESC in R0 ODT_NoESC: CLC ; Return with Carry flag cleared RTS PC ; Return ;----------------------------------------------------------------------------------------------------------- CONSOLE_OUT: ; >>> MAIN Console output routine. Data in R0, return unchanged <<<< #if S100_ONLY ; BR S100_CONSOLE_OUT ; Force output to S100 bus always #endif #if ODT_ONLY BR ODT_CONSOLE_OUT ; Force output to ODT UART always #endif CMP #&FFFF,@#CONSOLE_IO_FLAG ; FFFF = ALL CONSOLE IO TO ODT UART. ANYTHING ELSE THEN SEND TO S100 CONSOLE BEQ ODT_CONSOLE_OUT BR S100_CONSOLE_OUT ; If not go to the default ODT routine in the CPU S100_CONSOLE_OUT: ; S100 Bus Console output routine <<<< BITB #BIT2,@#S100_CONOUT_STAT ; Check bit-2/ready of Propeller board Console Out port (0H) BEQ S100_CONSOLE_OUT ; busy-loop while bit-2 is 0 MOVB R0,@#S100_CONOUT_DATA ; Send ASCII to Propeller board Console Out port (01H) RTS PC ; Note R0 contains ASCII ctaracter (as a Byte) ODT_CONSOLE_OUT: ; ODT Console Out Routine BITB #BIT7,@#ODT_CONOUT_STAT ; Check bit-7/ready of xmt status reg BEQ ODT_CONSOLE_OUT ; busy-loop while bit-7 is 0 MOVB R0,@#ODT_CONOUT_DATA ; send ASCII to xmt data reg RTS PC ; Note R0 is still valid (as a Byte) TU58_UART_OUT: BITB #BIT7,@#TU58_OUT_STAT ; Check bit-7/ready of TU58 xmt status reg BEQ TU58_UART_OUT ; busy-loop while bit-7 is 0 MOVB R0,@#TU58_OUT_DATA ; Send ASCII to TU58 xmt data reg RTS PC ; Note R0 is still valid (as a Byte) ;----------------------------------------------------------------------------------------------------------- CONSOLE_IN: ; >>> MAIN Console input routine. Data in R0, return unchanged <<<< #if S100_ONLY BR S100_CONSOLE_IN ; Force input to always come from teh S100 bus #endif #if ODT_ONLY BR ODT_CONSOLE_IN ; Force input to always come from ODT UART #endif CMP #&FFFF,@#CONSOLE_IO_FLAG ; FFFF = ALL CONSOLE IO TO ODT UART. ANYTHING ELSE THEN SEND TO S100 CONSOLE BEQ ODT_CONSOLE_IN BR S100_CONSOLE_IN ; If not go to the default ODT routine in the CPU S100_CONSOLE_IN: ; S100 Bus Console input routine <<<< BITB #BIT1,@#S100_CONIN_STAT ; Check bit-1/ready of Propeller board Console In port (0H) BEQ S100_CONSOLE_IN ; Nothing there while bit-1 is 0 MOVB @#S100_CONIN_DATA,R0 ; Get ASCII from Propeller board Console In port (01H) RTS PC ; Note R0 contains ASCII ctaracter (as a Byte) ODT_CONSOLE_IN: ; ODT Console In Routine BITB #BIT7,@#ODT_CONIN_STAT ; Check bit-7/ready of xmt status reg BEQ ODT_CONSOLE_IN ; Nothing there while bit-7 is 0 MOVB @#ODT_CONIN_DATA,R0 ; ASCII to R0 reg RTS PC ; Return TU58_UART_IN: ; TU58 UART In Routine BITB #BIT7,@#TU58_IN_STAT ; Check bit-7/ready of TU58 xmt status reg BEQ TU58_UART_IN ; Nothing there while bit-7 is 0 MOVB @#TU58_IN_DATA,R0 ; ASCII to R0 reg RTS PC ; Return ;---------------------------------------------------------------------------------------------- Align Ports_MenuString: equs CR,LF equs "IO PORTS MENU.",CR,LF equs "0 = Input byte from EVEN Port",CR,LF equs "1 = Input byte from ODD Port",CR,LF equs "2 = Input WORD from from EVEN Port",CR,LF equs "3 = Output byte to EVEN Port",CR,LF equs "4 = Output byte to ODD Port",CR,LF equs "5 = Output WORD to EVEN Port",CR,LF equs "6 = Send string to Console Port E001H (01H), 80 times",CR,LF equs "7 = Display PDP11 Valid Ports",CR,LF equs "ESC = Return to Main Menu",CR,LF,0 HPMsg: equs CR,LF,"Jump to code in HIGH PAGE ROM area",CR,LF,0 Flush_Msg: equs CR,LF,"FF to Printer",CR,LF,0 HMenu_Error: equs CR,LF,"Menu error in High ROM page",CR,LF,BELL,0 CMD_Done: equs CR,LF,"Test Finished",CR,LF,0 Port_Msg: equs " <--- Menu Item Selected. Enter Port # (XXXXH)+CR ",0 PortOK_Msg: equs CR,LF,"(Hit Reset to stop test) Test port = ",0 IO_Menu_Error: equs CR,LF,"Not a valid IO Ports Menu option. Returning to the Monitor Main Menu",CR,LF,LF,BELL,0 IOTestMsg: equs CR,LF,"Send character string to port E001H, 80 times",CR,LF,0 TestStr: equs CR,LF," !#$%&'()*+,-./0123456789@ABCDEFGHIJKLMNOPQRST abcdefghijklmnoqrstuvwxyz",CR,LF,0 XModemMsg: equs CR,LF,"Load a File from a PC into RAM",CR,LF,0 RAMStart: equs CR,LF,"Enter RAM address (up to 4 digits): ",0 StartMsg: equs CR,LF,"Will load data at RAM location ",0 HCRLFMsg: equs "H",CR,LF,0 RMSGMsg: equs CR,LF,"Waiting for Block# ",0 RAMMsg: equs "H. If OK will write to RAM at ",0 NOSOH: equs CR,LF,"Did not get SOH",CR,LF,BELL,0 XERR2: equs CR,LF,"Bad Block# in Header",CR,LF,BELL,0 XERR3: equs CR,LF,"Bad Checksum for Block",CR,LF,BELL,0 TRANS_DONE: equs CR,LF,LF,"Transfer Is Complete",CR,LF,LF,0 TimeOutMsg: equs CR,LF,"Timeout.",BELL,0 SERIAL_TEST_MSG: equs CR,LF,"Serial Ports test. Assumes Zilog SSC Ports A1H & A3H at 38,400 Baud.",CR,LF,0 SERIAL_OUT_ERR: equs CR,LF,"Timeout error",CR,LF,0 NoLowPageMsg: equs CR,LF,"ROM Address line LA13 switch not active (Check JP K12). CPU Halted.",CR,LF,BELL,0 IOPortsMsg: equs CR,LF,"Valid PDP11 INPUT Ports:-",CR,LF,0 IOPortsMsg2: equs "H --> ",0 IOPortsMsg3: equs "H Valid Input Port.",CR,LF,0 IOPortsMsg4: equs "H",CR,0 Align #if ROMS END_OF_HIGH_ROM: equs "EENNDD__OOFF__HHIIGGHH__RROOMM ((EOVDEDN BBYYTTEESS)) @@ CC000000HH ------>>",0 #else END_OF_HIGH_ROM: equs "EENNDD__OOFF__HHIIGGHH__RROOMM ((EOVDEDN BBYYTTEESS)) @@ 11000000HH ------>>",0 #endif ;END