I'm scratching the surface of assembly language programming as it pertains to my real hardware MZ-700 and the various emulators I've tried. I've done some Z80 programming in the past, but it's all been for non-specific platforms like single board computer stuff. Anyway, I'm familiar enough with the language and processor architecture, and now learning how to specifically apply it to the 700. Up until recently, I've used a DOS command line assembler called TASM for any "greater-than-hello-world" programming I've done for a Z80. Does anyone know how to port .BIN or .OBJ files generated by TASM on a PC to something that the MZ-700 can work with? Using the assemblers that were written to be executed within the 700 system is proving to be more of a challenge than I want right now because my Windows PC with a US keyboard layout doesn't 100% translate properly to the MZ system. My @ symbol is a double quote " and underscore _ is an equals sign = just to name a couple of misses. There are lots! I'd like to be able to write code in Notepad or some other text editor and assemble with TASM, then somehow convert that file output to .MZF, I suppose. I think I'm asking for something analogous to what MASM's linker does linking .OBJ to .EXE for an x86 system, if that helps.
Thank you so very much for that command line assembler with Sharp file output!! That has made Sharp programming life much, much easier. True, you must change the file extension of the output file (for my Sharp machine, at least) , and if it should help anyone to know this, create yourself a batch file containing the script below and programming life gets even easier. I named mine MZF.BAT. Just replace 'Hello' with whatever you've named your .asm file. I'm running Windows 7 32-bit:
Z80AS Hello.asm -m Hello.MZT
ren Hello.mzt Hello.mzf
Now just double-click the .BAT file name in the file browser and instant MZF file! That is, if the assembly went well.
Code: Select all
@del ..\SPACERALLY.mzf @echo --- [ Assembling game.a80... ] z80as.exe -x -m "SPACE RALLY" game.a80 @if %ERRORLEVEL% NEQ 0 goto :failure @echo. @echo --- [ Copying game as SPACERALLY.mzf ] copy /y game.mzt ..\SPACERALLY.mzf @if %ERRORLEVEL% NEQ 0 goto :failure @goto :eof :failure @exit /b 1 @goto :eof
-x outputs an .als file which combines hexa codes and source lines to help to debug and check address coherency, and so on.
This build.bat is called in /src from another build.bat which deals with several aspects of building.
Playing around with Z80AS and learning the ropes of the monitor routines. I expanded on this example:
Code: Select all
ORG $1200 LD A, $16 ; force clear screen CALL $0012 ; print clear screen LD DE, MSG1 ; Show Greeting and exit instructions CALL $0015 CALL $0009 ; Next line LD DE, MSG1+35 ; Clearance line (= <SPACE>+<CR>) CALL $0015 CALL $0009 ; Next line START: CALL $001B ; Check Keyboard, trap PC PUSH AF ; Save result CP $64 ; SHIFT+BREAK? (On Emulator, SHIFT+ESC) JP Z, EXIT ; Yes? Exit to Monitor. POP AF ; No? CALL NZ, $03C3 ; print Key hex value JP Z, START WAIT: CALL $001B ; Wait for finger to leave key JP NZ, WAIT JP START ; and do it all again. EXIT: POP AF ; Level up the stack LD A, $16 ; force clear screen CALL $0012 ; print clear screen JP $00AD ; Exit to Monitor MSG1: DB " PRESS KEYS. SHIFT+BREAK = EXIT ", $0D END
EDIT: For better clarification... Should I always ORG my Monitor Launched executable code at $1200? Also, I'm unclear on the syntax of the DUP statement. Can you show me how that's used? Everything I tried wouldn't assemble.
2) ORG can be anything, even $0000 or $F000 if you plan to rewrite some ROM contents. You are free to put your code somewhere between $1200-$CFFF if in DRAM.
3) I believe there is no DUP :
DB <expression> [, <expression> ...]
DB "<string>" + <immediate value>
Embeds the byte string specified by <expression>. If <character string> is specified, the ASCII code string is embedded.
If + <immediate value> is specified after <character string>, the specified immediate value is added to the last byte of <character string>.
DW <expression> [, <expression> ...]
Embeds the word string specified by <expression>.
DS <Equation 1> [, <Equation 2>]
Embeds 0s in the number of bytes specified in <Expression 1>. If <Expression 2> is specified, fill it with that value.
Well, I still have haven't done anything more interesting than writing a keyboard examination routine. It has had some improvements. I did just minutes ago, run the keyboard program on the real MZ-700. Up until then, it was only an emulator running on Win 7. For the most part, running it on the '700 works like it does on the emulator. However, there's one peculiarity... I can't get any results from pressing any of the function keys. I can't get results from F1 to F4 on the emulator either but F6 to F9 do work for me there. I'm guessing F1 to F4 not working on either platform is probably due to the particular monitor call I'm using for key input, but wanted to get answers from those with experience, so here's what I've assembled with Z80AS:
Code: Select all
ORG $1200 CALL INITIALIZE_DISPLAY MAIN: CALL DISPLAY_COUNTERS CALL $001B PUSH AF CP $64 ; SHIFT+BREAK (On PC, SHIFT+ESC or SHIFT+END) JP Z, EXIT ; Exit to Monitor CP $15 ; SHIFT+DEL = $15 = CLS CALL Z, CLEAR_SCREEN_15 ; CLS and Show Code for SHIFT+DEL CALL Z, RESET_COUNTERS LD DE, MSG2 ; <SPACE> + $0D CALL Z, $0015 POP AF CALL NZ, PRINT_CODE JP NZ, WAIT JP MAIN WAIT: CALL $001B JP NZ, WAIT LD DE, CHAR_COUNT LD A, (DE) INC A CP 8 LD (DE), A CALL Z, NEW_LINE JP MAIN EXIT: CALL CLEAR_SCREEN POP AF ; Restore $64 to A CALL $03C3 ; Print the $64 for user JP $00AD ; Exit to Monitor PRINT_CODE: PUSH AF CALL $03C3 LD DE, MSG2 ; <SPACE> + $0D CALL $0015 POP AF RET DISPLAY_COUNTERS: LD HL, $D070 ;$D3C0 LD DE, CHAR_COUNT LD A, (DE) ADD A, $20 LD B, A SUB $2A JR C, NUMERAL_COL LD A, (DE) SUB 10 ADD A, $01 LD B, A NUMERAL_COL: LD A, B LD (HL), A LD HL, $D071 ;$D3C3 LD DE, LINE_COUNT LD A, (DE) ADD A, $20 LD B, A SUB $2A JR C, NUMERAL_ROW LD A, (DE) SUB 10 ADD A, $01 LD B, A NUMERAL_ROW: LD A, B LD (HL), A RET CLEAR_SCREEN_15: PUSH AF CALL CLEAR_SCREEN LD DE, MSG1 CALL $0015 CALL $0009 LD DE, MSG2 ; <SPACE> + $0D CALL $0015 CALL $0009 POP AF RET CLEAR_SCREEN: LD A, $16 ;force clear screen CALL $0012 ;print clear screen RET NEW_LINE: PUSH AF LD A, 0 LD DE, CHAR_COUNT LD (DE), A LD DE, LINE_COUNT LD A, (DE) CP 15 CALL Z, NEW_PAGE CALL NZ, INC_LINE CALL NZ, $0009 LD DE, MSG2 ; <SPACE> + $0D CALL $0015 POP AF RET NEW_PAGE: PUSH AF NEW_PAGE_LP: LD HL, $D070 LD A, '.' LD (HL), A LD HL, $D071 LD (HL), A CALL $001B JP Z, NEW_PAGE_LP ; Hold here until a key is pressed CALL RESET_COUNTERS CALL CLEAR_SCREEN_15 POP AF RET INC_LINE: LD DE, LINE_COUNT LD A, (DE) INC A LD (DE), A RET INITIALIZE_DISPLAY: CALL CLEAR_SCREEN LD DE, MSG1 CALL $0015 CALL $0009 LD DE, MSG2 ; <SPACE> + $0D CALL $0015 CALL $0009 PUSH AF LD A, 0 LD DE, CHAR_COUNT LD (DE), A LD DE, LINE_COUNT LD (DE), A LD DE, MSG2 ; <SPACE> + $0D CALL $0015 POP AF RET RESET_COUNTERS: PUSH AF LD A, 0 LD DE, CHAR_COUNT LD (DE), A LD DE, LINE_COUNT LD (DE), A POP AF RET MSG1: DB " SHIFT+DEL = CLS, SHIFT+BREAK = EXIT" MSG2: DB " ", $0D CHAR_COUNT: DB 00h LINE_COUNT: DB 00h END
I do have other finicky/flaky keys that I suppose are not 100% due to the age and wear of the computer. I can get those to work by a little wiggling on the key itself. This trick doesn't seem to work for the function keys though. That's why I'm guessing it's the particular monitor call. Most keys do work surprisingly well for their age. Sadly, the space bar is one of the flaky ones.