; ; MASTER.Z80 This is the Z80 CPU main monitor program for my system. ; Assemble and SLR's Z80ASM Assembler (Can also use the Cromemco Assembler) ; Use:- Z80ASM MASTER FH ; ; Since V5.4, this monitor is now split into two sections. ; IF you have the V2 Z80 CPU S100 Board, the 4K monitor can reside in two 4K "Pages" in an ; 8K 28C64 EEPROM (or 27C64 UV-ROM). There is the "normal" lower 4K monitor where the A12 ; address line is low. This is the "normal" state upon reset (pin 16 of U17 is low which ; via P39, 7-8 will pull A12 of the EEPROM 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, outputting to port D3H with bit 1 high, will raise the A12 line ; thereby selecting the top 4K of the EEPROM. Outputting to port D3H with bit 1 low, will bring back ; the lower 4K section again. ; ; Code for the two "versions" of the monitor are: MASTER0 & MASTER1. The LOW version (MASTER0) will ; reside from 0-FFFH in a 28C64 EEPROM. The HIGH (MASTER1)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 "ACTIVATE_HIGH_PAGE:" and "ACTIVATE_LOW_PAGE". (See below) ; ; Currently almost all menu options are in the LOW PAGE of the ROM. However because of its ; size, the XModem routine (Menu "X") to download files directly into RAM from another computer ; (over a serial port) resides in the HIGH PAGE. Almost half of the HIGH PAGE is now free for ; further routines. ; ; To assemble under windows..... ; Load Altair.EXE in the Windows CMD box ; do cpm3 ; I: ; I:>Submit master0 ; I:>Submit master1 ; ; Master0.HEX and Master1.HEX are written back to the same windows folder that the PC file "altair.exe" is in. ; If this is not clear see here:- (http://s100computers.com/Software%20Index%20Page.htm) ; ; Programming an EEPROM for the V2-Z80 Board with a PROM burner is a little tricky. ; Using a 28C64 EEPROM and a Wellon VP-290 (or later versions) ; For a monitor at F000H-FFFFH:- ; Load the MASTER0.HEX file, (Make sure the ORG is F000H). ; ; Clear Buffer Options:- 00 ; Load Buffer Address :– 0000 ; From File address use:- F000H ; File Size use:- 1000H ; This will put the code (4K) in the lower “half” of the 8K EEPROM, (usually a 28C64). It can be seen/edited ; at 0000H in the ROM with the Wellon software. You can run this ROM on the S100Computers V2 Z80 CPU board ; just make sure P39 is jumpered just 3-4 (PROM address line A12 always low). You can also run it on our earlier ; Z80 CPU Boards. You can use all your Z80 monitor commands except (currently) the X Command. ; ; To burn an EEPROM that adds code to the upper half of the PROM (and has the XModem command): ; Load the MASTER1.HEX file, Make sure the ORG is F000H. Carefully set the following burner settings ; ; Clear Buffer Options:- Disable <-------- Note ; Load Buffer Address :– 1000 ; From File address use:- F000H ; File Size use:- 1000H ; ; Examine the code to be burnt to the EEPROM, It should start at 0H and Run to 1FFFH with the ; early code at 0h the same as at 1000H. ; ; ; Recent History... ; 26/2/09 Added ability to switch CO/CI to ACIA serial from PC. ; 5/3/09 Adjust RTS/CTS levels for Modem ; V3.5 6/3/09 Set talker messages for new V-Stamp chip. ; 12/09/09 Add SD Systems IO-8 board Serial ports. ; V3.52 16/9/09 Add SD Systems IO-8 Board clock display on signon ; v3.6 21/9/09 Add display command for greater than 64K RAM, removed ; V4.0 10/26/09 Switched in 8255 driven IDE HD Controller (Removed XComp) ; some old commands to make more room. ; V4.1 11/7/09 Added input ports scan/diagnostic ; V4.2 11/14/09 Remove Date (keep time) from Clock (Chip is messed up by CPM3 routine) ; also modified to switch from the SD System assembler to the SLR one. ; V4.21 11/17/09 Removed 8086 jump far setting code ; V4.3 11/18/09 Implement movement of 8086 Monitor code (EPROM) to correct location in RAM space ; V4.31 11/19/09 Check 8086 Monitor ROM->ROM went OK. Added W command. ; V4.32 12/7/09 Turn off any SD Systems 8024 video screen enhancements (flashing, underline etc). ; V4.33 12/25/09 Correct High/Low byte Sector read for IDE board ; V4.34 2/23/10 "O" command, 8086 Far jump to 500H (IF RAM @ FFFF0H), W command boots 8086 from reset at FFFF0H. ; V4.35 3/25/10 "O" command just puts 8086 Far JMP to 500H (IF RAM @ FFFF0H). Done also at each reset. ; V4.4 7/29/10 Removed all SD Systems IO-8. Added S-100Computers I/O board drivers. ; V4.41 7/29/10 Initilization of V-Stamp chip done. Cleaned up Serial port names etc ; V4.42 7/31/10 Switched RTC over to S-100Computers board (Ports A4,A5) ; V4.50 2/7/11 Added Floppy Boot loader for ZFDC board. Still have the Versafloppy loader but no BIOS functions ; V4.51 2/13/11 Check IDE if Boot sector is valid ; V4.52 2/15/11 Pulse CF/IDE cards twice to reset (some) cards properly ; V4.53 2/16/11 Initilize IDE board with IDE RD/WR lines inactive on power-up. ; V4.54 2/28/11 Incoporated new fast multi-sector boot for CPM floppy loading with ZFDC board ; V4.55 2/28/11 "O" command now jumps to SWITCH_8086 (activates 8086) when done ; V4.55a 3/1/11 "O" cmd will just put 33 on Console (temporary 8086 board test) ; V4.56 3/15/11 Re-did IDE drive hardware reset pulse to one (delayed) pulse, then wait for drive ready status. ; V4.57 6/3/11 Set up an equate for IDE drive reset pulse, Fixed Z command (Last version using MM58167 RTC chip) ; V4.6 11/27/11 Switched to Dallas Semiconductor/IBM-PC CMOS-RTC chip & MSDOS Support board for time & dates ; V4.7 3/26/12 Cleaned up IOBYTE options. Added 68000 CPU, I/O to serial port. ; V4.8 10/27/12 Corrected SERIAL_STAT: error. Further cleaned up info on IOBYTE ; V4.9 11/3/12 Added ability (XH, XL) Command to switch to low/high pages in 28C64 EEPROMS (for V2 Z80 Board) ; V5.0 12/18/13 Add "C" menu option to download a ZModem file from a PC/Serial/USB port directly to RAM ; V5.01 12/30/13 Add PC-Printer routines for new parallel Port Board with ST8C34 chip (ST8C4 = TRUE) ; V5.02 1/31/14 Allow output to port EEH 01h activate TMA0* (8086,80286,80386 Boards) and 02h TMA1* (68000 Board) ; V5.03 7/25/2014 Removed error in Z memu command ; V5.04 7/29/2014 Patched date to show correct century ; V5.1 3/18/2015 Added to test module to output "3" on console with 8986 reset (UP8086:) in High RAM section ; V5.2 12/17/2016 Change master/slave signon message ("O" commamd) for more general use (multiple slave CPU boards) ; V5.3 11/27/2017 Fix bug for console I/O to serial port if no Propeller Console I/O board is present ; V5.4 12/20/2017 Completely re-did HIGH/LOW ROM page approach. Page menus are now completely transparent to user ; V5.5 7/26/2019 Corrected Monitor Print Signon with printer active. (Was sending continous 0's, Printer LO: inbalance) ; V5.6 2/23/2021 Added IDE Menu for FPGA_DC Board ; V5.7 2/23/2021 Added Serial Board USB port for XModem downloads (X CMD) instead of the serial port. ; V5.8 3/24/2024 Added FPGA_VGA_LCD interface ; V6.0 10/26/2025 Major code rearrangements to make more Low ROM space. Remove old CPM V1.4 jump table at start and at F800H ; V6.1 10/26/2025 Simplifiy the "B", "O" and "W" commands into one "O" command with TMA 0-3 options ; V6.2 10/26/2025 All multiple ways to download code from a PC to this S100 System (Serial/USB) (X command) ; V6.3 10/27/2025 Reduced modem data transfers from PC to 19,200 baud ; V6.4 10/28/2025 Added Wayne Warthen's code to boot his ROMWBW Disk OS Package on CF & SD Cards ; V6.5 12/04/2025 Check for Console IO via USB port on V3 Z80 CPU Board. IOBYTE & Port E8H ; V6.51 12/04/2025 Added "B" to identify S100 Boards in the bus. ; V6.52 12/04/2025 Add "I" command to boot CPM3 from Dual SD card Board. No IDE/CF board required ; V6.6 12/07/2025 Changed IOBYTE to better detect Console IO. ; FALSE EQU 0 TRUE EQU NOT FALSE BASE EQU 0F000H ;Start or EPROM Location (Assume a 2732 or half of a 28C64) ;Note can test running in CPM (set ORG to 100H), BUT disable setting the stack ;by commenting out the 4 lines below SETUP_STACK: ORG BASE ;<--------<<<<<< LOCATION OF START OF MONITOR (First part) ;Normally this monitor will reside at F000H ;The CPM (V1.2) jump table will be at F800H forn some old software I have. ;Note. This is not a requirement for all my recent software/CPM3. ST8C4 EQU TRUE ;TRUE if S100_Parallel_IO Board. False if IMSAI PIO Board ;in this ROM. Most users can set this option to FALSE V3_Z80CPU_BOARD EQU TRUE ;TRUE if the S100Computers V3 Z80 CPU board is present SCROLL EQU 01H ;Set scrool direction UP. BELL EQU 07H SPACE EQU 20H TAB EQU 09H ;TAB ACROSS (8 SPACES FOR SD-BOARD) CR EQU 0DH LF EQU 0AH FF EQU 0CH QUIT EQU 11H ;Turns off any screen enhancements (flashing, underline etc). NO_ENHANCEMENT EQU 17H ;Turns off whatever is on FAST EQU 10H ;High speed scrool ESC EQU 1BH DELETE EQU 7FH BACKS EQU 08H CLEAR EQU 1AH ;TO CLEAR SCREEN RST7 EQU 38H ;RST 7 (LOCATION FOR TRAP) NN EQU 0H ;[I] INITIAL VALUE SOH EQU 1 ; For XModem etc. EOT EQU 4 ACK EQU 6 NAK EQU 15H STARTCPM EQU 100H ;LOCATION WHERE CPM WILL BE PLACED FOR COLD BOOT STARTDOS EQU 100H ;LOCATION WHERE MSDOS WILL BE PLACED FOR COLD BOOT FFILE_SIZE EQU 9000h/512 ;SIZE OF 5MSDOS20.COM IN 512 BYTE SECTORS ; ; ;IOBYTE = SENSE SWITCHES AT PORT 0EFH ; Note this Monitor assumes tha if there is no IOBYTE hardware port at 0EFH on the bus the Z80 ; will read the port input as 0FFH ; ; BIT MAP OF PORT 0EFH:- ; X X X X X X X X (11111111=NORMAL CONFIG) ; | | | | | | | |..For Z80 Monitor, 0=CONSOLE DATA TO PRINTER ALSO ; | | | | | | |....For 8086 Monitor, 0=Force MSDOS Console output to CGA/VGA Board ; | | | | | |......For 8086 Monitor, 0=Do not initialize MSDOS extra ROMS ; | | | | |........Unused ; | | | |.............................. Console Device ; | | 11: Propeller Console IO Board ; | | 01: Serial IO Board LP USB port ; | | 10: Serial I/O Board SCC Port A (19.2K, 1 Stop, NP) ; | | 00: VGA/PS2 Keyboard ; | | ; | | Note if the V3 Z80 CPU Board K8 jumper is jumpered 2-3 all Console IO will ; | | go to the USB port (ignoring this IOBYTE bits 5&6). ; | |...............For Z80 Monitor 0=Write protect Electralogics "Quasi-Disk" Memory disk for CPM3 ; |.................For 8086 Monitor, 0=Prevent doing a JMPF to 500H after 8086 reset (to CPM86 boot) ; Normally a test is made to see if the CPM86 Boot is already in RAM at 500H ; If it is, a 8086 reset will bypass the monitor and go directly there. ; (see Init: in 8086 Monitor) ; Note if 00xxxxxx, This will force hardware diagnostic in the 8086 Monitor (See code at FFFF0H) ; ; ; ;-------------- PROPELLER CONSOLE_IO (OR SD SYSTEMS VIDIO BOARD) FOR CONSOLE INPUT & OUTPUT CONSOL_STATUS EQU 0H CONSOL_IN EQU 01H CONSOL_OUT EQU 01H ;IF this monitor ROMM is on the V3 S100 Computers Board you can ;use the on-board USB port for console IO instead of the Propeller board. ;Bit 0 of port 0E8H must be jumpered (K8) low on the board. Otherewise the USB port is ignored Z80_USB_DATA EQU 0E9H ;PORT ASSIGNEMENT FOR DLP-USB Controller chip on V3 S100Computers Z80 CPU board Z80_USB_STATUS EQU 0E8H ;Status port for USB port (Port C of 8255, bits 6,7) VGA_IOBYTE EQU 86H ;Bit 0=0 Console Output to FPGA_VGA_LCD Board, Bit 1=0 Console input is from that boards PS2 Port VGA_CONSOL_STATUS EQU 80H VGA_CONSOL_OUT EQU 81H PS2_CONSOL_STATUS EQU 89H PS2_CONSOL_DATA EQU 8AH LCD_DATA_PORT EQU 8EH ESP32_RESET_PORT EQU 8FH ACTIVATE_LCD_PORT EQU 88H ;This pin must be 1 for the ESP32 code to respond ;-------------- THIS IS MY PORT TO OUTPUT DATA TO HP 4050T LASAR PRINTER (IMSAI 8PIO Board) IF ST8C4 ;If S100_Parallel_IO Board for Printer output PRINTER_CTRL EQU 0C2H ;ST8C4 Control Port PRINTER_STATUS EQU 0C1H ;ST8C4 Status port PRINTER_OUT EQU 0C0H ;ST8C4 Data port PRINTER_ST_LOW EQU 0DH ;OUT STROBE LOW PRINTER_ST_HIGH EQU 0CH ;OUT STROBE HIGH ELSE PRINTER_STATUS EQU 5 ;IN, IMSAI PIO Board PARRELL PORT PRINTER_OUT EQU 5 ;OUT PRINTER_STROBE EQU 4 ;OUT ENDIF DIAG_LEDS EQU 5 ;OUT, Will use this port (either board) initially for diagnostic LED display. ;-------------- S100Computers SERIAL I/O BOARD PORT ASSIGNMENTS (A0-AC) BCTL EQU 0A0H ;CHANNEL B CONTROL PORT ASSIGNMENTS OF THE ZILOG SCC CHIP ;<--- Adjust as necessary, BDTA EQU 0A2H ;CHANNEL B DATA ACTL EQU 0A1H ;CHANNEL A CONTROL (MODEM_CTL_PORT) ADTA EQU 0A3H ;CHANNEL A DATA (MODEM_DATA_PORT) PortA_8255 EQU 0A8H ;A port of 8255 ;<--- Adjust as necessary PortB_8255 EQU 0A9H ;B port of 8255 PortC_8255 EQU 0AAH ;C Port of 8255 PortCtrl_8255 EQU 0ABH ;8255 configuration port AinBout8255cfg EQU 10011000b ;Set 8255 ports:- A input, B output, USB_DATA EQU 0ACH ;PORT ASSIGNEMENT FOR DLP-USB Controller chip on Serial Board USB_STATUS EQU 0AAH ;Status port for USB port (Port C of 8255, bits 6,7) USB_RXE EQU 80H ;If Bit 7 = 0, data available to recieve by S-100 Computer USB_TXE EQU 40H ;If Bit 6 = 0 data CAN be written for transmission to PC BASE_PORT EQU 0A1H ;For XModem communication routines MODEM_CTL_PORT EQU BASE_PORT ;A1H (Note modem I/O will be on CHANNEL A. Speaker on CHANNEL B MODEM_DATA_PORT EQU BASE_PORT+2 ;A3H MODEM_SEND_MASK EQU 4 SEND_READY EQU 4 ;VALUE WHEN READY MODEM_RECV_MASK EQU 1 RECV_READY EQU 1 ;BIT ON WHEN READY MODEM_ERR_LIMIT EQU 8 ;Max number of Modem serial port re-reads aborting MODEM_RTS_DELAY EQU 1 ;Time to check Modem RTS line (See XMODEM_LOAD & P_XMODEM_LOAD). Not critical. RECVD_SECT_NO EQU 0H ;IX Offset for XModem Recieved Sector Number SECTNO EQU 1H ;IX Offset for XModem CURRENT SECTOR NUMBER ERRCT EQU 2H ;IX Offset for XModem ERROR COUNT MENU_NUMBER EQU 3H ;IX Offset for menu selection ;-------------- S100Computers MSDOS Support Board PORT ASSIGNMENTS CMOS_PORT EQU 70H ;Base Port for CMOS Clock/Date Chip on MSDOS Support Board MASTER_PIC_PORT EQU 20h ;Hardware port the 8259A (two ports 20H & 21H) MasterICW1 equ 00010111B ;EDGE triggered, 4 bytes, single Master,ICW4 needed MasterICW2 equ 8H ;Base address for 8259A Int Table (IBM-PC uses 8X4 = 20H) MasterICW3 equ 0H ;No slave MasterICW4 equ 00000011B ;No special mode, non buffer, Auto EOI, 8086. ;<<<<, ;--------------- PORTS FOR FOR Z80/WD2793 FDC Board S100_DATA_A EQU 10H ;IN, S100 Data port to GET data to from FDC Board S100_DATA_B EQU 10H ;OUT, S100 Data port to SEND data to FDC Board S100_STATUS_A EQU 11H ;Status port for A S100_STATUS_B EQU 11H ;Status port for B RESET_ZFDC_PORT EQU 13H ;Port to reset ZFDC Z80 CPU. STATUS_DELAY EQU 5 ;Time-out for waiting for ZFDC Board handshake signal (~0.5 seconds @ 10MHz) DIRECTION_BIT EQU 7 ;Bits for the ZFDC flags 0 = IN, 1 = OUT DATA_IN_RDY EQU 0 ;Bit for data available from ZFDC board DATA_OUT_RDY EQU 1 ;Bit for data can be sent to ZFDC board STD8IBM EQU 1 ;IBM 8" SDSS Diak NO_ERRORS_FLAG EQU 0 ;No Errors flag for previous cmd, sent back to S-100 BIOS ;Commands to the ZFDC Board:- CMD_RESET_ZFDC EQU 3H ;Reset the WD2793 chip and Board software CMD_SET_FORMAT EQU 4H ;This will select a specified drive and assign a disk format table to that drive CMD_SET_DRIVE EQU 5H ;This will select a specified drive (0,1,2,3) CMD_SET_TRACK EQU 7H ;This will set head request to a specified track CMD_SET_SIDE EQU 8H ;This will set side request to a specified side CMD_SET_SECTOR EQU 9H ;This will set sector request to a specified sector CMD_SET_HOME EQU 0AH ;This will set head request to Track 0 of CURRENT drive CMD_STEP_IN EQU 0BH ;Step head in one track of CURRENT drive CMD_SEEK_TRACK EQU 0EH ;Seek to track to (IY+DRIVE_TRACK) with the track verify bit set on CURRENT drive/format CMD_READ_SECTOR EQU 10H ;Read data from the CURRENT sector (on current track,side,drive). CMD_HANDSHAKE EQU 21H ;Handshake command only sent during board initilization/testing CMD_RD_MULTI_SECTOR EQU 29H ;Read data from multiple sectors starting at the CURRENT sector (on current track,side,drive). ;-------------- PORT(S) TO SWITCH MASTER/SLAVE(S) Z80PORT EQU 0D0H ;4 PORTS ON Z80 BOARD FOR MEMORY MANAGEMENT (& INT Controller on IA Z80 CPU Board) MPGSEL_0 EQU 0D2H ; MEM MGR BANK 0 PAGE SELECT REG (0K-16K) MPGSEL_1 EQU 0D3H ; MEM MGR BANK 1 PAGE SELECT REG (16K-32K) IOBYTE EQU 0EFH ;IOBYTE (SEE ABOVE) SW_TMAX EQU 0EEH ;OUTPUT BIT 0 HIGH FROM THIS PORT LOWERS DMA0* ON THE SMB_V2 (SWITCH IN THE 8086 FAMILY of boards) ;OUTPUT BIT 1 HIGH FROM THIS PORT LOWERS DMA1* ON THE SMB_V2 (SWITCH IN THE 68000 CPU Board) ;OUTPUT BIT 2 HIGH FROM THIS PORT LOWERS DMA2* ON THE SMB_V2 ;OUTPUT BIT 3 HIGH FROM THIS PORT LOWERS DMA3* ON THE SMB_V2 SW_TMA0 EQU 0EDH ;INPUT FROM THIS PORT LOWERS DMA0* (SWITCHES IN THE 8086 Family of boards) ;-------------- VERSAFLOPPY-II FLOPPY DISK CONTROLLER COMMANDS ETC. X EQU 50H ;BASE PORT FOR 1791 RSET EQU X+0 ;CONTROLLER RESET ADDRESS SELECT EQU X+3 ;DRIVE SELECT PORT STATUS EQU X+4 ;STATUS PORT TRACK EQU X+5 ;TRACK PORT SECTOR EQU X+6 ;SECTOR PORT DATA EQU X+7 ;DATA PORT CMD EQU X+4 ;COMMAND PORT CIOBYTE EQU 03H CDISK EQU 04H ZERO_L EQU 08H ;Some of my CPM Loader's needs these to be zero! ZERO_H EQU 09H ;(The Non Banked version of CPM3). Need to later see why @TADDR EQU 40H @UNIT EQU 42H ;NEW @UNIT BYTE @SCTR EQU 43H ;SECTOR (compatible with my old CPM2.2 Versafloppy BIOS) @TRK EQU 44H ;TRACK @NREC EQU 45H ;# OF SECTORS @ERMASK EQU 46H ;ERROR MASK @ERSTAT EQU 47H ;ERROR FLAG STORE @IDSV EQU 48H ;6 BYTES (USED FOR TRACK ID COMMAND) @CMDSV EQU 4EH ;COMMAND SAVE @SPSV EQU 4FH ;SP SAVE TEMP2 EQU 51H ;2 BYTE TEMP RECORD @SIDE EQU 51H ;SIDE STORE FOR MSDOS DISK @COUNT EQU 53H ;SECTORS/TRACK for BOOT (Currently unused) @UNITCK EQU 55H ;OLD @UNIT BYTE @RSEEK EQU 56H ;NBR OF RESEEKS @RTRY EQU 57H ;NBR OF RTRYS ADRIVE EQU 58H ;STORE OF A: DRIVE DENSITY ETC TYPE BDRIVE EQU 59H ;STORE OF B: DRIVE TYPE @FDCTYPE EQU 5BH ;0FFH = ZFDC FDC Board Boot, else Versafloppy II FDC Boot, @SEC_SIZE EQU 5CH ;Byte count of a sector fot loader @SSTACK EQU 80H ;SYSTEM STACK COLD EQU 80H ;COLD START ADDRESS FOR CPM FLOPPY (ONLY) BOOT LOADER RDACMD EQU 0C0H ;READ ADDRESS CODE RDCMD EQU 088H ;READ SECTOR CODE WRCMD EQU 0A8H ;WRITE SECTOR CODE WRTCMD EQU 0F4H ;WRITE TRACK CODE RSCMD EQU 008H ;RESTORE COMMAND (Note 3 Ms seek) SKNCMD EQU 018H ;SEEK NO VERIFY FSKCMD EQU 01CH ;FLOPPY SEEK COMAND RSVCMD EQU 00CH ;RESTORE WITH VERIFY COMMAND MSKCMD EQU 01FH ;MINI FLOPPY SEEK COMMAND SRMASK EQU 0FEH ;SECTOR READ ERROR BITS MASK STDSDT EQU 26 ;STANDARD 8" 26 SECTORS/TRACK STDDDT EQU 50 ;STANDARD DD 8" 50 SECTORS/TRACK NBYTES EQU 128 ;BYTES/SECTOR NTRKS EQU 77 ;TRACKS/DISK ;-------------- 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 ; ;-------------- S100Computers SD Interface ------------------------------------------ SD_STAT EQU 80H ; OFFSET OF STATUS PORT FROM BASE I/O ADDRESS SD_DATA EQU 81H ; OFFSET OF DATA PORT FROM BASE I/O ADDRESS ; SD$CMD$INIT0 EQU 80H ; INITIALIZE PRIMARY SD CARD SD$CMD$INIT1 EQU 81H ; INITIALIZE SECONDARY SD CARD SD$CMD$SEL0 EQU 82H ; (RE)SELECT PRIMARY SD CARD SD$CMD$SEL1 EQU 83H ; (RE)SELECT SECONDARY SD CARD SD$CMD$SETTRKSEC EQU 84H ; SET TRACK/SECTOR FOR SUBSEQUENT I/O SD$CMD$READ EQU 85H ; READ SECTOR FROM SELECTED SD CARD AT CURRENT LBA SD$CMD$WRITE EQU 86H ; WRITE SECTOR TO SELECTED SD CARD AT CURRENT LBA SD$CMD$FORMAT EQU 87H ; FORMAT SECTOR ON SELECTED SD CARD AT CURRENT LBA SD$CMD$RESET EQU 88H ; RESET ESP32 MODULE SD$CMD$FWVER EQU 90H ; REPORT ESP32 FIRMWARE VERSION SD$CMD$SETLBA EQU 91H ; SET NEW CURRENT LBA (32-BIT) SD$CMD$TYPE EQU 92H ; REPORT CARD TYPE OF SELECTED SD CARD SD$CMD$CAP EQU 93H ; REPORT CAPACITY (SECTORS) OF SELECTED SD CARD SD$CMD$CID EQU 94H ; REPORT CID DATA OF SELECTED SD CARD SD$CMD$CSD EQU 95H ; REPORT CSD DATA OF SELECTED SD CARD SD$CMD$DISP EQU 96H ; REPORT CSD DATA OF SELECTED SD CARD SD$CMD$ECHO EQU 97H ; REPORT CSD DATA OF SELECTED SD CARD ; SD_STAT_OK EQU 00H ; OPERATION COMPLETED OK SD_STAT_ERR EQU 1AH ; OPERATION FAILED ; ;--------------------- MATH BOARD PORTS MATH_DATA_PORT EQU 80H MATH_CTRL_PORT EQU 81H CHIP_8255_A EQU 82H CHIP_8255_B EQU 83H CHIP_8255_C EQU 84H CHIP_8255_CTRL_PORT EQU 85H ; ------- SUPER IO Board II PORTS --------------- SUP_ACTL EQU 089H ;CHANNEL A CONTROL (For RS232 Port) (#1 UART) SUP_ADTA EQU 08BH ;CHANNEL A DATA (MODEM_DATA_PORT) SUP_BCTL EQU 088H ;CHANNEL B CONTROL PORT ASSIGNMENTS OF THE ZILOG (For Speech Synthesizer) (#2 UART) SUP_BDTA EQU 08AH ;CHANNEL B DATA (For Speech Synthesizer) ; ------- FPGA VGA Board PORTS --------------- VGA_BASE_PORT EQU 80H ;SW3 set to ports block 80H or 00H VGA_IOBYTE_PORT EQU VGA_BASE_PORT+6H ;Port to communicate with VGA console IO VGA_CONSOL_STATUS EQU VGA_BASE_PORT+0H VGA_CONSOL_OUT EQU VGA_BASE_PORT+1H ;Port to send data to VGA display ACTIVATE_VGA_TYPE EQU VGA_BASE_PORT+7H ;Toggle between Z80 VGA and 8086+ VGA ACTIVATE_LCD_PORT EQU VGA_BASE_PORT+8H ;This pin must be 1 for the ESP32 code to respond PS2_CONSOL_STATUS EQU VGA_BASE_PORT+9H PS2_CONSOL_DATA EQU VGA_BASE_PORT+0AH ; ; ;---------------------------------------------------------------------------- ; ;JUMP TABLE TO ROUTINES WITHIN THE MONITOR1.Z80 :- ;PROGRAM CODE BEGINS HERE ;FIRST A JUMP TABLE FOR KEY JUMPS INTO THE MONITOR. NOTE THESE SHOULD NOT BE CHANGED BECAUSE ;SOME OF MY OLDER SOFTWARE JUMPS DIRECTLY TO THEM. (WHERE POSSIBLE, TDL's ZAPPLE MONITOR FORMAT IS USED). ZAPPLE: JP ACTIVATE_LOW_PAGE ;INITILIZATION ZCI: JP HIGH_CI ;CONSOL INPUT ZRI: JP NoHighPageError ;This routine resides on the LOW page ROM ZCO: JP HIGH_CO ;CONSOL OUTPUT ZPOO: JP NoHighPageError ;This routine resides on the LOW page ROM ZLO: JP HIGH_LO ;Printer Output ZCSTS: JP HIGH_CSTS ;CONSOL STATUS ;----------------->>> THIS CODE MUST BE AT THE SAME LOCATION AS FOR THE LOW PAGE ROM CODE <<<--------- ; ACTIVATE_HIGH_PAGE: ; SWITCH TO HIGH PAGE of ROM NOP NOP NOP NOP JP HIGH_MENU_OPTION ACTIVATE_LOW_PAGE: ; RETURN BACK TO LOW PAGE OF ROM LD A,04H ; 04H for MEMORY MANAGEMENT TO OVERLAP + Bit 1 = HIGH PAGE OUT (Z80PORT+3),A JP NoHighPageError ; Will arrive here only IF no address line switch. ; ;----------------------->>> END OF COMMON CODE LOACTIONS <<<---------------------------------- ; ; HIGH_MENU_OPTION: LD A,D ; HIGH PAGE code with 1 in [D] for XMODEM CP A,1 JP Z,HIGH_XMODEM CP A,2 JP Z,SDCPM CP A,3 JP Z,SDWBW CP A,4 JP Z,SHOW_TIME ;Display Time/Date if hardware is [present CP A,5 JP Z,HIGH_BOARDS ;Display S100 boards in system JP INVALID_MENU_ERROR ; The only menu option so far INVALID_MENU_ERROR: LD HL,INVALID_PARM_MSG ; Point Error Message CALL HIGH_PRINT_STRING ; Print string JP ACTIVATE_LOW_PAGE MENU_ERROR: LD HL,M_ERROR_MSG ; Point Error Message CALL HIGH_PRINT_STRING ; Print string JP ACTIVATE_LOW_PAGE NoHighPageError: LD HL,NoHighPageMsg ; "No address line LA13 switch active" CALL HIGH_PRINT_STRING ; Print string JP ACTIVATE_LOW_PAGE ; ; ; ; ;<<<<<<<<<<<<<<<<<<<<<< MAIN CONSOL OUTPUT ROUTINE FOR HIGH ROM >>>>>>>>>>>>>>>>>>>>>>>>> ; ; NOTE: If any changes are made here to the Console IO they must also be done ; for the "regular" Console IO in the LOW ROM page ; ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HIGH_CO: IF V3_Z80CPU_BOARD ; Is this an S100Computers V3 Z80 CPU Board IN A,(Z80_USB_STATUS) ;For V3 Z80 board special case check for USB output BIT 0,A ;jumper K8 is set to ground JP Z,Z80_USB_OUT ;Special case V3 CPU Board ENDIF IN A,(IOBYTE) ; Read IOBYTE (hopefully 0xFF if non-existent) BIT 0,A ; Check bit 0 for printer echo PUSH AF ; Preserve IOBYTE CALL Z,HIGH_LO ; Do printer echo if requested for ALL outputs below POP AF ; Restore IOBYTE AND 00110000B ; Isolate the console device bits CP 00110000B ; Propeller? JR Z,PROPELLER_CO ; If so, do it CP 00100000B ; Serial I/O Board SCC Port A? JP Z,SERIAL_OUT ; If so, do it CP 00010000B ; Serial I/O Board DLP USB Port? JP Z,SERIAL_USB_CO ; If so, do it JP VGA_CO ; VGA is only other possibility PROPELLER_CO: ;Must be standard PROPELLER CONSOLE I/O BOARD for output IN A,(CONSOL_STATUS) AND 4H JR Z,PROPELLER_CO ;Board not ready yet LD A,C CP 07H ;IS IT A BELL JR Z,BELL1 ;Special case CP 0H ;SD BOARD CANNOT TAKE A NULL! RET Z OUT (CONSOL_OUT),A ;Send character SDCON5: LD A,C RET ;RETURN CHARACTER SENT IN [A] SERIAL_USB_CO: IN A,(USB_STATUS) ;SEND CHARACTER FROM SERIAL BOARD USB PORT (AAH) AND A,USB_TXE JR NZ,SERIAL_USB_CO LD A,C ;GET CHAR OUT (USB_DATA),A RET VGA_CO: IN A,(VGA_CONSOL_STATUS) ;Check board is ready to recieve character BIT 0,A JR Z,VGA_CO LD A,C OUT (VGA_CONSOL_OUT),A ;Send 1 character RET Z80_USB_OUT: IN A,(Z80_USB_STATUS) ;Don't worry PC is always fast enough! AND A,USB_TXE JR NZ,Z80_USB_OUT LD A,C ;GET CHAR OUT (Z80_USB_DATA),A RET BELL1: LD A,06H ;SEND A BELL OUT (CONSOL_OUT),A LD A,0FH CALL DELAY LD A,07H OUT (CONSOL_OUT),A JR SDCON5 DELAY: DEC A ;GENERAL COUNT DOWN TIME DELAY RET Z ;LENGTH SET IN [A] PUSH AF LD A,05H MORE: DEC A PUSH AF XOR A MORE2: DEC A JR NZ,MORE2 POP AF JR NZ,MORE POP AF JR DELAY ;<<<<<<<<<<<<<<<<<<< MAIN CONSOL STATUS ROUTINE >>>>>>>>>>>>>>>>>>>>>> HIGH_CSTS: IF V3_Z80CPU_BOARD ; Is this an S100Computers V3 Z80 CPU Board IN A,(Z80_USB_STATUS) ; For V3 Z80 board special case check for USB output BIT 0,A ; jumper K8 is set to ground JP Z,Z80_USB_STAT ; Special case V3 CPU Board ENDIF IN A,(IOBYTE) ; Read IOBYTE (hopefully 0xFF if non-existent) Printer has no status AND 00110000B ; Isolate the console device bits CP 00110000B ; Propeller? JR Z,PROPELLER_CSTS ; If so, get it CP 00100000B ; Serial I/O Board SCC Port A? JP Z,SERIAL_STAT ; If so, do it CP 00010000B ; Serial I/O Board DLP USB Port? JP Z,SERIAL_USB_STAT ; If so, do it JP PS2_STAT ; PS2 keyboard on FPGA VGA Board is only other possibility PROPELLER_CSTS: IN A,(CONSOL_STATUS) AND 02H JP Z,NOCHAR GOT_CHAR: XOR A DEC A ;RETURN WITH 0FFH IN [A] IF SOMETHING RET NOCHAR: XOR A ;RETURN WITH 0 IN A IF NOTHING THERE RET SERIAL_USB_STAT: IN A,(USB_STATUS) ;GET CHARACTER FROM SERIAL BOARD USB PORT (AAH) AND USB_RXE JR NZ,NOCHAR JR GOT_CHAR Z80_USB_STAT: IN A,(Z80_USB_STATUS) ;Don't worry PC is always fast enough! AND USB_RXE JR NZ,NOCHAR JR GOT_CHAR PS2_STAT: IN A,(PS2_CONSOL_STATUS) AND 01H JR Z,NOCHAR ;RETURN WITH 0FFH IN [A] IF SOMETHING JR GOT_CHAR ;<<<<<<<<<<<<<<<<<<<< MAIN CONSOL INPUT ROUTINE >>>>>>>>>>>>>>>>>>>> HIGH_CI: IF V3_Z80CPU_BOARD ; Is this an S100Computers V3 Z80 CPU Board IN A,(Z80_USB_STATUS) ;For V3 Z80 board special case check for USB output BIT 0,A ;jumper K8 is set to ground JP Z,Z80_USB_IN ;Special case V3 CPU Board ENDIF IN A,(IOBYTE) ; Read IOBYTE (hopefully 0xFF if non-existent) AND 00110000B ; Isolate the console device bits CP 00110000B ; Propeller? JR Z,PROPELLER_CI ; If so, do it CP 00100000B ; Serial I/O Board SCC Port A? JP Z,SERIAL_CI ; If so, do it CP 00010000B ; Serial I/O Board DLP USB Port? JP Z,SERIAL_USB_CI ; If so, do it JP PS2_IN ; PS2 is only other possibility PROPELLER_CI: IN A,(CONSOL_STATUS) ;Else "normal" Propeller console IN AND 02H JR Z,PROPELLER_CI IN A,(CONSOL_IN) AND 7FH ;7 bits only RET SERIAL_CI: CALL SERIAL_STAT ;See if anything at Serial/Modem input JR Z,SERIAL_CI ;No, Keep trying CALL SERIAL_IN ;Jump to serial port routine RET SERIAL_USB_CI: ;Its not clear why this delay is required! PUSH DE ;---- GET CHARACTER FROM SERIAL BOARD VIA USB PORT ----- HMSEC3: LD DE,000BBH ;1 SEC DCR COUNT at 10 MHz (does not have to be accurate) HMWTI4: IN A,(USB_STATUS) AND A,USB_RXE JR Z,HMCHAR4 ;GOT CHAR DEC E ;COUNT DOWN JR NZ,HMWTI4 ;FOR TIMEOUT DEC D JR NZ,HMWTI4 DEC B ;DCR # OF SECONDS JR NZ,HMSEC3 ;MODEM TIMED OUT RECEIVING POP DE ;RESTORE D,E SCF ;CARRY SHOWS TIMEOUT RET ;GOT MODEM CHAR HMCHAR4: IN A,(USB_DATA) POP DE ;RESTORE DE PUSH AF ;CALC CHECKSUM ADD A,C LD C,A POP AF OR A ;TURN OFF CARRY TO SHOW NO TIMEOUT RET Z80_USB_IN: IN A,(Z80_USB_STATUS) AND USB_RXE ;80H JR NZ,Z80_USB_IN ;No character yet IN A,(Z80_USB_DATA) AND 7FH ;7 bits only RET PS2_IN: IN A,(PS2_CONSOL_STATUS) AND 01H JR Z,PS2_IN IN A,(PS2_CONSOL_DATA) AND 7FH ;7 bits only RET ; ; ;;>>>>>>>>>>>>>>>>>>>> MAIN PRINTER OUTPUT ROUTINE FOR HIGH ROM<<<<<<<<<<<<<<<<<<<<< HIGH_LO: PUSH BC LD B,0FFH ;First make sure an actual printer is connected LO2: CALL LSTAT JR NZ,LO1 ;Printer is ready go to it DJNZ LO2 POP BC XOR A LD A,C RET ;RET Z if Printer problem (Not switched on) IF ST8C4 ;If S100_Parallel_IO Board for Printer output LO1: POP BC LD A,PRINTER_ST_HIGH ;Make sure strobe is high OUT (PRINTER_CTRL),A LD A,C ;Send Data from [C] OUT (PRINTER_OUT),A LD A,PRINTER_ST_LOW ;Now send strobe High->Low OUT (PRINTER_CTRL),A LD A,PRINTER_ST_HIGH ;Now returb strobe back high OUT (PRINTER_CTRL),A OR A,A RET ;Ret NZ if OK ELSE ;IMSAI PIO Board PARRELL PORT LO1: POP BC LD A,0FFH ;Setup strobe high to low then high OUT (PRINTER_STROBE),A LD A,C OUT (PRINTER_OUT),A ;Now Data XOR A ;STROBE FOR CENTRONICS OUT (PRINTER_STROBE),A LD A,0FFH ;Raise strobe again OUT (PRINTER_STROBE),A OR A,A RET ;Ret NZ if OK ENDIF FLUSH: LD C,0FFH ;Send a Form Feed to laserJet Printer CALL HIGH_LO ;This forces a partial page to be printed RET ;>>>>>>>>>>>>>>>>>>>>>> PRINTER STATUS ROUTINE <<<<<<<<<<<<<<<<<<<<<<<< IF ST8C4 ;If S100_Parallel_IO Board for Printer output LSTAT: IN A,(PRINTER_STATUS) ;0CH status port of ST8C4 AND 11111111B ;For now CP 11011111B ;should see 11011111 if printer is selected, ready, with paper etc. JR Z,LSTAT1 XOR A RET ;Return Z if not ready LSTAT1: XOR A ;PUT 0FFH IN [A] IF READY & NO ZERO FLAG DEC A RET ELSE ;IMSAI PIO Board PARRELL PORT LSTAT: IN A,(PRINTER_STATUS) AND 00001111B ;XXXX0110 IS READY (BIT 3=PAPER BIT 2=FAULT CP 00000110B ;BIT 1=SELECT BIT 0=BUSY JR Z,LSTAT1 XOR A RET LSTAT1: XOR A ;PUT 0FFH IN [A] IF READY & NO ZERO FLAG DEC A RET ENDIF ; ; ; SPEAKOUT: ;Send test to serial board speaker XOR A,A ;Will try 256 times, then timeout SPXXX: PUSH AF IN A,(BCTL) ;(A0), Is SCC RX Buffer empty AND 04H JR NZ,SENDS ;NZ if ready to recieve character POP AF DEC A JR NZ,SPXXX RET SENDS: POP AF LD A,C OUT (BDTA),A ;(A2), Send it RET ; ;SPEAKTOMM THIS IS A ROUTINE TO SEND A STRING TO TALKER [HL] AT STRING HIGH_SPEAK: LD A,(HL) CP '$' JR Z,SPEAK1 LD C,A CALL SPEAKOUT INC HL JR HIGH_SPEAK SPEAK1: LD C,0DH ;MUST END WITH A CR JP SPEAKOUT ; ; ; ; ;>>>>>>>>>>>>>>>>>> S100Computers SERIAL I/O Board <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; Note the S100Computers I/O board will have the SSC-B set initially to 19,200 Baud ; SERIAL_OUT: XOR A,A ;Will try 256 times, then timeout MODXXX: PUSH AF IN A,(ACTL) ;MODEM/SERIAL OUT AND 04H ;Are we ready for a character JR NZ,SENDM ;NZ if ready to recieve character POP AF DEC A JR NZ,MODXXX RET SENDM: POP AF LD A,C OUT (ADTA),A ;Send it RET SERIAL_IN: XOR A,A ;Will try 256 times, then timeout SERIAL_INX: PUSH AF CALL SERIAL_STAT ;MODEN/SERIAL IN JR NZ,GETMOD POP AF DEC A JR NZ,SERIAL_INX RET GETMOD: POP AF IN A,(ADTA) RET SERIAL_STAT: IN A,(ACTL) AND 01H RET Z ;Ret Z if nothing XOR A DEC A RET ;Ret FF/NZ if something ;S100Computers Serial I/O Board Initilization ;Note Zilog SCC serial port A will be set to 19,200 Baud initially (for XModem etc). ;Note Zilog SCC serial port B will be set to 19,200 Baud initially (for speech synthesizer). HIGH_INIT_SCC_A: LD A,ACTL ;Program Channel A LD C,A LD B,0EH ;Byte count for OTIR below LD HL,HIGH_SCCINIT_A OTIR RET HIGH_INIT_SCC_B: LD A,BCTL ;Program Channel B LD C,A LD B,0EH ;Byte count for OTIR below LD HL,HIGH_SCCINIT_B OTIR RET ; ; HIGH_SCCINIT_A: 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 DB 0BH ;Set RTS,DTR, Enable. 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 <<<<<<<<<<< XModem I/O ; 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 HIGH_SCCINIT_B: 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 05H ;Point to WR5 DB 0EAH ;Enable, Transmit 8 bits DB 0BH ;Set RTS,DTR, Enable. Point to WR11 DB 56H ;Recieve/transmit clock = BRG DB 0CH ;Point to WR12 DB 06H ;Low byte 19,200 Baud <<<<<<<<<<< Note Speech synthizer defaults to this value 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 ; ; ; ;---------------WE NEED A FEW ROUTINES (ALSO IN THE LOW PAGE) TO PROCESS COMMNADS-------------- ; HIGH_QCHK: ;TEST FOR DELIMITERS CP SPACE RET Z CP ',' RET Z CP CR SCF RET Z CCF RET ;KEYBOARD HANDELING ROUTINE (WILL NOT ECHO CR/LF) ;IT CONVERTS LOWER CASE TO UPPER CASE FOR LOOKUP COMMANDS ;ALSO ^C WILL FORCE A JUMP TO BOOT IN CP/M ;ALL OTHERE CHARACTERS ARE ECHOED ON CONSOL HIGH_TI: CALL HIGH_CI CP CR RET Z CP 'C'-40H ;^C TO BOOT IN CP/M JP Z,NoHighPageError PUSH BC LD C,A CALL HIGH_CO LD A,C POP BC CP 40H ;LC->UC RET C CP 7BH RET NC SF754: AND 5FH RET EXPR1: LD C,01H ;GET ONE PARAMETER HIGH_HEXSP: LD HL,0000 EX0: CALL HIGH_TI EX1: LD B,A CALL HIGH_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 HIGH_QCHK JR NC,SF560 DEC C RET Z SF560: JP NZ,HIGH_ERROR DEC C JR NZ,HIGH_HEXSP RET EXF: LD C,01H LD HL,0000H JR EX1 ;CONVERT HEX TO ASCII HIGH_CONV: AND 0FH ADD A,90H DAA ADC A,40H DAA LD C,A RET HIGH_NIBBLE: SUB 30H RET C CP 17H CCF RET C CP LF CCF RET NC SUB 07H CP LF RET HIGH_PRINT_STRING: ;A ROUTINE TO PRINT OUT A STRING @ [HL] LD A,(HL) ;UP TO THE FIRST '$'. INC HL CP '$' RET Z LD C,A CALL HIGH_CO JR HIGH_PRINT_STRING ;SEND TO CONSOL CR/LF HIGH_CRLF: PUSH BC LD C,LF CALL HIGH_CO LD C,CR CALL HIGH_CO POP BC RET ;PRINT [HL] ON CONSOL HIGH_LADR: LD A,H CALL HIGH_LBYTE LD A,L HIGH_LBYTE: PUSH AF RRCA RRCA RRCA RRCA CALL SF598 POP AF SF598: CALL HIGH_CONV JP HIGH_CO PRTDOT: PUSH AF PUSH BC LD C,'.' CALL HIGH_CO POP BC POP AF RET HIGH_ERROR: ;RESTORE SYSTEM AFTER ERROR (Back to low page) LD C,'*' CALL HIGH_CO JP ACTIVATE_LOW_PAGE ;--------------------------------------------------------------------------------------------------------------- ;This code will read a download file from another computer (usually a PC) sent via a serial port and place ;it in RAM at a specified location. The file must be sent via the XModem protocol. On PC's there are ;many programs that do this. The "Absolute Telnet" program (by Celestial Software) is what I use. HIGH_XMODEM: LD HL,MODEM_SIGNON ;Send Modem signon message CALL HIGH_PRINT_STRING LD HL,0 ;SP to HL ADD HL,SP LD DE,40H ;Drop 40H bytes below stack to be safe SBC HL,DE PUSH HL POP IX ;Will store data in RAM 40H bytes below SP to be safe CALL HIGH_CI ;Get menu item 1,2 or 3 CP A,ESC JP Z,HIGH_ERROR LD (IX+MENU_NUMBER),A ;Store menu selection in RAM LD C,A CALL HIGH_CO CP A,'1' JR Z,SELECT_SERIAL1 CP A,'2' JR Z,SELECT_SERIAL2 CP A,'3' JR Z,SELECT_Z80_USB JP HIGH_ERROR SELECT_SERIAL1: IN A,(MODEM_CTL_PORT) CP A,0FFH JP Z,NO_SERIAL_1 LD HL,MODEM_SCC_MSG ;Send Modem serial parameters CALL HIGH_PRINT_STRING CALL HIGH_INIT_SCC_A ;INITITIALIZE THE SCC SERIAL PORT A JP SELECT_OK SELECT_SERIAL2: IN A,(MODEM_CTL_PORT) CP A,0FFH JP Z,NO_SERIAL_1 JP SELECT_OK NO_SERIAL_1 LD HL,NO_SERIAL_MSGG ;No Serial board detected CALL HIGH_PRINT_STRING JP ACTIVATE_LOW_PAGE SELECT_Z80_USB: IN A,(Z80_USB_STATUS) CP A,0FFH JP NZ,SELECT_OK LD HL,NO_Z80_USB_MSGG CALL HIGH_PRINT_STRING ;No Z80 USB PortSend Modem serial parameters JP ACTIVATE_LOW_PAGE SELECT_OK: XOR A,A ;Initilize flags LD (IX+RECVD_SECT_NO),A LD (IX+SECTNO),A LD (IX+ERRCT),A LD HL,MODEM_RAM_LOC ;Get RAM location for where to place code CALL HIGH_PRINT_STRING LD C,1 CALL HIGH_HEXSP ;Get 16 bit value, put on stack POP IY ;DMA Value now in IY CALL HIGH_CRLF LD B,1 ;TIMEOUT DELAY CALL RECV ;GOBBLE UP GARBAGE CHARS FROM THE LINE RECV_LOOP: ;------- MAIN RECIEVE LOOP --------------------- XOR A,A ;GET 0 LD (IX+ERRCT),A ;INITIAL ERROR COUNT SET TO 0 RECV_HDR: LD HL,RMSG CALL HIGH_PRINT_STRING LD A,(IX+SECTNO) ;Get current sector number INC A CALL HIGH_LBYTE ;Show Sector Number on Console LD HL,MODEM_RAM_MSG ;"H. IF OK, will write to RAM location" CALL HIGH_PRINT_STRING PUSH IY POP HL ;IY to HL CALL HIGH_LADR ;Show DMA Address CALL HIGH_CRLF LD B,5 ;5 SEC TIMEOUT CALL RECV JP NC,RHNTO ;IF ALL OK (NO TIMEOUT), THEN DROP DOWN TO RHNTO TO GET DATA RECV_HDR_TIMEOUT: CALL TOUT ;PRINT TIMEOUT RECV_SECT_ERR: ;PURGE THE LINE OF INPUT CHARS LD B,1 ;1 SEC W/NO CHARS CALL RECV JP NC,RECV_SECT_ERR ;LOOP UNTIL SENDER DONE LD A,NAK CALL SEND ;SEND NAK LD A,(IX+ERRCT) INC A LD (IX+ERRCT),A CP A,MODEM_ERR_LIMIT JP C,RECV_HDR CALL CHECK_FOR_QUIT JP Z,RECV_HDR LD HL,BAD_HEADER_MSG CALL HIGH_PRINT_STRING JP EXIT RHNTO: CP A,SOH ;GOT CHAR - MUST BE SOH JP Z,GOT_SOH ;Z IF OK OR A,A ;00 FROM SPEED CHECK? JP Z,RECV_HDR CP A,EOT JP Z,GOT_EOT ;DIDN'T GET SOH - CALL HIGH_LBYTE LD HL,ERRSOH CALL HIGH_PRINT_STRING JP RECV_SECT_ERR GOT_SOH: LD B,1 CALL RECV JP C,RECV_HDR_TIMEOUT LD D,A ;D=BLK # LD B,1 CALL RECV ;GET CMA'D SECT # JP C,RECV_HDR_TIMEOUT CPL CP A,D ;GOOD SECTOR #? JP Z,RECV_SECTOR LD HL,ERR2 ;GOT BAD SECTOR # CALL HIGH_PRINT_STRING JP RECV_SECT_ERR RECV_SECTOR: ;Sector is OK, so read data and place in RAM LD A,D ;GET SECTOR # LD (IX+RECVD_SECT_NO),A LD C,0 ;INIT CKSUM LD E,80H ;Sector Byte Count PUSH IY POP HL ;DMA address (IY) to HL RECV_CHAR: LD B,1 ;1 SEC TIMEOUT CALL RECV ;GET CHAR JP C,RECV_HDR_TIMEOUT LD (HL),A ;STORE CHAR INC HL DEC E ;Next sector byte JP NZ,RECV_CHAR ;VERIFY CHECKSUM LD D,C ;SAVE CHECKSUM LD B,1 ;TIMEOUT CALL RECV ;GET CHECKSUM JP C,RECV_HDR_TIMEOUT CP A,D ;CHECK JP NZ,RECV_CKSUM_ERR ;GOT A SECTOR, WRITE IF = 1+PREV SECTOR LD A,(IX+RECVD_SECT_NO) LD B,A ;SAVE IT LD A,(IX+SECTNO) ;GET PREV INC A ;CALC NEXT SECTOR # CP B ;MATCH? JP NZ,DO_ACK LD (IX+SECTNO),A ;UPDATE SECTOR # DO_ACK: LD A,ACK CALL SEND PUSH HL ;ALL OK SO SAVE DMA Address in IY POP IY JP RECV_LOOP ;Back to Top recieve loop RECV_CKSUM_ERR: LD HL,ERR3 CALL HIGH_PRINT_STRING JP RECV_SECT_ERR GOT_EOT: LD A,ACK ;ACK THE EOT CALL SEND JP XFER_CPLT ;---------------------------------------------------- ; XMODEM SERIAL OR USB PORT GET CHARACTER ROUTINE ;---------------------------------------------------- RECV: LD A,(IX+MENU_NUMBER) ;Get menu selection from above CP A,'1' ;To redirect character through the correct IO port JP Z,RECV_1 ;Serial board serial port for I/O CP A,'2' JP Z,RECV_2 ;Serial board USB port for I/O CP A,'3' JP Z,RECV_3 ;Z80 CPU Board for I/O JP HIGH_ERROR RECV_1: PUSH DE ;---- GET CHARACTER FEOM SERIAL BOARD VIA SERIAL PORT ----- LD A,5H ;Lower RTS line OUT MODEM_CTL_PORT,A ;Sel Reg 5 LD A,11101010B ;EAH OUT MODEM_CTL_PORT,A NOP NOP MSEC1: LD DE,0BBBBH ;1 SEC DCR COUNT MWTI1: IN A,MODEM_CTL_PORT AND A,MODEM_RECV_MASK CP A,RECV_READY JP Z,MCHAR1 ;GOT CHAR DEC E ;COUNT DOWN JP NZ,MWTI1 ;FOR TIMEOUT DEC D JP NZ,MWTI1 DEC B ;DCR # OF SECONDS JP NZ,MSEC1 ;MODEM TIMED OUT RECEIVING POP DE ;RESTORE D,E SCF ;CARRY SHOWS TIMEOUT RET ;GOT MODEM CHAR MCHAR1: IN A,MODEM_DATA_PORT POP DE ;RESTORE DE PUSH AF ;CALC CHECKSUM ADD A,C LD C,A POP AF OR A,A ;TURN OFF CARRY TO SHOW NO TIMEOUT RET RECV_2: PUSH DE ;---- GET CHARACTER FROM SERIAL BOARD VIA USB PORT ----- MSEC2: LD DE,0BBBBH ;1 SEC DCR COUNT at 10 MHz (does not have to be accurate) MWTI2: IN A,(USB_STATUS) AND A,USB_RXE JR Z,MCHAR2 ;GOT CHAR DEC E ;COUNT DOWN JR NZ,MWTI2 ;FOR TIMEOUT DEC D JR NZ,MWTI2 DEC B ;DCR # OF SECONDS JR NZ,MSEC2 ;MODEM TIMED OUT RECEIVING POP DE ;RESTORE D,E SCF ;CARRY SHOWS TIMEOUT RET ;GOT MODEM CHAR MCHAR2 IN A,(USB_DATA) POP DE ;RESTORE DE PUSH AF ;CALC CHECKSUM ADD A,C LD C,A POP AF OR A ;TURN OFF CARRY TO SHOW NO TIMEOUT RET RECV_3: PUSH DE ;---- GET CHARACTER FROM V3 Z80 CPU BOARD USB PORT ----- MSEC3: LD DE,0BBBBH ;1 SEC DCR COUNT at 10 MHz (does not have to be accurate) MWTI3: IN A,(Z80_USB_STATUS) AND A,USB_RXE JR Z,MCHAR3 ;GOT CHAR DEC E ;COUNT DOWN JR NZ,MWTI3 ;FOR TIMEOUT DEC D JR NZ,MWTI3 DEC B ;DCR # OF SECONDS JR NZ,MSEC3 ;MODEM TIMED OUT RECEIVING POP DE ;RESTORE D,E SCF ;CARRY SHOWS TIMEOUT RET ;GOT MODEM CHAR MCHAR3 IN A,(Z80_USB_DATA) POP DE ;RESTORE DE PUSH AF ;CALC CHECKSUM ADD A,C LD C,A POP AF OR A ;TURN OFF CARRY TO SHOW NO TIMEOUT RET ;---------------------------------------------------- ; XMODEM SERIAL OR USB PORT SEND CHARACTER ROUTINE ;---------------------------------------------------- SEND PUSH AF ;CHECK OUTPUT ADD A,C ;CALC CKSUM LD C,A LD A,(IX+MENU_NUMBER) ;Get menu selection from above CP A,'1' JP Z,SENDW_1 ;Serial board serial port for I/O CP A,'2' JP Z,SENDW_2 ;Serial board USB port for I/O CP A,'3' JP Z,SENDW_3 ;Z80 CPU Board for I/O JP HIGH_ERROR SENDW_1:IN A,MODEM_CTL_PORT ;---- SEND CHARACTER FEOM SERIAL BOARD VIA SERIAL PORT ----- AND A,MODEM_SEND_MASK CP A,SEND_READY JP NZ,SENDW_1 POP AF ;GET CHAR OUT MODEM_DATA_PORT,A LD A,5H ;while the Z80 is busy processing info OUT MODEM_CTL_PORT,A ;Sel Reg 5 LD A,11101000B ;E8H OUT MODEM_CTL_PORT,A RET SENDW_2:IN A,(USB_STATUS) ;---- GET CHARACTER FROM SERIAL BOARD USB PORT ----- AND A,USB_TXE JR NZ,SENDW_2 POP AF ;GET CHAR OUT (USB_DATA),A RET SENDW_3:IN A,(Z80_USB_STATUS) ;---- SEND CHARACTER FEOM V3 Z80 CPU BOARD USB PORT ----- AND A,USB_TXE JR NZ,SENDW_3 POP AF ;GET CHAR OUT (Z80_USB_DATA),A RET ;--------------------------------------------------------------- ;---------------- SUPPORT ROUTINES ----------------------------- ;--------------------------------------------------------------- TOUT: LD HL,TOUTM ;PRINT TIMEOUT MESSAGE CALL HIGH_PRINT_STRING LD A,(IX+ERRCT) CALL HIGH_LBYTE CALL HIGH_CRLF RET CO_A: PUSH AF ;PRINT VALUE of [A] on CRT PUSH BC LD C,A CALL HIGH_CO POP BC POP AF RET CHECK_FOR_QUIT: ;MULTIPLE ERRORS, ASK IF TIME TO QUIT XOR A,A ;GET 0 LD (IX+ERRCT),A ;RESET ERROR COUNT LD HL,QUITM CALL HIGH_PRINT_STRING CI3: IN A,CONSOL_STATUS ;NEED CONSTAT TO CLEAN UP SHIFT KEYS ETC AND A,02H JP Z,CI3 IN A,CONSOL_IN AND A,7FH PUSH AF ;SAVE CHAR CALL HIGH_CRLF POP AF CP A,'R' RET Z ;RETURN IF RETRY CP A,'r' RET Z CP A,'Q' ;QUIT? JP NZ,LCQ OR A,A ;TURN OFF ZERO FLAG RET LCQ: CP A,'q' JP NZ,CHECK_FOR_QUIT OR A,A ;TURN OFF ZERO FLAG RET XFER_CPLT: ;DONE - CLOSE UP SHOP LD HL,FINISH_SP ;Speak downloading finished CALL HIGH_SPEAK LD HL,MODEM_DONE_MSG CALL HIGH_PRINT_STRING EXIT: JP ACTIVATE_LOW_PAGE ;-------------- BOOT UP CPM FROM SD CARD ON S100COMPUTERS SD BOARD ---------------- SDCPM: LD HL,SDCPMLOAD$MSG ; CP/M load start message CALL HIGH_PRINT_STRING IN A,(SD_STAT) CP 0FFH JR NZ,INIT_SD LD HL,NO$SDCARD$MSG ; CP/M load start message CALL HIGH_PRINT_STRING JP EXIT INIT_SD: ; Initialize CALL SD_INIT ; initialize SD Card JP NZ,ERR_MEDIA ; handle error CALL PRTDOT ; display progress ; Read sectors LD B,SEC_COUNT ; number of sectors to load LD HL,CPM_ADDRESS ; memory buffer address LD DE,1 ; starting LBA SDCPM1: PUSH BC ; save loop control PUSH DE ; save LBA CALL SD_SEEK ; seek to desired LBA CALL Z,SD_READBLK ; read sector, HL will be incremented POP DE ; recover LBA POP BC ; recover loop control JP NZ,ERR_IO ; handle error INC DE ; next sector CALL PRTDOT ; display progress DJNZ SDCPM1 ; loop till all sectors read ; Completion message LD HL,SDDONE$MSG ; completion message CALL HIGH_PRINT_STRING ; display it ; Back to main menu (page 0) ;JP ACTIVATE_LOW_PAGE ; Return to main menu in ROM page A for debugging ;code loaded ; Check loaded image marker LD A,(STARTCPM) ; get first byte of loaded data CP 31H ; expect to have 31H, ie. ld sp,80h JP NZ,ERR_BADIMAGE ; handle invalid boot sector data ; Launch CP/M JP STARTCPM ; start CP/M ;-------------- BOOT UP ROMWBW FROM SD CARD ON S100COMPUTERS SD BOARD ---------------- SDWBW: LD HL,SDWBWLOAD$MSG ; ROMWBW load start message CALL HIGH_PRINT_STRING ; Initialize CALL SD_INIT ; initialize SD Card JP NZ,ERR_MEDIA ; handle error CALL PRTDOT ; display progress ; This is the main loading loop. Each MMU bank is 16K, so we ; have an inner loop to read and load 32 sectors. An outer ; loop increments the MMU bank selection, so we wind up loading ; the desired 128K in 8 consecutive banks. LD DE,1024 ; DE is LBA (start from sec 1024) LD C,4 ; C is MMU bank (start from 4) SDWBW1: ; Outer loop (once per bank) LD HL,0000H ; HL is RAM address LD B,32 ; B is sector count, load 32 sectors per bank LD A,C ; get bank to be loaded RLCA ; rotate bank num RLCA ; ... to top 6 bits OUT (MPGSEL_0),A ; and select it SDWBW2: ; Inner loop (once per sector) PUSH BC ; save loop control PUSH DE ; save LBA CALL SD_SEEK ; seek to desired LBA CALL Z,SD_READBLK ; read sector, HL will be incremented POP DE ; recover LBA POP BC ; recover loop control JP NZ,ERR_IO ; handle error INC DE ; next sector DJNZ SDWBW2 ; loop until all bank sectors done ; Show progress CALL PRTDOT ; display progress ; Setup for next bank and check for done INC C ; next bank LD A,C ; put in A CP 4 + 8 ; 128K / 16K = 8 banks JR NZ,SDWBW1 ; loop until all banks done ; Setup the lower 16K with the first 16K of RomWBW LD A,4 << 2 ; first 16K bank OUT (MPGSEL_0),A ; set it ; Completion message LD HL,SDDONE$MSG ; load complete message CALL HIGH_PRINT_STRING ; display it ;; Back to main menu (page 0) ;JP ACTIVATE_LOW_PAGE ; Return to main menu in ROM page A ; Check loaded image marker LD HL,(0004H) ; marker bytes location ptr LD A,(HL) CP 076H ; first marker byte JP NZ,ERR_BADIMAGE ; handle invalid boot sector data INC HL LD A,(HL) CP 0B5H ; second marker byte JP NZ,ERR_BADIMAGE ; handle invalid boot sector data ; Launch RomWBW JP 0000H ; start RomWBW ;-------------- SD CARD SUPPORT ROUTINES ---------------- ; Send command in C to SD interface, command result in A SD_CMD: PUSH BC ; save command byte LD C,33H ; set command prefix byte CALL SD_PUTBYTE ; send it POP BC ; recover command byte ; fall thru to send command byte ; Write byte in C to SD interface, put result in A SD_PUTBYTE: IN A,(SD_STAT) ; get status BIT 0,A ; check bit 0 for ready to send JR NZ,SD_PUTBYTE ; if not, loop LD A,C ; byte to send to A OUT (SD_DATA),A ; send it RET ; Read a byte from SD interface to C, read result in A SD_GETBYTE: IN A,(SD_STAT) ; get status BIT 7,A ; check bit 7 for ready to read JR Z,SD_GETBYTE ; if not, loop IN A,(SD_DATA) ; get the byte LD C,A ; put in C RET ; Initialize the SD Card, init result in A SD_INIT: LD C,SD$CMD$INIT0 ; setup command CALL SD_CMD ; send it CALL SD_GETBYTE ; get result OR A ; set flags RET ; Seek to LBA in DE, seek result in A SD_SEEK: LD C,SD$CMD$SETTRKSEC ; setup command CALL SD_CMD ; send it LD C,D ; setup track byte CALL SD_PUTBYTE ; send it LD C,E ; setup sector byte CALL SD_PUTBYTE ; send it CALL SD_GETBYTE ; get result OR A ; set flags RET ; Read a sector into buf at HL, read result in A SD_READBLK: LD C,SD$CMD$READ ; setup command CALL SD_CMD ; send it LD B,0 ; 256 loops, 2 bytes each SD_READBLK1: CALL SD_GETBYTE ; get next byte LD (HL),C ; save it INC HL ; bump buf ptr CALL SD_GETBYTE ; get next byte LD (HL),C ; save it INC HL ; bump buf ptr DJNZ SD_READBLK1 ; loop as needed CALL SD_GETBYTE ; get result OR A ; set flags RET ; Error handlers ERR_MEDIA: LD HL,NOMEDIA$MSG JR ERR_ABORT ERR_IO: LD HL,IOERR$MSG JR ERR_ABORT ERR_BADIMAGE: LD HL,BADIMAGE$MSG JR ERR_ABORT ERR_ABORT: CALL HIGH_PRINT_STRING XOR A ; reset low 16K bank OUT (MPGSEL_0),A ; ... to 0 JP ACTIVATE_LOW_PAGE ; ; ;------------------------------------------------------------------------------------------ ; ; ROUTINE TO GET THE TIME DATA FROM THE CMOS-RTC Chip on the MSDOS Support Board ; If No MSDOS board will return with SCF ; ;------------------------------------------------------------------------------------------- SHOW_TIME: LD HL,TIME_MSG CALL HIGH_PRINT_STRING ;Print message up to '$' CALL PRINT_TIME SHOW_DATE: LD HL,DATE_MSG CALL HIGH_PRINT_STRING ;Print message up to '$' CALL PRINT_DATE JP ACTIVATE_LOW_PAGE PRINT_TIME: CALL UPD_IN_PR ;CHECK FOR UPDATE IN PROCESS JP NC,RTC_2A ;GO AROUND IF OK JP RTC_ERROR ;IF ERROR RTC_2A: LD E,-2 ;-2 goes to 0 for PORT_INC_2 CALL PORT_INC_2 ;SET ADDRESS OF SECONDS IN A,(CMOS_PORT+1) ;Get BCD value returned LD D,A ;SAVE IN D CALL PORT_INC_2 ;SET ADDRESS OF MINUTES IN A,(CMOS_PORT+1) ;Get BCD value returned LD C,A ;SAVE IN C CALL PORT_INC_2 ;SET ADDRESS OF HOURS IN A,(CMOS_PORT+1) ;Get BCD value returned LD B,A ;SAVE LD E,0 ;SET E TO ZERO CALL DisplayTime XOR A,A ;Clear Carry RET ;BACK TO MONITOR RTC_ERROR: ;Indicate RTC Board is not present or Error SCF ;SET CARRY FOR ERROR RET ;Display time ; Arrive with B = HOURS IN BCD ; C = Minutes in BCD ; D = Seconds in BCD DisplayTime: PUSH DE PUSH BC LD A,B CALL PRINT_BCD ;Hours. Convert BCD to ASCII LD C,':' CALL ZCO POP BC LD A,C CALL PRINT_BCD ;Minutes. Convert BCD to ASCII LD C,':' CALL ZCO POP DE LD A,D CALL PRINT_BCD ;Seconds. Convert BCD to ASCII RET PRINT_DATE: CALL UPD_IN_PR JP NC,RTC_4A JP RTC_ERROR ;IF ERROR RTC_4A: LD E,6 CALL PORT_INC ;POINT TO DAY IN A,(CMOS_PORT+1) LD B,A ;SAVE IN A CALL PORT_INC ;POINT TO MONTH IN A,(CMOS_PORT+1) LD D,A ;SAVE IN D CALL PORT_INC ;POINT TO YEAR IN A,(CMOS_PORT+1) LD C,A ;SAVE IN C LD E,31H ;POINT TO CENTURY BYTE SAVE AREA CALL PORT_INC ; IN A,(CMOS_PORT+1) ;GET VALUE LD E,B ;GET DAY BACK LD B,A CALL DisplayDate XOR A,A ;Clear Carry RET ;FINISHED ;Display date ; Return B = CENTURY IN BCD ; C = Year in BCD ; D = Month in BCD ; E = Day in BCD DisplayDate: PUSH DE PUSH DE PUSH BC PUSH BC ;I am having a problem obtaining teh century. POP BC ;just force it to year 2000 LD A,20H ;<--20 CALL PRINT_BCD ;Century (19/20). Convert BCD to ASCII POP BC LD A,C CALL PRINT_BCD ;Year. Convert BCD to ASCII LD C,'/' CALL ZCO POP DE LD A,D CALL PRINT_BCD ;Month. Convert BCD to ASCII LD C,'/' CALL ZCO POP DE LD A,E CALL PRINT_BCD ;Day. Convert BCD to ASCII RET UPD_IN_PR: ;Check we are ready to read clock PUSH BC LD BC,600 ;SET LOOP COUNT UPDATE: LD A,0AH ;ADDRESS OF [A] REGISTER OUT (CMOS_PORT),A NOP NOP NOP IN A,(CMOS_PORT+1) ;READ IN REGISTER [A] AND A,80H ;IF 8XH--> UIP BIT IS ON (CANNOT READ TIME) JP Z,UPD_IN_PREND ;Are we ready/done DEC BC LD A,C OR A,B JP NZ,UPDATE ;Try again XOR A,A ; SCF ;SET CARRY FOR ERROR POP BC RET UPD_IN_PREND: XOR A,A ;Clear Carry POP BC RET ;RETURN PORT_INC: LD A,E INC A ;INCREMENT ADDRESS LD E,A OUT (CMOS_PORT),A RET PORT_INC_2: LD A,E ADD 2 ;INCREMENT ADDRESS LD E,A OUT (CMOS_PORT),A RET PRINT_BCD: ;Print BCD in [A] PUSH AF PUSH AF RRA RRA RRA RRA AND A,0FH ADD A,30H LD C,A ;Write high byte mins to CRT CALL ZCO POP AF AND A,0FH ADD A,30H LD C,A CALL ZCO POP AF RET ;------------------------------------------------------------------------------------------------- ; Detect boards in thisd S100 Bus system ;------------------------------------------------------------------------------------------------- HIGH_BOARDS: LD HL,S100_BOARDS_MSG ; The following S100 Boards were detected in the S100 Bus CALL HIGH_PRINT_STRING ; Print string IN A,(CONSOL_STATUS) CP 0FFH JP Z,NO_PROPELLER1 JP IS_PROPELLER NO_PROPELLER1: IN A,(CONSOL_IN) CP 0FFH JR Z,NO_PROPELLER2 IS_PROPELLER: LD HL,PROPELLER_MSG ; Propeller Board CALL HIGH_PRINT_STRING ; Print string NO_PROPELLER2: IN A,(PRINTER_CTRL) ;ST8C4 on S100_Parallel_IO Board for Printer output CP 0FFH JR Z,NO_ST8C4 LD HL,PARALLEL_PORTS_MSG ; Parallel Ports IO Board CALL HIGH_PRINT_STRING ; Print string JR NO_IMSAI_PP NO_ST8C4: IN A,(PRINTER_STATUS) ;IMSAI Parallel ports board CP 0FFH JR Z,NO_IMSAI_PP LD HL,IMSAI_PARALLEL_MSG ; IMSAI Parallel Ports IO Board CALL HIGH_PRINT_STRING ; Print string NO_IMSAI_PP: IN A,(IOBYTE) ; IOBYTE on smb or IMSAI FP Board or V3 Z80 CPU board CP 0FFH JR Z,NO_SMB ; Unfortunately it will not detect the default IOBYTE mode LD HL,SMB_MSG ; SMB or S100 Computers FP Board CALL HIGH_PRINT_STRING ; Print string NO_SMB: LD A,01111111B ;Check for MSDOS Support board. Send 7FH to 8259A and check it is there OUT (MASTER_PIC_PORT+1),A IN A,(MASTER_PIC_PORT+1) CP A,01111111B ;Should get same value back if 8259A is present JR NZ,NO_MSDOS_BRD LD A,11111111B ;Allow No Ints on 8259A for now OUT (MASTER_PIC_PORT+1),A LD HL,MSDOS_BRD_MSG ; MSDOS Board present CALL HIGH_PRINT_STRING ; Print string NO_MSDOS_BRD: IN A,(BCTL) ;CHANNEL B CONTROL PORT OF Serial Ports Board CP 0FFH JR Z,NO_SERIAL_BRD LD HL,SERIAL_BRD_MSG ; Serial Board present CALL HIGH_PRINT_STRING ; Print string NO_SERIAL_BRD: IN A,(IDEAport) ;lower 8 bits of IDE interface CP 0FFH JR Z,NO_IDE_BRD LD HL,IDE_BRD_MSG ; IDE Board present CALL HIGH_PRINT_STRING ; Print string NO_IDE_BRD: IN A,(S100_STATUS_A) ;Status port for A port in ZFDC CP 0FFH JR Z,NO_ZFDC_BRD LD HL,ZFDC_BRD_MSG ; ZFDC Board present CALL HIGH_PRINT_STRING ; Print string NO_ZFDC_BRD: IN A,(STATUS) ;Status port Versafloppy II board CP 0FFH JR Z,NO_VF_BRD LD HL,VFC_BRD_MSG ; VF Board present CALL HIGH_PRINT_STRING ; Print string NO_VF_BRD: IN A,(SD_STAT) ;Status port of SD Card Board CP 0FFH JR Z,NO_SD_BRD LD HL,SD_BRD_MSG ; SD Board present CALL HIGH_PRINT_STRING ; Print string NO_SD_BRD: IN A,(SUP_ACTL) ;Port on SUPER IO Board II CP 0FFH JR Z,NO_SUPER_II_BRD LD HL,SUPER_II_BRD_MSG ; Super IO Board present CALL HIGH_PRINT_STRING ; Print string NO_SUPER_II_BRD: IN A,(Z80_USB_STATUS) ;USB Status Port on V3 Z80 CPU Board BIT 1,A JR NZ,NO_V3_USB_Z80 LD HL,V3_Z80_BRD_MSG ; Super IO Board present CALL HIGH_PRINT_STRING ; Print string NO_V3_USB_Z80: LD HL,DONE_BRDS ; More boards undetected here are posibly present CALL HIGH_PRINT_STRING ; Print string JP ACTIVATE_LOW_PAGE ;--------------------------------------------------------------------------------------------------------------- MODEM_SIGNON: DB CR,LF,'Download a binary file from a PC to 100H in RAM',CR,LF DB '1. Download via S100 Computers serial board serial port',CR,LF DB '2. Download via S100 Computers serial board USB port',CR,LF DB '3. Download via S100 Computers V3 Z80 CPU board USB port',CR,LF DB '->$' MODEM_SCC_MSG: DB CR,LF,'Zilog SCC Ports A1H & A3H. Requires RTS & CTS, 19,200 Baud.1 stop bit, NP.',CR,LF,'$' RMSG: DB 'WAITING FOR SECTOR #$' ERRSOH: DB 'H RECEIVED, NOT SOH',0DH,0AH,'$' ERR2: DB '++BAD SECTOR # IN HDR',0DH,0AH,'$' ERR3: DB '++BAD CKSUM ON SECTOR',0DH,0AH,'$' TOUTM: DB 'TIMEOUT $' QUITM: DB 0DH,0AH,'MULTIPLE ERRORS.' DB 0DH,0AH,'TYPE Q TO QUIT, R TO RETRY:$' MODEM_DONE_MSG: DB 13,10,'TRANSFER COMPLETE$' BAD_HEADER_MSG: DB CR,LF,'INVALID HEADER.',0DH,0AH,'$' MODEM_RAM_MSG: DB 'H. If OK will write to RAM at $' DOWNLOAD_SP: DB 'Downloading file Started.$' FINISH_SP: DB 'Down loading of file complete. No Errors$' MODEM_RAM_LOC: DB CR,LF,'Enter RAM location (xxxxH +CR): $' M_ERROR_MSG: DB 'Menu Error'CR,LF,BELL,'$' NoHighPageMsg: DB 'No ROM HigH Page!',CR,LF,BELL,'$' INVALID_PARM_MSG: DB CR,LF,'Invalid paramater passed to HIGH Page ROM',CR,LF,BELL,'$' SDCPMLOAD$MSG DB CR,LF,'Loading CPM from Dual SD Card Board (SD Card 1)','$' SDWBWLOAD$MSG DB CR,LF,'Loading RomWBW ','$' SDDONE$MSG DB ' Done$' NOMEDIA$MSG DB CR,LF,'*** No media or media failure ***',CR,LF,'$' IOERR$MSG DB CR,LF,'*** I/O Error ***',CR,LF,'$' BADIMAGE$MSG DB BELL,CR,LF,'*** Invalid boot image ***',CR,LF,'$' S100_BOARDS_MSG DB CR,LF,'The following S100 Boards were detected in the S100 Bus:-$' PROPELLER_MSG DB CR,LF,'Propeller Console IO Board$' PARALLEL_PORTS_MSG DB CR,LF,'Parallel Ports IO Board$' IMSAI_PARALLEL_MSG DB CR,LF,'IMSAI Parallel Ports IO Board$' SMB_MSG DB CR,LF,'SMB,S100 Computers FP Board or V3 Z80 CPU board$' MSDOS_BRD_MSG DB CR,LF,'MSDOS Support Board$' SERIAL_BRD_MSG DB CR,LF,'Serial Board$' IDE_BRD_MSG DB CR,LF,'CF/IDE Board$' ZFDC_BRD_MSG DB CR,LF,'ZFDC Board$' VFC_BRD_MSG DB CR,LF,'Versa Floppy Board$' SD_BRD_MSG DB CR,LF,'SD Board or FPGA FDC Board$' SUPER_II_BRD_MSG DB CR,LF,'Super IO Board or Super IO Board II or FPGA VGA Board$' V3_Z80_BRD_MSG DB CR,LF,'USB port present on V3 Z80 CPU Board$' DONE_BRDS DB CR,LF,'Note: More boards undetected are posibly present$' NO_SERIAL_MSGG DB CR,LF,'Serial Board not detected!$' NO_Z80_USB_MSGG DB CR,LF,'V3 Z80 CPU board not detected!$' ; NO$SDCARD$MSG DB CR,LF,BELL,'No Dual SD CARD Board detected!$' TIME_MSG: DB CR,LF,'Time:- $' DATE_MSG: DB CR,LF,'Date:- $' ; END_OF_ROM_PAGE: DB ' End of ROM HIGH PAGE-->' ;END