zxsp - The Sinclair ZX Home Computer Simulator

Assembler

zxsp comes with a built-in Done: 2008-05-26 - Version 0.7.2
Done: 2007-07-28 - Version 0.7.1
Done: 2007-05-13 - Version 0.7.0
Done: 2007-05-01 - Version 0.6.7.1
Done: 2007-03-29 - Version 0.6.6
Done: 2006-11-18 - Version 0.6.5
Done: 2005-01-16 - Version 0.6.2
Done: 2004-11-26 - Version 0.6.1
version
of the Assembler: zasmzasm Snapshots: .Z80z80 Assemblerassembler. This allows to load Snapshotssnapshots from Assemblerassembler source, making edit-assemble-load-and-test cycles a more convenient task.

The required file name extension for Assemblerassembler sources is ".ass" or ".src".

You can find the Assemblerassembler as a stand-alone command line tool at k1.spdns.de/Develop/projects/zasm/. Source Done: 2000 – 0.1.8 and 0.2.2and binary distributions are in subdirectory k1.spdns.de/Develop/projects/zasm/distributions/ Done: 2000 – 0.1.8 and 0.2.2and documentation in subdirectory k1.spdns.de/Develop/projects/zasm/doc/. You may want to read the documentation in any case. You can Assemblerassemble Snapshots: .Z80Z80 source online with the cgi interface at k1.spdns.de/cgi-bin/zasm.cgi.

zasm

Assembler: zasmzasm is a two-pass Assemblerassembler which uses the standard layout for Snapshots: .Z80z80 Assemblerassembler sources: labels start in column 1, opcodes are prepended by white space Done: 2000 – 0.1.8 and 0.2.2and comments are introduced with a semicolon.

Assembler source example:
foopoint:   add     a,'0'           ; convert to numeric character
            call    print_a         ; to current stream
            ret

Label names can be any length, conditional assembly with #if, #else Done: 2000 – 0.1.8 and 0.2.2and #endif is possible. The Assemblerassembler can #include To Do: other:other Assemblersource files or #insert binary files. Numeric expressions use proper operator precedence. Numeric literals may be in decimal, hex, binary or ascii, where multiple formats are supported.

The Assemblerassembler requires a special overall layout of the source:

Template for .sna snapshots
#target Snapshots: .SNAsna
#head 27
    ; ...               ; Debugger: Registersregisters, as defined for the .Snapshots: .SNAsna format
Writing .tap sources: #code#code $4000,$c000       ; origin (must be $4000) Done: 2000 – 0.1.8 and 0.2.2and block size ($4000 or $c000)
    ; ...
#end
Template for .tap files
#target Snapshots: .TAPtap
Writing .tap sources: #code#code   0,17,0          ; header block
    ; ...
Writing .tap sources: #code#code   0,2000,255      ; data block
    ; ...
