; Compiles online at https://www.asm80.com/ ; Hex bytes checked against Byte Mag listing. ; Untested as of 2026-08-27. .CPU 8080 ; ************************************************************* ; INTEL BPK72 BUBBLE MEMORY DRIVER PACKAGE ; Copyright (C) 1983 Louis E. Wheeler ; ************************************************************* ; The subroutines contained in this package provide the user with ; the basic functions needed to communicate with the INTEL BPK-72 ; bubble memory system. Before calling any of these functions ; the user must establish a PARAMETER BLOCK with the following ; Parameters stored in the order shown: ; ; Name (Bytes) Function ; ; BLKLEN (0-1) = Block length. ; The number of 64 or 68 byte pages to be transfered. ; 0 implies a 2048 page transfer. ; ; CANALS (2) = The number of FSA channels. 0 or 1. ; Normally 1, indicating 2 FSA channels. ; ; ENABLE (3) = Defines various modes of operation ; for the 7220 controller. ; ; BEGADR (4-5) = Starting page number (address) ; for a transfer block. ; ; MBMSEL (9) = Bank number of multibank systems. ; Always 0 for single bank systems. ; ; BUFADR (7-8) = Address of user defined buffer. ; Minimum size 64 bytes ; (depends on BLKLEN and ENABLE). ; ; STATUS (9) = Status byte returned after all calls. ; ; ; The first five parameters are defined in the INTEL documentation. ; BUFADR points to a user-supplied buffer with a minimum size of 64 ; bytes. The actual size depends on the block length in pases and ; whether or not automatic error correction has been selected in the ; ENABLE byte. On return, the STATUS byte will contain the last ; BM status input from the BMC. If an error condition existed. ; the C-flag will be set. ; ; FUNCTIONS PROVIDED: ; ; BMINIT - Initializes the bubble memory system ; BMCNTL - Performs nor-data transfer control oferations ; BMREAD - Reads one block (record) from bubble memory ; BMWRIT - Writes one block (record) to bubble memory ; RDFIFO - Reads content of FIFO buffer ; WRFIFO - Writes 42-bytes of data into FIFO buffer ; ; CALLING SEQUENCE: ; ; MVI C.[command] ; Required for non-data transfer ; control operations only. ; LXI H.PARAMBLK ; HL = FWA of the above PARAMETER BLOCK ; CALL [function] ; Any of the above functions ; JC ERROR ; Transfer to user defined error routine ; ************************************************************* ORG 0F623H ; A place to put it. ; ************************************************************* ; ; COMMAND CODES ; CIZ EQU 11H ; INITIALIZE CRD EQU 12H ; READ CWR EQU 13H ; WRITE CAB EQU 19H ; ABORT CFR EQU 1DH ; FIFO RESET CPURG EQU 1EH ; MBM PURGE COMMAND ; ; STATUS WORD BITS ; FIFOBT EQU 01H ; FIFO STATUS OPDONE EQU 40H ; OPERATION COMPLETE BUSYBT EQU 80H ; BUSY BIT ; ; OTHER EQUATES ; REGB EQU 0BH ; FIRST BMC REG TO SET (BLKLEN) PTYMSK EQU 0FDH ; MASK FOR PARITY BIT STATER EQU 3CH ; STATUS WORD ERROR MASK IGNORE PARIТY ; ; I/O PORT ADDRESS ASSIGNMENTS ; BMSTAT EQU 0E1H ; STATUS PORT BMCOMD EQU 0E1H ; COMMAND PORT BMDATA EQU 0E0H ; DATA PORT ; ; ************************************************************* ; ; BMINIT- Initializes the MBM system for operation as specified ; in the PARAMETER BLOCK supplied by the user. ; CALLS: SENDREG, BMEXIT ; BMINIT: CALL SNDREG ; LOAD BMC REGISTERS MVI A,CIZ ; GET INITIALIZE COMMAND OUT BMCOMD ; SEND IT. JMP BMEXIT ; WAIT FOR COMPLETION ; ; ************************************************************* ; ; SNDREG - Formats and sends internal control resisters to the BMC. ; Note: HL must point ot the user suFFlied PARAMETER BLOCK. ; ; CALLS: None ; SNDREG: MVI A, REGB ; GET 1ST REG ADDRESS OUT BMCOMD ; AND SEND IT. ; ; CONSTRUCT AND SEND BLOCK LENGTH. [BLR] ; MOV A,M ; GET BLKLEN (LSB) OUT BMDATA ; SEND IT. (BMC B-REG INX H ; BUMP ADDR MOV B,M ; B=BLKLEN (MSB) INX H MOV A,M ; A=NUM OF FSA CHANNELS RAL ; SHIFT LEFT 4-PLACES RAL RAL RAL ORA B ; MELD WITH BLKLEN (MSB) OUT BMDATA ; SEND IT. (BMC C-REG) ; ; ENABLE BYTE. [ER] ; INX H ; BUMP ADDR MOV A,M ; GET ENABLE BYTE OUT BMDATA ; SEND IT. (BMC D-REG) ; ; CONSTRUCT AND SEND ADDRESS REGISTER. [AR] ; INX H ; BUMP ADDR MOV A,M ; A=ADDR REG (LSB) OUT BMDATA ; SEND IT. (BMC E-REG) INX H MOV B,M ; B=ADDR REG (MSB) InX H MOV A,M ; A=BUBBLE NUMBER RAL RAL ; SHIFT IT 3-PLACES RAL ORA B ; MELD WITH PAGE NUMBER (MSB) OUT BMDATA ; SEND IT. (BMC F-REG) INX H ; BUMP ADDR ; SWAPREG: MOV E,M ; GET USER BUFFER ADDR INX H ; TO DE-REG MOV D,M ; FOR LATER USE. INX H ; BUMP POINTER TO STATUS ADDR. XCHG ; HL=POINTER TO USER BUFFER ; DE=POINTER TO RETURN STATUS RET ; ; ************************************************************* ; ; BMEXIT - Waits for completion of the current BMC operation and ; then checks for any error conditions. ; If an error is indicated, the C-flag is set prior to exiting. ; This routine serves as a common exit for all functions. ; Note: A busy condition that persists too long is considered ; an error. ; This might occur if the parameter block ; is improperly constructed. ; ; CALLS: None BMEXIT: LXI B,0FFFFH ; SET UP TIMER. BMEX1: IN BMSTAT ; GET STATUS ANI PTYMSK ; MASK OUT PARITY ERROR STAX D ; SAVE IT. JP BMEX2 ; NO, GO CHECK FOR ERRORS. DCX B ; ELSE, FOR JUST MOV A,B ; SO MANY ORA C ; TIMES JNZ BMEX1 ; LOOP AND TRY AGAIN. JMP BMERRX ; TOOK TOO LONG IF BC=0 BMEX2: ANI STATER ; WAS THERE AN ERROR? JNZ BMERRX ; YES, TAKE ERROR EXIT. XRA A ; NO, CLEAR FLAG RET ; AND EXIT. BMERRX: MVI A, CAB ; CLEAR THE WRECKAGE OUT BMCOMD ; BY ABORTING MVI A, CPURG ; AND PURGING OUT BMCOMD ; EVERYTHING. STC ; SET CARRY FLAG RET ; AND EXIT. ; ; ************************************************************* ; ; BMCNTL - Facilitates direct user control of the MBM system thr oush ; command operations. No data is transferred. The rout.ine ; expects to find the COMMAND CODE in the C resister. ;CALLS: SNDREG, BMEXIT ; BMCHTL: CALL SNDREG ; LOAD BMC REGISTERS MOV A,C ; GET COMMAND OUT BMCOMD ; INITIATE IT. JMP BMEXIT ; WAIT TILL DONE ; ; ************************************************************* ; ; BMREAD- Reads one record as specified in the PARAMETER BLOCK. ; Note: Failure to provide sufficient butfer area car ; prove disastrous. ; ; CALLS: SHDREG, BMEXIT BMREAD: MVI A,CFR ; RESET FIFO OUT BMCOMD CALL SNDREG ; SEND REGISTERS TO BMC MVI A,CRD ; INITIATE READ OUT BMCOMD ; OPERATION. BMRD1: IN BMSTAT ; GET STATUS ORA A ; WAIT FOR BUSY JP BMRD1 ; LOOP UNTIL SET. BMRD2: IN BMSTAT ; GET STATUS ORA A ; BUSY? JP BMEXIT ; NO, ALL DONE. ANI FIFOBT ; FIFO EMРТУ? JZ BMRD2 ; YES, GO CK BUSY IN BMDATA ; NO, GET THE DATA MOV M,A ; STORE IT INX H ; BUMP STORE ADDR JMP BMRD2 ; AND LOOP FOR MORE. ; ; ************************************************************* ; ; BMWRIT- Writes one record to the BM. ; ; Note: records shorter ; than the block size specified in the PARAMETER BLOCK ; should be padded with a suitable character, else this ; record will be filled out with whatever is available. ; ; CALLS: SNDREG, BMEXIT. BMERRX ; BMWRIT: MVI A,CFR ; GET FIFO RESЕТ OUT BMCOMD ; SEND IT. CALL SNDREG ; SEND REGS MVI A,CWR ; GET WRITE COMMAND OUT BMCOMD ; SEND IT. BMWR1: IN BMSTAT ; GET STATUS ANI BUSYBT+FIFOBT ; WAIT FOR BUSY CPI BUSYBT+FIFOBT ; AND FIFO BITS. JNZ BMWR1 ; LOOP UNTIL... ; BMWR2: IN BMSTAT ; GET STATUS ANI PTYMSK ; MASK OUT PTY ERR STAX D ; SAVE IN E-REG JP BMWR3 ; OP COMPLETE/FAILED? ANI FIFOBT ; FIFO READY? JZ BMWR2 ; NOPE, LOOP TRY AGAIN. MOV A,M ; YES LOAD SOME DATA OUT BMDATA ; GIVE IT TO BMC INX H ; BUMP ADDR JMP BMWR2 ; AND LOOP FOR MORE. BMWR3: LDAX D ; GET STATUS CPI OPDONE+FIFOBT ; ALL DONE AND GOOD? JZ BMEXIT ; NORMAL EXIT. JMP BMERRX ; ERROR EXIT ; ; ************************************************************* ; ; RDFIFO- Reads the contents of the FIFO butfer. ; CALLS: SWAPREG, BMEXIT ; RDFIFO: LXI D,0007H ; POSITION PARAMBLK PNTR DAD D ; TO USER BUFFER ADDR. ; CALL SWAPREG ; SET UP HL/DE POINTERS. RDFIFO2: IN BMSTAT ; GET STATUS ANI FIFOBT ; ANY DATA THERE ; JZ BMEXIT ; NO. EXIT. IN BMDATA ; YES, GET DATA MOV M,A ; STORE IT INX H ; BUMP STORE ADDR JMP RDFIFO2 ; LOOP FOR MORE. ; ; ************************************************************* ; ; WRFIFO - Sends 42 bytes to the FIFO buffer. ; CALLS: SNDREG, BMEXIT ; WRFIFO: CALL SNDREG ; SEND REGS MVI C,42 ; SET COUNT FOR 42 BYTES WRFIFO2: MOV A,M ; GET SOME DATA OUT BMDATA ; SEND IT INX H ; BUMP LOAD ADDR DCR C ; COUNT IT AND JNZ WRFIFO2 ; LOOP IF NOT DONE. JMP BMEXIT ; EXIT.