home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
MBUG
/
MBUG097.ARC
/
WINDOW.MAC
< prev
Wrap
Text File
|
1979-12-31
|
46KB
|
2,711 lines
;
; *************************************************
; * *
; * WINDOW.SYS *
; * *
; * 512k/256k enhanced BIOS. *
; * System control window program. *
; * *
; * Copyright 1986/7/8 Peter Broughton. *
; * *
; *************************************************
;
;
;
;
true equ -1
false equ 0
version macro
db 'Version 2, 7th Jul., 1988'
endm
fake_standard equ false ; Makes Premium think it is a standard.
start_address equ 5D00h
num_fn_keys equ 12
fn_store equ 8000h-(num_fn_keys*128)
spare_fn_str equ fn_store-128 ; space for returning date, time
fn_key_1 equ 81h ; code returned by scn_in
fn_key_1_code equ 81h ; code in function string
fn_key_1_us equ '1'+80h ; code for new keyboard unshifted F1
fn_str_end equ 0FFh
fn_str_pause equ 0FEh
fn_str_wait equ 0FDh
window_key equ 0A0h ; this is the key returned by scn_in when
; user presses window combination
curs_key equ 90h ; values returned by scn_in for cursor keys
; start with this one
window_start equ 08000h+80+((80-num_cols)/2)
window_attr equ 1 ; value to put in attribute RAM if premium
; window size
num_lines equ 13
num_cols equ 40
def_bios_start equ 0E700h ; may not work unless bios start is this addr
print_s_line equ 5806h ; BIOS routine to update status line
; offsets in definition section of (MY!) BIOS
screen_colour equ 12Ah
status_on equ 3Ah
status_colour equ 228h
is_premium equ 21Ch
curs_key_tab equ 26Bh
click_length equ 223h
click_tone equ 224h
caps_lock equ 27Bh+17
cpu_speed equ 28Dh
fast_bit equ 2
speed_port equ 9
; graphic characters
pcg_1 equ 8Ch
char_tl equ pcg_1+0
char_t equ pcg_1+1
char_tr equ pcg_1+2
char_l equ pcg_1+3
char_bl equ pcg_1+4
char_br equ pcg_1+5
char_lm equ pcg_1+6
char_rm equ pcg_1+7
char_curs equ pcg_1+8
char_pause equ pcg_1+9
char_ctrl equ pcg_1+10
char_fn equ pcg_1+11
char_wait equ pcg_1+12
first_char equ 8800h+(16*(pcg_1-80h))
num_pcg equ 13
get_char equ 27Bh+0
get_rtc equ 27Bh+2
put_rtc equ 27Bh+4
con_out equ 27Bh+9
ptr_out equ 27Bh+11
col_latch equ 8
if fake_standard
vml equ 0
else
vml equ 1Ch
endif
; 128 bytes with addresses etc.
aseg
org 100h
.phase start_address-128
dw 8000h ; Min BIOS start
dw start_address ; Start address
dw end_code-start_address ; length
ds (start_address)-$
; Start of code
ld (save_sp),sp
ld sp,stack
; all used regs except a, bc, hl must be saved
push de
push ix
call do_checks
call save_screen
; main loop
main_loop:
call main_menu
m_lp1:
call get_a_key
jr nz,m_lp1
cp ' '
jr z,main_loop
call conv_upper
cp 'C'
jp z,set_curs_key
cp 'F'
jp z,set_fn
cp 'K'
jp z,set_click
cp 'M'
jp z,misc_functions
cp 'S'
jp z,screen_functions
cp 'T'
jp z,time_functions
cp 'W'
jp z,warm_boot
m_lp_2:
ld hl,last_key
cp (hl)
ld (hl),a
jr nz,m_lp_3
cp 'V'
call z,prt_version
cp 'X'-40h
call z,prt_hello_a
m_lp_3:
; ESC = exit
cp '['-40h
jr nz,m_lp1
exit_window:
call restore_screen
pop ix
pop de
ld sp,(save_sp)
ret
main_menu:
call prt_hello
call clear_lower
ld hl,main_menu_3
call print_string
ld hl,main_menu_4
call print_string
ld hl,main_menu_5
call print_string
ld hl,main_menu_6
call print_string
ld hl,main_menu_7
call print_string
ld hl,main_menu_8
call print_string
ld hl,main_menu_9
call print_string
xor a
ld (last_key),a
ret
prt_hello:
ld a,r
or a
ret nz
pop hl
prt_hello_a:
call clear_lower
call h_dec
ld hl,hello_1
call print_string
ld hl,hello_2
call print_string
ld hl,hello_3
call print_string
ld hl,hello_4
call print_string
ld hl,hello_5
call print_string
ld hl,hello_6
call print_string
call h_dec
xor a
ld (last_key),a
ret
h_dec:
ld hl,h31
ld b,4
h_d1:
ld a,(hl)
cp 255
jr z,h_d2
neg
ld (hl),a
inc hl
jr h_d1
h_d2:
inc hl
inc hl
inc hl
djnz h_d1
ret
hello_3:
dw window_start+(80*6)+((40-(h32-h31))/2)
h31: db -'B',-'r',-'o',-'u',-'g',-'h',-'t',-' ',-'t',-'o',-' '
db -'y',-'o',-'u',-' ',-'b',-'y',-' ',-'t',-'h',-'e',-' '
db -'p',-'r',-'o',-'g',-'r',-'a',-'m',-'m',-'i',-'n',-'g'
h32: db 255
hello_4:
dw window_start+(80*7)+((40-(h42-h41))/2)
h41: db -'s',-'k',-'i',-'l',-'l',-'s',-' ',-'o',-'f',-' '
db -'P',-'e',-'t',-'e',-'r',-' '
db -'B',-'r',-'o',-'u',-'g',-'h',-'t',-'o',-'n',-'.'
h42: db 255
hello_5:
dw window_start+(80*8)+((40-(h52-h51))/2)
h51: db -'N',-'o',-'t',-'e',-':',-' ',-'T',-'h',-'i',-'s',-' '
db -'i',-'s',-' ',-'i',-'n',-'e',-'x',-'p',-'e',-'n',-'s',-'i'
db -'v',-'e',-' ',-'S',-'/',-'W',-','
h52: db 255
hello_6:
dw window_start+(80*9)+((40-(h62-h61))/2)
h61: db -'p',-'l',-'e',-'a',-'s',-'e',-' ',-'d',-'o',-'n',-'''',-'t'
db -' ',-'c',-'o',-'p',-'y',-' ',-'i',-'t',-' '
db -'i',-'l',-'l',-'e',-'g',-'a',-'l',-'l',-'y',-' ',-'!',-'!'
h62: db 255
; The above lines read :
;Microbee 512k/256k
;Enhanced Operating System v2.2
;Brought to you by the programming
;skills of Peter Broughton.
;Note: This is inexpensive S/W,
;please don't copy it illegally !!
prt_version:
call clear_lower
ld hl,hello_1
call print_string
ld hl,hello_2
call print_string
ld hl,version_1
call print_string
ld hl,version_2
call print_string
xor a
ld (last_key),a
ret
hello_1:
dw window_start+(80*4)+((40-(h12-h11))/2)
h11: db 9,9,' Microbee 512k/256k ',13,13
h12: db 255
hello_2:
dw window_start+(80*5)+((40-(h22-h21))/2)
h21: db 'Enhanced Operating System v2.2'
h22: db 255
; System Setup Window.
; Version x.x, xx/xx/xx.
version_1:
dw window_start+(80*6)+((40-(v12-v11))/2)
v11: db 'System Setup Window.'
v12: db 255
version_2:
dw window_start+(80*7)+((40-(v22-v21))/2)
v21: version
v22: db 255
do_function:
sub fn_key_1
; jump to this point will 'do' fn in A ( 0.. , or -1 for time/date stamp )
do_fn_A:
add a,high (fn_store*2)
ld c,0
srl a
rr c
ld b,a
ld hl,def_bios_start+27Bh+6
ld (hl),true
inc hl
ld (hl),c
inc hl
ld (hl),b
jp exit_window
misc_functions:
call clear_lower
ld hl,misc_fn_1
call print_string
ld hl,misc_fn_2
call print_string
mf_1:
call get_a_key
call conv_upper
cp 'F'
jr z,set_fast
cp 'S'
jr z,set_slow
cp '['-40h
jr nz,mf_1
jp main_loop
set_fast:
ld a,true
sf_1:
ld (def_bios_start+cpu_speed),a
and fast_bit
in a,(speed_port)
jr mf_1
set_slow:
xor a
jr sf_1
warm_boot:
; must reset pointers to extended command line
ld hl,def_bios_start+15Ch
ld e,(hl)
ld (hl),60h ; low (bios_start)+160h
inc hl
ld (hl),h ; high (bios_start)+160h
inc hl
ld (hl),128 ; total length of command buffer
inc hl
ld (hl),0 ; length of command buffer used
inc hl
ld d,h
ld a,e
cp 60h
jr c,w_b_5 ; illegal if e < 60h
; cp 60h+128 ; or if e > 60h+128
; jr nc,w_b_5 ; then fill buffer with 0h's
; at this stage hl --> start of command buffer
; de --> start of valid section of command line
; now move back valid section to start of command buffer
w_b_4:
ld a,e
cp 60h+128
jr nc,w_b_5
ld a,(de)
ld (hl),a
inc hl
inc de
jr w_b_4
w_b_5:
; pad rest of line with 0h's
ld a,l
cp 60h+128
jr z,w_b_6
ld (hl),0
inc hl
jr w_b_5
w_b_6:
call clear_lower
ld hl,w_boot_1
call print_string
ld hl,w_boot_2
call print_string
ld hl,w_boot_3
call print_string
ld hl,w_boot_4
call print_string
w_b2:
call get_a_key
call conv_upper
cp 'B'
jr z,do_boot
cp 'S'
jr z,force_shell
cp 'C'
jr z,force_ccp
cp 'E'
jr z,mod_com
cp '['-40h
jr nz,w_b2
jp main_loop
; force to boot to shell
force_shell:
ld a,1
jr w_b3
force_ccp:
xor a
w_b3:
ld (def_bios_start+128h),a
; do the actual boot
do_boot:
call restore_screen
call clear_screen
ld hl,def_bios_start
inc hl
inc hl
inc hl
jp (hl)
; modify command line
mod_com:
ld hl,def_bios_start+160h
push hl
ld de,temp_string
ld bc,128
ldir
xor a
call clear_lower
call enter_string
pop de
jp z,warm_boot
ld hl,temp_string
ld bc,128
ldir
jp warm_boot
set_click:
call clear_lower
ld hl,click_1
call print_string
ld hl,click_2
call print_string
s_cl1:
call get_a_key
call conv_upper
cp '['-40h
jp z,main_loop
cp '1'
jr c,s_cl1
cp '9'+1
jr c,s_cl_tone
cp 'L'
jr nz,s_cl1
s_cl_len:
call get_a_key
jr nz,s_cl_len
sub '0'
jr c,s_cl1
cp 9+1
jr nc,s_cl1
ld hl,click_lengths
ld de,def_bios_start+click_length
s_cl2:
ld b,0
ld c,a
add hl,bc
ld a,(hl)
ld (de),a
jr s_cl1
s_cl_tone:
sub '1'
ld hl,click_tones
ld de,def_bios_start+click_tone
jr s_cl2
; program function keys
set_fn:
call clear_lower
s_fn3:
ld hl,set_fn_1
call print_string
ld hl,set_fn_2
call print_string
ld hl,set_fn_3
call print_string
ld a,(def_bios_start+220h)
ld hl,set_fn_on ; fn active message
or a
jr nz,s_fn4
ld hl,set_fn_off
s_fn4:
call print_string
s_fn1:
call get_a_key
call conv_upper
cp 'O'
jr z,fn_toggle
cp 'N'
jr z,fn_number
cp '['-40h
jp z,main_loop
; any one of a number of keys can get fn up : '1'.. (&'"','#','$','%'),
; F1.., 'unshifted' F1..
cp '"'
jr c,s_fn9
cp '%'+1
jr nc,s_fn8
; convert to F9..F12 (8..11)
sub '"'-8
jr s_fn10
s_fn8:
or 80h
s_fn9:
; convert '1'+80h to F1
cp fn_key_1_us
jr c,s_fn7
sub fn_key_1_us-fn_key_1
s_fn7:
cp fn_key_1
jr c,s_fn1
cp fn_key_1+num_fn_keys
jr nc,s_fn1
; function key is pressed so program it, first find its memory location
sub fn_key_1
s_fn10:
; and save its number (0.. ) for later printing
push af
ld l,0
srl a
rr l
add a,high fn_store
ld h,a
ld (prog_fn_addr),hl
ld de,temp_string
ld bc,128
ldir
call clear_lower
ld hl,window_start+(4*80)+4
ld (hl),char_fn
inc hl
pop af
; print fn number, first is it =>F10 ( 9 actually since now F1 = 0 )
cp 9
jr c,s_fn6
ld (hl),'1'
inc hl
sub 10 ; convert to second digit
s_fn6:
add a,'1'
ld (hl),a
ld a,true
call enter_string
jp z,s_fn3
ld hl,temp_string
ld de,(prog_fn_addr)
ld bc,128
ldir
jp set_fn
; toggle function keys on/off
fn_toggle:
call fn_tog1
jp s_fn3
fn_tog1:
ld hl,def_bios_start+220h
ld a,(hl)
xor true
ld (hl),a
ret
; assign numbers to unshifted function keys ( for Simply Write etc.)
fn_number:
ld hl,fn_num_1
call print_string
fn_n_1:
call get_a_key
jr nz,fn_n_1
call conv_upper
cp 'Y'
jp nz,set_fn
ld hl,fn_store
ld b,8
ld a,'1'
ld de,127
s_fn5:
ld (hl),a
inc hl
ld (hl),fn_str_end
add hl,de
inc a
djnz s_fn5
jp set_fn
; enter text into 128 byte buffer (temp_string)
; max 127 chars
; a is true for function string, ie. allow entering of control codes, etc.,
; false for command line, no control codes.
; returns nz if can save, ie. wasn't aborted
enter_string:
ld ix,fn_flag
ld (ix),a
or a
ld a,fn_str_end ; if true then end char is 0FFh or whatever
jr nz,es_2
xor a ; else is 0h
es_2:
ld hl,temp_string
ld c,0
es_3:
cp (hl)
jr z,es_4 ; found end
inc c ; one more char in valid line
bit 7,c ; has it gone too far
jr nz,es_8
inc hl
jr es_3
; physical end found first
es_8:
ld (hl),a ; give it an end char
dec c
es_4:
ld a,c
ld (line_length),a
call clear_p_lower
ld hl,ent_str_1
call print_string
bit 0,(ix)
jr z,es_10
ld hl,ent_str_2
call print_string
ld hl,ent_str_3
call print_string
ld hl,ent_str_4
call print_string
es_10:
xor a
; this is the main loop that is gone through once for every successful key
new_c_pos_1:
ld (pointer),a ; where cursor is
call print_line
es_1:
ld a,(pointer)
ld c,a
call get_a_key_c
jr nz,es_1
bit 7,(ix)
jr nz,es_15
call conv_upper ; convert to upper case if command line
jr es_17 ; and skip the next stuff
es_15:
; controls that are only available when entering function string
cp 'P'-40h
jp z,es_pause ; enter pause
cp 'W'-40h
jp z,es_wait
cp '^'
jp z,es_lit ; enter CTRL code
; is 'unshifted' function key pressed
; cp fn_key_1_us
; jr c,es_16
; cp fn_key_1_us+num_fn_keys
; jp c,es_chain
;es_16:
; is function key pressed (ie. chain to new function)
cp fn_key_1
jr c,es_17
cp fn_key_1+num_fn_keys
jp c,es_chain
; controls available for entering fn and command
es_17:
cp 80h ; don't let through any other high bit codes
jr nc,es_1
cp 127
jp z,es_del_u
cp ' '
jp nc,es_norm
cp 'A'-40h
jr z,es_left_lots
cp 'D'-40h
jr z,es_right
cp 'E'-40h
jr z,es_start
cp 'F'-40h
jr z,es_right_lots
cp 'G'-40h
jr z,es_del_u
cp 'H'-40h
jp z,es_del
cp 'S'-40h
jr z,es_left
cp 'X'-40h
jr z,es_end
cp 'Y'-40h
jr z,es_kill
cp '['-40h
jr z,es_quit
cp 'M'-40h
jr nz,es_1
; <RETURN> : return nz
or 0FFh
; <ESC> : return z
es_quit:
push af
call clear_lower
pop af
ret
; ^A : 8 left
es_left_lots:
ld a,c
sub 8
jr nc,new_c_pos
; ^E : start of line
es_start:
xor a
jr new_c_pos
; ^S : 1 left
es_left:
ld a,c
dec a
cp 255
jr nz,new_c_pos
jr es_start
; ^D : 1 right
es_right:
ld a,c
inc a
check_right:
ld b,a
ld a,(line_length)
inc a
ld c,a
ld a,b
cp c
jr c,new_c_pos
; ^X : end of line
es_end:
ld a,(line_length)
new_c_pos:
jp new_c_pos_1
; ^F : 8 right
es_right_lots:
ld a,c
add a,8
jr check_right
; ^Y : delete line
es_kill:
ld hl,temp_string
ld b,128
xor a
bit 0,(ix)
jr z,es_k1
ld a,fn_str_end
es_k1:
ld (hl),a
inc hl
djnz es_k1
xor a
ld (line_length),a
jr new_c_pos
; BS : delete char to left
es_del:
xor a
or c
jp z,es_1
call del_char
dec a
jr new_c_pos
; ^G, DEL : delete char under (above) cursor
es_del_u:
ld a,(line_length)
cp c
jp z,es_1
inc c
call del_char
jr new_c_pos
; ^ : enter control code
es_lit:
call get_a_key_c
jr nz,es_lit
cp 7Fh ; let through DEL char
jr z,es_norm
cp '^' ; let through ^
jr z,es_norm
and 31 ; else convert to CTRL
jr es_norm
; ^P : enter pause char into string
es_pause:
ld a,fn_str_pause
jr es_norm
; ^W : enter wait char into string
es_wait:
ld a,fn_str_wait
; jr es_norm
; chain to new function
es_chain:
; enter character in A into string
es_norm:
push af
ld a,(line_length)
cp 127 ; is line already full
jr z,str_full
inc a
ld (line_length),a
ld hl,temp_string+126 ; move rest of string to right
ld d,h
ld e,l
inc de
ld a,127
sub c ; num chars to move
ld c,a
ld b,0
lddr
pop af
ld (de),a ; insert new char
ld a,(pointer)
inc a
jp new_c_pos
str_full:
pop af
jp es_1
; toggle function keys on/off so that 'unshifted' F1.. can be entered
; with a standard keyboard
;es_fn_toggle:
; call fn_tog1
; jp es_1
; delete char to left of c, ie. move chars from c to end left one
; return current pointer in a
del_char:
ld b,0
ld hl,temp_string
add hl,bc
ld d,h
ld e,l
dec de
ld a,128
sub c
ld c,a
ldir
ld hl,line_length
dec (hl)
ld a,(pointer)
ret
; print section of line around cursor position ( in A )
; Try to position cursor at 13th column from start of line,
; else somewhere to left of this.
print_line:
; clear cursor line first
ld hl,window_start+(80*5)+8
ld b,28
p_l12:
ld (hl),' '
inc hl
djnz p_l12
; find pos to start display from
ld hl,temp_string
ld c,a
ld b,0
add hl,bc
ld b,16
ld c,a
p_l1:
dec hl
dec c
ld a,(hl)
; if chain to new fn then can display 1 or 2 less chars
; ditto for 'unshifted' F1..
cp fn_key_1_us
jr c,p_l19
cp fn_key_1_us+num_fn_keys
jr nc,p_l19
sub fn_key_1_us-fn_key_1
p_l19:
cp fn_key_1
jr c,p_l17
cp fn_key_1+num_fn_keys
jr nc,p_l17
dec b
jr z,p_l3
cp fn_key_1+9 ; >=F10 so 2 chars
jr nc,p_l18
p_l17:
cp ' ' ; ditto for control code
jr nc,p_l2
p_l18:
dec b
jr z,p_l3
p_l2:
djnz p_l1
p_l3:
bit 7,c
jr z,p_l10
; cursor is close to start of line and the above code went back too far so..
ld c,0
ld hl,temp_string
p_l10:
; at this stage HL should point to the start of the section to be displayed
; and C should contain the number of the character to start display with
ex de,hl
ld hl,window_start+(80*4)+8
; load B with end of line character
ld b,0
bit 0,(ix)
jr z,p_l7
ld b,fn_str_end
p_l7:
; loop printing characters until full or end of line encountered
p_l11:
; is this where the cursor is
ld a,(pointer)
cp c
jr nz,p_l8
push bc
push hl
ld bc,80
add hl,bc
ld (hl),char_curs ; if yes then print cursor on line below
pop hl
pop bc
p_l8:
ld a,(de)
cp b ; end of line
jr z,p_l4
cp fn_str_pause ; pause character
jr nz,p_l5
ld a,char_pause
jr p_l6
p_l5:
cp fn_str_wait ; wait character
jr nz,p_l21
ld a,char_wait
jr p_l6
p_l21:
cp fn_key_1 ; chain to fn
jr c,p_l15
; call check_eol
; jr z,p_l13
ld (hl),char_fn
; is it actually 'unshifted' F1..
; cp fn_key_1_us
; jr c,p_l20
; ld (hl),char_fn_us
; sub fn_key_1_us-fn_key_1
p_l20:
inc hl
sub fn_key_1
cp 9
jr c,p_l16
ld (hl),'1'
inc hl
sub 10
p_l16:
add a,'1'
jr p_l6
p_l15:
cp ' '
jr nc,p_l6
; call check_eol
; jr z,p_l13 ; not enough room on line
ld (hl),char_ctrl ; control character
inc hl
add a,40h
p_l6:
ld (hl),a ; put it on the screen
; next character until end
inc hl
inc de
inc c
; end of physical line, should not reach here as there should be an
; EOL character
ld a,128
cp c
jr z,p_l13
push bc
ld bc,window_start+(80*4)+8+24
or a
push hl
sbc hl,bc
pop hl
pop bc
jr c,p_l11
jr p_l13
; finished printing line but must add end of line character
p_l4:
ld (hl),13
inc hl
; now clear any unused positions
p_l13:
ex de,hl
ld hl,window_start+(80*4)+8+25+2 ; +2 for a bit extra
or a
sbc hl,de
ld b,l ; num unused
ex de,hl
p_l14:
ld (hl),' '
inc hl
djnz p_l14
; print number of characters on line
print_bin:
ld hl,window_start+(5*80)+28
ld c,false ; leading zero flag
ld a,(line_length)
; hundred
cp 100
ld b,' '
jr c,p_b_1
ld b,'1'
ld c,true
sub 100
p_b_1:
ld (hl),b
inc hl
; tens
ld d,10
ld e,0
p_b_3:
sub d
jr c,p_b_2
inc e
jr p_b_3
p_b_2:
add a,d
ld d,a
ld a,c ; blank if =0 and is leading number
or e
ld a,' '
jr z,p_b_4
ld a,'0'
add a,e
p_b_4:
ld (hl),a
inc hl
; units
ld a,'0'
add a,d
ld (hl),a
inc hl
ex de,hl
ld hl,char_word
ld bc,len_char_word
ldir
ld a,(line_length)
cp 1
ld a,' '
jr z,p_b_5
ld a,'s'
p_b_5:
ld (de),a
ret
char_word:
db ' char'
len_char_word equ $-char_word
; have we reached end of usable line
;check_eol:
; push bc
; ld bc,window_start+(80*4)+8+23
; or a
; push hl
; sbc hl,bc
; pop hl
; pop bc
; ret
; define premium cursor control keys
set_curs_key:
call clear_lower
ld hl,set_curs_1
call print_string
s_ck1:
call get_a_key
cp '['-40h
jp z,main_loop
cp curs_key
jr c,s_ck1
cp curs_key+10h
jr nc,s_ck1
; key has been found
s_ck3:
and 0Fh
ld hl,def_bios_start+curs_key_tab
ld c,a
ld b,0
add hl,bc
push hl
ld b,(hl) ; present value
ld hl,set_curs_2
call print_string
ld hl,set_curs_3
call print_string
ld hl,window_start+6*80+22 ; print it
ld a,b
cp ' '
jr nc,s_ck8
ld (hl),'^'
inc hl
add a,40h
s_ck8:
ld (hl),a
s_ck7:
call get_a_key_c ; get value to replace it with
jr nz,s_ck7
cp 80h ; don't want a 'key' above 80h
jr nc,s_ck7
pop hl
ld (hl),a ; put it in table
jr set_curs_key
time_functions:
ld a,(no_clock)
or a
jp nz,main_loop
call clear_lower
ld hl,time_1
call print_string
ld hl,time_2
call print_string
ld hl,time_3
call print_string
ld hl,time_4
call print_string
ld hl,time_5
call print_string
ld hl,time_6
call print_string
t_f1:
ld hl,spare_fn_str ; space for returning time
call get_a_key
cp '['-40h
jp z,main_loop
call conv_upper
cp '1'
jp z,date_st_1
cp '2'
jp z,date_st_2
cp '3'
jp z,date_st_3
cp '4'
jp z,date_st_4
cp 'T'
jp z,time_st
cp 'S'
jr nz,t_f1
; Set time, date
call clear_lower
ld hl,set_time_1
call print_string
ld hl,set_time_2
call print_string
ld hl,set_time_3
call print_string
ld hl,set_time_4
call print_string
ld ix,t_f_digits_info
ld hl,time
ld de,entered_time
ld bc,10
ldir
s_t_1:
push ix
ld ix,entered_time
call s_t_dow
jr z,s_t_18
call s_t_getdays ; if illegal then
dec a ; try max date for month
ld (entered_time+2),a
call s_t_dow
jr z,s_t_18
ld a,1 ; still illegal then
ld (entered_time),a ; reset date to 1st Jan 1901
ld (entered_time+1),a
ld (entered_time+2),a
ld a,3 ; which is a Tuesday
s_t_18:
ld (entered_time+3),a
ld hl,window_start+(80*4)+7
call display_time
pop ix
ld hl,window_start+(80*5)
call clear_a_line
ld hl,window_start+(80*5)
ld d,0
ld e,(ix+0)
add hl,de
ld b,(ix+1)
s_t_3:
ld (hl),char_curs
inc hl
djnz s_t_3
ld hl,entered_time
ld e,(ix+4)
add hl,de
s_t_2:
call get_a_key
call conv_upper
cp 'M'-40h
jp z,save_time
cp '['-40h
jp z,time_functions
cp 'D'
jp z,save_date
cp 'Z'-40h
jp z,s_t_zero_digits
ld bc,-6
cp 93h ; Left
jp z,s_t_move_digits
cp 'S'-40h
jp z,s_t_move_digits
ld bc,6
cp 96h ; Right
jr z,s_t_move_digits
cp 'D'-40h
jr z,s_t_move_digits
ld c,1
cp 90h ; Up
jr z,s_t_inc_digits
cp 'E'-40h
jr z,s_t_inc_digits
ld c,(ix+5)
cp 98h ; Shift Up
jr z,s_t_inc_digits
cp 'R'-40h
jr z,s_t_inc_digits
cp 9Ah ; Shift Down
jr z,s_t_dec_digits
cp 'C'-40h
jr z,s_t_dec_digits
ld c,1
cp 92h ; Down
jr z,s_t_dec_digits
cp 'X'-40h
jr nz,s_t_2
s_t_dec_digits:
ld a,(hl)
sub c
daa
ld b,a
ld a,(ix+3) ; maximum +1
cp 0FFh ; date? then get max for month
call z,s_t_getdays
or a
ld c,a
ld a,b
jr z,s_t_24 ; special case for years
ld b,(ix+2) ; minimum limit
cp b
jr nc,s_t_8
s_t_7:
sub b
daa
add a,c
daa
jr s_t_6
s_t_8:
cp c
jr nc,s_t_7
s_t_6:
ld (hl),a
jp s_t_1
s_t_24:
or a
jr nz,s_t_6
ld a,99h
jr s_t_6
s_t_inc_digits:
ld a,(hl)
add a,c
daa
ld b,a
ld a,(ix+3)
cp 0FFh ; is this date? then get max for month
call z,s_t_getdays
or a
ld c,a
ld a,b
jr z,s_t_23 ; special case for years
cp c
jr c,s_t_6
sub c
daa
add a,(ix+2)
daa
jr s_t_6
s_t_23:
or a
jr nz,s_t_6
inc a
jr s_t_6
s_t_zero_digits:
ld a,(ix+2)
jr s_t_6
s_t_move_digits:
add ix,bc
push ix
pop hl
ld d,h
ld e,l
ld bc,t_f_digits_info
xor a
sbc hl,bc
jr c,s_t_m_left
ld h,d
ld l,e
ld bc,t_f_digits_end
sbc hl,bc
jp c,s_t_1
; too far to right
ld ix,t_f_digits_info
jp s_t_1
; too far to left
s_t_m_left:
ld ix,t_f_digits_end-6
jp s_t_1
save_time:
ld b,10 ; 10 regs
s_t_9:
ld de,put_rtc
call get_address
ld (call_p_rtc+1),hl
ld hl,entered_time
ld e,0 ; read from reg 0
call_p_rtc:
call 0
jp time_functions
; only change date, leave time unaltered
save_date:
ld b,4 ; 4 regs only
jr s_t_9
; Return in A day of week of date (1 = SUN)
; also returns nz if illegal
; destroys - BC, DE, HL
s_t_dow:
; push de
; push hl
ld hl,2-1 ; 1st Jan 1901 = Tuesday but sub 1 extra
ld a,(ix+0) ; year
or a
jr z,s_t_d_err
call conv_bin
dec a
ld c,a
ld b,0
add hl,bc ; one extra day per year
xor a
srl c ; leap years
rra
srl c
rra
add hl,bc ; and one more for each completed leap year
cp 0C0h ; is this a leap year ?
ld a,(ix+1) ; months
jr nz,s_t_21
cp 3 ; and after Feb ?
jr c,s_t_21
inc hl ; then add 1 to day
s_t_21:
call conv_bin
dec a ; month 0..11
cp 12
jr nc,s_t_d_err
or a
jr z,s_t_19
ld de,days_in_month
s_t_20: ; count number of days in completed month
push af
ld a,(de)
call conv_bin
dec a
ld c,a
add hl,bc
pop af
inc de
dec a
jr nz,s_t_20
s_t_19:
ld a,(ix+2) ; date
or a
jr z,s_t_d_err
ld c,a
call s_t_getdays
dec a ; max for month
cp c
jr c,s_t_d_err ; illegal if max<date
ld a,c
call conv_bin
ld c,a
add hl,bc
; xor a ; clear carry, but add hl,bc does it
ld c,7 ; MOD 7
s_t_22:
sbc hl,bc
jr nc,s_t_22
ld a,l ; now -7..-1
add a,c ; now 0..6
inc a ; now 1..7
cp a ; makes Z - legal date
; pop hl
; pop de
ret
s_t_d_err:
or 0FFh ; makes NZ - illegal date
ret
; Return in A days+1 in month
s_t_getdays:
push bc
push hl
ld hl,days_in_month-1
ld a,(entered_time+1) ; get month
call conv_bin
ld c,a
ld b,0
add hl,bc
ld a,c
cp 2
ld a,(hl) ; get days in month
jr nz,s_t_14
; February :
ld c,a
ld a,(entered_time) ; get year
and 3 ; see if leap year
ld a,c
jr nz,s_t_14
inc a ; inc for leap year
s_t_14:
pop hl
pop bc
ret
days_in_month:
; actually days+1 (BCD) for compatability with checking code
; db Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
; db 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
db 32h, 29h, 32h, 31h, 32h, 31h, 32h, 32h, 31h, 32h, 31h, 32h
t_f_digits_info:
; db pos. of digits, num. of digits, min., max.+1 (BCD), reg., incr
db 7, 2, 0, 24h, 4, 12 ; hour
db 10, 2, 0, 60h, 5, 10 ; min
db 13, 2, 0, 60h, 6, 10 ; sec
; db 19, 3, 1, 08h, 3, 0 ; day -- will be handled by DOW code
db 24, 2, 1,0FFh, 2, 10 ; date -- FFh -> depends on month
db 27, 3, 1, 13h, 1, 6 ; month
db 31, 2, 1, 00h, 0, 10 ; year
t_f_digits_end equ $
date_st_1:
call d_s_pr_date
ld (hl),' '
inc hl
call d_s_pr_month
d_s_1:
ex de,hl ; print ', 19'
ld hl,d_s_year
ld bc,len_d_s_year
ldir
ex de,hl
ld a,(time) ; year
call print_bcd
do_time_fn:
ld (hl),fn_str_end
ld a,-1 ; spare function number
jp do_fn_a
date_st_2:
call d_s_pr_month
ld (hl),' '
inc hl
call d_s_pr_date
jr d_s_1
d_s_year:
db ', 19'
len_d_s_year equ $-d_s_year
d_s_pr_date:
ld a,(time+2) ; date
ld c,a
call print_bcd_1
ld de,'t'*256+'h' ; 4th etc
ld a,0F0h
and c
cp 10h ; skip 11th, 12th etc.
jr z,d_s_2
ld a,0Fh
and c
cp 1
jr nz,d_s_3
ld de,'s'*256+'t' ; 1st etc
jr d_s_2
d_s_3:
cp 2
jr nz,d_s_4
ld de,'n'*256+'d' ; 2nd etc
jr d_s_2
d_s_4:
cp 3
jr nz,d_s_2
ld de,'r'*256+'d' ;3rd etc
d_s_2:
ld (hl),d
inc hl
ld (hl),e
inc hl
ret
d_s_pr_month:
ex de,hl
ld hl,month_1
ld a,(time+1) ; month
call conv_bin
dec a
ld c,a ; *3
add a,c
add a,c
ld c,a
ld b,0
add hl,bc
ld bc,3
ldir
ex de,hl
ld a,(time+1)
cp 5
ret z ; if not May then add '.'
ld (hl),'.'
inc hl
ret
; date 16/1/86
date_st_3:
ld a,(time+2)
call print_bcd_1
ld (hl),'/'
inc hl
ld a,(time+1)
d_s_3_1:
call print_bcd_1
ld (hl),'/'
inc hl
ld a,(time+0)
call print_bcd
jp do_time_fn
; date 1/16/86 - American (yuk) format
date_st_4:
ld a,(time+1)
call print_bcd_1
ld (hl),'/'
inc hl
ld a,(time+2)
jr d_s_3_1
time_st:
ld c,'A'
ld a,(time+4) ; hours
or a
jr nz,t_s_1
ld a,12h ; 12 AM (midnight)
t_s_1:
cp 13h
jr c,t_s_2
sub 12h ; 1..11 PM
daa
ld c,'P'
t_s_2:
cp 12h
jr nz,t_s_5
ld c,'P' ; 12 PM (midday)
t_s_5:
call print_bcd_1
ld (hl),':'
inc hl
ld a,(time+5) ; minutes
call print_bcd
ld (hl),' '
inc hl
ld (hl),c ; A or P
inc hl
ld (hl),'M'
inc hl
jp do_time_fn
screen_functions:
call clear_lower
ld hl,screen_1
call print_string
ld hl,screen_2
call print_string
ld hl,screen_3
call print_string
ld hl,screen_4
call print_string
ld hl,screen_5
call print_string
ld hl,screen_6
call print_string
ld hl,screen_7
call print_string
ld a,(def_bios_start+is_premium)
ld ix,premium_col_masks
or a
jr nz,sc_f_1
ld ix,standard_col_masks
sc_f_1:
call get_a_key
cp '['-40h
jp z,main_loop
ld b,a
ld a,(colour_fitted)
or a
ld a,b
jr z,sc_f_5
ld hl,def_bios_start+caps_lock
bit 0,(hl)
jr z,sc_f_12
; caps lock is on
xor 'a'-'A' ; removes effect of caps lock
sc_f_12:
ld c,false ; 'increment'
cp 'a' ; if upper case then shift is pressed
jr nc,sc_f_11
ld c,true ; 'decrement' flag
sc_f_11:
call conv_upper
cp 'F'
jp z,sc_f_fore
cp 'B'
jp z,sc_f_back
cp 'C'
jp z,sc_f_w_fore
cp 'V'
jp z,sc_f_w_back
sc_f_5:
call conv_upper
cp 'L'
jp z,sc_f_w_toggle
ld bc,7*256+1 ; up
cp 90h
jr z,sc_f_move
cp 'E'-40h
jr z,sc_f_move
ld bc,7*256+255 ; down
cp 92h
jr z,sc_f_move
cp 'X'-40h
jr z,sc_f_move
ld bc,2*256+1 ; left
cp 93h
jr z,sc_f_move
cp 'S'-40h
jr z,sc_f_move
ld bc,2*256+255 ; right
cp 96h
jr z,sc_f_move
cp 'D'-40h
jr nz,sc_f_1
sc_f_move:
ld hl,def_bios_start
ld a,34h
add a,b
ld e,a
ld d,0
add hl,de
ld a,(hl)
add a,c
ld (hl),a
ld c,a
ld a,b
out (12),a
ld a,c
out (13),a
jp sc_f_1
sc_f_fore:
ld a,c ; true to decrement
ld hl,def_bios_start+screen_colour
ld b,(hl)
ld c,b
inc c ; increment
or a
jr z,sc_f_3
dec c ; no actually decrement
dec c
sc_f_3:
ld a,(ix+0) ; 0Fh / 1Fh
and c
ld c,a
ld a,(ix+1) ; 0F0h / 0E0h
sc_f_2:
and b
add a,c
ld (hl),a
ld c,a
ld a,40h
out (8),a
ld hl,8800h
ld (hl),c
ld de,8801h
ld bc,24*80-1
ldir
call window_colour
jp sc_f_1
sc_f_back:
ld hl,def_bios_start+screen_colour
ld b,(hl)
ld a,b
ld d,(ix+2) ; 10h / 20h
add a,d ; increment
bit 0,c ; true to decrement
jr z,sc_f_4
sub d ; no actually decrement
sub d
sc_f_4:
and (ix+1)
ld c,a
ld a,(ix+0) ; 0Fh, 1Fh
jr sc_f_2
sc_f_w_fore:
ld a,c ; true to decrement
ld hl,def_bios_start+status_colour
ld b,(hl)
ld c,b
inc c ; increment
or a
jr z,sc_f_6
dec c ; no actually decrement
dec c
sc_f_6:
ld a,(ix+0)
and c
ld c,a
ld a,(ix+1)
sc_f_7:
and b
add a,c
ld (hl),a
ld c,a
ld a,40h
out (8),a
ld hl,8800h+24*80
ld (hl),c
ld a,c
ld de,8801h+24*80
ld bc,80-1
ldir
ld b,num_lines
ld hl,window_start+800h
ld de,80-num_cols
sc_f_10:
push bc
ld b,num_cols
sc_f_9:
ld (hl),a
inc hl
djnz sc_f_9
add hl,de
pop bc
djnz sc_f_10
xor a
out (8),a
jp sc_f_1
sc_f_w_back:
ld hl,def_bios_start+status_colour
ld b,(hl)
ld a,b
ld d,(ix+2) ; 10h / 20h
add a,d ; increment
bit 0,c ; true to decrement
jr z,sc_f_8
sub d ; no actually decrement
sub d
sc_f_8:
and (ix+1)
ld c,a
ld a,(ix+0)
jr sc_f_7
sc_f_w_toggle:
ld hl,def_bios_start+3Ah
ld a,(hl)
xor 1
ld (hl),a
ld b,a
ld a,6
out (12),a
ld a,b
out (13),a
jp sc_f_1
premium_col_masks:
db 0Fh,0F0h,10h
standard_col_masks:
db 1Fh,0E0h,20h
;
; start of house keeping routines etc.
;
; convert BCD to binary for calculations
conv_bin:
push bc
ld b,a
and 0Fh
ld c,a
ld a,b
and 0F0h
rra
rra
rra
rra
ld b,a
ld a,c
jr z,c_b_2
ld c,10
c_b_1:
add a,c
djnz c_b_1
c_b_2:
pop bc
ret
; get address contained at (bios_start+DE)
get_address:
ld hl,def_bios_start
add hl,de
ld e,(hl)
inc hl
ld h,(hl)
ld l,e
ret
; get a key from keyboard (bypasses function keys)
; also updates clock display
; returns Z if key pressed
get_a_key:
push hl
push de
call get_key_1
pop de
pop hl
ret
; as above but convert cursor code to control code, ignore window key etc.
get_a_key_c:
push hl
push de
call get_key_1
jr nz,g_k_1
cp fn_key_1_us
jr nc,got_a_key
cp window_key
jr nc,not_a_key
cp curs_key
jr c,got_a_key
; cp curs_key+16
; jr nc,got_a_key
and 0Fh
ld hl,def_bios_start+curs_key_tab
ld e,a
ld d,0
add hl,de
ld a,(hl)
got_a_key:
cp a
jr g_k_1
not_a_key:
or -1
g_k_1:
pop de
pop hl
ret
get_key_1:
push ix
push bc
ld a,(def_bios_start+status_on)
cp 25
call z,print_s_line
call read_time
ld ix,time
ld hl,window_start+(80*2)+7
call z,display_time
ld de,get_char
call get_address
ld (call_kbd_i+1),hl
call_kbd_i:
call 0
pop bc
pop ix
ret
; convert char in A to upper case
conv_upper:
cp 'a'
ret c
cp 'z'+1
ret nc
sub 'a'-'A'
ret
; read time from RTC and return z if changed from last time
read_time:
; but first, is it there ?
ld a,(no_clock)
or a
ret nz ; no it wasn't there - make sure no display occurs
ld de,get_rtc
call get_address
ld (c_r1+1),hl
ld hl,new_time
ld e,0 ; read from reg 0
ld b,10 ; 10 regs
c_r1:
call 0
; update main time regs and check if any change has occurred
ld bc,10*256 ; b with 10, c with false
ld de,new_time
ld hl,time
r_t1:
ld a,(de)
cp (hl)
ld (hl),a
jr z,r_t2
ld c,true ; a value has changed
r_t2:
inc de
inc hl
djnz r_t1
ld a,true
cp c ; z if changed
ret
; print time from (ix) to (hl)
display_time:
ld a,(ix+4) ; hours
ld c,'P'
sub 12h
daa
jr nc,dt_1
add a,12h
daa
ld c,'A'
dt_1:
or a
jr nz,dt_2
ld a,12h
dt_2:
cp 10h
jr nc,dt_3
ld (hl),' '
inc hl
dt_3:
call print_bcd_1
ld (hl),':'
inc hl
ld a,(ix+5) ; min
call print_bcd
ld (hl),':'
inc hl
ld a,(ix+6) ; sec
call print_bcd
inc hl
ld (hl),c
inc hl
ld (hl),'M'
inc hl
inc hl
ld c,(ix+3) ; day
dec c
ld a,c
add a,c ; *2
add a,c ; *3
ld c,a
ld b,0
ex de,hl
ld hl,day_1 ; --> day name
add hl,bc
ld c,3
ldir
ex de,hl
ld (hl),','
inc hl
inc hl
ld a,(ix+2) ; date
call print_bcd
ld (hl),'-'
inc hl
ld a,(ix+1) ; month
call conv_bin
dec a
ld c,a
add a,a ; *2
add a,c ; *3
ld c,a
ex de,hl
ld hl,month_1
add hl,bc
ld c,3
ldir
ex de,hl
ld (hl),'-'
inc hl
ld a,(ix+0) ; year
call print_bcd
ret
; print bcd num in a to (hl)
print_bcd:
push de
ld e,a
rra
rra
rra
rra
and 0Fh
add a,'0'
ld (hl),a
inc hl
ld a,e
and 0Fh
add a,'0'
ld (hl),a
inc hl
pop de
ret
; print bcd with leading zero blanking
print_bcd_1:
cp 10h
jr nc,print_bcd
add a,'0'
ld (hl),a
inc hl
ret
; subroutine to check for premium, colour and clock
do_checks:
; standard BIOS location has is_premium flag
ld ix,def_bios_start+is_premium
bit 0,(ix)
jr z,d_c_1
; is premium so get old value of vml and must have colour
in a,(vml) ; premium - VML latch, standard - same as 0Ch
ld (old_vml),a
ld a,true
ld (colour_fitted),a
jr d_c_2
; now check for colour
d_c_1:
ld hl,8800h
ld b,(hl)
ld a,40h
out (8),a
ld c,(hl)
ld a,b
cpl
ld d,a
ld (hl),a
xor a
out (8),a
ld a,(hl)
cp d
ld a,false
jr z,no_colour
ld a,true
no_colour:
ld (colour_fitted),a
ld (hl),b
ld a,40h
out (8),a
ld (hl),c
xor a
out (8),a
d_c_2:
; now check for clock
ld c,7
ld a,14
out (4),a
in b,(c)
ld a,14
out (4),a
ld a,85
out (6),a
ld a,14
out (4),a
in d,(c)
ld a,14
out (4),a
ld a,b
out (6),a
ld a,d
sub 85
ld (no_clock),a ; nz if no rtc present
ret
; save contents of screen, PCG, colour and attribute RAM as necessary
; and set up for window
save_screen:
; colour first
ld a,(colour_fitted)
or a
jr z,s_sc8
call window_colour
s_sc8:
; now attribute
bit 0,(ix)
jr z,s_sc9
ld a,90h
out (vml),a
ld a,window_attr
ld hl,window_start
ld de,temp_attr
call save_block
ld a,80h
out (vml),a
s_sc9:
; now screen
ld hl,window_start
ld de,temp_screen
ld a,' '
call save_block
; now inverse
bit 0,(ix)
jr z,s_sc10
ld a,80h+(window_attr and 0Fh) ; select PCG 1 if premium
out (vml),a
s_sc10:
ld hl,first_char
ld de,temp_inverse
ld bc,num_pcg*16
ldir
ld hl,inv_chars
ld de,first_char
ld bc,num_pcg*16
ldir
; now set up window on screen
ld hl,window_start
ld de,80-num_cols+1
ld (hl),' '
inc hl
ld (hl),char_tl
inc hl
ld b,num_cols-4
s_sc1:
ld (hl),char_t
inc hl
djnz s_sc1
ld (hl),char_tr
inc hl
ld (hl),' '
add hl,de
call clear_a_line
call clear_a_line
ld (hl),' '
inc hl
ld (hl),char_lm
inc hl
ld b,num_cols-4
s_sc2:
ld (hl),char_t
inc hl
djnz s_sc2
ld (hl),char_rm
inc hl
ld (hl),' '
add hl,de
ld bc,80*(num_lines-6)
add hl,bc
call clear_a_line
ld (hl),' '
inc hl
ld (hl),char_bl
inc hl
ld b,num_cols-4
s_sc4:
ld (hl),char_t
inc hl
djnz s_sc4
ld (hl),char_br
inc hl
ld (hl),' '
ld hl,top_line
call print_string
ld hl,esc_exit_1
call print_string
ret
window_colour:
ld hl,def_bios_start+228h
ld c,(hl)
ld a,40h
out (8),a
ld a,c
ld hl,window_start+800h
ld de,temp_col
call save_block
xor a
out (8),a
ret
; save screen section from any bank of RAM
; and fill with value in A
save_block:
ld b,num_lines
s_b2:
push bc
ld bc,num_cols
push hl
ldir
pop hl
ld b,num_cols
s_b1:
ld (hl),a
inc hl
djnz s_b1
ld c,80-num_cols
add hl,bc
pop bc
djnz s_b2
ret
; restore screen, colour, attribute and inverse
restore_screen:
; colour..
ld a,(colour_fitted)
or a
jr z,r_sc1
ld a,40h
out (8),a
ld hl,temp_col
ld de,window_start+800h
call restore_block
xor a
out (8),a
r_sc1:
; screen..
ld hl,temp_screen
ld de,window_start
call restore_block
; inverse..
ld hl,temp_inverse
ld de,first_char
ld bc,num_pcg*16
ldir
; attribute..
ld a,(def_bios_start+is_premium)
or a
ret z
ld a,90h
out (vml),a
ld hl,temp_attr
ld de,window_start
call restore_block
ld a,(old_vml)
out (vml),a
ret
restore_block:
ld b,num_lines
r_b1:
push bc
ld bc,num_cols
ldir
ld c,80-num_cols
ex de,hl
add hl,bc
ex de,hl
pop bc
djnz r_b1
ret
clear_lower:
ld hl,window_start+(80*4)
ld b,num_lines-6
cl_low1:
call clear_a_line
djnz cl_low1
ret
clear_p_lower:
ld hl,window_start+(80*5)
ld b,num_lines-7
jr cl_low1
clear_a_line:
push bc
ld (hl),' '
inc hl
ld (hl),char_l
inc hl
ld b,num_cols-4
cl_line1:
ld (hl),' '
inc hl
djnz cl_line1
ld (hl),char_l
inc hl
ld (hl),' '
ld de,80-num_cols+1
add hl,de
pop bc
ret
clear_screen:
ld hl,8000h
ld de,8001h
ld bc,7FEh
ld (hl),' '
ldir
ld a,(is_premium)
or a
jr z,cl_s1
xor a
out (vml),a
cl_s1:
; must set cursor address to 8000h
ld hl,def_bios_start+286h
ld (hl),0
inc hl
ld (hl),0
inc hl
ld (hl),0
inc hl
ld (hl),80h
ret
; print string pointed to by HL, starts with screen address, ends with 0FFh
print_string:
push de
ld e,(hl)
inc hl
ld d,(hl)
inc hl
prt_st1:
ld a,(hl)
cp 0FFh
jr z,prt_exit
ld (de),a
inc hl
inc de
jr prt_st1
prt_exit:
pop de
ret
top_line:
dw window_start+80+((40-(t_l2-t_l1))/2)
t_l1: db 'SYSTEM SETUP WINDOW'
t_l2: db 255
esc_exit_1:
dw window_start+(80*(num_lines-2))+5
db '<ESC> to exit.',255
main_menu_3:
dw window_start+(80*9)+5
db '<W> to Warm Boot,',255
main_menu_4:
dw window_start+(80*4)+5
db '<F> to set Function Keys,',255
main_menu_5:
dw window_start+(80*5)+5
db '<C> to set Cursor Keys,',255
main_menu_6:
dw window_start+(80*6)+5
db '<K> to set Key Click,',255
main_menu_7:
dw window_start+(80*8)+5
db '<T> for Clock Functions,',255
main_menu_8:
dw window_start+(80*7)+5
db '<S> for Screen Functions,',255
main_menu_9:
dw window_start+(80*10)+5
db '<M> for Miscellaneous.',255
day_1:
db 'SunMonTueWedThuFriSat'
month_1:
db 'JanFebMarAprMayJunJulAugSepOctNovDec'
misc_fn_1:
dw window_start+(80*4)+5
db '<F> for Fast CPU (6.75 MHz),',255
misc_fn_2:
dw window_start+(80*5)+5
db '<S> for Slow CPU (3.375 MHz).',255
click_1:
dw window_start+(80*4)+5
db '1..9 to set click pitch,',255
click_2:
dw window_start+(80*5)+5
db '<L> 0..9 to set length.',255
click_tones:
db 11,15,23,33,51,75,111,171,255 ; Odd
click_lengths:
db 0,1,3,5,7,11,15,21,31,45
set_fn_1:
dw window_start+(80*4)+5
db 'Select function ',char_fn,'1..',char_fn,'12,',255
set_fn_2:
dw window_start+(80*5)+5
db '<O> to toggle on/off (',255
set_fn_on:
dw window_start+(80*5)+5+22
db 'ON), ',255
set_fn_off:
dw window_start+(80*5)+5+22
db 'OFF),',255
set_fn_3:
dw window_start+(80*6)+5
db '<N> assign numbers to ',char_fn,'1..',char_fn,'8.',255
fn_num_1:
dw window_start+(80*8)+5
db 'Erases ',char_fn,'1..',char_fn,'8 !! Sure ?',255
ent_str_1:
dw window_start+(80*6)+5
db '<RETURN> to save line,',255
ent_str_2:
dw window_start+(80*7)+5
db '<^> to enter CTRL key,',255
ent_str_3:
dw window_start+(80*8)+5
db '^P to enter pause (',char_pause,'),',255
ent_str_4:
dw window_start+(80*9)+5
db '^W to enter wait (',char_wait,').',255
w_boot_1:
dw window_start+(80*4)+5
db '<B> to warm boot,',255
w_boot_2:
dw window_start+(80*5)+5
db '<S> to boot to Shell,',255
w_boot_3:
dw window_start+(80*6)+5
db '<C> to boot to CCP,',255
w_boot_4:
dw window_start+(80*7)+5
db '<E> to edit command line.',255
set_curs_1:
dw window_start+(80*4)+5
db 'Press cursor key to change.',255
set_curs_2:
dw window_start+(80*6)+10
db 'Currently - ',255
set_curs_3:
dw window_start+(80*8)+10
db 'Change to ?',255
time_1:
dw window_start+(80*4)+5
db '<S> Set time/date,',255
time_2:
dw window_start+(80*5)+5
db '<1> Date - 20th Dec., 1987,',255
time_3:
dw window_start+(80*6)+5
db '<2> Date - Dec. 20th, 1987,',255
time_4:
dw window_start+(80*7)+5
db '<3> Date - 20/12/87,',255
time_5:
dw window_start+(80*8)+5
db '<4> Date - 12/20/87 (U.S.),',255
time_6:
dw window_start+(80*9)+5
db '<T> Time stamp.',255
set_time_1:
dw window_start+(80*6)+5
db 'Use cursor keys to set,',255
set_time_▓:
dw window_start+(80*7)+5
db '^Z to zero digits,',255
set_time_3:
dw window_start+(80*8)+5
db '<RETURN> to save new time,',255
set_time_4:
dw window_start+(80*9)+5
db '<D> to save date only.',255
screen_1:
dw window_start+(80*4)+5
db 'Use cursor keys to move screen,',255
screen_2:
dw window_start+(80*5)+5
db '<F> foreground colour,',255
screen_3:
dw window_start+(80*6)+5
db '<B> background colour,',255
screen_4:
dw window_start+(80*7)+5
db '<C> window foreground,',255
screen_5:
dw window_start+(80*8)+5
db '<V> window background,',255
screen_6:
dw window_start+(80*9)+7
db '( <SHIFT> to reverse )',255
screen_7:
dw window_start+(80*10)+5
db '<L> status line on/off.',255
inv_chars:
;; top left
; db 000h,000h,000h,000h,00Fh,01Fh,01Ch,01Ch,01Ch,01Ch,01Ch
; db 01Ch,01Ch,01Ch,01Ch,01Ch
;; top, bottom
; db 000h,000h,000h,000h,0FFh,0FFh,000h,000h,000h,000h,000h
; db 000h,000h,000h,000h,000h
;; top right
; db 000h,000h,000h,000h,0F8h,0FCh,01Ch,01Ch,01Ch,01Ch,01Ch
; db 01Ch,01Ch,01Ch,01Ch,01Ch
;; left, right
; db 01Ch,01Ch,01Ch,01Ch,01Ch,01Ch,01Ch,01Ch,01Ch,01Ch,01Ch
; db 01Ch,01Ch,01Ch,01Ch,01Ch
;; bottom left
; db 01Ch,01Ch,01Ch,01Ch,01Fh,00Fh,000h,000h,000h,000h,000h
; db 000h,000h,000h,000h,000h
;; bottom right
; db 01Ch,01Ch,01Ch,01Ch,0FCh,0F8h,000h,000h,000h,000h,000h
; db 000h,000h,000h,000h,000h
;; middle left
; db 01Ch,01Ch,01Ch,01Ch,01Fh,01Fh,01Ch,01Ch,01Ch,01Ch,01Ch
; db 01Ch,01Ch,01Ch,01Ch,01Ch
;; middle right
; db 01Ch,01Ch,01Ch,01Ch,0FCh,0FCh,01Ch,01Ch,01Ch,01Ch,01Ch
; db 01Ch,01Ch,01Ch,01Ch,01Ch
; Alternate set with two lines ...
; top left
db 000h,000h,000h,000h,00Fh,010h,021h,022h,024h,024h,024h
db 024h,024h,024h,024h,024h
; top, bottom
db 000h,000h,000h,000h,0FFh,000h,0FFh,000h,000h,000h,000h
db 000h,000h,000h,000h,000h
; top right
db 000h,000h,000h,000h,0F0h,008h,084h,044h,024h,024h,024h
db 024h,024h,024h,024h,024h
; left, right
db 024h,024h,024h,024h,024h,024h,024h,024h,024h,024h,024h
db 024h,024h,024h,024h,024h
; bottom left
db 024h,024h,024h,022h,021h,010h,00Fh,000h,000h,000h,000h
db 000h,000h,000h,000h,000h
; bottom right
db 024h,024h,024h,044h,084h,008h,0F0h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h
; middle left
db 024h,024h,024h,022h,021h,020h,021h,022h,024h,024h,024h
db 024h,024h,024h,024h,024h
; middle right
db 024h,024h,024h,044h,084h,004h,084h,044h,024h,024h,024h
db 024h,024h,024h,024h,024h
; cursor for entering strings, time
db 0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h
; pause
; db 000h,000h,000h,000h,008h,014h,008h,000h,000h,000h,000h
db 000h,000h,000h,000h,03Ch,008h,01Eh,000h,000h,000h,000h
db 000h,000h,000h,000h,000h
; control code
db 000h,000h,008h,01Ch,036h,022h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h
; chain function
db 000h,03Eh,030h,030h,03Eh,030h,030h,030h,000h,000h,000h
db 000h,000h,000h,000h,000h
; wait
db 000h,000h,000h,03Eh,030h,03Eh,030h,030h,000h,000h,000h
db 000h,000h,000h,000h,000h
end_code equ $
; zero fill to end of CP/M record (128 bytes)
if ($ and 127) ne 0
ds 128-($ and 127)
endif
; start of uninitialised storage
save_sp equ end_code
stack equ save_sp+64+2
temp_screen equ stack
temp_inverse equ temp_screen+(num_lines*num_cols)
temp_col equ temp_inverse+(num_pcg*16)
temp_attr equ temp_col+(num_lines*num_cols)
time equ temp_attr+(num_lines*num_cols)
new_time equ time+10
entered_time equ new_time+10
no_clock equ entered_time+10
prog_fn_addr equ no_clock+1
temp_string equ prog_fn_addr+2
pointer equ temp_string+128
line_length equ pointer+1
fn_flag equ line_length+1
colour_fitted equ fn_flag+1
old_vml equ colour_fitted+1
last_key equ old_vml+1
last_addr equ last_key+1
if (last_addr gt spare_fn_str)
error equ code gone too far !!!
dw last_addr-spare_fn_str+zero
endif
end