#end
Template for .o or .80 files
    #target 80              ; or target o
    Writing .tap sources: #code#code   $4000,$2000     ; origin (must be $4000) Done: 2000 – 0.1.8 and 0.2.2and memory size (max. $c000)
        ; ...
    #end
    Template for .p or .81 files
      #target 81              ; or target p
      Writing .tap sources: #code#code   $4009,$2000-$09 ; origin (must be $4009) Done: 2000 – 0.1.8 and 0.2.2and memory size (max. $c000-$09)
          ; ...
      #end

      Integration in zxsp

      When you load an Assemblerassembler source from the 'open file' dialog, the source is assembled Done: 2000 – 0.1.8 and 0.2.2and the resulting file is loaded just as if you had opened it in first place.

      However, the original Assemblerassembler source filename is remembered for 'Reload current file'. So if you select 'Reload current file' from the file menu then the source is assembled again before loading. This is handy if you modify your source Done: 2000 – 0.1.8 and 0.2.2and want to test the new Done: 2008-05-26 - Version 0.7.2
      Done: 2007-07-28 - Version 0.7.1
      Done: 2007-05-13 - Version 0.7.0
      Done: 2007-05-01 - Version 0.6.7.1
      Done: 2007-03-29 - Version 0.6.6
      Done: 2006-11-18 - Version 0.6.5
      Done: 2005-01-16 - Version 0.6.2
      Done: 2004-11-26 - Version 0.6.1
      version
      : Just save the source Done: 2000 – 0.1.8 and 0.2.2and press 'cmd' + 'R' in zxsp Done: 2000 – 0.1.8 and 0.2.2and it loads the new Done: 2008-05-26 - Version 0.7.2
      Done: 2007-07-28 - Version 0.7.1
      Done: 2007-05-13 - Version 0.7.0
      Done: 2007-05-01 - Version 0.6.7.1
      Done: 2007-03-29 - Version 0.6.6
      Done: 2006-11-18 - Version 0.6.5
      Done: 2005-01-16 - Version 0.6.2
      Done: 2004-11-26 - Version 0.6.1
      version
      .

      If the Assemblerassembler finds errors then loading fails. An alert box pops up to indicate the case Done: 2000 – 0.1.8 and 0.2.2and the Assemblerassembler listing of pass 1 or pass 2 (whatever is appropriate) is saved for your inspection.

      Writing .sna sources

      If you create a .Snapshots: .SNAsna Snapshotssnapshot, then setting up the Debugger: Registersregisters, system variables Done: 2000 – 0.1.8 and 0.2.2and BASIC program can be painful. A good idea is, to write the BASIC program on a Modifier keys: ZX SpectrumZX Spectrum, that is, in zxsp, Done: 2000 – 0.1.8 and 0.2.2and save a Snapshotssnapshot at the position where you want to start off. Then split the Snapshotssnapshot with a hexeditor into Debugger: Registersregisters (first 27 bytes) Done: 2000 – 0.1.8 and 0.2.2and screen, sysvars Done: 2000 – 0.1.8 and 0.2.2and BASIC program (length varies) Done: 2000 – 0.1.8 and 0.2.2and #insert these files into the main Assemblerassembler source files after #head Done: 2000 – 0.1.8 and 0.2.2and Writing .tap sources: #code#code respectively.

      The files for the following example are available here: sna_example.zip

      Example for a .sna source
      #target Snapshots: .SNAsna
      
      #head   27
      #insert "empty_sna_head"
      
      Writing .tap sources: #code#code   $4000,$c000
      #insert "empty_sna_page1"
      
      
      ; note:
      ;   bc = return value
      ;   rst 16: print char in A
      
      OPKAN       equ     $1601       ; open channel in register A
      
      ; ------------- entry point ----------------------
      start:
                  ld      a,2         ; Stream: main screen
                  call    OPKAN       ; open channel
      
                  call    printmsg
                  defm    $0d, "Hello world", $0d, $00
      
                  ld      bc,4711
                  ret
      
      printmsg:   pop     hl
      printmsg_1  ld      a,(hl)
                  inc     hl
                  and     a
                  ret     z
                  rst     16
                  jr      printmsg_1
      
      #end
      Writing .tap sources

      If you create a .Snapshots: .TAPtap Snapshots: .TAPtape file, then you probably need 4 Writing .tap sources: #code#code blocks in your source, because a BASIC loader is required in most cases.

      The files for the following example are available here: tap_example.zip

      Example for a .tap source
      headerflag:     equ 0
      dataflag:       equ $ff
      
      tCLEAR  equ     $FD             ; token CLEAR
      tLOAD   equ     $EF             ; token LOAD
      tCODE   equ     $AF             ; token CODE
      tPRINT  equ     $F5             ; token PRINT
      tUSR    equ     $C0             ; token USR
      tLET    equ     $F1             ; token LET
      tSAVE   equ     $F8             ; token SAVE
      
      #target Snapshots: .TAPtap
      
      Writing .tap sources: #code#code   0,17,headerflag     ; program header
      
              defb    0               ; program
              defm    "testloader"    ; make sure these are 10 bytes!
              defw    programsize     ; length of basic program Done: 2000 – 0.1.8 and 0.2.2and variables
              defw    10              ; line number for auto start
              defw    programsize     ; length of basic program without variables
      
      
      Writing .tap sources: #code#code   0,$100,dataflag     ; program data. size is truncated as required
      
      ; 60 CLEAR $6000
                  defb    0,60                    ; line number
                  defb    end60-($+1)             ; line length
                  defb    0                       ; statement number
                  defb    tCLEAR                  ; token CLEAR
                  defm    '24576',$0e0000006000   ; number $6000, ascii & internal format
      end60:      defb    $0d                     ; line end marker
      
      ; 70 LOAD "" CODE $8000
                  defb    0,70                    ; line number
                  defb    end70-($+1)             ; line length
                  defb    0                       ; statement number
                  defb    tLOAD,'"','"',tCODE     ; token LOAD, 2 quotes, token CODE
                  defm    '32768',$0e0000008000   ; number $8000, ascii & internal format
      end70:      defb    $0d                     ; line end marker
      
      ; 80 LET n = USR 32768
                  defb    0,80                    ; line number
                  defb    end80-($+1)             ; line length
                  defb    0                       ; statement number
                  defb    tLET,'n','=',tUSR       ; token LET, n, =, token USR
                  defm    '32768',$0e0000008000   ; number $8000, ascii & internal format
      end80:      defb    $0d                     ; line end marker
      
      programsize     equ     $
      
      
      Writing .tap sources: #code#code   0,17,headerflag         ; CODE header
      
              defb    3               ; code
              defm    "testcode  "    ; make sure these are 10 bytes!
              defw    codeend-32768   ; length of data block
              defw    32768           ; original position
              defw    0               ; unused
      
      
      Writing .tap sources: #code#code   32768,32768,dataflag    ; CODE data
      
      ; note:
      ;   bc = return value
      ;   rst 16: print char in A
      
      OPKAN       equ     $1601       ; open channel in register A
      
      ; ------------- entry point ----------------------
      start:
                  ld      a,2         ; Stream: main screen
                  call    OPKAN       ; open channel
      
                  call    printmsg
                  defm    $0d, "Hello world", $0d, $00
      
                  ld      bc,4711
                  ret
      
      printmsg:   pop     hl
      printmsg_1  ld      a,(hl)
                  inc     hl
                  Done: 2000 – 0.1.8 and 0.2.2and     a
                  ret     z
                  rst     16
                  jr      printmsg_1
      
      codeend     equ     $
      #end
      #code

      As you may already know from the Assembler: zasmzasm documentation, the three arguments to Writing .tap sources: #code#code are code origin, block length (max.), Done: 2000 – 0.1.8 and 0.2.2and block type. The final checksum for each block is calculated Done: 2000 – 0.1.8 and 0.2.2and appended by Assembler: zasmzasm automatically. Writing .tap sources: #code#code blocks for #target Snapshots: .TAPtap are truncated as required. So it is not neccessary to know the exact length beforehand. Just insert your expected maximum sizes.

      Getting the proper internal representation for BASIC lines may be a little bit tricky. You may enter them in zxsp Done: 2000 – 0.1.8 and 0.2.2and save a Snapshotssnapshot which you can scrutinize in a hex editor. The basic layout should be obvious from the above example.

      After assembling a Snapshots: .TAPtap file zxsp loads this in the "open file" mode, that is, it does not insert it into the Tape recordertape recorder but tries to .TAP: Instant loading ".tap" filesinstant load it. For this to work, you must only use the Snapshots: .ROM
      MMU registers for the +128K / +2: ROM $0000
      rom
      Snapshots: .TAPtape loading routines. Whenever your code on the Snapshots: .TAPtap file starts to load with it's own routine, then .TAP: Instant loading ".tap" files
      Limitations of tzx files in zxsp: Instant loading
      instant loading
      does not finish, because this is not detected by the emulator. You had to insert the Snapshots: .TAPtap file into the Tape recorder: The built-in virtual tape recordervirtual tape recorder instead. Currently (zxsp 0.7.1) the Snapshots: .TAPtap file is always loaded into a Modifier keys: ZX SpectrumZX Spectrum 48k. This may be improved some day.

      Valid HTML   Valid CSS