;On86 3.1 ;by Jonah Cohen ;http://jonah.ticalc.org #include "TI86.inc" password_size equ $d610 password equ $d611 temp_size equ $8800 temp_pw equ $8801 temp_size2 equ $8900 temp_pw2 equ $8901 .org _asm_exec_ram #define checksum $2a #ifndef checksum call _clrWindow ;clear screen ld a,'$' ;since it's a hex digit call _putc ;display char ;calculate the checksum ld hl,off ;start of off routine ld de,_alt_off_exec ;where it goes in ram push de ;save this pointer ld bc,off_end-off ;size to copy ldir ;copy it pop hl ;retrieve pointer to _alt_off_exec ld a,(hl) ;get first byte dec hl ;since checksum is 1st, 40th, 80th, etc, we subtract 1 ld de,40 ;increment between bytes ld b,5 ;number of bytes we're adding checksum_loop: add hl,de ;go to next byte add a,(hl) ;add byte to checksum djnz checksum_loop ;loop 5 times ld (_alt_off_chksum),a ;store in memory ;a contains checksum. now we display it push af ;save checksum call _SHRACC ;a=upper nibble call dispnibble ;display it pop af ;retrieve checksum and $0f ;mask off upper nibble call dispnibble ;display lower nibble jp _newline ;go to next line and quit dispnibble: cp 10 jr nc,skipadd ;check if A-F add a,'0' ;if not, add '0' skipadd: jp _putc ;display digit #endif nop jp start .dw 0 .dw comment off_checksum: #ifdef checksum .db checksum #endif off: ei ;enable interrupts ld (_onCheckSum),a ;in case they pull a battery release_key: halt in a,(3) bit 3,a jr z,release_key ;make sure they aren't holding down on shutdown: ld hl,(_curRow) ;get cursor row/col push hl ;save onto stack ld a,1 out (3),a ;turn off screen halt ;wait for on key res 1,(iy+13) ;don't save to textShadow call _cursorOff ;turn off cursor ld a,11 out (3),a ;turn on screen call get_password-off+_alt_off_exec ;get password pop de ;retrieve cursor position ld (_curRow),de ;restore cursor ld ix,_JforceCmdNoChar ;return to home screen if correct password ld bc,shutdown-off+_alt_off_exec ;shutdown if incorrect password push bc ;so it can return to it check_password: ld de,password_size ;de points to real password check_pw: call _pstrCmp ;compare passwords ret nz ;return if not equal ;data equal pop af ;clean up stack jp (ix) ;passwords equal title = $-off+_alt_off_exec call _clrLCD ;clear screen ld hl,$002b ;move pen location column = $-2-off+_alt_off_exec ld (_penCol),hl ld hl,message-off+_alt_off_exec ;display title message call _vputs ;display message ld de,$fc70 ;hl points to video mem reverseline: dec e ;move to next byte ld a,(de) ;get byte cpl ;reverse it ld (de),a ;store it jr nz,reverseline ;repeat until we're at top ret get_password: ld hl,enter_password-off+_alt_off_exec ;display "Enter password:" get_pw: push hl call title ;clear screen pop hl ld c,2 ;third line ld (_curRow),bc ld de,temp_size ;store here get_pw_skip: call _puts ;display message ld hl,password_end-off+_alt_off_exec call _puts ;finish prompt with " password:" call _newline ;next line ld h,d ;hl->password length ld l,e ld (hl),l ;reset length ld b,15 ;set counter for 15 keypresses max pw_loop: inc (hl) ;increment password length inc de ;move de to next byte in storage push hl ;save length pointer key_input: call _getcsc ;get a key or a ;is it 0? jr z,key_input ;if so, get another keypress pop hl ;retrieve length pointer ld (de),a ;store input at temporary password storage cp K_ENTER ;is it enter? ret z ;if so, return. ld a,'*' ;print a * to the screen call _putc djnz pw_loop ;get next keypress ret ;messages used in off routine enter_password: .db "Enter",0 password_end: .db " Password:",0 message: .db "Property of " name = $-off+_alt_off_exec off_end: ;end of off routine display: ;pause with message displayed push hl call title ;clear screen, keeping title bar at top pop hl ld c,(hl) ;retrieve column inc hl ld b,$1c ;normal row location call vputs ;display message getkey: call _getcsc ;get keypress or a ;did they hit anything? jr z,getkey ;if not, keep looping ret move_loop: ;bc is current penCol and penRow ;moves pen cursor down 9 pixels and displays whatever hl points to. ld a,b add a,9 ld b,a vputs: ld (_penCol),bc ;move cursor cvputs: ;display message ld a,(hl) ;get character inc hl ;increment string pointer add a,a ;check for a=0 or bit 7 set ret z ;return if 0 push af ;save character call c,_VPUTBLANK ;if bit 7 set, display preceding space pop af ;retrieve character rrca ;shift right again call _vputmap ;display character jr cvputs ;loop until we hit 0 start: call _runIndicOff ;turn off run indicator call _flushAllMenus ;close all menus ld a,(column) ;save column before recopying ld l,off_checksum&$ff ;h=$d7 from _flushAllMenus ld de,_alt_off_chksum ;start of off routine ld c,name-_alt_off_chksum ;safe size to copy ldir ;restore beginning of _alt_off ld c,a ;save column in b ld hl,password_size ;point to password length ld a,(hl) ;get length or a ;if 0, not installed yet jr nz,not_new ;valid password already there d ld (de),a ;reset name inc (hl) ;1 is default password length inc hl ld (hl),K_ENTER ;enter is default password jr menu ;skip password prompt not_new: ld a,c ;get column in a ld (column),a ;restore column call get_password ;get password from user ld ix,menu ;go here if correct call check_password ;check passwords ;wrong password ld hl,wrong_pw_message ;hl points to message "incorrect password." call display ;pause with message exit: res 4,(iy+9) ;no error 07 break if they hit on jp _clrWindow ;clear screen, move cursor to upper left, then quit menu: call title ;display title ld bc,$0e0b ;move pen location ld hl,f1 ;display first message call vputs call move_loop ;display second message bit 7,(iy+$23) ;if alternate off routine flag isn't set, F3 enables it jr z,not_disable ;otherwise, F3 disables it ld l,disable&$ff ;change message not_disable: call move_loop ;move cursor and display text ld l,able_message&$ff ;last part of message ("able On86") call cvputs call move_loop ;display exit start_loop: call _getcsc ;get a keypress cp K_EXIT ;is it exit? jr z,exit ;if so, exit sub K_F1 ;is it F1? jr z,new_password ;get new password inc a ;is it F2? jr z,new_name ;get new name inc a ;is it F3? jr nz,start_loop ;if not, get another keypress change_flag: ld hl,_Flags+$23 ;alt routine flag ld a,(hl) ;get byte xor $80 ;toggle on/off ld (hl),a ;store toggled flag jr menu ;back to main menu store_pw: ;hl points to new password ld de,password_size ;de points to old password where we're copying to ld c,16 ;1 byte for size, 15 for password (b=0 already) ldir ;save password jr menu ;back to main menu new_password: ld hl,new ;"Enter new password:" call get_pw ;get password push hl ;save pointer to first password call _newline ;move to next line ld hl,verify ;message: "Verify password:" ld de,temp_size2 call get_pw_skip ;get second input pop de ;retrieve first password pointer ld ix,store_pw ;where to go if passwords are identical call check_pw ;check passwords ;a mistype ld hl,mistype_message ;hl points to message "passwords do not match." call display ;display and pause menu_: jr menu ;back to main menu new_name: ld bc,$320b ;below "Exit" ld hl,enter_name ;"Enter name: " call vputs ;display prompt ld hl,name ;hl points to name ld (hl),a ;reset name ld d,'A' ;first letter uppercase get_name: push hl ;save name pointer call _getcsc ;get key ld hl,letters ;point to key table ld bc,26 ;26 letters cpir ;search for key pop hl ;retrieve name jr nz,check_space ;not a letter ld a,c ;get letter add a,d ;add to "case" ld d,'a' ;next letter lowercase jr add_letter ;insert letter check_space: cp K_SIGN ;check for space jr nz,check_enter ld a,' ' ;character ld d,'A' ;next letter uppercase add_letter: ld c,a ld a,l ;get string pointer cp (password_size-2)&$ff;check if we're at end jr z,get_name ;can't add any letters ld (hl),c ;store letter inc hl ;increment pointer ld (hl),b ;null terminator ld a,c ;get char back push de call _vputmap ;display letter pop de jr get_name ;get another letter check_enter: cp K_EXIT ;check for exit jr z,got_name ;if so, save name cp K_ENTER ;check for enter jr nz,get_name ;if not, get another letter got_name: ld a,(_penCol) ;get column rra ;divide by two cpl ;make negative add a,70 ;center it ld (column),a ;store as column for on prompt jr menu_ ;redraw menu ;messages not used in off routine new: .db "Enter new",0 verify: .db "Verify",0 enter_name: .db "Enter",$80+'n',"ame: ",0 f1: .db "F1",$80+'-',$80+'C',"hange",$80+'P',"assword",0 .db "F2",$80+'-',$80+'C',"hange",$80+'N',"ame",0 enable: .db "F3",$80+'-'," En",0 disable: .db "F3",$80+'-'," Dis",0 able_message: .db "able",$80+'O',"n86",0 .db "Exit",$80+'-',$80+'Q',"uit",$80+'O',"n86",0 wrong_pw_message: .db $1e,"Incorrect",$80+'P',"assword",0 mistype_message: .db $18,"Passwords",$80+'d','o',$80+'n',"ot",$80+'m',"atch",0 comment: .db "On86 3.1 by Jonah Cohen",0 letters: .db $19,$21,$0a,$12,$1a,$22,$0b,$13,$1b .db $23,$2b,$0c,$14,$1c,$24,$2c,$0d,$15 .db $1d,$25,$2d,$0e,$16,$1e,$26,$2e .end