;; Emacs Mode Selection Info: -*-mode: ASM; coding: iso-latin-1-dos;-*- * ;; ******************************************************************************************** ;; File Name: Four_3.asm ;; Auther: John L. Weinrich ;; Date: 01/31/03 ;; Useage 4004 TIC-TAC-TOE Game ;; Description: ;; ;; This routine is used for the 4004 TIC-TAC-TOE Game. ;; ;; Assumptions: ;; This assembly code and all the included files assume the following: ;; ;; RAM Memory: 2048 X 4 (8 RAM banks, 4 RAMs/bank, 4 registers/RAM, 16 Char/Reg) ;; 256 status characters. ;; 2 I/O Port ;; RAM1: SPEAKER PITCH/write ;; RAM2: SPEAKER LEVEL/write ;; ;; ROM Memory: 4096 X 8 (16 ROMs @ 256 locations ;; 11 I/O Ports (3 - R/W, 4- Read, 4 - Write) ;; ROM0: MISC/read ;; ROM0: MISC/write ;; ROM3: DISPLAY HIGH IN/read ;; ROM3: DISPLAY HIGH OUT/write ;; ROM4: DISPLAY LOW IN/read ;; ROM4: DISPLAY LOW OUT/write ;; ROM5: KEYBOARD HIGH INPUT/read ;; ROM6: KEYBOARD LOW INPUT/read ;; ROM7: MISC2/write ;; ROM8: PAGE/write ;; ROM9: RANDOM NUMBER GENERATOR/read ;; ROM10: FPGA VERSION/read ;; ;; See "4004 FPGA Design" and "4004 Software Design " documents for more detail information. ;; ;; Registers used: ;; Memory used: ;; Entrance parameters: ;; Exit parameters: ;; Labels used: ;; ******************************************************************************************** ;; ******************************************************************************************** ;; Here are the assembler directives ;; What CPU to assemble for and where in memory to start ;; Also there is the all the include files ;; except subroutines. include "four_ALL.equ" ; Get all equates include "bitfuncs.inc" ; Include bit functions so that fin can be ; loaded from a label (upper 4 bits of address ; are loped off) include "four_03.equ" ; Get Page #3 equates cpu 4004 ; Tell assembler that the processor is a 4004 org CODE_LOCATION ; Set code start location in memory ;; ******************************************************************************************** ;; This is the begining of the get mode routine ;; ******************************************************************************************** ;; Clear display, turn cursor off GetMode jms DisplayModeCMND ; Put the display into command mode jms ClearDisplay ; Clear the display jms OffCurDisplay ; Turn off display cursor jms CurBlinkOffDis ; Turn off display cursor blink jms WaitForDisplay ; Wait for display to become ready for data or commands jms DisplayModeData ; Set the display to data mode ;; Display game welcome message jms DisWelcome1 ; Display the welcome message jms DisWelcome2 ; "" jms DisKeyPress ; Prompt user to press any key to continue ;; Wait for key press jms GetChar ; Get charactor from keyboard jms Level5 ; Set level to "5" jms Pitch1116HZ ; Set pitch to "happy" jms Beep ; Tell user that key was pressed jms DisplayModeCMND ; Put the display into command mode jms ClearDisplay ; Clear the display jms WaitForDisplay ; Wait for display to become ready for data or commands jms DisplayModeData ; Set the display to data mode ;; Display game mode prompt jms DisModePrompt1 ; Display the prompt for game mode selection jms DisModePrompt2 ; "" jms DisModePrompt3 ; "" ;; ******************************************************************************************** ;; Get key press for game mode selection ;; ;; Wait for key press KeyNotValid1 jms GetChar ; Get charactor from keyboard ;; Get game mode selection ;; Get upper nibble from keyboard ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_H_RAM ; Select high keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard high state charactor from RAM fim SCRATCH_1_P,'1' ; Get the number "1" sub SCRATCH_1_H ; Check that the upper nibble is a number jcn Z,GetLowNib1 ; Equal, now get lower nibble jms InitKYBD ; clear out any key presses jms Level15 ; Set level to "15" jms Pitch406HZ ; Set pitch to "sad" jms Beep ; Tell user that key was pressed jun KeyNotValid1 ; Not equal, prompt again ;; Get lower nibble from keyboard GetLowNib1 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_L_RAM ; Select low keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard low state charactor from RAM fim SCRATCH_1_P,'1' ; Get the number "1" sub SCRATCH_1_L ; Check that the lower nibble is the number "1" jcn Z,Mode1 ; Equal, set mode to 1 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_L_RAM ; Select low keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard low state charactor from RAM fim SCRATCH_1_P,'2' ; Get the number "2" sub SCRATCH_1_L ; Check that the lower nibble is the number "2" jcn Z,Mode2 ; Equal, set mode to 2 jms Level15 ; Set level to "15" jms Pitch406HZ ; Set pitch to "sad" jms Beep ; Tell user that key was pressed jun KeyNotValid1 ; Loop till valid key is pressed ;; Store mode selection Mode2 jms SetMode2 ; Call routine to set/store mode 2 jms Level5 ; Set level to "5" jms Pitch1116HZ ; Set pitch to "happy" jms Beep ; Tell user that key was pressed jun ModeSet ; Mode stored, continue Mode1 jms SetMode1 ; Call routine to set/store mode 1 jms Level5 ; Set level to "5" jms Pitch1116HZ ; Set pitch to "happy" jms Beep ; Tell user that key was pressed jms DisplayModeCMND ; Put the display into command mode jms ClearDisplay ; Clear the display jms WaitForDisplay ; Wait for display to become ready for data or commands jms DisplayModeData ; Set the display to data mode jms DisSkillPrompt1 ; Display the prompt for skill level #1 jms DisSkillPrompt2 ; Display the prompt for skill level #2 jms DisSkillPrompt3 ; Display the prompt for skill level #3 ;; Get skill level charactor KeyNotValid2 jms GetChar ; Get charactor from keyboard ;; Get Skill level selection ;; Get upper nibble from keyboard ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_H_RAM ; Select high keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard high state charactor from RAM fim SCRATCH_1_P,'1' ; Get the number "1" sub SCRATCH_1_H ; Check that the upper nibble is a number jcn Z,GetLowNib2 ; Equal, now get lower nibble jms InitKYBD ; clear out any key presses jms Level15 ; Set level to "15" jms Pitch406HZ ; Set pitch to "sad" jms Beep ; Tell user that key was pressed jun KeyNotValid1 ; Not equal, prompt again ;; Get lower nibble from keyboard GetLowNib2 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_L_RAM ; Select low keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard low state charactor from RAM fim SCRATCH_1_P,'1' ; Get the number "1" sub SCRATCH_1_L ; Check that the lower nibble is the number "1" jcn Z,Skill1 ; Equal, set skill to 1 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_L_RAM ; Select low keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard low state charactor from RAM fim SCRATCH_1_P,'2' ; Get the number "2" sub SCRATCH_1_L ; Check that the lower nibble is the number "2" jcn Z,Skill2 ; Equal, set skill level to 2 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_L_RAM ; Select low keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard low state charactor from RAM fim SCRATCH_1_P,'3' ; Get the number "2" sub SCRATCH_1_L ; Check that the lower nibble is the number "2" jcn Z,Skill3 ; Equal, set skill level to 2 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,KYB_STATE_L_RAM ; Select low keyboard state charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get keyboard low state charactor from RAM fim SCRATCH_1_P,'4' ; Get the number "2" sub SCRATCH_1_L ; Check that the lower nibble is the number "2" jcn Z,Skill4 ; Equal, set skill level to 2 jms Level15 ; Set level to "15" jms Pitch406HZ ; Set pitch to "sad" jms Beep ; Tell user that key was pressed jun KeyNotValid2 ; Loop till valid key is pressed ;; Set skill level to 1 Skill1 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,SKILL_STATE_RAM ; Select skill level state charactor src SRC_P ; Tell RAM of selection ldm SKILL_LEVEL1 ; Get skill level #1 wrm ; Save skill level in RAM jun SkillLevelSet ; Continue ;; Set skill level to 2 Skill2 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,SKILL_STATE_RAM ; Select skill level state charactor src SRC_P ; Tell RAM of selection ldm SKILL_LEVEL2 ; Get skill level #2 wrm ; Save skill level in RAM jun SkillLevelSet ; Continue ;; Set skill level to 3 Skill3 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,SKILL_STATE_RAM ; Select skill level state charactor src SRC_P ; Tell RAM of selection ldm SKILL_LEVEL3 ; Get skill level #3 wrm ; Save skill level in RAM jun SkillLevelSet ; Continue ;; Set skill level to 4 Skill4 ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,SKILL_STATE_RAM ; Select skill level state charactor src SRC_P ; Tell RAM of selection ldm SKILL_LEVEL4 ; Get skill level #4 wrm ; Save skill level in RAM jun SkillLevelSet ; Continue SkillLevelSet jms Level5 ; Set level to "5" jms Pitch1116HZ ; Set pitch to "happy" jms Beep ; Tell user that key was pressed ;; Display game player #1 prompt ModeSet jms DisplayModeCMND ; Put the display into command mode jms ClearDisplay ; Clear the display jms WaitForDisplay ; Wait for display to become ready for data or commands jms DisplayModeData ; Set the display to data mode jms DisPlayer1 ; Display the prompt for player #1 selection1 jms DisPlayer3 ; Display the prompt for player #1 selection2 jms DisPlayer12 ; Display the prompt for player #1 selection2 ;; Turn on display cursor jms DisplayModeCMND ; Put the display into command mode jms OnCurDisplay ; Turn on display cursor jms CurBlinkOnDis ; Turn off display cursor jms DisplayModeData ; Put the display back to data mode jms GetPlayer1 ; Get player #1 name fim SCRATCH_1_P,DEFAULT_PLAYER ; Get default player constant sub SCRATCH_1_L ; Check if default player is selected jcn NZ,NotDefaultP1 ; Not default name jms DefaultPlayer1 ; Set player #1 to default name ;; Check if needed to get player #2 name NotDefaultP1 jms Level5 ; Set level to "5" jms Pitch1116HZ ; Set pitch to "happy" jms Beep ; Tell user that key was pressed ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,GAME_MODE_RAM ; Select mode charactor src SRC_P ; Tell RAM of selection clb ; Make sure accumulator is clear rdm ; Get mode fim SCRATCH_1_P,MODE2 ; Select Mode #2 sub SCRATCH_1_L ; Check for mode #2 jcn NZ,NotMode2 ; Not Mode #2 ;; Display game player #2 prompt jms DisplayModeCMND ; Put the display into command mode jms ClearDisplay ; Clear the display jms WaitForDisplay ; Wait for display to become ready for data or commands jms DisplayModeData ; Set the display to data mode jms DisPlayer1 ; Display the prompt for player #1 selection1 jms DisPlayer3 ; Display the prompt for player #1 selection2 jms DisPlayer22 ; Display the prompt for player #1 selection2 ;; Turn on display cursor jms DisplayModeCMND ; Put the display into command mode jms OnCurDisplay ; Turn on display cursor jms CurBlinkOnDis ; Turn off display cursor jms DisplayModeData ; Put the display back to data mode jms GetPlayer2 ; Get player #2 name fim SCRATCH_1_P,DEFAULT_PLAYER ; Get default player constant sub SCRATCH_1_L ; Check if default player is selected jcn NZ,NotDefaultP2 ; Not default name jms DefaultPlayer2 ; Set player #2 to default name NotDefaultP2 jms Level5 ; Set level to "5" jms Pitch1116HZ ; Set pitch to "happy" jms Beep ; Tell user that key was pressed jun GetModeP3Rtn ;; Set player #2 to 4004 NotMode2 jms Mode2_4004 jun GetModeP3Rtn