home *** CD-ROM | disk | FTP | other *** search
- ; --- PASCAL BOOTER PROGRAM ---
- ;
- ; S. J. SINGER (714)-780-8853
- ; GEORGE BOLTHOFF
- ;
- ;
- ; THIS PROGRAM IS A COMBINATION OF PINIT THE PASCAL INITIALIZATION
- ;PROGRAM AND A BIOS THAT SUPPORTS BOTH STANDARD IBM 3740 FORMAT DISKS AS WELL
- ;AS DISKS FORMATTED INTO 512 BYTE BLOCKS SINGLE AND DOUBLE DENSITY. THE PROGRAM
- ;HAS CONDITIONAL ASSEMBLIES FOR 3 DIFFERENT DISK CONTROLLERS, THE OLD TARBELL
- ;1771 CONTROLLER, THE NEW TARBELL DOUBLE DENSITY CONTROLLER AND THE DELTA
- ;DOUBLE DENSITY CONTROLLER.
- ; THE INITIALIZATION SECTION POLLS UP TO 4 DRIVES AND INITIALIZES THE
- ;SYSTEM FOR THE DRIVES WHICH ARE READY. DRIVES 0 AND 1 CORRESPOND TO PASCAL
- ;LOGICAL UNITS 4 AND 5 RESPECTIVELY WHILE DRIVES 2 AND 3 CORRESPOND TO PASCAL
- ;LOGICAL UNITS 9 AND 10. AT LEAST ONE DRIVE UNIT 4 MUST BE READY.
- ; THE PROGRAM THEN READS TRACK ZERO SECTOR ONE FOR EACH UNIT THAT IS
- ;READY AND EXAMINES THE FORMAT BYTE 7FH TO DETERMINE THE PROPER INITIALIZATION
- ;FOR EACH DISK. AT PRESENT FOUR DIFFERENT FORMATS ARE SUPPORTED.
- ;
- ; FMT CODE DISK FORMAT BLOCKS
- ; 20H SNGL DENSITY, SNGL SIDED, 26 SECTORS/TRK 128 BYTES 494
- ; 22H SNGL DENSITY, SNGL SIDED, 8 SECTORS/TRK 512 BYTES 608
- ; 12H DBL DENSITY, SNGL SIDED, 16 SECTORS/TRK 512 BYTES 1216
- ; 92H DBL DENSITY, DBL SIDED, 16 SECTORS/TRK 512 BYTES 2448
- ;
- ;
- ;IF AN IMPROPER FORMAT CODE IS READ SUCH AS ANY DOUBLE DENSITY CODE WITH
- ;A SINGLE DENSITY TARBELL CONTROLLER THE PROGRAM WILL HALT WITH AN ERROR MESSAGE
- ;A FORMAT CODE OF 0DDH IS ASSUMED TO BE DOUBLE DENSITY 128 BYTE SECTORS AND
- ;ANY OTHER CODE IS ASSUMED TO IDENTIFY A STANDARD IBM 3740 DISKETTE.
- ;IF THE DISK FORMATTING PROGRAM 'DFOCO' IS USED TO FORMAT THE DISKS THE
- ;PROPER FORMAT BYTE IS AUTOMATICALLY PLACED ON TRACK ZERO SECTOR ONE.
- ;SYSTEM VARIABLES ARE INITIALIZED FOR ALL DRIVES THAT ARE READY. IF FORMATS
- ;ARE DETERMINED TO BE INCOMPATABLE THE SYSTEM WILL HALT WITH AN ERROR MESSAGE
- ;IDENTIFYING THE DRIVE HAVING THE INCORRECT FORMAT (FOR EXAMPLE A DOUBLE
- ;DENSITY DISK WITH A 1771 CONTROLLER) AND ASK YOU TO REBOOT.
- ;
- ; OFFSET FOR 64K SYSTEM IS 1380H IF BIOS STARTS AT 0FA00H
- ;
- FALSE EQU 00H ;LOGICAL FALSE
- TRUE EQU NOT FALSE
- ;
- DELTA EQU FALSE ;CONDITIONAL ASSMEBLY FOR DELTA CONTROLLER
- TARBELL EQU FALSE ;CONDITIONAL ASSEMBLY FOR NEW TARBELL CONTROLLER
- ISIO2 EQU TRUE ;CONDITIONAL FOR IMSAI SIO-2 SERIAL BOARD (8251'S)
- PT3PLUS EQU FALSE ;CONDITIONAL FOR PROCESSOR TECH 3P+S BOARD
- TUART EQU FALSE ;CONDITIONAL FOR CROMEMCO TUART SERIAL BOARD
- ADM3A EQU TRUE ;CONDITIONAL FOR ADM-3A TERMINAL
- SOROC EQU FALSE ;CONDITIONAL FOR SOROC OR OTHER TERM NO SOFTWARE DRV
- PERSCI EQU FALSE ;CONDITIONAL FOR FAST SEEK ON DUAL PERSCI DRIVES
- STEP EQU 1 ;STEP RATE 1791 0=3 MSEC, 1=6 MSEC, 2=10 MSEC
- MSIZE EQU 64 ;MEMORY SIZE IN DECIMAL KB
- BIOSSZ EQU 1536 ;BYTES IN THIS BIOS
- LOADP EQU MSIZE*1024-BIOSSZ ;LOAD POINT
- ;
- ; ---- LIST (PRINTER) EQUATES ----
- ;
- LSTAT EQU 4 ;LIST STATUS PORT.
- LDATA EQU 4 ;LIST DATA PORT.
- LMASK EQU 1 ;LIST DATA READY MASK
- ;
- ; ----- TERMINAL EQUATES -----
- IF ISIO2
- TSTAT EQU 3H ;STATUS AND COMMAND PORT
- PORT01 EQU 2H ;SERIAL PORT 1
- IMSK01 EQU 02H ;RX READY PORT 1
- OMSK01 EQU 01H ;TX READY PORT 1
- ENDIF
- ;
- IF PT3PLUS
- TSTAT EQU 00H ;TERMINAL STATUS AND COMMAND PORT
- PORT01 EQU 01H ;TERMINAL DATA PORT
- IMSK01 EQU 01H ;RX READY PORT 1
- OMSK01 EQU 80H ;TX READY PORT 1
- ENDIF
- ;
- CTRLS EQU 19 ;CONTROL S USED TO STOP DISPLAY ON TERMINAL
- CR EQU 13 ;ASCII CARRIAGE RETURN
- ;
- ; ----- DISK DRIVER EQUATES -----
- ;
- DISK EQU 0F8H ;DISK BASE ADDRESS.
- DCOM EQU DISK ;DISK COMMAND PORT.
- DSTAT EQU DISK ;DISK STATUS PORT.
- TRACK EQU DISK+1 ;DISK TRACK PORT.
- SECTP EQU DISK+2 ;DISK SECTOR PORT.
- DDATA EQU DISK+3 ;DISK DATA PORT.
- WAIT EQU DISK+4 ;DISK WAIT PORT.
- DCONT EQU DISK+4 ;DISK CONTROL PORT.
- RTCNT EQU 10 ;RETRY COUNT.
- ;
- ;---- PASCAL IO TEMPORARIES ---
- ;---- PBIOS TEMPORARIES ---
- ;
- BIOSADR:EQU 40H ;CONTAINS HEX ADDR OF START OF BIOS
- UPTR EQU BIOSADR+2
- UREQ EQU UPTR+2
- UNIT EQU UREQ+1
- UBUF EQU UNIT+1
- ULEN EQU UBUF+2
- UBLK EQU ULEN+2
- UASY EQU UBLK+2
- URTN EQU UASY+2
- ERRFLG EQU URTN+2
- ;
- BIOSTEM:EQU 70H ;ADDITIONAL TEMPORARIES FOR BIOS VARIABLES
- SECLEN EQU BIOSTEM ;SECTOR LENGTH CODE 0=128 BYTES 2=512 BYTES
- DSKDR EQU SECLEN+1 ;CURRENTLY SELECTED DISK DRIVE
- NUMSEC EQU DSKDR+1 ;NUMBER OF SECTORS PER TRACK (8 OR 16 FOR 512)
- NUMDSK EQU NUMSEC+1 ;NUMBER OF DISKS ON LINE 1 TO 4
- DBLSID EQU NUMDSK+1 ;FLAG TRUE IF DOUBLE SIDED DISK
- ERCNT EQU DBLSID+1 ;ERROR COUNT FOR DISK I/O OPERATIONS
- DMAADD EQU ERCNT+1 ;MEMORY ADDRESS FOR DISK I/O TRANSFERS
- TRKTBL EQU DMAADD+2 ;CONTAINS PARAMETERS FOR ALL DISK DRIVES
- ;
- ; FOR FLOPPY DISKS TRKTBL CONTAINS TRACK SECTOR SIZE AND DENSITY FOR EACH
- ; DISK DRIVE (MAX OF FOUR FLOPPY DISK DRIVES AT PRESENT)
- ;
- ;DRIVE ADDR TRACK DENSITY SECSIZ
- ; 4 TRKTBL 0 - 76 1 OR 2 0 OR 2
- ; 5 TRKTBL+3
- ; 9 TRKTBL+6
- ; 10 TRKTBL+9
- ;
- ;
- ASNCBIT EQU 01H
- DRCTBIT EQU 02H
- ASYBIT EQU 01H
- DSKBIT EQU 02H
- EOFBIT EQU 04H
- DLEBIT EQU 04H
- CRLFBIT EQU 08H
- INBIT EQU 01H
- OUTBIT EQU 02H
- CLRBIT EQU 04H
- ALLBIT EQU 07H
- ;
- ;
- MACLIB Z80 ;INCLUDE Z-80 MICROS
- ;
- BIOS$PAGE EQU 2H ;bios page pointer
- BIOS EQU MSIZE*1024-BIOSSZ
- IBASE EQU BIOS-1024 ;1024 byte allowed
- ;
- ; 8251 USART INIT. EQUATES,7 BIT CHAR-NO PARITY
- ; 1 STOP BIT-BAUD RATE 16X...COMMAND WORD = 4AH
- ;
- CMMND EQU 4AH ;USART COMMAND AS ABOVE
- ;
- INTERP$BASE EQU 100H ;first loc used by inte
- PBEGIN EQU INTERP$BASE+100H
- FIRSTSP EQU INTERP$BASE+103H
- DENTSZ EQU 1AH ;dir entry size,bytes
- DTITLE EQU 06H
- NBLOCKS EQU 19 ;size of SYSTEM.MICRO
- DIRTOP EQU IBASE-1000H
- BUFFER EQU DIRTOP ;USED FOR DENSITY DETERMINATION
- ;
- ORG IBASE
- ;
- LXI SP,100H ;INITIALIZE STACK POINTER
- JMP INIT$IO
- MAIN: LXI H,DIRTOP
- CALL READ$DIR ;read dir into dirtop
- LXI H,DIRTOP ;set dir entry pointer
- LXI D,DENTSZ ;to firet entry after volume
- DAD D
- SHLD DENTP
- ;
- CALL FIND$INTERP ;find the interpreter
- LXI H,LDMSG
- CALL MSG
- CALL READ$INTERP ;then read it in
- ;
- JMP PBEGIN ;boot in SYSTEM.PASCAL
- ;
- ; ---- INITIALIZE I/O -----
- ;All terminal,UART,etc initializing to be done here
- ;Initialize terminal first,in case error message needed
- IF PT3PLUS
- INIT$IO:NOP
- ENDIF
- ;
- ;
- IF ISIO2 ;INITIALIZE 8251
- INIT$IO:MVI A,80H
- OUT TSTAT ;DO A SOFTWARE RESET
- MVI A,80H ;KILL SOME TIME !
- OUT TSTAT
- MVI A,40H ;HERE'S THE RESET
- OUT TSTAT
- MVI A,CMMND ;INIT 8251
- OUT TSTAT
- MVI A,27H
- OUT TSTAT
- ENDIF
- ;
- IF TUART ;INITIALIZE CROMEMCO TUART
- BAUDRS: DB 94H,0CEH,0A2H,92H,88H,84H,82H,1
- INIT$IO:MVI A,1 ;SET A = 1.
- OUT 54H ;SELECT DEVICE A.
- OUT 52H ;RESET DEVICE B.
- LXI H,BAUDRS ;GET ADR OF BAUD RATE TABLE.
- MVI A,11H ;OCTUPLE THE CLOCK.
- IT1: OUT 02H ;& RESET CURRENT DEV.
- MOV A,M ;GET BAUD RATE FROM TABLE.
- INX H ;INCREMENT POINTER.
- OUT 0 ;SET BAUD RATE.
- CALL CIN ;READ KEYBOARD.
- CALL CIN ;READ KEYBOARD AGAIN.
- CPI CR ;IF NOT CARRIAGE-RETURN,
- MVI A,1 ;SLOW THE CLOCK.
- JNZ IT1 ;UNTIL A CARRIAGE-RETURN.
- ENDIF
-
-
- ;
- SCRCLR: LXI H,CLRSCR ;CLEAR TERMINAL
- CALL MSG
- ;
- ; INITIALIZE ALL VARIABLES, POINTERS ETC. AS REQUIRED
- ; DEFAULT FOR BOOT IS STANDARD 3740 FORMAT. PROGRAM CHECKS DENSITY FMT CODE
- ; TRK 0 SEC 1 BYTE 128 FOR OTHER FORMATS
- ;
- INIT01: LXI H,BIOS ;ADDR OF BIOS
- SHLD BIOSADR ;SET ADDR VECTOR FOR INTERPRETER
- XRA A ;DEFAULT TO 128 BYTE SECTORS
- STA SECLEN
- MVI A,8 ;SECTORS PER TRACK
- STA NUMSEC
- LXI H,TRKTBL ;POINT TO DISK PARAMETER TABLE
- MVI B,12 ;LIMIT
- XRA A
- INIT02: MOV M,A ;STORE A ZERO
- INX H ;INCR MEMORY POINTER
- DCR B ;DECR COUNT
- JNZ INIT02 ;LOOP TILL DONE
- ;
- ; CHECK WHICH DRIVES ARE ON LINE AND INITIALIZE THEM
- ;
- CALL DSKINT
- LXI H,ONMSG
- CALL MSG
- LDA NUMDSK ;NUMBER OF DRIVES ON LINE
- ADI 48 ;CONVERT TO ASCII
- MOV C,A
- CALL COUT ;PRINT IT
- LXI H,ONMSG1
- LDA NUMDSK
- CPI 1
- JNZ IND11
- LXI H,ONMSG2
- IND11: CALL MSG ;DISK INITIALIZATION MESSAGE
- LXI H,TRKTBL+1 ;POINT TO DENSITY CODE UNIT #4
- MOV A,M ;GET IT
- PUSH PSW
- ;
- IF DELTA ;(1791)
- CALL DENSEL1 ;SELECT DENSITY FOR READING SYSTEM.MICRO
- ENDIF
- ;
- IF TARBELL ;(1791)
- MVI C,0 ;SELECT DRIVE 0 (UNIT 4)
- CALL SELECT ;SELECTS DENSITY ALSO
- ENDIF
- ;
- LXI H,ONMSG3
- CALL MSG
- POP PSW
- LXI H,ONMSG5
- CPI 1
- JZ IND15
- LXI H,ONMSG4
- IND15: CALL MSG
- LXI H,TRKTBL+2 ;POINT TO SECTOR SIZE CODE
- MOV A,M
- ORA A ;SET FLAGS
- LXI H,ONMSG6
- JZ IND18
- LXI H,ONMSG7
- IND18: CALL MSG ;PRINT THE MESSAGE
- LXI D,TRKTBL+4 ;DENSITY CODE UNIT 5
- LDAX D ;PICK UP THE CODE
- ORA A
- JZ MAIN ;EXIT IF ONLY ONE DRIVE
- LXI H,ONMSG8
- CALL MSG
- LDAX D ;DENSITY CODE
- LXI H,ONMSG4
- CPI 2 ;SINGLE DENSITY ?
- JZ IND20
- LXI H,ONMSG5
- IND20: CALL MSG
- LXI H,TRKTBL+5 ;POINT AT SECSIZ UNIT 5
- MOV A,M ;PICK IT UP
- ORA A
- LXI H,ONMSG6
- JZ IND23
- LXI H,ONMSG7
- IND23: CALL MSG
- JMP MAIN ;RETURN WITH JUMP
- ;
- ;---- READ DIRECTORY AND LOAD IN SYSTEM.MICRO ----
- ;
- READ$DIR: ;read dir 4 blocks into buffer
- ;buffer adr in HL reg
- SHLD UBUF ;DMA DIRECTORY LOAD POINT
- LXI H,800H ;LENGTH=2048 BYTES 800H
- SHLD ULEN
- LXI H,0002H ;STARTING BLOCK
- SHLD UBLK
- XRA A ;ZERO REG A
- STA UNIT
- STA UASY
- MVI A,1
- STA UREQ ;READ REQUEST
- MVI C,0 ;SELECT DRIVE 0
- CALL BIOS ;READ IN DIRECTORY
- RET
- ;
- FIND$INTERP: ;FIND 'SYSTEM.MICRO'
- MVI C,77 ;STOP AFTER THE 77'TH ENTRY
- LHLD DENTP ;GET STARTING ENTRY
- FI$SCH$LP:
- LXI D,DTITLE ;ADVANCE TO TITLE STRING
- DAD D
- LXI D,SYSTLE ;SET DE-REG TO COMPARISON STRING
- MVI B,LENGTH+1 ;COMPARISON LENGTH
- FI$CMP$LP: ;START COMPARING
- LDAX D
- CMP M
- JNZ FI$CONT ;IT'S NOT THIS ONE
- INX D ;HEY, WE'VE STILL GOT A CHANCE
- INX H
- DCR B ;IS THIS THE END OF THE STRING
- JNZ FI$CMP$LP
- JMP FI$FOUND ;I THINK WE FOUND IT
- FI$CONT:
- LHLD DENTP ;ON TO THE NEXT ENTRY
- LXI D,DENTSZ
- DAD D
- SHLD DENTP
- DCR C ;WAIT, IS THERE ANY DIR LEFT?
- JNZ FI$SCH$LP
- FI$HANG: ;INTERPRETER NOT THERE, GO DUMB
- LXI H,NOMICRO
- CALL MSG
- HANG: JMP HANG
-
- FI$FOUND: ;WE'VE GOT IT
- RET
- ;
- LENGTH EQU 12 ;TITLE LENGTH
- SYSTLE DB LENGTH,'SYSTEM.MICRO'
- ;
- ;
- READ$INTERP: ;PUT INTERP IN ITS PLACE
- LHLD DENTP ;GET STARTING BLOCK
- MOV E,M ; INTO HL-REG
- INX H
- MOV D,M
- XCHG
- SHLD UBLK ;STARTING BLOCK
- LXI H,INTERP$BASE ;DMA LOAD POINT
- SHLD UBUF
- LXI H,NBLOCKS*512
- SHLD ULEN
- MVI C,0 ;SELECT DRIVE 0
- CALL BIOS ;READ IN INTERP
- RET
- ;
- ;
- DENTP DS 2
- ;
- ;--------- CHARACTER DRIVERS ---------------
- ;
- ; --- MESSAGE HANDLER -----
- ;
- MSG: MOV A,M ;GET BYTE
- ORA A ;IS IT ZERO
- RZ ;RETURN IF SO
- MOV C,A
- PUSH H ;SAVE POINTER
- CALL COUT ;GIVE BYTE TO TERMINAL
- POP H
- INX H
- JMP MSG
- ;
- ; LOTS OF MESSAGES FOR INITIALIZE
- ;
- NOMICRO:DB 0DH,0AH,'No SYSTEM.MICRO .....',0
- LDMSG: DB 0DH,0AH,0AH,' Loading PASCAL system.....',0
- RDMSG: DB 0DH,0AH,' ERROR ATTEMPTING TO READ DENSITY CODES ',0
- BADFMT: DB 0DH,0AH,'UNSUPPORTED DISK FORMAT UNIT ',0
- BADFM1: DB ' .... PLEASE REBOOT',0DH,0AH,0AH,0
- QUITMSG:DB 0DH,0AH,'UNIT #4 NOT READY .... PLEASE REBOOT',0DH,0AH,0AH,0
- ONMSG: DB 0DH,0AH,0AH,'PASCAL SYSTEM INITIALIZED FOR ',0
- ONMSG1: DB ' DISK DRIVES',0DH,0AH,0
- ONMSG2: DB ' DISK DRIVE',0DH,0AH,0
- ONMSG3: DB 'UNIT NUMBER FOUR IS',0
- ONMSG4: DB ' SINGLE DENSITY',0
- ONMSG5: DB ' DOUBLE DENSITY',0
- ONMSG6: DB ' WITH 128 BYTE SECTORS',0DH,0AH,0
- ONMSG7: DB ' WITH 512 BYTE SECTORS',0DH,0AH,0
- ONMSG8: DB 'UNIT NUMBER FIVE IS',0
- CLRSCR: DB 27,42,26,0 ;CLEARSCREEN FOR ADM-3A AND SOROC
- ;
- ;
- ;---------- DISK ROUTINES -----------
- ;
- ; HOME ALL DRIVES THAT ARE READY, THEN READ FORMAT CODE FROM TRACK
- ; ZERO AND INITIALIZE TRKTBL ENTRIES. FINALLY BOOT SYSTEM FROM DRIVE 0
- ;
- DSKINT: MVI A,2 ;MAX NUMBER OF FLOPPY DRIVES
- STA NUMDSK ;CHECK FOR UP TO 4 DRIVES
- IDSK01: DCR A
- STA DSKDR ;SAVE FOR LATER
- MOV C,A ;TO C ALSO FOR SELECT ROUTINES
- LXI H,TRKTBL+1 ;DENSITY UNIT 4 (WILL ALWAYS BE SINGLE)
- CALL SELECT ;SELECT THE DRIVE
- MVI A,0DH
- OUT DCOM ;INTERRUPT CONTROLLER
- XTHL
- XTHL
- XTHL
- XTHL ;SHORT WAIT FOR STATUS
- IN DSTAT ;READ DISK STATUS
- ANI 80H ;CHECK DRIVE READY
- JZ IDSK03 ;CONTINUE IF READY
- LDA NUMDSK ;NUMBER OF DISKS
- DCR A
- STA NUMDSK ;REDUCE NO OF DRIVES ON LINE BY ONE
- LDA DSKDR ;LOAD DRIVE NO
- JP IDSK01 ;LOOP IF UNIT 4 OK
- LXI H,QUITMSG ;UNIT 4 NOT READY
- CALL MSG
- JMP HANG ;PROCESSOR HALT - MUST REBOOT
- IDSK03: LDA DSKDR ;GET CURRENT DRIVE NO
- CALL INDEX ;GET DISK PARAMETER TABLE POINTER
- XRA A
- MOV M,A ;SET TRACK TO ZERO
- PUSH H ;SAVE FOR LATER
- CALL HOME ;home this drive
- CALL RDSEC1 ;READ IN SECTOR ONE
- CALL LONGDEL ;JUST WAIT
- LDA BUFFER+7FH ;GET DENSITY CODE FROM BUFFER
- ;
- IF NOT DELTA AND NOT TARBELL
- CPI 12H ;SINGLE SIDE DD
- JZ IDSK04
- CPI 92H ;DOUBLE SIDE DD
- JZ IDSK04
- ENDIF
- ;
- CPI 0DDH ;CHECK FOR DD DISK WITH 128 BYTE SECTORS
- JNZ IDSK05
- IDSK04: LXI H,BADFMT ;PRINT ERROR MESSAGE
- CALL MSG
- LDA DSKDR ;DRIVE NO
- ADI 52 ;COMPUTE UNIT NO
- MOV C,A
- CALL COUT ;PRINT IT
- LXI H,BADFM1
- CALL MSG ;PRINT REST OF MESSAGE
- JMP HANG ;AND QUIT
- IDSK05: RRC
- RRC
- RRC
- RRC ;SHIFT RIGHT 4
- ANI 0FH ;EXTRACT DENSITY (1=DBL, 2=SNGL)
- POP H ;get back trktab pointer
- INX H ;POINT TO DENSITY
- MVI B,2 ;DENSITY CODE FOR SINGLE DENSITY
- MOV M,B ;DEFAULT FOR DISKS WITH NO ID CODE
- ORA A
- JZ IDSK09 ;3740 DISK
- CPI 3
- JP IDSK09 ;SHOULDN'T BE > 2 EITHER
- MOV M,A ;STORE DENSITY
- INX H ;POINT TO SECTOR LENGTH CODE
- LDA BUFFER+7FH ;DISK ID CODE
- ANI 0FH ;EXTRACT LENGTH
- MOV M,A ;STORE IN TABLE
- IDSK09: LDA DSKDR ;check if done yet
- ORA A
- JNZ IDSK01 ;not done,continue
- LDA TRKTBL+2 ;SECTOR SIZE UNIT 4
- CPI 2 ;2 = 512 BYTE SECTORS
- RNZ ;ASSUME DEFAULT 128
- LXI H,NUMSEC ;POINT TO NUMBER OF SECTORS UNIT 4
- STA SECLEN ;SET SECTOR LENGTH TO 2 (512 BYTES)
- LDA TRKTBL+1 ;GET DENSITY FLAG
- CPI 1 ;1 = DOUBLE DENSITY
- MVI A,8 ;8 SECTORS PER TRACK (SINGLE DENSITY)
- MOV M,A ;SELECT SINGLE
- RNZ ;RETURN IF NOT DOUBLE
- ADD A ;16 SECTORS PER TRACK (DOUBLE DENSITY)
- MOV M,A ;SELECT DOUBLE
- RET ;exit DSKINT
- ;
- ; READ SECTOR ONE TRACK ZERO INTO BUFFER
- ;
- RDSEC1: LXI H,BUFFER
- SHLD DMAADD ;MEMORY ADDR FOR READ
- LXI H,128
- SHLD ULEN ;NUMBER OF BYTES TO READ
- XRA A
- STA ERRFLG ;ZERO DISK I/O ERROR FLAG
- MVI C,0
- CALL SETTRK ;SET TRACK TO ZERO
- MVI A,1
- STA SECT ;SELECT SECTOR ONE
- CALL READ
- LDA ERRFLG ;CHECK ERROR FLAG
- ORA A
- RZ
- LXI H,RDMSG
- CALL MSG
- JMP HANG
- ;
- ;
- ;Delay loop gives drive 11 mill sec to settle
- ;
- DELAY: LXI B,700H
- DELAY1: DCX B
- MOV A,B
- ORA C
- JNZ DELAY1
- RET
- ;
- ;
- ; LONGDEL LONG DELAY FOR HOME COMMAND
- ;
- LONGDEL:LXI H,5000H
- LXI D,0001H
- XRA A
- LD01: DAD D
- JNC LD01
- RET
-
- ; ***********************************************************
- ;
- ; BIOS ROUTINES START HERE.
- ;
- ; ***********************************************************
- ;
- ;
- ; PBIOS PASCAL I-O ROUTINES 28-JULY-79
- ; MODIFIED FOR DOUBLE DENSITY 15-NOV-79
- ORG LOADP
- ;
- ; I/O JUMP VECTOR
- BEGIN: JMP DSKIO ;ENTRY POINT FOR DISK DRIVERS
- JMP CHDRVR ;ENTRY FOR CHARACTER DRIVERS
- JMP REMIN ;REMOTE IN
- JMP REMOUT ;REMOTE OUT
- ;
- IOXIT: RET
- ;----- PBIOS SCRATCH AREA ------
- TRK: DB 0 ;CURRENT TRACK
- SECT: DB 0 ;CURRENT SECTOR
- DSCT0: DB 0
- DSCT: DB 0
- DTRK: DB 0
- CLAST: DB 0
- LATCH: DB 0 ;LATCH FOR CURRENT DRIVE SELECT
- ;
- ;***************** CHARACTER DRIVERS ******************
- ;
- CHDRVR: LDA UREQ
- ANI CLRBIT
- JRZ CH01
- XRA A
- STA CLAST
- JMP CHX
- CH01: LHLD ULEN
- XCHG
- LHLD UBUF
- CH02: MOV A,E ;SET UP LOOP
- ORA D
- JZ CHX
- DCX D
- LDA UREQ ;WHICH DIRECTION
- ANI OUTBIT
- JRZ CH03
- MOV C,M ;DO OUTPUT
- CALL ECHO
- JR CH06
- CH03: CALL CIN ;DO INPUT
- MOV C,A
- MOV M,A
- LDA UASY
- ANI EOFBIT
- JRNZ CH05
- MVI A,03H
- CMP M
- JRNZ CH05
- LDA UNIT
- CPI 01H
- JRNZ CHX
- INX D
- CH04: MVI M,0 ;LOOP,PUTING ZERO'S IN BUFFER
- DCX D
- INX H
- MOV A,E
- ORA D
- JRNZ CH04
- JR CHX
- CH05: LDA UNIT
- CPI 01H
- CZ ECHO
- CH06: INX H
- JR CH02
- CHX: JP IOXIT
- ;CHAR IN REG C IS INTERPRETED AND OUTPUT
- ECHO: LDA UASY
- ANI DLEBIT
- JRNZ ECH03
- ECH01: LDA CLAST
- CPI 10H
- JRNZ ECH03
- MOV A,C
- SUI 20H
- STA CLAST
- ECH02: LDA CLAST
- DCR A
- JM ECH05
- STA CLAST
- MVI C,32 ;ASCII SPACE
- CALL COUT
- JR ECH02
- ECH03: MOV A,C
- STA CLAST
- CPI 10H
- JRNZ ECH04
- LDA UASY
- ANI DLEBIT
- JRZ ECH05
- MVI A,20H
- STA CLAST
- ECH04: CALL COUT
- LDA UASY
- ANI CRLFBIT
- JRNZ ECH05
- LDA CLAST
- CPI CR
- JRNZ ECH05
- MVI A,0AH
- STA CLAST
- MOV C,A
- CALL COUT
- ECH05: RET
-
- REMIN: RET
- REMOUT: RET
- ;
- ;------------- DISK DRIVERS -------------------
- DSKIO: CALL SELDSK ;SELECT DRIVE IN REG C
- LDA UREQ
- ANI CLRBIT
- JRZ CHK00
- ; DONT ALLOW PASCAL TO CLEAR (HOME) DRIVES
- JP XDSK
- CHK00: LDA UASY
- ANI DSKBIT ;DONT ALLOW SECTOR ACCESS
- JRZ CHKDSK
- JMP IOERR
- CHKDSK: LHLD UBUF ;INIT
- SHLD DMAADD
- LHLD ULEN ;CHECK FOR NO BYTES
- MOV A,H
- ORA L
- JZ XDSK
- CHK01: LDA SECLEN ;CHECK WHICH MAP TO USE
- ANI 03H ;LOOK AT ONLY 2 LSB'S
- CPI 02H
- JRZ NEWMAP
- ORA A ;CHECK IF ZERO
- JZ DSK03
- JMP IOERR ;FORMAT ERROR
- ;
- ;************ MAP FOR 512 BYTE SECTORS ************
- ;
- NEWMAP: LHLD UBLK ;TRACK=BLOCK DIV NUMSEC
- LDA NUMSEC ;GET NUMBER OF SECTORS/TRACK
- MOV C,A ;AND PUT INTO REG BC
- MVI B,0
- CALL DIVPOS
- MOV A,E ;REG E = TRACK
- STA DTRK
- INR A ;ADJUST FOR NO TRACK 0
- MOV C,A
- CALL SETTRK ;SEEK FIRST TRACK
- ; SECTOR = (BLOCK-TRACK*NUMSEC)+1
- LDA DTRK ;TRACK BEFORE ADJUSTMENT
- MOV E,A ;PUT INTO REG DE
- MVI D,0
- LXI H,0000H
- LDA NUMSEC ;GET COUNTER
- MOV B,A
- MULT: DAD D
- DJNZ MULT ;MULTIPLY LOOP
- XCHG ;REG DE=TRK*NUMSEC
- LHLD UBLK ;SET UP FOR SUBTRACTION
- ANA A ;RESET CARRY FLAG
- DSBC DE ;SUBTRACT HL-DE
- MOV A,L ;REG L =SECTOR
- INR A ;ADJUST FOR NO SECTOR 0
- STA SECT ;SAVE SECTOR
- LDA DTRK ;UPDATE TRACK COUNTER
- INR A
- STA DTRK
- ;------------------------------------------------
- ; LOOP ON BYTES (IN ULEN)
- ;------------------------------------------------
- NEW01: LDA UREQ ;READ/WRITE
- ANI OUTBIT ;LOOP ON BYTES IN ULEN
- JRZ NEW02
- CALL WRITE ;DO WRITE
- JR NEW03
- NEW02: CALL READ ;DO READ
- NEW03: SHLD DMAADD ;SAVE COUNTERS AND POINTERS
- SDED ULEN
- MOV A,D ;CHECK FOR DONE
- ORA E
- JZ XDSK ;LEAVE IF DONE
- ;--- SECTOR MAP -----
- LXI H,NUMSEC ;SETUP MEMORY POINTER
- LDA SECT ;GET LAST SECTOR
- CMP M ;END OF TRACK YET
- JRZ NEWTRK
- INR A ;ADD ONE TO SECTOR
- STA SECT ;NO,SAVE NEW SECTOR
- JMP NEW01 ;CONTINUE
- NEWTRK: LDA DTRK ;GET OLD TRACK
- INR A ;ADD ONE
- STA DTRK
- MOV C,A
- CALL SETTRK ;SEEK NEW TRACK
- MVI A,1 ;UPDATE SECTOR COUNTER
- STA SECT
- JMP NEW01
- TRKERR: MVI A,4 ;MUST BE BAD ERROR HERE
- STA ERRFLG
- JMP IOXIT
- ;
- ;
- ;******** STANDARD MAPPING ROUTINES ************
- ;
- ;------- START INITIALIZING FOR THE LOOP --------
- DSK03: LHLD UBLK
- DAD H
- DAD H
- LXI B,1AH
- CALL DIVPOS
- PUSH H
- PUSH D
- MOV A,E
- INR A
- STA DTRK
- MOV C,A
- CALL SETTRK
- POP D
- MVI A,06H
- LXI H,0000H
- DSK04: DAD D
- DCR A
- JRNZ DSK04
- LXI B,1AH
- CALL DIVPOS
- INX H
- POP D
- MOV A,E
- CPI 0CH+1
- JC DSK05
- INX H
- DSK05: MOV A,L
- STA DSCT0
- ADD E
- ADD E
- DCR A
- DSK06: SUI 1AH
- JNC DSK06
- ADI 1AH+1
- STA DSCT
- STA SECT
- ;
- ;----------------------------------------------
- ; LOOP ON BYTES (IN ULEN)
- ;----------------------------------------------
- DSK07: LDA UREQ ;DO THE INPUT/OUTPUT NOW
- ANI OUTBIT
- JRZ DSK08
- CALL WRITE
- JR DSK09
- DSK08: CALL READ
- DSK09: SHLD DMAADD ;UPDATE COUNTERS AND POINTERS
- SDED ULEN
- MOV A,D
- ORA E ;CHECK IF DONE YET
- JZ XDSK ;EXIT IF ULEN=0
- ;------ CALCULATE NEXT SECTOR -------
- LDA DSCT
- ADI 02H
- CPI 1BH
- JC DSK14
- SUI 1AH
- DSK14: LXI H,DSCT0
- CMP M
- JRNZ DSK17
- INR A
- RRC
- RAL
- JNC DSK16
- ADI 04H
- CPI 1AH+1
- JC DSK15
- SUI 1AH
- DSK15: PUSH PSW
- LDA DTRK
- INR A
- STA DTRK
- MOV C,A
- CALL SETTRK
- POP PSW
- DSK16: STA DSCT0
- DSK17: STA DSCT
- STA SECT
- JMP DSK07
- XDSK: JMP IOXIT
- ;
- ;DIVPOS - DIVIDES 2 POSITIVE INTERGERS
- ; ENTRY BC=DIVISOR HL=DIVIDEND
- ; EXIT BC=DIVISOR HL=REMAINDER DE=QUOTIENT
- ;
- DIVPOS: LXI D,0000H
- MVI A,01H
- DIV01: INR A
- SLAR C
- RALR B
- JP DIV01
- DIV02: STC
- RALR E
- RALR D
- DSBC BC
- JNC DIV03
- DAD B
- DCX D
- DIV03: SRLR B
- RARR C
- DCR A
- JRNZ DIV02
- RALR C
- RALR B
- RET
- ;
- ;---------- CHARACTER DRIVER PRIMATIVES -------------
- ;
- ; DRIVER FOR CENTRONICS PRINTER (HARDWARE STROBE)
- ; V-G "BIT STREAMER" WITH ADDED ONE SHOT FOR STROBE
- ; CHARACTER IN REG C
- LIST: MOV A,C
- CPI 0CH ;FF CHAR
- RZ ;RETURN IF FF
- LSTLP: IN LSTAT
- ANI LMASK
- JRNZ LSTLP
- MOV A,C ;GET CHAR
- OUT LDATA
- RET
- ;
- ;
- IF ADM3A
- ; ---------------------------------------------------------
- ; ADM-3A DRIVER THIS CODE SIMULATES THE CLEAR TO END OF LINE
- ; AND CLEAR TO END OF SCREEN FUNCTIONS FOR THE ADM-3A
- ; ---------------------------------------------------------
- ; CHARACTER EQUATES
- ;
- NULL EQU 0 ; NULL
- OTHER EQU 0 ; NULL CHARACTER
- HOMCRT EQU 30 ; HOME CURSOR
- RIGHT EQU 12 ; MOVE RIGHT 1 SPACE
- LEFT EQU 8 ; MOVE LEFT 1 SPACE
- UP EQU 11 ; MOVE UP 1 ROW
- DOWN EQU 10 ; MOVE DOWN 1 ROW
- CR EQU 13 ; CARRIAGE RETURN
- EOLN EQU 28 ; CLEAR TO END OF LINE
- EOSN EQU 25 ; CLEAR TO END OF SCREEN
- ERASE EQU 26 ; ERASE SCREEN
- SETXY EQU 29 ; SET X-Y CURSOR ADDRESS
- TAB EQU 9 ; HORIZONTAL TAB
- CTLF EQU 6 ; FLUSH CHARS TO SCREEN (TOGGLE)
- CTLS EQU 19 ; FREEZE CRT (TOGGLE)
-
- ;
- ; CODES FOR CURSOR ACTION CONTROL TABLE (TBL1)
- ;
- DCOL EQU 0 ; COL = COL-1
- ECOL EQU 1 ; COL = COL
- ICOL EQU 2 ; COL = COL + 1
- ZCOL EQU 3 ; COL = 0
-
-
- ;
- ; CONSOLE CHARACTER INPUT ROUTINE
- ;
- CIN: XRA A
- STA FFLG ; RESET FLUSH FLAG
- JMP CONIN ; GO TO CONSOLE INPUT
-
-
-
- ;
- ; CONSOLE OUTPUT DRIVER FOR PASCAL SYSTEM
- ;
- COUT: PUSH H ; SAVE ENVIRONMENT
- PUSH D
- PUSH B
- LDA COL
- MOV E,A ; E = CURRENT COLUMN ADDRESS
- LXI H,XYFLG
- MOV A,M
- ORA A
- JRZ COUT1 ; JUMP IF NOT PROCESSING X-Y CURSOR
- DCR M
- JRNZ DOROW ; ROW ADDRESS
- MOV A,C ; GET NEW COL POSITION
- SUI 32 ; REMOVE ASCII BIAS
- MOV E,A ; UPDATE COL POSITION
- DOXY: CALL CONOUT ; POSITION CURSOR
- JR EXIT0
- DOROW: MOV A,C ; ROW INDEX
- SUI 32 ; ASCII BIAS
- CPI 24 ; LIMIT
- JM DOROW1 ; DO NOT ALLOW SCREEN WRAP AROUND
- MVI C,'7' ; ROW 23
- MVI A,23
- DOROW1: STA ROW ; SAVE ROW INDEX
- JR DOXY
- ;
- COUT1: PUSH B ; SAVE CHARACTER
- MOV A,C
- LXI H,CTBLND
- LXI B,CTBLSZ
- CCDR ; SEARCH CHARACTER TABLE
- LXI H,TBL1
- DAD B ; H/L =ADR IN CHARACTER ACTION TABLE
- MOV A,M ; A = ACTION BYTE
- ANI 3
- DCR A
- CPI ZCOL-1 ; ZERO COLUMN IF NECESSARY
- JRNZ YC1
- XRA A
- MOV E,A
- YC1: ADD E ; ADD IN COLUMN OFFSET
- MOV E,A
- LXI H,TBL2
- DAD B
- DAD B
- MOV A,M
- INX H
- MOV H,M
- MOV L,A ; H/L = ADR OF PROCESSING ROUTINE FOR CHARACTER
- POP B ; CHAR RESTORED TO C REG
- PCHL ; BYE
- ;
- ; PROCESS X-Y CURSOR POSITIONING REQUEST
- ;
- GOXY: LXI H,XYFLG
- MVI M,2 ; COUNT FOR X, Y ADR BYTES
- MVI C,1BH ; ESCAPE
- CALL CONOUT
- MVI C,'=' ; ESCAPE EQUALS SEQUENCE LOADS CURSOR
- JR PUT
- ;
- ; PROCESS TAB EXPANSION TO BLANKS
- ;
- TABOUT: MVI C,RIGHT
- XT0: CALL CONOUT
- INR E ; INCREMENT COL, STOP AT NEXT TAB STOP
- MOV A,E
- ANI 7
- JRNZ XT0
- JR EXIT0
- ;
- ; OUTPUT CHAR IN C WITH ROW PROCESSING
- ;
- PUTH: XRA A ; ZERO
- JR PUTLF1 ; ROW ZERO FOR HOME
- PUTRLF: LDA ROW
- DCR A ; DECR ROW INDEX
- JP PUTRLF1
- XRA A ; SET ROW TO ZERO IF PAST TOP OF SCREEN
- PUTRLF1:JR PUTLF1
- PUTLF: LDA ROW
- INR A ; INCR ROW INDEX
- CPI 24 ; MAX ROW IS 23
- JM PUTLF1
- MVI A,23
- PUTLF1: STA ROW ; SAVE ROW INDEX
- ;
- ; OUTPUT CHAR IN REG C
- ;
- PUT: CALL CONOUT
- ;
- ; TEST AND UPDATE COL POSITION FROM REG E
- ;
- EXIT0: MOV A,E
- ORA A ;CHECK IF MOVED TO HIGHER LINE
- JP YE0
- XRA A ;FORM CURSOR ADDR 0..79
- YE0: CPI 80 ;CHECK IF MOVED TO LOWER LINE
- JRC XE1
- MVI A,79 ; NO AUTO LINE FEED
- XE1: STA COL ; SAVE COL ADDRESS
- ;
- ; RESTORE REGISTERS AND EXIT
- ;
- EXIT1: POP B
- POP D
- POP H
- MOV A,C
- RET
- ;
- ;
- RESET: CALL CLRLN ; CALL CLEAR TO END OF LINE
- JR EXIT0
- ;
- CLRLN: MVI C,' ' ; SPACE TO CLEAR END OF LINE
- MVI A,80 ; COL LIMIT
- SUB E
- JRZ XR1 ; CONTINUE IF COL 80
- MOV B,A ; SPACE COUNT TO B
- XR0: CALL CONOUT ; PRINT A SPACE
- DJNZ XR0 ; LOOP TILL END OF LINE
- XR1: MVI C,0DH
- CALL CONOUT ; REPOSITION CURSOR ON ORIGINAL LINE
- MVI C,RIGHT ; FORWARD SPACE
- MOV B,E ; COL POSITION TO B
- MOV A,B
- ORA A
- RZ ; EXIT IF AT COL 0
- XR2: CALL CONOUT
- DJNZ XR2 ; FORWARD SPACE TILL BACK TO ORIG POSITION
- RET
- ;
- ; CLEAR TO END OF SCREEN
- ;
- CLRS: CALL CLRLN ; CLEAR TO END OF FIRST LINE
- LXI H,ROW ; POINT TO ROW INDEX
- MVI A,23 ; ROW LIMIT
- SUB M ; SUBTRACT ROW INDEX
- JZ EXIT0 ; EXIT IF ALREADY ON LAST ROW
- MOV B,A ; COUNT OF ROWS TO CLEAR
- MVI C,0DH ; CARRIAGE RET
- CALL CONOUT ; PRINT IT
- MOV C,E ; SAVE COL INDEX IN C
- MVI E,0 ; SET COL TO ZERO
- CLRS2: PUSH B ; SAVE INDICES
- MVI C,0AH ; LINE FEED
- CALL CONOUT
- CALL CLRLN ; CLEAR THE LINE
- POP B ; RESTORE INDICES
- DJNZ CLRS2 ; LOOP TILL B IS ZERO
- MOV E,C ; RESTORE COL INDEX
- MVI C,1BH ; ESCAPE
- CALL CONOUT
- MVI C,'=' ; EQUALS
- CALL CONOUT
- LDA ROW
- MOV C,A
- CALL CONOUT ; PRINT ROW
- MOV A,E ; COL INDEX
- ADI 32 ; ASCII BIAS
- MOV C,A
- CALL CONOUT ; PRINT COL
- JMP EXIT0
- ;
- ; SPECIAL CHARACTER TABLE
- ;
- CHRTBL: DB OTHER ; NON-SPECIAL CHARACTER
- DB NULL ; NULL CHARACTER
- DB HOMCRT ; HOME CURSOR
- DB RIGHT ; MOVE CURSOR RIGHT 1 SPACE
- DB LEFT ; MOVE CURSOR LEFT 1 SPACE
- DB UP ; MOVE CURSOR UP 1 SPACE
- DB DOWN ; MOVE CURSOR DOWN 1 SPACE
- DB CR ; CARRIAGE RETURN
- DB EOLN ; ERASE TO END OF LINE
- DB EOSN ; ERASE TO END OF SCREEN
- DB ERASE ; ERASE SCREEN, HOME CURSOR
- DB SETXY ; SET CURSOR ADDRESS
- CTBLND: DB TAB ; MOVE TO NEXT TAB STOP
- CTBLSZ EQU $-CHRTBL ; NUMBER OF ENTRIES IN TABLE
- ;
- ; CURSOR MOTION AND LEAD IN TABLE
- ;
- TBL1: DB ICOL ; NOTHING SPECIAL
- DB ECOL ; NULL
- DB ZCOL ; HOME
- DB ICOL ; RIGHT
- DB DCOL ; LEFT
- DB ECOL ; UP
- DB ECOL ; DOWN
- DB ZCOL ; CR
- DB ECOL ; EOLN
- DB ECOL ; EOSN
- DB ZCOL ; ERASE
- DB ECOL ; SET X-Y ADDRESS
- DB ECOL ; TAB (PROCESSING ROUTINE HANDLES COLUMN)
- ;
- ; CHARACTER DISPATCH TABLE
- ;
- TBL2: DW PUT ; NON-SPECIAL CHARACTER
- DW PUT ; NULL
- DW PUTH ; HOME
- DW PUT ; RIGHT
- DW PUT ; LEFT
- DW PUTRLF ; UP
- DW PUTLF ; DOWN
- DW PUT ; CR
- DW RESET ; EOLN
- DW CLRS ; EOSN
- DW PUTH ; ERASE
- DW GOXY ; SET X-Y ADDRESS
- DW TABOUT ; TAB
- ;
- ; STORAGE LOCATIONS
- ;
- COL: DB 0 ; CURRENT COLUMN
- ROW: DB 0 ; CURRENT ROW
- FFLG: DB 0 ; FLUSH FLAG
- XYFLG: DB 0 ; X-Y FLAG (INITIALLY RESET)
- ATOGL: DB 20H ; UPPER-LOWER CASE TOGGLE ON ^A
- PFLG: DB 0 ; PRINT (ECHO) FLAG
-
- CONST: IN 3
- ANI 2
- RZ
- MVI A,0FFH
- RET
-
- CONIN: IN 3
- ANI 2
- JRZ CONIN
- IN 2
- ANI 7FH ; REMOVE PARITY BIT
- CPI 1 ; CONTROL A
- JRNZ CONIN4
- LDA ATOGL ; TOGGLE LOWER CASE SWITCH
- XRI 20H
- STA ATOGL
- MVI A,1 ; RETURN A CONTROL A
- RET
- CONIN4: MOV C,A ; SAVE CHAR IN C
- CPI 61H ; LOWER CASE A
- JM CONIN6 ; EXIT IF < A
- CPI 7BH ; LOWER CASE Z + 1
- JP CONIN6 ; EXIT IF > Z
- LDA ATOGL ; LOAD LOWER CASE SWITCH
- XRA C ; EXCLUSIVE OR WITH CHAR
- RET
- CONIN6: MOV A,C ; RESTORE CHAR TO A
- RET
-
- CONOUT: IN 3
- ANI 1
- JRZ CONOUT
- MOV A,C ; GET OUTPUT CHAR
- OUT 2
- RET
- ENDIF
- ;
- IF SOROC
- ; ************************************************************
- ;
- ; SOROC AND OTHER TERMINALS NOT REQUIRING COMPLEX SOFTWARE
- ; DRIVERS USE THIS CODE
- ;
- ; *************************************************************
- ;
- ; ---- READ A CHARACTER FROM KEYBOARD ----
- CIN: IN TSTAT ;READ STATUS
- ANI IMSK01
- JRZ CIN
- IN PORT01 ;GET CHAR
- ANI 7FH ;REMOVE BIT 7
- RET
- ;
- ; ----- WRITE CHARACTER IN REG C TO SOROC TERMINAL -----
- ;
- COUT: LDA UNIT
- CPI 06H
- JRZ LIST
- MOV A,C
- CPI CR ;IS IT A CR
- JRZ CURET ;YES,THEN CHECK IF TO FREEZE VIDEO
- CHOUT: IN TSTAT ; GIVE CHAR TO TERMINAL
- ANI OMSK01
- JRZ CHOUT ;WAIT FOR 8251
- MOV A,C ;GET CHAR
- OUT PORT01
- RET
- ;
- ; CARRAGE RETURN- CHECK IF CRT IS TO BE STOPPED - CTRL S
- ;
- CURET: IN TSTAT
- ANI IMSK01
- JRZ CHOUT
- IN PORT01
- ANI 7FH
- CPI CTRLS
- JRNZ CHOUT
- CRLOOP CALL CIN
- CPI CTRLS
- JRZ CHOUT
- JR CRLOOP
- ENDIF
- ;
- ;************************************************************
- ;
- ; DISK DRIVERS TARBELL AND DELTA CONTROLLERS
- ;
- ;************************************************************
- ;
- ; ----- SELECT DISK ,NUMBER IN REG. C -----
- ;
- SELDSK: MOV A,C ;GET NEW DISK NUMBER.
- ANI 3 ;ONLY LOOK AT 2 LSBS
- MOV C,A
- LDA DSKDR ;CURRENTLY SELECTED DRIVE
- CMP C ;COMPARE WITH NEW DRIVE
- RZ ;IF SAME, RETURN.
- LDA NUMDSK ;NUMBER OF DRIVES ON LINE
- DCR A ;SUBTRACT 1 TO GET MAXIMUM DR CODE
- CMP C ;NEWDRIVE > NUMDISKS ?
- JP SELMOR
- ;
- ;IO ERROR EXIT FOR UNRECOVERABLE IO ERRORS,SET ERROR FLAG
- ;
- IOERR: MVI A,4 ;DISK ERROR FLAG
- STA ERRFLG ;PUT IN FLAG
- RET
- ;
- IF PERSCI ;DON'T UPDATE TRACK POSITION, SAME FOR ALL
- SELMOR: MOV A,C ;NEW DRIVE NO
- STA DSKDR ;SAVE IT
- CALL INDEX ;POINT TO DRIVE PARAMETERS
- ELSE
- SELMOR: LDA DSKDR ;UP DATE TRACK TABLE
- CALL INDEX ;FIND TABLE ENTRY FOR DRIVE PARAMETERS
- IN TRACK
- MOV M,A ;SAVE IT IN TABLE
- MOV A,C ;GET NEW DRIVE
- STA DSKDR ;SAVE IN DISKDR
- CALL INDEX ;FIND PARAMETERS FOR NEW DRIVE
- MOV A,M ;GET LAST TRACK POSITION
- OUT TRACK ;UPDATE 1791 TRACK REGISTER
- ENDIF
- ;
- IF DELTA ;(1791)
- INX H ;POINT TO DENSITY
- CALL SELECT ;DRIVE NO IS IN C
- CALL DENSEL ;SELECT IT AND SET SECLEN
- MOV A,M ;GET DENSITY CODE
- CPI 1 ;IS IT DOUBLE
- RZ ;RETURN IF DOUBLE
- ENDIF
- ;
- IF TARBELL ;(1791)
- INX H ;POINT TO DENSITY
- CALL SELECT ;SELECT BOTH DRIVE AND DENSITY FOR TARBELL
- ORA A ;A CONTAINS A ZERO IF SINGLE DENSITY
- RNZ ;RETURN IF DOUBLE DENSITY
- ENDIF
- ;
- IF NOT DELTA AND NOT TARBELL ;(1771)
- CALL SELECT
- ENDIF
- ;
- CALL TIME ;ALLOW STEPPER SETTLE TIME
- CALL IDREAD
- LDA IDTAB3 ;SECTOR LENGTH CODE FROM ADDR FIELD
- STA SECLEN
- MVI A,8 ;512 BYTE SECTORS SINGLE DENSITY
- STA NUMSEC ;SET IT
- RET
- ;
- ;
- ; INDEX PUTS ADDR OF START OF DISK DRIVE PARAMETER BLOCK IN HL
- ; INDEX IS CALLED WITH THE DRIVE NUMBER IN A
- ;
- INDEX: LXI H,TRKTBL
- MOV E,A ;SAVE A COPY OF REG A
- ADD A ;FIGURE OFFSET INTO TABLE
- ADD E
- MOV E,A ;ADD OFFSET TO BASE
- MVI D,00
- DAD D
- RET
- ;
- ; SELECT WILL SELECT THE DISK IN C FOR APPROPRIATE CONTROLLER
- ;
- IF DELTA ;(1791)
- SELECT: MOV A,C ;DRIVE NO TO A
- CMA ;COMPLIMENT IT
- OUT DCONT ;ISSUE COMMAND
- RET
- ENDIF
- ;
- IF TARBELL ;(1791)
- SELECT: MOV A,M ;PICK UP DENSITY CODE
- ADD A
- ADD A
- ADD A ;SHIFT LEFT 3 BITS
- ANI 8 ;MASK OFF TARBELL DD BIT
- MOV B,A ;SAVE IN B FOR LATER
- MOV A,C ;GET DRIVE NUMBER
- ADD A
- ADD A
- ADD A
- ADD A ;SHIFT LEFT 4
- ORA B ;ADD IN THE SINGLE/DOUBLE DENSITY BIT
- OUT DCONT ;ISSUE COMMAND
- MOV A,B ;GET BACK DENSITY BIT
- ORA A ;CHECK FOR ZERO (SINGLE DENSITY)
- RZ
- MVI A,2 ;IF NOT SET SECLEN AND NUMSEC
- STA SECLEN
- MVI A,16
- STA NUMSEC ;16 SECTORS PER TRACK DOUBLE DENSITY
- RET
- ENDIF
- ;
- IF NOT DELTA AND NOT TARBELL ;(1771)
- SELECT: MOV A,C ;GET DRIVE NO
- CMA ;COMPLIMENT IT
- ADD A
- ADD A
- ADD A
- ADD A ;SHIFT LEFT FOUR
- ORI 02H
- STA LATCH ;SAVE IN LATCH
- OUT DCONT ;ISSUE COMMAND
- RET
- ENDIF
- ;
- ; DENSEL SELECTS DENSITY, CODE IN (HL) 1=DOUBLE DENSITY 2=SINGLE DENSITY
- ;
- IF DELTA
- DENSEL: MOV A,M ;GET THE DENSITY CODE
- DENSEL1:OUT WAIT+1 ;SENT CODE TO DENSITY PORT
- CPI 2 ;IS IT SINGLE DENSITY
- RZ ;IF SO RETURN
- MVI A,2 ;IF NOT SET SECLEN AND NUMSEC
- STA SECLEN
- MVI A,16
- STA NUMSEC ;16 SECTORS PER TRACK DOUBLE DENSITY
- RET
- ENDIF
- ;
- ;
- ;READ READ THE SECTOR IN (SECT),FROM PRESENT TRACK
- ;USE STARTING ADDRESS IN (DMAADD).
- ;
- READ: MVI A,RTCNT
- RRETRY: STA ERCNT ;STORE IN ERROR CTR.
- MVI A,0D0H
- OUT DCOM ;INTERRUPT CONTROLLER
- LXI H,RDDONE
- PUSH H ;SET UP RETURN ADDR
- LHLD DMAADD ;GET STARTING ADR.
- LDED ULEN ;BYTES TO DO
- MVI C,DDATA ;DISK DATA PORT
- XTHL
- XTHL ;SHORT DELAY
- IN DSTAT ;READ STATUS.
- ANI 20H ;LOOK AT HLD BIT.
- LDA SECT ;GET SECTOR NUMBER.
- OUT SECTP ;SET SECTOR INTO 1771.
- MVI A,8CH ;READ WITH HEAD LOAD
- JRZ READE ;HEAD NOT LOADED.
- MVI A,88H ;CODE FOR READ W/O HD LD.
- READE: OUT DCOM ;SEND COMMAND TO 1771.
- RLOOP: IN WAIT ;WAIT FOR DRQ OR INTRQ.
- ORA A ;SET FLAGS.
- RP ;DONE IF INTRQ.
- INI ;READ FROM DISK INTO (HL)
- DCX D ;DECREASE BYTE COUNTER
- MOV A,D ;AND CHECK FOR 0
- ORA E
- JNZ RLOOP ;KEEP READING
- POP B ;FIX UP STACK
- RDLP02: CALL BUSY
- ANI 18H
- JRNZ CHECK
- RET
- RDDONE: IN DSTAT ;READ DISK STATUS
- ANI 9DH ;LOOK AT ERROR BITS.
- RZ ;RETURN IF NONE.
- CHECK: CALL ERCHK ;CHECK FOR SEEK ERROR.
- LDA ERCNT ;GET ERROR COUNT.
- DCR A ;DECREMENT COUNT.
- JRNZ RRETRY ;TRY TO READ AGAIN.
- JMP IOERR ;READ DISK ERROR
- ;
- ;ERROR CHECK CHECK FOR RECORD NOT FOUND ERROR,AND SEEK TO
- ;CORRECT TRACK IF REQUIRED.
- ;
- ERCHK: ANI 10H
- RZ ;NOT SEEK ERROR
- CALL IDREAD ;READ TRACK ADDRESS
- LDA IDTAB
- MOV C,A ;SAVE TRACK
- IN TRACK ;CHECK 1771 TRACK REG
- CMP C ;IF SAME,NO ERROR
- RZ
- MOV A,C ;PUT CORRECT TRACK IN 1771
- OUT TRACK
- LDA TRK ;GET TRACK WANTED
- MOV C,A
- CALL SEEK ;AND GO TO IT
- RET
- ;
- ;WRITE WRITE THE SECTOR IN (SECT),FROM PRESENT TRACK
- ;USE STARTING ADDRESS IN (DMAADD)
- ;
- WRITE: MVI A,RTCNT
- WRETRY: STA ERCNT ;STORE IN ERROR COUNTER.
- MVI A,0D0H ;CAUSE INTERUPT
- OUT DCOM
- LXI H,WDONE
- PUSH H ;SET UP RETURN ADDR
- LHLD DMAADD ;GET STARTING ADR
- LDED ULEN ;BYTES TO DO
- MVI C,DDATA ;DISK DATA PORT
- XTHL
- XTHL ;SHORT DELAY
- IN DSTAT ;GET 1771 STATUS.
- ANI 20H ;CHECK FOR HEAD LOAD.
- LDA SECT ;GET SECTOR NUMBER.
- WRITE1: OUT SECTP ;SET THE SECTOR INTO 1771.
- MVI A,0ACH ;SET UP 1771 FOR WRITE.
- JRZ WRITE2 ;HEAD IS NOT LOADED
- MVI A,0A8H ;CODE FOR WRITE W/O HD LD.
- WRITE2: OUT DCOM
- WLOOP: IN WAIT ;WAIT FOR READY.
- ORA A ;SET FLAGS.
- RP ;HOP OUT WHEN DONE.
- OUTI ;WRITE TO DISK FROM (HL)
- DCX D ;DECREASE BYTE COUNTER
- MOV A,D ;AND CHECK FOR 0
- ORA E
- JNZ WLOOP ;KEEP WRITING.
- POP B ;FIX UP STACK
- WRT02: CALL BUSY
- ANI 18H ;DONT LOOK AT LOST DATA BIT
- JRNZ PROCER
- RET
- WDONE: IN DSTAT ;READ DISK STATUS.
- ANI 0FDH ;LOOK AT THESE BITS.
- RZ ;RETURN IF NO ERRORS
- PROCER: CALL ERCHK ;CHECK/CORRECT SEEK ERROR
- LDA ERCNT ;GET ERROR COUNT.
- DCR A ;DECREMENT COUNT.
- JNZ WRETRY ;TRY TO WRITE AGAIN.
- JMP IOERR ;WRITE DISK ERROR
- ;
- ;HOME MOVES HEAD TO TRACK ZERO.USES RESTORE COMMAND,NO HDL
- ;
- HOME: MVI A,0D0H ;CAUSE INTERUPT
- OUT DCOM
- CALL BUSY
- MVI A,01H ;RESTORE,NO HDL,NO VERIFY
- OUT DCOM
- CALL BUSY
- IN DSTAT
- ANI 04H ;MAKE SURE IT'S HOMED
- JRZ HOME
- RET
- ;
- ;
- ;SET TRACK CHECK IF TRACK IN REG C IS EQUAL TO PRESENT
- ;TRACK,AND MOVE TO NEW TRACK IF NOT.
- ;CALLABLE ROUTINES:
- ;SEEK:MOVES HEAD TO TRACK IN REG A
- ;
- SETTRK: IN TRACK
- MOV B,A ;SAVE PRESENT TRACK IN B
- CMP C ;COMPARE WITH NEW TRACK
- RZ ;GO BACK IF SAME
- ;
- IF NOT PERSCI
- MOV A,C ;MOVE TRACK TO SEEK TO
- SEEK: OUT DDATA
- STA TRK ;DO UPDATING WHILE WAITING FOR 1791
- CALL BUSY ;WAIT UNTIL 1791 NOT BUSY
- MVI A,18H+STEP
- OUT DCOM ;SEEK COMMAND,NO VERIFY,WITH HDL
- IN WAIT
- RET
- ENDIF
- ;
- IF PERSCI
- SEEK: MVI A,48H+STEP ;STEP IN WITH HEAD LOAD
- JC SDIR ;STEP IN IF MINUS
- MVI A,68H+STEP ;STEP OUT WITH HEAD LOAD
- SDIR: OUT DCOM ;ISSUE STEP COMMAND
- MVI A,20
- DLOOP: DCR A ;SHORT DELAY LOOP
- JNZ DLOOP
- MOV A,B ;GET PRESENT TRACK
- SUB C ;CALC REQUIRED NUMBER OF STEPS
- JP STEP0 ;CHECK PLUS OR MINUS
- CMA ;COMPLIMENT IF MINUS
- INR A ;TWO'S COMP
- STEP0: MOV B,A ;STEPS TO B
- MVI A,1 ;PERSCI STEP COMMAND
- STEP1: OUT DCONT ;ISSUE PERSCI STEP
- DCR B ;COUNT DOWN NO OF STEPS
- JNZ STEP1 ;LOOP TILL STEPS DOWN TO ZERO
- IN WAIT ;CLEAR 1791
- IN DSTAT ;READ STATUS
- MOV A,C ;GET DESTINATION TRACK
- OUT TRACK ;UPDATE TRACK REGISTER
- LDA LATCH ;SELECT LATCH CODE
- ANI 72H ;MAKE SEEK COMPLETE COMMAND
- OUT DCONT ;ISSUE IT
- IN WAIT ;WAIT TILL SEEK COMPLETE
- LDA LATCH ;GET BACK LATCH
- OUT DCONT ;RESTORE OLD LATCH CODE
- RET
- ENDIF
- ;
- ;BUSY CHECKS 1791 FOR BUSY,RETURNS WHEN NOT BUSY
- ;
- BUSY: MVI A,6 ;ALLOW 12 MICRO SEC SETTLE TIME
- BUSY1: DCR A
- JNZ BUSY1
- BUSY2: IN DSTAT ;GET 1791 STATUS
- RRC ;CHECK BIT 0
- JC BUSY2 ;not done, continue
- RAL ;PUT BITS BACK
- RET
- ;
- ; DELAY LOOP,APPROX 1.8 MILL/SEC ALLOW TIME FOR DRIVE TO SETTLE
- ;
- TIME: LXI B,2000H
- DEL: DCX B
- MOV A,B
- ORA C
- JRNZ DEL
- RET
- ;
- ;
- ;ID READ READS THE ID FIELD ON CURRENT TRACK,AND PUTS DATA
- ;INTO IDTAB. USED TO DETERMINE SECTOR LENGTH,AND CURRENT TRACK
- ;
- IDREAD: IN TRACK
- ORA A ;MAY HAVE DIFFERENT FORMAT
- JRNZ IDRD00
- INR A ;MOVE TO TRACK 1
- CALL SEEK
- IDRD00: MVI A,RTCNT
- IDRD01: STA IDECNT
- MVI A,0D0H
- OUT DCOM
- LXI H,IDTAB
- CALL BUSY
- MVI A,0C4H ;READ ADDRESS COMMAND
- OUT DCOM
- IDRD02: IN WAIT ;WAIT FOR DATA OR INTER
- ORA A
- JP IDRD03
- IN DDATA
- MOV M,A ;PUT BYTE IN TO TABLE
- INX H
- JMP IDRD02
- IDRD03: IN DSTAT
- ANI 08H
- RZ
- LDA IDECNT
- DCR A
- JRNZ IDRD01 ;TRY AGAIN
- JMP IOERR ;ID READ ERROR
-
-
- IDECNT: DB 0 ;RETRY COUNTER
- IDTAB: DB 0
- IDTAB1: DB 0 ;ZERO
- IDTAB2: DB 0 ;SECTOR ADDRESS
- IDTAB3: DB 0
- IDTAB4: DB 0 ;CRC
- IDTAB5: DB 0 ;CRC
- ;
- END
-