opt 7›››*------------------------------*›*The "M:" driver *›*Using memory as a device *›*Includes installation program *›* *›*Written by Bill Wilkinson *›*for January, 1982, COMPUTE! *›*------------------------------*›››*- Converted from MAC to QA by Mikey›››ICAUX1 equ $34A ; The AUX1 byte of IOCB›OPOUT equ 8 ; Mode 8 is OPEN for OU› ; TPUT›MEMLO equ $2E7 ; pointer to bottom of› ; free RAM›MEMTOP equ $2E5 ; pointer to top of free› ; RAM›FR1 equ $E0 ; Fltg Pt Register 1,› ; scratch››STATUSOK equ 1 ; I/O was good›STATEOF equ $88 ; reached an end-of-file››HATABS equ $31A›HIGH equ $100 ; divisor for high byte›LOW equ $FF ; mask for low byte››*-Installation of the driver›› org $3000 *-Change it if you wish››*- This first routine is simply›*- used to connect the driver›*- to Atari's handler address›*- table.››LOADANDGO equ *›› LDX #0 ; We begin at start of table››SEARCHING equ *›› LDA HATABS,X ; Check device name› BEQ EMPTYFOUND ; Found last one› CMP #'M' ; Already have M: ?› BEQ MINSTALLED ; Yes, don't reinstall› INX› INX› INX ; Point to next entry› BNE SEARCHING ; and keep looking› RTS ; Huh? Impossible!!!››*- We found the current end of the›*- table...so extend it.››EMPTYFOUND equ *›› LDA #'M' ; Our device name, "M:"› STA HATABS,X ; is first byte of entry› LDA MDRIVER ; HIGH› STA HATABS+2,X ; and MSB of addr› LDA #0› STA HATABS+3,X ; A new end for the table››*- now change LOMEM so BASIC won't›*- overwrite us.››MINSTALLED equ *›› LDA DRIVERTOP ;HIGH› STA MEMLO+1 ; and MSB therof››*- and that's all we have to do!›› RTS››*- This entry point is provided›*- so that BASIC can reconnect›*- the driver via a USR(RECONNECT)››RECONNECT equ *›› PLA› BEQ LOADANDGO ; No parameters, I hope› TAY››PULLTHEM equ *›› PLA› PLA ; get rid of a parameter› DEY› BNE PULLTHEM ; and pull another› BEQ LOADANDGO ; go reconnect››*- The driver itself›*- Recall that all drivers must›*- be connected to OS through›*- a driver routines address table.››MDRIVER equ *›› dta a(MOPEN-1) ; The addresses must› dta a(MCLOSE-1) ; be given in this› dta a(MGETB-1) ; order and must› dta a(MPUTB-1) ; be one (1) less› dta a(MSTATUS-1) ; than the actual› dta a(MXIO-1) ; address› JMP MINIT ; This is for safety only››*- For many drivers, some of these›*- routines are not needed, and›*- can effectively be null routines›*- A null routine should return›*- a one (1) in the Y-register›*- to indicate success.››MXIO equ *›MINIT equ *›› LDY #1 ; success› RTS››*-If a routine is omitted because›*-it is illegal (reading from a›*-printer, etc.), simply pointing›*-to an RTS is adequate, since›*-Atari OS preloads Y with a›*-'Function Not Implemented' error›*-return code.››*-The driver function routines›*-Now we begin the code for the›*-routines that do the actual›*-work››MOPEN equ *›› LDA ICAUX1,X ; Check type of open› AND #OPOUT ; Open for output?› BEQ OPENFORREAD ; No...assume for input› LDA MEMTOP› STA MSTART ; We start storing› LDY MEMTOP+1 ; ...the bytes› DEY ; ...one page below› STY MSTART+1 ; the supposed top of mem››*- now we join up with mode 4 open››OPENFORREAD equ *›› LDA MSTART ; simply move the› STA MCURRENT ; start pointer› LDA MSTART+1 ; to the current› STA MCURRENT+1 ; pointer, both bytes› LDY #STATUSOK› RTS ; we don't acknowledge failure››MCLOSE equ *›› LDA ICAUX1,X ; check mode of open› AND #OPOUT ; was for output?› BEQ MCLREAD ; no...close input 'file'› LDA MCURRENT ; we establish our› STA MSTOP ; ...limit so that› LDA MCURRENT+1 ; ...next use can't› STA MSTOP+1 ; ...go too far››MCLREAD equ *›› LDY #STATUSOK› RTS ; and guaranteed to be ok›››››*- This routine puts one byte›*- to the memory for later›*- retrieval.››MPUTB equ *›› PHA ; save the byte to be PUT› JSR MOVECURRENT ; get ptr to zero page› PLA ; the byte again› LDY #0› STA (FR1),Y ; put the byte, indirectly› JSR DECCURRENT ; point to nxt byte› RTS ; that's all››*- routine to get a byte put›*- in memory before.››MGETB equ *›› JSR MSTATUS ; any more bytes?› BCS MGETRTS ; no...error› LDY #0› LDA (FR1),Y ; yes...get a byte› JSR DECCURRENT ; and point to next byte››MGETRTS equ *›› RTS››*- check the status of the driver›*- this routine is only valid›*- when READing the 'file'...›*- "M:" never gets errors when›*- writing.››MSTATUS equ *›› JSR MOVECURRENT ; current ptr to zero page› CMP MSTOP ; any more bytes to get?› BNE MSTOK ; yes› CPY MSTOP+1 ; double chk› BNE MSTOK ; yes, again› LDY #STATEOF ; oops...› SEC ; no more bytes› RTS››MSTOK equ *›› LDY #STATUSOK ; all is okay› CLC ; flag for MGETB› RTS››*-Miscellaneous subroutines››*- finally, we have a couple of›*- short and simple routines to›*- manipulate MCURRENT, the ptr›*- to the currently accessed byte›››*- MOVECURRENT simply moves›*- MCURRENT to the floating›*- point register, FR1, in›*- zero page. FR1 is always›*- safe to use except in the›*- middle of an expression.››MOVECURRENT equ *›› LDA MCURRENT› STA FR1 ; notice that we use› LDY MCURRENT+1 ; both the A and› STY FR1+1 ; Y registers...this› RTS ; is for MSTATUS use››*- DECCURRENT simply does a two›*- byte decrement of the MCURRENT›*- pointer and returns with the›*- Y register indicating OK status.›*- NOTE that the A register is›*- left undisturbed.››DECCURRENT equ *›› LDY MCURRENT ; check LSB's value› BNE DECLOW ; if non-zero, MSB is ok› DEC MCURRENT+1 ; if zero, need to bump MSB››DECLOW equ *›› DEC MCURRENT ; now bump the LSB› LDY #STATUSOK ; as promised› RTS››*-RAM usage and clean up››*- END OF CODE››*- Now we define our storage›*- locations.›*- MCURRENT holds the pointer to›*- the next byte to be PUT or GET››MCURRENT dta a(0)››*- MSTOP is set by CLOSE to point›*- to the last byte PUT, so GET›*- won't try to go past the end›*- of data.››MSTOP dta a(0)››*- MSTART is derived from MEMTOP›*- and points to the first byte›*- stored. The bytes are stored›*- in descending addresses until›*- MSTOP is set by CLOSE.››MSTART dta a(0)››*- DRIVERTOP becomes the new›*- contents of MEMLO››DRIVERTOP org *+$FF &$FF00››› org $2E0› dta a(loadandgo)›› end››