home *** CD-ROM | disk | FTP | other *** search
-
- title 'CP/M 3 ROM loader 13 May 85'
-
-
- maclib z80
-
- maclib cpm3
-
- maclib cxequ
-
- maclib x6502
-
-
- boot$8502 equ 1100h
- lines equ 24 ; number of user lines on screen(s)
-
-
- rownum macro row,col
- db row+80h,col
- endm
-
-
-
- ;
- ; power on location
- ;
- org 00h ; RST 0
-
- mvi a,3eh
- sta force$map
- jmp power$up ; continue init somewhere else
-
-
- ;
- ; boot CP/M entry point
- ;
- ; org 08h ; RST 1
-
- lxi sp,boot$stack
- mvi a,3Fh ; MMU enable RAM bank 0 no I/O
- jmp loader$start
-
- page
- ;
- ; * TJMP * user to jmp to a Terminal ROM routine
- ; user code:
- ; RST 2
- ; db fun# (0,4,8,C,....,44)
- ;
- ; org 10h ; RST 2
-
- pop h
- mov l,m
- jmp 020h
- nop
- nop
- nop
-
- ;
- ; * RJMP * user to jmp to a ROM routine
- ; user code:
- ; RST 3
- ; db fun#
- ;
- ; org 18h ; RST 3
-
- pop h ; get the return address
- mov l,m ; get user function # (0,2,...,fe)
- jmp 028h ;
- nop
- nop
- nop
-
- page
- ;
- ; * TCALL * used to call a Terminal ROM routine
- ; user code:
- ; mvi l,fun# (0,4,8,C,....,44)
- ; RST 4
- ;
- ; org 20h ; RST 4
-
- lda fun$offset ; =0 if 80 column, <>0 if 40 column
- ana a ; is this an 80 column function?
- jrz 28h ; yes, no offset required
- inr l ; no, advance to next vector
- inr l
-
-
- ;
- ; * RCALL * used to call a ROM routine
- ; user code:
- ; mvi l,fun# (0,2,4,6,.....,7E)
- ; RST 5
- ;
- ; org 28h ; RST 5
-
- mvi h,01h ; vectors on page 1
- mov a,m
- inx h
- mov h,m
- mov l,a
- pchl
- nop
-
- page
- ;
- ; RST 6 is NOT defined.. this area is used for the ROM date
- ; ONLY....
- ;
- ; org 30h ; RST 6
-
- db '05/12/85'
-
-
- ; org 38h ; RST 7 (interrupt mode 1 start adr)
- jmp 0fdfdh
-
- page
- ;
- ;
- ;
- power$up:
- lxi b,VIC$key$row
- lxi d,0fffch ; D=ff, E=fc
- outp d ; set extra 3 scan lines off
- inx b ; point to clock speed reg
- outp e ; bits 7-2 unused
- ; bit 1 enable test mode (1)
- ; bit 0 2 Mhz (1) / 1 MHz (0)
- ;
- ; continue the check to see if a C64 type chartrage is installed
- ; (EXROM or GAME active) if so we enter C64 mode
- ;
- lxi b,mode$reg ; get EXROM and GAME bits
- mvi a,z80$on
- outp a ; set bit high
- inp a ; see if they went high
- cma ; make highs low
- ani 30h ; EXROM or GAME enabled?
- jrz test$key ; no, now test the commodore key
-
- ;
- ; This is a one way trip, no return flights.
- ; Thus we do not have to do the transfer from RAM
- ; (as in C128 mode). We just enable C64 and run.
- ;
- go$c64:
- mvi a,enable$c64
- outp a
- ; should never get here
- RST 0 ; unless there are hardware problems
-
- page
-
- test$key:
- lxi b,0dc0fh ; D1CRB
- mvi a,8h ; turn off timers
- outp a
- dcr c ; D1CRA
- outp a
-
- mvi c,03h ; D1DDRB = inputs
- xra a ; A=00
- outp a
- dcr c ; D1DDRA = outputs
- dcr a ; A=FF
- outp a
- dcr c ; dc01
- dcr c ; dc00
- mvi a,01111111b ; bit 7 for commodore key
- outp a
- inx b ; dc01 point to key$col
- inp a
- ani commodore$key
- lxi b,mode$reg
- jrz go$c64
-
- go$c128:
- ;
- ; set MMU registers to a known state
- ;
- lxi h,mmu$init$data+11-1 ; start at the End
- lxi b,mmu$start+11-1 ; and work forward
- mvi d,11 ; for all 11 bytes
-
- init$mmu$next:
- mov a,m ; get table value
- outp a ; send to MMU
- dcx h
- dcr c
- dcr d
- jrnz init$mmu$next
-
-
- ;
- ; install 8502 code that will enable C128 mode and
- ; execute at the location pointed to by FFFC (reset vector)
- ;
- lxi h,boot$02$code
- lxi d,boot$8502
- lxi b,boot$size
- ldir
-
- lxi h,swap$code
- lxi d,enable$z80
- lxi b,swap$size
- ldir
-
- ;
- ; Get ready to enter C128 mode. Install vectors in ram that will
- ; force the processor to execute RAM code in low memory.
- ; The RAM code in low memory ENABLES the kernal and does
- ; an indirect JMP to FFFC (reset vector).
- ;
- lxi h,boot$8502 ; C128 start adr
- shld 0fffah ; install NMI vector
- shld 0fffch ; install RESET vector
- shld 0fffeh
- shld return$z80+1
- jmp enable$6502
-
- page
- ;
- ; scan buffer for CPM+.SYS file
- ;
- scan$dir:
- call update$buffer ; returns HL=block$buffer
- lda block$size ; 32 for 1K block, 64 for 2K block
- ; ..number director entries/sector
-
- check$next:
- shld @dma
- lxi d,sys$name ; point to system name
- push psw
- call name$match
- cz found
- pop psw
- lhld @dma ; get current buffer pointer
- lxi d,32
- dad d
- dcr a
- jrnz check$next
- ret
-
- page
- ;
- ; compare the strings (11 bytes each) pointed to by
- ; DE and HL. Return with Zero flag set if equal.
- ;
- name$match:
- mvi b,12 ; number of bytes to match
- xchg ; [HL]=search name [DE]=dir entry
-
- match$next:
- ldax d ; get string 1 character
- ani 7fh ; remove any attr.
- cmp m ; compare to string 2
- rnz ; exit if they don't match
-
- inx h
- inx d
- djnz match$next
-
- lda block$size ;
- cpi 64 ; 2K block?
- ldax d ; get the dir ext#
- jrnz ext$1k ; no, ext # ok
- ; yes, (carry=0)
- rar ; divide by 2, ext could be 0 or 1
- ; ..for the 1st and 2 or 3 for the
- ext$1k: ; ..second entry
- sta ext$num
- null$code:
- xra a ; return with zero flag set
- ret
-
- page
- ;
- ;
- ;
- sys$name:
- ; 12345678901
- db 0,'CPM+ SYS' ; must be in user 0's space
-
- db 0
- ;
- ;
- ;
- ; org 0100h-6
- cmp$hl$de:
- mov a,h
- cmp d
- rnz
- mov a,l
- cmp e
- ret
-
- page
-
- ; org 0100h
-
- dw wr$char$80 ; function # 00
- dw wr$char$40 ; function # 02
- dw crs$pos$80 ; function # 04
- dw crs$pos$40 ; function # 06
- dw crs$up$80 ; function # 08
- dw crs$up$40 ; function # 0A
- dw crs$down$80 ; function # 0C
- dw crs$down$40 ; function # 0E
-
- dw crs$left$80 ; function # 10
- dw crs$left$40 ; function # 12
- dw crs$rt$80 ; function # 14
- dw crs$rt$40 ; function # 16
- dw crs$cr$80 ; function # 18
- dw crs$cr$40 ; function # 1A
- dw CEL$80 ; function # 1C
- dw CEL$40 ; function # 1E
-
- dw CES$80 ; function # 20
- dw CES$40 ; function # 22
- dw char$ins$80 ; function # 24
- dw char$ins$40 ; function # 26
- dw char$del$80 ; function # 28
- dw char$del$40 ; function # 2A
- dw line$ins$80 ; function # 2C
- dw line$ins$40 ; function # 2E
-
- dw line$del$80 ; function # 30
- dw line$del$40 ; function # 32
- dw set$color$80 ; function # 34
- dw set$color$40 ; function # 36
- dw set$attr$80 ; function # 38
- dw set$attr$40 ; function # 3A
- dw rd$chr$80 ; function # 3C
- dw rd$chr$40 ; function # 3E
-
- page
-
- dw wr$chr$80 ; function # 40
- dw wr$chr$40 ; function # 42
- dw rd$color$80 ; function # 44
- dw rd$color$40 ; function # 46
- dw null$code ; function # 48
- dw null$code ; function # 4A
- dw null$code ; function # 4C
- dw null$code ; function # 4E
-
- dw convert$record ; function # 50
- dw check$cbm ; function # 52
- dw bell ; function # 54
- dw null$code ; function # 56
- dw null$code ; function # 58
- dw null$code ; function # 5A
- dw null$code ; function # 5C
- dw null$code ; function # 5E
-
- dw trk$40 ; function # 60
- dw set$cursor$40 ; function # 62
- dw line$paint ; function # 64
- dw screen$paint ; function # 66
- dw prt$msg$both ; function # 68
- dw prt$de$both ; function # 6A
- dw update$it ; function # 6C
- dw null$code ; function # 6E
-
- dw ASCII$to$petASCII ; function # 70
- dw cur$adr$40$hl$sz$a ; function # 72
- dw cur$adr$80$hl$sz$a ; function # 74
- dw lookup$color ; function # 76
- dw null$code ; function # 78
-
- dw blk$fill ; function # 7A ret adr, HL on stack
- dw blk$move ; function # 7C ret adr, HL on stack
- dw char$install$gp ; function # 7E ret adr, HL on stack
-
- ; the last 3 function are called by 1st pushing HL on the stack
- ; and then doing the call
- ; user code as follows:
- ; lxi h,xyz ; value to be passed in HL
- ; push h ; extra value on stack
- ; RCALL ....
- ; ; stack clean
-
- page
- ;
- ; org 180h
- ;
- jmp write$memory
- jmp read$memory
- jmp set$update$adr
- jmp wait
-
- ;
- ;
- ;
- loader$start:
- ;
- ; setup the MMU for booting CP/M
- ;
- sta force$map
-
- ;
- ; clear bank 0 RAM 3000h to feffh. This is the system area.
- ;
- lxi h,3000h
- lxi d,3001h
- lxi b,0ff00h-3000h-1
- mov m,l
- ldir
-
- ;
- ; move bios and swap code into ram
- ;
- lxi h,bios$65$code
- lxi d,bios$02
- lxi b,bios$size
- ldir
-
- lxi h,swap$code
- lxi d,enable$z80
- lxi b,swap$size
- ldir
-
- mvi a,RET ; get z80 return adr
- sta return$6502 ; store the RET
-
- ;
- ; initilize the 8502 bios
- ;
- ; xra a ; cleared by memory fill
- ; sta vic$cmd
- call enable$6502
-
- page
- ;
- ; set MMU registers to a known state (for CP/M to use)
- ;
- lxi h,mmu$init$data+11-1 ; start at the End
- lxi b,mmu$start+11-1 ; and work forward
- mvi d,11 ; for all 11 bytes
-
- init$mmu$cpm:
- mov a,m ; get table value
- outp a ; send to MMU
- dcx h
- dcr c
- dcr d
- jrnz init$mmu$cpm
- ; re-enabled RAM bank 0 (no I/O)
- ;
- ; Clear the work area
- ;
- lxi h,1000h
- lxi d,1000h+1
- lxi b,3000h-1000h-1 ; number of bytes to clear
- mov m,l ; clear the 1st one
- ldir ; copy 1st to all
-
- page
- ;
- ; set 80 column colors and set up Video memory with ASCII char set
- ;
- mvi a,26
- call wait
- mvi a,90h ; foreground red background black
- outp a
- mvi a,83h ; set attr and color (lt. blue)
- sta current$atr ; ..for 80 column display
- mvi a,0eh ; set color (lt. blue)
- sta attr$40 ; ..for 40 column display
- call install$ASCII ; convert char set to true ASCII
-
- mvi a,25 ; number of lines on the 40 col display
- sta paint$size
- ;
- ; Let the user know we are booting CP/M
- ;
- call prt$msg$both
- db -1 ; clear both screens
- rownum 1,10
- db 'BOOTING CP/M PLUS',0
-
- ;
- ; point 40 column screen to CP/M screen area
- ;
- lxi b,VIC+24
- mvi a,vic$screen*4/256+6 ; upper and lower case set (+6)
- outp a
-
- page
-
- call check$dsk ; is this a C128 disk ?
- jnz tell$user ; no, tell the user
- ;
- ;
- ;
- lxi h,dir$ptrs
- shld ld$blk$ptr
- call scan$dir ; check 1st block
- call scan$dir ; check 2nd block (1K or 2K)
-
- lhld block$ptrs ; 1st pointer <>0 if file
- mov a,h ; name exist
- ora l ; pointer = 0
- jz tell$user ; yes, inform user there is a error
- ; no, file found, process it
- page
- ; *************************************************
- ; * *
- ; * load 1st group to 1K buffer *
- ; * *
- ; *************************************************
-
- ;
- ;
- ;
- file$found:
- lxi h,block$ptrs
- shld ld$blk$ptr
- call update$buffer
-
-
- ; *************************************************
- ; * *
- ; * extract boot info *
- ; * *
- ; *************************************************
-
- ;
- ;
- ;
- get$boot$info:
- lxi h,block$buffer
- lxi d,info$buffer
- lxi b,12
- ldir
-
- call prt$msg$both
- rownum 10,0
- db 0 ; end of string marker
- lxi h,block$buffer+80h
- call prt$hl$both
-
- lxi h,block$buffer+256 ; set scan pointer
- shld blk$unld$ptr
-
- page
- ; *************************************************
- ; * *
- ; * load keyboard data to system RAM *
- ; * *
- ; *************************************************
-
- call prt$msg$both
- rownum 3,12
- ; db 'LOADING DATA TABLES',0
- db 'DATA TABLES',0
- lhld info$buffer+10
- shld key$tbl ; install keyboard translation pointer
-
- lxi h,info$buffer+9
- call get$size$adr ; HL=adr DE=# (128 btye) records
- shld fun$tbl
-
- load$next$forward:
- call load$record ; HL =load address (in and out)
- lxi d,128 ; move pointer back to buf start
- dad d
- jrnz load$next$forward
-
-
- page
- ; *************************************************
- ; * *
- ; * transfer CP/M code to load address *
- ; * *
- ; *************************************************
- ;
- ;
- ;
- load$common:
- call prt$msg$both
- rownum 4,12
- ; db 'LOADING COMMON CODE',0
- db 'COMMON CODE',0
- lxi h,info$buffer+1 ; load common code
- call load$reverse
-
-
- call prt$msg$both
- rownum 5,12
- ; db 'LOADING BANKED CODE',0
- db 'BANKED CODE',0
- lxi h,info$buffer+3 ; load banked code
- call load$reverse
-
- page
- ; *************************************************
- ; * *
- ; * now load the bios8502 code *
- ; * *
- ; *************************************************
-
- call prt$msg$both
- rownum 6,12
- ; db 'LOADING BIOS8502 CODE',0
- db 'BIOS8502 CODE',0
- lxi h,info$buffer+7 ; load banked code
- call load$reverse
-
- lda info$buffer+7 ; get code size (in 256 byte blocks)
- mov b,a
- lda info$buffer+6 ; get page pointer (pointer to end)
- sub b ; find the start
-
- ; install jmp adr to BIOS02
- sta return$z80+2 ; (jmp) (low) (high)
- xra a
- sta return$z80+1 ; (jmp) (low) (high)
-
-
- ; *************************************************
- ; * *
- ; * now let's start executing CP/M Plus *
- ; * *
- ; *************************************************
-
- lhld info$buffer+4 ; get start address
- pchl ; transfer control to CP/M
-
- page
- ; *********************************
- ; - -
- ; - SUBROUTINES -
- ; - -
- ; *********************************
-
- ;
- ; returns with zero flag set if bootable disk in drive
- ;
- check$dsk:
- lxi h,@buffer
- shld @dma
- xra a
- sta vic$sect ; set track 1 sector 0 (1st sector
- inr a ; on the disk)
- sta vic$trk
- call read$sector ; a=0 if no errors
- call check$cbm ; disk have CBM in first sector ?
- rnz ; no, exit
- inr a ; yes, is it double sided?
- lxi h,block$buffer+1024 ; buffer end address (1K blocks)
- mvi a,32 ; number of dir entries per block
- jrnz set$block$size ; yes, set it
- ; no, set 2K block parameters
- mvi h,high(block$buffer+2048)
- add a ; 64 dir entries
-
- set$block$size
- shld block$end
- sta block$size ; 32=1K, 64=2K (# dir entries/block)
- xra a ; set zero flag (is CP/M disk)
- ret
-
- page
- ; *************************************************
- ; - -
- ; - save CPM+.SYS group numbers -
- ; - -
- ; *************************************************
- ;
- ; found a dir entry that has the right name
- ; add block pointers to list
- ;
- found:
- lxi d,block$ptrs ; point to start of block pointers
- lda ext$num
- ora a
- jrz ext$num$0
-
- lxi d,block$ptrs+16
- dcr a
- jnz ext$error
-
- ext$num$0:
- lhld @dma ; get current pointer
-
- lxi b,16 ; number of bytes to move
- dad b ; also advance to block pointers
- ldir
-
- lda block$ptrs
- ora a ; 1st block present ?
- rz ; no, read more dir.
-
- lhld block$ptrs+15 ; extent full?
- xra a ; get a zero
- cmp l ; cmp to block$prt+15
- jrz go$boot$it ; no, this is it then
-
- cmp h ; cmp to block$prt+16
- ; 2nd block present ?
- rz ; no, read more dir.
-
- go$boot$it:
- jmp file$found ; two parms are still on the stack
- ; but at this point who cares
-
- page
- ;
- ;
- ;
- load$reverse:
- call get$size$adr ; HL=adr DE=# records (128 byte)
-
- load$next:
- lxi d,-128 ; move pointer back to buf start
- dad d
- call load$record
- jrnz load$next
- ret
-
- ;
- ;
- ;
- get$size$adr:
- mov e,m
- mvi d,0 ; get buffer size (#256 byte)
- mov a,e ; get size to A
- ora a
- jz table$error ; exit if count=0
-
- xchg
- dad h ; HL=#128 byte blocks
- shld load$count
- xchg
- dcx h
- mov h,m
- mvi l,0
- ret
-
- page
- ;
- ;
- ;
- load$record:
- push h ; save to address
- lhld block$end ; get buffer end adr
- xchg
- lhld blk$unld$ptr
- call cmp$hl$de
- cz update$buffer
- xchg
- lxi h,128
- dad d
- shld blk$unld$ptr
- pop h ; recover save address
- push h
- xchg ; HL=source DE=dest.
- lxi b,128 ; size of move
- ldir
- lhld load$count
- dcx h
- shld load$count
- mov a,l
- ora h
- pop h
- ret
-
- page
- ;
- ;
- ;
- update$buffer:
- lxi h,block$buffer
- shld @dma
- push h ; save block buffer adr for ret
- lhld ld$blk$ptr ; get the current block pointer
- mvi d,0 ; zero MSB of block pointer
- mov e,m ; get LSB of block pointer
- inx h ; advance pointer
- shld ld$blk$ptr
- xchg ; get block number to HL
- ;
- ; read the block pointed to by the HL
- ; into the data buffer
- ;
- dad h ; 2x
- dad h ; 4x 256=1K
- lda block$size ; =32 for 1K, =64 for 2K
- rrc
- rrc
- rrc ; 32/8=4, 64/8=8
- cpi 32/8 ; 1K block size?
- jrz is$1K$block
- dad h ; 8x 256=2K
- is$1K$block:
- shld @trk
- next$block:
- dcr a ; 3 or 7 sectors left to read
- sta vic$count ; ..1st sector is read anyway
- push psw
- mvi a,1
- sta F$rd$count+BB ;
-
- call convert$record ; set track, sector (adjust for offset)
- lhld @trk
- inx h
- shld @trk ; save for later
- pop psw
- jrz rd$1541
-
- lda fast
- ana a ; 0=1541, 0<>1571
- jrz rd$1541
-
- lhld vic$trk ; get track and sector #
- push h ; save on stack
- check$next$trk:
- call convert$record ; convert next track and sector
- pop h ; recover 1st trk and sector #
-
- lda vic$trk ; get trk$number
- cmp l ; same trk as 1st sector
- jrnz not$same$trk
-
- push h ; resave 1st trk and sect
- lhld @trk
- inx h
- shld @trk
- lxi h,F$rd$count+BB
- inr m
- lxi h,vic$count
- dcr m
- jrnz check$next$trk
- pop h
-
- not$same$trk:
- shld vic$trk ; save the 1st track sector #
- rd$1541:
- call read$sector ; read the sector to the buffer
- lxi h,@dma+1 ; point to dma high byte
- lda F$rd$count+BB
- add m
- mov m,a ; adjust for next read
- lda vic$count
- ana a ; test if all sectors read?
- jrnz next$block ; no loop back
-
- pop h ; recover block buffer adr
- ret
-
- page
- ;
- ; convert block number to sector and track
- ;
- convert$record:
- mvi a,35
- sta temp$1 ; store a track offset of 35
- lhld @trk ; get start block #
- lxi d,680 ; 0 to 680 sectors per side
- ora a ; clear the carry
- dsbc d ; negative if <680
- jrnc side$1 ; jump if still positive >=680
- xra a ;
- sta temp$1 ; store a track offset of 0
- dad d ; add it back
-
- side$1:
- inx h ; skip 1st sector (both sides)
- inx h ; skip 2nd sector (both sides)
- lxi d,357 ; get first value to subtract
- lxi b,21*256+1-1 ; b=sectors/track c=track offset-1
- ora a ; clear the carry bit
- dsbc d ;
- jrc too$much ;
- inx h ; add 1 to skip track 18 sector 0
- lxi d,490-357 ; get first value to subtract
- lxi b,19*256+18-1 ; b=sectors/track c=track offset-1
- dsbc d ;
- jrc too$much ;
- lxi d,598-490 ; get first value to subtract
- lxi b,18*256+25-1 ; b=sectors/track c=track offset-1
- dsbc d ;
- jrc too$much ;
- lxi d,0
- lxi b,17*256+31-1 ; b=sectors/track c=track offset-1
-
- page
- ;
- ; at this point B= number of sectors/track and C=track offset
- ; after DE is added back to HL (1st inst), HL is the number of
- ; sector past the current track (in C).
- ;
- too$much:
- dad d ; add back what made sum go negitive
- mvi d,0 ; number of sectors/track in DE
- mov e,b
- ora a ; clear the carry bit
- sect$pos:
- inr c ; add one to the current track (1-35)
- dsbc d ; remove a track's worth of sectors
- jrnc sect$pos ; less then one?, no jmp
- dad d ; make HL positive again
- ;
- ; at this point HL has the remainder (sector # 0-20) and
- ; C has the track number (1-35), DE and B still has the
- ; # sectors/track for the current track.
- ;
- lda temp$1 ; get track offset
- add c ; add to current track
- sta vic$trk ; save it
- push h
- lxi h,special$skew
- lxi b,21 ; number of sectors in 1st region
- mov a,e
- cmp c
- jrz correct$region
- dad b ; move past current region
- dcx b
- dcx b ; 19
- adjust$loop:
- cmp c
- jrz correct$region
- dad b
- dcx b
- jr adjust$loop
- ;
- ;
- ;
- correct$region:
- pop b ; get logical sector # in BC
- dad b
- mov a,m ; get translated sector number to A
- sta vic$sect ; value from 0 to 20 will be returned
- inr a ; A is required to be non-zero on ret
- ret
-
- page
- ;
- ;
- ;
- read$sector:
- mvi a,3
- sta retry
-
- read$again:
- mvi a,vicrd ; read a sector of data
- sta vic$cmd
- call disp$dsk$info
- call enable$6502
- mvi a,3fh ; mmu ram bank 0 (no I/O)
- sta force$map
- lda vic$data
- ora a ; problems?
- jrnz read$error ; yes, check for disk error or media change
- ; no, go move buffer to DMA address
- ret
-
- page
- ;
- ;
- ;
- check$cbm:
- lxi h,@buffer
- mov a,m
- cpi 'C' ; C ?
- rnz ; no, return
-
- inr l ; @buffer+1
- mov a,m
- cpi 'B' ; B ?
- rnz ; no, return
-
- inr l ; @buffer+0
- mov a,m
- cpi 'M' ; M ?
- rnz
-
- mvi l,0ffh ; @buffer+0ffh
- ; point to the double sided flag
- mov a,m ; read it, 0FFh if double sided
- ret
-
- page
- ;
- ;
- ;
- ext$error:
- call prt$msg$both
- rownum 19,5
- db '32K MAX CPM+.SYS SIZE',0
-
- try$again:
- rst 1
-
- ;
- ;
- ;
- read$error:
- inr a ; test for -1
- jrz try$again
-
- lda retry
- dcr a
- sta retry
- jrnz read$again
-
-
-
- call prt$msg$both
- rownum 19,5
- db 'READ ERROR',0
- error$2:
- call prt$msg$both
- db ' - HIT RETURN TO RETRY'
- rownum 20,15
- db 'DEL TO ENTER C128 MODE',0
-
- ;
- ;
- ;
- wait$key:
- lxi b,key$row
- mvi a,11111110b ; bit 0 for RETURN key
- outp a
- inr c ; point to key$col
- inp a
- ani 2 ; on bit 1 (0-7)
- jrz try$again
-
- inp a
- ani 1 ; delete key down
- jrnz wait$key ; no, wait for RETURN key
-
- rst 0 ; yes, reboot C128-mode
-
-
- page
- ;
- ; CPM+.SYS file not on this disk test user to install
- ; a system disk and wait for a CR to continue
- ;
- tell$user:
- call prt$msg$both
- rownum 19,5
- db 'NO',0
- error$1:
- call prt$msg$both
- db ' CPM+.SYS FILE',0
- jr error$2
-
- ;
- ;
- ;
- table$error:
- call prt$msg$both
- rownum 19,5
- db 'BAD',0
- jr error$1
-
- page
-
- ;
- ;
- ;
- prt$msg$both:
- xthl
- call prt$hl$both
- xthl
- ret
-
- update$it:
- lxi h,-1
- shld old$offset ; force an update
- ;
- ;
- ;
- prt$de$both:
- push d
- ;
- ;
- ;
- prt$hl$both$loop:
- pop h
- ;
- ;
- ;
- prt$hl$both:
- mov d,m
- inx h ; advance the pointer
- lda prt$flg
- ana a
- jrz no$flag
- xra d
- sta prt$flg
- mov d,a
- no$flag:
- mov a,d
- ora a
- rz
-
- cpi '$'
- rz ; yes, return
-
- push h
- lxi h,prt$hl$both$loop
- push h
- cpi LF
- rz
-
- page
- ;
- ;
- ;
- check$both$CR:
- cpi CR
- jrnz check$erase$both
- ;
- ;
- do$crlf$both:
- call crs$cr$40
- call crs$cr$80
- call crs$down$40
- RJMP FR$cursor$down ; cursor down 80
-
- ;
- ;
- ;
- check$erase$both:
- cpi -1
- jrnz check$both$CUR$$POS
- ;
- ; Erase both screens
- ;
- lxi d,24*256 ; erase the status line 1st
- call curpos$BC$both
- call CEL$40
- call CEL$80
- lxi d,0 ; erase main screen
- call curpos$BC$both
- call CES$40
- RJMP FR$CES
-
-
- check$both$CUR$POS:
- ani 80h
- jrz out$d$both
- ;
- curpos$D$both:
- pop b ; get return adr in BC
- pop h ; get pointer in HL
- mov e,m ; E=column #
- inx h
- push h ; save new pointer
- push b ; save return adr
- res 7,d ; D=row #
-
- curpos$BC$both:
- push d ; save cursor address
- call crs$pos$40
- pop d
- RJMP FR$cursor$pos ; 80 column
-
-
- page
- ;
- ;
- ;
- disp$dsk$info:
- lxi d,24*256+80-6
- call crs$pos$80
- lxi d,24*256+40-6
- call crs$pos$40
-
-
- lda vic$trk
- call disp$dec
- mvi d,' '
- call out$d$both
- lda vic$sect
-
- disp$dec:
- mvi b,'0'-1
-
- conv$loop:
- inr b
- sui 10
- jrnc conv$loop
-
- adi '0'+10
- push psw
- mov a,b
- call disp$A
- pop psw
-
- disp$A:
- mov d,a
- ;
- ;
- ;
- out$d$both:
- push d
- call wr$char$40
- pop d
- RJMP FR$wr$char
-
-