home *** CD-ROM | disk | FTP | other *** search
-
- TITLE 'BDOS-BIOS EMULATOR for V20 on IBM PC'
- PAGE 60
- ; this is bdos minus the disk calls, which are passed on to msdos
-
- ; philosophy
-
- ; handle character calls in 8080 mode so that
- ; can do submit and EX files
- ; line editing and ^S , ^C handling are easier this way
-
- ; the character i/o calls are off to the BIOS
- ; eventually anyway
-
- ; bdos disk calls passed off directly to 8086 MSDOS
- ; add selected higher calls to support
- ; time, date, make dir, change dir calls
- ; can be done in Turbo bdos-handler
-
- VER equ 2
- REV equ 2
-
- BDOSHANDLE equ 0c2h; 8086 interrupt numbers to get to 8086 mode
- BIOSHANDLE equ 0c3h; 80,81h used by other end to get here
-
- ; V20 macros ( used only once )
-
- CALLN macro x ; call 8088 routine at int x
- db 11101101b,11101101b ;
- db (x and 0ffh) ;
- endm
-
- RETEM macro
- db 0edh,0fdh
- endm
-
- BOOTV equ 0000H; Vector to BIOS warm boot routine
- IOBYTE equ 0003H; System I/O device assignment
- TBUFF equ 0080H; Default DMA buffer location
-
- FALSE equ 0
- TRUE equ 1
-
- CR equ 0DH
- LF equ 0AH
- TAB equ 09H ; Tab
- BACKSP equ 08H ; Backspace
- CTRLC equ 03H ; Control-C
- CTRLE EQU 05H ; Control-E
- CTRLP EQU 10H ; Control-P
- CTRLR EQU 12H ; Control-R
- CTRLS EQU 13H ; Control-S
- CTRLU EQU 15H ; Control-U
- CTRLX EQU 18H ; Control-X
- DELDAT EQU 0E5H ; Deleted data byte
-
- ORG 0FA00H ; CSEG ; DOSLOC
-
- SERIAL: DB 0,0,0 ; Room for serial number
- DB 0,0,0
-
- ENTRY: JMP BDOS ; Entry to disk monitor ; serial + 6
-
- ;****
- ;Put bdos dpb and allocation vector here so can be found easily.
- ; these are doctored up by the Turbo Bdos-handler
-
- DATASTART EQU $
- BDOSDPB: ;serial + 9
- DS 16 ;
- BDOSALLOC: ;serial + 25
- DS 256
- CTEMP1: DB 0 ; temp used for console input buffer
- CTEMP2: DB 0 ; temp count holder for buffer
- COLUMN: DB 0 ; column pointer for buffer
- LSTCPY: DB 0 ; list copy toggle byte
- CHRRDY: DB 0 ; char waiting flag
- OLDSP: DB 0,0 ; Caller's Stack ptr
- DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- DB 0,0,0,0,0,0,0,0 ; 48 bytes (room for stack)
- USRCOD: DB 0 ; user and disk code lives here
- CURDSK: DB 0 ; current disk holder
- FCB: DW 0 ; Storage for caller's parms
- ODATA: DW 0 ; return information storage
- IDATA: DB 0
- OUT1: DB 0
- OLDDSK: DB 0
- OUTDSK: DB 0
- DATAEND equ $
- ds 4 ; buffer area in case miscounted
-
-
- ;****
- ;bdos entry point. data enters as follows:
- ; C = command
- ; DE = address or 16 bit data word
- ; E = 8 bit data word
-
- ; return from bdos data is as follows:
- ; A = status or value
- ; HL = 16 bit value or address
-
-
- ;****
- ;bdos entry saves input data as follows:
-
- ; DE -> FCB 0 -> OLDDSK
- ; E -> IDATA 0 -> OUT1
- ; 0 -> ODATA sets return to BEXIT on stack
- ; SP -> OLDSP
-
- ; saves input data and jumps to command routine
-
- ; DESTROYS A AND HL RIGHT AWAY
-
- BDOS: LDA 0FFFFH; -1 ; test for exit
- ORA A
- JNZ BREAKOUT ; in BIOS area do a RETEM
-
- BEGIN:
- XCHG ; mov de to fcb and bdde
- SHLD BDDE
- SHLD FCB
- XCHG
- LXI H,BDBC
- mov m,c ;
- LXI h,0 ; zero hl
- SHLD ODATA ; save this for the return
- DAD SP ; add in the user stack pointer
- SHLD OLDSP ; save this for the return also
- LXI SP,USRCOD ; point to BDOS stack { use private stack }
- MOV A,E ; move data byte into A
- STA IDATA ; save it
- XRA A ; zero out a
- STA OLDDSK ; save this as the old disk
- STA OUT1 ; and at OUT1 for disk relog on exit
- LXI H,BEXIT ;Bexit ; get the return point address
- PUSH H ; and stuff it on the stack for exiting
- MOV A,C ; move the command into A
- STA BDPSW ; put it into registers at the end
- CPI 13 ; Max Char cmds +1 - is it too big?
- JNC MSDOSHANDLER ; return if so
- MOV C,E ; get input data from E into C
- LXI H,CMMNDS ; point to the dispatch table
- MOV E,A ; move the command from A into E
- MVI D,0 ; zero out D
- DAD D ; add in the dispatch table
- DAD D ; once more - over two bytes
- MOV E,M ; pull the jump address
- INX H ; into
- MOV D,M ; DE
- LHLD FCB ; get the info word into HL
- XCHG ; swap DE and HL
- PCHL ; jump to the command routine
-
- ;****
- ; command dispatch table
-
- CMMNDS: DW WBOOTF ; 0: System reset
- DW REDCON ; 1: Console input
- DW WRTCON ; 2: Console output
- DW REDRDR ; 3: Reader input
- DW PUNF ; 4: Punch output
- DW LISTF ; 5: List output
- DW DIRTIO ; 6: Direct console I/O
- DW GETIOB ; 7: Get I/O Byte
- DW PUTIOB ; 8: Set I/O Byte
- DW PRNBUF ; 9: Print string
- DW REDBUF ; 10: Read console buffer
- DW GCSTAT ; 11: Get console status
- DW GETVER ; 12: Get version number ( 2.2 )
-
- ;****
- ; Read next console character
-
- CONIN: LXI H,CHRRDY ; Point to the char ready flag
- MOV A,M ; move the ready byte into A
- MVI M,0 ; and zero out the flag
- ORA A ; was anyone home
- RNZ ; return if not
- JMP CONIF ; otherwise go get the thing
-
- ;****
- ; Read console character, echo print if it is ok
-
- CIECHO: CALL CONIN ; get a character
- CALL GRAFIC ; check the control characters
- RC ; return if the char is not printable
- PUSH PSW ; otherwise save it
- MOV C,A ; put a copy into C
- CALL WRTCON ; and print it out
- POP PSW ; restore it
- RET ; and return to sender
-
- ;****
- ;see if A is a good control char, ret with CY set if not
-
- GRAFIC: CPI CR ; test for carriage return
- RZ ; return if it was
- CPI LF ; how about line feed
- RZ ; that is ok
- CPI TAB ; as is tab
- RZ ; so back with it
- CPI BACKSP ; Backspace in 2.0
- RZ ; is known
- CPI ' ' ; test all other control characters
- RET ; and go back with carry set for no echo
-
- ;****
- ; Check for console break and abort
-
- CONBRK: LDA CHRRDY ; get the character ready byte
- ORA A ; and check for waiting char
- JNZ CB1 ; non zero says something is there
- CALL CONSF ; check the console if none there
- ANI 01H ; and in the status bit
- RZ ; return if it came up zero
- CALL CONIF ; otherwise go get the waiting char
- CPI CTRLS ; was it a control-s
- JNZ CB0 ; if not return with ready flag set
- CALL CONIF ; if it was wait for the next char
- CPI CTRLC ; is this one control c?
- JZ BOOTV ; if so we reboot
- XRA A ; or else zero a
- RET ; and simply return
-
- CB0: STA CHRRDY ; Save input char
- CB1: MVI A,TRUE ; and say true to the caller
- RET ; and go back
-
- ;****
- ; Output char in C to console, list also if LSTCPY = true
-
- CONOUT: LDA CTEMP1 ; get the first temp column counter
- ORA A ; is it zero?
- JNZ CONOU1 ; if nonzero jump over
- PUSH B ; otherwise save input character
- CALL CONBRK ; Check for abort
- POP B ; recover the char
- PUSH B ; save it again
- CALL CONOF ; and print the character on the console
- POP B ; recover once more
- PUSH B ; would you believe save it again
- LDA LSTCPY ; get the list flag byte
- ORA A ; to set flags
- CNZ LISTF ; and to list if LSTCPY=true
- POP B ; restore char one last time
- CONOU1: MOV A,C ; put the byte into A
- LXI H,COLUMN ; point to the buffer column counter
- CPI 7FH ; Rubout ?
- RZ ; return if so
- INR M ; Increment column
- CPI ' ' ; is the character a space?
- RNC ; return if less - must be control
- DCR M ; Decrement column
- MOV A,M ; and get the character there
- ORA A ; check for a null
- RZ ; return if it is
- MOV A,C ; move the char into C
- CPI BACKSP ; was it a backspace?
- JNZ CONOU2 ; if not jump over
- DCR M ; Decrement column
- RET ; and return
-
- CONOU2: CPI LF ; was it a linefeed?
- RNZ ; return if not again
- MVI M,0 ; Set column to 0
- RET ; and return
-
- ;****
- ; Print char in C at console, convert Ctrl chars to ^[char]
-
- CTLOUT: MOV A,C ; move the char into A
- CALL GRAFIC ; see if it is printable
- JNC WRTCON ; jump past cause it is ok
- PUSH PSW ; otherwise save ctrl char on the stack
- MVI C,5EH ; get the "^" char
- CALL CONOUT ; and print it
- POP PSW ; get the char back
- ORI 40H ; add in the bias to make it print
- MOV C,A ; put it into C for the next
-
- ;****
- ; BDOS function 2: write to the system console char in C
-
- WRTCON: MOV A,C ; which puts it into A
- CPI TAB ; check for tab
- JNZ CONOUT ; if not jump and print
- TABOUT: MVI C,' ' ; Space gets printed to expand tabs
- CALL CONOUT ; to
- LDA COLUMN ; next
- ANI 07H ; tab
- JNZ TABOUT ; stop
- RET ; Return
-
- DELAST: CALL BACKUP ; back up one character
- MVI C,' ' ; then get a blank
- CALL CONOF ; and print it out
- BACKUP: MVI C,BACKSP ; get a backspace
- JMP CONOF ; and print it as well to move into spot
-
- ;****
- ; Print pound sign, CRLF, and fix columns
-
- LBCRLF: MVI C,'#' ; get a pound sign
- CALL CONOUT ; and print it
- CALL CRLF ; Turn up a new line
- LB1: LDA COLUMN ; get the column counter
- LXI H,CTEMP2 ; point to the temp counter
- CMP M ; are they equal?
- RNC ; not there yet
- MVI C,' ' ; so get a space
- CALL CONOUT ; and print it out
- JMP LB1 ; loop til the counts are the same
-
- ;****
- ; Print CR/LF at console
-
- CRLF: MVI C,CR ; get a cr
- CALL CONOUT ; and print it out
- MVI C,LF ; followed by a lf
- JMP CONOUT ; which goes out too
-
- ;****
- ; Print string at (BC) until '$' with TAB expansion
-
- PRINT: LDAX B ; get the byte at (BC)
- CPI '$' ; is it the end mark?
- RZ ; if so we are done
- INX B ; otherwise bump the pointer
- PUSH B ; and save it in the stack
- MOV C,A ; get the character into C
- CALL WRTCON ; write it out expanding tabs
- POP B ; recover the pointer
- JMP PRINT ; and loop til we hit the stop
-
- ;****
- ; BDOS function 10: Read console buffer at
- ; enter with BC -> console buffer address
-
- REDBUF: LDA COLUMN ; get the column counter into A
- STA CTEMP2 ; save it at CTEMP2
- LHLD FCB ; get the information into HL
- MOV C,M ; get the buffer count byte
- INX H ; and bump the pointer to the next spot
- PUSH H ; save it for later
- MVI B,0 ; zero B
- RB0: PUSH B ; save BC for later
- PUSH H ; and HL as well
- RB1: CALL CONIN ; go get a char from the console
- ANI 7FH ; strip the parity bit
- POP H ; recover HL
- POP B ; and BC
- CPI CR ; is this character a CR?
- JZ RBEXIT ; if so jump over
- CPI LF ; how about a LF
- JZ RBEXIT ; jump with that as well
- CPI BACKSP ; do we have a backspace?
- JNZ CHKRUB ; if not over we go
- MOV A,B ; put B into A
- ORA A ; is it still zero?
- JZ RB0 ; if so go get another character
- DCR B ; if not decrement the count in B
- LDA COLUMN ; get the column counter
- STA CTEMP1 ; save it at CTEMP1 for later
- JMP RB65 ; jump over
-
- ; Check for Rubout (remove & echo last char.)
-
- CHKRUB: CPI 7FH ; do we have a rubout?
- JNZ CHKEOL ; if not jump over
- MOV A,B ; if so move b into A
- ORA A ; set the flags
- JZ RB0 ; if b was zero go get another
- MOV A,M ; get the char at (ODATA)
- DCR B ; decrement the count in B
- DCX H ; point back to FCB
- JMP RB10 ; jump to echo the char
-
- ; Check for Control-E (physical end-of-line)
-
- CHKEOL: CPI CTRLE ; is it end of line?
- JNZ CKPTOG ; jump over if not
- PUSH B ; if so save BC
- PUSH H ; and FCB address
- CALL CRLF ; Turn up a new line
- XRA A ; zero A
- STA CTEMP2 ; set it into CTEMP2
- JMP RB1 ; and go get more
-
- ; Check for Control-P
-
- CKPTOG: CPI CTRLP ; is it the print toggle
- JNZ CKBOL ; if not jump past
- PUSH H ; if so save FCB address
- LXI H,LSTCPY ; get the pointer to print toggle byte
- MVI A,01H ; put a 1 into A
- SUB M ; subtract it from the toggle
- MOV M,A ; and put it back
- POP H ; recover FCB
- JMP RB0 ; and go get more
-
- ; Check for Control-X (bacK space to beg. current line)
-
- CKBOL: CPI CTRLX ; do we back up?
- JNZ CKREML ; if not on to the next choice
- POP H ; if so restore the stack pointer
- BLOOP: LDA CTEMP2 ; get the byte at CTEMP2
- LXI H,COLUMN ; and point to the column counter
- CMP M ; are they the same?
- JNC REDBUF ; if so go try again for input
- DCR M ; if not decrement the CTEMP2 count
- CALL DELAST ; delete the character there
- JMP BLOOP ; and loop until we are done
-
- ; check for control-U
-
- CKREML: CPI CTRLU ; do we remove the line after newline?
- JNZ CKRETL ; if not try again
- CALL LBCRLF ; if so print a "#" and CR
- POP H ; restore the stack
- JMP REDBUF ; and try for input again
-
- ; Check for Control-R (retype current line after new line)
-
- CKRETL: CPI CTRLR ; want to retype?
- JNZ ECHOCC ; if not onward for next
- RB65: PUSH B ; if so save the count in B
- CALL LBCRLF ; print a "#" and CRLF
- POP B ; recover ODATA
- POP H ; and FCB
- PUSH H ; saving FCB again
- PUSH B ; and ODATA
- RB7: MOV A,B ; move the count into
- ORA A ; see if it is zero
- JZ FIXCOL ; if so jump over
- INX H ; if not point to ODATA
- MOV C,M ; pull the byte there into C
- DCR B ; decrement the count
- PUSH B ; save it on the stack
- PUSH H ; and the ODATA pointer
- CALL CTLOUT ; print it out expanding control chars
- POP H ; recover the ODATA pointer
- POP B ; and the count in B
- JMP RB7 ; loop until the line is out
-
- ;fix up the column counters
-
- FIXCOL: PUSH H ; save the pointer
- LDA CTEMP1 ; get CTEMP1
- ORA A ; set the flags
- JZ RB1 ; if zero go get the next character
- LXI H,COLUMN ; point to the column counter
- SUB M ; subtract it from the value of CTEMP1
- STA CTEMP1 ; and save this back in CTEMP1
- FXLOOP: CALL DELAST ; delete the last character
- LXI H,CTEMP1 ; point to CTEMP1
- DCR M ; decrement it by one
- JNZ FXLOOP ; loop to delete all of them
- JMP RB1 ; go get the next character
-
- ;echo the control character
-
- ECHOCC: INX H ; must be some other control character
- MOV M,A ; put the character into ODATA+1
- INR B ; bump the count by one
- RB10: PUSH B ; save it on the stack
- PUSH H ; and the pointer as well
- MOV C,A ; put the character into C
- CALL CTLOUT ; print it out with grafic control chars
- POP H ; recover the pointer
- POP B ; and the count
- MOV A,M ; put the byte at (HL) into A
- CPI CTRLC ; is it an abort?
- MOV A,B ; put the count into A
- JNZ RB11 ; if no abort jump over
- CPI 01H ; is the count 1?
- JZ BOOTV ; if so boot
- RB11: CMP C ; if not does it equal C
- JC RB0 ; if less go get another char
- RBEXIT: POP H ; recover the pointer
- MOV M,B ; put the count in b there
- MVI C,CR ; get a CR
- JMP CONOUT ; and print it out
-
- ;****
- ;BDOS function 1: Read console - return with byte in A
-
- REDCON: CALL CIECHO ; get a char echo if printable
- JMP GOBAK ; and go back with it
-
- ;****
- ; BDOS function 3: Read reader - return with byte in A
-
- REDRDR: CALL READF ; get byte from reader
- JMP GOBAK ; and return with it
-
- ;****
- ; BDOS function 6: Direct I/O
- ; on entry, C=FF for input, C=char for output
- ; (Book says E reg vice C)
- ; appears can enter with FE or FF --- ????
-
- ; return with char or status in A
-
- DIRTIO: MOV A,C ; Get request
- INR A ; Test for FF=input request
- JZ INREQ ; Skip down if input request
- INR A ; if FF adding one will set zero flag
- JZ CONSF ; if it was go get console status
- JMP CONOF ; otherwise go send it out
-
- INREQ: CALL CONSF ; get console status
- ORA A ; set flags
- JZ REXIT ; return if none - restore first
- CALL CONIF ; if someone is there go get it
- JMP GOBAK ; and return with it
-
- ;****
- ; BDOS function 7: get IO byte into A
-
- GETIOB: LDA IOBYTE ; get the iobyte
- JMP GOBAK ; and go back with it
-
- ;****
- ; BDOS function 8: set IO byte from C into place
-
- PUTIOB: LXI H,IOBYTE ; point to the iobyte
- MOV M,C ; put the new value in from C
- RET ; and return
-
- ;****
- ; BDOS function 9: Print console buffer until '$'
- ; entry string address in DE
-
- PRNBUF: XCHG ; swap DE and HL - HL points to buffer
- MOV C,L ; and get a copy
- MOV B,H ; of HL into BC
- JMP PRINT ; go to the print routine
-
- ;****
- ; BDOS function 11: check console status - return in A
-
- GCSTAT: CALL CONBRK ; Check for abort
- GOBAK: STA ODATA ; save result in return info byte
- JR: RET ; and go back to caller
-
- JR1: MVI A,01H ; get a 1 for return
- JMP GOBAK ; set it in to rinfo and return
-
- ;****
- ; BDOS function 12: return version number
-
- GETVER:
- MVI A,22H
- JMP GOBAK
-
- ;****
- ; bdos exit routine
-
- BEXIT: LDA OUT1 ; get the out flag for drive reset
- ORA A ; set the flags
- JZ REXIT ; if zero we may exit as is
- LHLD FCB ; otherwise get the FCB address
- MVI M,0 ; put a zero into drive select byte
- LDA OLDDSK ; get the old disk out
- ORA A ; was it zero
- JZ REXIT ; if so exit
- MOV M,A ; otherwise set in the old disk byte
- LDA OUTDSK ; get the disk to relog
- STA IDATA ; save it for the login
- CALL LOGIN ; go log in the old disk
-
- REXIT: LHLD OLDSP ; get the old stack pointer out
- SPHL ; put it back in place
- LHLD ODATA ; get the output data into place
- MOV A,L ; put L into A
- MOV B,H ; and H into B
- RET ; then return from BDOS happy
- ;****
- ; hand off all higher calls to 8086 handler
- ;
- MSDOSHANDLER:
- lhld fcb ; recover de
- mov d,h
- mov e,l
- mov c,a ; put call back
- calln bdoshandle ; special v20 call
- BDOSCALL EQU $-1
- lhld bdhl ; get return
- shld odata ; should return in hl and a
- jmp Bexit
- LOGIN:
- lxi h,bdbc
- mvi m,0eh ; select the disk in a
- lxi h,bdpsw
- mov m,a
- CALLN BDOSHANDLE
- LOGCALL EQU $-1
- ret
-
- ; put data at the rear
- ;****
- ; console input buffer data storage area
-
-
- ; move part of bios here
-
- COLDBOOT: ; should load addresses in lower memory
- jmp0:
- ; MOVE INTERRUPT LOCATIONS INTO PLACE
- ; FOR BDOS AND BIOS
- LDA BIOSHAN
- STA CMMNCALL ; COMMON BIOS CALL HANDLER
- STA WMNCALL ; WARMBOOT CALL HANDLER
- LDA BDOSHAN
- STA LOGCALL
- STA BDOSCALL ; AND DO WARM BOOT
-
- jmp1: ; warm boot
- ; zero out data areas in bdos also
- lxi h,datastart
- lxi b,dataend-datastart
- luuu:
- mov a,b
- ora c
- jz doneit
- xra a
- mov m,a
- inx h
- dcx b
- jmp luuu
- doneit:
- mvi a,1
- jmp warmer
-
- jmp2:
- mvi a,2
- jmp commonbios
-
- jmp3:
- mvi a,3
- jmp commonbios
-
- jmp4:
- mvi a,4
- jmp commonbios
-
- jmp5:
- mvi a,5
- jmp commonbios
-
- jmp6:
- mvi a,6
- jmp commonbios
-
- jmp7:
- mvi a,7
- jmp commonbios
-
- jmp8:
- mvi a,8
- jmp commonbios
-
- jmp9:
- mvi a,9
- jmp commonbios
-
- jmp10:
- mvi a,10
- jmp commonbios
-
- jmp11:
- mvi a,11
- jmp commonbios
-
- jmp12:
- mvi a,12
- jmp commonbios
-
- jmp13:
- mvi a,13
- jmp commonbios
-
- jmp14:
- mvi a,14
- jmp commonbios
-
- jmp15:
- mvi a,15
- jmp commonbios
-
- jmp16:
- mvi a,16
- jmp commonbios
-
- FILLEND EQU $
-
- ORG SERIAL + 500H;
- BIOS:
- COLD: jmp coldboot
- WBOOTF: jmp jmp1 ; do dos call to load the ccp again
- ; under CP/M-86, could reinitialize BDOS
- CONSF: jmp jmp2 ; CONSOLE STATUS
- CONIF: jmp jmp3 ; conin
- CONOF: jmp jmp4 ; Conout
- LISTF: jmp jmp5 ; list
- PUNF: jmp jmp6 ; punch
- READF: jmp jmp7 ; reader
-
- ;the following (except for listst) are not implemented
- ;and will warm boot the CP/M-80 system
-
- HOMF: jmp jmp8 ; notimpl; home
- SELF: jmp jmp9 ; notimpl; seldsk
- TRKF: jmp jmp10 ; notimpl; settrk
- SECF: jmp jmp11 ; notimpl; setdsk
- DMAF: jmp jmp12 ; setdma
- DRDF: jmp jmp13 ; notimpl; read
- DWRF: jmp jmp14 ; notimpl; write
- LISTS: jmp jmp15 ; listst ;
- SECTRN:jmp jmp16 ; sectran
-
- ; pass all bios calls onto the turbo handler
- ; wipes out a,bc,hl
-
- breakout: ; return permanently to 8086 mode where we left with BRKEM
- RETEM ; to whence it came
-
- commonbios: ; call 8088 code
- sta bpsw ; show call
- lda abortflag ; TEST FOR ABORT
- ora a
- jnz breakout
- ; most cp/m bios routines only use bc
- ; disk routines may use more, but not implemented here
- mov h,b
- mov l,c
- shld bbc
- CALLN BIOSHANDLE ; go to turbo handler and do it
- cmmncall EQU $-1
- lhld bhl ; bios returns in a and hl
- lda bpsw
- ret ; this one not used usually
-
- warmer:
- sta bpsw ; show call
- lda abortflag ; TEST FOR ABORT
- ora a
- jnz breakout
- CALLN BIOSHANDLE
- WMNCALL EQU $-1
- LXI SP,CPMSTACK
- LHLD BHL ; get the address
- PCHL ; and jump
-
- codeend equ $
- org 0ff80h;
-
- cpmstack: dw 0
-
- ORG 0FFB0H
-
- COLDHAN: DB 80H
- CCPHAN: DB 81H
- BDOSHAN: DB 82H
- BIOSHAN: DB 83H
-
- org 0ffc0h;
- ccpreg:
- ccppsw: dw 0 ;ax
- ccphl: dw 0 ;bx
- ccpbc: dw 0 ;cx
- ccpde: dw 0 ;dx
-
- org 0ffd0h
- bpsw: dw 0 ;ax
- bhl: dw 0 ;bx
- bbc: dw 0 ;cx
- bde: dw 0 ;dx
-
- org 0ffe0h
- BDOSreg:
- bdpsw: dw 0 ;ax
- bdhl: dw 0 ;bx
- bdbc: dw 0 ;cx
- bdde: dw 0 ;dx
-
- org 0ffffh;
- abortflag: db 0; non-zero aborts
- biosend EQU $
-
- end ; stub bdos-bios