home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- ;
- title 'C128 BIOS, main I/O and sys functions 28 Apr 86'
-
- ;
- ; This module contains CXIO,CXINIT,CXMOVE and CXTIME.
- ;
- maclib cpm3
-
- maclib z80
-
- maclib cxequ
-
- maclib modebaud
-
-
- public ?init,?ldccp,?rlccp
-
- public ?user,?di$int
-
- extrn ?sysint
-
- bdos equ 5
-
- extrn @civec,@covec,@aivec,@aovec,@lovec
- extrn ?bnksl
-
- public ?cinit,?ci,?co,?cist,?cost
- public @ctbl
- extrn ?kyscn
-
- ; Utility routines in standard BIOS
- extrn ?wboot ; warm boot vector
- extrn ?pmsg ; print message @<HL> up to 00
- ; saves <BC> & <DE>
- extrn ?pdec ; print binary number in <A> from 0 to 99.
- extrn ?pderr ; print BIOS disk error header
- extrn ?conin,?cono ; con in and out
- extrn ?const ; get console status
-
- extrn @hour,@min,@sec,@date,?bnksl
- public ?time
-
- page
- ;
- ; keyboard scanning routine
- ;
- extrn ?get$key,?int$cia
- extrn Fx$V$tbl
- ;
- ; links to 80 column display
- ;
- extrn ?out80,?int80
- extrn ?out40,?int40
-
- extrn ?pt$i$1101,?pt$o$1,?pt$o$2
- extrn ?convt
- ; extrn ?pt$s$1101
-
- ;
- ; bios8502 function routines
- ;
- public ?fun65
-
- ;
- ;
- ;
- public ?intbd
- extrn ?int65,?in65,?ins65,?out65,?outs65
-
- ; cseg
- ;trace:
- ; xthl ; save hl on stack
- ; push psw
- ; call ?pmsg ; DE and BC saved by ?pmsg
- ; pop psw
- ; xthl
- ; ret
- ;
- ; CSEG
- ;disp$A:
- ; push psw ;;;test
- ; ani 0fh ;;;test
- ; adi 90h ;;;test
- ; daa ;;;test
- ; aci 40h ;;;test
- ; daa ;;;test
- ; sta low$test ;;;test
- ; pop psw ;;;test
- ; rar ;;;test
- ; rar ;;;test
- ; rar ;;;test
- ; rar ;;;test
- ; ani 0fh ;;;test
- ; adi 90h ;;;test
- ; daa ;;;test
- ; aci 40h ;;;test
- ; daa ;;;test
- ; sta hi$test ;;;test
- ; call trace ;;;test
- ;hi$test: ;;;test
- ; db 31 ;;;test
- ;low$test: ;;;test
- ; db 31 ;;;test
- ; db ' ' ;;;test
- ; db 0 ;;;test
- ; ret ;;;test
- ;
- page
-
- DSEG
- ?fun65:
- sta vic$cmd ; save the command passed in A
- if not use$6551
- fun$di$wait:
- lda RS232$status
- ani 11000010b ; char to Xmit, Xmiting or receiving ?
- jrnz fun$di$wait ; yes, wait for int to clean up
- endif
- di
- lda force$map ; get current MMU configuration
- push psw ; save it
- sta io$0 ; make I/O 0 current
-
- lxi d,1 ; D=0, E=1
- if use$fast
- lxi b,VIC$speed
- inp a
- sta sys$speed
- outp d ; set slow mode (1 2 MHz Z80)
- endif
- lxi b,page$1$h
- outp d
- dcr c
- outp e ; page 1, 0-1
- dcr c
- outp d
- dcr c
- outp d ; page 0, 0-0
- call enable$6502+6 ; go run the 8502
- mvi c,low(page$1$h)
- outp e
- dcr c
- outp e ; page 1, 1-1
- dcr c
- outp e
- dcr c
- outp d ; page 0, 1-0
- if use$fast
- lxi b,VIC$speed
- lda sys$speed ; get desired system speed
- outp a ; set speed (2 or 4 MHz Z80)
- endif
- pop psw ; recover the MMU config.
- sta force$map ; restore it
- ei ; turn interrupts back on
- lda vic$data ; get command results
- ora a ; set the zero flag if A=0
- ret
-
- ?di$int:
- if not use$6551
- push psw
- di$int$1:
- lda RS232$status ; character to Xmit or currently
- ani 11000010b ; ..transmitting or receiving ?
- jrnz di$int$1 ; yes, wait for int to clean up
- pop psw
- endif
- di
- ret
-
- page
- ;
- ; set up the MMU for CP/M Plus
- ;
- DSEG ; init done from banked memory
- ?init:
- mvi a,3eh ; force MMU into I/O space
- sta force$map ;
- lxi h,mmu$table+11-1 ; table of 11 values
- lxi b,mmu$start+11-1 ; to to MMU registers
- mvi d,11 ; move all 11 bytes to the MMU
-
- init$mmu$loop:
- mov a,m
- outp a
- dcx h
- dcx b
- dcr d
- jrnz init$mmu$loop
-
- mvi a,1 ; enable track and sector status
- sta stat$enable ; on the status line
- ; mvi a,1 ; no parity, 8 bits, 1 stop bit
- sta XxD$config
- ;
- if use$6551
- lxi h,int$6551
- else
- lxi h,usart
- endif
- shld usart$adr
-
- lxi h,?convt
- shld prt$conv$1
- shld prt$conv$2
-
- lxi h,Fx$V$tbl
- shld key$FX$function
- ;
- ; install I/O assignments
- ;
- lxi h,4000h+2000h ; 80 and 40 column drivers
- shld @covec
- mvi h,80h
- shld @civec ; assign console input to keys
- mvi h,10h
- shld @lovec ; assign printer to LPT:
- mvi h,00h
- shld @aivec
- shld @aovec ; assign rdr/pun port
-
- page
- ;
- ; print sign on message
- ;
- call prt$msg ; print signon message
- db 'Z'-'@' ; initialize screen pointers
- db esc,esc,esc
- db purple+50h ; set character color
- db esc,esc,esc
- db black+60h ; set background (BG) color
- db esc,esc,esc
- db brown+70h ; set border color
- db 'Z'-'@' ; home and clear screen (to BG color)
-
- db lf,lf,lf
- if use$fast
- db 'Fast '
- endif
-
- if use$6551
- db '/w 6551 '
- endif
-
- db 'CP/M 3.0'
- if not banked
- db ' Non-Banked'
- endif
- db ' On the Commodore 128 '
- date
- warning
- db cr,lf
- db ' ',0
-
- ;
- ; set CONOUT driver to correct screen
- ;
- lxi h,4000h ; 80 column screen vector
- call read$d505
- ral
- jrnc set$screen
- mvi a,'4'
- sta screen$num
- mvi h,20h ; 40 column screen vector
-
- set$screen:
- call prt$msg ; HL saved
- screen$num:
- db '80 column display',cr,lf,lf,lf,lf,0
- shld @covec ; assign console output to CRT: (40/80)
-
- page
-
- ;
- ;
- mvi a,-1 ; set block move to NORMAL mode
- sta source$bnk
- ;
- ; install mode 2 page vectors
- ;
- mvi a,JMP
- sta INT$vector ; install a JMP at vector location
- lxi h,?sysint
- shld INT$vector+1 ; install int$handler adr
- ;
- ; A software fix is required for the lack of hardware to force the
- ; LSB of the INT vector to 0. If the bus floats INT VECT could be
- ; read as 0FFh; thus ADRh=I (I=0FCh) ADRl=FF for first read, and
- ; ADRh=I+1 ADRl=00 for second, to ensure that control is retained
- ; 0FD00h will also have FDh in it.
- ;
- lxi h,int$block ; FC00h
- lxi d,int$block+1 ; FC01h
- lxi b,256-1+1 ; interrupt pointer block
- mvi m,INT$vector/256 ; high and low are equal (FD)
- ldir
- mvi a,INT$block/256
- stai ; set interrupt page pointer
- im2 ; enable mode 2 interrupts
-
- page
- ;
- ;
- mvi a,vicinit ; null command just to setup BIOS8502
- call ?fun65
- ;
- ;
- ;
- lda sys$freq ; 0=60Hz 0FFh=50Hz
- ani 80h ; 0=60Hz 080h=50Hz
- mov l,a ; save in L
- lxi b,cia$1+0eh ; point to CRA
- inp a ; get old config
- ani 7fh ; clear freq bit
- ora l ; add in new freq bit
- outp a ; set new config
-
- mvi c,8 ; start RTC
- outp a
-
- lxi h,date$hex
- shld @date ; set date to system data
-
- ;
- ; setup the sound variables
- ;
- lhld key$tbl
- lxi d,58*4
- dad d
- mov e,m
- inx h
- mov d,m
- inx h
- xchg
- shld sound1 ; H=SID reg 24, L=SID reg 5
- xchg
- mov e,m
- inx h
- mov d,m
- xchg
- shld sound2 ; H=SID reg 6, L=SID reg 1
- lxi h,9
- dad d
- mov e,m
- inx h
- mov d,m
- xchg
- shld sound3 ; H=SID reg 4 then L=SID reg 4
- ;
- ; set-up key click sound registers
- ;
- lxi b,sid+7
- lxi h,0040h
- outp l ; (sid+7)=40h
- inr c
- outp l ; (sid+8)=40h
- mvi c,low(sid+12)
- outp h ; (sid+12)=0 Attack=2ms, Decay=6ms
- inr c
- outp h ; (sid+13)=0 Sustain=0, Release=6ms
- mvi a,6
- sta tick$vol ; set keyclick volumn level
- ;
- ; set up interrupts for key scan (not software usart)
- ;
- if use$6551
- lxi d,2273 ; int at 150 BAUD rate
- lxi b,CIA1+timer$b$low ;
- outp e ;
- inr c ; point to timer$b$high
- outp d ;
-
- mvi a,11h ;
- mvi c,CIA$ctrl$b ; turn on timer B
- outp a ;
-
- lxi b,CIA2+data$b ; setup user port for RS232
- inp a ; get old data
- ori 6 ; set CTS and DTR
- outp a ; update it
- endif
- ret
-
-
- mmu$table:
- mmu$tbl$M
-
- page
- ;
- ;
- ;
- CSEG
- prt$msg:
- xthl
- call ?pmsg
- xthl
- ret
-
-
- ;
- ; placed in common memory to keep IO from stepping on this code
- ; always called from bank 0
- ;
- CSEG
- read$d505:
- sta io$0 ; enable MMU (not RAM)
- lxi b,0d505h
- inp a ; read 40/80 column screen
- sta bank$0 ; re-enable RAM
- ret
-
- page
- ;
- ;
- ;
- DSEG
- if not use$6551
- init$RS232:
- di
-
- xra a
- sta RS232$status
- lxi h,RxD$buf$count ; clear the count
- mvi m,0
- inr l ; point to RxD$buf$put
- mvi m,low(RxD$buffer)
- inr l ; point to RxD$buf$get
- mvi m,low(RxD$buffer)
-
- lxi h,NTSC$baud$table
- lda sys$freq
- ora a
- jrz use$NTSC
- lxi h,PAL$baud$table
- use$NTSC:
- lda RS232$baud
- cpi baud$1200 ; baud rate less then 1200 baud
- jrc baud$ok ; yes, go set it
- mvi a,baud$1200 ; no, 1200 baud is the max
- sta RS232$baud ; (change to 1200 baud)
-
- baud$ok:
- mov e,a
- mvi d,0
- dad d ; +1X
- dad d ; +1X
- dad d ; +1X = +3X
- mov e,m
- inx h
- mov d,m
- inx h ;
- mov a,m ; get rate #
- sta int$rate ;
- lxi b,CIA1+timer$b$low ;
- outp e ;
- inr c ; point to timer$b$high
- outp d ;
-
- mvi a,11h ;
- mvi c,CIA$ctrl$b ; turn on timer B
- outp a ;
-
- lxi b,CIA2+data$b ; setup user port for RS232
- inp a ; get old data
- ori 6 ; set CTS and DTR
- outp a ; update it
- ei
- ret
-
- page
- ;
- ; NTSC rates (1.02273 MHz)
- ;
- NTSC$baud$table:
- dw 6818 ; no baud rate (6666.47)
- db 1
- dw 6818 ; 50 6666.7us (6666.47)
- db 1
- dw 4545 ; 75 4444.4us (4443.99)
- db 1
- dw 3099 ; 110 3030.3us (3030.13)
- db 1
- dw 2544 ; 134 2487.6us (2487.46)
- db 1
- dw 2273 ; 150 2222.2us (2222.48)
- db 2
- dw 1136 ; 300 1111.1us (1110.75)
- db 3
- dw 568 ; 600 555.6us ( 555.38)
- db 6
- dw 284 ; 1200 277.8us ( 277.69)
- db 12
-
- ;
- ; PAL rates (0.98525 MHz)
- ;
- PAL$baud$table:
- dw 6568 ; no baud rate (6666.32)
- db 1
- dw 6568 ; 50 6666.7us (6666.32)
- db 1
- dw 4379 ; 75 4444.4us (4444.56)
- db 1
- dw 2986 ; 110 3030.3us (3030.70)
- db 1
- dw 2451 ; 134 2487.6us (2487.69)
- db 1
- dw 2189 ; 150 2222.2us (2221.77)
- db 2
- dw 1095 ; 300 1111.1us (1111.39) 300*3
- db 3
- dw 547 ; 600 555.6us ( 555.19) 600*3
- db 6
- dw 274 ; 1200 277.8us ( 278.10) 1200*3
- db 12
-
- page
- ;
- ;
- ;
- out$RS232:
- call out$st$RS232
- jrz out$RS232
- mov a,c
- sta xmit$data ; get character to send in A
- lxi h,RS232$status
- setb 7,m ; set Xmit request bit
- ret
-
- ;
- ;
- ;
- out$st$RS232:
- lda RS232$status
- ani 80h ; bit 8 set if busy
- xri 80h ; A cleared if busy (=80h if not)
- rz
- ori 0ffh ; A=ff if ready (not busy)
- ret
-
- ;
- ;
- ;
- in$RS232:
- call in$st$RS232
- jrz in$RS232
- lda recv$data
- lxi h,RS232$status
- res 0,m
- ret
-
- ;
- ;
- ;
- in$st$RS232:
- lda RS232$status
- ani 1
- rz
- ori 0ffh ; set data ready (-1)
- ret
- endif
- page
- ;
- ; this routine is used to provide the user with a method
- ; of interfacing with low level system functions
- ;
- CSEG
- ;
- ; input:
- ; all registers except HL and A are passed to function
- ;
- ; output:
- ; all resisters from function are preserved
- ;
- ?user:
- shld user$hl$temp
- xchg
- shld de$temp ; save DE for called function
-
- mov e,a ; place function number in E
- mvi a,num$user$fun-1 ; last legal function number
-
- call vector ; function
- usr$tb: dw read$mem$0 ; 0
- dw write$mem$0 ; 1
- dw ?kyscn ; 2
- dw do$rom$fun ; 3 (L=function #)
- dw do$6502$fun ; 4 (L=function #)
- dw read$d505 ; 5 returns MMU reg in A
- dw code$error ; not 0 to 5 ret version number in HL
-
- num$user$fun equ ($-usr$tb)/2
-
- page
- ;
- ; address in DE is read and returned in C
- ; A=0 if no error
- ;
- DSEG
- read$mem$0:
- ldax d ; read location addressed by DE
- mov c,a ; value returned in C
- xra a ; clear error flag
- ret
-
- ;
- ; address in DE is written to with value in C
- ; A=0 if no errors
- ;
- write$mem$0:
- mvi a,-1 ; get error flag and 0ffh value
- cmp d ; do not allow write from FF00 to FFFF
- ; this is 8502 space, MMU direct reg.
- rz
- mov a,d
- cpi 10h ; do not allow write from 0000 to 0FFF
- ; this is ROM space
- mvi a,-1 ; get error flag
- rc ; return if 00h to 0fh
- mov a,c
- stax d
- xra a ; clear error flag
- ret
-
- page
- ;
- ; This is the function code entry point for direct execution
- ; of driver functions. If the MSB of the function number is
- ; set, the 40 column driver is used; else the 80 column drive
- ; is used.
- ;
- do$rom$fun:
- lhld user$hl$temp ; get HL (L=fun #)
-
- mvi a,7eh ; only allow even functions
- ana l
- cpi 79h
- jrc no$hl$req
- lhld @dma ; HL will be passed in @dma by
- push h ; ..the user
- no$hl$req:
- mov l,a
- rst 5 ; call rom functon (RCALL) L=fun #
- ret
-
- ; mvi a,7eh ; only allow even functions
- ; ana l
- ; sta no$hl$req+1
- ; cpi 79h
- ; jrc no$hl$req
- ; lhld @dma ; HL will be passed in @dma by
- ; push h ; ..the user
- ;no$hl$req:
- ; will be changed to RCALL xx RET for next release (ROM FN 7A, 7C
- ; and 7E will not function with current code, they expect
- ; a return address on the stack
- ;
- ; RJMP 5Eh ; unused function, real fun# installed
- ; ..above
-
- do$6502$fun:
- lhld user$hl$temp
- mov a,l
- jmp ?fun65
- ;
- ;
- ;
- code$error:
- lxi h,date$hex
- mvi a,-1
- ret
-
- page
- ;
- ;
- ;
- CSEG
- ?rlccp:
- lxi h,ccp$buffer
- lxi b,0c80h
-
- load$ccp:
- sta bank$0
- mov a,m
- sta bank$1
- lxi d,-ccp$buffer+100h
- dad d
- mov m,a
- lxi d,ccp$buffer-100h+1
- dad d
- dcx b
- mov a,b
- ora c
- jrnz load$ccp
- ret
-
- page
- ;
- ;
- ;
- CSEG
- ?ldccp:
- xra a
- sta ccp$fcb+15 ; zero extent
- lxi h,0
- shld fcb$nr ; start at beginning of file
- lxi d,ccp$fcb
- call open ; open file containing CCP
- inr a
- jrz no$CCP ; error if no file...
- lxi d,0100h
- call setdma ; start of TPA
- è lxi d,128
- call setmulti ; allow up to 16K bytes
- lxi d,ccp$fcb
- call read
-
- lxi h,0100h
- lxi b,0c80h
- lda force$map
- push psw
-
- ;
- ;
- save$ccp:
- sta bank$1
- mov a,m
- sta bank$0
- lxi d,ccp$buffer-100h
- dad d
- mov m,a
- lxi d,-ccp$buffer+100h+1
- dad d
- dcx b
- mov a,b
- ora c
- jrnz save$ccp
-
- pop psw
- sta force$map
- ret
-
- page
- ;
- ; The following code does not work with the NEW MMU
- ;
- ;?ldccp:
- ; xra a
- ; sta ccp$fcb+15 ; zero extent
- ; lxi h,0
- ; shld fcb$nr ; start at beginning of file
- ; lxi d,ccp$fcb
- ; call open ; open file containing CCP
- ; inr a
- ;
- ;; trace jz below should be jrz
- ; jz no$CCP ; error if no file...
- ;
- ; lda fcb$rc ; get the record count
- ; sta ccp$count ; save for later
- ; lxi d,0100h
- ; call setdma ; start of TPA
- è; lxi d,128
- ; call setmulti ; allow up to 16K bytes
- ; lxi d,ccp$fcb
- ; call read
- ;
- ; lxi d,1f0h ; point to buffer
- ; ; bank 1, page F0
- ;; lxi h,101h ; point to CCP (in TPA)
- ; ; bank 1, page 01
- ; mov h,d
- ; mov l,d
- ; jr save$ccp
- ;
- ;
- ;
- ;
- ;?rlccp:
- ; lda ccp$count ;
- ; sui 30 ; we can only save 30 records
- ; jp ?ldccp
- ;
- ; lxi h,1F0h ; point to buffer
- ; ; bank 1, page F0
- ;; lxi d,101h ; point to TPA space
- ; ; bank 1, page 01
- ; mov d,h
- ; mov e,h
- ;
- ;save$ccp:
- ; mvi b,15 ; number of pages in buffer
- ;ccp$move$loop:
- ; push h
- ; push d
- ; push b
- ; call do$move$0$to$1
- ; pop b
- ; pop d
- ; pop h
- ; inx h
- ; inx d
- ; djnz ccp$move$loop
- ;
- ; ret
- ;
- ;
- ;do$move$0$to$1:
- ; call set$0$and$1
- ; call move$0$to$1
- ; lxi h,100h ; bank 1 page 0
- ;; lxi d,101h ; bank 1 page 1
- ; mov d,h
- ; mov e,h
- ;;
- ;;
- ;;
- ;set$0$and$1:
- ; lda force$map ; get current map
- ; sta io ; force to i/o in bank 0
- ; lxi b,page$0$l ; point to 1st page register
- ; outp l ; set page 0 low
- ; inr c
- ; outp h ; set page 0 high
- ; inr c
- ; outp e ; set page 1 low
- ; inr c
- ; outp d ; set page 1 high
- ; sta force$map
- ; ret
- ;
- ;;
- ;;
- ;;
- ;move$0$to$1:
- ; lda force$map
- ; sta bank$1 ; force bank 1 memory
- ; lxi h,000h ; source
- ; lxi d,100h ; dest.
- ;; lxi b,100h
- ; mov b,d
- ; mov c,e ; count
- ; ldir
- ; sta force$map
- ; ret
- ;
- page
- ;
- ;
- ;
- no$CCP: ; here if we couldn't find the file
- call prtmsg ; report this...
- db cr,lf,'BIOS Err on A: No CCP.COM file',0
- call ?conin ; get a response
- jr ?ldccp ; and try again
-
- ;
- ; CP/M BDOS Function Interfaces
- ;
- CSEG
- open:
- mvi c,15 ; open file control block
-
- db 21h ; lxi h,(mvi c,26)
- setdma:
- mvi c,26 ; set data transfer address
-
- db 21h ; lxi h,(mvi c,44)
- setmulti:
- mvi c,44 ; set record count
-
- db 21h ; lxi h,(mvi c,20)
- read:
- mvi c,20 ; read records
- jmp bdos
-
- ; 12345678901
- ccp$fcb db 1,'CCP COM',0,0,0
- fcb$rc db 0
- ds 16
- fcb$nr db 0,0,0
-
-
- page
- ;
- ; CXIO.ASM and CXEM.ASM
- ;
- ;==========================================================
- ; ROUITINE TO VECTOR TO HANDLER
- ;==========================================================
- ; CP/M IO routines b=device : c=output char : a=input char
- ;
- CSEG
- ;
- ;
- ;
- ?cinit: ; initialize usarts
- mov b,c
- call vector$io ; jump with table adr on stack
- number$drivers:
- dw ?int$cia ; keys
- dw ?int80 ; 80col
- dw ?int40 ; 40col
- dw ?pt$i$1101 ; prt1
- dw ?pt$i$1101 ; prt2
- dw ?int65 ; 6551
- if not use$6551
- dw init$RS232 ; software RS232
- endif
- dw rret ;
- max$devices equ (($-number$drivers)/2)-1
-
- ;
- ;
- ;
- ?ci║ ╗ characte≥ input
- call vector$io ; jump with table adr on stack
- dw key$board$in ; keys
- dw rret ; 80col
- dw rret ; 40col
- dw rret ; ptr1
- dw rret ; prt2
- dw ?in65 ; 6551
- if not use$6551
- dw in$RS232 ; software RS232
- endif
- dw null$input
-
- ;
- ;
- ;
- ?cist: ; character input status
- call vector$io ; jump with table adr on stack
- dw key$board$stat ; keys
- dw rret ; 80col
- dw rret ; 40col
- dw rret ; prt1
- dw rret ; prt2
- dw ?ins65 ; 6551
- if not use$6551
- dw in$st$RS232 ; software RS232
- endif
- dw rret
-
- ;
- ;
- ;
- ?co: ; character output
- call vector$io ; jump with table adr on stack
- dw rret ; keys
- dw ?out80 ; 80col
- dw ?out40 ; 40col
- dw ?pt$o$1 ; prt1
- dw ?pt$o$2 ; prt2
- dw ?out65 ; 6551
- if not use$6551
- dw out$RS232 ; software RS232
- endif
- dw rret
-
- ;
- ;
- ;
- ?cost: ; character output status
- call vector$io ; jump with table adr on stack
- dw ret$true ; keys
- dw ret$true ; 80col
- dw ret$true ; 40col
- dw ret$true ; prt1 ?pt$s$1101
- dw ret$true ; prt2
- dw ?outs65 ; 6551
- if not use$6551
- dw out$st$RS232 ; software RS232
- endif
- dw ret$true
-
- page
- ;
- ; This entry does not care about values of DE
- ;
- vector$io:
- mvi a,max$devices ; check for device # to high
- mov e,b ; get devive # in E
- ;
- ;
- ; INPUT:
- ; Vector # in E, Max device in A
- ; passes value in DE$TEMP in DE
- ; HL has routine's address in it on entering routine
- ;
- ; OUTPUT:
- ; ALL registers of returning routine are passed
- ;
- vector:
- pop h ; get address vector list
- mvi d,0 ; zero out the MSB
- cmp e ; is it too high?
- jrnc exist ; no, go get the handler address
-
- mov e,a ; yes, set to max$dev$handler(last one)
- exist:
- dad d ;
- dad d ; point into table
-
- mov a,m
- inx h
- mov h,m
- mov l,a ; get routine adr in HL
-
- if banked
- shld hl$temp ; save exec adr
- lxi h,0
- dad sp
- lxi sp,bios$stack
- push h ; save old stack
-
- lhld de$temp
- xchg
- lhld hl$temp ; recover exec adr
-
- lda force$map ; get current bank
- push psw ; save on stack
- sta bank$0 ; set bank 0 as current
-
- call ipchl
-
- sta a$temp ; save value to return
- pop psw
- sta force$map ; set old bank back
- lda a$temp ; recover value to return
-
- shld hl$temp
- pop h ; recover old stack
- sphl ; set new stack
- lhld hl$temp
- ret
-
- ipchl:
- pchl ; jmp to handler
-
- ds 30h
- bios$stack:
-
- else
- lda a$temp
- xchg
- lhld de$temp
- xchg
- pchl
- endif
-
- page
- ;==========================================================
- ; CHARACTER INPUT ROUTINES
- ;==========================================================
-
- DSEG
- ;
- ;
- ;
- key$board$in:
- call key$board$stat ; test if key is available
- jrz key$board$in
-
- lda key$buf
- push psw ; save on stack
- xra a ; clear key
- sta key$buf
- ;
- ;** the tracking of the display should be able to be turned off
- ;** this could be done with one of the keyboard's Fx codes
- ;
- lda stat$enable
- bit 6,a
- jrnz no$update
- lda char$col$40
- mov b,a
- lda @off40
- cmp b
- jrnc do$update
- adi 39-1
- cmp b
- jrnc no$update
- do$update:
- mvi a,80h
- sta old$offset ; store 80h to demand update
- no$update:
- pop psw ; recover current key
- rret:
- ret
-
- ;
- ;
- ;
- null$input: ; return a ctl-Z for no device
- mvi a,1Ah
- ret
-
-
- page
-
- ;==========================================================
- ; CHARACTER DEVICE INPUT STATUS
- ;==========================================================
-
- DSEG
- ;
- ;
- ;
- key$board$stat:
- lda key$buf
- ora a
- jrnz ret$true
-
- call ?get$key
- ora a ; =0 if none
- rz ; return character not advailable
-
- sta key$buf ; was one, save in key buffer
-
- ret$true:
- ori 0ffh ; and return true
- ret
-
- page
-
- cseg
- @ctbl
- db 'KEYS ' ; device 0, internal keyboard
- db mb$input
- db baud$none
-
- db '80COL ' ; device 1, 80 column display
- db mb$output
- db baud$none
-
- db '40COL ' ; device 2, 40 column display
- db mb$output
- db baud$none
-
- db 'PRT1 ' ; device 3, serial bus printer (device 4)
- db mb$output
- db baud$none
-
- db 'PRT2 ' ; device 4, serial bus printer (device 5)
- db mb$output
- db baud$none
-
- db '6551 ' ; device 5, EXT CRT
- db mb$in$out+mb$serial+mb$softbaud+mb$xonxoff
- ?intbd:
- db baud$1200
- if not use$6551
- db 'RS232 ' ; device 6, software RS232 device
- db mb$in$out+mb$serial+mb$xonxoff+mb$softbaud
- RS232$baud:
- db baud$300
- endif
- db 0 ; mark end of table
-
- page
- ;
- ; TIME.ASM
- ;
- cseg
- ;
- ; HL and DE must be presevered
- ;
- ?time:
- inr c
- lxi b,cia$hours
- jrz set$time
- ;
- ; update SCB time (READ THE TIME)
- ;
- inp a ; read HR (sets sign flag)
- jp is$am ; jmp if AM (positive)
- ani 7fh
- adi 12h ; noon=24(PM), midnight=12(AM)
- daa
- cpi 24h ; check for noon (12+12 PM)
- jrnz set$hr
- mvi a,12h
- jr set$hr
-
- is$am:
- cpi 12h ; check for midnight (AM)
- jrnz set$hr
- xra a ; becomes 00:00
- set$hr:
- sta @hour
- mov b,a
- lda old$hr
- mov c,a
- mov a,b
- sta old$hr
- cmp c ; if @hour<old$hr
- jrnc same$day
-
- push h
- lhld @date
- inx h
- shld @date
- pop h
-
- same$day:
- lxi b,cia$hours-1
- inp a ; read MIN
- sta @min
-
- dcr c
- inp a ; read SEC
- sta @sec
-
- dcr c
- inp a ; read 1/10 of SEC (a must to free
- ret ; the holding register)
-
- old$hr:
- ds 1
-
- page
- ;
- ;
- ;
- set$time
- lda @hour
- sta old$hr
- cpi 12h ; test for noon
- jrz set$as$is
- ana a ; test for 00:xx
- jrnz not$zero$hundred
- mvi a,80h+12h ; set to midnight
- jr set$as$is
-
- not$zero$hundred:
- cpi 11h+1 ; test for 1 to 11 AM
- jrc set$as$is
- sui 12h
- daa ; decimal adjust
- set$msb:
- ori 80h ; set PM
-
- set$as$is:
- outp a
- dcr c
- lda @min
- outp a
- dcr c
- lda @sec
- outp a
- dcr c
- xra a
- outp a
- ret
-
- page
- ;
- ; CXMOVE.ASM
- ;
- public ?move,?xmove,?bank
-
- ;
- ; Move a block of data from DE to HL
- ; count is in BC (within current bank)
- ;
- ;
- cseg ; place code in common
- ?move:
- xchg ;*
- lda source$bnk ; =FFh if normal block move
- inr a ;
- jrnz inter$bank$move
-
- LDIR ;* do block move
- xchg ;*
- ret
-
-
- ;
- ;
- ;
- ?xmove: ; can be in bank 0
- mov a,c
- sta source$bnk
- mov a,b
- sta dest$bnk
- ret ;*
-
- page
- ;
- ;
- ;
- inter$bank$move:
- shld @buffer ; save HL TEMP
- lxi h,0
- dad sp
- lxi sp,bios$stack
- push h ; save old stack ;**1
- lhld @buffer
-
- inter$bank$move$1:
- mov a,b ; get msb of count
- ora a
- jrz count$less$than$256
- push b ; save the count ;**2
- push d ; save the dest ;**3
- lxi d,@buffer ; make buffer the dest
- lxi b,256 ; move 256 bytes
- lda source$bnk
- call ?bank
- ldir ; move source to buffer
-
- pop d ; recover dest ;**2
- push h ; save updated source ;**3
- lxi h,@buffer ; make the buffer the source
- lxi b,256 ; move 256 bytes
- lda dest$bnk
- call ?bank
- ldir ; move buffer to dest
-
- pop h ; recover updated source ;**2
- pop b ; recover count ;**1
- dcr b ; subtract 256 from count
- jr inter$bank$move$1
-
- page
- ;
- ;
- ;
- count$less$than$256:
- ora c ; BC=0 [A (0) or'ed with C]
- jrz exit$move
-
- push d ; save count for 2nd half ;**2
- push b ; save dest adr ;**3
- lxi d,@buffer
- lda source$bnk
- call ?bank
- ldir ; move source to buffer
-
- pop b ; recover count ;**2
- pop d ; recover dest ;**1
- push h ; save updated dest ;**2
- lxi h,@buffer
- lda dest$bnk
- call ?bank
- ldir ; move buffer to dest
- pop h ;**1
- ;
- ;
- ;
- exit$move:
- xchg
- mvi a,-1
- sta source$bnk ; set MOVE back to normal
- lda @cbnk
-
- shld @buffer
- pop h ; recover old stack ;**0
- sphl
- lhld @buffer
-
- ; call ?bank ; set current bank
- ; ret
-
- page
- ;
- ; switch bank to bank number in A
- ;
- cseg ; (must be in common)
- ?bank:
- if banked
- ora a ; bank 0 ?
- jrnz not$bank$0 ; go check for bank 1
-
- sta bank$0 ; set bank 0
- ret
-
- ;
- ;
- not$bank$0:
- dcr a ; bank 1 ?
- rnz ; if not a valid bank just return
- sta bank$1 ; set bank 1
- endif
- ret
-
- end