;ENTROPY SAMDOS patch, to clear up system ;---------------------------------------- ;February 1994 ;Resets all vectors to original values - namely to clear out ;other DOS'es, etc... ;Also determines number of internal drives, memory, etc... lmpr: EQU &FA hmpr: EQU &FB vmpr: EQU &FC yscan: EQU &01F8 border: EQU &FE status: EQU &F9 clut0: EQU &00F8 jclsbl: EQU &014E jpalet: EQU &0154 jclscr: EQU &018D jscrn: EQU &0100 jmode: EQU &015A romvers: EQU &000F version: EQU 11 ;boot sys version 1.1 chars: EQU &5C36 pramtp: EQU &5CB4 xmeml: EQU 128 ;Version History ;--------------- ;1.0 : Original released version. Now used on PD discs, software throughout ; the SAM owning world. ;1.1 : Corrected two bugs: If a user had 4Mb of external memory, it would ; print ZERO, as an 8 bit counter had been used for the number of ; memory pages present. Changed it for a 16 bit one. ; Also, memory location used for 512k testing was not restored, which ; could affect resident programs. Altered it so that it DID restore it. ORG &8009 DUMP &8009 MDAT "SAMDOS" ;include OLD DOS code for modification. start: LD H,81 ;set up DOS page... (taken from DOS - not LD L,A ;documented) LD (HL),96 LD HL,324 LD (23046),HL DI XOR A OUT (border),A LD BC,511 ;turn soundchip off LD D,0 LD A,28 clear.chip: OUT (C),A DEC A DEC B OUT (C),D INC B CP 255 JR NZ,clear.chip LD HL,(chars) ;copy font to Systems Variables page... INC H ;(restores FONT from power-up) EX DE,HL LD HL,sam.font LD BC,768 LDIR LD HL,sam.font ;take this font and expand it into MODE 3 LD IX,font.space ;for quick printing by my routines... EXX LD D,&FF ;colour mask -- all bits set (WHITE) EXX CALL build.font LD HL,sam.font ;different colour for font LD IX,font.space2 EXX LD D,%01010101 ;colour mask -- alternate bits (RED/BLACK) EXX CALL build.font IN A,(hmpr) AND %00011111 OUT (hmpr),A IN A,(lmpr) ;store system for BASIC LD (lmpr.store+1),A LD (sp.store+1),SP LD SP,stack+256 IN A,(vmpr) ;page in screen (mode 3) AND 127 LD (vmpr.store+1),A IN A,(vmpr) AND %10011111 OR %01000000 OUT (vmpr),A CALL query.system ;check hardware for presence... ;Also gets the current ROM version and puts ;it in the text data.. LD A,(vmpr.store+1) AND 31 OR 32 OUT (lmpr),A CALL clear.scr ;clear the screen area LD BC,&03F8 ;set basic MODE 3 palette LD A,127 OUT (C),A DEC B XOR A OUT (C),A LD B,A OUT (C),B LD HL,font.space2-512 ;select font colour LD (font.pos+1),HL LD HL,6*1024 ;screen line start LD IX,topmesg CALL print.line ;print top line of screen LD HL,17*1024 LD IX,copyright CALL print.line ;print copyright message LD HL,font.space-512 LD (font.pos+1),HL LD HL,8*1024 LD IX,drives ;print number of drives CALL print.line LD HL,9*1024 LD IX,internalk ;print internal memory size CALL print.line LD HL,10*1024 LD IX,externalk ;print external memory size CALL print.line LD HL,12*1024 LD IX,basicrom ;print BASIC Rom version CALL print.line LD HL,14*1024 LD IX,sambus ;print SAMBUS clock present status CALL print.line LD HL,15*1024 LD IX,sammouse ;print SAM Mouse status CALL print.line CALL wait.15 ;wait for 15 seconds, or a keypress CALL clear.scr ;clear screen and return to BASIC sp.store: LD SP,&0000 lmpr.store: LD A,&00 OUT (lmpr),A IN A,(vmpr) AND %10000000 vmpr.store: OR &00 OUT (vmpr),A EI XOR A LD (&5C4B),A ;taken from SAMDOS initialisation routine HALT ;restore palette! RET clear.scr: LD HL,0 LD DE,1 LD BC,&5FFF LD (HL),L LDIR RET wait.15: LD DE,750 waiter: LD BC,yscan IN A,(C) CP 1 JR NZ,waiter XOR A ;read keyboard bits 4-0 IN A,(border) CPL AND 31 LD C,A XOR A IN A,(status) ;read keyboard bits 7-5 CPL AND %11100000 OR C RET NZ ;if any key has been pressed, exit... ;doesnt check cursors or CNTRL -- would be ;upset by the mouse? LD HL,line.table ;put palette bars on-screen. PUSH DE colorloop: LD A,(HL) INC HL CP 255 JR Z,exitcolor LD E,A LD BC,yscan lwait: IN A,(C) CP E JR NZ,lwait LD A,(HL) INC HL LD BC,clut0 OUT (C),A JR colorloop exitcolor: POP DE DEC DE LD A,D OR E JR NZ,waiter RET ;Print a MODE 3 text line onscreen ;------------------------------- ;Entered: IX = Text address ; HL = Screen address to put text at. print.line: PUSH IX LD C,0 line.l: INC C LD A,(IX) INC IX BIT 7,A ;bit 7 is set on last character JR Z,line.l POP IX LD B,C LD A,64 SUB C LD L,A put.line: PUSH HL PUSH BC LD A,(IX) AND 127 INC IX LD B,8 PUSH HL ;find character's position in FONT LD L,A LD H,0 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL font.pos: LD DE,&0000 ADD HL,DE EX DE,HL POP HL put.char: LD A,(DE) ;put data on screen... 2 bytes per char in mode3 LD (HL),A INC DE INC L LD A,(DE) LD (HL),A DEC L INC DE PUSH DE LD DE,128 ;move to next screen line ADD HL,DE POP DE DJNZ put.char ;loop for rest of character's height POP BC POP HL INC L ;move to next character position INC L DJNZ put.line RET ;Build a bold font from the SAM font (768 bytes, 1 bit per pixel, 8 lines ;per character, 8 bits per line) ;D = Colour mask ;HL = Font address ;IX = Address to store converted font at. build.font: LD BC,768 bloop: LD A,(HL) ;make font BOLD ADD A,A OR (HL) INC HL LD E,A PUSH HL PUSH DE LD HL,table SRL E SRL E SRL E SRL E LD D,0 ADD HL,DE LD A,(HL) EXX AND D EXX LD (IX),A INC IX POP DE LD A,E AND &0F LD HL,table LD D,0 LD E,A ADD HL,DE LD A,(HL) EXX AND D EXX LD (IX),A INC IX POP HL DEC BC LD A,B OR C JR NZ,bloop RET ;QUERY SYSTEM ;------------ ;Checks Current ROM VERSION number ;Number of drives ;Presence of Mouse/Realtime clock ;Size of internal memory ;Size of external memory query.system: LD A,(romvers) LD HL,vrsion LD B,0 ;Convert number in A into a version number hundreds: CP 100 JR C,lessth100 INC B SUB 100 JR hundreds lessth100: EX AF,AF' LD A,B OR A JR Z,tens ADD A,48 LD (HL),A INC HL tens: EX AF,AF' LD B,0 tenloop: CP 10 JR C,lessth10 INC B SUB 10 JR tenloop lessth10: EX AF,AF' LD A,B ADD A,48 LD (HL),A INC HL LD (HL),"." ;version spacer... INC HL EX AF,AF' ADD A,48 OR 128 LD (HL),A ;Check for presence of drive 2... assumes that we HAVE a drive 1, or DOS ;couldn't have been loaded... (no hard-drive on SAM yet) ;Checks by writing 256 values to the drive controller's DATA register, and ;reading them back in... waits about 250ms before reading again, to allow the ;chip to respond (might be slow???) ;If all bytes are not returned as sent, it is assumed that the drive is not ;present (SAM Coupe internal drives have separate controllers, mounted in the ; drives themselves) LD B,255 check.drv2: LD A,B OUT (243),A ;drive 2 data port.. PUSH BC LD B,0 DJNZ $ POP BC IN A,(243) CP B JR NZ,not.drv2 DJNZ check.drv2 LD A,208 ;set up dvar for drive 2 LD (32768+147),A ;(allows DOS to use drive 2 without the ;user having to mess about -- which is ;what USED to happen before I wrote this ;patch -- the user used to have to set ;this variable MANUALLY!!!) JR check.mem ;check for memory, don't alter text not.drv2: LD A,"1" ;if only one drive present, alter text LD (drives),A ;and clear the drive 2 enable disk var LD A,"e"+128 LD (grammar),A XOR A ;clear drive 2 dvar LD (32768+147),A ;Check how much memory is present in machine. First, internally, then ;externally. check.mem: IN A,(lmpr) EX AF,AF' LD A,16+32 ;page in 1st page of 512k memory area OUT (lmpr),A ;(not present on a 256k machine) LD HL,k512 ;points to "512" text in memory. LD A,(0) ;store contents of the byte -- just in LD E,A ;case important data is there. LD B,255 ;write 255 values to the page, ensuring ramloop: ;that they can all be read back. LD A,B LD (0),A LD A,(0) CP B JR NZ,k256k ;if can't be read as written, 256k machine DJNZ ramloop LD A,E LD (0),A EX AF,AF' OUT (lmpr),A EX AF,AF' LD A,(pramtp) ;checks to see if system started up in 256 CP 15 ;mode when 512 was present... JR NZ,found512k LD A,"M" ;Print "Masquerading as..." message LD (internex),A JR found512k k256k: LD HL,k256 ;copy number of K onto the text aea. found512k: EX AF,AF' OUT (lmpr),A LD DE,internalk+1 LD BC,3 LDIR ;Check for presence of realtime clock. check.clok: LD BC,&B0EF ;BC = Year MSB of realtime clock LD DE,&0F00 IN A,(C) ;read in the Year MSB -- we can pretty much PUSH AF ;guarantee that this won't change while ;testing for the clock's presence. clk.llp: OUT (C),D ;output 15 different values to the clock IN A,(C) ;and ensure that they can be read back AND 15 ;strip unused bits CP D JR NZ,no.clk DEC D JR NZ,clk.llp LD E,1 ;set E to 1 if clock is present no.clk: POP AF OUT (C),A ;restore YEAR data. LD A,E OR A ;finished init messages JR Z,noclock LD HL,found ;put the CLOCK FOUND message into the text LD DE,nsambus LD BC,5 LDIR noclock: ;Check for presence of mouse. mouse_detect: CALL mouse_scan ;clear the mouse data XOR A LD (mouse_space+6),A CALL mouse_scan LD A,(mouse_space+6) AND &0F JR NZ,nomse ;if data has been changed, no mouse present LD HL,found LD DE,nsammouse LD BC,5 LDIR nomse: ;check for external memory presence IN A,(lmpr) ;external memory can only be paged into EX AF,AF' ;&8000-&FFFF. Unfortunately, our routine IN A,(hmpr) ;is currently in that area, so drop down. AND 31 OR 32 OUT (lmpr),A JP herewego-&8000 herewego: IN A,(hmpr) ;set &8000-&FFFF to external memory OR 128 OUT (hmpr),A LD DE,&0000 ;number of external memory pages counter LD C,0 memloop1: LD A,C ;set external memory page OUT (xmeml),A LD B,255 ramloop2: ;make sure 1st byte can be altered, by LD A,B ;writing/reading 255 values to it. LD (&8000),A LD A,(&8000) CP B JR NZ,nomemhere ;if fails, page not present. DJNZ ramloop2 INC DE nomemhere: LD A,E LD (&8000),A ;restore contents of &8000 DEC C JR NZ,memloop1 IN A,(hmpr) ;page out external memory. AND 127 OUT (hmpr),A JP herewegob herewegob: EX AF,AF' OUT (lmpr),A ;multiply number of pages found by 16 EX DE,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD IX,numstore CALL ptnum ;convert number of pages in HL to an ASCII LD DE,externalk ;number and put it on the screen. EX AF,AF' ;Don't do leading zeroes. LD B,A EX AF,AF' LD A,4 SUB B LD B,A OR A JR Z,nospaces LD A," " spaceloop: LD (DE),A INC DE DJNZ spaceloop nospaces: LD HL,numstore EX AF,AF' LD C,A EX AF,AF' LD B,0 LDIR ;Clears allocation table to start-up values... ;(Wipes data for programs that may not be present any more) LD HL,&5100 LD B,32 loopalloc: LD A,(HL) CP &FF ;page not present marker -- don't clear JR Z,notthis CP &40 ;System values... don't clear. JR Z,notthis CP &60 JR Z,notthis CP &C0 JR Z,notthis LD (HL),&00 notthis: INC HL DJNZ loopalloc ;Clear vectors: ;-------------- ;Reset all system vectors to zero (unused) LD HL,&0000 LD (&5ADA),HL LD (&5ADC),HL LD (&5ADE),HL LD (&5AE2),HL LD (&5AE4),HL LD (&5AE6),HL LD (&5AE8),HL LD (&5AEA),HL LD (&5AEC),HL LD (&5AEE),HL LD (&5AF0),HL LD (&5AF2),HL LD (&5AF4),HL LD (&5AF6),HL LD (&5AF8),HL LD (&5AFA),HL LD (&5AFC),HL LD (&5AFE),HL ;Doesn't clear NMI vector (yet!) LD A,(romvers) ; if ROM version is high enough, ANYIV vector CP 11 ; will be present, so reset it to its RET C ; original value. LD HL,73 LD (&5B70),HL ;restore ANYIV RET ;Reads mouse - was a bug in original for some reason, though. ;----------------------------------------------------------- mouse_scan: LD BC,rdmsel IN A,(C) LD HL,mouse_space LD DE,&080F IN A,(C) AND E CP E RET NZ ms1: LD (HL),A INC HL IN A,(C) DEC D JR NZ,ms1 RET ;Convert 16bit number to ASCII ptnum: EX AF,AF' XOR A EX AF,AF' XOR A LD DE,0 RR C RR D RR C RR D LD A,D ADD H LD H,A LD A,C ADC E LD B,A LD DE,34464 LD C,A CALL pnm2 JR pnum5y pnum5: LD A,&20 pnum5x: LD B,0 pnum5y: LD C,0 LD DE,10000 CALL pnm2 pnum4: LD DE,1000 CALL pnm1 pnum3: LD DE,100 CALL pnm1 pnum2: LD DE,10 CALL pnm1 pnum1: LD A,L ADD &30 JR pnt pnm1: LD BC,0 pnm2: PUSH AF LD A,B LD B,0 AND A pnm3: SBC HL,DE SBC A,C JR C,pnm4 INC B JR pnm3 pnm4: ADD HL,DE ADC A,C LD C,A LD A,B LD B,C AND A JR NZ,pnm5 POP DE ADD D RET Z JR pnt pnm5: ADD &30 CALL pnt POP DE LD A,&30 RET pnt: LD (IX),A INC IX EX AF,AF' INC A EX AF,AF' RET table: DEFB %00000000 ;font conversion table DEFB %00000011 DEFB %00001100 DEFB %00001111 DEFB %00110000 DEFB %00110011 DEFB %00111100 DEFB %00111111 DEFB %11000000 DEFB %11000011 DEFB %11001100 DEFB %11001111 DEFB %11110000 DEFB %11110011 DEFB %11111100 DEFB %11111111 topmesg: DEFM "System Auto-Boot v" DEFB version/10+48,"." DEFB version\10+48+128 drives: DEFM "2 Disc Driv" grammar: DEFB "e","s"+128 internalk: DEFM " 768k Internal RA" ;dummy values for memory size... internex: DEFB "M"+128 ;to confuse hackers? :) DEFM " masquerading as 256" DEFB "k"+128 externalk: DEFM "8192k External RA" DEFB "M"+128 basicrom: DEFM "BASIC ROM version " vrsion: DEFM "x.x" DEFB " "+128 sambus: DEFM "SAMBus Clock " nsambus: DEFM "not " DEFM "foun" DEFB "d"+128 found: DEFM "foun" DEFB "d"+128 sammouse: DEFM "SAM Mouse Interface " nsammouse: DEFM "not foun" DEFB "d"+128 copyright: DEFM "(C) 1994 -Cookie of Entropy" DEFB "-"+128 k256: DEFM "256" k512: DEFM "512" ;Colour bars line table -- Y coord then CLUT data value. Currently RED>WHITE line.table: DEFB 46,2,47,32,48,34,49,34+5,50,34+16+64 DEFB 51,34+68+17,52,34+16+64,53,34+5 DEFB 54,34,55,32,56,2,57,0 DEFB 134,2,135,32,136,34,137,34+5,138,34+16+64 DEFB 139,34+68+17,140,34+16+64,141,34+5 DEFB 142,34,143,32,144,2,145,0 DEFB 255,255 palette: DEFB 0,16,32,48,64,18,96,120 DEFB 0,17,34,51,68,85,102,127 ;standard SAM palette sam.font: MDAT "samfont" length: EQU $-&8009 font.space: DEFS 1536 font.space2: DEFS 1536 stack: DEFS 256 mouse_space: DEFS 9 numstore: DEFS 6 ORG 32901 ;modify SAMDOS to call our routines... DUMP 32901 JP start