;TAPE100B/ASM - Disk I/O & other routines ; ; DISPSTR - Display String ; DISPSTR PUSH DE ;Save DE LD DE,(CURPOS) ;P/u cursor position DSLP LD A,(HL) ;P/u source char CP ETX ;Done ? JR Z,EXIT1 ;Yes - exit CP CR ;Done ? JR Z,EXIT2 ;Yes - exit CP LF ;Line feed ? JR NZ,STUFCHR ;No - stuff character CALL NEXTLIN ;Get next line JR BUMPIT STUFCHR LD (DE),A ;Output to video INC DE BUMPIT INC HL ;No - bump count JR DSLP EXIT2 CALL NEXTLIN ;Next one down EXIT1 LD (CURPOS),DE ;Save cursor position POP DE ;Restore DE RET ; ; NEXTLIN - Position to next line on video ; DE => RAM location ; NEXTLIN PUSH HL ;Save regs EX DE,HL ;Xfer # to HL CALL GETCRS ;Calculate X,Y INC H ;Bump row # LD L,0 ; and start @ beginning CALL GETPOS2 ;Convert to RAM location EX DE,HL ;Stuff into DE POP HL RET ; ; CONV_UC - Convert A to upper case ; CONV_UC CP 'a' ;Lower case ? RET C ;No CP 'z'+1 ;Lower case ? RET NC ;No RES 5,A ;Convert to Upper Case RET ; ; CURSOFF - Turn off Cursor ; CURSOFF PUSH AF ;Save regs PUSH DE PUSH BC LD C,CUROFF ;Cursor off Character @@DSP JP NZ,IOERR POP BC ;Restore regs POP DE POP AF RET ; ; INIT - Init a file ; INIT LD A,@INIT ;SVC # JR DOSVC ;INIT file ; ; OPEN - Open Source File ; OPEN SET 0,(IY+SFLAG$) ;Inhibit file-open bit LD A,@OPEN ;OPEN SVC # ; DOSVC PUSH AF PUSH DE LD HL,DFBUF ;HL => Disk filename buf TLP LD A,(DE) ;P/u byte from FCB LD (HL),A ;Xfer to TEMBUF INC HL INC DE CP CR+1 ;Done ? JR C,DUN CP ':' JR Z,DUN CP '.' JR NZ,TLP ; ; Found valid terminator - Is this a device ? ; DUN DEC HL ;Back up to term POP DE ;DE => FCB+0 LD A,(DE) ;Device ? CP '*' JR Z,DUN2 ;Yes - done LD (HL),':' ;No - overwrite with ":" INC HL ;Bump LD (DSPEC+1),HL ;Save drivespec location INC HL ;Bump DUN2 LD (HL),ETX ;End with X'03' POP AF ;A = SVC # LD (SVCNUM+1),A ;Save SVC # LD HL,IOBUFF ;HL => I/O Buffer LD B,0 ;LRL = 256 RST 28H ;OPEN or INIT file CHECK JR Z,CHKPROT ;Check PROTection status ; ; Ignore Error #42 - "LRL Open Fault" ; CP 42 ;Ignore this error RET NZ ;NZ - Abort ; ; Stuff Drive # into Buffer ; CHKPROT PUSH DE ;P/u drivespec POP IX ; from FCB+6 LD A,(IX+6) ADD A,'0' ;Convert to ASCII DSPEC LD ($-$),A ; ; Check if File has proper Access ; BIT 7,(IX) ;Is FCB open? JR Z,ILLFILE ;No - Illegal Filename LD A,(IX+1) ;P/u protection byte AND 7 LD B,A ;Xfer to B ; SVCNUM LD A,$-$ ;P/u SVC # CP @INIT ;@INIT ? LD A,B ;P/u protection level JR Z,INIT1 ;Z - Must be < 5 CP 6 ;Read Access ? JR C,OKYDOKY ;Yes - set Z & RETurn ; ; Illegal Access to protected file ; ILLACC @@CLOSE ;Close File LD A,25 ;File Access Denied JP IOERR ;Error - Regardless ; INIT1 CP 5 ;Update Access ? JR NC,ILLACC ;No - Illegal Access OKYDOKY XOR A ;RETurn Z RET ; ILLFILE LD A,19 ;Illegal Filename OR A ;Set NZ RET ; ; ; CLOSE - Close the Destination File ; CLOSE LD DE,FCB2 ;DE => FCB @@CLOSE ;Close File RET Z ;Good - RETurn JP IOERR ;Bad - Quit ; ; WRITESC - Write a Sector to Destination file ; WRITESC LD DE,FCB2 ;DE => FCB @@WRITE ;Write Sector JP NZ,IOERR ;Bad - quit RET ;Good - RETurn ; ; WRTDEST - Write Destination File ; WRTDEST LD DE,FCB2 ;DE => Destination FCB WRTDES LD HL,FCB2+4 ;HL => msb of I/O buffer INC (HL) ;Bump CALL WRITESC ;Write Sector EOTF2 LD A,$-$ ;P/u # of sectors CP (HL) ;Finished ? JR NZ,WRTDES ;No - back to loop ; ; Finished Writing - Set EOF offset byte ; OFFSET LD A,$-$ ;P/u offset byte LD (FCB2+8),A ; & stuff into FCB CALL CLOSE ;Close the File RET ; ; READSRC - Read in chunk of Source Disk file ; READSRC LD HL,FCB1+4 ;HL => Hi byte of I/O buf LD (HL),MEM<-8-1 ;Init FCB I/O buffer ; ; Read in Source file ; READSR2 LD DE,FCB1 ;Pt DE to FCB INC (HL) ;Bump I/O buffer @@READ ;Read a sector JR Z,READSR2 ; ; Fill remainder of sector w/ X'1A's ; PUSH AF ;Save Error code NOMORE LD A,(FCB1+8) ;P/u EOF offset byte NEG LD B,A ;Xfer to B for DJNZ LD H,(HL) ;P/u I/O buffer msb LD L,0FFH ;End of sector JR Z,NULBUF ;Z - keep HL here DEC H ;Sector boundary NULBUF LD (HL),1AH ;Fill remainder of buffer DEC HL ; with zeroes DJNZ NULBUF ; ; Add a sector of 1As ; INC H ;Pt to next sector LD L,0 XTR1AS LD (HL),01AH ;EOF indicator INC HL ;Bump DJNZ XTR1AS DONTFIL POP AF ;Recover error code ; ; I/O Error - Better be EOF error ; CP 1CH ;EOF ? RET Z ;Yes - RETurn CP 1DH ;NRN > ERN RET Z ;Yes - RETurn JP IOERR ;No - Disk Error ; ; ENDOKI - Enable Video & Keyboard ; ENDOKI PUSH AF PUSH HL LD A,(OPREG$) ;P/u port mask LD (SVOPREG+1),A ; and save it for DISDOKI RES 0,A ;Reset bit 0 SET 1,A ;Set bit 1 JR DOOPREG ;Set new assignment ; ; DISDOKI - Disable Video & Keyboard ; DISDOKI PUSH AF PUSH HL ; SVOPREG LD A,$-$ ;Restore original mask DOOPREG LD (OPREG$),A OUT (@OPREG),A ; and disable video ; POP HL ;Restore regs & RETurn POP AF RET ; ; SWAP38 - Swap 38H - 3AH with save area ; SWAP38 LD B,3 ;3 bytes to exchange LD HL,SWAREA ;HL => Swap Area LD DE,38H ;DE => Restart Xfer addr SWAPLP LD C,(HL) ;P/u source LD A,(DE) EX DE,HL ;Swap ptrs LD (HL),C ;Stuff in dest LD (DE),A INC HL ;Bump ptrs INC DE DJNZ SWAPLP ;3 bytes to swap RET ; SWAREA JP RST38V ;JP vector ; ; GETPOS - Get current cursor position in video ; GETPOS LD B,4 ;P/u current cursor pos @@VDCTL GETPOS2 LD C,L ;Save column # LD L,H LD H,0 ;HL => Row # LD D,H ;Set DE = HL LD E,L ADD HL,HL ;X 2 ADD HL,HL ;X 4 ADD HL,DE ;X 5 ADD HL,HL ;X 10 ADD HL,HL ;X 20 ADD HL,HL ;X 40 ADD HL,HL ;X 80 LD B,VIDEO<-8 ;D = high byte of video ADD HL,BC ;HL => Cursor location LD (CURPOS),HL ;Save cursor position RET ; ; GETCRS - Calculate row x column cursor pos ; HL => Cursor position in RAM ; HL <= Cursor position in Row (H) Column (L) ; GETCRS LD DE,VIDEO ;Get offset OR A SBC HL,DE LD C,80 ;Calculate row # @@DIV16 LD H,L ;Set H = Row LD L,A ;Set L = Column RET