Skip to content

Commit 689f661

Browse files
committed
Added further notes to SLF80037, fixed md5sum for relocated area which contained extra bytes
1 parent 562c64f commit 689f661

File tree

3 files changed

+105
-90
lines changed

3 files changed

+105
-90
lines changed

applications/SLF80037.COM.asm

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ timer12_cfg: ;[0111]
3232
DB $00
3333

3434
;[0118]
35-
DB $00,$00,$00,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
35+
DB $00,$00,$00
36+
37+
iobyte_init: ;[011b]
38+
DB $80
39+
40+
;[011c]
41+
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
3642
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$e0,$80,$e3,$03
3743
DB $e3,$05,$e3,$01,$e3,$c1,$ff,$cb,$00,$00,$00,$00,$80,$00
3844
DB $cd,$30,$01,$0e,$09,$cd,$05,$00,$c1,$21,$07,$00,$7e,$3d
@@ -533,11 +539,11 @@ entrypoint:
533539
out ($a1),a ;[2110] (no displayed character?)
534540
ld a,$00 ;[2112]
535541
ld ($0003),a ;[2114] I/O byte: set to zero (see below)
536-
call $2145 ;[2117] TODO
542+
call loadrelocated ;[2117] load some pointers and routines used by ROM and CP/M bios
537543
call loadkeys ;[211a] load the keyboard layout in the proper area
538544
call loadshortcuts ;[211d] load the content of the shortcuts bar
539-
ld a,($011b) ;[2120] TODO $80
540-
ld ($0003),a ;[2123] I/O byte [TODO: https://www.mark-ogden.uk/mirrors/www.cirsovius.de/CPM/Projekte/Artikel/Grundlagen/IOByte/IOByte-de.html]
545+
ld a,(iobyte_init) ;[2120] Initialize I/O byte
546+
ld ($0003),a ;[2123] I/O byte [https://www.mark-ogden.uk/mirrors/www.cirsovius.de/CPM/Projekte/Artikel/Grundlagen/IOByte/IOByte-de.html]
541547
ld c,$09 ;[2126] C_WRITESTR(welcome_str)
542548
ld de,welcome_str ;[2128] the welcome string with CP/M version
543549
call SYSCALL ;[212b]
@@ -553,13 +559,15 @@ entrypoint:
553559
ld c,$00 ;[2140] P_TERMCPM - System reset
554560
call SYSCALL ;[2142]
555561

556-
; in here: the content of some configuration variables
557-
; TODO
558-
call bank_off ;[2145] TODO
559-
ld de,$b821 ;[2148]
560-
ld hl,relocated_area ;[214b] TODO what's here?
561-
ld bc,$07db ;[214e]
562-
ldir ;[2151]
562+
; Load the relocated area in place (see SLF80037.relocated.asm)
563+
; This area contains pointers to keyboard layout area, keyboard shortcuts,
564+
; the dead keys handling, and the custom escape routine used in ROM's putchar.
565+
loadrelocated:
566+
call bank_off ;[2145]
567+
ld de,$b821 ;[2148] base address of where the area should be relocated
568+
ld hl,relocated_area ;[214b]
569+
ld bc,$07db ;[214e] relocated area size
570+
ldir ;[2151] memcpy($b821, relocated_area, 0x07db)
563571
call bank_on ;[2153]
564572
ret ;[2156]
565573

@@ -578,8 +586,8 @@ loadkeys:
578586
loadshortcuts:
579587
call bank_off ;[216a]
580588
ld hl,($ffad) ;[216d] *$ffad=$feb4, loaded by cp/m bios
581-
ld ($bff4),hl ;[2170] store the shortcuts address in a local variable (TODO)
582-
ld de,shortcuts_str ;[2173]
589+
ld ($bff4),hl ;[2170] update the pointer to the shortcuts (used by keyboard routine
590+
ld de,shortcuts_str ;[2173] in CP/M bios to recall commands)
583591
ex de,hl ;[2176]
584592
ld bc,$0050 ;[2177] length of shortcuts string
585593
ldir ;[217a] memcpy(*$ffad, shortcuts_str, 0x0050)
Lines changed: 83 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
org $b821
22

3+
; Empty, it's populated directly by the SLF80037 main code
34
scancode_table:
45
REPT 640 ;[b821]
56
nop
67
ENDR
78

8-
mr2_table: ;[baa1]
9+
; Local variables for the "accented letter print" routine
10+
alp_table: ;[baa1]
911
DB $D0,$5C,$00
1012
DB $D1,$7E,$00
1113
DB $D2,$7B,$00
@@ -27,127 +29,135 @@ mr2_table: ;[baa1]
2729
DB $E2,$5D,$00
2830
DB $00
2931

30-
mr1_table: ;[badb]
31-
DB $61,$DB,$D6
32-
DB $65,$DC,$D7
33-
DB $69,$DD,$D8
34-
DB $6F,$DE,$D9
35-
DB $75,$DF,$DA
32+
dkh_table: ;[badb]
33+
; vowel,circumflex,umlaut
34+
DB $61, $DB, $D6 ; a
35+
DB $65, $DC, $D7 ; e
36+
DB $69, $DD, $D8 ; i
37+
DB $6F, $DE, $D9 ; o
38+
DB $75, $DF, $DA ; u
3639
DB $00
3740

38-
mr1_scratch: ;[baeb]
41+
dkh_scratch: ;[baeb]
3942
DB $00
4043

41-
; Briefly, this routine takes c as parameter.
42-
; It has some kind of memory, since it uses mr1_scratch as internal status.
43-
; If c is $f1, mr1_scratch is set to 1 else is set to 2 and carry flag is set.
44-
; For all other values of c, the c value is used to find an entry in mr1_table table.
45-
; If mr1_scratch is zero, c itself is returned
46-
; If mr1_scratch is one, left value of the table is returned in c.
47-
; If mr1_scratch is two, right value of the table is returned in c.
48-
; At the end, mr1_scratch is clear.
49-
mysterious_routine_1: ;[baec]
44+
; Dead key handling
45+
; The routine takes c as parameter, which is the input char, and leaves the eventually
46+
; modified char in c as output. Carry is set if the output char should not be printed
47+
; (i.e. when a modifier key is pressed).
48+
; dkh_scratch is used as dead key status, deafult is 0 (no modifier key pressed and c itself
49+
; is returned).
50+
; There are two possible modifier keys that can change the output status: c=$f1 (up arrow) and
51+
; c=$f2 (down arrow).
52+
; If a modifier key is pressed, dkh_scratch is set to a value other than zero and carry is set:
53+
; this changes the behavior of the routine at the next call:
54+
; if the next pressed char is in dkh_table, then
55+
; - left value of the table is returned in c if dkh_scratch is 1 (circumflex modifier).
56+
; - right value of the table is returned in c if dkh_scratch is 2 (umlaut modifier).
57+
; - the unchanged character is returned if it's not in dkh_table.
58+
; At the end, dkh_scratch is clear.
59+
deadKeyHandler: ;[baec]
5060
ld a,c
5161
cp $f1
52-
jr z,mr1_isf1
62+
jr z,dkh_isf1
5363
cp $f2
54-
jr nz,mr1_nof1f2
55-
ld a,$02 ; if $f2, write 2 in mr1_scratch and return
56-
jr mr1_f1f2_epilogue
57-
mr1_isf1:
58-
ld a,$01 ; if $f1, write 1 in mr1_scratch and return
59-
mr1_f1f2_epilogue:
60-
ld (mr1_scratch),a
64+
jr nz,dkh_nof1f2
65+
ld a,$02 ; if $f2, write 2 in dkh_scratch and return
66+
jr dkh_f1f2_epilogue
67+
dkh_isf1:
68+
ld a,$01 ; if $f1, write 1 in dkh_scratch and return
69+
dkh_f1f2_epilogue:
70+
ld (dkh_scratch),a
6171
scf ; carry set
6272
ret
6373
; Anything but f1 and f2
64-
mr1_nof1f2:
65-
ld a,(mr1_scratch)
74+
dkh_nof1f2:
75+
ld a,(dkh_scratch)
6676
or a
67-
jr z,mr1_return
68-
ld hl,mr1_table
77+
jr z,dkh_return
78+
ld hl,dkh_table
6979
ld b,$05
70-
mr1_loop:
80+
dkh_loop:
7181
ld a,(hl)
7282
cp c
73-
jr z,mr1_found
83+
jr z,dkh_found
7484
inc hl
7585
inc hl
7686
inc hl
77-
djnz mr1_loop
87+
djnz dkh_loop
7888
epilogue:
7989
xor a
80-
ld (mr1_scratch),a ; clear mr1_scratch
81-
mr1_return:
90+
ld (dkh_scratch),a ; clear dkh_scratch
91+
dkh_return:
8292
ret
83-
mr1_found:
84-
ld a,(mr1_scratch)
93+
dkh_found:
94+
ld a,(dkh_scratch)
8595
ld b,$00
8696
ld c,a
8797
add hl,bc
88-
ld c,(hl) ; c = hl + mr1_scratch
98+
ld c,(hl) ; c = hl + dkh_scratch
8999
jr epilogue ; where hl is the pointer to found
90100

91101

92102
; Briefly, this routine takes c as parameter.
93103
; It has some kind of memory, since it uses:
94-
; - mr2_scratch as internal status
104+
; - alp_scratch as internal status
95105
; - the jp at the entrypoint as trampoline, since its jp address is altered at runtime!
96-
; By default, mr2_entrypoint1 is used as trampoline jp address.
97-
; Following this branch, c value is used to find an entry in the mr2_table table.
106+
; By default, alp_entrypoint1 is used as trampoline jp address.
107+
; Following this branch, c value is used to find an entry in the alp_table table.
98108
; If found, left value of the entry is returned in c, right value in a.
99-
; A pointer to the the right value is stored in the mr2_scratch.
109+
; A pointer to the the right value is stored in the alp_scratch.
100110
; If the right value is zero, the routine returns.
101111
; If the right value is not zero, trampoline is altered enabling the secondary entrypoint.
102112
; If the entrypoint has been altered, the next calls follow a fixed pattern:
103-
; - mr2_entrypoint2: c cargument is returned as is, $08 is returned in a and
104-
; trampoline is changed to mr2_entrypoint3.
105-
; - mr2_entrypoint3: the right value that triggered the alternate path is loaded in c (via mr2_scratch).
113+
; - alp_entrypoint2: c cargument is returned as is, $08 is returned in a and
114+
; trampoline is changed to alp_entrypoint3.
115+
; - alp_entrypoint3: the right value that triggered the alternate path is loaded in c (via alp_scratch).
106116
; a is zeroed and path is restored to the default entrypoint.
107-
mysterious_routine_2: ;[bb23]
108-
jp mr2_entrypoint1 ; this jp is altered at runtime!
109-
mr2_entrypoint1:
117+
accentedLetterPrintHandler: ;[bb23]
118+
jp alp_entrypoint1 ; this jp is altered at runtime!
119+
alp_entrypoint1:
110120
ld a,c
111121
bit 7,a
112122
ret z ; return if bit 7 is cleared
113-
ld hl,mr2_table
114-
mr2_loop:
123+
ld hl,alp_table
124+
alp_loop:
115125
ld a,(hl)
116126
or a
117127
ret z
118128
cp c
119129
inc hl
120-
jr z,mr2_mr1_found
130+
jr z,alp_found
121131
inc hl
122132
inc hl
123-
jr mr2_loop
124-
mr2_mr1_found:
133+
jr alp_loop
134+
alp_found:
125135
ld c,(hl)
126136
inc hl
127-
ld (mr2_scratch),hl
137+
ld (alp_scratch),hl
128138
ld a,(hl)
129139
or a
130140
ret z
131141
ld a,c
132-
ld de,mr2_entrypoint2 ; change the entrypoint to the first stage alternate one
133-
jr mr2_epilogue
142+
ld de,alp_entrypoint2 ; change the entrypoint to the first stage alternate one
143+
jr alp_epilogue
134144

135-
mr2_entrypoint2: ; first stage alternate entrypoint
145+
alp_entrypoint2: ; first stage alternate entrypoint
136146
ld a,$08
137-
ld de,mr2_entrypoint3 ; change the entrypoint to the second stage alternate one
138-
jr mr2_epilogue
147+
ld de,alp_entrypoint3 ; change the entrypoint to the second stage alternate one
148+
jr alp_epilogue
139149

140-
mr2_entrypoint3: ; second stage alternate entrypoint
141-
ld hl,(mr2_scratch)
150+
alp_entrypoint3: ; second stage alternate entrypoint
151+
ld hl,(alp_scratch)
142152
ld c,(hl) ; take back the "right value" that triggered the alternate path
143153
xor a
144-
ld de,mr2_entrypoint1 ; restore the default entrypoint
145-
mr2_epilogue:
146-
ld (mysterious_routine_2+1),de
154+
ld de,alp_entrypoint1 ; restore the default entrypoint
155+
alp_epilogue:
156+
ld (accentedLetterPrintHandler+1),de
147157
or a ; set flags according to a content
148158
ret ; result is in a
149159

150-
mr2_scratch:
160+
alp_scratch:
151161
DW $0000
152162

153163
; This function is indirectly called by ROM's putchar during second stage escaping
@@ -177,12 +187,14 @@ pScancode_table: ;[bff2]
177187
pShortcuts_base:
178188
DB 0, 0 ;[bff4]
179189

180-
; TODO referenced in CP/M BIOS when reading from kbd
181-
pMysterious_routine_1: ;[bff6]
182-
DW mysterious_routine_1
183-
; TODO referenced in CP/M BIOS when writing to printer
184-
pMysterious_routine_2: ;[bff8]
185-
DW mysterious_routine_2
190+
; Dead key handler pointer
191+
; referenced in CP/M BIOS when reading from kbd
192+
pDeadKeyHandler: ;[bff6]
193+
DW deadKeyHandler
194+
; (TODO) Custom character print handler
195+
; referenced in CP/M BIOS when writing to printer
196+
pAccentedLetterPrintHandler: ;[bff8]
197+
DW accentedLetterPrintHandler
186198

187199
; Pointer to a custom routine used to handle escape during putchar.
188200
; The routine is implemented here, and at the moment is just a ret.
@@ -191,9 +203,4 @@ pMysterious_routine_2: ;[bff8]
191203
; unexpected behavior!
192204
pCustom_escape: ;[bffa]
193205
DW custom_escape
194-
195-
; This version string is populated by the cpm_bios with "8003", but
196-
; SLF80037 overwrites it.
197-
version: ;[bffc]
198-
DB "8.10"
199-
DB 0
206+
;[bffc]

applications/md5sum.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
2a75591c8b454c74df433ab1b58a47fd build/PAR8003.COM
33
5c6f140b44c03539fea2e30eab1bb138 build/PAR8003.relocated
44
8c0541188297d176ffa06d4cae53591f build/SLF80037.COM
5-
fda2bf1e49a0d91488906d6b5456ba88 build/SLF80037.relocated
5+
b022bb2d88531e11fd4f6fc4c89f31ed build/SLF80037.relocated

0 commit comments

Comments
 (0)