TITLE 'SPECTRAVIDEO SV318/328 CP/M BIOS' ; ; REV 21/03/85 TMK rev a.p ; ; 1) SUPPORTS NEW 80-COLUMN CARD IF PRESENT (AUTO-DETECTED) (NEW METHOD) ; 2) FORMAT IMPLEMENTED FOR XEROX 820-II ; 3) TRANSLATES CURSOR KEYS/JOYSTICK INTO WORDSTAR (TM) CURSOR MOVEMENT ; 4) DON'T ALLOW USER TO STAT THE CONSOLE TO THE 80-COLUMN BOARD IF IT ; ISN'T PRESENT AS THIS WILL CRASH THE SYSTEM ; 5) SUPPORT USER DEFINITIONS OF SCREEN COLOR AND CURSOR TRANSLATION ; 6) SUPPORT USER DEFINITION OF FUNCTION KEYS & THEIR SCREEN DISPLAY ; 7) SUPPORT USER SELECTION OF SCREEN SIZE (39 OR 40 COLUMNS) ; 8) FIX CENTRONICS DRIVER SO WON'T GO INTO BASIC IF CTL-STOP IS PRESSED ; 9) ADD RS-232 CARD SUPPORT AS CONSOLE, READER/PUNCH, PRINTER (ALL AS TTY:) ;10) ADD ADM-3A/ADM-31 EMULATION ;11) PATCH CCP SO WE GET 4-ACROSS DIR IF ON 80-COLUMN CARD ; ; TITLE 'BIOS FOR SPECTRAVIDEO CP/M - 21/03/85' ; ; ; CHECKED BO DATA 1984-01-30 ; ; SOME COMMENTS TO THE PROPERTIES OF THIS BIOS IS MARKED ; WITH THE TEXT BO DATA AND A DATE. ; ; UPDATED FOR USE WITH 80 TRACK DRIVES BO DATA 1984-02-27 ; ; modifyd by a.p 1985-03-18 ; 1) Translation to Z-80 Version ; 2) [ Single / Dublesided ] ; PAGE ; ; SPECTRAVIDEO CP/M BIOS [BASIC I/O SYSTEM] ; ; ORIGINALLY WRITTEN BY H.KAWAZOE (DEC 18, 1982) ; REVISED BY JEY SUZUKI (MAR 24, 1983) ; REVISED BY TERRY KENNEDY (JUL 17, 1983 - NOV 29, 1983) ; .z80 ; MACLI B Z80 ; nur bei macro 8080-85 ; ; JUMP VECTOR DEFINITION ; CHSNS EQU 59 CHGET EQU CHSNS+3 CHPSTT EQU CHGET+3 CHPLPT EQU CHPSTT+3 INITXT EQU CHPLPT+3 ; CHPUT EQU 24 HOKENT EQU 38 ;WHERE TOP ADDRESS HOOK TABLE IS HELD ; ; WORK AREA OF ROUTINES IN ROM ; LINLEN EQU 0F543H CNSDFG EQU 0FA06H ; ; UTILITY MACRO DEFINITION ; DELAY MACRO EX (SP),HL EX (SP),HL EX (SP),HL EX (SP),HL ENDM PAGE MTIME EQU 60*30 ;TIME TO STOP MOTOR (30 SEC) ; ; ADDRESS DEFINITION ; FD$CMD EQU 30H ;COMMAND TO FDC FD$STT EQU FD$CMD ;STATUS FROM FDC FD$TRK EQU 31H ;TRACK REGISTER FD$SEC EQU 32H ;SECTOR REGISTER FD$DAT EQU 33H ;DATA REGISTER ; ; COMMAND DEFINITION ; FRCRDY EQU 11010001B ;FORCE READY RESTRE EQU 00000000B ;RESTORE COMMAND SEEK EQU 00010000B ;SEEK COMMNAD STPIN EQU 01010000B ;STEP IN COMMAND (UPDATES TRACK REGISTER) strat6 equ 00000000B ;STEPING MOTOR RATE fuer FD 55F 6 msec. strat12 equ 00000001B ;'-----' '--------' fuer FD 55F 12 msec. STRATE EQU 00000010B ;'-----' '--------' ist normal 20 msec. RDCMD EQU 10000000B ;SECTOR READ COMMAND WRCMD EQU 10100000B ;SECTOR WRITE COMMAND ; ; STATUS DEFINITION ; NOREDY EQU 10000000B ;NOT READY WRPRTC EQU 01000000B ;WRITE PROTECT RTWF EQU 00100000B ;RECORD TYPE/WRITE FAULT RNF EQU 00010000B ;RECORD NOT FOUND SEKERR EQU 00010000B ;SEEK ERROR CRCERR EQU 00001000B ;CRC ERROR LOSTDT EQU 00000100B ;LOST DATA DTREQ EQU 00000010B ;DATA REQUEST INDEX EQU 00000010B ;INDEX HOLE BUSY EQU 00000001B ;BUSY ; ; MISCELLANEOUS I/O PORTS ; INTRQP EQU 34H ;ADDRESS OF INTRQ AND DRQ INTRQ EQU 10000000B ;INTERRUPT REQUEST BIT DRQ EQU 01000000B ;DATA REQUEST BIT ; DSKSEL EQU 34H ;ADDRESS OF DISK SELECT AND MOTOR CONTROL SD0 EQU 00000001B ;SELECT DISK 0 BIT SD1 EQU 00000010B ;SELECT DISK 1 BIT MOTOR0 EQU 00000100B ;DISK 0 MOTOR ON BIT MOTOR1 EQU 00001000B ;DISK 1 MOTOR ON BIT ; DENSEL EQU 38H ;ADDRESS OF DENSITY SELECT FLAG DESMFM EQU 00000000B ;DENSITY MFM BIT u. Vorderseite DESFM EQU 00000001B ;DENSITY FM BIT ruecks equ 00000010B ;density mfm bit u. Rueckseite a.p ; ; BANK SWITCHING PORTS ; PSG$LW EQU 88H ;PSG LATCH PORT PSG$DW EQU 8CH ;PSG WRITE PORT PSG$DR EQU 90H ;PSG READ PORT ; ; CP/M SIZE AND ENTRY DEFINITION ; MSIZE EQU 59 ; BIOSB EQU MSIZE*1024-3*512 CBASE EQU (MSIZE-20)*1024 CPMB EQU CBASE+3400H DOSB EQU CBASE+3C06H IOBYT EQU 3 LOGDIS EQU 4 MAXDRV EQU 2 ; ; patch entfernt da schon gepatcht ! ; CCP PATCH ADRESSES FOR DIRECTORY DISPLAY FIX ; ; ORG CPMB+430H+80H ; ;CCPAT1: JP PATCH1 ;GO TO PATCH AREA FOR FIX ; ; ORG CPMB+465H+80H ;CCPAT2: JP PATCH2 ;GO TO PATCH AREA FOR FIX ; ;BO DATA 1984-02-28 ; DEBLOCK PATCH IN BDOS DIGITAL RESEARCH ID# CPM22-0001 02/19/80 ; NOTE THAT THIS PATCH ALWAYS MUST BE DONE IN DEBLOCKED SYSTEMS ; OTHERWISE THE WRITE TO DIRECTORY FLAG WILL NEVER BE TRANSMITTED ; TO BIOS. THIS PATCH IS NOT INSTALLED IN MOVCPM.COM AS DISTRIBUTED ; BY DIGITAL RESEARCH. IF THE PATCH ISN'T INSTALLED THE ARE FILES ; NOT ALWAYS PROPERLY CLOSED. (THIS IS A VERY COMMON ERROR WHEN YOU ; INSTALL CP/M 2.2 . I HAVE DONE THIS MISSTAKE MYSELF AND THE RESULT ; IS ALWAYS UNPREDICTABLE ERRORS) ;**** geloescht da schon gepatcht ! ; ORG CPMB+12D2H ; NOP ; NOP ; LD HL,0 ; ; END DEBLOCK PATCH ; PAGE ;**** ORG BIOSB ;geloescht .phase BIOSB ; neu da mit m80 zum anhaengen an sysgen ; ACHTUNG .depase nicht vergessen ; BIOS BODY ; START: CBOOTE: JP CBOOT ;COLD START WBOOTE: JP WBOOT ;WARM START JP CONST ;CONSOLE STATUS JP CONIN ;CONSOLE INPUT JP CONOUT ;CONSOLE OUTUT JP LIST ;LIST OUTPUT JP PUNCH ;SERIAL INPUT JP READER ;SERIAL OUTPUT JP HOME ;GO HOME POSITION JP SELDSK ;SELECT DRIVE JP SETTRK ;SET TRACK JP SETSEC ;SET SECTOR JP SETDMA ;SET DMA ADDRESS JP READ ;SECTOR READ JP WRITE ;SECTOR WRITE JP LISTST ;LIST STATUS JP SECTRA ;TRANSLATE LOGICAL TO PHISYCAL DEFS 10*3 ;RESERVED FOR FUTURE EXPANSION ; ; ENTRY VECTOR INTO SOME USEFUL ROUTINES OF CUSTOMIZED BIOS ; JP CALROM JP BLKRD JP BLKWRT JP DMOTOR JP SWITCH ; ;NOTE: BO DATA 1984-02-28 ; THE FIRST CALL TO SWITCH WILL SET DRIVE B: TO SV FORMAT ; THE ONLY WAY TO RETURN TO 80 TRACK ON B: IS TO REBOOT. ; THE SECOND CALL WILL SELECT XEROX 820 FORMAT. ; NEXT CALL WILL SELECT SV FORMAT AND SO ON. ; N.B. IF YOU SELECT A 40 TRACK FORMAT FOR B: THE DRIVE MUST ; ALSO PHYSICALLY BE A 40 TRACK DRIVE. PAGE ; ; USER PARAMETERS LIVE HERE ; ; NOTE: THE LENGTH AND ORDER OF THE FOLLOWING ITEMS MUST NOT BE CHANGED. ; MAKE ADDITIONS BY USING ONE OR MORE OF THE 'RESERVED FOR FUTURE ; EXPANSION' BYTES AND REDUCING THE DS. ; UPARMS: DEFB 0 ;SET -1 IF CURSOR TRANSLATION NOT DESIRED DEFB 15 ;FOREGROUND COLOR, DEFAULT IS WHITE DEFB 1 ;BACKGROUND COLOR, DEFAULT IS black a.p DEFB 1 ;SCREEN BORDER COLOR, DEFAULT IS black a.p DEFB 0 ;SET -1 IF SCREEN WIDTH OF 39 IS DESIRED DEFB 0 ;SET -1 IF FUNCTION KEY DISPLAY IS DESIRED DEFB 0 ;SET -1 IF ADM-3A EMULATION IS DESIRED DEFW 20 ;RS-232 CARD BAUD RATE (SEE 8250 MANUAL) DEFB 0FFH ;SET -1 IF HARDWARE H/S ON RS-232 DESIRED (PIN 5) DEFB 83H ;DEFAULT IOBYTE (LST:=LPT:; RDR:,PUN:=TTY:; CON:=[DYNAMIC] DEFS 8 ;RESERVED FOR FUTURE EXPANSION ; ; NOTE: (BO DATA 1984-02-27) ; ; THE LAST TWO ENTRIES IN THE PARAMETER AREA IS USED BY BO DATA TO ; INDICATE THE NUMBER OF TRACKS ON EACH DRIVE ; PLEASE NOTE THAT THERE IS A DIFFERENCE IN BLOCK LENGHT WHEN USING ; 80 TRACK DRIVES. ; I.E. YOU CANNOT USE COPY BETWEEN 80 AND 40 TRACK DRIVES. ; THIS ERROR WILL ONLY BE OBSERVED BY THE SYSTEM IF YOU TRY TO READ ; OR WRITE DATA TO TRACK 41 ON A 40 TRACK DRIVE. ; IF YOU USE THE OLD 40 TRACK DISKCOPY PROGRAM ON A 80 TRACK SYSTEM ; ONLY THE FIRST 40 TRACKS ON DISK WILL BE COPIED. ; THESE FLAGS ARE PRIMARILY USED TO ALLOW FORMATTING CORRECT NUMBER ; OF TRACKS (THE NEW VERSION OF FORMAT WILL ALSO WORK ON 40 TRACK SYSTEMS) ; THE NEW VERSION OF COPY WILL NOT COPY DISKETTES DEFINED WITH ; DIFFERENT NUMBER OF TRACKS. gilt nur fuer einseitige Laufwerke ! a.p ; ; [ a.p ] fuer doppelseitige Laufwerke sind die trk_?_fl ; verwendet, um festzulegen ab welchem Track auf die ; Rueckseite umgeschaltet werden muss. ; trkAfl: DEFB 80 ;default 80 TRACKS ON DRIVE A: a.p trkBfl: DEFB 80 ;DEFAULT 80 TRACKS ON DRIVE B: PAGE ; FUNDEF: DEFB 'DIR A:',0DH,0 ;F1 DEFB 0,0,0,0,0,0,0,0 ; DEFB 'STAT',0DH,0,0,0;F2 DEFB 0,0,0,0,0,0,0,0 ; DEFB 'WS',0DH,0,0,0,0;F3 DEFB 0,0,0,0,0,0,0,0,0 ; DEFB 'ZSID ',0DH,0,0 ;F4 DEFB 0,0,0,0,0,0,0,0 ; DEFB 'type ',0,0,0,0 ;F5 DEFB 0,0,0,0,0,0,0 ; DEFB 'DIR B:',0DH,0 ;F6 DEFB 0,0,0,0,0,0,0,0 ; DEFB 'stat ',0,0,0 ;F7 DEFB 0,0,0,0,0,0,0,0 ; DEFB 'ren ',0,0,0,0,0;F8 DEFB 0,0,0,0,0,0,0 ; DEFB 'era ',0,0,0,0,0;F9 DEFB 0,0,0,0,0,0,0 ; DEFB 'user ',0,0,0 ;F10 DEFB 0,0,0,0,0,0,0,0 ; ; THIS IS THE END OF THE AREA WHOSE LENGTH MAY NOT VARY ; ***************************************************** PAGE ; DISKS 2 ; DISKDEF 0,1,34,,1024,157,64,64,2 ; DISKDEF 1,0 ; XLT0 EQU 0 ;NO TRANSLATION NECESSARY XLT1 EQU 0 ; DPBASE: ;BASE OF DISK PARAMETER BLOCK DPE0: DEFW XLT0,0000 ;TRANSLATE TABLE DEFW 0000,0000 ;SCRATCH AREA DEFW DIRBUF,dpb0 ;DIR BUFF,PARM BLOCK (DEFAULT 40 TRACK) DEFW CSV0,ALV0 ;CHECK ALLOC VECTORS [ a.p ] ; DPE1: DEFW XLT1,0000 ;TRANSLATE TABLE DEFW 0000,0000 ;SCRATCH AREA DEFW DIRBUF,DPB2 ;DIR BUFF,PARM BLOCK (DEFAULT 80 TRACK ds ) DRBDPB EQU $-2 ; [ a.p ] DEFW CSV1,ALV1 ;CHECK ALLOC VECTORS ; ; SV 40 Track Single Sided ; DPB0: DEFW 34 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT DEFB 7 ;BLOCK MASK DEFB 0 ;EXTENT MASK DEFW 156 ;DISK SIZE - 1 DEFW 63 ;DIRECTORY MAX DEFB 192 ;ALLOC0 DEFB 0 ;ALLOC1 DEFW 16 ;CHECK SIZE DEFW 3 ;RESERVED TRACK ; ; TABLE TO GENERATE PC8001 FORMAT DISK ; DPB1: DEFW 32 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT DEFB 7 ;BLOCK MASK DEFB 0 ;EXTENT MASK DEFW 131 ;DISK SIZE - 1 DEFW 63 ;DIRECTORY MAX DEFB 192 ;ALLOC0 DEFB 0 ;ALLOC1 DEFW 16 ;CHECK SIZE DEFW 2 ;RESERVED TRACK ; ; SV 80 TRACK SINGLE SIDED ; DPB2: DEFW 22h ;34 ;SECTORS PER TRACK DEFB 4 ;BLOCK SHIFT 2K BLOCK DEFB 0FH ;BLOCK MASK 2K BLOCKS DEFB 0 ;1 ;EXTENT MASK (32K/EXTENT) DEFW 14ch ;162 ;DISK SIZE - 1 (326 K) DEFW 7fh ;63 ;DIRECTORY MAX (64 FILES) DEFB 0C0h ;128 ;ALLOC0 DEFB 0 ;ALLOC1 DEFW 20h ;32 ;CHECK SIZE DEFW 3 ;RESERVED TRACKS PAGE ; ; THIS IS THE PATCH AREA FOR THE CCP ; PATCH1: PUSH DE ;SEE CCP.ASM FOR DETAILS PUSH BC ;SAVE CCP'S [BC] CALL GETWID ;GET THE WIDTH CODE, EITHER 1 OR 3 AND B POP BC ;RESTORE CCP'S [BC] JP CPMB+433H+80H ;AND RETURN ; PATCH2: PUSH AF ;SEE CCP.ASM FOR DETAILS PUSH BC ;SAVE CCP'S [BC] CALL GETWID ;GET THE WIDTH CODE, EITHER 1 OR 3 CP B POP BC ;RESTORE CCP'S [BC] JP CPMB+468H+80H ;AND RETURN ; GETWID: PUSH AF ;SAVE INPUT STATE LD A,(IOBYT) ;GET THE IOBYTE AND 3 ;ONLY LOOK AT THE CON: ASSIGNMENT CP 1 ;ON THE 40-COLUMN DISPLAY? JP Z,WEXIT ;IF SO LD A,3 ;ALL ELSE ARE 80-COLUMN DEVICES WEXIT: LD B,A ;RESULT TO [B] POP AF ;RESTORE INPUT STATE RET ; ; SWITCH BETWEEN PC8001 FORMAT AND XEROX 820 FORMAT ; SWITCH: LD A,(DRBDPB) LD HL,DPB0 CP L JR NZ,SWTCH1 LD HL,DPB1 SWTCH1: LD (DRBDPB),HL ; BO DATA 1984-02-28 ADDED CODE LD A,40 ; TELL FORMAT THAT THERE ARE ONLY LD (TRKBFL),A ; 40 TRACKS ON DRIVE B: ; END ADDED CODE RET PAGE ; ; LOGICAL DEVICE HANDLER ; ; DISPATCHER ; DSPCON: LD B,1 DEFB 00010001B DSPRDR: LD B,7 DEFB 00010001B DSPPUN: LD B,5 DEFB 00010001B DSPLST: LD B,3 LD A,(IOBYT) ;GET IOBYTE DSPLOP: RLCA DJNZ DSPLOP AND 00000110B ;GET OFFSET INTO TABLE EX (SP),HL LD E,A LD D,B ADD HL,DE LD A,(HL) INC HL LD H,(HL) LD L,A EX (SP),HL RET ;GOTO DEST ADDRESS PAGE ; ((( CONSOLE STATUS ))) CONST: CALL DSPCON ;CHECK CONSOLE FIELD [BIT 0,1] DEFW TTYSTI ;[TTY:] DEFW CRTSTI ;[CRT:] DEFW BATSTI ;[BAT:] DEFW UC1STI ;[UC1:] ; ; ((( CONSOLE INPUT ))) ; CONIN: CALL DSPCON ;CHECK CONSOLE FIELD [BIT 0,1] DEFW TTYINM ;[TTY:] BO DATA 840131 MASK PARITY ; ONLY IF CONIN DEFW CRTIN ;[CRT:] DEFW BATIN ;[BAT:] DEFW UC1IN ;[UC1:] ; ; ((( CONSOLE OUTPUT ))) CONOUT: CALL DSPCON ;CHECK CONSOLE FIELD [BIT 0,1] DEFW TTYOUT ;[TTY:] DEFW CRTOUT ;[CRT:] DEFW BATOUT ;[BAT:] FUDGE: DEFW UC1OUT ;[UC1:] (WILL GET PATCHED IF NO 80-COL) ; ; ((( LIST STATUS ))) LISTST: CALL DSPLST ;CHECK CONSOLE FIELD [BIT 6,7] DEFW TTYSTO ;[TTY:] DEFW CRTSTO ;[CRT:] DEFW LPTSTO ;[LPT:] DEFW UL1STO ;[UL1:] ; ; ((( LIST OUTPTUT ))) LIST: CALL DSPLST ;CHECK CONSOLE FIELD [BIT 6,7] DEFW TTYOUT ;[TTY:] DEFW CRTOUT ;[CRT:] DEFW LPTOUT ;[LPT:] DEFW UL1OUT ;[UL1:] ; ; ((( PUNCH OUTPUT ))) PUNCH: CALL DSPPUN ;CHECK PUNCH FIELD [BIT 4,5] DEFW TTYOUT ;[TTY:] DEFW PTPOUT ;[PTP:] DEFW UP1OUT ;[UP1:] DEFW UP2OUT ;[UP2:] ; ; ((( READER INPUT ))) READER: CALL DSPRDR ;CHECK READER FIELD [BIT 2,3] DEFW TTYIN ;[TTY:] DEFW CRTIN ;[CRT:] DEFW UR1IN ;[UR1:] DEFW UR2IN ;[UR2:] PAGE ; ; PHYSICAL HANDLER ; ; CRT: ; CRTSTI: LD HL,CHSNS JR CALROM ; CRTIN: LD HL,CHGET CALL CALROM ;%% FOR WS CURSOR KEYS, TILL NEXT ;%% LD B,A ;SAVE IN [B] FOR NOW LD A,(UPARMS) OR A ;FUNCTION KEY TRANSLATION DESIRED? LD A,B ;GET KEYPRESS BACK TO [A] JP Z,TRANSL ;YES RET ;IF NOT, JUST EXIT ; TRANSL: CP 30 JR NZ,NOTU LD A,'E'-40H RET NOTU: CP 31 JR NZ,NOTD LD A,'X'-40H RET NOTD: CP 28 JR NZ,NOTR LD A,'D'-40H RET NOTR: CP 29 RET NZ LD A,'S'-40H RET ;%% ALL DONE ; CRTSTO: LD A,255 ;CRT: IS ALWAYS READY RET ; CRTOUT: LD HL,CHPUT JR LPTOU1 PAGE ; ; LPT: ; LPTDW EQU 10H ;PRINTER DATA WRITE PORT LPTSB EQU 11H ;PRINTER STROBE PORT LPTST EQU 12H ;PRINTER STATUS PORT ; LPTSTO: IN A,(LPTST) ;GET STATUS DATA RRCA ;AND MASSGAE CCF SBC A,A RET ; LPTOUT: CALL LPTSTO ;GET STATUS JR Z,LPTOUT ;LOOP IF BUSY LD A,C ;CHARACTER TO [A] OUT (LPTDW),A ;SEND TO DATA PORT XOR A OUT (LPTSB),A ;SET STROBE LOW DEC A OUT (LPTSB),A ;AND HIGH RET ;AND EXIT ; LPTOU1: LD A,C ;VESTIGAL, STILL USED BY OTHER DRIVERS PAGE ; ; CALL A SUBROUTINE OF ROM ; ; THE ADDRESS SHOULD BE PASSED VIA [HL] ; CALROM: LD (CALLA+1),HL ;SET UP JUMP ADDRESS LD (STKSAV+1),SP ;SAVE CURRENT VALUE OF STACK POINTER ;'CAUSE THE STACK POINTER MAY BE ;POINTING INSIDE OF ROM LD SP,BIOSTK PUSH AF DI LD A,15 OUT (PSG$LW),A IN A,(PSG$DR) OR 00000010B ;ENABLE BASIC ROM OUT (PSG$DW),A EI POP AF CALLA: CALL 0 ;DUMMY, MODIFIED EACH TIME PUSH AF DI LD A,15 OUT (PSG$LW),A IN A,(PSG$DR) AND 11111101B ;ENABLE BK21 OUT (PSG$DW),A EI POP AF STKSAV: LD SP,0 ;DUMMY, MODIFIED EACH TIME RET PAGE ; INTRPT: PUSH AF IF 0 PUSH HL LD HL,(ISTKSV+1) ;IS THIS THE SECOND INTERRUPT? LD A,H OR L POP HL JR NZ,INTIGN ;YES, IGNORE THIS ENDIF LD (ISTKSV+1),SP LD SP,INTSTK LD A,15 OUT (PSG$LW),A IN A,(PSG$DR) OR 00000010B ;ENABLE BASIC ROM OUT (PSG$DW),A CALL 56 ;CALL INTERRUPT ENTRY IN ROM DI IF 0 XOR A LD (ISTKSV+1),A LD (ISTKSV+2),A ENDIF LD A,15 OUT (PSG$LW),A IN A,(PSG$DR) AND 11111101B ;ENABLE BK21 OUT (PSG$DW),A ISTKSV: LD SP,0 POP AF EI RET IF 0 INTIGN: POP AF RET ENDIF ; ; CHECK THE STATUS OF FLOPPY DISK MOTOR ; CHKMOT: LD HL,(MTRCNT) ;GET MOTOR COUNTER LD A,H ;IS COUNTER ALREADY 0? (I.E. STOPPED) OR L RET Z ;YES, DO NOTHING DEC HL ;UPDATE COUNTER LD (MTRCNT),HL ;SET UPDATED VALUE LD A,H ;GONE TO 0? OR L RET NZ ;NOT YET OUT (DSKSEL),A ;YES, STOP MOTOR RET PAGE ; ; TTY: ; TTYSTI: IN A,(TTSTAT) ;GET STATUS BYTE AND 1 ;IS RXRDY SET? RET Z ;NOPE, EXIT XOR A DEC A ;YES, SET FF AND EXIT RET ; ; TTYINM ADDED BY BO DATA 840131 FOR USE WITH CONIN ; TTYINM: CALL TTYIN AND 7FH ;MASK PARITY RET ; TTYIN: CALL TTYSTI ;GET STATUS JP Z,TTYIN ;IF NOT THERE YET IN A,(TTDATA) ;ELSE GET DATA ; NOTE: TTYIN PARITY MUST NOT BE MASKED IF READER (BO DATA 840131) ; IF YOU WANT TO RECEIVE OBJECT CODE FILES USING PIP. ; ; ANI 7FH ;MASK PARITY RET ;AND RETURN ; TTYSTO: IN A,(TTSTAT) ;GET STATUS BYTE AND 20H ;IS TXRDY SET? RET Z ;NOPE, EXIT LD A,(UPARMS+9) ;IS H/W H/S ENABLED? OR A JP Z,SETRDY ;NOPE, GO SIGNAL READY STATE IN A,(TTMODST) ;ELSE GET MODEM STATUS AND 10H ;LOOK AT CTS PIN RET Z ;EXIT IF NOT READY SETRDY: XOR A DEC A ;ELSE SET FF AND EXIT RET ; TTYOUT: CALL TTYSTO ;GET STATUS JP Z,TTYOUT ;IF NOT READY YET LD A,C ;GET CHARACTER TO SEND OUT (TTDATA),A ;SEND IT OUT RET ;AND EXIT ; ; BAT: ; BATSTI: JP CRTSTI BATIN: JP CRTIN BATOUT: JP CRTOUT ; ; UC1: ; UC1STI: JP CRTSTI UC1IN: JP CRTIN UC1OUT: JP CH8PUT ;80-COLUMN DRIVER PAGE ; ;************************************************************************* ; ; MACRO DEFINITION FOR Z80 OPCODES ; UNNECESSARY AS LONG AS YOU'RE USING Z80 ASSEMBLER ; ------------- ;RL MACRO R ; DEFB 11001011B ; DEFB 00010000B+R ; ENDM ;RR MACRO R ; DEFB 11001011B ; DEFB 00011000B+R ; ENDM ; ; EXTERNAL REFERENCES ; PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; PORT DEFINITION ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; CRTC PORT DEFINITION ; CRT$AD EQU 50H ;ADDRESS LATCH PORT (50H) CRT$DA EQU 51H ;DATA PORT (51H) CRT$BK EQU 58H ;BANK SELECT PORT (LSB SHOULD BE 1 TO ENABLE VR ; VRAM EQU 0F000H CRTCNT EQU 24 CRTWDT EQU 80 ; SUBTTL CH8PUT - OUTPUT A CHARACTER TO CRT - ; CH8PUT: PUSH HL PUSH DE PUSH BC PUSH AF CALL CHPUT1 CALL CKDPCS ;DISPLAY NEW CURSOR IF CURSOR ENABLED POP AF POP BC POP DE POP HL RET ; CHPUT1: LD HL,ESCCNT LD A,(HL) ;ARE WE EXECUTING ESCAPE SEQUENCE? AND A JP NZ,INESC ;YES LD A,C ;RESTORE CHARACTER CP ' ' ;CONTROL CODE? JR C,CNTPUT ;YES LD HL,(CSRY) CP 127 ;RUBOUT? JP Z,RUBOUT ;YES CALL PUTCOD ;CONVERT TO RAW CODE AND WRITE TO VRAM CALL RIGHT ;ADVANCE CURSOR RET NZ ;ALL DONE IF NOT WRAPPED TO NEXT LINE LD H,1 ;GO TO START OF THE NEXT LINE PAGE ; ; LINE FEED ; LF: CALL DOWN ;DOWN CURSOR RET NZ ;EXIT IF NOT AT BOTTOM CALL STOCSR LD L,1 ;L:=WINDOW TOP LINE JP DELLN0 ;SCROLL UP BY DELETING THE FIRST LINE ; ; FOLLOWING CONTROL CODES ARE SUPPORTED IN VT-52 MODE ; ; 7 BELL ; 8 BACK SPACE ; 9 TAB ; 10 LINE FEED ; 11 CURSOR HOME ; 12 CLEAR SCREEN ; 13 CARRIAGE RETURN ; ; 27 ENTER ESCAPE SEQUENCE ; 28 CURSOR RIGHT ; 29 CURSOR LEFT ; 30 CURSOR UP ; 31 CURSOR DOWN ; CNTPUT: PUSH AF ;SAVE CHARACTER LD A,(UPARMS+6) ;GET EMULATION MODE OR A JP Z,EMLV52 ;IF EMULATING A VT-52 LD HL,CNATBL-2 ;ELSE SET ADM-3A TABLES LD C,CNAMAX POP AF ;RESTORE CHARACTER JP INDJMP ; EMLV52: LD HL,CNTTBL-2 LD C,CNTMAX POP AF ;RESTORE CHARACTER INDJMP: INC HL INC HL AND A ;MAKE SURE CARRY IS CLEARED DEC C RET M ;UNDEFINED FUNCTION CP (HL) ;FOUND? INC HL JR NZ,INDJMP ;NO LD C,(HL) ;GET ROUTINE ADDRESS IN BC INC HL ; LD B,(HL) ; LD HL,(CSRY) ;JUMP TO EACH ROUTINE WITH CURSOR POS PUSH BC RET PAGE ; ; FUNCTION DISPATCH TABLE - VT-52 ; CNTTBL: DB 7 ;Beep DW fBEEP ;fake a beep for now DB 8 ;Back space DW BS DB 9 ;Tabulation DW TAB DB 10 ;Line feed DW LF DB 11 ;Home DW CSHOME DB 12 ;Clear DW CLRTXT DB 13 ;Carriage return DW CR DB 27 ;Enter escape sequence DW ENTESC DB 28 ;Cursor right (^\) DW ADVCUR DB 29 ;Cursor left (^]) DW BS DB 30 ;Cursor up (^^) DW UP DB 31 ;Cursor down (^_) DW DOWN CNTMAX EQU ($-CNTTBL)/3 ; ; Function dispatch table - ADM-3A ; CNaTBL: DB 7 ;Beep (^G) DW fBEEP ;fake a beep for now DB 8 ;Back space (^H) DW BS DB 9 ;Tabulation (^I) DW TAB DB 10 ;Line feed (^J) DW LF db 11 ;Cursor up (^K) dw up db 12 ;Cursor right (^L) dw right DB 13 ;Carriage return (^M) DW CR db 26 ;Clear screen (^Z) dw clrtxt DB 27 ;Enter escape sequence (^[) DW ENTESC DB 30 ;Cursor home (^^) DW CSHOME CNaMAX EQU ($-CNaTBL)/3 ; FBEEP: LD C,7 ;SEND BEEPS TO OLD HANDLER JP CRTOUT ;LIKE SO... PAGE ; ; SUBTTL ESCAPE SEQUENCE HANDLER (VT-52) ** SVI normal ** ; ESCTBL: DB 'j' ;Clear screen DW CLRTXT DB 'E' ;Clear screen DW CLRTXT ; To maintain compatibility with VT52 DB 'K' ;Erase to end-of-line DW EOL DB 'J' ;Erase to end-of-page DW EOP DB 'l' ;Erase entire line DW ELN DB 'L' ;Insert a line DW ILN DB 'M' ;Delete a line DW DLN DB 'Y' ;Locate cursor DW LOC DB 'A' ;Cursor up DW UP DB 'B' ;Cursor down DW DOWN DB 'C' ;Cursor right DW RIGHT DB 'D' ;Cursor left DW LEFT DB 'H' ;Cursor home DW CSHOME DB 'p' ;Enter reverse mode DW ENTREV DB 'q' ;Exit reverse mode DW EXTREV DB 'x' ;Set modes DW SETMOD DB 'y' ;Reset modes DW RSTMOD ESCMAX EQU ($-ESCTBL)/3 page ; ; SUBTTL Escape sequence handler (ADM-3A / ADM-31) ; ESaTBL: DB '*' ;Clear screen DW CLRTXT DB ':' ;Clear screen DW CLrtxt db '+' ;Clear screen dw clrtxt DB 'y' ;Erase to end-of-page DW EOP DB 'T' ;Erase to end of line DW Eol DB 'E' ;Insert a line DW ILN DB 'R' ;Delete a line DW DLN DB '=' ;Locate cursor DW LOC DB ')' ;Enter reverse mode DW ENTREV DB '(' ;Exit reverse mode DW EXTREV ESaMAX EQU ($-ESaTBL)/3 PAGE ; SETMOD: LD A,1 DEFB 01H RSTMOD: LD A,2 DEFB 01H LOC: LD A,4 ;SAY ROW IS EXPECTED NEXT DEFB 01H ;'LXI B' INSTRUCTION ENTESC: LD A,255 ;TELL HIM WE'RE IN ESCAPE SEQUENCE LD (ESCCNT),A RET ; INESC: JP P,INESC1 ;ARGUMENTS EXPECTED LD (HL),0 ;EXIT FROM ESCAPE SEQUENCE LD A,C ;RESTORE CHARACTER PUSH AF ;SAVE LD A,(UPARMS+6) ;GET EMULATION MODE OR A JP Z,EMNV52 ;IF EMULATING A VT-52 LD HL,ESATBL-2 LD C,ESAMAX POP AF ;RESTORE CHARACTER JP INDJMP ;AND JUMP ; EMNV52: LD HL,ESCTBL-2 LD C,ESCMAX POP AF ;RESTORE CHARACTER JP INDJMP ; INESC1: DEC A ;SET MODES? JR Z,GOSET ;YES DEC A ;RESET MODES? JR Z,GORSET DEC A LD (HL),A ;UPDATE ESCCNT LD A,CRTWDT LD DE,CSRX ; JR Z,INESC2 ;COLUMN EXPECTED LD (HL),3 LD A,CRTCNT ;ROW EXPECTED DEC DE ;POINT CSRY INESC2: LD B,A ;GET MAX LIMIT IN B LD A,C ;RESTORE CHARACTER SUB ' ' ;0-XX CP B INC A LD (DE),A RET C ;LEGAL VALUE LD A,B ;SUBSTITUTE BY POSSIBLE LARGEST VALUE LD (DE),A RET PAGE ; ; SET VARIOUS MODES ; GOSET: LD (HL),A ;EXIT FROM ESCAPE SEQUENCE LD A,C ;RESTORE CHARACTER SUB '4' ;BLOCK CURSOR? JR NZ,GOSET1 ;NO BLKCSR: LD BC,11100000B JR STRG10 ; GOSET1: DEC A ;CURSOR OFF? RET NZ ;UNIMPLEMENTED FEATURE OFFCSR: LD BC,256*00100000B+10011111B JR STRG10 ; ; RESET VARIOUS MODES ; GORSET: LD (HL),A ;EXIT FROM ESCAPE SEQUENCE LD A,C ;RESTORE CHARACTER SUB '4' ;UNDERSCORE CURSOR? JR NZ,GORST1 ;NO UNDCSR: LD BC,256*00000101B+11100000B JR STRG10 ; GORST1: DEC A ;CURSOR ON? RET NZ ;NO, UNIMPLEMENTED FEATURE ONCSR: LD BC,256*01000000B STRG10: LD A,10 ;SELECT 'CURSOR-START-RASTER' OUT (CRT$AD),A LD A,(CREG10) ;GET WHAT IS CURRENTLY OUTPUT AND C ;STRIP OFF SOME BITS OR B ;ADD SOME BITS LD (CREG10),A ;REMEMBER THIS VALUE OUT (CRT$DA),A ;SET CRTC'S REGISTER RET ; ; ENTER REVERSE MODE ; ENTREV: DEFB 3EH ;'MVI A,' INSTRUCTION ; ; EXIT REVERSE MODE ; EXTREV: XOR A LD (REVFLG),A RET PAGE ; ; DISPLAY A CURSOR ; CKDPCS: DSPCSR: PUSH AF LD HL,(CSRY) ;GET CURRENT CURSOR POSITION CALL GETOFS ;CALCULATE OFFSET FROM SCREEN TOP LD A,14 OUT (CRT$AD),A LD A,H OUT (CRT$DA),A LD A,15 OUT (CRT$AD),A LD A,L OUT (CRT$DA),A POP AF RET PAGE ; SUBTTL CURSOR MOVE OPERATIONS ; ; CURSOR RIGHT ; RIGHT: LD A,CRTWDT CP H ;ARE WE AT THE RIGHT-END OF LINE? RET Z ;YES, RETURN WITH Z FLAG INC H ;GO TO NEXT COLUMN JR STOCSR ; ; BACK SPACE ; BS: CALL LEFT RET NZ ;NOT AT LEFT-END LD H,CRTWDT DEFB 11H ;'LXI D,' INSTRUCTION ; ; CURSOR LEFT ; LEFT: DEC H ;ARE WE AT THE LEFT-END OF LINE? DEFB 3EH ;'MVI A,' INSTRUCTION ; ; CURSOR UP ; UP: DEC L ;ARE WE AT THE TOP OF ANY WINDOW? RET Z ;YES, RETURN WITH Z FLAG JR STOCSR ; ; ADVANCE CURSOR ; ADVCUR: CALL RIGHT RET NZ LD H,1 ; ; CURSOR DOWN ; DOWN: LD A,CRTCNT ;GET AN ACTUAL BOTTOM OF SCREEN CP L ;ARE WE AT THE BOTTOM OF SCREEN? RET Z ;YES, RETURN WITH Z FLAG JR C,DOWN1 ;WE'RE BELOW SCREEN BOTTOM! INC L ;GO TO NEXT LINE STOCSR: LD (CSRY),HL RET ; DOWN1: DEC L XOR A JR STOCSR ; ; TABULATION ; TAB: LD A,' ' CALL CHPUT1 LD A,(CSRX) DEC A AND 00000111B JR NZ,TAB RET ; ; CURSOR HOME ; CSHOME: LD L,1 ; ; CARRIAGE RETURN ; CR: LD H,1 ;CR ONLY, NOT NEW-LINE JR STOCSR PAGE ; SUBTTL LINE DELETE & LINE INSERT STUFF OF CRT ; ; DELETE A LINE SPECIFIED BY L ; ; CURSOR SHOULD BE SET AT THE TOP OF LINE ; DLN: CALL CR DELLN0: LD A,CRTCNT ;GET AN ACTUAL HEIGHT OF SCREEN SUB L RET C ;SOMETHING IS WRONG JP Z,ELN ;DELETE THE BOTTOM LINE ONLY ; ; WE MOVE LINE BY LINE BECAUSE WE DON'T WANT INTERRUPTS DISABLED ; FOR LONG PERIOD OF TIME. ; DELLN1: PUSH AF ;SAVE COUNTER INC L CALL MOVUP POP AF ;RESTORE COUNTER DEC A JR NZ,DELLN1 JP ELN ;BLANK BOTTOM LINE ; ; INSERT A LINE ; ; CURSOR SHOULD BE SET AT THE TOP OF LINE ; ILN: CALL CR INSLN0: LD A,CRTCNT ;GET AN ACTUAL HEIGHT OF SCREEN LD H,A SUB L RET C ;SOMETHING IS WRONG!! JP Z,ELN LD L,H ; ; WE MOVE LINE BY LINE BECAUSE WE DON'T WANT INTERRUPTS DISABLED ; FOR LONG PERIOD OF TIME. ; INSLN1: PUSH AF ;SAVE COUNTER DEC L CALL MOVDWN POP AF ;RESTORE COUNTER DEC A JR NZ,INSLN1 JR ELN PAGE ; SUBTTL ERASING STUFF ; ; ERASE PREVIOUS CHARACTER ; RUBOUT: CALL BS ;BACK SPACE RET Z ;WE'RE AT THE TOP OF SCREEN LD C,0 ;OVERSTRIKE WITH A SPACE JP PUTVRM ;0 IS A RAW CODE FOR ' ' ; ; ERASE ENTIRE LINE ; ; CURSOR SHOULD REMAIN UNCHANGED ; ELN: LD H,1 ; ; ERASE TO END-OF-LINE ; ; CURSOR SHOULD REMAIN UNCHANGED ; EOL: PUSH HL ;SAVE CURRENT POSITION (COLUMN) PUSH HL ;DITTO CALL VADDR ;GET VRAM ADDRESS TO [HL] POP DE ;RESTORE CURRENT POSITION LD A,1 DI ;INTERRUPTS SHOULD BE DISABLED OUT (CRT$BK),A ;CONNECT VRAM LD A,CRTWDT EREOL1: LD (HL),0 ;OVERSTRIKE WITH A SPACE INC HL INC D CP D JR NC,EREOL1 XOR A ;DISCONNECT VRAM OUT (CRT$BK),A EI ;END OF CRITICAL SECTION POP HL RET ; CLRTXT: CALL CSHOME ; ; ERASE TO END-OF-PAGE ; ; CURSOR SHOULD REMAIN UNCHANGED ; EOP: CALL EOL ;ERASE TO END-OF-LINE LD A,CRTCNT ;GET AN ACTUAL HEIGHT OF CRT CP L RET C ;SOMETHING IS WRONG! RET Z ;ALL DONE LD H,1 INC L JR EOP PAGE ; SUBTTL LOW LEVEL SUBROUTINES ; ; MOVE A LINE SPECIFIED BY [L] UPWARD ; MOVUP: PUSH HL ;SAVE CURSOR POSITION LD H,1 CALL VADDR EX DE,HL LD HL,-80 JR MOVDN1 ; ; MOVE A LINE SPECIFIED BY [L] DOWNWARD ; MOVDWN: PUSH HL LD H,1 CALL VADDR EX DE,HL LD HL,80 MOVDN1: ADD HL,DE EX DE,HL ;NOW [DE]=DESTINATION, [HL]=SOURCE LD BC,80 LD A,1 DI ;INTERRUPTS SHOULD BE DISABLED OUT (CRT$BK),A ;CONNECT VRAM LDIR XOR A OUT (CRT$BK),A EI POP HL RET ; GETCOD: CALL GETVRM CP 60H ;NORMAL ASCII? (00H - 5FH) JR C,GETCD1 ;YES SUB 60H CP 60H ;REVERSE ASCII? (60H - 0BFH) JR C,GETCD1 ;YES ADD A,40H ;GRAPHIC CHARACTER (0C0H - 0FFH) RET ; GETCD1: ADD A,' ' ;MAKE IT 20H - 7FH RET ; GETVRM: PUSH HL ;SAVE COORDINATE CALL VADDR ;CALCULATE VRAM ADDRESS LD A,1 DI ;INTERRUPTS SHOULD BE DISABLED OUT (CRT$BK),A ;CONNECT VRAM LD C,(HL) ;GET FROM VRAM XOR A OUT (CRT$BK),A ;DISCONNECT VRAM EI ;END OF CRITICAL SECTION LD A,C ;PASS CODE TO [ACC] ALSO POP HL ;RESTORE COORDINATE RET PAGE ; ; CONVERT AN ASCII CODE IN [C] REGISTER TO A RAW CODE ; ; 020H - 07EH ARE MAPPED TO 000H - 05EH (NORMAL) ; 060H - 0BEH (REVERSE) ; 0A0H - 0DEH ARE MAPPED TO 0C0H - 0FFH ; ; NOTE THAT 0BFH IS RESERVED FOR CURSOR ; CNVCOD: LD A,C SUB ' ' ;CONTROL CHARACTER? JR C,CNVCD1 ;YES, ILLEGAL CHARACTER. RETURN BLANK CP 127-' ' ;LESS THEN 7FH? JR C,CNVCD2 ;YES, LEGAL ASCII CHARACTER CP 160-' ' ;LESS THEN 0A0H? JR C,CNVCD1 ;YES, ILLEGAL CHARACTER. RETURN BLANK CP 224-' ' ;GREATER THAN 0DFH? JR NC,CNVCD1 ;YES, ILLEGAL CHARACTER. RETURN BLANK ADD A,64 LD C,A RET ; CNVCD1: XOR A CNVCD2: LD C,A LD A,(REVFLG) ;ARE WE IN REVERSE MODE? AND A RET Z LD A,C ADD A,60H ;MAKE IT A REVERSE PATTERN LD C,A RET ; PUTCOD: CALL CNVCOD ;CONVERT CODE AND PASS RESULT TO [C] PUTVRM: PUSH HL ;SAVE CURSOR POSITION CALL VADDR ;CALCULATE ACTUAL ADDRESS LD A,1 DI ;INTERRUPTS SHOULD BE DISABLED OUT (CRT$BK),A ;CONNECT VRAM LD (HL),C ;PUT CODE THERE XOR A ;DISCONNECT VRAM OUT (CRT$BK),A EI ;END OF CRITICAL SECTION POP HL ;RESTORE CURSOR POSITION RET PAGE ; ; CALCULATE BUFFER ADDRESS OUT OF H,L (COLUMN,ROW) ; ; ADDRESS RETURNED IN HL ; VADDR: CALL GETOFS LD DE,VRAM ADD HL,DE RET ; GETOFS: LD A,L ;GET ROW IN A LD E,H ;GET COLUMN IN E LD H,0 LD D,H ADD A,A ;*2 ADD A,A ;*4 ADD A,L ;*5 ADD A,A ;*10 ADD A,A ;*20 RL H ADD A,A ;*40 RL H ADD A,A ;*80 RL H LD L,A ADD HL,DE LD DE,-80-1 ADD HL,DE RET ; CREG10: DEFB 01100111B ;CURSOR START RASTER (strich blinkend) CSRY: DEFB 1 CSRX: DEFB 1 ESCCNT: DEFB 0 REVFLG: DEFB 0 ; BO DATA 1984-02-28 ; CHECK SPACE IN MEMORY (VIDEO RAM IS BASED AT 0F000H) ; IF MARGIN IS A POSITIVE NUMBER THEN ALL IS OK ; MARGIN EQU 0F000H-$ ; IS THERE SPACE TO MOVE CP/M UPWARDS ; IN MEMORY ??? PAGE ; ;************************************************************************* ; ; UL1: ; UL1 IS ADDED AS AN XON/XOFF USING THE SERIAL CARD ; BO DATA 840131 ; ; NOTE: ALL CHARACTERS RECEIVED EXCEPT XOFF (CTRL S) WILL BE ; ACCEPTED AS XON ; UL1STO: IN A,(TTDATA) ; CHECK CONTENT OF RECEIVER REG ; THIS READ MAY BE DONE AT ANY TIME ; SINCE PREVIOUS BYTE WILL REMAIN IN ; THE RECEIVER REGISTER UNTIL A NEW BYTE ; IS RECEIVED. CP 'S'-64 ; CHECK XOFF LD A,0 ; SET FOR RETURN RET Z ; RETURN IF XOFF IN A,(TTSTAT) ; GET TRANSMITTER STATUS AND 2 ; CHECK TRANSMITTER EMPTY RET Z ; IF NOT SAY SO OR 0FFH ; OTHERWISE ALL IS OK RET UL1OUT: CALL UL1STO ; GET STATUS JR Z,UL1OUT ; WAIT FOR READY LD A,C ; PREPARE FOR OUTPUT OUT (TTDATA),A ; OUTPUT BYTE RET ; ; ; UR1: ; UR1IN: JP CRTIN ; ; UR2: ; UR2IN: JP CRTIN ; ; PTP: ; PTPOUT: JP CRTOUT ; ; UP1: ; UP1OUT: JP CRTOUT ; ; UP2: ; UP2OUT: JP CRTOUT ; PAGE ; DISK HANDLER ; ; ; ((( ASK SECTOR TRANSLATE TABLE ))) ; ; SECTRA: LD H,B ;RETURN WITH ORIGINAL VALUE. LD L,C ;BECAUSE "SKEW" IS NOT USED. INC HL ;SET IT FROM SECTOR-1 RET ; ; ; ((( SELECT SPECIFIED DRIVE ))) ; ; SELDSK: LD A,MAXDRV-1 ;GET MAXIMUM DRIVE # CP C ;MUST BE BETWEEN 0 AND MAX JR C,SELERR ;INVALID DRIVE NUMBER. LD A,C ;SAVE IT FOR THE FUTURE. LD (LOGDRV),A ;JUST SAVE, NOW. LD L,C ;[L]=DISK DRIVE # LD H,0 ;HIGH ORDER ZERO. ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD DE,DPBASE ;SET TABLE ADRS. ADD HL,DE ;MAKE DPBASE+(DISK# * 16) ; ; 20/03/85 a.p push af ; sichern cp 0 ; drive 0 ? jr nz,Blw ; nein so b: ld a,(trkAfl) ld (tst$s),a ; setze umschaltabfrage fuer das A: pop af ret Blw: ld a,(trkBfl) ld (tst$s),a ; setze umschaltabfrage fuer das B: pop af RET ; SELERR: XOR A LD (LOGDIS),A ;CLEAR LOGDIS TO AVOID INFINITE LOOP LD L,A LD H,A RET ; PAGE ; ; ((( SET HEAD TO TRACK 0 ))) ; ; HOME: LD C,0 ; ; ; ((( SET DESIRED TRACK ))) ; ; SETTRK: LD A,C ;GIVEN BY [C]. LD (LOGTRK),A ;SAVE THE TRACK. RET ; ; ; ((( SET DESIRED SECTOR ))) ; ; SETSEC: LD A,C AND A INC A ;YOU KNOW THAT. RRA ;MAKE IT AS [0-..] LD (LOGSEC),A ;SAVE LOGICAL SECTOR. LD HL,SECFLG ;SET TO "SECFLG". LD (HL),0 ;SHOULD BE ODD. RET NC ;RETURN, IF SO. INC (HL) ;SET IT AS EVEN SECTOR. RET ; ; ; ((( SET DMA ADDRESS ))) ; ; SETDMA: LD (BUFADR),BC RET PAGE ; ********************************* ; *** DISK READ / WRITE ROUTINE *** ; *** WITH SECTOR BLOCKING *** ; *** LOGICAL TO PHYSICAL *** ; ********************************* ; ; ; NOTE: (BO DATA 1984-02-27) ; THE BDOS DIRECTIVE "WRITE UNALLOCATED" IS NOT HANDLED ; IN THIS BIOS. IN AN ENVIRONMENT WITH MIXED BLOCK SIZE ; LIKE THIS SYSTEM THE SOFTWARE IS SIMPLIFIED. ; UNNECCESSARY PREREADS WILL OCCOUR FREQUENTLY. ; NO CHANGES IN THE DISK DRIVERS ARE MADE BY BO DATA. PAGE ; ((( READ LOGICAL ONE BLOCK ))) ; READ: LD HL,IFACT ;SELECT ACTIVE FLAG. LD B,(HL) ;PICK IT UP. LD (HL),1 ;ALWAYS BECOMES ACTIVE LD HL,LOGTRK ;CHECK IF DIRECTORY TRACK LD A,3 ;READING DIRECTORY TRACK? CP (HL) JR NZ,SKIPS ;SKIP IF NOT INC HL ;BUMP TO THE LOGSEC LD A,(HL) ;PICK UP THE SECTOR DEC A ;IS IT SECTOR-01? JR Z,ACTIO ;IF SO, BE SURE TO READ SKIPS: LD A,B ; OR A ;BUFF ACTIVE? JR Z,ACTIO ;NO, DO ACTUAL IO CALL CHKNEW ;CHECK NEW BLCOCK OR NOT. JR NZ,ACTIO ;NEW DISK! SKIP READ DISK ; ; READ HAS BEEN ISSUED TO THE SAME POSITION ; LD A,(ODDFLG) ;HAS BEEN "WRITE ODD" OR A ; JR Z,RDOK ;DO NOT PRE-READ, JUST MOVE FROM BUFFER ; ; CHECK DFLAG AND IF DFLAG THEN WRITE BUFF1 ; ACTIO: CALL OLDWR ;IF DFLAG THEN WRITE CALL OLDNEW ;SET UP PARAMETERS FOR READ CALL DSKRD ; ; ; SET-UP BUFF POINTER FOR DATA TRANSFER ; RDOK: LD DE,IFBUFF ;SOURCE AS SCA CALL SCTAB ;IS IT ODD ? JR NC,TRANDAT ;IF SO, AS IT IS. LD DE,IFBUFF+128 ;SET SCB AS SOURCE. ; ; TRANSFER TO BUFFER SPECIFIED BY DOS ; TRANDAT:LD HL,(BUFADR) ;BUFADR AS DESTINATION. EX DE,HL ;XCHANGE IT. JP TRAN ; ; PAGE ; ((( WRITE LOGICAL ONE BLOCK ))) ; WRITE: LD A,C ;CHECK WRITE FOR "DIR" LD (DIRFLG),A ;SAVE IT. CALL CHKNEW ;PREREAD IS NECESSARY ? JP Z,OLDCAS ;SAVE OLD BLOCK. ; ; WRITE HAS BEEN ISSUED TO DIFFERENT POSITION ; CALL OLDWR ;IF DFLAG THEN WRITE CALL OLDNEW ; CALL SCTAB ; JP NC,DF0NA ; ; ; (((( READ (NEW) TO IFBUFF )))) ; CALL DSKRD ;PERFORM PHYSICAL READ. DF1NB: LD DE,SCB ;TRANSFER DMA TO SCB. CALL TRNDMA ;MOVING ON. JP OLDWR1 ; ; OLDCAS: CALL SCTAB ; JP C,DF1NB ; ; ; (((( DMA TO SCA )))) ; DF0NA: LD DE,SCA ;TRANSFER DMA TO SCA. CALL TRNDMA ;MOVING ON. LD A,(DIRFLG) ;IS THERE "DIR" AREA DEC A ;HAS BEEN SO ? JR Z,DIRWR ;WRITE "DIR" LD A,1 ;HOW LONELY YOU WRE. LD (ODDFLG),A ; JR OLDWR2 ;PERFORM IN GENERAL.(D/D) ; ; (((( IF DFLAG IS ON, THEN WRITE OLD BLOCK )))) ; OLDWR: LD A,(DFL) ;CHECK BUFFER REMAINS OR NOT. AND A ;HAS BEEN EMPTY ? RET Z ;IF SO, GET BACK SOON. DIRWR: LD HL,SCA ;MOVE SCA TO BUF2. LD DE,BUF2 ;SAVE FOR A WHILE. CALL TRAN ;MOVING ON. CALL DSKRD ; LD HL,BUF2 ;MOVE BUF2 TO SCA. LD DE,SCA ;SET IT BACK TO SCA. OLDWR0: CALL TRAN ;MOVING ON. OLDWR1: CALL DSKWR ; OLDWR2: LD (DFL),A ;SET BUFFER EMPTY. XOR A ;SET NON ERROR CODE. RET ; PAGE ; (((( CHECK IF ODD SECTOR OR EVEN )))) ; SCTAB: LD A,(SECFLG) ;CHECK ODD OR EVEN. RRA ;SET THE ANSWER IN CARRY. RET ; ; ((( CHECK IF NEWPRM=OLDPRM ))) ; Z FLAG MEANS SAME ; CHKNEW: LD B,3 ;SET 3 TIMES AS CHECK. LD DE,NEWPRM ;CHECK WITH NEWPRM. LD HL,OLDPRM ;AND OLDPRM. CHKLOP: LD A,(DE) ;PICK UP NEW ONE. CP (HL) ;IS IT LOOKS LIKE ? RET NZ ;IF NOT SO, LET HIM KNOW. INC HL ;BUMP THE POINTER. INC DE ;BUMP IT ALSO. DJNZ CHKLOP ;LOOP UNTIL DONE. RET ; ; ((( OLD PRM=NEWPRM ))) ; OLDNEW: LD HL,NEWPRM ;PUT OLD PRAM. LD DE,OLDPRM ;INTO NEW PARAMETER BLOCK. LD BC,3 ;SHOULD BE 3 TIMES. LDIR RET ; ; TRANSFER DMA TO BUFFER ; TRNDMA: LD HL,(BUFADR) TRAN: LD BC,128 LDIR IF 0 LD A,(RTYCNT) CP 10 RET NC XOR A ; ENDIF RET PAGE ; ; DISK READ (PHYSICAL) ; DSKRD: XOR A ;SET READ FLAG LD (ODDFLG),A ; DEFB 3EH ;SKIP 1 BYTE ; ; DISK WRITE (PHYSICAL) ; DSKWR: SCF ;SET WRITE FLAG LD A,(OLDDRV) ;GET SELECTED DRIVE NAME LD (PHDRIV),A LD A,(OLDTRK) LD (PHTRCK),A LD A,(OLDSEC) ;PICK UP OLD SECTOR. LD (PHSECT),A LD HL,IFBUFF ;SET SOURCE/DESTINATION ADDRESS DISKIO: JP NC,PHYRD ;DO READ OPERATION. ; PAGE ; WRITE A SECTOR ; PHYWRT: XOR A LD (RTYCNT),A PHYWR1: PUSH HL ;SAVE SOURCE ADDRESS CALL SELPDR ;SELECT PHYSICAL DRIVE CALL PHSEEK ;SELECT PHYSICAL TRACK LD A,(PHSECT) ;GET SELECTED SECTOR OUT (FD$SEC),A ;WRITE SECTOR REGISTER CALL BSYCHK LD A,WRCMD ;SECTOR WRITE COMMAND DI OUT (FD$CMD),A ;ISSUE WRITE COMMAND POP HL ;LOAD SOURCE ADDRESS PUSH HL ;SAVE IT BACK LD C,FD$DAT DELAY WRLOP: IN A,(INTRQP) ;READ DATA REQUEST PORT ADD A,A JR C,WDONE ;WRITE CONFIRMED JP P,WRLOP ;NO DATA REQUIRED OUTI JR WRLOP ; WDONE: EI POP HL ;RESTORE SOURCE ADDRESS IN A,(FD$STT) AND 11111100B ;ANY ERRORS DETECTED? RET Z ;NO, ALL DONE CALL RETRY ;RECALIBRATE DRIVE AND BUMP RETRY COUNTER JR C,PHYWR1 ;RETRY PUSH HL LD HL,WREMSG CALL FATAL ;FATAL ERROR HAS BEEN DETECTED POP HL JR NC,PHYWRT ;USER ASKED FOR RETRY RET ; WREMSG: DEFB 'WRITE',0 ; PAGE ; READ A SECTOR ; PHYRD: XOR A LD (RTYCNT),A PHYRD1: PUSH HL ;SAVE DESTINATION ADDRESS CALL SELPDR ;SELECT PHYSICAL DRIVE CALL PHSEEK ;SELECT PHYSICAL TRACK LD A,(PHSECT) ;GET SELECTED SECTOR OUT (FD$SEC),A ;WRITE SECTOR REGISTER CALL BSYCHK LD A,RDCMD ;SECTOR READ COMMAND DI OUT (FD$CMD),A ;ISSUE READ COMMAND LD C,FD$DAT POP HL ;LOAD DESTINATION ADDRESS PUSH HL DELAY RDLOP: IN A,(INTRQP) ;READ DATA REQUEST PORT ADD A,A JR C,RDONE ;READ CONFIRMED JP P,RDLOP ;NO DATA VALID INI JR RDLOP ; RDONE: EI POP HL ;RESTORE DESTINATION ADDRESS IN A,(FD$STT) AND 00011100B ;ANY ERRORS DETECTED? RET Z ;NO, ALL DONE CALL RETRY ;RECALIBRATE AND BUMP RETRY COUNTER JR C,PHYRD1 ;TRY AGAIN PUSH HL LD HL,RDEMSG CALL FATAL ;FATAL ERROR HAS BEEN DETECTED POP HL JR NC,PHYRD ;USER ASKED FOR RETRY RET ; RDEMSG: DEFB 'READ',0 ; PAGE ; RECALIBRATE TARGET DRIVE, AND BUMP ERROR COUNTER ; RETRY: LD A,(RTYCNT) ;BUMP ERROR COUNTER INC A LD (RTYCNT),A RRCA RET C ; IF RTYCNT ODD RETURN PUSH AF LD A,RESTRE+STRATE OUT (FD$CMD),A DELAY CALL BSYCHK POP AF CP 5 RET PAGE ; FATAL: PUSH HL LD HL,CRLFMS CALL STROUT POP HL CALL STROUT LD HL,ERRMSG CALL STROUT FATAL1: LD HL,PROMSG CALL STROUT CALL CONIN PUSH AF LD C,A CALL CONOUT LD C,0DH CALL CONOUT LD C,0AH CALL CONOUT POP AF CP 'a' JR C,NOTLOW CP 'z'+1 JR NC,NOTLOW AND 11011111B NOTLOW: CP 'A' JP Z,0 CP 'I' SCF RET Z CP 'R' JR NZ,FATAL1 RET ; CRLFMS: DEFB 0DH,0AH,0AH DEFB 'FATAL ' DEFB 0 ERRMSG: DEFB ' ERROR.' DEFB 0 PROMSG: DEFB 0DH,0AH DEFB 'Abort, Retry, Ignore ?:' DEFB 0 PAGE ; ; SELECT PHYSICAL DRIVE ; SELPDR: CALL DMOTOR LD A,(PHDRIV) ;0 OR 1 LD E,A ;SAVE PHYSICAL DRIVE NUMBER TO [E] INC A ;MAKE IT 1 OR 2 (01 OR 10) OR 00001100B OUT (DSKSEL),A ;SELECT PHDRIV LD A,(CURDRV) ;GET CURRENTLY SELECTED DRIVE NO. CP E ;SAME? RET Z ;YES NO ACTION NEEDS DONE ; ; OTHER DRIVE SELECTED, SO UPDATE TRACK REGISTER ; LD HL,TRKTBL PUSH HL LD C,A ;[BC]=CURRENTLY SELECTED DRIVE LD B,0 ADD HL,BC ;CALCULATE ADDRESS OF TRACK TABLE IN A,(FD$TRK) ;READ CURRENT TRACK POSITION LD (HL),A ;SET IT POP HL ;LOAD TRACK TABLE ADDRESS LD D,B ;[DE]=NEWLY SELECTED DRIVE ADD HL,DE ;CALCULATE ADDRESS OF TRACK TABLE LD A,(HL) ;GET SELECTED DRIVE'S CUREENT TRACK # OUT (FD$TRK),A ;SAY TO FDC LD A,E ;GET SELECTED DRIVE NO. LD (CURDRV),A ;UPDATE CURDRV INC A OR 00001100B OUT (DSKSEL),A RET ; ; CANCEL DOWN-COUNT TIMER FOR MOTOR ; DMOTOR: LD HL,MTIME LD (MTRCNT),HL RET ; PAGE ; SEEK TRACK ; PHSEEK: CALL BSYCHK ;MAKE SURE FDC IS READY FOR COMMAND LD A,(PHTRCK) ;GET PHYSICAL TRACK LD B,A ; [ 20/03/85 a.p ] sub 80 tst$s equ $-1 jr nc,Bseite ; ist >= tracks so ist es d. rueckseite ld a,b and a ld a,DESMFM ; vorderseite MFM jr nz,SELDBL ld a,DESFM ; vorderseite FM jr SELDBL Bseite: ld b,a ; umschalten auf d. rueckseite u. MFM ld a,ruecks ; SELDBL: OUT (DENSEL),A IN A,(FD$TRK) ;GET TRACK # HELD IN FDC'S REGISTER CP B ;COMPARE THEM RET Z ;LOOKS SAME, NO ACTION NECESSARY LD A,B ;DIFFERENT, SEEK OPERATION MUST BE DONE OUT (FD$DAT),A LD A,SEEK+STRATE OUT (FD$CMD),A ;ISSUE SEEK COMMAND CALL BSYCHK ;WAIT TILL FDC FINISHES SEEK AND 10011000B ;ANY ERRORS? RET Z ;NO CALL RETRY ;RECALIBRATE DRIVE AND BUMP RETRY COUNTER JR C,PHSEEK ;TRY AGAIN RET ; ; WAIT UNTIL FDC IS READY FOR NEW COMMAND ; BSYCHK: IN A,(FD$STT) ;GET FDC STATUS RRA ;LOOK BUSY BIT [LSB] JR C,BSYCHK ;WAIT RLA ;REMAKE STATUS BYTE RET ; PAGE ; **************************************** ; *** BOOT PROGRAM & SET UP PARAMETERS *** ; **************************************** ; ; ((( COLD BOOT ROUTINE ))) ; THE COLD BOOT ROUTINES ARE COLLECTED TO A SINGLE AREA ; SINCE THE SPACE MIGHT BE USED LATER ON. BO DATA 840131 ; CBOOT: DI LD SP,128 ;SET TEMPORARY STACK POINTER XOR A LD (LOGDIS),A ;LOG TO DRIVE A LD (CURDRV),A ;DRIVE A IS ALWAYS SELECTED AT THIS POINT IN A,(FD$TRK) LD (TRKTBL),A ;SET TRACK TABLE FOR DRIVE A LD A,(UPARMS+10) ;GET DEFAULT IOBYTE LD (IOBYT),A LD A,0C3H LD HL,INTRPT ;SET INTERRUPT VECTOR LD (38H),A LD (39H),HL LD A,15 OUT (PSG$LW),A IN A,(PSG$DR) OR 00000010B ;ENABLE BASIC ROM OUT (PSG$DW),A LD HL,(HOKENT) AND 11111101B ;ENABLE BK21 OUT (PSG$DW),A LD DE,75*3 ADD HL,DE LD (HL),0C3H ;SET UP A HOOK INC HL LD DE,CHKMOT LD (HL),E INC HL LD (HL),D ; ; MODIFY SCREEN PARAMETERS ; XOR A ;DISABLE FUNCTION KEY DISPLAY LD (CNSDFG),A LD A,(UPARMS+4) ;GET LINE LENGTH OR A JP Z,LEN40 LD A,39 ;SET SCREEN SIZE TO 39 JP LENMOR ; LEN40: LD A,40 ;SET SCREEN SIZE TO 40 LENMOR: LD (LINLEN),A ; PAGE LD HL,UPARMS+1 ;COPY SCREEN COLOR INFORMATION LD DE,0FA0AH ;TO BASIC ROM RAM WORK AREA LD B,3 ;3 BYTES COLORS: LD A,(HL) LD (DE),A INC HL INC DE DEC B JP NZ,COLORS ;IF MORE TO GO LD HL,FUNDEF ;NEXT, COPY FUNCTION KEY DEFINITIONS LD DE,0FA1EH ;TO BASIC LD B,16*10 ; FKEYS: LD A,(HL) LD (DE),A INC HL INC DE DEC B JP NZ,FKEYS ;IF MORE TO GO LD A,(UPARMS+5) ;SET FKEY DISPLAY MODE LD (0FA06H),A LD HL,INITXT CALL CALROM ;INITIALIZE VDP FOR TEXT MODE CALL NIT80 ;INIT 80-COLUMN BOARD CALL NIT232 ;INIT RS-232 CARD LD HL,HEDING CALL STROUT JP WBOOT ; HEDING: DEFB 0CH,1AH defb 'Spectravideo CP/M-80 Revision 2.2x 1985' ; a.p 3/85 DEFB 0DH,0AH DEFB ' (C) by Digital Research ' ; a.p 3/85 DEFB 0DH,0AH DEFB 0 PAGE ; ; 80-COLUMN INIT CODE (UPDATED VERSION) ; NIT80: DI LD A,15 ;SET TO WRITE TO CURSOR ADDRESS LOW BYTE OUT (50H),A XOR A ;SET TO 0 OUT (51H),A ;AND SEND IT LD B,A ;COPY TO [B] IN A,(51H) ;GET IT BACK CP B ;SAME? JP NZ,NOT80C ;IF NOT, IT'S NOT THERE INC A JP NZ,PRESNT ;IF WASN'T FF, ALL IS FINE NOT80C: LD HL,CRTOUT LD (FUDGE),HL ;THIS WILL KEEP HIM FROM RE-ASSIGNING LD A,(IOBYT) ;RE-ASSIGN CONSOLE TO CRT: AND 0FCH ;LEAVE ALL BUT CON: OR 1 ;FORCE CON: TO 40-COLUMN CARD (CRT:) LD (IOBYT),A RET ; PRESNT: LD A,0FFH OUT (58H),A LD HL,0F000H LD BC,7FFH LOOP1: LD A,0 LD (HL),A INC HL DEC BC LD A,B OR C JP NZ,LOOP1 ; LD C,0 LD HL,CRTBL NEXT: LD A,C CP 10H JP Z,EINT OUT (50H),A LD A,(HL) OUT (51H),A INC HL INC C JP NEXT ; EINT: XOR A OUT (58H),A EI RET PAGE ; ; TABELL [NDRAD F\R 50 HZ a.p 3/85 ; CRTBL: DEFB 108 ;107 ;109 DEFB 80 DEFB 90 ;88 ;89 DEFB 8 ;12 DEFB 30 ;38 ;31 DEFB 4 ;5 ;2 DEFB 24 DEFB 26 ;30 ;26 DEFB 0 DEFB 9 ;7 DEFB 60H DEFB 8 ;7 DEFB 0 DEFB 0 DEFB 0 DEFB 0 PAGE ; ; RS-232 INIT CODE (TEST VERSION) ; TTDATA EQU 28H ;DATA PORT OF WD8250 TTIER EQU TTDATA+1 ;INTERRUPT ENABLE REGISTER TTIDENT EQU TTDATA+2 ;INTERRUPT IDENT REGISTER TTLCR EQU TTDATA+3 ;LINE CONTROL REGISTER TTMCR EQU TTDATA+4 ;MODEM CONTROL REGISTER TTSTAT EQU TTDATA+5 ;LINE STATUS REGISTER TTMODST EQU TTDATA+6 ;MODEM STATUS REGISTER DLL EQU TTDATA ;DIVISOR LATCH LOW DLH EQU TTDATA+1 ;DIVISOR LATCH HIGH ; NIT232: XOR A ;BURP 8250 OUT (TTSTAT),A LD A,0FH ;ACTIVATE ALL MODEM CONTROL LINES OUT (TTMCR),A XOR A ;DISABLE ALL INTERRUPTS OUT (TTIER),A LD A,83H ;ENABLE DIVISOR LATCH OUT (TTLCR),A LD HL,(UPARMS+7) ;GET BAUD RATE LD A,L ;SEND LOW FIRST OUT (DLL),A LD A,H ;AND THEN HIGH OUT (DLH),A LD A,3 ;SELECT 8 DATA BITS, 1 STOP BIT, NO PARITY OUT (TTLCR),A XOR A ;BURP IT AGAIN OUT (TTSTAT),A RET ;ALL DONE INICODE EQU $-CBOOT ; VAD FINNS ATT VINNA??? ; PAGE ; ((( WARM BOOT ROUTINE ))) ; ; WBOOT: ; NOTE: YOU MUST NEVER WRITE TO DISKETTE AT WARM BOOT ; SINCE THIS WILL DESTROY THE DISKETTE AFTER DISK ; CHANGE. IF YOU HAVE CLOSED ALL FILES BEFORE ; WARM BOOT THE HOST BUFFER WILL BE EMPTY. ; I.E. FOLLOWING "CALL OLDWR" REMOVED BY BO DATA 840130 ; CALL OLDWR ;WRITE A SECTOR, IF IT REMAINS. ; ; SET UP JUMP VECTOR FOR SYSTEM ; SETUP: LD A,0C3H ;SET JMP INSTRUCTION. LD HL,WBOOTE ;SET WARM BOOT ENTRY ADRS. LD (0),A ;PUT IT INTO 0000H. LD (1),HL ;PUT THEM INTO 0001H LD HL,DOSB ;SET UP BDOS FUNCTION CALL. LD (5),A ;SET IT INTO 0005H. LD (6),HL ;SET OPERAND, ALSO. LD SP,128 ;SET TEMPORARY STACK POINTER ; ; READ CCP AND BDOS ; CALL BLKRD ;READ CCP & BDOS DEFW CPMB ;THE START ADRS. DEFB 13 ;SET SECTOR 13 DEFB 1 ;SET TRACK 1 DEFB 0 ;SET DRIVE A: DEFB 22 ;(BIOSB-CPMB)/256 LD BC,128 ;SET DEFAULT DMA ADRS. CALL SETDMA XOR A ;TO WIPE OUT THEM. LD (IFACT),A ;RESET BUFF ACTIVE FLAG LD (DFL),A LD A,(LOGDIS) ;GET LOG DISK. LD C,A ;TELL CCP DRIVE=(C) JP CPMB ;GET INTO CP/M MAIN. ; PAGE ; ((( BLOCK READ/WRITE UTILITY ))) ; ; CALLING SEQUENCE ; ; CALL BLKRD / BLKWRT ; DW START ADDRESS ; DB SECTOR ; DB TRACK ; DB DRIVE ; DB # OF SECTORS TO BE READ / WRITTEN ; BLKRD: DEFB 11100110B ;CLEAR CARRY FOR READ BLKWRT: SCF ;SET CARRY FOR WRITE EX (SP),HL LD E,(HL) INC HL LD D,(HL) LD (PHADDR),DE INC HL LD DE,PHSECT LD BC,3 LDIR LD B,(HL) ;GRAB COUNTER. INC HL ;MAKE FINAL ADRS. EX (SP),HL ;SAVE BUMPED ADRS. RELOOP: PUSH BC ;SAVE SECTOR COUNT PUSH AF ;SAVE READ/WRITE FLAG LD HL,(PHADDR) ;GET TARGET ADDRESS CALL DISKIO ;DO DISK READ/WRITE CALL UPDATE ;UPDATE PARAMETERS POP AF ;RESTORE READ/WRITE FLAG POP BC ;RESTORE SECTOR COUNT DJNZ RELOOP RET PAGE ; UPDATE: LD A,(PHTRCK) AND A ;TRACK 0? LD DE,256 ;ASSUME NOT LD C,17+1 JR NZ,UPDDBL ;GOOD ASSUMPTION LD DE,128 INC C UPDDBL: LD HL,(PHADDR) ADD HL,DE LD (PHADDR),HL LD HL,PHSECT INC (HL) LD A,(HL) CP C ;WRAPPED TO NEXT SECTOR? RET C ;NO LD (HL),1 ;SET SECTOR 1 INC HL ;POINT TO PHTRCK INC (HL) ;BUMP TRACK # ALSO RET ; STROUT: LD A,(HL) ;GET STRING OR A ;END OF STRING? RET Z ;YES LD C,A ;CHARACTER SHOULD BE PASSED VIA [C] PUSH HL CALL CONOUT POP HL INC HL JR STROUT PAGE ; ; ************************** ; *** WORK AREA FOR BIOS *** ; ************************** ; MTRCNT: DEFW 0 ;DOWNCOUNT TIMER FOR MOTOR ; DIRFLG: DEFB 0 ODDFLG: DEFB 0 SECFLG: DEFB 0 ;TO CHECK ODD OR EVEN. ; ; LOGICAL DISK PARAMTERS ; NEWPRM: LOGDRV: DEFB 0 ;LOGICAL DRIVE NUMBER. LOGTRK: DEFB 0 ;LOGICAL TRACK NUMBER. LOGSEC: DEFB 1 ;LOGICAL SECTOR NUMBER. ; ; OLD DISK PARAMETERS ; OLDPRM: OLDDRV: DEFB 0 ;OLD DRIVE NUMBER. OLDTRK: DEFB 0 ;OLD TRACK NUMBER. OLDSEC: DEFB 1 ;OLD SECTOR NUMBER. ; ; CURDRV: DEFB 0 ;CURRENT SELECTED DRIVE# TRKTBL: DEFS 2 ;TRACK # OF EACH DRIVE ; PAGE CSV0: DEFS 35 ALV0: DEFS 45 ; a.p 3/85 CSV1: DEFS 35 ALV1: DEFS 45 ; a.p 3/85 DIRBUF: DEFS 128 ; ; **************************** ; *** BLOCKING BUFFER AREA *** ; **************************** ; ; (((( BLOCKING BUFFER DIAGRAM )))) ; ; PHYSICAL SECTOR: TEMPORARY BUFF: ; (256 BYTES):IFBUFF (128 BYTES):BUF2 ; ]----------------[ ]--------------[ ; ] LOGICAL SECTOR [ ] TEMPO. BUFF. [ ; ] (ODD SECTOR) [ ] AT PRE-READ [ ; ]----------------[ ]--------------[ ; ] LOGICAL SECTOR [ ; ] (EVEN SECTOR) [ ; ]----------------[ ; ; )))((( THIS PART WILL BE USED AS BLOCKING BUFFER )))((( ; ; IFBUFF: DEFS 256 BUF2: DEFS 128 SCA EQU IFBUFF SCB EQU IFBUFF+128 ; ; FOLLOWING 4 VARIABLES ARE PARAMETERS PASSED TO PHYSICAL DISK ; DRIVER. THE ORDER MUST BE EXACTLY AS SHOWN. ; PHADDR: DEFS 2 ;DESIRED DMA ADDRESS PHSECT: DEFS 1 ;DESIRED SECTOR # PHTRCK: DEFS 1 ;DESIRED TRACK # PHDRIV: DEFS 1 ;DESIRED DRIVE # ; RTYCNT: DEFS 1 ;RETRY COUNTER DFL: DEFS 1 ;BUFFER-REMAIN FLAG IFACT: DEFS 1 ;BUFFER ACTIVATE FLAG. BUFADR: DEFS 2 ;DMA ADRS FOR LOGICAL TRANSFER. DEFS 2*50 ;STACK AREA WHEN CALLING ROM ROUTINES BIOSTK: DEFS 2*50 ;STACK AREA WHEN INTERRUPT OCCURED INTSTK: ; BO DATA 1984-02-28 ; ; IFT $ > 0F543H ;BIOS TO LARGE TO FIT IN SPECTRA VIDEO MEMORY ; ENDIF ; .dephase END