; TEST VEHICLE FOR READTRACK, WRITETRACK ROUTINES ; *** EQU TABLES *** 000D = CARET EQU 0DH ; CARRIAGE RETURN 000A = LFEED EQU 0AH ; LINE FEED 001A = CTRLZ EQU 1AH ; OPERATOR INTERRUPT 0001 = RCONF EQU 01H ; DUMP INPUT FROM CONSOLE 0002 = WCONF EQU 02H ; WRITE A CONTENTS TO CONSOLE 000B = CSTAF EQU 0BH ; CHECK CON: STATUS 0004 = DRIVE EQU 04H ; CURRENT DRIVE NUMBER 000A = RBUFF EQU 0AH ; READ A CONSOLE LINE 0080 = TBUFF EQU 80H ; BASE PAGE DEFAULT BUFFER 0005 = BDOS EQU 05H ; BDOS ENTRY POINT 0100 ORG 100H ; TPA START ADDRESS 0100 210000 BEGIN: LXI H,0 ; CLEAR HL BEFORE LOADING 0103 39 DAD SP ; OLD STACK POINTER 0104 22DA01 SHLD CPMSP ; AND SAVE IT. 0107 310002 LXI SP, STAK ; SET NEW STACK 010A 3A0400 LDA DRIVE ; GET CURRENT DRIVE 010D 32D901 STA DRSAV ; AND SAVE IT 0110 0E0B MVI C,CSTAF ; GET CONSOLE STATUS 0112 CD0500 CALL BDOS 0115 B7 ORA A 0116 CA1B01 JZ BEGIN1 ; NO INPUT, GET SOME. 0119 0E01 MVI C,RCONF ; IGNORE ANY IF PRESENT. 011B CD4E01 BEGIN1: CALL CCRLF 011E CD3F01 CALL SPMSG 0121 2050757420 DB ' Put your message here ',0 0139 CD4E01 CALL CCRLF 013C C30002 JMP START ; GO TO MAIN PROGRAM ENTRY POINT. ; DISPLAY MESSAGE TO CONSOLE 013F E3 SPMSG: XTHL ; LOAD PHONY RET TO HL REGS 0140 AF XRA A ; CLEAR FLAGS ETC. 0141 86 ADD M ; MOVE ONE MESSAGE CHARACTER 0142 23 INX H ; AND POINT TO NEXT. 0143 E3 XTHL ; RESTORE STACK TO RETURN IF DONE. 0144 C8 RZ ; DONE IF 00 IN A. 0145 CD5501 CALL CONOUT ; IF NOT DONE, DISPLAY IT 0148 C33F01 JMP SPMSG ; AND CONTINUE. ; DO A CR/LF TO CONSOLE 014B CD4E01 TWOCR: CALL CCRLF 014E 3E0D CCRLF: MVI A,CARET 0150 CD5501 CALL CONOUT 0153 3E0A MVI A,LFEED 0155 = CO: EQU $ ; ALLOW TWO NAMES 0155 C5 CONOUT: PUSH B ; DISPLAY ONE CHARACTER 0156 D5 PUSH D ; PUSH ALL REGS 0157 E5 PUSH H 0158 0E02 MVI C,WCONF ; SELECT THE WRITE FUNCTION 015A 5F MOV E,A ; AND PUT IN CORRECT REG 015B CD0500 CALL BDOS ; DO THE FUNCTION 015E E1 POP H 015F D1 POP D ; POP ALL BACK. 0160 C1 POP B 0161 C9 RET ; SHOW SPACES 0162 C5 SPACES: PUSH B ; ENTER WITH COUNT IN C 0163 4F MOV C,A ; SAVE TEMP REG FOR COUNT 0164 B7 ORA A ; TEST FOR NONE 0165 CA7101 JZ SPACE2 ; AND QUIT IF SO. 0168 3E20 SPACE1: MVI A, ' ' ; LOAD A SPACE 016A CD5501 CALL CONOUT 016D 0D DCR C 016E C26801 JNZ SPACE1 ; TEST COUNTDOWN 0171 C1 SPACE2: POP B ; CLEAR STACK 0172 C9 RET ; CONSOLE OPERATOR INTERRUPT 0173 0E0B OPINT: MVI C,CSTAF ; CHECK FOR OPERATOR KILL 0175 CD0500 CALL BDOS 0178 B7 ORA A ; TEST IF KEYPRESS 0179 C8 RZ ; RETURN IF NONE. 017A 0E01 MVI C,RCONF ; WAS, CHECK IT. 017C CD0500 CALL BDOS 017F FE1A CPI CTRLZ 0181 C0 RNZ 0182 3AD901 DONE: LDA DRSAV ; ALL DONE, CHECK OUT. 0185 320400 STA DRIVE ; RESTORE CURRENT DRIVE 0188 2ADA01 LHLD CPMSP ; GET OLD STACK POINTER 018B F9 SPHL ; LOAD IT, AND GO 018C C9 RET ; INPUT CONSOLE MESSAGE INTO BUFFER- 018D C5 CIMSG: PUSH B 018E D5 PUSH D ; PUSH ALL REGS 018F E5 PUSH H 0190 21DD01 LXI H,INBUFF+1 ; POINT TO MESSAGE START 0193 3600 MVI M,0 ; AND ZERO COUNTER 0195 2B DCX H ; BACK TO LENGTH CELL 0196 3650 MVI M,80 ; AND SET MAX LINE 0198 EB XCHG ; INPUT POINTER TO DE- 0199 0E0A MVI C,RBUFF ; SET READ BUFFER FUNCTION 019B CD0500 CALL BDOS ; AND DO IT. 019E 21DD01 LXI H,INBUFF+1 ; POINT TO COUNTER 01A1 5E MOV E,M ; AND SAVE IT 01A2 1600 MVI D,0 ; CLEAR UPPER BYTE 01A4 19 DAD D ; AND ADD LENGTH TO START 01A5 23 INX H ; ADD ONE MORE FOR END 01A6 3600 MVI M,0 ; AND SET 00 TO END IT. 01A8 E1 POP H 01A9 D1 POP D ; RESTORE THEM ALL 01AA C1 POP B 01AB C9 RET ; (Y)ES OR (N)O FROM CONSOLE 01AC CD3F01 GETYN: CALL SPMSG ; PROMPT FOR INPUT 01AF 2028592F4E DB ' (Y/N)?: ',0 ; THIS IS THE PROMPT. 01B9 CD8D01 CALL CIMSG ; READ AN INPUT LINE 01BC CD4E01 CALL CCRLF ; AND DO A CR/LF 01BF 3ADE01 LDA INBUFF+2 ; USE FIRST CHARACTER ONLY. 01C2 E65F ANI 5FH ; MAKE UPPER CASE ONLY 01C4 FE59 CPI 'Y' 01C6 C8 RZ 01C7 FE4E CPI 'N' 01C9 C2AC01 JNZ GETYN 01CC FE00 CPI 0 01CE C9 RET ; MESSAGE OUT TO CONSOLE 01CF 7E COMSG: MOV A,M 01D0 B7 ORA A ; TEST FOR 00 01D1 C8 RZ 01D2 CD5501 CALL CONOUT 01D5 23 INX H 01D6 C3CF01 JMP COMSG ; LOCAL STORAGE AREA 01D9 00 DRSAV DB 0 ; CURRENT DRIVE STORAGE 01DA 0000 CPMSP DW 0 ; OLD STACK POINTER 01DC INBUFF DS 83 ; LINE INPUT BUFFER 0200 ORG 200H 0200 = STAK: EQU $ START: 0200 0E01 MVI C,01 0202 CD4F03 CALL SETDRV 0205 CD3F01 CALL SPMSG 0208 20496E7075 DB ' Input track number: ',0 021E CD8D01 CALL CIMSG 0221 CD3902 CALL SETTRK 0224 CD8302 CALL REDTRK REPT 18 DB 00 ENDM 0227+00 DB 00 0228+00 DB 00 0229+00 DB 00 022A+00 DB 00 022B+00 DB 00 022C+00 DB 00 022D+00 DB 00 022E+00 DB 00 022F+00 DB 00 0230+00 DB 00 0231+00 DB 00 0232+00 DB 00 0233+00 DB 00 0234+00 DB 00 0235+00 DB 00 0236+00 DB 00 0237+00 DB 00 0238+00 DB 00 E3FD = TRKREG EQU 0E3FDH ; MORROW DJ2B TRACK REGISTER SETTRK: 0239 2ADE01 LHLD INBUFF+2 ; GET TRACK NUMBER FROM BUFFER 023C CDD102 CALL ASCBIN ; CONVERT TO BINARY FROM ASCII 023F FE4D CPI 77 ; TEST FOR LEGAL RANGE. 0240 = MAXTRK EQU $-1 ; SET IN PROPER MAX TRACK #+1 0241 D25B02 JNC TRKERR 0244 FE00 CPI 00H 0246 DA5B02 JC TRKERR ; NEGATIVES NOT ALLOWED 0249 328102 STA CURTRK ; MAKE IT CURRENT TRACK 024C CDBC02 CALL NOTBSY ; MAKE SURE 1791 IS IDLE 024F 3A8102 LDA CURTRK 0252 32FDE3 STA TRKREG ; AND LOAD TRACK REGISTER 0255 C630 ADI 30H ; MAKE IT ASCII FOR POSSIBLE 0257 328202 STA ASCTRK ; USE ELSEWHERE. 025A C9 RET TRKERR: 025B CD4E01 CALL CCRLF 025E CD3F01 CALL SPMSG 0261 2054726163 DB ' Track number not acceptable.',0 027F AF XRA A ; SET Z FLAG 0280 C9 RET 0281 01 CURTRK DB 1 ; CMDREG IS PART OF SELCTDRV.LIB 0282 01 ASCTRK DB 1 E3FF = DATREG EQU 0E3FFH ; MORROW DJ2B 1791 DATA PORT E3FC = CMDREG EQU 0E3FCH ; MORROW DJ2B 1791 COMMAND PORT 00E4 = RTKCMD EQU 000E4H ; 1791 READ TRACK COMMAND REDTRK: 0283 CDBC02 CALL NOTBSY ; WAIT UNTIL 1791 IS IDLE 0286 11FFE3 LXI D,DATREG ; LOOK AT 1791 DATA REGISTER 0289 216203 LXI H,TRKBUF ; AND SET UP BUFFER AREA 028C 0E18 MVI C,24 ; LOAD NUMBER OF PAGES 028D = MAXPAG EQU $-1 ; TO BE READ FROM TRACK. 028E 3EE4 MVI A,RTKCMD ; LOAD AND ISSUE TRACK READ 0290 32FCE3 STA CMDREG ; COMMAND FOR THE 1791 DATAIN: 0293 1A LDAX D ; LOAD DATA BYTE 0294 77 MOV M,A ; AND STORE IN BUFFER. 0295 2C INR L 0296 C29302 JNZ DATAIN ; LOOP UNTIL ALL WRITTEN. 0299 24 INR H 029A 0D DCR C 029B C29302 JNZ DATAIN 029E C9 RET 00F4 = WRTCMD EQU 000F4H ; WRITE TRACK COMMAND WRTTRK: 029F CDBC02 CALL NOTBSY ; WAIT UNTIL 1791 IDLE 02A2 11FFE3 LXI D,DATREG ; POINT TO 1791 DATA PORT 02A5 216203 LXI H,TRKBUF ; AND TO SOURCE CODE. 02A8 0E18 MVI C,24 ; SET NUMBER OF PAGES TO BE 02A9 = WRTPAG EQU $-1 ; WRITTEN TO DISK 02AA 3EF4 MVI A,WRTCMD ; GET AND ISSUE A WRITE 02AC 32FCE3 STA CMDREG ; TRACK COMMAND. 02AF EB XCHG ; SWAP THE POINTERS- WRTLUP: 02B0 1A LDAX D ; GET A DATA BYTE AND DUMP 02B1 77 MOV M,A ; IT INTO THE 1791. THEN 02B2 1C INR E ; UPDATE THE BYTE POINTER TO 02B3 C2B002 JNZ WRTLUP ; THE NEXT CELL AND CONTINUE 02B6 14 INR D ; UNTIL THE ENTIRE BUFFER HAS 02B7 0D DCR C ; BEEN WRITTEN TO DISK : ONE 02B8 C2B002 JNZ WRTLUP ; ENTIRE TRACK'S WORTH. 02BB C9 RET NOTBSY: 02BC 0E0A MVI C,10 ; PRESET COUNTER WAIT1: 02BE 21FCE3 LXI H,CMDREG ; POINT TO COMMAND PORT OF 02C1 7E MOV A,M ; 1791 AND GET A STATUS BYTE. 02C2 1F RAR ; TEST BUSY FLAG - IF NOT UP, 02C3 D2CC02 JNC TIMEOT ; WAIT FOR IT TO COME UP FOR ; SHORT PERIOD. WAIT2: 02C6 7E MOV A,M ; GET STATUS BYTE AND TEST FOR 02C7 1F RAR ; BUSY FLAG UP. LOOP UNTIL IT 02C8 DAC602 JC WAIT2 ; COMES DOWN AGAIN. 02CB C9 RET ; 1791 IDLE, GO HOME. 02CC 0D TIMEOT: DCR C ; DON'T LOOK FOR FLAG TO COME UP 02CD C2BE02 JNZ WAIT1 ; FOREVER. IF NO BUSY FLAG BY 02D0 C9 RET ; TEN TRIES, IS NOT COMING UP. ASCBIN: 02D1 7C MOV A,H ; LOAD THE SECOND BYTE 02D2 B7 ORA A ; AND TEST FOR ENTRY. 02D3 CAE802 JZ ONLY1 ; EXIT IF NO SECOND NUMBER. 02D6 7D MOV A,L ; GET FIRST ENTRY 02D7 D630 SUI 30H ; CONVERT FROM ASCII AND 02D9 171717 RAL!RAL!RAL ; MULTIPLY X8 AND THEN ADD 02DC 85 ADD L ; TO GET X10. 02DD D630 SUI 30H ; CONVERT TO BINARY 02DF 85 ADD L 02E0 D630 SUI 30H 02E2 4F MOV C,A ; STORE INTERMEDIATE VALUE 02E3 7C MOV A,H ; GET SECOND VALUE 02E4 D630 SUI 30H ; MAKE BINARY 02E6 81 ADD C ; COMBINE FOR FINAL VALUE 02E7 C9 RET ; RETURN WITH BINARY IN A ONLY1: 02E8 7D MOV A,L ; GET FIRST BYTE 02E9 D630 SUI 30H ; MAKE BINARY 02EB C9 RET ; AND RETURN. SORCDISK: 02EC CD3F01 CALL SPMSG ; ASK FOR SOURCE DRIVE NUMBER 02EF 20496E7075 DB ' Input source drive (a,b,c,d): ',0 0310 CD8D01 CALL CIMSG ; GET THE INPUT 0313 E65F ANI 5FH ; THEN FORCE UPPER CASE. 0315 D641 SUI 41H ; CONVERT TO BINARY 0317 CA4303 JZ SSAVE ; WAS A DRIVE, IS OK. 031A FE00 CPI 00 ; GREATER THAN A? 031C D23B03 JNC UPPER ; YES, MAYBE OK. ERRDRV: 031F CD3F01 CALL SPMSG ; PRINT ERROR MESSAGE 0322 204E6F7420 DB ' Not legal drive: ',0 0335 CD4E01 CALL CCRLF 0338 C3EC02 JMP SORCDISK UPPER: 033B FE04 CPI 4 ; LESS THAN E? 033D DA4303 JC SSAVE ; YES, IS LEGAL 0340 C31F03 JMP ERRDRV ; NO, TRY AGAIN SSAVE: 0343 324D03 STA SRCDRV ; SAVE THE REQUESTED DRIVE 0346 4F MOV C,A ; READY FOR SETDRIVE 0347 C641 ADI 41H ; CONVERT BACK TO ASCII 0349 324E03 STA ASCDRV ; AND SAVE IF LETTER NEEDED. 034C C9 RET 034D 01 SRCDRV DB 1 ; BINARY VALUE OF SOURCE DRIVE 034E 01 ASCDRV DB 1 ; ASCII VALUE OF SOURCE DRIVE D31B = DJDRIV EQU 0D31BH ; MORROW DJ2B BIOS SETDRIVE ENTRY E3FA = DJFUNC EQU 0E3FAH ; MORROW DJ2B DRIVE FUNCTION PORT SETDRV: 034F 79 MOV A,C ; SAVE DESIRED DISK (IN C ON ENTRY) 0350 D641 SUI 41H ; MAKE BINARY IF NOT ALREADY 0352 326003 STA CURDSK ; AND SAVE IT FOR POSSIBLE USE 0355 F5 PUSH PSW 0356 CD1BD3 CALL DJDRIV ; BRING UP THE DRIVE 0359 F1 POP PSW 035A F641 ORI 41H ; CONVERT TO ASCII VALUE 035C 326103 STA ASCDSK ; AND SAVE FOR POSSIBLE USE 035F C9 RET 0360 01 CURDSK DB 1 0361 01 ASCDSK DB 1 0362 TRKBUF DS 17FFH ; ROOM NEEDED TO READ 8" TRACK. 1B61 END STA SRCDRV ; SAVE THE REQUESTED DRIVE