;FLIPKEYS.ASM ;Curt Edwards 11/11/85 ;<<<<<<<<<<<<<<<<<<<< Bdos Call Equates >>>>>>>>>>> ; boot equ 00h ;reset (warm boot) conin equ 01h ;console input conout equ 02h ;console output prints equ 09h ;print string ; ;<<<<<<<<<<<<<<<<<<<< Misc Equates >>>>>>>>>>>>>>>>> ; true equ 0ffh false equ 00 Osborne equ true ;Either Osborne or normcpm equ false ;normcpm must be true bdos equ 05h ;bdos address bell equ 07h ;bell eof equ 1ah ;end of file or clear screen character cr equ 0dh ;carrige return lf equ 0ah ;line feed tab equ 09h ;tab esc equ 1bh ;escape ; ;<<<<<<<<<<<<<<<<<<<< End of Equates >>>>>>>>>>>>> ; org 100h jmp start ; mess: db 'Curious aren''t we now!!' ;for the nosey prg: db ' FLIPKEYS ' ;who like to poke vermess:db ' Version 1.0' ;around with DDT mess1: db ' By Curt Edwards' ;like myself. mess2: db ' SoftStone Technologies' crnote: db 'Copyright 11/11/85 All Rights Reserved' ; ; <<<<< Set up Local Stack >>>>> ; start: lxi h,0 ;zero hl register pair dad sp ;add the stack pointer shld oldsp ;store oldsp to restore when done lxi sp,stktop;point to new local stack ; ;<<<<<<<<<< S T A R T O F P R O G R A M >>>>>>> ; ; <<<<< Print opening message >>>>> ; call clr ;clear screen lxi d,omess1;1st line of opening mess call pstring ;print it call halfon ;turn off half intensity lxi d,omess2;2nd line of opening mess call pstring ;print it call halfoff ;turn half inten on again ; ; <<<<< Check if single or double density >>>>> ; lxi h,0002h ;load hl with value of address 3 mov a,m ;put value in a reg cpi 0e5h ;is it single density? jz single ;yes cpi 0e1h ;is it double density? jz double ;yes jmp error ; error: lxi d,errormess ;point to error message call pstring ;print it jmp fini ; ; single: lhld 0e57fh ;addr to 1st entry in arrow key vector shld vectadr lxi d,singlemess ;point to single density message call pstring ;print it jmp check ;jmp to check rountine ; double: lhld 0e17fh ;addr to 1st entry in arrow key vector shld vectadr lxi d,doublemess ;point to double density message call pstring ;print it jmp check ;jmp to check routine ; ; <<<<< Check if current keys are Wordstar or CP/M >>>>> ; check: lhld vectadr mov a,m ;put up key code in a reg cpi 05h ;is it Wordstar keys? jz ws2cpm ;yes cpi 0bh ;is it cpm keys jz cpm2ws ;yes jmp cpm2ws ;default to cp/m ; ; ; <<<<< Change the key configurations >>>>> ; ws2cpm: call halfon ;turn on half intensity lxi d,wsmess;set up to print key status mess call pstring call halfoff lxi d,wsmess1 call pstring call halfon lxi d,wsmess2 call pstring call halfoff call uline lxi d,wsmess3 call pstring call nuline mvi b,4 ;set up counter lhld vectadr lxi d,cpmtbl;point to cpm key codes loop1: ldax d ;put code in a reg mov m,a ;put it in vector inx h ;increment key code pointer inx d ;increment table pointer dcr b ;decrment counter jnz loop1 ;done? no get next code jmp fini ;yes, return to cp/m ; cpm2ws: call halfon ;turn on half intensity lxi d,cpmmess ;set up to print key status message call pstring call halfoff lxi d,cpmmess1 call pstring call halfon lxi d,cpmmess2 call pstring call halfoff call uline lxi d,cpmmess3 call pstring call nuline mvi b,4 ;set up counter lhld vectadr lxi d,wstbl ;point to ws key codes loop2: ldax d ;put code in a reg mov m,a ;put it in vector inx h ;incr key code pointer inx d ;incr table pointer dcr b ;dcr counter jnz loop2 ;done? no get next code jmp fini ;yes return to cp/m ; ; <<< restore old stack pointer and warm boot system >>> ; fini: lxi h,oldsp ;load h with old stack pointer sphl ;put it in the stack pointer ret ;back to cpm ; ;<<<<<<<<<< E N D O F P R O G R A M >>>>>>>>>>> ;--------------------------------------------------- ;<<<<<<<<<<<<<<<<< SUBROUTINES >>>>>>>>>>>>>>>>>>>> ; ------------------------------------- ; |[[[[ Osborne Specific Routines ]]]]] | ; ------------------------------------- ;--------------------------------------------------- ; <<<<< Clear the screen >>>>> ; clr: push d! push b! push h call ilprt db 1ah,0 pop h! pop b! pop d ret ; ;-------------------------------------------------- ; <<<<< Set Half Intensity Video >>>>> ; halfon: push d! push b! push h ;save enviroment call ilprt ;call print routine db esc,29h,0 ;code for half inten. pop h! pop b! pop d ;restore enviroment ret ;return to calling routine ; ;-------------------------------------------------- ; <<<<< Set Full Intensity Video >>>>> ; halfoff: push d! push b! push h ;save enviroment call ilprt ;call print routine db esc,28h,0 ;code for full inten. pop h! pop b! pop d ;restore enviroment ret ;return to calling routine ; ; ------------------------------------------------- ; <<<<< Turn Underline on >>>>> ; uline: push b! push d! push h ;save enviroment call ilprt ;call print routine db esc,6ch,0 ;code for underline on pop h! pop d! pop b ;restore enviroment ret ;return to calling routine ; -------------------------------------------------- ; <<<<< Turn Underline off >>>>> ; nuline: push b! push d! push h ;save enviroment call ilprt ;call print routine db esc,6dh,0 ;code for underline off pop h! pop d! pop b ;restore enviroment ret ;return to calling routine ; ; -------------------------------------------------- ; <<<<< Start Graphics >>>>> ; graphon: push b! push d! push h ;save enviroment call ilprt ;call print routine db esc,67h,0 ;code for start graphics pop h! pop d! pop b ;restore enviroment ret ;return to calling routine ; ; -------------------------------------------------- ; <<<<< Stop Graphics >>>>> ; graphoff: push b! push d! push h ;save enviroment call ilprt ;call print routine db esc,47h,0 ;code for stop graphics pop h! pop d! pop b ;restore enviroment ret ;return to calling routine ; ; -------------------------------------------------- ; <<<<< Set cursor position on screen >>>>> ; y=line number x=column number ;NOTE: yy,xx position must be in the hl register ;pair when this call is made y in h and x in l ; curpos: push b! push d! push h ;save calling enviroment xchg ;put position in hl into de lxi h,posseq;load h with postion sequence mov a,d ;move y postion in a adi 20h ;add bias mov m,a ;put it in postion sequence 3 inx h ;increment h to point to next byte mov a,e ;put x postion in a adi 20h ;add bias mov m,a ;put it in position sequence 4 call ilprt ;print complete postion sequence db esc,'=' ;1st two bytes to postion cursor posseq: db 0ffh,0ffh,0 ; yy,xx postion, zero to end pop h! pop d! pop b ;restore calling enviroment ret ;go back ; ;--------------------------------------------------- ; ------------------------------------------ ; |[[[[ End of Osborne Specific Routines ]]]]| ; ------------------------------------------- ;--------------------------------------------------- ; <<<<< Print out a string w/console out function >>>>> ; ; db must end with 0 to flag end of string ; ; MUST HAVE THIS ZERO...----------------------+ ; example: | ; | ; call ilprt V ; db cr,lf,'This would be the string',0 ; ; ilprt: xthl ;put SP in hl, hl now has 1st ;character of db at return address mov a,m ;move 1st char in a register inx h ;increment string pointer xthl ;put SP in hl again ora a ;is it zero rz ;yes retrun push h ;save string pointer mov e,a ;put 1st character in e call outch ;call console out routine pop h ;restore string pointer jmp ilprt ;get next character ; ;--------------------------------------------------- ; <<<<< Print string subroutine >>>> ; de pair must point to string upon entry ; pstring: push h! push d! push b mvi c,prints;set up print string function call bdos ;print it pop b! pop d! pop h ret ; ;--------------------------------------------------- ; <<<< Send Carrige Return/Line Feed >>>>> ; crlf: push b! push d! push h call ilprt db 0dh,0ah,0 pop h! pop d! pop b ret ; ;--------------------------------------------------- ; <<<< Reset System (warm boot) >>>>> ; wmboot: push b! push d! push h call ilprt db cr,lf,lf,'Warm Boot...',cr,lf,0 mvi c,boot call bdos pop h! pop d! pop b ret ;--------------------------------------------------- ; <<<<< Get a Single Character >>>>> ; inch: push h! push b! push d mvi c,conin call bdos pop d! pop b! pop h ret ;on return A reg will hold ; ;ascii character ;--------------------------------------------------- ; <<<<< Output a Single Character >>>> ; outch: push h! push b! push d mvi c,conout ;assumes character is in e register call bdos pop d! pop b! pop h ret ;--------------------------------------------------- ; <<<<< Tables >>>>> ;--------------------------------------------------- ; ; <<<<< wordstar arrow key code table >>>>> ; ; This is a neat little routine to save someone from ; having to look up what the ASCII equivilant for a ; control character is. By using the uppercase ASCII ; character in quotes and subtracting 40 hex from it the ; assembler read it as the proper code. ; ie: 'E'-40h is read as 05H, beacuse ASCII 'E' is ; 45h minus 40h equals 05H. wstbl: db 'E'-40h ;up arrow ^E db 'D'-40h ;right arrow ^D db 'X'-40h ;down arrow ^X db 'S'-40h ;left arrow ^S ; ; <<<<< cp/m arrow key code table >>>>> ; cpmtbl: db 'K'-40h ;up arrow ^K db 'L'-40h ;right arrow ^L db 'J'-40h ;down arrow ^J db 'H'-40h ;left arrow ^H ; ;--------------------------------------------------- ; <<<<< Message area >>>>> ;--------------------------------------------------- ; ; <<<<< opening message >>>>> ; omess1: db 'FLIPKEYS','$' omess2: db ' Version 1.0',cr,lf db '(c)Curt Edwards 11/25/85 ',cr,lf db 'Sysop: SoftStone RCP/M (502) 241-4109',cr,lf db ' P.O Box 694 Crestwood, Ky 40014',cr,lf,'$' ; ; <<<<< single density message >>>>> ; singlemess: db cr,lf,'Osborne-1 Single density system','$' ; ; <<<<< double density message >>>>> ; doublemess: db cr,lf,'Osborne-1 Double density system','$' ; ; <<<<< ws2cpm message >>>>> ; wsmess: db cr,lf,lf,bell,'Arrow keys were ','$' wsmess1: db 'Wordstar','$' wsmess2: db ' they are now set for ','$' wsmess3: db 'CP/M',cr,lf,lf,'$' ; ; <<<<< cpm2ws message >>>>> ; cpmmess: db cr,lf,lf,bell,'Arrow keys were ','$' cpmmess1: db 'CP/M','$' cpmmess2: db ' they are now set for ','$' cpmmess3: db 'Wordstar',cr,lf,lf,'$' ; ; <<<<< error message >>>>> ; errormess: db cr,lf,lf,lf,bell,bell,'Not a reconizable Osborne system',cr,lf db lf,'Returning to CP/M !','$' ;--------------------------------------------------- ; <<<<< Reserve Memory >>>>> ;--------------------------------------------------- vectadr: ds 2 ;starage for 1st entry to arrow key ; ;arrow key vetor ; oldsp: ds 2 ;old stack pointer ds 32 ;new stack stktop: ; end 100h