//----------------------------------------------------- version 2.4 -- // // /¯/\ // / / / // |¯|\ / / / a program by Tijl Coosemans (tijl@ulyssis.org) // | | | / /s/ // | | |/ /u/ website: http://www.kalimero.be/ // | | / /n/ // | |/ /e/ !! with special thanks to Jean Carot, Henk Poley, // | /V/ !! Dan Weiss, Guillaume Hoffmann, Patai Gergely // |__/ / !! and Pieter Van Nuffel for the impressive tips // \__\/ !! and beta testing // // // $LastChangedDate: 2005-02-04 19:39:49 +0100 (Fri, 04 Feb 2005) $ // //-------------------------------------------------------------------- processor z80 //-------------------------------------------------------------------- _cleanUpASM equ 0x52A1 _delMemUpdate equ 0x44B6 _getProgInfo equ 0x4426 _getDataSize equ 0x44CE _insMemUpdate equ 0x44BE _setGraphDirty equ 0x001B _setRunIndicOff equ 0x4795 //-------------------------------------------------------------------- //-------------------------------------------------------------------- // ## startup code //-------------------------------------------------------------------- // The following data is unsquished code. Send(9prgm0V squishes it // (until the End token), copies it to 0x9327 and then runs it. // This code will look up where venus has been stored in ram and then // jump to that location. Since this data is located at the beginning, // it will be executed as if it were code. So be careful if you change // anything here. Disassemble it to see what code it produces. //-------------------------------------------------------------------- db "CD2644" // call _getProgInfo // OP1 is 0x05,"0V" (TIOS) db "D5" // push de db "C9" // ret db 0xD4 // End token db "T" // one random byte db "0000" // 0000 db "C" // an extra random byte // because of the junk code // all this data generates //-------------------------------------------------------------------- // ## non-relocated code (origin is variable) //-------------------------------------------------------------------- //------------------------------------------------------------ // ## relocate venus //------------------------------------------------------------ ld hl,vRstart+2 // 2 for the size bytes add hl,de // DE -> start of prgm0V ld de,vRorg // HL -> vStart ld bc,vRend-vRstart ldir //------------------------------------------------------------ // ## do not run prgm# (prompt) as assembly program //------------------------------------------------------------ ld hl,0x913B+1 // name of TIBasic program ld a,(hl) cp '#' ret z dec hl //------------------------------------------------------------ // ## change program end pointer //------------------------------------------------------------ // (0x9148) is a pointer to the end of the currently running // TIBasic program (which is the one that started Venus). // (0x9146) is a pointer to the currently interpreted byte. // // If (0x9146) is larger than (0x9148), the TIOS returns // from the TIBasic program and that's what we want. // Otherwise the program header would've been something // like this. // :send(9prgm0V // :Return // That Return now isn't necessary. // // HL = 0x913B and (0x9146) is somewhere in user memory, // which starts at 0x9327 and goes upwards. //------------------------------------------------------------ ld (0x9148),hl //------------------------------------------------------------ // ## get program data pointers and size //------------------------------------------------------------ rst 0x20 // copy name to OP1 call _getProgInfo // get vat/data location dec hl // update vat entry ld (hl),0x27 dec hl ld (hl),0x93 ex de,hl call _getDataSize // get data size in DE ex de,hl //------------------------------------------------------------ // ## update all vat entries //------------------------------------------------------------ push de // data location push hl // data size push hl push hl pop bc call _delMemUpdate pop bc ld de,0x9327+4 // data destination - 1 call _insMemUpdate inc de // data destination pop bc // data size pop hl // data location call _setRunIndicOff // resets carry flag jp moveProgram //-------------------------------------------------------------------- // ## relocated code (fixed origin) //-------------------------------------------------------------------- vRstart vRorg equ 0xFE72 rorg vRorg //------------------------------------------------------------ // ## routines //------------------------------------------------------------ // vRandom equ 0xFE72 // vFastCopy equ 0xFE75 //------------------------------------------------------------ jp vRandom //---------------------------------------------------- // ## vFastCopy - copy screen buffer to lcd //---------------------------------------------------- // by Joe Wingbermuehle (ionFastCopy) //---------------------------------------------------- vFastCopy di // don't interrupt ld a,0x80 // first row out (0x10),a ld hl,0x8E29-12-(-(12*64)+1) ld a,0x20 // first column ld c,a inc hl // delay dec hl // delay vFastCopyAgain ld b,64 // 64 rows inc c // next column ld de,-(12*64)+1 out (0x10),a // set current column add hl,de // current column in screenBuf ld de,6 vFastCopyLoop add hl,de // + 6 add hl,de // + 6 = 12 (next row) inc de // delay ld a,(hl) out (0x11),a // display byte dec de // delay djnz vFastCopyLoop // loop 64 times ld a,c // next column cp 0x2C // cp (last column + 1) jr nz,vFastCopyAgain ret //---------------------------------------------------- // ## vRandom - iterate a seed //---------------------------------------------------- // seed = (254 * seed + 253) mod 65537 // 0 =< seed < 65536 (formula never generates 65536) //---------------------------------------------------- vRandom ld de,0x0000 // get seed ld a,d // AHL = 256 * seed + 253 ld h,e ld l,253 or a // clear carry flag sbc hl,de // AHL = 255 * seed + 253 sbc a,0 sbc hl,de // AHL = 254 * seed + 253 ld d,0 sbc a,d ld e,a sbc hl,de // HL = HL - A jr nc,$+3 // +1 if negative inc hl // HL = AHL mod 65537 ld (vRandom+1),hl // store seed ret //---------------------------------------------------- //------------------------------------------------------------ // ## move program to progstart //------------------------------------------------------------ // Swap mem area A (program) and B (progstart-program). //------------------------------------------------------------ swapAgain sbc hl,bc jr nc,swapSize add hl,bc // HL = size A mod size B push bc ex (sp),hl // HL = size B pop bc // BC = new size A add hl,de // HL = end A sbc hl,bc // HL = new A moveProgram push bc // BC = new size A swapLoop ld a,(de) // swap (A) and (B) ldi dec hl ld (hl),a inc hl jp pe,swapLoop // loop size A times sbc hl,de // HL = size B ex (sp),hl // HL = size A pop bc // BC = size B swapSize jr nz,swapAgain //------------------------------------------------------------ // ## final things //------------------------------------------------------------ ld h,a // init vRandom seed ld a,r ld l,a ld (vRandom+1),hl call _setGraphDirty // graph buffer is dirty res 0,(iy+0x17) // always clear graph buffer call nc,_cleanUpASM // remove startup code // always called // call nc is the End token //------------------------------------------------------------ // ## run program //------------------------------------------------------------ // Make sure carry is reset. //------------------------------------------------------------ or a jp 0x9330 // jump to loaded program //------------------------------------------------------------ // ## end of relocated code //------------------------------------------------------------ rorg $$ vRend //-------------------------------------------------------------------- // ## end of program //-------------------------------------------------------------------- // EndxxxxxxEnd //-------------------------------------------------------------------- db 0xD4 // End token //--------------------------------------------------------------------