[Copyright 1999,2002 Frank Durda IV, All Rights Reserved. Mirroring of any material on this page in any form is expressly prohibited. The official web site for this material is: http://nemesis.lonestar.org Contact this address for use clearances: clearance at nemesis.lonestar.org Comments and queries to this address: web_software_2011 at nemesis.lonestar.org]
MISOSYS EDAS-4.3 04/11/99 22:06:16 TAPE100 - LS-DOS 6.2 Page 00001
00001 ;TAPE100 - Tape/Disk & Disk/Tape Xfer Utility
00003 ;
F440 00004 BREAKLC EQU 0F440H ; key location
003A 00005 LOADA EQU 3AH ; LD A,(nnnn) opcode
0016 00006 WRMASK EQU 'W'-'A' ;WRINTMASK port mask byte
000C 00007 MODMASK EQU 'M'-'A' ;MODOUT port mask byte
00008 ;
003A 00009 @INIT EQU 58 ;@INIT SVC #
003B 00010 @OPEN EQU 59 ;@OPEN SVC #
00011 ;
00E0 00012 PORTE0 EQU 0E0H
00EC 00013 MODOUT EQU 0ECH
00FF 00014 PORTFF EQU 0FFH
0078 00015 OPREG$ EQU 78H ;Operating Register
0084 00016 @OPREG EQU 84H ;Video/Keyboard Control Port
F800 00017 VIDEO EQU 0F800H ;Start of Video RAM
00018 ;
0022 00019 WHICH1 EQU 22H ;Which one - 0 or 1 ?
000F 00020 TOOSHRT EQU 0FH ;Pulse too Short ?
003E 00021 TOOLONG EQU 3EH ;Pulse too Long ?
0006 00022 ROUTOFF EQU 6 ;Interrupt rout offset
000D 00023 DIFFER EQU 0DH ;Difference between 2 pulses
2B2F 00024 DELAY0 EQU 2B2FH ;Bit = 0 Delay count
1217 00025 DELAY1 EQU 1217H ;Bit = 1 Delay count
00026 ;
000E 00027 CURON EQU 14 ;Cursor on
000F 00028 CUROFF EQU 15 ;Cursor off
00029 ;
0000 00030 *GET SVCMAC:3 ;SVC Macro equivalents
00031 ;SVCMAC/ASM - LS-DOS Version VI
00032 *LIST OFF
00424 *LIST ON
0000 00426 *GET VALUES:3 ;Misc. equates
00427 ;VALUES/ASM - Version 6
00428 *LIST OFF
00455 *LIST ON
0000 00456 *GET COPYCOM:3 ;Copyright message
00457 ; COPYCOM - File for Copyright COMment block
00458 ;
0000 00459 *GET BUILDVER/ASM:3
00460 ;
00461 ; Buildver/asm is a bit of a kludge since not all utilities can load
00462 ; equates from LDOS60 and still compile. LOWCORE and everybody else
00463 ; relies on this setting, and it eventually ends up in LDOS60/EQU
00464 ; for programs that can use that.
00465 ;
FFFF 00466 @BLD631 EQU -1 ;<631>Build 631 distribution (LEVEL 1B)
00467 ; These switches activate patches made since the 1B release.
00468 ; It is important that all earlier patches be enabled when a higher
00469 ; patch is enabled.
00470 ; Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the
00471 ; patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.)
FFFF 00472 @BLD631C EQU -1 ;<631>Apply 1C patches (SETKI)
FFFF 00473 @BLD631D EQU -1 ;<631>Apply 1D patches (DIR)
FFFF 00474 @BLD631E EQU -1 ;<631>Apply 1E patches (DIR & MEMDISK/DCT)
FFFF 00475 @BLD631F EQU -1 ;<631>Apply 1F patches (SPOOL)
00476 ; Patches G and H were published in TMQ V.i, pages 10 and 18/19.
FFFF 00477 @BLD631G EQU -1 ;<631>Apply 1G patches (//KEYIN,DIR,DO *)
FFFF 00478 @BLD631H EQU -1 ;<631>Apply 1H patches (MEMORY)
00479 ;
00480 ;End of BUILDVER/ASM
00481 IF @BLD631
00483 ELSE
00484 COM '<*(C) 1982,3,4,6 by LSI*>'
00485 ENDIF
00486 ;
2600 00487 ORG 2600H
00488 ;
00489 START
2600 00490 @@CKBRKC ;Check for break
2600+3E6A 00491 LD A,106
2602+EF 00492 RST 40
2603 2804 00493 JR Z,STARTA ;Continue if not
2605 21FFFF 00494 LD HL,-1 ; else abort
2608 C9 00495 RET
00496 ;
2609 ED735C27 00497 STARTA LD (OLDSP+1),SP ;Save entry stack
260D CDC727 00498 CALL DOINIT ;Do initialization
00499 ;
00500 ; Was READ or WRITE entered ?
00501 ;
2610 3AD729 00502 LD A,(RRESP) ;P/u read response
2613 47 00503 LD B,A ;Xfer to B
2614 3ACF29 00504 LD A,(WRESP) ;P/u write response
2617 A8 00505 XOR B ;Are both the same ?
2618 2807 00506 JR Z,INP_R_W ;Yes - prompt
00507 ;
00508 ; Both weren't entered - which one was
00509 ;
261A 04 00510 CHKPRM INC B ;READ entered ?
261B 05 00511 DEC B
261C 281C 00512 JR Z,WRTAPE ;rite a tapefile
261E C3B126 00513 JP RDTAPE ;ead a tapefile
00514 ;
00515 ; Prompt for READ or WRITE
00516 ;
2621 E5 00517 INP_R_W PUSH HL ;Save command ptr
00518 ;
2622 21DB28 00519 LD HL,RDORWR ;"Read or Write"
2625 CD4928 00520 CALL DSPLY
00521 ;
00522 ; Input R (Read) or W (Write)
00523 ;
2628 0601 00524 LD B,1 ;Take input, 1 char
262A CD3528 00525 CALL INPUT
262D 7E 00526 LD A,(HL) ;P/u first char
262E E1 00527 POP HL ;Recover command ptr
262F CBAF 00528 RES 5,A ;Convert to U/C
2631 FE52 00529 CP 'R' ;ead ?
2633 CAB126 00530 JP Z,RDTAPE
2636 FE57 00531 CP 'W' ;rite ?
2638 20E7 00532 JR NZ,INP_R_W ;No - re-prompt
00533 ;
00534 ; WRITE diskfile to tapefile
00535 ;
263A 11F12D 00536 WRTAPE LD DE,FCB1 ;DE => Source FCB
263D 00537 @@FSPEC ;If a bad spec,
263D+3E4E 00538 LD A,78
263F+EF 00539 RST 40
2640 C40828 00540 CALL NZ,PRSOUR ; prompt for source
00541 ;
00542 ; WRITE - check if destination filespec input
00543 ;
2643 11112E 00544 WRTAPE2 LD DE,FCB2 ;DE => Destination FCB
2646 00545 @@FSPEC
2646+3E4E 00546 LD A,78
2648+EF 00547 RST 40
2649 C41028 00548 CALL NZ,PRDEST ;Prompt for destination
264C CDAC27 00549 CALL GTFILE ;Xfer into Filename
00550 ;
00551 ; Open Disk Source file
00552 ;
264F 11F12D 00553 OPDSRC LD DE,FCB1 ;DE => Source
2652 CDCF2C 00554 CALL OPEN
2655 C24627 00555 JP NZ,IOERR ;NZ - abort
00556 ;
00557 ; Can this disk file fit into memory ?
00558 ;
2658 2AFD2D 00559 LD HL,(FCB1+12) ;P/u ERN
265B 24 00560 INC H ;Too big ?
265C 25 00561 DEC H
265D C2BF29 00562 JP NZ,TOOBIG ;Yes - forget it
2660 3E00 00563 ENUF LD A,$-$ ;Enough memory ?
2662 C630 00564 ADD A,MEM<-8 ;Add mem start
2664 BD 00565 CP L
2665 DABF29 00566 JP C,TOOBIG ;No - forget it
00567 ;
00568 ; Read in Disk file & Write to tape
00569 ;
2668 CD3B2A 00570 CALL PRTAPE ;Display "Ready Tape"
266B CDBC2C 00571 CALL CURSOFF ;Turn of cursor
266E 217B27 00572 LD HL,READING ;Init "Reading : "
2671 CD4928 00573 CALL DSPLY ;Display line
2674 219D27 00574 LD HL,DFBUF ;HL => Disk Filename
2677 CD4928 00575 CALL DSPLY
267A CD692D 00576 CALL READSRC ;Read the source file
267D CDCA2D 00577 CALL GETPOS ;Get new cursor pos
2680 CD9B2D 00578 CALL ENDOKI ;Bring in Video
2683 218527 00579 LD HL,WRITING ;Display "Writing : "
2686 CD802C 00580 CALL DISPSTR
2689 219027 00581 LD HL,FILENM ;"filenm"
268C CD802C 00582 CALL DISPSTR
268F CD1A2A 00583 CALL CASSON ;Turn on cassette
2692 0680 00584 LD B,80H ;Pause a bit
2694 00585 @@PAUSE
2694+3E10 00586 LD A,16
2696+EF 00587 RST 40
2697 CDEC2B 00588 CALL WRHEAD ;Write Header
269A CD192C 00589 CALL WRDAT ;Write Data
269D 2A6627 00590 LD HL,(CURPOS) ;P/u new cursor pos
26A0 CDE32D 00591 CALL GETCRS
26A3 0603 00592 LD B,3 ;Give to system
26A5 00593 @@VDCTL
26A5+3E0F 00594 LD A,15
26A7+EF 00595 RST 40
26A8 CDA92D 00596 CALL DISDOKI ;Restore video
26AB CD2B2A 00597 CALL CASSOFF ;Turn off cassette
26AE C35827 00598 JP EXIT ;Clean exit
00599 ;
00600 ; Get Source & Destination for READ
00601 ;
26B1 11F12D 00602 RDTAPE LD DE,FCB1 ;First filespec legal ?
26B4 00603 @@FSPEC
26B4+3E4E 00604 LD A,78
26B6+EF 00605 RST 40
26B7 280D 00606 JR Z,CHKSEC ;Yes - check for second
00607 ;
00608 ; Accept first filename on tape
00609 ;
26B9 3EC9 00610 LD A,0C9H
26BB 320D2B 00611 LD (CORRECT),A
26BE 11112E 00612 LD DE,FCB2 ;Prompt for dest filename
26C1 CD2D28 00613 CALL PRDEST2 ;Prompt for dest
26C4 1825 00614 JR READFIL ; and read file
00615 ;
00616 ; Copy source FCB into destination
00617 ;
26C6 E5 00618 CHKSEC PUSH HL ;Save comm ptr
26C7 EB 00619 EX DE,HL
26C8 11112E 00620 LD DE,FCB2 ;DE => Disk FCB
26CB 012000 00621 LD BC,32
26CE D5 00622 PUSH DE ;Save dest FCB
26CF EDB0 00623 LDIR
26D1 D1 00624 POP DE
26D2 E1 00625 POP HL
00626 ;
00627 ; P/u destination filespec
00628 ;
26D3 2B 00629 DEC HL ;Skip leading spaces
26D4 23 00630 SKPSPC INC HL
26D5 7E 00631 LD A,(HL) ;P/u char
26D6 FE20 00632 CP ' ' ;Space ?
26D8 28FA 00633 JR Z,SKPSPC
26DA FE0E 00634 CP CR+1 ;Eol ?
26DC 3807 00635 JR C,GTFILE2 ;Yes - use default
26DE FE28 00636 CP '(' ;Eol ?
26E0 2803 00637 JR Z,GTFILE2
26E2 00638 @@FSPEC ;Xfer in if legal
26E2+3E4E 00639 LD A,78
26E4+EF 00640 RST 40
00641 ;
00642 ; Transfer filename into buffer left just'd
00643 ;
26E5 11F12D 00644 GTFILE2 LD DE,FCB1 ;DE => Source
26E8 CDAC27 00645 CALL GTFILE ;Stuff Filename into buff
00646 ;
00647 ; Read in Tape Source file
00648 ;
26EB 11112E 00649 READFIL LD DE,FCB2 ;@INIT the dest file
26EE CDCB2C 00650 CALL INIT
26F1 C24627 00651 JP NZ,IOERR
26F4 DD4E06 00652 LD C,(IX+6) ;P/u drive #
26F7 00653 @@CKDRV ;Write protected ?
26F7+3E21 00654 LD A,33
26F9+EF 00655 RST 40
26FA 3E0F 00656 LD A,15 ;Write Protected Disk
26FC DA4627 00657 JP C,IOERR ;Good bye
26FF CD3B2A 00658 CALL PRTAPE ;"Ready Cassette"
2702 CDBC2C 00659 CALL CURSOFF
2705 CD9B2D 00660 CALL ENDOKI ;Bring in KI & DO RAM
2708 CDCA2D 00661 CALL GETPOS ;Calculate cursor posn
270B 217B27 00662 LD HL,READING ;Display "Reading : "
270E CD802C 00663 CALL DISPSTR
2711 CD1A2A 00664 CALL CASSON ;Turn on cassette
2714 CDD82A 00665 CALL RDHEAD ;Search for header
2717 CD492A 00666 CALL RDDAT ;Read in Data
271A F3 00667 DI ;Make sure off
271B CD2B2A 00668 CALL CASSOFF ;Turn off cassette
271E 218527 00669 LD HL,WRITING ;Display "Writing : "
2721 CD802C 00670 CALL DISPSTR ;
2724 219D27 00671 LD HL,DFBUF ;HL => Destination
2727 CD802C 00672 CALL DISPSTR ;
272A 2A6627 00673 LD HL,(CURPOS) ;P/u new cursor position
272D CDE32D 00674 CALL GETCRS ;Convert to Row, Column
2730 0603 00675 LD B,3 ;Give system new cursor
2732 00676 @@VDCTL ;
2732+3E0F 00677 LD A,15
2734+EF 00678 RST 40
2735 CDA92D 00679 CALL DISDOKI ;Enable real RAM
2738 1806 00680 JR WRTDES2 ;
273A CDA92D 00681 FORNOW CALL DISDOKI ;Enable real RAM
273D CD2B2A 00682 CALL CASSOFF ;Turn off cassette
2740 CD512D 00683 WRTDES2 CALL WRTDEST ;Write Destination file
2743 C35827 00684 JP EXIT ;Clean exit
00685 ;
00686 ;
2746 6F 00687 IOERR LD L,A ;Xfer error # to HL
2747 2600 00688 LD H,0 ;
2749 F6C0 00689 OR 0C0H ;Abbrev, return
274B 4F 00690 LD C,A
274C 00691 @@ERROR ;Display error
274C+3E1A 00692 LD A,26
274E+EF 00693 RST 40
274F 180A 00694 JR OLDSP ; and abort
00695 ;
2751 C35427 00696 ILLEGAL JP ABORT ;For now
00697 ;
2754 21FFFF 00698 ABORT LD HL,-1 ;Show error return
2757 DD 00699 DB 0DDH ;Skip LD HL,0
2758 210000 00700 EXIT LD HL,0 ;Clean exit
275B 310000 00701 OLDSP LD SP,$-$ ;P/u original SP
275E FB 00702 EI ;Re-enable interrupts
275F 00703 @@CKBRKC ;Clear Break
275F+3E6A 00704 LD A,106
2761+EF 00705 RST 40
2762 C9 00706 RET ; and RETurn
00707 ;
2763 00 00708 DLEN DB 0,0,0
00 00
2766 0000 00709 CURPOS DW 0 ;Cursor Position
2768 0A 00710 READERR DB LF,'Tape Read Error ',CR
54 61 70 65 20 52 65 61
64 20 45 72 72 6F 72 20
20 0D
277B 52 00711 READING DB 'Reading: ',ETX
65 61 64 69 6E 67 3A 20
03
2785 0A 00712 WRITING DB LF,'Writing: ',ETX
57 72 69 74 69 6E 67 3A
20 03
2790 46 00713 FILENM DB 'FILENM',CR
49 4C 45 4E 4D 0D
2797 00714 BUFFER DS 6
279D 46 00715 DFBUF DB 'Filename/ext:d',ETX
69 6C 65 6E 61 6D 65 2F
65 78 74 3A 64 03
00716 ;
00717 ;
00718 ; GTFILE - Stuff filename from FCB into buffer
00719 ; DE => FCB with filename contained
00720 ;
27AC 219027 00721 GTFILE LD HL,FILENM ;HL => Filename buffered
27AF E5 00722 PUSH HL ;Save it
27B0 0606 00723 LD B,6 ;Init to all spaces
27B2 3620 00724 CLEAN LD (HL),' '
27B4 23 00725 INC HL
27B5 10FB 00726 DJNZ CLEAN
27B7 E1 00727 POP HL ;HL => Filename dest
27B8 0606 00728 LD B,6 ;Only accept first 6
00729 ;
27BA 1A 00730 GETFILN LD A,(DE) ;P/u char
27BB FE0E 00731 CP CR+1 ;End ?
27BD D8 00732 RET C ;Yes - done
27BE FE2E 00733 CP '.' ;Start of password?
27C0 C8 00734 RET Z ;Yes - done
27C1 77 00735 LD (HL),A ;Stuff into filename buff
27C2 23 00736 INC HL ;Bump
27C3 13 00737 INC DE
27C4 10F4 00738 DJNZ GETFILN
27C6 C9 00739 RET ;Done - RETurn
00740 ;
00741 ; DOINIT - Do initialization
00742 ;
27C7 00743 DOINIT @@FLAGS ;IY => System Flags
27C7+3E65 00744 LD A,101
27C9+EF 00745 RST 40
00746 ;
00747 ; Calculate highest mem address of buffer
00748 ;
27CA E5 00749 PUSH HL ;Save command line stuff
27CB 210000 00750 LD HL,0 ;P/u HIGH$
27CE 45 00751 LD B,L
27CF FDCB024E 00752 BIT 1,(IY+CFLAG$) ;@CMNDR ?
27D3 2801 00753 JR Z,USEHI
27D5 04 00754 INC B ;Use LOW$
27D6 00755 USEHI @@HIGH$
27D6+3E64 00756 LD A,100
27D8+EF 00757 RST 40
27D9 23 00758 INC HL ;Set hi-mem byte
27DA 25 00759 DEC H ;Give some lee-way
27DB 25 00760 DEC H
27DC 7C 00761 LD A,H ; & stuff in R/W routines
27DD 326126 00762 LD (ENUF+1),A
00763 ;
00764 ; Display Log-on message
00765 ;
27E0 215328 00766 LD HL,HELLO$ ;Display banner
27E3 CD4928 00767 CALL DSPLY
27E6 E1 00768 POP HL ;Process parm line
00769 ;
00770 ; P/u READ or WRITE parm if entered
00771 ;
27E7 E5 00772 PUSH HL ;Save HL
27E8 2B 00773 DEC HL ;Back up one
27E9 23 00774 CKPLP INC HL ;Bump
27EA 7E 00775 LD A,(HL) ;P/u char
27EB FE0E 00776 CP CR+1 ;Eol ?
27ED 380D 00777 JR C,DUNLIN ;Yes - done
27EF FE28 00778 CP '(' ;Paramter entered ?
27F1 20F6 00779 JR NZ,CKPLP ;No - go til eol
00780 ;
00781 ; Process parameter entry
00782 ;
27F3 11C829 00783 LD DE,PARMTBL ;DE => Param table
27F6 00784 @@PARAM
27F6+3E11 00785 LD A,17
27F8+EF 00786 RST 40
27F9 C2BB29 00787 JP NZ,PRMERR ;NZ - parameter error
27FC E1 00788 DUNLIN POP HL ;Rcvr command ptr
00789 ;
00790 ; If C=N entered then use checksum
00791 ;
27FD 01FFFF 00792 CPARM LD BC,0FFFFH ;Default no checksum
2800 04 00793 INC B ;User requesting checksum?
2801 C0 00794 RET NZ ;Yes, return
2802 3EC9 00795 LD A,0C9H ;Init RET opcode
2804 32242B 00796 LD (CHKERR+1),A ;Stuff into Checksum error
2807 C9 00797 RET
00798 ;
00799 ; PRSOUR/PRDEST - Prompt for Source & Destination
00800 ;
2808 E5 00801 PRSOUR PUSH HL ;Save HL
2809 210A29 00802 LD HL,DSF ;"Disk Source Filename"
280C 0617 00803 LD B,23 ;23 chars max
280E 1806 00804 JR DOINPUT
2810 E5 00805 PRDEST PUSH HL ;Save HL
2811 212329 00806 LD HL,TDF ;"Tape Dest Filename"
2814 0606 00807 LD B,6 ;6 char max
2816 CD4928 00808 DOINPUT CALL DSPLY ;Display prompt
2819 E5 00809 PUSH HL ;Save prompt start
281A CD3528 00810 CALL INPUT ;Input
281D 00811 @@FSPEC ;Legal ?
281D+3E4E 00812 LD A,78
281F+EF 00813 RST 40
2820 E1 00814 POP HL ;HL => Prompt string
2821 20F3 00815 JR NZ,DOINPUT ;Reprompt on bad name
2823 E1 00816 POP HL ;Recover ptr
2824 C9 00817 RET ; and return
00818 ;
00819 ; PRSOUR2/PRDEST2 - Prompt for READ source/dest
00820 ;
2825 E5 00821 PRSOUR2 PUSH HL ;Save HL
2826 21F128 00822 LD HL,TSF ;"Tape Source filename"
2829 0606 00823 LD B,6 ;6 char max
282B 18E9 00824 JR DOINPUT
282D E5 00825 PRDEST2 PUSH HL ;Save HL
282E 214129 00826 LD HL,DDF ;"Disk Destination file"
2831 0617 00827 LD B,23 ;23 char max
2833 18E1 00828 JR DOINPUT
00829 ;
00830 ; INPUT - Line input routine
00831 ;
2835 D5 00832 INPUT PUSH DE ;Save DE
2836 C5 00833 PUSH BC ; and BC
2837 21312E 00834 LD HL,INBUFF ;HL => Input buffer
283A 00835 @@KEYIN ;Input line
283A+3E09 00836 LD A,9
283C+EF 00837 RST 40
283D DA5427 00838 JP C,ABORT ; abort
2840 C1 00839 POP BC ;Restore regs
2841 D1 00840 POP DE
2842 C9 00841 RET
00842 ;
2843 D5 00843 DSP PUSH DE ;Save DE
2844 00844 @@DSP ;Output char
2844+3E02 00845 LD A,2
2846+EF 00846 RST 40
2847 1804 00847 JR EXDSP
00848 ;
2849 D5 00849 DSPLY PUSH DE ;Save DE
284A 00850 @@DSPLY ;Display message
00851 IFEQ 00H,1
00852 LD HL,
00853 ENDIF
284A+3E0A 00854 LD A,10
284C+EF 00855 RST 40
284D D1 00856 EXDSP POP DE ;Rcvr DE
284E C8 00857 RET Z ;RETurn if OK
284F C34627 00858 JP IOERR ; else abort
00859 ;
2852 00 00860 COUNT DB 0 ;Count
00861 ;
2853 1C 00862 HELLO$ DB 1CH,1FH,'TAPE100'
1F 54 41 50 45 31 30 30
285C 00863 *GET CLIENT:3
00864 ;CLIENT/ASM - File to establish sign-on headers
00865 ; and version numbers.
00866 ;
00867 ; EACH STRING SHOULD CONTAIN ONLY 63 CHARACTERS !!
00868 ;
00869 IF @BLD631
00870 ; 12345678901234567890123456789012345678901234567890
285C 20 00871 DB ' - 6.3.1 - Copyright 1982/83/84/86/90 by MISOSYS, ';<631>
2D 20 36 2E 33 2E 31 20
2D 20 43 6F 70 79 72 69
67 68 74 20 31 39 38 32
2F 38 33 2F 38 34 2F 38
36 2F 39 30 20 62 79 20
4D 49 53 4F 53 59 53 2C
20
288E 49 00872 DB 'Inc., ',10 ;<631>
6E 63 2E 2C 20 20 20 20
20 20 20 0A
00873 ELSE
00874 DB ' - 6.3.0 - Copyright 1982/83/84/86 by Logical Syst'
00875 DB 'ems, Inc. ',10
00876 ENDIF
00877 ;
00878 ; DB 'All Rights Reserved. Licensed 1982/83/84 to Tandy '
00879 ; DB 'Corporation.',10,13
00880 ;
00881 ; DB 'All Rights Reserved. Beta-TEST Level/AD, DO NOT DI'
00882 ; DB 'STRIBUTE !! ',10,13
00883 ; DB 'All Rights reserved by LSI, 8970 N. 55th St. Milwa'
00884 ; DB 'ukee, Wisc. ',10,13
289B 41 00885 DB 'All Rights Reserved. Unauthorized duplication is p'
6C 6C 20 52 69 67 68 74
73 20 52 65 73 65 72 76
65 64 2E 20 55 6E 61 75
74 68 6F 72 69 7A 65 64
20 64 75 70 6C 69 63 61
74 69 6F 6E 20 69 73 20
70
28CD 72 00886 DB 'rohibited. ',10,13
6F 68 69 62 69 74 65 64
2E 20 20 0A 0D
00887 ;
28DB 3C 00888 RDORWR DB 'ead or rite ? ',CURON,ETX
52 3E 65 61 64 20 6F 72
20 3C 57 3E 72 69 74 65
20 3F 20 0E 03
28F1 54 00889 TSF DB 'Tape Source Filespec ? ',CURON,ETX
61 70 65 20 53 6F 75 72
63 65 20 46 69 6C 65 73
70 65 63 20 3F 20 0E 03
290A 44 00890 DSF DB 'Disk Source Filespec ? ',CURON,ETX
69 73 6B 20 53 6F 75 72
63 65 20 46 69 6C 65 73
70 65 63 20 3F 20 0E 03
2923 54 00891 TDF DB 'Tape Destination Filespec ? ',CURON,ETX
61 70 65 20 44 65 73 74
69 6E 61 74 69 6F 6E 20
46 69 6C 65 73 70 65 63
20 3F 20 0E 03
2941 44 00892 DDF DB 'Disk Destination Filespec ? ',CURON,ETX
69 73 6B 20 44 65 73 74
69 6E 61 74 69 6F 6E 20
46 69 6C 65 73 70 65 63
20 3F 20 0E 03
295F 52 00893 TREADY DB 'Ready Cassette & Press '
65 61 64 79 20 43 61 73
73 65 74 74 65 20 26 20
50 72 65 73 73 20 3C 45
4E 54 45 52 3E
297D 0E 00894 DB CURON,ETX
03
297F 50 00895 PRMERR$ DB 'Parameter error',LF,CR
61 72 61 6D 65 74 65 72
20 65 72 72 6F 72 0A 0D
2990 46 00896 TOOBIG$ DB 'File too large to fit in available '
69 6C 65 20 74 6F 6F 20
6C 61 72 67 65 20 74 6F
20 66 69 74 20 69 6E 20
61 76 61 69 6C 61 62 6C
65 20
29B3 6D 00897 DB 'memory',LF,CR
65 6D 6F 72 79 0A 0D
00898 ;
00899 ;
00900 ; Error Exit routine
00901 ;
29BB 217F29 00902 PRMERR LD HL,PRMERR$ ;"Parameter Error"
29BE DD 00903 DB 0DDH ;Skip
29BF 219029 00904 TOOBIG LD HL,TOOBIG$ ;"File too Big"
00905 ;
29C2 00906 @@LOGOT ;Display error
00907 IFEQ 00H,1
00908 LD HL,
00909 ENDIF
29C2+3E0C 00910 LD A,12
29C4+EF 00911 RST 40
29C5 C35427 00912 JP ABORT ;Good bye
00913 ;
00914 ; Parameter Table
00915 ;
29C8 80 00916 PARMTBL DB 80H ;6.x @PARAM
29C9 55 00917 DB FLAG!ABB!5
29CA 57 00918 DB 'WRITE'
52 49 54 45
29CF 00 00919 WRESP DB 0
29D0 E629 00920 DW WPARM
00921 ;
29D2 54 00922 DB FLAG!ABB!4
29D3 52 00923 DB 'READ'
45 41 44
29D7 00 00924 RRESP DB 0
29D8 E429 00925 DW RPARM
00926 ;
29DA 54 00927 DB FLAG!ABB!4
29DB 43 00928 DB 'CHECK'
48 45 43 4B
29E0 00 00929 CRESP DB 0
29E1 FE27 00930 DW CPARM+1
00931 ;
29E3 00 00932 DB 0
00933 ;
29E4 0000 00934 RPARM DW 0
29E6 0000 00935 WPARM DW 0
00936 ;
29E8 00 00937 DC 50,0 ;Patch space
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00
00938 ;
2A1A 00939 *GET TAPE100A:3
00940 ;TAPE100A/ASM - Tape I/O routines
00941 ; CASSON - Turn Cassette Motor On
00942 ;
2A1A F3 00943 CASSON DI ;Disable interrupts
2A1B CDB52D 00944 CALL SWAP38 ;Grab RST 38H vector
2A1E DBE0 00945 IN A,(PORTE0) ;Clear any latches
2A20 DBEC 00946 IN A,(MODOUT) ;Clear any latches
2A22 3E02 00947 LD A,2 ;Motor on, slow speed
2A24 D3EC 00948 OUT (MODOUT),A ;Turn on motor
2A26 3E03 00949 LD A,3 ;Disable other interrupts
2A28 D3E0 00950 OUT (PORTE0),A
2A2A C9 00951 RET
00952 ;
00953 ; CASSOFF - Turn off Cassette Motor
00954 ;
2A2B FD7E16 00955 CASSOFF LD A,(IY+WRMASK) ;P/u original
2A2E D3E0 00956 OUT (PORTE0),A ;Set up R/F interrupt
2A30 DBFF 00957 IN A,(PORTFF) ;Clear 1500 bd interrupts
2A32 FD7E0C 00958 LD A,(IY+MODMASK) ;Turn off motor
2A35 D3EC 00959 OUT (MODOUT),A
2A37 CDB52D 00960 CALL SWAP38 ;Restore RST 38H vector
2A3A C9 00961 RET
00962 ;
00963 ; PRTAPE - Prompt for "Tape Ready" & turn motor on
00964 ;
2A3B 215F29 00965 PRTAPE LD HL,TREADY ;"Ready cassette &
2A3E CD4928 00966 CALL DSPLY
2A41 0601 00967 NOTENT LD B,1 ;Just 1 char
2A43 CD3528 00968 CALL INPUT ; or
2A46 C3BC2C 00969 JP CURSOFF ;Turn off Cursor & RETurn
00970 ;
00971 ; RDDAT - Read in a tape file
00972 ;
2A49 21002F 00973 RDDAT LD HL,MEM-100H ;HL => Start of file
2A4C 24 00974 RDDAT2 INC H ;Bump hi-byte
2A4D CD582A 00975 CALL RDDATA ;Read a block
2A50 C8 00976 RET Z ;Eof ?
2A51 3E00 00977 EOTF LD A,$-$ ;At top of memory ?
2A53 BC 00978 CP H
2A54 20F6 00979 JR NZ,RDDAT2 ;No
2A56 B7 00980 OR A ;Top of mem -
2A57 C9 00981 RET ;RETurn NZ
00982 ;
00983 ; RDDATA - Read in a block of Data
00984 ; HL => Destination of Block
00985 ;
2A58 CD392B 00986 RDDATA CALL RDSYNC ;Read sync field
2A5B CDA72B 00987 CALL RDBYTE ;Read a byte
2A5E FE8D 00988 CP 8DH ;Legal ?
2A60 C25127 00989 JP NZ,ILLEGAL ;No - bad news
2A63 110000 00990 LD DE,0 ;D=EOF flag, E = checksum
00991 ;
2A66 CDA72B 00992 RDLP1 CALL RDBYTE ;Read a byte
2A69 77 00993 LD (HL),A ;Stuff into buffer
00994 ;
00995 ; Check for End of File byte X'1A'
00996 ;
2A6A FE1A 00997 CP 1AH ;Eof ?
2A6C 2005 00998 JR NZ,AFTER ;No
2A6E BA 00999 CP D ;Been here before ?
2A6F 2802 01000 JR Z,AFTER ;First time ?
2A71 57 01001 LD D,A ;Set D = 1AH
2A72 45 01002 LD B,L ;Yes - set B = pos
01003 ;
01004 ; Add byte to checksum
01005 ;
2A73 83 01006 AFTER ADD A,E ;Add checksum
2A74 5F 01007 LD E,A ;Xfer back to E
2A75 2C 01008 INC L ;Bump
2A76 20EE 01009 JR NZ,RDLP1
2A78 ED44 01010 NEG ;Negate checksum
2A7A 5F 01011 LD E,A ;Stuff back in E
01012 ;
01013 ; Verify Checksum byte
01014 ;
2A7B CDA72B 01015 CALL RDBYTE ;Read in byte
2A7E BB 01016 CP E ;Checksums match ?
2A7F C4232B 01017 CALL NZ,CHKERR ;No - checksum error
01018 ;
01019 ; Stuff EOF offset byte into WRTDEST routine
01020 ;
2A82 7C 01021 LD A,H ;P/u eom
2A83 325C2D 01022 LD (EOTF2+1),A ;Stuff into WRTDEST
2A86 78 01023 LD A,B ;P/u byte
2A87 3C 01024 INC A ;Bump
2A88 32612D 01025 LD (OFFSET+1),A
01026 ;
01027 ; Read past 20 dummy zeroes
01028 ;
2A8B 0614 01029 LD B,20
2A8D CDA72B 01030 RDLP2 CALL RDBYTE
2A90 10FB 01031 DJNZ RDLP2
01032 ;
01033 ; Set Z flag if at EOF
01034 ;
2A92 7A 01035 LD A,D ;Eof ?
2A93 FE1A 01036 CP 1AH
2A95 C9 01037 RET ;Done
01038 ;
01039 ; RDBIT - Read a Bit from Cassette
01040 ;
2A96 0E00 01041 RDBIT LD C,0 ;Init count = 0
2A98 FB 01042 EI ;Back on
2A99 0C 01043 RBLP INC C ;Bump count
2A9A 3A40F4 01044 LD A,(BREAKLC) ; hit ?
2A9D E604 01045 AND 4
2A9F 28F8 01046 JR Z,RBLP ;No - wait for interrupt
01047 ;
01048 ; key hit - Abort
01049 ;
2AA1 F3 01050 DI ;Cancel next interrupt
2AA2 CDA92D 01051 CALL DISDOKI ;Put *DO & *KI back
2AA5 CD2B2A 01052 CALL CASSOFF ;Turn off cassette
2AA8 0E0D 01053 LD C,CR ;End line
2AAA CD4328 01054 CALL DSP
2AAD C35427 01055 JP ABORT ;Go to abort routine
01056 ;
01057 ; Interrupt Handler - Comes from RST 38
01058 ;
2AB0 C3B32A 01059 RST38V JP $+3 ;Wait
2AB3 F5 01060 PUSH AF ;Save status
2AB4 DBE0 01061 IN A,(PORTE0) ;Read port
2AB6 1F 01062 RRA ;Bit 0 low ?
2AB7 D2C12A 01063 JP NC,BIT0LOW
2ABA 1F 01064 RRA ;Bit 1 low ?
2ABB D2C52A 01065 JP NC,BIT1LOW
2ABE F1 01066 POP AF ;Recover status
2ABF FB 01067 EI ;Back on
2AC0 C9 01068 RET ;RETurn
01069 ;
01070 ; Set E = bit image - bit 0 or 1
01071 ;
2AC1 1E01 01072 BIT0LOW LD E,1 ;High
2AC3 1802 01073 JR BIT1LOW+2 ;Add interrupt offset
2AC5 1E00 01074 BIT1LOW LD E,0 ;Low
2AC7 3E06 01075 LD A,ROUTOFF ;Add interrupt routine
2AC9 81 01076 ADD A,C ;Offset to C
2ACA 4F 01077 LD C,A
01078 ;
01079 ; Is the Head on a valid pulse ?
01080 ;
2ACB DBFF 01081 IN A,(PORTFF) ;Read cassette level
2ACD E601 01082 AND 1 ;Mask off all but bit 0
2ACF BB 01083 CP E ;Same as given level ?
2AD0 2003 01084 JR NZ,WAITINT ;No - wait for next inter
01085 ;
01086 ; Valid pulse - Get out of interrupt routine
01087 ;
2AD2 F1 01088 POP AF ;Remove RST 38 RET addr
2AD3 F1 01089 POP AF
2AD4 C9 01090 RET
01091 ;
01092 ; Not the right interrupt - wait for next
01093 ;
2AD5 F1 01094 WAITINT POP AF ;Recover status
2AD6 FB 01095 EI ; and wait for next
2AD7 C9 01096 RET ; interrupt
01097 ;
01098 ; RDHEAD - Read a TAPE100 header
01099 ;
2AD8 2A6627 01100 RDHEAD LD HL,(CURPOS) ;P/u cursor position
2ADB 119727 01101 LD DE,BUFFER ;Buffer
2ADE CD392B 01102 CALL RDSYNC ;Read in SYNC
01103 ;
01104 ; Read in Header Type byte
01105 ;
2AE1 CDA72B 01106 CALL RDBYTE ;Read type byte
2AE4 FE9C 01107 CP 9CH ;Text type ?
2AE6 20F0 01108 JR NZ,RDHEAD ;No - try again
01109 ;
2AE8 010006 01110 LD BC,600H ;B=6 bytes, Checksum = 0
01111 ;
2AEB CDA22B 01112 RFNLP CALL RDBYTEC ;Read byte
2AEE 77 01113 LD (HL),A ;Save byte
2AEF 12 01114 LD (DE),A ;Stuff in buffer
2AF0 23 01115 INC HL ;Bump cursor pos
2AF1 13 01116 INC DE ;Bump buffer ptr
2AF2 10F7 01117 DJNZ RFNLP
01118 ;
01119 ; Next ten bytes are unused
01120 ;
2AF4 060A 01121 LD B,10
2AF6 CDA22B 01122 BOGUSLP CALL RDBYTEC ;Read byte & checksum
2AF9 10FB 01123 DJNZ BOGUSLP
01124 ;
01125 ; Negate checksum
01126 ;
2AFB 79 01127 LD A,C ;P/u checksum
2AFC ED44 01128 NEG ;Negate it
2AFE 4F 01129 LD C,A
2AFF CDA72B 01130 CALL RDBYTE ;Read in Checksum byte
2B02 B9 01131 CP C ;Match ?
2B03 C4232B 01132 CALL NZ,CHKERR ;No - checksum error
01133 ;
01134 ; Read in twenty zeros
01135 ;
2B06 0614 01136 LD B,20
2B08 CDA72B 01137 DUMBYT CALL RDBYTE
2B0B 10FB 01138 DJNZ DUMBYT
01139 ;
01140 ; Check if this is the correct filename
01141 ;
2B0D 00 01142 CORRECT NOP ;X'C9' if first filename
2B0E 119727 01143 LD DE,BUFFER ;Is this the one ?
2B11 219027 01144 LD HL,FILENM
2B14 0606 01145 LD B,6 ;6 chars in filename
01146 ;
01147 ; Loop to compare (HL) to (DE)
01148 ;
2B16 1A 01149 CKFILE LD A,(DE) ;P/u header byte
2B17 CDB32C 01150 CALL CONV_UC ;Convert to U/C
2B1A BE 01151 CP (HL) ;Match ?
2B1B 23 01152 INC HL
2B1C 13 01153 INC DE
2B1D C2D82A 01154 JP NZ,RDHEAD ;No - try again
2B20 10F4 01155 DJNZ CKFILE
2B22 C9 01156 RET ;Yes - RETurn
01157 ;
01158 ; Checksum error - Either ignore it or "C"
01159 ;
2B23 00 01160 CHKERR NOP ;RETurn or NOP
2B24 F3 01161 DI ;Disable interrupts
2B25 3E43 01162 LD A,'C' ;hecksum error
2B27 324FF8 01163 CHKERR2 LD (VIDEO+79),A
2B2A CDA92D 01164 CALL DISDOKI ;Bring back RAM
2B2D CD2B2A 01165 CALL CASSOFF ;Turn off motor
2B30 216827 01166 LD HL,READERR ;"Tape Read Error!"
2B33 CD4928 01167 CALL DSPLY
2B36 C35427 01168 JP ABORT ;Good bye
01169 ;
01170 ; RDSYNC - Read Cassette SYNC byte field
01171 ;
01172 ; Save Registers
01173 ;
2B39 E5 01174 RDSYNC PUSH HL ;Save regs
2B3A D5 01175 PUSH DE
2B3B C5 01176 PUSH BC
2B3C 3E01 01177 LD A,1 ;Set interrupt vector
2B3E D3E0 01178 OUT (PORTE0),A
01179 ;
01180 ; Read in 128 bits (16 bytes) initially
01181 ;
2B40 0680 01182 RDSYNC2 LD B,80H ;Read 128 bits (16 bytes)
2B42 CD962A 01183 RBTLP CALL RDBIT ;Read bit
2B45 79 01184 LD A,C ;P/u count value
2B46 FE0F 01185 CP TOOSHRT ;Is this a bit ?
2B48 38F6 01186 JR C,RDSYNC2 ;No - didn't find a bit
2B4A FE3E 01187 CP TOOLONG ;Is this a bit ?
2B4C 30F2 01188 JR NC,RDSYNC2 ;No - wait for bit
2B4E 10F2 01189 DJNZ RBTLP ;Legal bit - dec count
01190 ;
01191 ; Now check parity of next 128 bits
01192 ;
2B50 210000 01193 RESCNT LD HL,0 ;H = 0's count, L = 1's
2B53 0640 01194 LD B,40H
01195 ;
01196 ; Read in 3 bits
01197 ;
2B55 CD962A 01198 LOOP CALL RDBIT ;Read bit
2B58 CD962A 01199 CALL RDBIT ;Read bit
2B5B 51 01200 LD D,C ;Save count
2B5C CD962A 01201 CALL RDBIT ;Read bit
01202 ;
01203 ; Calculate Difference between last 2 bits
01204 ;
2B5F 7A 01205 LD A,D ;P/u last bit
2B60 91 01206 SUB C ;Subtract current bit
2B61 3002 01207 JR NC,ABSVAL
2B63 ED44 01208 NEG ;Change to ABS value
01209 ;
01210 ; If Value < DIFFER then Bit = 1, else Bit = 0
01211 ;
2B65 FE0D 01212 ABSVAL CP DIFFER ;Bit = 1 ?
2B67 3803 01213 JR C,BIT1 ;Yes - bump Bit 1 count
2B69 24 01214 INC H ;No - bump Bit 0 count
2B6A 1801 01215 JR DODJ ;Back to loop
2B6C 2C 01216 BIT1 INC L ;Bump Bit 1 count
2B6D 10E6 01217 DODJ DJNZ LOOP ;Dec count - go to loop
01218 ;
01219 ; Check if H (0's count) & L (1's count) = 40
01220 ;
2B6F 3E40 01221 LD A,40H ;Is H = 64 ?
2B71 BC 01222 CP H
2B72 280A 01223 JR Z,CHKMARK ;Yes - check for marker
2B74 BD 01224 CP L ;Is L = 64 ?
2B75 20D9 01225 JR NZ,RESCNT ;No - Reset count
01226 ;
01227 ; Set interrupt Vector & discard 1 bit
01228 ;
2B77 3E02 01229 LD A,2 ;Set interrupt vector
2B79 D3E0 01230 OUT (PORTE0),A
2B7B CD962A 01231 CALL RDBIT ;Read bit
01232 ;
01233 ; Rotate each bit read in D & check if = X'7F'
01234 ;
2B7E 1600 01235 CHKMARK LD D,0 ;Set byte = 0
2B80 CD962A 01236 GETBIT CALL RDBIT ;Read next bit
2B83 CD8F2B 01237 CALL ROTBYTE ;Rotate into Byte (D)
2B86 7A 01238 LD A,D ;P/u byte
2B87 FE7F 01239 CP 7FH ;Marker byte ?
2B89 20F5 01240 JR NZ,GETBIT ;No - get another bit
01241 ;
01242 ; Found marker byte - Restore Regs & RETurn
01243 ;
2B8B C1 01244 POP BC ;Restore Registers
2B8C D1 01245 POP DE
2B8D E1 01246 POP HL
2B8E C9 01247 RET ;Done
01248 ;
01249 ; ROTBYTE - Rotate bit through D & check if error
01250 ;
2B8F 79 01251 ROTBYTE LD A,C ;P/u count
2B90 FE22 01252 CP WHICH1 ;Bit = 0 or 1 ?
2B92 CB12 01253 RL D ;Set bit if Carry set
2B94 FE0F 01254 CP TOOSHRT ;Too quick ?
2B96 DA9C2B 01255 JP C,CIOERR ;Yes - I/O Error
2B99 FE3E 01256 CP TOOLONG ;Too long
2B9B D8 01257 RET C ;No - RETurn
01258 ;
01259 ; Cassette I/O Error - Display Error
01260 ;
2B9C F3 01261 CIOERR DI ;Interrupts off
2B9D 3E44 01262 LD A,'D' ;Data Error
2B9F C3272B 01263 JP CHKERR2
01264 ;
01265 ; RDBYTEC - Read byte & Add byte to Check Sum
01266 ;
2BA2 CDA72B 01267 RDBYTEC CALL RDBYTE ;Read byte
2BA5 81 01268 ADD A,C ;Add to checksum
2BA6 C9 01269 RET ;Done
01270 ;
01271 ; RDBYTE - Read a byte
01272 ; A <= Byte
01273 ;
2BA7 D5 01274 RDBYTE: PUSH DE ;Save regs
2BA8 C5 01275 PUSH BC
2BA9 CD962A 01276 CALL RDBIT ;Get bogus bit
2BAC 1600 01277 LD D,0 ;Init byte = 0
2BAE 0608 01278 LD B,8 ;8 bits to read
01279 ;
2BB0 CD962A 01280 RDBLP CALL RDBIT ;Read a bit
2BB3 CD8F2B 01281 CALL ROTBYTE ;Rotate into D
2BB6 10F8 01282 DJNZ RDBLP
01283 ;
01284 ; Add to Byte count
01285 ;
2BB8 3A5228 01286 LD A,(COUNT) ;P/u count
2BBB 3C 01287 INC A ; & inc it
2BBC E63F 01288 AND 3FH ;Ck if the 64th
2BBE 325228 01289 LD (COUNT),A ;Save the count
2BC1 2008 01290 JR NZ,NOTBLNK
01291 ;
2BC3 3A4FF8 01292 LD A,(VIDEO+79) ;Blink every 64
2BC6 EE0A 01293 XOR 0AH
2BC8 324FF8 01294 LD (VIDEO+79),A
01295 ;
2BCB 7A 01296 NOTBLNK LD A,D ;Xfer byte to A
2BCC 1800 01297 JR NEXTINS ;Timing
01298 ;
2BCE C1 01299 NEXTINS POP BC ;Restore BC & DE
2BCF D1 01300 POP DE
2BD0 C9 01301 RET ;Done
01302 ;
01303 ; WRBIT - Write a bit to Cassette
01304 ;
01305 ; Set DE = Delay Count for bit
01306 ;
2BD1 CB01 01307 WRBIT RLC C ;Get bit
2BD3 3005 01308 JR NC,NOPULS ;NC - bit 0
2BD5 111712 01309 BT1 LD DE,DELAY1 ;Delay for bit 1
2BD8 1803 01310 JR DEL_LP ;Go to delay
2BDA 112F2B 01311 NOPULS LD DE,DELAY0 ;Delay for bit=0
01312 ;
01313 ; Delay 18 counts for 1, 43 counts for 0
01314 ;
2BDD 15 01315 DEL_LP DEC D ;Dec count
2BDE 20FD 01316 JR NZ,DEL_LP
2BE0 3E02 01317 LD A,2 ;0 Volts to tape
2BE2 D3FF 01318 OUT (PORTFF),A
2BE4 1D 01319 DEL_LP2 DEC E ;Secondary delay
2BE5 20FD 01320 JR NZ,DEL_LP2
2BE7 3E01 01321 LD A,1 ;0.85 volts to tape
2BE9 D3FF 01322 OUT (PORTFF),A
2BEB C9 01323 RET ;Done
01324 ;
01325 ; WRHEAD - Write a cassette header
01326 ;
2BEC CD602C 01327 WRHEAD CALL WRSYNC ;Write SYNC pattern
01328 ;
01329 ; Write Text header type byte X'9C'
01330 ;
2BEF 1600 01331 LD D,0 ;Init checksum = 0
2BF1 0E9C 01332 LD C,9CH ;Text header type byte
2BF3 CD512C 01333 CALL WRBYTE ;Write type byte
01334 ;
01335 ; Write Filename in header block
01336 ;
2BF6 0606 01337 LD B,6 ;B = 6 chars
2BF8 219027 01338 LD HL,FILENM ;HL => Filename
2BFB 4E 01339 FILELP LD C,(HL) ;P/u filename character
2BFC CD4A2C 01340 CALL WRBYTEC ; and write it
2BFF 23 01341 INC HL ;Bump count
2C00 10F9 01342 DJNZ FILELP
01343 ;
01344 ; Write 10 filler bytes
01345 ;
2C02 060A 01346 LD B,10
2C04 CD4A2C 01347 BOGUS CALL WRBYTEC
2C07 10FB 01348 DJNZ BOGUS
01349 ;
01350 ; Write checksum byte & 20 dummy X'00' bytes
01351 ;
2C09 7A 01352 LD A,D ;P/u checksum
2C0A ED44 01353 NEG
2C0C 4F 01354 LD C,A ; & xfer to C
2C0D CD512C 01355 CALL WRBYTE ;Write Checksum byte
2C10 010014 01356 LD BC,1400H ;B = 20 bytes, C = 0
2C13 CD512C 01357 DUMMY CALL WRBYTE ;Write byte
2C16 10FB 01358 DJNZ DUMMY
2C18 C9 01359 RET ;Get back quick
01360 ;
01361 ; WRDAT - Write a chunk of data to cassette
01362 ;
2C19 210030 01363 WRDAT LD HL,MEM ;HL => Mem start
2C1C CD272C 01364 WRDAT2 CALL WRDATA ;Write Block
2C1F 24 01365 INC H
2C20 3AF52D 01366 LD A,(FCB1+4) ;Finished ?
2C23 BC 01367 CP H
2C24 20F6 01368 JR NZ,WRDAT2 ;No - write another
2C26 C9 01369 RET ;Yes - RETurn
01370 ;
01371 ; WRDATA - Write a data Block
01372 ; HL => 256 byte block of data (page boundary)
01373 ;
2C27 CD602C 01374 WRDATA CALL WRSYNC ;Write sync pattern
2C2A 0E8D 01375 LD C,8DH ;Write X'8D' type byte
2C2C CD512C 01376 CALL WRBYTE
01377 ;
01378 ; Write 256 byte block of data
01379 ;
2C2F AF 01380 XOR A ;Set checksum = 0
2C30 4E 01381 WBLP LD C,(HL) ;P/u byte
2C31 81 01382 ADD A,C ;Add checksum
2C32 F5 01383 PUSH AF ;Save A
2C33 CD512C 01384 CALL WRBYTE ;Write byte
2C36 F1 01385 POP AF ;Recover checksum
2C37 2C 01386 INC L ;Bump count
2C38 20F6 01387 JR NZ,WBLP
01388 ;
01389 ; Write checksum byte
01390 ;
2C3A ED44 01391 NEG ;Negate checksum
2C3C 4F 01392 LD C,A ;Write checksum byte
2C3D CD512C 01393 CALL WRBYTE
01394 ;
01395 ; Write 20 dummy bytes - X'00'
01396 ;
2C40 0614 01397 LD B,20 ;Write 20 dummy zeroes
2C42 0E00 01398 WDLP LD C,0
2C44 CD512C 01399 CALL WRBYTE
2C47 10F9 01400 DJNZ WDLP
2C49 C9 01401 RET ;Done
01402 ;
01403 ; WRBYTEC - Write a byte & add checksum
01404 ;
2C4A CD512C 01405 WRBYTEC CALL WRBYTE ;Write byte
2C4D 79 01406 LD A,C ;P/u byte
2C4E 82 01407 ADD A,D ;Add checksum
2C4F 57 01408 LD D,A ;New checksum
2C50 C9 01409 RET ;And RETurn
01410 ;
01411 ; WRBYTE - Write a byte to Cassette
01412 ; C => Byte to Output
01413 ;
2C51 C5 01414 WRBYTE: PUSH BC ;Save regs
2C52 D5 01415 PUSH DE
2C53 CDDA2B 01416 CALL NOPULS ;Write dummy pulse
2C56 0608 01417 LD B,8 ;8 bits to write
2C58 CDD12B 01418 WRBTLP CALL WRBIT ;Write bit
2C5B 10FB 01419 DJNZ WRBTLP
2C5D D1 01420 POP DE ;Restore regs
2C5E C1 01421 POP BC
2C5F C9 01422 RET
01423 ;
01424 ; WRSYNC - Write a SYNC pattern to Cassette
01425 ;
2C60 F3 01426 WRSYNC DI ;Disable interrupts
2C61 C5 01427 PUSH BC ;Save BC
2C62 0680 01428 LD B,80H ;Delay
2C64 01429 @@PAUSE
2C64+3E10 01430 LD A,16
2C66+EF 01431 RST 40
2C67 015500 01432 LD BC,0055H ;B = 256, C = X'55'
01433 ;
01434 ; Write SYNC bytes - X'55'
01435 ;
2C6A CD762C 01436 WR55LP CALL WRBYTE8 ;Write 8 bit byte
2C6D 10FB 01437 DJNZ WR55LP
01438 ;
01439 ; Write Marker byte - X'7F'
01440 ;
2C6F 0E7F 01441 LD C,7FH ;Write marker byte X'7F'
2C71 CD762C 01442 CALL WRBYTE8
2C74 C1 01443 POP BC ;Recover BC
2C75 C9 01444 RET ;Done
01445 ;
2C76 C5 01446 WRBYTE8 PUSH BC ;Save B
2C77 0608 01447 LD B,8 ;8 bits long
2C79 CDD12B 01448 WB8LP CALL WRBIT ;Write bit
2C7C 10FB 01449 DJNZ WB8LP
2C7E C1 01450 POP BC
2C7F C9 01451 RET
2C80 01452 *GET TAPE100B:3
01453 ;TAPE100B/ASM - Disk I/O & other routines
01454 ;
01455 ; DISPSTR - Display String
01456 ;
2C80 D5 01457 DISPSTR PUSH DE ;Save DE
2C81 ED5B6627 01458 LD DE,(CURPOS) ;P/u cursor position
2C85 7E 01459 DSLP LD A,(HL) ;P/u source char
2C86 FE03 01460 CP ETX ;Done ?
2C88 2815 01461 JR Z,EXIT1 ;Yes - exit
2C8A FE0D 01462 CP CR ;Done ?
2C8C 280E 01463 JR Z,EXIT2 ;Yes - exit
2C8E FE0A 01464 CP LF ;Line feed ?
2C90 2005 01465 JR NZ,STUFCHR ;No - stuff character
2C92 CDA52C 01466 CALL NEXTLIN ;Get next line
2C95 1802 01467 JR BUMPIT
2C97 12 01468 STUFCHR LD (DE),A ;Output to video
2C98 13 01469 INC DE
2C99 23 01470 BUMPIT INC HL ;No - bump count
2C9A 18E9 01471 JR DSLP
2C9C CDA52C 01472 EXIT2 CALL NEXTLIN ;Next one down
2C9F ED536627 01473 EXIT1 LD (CURPOS),DE ;Save cursor position
2CA3 D1 01474 POP DE ;Restore DE
2CA4 C9 01475 RET
01476 ;
01477 ; NEXTLIN - Position to next line on video
01478 ; DE => RAM location
01479 ;
2CA5 E5 01480 NEXTLIN PUSH HL ;Save regs
2CA6 EB 01481 EX DE,HL ;Xfer # to HL
2CA7 CDE32D 01482 CALL GETCRS ;Calculate X,Y
2CAA 24 01483 INC H ;Bump row #
2CAB 2E00 01484 LD L,0 ; and start @ beginning
2CAD CDCF2D 01485 CALL GETPOS2 ;Convert to RAM location
2CB0 EB 01486 EX DE,HL ;Stuff into DE
2CB1 E1 01487 POP HL
2CB2 C9 01488 RET
01489 ;
01490 ; CONV_UC - Convert A to upper case
01491 ;
2CB3 FE61 01492 CONV_UC CP 'a' ;Lower case ?
2CB5 D8 01493 RET C ;No
2CB6 FE7B 01494 CP 'z'+1 ;Lower case ?
2CB8 D0 01495 RET NC ;No
2CB9 CBAF 01496 RES 5,A ;Convert to Upper Case
2CBB C9 01497 RET
01498 ;
01499 ; CURSOFF - Turn off Cursor
01500 ;
2CBC F5 01501 CURSOFF PUSH AF ;Save regs
2CBD D5 01502 PUSH DE
2CBE C5 01503 PUSH BC
2CBF 0E0F 01504 LD C,CUROFF ;Cursor off Character
2CC1 01505 @@DSP
2CC1+3E02 01506 LD A,2
2CC3+EF 01507 RST 40
2CC4 C24627 01508 JP NZ,IOERR
2CC7 C1 01509 POP BC ;Restore regs
2CC8 D1 01510 POP DE
2CC9 F1 01511 POP AF
2CCA C9 01512 RET
01513 ;
01514 ; INIT - Init a file
01515 ;
2CCB 3E3A 01516 INIT LD A,@INIT ;SVC #
2CCD 1806 01517 JR DOSVC ;INIT file
01518 ;
01519 ; OPEN - Open Source File
01520 ;
2CCF FDCB12C6 01521 OPEN SET 0,(IY+SFLAG$) ;Inhibit file-open bit
2CD3 3E3B 01522 LD A,@OPEN ;OPEN SVC #
01523 ;
2CD5 F5 01524 DOSVC PUSH AF
2CD6 D5 01525 PUSH DE
2CD7 219D27 01526 LD HL,DFBUF ;HL => Disk filename buf
2CDA 1A 01527 TLP LD A,(DE) ;P/u byte from FCB
2CDB 77 01528 LD (HL),A ;Xfer to TEMBUF
2CDC 23 01529 INC HL
2CDD 13 01530 INC DE
2CDE FE0E 01531 CP CR+1 ;Done ?
2CE0 3808 01532 JR C,DUN
2CE2 FE3A 01533 CP ':'
2CE4 2804 01534 JR Z,DUN
2CE6 FE2E 01535 CP '.'
2CE8 20F0 01536 JR NZ,TLP
01537 ;
01538 ; Found valid terminator - Is this a device ?
01539 ;
2CEA 2B 01540 DUN DEC HL ;Back up to term
2CEB D1 01541 POP DE ;DE => FCB+0
2CEC 1A 01542 LD A,(DE) ;Device ?
2CED FE2A 01543 CP '*'
2CEF 2807 01544 JR Z,DUN2 ;Yes - done
2CF1 363A 01545 LD (HL),':' ;No - overwrite with ":"
2CF3 23 01546 INC HL ;Bump
2CF4 22122D 01547 LD (DSPEC+1),HL ;Save drivespec location
2CF7 23 01548 INC HL ;Bump
2CF8 3603 01549 DUN2 LD (HL),ETX ;End with X'03'
2CFA F1 01550 POP AF ;A = SVC #
2CFB 32212D 01551 LD (SVCNUM+1),A ;Save SVC #
2CFE 21002F 01552 LD HL,IOBUFF ;HL => I/O Buffer
2D01 0600 01553 LD B,0 ;LRL = 256
2D03 EF 01554 RST 28H ;OPEN or INIT file
2D04 2803 01555 CHECK JR Z,CHKPROT ;Check PROTection status
01556 ;
01557 ; Ignore Error #42 - "LRL Open Fault"
01558 ;
2D06 FE2A 01559 CP 42 ;Ignore this error
2D08 C0 01560 RET NZ ;NZ - Abort
01561 ;
01562 ; Stuff Drive # into Buffer
01563 ;
2D09 D5 01564 CHKPROT PUSH DE ;P/u drivespec
2D0A DDE1 01565 POP IX ; from FCB+6
2D0C DD7E06 01566 LD A,(IX+6)
2D0F C630 01567 ADD A,'0' ;Convert to ASCII
2D11 320000 01568 DSPEC LD ($-$),A
01569 ;
01570 ; Check if File has proper Access
01571 ;
2D14 DDCB007E 01572 BIT 7,(IX) ;Is FCB open?
2D18 281F 01573 JR Z,ILLFILE ;No - Illegal Filename
2D1A DD7E01 01574 LD A,(IX+1) ;P/u protection byte
2D1D E607 01575 AND 7
2D1F 47 01576 LD B,A ;Xfer to B
01577 ;
2D20 3E00 01578 SVCNUM LD A,$-$ ;P/u SVC #
2D22 FE3A 01579 CP @INIT ;@INIT ?
2D24 78 01580 LD A,B ;P/u protection level
2D25 280C 01581 JR Z,INIT1 ;Z - Must be < 5
2D27 FE06 01582 CP 6 ;Read Access ?
2D29 380C 01583 JR C,OKYDOKY ;Yes - set Z & RETurn
01584 ;
01585 ; Illegal Access to protected file
01586 ;
2D2B 01587 ILLACC @@CLOSE ;Close File
2D2B+3E3C 01588 LD A,60
2D2D+EF 01589 RST 40
2D2E 3E19 01590 LD A,25 ;File Access Denied
2D30 C34627 01591 JP IOERR ;Error - Regardless
01592 ;
2D33 FE05 01593 INIT1 CP 5 ;Update Access ?
2D35 30F4 01594 JR NC,ILLACC ;No - Illegal Access
2D37 AF 01595 OKYDOKY XOR A ;RETurn Z
2D38 C9 01596 RET
01597 ;
2D39 3E13 01598 ILLFILE LD A,19 ;Illegal Filename
2D3B B7 01599 OR A ;Set NZ
2D3C C9 01600 RET ;
01601 ;
01602 ; CLOSE - Close the Destination File
01603 ;
2D3D 11112E 01604 CLOSE LD DE,FCB2 ;DE => FCB
2D40 01605 @@CLOSE ;Close File
2D40+3E3C 01606 LD A,60
2D42+EF 01607 RST 40
2D43 C8 01608 RET Z ;Good - RETurn
2D44 C34627 01609 JP IOERR ;Bad - Quit
01610 ;
01611 ; WRITESC - Write a Sector to Destination file
01612 ;
2D47 11112E 01613 WRITESC LD DE,FCB2 ;DE => FCB
2D4A 01614 @@WRITE ;Write Sector
2D4A+3E4B 01615 LD A,75
2D4C+EF 01616 RST 40
2D4D C24627 01617 JP NZ,IOERR ;Bad - quit
2D50 C9 01618 RET ;Good - RETurn
01619 ;
01620 ; WRTDEST - Write Destination File
01621 ;
2D51 11112E 01622 WRTDEST LD DE,FCB2 ;DE => Destination FCB
2D54 21152E 01623 WRTDES LD HL,FCB2+4 ;HL => msb of I/O buffer
2D57 34 01624 INC (HL) ;Bump
2D58 CD472D 01625 CALL WRITESC ;Write Sector
2D5B 3E00 01626 EOTF2 LD A,$-$ ;P/u # of sectors
2D5D BE 01627 CP (HL) ;Finished ?
2D5E 20F4 01628 JR NZ,WRTDES ;No - back to loop
01629 ;
01630 ; Finished Writing - Set EOF offset byte
01631 ;
2D60 3E00 01632 OFFSET LD A,$-$ ;P/u offset byte
2D62 32192E 01633 LD (FCB2+8),A ; & stuff into FCB
2D65 CD3D2D 01634 CALL CLOSE ;Close the File
2D68 C9 01635 RET
01636 ;
01637 ; READSRC - Read in chunk of Source Disk file
01638 ;
2D69 21F52D 01639 READSRC LD HL,FCB1+4 ;HL => Hi byte of I/O buf
2D6C 362F 01640 LD (HL),MEM<-8-1 ;Init FCB I/O buffer
01641 ;
01642 ; Read in Source file
01643 ;
2D6E 11F12D 01644 READSR2 LD DE,FCB1 ;Pt DE to FCB
2D71 34 01645 INC (HL) ;Bump I/O buffer
2D72 01646 @@READ ;Read a sector
2D72+3E43 01647 LD A,67
2D74+EF 01648 RST 40
2D75 28F7 01649 JR Z,READSR2
01650 ;
01651 ; Fill remainder of sector w/ X'1A's
01652 ;
2D77 F5 01653 PUSH AF ;Save Error code
2D78 3AF92D 01654 NOMORE LD A,(FCB1+8) ;P/u EOF offset byte
2D7B ED44 01655 NEG
2D7D 47 01656 LD B,A ;Xfer to B for DJNZ
2D7E 66 01657 LD H,(HL) ;P/u I/O buffer msb
2D7F 2EFF 01658 LD L,0FFH ;End of sector
2D81 2801 01659 JR Z,NULBUF ;Z - keep HL here
2D83 25 01660 DEC H ;Sector boundary
2D84 361A 01661 NULBUF LD (HL),1AH ;Fill remainder of buffer
2D86 2B 01662 DEC HL ; with zeroes
2D87 10FB 01663 DJNZ NULBUF
01664 ;
01665 ; Add a sector of 1As
01666 ;
2D89 24 01667 INC H ;Pt to next sector
2D8A 2E00 01668 LD L,0
2D8C 361A 01669 XTR1AS LD (HL),01AH ;EOF indicator
2D8E 23 01670 INC HL ;Bump
2D8F 10FB 01671 DJNZ XTR1AS
2D91 F1 01672 DONTFIL POP AF ;Recover error code
01673 ;
01674 ; I/O Error - Better be EOF error
01675 ;
2D92 FE1C 01676 CP 1CH ;EOF ?
2D94 C8 01677 RET Z ;Yes - RETurn
2D95 FE1D 01678 CP 1DH ;NRN > ERN
2D97 C8 01679 RET Z ;Yes - RETurn
2D98 C34627 01680 JP IOERR ;No - Disk Error
01681 ;
01682 ; ENDOKI - Enable Video & Keyboard
01683 ;
2D9B F5 01684 ENDOKI PUSH AF
2D9C E5 01685 PUSH HL
2D9D 3A7800 01686 LD A,(OPREG$) ;P/u port mask
2DA0 32AC2D 01687 LD (SVOPREG+1),A ; and save it for DISDOKI
2DA3 CB87 01688 RES 0,A ;Reset bit 0
2DA5 CBCF 01689 SET 1,A ;Set bit 1
2DA7 1804 01690 JR DOOPREG ;Set new assignment
01691 ;
01692 ; DISDOKI - Disable Video & Keyboard
01693 ;
2DA9 F5 01694 DISDOKI PUSH AF
2DAA E5 01695 PUSH HL
01696 ;
2DAB 3E00 01697 SVOPREG LD A,$-$ ;Restore original mask
2DAD 327800 01698 DOOPREG LD (OPREG$),A
2DB0 D384 01699 OUT (@OPREG),A ; and disable video
01700 ;
2DB2 E1 01701 POP HL ;Restore regs & RETurn
2DB3 F1 01702 POP AF
2DB4 C9 01703 RET
01704 ;
01705 ; SWAP38 - Swap 38H - 3AH with save area
01706 ;
2DB5 0603 01707 SWAP38 LD B,3 ;3 bytes to exchange
2DB7 21C72D 01708 LD HL,SWAREA ;HL => Swap Area
2DBA 113800 01709 LD DE,38H ;DE => Restart Xfer addr
2DBD 4E 01710 SWAPLP LD C,(HL) ;P/u source
2DBE 1A 01711 LD A,(DE)
2DBF EB 01712 EX DE,HL ;Swap ptrs
2DC0 71 01713 LD (HL),C ;Stuff in dest
2DC1 12 01714 LD (DE),A
2DC2 23 01715 INC HL ;Bump ptrs
2DC3 13 01716 INC DE
2DC4 10F7 01717 DJNZ SWAPLP ;3 bytes to swap
2DC6 C9 01718 RET
01719 ;
2DC7 C3B02A 01720 SWAREA JP RST38V ;JP vector
01721 ;
01722 ; GETPOS - Get current cursor position in video
01723 ;
2DCA 0604 01724 GETPOS LD B,4 ;P/u current cursor pos
2DCC 01725 @@VDCTL
2DCC+3E0F 01726 LD A,15
2DCE+EF 01727 RST 40
2DCF 4D 01728 GETPOS2 LD C,L ;Save column #
2DD0 6C 01729 LD L,H
2DD1 2600 01730 LD H,0 ;HL => Row #
2DD3 54 01731 LD D,H ;Set DE = HL
2DD4 5D 01732 LD E,L
2DD5 29 01733 ADD HL,HL ;X 2
2DD6 29 01734 ADD HL,HL ;X 4
2DD7 19 01735 ADD HL,DE ;X 5
2DD8 29 01736 ADD HL,HL ;X 10
2DD9 29 01737 ADD HL,HL ;X 20
2DDA 29 01738 ADD HL,HL ;X 40
2DDB 29 01739 ADD HL,HL ;X 80
2DDC 06F8 01740 LD B,VIDEO<-8 ;D = high byte of video
2DDE 09 01741 ADD HL,BC ;HL => Cursor location
2DDF 226627 01742 LD (CURPOS),HL ;Save cursor position
2DE2 C9 01743 RET
01744 ;
01745 ; GETCRS - Calculate row x column cursor pos
01746 ; HL => Cursor position in RAM
01747 ; HL <= Cursor position in Row (H) Column (L)
01748 ;
2DE3 1100F8 01749 GETCRS LD DE,VIDEO ;Get offset
2DE6 B7 01750 OR A
2DE7 ED52 01751 SBC HL,DE
2DE9 0E50 01752 LD C,80 ;Calculate row #
2DEB 01753 @@DIV16
2DEB+3E5E 01754 LD A,94
2DED+EF 01755 RST 40
2DEE 65 01756 LD H,L ;Set H = Row
2DEF 6F 01757 LD L,A ;Set L = Column
2DF0 C9 01758 RET
01759 ;
2DF1 01760 FCB1 DS 32
2E11 01761 FCB2 DS 32
2E31 01762 INBUFF DS 25
01763 ;
2F00 01764 ORG $<-8+1<+8
01765 ;
2F00 01766 IOBUFF DS 256
3000 01767 MEM EQU $
01768 ;
2600 01769 END START
2600 is the transfer address
00000 Total errors
[Copyright 1999,2002 Frank Durda IV, All Rights Reserved. Mirroring of any material on this page in any form is expressly prohibited. The official web site for this material is: http://nemesis.lonestar.org Contact this address for use clearances: clearance at nemesis.lonestar.org Comments and queries to this address: web_software_2011 at nemesis.lonestar.org]