; Overlay to MBASIC R.Gaspari 12-04-87 ; Assemble with Z80MR. Overlay onto MBASIC with DDT. PROGEND EQU 6000h ; original end of the program being modified KBA EQU 0D700H ; base addr below which code is loaded (ccp) KKS EQU 200H ; how far below kba code will go NO EQU 0 YES EQU .NOT.NO NSADV EQU YES ; using Northstar Advantage? @N ; (for on-screen BOLD and UNDERLINE) SMTCLK EQU YES ; using SMT no-slot clock? @S ; (for pop-up clock display) Z80DOS EQU YES ; using Z80DOS? @Z ; (to trap make-file bdos calls) ORG 0100h ; overlay the program being modified JP LOADCD ; (MBASIC had a JMP 5D8C here) ORG PROGEND ; point to end of normal MBASIC LOADCD: LD HL,0 ; * prevent soft return to CCP EX (SP),HL ; * any soft retn becomes JP 0 CALL SETUP ; load CCP and BIOS overlays JP 5D8CH ; continue with original program ; ************************************ ; PART I - SETUP JUMP VECTORS ; ************************************ M6 EQU -6 ; a constant SETUP: if nsadv.and.smtclk ; @N3 @S1 USORG EQU 0F400h ; start of USER.ASM (F400 for floppy) LD DE,USORG ; spot in BIOS to put clock code LD HL,UCODE ; point to data we'll put there LD BC,USIZE ; size of code block to be moved LDIR endif ; @N3 @S1 LD HL,(6) ; get bdos vector DF06 LD (KREM6),HL ; store it for future use LD DE,M6 ; get -6 ADD HL,DE ; HL now has DF00 (source) LD DE,KBA-KKS ; DE now has D300 (destination) LD BC,9 ; move 9 bytes LDIR LD HL,(1) ; get warm boot vector ED03 (source) LD DE,KBA-KKS+9 ; DE now has D309 (destination) LD BC,12 ; move 12 bytes LDIR LD DE,KBA-KKS+21 ; DE has D315 (destination) LD HL,KKODE+21 ; HL points to code below LD BC,KSIZE ; move bytes LDIR LD HL,KBDOS ; get new bdos vector LD (6),HL ; put it in place LD HL,(1) ; point to actual table (dest) LD DE,KBOOT ; point to replace table (source) EX DE,HL ; LD BC,12 ; move 12 bytes LDIR if z80dos ; @Z1 LD HL,(KBA-KKS+7) LD (Z8ENTRY+1),HL LD HL,Z8NEW LD (KBA-KKS+7),HL endif ; @Z1 RET ; done with SETUP ; ******************************************************** ; PART II - NEW VECTOR CODE (move to high memory) ; ******************************************************** KKODE: OK EQU (KBA-KKS)-KKODE ; offset KSER EQU $+OK DS 6 ; space for serial number KBDOS EQU $+OK DS 3 ; space for bdos jump BBOOT EQU $+OK DS 3 ; orig warm boot jmp vector BSTAT EQU $+OK DS 3 ; orig console status BCONIN EQU $+OK DS 3 ; orig console input BCONOUT EQU $+OK DS 3 ; orig console output KBOOT EQU $+OK JP KBT ; new warm boot vector KCSTAT EQU $+OK JP KST ; new console status KCONIN EQU $+OK JP KIN ; new console input KCONOUT EQU $+OK JP BCONOUT ; new console output ; ***************************************** ; REPLACEMENT WARM BOOT ROUTINE KBT EQU $+OK ; remove key code each wm boot CALL KREM ; put the 4 bios vectors back JP 0 ; exit to cpm KREM EQU $+OK LD HL,(KREM6) ; get orig bdos jmp vector LD (6),HL ; put it back LD DE,(1) ; point to ED03 LD HL,BBOOT ; get orig actual data LD BC,12 ; move 12 bytes LDIR XOR A RET ; ************************************** ; REPLACEMENT CONSOLE STATUS KST EQU $+OK LD A,(KEYINF) OR A JP Z,BSTAT ; LD A,0FFH RET ; *************************************** ; REPLACEMENT CONSOLE INPUT KIN EQU $+OK LD HL,KEYINF ; get the counter of keys waiting LD A,(HL) OR A JR NZ,KEYWAT ; go process the keys waiting CALL BCONIN ; get the byte using actual bios CP 7FH ; see if it's a "delete" RET C ; if less than 7F, return with it JR NZ,KEYFNI ; if greater than 7F, prep for funct key LD A,(KEYDEL) ; if equal to 7F, replace with a ^H RET ; KEYFNI: CP 9EH ; see if it's CMND-F4 JR NZ,KEYNR ; (2nd F4 removes fnct key code) LD HL,KREMC ; look at the removal counter INC (HL) LD A,(HL) AND 2 JP NZ,KREM ; if Z, go remove key code KEYNR: LD B,A ; store the function key LD A,(KEYLEN) ; get length of replacement byte string OR A ; see if zero LD A,B ; get the function key back RET Z ; if len=0, don't process function keys KEYFN EQU $+OK CP 0DBH ; now see if its F1 - F15 or if a cursor JR NC,KEY2 ; if no carry, its greater (F1 - F15) SBC A,7FH ; subtract to point to offset in table LD HL,(KEYNMP) ; get address of the cursor replacements JR KEYX ; go to the exchange routine KEY2: SBC A,0DBH ; subtract to get the offset for our table LD HL,(KEYFNP) ; get address of the fn key replacements KEYX: LD C,A ; store offset temporarily in C LD A,(KEYLEN) ; get the length of each replacement str DEC A ; LD (KEYINF),A ; store the number of remaining bytes LD D,A ; the number of times to add A to itself LD A,C ; get the offset back from C KEYX2: ADD A,c ; by adding N times, adjust offset for DEC D ; the number of bytes in KEYLEN JR NZ,KEYX2 ; repeat till D=0 LD E,A ; put the offset in DE, prep for DAD D LD D,0 ; ditto ADD HL,DE ; HL now points to the replacement bytes LD D,(HL) ; get first replacement byte INC HL ; point to next byte LD (KEYPTR),HL ; store pointer to the next byte LD A,(HL) ; get next byte OR A JR NZ,KNXTZ ; if next byte NZ skip, otherwise... LD (KEYINF),A ; notify keyinf that there's no more KNXTZ: LD A,D ; get the replacement key back OR A ; check that it's not a null RET NZ ; if no null, return with it LD (KEYINF),A ; otherwise notify keyinf that no more RET ; return with function key replacement KEYWAT: DEC A ; decrement count of keys waiting LD (HL),A ; store for future use LD HL,(KEYPTR) ; get address of next byte waiting LD A,(HL) ; get the byte there INC HL ; update the pointer to the next byte LD (KEYPTR),HL ; and store it RET ; return with the byte that was waiting KREMC EQU $+OK DW 0 ; temp storage for CMND-F4 counter KEYPTR EQU $+OK DEFW 0 ; temp pointer to next replacement byte KEYINF EQU $+OK DEFB 0 ; temp storage for number of keys waiting KREM6 EQU $+OK DW 0 ; temp storage for orig bdos (DF06) KEYDEL EQU $+OK ; permanent storage for delete key DEFB 08H ; replacement (set delete = ^H) KEYLEN EQU $+OK ; permanent storage for length of DEFB 7 ; each replacement string KEYFNP EQU $+OK dw KFNTBL ; pointer to KFNTBL KEYNMP EQU $+OK dw KNMTBL ; pointer to KNMTBL ; ***************************************************** ; PART IIb - FUNCTION KEY REPLACEMENT DATA ; ***************************************************** KNMTBL EQU $+OK db 0,0,0,0,0,0,0 ; 80h cmnd - db 0,0,0,0,0,0,0 ; 81h cmnd . db 0,0,0,0,0,0,0 ; 82h up arrow db 0,0,0,0,0,0,0 ; 83h 3 arrow db 0,0,0,0,0,0,0 ; 84h 1 arrow db 'EDIT ',0,0 ; 85h 5 arrow (center) db ' ',0,0,0,0,0,0 ; 86h rt arrow db 0,0,0,0,0,0,0 ; 87h 7 arrow db 8,0,0,0,0 ; 88h lf arrow KFNTBL EQU $+OK db 'SAVE "' ; dbh F1 key db 0,0,0,0,0,0,0 ; dch F2 db 'PRINT ' ; ddh F3 db 'LPRINT ' ; deh F4 db 18H,0,0,0,0,0,0 ; dfh F5 db 0,0,0,0,0,0,0 ; e0h F6 db 0,0,0,0,0,0,0 ; e1h F7 db 0,0,0,0,0,0,0 ; e2h F8 db 'RUN ',0,0,0 ; e3h F9 db 'SYSTEM',0DH ; e4h F10 db 0,0,0,0,0,0,0 ; e5h F11 db 'LIST ',0,0 ; e6h F12 db 'LLIST ',0 ; e7h F13 db 'LOAD "' ; e8h F14 db 08H,0,0,0,0,0,0 ; e9h F15 ; ********************************* ; PART IIc - Z80DOS TRAP ; ********************************* if z80dos ; @Z2 Z8NEW EQU $+OK LD A,C ; move bdos funct number into A CP 0FH ; see if it's the first open-file call JR Z,Z8GET ; if yes, GET the time stamp CP 16H ; see if this is make-file call JR Z,Z8USE ; if yes, USE the time stamp JR Z8ENTX ; all else, go do real bdos jump Z8GET: PUSH DE ; preserve the fcb for bdos 54 PUSH DE CALL Z8ENTRY ; go to bdos & return POP DE ; get the fcb back again PUSH AF ; preserve open-file bdos status INC A ; see if it's 0ffh (no file found) LD (Z8NFF),A ; store results for use later JR Z,Z8SKP ; if no file found, skip get stamp LD C,54 ; 54 = get stamp CALL 5 ; Z8SKP: POP AF ; get orig open-file status back POP DE ; and orig fcb RET Z8USE: LD A,(Z8NFF) ; see if open-file was successful OR A ; a=0 if unsuccessful JR Z,Z8ENTX ; if zero, skip use-stamp PUSH BC ; save bdos funct number (c=16h) PUSH DE ; save fcb LD C,55 ; 55 = use stamp CALL 5 POP DE POP BC Z8ENTRY EQU $+OK Z8ENTX: JP 0 ; do the JP into real bdos Z8NFF EQU $+OK DB 0 ; flag for no-file-found endif ; @Z2 KREF1 EQU $ ; location of end of code KREF2 EQU $+OK ; location of end (after it's moved) KSIZE EQU $-KKODE ; the size code to be moved IF (KSIZE).GT.(KKS) * ERROR - allow more size for KKS ENDIF ; *************************************************** ; PART III - BIOS CODE (moved to high memory) ; *************************************************** if nsadv.and.smtclk ; @N4 @S2 *include user201.azm ; see NOSLTDOS.LBR for more info endif ; @N4 @S2 end