.TITLE CBIOS .IDENT /CBIOS V1.2/ .PSECT CBIOS,REL,LONG ; THE IN INSTRUCTION BRANCHES TO ONE OF THESE GOODIES DEP ON NEXT BYTE ; CPM IS THE MAIN ENTRY POINT FOR WHOLE SHEBANG $RMSDEF ; symbols for RMS $SECDEF ; symbols for global sections ; TTCHAN:: .WORD 0 ; OUTBUF_SIZE==135 PRINT_POS::.LONG OUTBUF ; current print position on console line LOAD_POS::.LONG OUTBUF ; current end position of cnsole line OUTBUF::.BLKB OUTBUF_SIZE ; current console line. ; OUT_INST::.WORD 0 BPT RET ; IN_INST::.WORD 0 CASEB 4(AP),#1,#17 10$: .WORD BOOT-10$,WBOOT-10$,CONST-10$,CONIN-10$,CONOUT-10$,LIST-10$ .WORD PUNCH-10$,READER-10$,HOME-10$,SELDSK-10$,SETTRK-10$ .WORD SETSEC-10$,SETDMA-10$,READ-10$,WRITE-10$,LISTST-10$,SECTRAN-10$ BPT RET CALLBOOT::.WORD 0 BOOT:: ;CP/M BOOT CLRW @#3 ; IOBYTE AND DISK SELECT GOCPM:: MOVB #^XC3,@#0 MOVW #,@#1 ; SET UP WARM BOOT MOVB #^XC3,@#5 ; JMP INST MOVW #BDOS,@#6 MOVZWL #^X80,DMAADR ; DEFAULT DMA MOVB @#4,REG_C ; CURRENT DISK - CANT USE C(R4) MOVW #CCP,REG_PC RET ; WBOOT:: ;WARM BOOT MOVW #^X80,R6 ; SET STACK ADDL3 #128,DISK_A,R1 MOVC3 #,(R1),@#CCP ; READ CPM BRB GOCPM ; CONSOLE_STATUS::.BYTE 0 ; current console status. CONSOLE_CHAR:: .BYTE 0 ; CHAR FROM TT CONST:: SUBL3 PRINT_POS,LOAD_POS,R1 BLEQ 20$ $QIOW_S CHAN=TTCHAN,FUNC=#IO$_WRITELBLK!IO$M_NOFORMAT,P1=@PRINT_POS,P2=R1 MOVL LOAD_POS,PRINT_POS 20$: MOVB CONSOLE_STATUS,REG_A RET ; CONIN:: SUBL3 PRINT_POS,LOAD_POS,R1 BLEQ 20$ $QIOW_S CHAN=TTCHAN,FUNC=#IO$_WRITELBLK!IO$M_NOFORMAT,P1=@PRINT_POS,P2=R1 MOVL LOAD_POS,PRINT_POS 20$: $WAITFR_S EFN=#1 ; wait for a character BICB3 #128,CONSOLE_CHAR,REG_A ; get character from buffer before read. MOVL #OUTBUF,PRINT_POS ; reprint line if interupted. CMPB #25,REG_A ; character a ctrl Y? BNEQ 15$ ; no, just return it. CALLS #0,CTRLY ; call ctrl Y routine before redoing read. CALLS #0,CONSOLE_READ ; set up another read BRB CONIN ; ignore ctrl Y 15$: CALLS #0,CONSOLE_READ ; set up another read MOVL LOAD_POS,PRINT_POS ; update print position RET ; CONSOLE_READ:: .WORD 0 CLRB CONSOLE_STATUS ; initialise console read. $QIO_S CHAN=TTCHAN,FUNC=#IO$_TTYREADALL!IO$M_NOECHO!IO$M_REFRESH,- EFN=#1,ASTADR=CONSOLE_AST,- P1=CONSOLE_CHAR,P2=#1 RET ; CONSOLE_AST:: .WORD 0 MOVB #^XFF,CONSOLE_STATUS ; set up console status. RET ; CONSOLE_CANCEL:: .WORD 0 $CANCEL_S CHAN=TTCHAN ; turn off console input. RET ; CONOUT:: MOVB REG_C,@LOAD_POS ; store character in print line INCL LOAD_POS ; update load position. CMPB REG_C,#^XD ; end of line? BEQL 10$ ; yes! CMPL LOAD_POS,#OUTBUF+OUTBUF_SIZE-1 ;buffer full? BLSSU 20$ 10$: SUBL3 PRINT_POS,LOAD_POS,R1 ; print the line $QIOW_S CHAN=TTCHAN,FUNC=#IO$_WRITELBLK!IO$M_NOFORMAT,P1=@PRINT_POS,P2=R1 MOVL #OUTBUF,LOAD_POS ; reset load position MOVL #OUTBUF,PRINT_POS ; reset print position 20$: RET ; ; ; LISTST:: CLRB REG_A RET ; LIST:: PUSHAB REG_C CALLS #1,LISTCH RET ; PUNCH:: PUSHAB REG_C CALLS #1,PUNCHCH RET ; READER:: CALLS #0,READERCH MOVB R0,REG_A RET ; DISK_CHAN:.BLKW 16 DISK_A:: VIRT_DISK:.BLKQ 16 DISK_FLAGS:.BLKB 16 WR_LOCK = 1 DISKNO: .LONG 0 TRACK: .LONG 0 SECT: .LONG 0 DMAADR: .LONG 0 ; .ALIGN LONG CPMFAB:: $FAB FNM=,ALQ=508,FAC=PUT,FOP= ; MAP_DISK::.WORD ^M $SETSFM_S #0 $CREATE FAB=CPMFAB BLBS R0,10$ CALLS #0,NOTFND BRB 20$ 10$: MOVL 4(AP),R2 MOVL R0,R7 ;REMEMBER STATUS. MOVW CPMFAB+FAB$L_STV,DISK_CHAN[R2] ;REMEMBER CHANNEL. MOVAQ VIRT_DISK[R2],R3 ;SPOT FOR SECT ADDRESSES. $CRMPSC_S INADR=(R3),RETADR=(R3),PAGCNT=#508,- FLAGS=#SEC$M_WRT!SEC$M_EXPREG,CHAN=CPMFAB+FAB$L_STV CMPL R7,#RMS$_CREATED ;NEW DISC? BNEQ 20$ ;NO. SUBL3 (R3),4(R3),R6 MOVC5 #0,.,#^XE5,R6,@(R3) ;INIT DISC WITH E5'S. 20$: $SETSFM_S #1 RET ; REM_DISK::.WORD ^M MOVL 4(AP),R2 MOVAQ VIRT_DISK[R2],R1 BISL3 (R1),4(R1),R0 BEQL 10$ $DELTVA_S INADR=(R1) CLRQ VIRT_DISK[R2] $DASSGN_S CHAN=DISK_CHAN[R2] 10$: RET LOCK_DISK::.WORD 0 MOVL 4(AP),R0 BISB2 #WR_LOCK,DISK_FLAGS[R0] RET ; UNLOCK_DISK::.WORD 0 MOVL 4(AP),R0 BICB2 #WR_LOCK,DISK_FLAGS[R0] RET ; HOME:: CLRL TRACK RET ; SELDSK:: MOVZBL REG_C,DISKNO ASHL #4,DISKNO,R0 MOVAB L^DPBASE(R0),R4 MOVW R4,REG_HL RET ; SETTRK:: MOVZBL REG_C,TRACK RET ; SETSEC:: MOVZBL REG_C,SECT RET ; SECTRAN:: MOVZWL REG_BC,R0 MOVZWL REG_DE,R1 MOVZBW (R1)[R0],REG_HL RET ; SETDMA:: MOVZWL REG_BC,DMAADR RET ; READ:: JSB B^SETUPIO MOVC3 #128,-128(R1),@DMAADR RET ; WRITE:: MOVL DISKNO,R1 BITB #WR_LOCK,DISK_FLAGS[R1] BEQL 10$ MOVB #1,REG_A RET 10$: JSB B^SETUPIO MOVC3 #128,@DMAADR,-128(R1) RET ; SETUPIO:: MOVL DISKNO,R1 MOVQ VIRT_DISK[R1],R2 BNEQ 10$ PUSHAL DISKNO CALLS #1,ASKDISK MOVL DISKNO,R1 MOVQ VIRT_DISK[R1],R2 10$: CLRB REG_A MULL3 #<26*128>,TRACK,R0 ; ??? MULL3 #128,SECT,R1 ;??? ADDL2 R0,R1 ADDL2 R2,R1 CMPL R1,R3 BGTRU 20$ CLRB REG_A RSB 20$: MOVB #1,REG_A RET ; BOB's funny fellow return. ; ; TTDESC: .ASCID /TT/ ; PROM_BOOT::.WORD 0 ; SIMULATE CPM PROM BOOT UP ADDL3 #128,DISK_A,R1 MOVC3 #,(R1),@#CCP CALLS #0,CALLBOOT $ASSIGN_S CHAN=TTCHAN,DEVNAM=TTDESC CALLS #0,CONSOLE_READ BRW BEGIN ; BRANCH TO LOOP FOREVER ; ; ; .TITLE VBIOS .IDENT /VBIOS V1.2/ .PSECT VBIOS,REL,LONG CCP == ^XE400 BDOS == ^XEC06 BIOS == ^XFA00 BIOSEND == ^XFB8F DPBASE == ^XFA66 .END